¿Cómo diseña un esquema para consultar de manera eficiente los elementos anidados en una base de datos de valores clave?

StackOverflow https://stackoverflow.com/questions/607746

Pregunta

Estoy usando Mnesia con Erlang, pero esta pregunta se aplica a cualquier db de valor clave como couchdb, etc.

Estoy tratando de liberarme del proceso de pensamiento RDBMS, pero no puedo envolver mi cabeza en cómo implementar de manera eficiente este tipo de esquema.

Diga que tengo un registro de usuario y él tiene muchos registros de SubItemA, que tiene muchos registros de Subitema B, por lo que:

User
-SubItem A
--SubItem B
...

Necesito ejecutar consultas en el Subtítulo B. ¿Es eficiente hacerlo cuando está esta anidado? ¿Debería simplemente normalizarlo para que sea más rápido?

He oído hablar de algunas personas que utilizan la duplicación de datos, por lo que los datos son a la vez anidado y separado, ¿es esto ridículo o es realmente útil en ¿algunos casos?

¿Fue útil?

Solución

La pregunta subyacente es: ¿cuándo es el rendimiento suficientemente bueno ?

La exploración de tablas del diccionario del usuario no es una sobrecarga excesiva si realmente necesita examinar cada Subtema B en detalle y el tamaño de las B domina el tamaño general del diccionario.

Si eso no es lo suficientemente bueno, normalícelo para que pueda evitar leer todos los datos del Usuario y el Subtítulo A cuando esté consultando el Subtítulo B. Use una clave compuesta como (UserId, SubItemAId, SubItemBId) en el diccionario de SubItem B si la tabla está ordenada para que pueda hacer consultas de rango.

Si eso destruye totalmente el rendimiento de la consulta de Usuario / Subtítulo A, considere la duplicación de datos como último recurso porque es más propenso a errores.

Otros consejos

En CouchDb, sería trivial emitir entradas de vista para cada uno de los SubItems. Esto le daría un acceso muy rápido a esos artículos. Dependiendo de lo que también coloque en las entradas de la vista, probablemente pueda proporcionar cualquier información que necesite para enlazar con documentos / subelementos principales.

No estoy seguro de Mnesia, y apenas estoy empezando con CouchDB, pero tengo entendido que en CouchDB, ya que genera sus propios índices personalizados ("quot" " views "), puede crear un índice directamente. en esos subelementos.

Una función de mapa de ejemplo:

function(doc) {
    for(var i in doc.subitems_a) {
        var subitem_a = doc.subitems_a[i];

        for(var j in doc.subitems_a[item_a].subitems_b) {
            var subitem_b = subitem_a.subitems_b[j];

            emit(subitem_b, doc)
        }
    }
}

Eso es efectivamente una lista indexada de SubItem Bs y luego puedes cortar y empalmar esa lista como elijas.

En realidad, depende de la base de datos que estés usando, creo. En CouchDB, una cosa funcionará mejor, mientras que en Mnesia otra cosa será mejor. ¿Debes particionar y fragmentar los datos? ¿En qué criterios deberías hacerlo? ¿Cuánta duplicación de datos es suficiente?

Como Jeffery Hantin dijo que tomará un poco de experimentación y análisis para encontrar la solución correcta. Dicho esto, la mayoría de las bases de datos no relacionales que hay por ahí le brindan las herramientas que necesita para resolver el problema. Su parte es determinar las compensaciones de cada una y qué compensación puede aceptar en comparación con las demás.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top