Нужен эффективный способ хранения/запроса json в базе данных SQL

Я реализую сервис, в котором каждый пользователь должен иметь свою собственную базу данных json/document. Помимо предоставления пользователю возможности запрашивать документы 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
)

У каждого пользователя будет база данных с этими двумя таблицами, и пользователь должен будет объявить, какие поля ему нужно запрашивать, чтобы система могла правильно заполнить таблицу «Индексы».Таким образом, если пользователь «А» настраивает свою учетную запись для включения запросов по «имени» и «возрасту», каждый раз, когда этот пользователь вставляет документ со свойством «имя» или «возраст», система также будет вставлять запись в «индексы». таблица, где столбец «свойство» будет содержать имя/возраст, «значение» будет содержать значение свойства, а «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 условий И), что приведет к очень высокой вложенности подзапросов, насколько эффективным будет приведенный выше запрос SELECT для большинства систем баз данных (postgres, mysql...)?
  • Пригодно ли приведенное выше решение для базы данных, которая в конечном итоге будет содержать миллионы/миллиарды документов в формате json?
  • Есть ли лучший способ удовлетворить мои требования?
  • Существует ли масштабируемая база данных документов, которая может выполнять транзакции ACID с участием нескольких документов и работает в системах Unix?
5
задан Thiago de Arruda 25 June 2012 в 15:20
поделиться