2010-11-06 8 views
12

En mi búsqueda para entender a Mnesia, todavía lucho con el pensamiento en términos relacionales. Así que voy a poner mi lucha aquí y pedir la mejor manera de resolverlos.Ayúdame a entender el modelado de mnesia (NoSQL)

uno-a-muchos de relaciones decir que tengo un montón de gente,

-record(contact, {name, phone}). 

Ahora, sé que puedo definir el teléfono para ser salvo siempre como una lista, por lo que la gente puede tener varios números de teléfono, y supongo que esa es la manera de hacerlo (¿es así? ¿Cómo buscaría esto al revés, digamos, encontrar un nombre para un número?). .

muchos-a-muchos de relaciones Supongamos ahora tengo varios grupos que puedo poner a las personas en Los nombres de los grupos no tienen ningún significado, no son más que nombres; el concepto es "grupos de sistemas de Unix" o "etiquetas". Ingenuamente, me gustaría modelar esta pertenencia como proplist, como

{groups [{friends, bool()}, {family, bool()}, {work, bool()}]} %% and so on... 

como un campo dentro del "contacto" registro desde arriba, por ejemplo. ¿Cuál es la mejor manera de modelar esto dentro de mnesia si quiero poder buscar rápidamente todos los miembros de un grupo según el nombre del grupo y también quiero poder buscar todo el grupo en el que está registrada una persona? También podría modelar esto como una lista que contiene solo los identificadores de grupo, por supuesto. Para usar con mnesia, , ¿cuál es la mejor manera de modelar esto?

Me disculpo si esta pregunta es tonta. Hay mucha documentación sobre mnesia, pero le faltan (IMO) algunos buenos ejemplos para el uso general.

+1

No hay necesidad de disculparse En mi humilde opinión, la pregunta no es tonto en absoluto +1 para que –

Respuesta

3

Para el primer ejemplo, considere este registro:

-record(contact, {name, [phonenumber, phonenumber, ...]}). 

contact es un registro con dos campos, y namephone donde el teléfono es una lista de números de teléfono.Como user425720 dijo que podría tener sentido almacenar esto como algo más que cadenas, por ejemplo, si tiene requisitos extremos para una pequeña huella de almacenamiento.

Ahora aquí viene la parte que es difícil de "obtener" con tiendas clave-valor: también es necesario almacenar la relación inversa. En otras palabras, se necesita algo similar a lo siguiente:

-record(phone, {phonenumber, contactname}). 

Si usted tiene una capa en su aplicación para abstraer el manejo de base de datos, se puede hacer siempre añadir/cambiar los registros telefónicos al añadir/cambiar un contacto .

-

Para el segundo ejemplo, considere estos dos registros:

-record(contact, {uuid, name, [group_id, group_id]}). 
-record(group, {uuid, name, [contact_id, contact_id]}). 

La forma más fácil es simplemente almacenar los identificadores que apunten a los registros relacionados. Dado que Mnesia no tiene ningún concepto de integridad referencial, puede perder sincronía si, por ejemplo, elimina un grupo sin eliminar ese grupo de todos los usuarios.

Si necesita almacenar el tipo de grupo en el registro de contacto, puede utilizar el siguiente:

-record(contact, {name, [{family, [group_id, group_id]}, {work, [..]}]}). 

-

Su segundo problema también podría ser resuelto mediante el uso de un registro intermedio, que puedes pensar como "membresía".

-record(contact, {uuid, name, ...}). 
-record(group, {uuid, name, ...}). 
-record(membership, {contact_uuid, group_uuid}). # must use 'bag' table type 

Puede haber cualquier cantidad de registros de "membresía". Habrá un registro para cada grupo de usuarios.

+0

Aceptaré esta respuesta. Gracias. –

-1

Antes que nada, solicite los patrones de diseño de la tienda clave-valor. Perfectamente bien. Antes de intentar responder a su pregunta, dejemos en claro: ¿qué es Mnesia? Es k-v DB, que se incluye en OTP. Debido a que es nativo, es muy cómodo de usar de Erlang. Pero ten cuidado. Esta es una base de datos antigua con supuestos muy antiguos (por ejemplo, distribución de datos con hashing lineal). Así que adelante, aprenda y juegue con él, pero para la producción, tómese su tiempo y explore la tienda NoSQL para encontrar lo mejor para sus necesidades.

ejemplo de teléfono. No guarde cosas como cadenas (list()) - es muy pesado para GC. Haría campos de pareja como phone_1 :: < < binary>>, phone_2 :: < < binary>>, phone_extra :: [< < binary>>] e índice de compilación en el campo de consulta más frecuente. Además, las indicaciones de mnesia son complicadas: cuando un nodo se cuelga y sube, necesitan reconstruirse (puede llevar mucho tiempo).

@family example. Es bastante difícil con el espacio de nombres plano. Puede jugar con claves más complejas. ¿Tal vez crear una tabla separada para TheGroup y conservar los identificadores de los miembros? O cada miembro tendría identificaciones de grupos a los que pertenece (difícil de mantener ...). Si desea reconocer a los amigos, implementaría algún tipo de contrato antes de presentar los datos (A es amigo de B si B es amigo de A); este enfoque podría hacer frente a la eventual consistencia y conflictos en los datos.

+0

heh, tal vez algún comentario antes de este voto a favor? – user425720

+0

Si bien no te voté negativamente, me parece claro que no obtuviste lo que estaba preguntando en la segunda pregunta (o no lo dejé en claro). Quiero modelar relaciones de muchos a muchos; "familia" y "amigos" no se referían a ningún concepto en particular. También ya señalé que las listas con los miembros son una forma, pero me pidieron una mejor manera. –

+0

sí, nev. Sin embargo, su ejemplo de tupla parece ser lo que escribo en la segunda parte. La primera parte dice modelar muchos a muchos como una tabla separada que contiene las claves de los miembros. Depende de DB. En Riak hay una estructura de clave de 2 niveles (cubo, clave) - (valor) por lo que puede tener todos los miembros del grupo en un cubo. Por definición, las tiendas KV no son buenas para representar relaciones. – user425720

Cuestiones relacionadas