2011-11-23 99 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