`
kanwoerzi
  • 浏览: 1648126 次
文章分类
社区版块
存档分类
最新评论

INTEGER PRIMARY KEY简介

 
阅读更多
Sqlite中INTEGERPRIMARYKEYAUTOINCREMENT和rowid/INTEGERPRIMARYKEY的使用
在用sqlite设计表时,每个表都有一个自己的整形id值作为主键,插入后能直接得到该主键.
因为sqlite内部本来就会为每个表加上一个rowid,这个rowid可以当成一个隐含的字段使用,
但是由sqlite引擎来维护的,在3.0以前rowid是32位的整数,3.0以后是64位的整数,可以使用这个内部的rowid作为每个表的
id主键
查了下文档:
参照http://www.sqlite.org/c3ref/last_insert_rowid.html<wbr style="line-height:25px">。<br style="line-height:25px"> EachentryinanSQLitetablehasaunique64-bitsignedintegerkeycalledthe"rowid".<br style="line-height:25px"> TherowidisalwaysavailableasanundeclaredcolumnnamedROWID,OID,<br style="line-height:25px"> or_ROWID_aslongasthosenamesarenotalsousedbyexplicitlydeclaredcolumns.<br style="line-height:25px"> IfthetablehasacolumnoftypeINTEGERPRIMARYKEYthenthatcolumnisanotheraliasfortherowid.<br style="line-height:25px"><span style="color:#000080; line-height:25px">如果表中有个INTEGERPRIMARYKEY字段,那么它只是rowid的别名。</span><br style="line-height:25px"> ThisroutinereturnstherowidofthemostrecentsuccessfulINSERTintothedatabasefromthedatabaseconnectioninthefirstargument.<br style="line-height:25px"> IfnosuccessfulINSERTshaveeveroccurredonthatdatabaseconnection,zeroisreturned.<br style="line-height:25px"><span style="color:#000080; line-height:25px">如果成功插入一条数据,会返回刚刚插入的数据的rowid.如果失败返回0.Android中如果发生错误返回的是-1</span><br style="line-height:25px"> 参照<a target="_blank" rel="nofollow" href="http://www.sqlite.org/faq.html" style="color:rgb(207,121,28); line-height:25px; text-decoration:none">http://www.sqlite.org/faq.html</a><wbr style="line-height:25px"><br style="line-height:25px"> Shortanswer:AcolumndeclaredINTEGERPRIMARYKEYwillautoincrement.<br style="line-height:25px"> Hereisthelonganswer:IfyoudeclareacolumnofatabletobeINTEGERPRIMARYKEY,<br style="line-height:25px"> thenwheneveryouinsertaNULLintothatcolumnofthetable,<br style="line-height:25px"> theNULLisautomaticallyconvertedintoanintegerwhichisonegreaterthanthelargestvalueofthatcolumnover<br style="line-height:25px"> allotherrowsinthetable,or1ifthetableisempty.(Ifthelargestpossibleintegerkey,9223372036854775807,<br style="line-height:25px"> thenanunusedkeyvalueischosenatrandom.)Forexample,supposeyouhaveatablelikethis:<br style="line-height:25px"><span style="color:#0000ff; line-height:25px"></span><span style="color:#993300; line-height:25px">CREATE</span><span style="color:#0000ff; line-height:25px">TABLEt1(<br style="line-height:25px"> aINTEGERPRIMARYKEY,<br style="line-height:25px"> bINTEGER<br style="line-height:25px"> );</span><br style="line-height:25px"> Withthistable,thestatement<br style="line-height:25px"><span style="color:#0000ff; line-height:25px">INSERTINTOt1VALUES(NULL,123);</span><br style="line-height:25px"> islogicallyequivalenttosaying:<br style="line-height:25px"><span style="color:#0000ff; line-height:25px">INSERTINTOt1VALUES((SELECTmax(a)FROMt1)+1,123);</span><br style="line-height:25px"> Thereisafunctionnamedsqlite3_last_insert_rowid()whichwillreturntheintegerkeyforthemostrecentinsertoperation.<br style="line-height:25px"> Notethattheintegerkeyisonegreaterthanthelargestkeythatwasinthetablejustpriortotheinsert.<br style="line-height:25px"> Thenewkeywillbeuniqueoverallkeyscurrentlyinthetable,<br style="line-height:25px"> butitmightoverlapwithkeysthathavebeenpreviouslydeletedfromthetable.<br style="line-height:25px"> Tocreatekeysthatareuniqueoverthelifetimeofthetable,<br style="line-height:25px"> addtheAUTOINCREMENTkeywordtotheINTEGERPRIMARYKEYdeclaration.<br style="line-height:25px"> Thenthekeychosenwillbeonemorethanthanthelargestkeythathaseverexistedinthattable.<br style="line-height:25px"> Ifthelargestpossiblekeyhaspreviouslyexistedinthattable,thentheINSERTwillfailwithanSQLITE_FULLerrorcode.<br style="line-height:25px"><span style="color:#003366; line-height:25px">把一个列申明为</span><span style="color:#993300; line-height:25px">INTEGERPRIMARYKEY</span><span style="color:#003366; line-height:25px">,那么在向它插入</span><span style="color:#0000ff; line-height:25px">NULL</span><span style="color:#003366; line-height:25px">,该列就由系统指定。该值为已经存在的数据的该列的最大值加1。空表时该值就为1<br style="line-height:25px"> 如果该值已经超过了最大值,那么它会随即选择一个已存数据没使用过的值做个插入数据的值。<br style="line-height:25px"> 如果用户在插入时给它指定一个值,那么返回的也是那个值。</span><br style="line-height:25px"><span style="color:#003366; line-height:25px">因为本来返回的应该是rowid,但如果表中有个</span><span style="color:#993300; line-height:25px">INTEGERPRIMARYKEY</span><span style="color:#003366; line-height:25px">字段,那么它只是rowid的别名。<br style="line-height:25px"> 所以返回的就是指定的那个值。<br style="line-height:25px"> 把一个列声明为</span><span style="color:#993300; line-height:25px">INTEGERPRIMARYKEY</span><span style="color:#ff00ff; line-height:25px">AUTOINCREMENT</span><span style="color:#003366; line-height:25px">的话,它的值是选择的在该表中曾经使用过的最大值+1。<br style="line-height:25px"> 如果达到了最大值的话,会插入失败,并抛出anSQLITE_FULLerrorcode。</span><br style="line-height:25px"> 再参照sqlite的文档:<br style="line-height:25px"><a target="_blank" rel="nofollow" href="http://www.sqlite.org/autoinc.html" style="color:rgb(207,121,28); line-height:25px; text-decoration:none">http://www.sqlite.org/autoinc.html</a><wbr style="line-height:25px"><br style="line-height:25px"><span style="line-height:25px">最后得出以下结论</span>:<br style="line-height:25px"><span style="color:#003366; line-height:25px">用自增长字段为主键有不少问题,比如维护或是在大型分布应用中主键冲突的解决等。在一些大型分布应用中主键一般选用guid,这可以有效的避免主键冲突,减少对主键维护的工程<br style="line-height:25px"> 当然,对于中小型的应用,自增长字段的好处更多一些,简单、快速。</span><br style="line-height:25px"><span style="color:#000080; line-height:25px">Sqlite中,一个自增长字段定义为</span><span style="color:#993300; line-height:25px">INTEGERPRIMARYKEY</span><span style="color:#000080; line-height:25px"></span><span style="color:#ff00ff; line-height:25px">AUTOINCREMENT</span><span style="color:#000080; line-height:25px">或者</span><span style="color:#993300; line-height:25px">INTEGERPRIMARYKEY</span><span style="color:#000080; line-height:25px">时,那么在插入一个新数据时,只需要将这个字段的值指定为NULL,即可由引擎自动设定其值。<br style="line-height:25px"> 当然,也可以设置为非NULL的数字来自己指定这个值,但这样就必须自己小心,不要引起冲突。</span><br style="line-height:25px"> 对于<span style="color:#993300; line-height:25px">INTEGERPRIMARYKEY</span>,当这个rowid的值大于所能表达的最大值9223372036854775807(3.0及以后版本的rowid最大值)后,rowid的新值会这个最大数之前随机找一个没被使用了的值。<br style="line-height:25px"> 所以在rowid达到最大值前,rowid的值是严格单调增加的。<br style="line-height:25px"><span style="color:#993300; line-height:25px">INTEGERPRIMARYKEY</span><span style="color:#ff00ff; line-height:25px">AUTOINCREMENT</span>自增长字段的算法与<span style="color:#993300; line-height:25px">rowid/INTEGERPRIMARYKEY</span>稍微有些不同。<br style="line-height:25px"><span style="line-height:25px">第一</span>,在达到最大值后,<span style="color:#993300; line-height:25px">rowid/INTEGERPRIMARYKEY</span>会找已被删除的字段对应的rowid/INTEGERPRIMARYKEY作为新值,<br style="line-height:25px"> 而自增长字段<span style="color:#993300; line-height:22px">INTEGERPRIMARYKEY</span><span style="color:#ff00ff; line-height:22px">AUTOINCREMENT</span>则会丢出一个SQLITE_FULL的错误。<br style="line-height:25px"><span style="line-height:25px">第二</span>,自增长字段<span style="color:#993300; line-height:22px">INTEGERPRIMARYKEY</span><span style="color:#ff00ff; line-height:22px">AUTOINCREMENT</span>在增加新值时,是找一个从没被使用过的值作为新值,而<span style="color:#993300; line-height:25px">rowid/INTEGERPRIMARYKEY</span>则是找最大已存在的<span style="color:#993300; line-height:25px">(rowid/INTEGERPRIMARYKEY)</span><span style="color:#0000ff; line-height:25px">+1</span>。<br style="line-height:25px"> 这里对应用的影响会比较大,尤其是一些对id值有依赖的元记录,只适合使用自增长字段而不能用rowid/INTEGERPRIMARYKEY。<br style="line-height:25px"> 比如,我们设计一个元记录表:<br style="line-height:25px"><span style="color:#0000ff; line-height:25px">Createtablemeta_struct(id</span><span style="color:#993300; line-height:25px">INTEGERPRIMARYKEY</span><span style="color:#ff00ff; line-height:25px">AUTOINCREMENT</span><span style="color:#0000ff; line-height:25px">,namevarchar,typeInteger);</span><br style="line-height:25px"> 然后,定义一个一级表,来描述其它表的结构:<br style="line-height:25px"><span style="color:#0000ff; line-height:25px">Createtablemeta_table(tableidINTEGER,table_fieldinteger)</span><br style="line-height:25px"> 最后,我们的应用可以根据这个一级表来产生实际使用的二级表。<br style="line-height:25px"> 这样为保证兼容性meta_struct中的id必须是唯一的,如果有字段被删除,也不能重复使用这个字段的id值,不然,在数据库合并时,一级表和二级表就会混乱。<br style="line-height:25px"><span style="color:#000080; line-height:25px">所以meta_struct表中的主键只能使用自增长字段,而不能用rowid。</span><br style="line-height:25px"><span style="line-height:25px">第三</span>,<span style="color:#003366; line-height:25px">使用自增长字段</span><span style="color:#993300; line-height:22px">INTEGERPRIMARYKEY</span><span style="color:#ff00ff; line-height:22px">AUTOINCREMENT</span>,<span style="color:#003366; line-height:25px">引擎会自动产生一个sqlite_sequence表,用于记录每个表的自增长字段的已使用的最大值,<br style="line-height:25px"> 用户可以看到,并可以用使用Update、Delete和Insert操作,但不建议这么使用,这会让引擎混乱。<br style="line-height:25px"> 如果使用</span><span style="color:#993300; line-height:25px">rowid/INTEGERPRIMARYKEY</span><span style="color:#003366; line-height:25px">,也会有这么一个内部表,用户可以维护</span><span style="color:#993300; line-height:25px">rowid/INTEGERPRIMARYKEY</span><span style="color:#003366; line-height:25px">值,但看不到。<br style="line-height:25px"> 这么看来,如果直接使用</span><span style="color:#993300; line-height:25px">rowid/INTEGERPRIMARYKEY</span><span style="color:#003366; line-height:25px">来代替自增加字段,根据两者的细微的差别,需要注意是否与自己的应用冲突,<br style="line-height:25px"> 如果没有冲突,那么用</span><span style="color:#993300; line-height:25px">rowid/INTEGERPRIMARYKEY</span><span style="color:#003366; line-height:25px">会更快一</span><br style="line-height:25px"><span style="line-height:25px">第四</span>,<span style="color:#000080; line-height:25px">在android中,对于</span><span style="color:#993300; line-height:25px">INTEGERPRIMARYKEY</span><span style="color:#000080; line-height:25px">,<br style="line-height:25px"> 如果插入数据A,B,C,它们的_id为1,2,3,那么如果把他们都删除了,再插入一条数据,那么它的id为1而不是4。</span></wbr></wbr></wbr>
分享到:
评论

相关推荐

    布林效益工资管理 (ACCESS).rar_default.key_float_工资_布林效益工资管理

    create table fyjsb (id integer primary key , nf integer, 年分 yf integer, 月份 ks string, 科室 mark integer, 标记 1收入 0支出 num float, 钱数 xmmc string, 项目名称 xmdh string, 项目代号 kszsry...

    中文汉字笔划数据库

    CREATE TABLE IF NOT EXISTS "CHILD_BEAN" ("_id" INTEGER PRIMARY KEY ,"NAME" TEXT,"ADDRESS" TEXT,"BIHUA_COUNT" INTEGER NOT NULL ,"CHILD_ID" INTEGER); CREATE TABLE IF NOT EXISTS "CLASSIFY_BEAN" ("_id" ...

    MyBatis结果映射.docx

    创建两张表 客户表和订单表 ... id integer primary key auto_increment, name varchar(20)); create table order_tbl( id integer primary key auto_increment, name varchar(20), cid integer);

    java 个人记账管理系统

    + KEY_SETTINGTBL_ID + " INTEGER PRIMARY KEY AUTOINCREMENT, " + KEY_SETTINGTBL_NAME + " TEXT NOT NULL, " + KEY_SETTINGTBL_VALUE + " TEXT NOT NULL);"; db.execSQL(strCreateTbl); // ...

    1008家航空公司2018年机队sqlite3数据库

    截至2018年11月底,世界范围内1008家航空公司机队信息,内有两个表,一个airlines(id integer primary key autoincrement, airline text not null, url text not null, country text not null),一个products(id ...

    testSystem.rar

    pno integer primary key autoincrement, ptext char(5000) not null ); CREATE TABLE option( ono integer primary key autoincrement, otext char(5000) not null, pno integer, score integer not null, foreign...

    android数据库

    + " (" + KEY_ID + " integer primary key autoincrement, " + KEY_NAME + " text not null, " + KEY_AGE + " integer," + KEY_HEIGHT + " float);"; //SQL建表语句 public DBOpenHelper(Context context, ...

    python创建属于自己的单词词库 便于背单词

    本文实例为大家分享了python...复制代码 代码如下:cu.execute(‘create table test (id INTEGER PRIMARY KEY AUTOINCREMENT,dc varchar(20),cx varchar(20),cy varchar(50),mp3 varchar(50));’) 完整代码,效率不高,

    第一个MyBatis项目.txt

    创建一张表—— create table stu_tbl( id integer primary key auto_increment, name varchar(20), age integer);

    09 数据存储(二)1

    1. String sql=“create table demo ( Pid integer primary key 2. values指的是想要更新的数据 3

    EloRanking:用于足球联赛中 ELO 排名的闪亮应用

    排名 一个闪亮的服务器项目,用于跟踪... id INTEGER PRIMARY KEY, name VARCHAR(255) NOT NULL ); CREATE TABLE rounds ( id INTEGER PRIMARY KEY, name VARCHAR(255) NOT NULL ); CREATE TABLE games ( id INT

    politicalperspective

    id INTEGER PRIMARY KEY, fname VAR_CHAR(50), lname VAR_CHAR(50), age INTEGER, email VAR_CHAR(50), password VAR_CHAR(50); 资源2 文章 属性: id(整数) 来源(字符串) 标题(字符串) 网址(字符串) ...

    Node.js数据库实时监控库node-dbmon.zip

    create table testtable(id integer primary key, val varchar(10));'); var channel=dbmon.channel({ driver:'postgresql', driverOpts:{ postgresql:{ cli:cli } }, table:'testtable', monitor:'all', ...

    科技日报,2016年1月1日到2020年2月25日的所有文章SQLITE数据库,52500篇文章.rar

    conID INTEGER PRIMARY KEY ,--文章ID nDate date,--文章日期 cDate varchar(14),--中文日期(超长varchar不截断) nodeName varchar(30),--版名(超长varchar不截断) nodeNum int,--版次,即文章在第几版...

    自己封装的log存储类,用到qt自带的sqlite

    2.该类将log保存到sqlite数据库中,数据库的表包括“id,时间戳,日期,时间,log等级,log内容”,变量类型如下:(id INTEGER PRIMARY KEY autoincrement,Timestamp BIGINT,Date text,Time text,Level text,LogInfo...

    中国税务报,2009年12月7日到2020年2月25日的所有文章SQLITE数据库,共135761篇文章.rar

    conID INTEGER PRIMARY KEY ,--文章ID nDate date,--文章日期 cDate varchar(14),--中文日期(超长varchar不截断) nodeName varchar(30),--版名(超长varchar不截断) nodeNum int,--版次,即文章在第几版...

    C#开发计算器

    + "id integer primary key autoincrement," + "author text," + "price real," + "pages integer," + "name text)"; private Context mContext; public MyDatabaseHelper(Context context, String name, ...

    手机归属地数据库43万条 sqlite3 格式

    PRIMARY KEY (id), FOREIGN KEY(region_id) REFERENCES regions (id) ); CREATE INDEX ix_phones_number ON phones (number); sqlite&gt; .schema regions CREATE TABLE regions ( id INTEGER NOT NULL, ...

    信息发布网站数据库文档

    [id] integer primary key autoincrement, [title] nvarchar(100), [num] integer default '0', [path] nvarchar(20), [keys] nvarchar(200), [desc1] nvarchar(200)); create table [info]

    android fisrtdemo

    + "_id integer primary key autoincrement, " + remote_tables.tv_remote_config_table.KEY_REMOTE_ID + " integer not null, " + remote_tables.tv_remote_config_table.KEY_REMOTE_BITS + " integer not null,...

Global site tag (gtag.js) - Google Analytics