SQLite数据类型

简介:

大多数 SQL 数据库引擎(据我们所知,除 SQLite 之外的所有SQL 数据库引擎)都使用严格的静态类型。使用静态类型,值的类型便由它的容器 --存储值的特定的列 --来决定。

SQLite 使用更通用的动态类型系统。在SQLit 中,值的数据类型与值本身相关,而不是与它的容器。SQLite的动态类型系统与其它数据库引擎的常用静态类型系统是向后兼容的,在这个意义上,工作在静态类型数据库上的SQL 语句应该以同样的方式工作在SQLite 中。然而,SQLite中的动态类型允许它做传统的严格类型的数据库所不能做的事。

1.0 存储类型与数据类型

存储在 SQLite 数据库中的每个值(或是由数据库引擎所操作的值)都有一个以下的存储类型:

1     NULL. 值是空值。

2     INTEGER. 值是有符号整数,根据值的大小以12348字节存储。

3     REAL. 值是浮点数,以8字节IEEE 浮点数存储。

4     TEXT. 值是文本字符串,使用数据库编码(UTF-8,UTF-16BE UTF-16LE)进行存储。

5     BLOB. 值是一个数据块,按它的输入原样存储。

注意,存储类型比数据类型更笼统。以 INTEGER 存储类型为例,它包括6种不同的长度不等的整数类型,这在磁盘上是不同的。但是只要INTEGER 值从磁盘读取到内存进行处理,它们就被转换为更为一般的数据类型(8字节有符号整型)。因此在一般情况下,存储类型”  “数据类型” 没什么差别,这两个术语可以互换使用。

SQLite 版本3数据库中的任何列,除了整型主键列,都可用于存储任何存储类型的值。

SQL 语句中的任何值,无论它们是嵌入到SQL 语句中的字面量还是绑定到预编译SQL 语句中的参数,都有一个隐含的存储类型。在下述情况下,数据库引擎会在执行查询时在数值存储类型(INTEGERREAL)和TEXT 之间进行转换。

1.1 布尔类型

SQLite 并没有单独的布尔存储类型,而是将布尔值存储为整数 0(false)  1(true)

1.2 日期和时间类型

SQLite 没有另外的存储类型来存储日期和时间。SQLite的内置的日期和时间函数能够将日期和时间存为TEXTREALINTEGER 值:

1     TEXT  ISO8601 字符串 ("YYYY-MM-DD HH:MM:SS.SSS")

2     REAL 儒略日数(Julian Day Numbers),按照前公历,自格林威治时间公元前47141124日中午以来的天数。

3     INTEGER Unix 时间,自1970-01-01 00:00:00 UTC 以来的秒数。

应用可以选择这些格式中的任一种存储日期和时间,并使用内置的日期和时间函数在这些格式间自由转换。

2.0 类型亲和性

为了最大限度地提高 SQLite 和其它数据库引擎之间的兼容性,SQLite支持列的类型亲和性的概念。列的类型亲和性是指数据存储于该列的推荐类型。这里重要的思想是类型是推荐的,而不是必须的。任何列仍可以存储任何类型的数据。这只是让一些列有选择性地优先使用某种存储类型。一个列的首选存储类型被称为它的亲和性

每个 SQLite 3 数据库中的列都归于以下的类型亲和性中的一种:

1     TEXT

2     NUMERIC

3     INTEGER

4     REAL

5     NONE

一个具有 TEXT 亲和性的列使用存储类型 NULLTEXT BLOB 存储所有数据。如果数值数据被插入到一个具有TEXT 亲和性的列,则数据在存储前被转换为文本形式。

数值亲和性的列可能包含了使用所有五个存储类的值。当插入文本数据到数值列时,该文本的存储类型被转换成整型或实数(按优先级排序)如果这种转换是无损或可逆的的话。对于文本与实数类型之间的转换,如果前15个重要十进制数字被保留的话,SQLite认为这种转换是无损并可逆的。如果文本不能无损地转换成整型或实数,那这个值将以文本类型存储。不要试图转换NULLBLOB值。

一个字符串可能看上去像带有小数点和/或指数符的浮点文字,但只要这个值可以用一个整型表示,数值亲和性就会把它转换成一个整型。因此,字符串‘3.0e+5'以整型300000,而不是浮点值30000.0的形式存储在一个数值亲和性的列里。

 

一个使用整型亲和性的列与具有数值亲和性的列表现一致。只是在CAST表达式里,它们之间的区别体现得明显。

除了强制将整型值转换成浮点表示外,一个具有实数亲和性的列与具有数值亲和性的列表现一致(作为一个内部的优化,为了少占用空间,无小数部分且存储在实数亲和性列上的小浮点值以整型形式写到磁盘,读出时自动转换回浮点值。在SQL级别,这种优化是完全不可见的,并且只能通过检查数据库文件的原始比特检测到)。

一个具有NONE亲和性的列不能从一种存储类型转换成另一种,也不要试图强制对它进行转换。

2.1 列亲和性测定

列的亲和性是由它的声明类型决定的,按照以下顺序所示的规则:

1. 如果声明类型包含字符串“INT”,那它被指定为整型亲和性;

2. 如果列的声明类型包含任何“CHAR”“CLOB”“TEXT”字符串,那么该列具有文本亲和性。注意:VARCHAR类型包含“CHAR”并且被指定为文本亲和性;

3. 如果列的声明类型包含“BLOB”或者没有指定类型,那这列具有NONE亲和性;

4. 如果列的声明类型包含任何“REAL”“FLOA”“DOUB”字符串,则该列具有实数亲和性;

5. 否则,它将具有数值亲和性。

注意:判定列亲和性规则的顺序是很重要的。一个具有“CHARINT”声明类型的列将匹配规则12,但是规则1优先所有该列具有整型亲和性。

2.2 亲和性名字实例

下表显示了有多少从更传统的SQL实现的常用数据类型名,通过上一节介绍的五个规则被转换成各种亲和性类型。这张表只显示了SQLite可接受的一小部分数据类型名。注意:跟在类型名后,括号内数值参数(如:VARCHAR255))将被SQLite忽略 -SQLite不对字符串、BLOBs或数值的长度强加任何限制(除了大型全局SQLITE_MAX_LENGTH限制)。

spacer.gif

注意:因为在“POINT”末尾的“INT”,一个“ FLOATING POINT”声明类型会被赋予整型亲和性,而不是实数亲和性。而且“STRING”声明类型具有数值亲和性,而不是文本亲和性。

2.3 列亲和性行为实例

以下SQL演示当有值插入到一张表时,SQLite如何使用列亲和性实现类型转换的:

 

?

1

2

3

4

5

6

7

CREATE TABLE  t1(

  t  TEXT,   -- text affinity by rule 2

  nu  NUMERIC--  numeric affinity by rule 5

  i  INTEGER--  integer affinity by rule 1

  r  REAL,   -- real affinity by rule 4

  no BLOB   --  no affinity by rule 3

);

 

?

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

-- Values stored as TEXT, INTEGER, INTEGER, REAL, TEXT.(值分别以文本、整型、整型、实数、文本形式存储)

INSERT INTO  t1 VALUES('500.0',  '500.0''500.0',  '500.0''500.0');

SELECT typeof(t), typeof(nu), typeof(i),  typeof(r), typeof(noFROM t1;

text|integer|integer|real|text

  

-- Values stored as TEXT, INTEGER, INTEGER, REAL, REAL.

DELETE FROM  t1;

INSERT INTO  t1 VALUES(500.0, 500.0, 500.0,  500.0, 500.0);

SELECT typeof(t), typeof(nu), typeof(i),  typeof(r), typeof(noFROM t1;

text|integer|integer|real|real

  

-- Values stored as TEXT, INTEGER, INTEGER, REAL, INTEGER.

DELETE FROM  t1;

INSERT INTO  t1 VALUES(500, 500, 500, 500, 500);

SELECT typeof(t), typeof(nu), typeof(i),  typeof(r), typeof(noFROM t1;

text|integer|integer|real|integer

  

-- BLOBs are always stored as BLOBs regardless of column affinity.  DELETE FROM t1;

INSERT INTO  t1 VALUES(x'0500',  x'0500', x'0500',  x'0500', x'0500');

SELECT typeof(t), typeof(nu), typeof(i),  typeof(r), typeof(noFROM t1;

blob|blob|blob|blob|blob

  

-- NULLs are also unaffected by affinity

DELETE FROM  t1;

INSERT INTO  t1 VALUES(NULL,NULL,NULL,NULL,NULL);

SELECT typeof(t), typeof(nu), typeof(i),  typeof(r), typeof(noFROM t1;

null|null|null|null|null

3.0 比较表达式

同标准SQL一样,SQLite 3支持如下的比较操作符:"=","==", "<", "<=", ">",">=", "!=", "<>", "IN","NOT IN", "BETWEEN", "IS", 以及"IS NOT"

3.1 排序规则

比较的结果与操作数的存储类型有关,同时依据以下的规则:

1     NULL值小于其他任何值(包括另外一个NULL

2     INTEGERREAL小于TEXTBLOB值;若两个INTEGER(或者REAL)比较,则按照实际的数值进行。

3     TEXT小于BLOB,若两个TEXT比较,结果则由适当的整理顺序决定

4     若两个BLOD比较,与memcmp()的结果一致

3.2 操作数进行比较时的相似性

在进行值的比较之前,SQLite会尝试在存储类INTEGERREAL/TEXT之间进行值的转换。在比较之前尝不尝试进行转换完全取决于操作数的相似性。操作数相似性的判定规则如下:

1     只是对一个列中的值进行引用的表达式同被引用的列具有完全相同的相似性。注意,如果XY.Z代表的是列的名称,那么+X+Y.Z可以认为是为了判定其相似性的表达式。

2     "CAST(expr AS type)"所表示的表达式同类型定义为"type"的列具有完全相同的相似性。

3     其它情况下的表达式具有NONE相似性。

 

3.3 比较前的类型转换

应用相似性"applyaffinity")的意思是,当且仅当所涉及的转换是无损且可逆的情况下,将一个操作数转换为某特定的存储类型。在进行比较之前对比较运算符的操作数应用相似性的规则如下按顺序所示:

1     如果其中的一个操作数具有INTEGERREAL或者NUMERIC相似性而另外一个操作数具有TEXT或者NONE相似性,那么就要对这另外一个操作数应用NUMERIC相似性。

2     如果其中的一个操作数具有TEXT相似性而另外一个具有NONE相似性,那么就要对这另外一个操作数应用TEXT相似性。

3     其它情况下不会应用任何相似性,两个操作数按照各自的原样进行比较。

将表达式"a BETWEEN b AND c"看作两个单独的二元比较运算"a>= b AND a <= c",即使这么一来,可能会造成其中的a在两次比较中会被应用不同的相似性,也要这么处理。Datatypeconversions in comparisons of the form "x IN (SELECT y ...)"这种形式的比较中,数据类型的转换完全同"x=y"一样进行处理。表达式"aIN (x, y, z, ...)" "a = +x OR a = +y OR a = +z OR ..."等价。换句话说,IN运算符右侧的值(本例中就是"x","y", and "z")被看作是无相似性的,即使它们凑巧是某列的值或者是CAST表达式。

3.4 比较示例 










本文转自 h2appy  51CTO博客,原文链接:http://blog.51cto.com/h2appy/1964588,如需转载请自行联系原作者
目录
相关文章
|
10天前
|
关系型数据库 MySQL 数据库
Python处理数据库:MySQL与SQLite详解 | python小知识
本文详细介绍了如何使用Python操作MySQL和SQLite数据库,包括安装必要的库、连接数据库、执行增删改查等基本操作,适合初学者快速上手。
74 15
|
1月前
|
存储 SQL 数据库
数据库知识:了解SQLite或其他移动端数据库的使用
【10月更文挑战第22天】本文介绍了SQLite在移动应用开发中的应用,包括其优势、如何在Android中集成SQLite、基本的数据库操作(增删改查)、并发访问和事务处理等。通过示例代码,帮助开发者更好地理解和使用SQLite。此外,还提到了其他移动端数据库的选择。
41 8
|
2月前
|
Web App开发 SQL 数据库
使用 Python 解析火狐浏览器的 SQLite3 数据库
本文介绍如何使用 Python 解析火狐浏览器的 SQLite3 数据库,包括书签、历史记录和下载记录等。通过安装 Python 和 SQLite3,定位火狐数据库文件路径,编写 Python 脚本连接数据库并执行 SQL 查询,最终输出最近访问的网站历史记录。
40 4
|
2月前
|
存储 关系型数据库 数据库
轻量级数据库的利器:Python 及其内置 SQLite 简介
轻量级数据库的利器:Python 及其内置 SQLite 简介
68 3
|
2月前
|
应用服务中间件 PHP Apache
PbootCMS提示错误信息“未检测到您服务器环境的sqlite3数据库扩展...”
PbootCMS提示错误信息“未检测到您服务器环境的sqlite3数据库扩展...”
|
3月前
|
存储 API 数据库
QML使用Sqlite数据库存储ListModel数据
本文介绍了在QML中使用Sqlite数据库存储ListModel数据的方法,包括如何创建数据库、读取数据、动态添加和删除数据,以及如何在程序启动和退出时与数据库同步数据。
|
3月前
|
数据库 数据库管理
qt对sqlite数据库多线程的操作
本文总结了在Qt中进行SQLite数据库多线程操作时应注意的四个关键问题,包括数据库驱动加载、加锁、数据库的打开与关闭,以及QsqlQuery变量的使用。
216 1
|
2月前
|
存储 缓存 关系型数据库
sqlite 数据库 介绍
sqlite 数据库 介绍
48 0
|
4月前
|
人工智能 小程序 Java
【工具】轻松解锁SQLite数据库,一窥微信聊天记录小秘密
本文介绍了一款名为PyWxDump的开源工具,它可以获取微信账户信息、解密SQLite数据库以查看和备份聊天记录。此工具适用于已登录电脑版微信的用户,通过GitHub下载后简单几步即可操作。适合对数据恢复感兴趣的开发者,但请注意合法合规使用并尊重隐私。
601 2
【工具】轻松解锁SQLite数据库,一窥微信聊天记录小秘密
|
4月前
|
关系型数据库 Java MySQL
C#winform中使用SQLite数据库
C#winform中使用SQLite数据库
209 3
C#winform中使用SQLite数据库