溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊(cè)×
其他方式登錄
點(diǎn)擊 登錄注冊(cè) 即表示同意《億速云用戶服務(wù)條款》

SQLite 遞增主鍵 (Autoincrement)

發(fā)布時(shí)間:2020-08-06 14:46:04 來(lái)源:網(wǎng)絡(luò) 閱讀:501 作者:fengyuzaitu 欄目:數(shù)據(jù)庫(kù)

翻譯:https://www.sqlite.org/autoinc.html
?
概述
1 自增主鍵(TheAUTOINCREMENT keyword)占用額外CPU,內(nèi)存,磁盤(pán)空間,并且增加磁盤(pán)I/O的開(kāi)銷(xiāo)(disk I/O overhead),所以如無(wú)必要,應(yīng)該禁用。通常情況下是不需要的。
2 SQLite中,指定其中的一列的屬性為INTEGERPRIMARY KEY,和指定為ROWID,效果是一樣的(an alias for the ROWID),(除非在創(chuàng)建表的時(shí)候,指定了WITHOUT_ROWID),存儲(chǔ)類(lèi)型是64位符號(hào)整型。
3 在插入操作中,如果ROWID或者INTEGERPRIMARY KEY列沒(méi)有指定值,SQLITE將會(huì)自動(dòng)填充一個(gè)沒(méi)有使用的整型,通常大于已經(jīng)使用的任何一個(gè)ROWID值。不管是否已經(jīng)指定了AUTOINCREMENT關(guān)鍵字,效果還是一樣。
4 如果AUTOINCREMENT關(guān)鍵字緊隨INTEGEPRIMARY KEY關(guān)鍵字,將會(huì)改變ROWID的分配算法,不再使用已經(jīng)被使用的ROWID值,換句話說(shuō),就是AUTOINCREMENT將阻止ROWID的重用,盡管該ROWID已經(jīng)隨著某一行的數(shù)據(jù)刪除,而沒(méi)有被使用。
?
背景
對(duì)于SQLite來(lái)說(shuō),每一個(gè)表的每一行都會(huì)有一個(gè)64位符號(hào)整型ROWID,該ROWID在該表中唯一表示(指定了WITHOUT_ROWID表例外)
?
你可以通過(guò)特殊的列名(如ROWID,_ROWID,或者OID)訪問(wèn)SQLITE表中的ROWID的值。除非你在表中定義了與上述相同名稱的列名,如果真的定義了,該名字將只會(huì)應(yīng)用到定義的列而不是內(nèi)置的ROWID.
?
如果表中有定義為INTEGER PRIMARY KEY的屬性列,將產(chǎn)生和ROWID同樣的效果(an alias for),我想翻譯成別名,但是或許沒(méi)有人理解。這個(gè)時(shí)候,可以通過(guò)四種不同的方式訪問(wèn)ROWID,前三種方式請(qǐng)參考前面一段話,最后一種方式自然是指定了INTEGER PRIMARY KEY屬性的那一列??!都是別名而已。
?
當(dāng)一新行將被插入到SQLITE表中,ROWID可以在插入語(yǔ)句中指定,或者讓數(shù)據(jù)庫(kù)引擎自動(dòng)賦值。手動(dòng)指定ROWID的例子如下:
CREATE TABLE test1(a INT, b TEXT);
INSERT INTO test1(rowid, a, b) VALUES(123, 5,'hello');
?
如果在插入語(yǔ)句中沒(méi)有指定ROWID,或者ROWID指定了一個(gè)NULL值,數(shù)據(jù)庫(kù)引擎會(huì)自定指定一個(gè)合適的ROWID值。通用的算法將創(chuàng)建一個(gè)新的ROWID,這個(gè)值比以前分配的任何ROWID值都大,反映了增長(zhǎng)的情況。如果表為空,ROWID就會(huì)被指定為1.If the largest ROWID is equal to the largest possibleinteger (9223372036854775807) then the database engine starts picking positivecandidate ROWIDs at random until it finds one that is not previously used.
如果沒(méi)有找到一個(gè)未曾使用的ROWID值,插入操作將會(huì)以失敗告終,并且返回一個(gè)SQLITE_FULL錯(cuò)誤碼!如果ROWID沒(méi)有在插入語(yǔ)句中顯示指定,自動(dòng)生成的ROWID值總是比0大。
?
正常的ROWID選擇算法會(huì)產(chǎn)生單調(diào)遞增并且唯一的ROWID,只要你沒(méi)有使用最大的ROWID值,并且也從來(lái)沒(méi)有刪除最大的ROWID數(shù)據(jù)列。如果你刪除某些行,或者你曾經(jīng)創(chuàng)建一個(gè)最大的ROWID值,之前被刪除行使用的ROWID,可能被新插入的行重用。
?
自增主鍵
如果某一屬性列指定了INTEGER PRIMARY KEYAUTOINCREMENT屬性,ROWID選取算法會(huì)稍微不同。產(chǎn)生的ROWID比表中已經(jīng)存在的記錄中的ROWID都大。如果之前表為空,那么ROWID就會(huì)分配數(shù)值1.如果用戶指定了ROWID的值是最大值,接下來(lái)就不會(huì)允許任何的插入操作,與此同時(shí),任何的插入操作都會(huì)返回SQLITE_FULL的錯(cuò)誤碼。Only ROWID values frompreviously transactions that were committed are considered. ROWID values thatwere rolled back are ignored and can be reused.
?
SQLite在內(nèi)部維護(hù)了一個(gè)名字叫“sqlite_sequence”的表,記錄了一個(gè)表已經(jīng)使用的最大ROWID.不管一個(gè)表有沒(méi)有指定AUTOINCREMENT列的屬性值,該表都會(huì)被自動(dòng)創(chuàng)建,然后進(jìn)行初始化。該表也可以通過(guò)一般的UPDATE,INSERT和DELETE語(yǔ)句進(jìn)行編輯修改。但是修改該表會(huì)影響到AUTOINCREMENT生成算法。當(dāng)你修改的時(shí)候,請(qǐng)確保你知道自己正在干嘛?。?br />?
指定AUTOINCREMENT關(guān)鍵字的實(shí)現(xiàn)和默認(rèn)的實(shí)現(xiàn)有所不同。對(duì)于AUTOINCREMENT,每列得到的ROWID值對(duì)于相同的數(shù)據(jù)庫(kù)相同的表來(lái)說(shuō),都是未曾使用的。生成的ROWID單調(diào)遞增。對(duì)于某些應(yīng)用這是非常重要的屬性。但是如果你的應(yīng)用程序不需要這些屬性,你可以直接采用默認(rèn)的方式,而不是指定AUTOINCREMENT。畢竟AUTOINCREMENT在插入的過(guò)程中需要做一些額外的工作,導(dǎo)致插入的速度有所緩慢。
?
請(qǐng)注意單調(diào)遞增并不意味著ROWID總是加1(increases by exactly one).增1是最常見(jiàn)的。但是如果在插入的過(guò)程中失敗了,被分配的ROWID不會(huì)被接下來(lái)的插入數(shù)據(jù)重用到,導(dǎo)致了ROWID序列出現(xiàn)缺口。AUTOINCREMENT確保了ROWID是自動(dòng)遞增的,但是沒(méi)有保證是連續(xù)遞增的。
?
因?yàn)锳UTOINCREMENT關(guān)鍵字改變了ROWID的選取算法,所以AUTOINCREMENT不能應(yīng)用在指定了WITHOUT_ROWID的表或者指定了其他的列為INTEGER PRIMARYKEY.任何嘗試應(yīng)用AUTOINCREMENT關(guān)鍵字在上面兩種情況下都會(huì)導(dǎo)致錯(cuò)誤。
注意:
1)指定了WITHOUT_ROWID屬性,就不能再使用AUTOINCREMENT
2) 如果已經(jīng)有表中的某一列指定了INTEGER PRIMARY KEY屬性,AUTOINCREMENT不能修飾表的其他任何一列。

如下是擴(kuò)展閱讀:
摘自:http://www.jb51.net/article/50049.htm
針對(duì)于用戶使用自定義的自增主鍵,還是系統(tǒng)內(nèi)部維護(hù)的ROWID,上面已經(jīng)描述的非常清楚,并且鏈接也已經(jīng)提供了操作ROWID的方法。
現(xiàn)在重點(diǎn)討論:在大型的分布式應(yīng)用中,自增主鍵的使用,當(dāng)然SQLite數(shù)據(jù)只能夠是一只麻雀,對(duì)于我們來(lái)說(shuō),完全沒(méi)有任何的大數(shù)據(jù)量的概念,針對(duì)于作者提及的一級(jí)表以及二級(jí)表的使用概念,有著深遠(yuǎn)的好奇,但是目前沒(méi)有任何的操作環(huán)境。
摘自文中:使用自增長(zhǎng)字段為主鍵有不少問(wèn)題,比如維護(hù)或是在大型分布應(yīng)用中主鍵沖突的解決等。
在一些大型分布應(yīng)用中主鍵一般選用guid,這可以有效的避免主鍵沖突,減少對(duì)主鍵維護(hù)的工程。
當(dāng)然,對(duì)于中小型的應(yīng)用,自增長(zhǎng)字段的好處更多一些,簡(jiǎn)單、快速。
??? 采用自增主鍵的理由,在什么情況下,需要建立一個(gè)主鍵,尤其是分布式數(shù)據(jù)庫(kù)??!


向AI問(wèn)一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI