SQlite 在处理数据类型时与其他的数据库不同,区别在于它所支持的类型以及这些类型是如何存储、比较、强化(enforced)和指派(assign)的。下面将介绍 SQLite 存储类的基础。
一般情况下,SQLite 有 5 个原始的数据类型,被称为存储类。存储类通常是指值在磁盘上存储的格式,其实就是类型或数据类型的同义词。下表列出了这 5 个存储类型及说明。
名称 | 说明 |
---|---|
integer | 整数值是全部的数字(包括正和负)。整数可以是 1、2、3、4、6 或 8 字节。整数的最大范围(8字节)是 { -9223372036854775808,-1,0,1,+9223372036854775807 }。SQLite 根据数字的值自动控制整数所占的字节数 |
real | 实数是十进制的数值。SQLite 使用 8 字节的浮点数来存储实数 |
text | 文本是字符数据。SQLite 支持几种字符编码,包括 UTF-8 和 UTF-16(大字节头和小字节头)。字符串的最大值在编译和运行时可以调整,默认最大值是 1,000,000,000 字节 |
blob | 二进制大对象(BLOB)数据可以是任意类型的数据,BLOB 的最大值在编译和运行时可以调整,默认最大值是 1,000,000,000 字节 |
NULL | NULL 表示没有值。SQLite 具有对 NULL 的完全支持 |
SQlite 通过值的表示方法来判断其类型,下面就是 SQLite 使用的推断方法:
- SQLite 语句中用单引号或双引号括包来的文字被指派为 text。
- 如果文字是未用引号引起来的数据,并且没有小数点和指数,被指派为 integer。
- 如果文字是未用引号引起来的数据,并且带有小数点或指数,被指派为 real。
- 用 NULL 说明的值被指派为 NULL 存储类。
- 如果一个值的格式为 x’ABCD’,其中 ABCD 为 16 进制数字,则该值被指派为 blob。其中,x 前缀大小写皆可。
SQL 函数 typeof() 根据值的表示方法返回其存储类。使用该函数后,下面 SQL 语句返回的结果为:
这是 5 中内部的存储类,其中的 3.14 看起来就像实数,因此它就是实数。’3.14’ 看起来就像文本,因此就是文本,以此类推。
SQLite 中单独的一个字段可能包含不同存储类的值。这也是 SQLite 处理数据与其他数据库不同的第一个地方,许多熟悉其他数据库的人常常会问到“什么,一个字段可以有不同的存储类型?”请看下面的示例:
1 | CREATE TABLE DOMAIN(x); |
这种操作会带来一些问题。这种字段中的值如何存储和比较?如何对一个包含了 integer、real、text、blob 和 null 值的字段排序?一个整数和一个 blob 如何比较?哪个更大?它们能相等吗?
答案是:具有不同存储类的值可以存储在同一个字段中。可以被排序,因为这些值可以相互比较。SQLite 实现了完善额定义规则来做这件事。不同存储类的值可以通过它们各自类的“类值”进行排序,定义如下:
- NULL 存储类具有最低的类值。一个具有 NULL 存储类的值比所有其他的值都小(包括其他具有 NULL 存储类的值)。在 NULL 值之间,没有具体的排序顺序。
- integer 或 real 存储类值高于 NULL,它们的类值相等。integer 值和 real 值通过其数值进行比较。
- text 存储类的值比 integer 和 real 高。数值永远比字符串的值低。当两个 text 值进行比较时,其值大小由该值中定义的“排序法”决定。
- blob 存储类具有最高的类值。具有 blob 类的值大于其他所有类的值。blob 值之间在比较时使用 C 函数 memcmp()。
所以,当 SQLite 存储一个字段时,它首先按存储类分组———NULL 第一,然后是 integer 和 real,接着是 text,最后是 blob。然后进行分组内的排序,NULL 类内部各值不必排序,integer 和 real 按照数字比较,text 按照恰当的排序算法比较,blob 使用 memcmp()———实际上是比较比特位。下图说明了一个假设字段如何按照升序排序。