【发布时间】:2012-06-26 21:03:12
【问题描述】:
我正在实施一项服务,其中每个用户都必须拥有自己的 json/文档数据库。除了让用户通过示例查询 json 文档之外,数据库还必须支持涉及多个文档的 ACID 事务,所以我放弃了使用 Couch/Mongo 或其他 NoSQL 数据库(不能使用 RavenDB,因为它必须在 Unix 系统上运行)。
考虑到这一点,我一直试图想办法在 SQL 数据库之上实现它。到目前为止,这是我想出的:
CREATE TABLE documents (
id INTEGER PRIMARY KEY,
doc TEXT
);
CREATE TABLE indexes (
id INTEGER PRIMARY KEY,
property TEXT,
value TEXT,
document_id INTEGER
)
每个用户都有一个包含这两个表的数据库,并且用户必须声明他需要查询哪些字段,以便系统可以正确填充“索引”表。因此,如果用户“A”将其帐户配置为启用按“姓名”和“年龄”进行查询,则每次该用户插入具有“姓名”或“年龄”属性的文档时,系统也会向“索引”插入一条记录表,其中 'property' 列将包含 name/age , 'value' 将包含属性值, 'document_id' 将指向相应的文档。
例如,假设用户插入以下文档:
'{"name" : "Foo", "age" 43}'
这将导致对“文档”表的插入和对“索引”表的另外两个插入:
INSERT INTO documents (id,doc) VALUES (1, '{"name" : "Foo", "age" 43}');
INSERT INTO indexes (property, value, document_id) VALUES ('name', 'foo', 1);
INSERT INTO indexes (property, value, document_id) VALUES ('age', '43', 1);
假设用户“A”向服务发送了以下查询:
'{"name": "Foo", "age": 43}' //(the queries are also json documents).
此查询将被转换为以下 SQL:
SELECT doc FROM documents
WHERE id IN (SELECT document_id FROM indexes
WHERE document_id IN (SELECT document_id FROM indexes
WHERE property = 'name' AND value = 'Foo')
AND property = 'age' AND value = '43')
我的问题:
- 知道用户可能能够在他的查询中使用大量条件(比如说 20-30 个 AND 条件),这会导致子查询嵌套非常高,上面的 SELECT 查询在大多数情况下的效率如何数据库系统(postgres、mysql...)?
- 对于最终将包含数百万/数十亿 json 文档的数据库,上述解决方案是否可行?
- 有没有更好的方法来满足我的要求?
- 是否有可扩展的文档数据库,可以执行涉及多个文档的 ACID 事务并在 Unix 系统上运行?
【问题讨论】:
-
PostgreSQL 9.2 将支持 JSON 数据类型,并且通过一些函数(例如用 JavaScript 编写),上述内容应该是可能的。示例见此处:people.planetpostgresql.org/andrew/index.php?/archives/…
-
看看 CouchDB 是否适合你:“CouchDB 提供 ACID 语义。它通过实现一种多版本并发控制的形式来做到这一点,这意味着 CouchDB 可以处理大量并发读者和作者,而无需冲突。”
-
关于 PostgreSQL 的有趣提示,我去看看,谢谢
-
Dmitriy,CouchDB 仅在单个文档操作上是 ACID
标签: sql database nosql acid document-database