动态数据类型

SQLite与大部分传统的SQL数据库不同,大部分传统SQL数据库采用的是静态数据类型,而SQLite是动态数据类型。即存储的值的数据类型,由值本身决定,而非存储容器决定。

例如,定义一个名为test的table,然后插入一行文本数据,则select出的数据类型为文本。

create test table (c1 int); 
insert into test values ("abc"); 
select typeof(c1) from test;  
-- 输出:text

这里存储容器就是test表的c1列,插入的值为"abc",实际存储类型并非int,而是根据插入的值"abc"本身决定。

支持的数据类型

SQLite原生支持5中数据类型:NULL、INTEGER、REAL、TEXT、BLOB。在SQLite中,所有数据最终都转化为该5中类型进行存储。

在SQLite中不支持BOOLEAN,在存储时,会将false转换为0,true转换为1。

同时SQLite不支持Date和Time数据类型,但是内置提供了一些时间操作函数,帮助用于转换为其他数据类型进行存储。

Affinity类型

大部分的中文文档都对Affinity类型翻译为「亲和类型」,这么翻译过于直译且不利于理解,个人认为翻译为「建议类型」更好。

回到刚才创建test表的示例:create test table (c1 int);
这里指定c1为int类型,就是声明了c1列的建议类型。由于SQLite是动态数据类型,从而在存储的时候,会先检查传入的值是否可以友好无损的转换为对应的建议类型,如果可以转换,则存储为建议类型,如果不能友好转换,则存储为传入值本身的类型。

例如刚才的示例,insert into test values ("abc"); 这里检查"abc"无法正确转换,从而存储为文本类型。

列的Affinity类型声明

在示例create test table (c1 int);中声明了c1列的Affinity类型为int类型,但是在SQLite支持的5中数据类型中,并没有int类型。
这是因为SQLite为了与传统SQL数据库有更好的兼容性,实际c1列Affinity类型是INTEGER。以下是常见的数据类型与SQLite的Affinity类型的对应关系。

常见类型声明对应的Affinity类型:

常见类型声明对应的Affinity类型
INT
INTEGER
TINYINT
SMALLINT
MEDIUMINT
BIGINT
UNSIGNED BIG INT
INTEGER
CHARACTER
VARCHAR
VARYING CHARACTER
NCHAR
NATIVE CHARACTER
NVARCHAR
TEXT
CLOB
TEXT
REAL
DOUBLE
DOUBLE PRECISION
FLOAT
REAL
NUMERIC
DECIMAL
BOOLEAN
DATE
DATETIME
NUMERIC
BLOBBLOB

CREATE TABLE

另外需要注意的是,如果在CREATE TABLE语句中未声明每一列的数据类型,则会将数据保存为其传入值的亲和类型。例如:

CREATE TABLE TB ( c1 );
INSERT INTO TB VALUES ( 1, "1" );
SELECT rowid, typeof(c1) from TB; 
-- 1, integer
-- 2, text