(1)一個表只能有一個主鍵
每個表只能有最多一個主鍵。具有主鍵的表中的每一行在其主鍵列中必須具有唯一的值組合。如果INSERT或UPDATE語句嘗試修改表內容,以使兩行或更多行具有相同的主鍵值,則違反約束。
只能有一個主鍵,並不等同於只能有一列是主鍵,因為可以定義聯合主鍵。例如:
Create table t1 (a, B, C, PRIMARY KEY(A,B) ); INSERT INTO T1 VALUES (1,1,2) INSERT INTO T1 VALUES (1,2,2) INSERT INTO T1 VALUES (2,1,2) INSERT INTO T1 VALUES (2,2,2)
並不會報錯,而如果繼續添加下面的語句
INSERT INTO T1 VALUES (1,2,52),則會報錯
(2)NULL值主鍵
按照設計理念,主鍵應該不能為空值,但早起的SQLITE出了BUG,為了實現向后兼容,SQLITE最終確定了,主鍵允許NULL值。為了確定主鍵值的唯一性,將NULL值視為與所有其他值(包括其他NULL)不同。
(3)ROWID
未定義主鍵的表,默認有一個隱藏的主鍵:rowid,並且rowid還有另兩個別名“OID”和“_ROWID_”。
這個ROWID和定義的唯一性主鍵不沖突,並不占用主鍵定義的“名額”。同樣是上一個表,添加rowid的顯示結果如下:
ROWID是個64位的有符號整數,從1開始自動增長。可以指定ROWID進行刪除。
(4)WITHOUT ROWID
當創建表時,最后添加了WITHOUT ROWID語句,則強制不創建ROWID列。
但沒有ROWID的表,則必須創建主鍵。例如:
並且此時主鍵的值不允許空值。
例如:
(5)integer primary key
當一個表沒有使用“without rowid”,並且設置了單列“integer primary key”,則這個單列相當於ROWID的顯示別名,請看下圖的例子,當插入a=0的行時,ROWID也並沒有自動變為4,也成了0
上面提到的例外是,如果聲明類型為“ INTEGER”的列的聲明包含“ PRIMARY KEY DESC”子句,則它不會成為rowid的別名,也不會歸類為整數主鍵。 這個怪癖不是故意的。 這是由於早期SQLite版本中的錯誤所致。 但是修復該錯誤可能會導致向后不兼容。 因此,原始行為得以保留(並記錄在案),因為在極端情況下的奇怪行為要比兼容性破壞要好得多。 這意味着以下三個表聲明都使“ x”列成為rowid(整數主鍵)的別名:
- CREATE TABLE t(x INTEGER PRIMARY KEY ASC, y, z);
- CREATE TABLE t(x INTEGER, y, z, PRIMARY KEY(x ASC));
- CREATE TABLE t(x INTEGER, y, z, PRIMARY KEY(x DESC));
而下面的語句卻不會:
- CREATE TABLE t(x INTEGER PRIMARY KEY DESC, y, z);
作為ROWID的別名列,是不允許空值的,如果未能成為ROWID的別名列,則可以是空值,例如:
如下面所示,A列明顯未能成為ROWID的別名。