是否可以在 SQLite 中存储和查询 JSON?

tux*_*xlu 51 sqlite json

我需要将 JSON 对象存储在 SQLite 数据库中,然后对其进行复杂的查询。

我做了一个这样的表:

+--------------------------------------+
|document |  property | string | number|
+--------------------------------------+
|foo      |  "title"  | "test" |       | 
+--------------------------------------+
|foo      |  "id"     |        |  42   | 
+--------------------------------------+
|bar      |  "id"     |        |  43   | 
+--------------------------------------+
Run Code Online (Sandbox Code Playgroud)

对于两个对象

foo {"title": "test", "id": 42} 
bar {id: 43}
Run Code Online (Sandbox Code Playgroud)

但我不能做“AND”查询,比如:

SELECT DISTINCT id  FROM table WHERE title = "test" AND id = 42 
Run Code Online (Sandbox Code Playgroud)

如您所见,“WHERE”之后的部分完全是胡说八道,但我不知道如何创建一个可以做我想做的查询。

那么您认为有更好的方法来存储我的数据,还是有一种解决方法来执行“AND”查询?

当然,JSON 可以包含任何属性,因此我无法为每个属性创建一个包含列的表。

我正在使用 WebSQL,它是没有扩展的 SQLite。

我知道我的问题很具体,但你能帮我吗?

The*_*ist 52

SQLite 3.9 引入了一个新的扩展 ( JSON1 ),它允许您轻松地处理 JSON 数据。

此外,它还引入了对表达式索引的支持,这(在我的理解中)应该允许您在 JSON 数据上定义索引。


小智 10

PostgreSQL 有一些很好的 JSON 存储特性。您可以通过执行选择 JSON 值

SELECT DISTINCT FROM TABLE WHERE foo->title=test AND id=42
Run Code Online (Sandbox Code Playgroud)

如果您使用该jsonb类型,您还可以索引 JSON 对象上的特定键。

  • 不回答 OP 问题...不是关于 PG (10认同)
  • 在 2020 年以后的这些日子里,Sqlite3 中是否有与此等效的 1:1? (3认同)
  • @NickSweeting 2022 年 `->` 和 `->>` 运算符在 sqlite 中工作 https://www.sqlite.org/json1.html#jptr `select foo->'title' from atable` (2认同)

小智 6

对此的现有答案实际上是将 OP 的数据存储为 JSON(这可能是解决其潜在问题的更好解决方案)。

但是,实际问题是如何根据多个属性在提供的 EAV 样式表中获取查找文档。所以,也许这个问题的答案会有用。

执行您所说的标准 SQL 方法是 INTERSECTION。

(SELECT document FROM table WHERE property="id" AND number=43)
INTERSECTION 
(SELECT document FROM table WHERE property="title" AND string="test")
Run Code Online (Sandbox Code Playgroud)

如果您愿意,也可以使用自联接来执行此操作。

SELECT t1.document
FROM table as t1, table as t2
WHERE t1.document = t2.document
AND t1.property="id" AND t1.number=43
AND t2.property="title" AND t2.string="test"
Run Code Online (Sandbox Code Playgroud)

当然,更“正确”且可以说是最有效的方法是为您需要的每个属性创建一列,例如“id”和“title”。