我正在为一个应用程序创建一个Django后端,我希望我们的实体的主键满足某些标准.第一个标准是它始终是10个字符的长度,以便在需要时易于阅读和口头分享.第二个标准是,它始终遵循相同的格式:

  1. 实体的前2个字符=>代码(例如,"US"表示用户记录,"To"表示主题,"BO"表示图书等),这样任何人都可以很容易地说出某个ID的用途
  2. 后2个字符=>创建日期的年份(‘24’、‘23等)
  3. 其余6个字符是随机生成的字母数字字符

我编写了以下代码来生成id:-

def auto_increment_id():

alphanumeric_chars = string.ascii_letters + string.digits
last_chars = ''.join(random.choice(alphanumeric_chars) for _ in range(6))
user_id = 'US' + str(datetime.date.today().year)[2:] + str(last_chars)
return user_id

我在用户模型中设置了它,如下所示

class User(models.Model):
id = models.CharField(max_length=10, primary_key=True,
                      default=auto_increment_id, editable=False)

我的问题是,当我们扩展时,这是否会导致性能问题或其他问题?这是一个明智的安排吗?

推荐答案

除了性能之外,这种策略还存在一些问题.

您只能有36^6个可能的6个字母数字字符随机字符串.这实际上接近于4字节整数中相同数量的正值(PostgreSQL不支持无符号整数数据类型).因此,使用整数而不是字符串可以节省1/3的空间.

如果您的随机六位数字符串生成的字符串已被另一行使用,会发生什么情况?这将导致重复的键冲突,并且您的客户端将需要重新try 插入(可能不止一次).显然,这将是罕见的,因为生成相同字符串的机会很低.但是客户端仍然必须处理这个潜在的错误,因为它不能保证永远不会发生.因此,您需要为非常罕见的情况编写更多代码.不要忘记在您的自动化测试中包括这个 case .

另一种方法是在三列上定义一个主键约束,但是是Django currently only supports single-column primary key列.

但是,我上面提到的两个问题可以通过使用传统的IDENTITY主键轻松解决--即一个自动递增的整型列.

  • 更节省空间
  • 没有随机重复密钥的可能性
  • 由Django型号支持

我认为你正在试图解决一个已经存在简单解决方案的问题.

Django相关问答推荐

DRF中没有参数的视图的警告-壮观

django优化查询

Urls.py中路径**kwargs的Django翻译?

如何在两个字段上查找 django 模型的副本?

如何在视图中的 Django 重定向末尾附加字符串?

Django celery 页面给出 404

Playframework 和 Django

AttributeError:'Manager'对象在Django中没有属性'get_by_natural_key'错误?

Django {{ MEDIA_URL }} 空白 @DEPRECATED

TestCase 类中的 setUpClass、setUpTestData 和 setUp 有什么区别?

将现有 auth.User 数据迁移到新的 Django 1.5 自定义用户模型?

如何在 Django 中向 ChoiceField 添加class?

创建新内容类型时出错.请确保在try 单独迁移应用程序之前迁移内容类型

Django 登录到控制台

更新Django模型对象多个字段的有效方法

如何在 django admin 中显示布尔属性

从基于类的通用视图中获取 request.session

如何在 Django/Python 中减go 两个日期?

模型表格Save保存,Get获取保存的对象

如何将 settings.py 中的变量传递给视图?