2011-11-23 103 views
9

这并不执行:为什么你不能使用SQLite ROWID作为主键?

create table TestTable (name text, age integer, primary key (ROWID)) 

的错误信息是:

11月11日至23日:05:05.298:ERROR /数据库(31335):失败1(表TestTable的不具有指定的列ROWID)在准备'创建表TestTable(名称文本,年龄整数,主键(ROWID))'时在0x2ab378上。

然而,在创建TestTable的之后,这个准备并执行就好了:

create table TestTable (name text, age integer); 

insert into TestTable (name, age) values ('Styler', 27); 

select * from TestTable where ROWID=1; 

我可能看到ROWID为到需要一个自动增加的主键和外键这是一个解决方案永远不会像应用程序层上的数据那样被使用。由于默认情况下,ROWIDselect结果集隐藏起来,因此将它与主键相关联,同时将它与应用程序逻辑保持隐藏状态是很好的。 OracleBlog: ROWNUM and ROWID表示这是不可能的和不可取的,但除此之外不提供太多解释。

因此,既然'这是可能'的答案肯定不是/不可取的,那么问题是或多或少'为什么不',?

+1

ROWNUM随记录更新而更改,ROWID根据排序或结果集的顺序而变化。所以RowNum很糟糕,因为每次对主服务器进行更改时都需要更新所有外键。 (大量开销),并且ROWID不好,因为直到结果集被创建和排序,ID才会存在。如果它不存在,则无法加入。 – xQbert

+0

@xQbert如果ROWID被主键引用,它将如何根据结果集中的列顺序进行更改? – styler1972

+0

您的表格中不存在ROWID describe testtable。你会看到ROWID不在那里。 ROWID是系统列和系统维护的值。您不能在系统列上拥有PK;您没有权限执行此操作。关于上述:我把它倒过来; ROWID可以根据更新与ROWNUM进行更改,ROWNUM根据where条款选择更改。 – xQbert

回答

28

从SQLite.org:

如果表中包含类型INTEGER PRIMARY KEY的列,则该列 变为用于ROWID的别名。然后,您可以使用四种不同名称中的任意一种来访问ROWID ,原始三个名称分别描述如上 或给予INTEGER PRIMARY KEY列的名称。所有这些 名称都是别名的别名,并且在任何 上下文中均可以很好地工作。

只要使用它作为主键。

+1

通过添加任何自动递增主键,我基本上使用ROWID作为主键。正在考虑,因为这很容易,我可以宣布rowid为主。很显然,这些比这还要多一点。这就是我对不同的想法,对我感到羞耻:D – styler1972

+2

[添加自动增量键会稍微改变行为](http://www.sqlite.org/autoinc.html)。 ROWID并不总是合适的,主要是如果要求单调递增的值。 – user2864740