Estoy implementando un servicio donde cada usuario debe tener su propia base de datos json/documento. Más allá de dejar que el usuario consulte documentos json por ejemplo, la base de datos también debe admitir transacciones ACID que involucren múltiples documentos, por lo que me he descartado usando Couch/Mongo u otras bases de datos NoSQL (no puedo usar RavenDB ya que debe ejecutarse en sistemas Unix).Necesito una forma eficiente de almacenar/consultar json en una base de datos SQL
Con esto en mente, he estado tratando de encontrar una forma de implementar eso encima de una base de datos SQL. Esto es lo que he ocurrió hasta el momento:
CREATE TABLE documents (
id INTEGER PRIMARY KEY,
doc TEXT
);
CREATE TABLE indexes (
id INTEGER PRIMARY KEY,
property TEXT,
value TEXT,
document_id INTEGER
)
Cada usuario tendrá una base de datos con estas dos tablas, y el usuario tendría que declarar qué campos que necesitaba para consultar lo que el sistema podría llenar adecuadamente los 'Índices ' mesa. Entonces, si el usuario 'A' configura su cuenta para habilitar las consultas por 'nombre' y 'edad', cada vez que el usuario inserte un documento que tenga una propiedad 'nombre' o 'edad' el sistema también insertará un registro en los 'índices' tabla, donde la columna 'propiedad' contendría nombre/edad, 'valor' contendría el valor de la propiedad y 'documento_id' apuntaría al documento correspondiente.
Por ejemplo, digamos que el usuario inserta el siguiente documento:
'{"name" : "Foo", "age" 43}'
Esto daría lugar a un inserto de la mesa 'documentos' y dos insertos más a la mesa 'índices':
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);
Entonces digamos que el usuario 'A' envió el servicio la siguiente consulta:
'{"name": "Foo", "age": 43}' //(the queries are also json documents).
esta consulta traducirse a la siguiente 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')
Mis preguntas:
- sabiendo que el usuario puede ser capaz de utilizar un gran número de condiciones en sus consultas (digamos 20-30 y condiciones), lo que haría que la anotación de la subconsulta sea muy alta, ¿cuán eficiente sería la consulta SELECT anterior en la mayoría de los sistemas de bases de datos (postgres, mysql ...)?
- ¿La solución anterior es viable para una base de datos que finalmente contendrá millones/miles de millones de documentos json?
- ¿Existe alguna manera mejor de cumplir con mis requisitos?
- ¿Existe una base de datos de documentos escalable que pueda realizar transacciones ACID que involucren varios documentos y se ejecute en sistemas Unix?
PostgreSQL 9.2 apoyará un tipo de datos JSON y con algunas funciones (por ejemplo, escritas en JavaScript) Lo anterior debería ser posible. Vea aquí un ejemplo: http://people.planetpostgresql.org/andrew/index.php?/archives/249-Using-PLV8-to-index-JSON.html –
ver si CouchDB funcionará para usted: "CouchDB ofrece Semántica ÁCIDA. Hace esto implementando una forma de Control de Simultaneidad de Versiones Múltiples, lo que significa que CouchDB puede manejar un gran volumen de lectores y escritores simultáneos sin conflicto ". –
dato interesante acerca de PostgreSQL, voy a echarle un vistazo, gracias –