2011-11-19 166 views
11

Digamos que tengo una colección de documentos tales como:Cómo aplicar claves foráneas en bases de datos NoSql (MongoDB)?

{ "_id" : 0 , "owner":0 "name":"Doc1"},{ "_id" : 1 , "owner":1, "name":"Doc1"}, etc 

Y, por otra parte, los propietarios están representados como la recogida selectiva:

{ "_id" : 0 , "username":"John"}, { "_id" : 1 , "username":"Sam"} 

¿Cómo puedo estar seguro de que, cuando se Inserté un documento que hace referencia al usuario de forma correcta. En RDBMS de la vieja escuela esto podría hacerse fácilmente usando una clave externa.

Sé que puedo verificar la corrección de la inserción de mi código comercial, PERO, ¿qué sucede si un atacante altera mi solicitud al servidor y coloca "owner": 100 y Mongo no devuelve ninguna excepción.

Me gustaría saber cómo debe manejarse esta situación en una aplicación de palabras reales.

¡Gracias de antemano!

+1

Si un atacante podría alterar su solicitud, ¿qué le hace pensar que no podrían alterar la excepción que responde? – deed02392

Respuesta

12

MongoDB no tiene claves externas (como presumiblemente ha notado). Fundamentalmente, la respuesta es, por lo tanto, "No permita que los usuarios manipulen las solicitudes. Solo permita que la aplicación inserte datos que sigan sus reglas de integridad referencial".

MongoDB es genial en muchos aspectos ... pero si encuentra que necesita claves externas, entonces probablemente no sea la solución correcta a su problema.

13

Para responder a su pregunta específica, mientras que MongoDB fomenta el manejo de las relaciones de clave externa en el lado del cliente, también proporcionan la idea de "Referencias de bases de datos" - Consulte this help page.

Dicho esto, No recomiendo usar un DBRef. O bien, permita que su código de cliente administre las asociaciones o (mejor aún) vincule los documentos desde el principio. Es posible que desee considerar incrustar los "documentos" del propietario dentro del propio objeto propietario. Arme sus documentos para que coincidan con sus patrones de uso y MongoDB brillará.

+0

+1 para obtener una pista sobre cómo reestructurar para evitar este problema. – deed02392

0

También recomendaría que si el nombre de usuario es único, utilícelos como _id. Ahorrará en un índice. En el documento que se está almacenando, establezca el valor de 'propietario' en la aplicación como el valor de 'nombre de usuario' cuando se crea el documento y nunca permita que ningún otro elemento de código lo actualice.

Si existen requisitos para cambiar el propietario, proporcione las API apropiatorias con las reglas empresariales implementadas.

No habrá necesidad de llaves foráneas.

+1

Excepto que si hace esto, si un usuario desea cambiar su nombre de usuario, debe eliminar el registro existente y luego insertar uno nuevo con el nombre de usuario modificado. –

0

Si alguien realmente quiere hacer cumplir las claves externas en el proyecto/aplicación web. Entonces debería hacerlo con un enfoque MixSQL, es decir, SQL + NoSQL

Preferiría que los datos voluminosos que no tienen tantas referencias puedan almacenarse en la base de datos NoSQL. Me gusta: tipo de datos de hoteles o lugares.

Pero si hay algunas cosas serias como los módulos OAuth Tablas, TokenStore y UserDetails y UserRole (Mapping Table) etc ... entonces puede ir con SQL.

0

Como solución NoSQL, puede utilizar MariaDB (NewSQL) Es una combinación de SQL y NoSQL e implementada por los desarrolladores de MySQL con un gran rendimiento.

0

Esta es una relación de uno a uno. Es mejor insertar un documento en otro, en lugar de mantener colecciones separadas. Consulte here sobre cómo modelarlos en mongodb y sus ventajas.

Aunque no se menciona explícitamente en los documentos, la incrustación le da el mismo efecto que las restricciones de clave externa. Solo quiero aclarar esta idea. Cuando se tienen dos colecciones como que:

C1:

{ "_id" : 0 , "owner":0 "name":"Doc1"},{ "_id" : 1 , "owner":1, "name":"Doc1"}, etc 

C2:

{ "_id" : 0 , "username":"John"}, { "_id" : 1 , "username":"Sam"} 

Y si tuviera que declarar la restricción de clave externa en C2._id para hacer referencia C1._id (suponiendo MongoDB lo permite) , significaría que no puede insertar un documento en C2 donde C2._id no existe en C1. Compárese esto con un documento incrustado:

{ 
    "_id" : 0 , 
    "owner" : 0, 
    "name" : "Doc1", 
    "owner_details" : { 
     "username" : "John" 
    } 
} 

Ahora el campo owner_details representa los datos de la colección C2, y los campos restantes representan los datos de C1. No puede agregar un campo owner_details a un documento inexistente. Básicamente estás logrando el mismo efecto.

Cuestiones relacionadas