type(类型相似性)只有一个例外,没有真正的区别。
例外情况是 the_column_name INTEGER PRIMARY KEY(有或没有 AUTOINCREMENT),它将列定义为 rowid 列的别名。 INT PRIMARY KEY 没有。
所以the_column_name CHAR_INT PRIMARY KEY、the_column_name INT CHAR PRIMARY KEY 甚至the_column_name INT PRIMARY KEY 实际上是相同的,甚至可以使用the_column_name RUMPLESTILTSKIN PRIMARY KEY(尽管后者具有不同的类型亲和力)。
是决定类型亲和性的规则。有 5 个。优先级最高的规则是,如果类型具有 INT,则类型亲和性为 INTEGER。 RUMPLESTILTSKIN 作为一种类型会通过所有规则,除了最后一条规则,如果前面的规则都不适用,则类型关联为 NUMERIC。
3.1.柱亲和性的测定
列的亲和性由列的声明类型决定,根据
以下规则按所示顺序:
如果声明的类型包含字符串“INT”,那么它被赋值
INTEGER 亲和力。
如果列的声明类型包含任何字符串“CHAR”,
“CLOB”或“TEXT”,则该列具有 TEXT 亲和性。请注意,
类型 VARCHAR 包含字符串“CHAR”,因此被分配了 TEXT
亲和力。
如果声明的列类型包含字符串“BLOB”,或者如果没有
指定类型,则该列具有亲和性 BLOB。
如果列的声明类型包含任何字符串“REAL”,
"FLOA" 或 "DOUB" 则该列具有 REAL 亲和力。
否则,亲和度为 NUMERIC。
请注意,确定列亲和性的规则的顺序是
重要的。声明类型为“CHARINT”的列将同时匹配
规则 1 和 2,但第一个规则优先,因此该列
亲和力将是整数。
Datatypes In SQLite
说类型亲和性并不能决定数据的存储方式。每一列都根据依赖于所存储数据的存储类进行存储。
Null 存储为 null,一串数字(封闭或不封闭为字符串)作为整数。简而言之,数据将按照 SQLite 确定的方式存储,并且 SQlite 将尝试尽可能高效地存储数据,并且在尽可能小的空间内存储到一个字节作为存储的最小单位。
考虑以下几点:-
DROP TABLE IF EXISTS mytable1;
DROP TABLE IF EXISTS mytable2;
DROP TABLE IF EXISTS mytable3;
CREATE TABLE IF NOT EXISTS mytable1 (c1 CHAR_INT PRIMARY KEY);
CREATE TABLE IF NOT EXISTS mytable2 (c1 INT PRIMARY KEY);
CREATE TABLE IF NOT EXISTS mytable3 (c1 RUMPLEstiltSkin PRIMARY KEY);
-- INSERT INTO mytable1 VALUES(12345),('12345'),('a_12345'),('1_12345'),(x'0102030405'); -- fails due to unique constraint 12345 and '12345' are the same
-- INSERT INTO mytable2 VALUES(12345),('12345'),('a_12345'),('1_12345'),(x'0102030405'); -- fails due to unique constraint 12345 and '12345' are the same
-- INSERT INTO mytable3 VALUES(12345),('12345'),('a_12345'),('1_12345'),(x'0102030405'); -- fails due to unique constraint 12345 and '12345' are the same
INSERT INTO mytable1 VALUES(12345),('54321'),('a_12345'),('1_12345'),(x'0102030405');
INSERT INTO mytable2 VALUES(12345),('54321'),('a_12345'),('1_12345'),(x'0102030405');
INSERT INTO mytable3 VALUES(12345),('54321'),('a_12345'),('1_12345'),(x'0102030405');
SELECT c1, typeof(c1) FROM mytable1;
SELECT c1, typeof(c1) FROM mytable2;
SELECT c1, typeof(c1) FROM mytable3;
- 注释掉的 INSERTS(如果未注释并运行)失败并出现 UNIQUE 冲突,因为 SQLite 认为 12345 与“12345”相同。
typeof 函数返回列的类型(存储类型不是列亲和性)
结果如下:-
使用除 INTEGER PRIMARY KEY 之外的任何东西(有一些派生),因此 rowid 的别名是
搜索一个索引,比较快,相对于数据本身来说,数据比较少,而且数据本身是只读的。
也许考虑以下几点:-
DROP TABLE IF EXISTS mytable1;
DROP TABLE IF EXISTS mytable2;
DROP TABLE IF EXISTS mytable3;
CREATE TABLE IF NOT EXISTS mytable1 (pk INT PRIMARY KEY, name TEXT);
CREATE TABLE IF NOT EXISTS mytable2 (pk CHAR_INT PRIMARY KEY, name TEXT);
CREATE TABLE IF NOT EXISTS mytable3 (pk INT PRIMARY KEY, name TEXT) WITHOUT ROWID;
INSERT INTO mytable1
WITH RECURSIVE cte1(a,b) AS (
SELECT 'ABC_'||CAST(abs(random()) AS TEXT),'some data' UNION ALL
SELECT DISTINCT (substr(a,1,4))||CAST(abs(random()) AS TEXT),'some data' FROM cte1 LIMIT 1000000
)
SELECT * FROM cte1
;
INSERT INTO mytable2
WITH RECURSIVE cte1(a,b) AS (
SELECT '1_'||CAST(abs(random()) AS TEXT),'some data' UNION ALL
SELECT DISTINCT (abs(random()) % 100)||'_'||CAST(abs(random()) AS TEXT),'some data' FROM cte1 LIMIT 1000000
)
SELECT * FROM cte1
;
INSERT INTO mytable3 SELECT * FROM mytable1;
SELECT * FROM mytable1 WHERE name LIKE('%me data%');
SELECT * FROM mytable2 WHERE name LIKE('%me data%');
SELECT * FROM mytable3 WHERE name LIKE('%me data%');
SELECT * FROM mytable3 WHERE name LIKE('%me data%');
SELECT * FROM mytable1 WHERE name LIKE('%me data%');
SELECT * FROM mytable2 WHERE name LIKE('%me data%');
SELECT * FROM mytable2 WHERE name LIKE('%me data%');
SELECT * FROM mytable3 WHERE name LIKE('%me data%');
SELECT * FROM mytable1 WHERE name LIKE('%me data%');
这将创建 3 个排列,全部为 1,000,000 行
-
mytable1 的主键为 ABC_????例如:-
-
mytable2 的主键为 ??_????例如:-
mytable3 是 mytable1 的副本,但该表是使用 WITHOUT ROWID 定义的
时间
所有 3 个的 SELECTS 都非常接近(完成多个选择并且以不同的顺序来平衡缓存)。包含时间的消息是:-
SELECT * FROM mytable1 WHERE name LIKE('%me data%')
> OK
> Time: 0.672s
SELECT * FROM mytable2 WHERE name LIKE('%me data%')
> OK
> Time: 0.667s
SELECT * FROM mytable3 WHERE name LIKE('%me data%')
> OK
> Time: 0.702s
SELECT * FROM mytable3 WHERE name LIKE('%me data%')
> OK
> Time: 0.7s
SELECT * FROM mytable1 WHERE name LIKE('%me data%')
> OK
> Time: 0.675s
SELECT * FROM mytable2 WHERE name LIKE('%me data%')
> OK
> Time: 0.673s
SELECT * FROM mytable2 WHERE name LIKE('%me data%')
> OK
> Time: 0.676s
SELECT * FROM mytable3 WHERE name LIKE('%me data%')
> OK
> Time: 0.709s
SELECT * FROM mytable1 WHERE name LIKE('%me data%')
> OK
> Time: 0.676s
-
我相信 mytable3 会受到一些影响,因为扫描(在这种情况下)是在 PRIMARY KEY 上,而不是适合/首选其他两个的 rowid。李>
除了之前的链接,大家不妨看看:-