(转)Sqlite中INTEGER PRIMARY KEY AUTOINCREMENT和rowid的使用
原文:http://www.cnblogs.com/peida/archive/2008/11/29/1343832.html
Sqlite中INTEGER PRIMARY KEY AUTOINCREMENT和rowid的使用
在用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会更快一点。 |
(转)Sqlite中INTEGER PRIMARY KEY AUTOINCREMENT和rowid的使用的更多相关文章
- SQLite3中自增主键相关知识总结,清零的方法、INTEGER PRIMARY KEY AUTOINCREMENT和rowid的使用
这篇文章主要介绍了SQLite3中自增主键相关知识总结,清零的方法.INTEGER PRIMARY KEY AUTOINCREMENT和rowid的使用等,需要的朋友可以参考下 一.SQLite清空表 ...
- SQLite中的自增关键字:AUTO_INCREMENT、INTEGER PRIMARY KEY与AUTOINCREMENT
1.SQLite不支持关键字AUTO_INCREMENT 1)AUTO_INCREMENT不生效的问题 SQL语句: CREATE TABLE todo ( id INTEGER AUTO_I ...
- SQLite主键自增需要设置为integer PRIMARY KEY
按照正常的SQL语句,创建一个数据表,并设置主键是这样的语句: ), EventType )) 但使用这种办法,在SQLite中创建的的数据表,如果使用Insert语句插入记录,如下语句: INSER ...
- Mysql中的primary key 与auto_increment
mysql> create table cc(id int auto_increment); ERROR (): Incorrect table definition; there can be ...
- shell脚本检索所有mysql数据库中没有primary key的表
1.mkdir -p /root/scripts/ 2. cd /root/scripts/ vim query.sql,代码如下: SELECT CONCAT(t.table_schema,&quo ...
- EF6 在 SQLite中使用备忘
== 菜鸟级选手试验在EF6中使用Sqlite,零EF基础,少量Sqlite基础.经过断断续续的很长时间 - _ -! >>连接 1. 安装 使用目前最新版本EF6.1,Sqlite1.0 ...
- Android把图片保存到SQLite中
1.bitmap保存到SQLite 中 数据格式:Blob db.execSQL("Create table " + TABLE_NAME + "( _id INTEGE ...
- Android 保存图片到SQLite,读出SQLite中的图片
1.bitmap保存到SQLite 中 数据格式: db.execSQL("Create table express ( _id INTEGER PRIMARY KEY AUTOINCREM ...
- SQLite中的增删改查
虽然android提供了sql查询的封装方法,但是理解起来还是麻烦,所以我这里用sql语句来完成工作. 首先是建立一个类,继承SQLiteOpenHelper 这里面会建立一个数据库,并且初始化一个表 ...
随机推荐
- 【转】 C++ vector用法
在c++中,vector是一个十分有用的容器,下面对这个容器做一下总结. 1 基本操作 (1)头文件#include<vector>. (2)创建vector对象,vector<in ...
- db:seed 更好的生成测试数据
make:model -m -> 在database/migrations/目录下生成的table表中设置表的字段名和字段类型->在app/目录下对应的模型文件中设置可添加字段 -> ...
- sass less
CSS 预处理器技术已经非常的成熟,而且也涌现出了越来越多的 CSS 的预处理器框架.本文向你介绍使用最为普遍的三款 CSS 预处理器框架,分别是 Sass.Less CSS.Stylus. 首先我们 ...
- 转 http://www.5icool.org/a/201106/a654.html CSS开发中常用的公用样式
overflow:hidden 隐藏溢出 一.自己总结的公用样式解析 html, body, div, p, ul, li, dl, dt, dd, h1, h2, h3, h4, h5, h6, f ...
- viewDidLoad && loadView
viewDidLoad 方法在controller加载了相关的views后被调用,而不论这些views存储在nib文件里还是在loadView函数中生成. loadView 方法在控制器的 view ...
- URL和搜索引擎优化
URL要短:谷歌的算法是给5个以后的单词更少的权重 URL不含和少含问号:防止死循环 小写字母:搜索引擎遵守HTTP规范,区分大小写.
- Hibernate缓存机制
缓存是介于应用程序和物理数据源之间,其作用是为了降低应用程序对物理数据源访问的频次,从而提高了应用的运行性能.缓存内的数据是对物理数据源中的数据的复制,应用程序在运行时从缓存读写数据,在特定的时刻或事 ...
- Oracle存储过程写法
create or replace procedure QIANFEIGL_JIAOKUANDY( cebenh varchar2, kehuh varchar2, hetongh varchar2, ...
- 【转】数据库范式(1NF 2NF 3NF BCNF)详解一
以下内容转自:http://jacki6.iteye.com/blog/774866 --------------------------------------------分割线---------- ...
- 为不同浏览器创建XMLHttpRequest对象
/*声明一个XMLHttpRequest对象*/ var xmlHttp=false; /*@cc_on@*/ /*if(@_jscript_version>=5) try { xmlHttp= ...