在什么情况下应该使用AUTOINCREMENT而不是默认的ROW ID?

时间:2016-10-02 19:17:18

标签: sqlite

在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关键字是合适的?

2 个答案:

答案 0 :(得分:2)

文档说明

  

AUTOINCREMENT的目的是防止从先前删除的行重用ROWID。

因此,当您需要阻止从先前删除的行重用ROWID时,使用AUTOINCREMENT关键字是合适的。如果您对这些已删除的行有外部引用,则可能需要这样做,并且不得将它们与新行混淆。

答案 1 :(得分:0)

  

” AUTOINCREMENT的目的是防止ROWID的重用   先前删除的行。”

脱离上下文,这听起来像是目的。我认为对于AUTOINCREMENT,最明显的决策点之一就是您是否需要保证单调递增的整数。反过来,肯定会出现这种最常见的需求,因为您需要知道发生了什么顺序插入。为此,人们可能更喜欢整数而不是时间戳,原因是:时钟分辨率不足,担心时钟不稳定,如果涉及多个时钟源,则难以同步等

当然,总是可以通过以下一种情况来弥补:交易首先完成,但比竞争交易获得更高的数量。但是,这似乎与两个人可能在首先发生“交易”的交易上存在分歧的情况相对应,因此,IMO就可以保证单调性。如果您使用AUTOINCREMENT,那是SQLite提供的保证。

  

”您是否有一个用例,可以在什么时候保留外部   引用删除的行?”

与其说是一个好主意,不如说是什么:如果人们以任何形式看到/使用ID,那么如果他们认为唯一的数字被重新分配,可能会造成混乱。这是in the wild的示例。这是单调增加ID需求范围的一部分,但比您想象的要普遍得多。人类善于潜意识地吸收数字“应该”总是变大的事实。例如,在昔日的日子里,人们可以浏览您的用户ID号来衡量您成为会员的时间。在slashdot上,我想将鼠标悬停在用户名上可以完成相同的操作,并且省去了查看其个人资料的麻烦。