SQLite 使用主键,ROWID 及自增列
SQLite 使用主键,ROWID 及自增列
之前关注过一些嵌入式数据库,倒时 SQLite 风头更劲,在 Android 上被应用,在 HTML5 中一些浏览器的 Local Database 的实现也是 SQLite。因在 PhoneGap 中使用数据库存储的选择也期待着它的表现,首先要建个数据库,第一要义就是主键的选择,自增列是最有效更简单的。
这里就看下 SQLite 怎么使用自动列,了解三个内容,ROWID, ROWID 的别名,自动列与序列表,归根结底它们都是 ROWID。
1. ROWID
每个表默认都有 rowid 列,除非创建表时指定了 WITHOUT ROWID, 它现在是 64 位长的。在查询时用 select * from table1
里没有它,要显式的用 select rowid, * from table1
就会列出它来。
2. ROWID 的别名
ROWID 除了可用 rowid 查出它之外,还可用别名 _ROWID_ 和 OID,都不分大小写的, 例如 select oid from table1
。另外我们还可以自定义一个 ROWID 的别名,用 INTEGER PRIMARY KEY
标识的列也是 ROWID 的一个别名,比如我们用 id 来作为 ROWID 的别名。
ROWID 的表示也是个自增列,每个表有自己的计数器,和常见的数据库的自增列是一致的。
SQLite 的 ROWID 可不象 Oracle 的 ROWID, Oracle 的 ROWID 是纯内部的,标记着记录的物理位置,所以数据库导入导出 Oracle 的 ROWID 就会变了。更为可怕的是 SQLite 的 ROWID 是可以自己赋值的。
3. 自增列序列表(也是 ROWID)
用 INTEGER PRIMARY KEY AUTOINCREMENT 标识的列就是个自增列,说到底它也是 ROWID 别名。数据库中存在自增列后,SQLite 就会创建一个 sqlite_sequence 表。所有表的自增列都共享这个表,sqlite_sequence 分别维护着每个自增列的当前值,所以自增列的计数也是单独的。它不象于 Oracle 中多个表在共用一个序列时,ID 值是交错的,Oracle 的序列的好处就是插入前可获知下一个序列值。
自增列的好处就能查看到当前的序列值,sqlite_sequence 中的值也是可以修改的,不过一般人不会这么干,可以用 select last_insert_rowid()
得到刚刚插入的 ROWID 值。
4. VACUUM 命令
VACUUM 能重建 ROWID 值,比如对于非自增列,select rowid, c1
1|a
2|b
3|c
把中间那条记录删除后,select rowid, c1 后的记录是
1|a
3|c
这个结果我们没什么惊奇的,现在我们来执行下 vacuum 命令,再 select rowid, c1 后记录是
1|a
2|b
ROWID 又可重复利用了,但命令 vacuum 对于自增列是不起作用的,因为自增列的值是由 sqlite_sequence 表维护的。
下面是演示那几个概念的全过程:
SQLite version 3.8.2 2013-12-06 14:53:3
Enter ".help" for instructions
Enter SQL statements terminated with a ";"
sqlite> create table t1(c1);
sqlite> create table t2(c1);
sqlite> insert into t1(c1) values('a');
sqlite> insert into t2(c1) values('b');
sqlite> select * from t1;
a
sqlite> insert into t2(oid, c1) values(5, 'c');
sqlite> select rowid, * from t1 union select rowid, * from t2;
1|a
1|b
5|c
sqlite> create table t3(c1 integer primary key, c2);
sqlite> insert into t3(c2) values('c');
sqlite> select rowid, * from t3;
1|1|c
sqlite> select rowid, _rowid_, oid, * from t3;
1|1|1|1|c
sqlite> select 8 from sqlite_master;
sqlite> select * from sqlite_master;
table|t1|t1|2|CREATE TABLE t1(c1)
table|t2|t2|3|CREATE TABLE t2(c1)
table|t3|t3|4|CREATE TABLE t3(c1 integer primary key, c2)
sqlite> create table t4(c1 integer primary key autoincrement, c2);
sqlite> select * from sqlite_master;
table|t1|t1|2|CREATE TABLE t1(c1)
table|t2|t2|3|CREATE TABLE t2(c1)
table|t3|t3|4|CREATE TABLE t3(c1 integer primary key, c2)
table|t4|t4|5|CREATE TABLE t4(c1 integer primary key autoincrement, c2)
table|sqlite_sequence|sqlite_sequence|6|CREATE TABLE sqlite_sequence(name,seq);
sqlite> insert into t4(c2) values('d');
sqlite> select rowid, * from t4;
1|1|d
sqlite> select * from sqlite_sequence;
t4|1
sqlite> create table t5(c1 integer primary key autoincrement, c2);
sqlite> select * from sqlite_sequence;
t4|1
sqlite> insert into t5(c2) values('e');
sqlite> select * from sqlite_sequence;
t4|1
t5|1
sqlite> insert into t1(c1) values('f');
sqlite> delete from t1 where rowid=1;
sqlite> select rowid, * from t1;
1|f
sqlite> update sqlite_sequence set seq=4 where name='t5';
sqlite> insert into t5(c2) values('h');
sqlite> select * from t5;
1|e
4|h
sqlite> delete from t5 where c1=1;
sqlite> select * from t5
4|h
参考:1. SQLite Autoincrement
2. sqlite_sequence table
SQLite 使用主键,ROWID 及自增列的更多相关文章
- SQLITE数据表主键设置Id自增方法
SQLITE数据表主键设置Id自增方法 标签: sqliteintegerinsertnulltableapi 2010-01-12 08:39 35135人阅读 评论(8) 收藏 举报 分类: S ...
- Mysql增加主键或者更改表的列为主键的sql语句
...
- SQLServer 自增主键创建, 指定自增主键列值插入数据,插入主键
http://blog.csdn.net/zh2qiang/article/details/5323981 SQLServer 中含自增主键的表,通常不能直接指定ID值插入,可以采用以下方法插入. 1 ...
- powerdesigner中怎么给一主键设为自增型auto increme
在使用powerdesigner 设计数据库表时,通常要对主键进行设置,如果主键是int 类型,一般会设置成自增,那么怎么在 powerdesigner 中设置呢,以下是具体的方法: 在所要设为自增型 ...
- 修改主键id为自增
详见:sqlserver修改主键为自增 先删除id字段, 执行下面sql即可: alter table sms_rec add id int IDENTITY (1,1) PRIMARY KEY
- SQLite设置主键自动增长及插入语法
SQLite中,一个自增长字段定义为INTEGER PRIMARY KEY AUTOINCREMENT,那么在插入一个新数据时,只需要将这个字段的值指定为NULL,即可由引擎自动设定其值,引擎会设定为 ...
- mysql自增列导致主键重复问题分析。。。
前几天开发童鞋反馈一个利用load data infile命令导入数据主键冲突的问题,分析后确定这个问题可能是mysql的一个bug,这里提出来给大家分享下.以免以后有童鞋遇到类似问题百思不得其解,难 ...
- mysql iot 主键自增列问题
mysql 如何避免热点块? 主键按sn自增列 Oracle 可以通过翻转索引 比如 插入101 102 103 104 变成101 201 301 401 分散数据 反转索引坏处,无法index r ...
- (转)mysql自增列导致主键重复问题分析
mysql自增列导致主键重复问题分析... 原文:http://www.cnblogs.com/cchust/p/3914935.html 前几天开发童鞋反馈一个利用load data infile ...
随机推荐
- kubernetes资源清单之DaemonSet
什么是 DaemonSet? DaemonSet 确保全部(或者某些)节点上运行一个 Pod 的副本.当有节点加入集群时,也会为他们新增一个 Pod . 当有节点从集群移除时,这些 Pod 也会被回收 ...
- Vivotek 摄像头远程栈溢出漏洞分析及利用
Vivotek 摄像头远程栈溢出漏洞分析及利用 近日,Vivotek 旗下多款摄像头被曝出远程未授权栈溢出漏洞,攻击者发送特定数据可导致摄像头进程崩溃. 漏洞作者@bashis 放出了可造成摄像头 C ...
- kill命令和killall命令
kill命令用于终止指定的进程(terminate a process),是Unix/Linux下进程管理的常用命令.通常,我们在需要终止某个或某些进程时,先使用ps/pidof/pstree/top ...
- MySQL查询数据库中所有数据表的数据条数
select table_name,table_rows from information_schema.tables where TABLE_SCHEMA = '数据库名称' order by ta ...
- SAP笔记
1,负数的表示增强 负号从数字后更改到数字前面 适用于字符型字段: CALL FUNCTION 'CLOI_PUT_SIGN_IN_FRONT' CHANGING VALUE = gt_table-c ...
- XMLHttpRequest status为0
//创建XMLHttpRequest()对象 var request = new XMLHttpRequest(); ...... 今天写一个ajax , 明明是有结果返回的,但得到的request ...
- Internet层协议下IP协议
Internet层协议特征 运行于 OSI 网络层面向无连接的协议独立处理数据包分层编址尽力而为传输无数据恢复功能 Internet层主要包含IP.ICMP.ARP.RARP几个协议. 这一主要说IP ...
- 给定一个矩阵 A, 返回 A 的转置矩阵。
给定一个矩阵 A, 返回 A 的转置矩阵. 矩阵的转置是指将矩阵的主对角线翻转,交换矩阵的行索引与列索引. 示例 1: 输入:[[1,2,3],[4,5,6],[7,8,9]]输出:[[1,4,7], ...
- 云原生相关名词Istio发音
服务网格词汇 Istio,希腊语言中大概是风帆的意思, 发音 [iːst'iəʊ] ,相当于中文的 伊斯特亿欧
- Java-JDBCUtil工具类
import java.io.File; import java.io.FileInputStream; import java.io.FileNotFoundException; import ja ...