INT, INTEGER, SMALLINT, TINYINT
DEC, DECIMAL
LONGCHAR, LONGVARCHAR
DATETIME, SMALLDATETIME
是否有某个文档列出了各种数据类型的最小/最大容量?例如,我猜 smallint
的最大值比 tinyint
大,但比整数小,但我不知道这些容量是多少。
INT, INTEGER, SMALLINT, TINYINT
DEC, DECIMAL
LONGCHAR, LONGVARCHAR
DATETIME, SMALLDATETIME
是否有某个文档列出了各种数据类型的最小/最大容量?例如,我猜 smallint
的最大值比 tinyint
大,但比整数小,但我不知道这些容量是多少。
SQLite
在技术上没有数据类型,而是使用显式类型转换系统的存储类,如果您习惯于传统的RDBMS
,可能会感到困惑。内部所有数据都存储为文本。数据类型根据亲和性(分配给列的数据类型)被强制转换/转换为各种存储位置。
我建议您做的最好的事情是:
暂时忘记您以前了解的独立数据库数据类型
阅读来自SQLite
网站的上述链接。
获取旧模式中基于类型的类型,并查看它们在SQLite
中的映射
将所有数据迁移到SQLite
数据库。
注意:数据类型限制可能很麻烦,特别是如果您在SQL
中添加时间持续时间、日期或类似的东西。 SQLite
对此类事物提供的内置函数非常少。但是,SQLite
通过sqlite3_create_function
库函数为您提供了一种轻松的方法来创建自己的内置函数以添加时间持续时间和类似的事物。您将使用该功能来替换传统存储过程。
CREATE TABLE T (
N INTEGER CHECK(TYPEOF(N) = 'integer'),
Str TEXT CHECK(TYPEOF(Str) = 'text'),
Dt DATETIME CHECK(JULIANDAY(Dt) IS NOT NULL)
);
但我从不去烦它。
至于每种类型的容量:
TYPEOF
中相同的存储类。因此,尝试插入一个本来会被SQLite转换为NUMERIC / INTEGER存储类的TEXT(即,根据https://www.sqlite.org/datatype3.html#affinity,这种转换是无损的)将失败。换句话说,这种方法比通过插入值然后以某种神奇的方式验证SQLite用于存储该值的存储类的临时方法更加*严格*。对于更宽松的方法,请参见下面的答案。 - eold大部分是为了兼容性而存在的。实际上,您只有整数、浮点数、文本和 blob(二进制大对象)类型可用。日期可以存储为数字(Unix时间为整数,Microsoft时间为浮点数)或文本。
NULL
。该值为一个空值。
INTEGER
。该值为一个有符号整数,根据值的大小,存储在1、2、3、4、6或8个字节中。
REAL
。该值为浮点数,以8字节IEEE浮点数的形式存储。
TEXT
。该值为文本字符串,使用数据库编码(UTF-8、UTF-16BE或UTF-16LE)进行存储。
BLOB
。该值为数据块,完全按输入时的格式进行存储。
作为对dan04的回答的补充,如果您想要盲目插入一个由TEXT
表示但确保文本可以转换为数字的非零NUMERIC
:
your_numeric_col NUMERIC CHECK(abs(your_numeric_col) <> 0)
INSERT INTO table (..., your_numeric_column, ...) VALUES (..., some_string, ...)
如果您使用占位符,这将非常方便,因为您不必特别处理这些非零数字字段。一个使用Python的sqlite3
模块的例子如下:
conn_or_cursor.execute(
"INSERT INTO table VALUES (" + ",".join("?" * num_values) + ")",
str_value_tuple) # no need to convert some from str to int/float
str_value_tuple
中的所有值都将被转义并作为字符串引用。然而,由于我们没有通过 TYPEOF
显式地检查类型,而是只检查了可转换性,因此它仍将按预期工作(即,SQLite将将其存储为数字或以其他方式失败)。
DATE
或BOOLEAN
类型很有用,但我不会费心去区分不同大小的整数。对于INTEGER PRIMARY KEY
的情况尤其如此,这是唯一一个确切的类型名称很重要的情况。 - dan04