动态数据类型
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 |
BLOB | BLOB |
CREATE TABLE
另外需要注意的是,如果在CREATE TABLE
语句中未声明每一列的数据类型,则会将数据保存为其传入值的亲和类型。例如:
CREATE TABLE TB ( c1 );
INSERT INTO TB VALUES ( 1, "1" );
SELECT rowid, typeof(c1) from TB;
-- 1, integer
-- 2, text