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

问题描述 投票:0回答:1

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

测试:

$ 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
sqlite
1个回答
0
投票

除了特殊/通常隐藏的 rowid 列或其别名(作为主键中唯一列的列,并且列类型特别是 INTEGER (与大小写无关)(而不是例如 INT));那么任何类型的值都可以存储在任何亲和类型中。

这是 SQLite 的有意的灵活性功能

列类型在解析为类型关联时(例如 INT、TINT 解析为 INTEGER 的类型关联),只是列中存储了哪些数据的可能指示。

列类型实际上可以是任何类型,只要不与其他规则冲突即可。

  • 例如
    thecolumn rumplestilskin
    是允许的,结果类型关联将为 NUMERIC,但可以将 BLOB 存储在列中。

有 5 种类型亲和性:INTEGER、REAL、TEXT、BLOB 和 NUMERIC(如果分配列类型的规则与前面的任何规则都不匹配,则分配的类型为后者)。例如第一条规则是如果列类型包括 INT,则亲和力为 INTEGER。

但是,还有另一个级别,那就是存储类,它是数据实际存储在磁盘/内存中的方式(通常不需要理解这一点,因为 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;

这将输出(选择)类似:-

  • idrowid的别名,它只能是整数值
  • 可以看到,不同的列中存储了各种类型的值,这些列具有类型亲和性(根据分配类型亲和性的规则,因此 col3 的类型亲和性为 NUMERIC,因为前面的亲和性确定规则都没有)遇见(更多信息请参阅链接))。
  • 然而,typeof
    函数返回的类型(col?type列)是根据实际存储的值的类型确定的,因此类型不一致,因为存储的值的类型不一致。 
最近 SQLite 引入了

STRICT,如果担心 SQLite 的正常灵活性,这可能更可取。

© www.soinside.com 2019 - 2024. All rights reserved.