为什么SQLite将值存储为BLOB列中的INT?

8fsztsew  于 2023-10-23  发布在  SQLite
关注(0)|答案(1)|浏览(153)

根据我的SQL知识,整个表列必须具有相同的数据类型。然而,在SQLite中,似乎可以在blob列中存储任何类型的数据-即。一个blob列实际上不是一个blob类型,而是一个类型化的值,其中“valueblob”是“columnblob”的一个子类型(嵌套类型?)。这是否是设计和/或记录在任何地方?这是否也意味着它本质上是不可预测的,因为将整数转换为blob取决于编码(utf8 vs be/le utf 16)?
测试:

$ sqlite3
sqlite> create table tbl(value blob);
sqlite> INSERT INTO tbl VALUES (cast(1 as integer));
sqlite> INSERT INTO tbl VALUES (cast(2 as blob));
sqlite> INSERT INTO tbl VALUES (cast(3 as text));
sqlite> select value, typeof(value) from tbl;
1|integer
2|blob
3|text
uinbv5nw

uinbv5nw1#

除了特殊/通常隐藏的rowid列或其别名(主键中唯一的列,并且列类型特别是INTEGER(大小写无关)(而不是INT));则任何类型的值可以存储在任何亲和类型中。
这是SQLite的一个有意的灵活性特性
当解析时,列类型与类型亲和性(例如,INT,TINT解析为INTEGER的类型关联),只是列中存储了什么数据的可能指示。
列类型实际上可以是任何类型,只要它不与其他规则冲突。

  • 例如thecolumn rumplestilskin是允许的,则结果类型亲和性将是NUMERIC,但可以在列中存储BLOB。

有5种类型亲和性,INTEGER,真实的,TEXT,BLOB和NUMERIC(如果分配列类型的规则与前面的任何规则都不匹配,则分配后者)。例如,第一个规则是如果列类型包括INT,则亲和性是INTEGER。
然而,还有另一个级别,那就是SQLite CLASS,它是数据实际存储在磁盘/内存中的方式(通常不需要理解,因为SQLite根据存储的数据来管理它)。
要重申该注解,请参阅https://www.sqlite.org/datatype3.html
可以考虑这个简单的演示:

DROP TABLE IF EXISTS anycolumntypedemo;
CREATE TABLE IF NOT EXISTS anycolumntypedemo (
    id INTEGER PRIMARY KEY /* CAN ONLY HAVE INTEGER VALUE AS DATA TYPE MISMATCH ERROR */,
    col1 VARCHAR,
    col2 BLOB,
    col3 nearlyanythinggoestype,
    col4 INTEGER
);
INSERT INTO anycolumntypedemo VALUES
    (null,100,100,100, 100),
    (null,0987654321,' 1999', '  1234567890',' 0987654321'),
        (null,'FRED','BERT','HARRY','SUSAN'),
        (null,x'0102ff',datetime('now'),'',randomblob(10))
;
SELECT *,typeof(col1) AS c1type, typeof(col2) AS c2type, typeof(col3) AS c3type, typeof(col4) AS c4type FROM anycolumntypedemo;
DROP TABLE IF EXISTS anycolumntypedemo;

这将输出(SELECT)类似于:

*idrowid的别名,它不能有任何东西,但一个整数值

  • 可以看出,各种类型的值已经被存储在各种列中,这些列具有类型亲和性(根据分配类型亲和性的规则,因此col 3具有NUMERIC的类型亲和性,因为没有一个前面的亲和性确定规则被满足(更多信息参见链接))。
    *然而typeof函数返回一个类型(col?类型列),因此由于存储的值的类型不一致,因此类型不一致。

最近,SQLite引入了STRICT tables,如果SQLite的正常灵活性是一个问题,这可能是更可取的。

相关问题