Django:关于自动递增主键的最佳实践

Posted

技术标签:

【中文标题】Django:关于自动递增主键的最佳实践【英文标题】:Django: Best practice regarding auto increment primary key 【发布时间】:2018-08-29 08:46:00 【问题描述】:

您好,我正在构建一个 Django 应用程序,在此期间我正在将测试上传到我的数据库中,然后删除数据。我知道,当我这样做时,下一个插入将在插入自动增量主键 int 时“从中断处继续”。

即:

我在表“样本”中插入 3 行:

auto_id    |     sample 
  1        |    JSUDH172
  2        |    QIUWJ185
  3        |    PNMSY111

当我删除这些并再次输入时,它将从 4 开始:

auto_id    |     sample 
  4        |    JSUDH172
  5        |    QIUWJ185
  6        |    PNMSY111

我知道这是为了阻止 Django 覆盖主键而内置的,但是当主键不再存在时,它(主要从肤浅的角度来看)让我很恼火,因为它没有重置。在此开发过程中,我将数千行上传到某些表中,因此有时它会开始成百上千。

我知道我总是可以在开发完成后“从头开始”重新启动项目,但我想知道是否有人有任何有用的解决方法,或者人们是否只是保持原样(如果他们和我的观点相同)

谢谢

【问题讨论】:

表面上的烦恼是可以忍受的。重新播种然后更新子表中的所有引用的替代方法比任意 ID 更痛苦。如果您担心 ID 空间问题,您可以针对另一个数据库运行测试 您使用的是哪种 RDBMS?后格雷斯? SQL 服务器?您可以生成您的迁移,然后通过添加 sql 命令来重新设置您的身份列来修改它。或者可能使用固定装置? 我正在使用 mysql 【参考方案1】:

所以有几种方法。其中一些已经被提及。首先,重要的是要知道。虽然在 django 模型字段上设置了 auto_increment,但它会转换为数据库命令。当你运行

python3 manage.py migrate

对于具有 auto_increment 字段的模型,它在 this 这样的 sql 命令中执行

当您删除数据时,进入您的 sql cli 并重置它manually。但是,以非编程方式直接与数据库交互,不是 django 方式,也不应该这样做。在这种情况下,您必须删除所有数据并重置自动增量,比如说在生产环境中,我将通过./manage.py makemigrations theappname --empty 创建一个迁移脚本。并在迁移脚本中执行sql语句。

【讨论】:

【参考方案2】:

通常整数主键的值基于数据库[1][2]中的底层sequence,它允许在所有多事务、多事务下以安全的方式分配唯一值-tenant,多连接的荣耀,是一个客户端-服务器数据库。安全地填充稀疏填充的 ID 序列中的空白比“获取和递增”复杂得多,并且对于约束是功能而非美学的列没有任何实际价值。

从实际的角度来看,几乎在所有情况下都不会用完整数主键,因此实际上没有必要重复使用空槽。

如果您需要一个从零开始平滑填充的序列号,也许您可​​以为此目的使用另一列并保持由另一种机制填充,也许使用存储过程来找到用于新行的最小可用值.

[1]https://www.postgresql.org/docs/10/static/sql-createsequence.html

[2]https://www.postgresql.org/docs/10/static/functions-sequence.html

【讨论】:

以上是关于Django:关于自动递增主键的最佳实践的主要内容,如果未能解决你的问题,请参考以下文章

SQL 最佳实践 - 可以依靠自动增量字段按时间顺序对行进行排序吗?

在现有 Django 应用程序中更改主键的最佳方法是啥?

Azure 表:选择分区/行键的最佳实践

将 sqlite 用于数据库队列的最佳实践

关于自定义用户模型的 Django 最佳实践

SQL java获取分配给自动递增主键的值[重复]