SQLITE3 将文本和数字存储在同一列中

标签 sqlite

在 SQLITE3 文档中您可以找到:

“SQLite 使用更通用的动态类型系统。在 SQLite 中,值的数据类型与值本身相关联,而不是与其容器相关联。SQLite 的动态类型系统向后兼容更常见的静态类型系统其他数据库引擎,从某种意义上说,在静态类型数据库上工作的 SQL 语句在 SQLite 中应该以相同的方式工作。但是,SQLite 中的动态类型允许它执行传统严格类型数据库中不可能完成的操作。”

我有一列包含不同的值,有些是整数,有些是 float ,有些是文本。我使用 BLOB 存储类并且工作正常。但我对这个解决方案有点怀疑。这是将数字和文本存储在同一列中的正确方法吗?

最佳答案

TLDR;你没有做错,但我也认为你没有做你认为自己正在做的事情。

我认为您使用的不是 BLOB 存储类,而是 BLOB 类型关联。 In SQLite there are 2 concepts of datatype 。存储类别和类型关联性。

存储类是给定值在内存中存储的方式,它描述了位模式如何表示值。例如。虽然在数值上相等,但整数 1 和浮点 1.0 由非常不同的位模式表示(至少在内存中,但奇怪的是“作为内部优化,没有小数分量并存储在具有 REAL 亲和性的列中的小浮点值是作为整数写入磁盘”)。 有 5 种存储类别:NULL、INTEGER、REAL、TEXT 和 BLOB。

另一方面,类型关联不是一个值,而是一个列级概念。类型亲和性是给定列的一个特征。还有 5 种类型关联:NUMBER、INTEGER、REAL、TEXT 和 BLOB。

您可能注意到的第一件事是,存储类和关联性之间不存在 1-1 映射。那是因为它们确实几乎完全不相关。考虑以下因素

sqlite> CREATE TABLE Test(A TEXT, B BLOB, C REAL);
sqlite> INSERT INTO Test VALUES ('text', 'also a text', 'another one');
sqlite> INSERT INTO Test VALUES (10, 10.1, 10.11111111111111111111111);
sqlite> SELECT A, TYPEOF(A), B, TYPEOF(B), C, TYPEOF(C) FROM Test;
text|text|also a text|text|another one|text
10|text|10.1|real|10.1111111111111|real

如您所见,我定义了 TEXT、BLOB 和 REAL 类型的列。 Those are the affinities 。但我能够将不同类型的值插入其中,无论它们的相似性如何。例如。现在,C 列既存储存储类 TEXT 的“另一个”,也存储存储类 REAL 的 10.1111111111111。

通常你不应该太关心存储类,正如你从我的例子中看到的,SQLite只是自动地、正确地从我插入的数据中推断出它们。 类型亲和性更重要。这描述了如何比较、排序数据以及如何确定数据的唯一性。例如

sqlite> CREATE Table T(A TEXT);
sqlite> INSERT INTO T VALUES ('1'), (2), (0.0);
sqlite> SELECT * FROM T ORDER BY A ASC;
0.0
1
2
sqlite> CREATE TABLE R(A REAL);
sqlite> INSERT INTO R VALUES ('1'), (2), (0.0);
sqlite> SELECT * FROM R ORDER BY A ASC;
0.0
1.0
2.0
sqlite> CREATE TABLE B(A BLOB);
sqlite> INSERT INTO B VALUES ('1'), (2), (0.0);
sqlite> SELECT * FROM B ORDER BY A ASC;
0.0
2
1

因此,出于实际目的,它与您对数据类型的直观想法更密切相关。考虑您的数据意味着什么,并相应地选择关联性。如果将值存储在 BLOB 亲和性列中,则会对它们使用按位比较。如果这就是你想要的,那就去做吧。但是,如果您想要进行字典顺序比较,则需要 TEXT 亲和性,或者如果您想根据数据表示的数值进行比较,那么例如真实。

关于SQLITE3 将文本和数字存储在同一列中,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53117756/

相关文章:

android - Greendao:如何更新多实体

python - 当其中一行匹配条件时如何返回数据库实体的总计数

database - sqlite3 从空表中选择 = 不选择?

递归调用Android sqlite getdatabase

ruby-on-rails - 推送到heroku,sqlite3时出现Ruby on Rails错误

php - 使用 sqlite 的 PDO 不会插入任何内容

python - Python Peewee 中同一张表的外键

python - 如何对字段值的每个给定增量进行 GROUP BY?

database-design - 我应该担心 sqlite 文件大小吗?

iPhone Dev - 尝试按顺序访问 sqlite3 表的每一行