一、SQLite清空表並將自增列歸零
SQL標準中有TRUNCATE TABLE語句,用來清空表的所有內容。
但SQLite不支援這個語句。在SQLite中直接使用 DELETE FROM TableName 就可以了。
對於大多數DBMS來說,用DELETE不如用TRUNCATE 速度快,因為TRUNCATE 不用訪問整個表,不用記錄資料的變動。
SQLite雖然不支援TRUNCATE,但它對DELETE做了最佳化:
通常在清空表的時候,還需要把自增列歸零。在SQLite中定義自增列的方法如下:
複製代碼 代碼如下:CREATE TABLE TableName ( id INTEGER PRIMARY KEY AUTOINCREMENT, name varchar, type Integer );
當SQLite資料庫中包含自增列時,會自動建立一個名為 sqlite_sequence 的表。
這個表包含兩個列:name和seq。name記錄自增列所在的表,seq記錄當前序號(下一條記錄的編號就是當前序號加1)。
如果想把某個自增列的序號歸零,只需要修改 sqlite_sequence表就可以了。
複製代碼 代碼如下:UPDATE sqlite_sequence SET seq = 0 WHERE name='TableName';
也可以直接把該記錄刪掉:
複製代碼 代碼如下:DELETE FROM sqlite_sequence WHERE name='TableName';
要想將所有表的自增列都歸零,直接清空sqlite_sequence表就可以了:
複製代碼 代碼如下:DELETE FROM sqlite_sequence;
二、Sqlite中INTEGER PRIMARY KEY AUTOINCREMENT和rowid的使用
在用sqlite設計表時,突然想到一個問題,就是我設計的表中,每個表都有一個自己的整形id值作為主鍵,
其實可以不指定這麼一個id值,sqlite內部本來就會為每個表加上一個 rowid,這個rowid可以當成一個隱含的欄位使用,
為什麼不直接使用這個內部的rowid作為每個表的id主鍵呢。
使用自增長欄位為主鍵有不少問題,比如維護或是在大型分布應用中主鍵衝突的解決等。
在一些大型分布應用中主鍵一般選用guid,這可以有效避免主鍵衝突,減少對主鍵維護的工程。
當然,對於中小型的應用,自增長欄位的好處更多一些,簡單、快速。
Sqlite中,一個自增長欄位定義為 INTEGER PRIMARY KEY AUTOINCREMENT
那麼在插入一個新資料時,只需要將這個欄位的值指定為NULL,即可由引擎自動設定其值,
引擎會設定為最大的rowid+1 當然,也可以設定為非NULL的數字來自己指定這個值,但這樣就必須自己小心,不要引起衝突。
rowid的新值會這個最大數之前隨機找一個沒被使用了的值。所以在rowid達到最大值前,rowid的值是嚴格單調增加的。
INTEGER PRIMARY KEY AUTOINCREMENT 自增長欄位的演算法與rowid稍微有些不同。
第一,在達到最大值後,rowid會找已被刪除的欄位對應的rowid作為新值,而自增長欄位則會丟出一個SQLITE_FULL的錯誤。
第二,自增長欄位在增加新值時,是找一個從沒被使用過的rowid作為新值,而rowid則是找最大已存在的rowid+1。
這裡對應用的影響會比較大,尤其是一些對id值有依賴的元記錄,只適合使用自增長欄位而不能用rowid。
比如,我們設計一個元記錄表:
複製代碼 代碼如下:Create table meta_struct(id INTEGER PRIMARY KEY AUTOINCREMENT, name varchar, type Integer);
然後,定義一個一級表,來描述其它表的結構:
複製代碼 代碼如下:Create table meta_table(tableid INTEGER, table_field integer)
最後,我們的應用可以根據這個一級表來產生實際使用的二級表。
這樣為保證相容性meta_struct中的id必須是唯一的,如果有欄位被刪除,也不能重複使用這個欄位的id值,不然,在資料庫合并時,
一級表和二級表就會混亂。所以meta_struct表中的主鍵只能使用自增長欄位,而不能用rowid。
第三,使用自增長欄位,引擎會自動產生一個sqlite_sequence表,用於記錄每個表的自增長欄位的已使用的最大值,使用者可以看到,
並可以用使用Update、Delete和Insert操作,但不建議這麼使用,這會讓引擎混亂。如果使用rowid,也會有這麼一個內部表,使用者可以維護rowid值,但看不到。