在Sqlite中,有两种方法可以通过默认的ROWID
机制或AUTOINCREMENT
机制创建由数据库引擎生成的单调递增的主键值。
sqlite> -- Through the default ROWID mechanism
sqlite> CREATE TABLE foo(id INTEGER NOT NULL PRIMARY KEY, foo);
sqlite> INSERT INTO foo (foo) VALUES ('foo');
sqlite> INSERT INTO foo (foo) VALUES ('bar');
sqlite> SELECT * FROM foo;
1|foo
2|bar
sqlite>
sqlite> -- Through the AUTOINCREMENT mechanism
sqlite> CREATE TABLE bar(id INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT, bar);
sqlite> INSERT INTO bar (bar) VALUES ('foo');
sqlite> INSERT INTO bar (bar) VALUES ('bar');
sqlite> SELECT * FROM bar;
1|foo
2|bar
sqlite> -- Only the AUTOINCREMENT mechanism uses the sqlite_sequence table
sqlite> SELECT * FROM sqlite_sequence WHERE name in ('foo', 'bar');
bar|2
documentation似乎暗示使用AUTOINCREMENT
是不好的:
AUTOINCREMENT关键字会产生额外的CPU,内存,磁盘空间和磁盘I / O开销,如果不是严格需要,应该避免使用。通常不需要它。
如果AUTOINCREMENT关键字出现在INTEGER PRIMARY KEY之后,则会更改自动ROWID分配算法,以防止在数据库的生命周期内重用ROWID。换句话说,AUTOINCREMENT的目的是防止从以前删除的行重用ROWID。
[使用AUTOINCREMENT,] SQLite使用名为" sqlite_sequence"的内部表跟踪表所拥有的最大ROWID。每当包含一个普通表的普通表时,都会自动创建并初始化sqlite_sequence表。 AUTOINCREMENT列已创建。可以使用普通的UPDATE,INSERT和DELETE语句修改sqlite_sequence表的内容。但是对此表进行修改可能会扰乱AUTOINCREMENT密钥生成算法。在进行此类更改之前,请确保您知道自己在做什么。
在什么情况下使用AUTOINCREMENT关键字是合适的?
答案 0 :(得分:2)
文档说明
AUTOINCREMENT的目的是防止从先前删除的行重用ROWID。
因此,当您需要阻止从先前删除的行重用ROWID时,使用AUTOINCREMENT关键字是合适的。如果您对这些已删除的行有外部引用,则可能需要这样做,并且不得将它们与新行混淆。
答案 1 :(得分:0)
” AUTOINCREMENT的目的是防止ROWID的重用 先前删除的行。”
脱离上下文,这听起来像是仅目的。我认为对于AUTOINCREMENT,最明显的决策点之一就是您是否需要保证单调递增的整数。反过来,肯定会出现这种最常见的需求,因为您需要知道发生了什么顺序插入。为此,人们可能更喜欢整数而不是时间戳,原因是:时钟分辨率不足,担心时钟不稳定,如果涉及多个时钟源,则难以同步等
当然,总是可以通过以下一种情况来弥补:交易首先完成,但比竞争交易获得更高的数量。但是,这似乎与两个人可能在首先发生“交易”的交易上存在分歧的情况相对应,因此,IMO就可以保证单调性。如果您使用AUTOINCREMENT,那是SQLite提供的保证。
”您是否有一个用例,可以在什么时候保留外部 引用删除的行?”
与其说是一个好主意,不如说是什么:如果人们以任何形式看到/使用ID,那么如果他们认为唯一的数字被重新分配,可能会造成混乱。这是in the wild的示例。这是单调增加ID需求范围的一部分,但比您想象的要普遍得多。人类善于潜意识地吸收数字“应该”总是变大的事实。例如,在昔日的日子里,人们可以浏览您的用户ID号来衡量您成为会员的时间。在slashdot上,我想将鼠标悬停在用户名上可以完成相同的操作,并且省去了查看其个人资料的麻烦。