2016-10-02 231 views
2

在Sqlite中,有两种方法可以通过默认的ROWID机制或通过AUTOINCREMENT机制创建由数据库引擎生成的单调递增的主键值。在什么情况下应该使用AUTOINCREMENT而不是默认的ROW ID?

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” .The sqlite_sequence表创建一个内部表中保存和自动初始化最大的ROWID 。可以使用普通的UPDATE,INSERT和DELETE语句修改sqlite_sequence表的内容。但是对该表进行修改可能会干扰AUTOINCREMENT密钥生成算法。在进行这样的改变之前,确保你知道你在做什么。


在什么情况下是适合使用AUTOINCREMENT关键字?

回答

2

文档说

AUTOINCREMENT的目的是为了防止的ROWID的重用以前删除的行。

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

+0

假设您启用了外键,不可能对已删除的行进行外部引用。假设你禁用了外键,那么你是否有一个用例来保留对被删除行的外部引用是一个好主意? –

+0

这里,“外部”是指数据库外部。 –

+0

对不起,我还是不明白:)。何时对外部数据库保留对已删除标识的引用有用? –

相关问题