程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 數據庫知識 >> SqlServer數據庫 >> 關於SqlServer >> 兩種方式實現SQLite 主鍵自動增加

兩種方式實現SQLite 主鍵自動增加

編輯:關於SqlServer
 

SQLite 主鍵自動增加(autoincrease)可以實現,經過測試,有以下兩種方法:
下面所有的代碼和結果,都是真實實驗的結果。

1、使用類似 MySQL 的 autoincrease 參數,例如:
Create table meta_struct(id INTEGER PRIMARY KEY AUTOINCREMENT, name varchar, type Integer);
程序修改(DataAccess.cs第84行):
string sql = "Create TABLE " + tableName + " (";
改為
string sql = "Create TABLE " + tableName + " (ids INTEGER PRIMARY KEY AUTOINCREMENT, ";
其他都不需要修改。

2、系統默認有一個偽列(rowid)已經實現了自增,可以當做主鍵來使用,不需要修改程序。

PS:
autoincrease使用的是MySQL語法,所以,處理起來和MySQL數據庫一模一樣。
rowid(偽列)使用的是Oracle的特性,所以,處理起來和Oracle一模一樣。
C#版的SQLite繼承了,MySQL和Oracle的特性。
Java版的SQLite(即,常用的sqlitejdbc.jar),不能直接使用autoincrease,需要借助native方法(即 sqlitejdbc.dll)。
內部機理,使用的是Oracle序列(sequence),來實現自增。


在用sqlite設計表時,突然想到一個問題,就是我設計的表中,每個表都有一個自己的整形id值作為主鍵,其實可以不指 定這麼一個id值,sqlite內部本來就會為每個表加上一個 rowid,這個rowid可以當成一個隱含的字段使用,但是由sqlite引擎來維護 的,在3.0以前rowid是32位的整數,3.0以後是64位的整數,為什麼不直接使用這個內部的rowid作為每個表的id主鍵呢。

想到就立即先查找一下sqlite的文檔,看看用指定INTEGER PRIMARY KEY AUTOINCREMENT 和不指定自增長字段用rowid有什麼區別。相關的文檔在這裡:
http://www.sqlite.org/autoinc.html
http://www.sqlite.org/faq.html

使用自增長字段為主鍵有不少問題,比如維護或是在大型分布應用中主鍵沖突的解決等。在一些大型分布應用中主鍵一般選用 guid,這可以有效的避免主鍵沖突,減少對主鍵維護的工程。當然,對於中小型的應用,自增長字段的好處更多一些,簡單、快速。

Sqlite中,一個自增長字段定義為INTEGER PRIMARY KEY AUTOINCREMENT ,那麼在插入一個新數據時,只需要將這個字段的值指定為NULL,即可由引擎自動設定其值,引擎會設定為最大的rowid+1。當然,也可以設置為非 NULL的數字來自己指定這個值,但這樣就必須自己小心,不要引起沖突。當這個rowid的值大於所能表達的最大值 9223372036854775807 (3.0及以後版本的rowid最大值)後,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值,但看不到。

這麼看來,如果直接使用rowid來代替自增加字段,根據兩者的細微的差別,需要注意是否與自己的應用沖突,如果沒有沖 突,那麼用rowid會更快一點。

 
  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved