2009-12-23 18 views
12

Soy nuevo en CouchDB y me entero de ello. No encontré el soporte de CouchDB para la integridad referencial. ¿Podemos crear una clave foránea para un campo en el documento CouchDB?¿CouchDB es compatible con la integridad referencial?

Por ej. ¿Es posible garantizar que el nombre de un proveedor utilizado en un documento de pedido esté disponible en la base de datos del proveedor?

¿Soporta CouchDB integridad referencial? ¿Y es posible crear un campo en un documento como clave principal?

Respuesta

11

No, CouchDB no hace claves externas como tales, por lo que no puede tener que manejar la integridad referencial del sistema para usted. Debería controlar los proveedores en el nivel de la aplicación.

En cuanto a si puede hacer que un campo sea una clave principal, la clave principal es el campo _id, pero puede usar cualquier json válida como clave para las vistas en el archivo db. Entonces, por ejemplo, podría crear una vista de pedidos con su proveedor como la clave.

algo así como

function(doc) { 
    if (doc.type == 'order') 
    emit(doc.vendor,doc); 
} 

sería agarrar todos los documentos en la base de datos que tiene un atributo type con el orden de valores y añadirlos a una vista con su proveedor como la clave.

Intro to CouchDB views

8

Estas preguntas son de base de datos relacional muy específica.

En CouchDB, o cualquier otro no RDBMS, no almacenaría sus datos de la misma manera que lo haría en un RDBMS, por lo que diseñar la relación de esta manera puede no ser el mejor. Pero, solo para darle una idea de cómo podría hacerlo, supongamos que tiene un documento para un proveedor y un montón de documentos para pedidos que necesitan "relacionarse" con el documento del proveedor.

No hay claves principales, los documentos tienen un _id que es un uuid. Si tiene un documento para un proveedor y está creando un documento nuevo para algo similar a un pedido, puede hacer referencia al _id del documento del proveedor.

{"type":"order","vendor-id":"asd7d7f6ds76f7d7s"} 

Para consultar todos los pedidos de un proveedor particular que le tienes un mapa de vista algo como:

function(doc) { if (doc.type == 'order') {emit(doc['vendor-id'], doc)}} 

_ID documento no va a cambiar, por lo que no es "integridad" allí, incluso si cambie otros atributos en el documento del proveedor, como su nombre o información de facturación. Si inserta el nombre del proveedor u otros atributos del documento del proveedor directamente en el documento de pedido, necesitará escribir un script si alguna vez quisiera cambiarlos a granel.

Espero que ayude un poco.

+2

La integridad referencial es Do-it-yourself, en otras palabras. El programador debe recordar crear el documento del proveedor primero, luego escribir los elementos que hacen referencia a su ** _ id **, porque CouchDB no puede imponer eso para ellos. De manera similar, el programador luego de la eliminación debe recordarse a sí mismo para eliminar primero los pedidos asociados con un proveedor antes de eliminar al proveedor: CouchDB no hará eso por ellos. Así que CouchDB te permitirá entrar constantemente en estados inconsistentes; no hay soporte para la protección contra esto. –

+0

No llamaría a un documento colgante sin referencia a él un "estado incoherente" ya que el estado en este caso es la referencia del otro documento que se eliminaría. Pero su caracterización de la semántica aquí es precisa. Las referencias son solo índices y eliminar un documento no implica una transacción más grande que borrará la referencia anterior, aunque limpiaría la referencia directa. – mikeal

+0

Lo que es más importante, un servidor couchdb tiene la capacidad REST-3 (y puede construir la capacidad REST-4 si lo desea con los documentos de diseño). Aplicar el término "integridad referencial" no tiene más sentido para una base de datos documental que para un videojuego. No es una base de datos relacional y no pretende serlo. –

0

Aunque no es posible crear una restricción FK, es posible utilizar Validate función de sofá

function(newDoc, oldDoc, userCtx, secObj) { 
    if(newDoc && newDoc.type) switch(newDoc.type){ 
     case 'fish': 
      var allSpecies = ['trout','goldfish']; 
      if(!allSpecies.contains(newDoc.species)){ 
       throw({forbidden : 'fish must be of a know species'}); 
      } 
      break; 
     case 'mammals': 
      if(!['M','F'].contains(newDoc.sex)){ 
       throw({forbidden : 'mammals must have their sex listed'}); 
      } 
      break; 
    } 
} 

Ahora, si una persona realmente inteligente (no soy), que podrían hacer una llamada a la DB mismo para la lista de especies ... que sería una clave foránea.

También es posible que desee leer sobre: ​​ How do I DRY up my CouchDB views?

Cuestiones relacionadas