Come si progetta uno schema per interrogare in modo efficiente elementi nidificati in un database di valori-chiave?

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

Domanda

Sto usando Mnesia con Erlang, ma questa domanda si applica a qualsiasi valore-chiave db come couchdb, ecc.

Sto cercando di liberarmi dal processo di pensiero RDBMS, ma non ci riesco avvolgo la mia testa su come implementare in modo efficiente questo tipo di schema.

Dire che ho un record utente e che ha molti record SubItemA, che ha molti record del sottoelemento B, quindi:

User
-SubItem A
--SubItem B
...

Devo eseguire query sull'elemento secondario B. È efficace farlo quando lo è questo nidificato? Devo solo normalizzarlo in modo che sia più veloce?

Ho sentito parlare di alcune persone che usano la duplicazione dei dati, quindi i dati sono entrambi annidato e separato, è ridicolo o è davvero utile in alcuni casi?

È stato utile?

Soluzione

La domanda di fondo è: quando il rendimento è abbastanza buono ?

La scansione della tabella del dizionario utente non è eccessiva se si deve davvero esaminare ogni elemento secondario B in dettaglio e la dimensione della B domina la dimensione complessiva del dizionario.

Se ciò non è abbastanza buono, normalizzalo in modo da evitare di leggere in anticipo tutti i dati Utente e Sottomittente A quando esegui una query sul Sotto-oggetto B. Usa una chiave composta come (UserId, SubItemAId, SubItemBId) in il dizionario SubItem B se la tabella è ordinata in modo da poter eseguire query di intervallo.

Se questo uccide totalmente le prestazioni della query dell'utente / oggetto secondario A, considera la duplicazione dei dati come ultima risorsa perché è più soggetta a errori.

Altri suggerimenti

In CouchDb sarebbe banale emettere voci di visualizzazione per ciascuno degli elementi secondari. Ciò ti darebbe un accesso molto rapido a quegli articoli. A seconda di ciò che hai inserito anche nelle voci della vista, potresti probabilmente fornire tutte le informazioni necessarie per il collegamento a documenti / elementi secondari principali.

Non sono sicuro di Mnesia e sto solo iniziando con CouchDB, ma la mia comprensione è che in CouchDB, dal momento che generi i tuoi indici personalizzati (" view "), puoi facilmente creare un indice su questi sotto-elementi.

Una funzione di mappa di esempio:

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)
        }
    }
}

Questa è effettivamente una lista indicizzata di SubItem Bs e quindi puoi tagliare e giuntare da quella lista come preferisci.

In realtà dipende dal database che stai usando, credo. In CouchDB una cosa funzionerà meglio mentre in Mnesia qualcos'altro sarebbe meglio. Dovresti partizionare e suddividere i dati? Su quali criteri dovresti farlo? Quanta duplicazione dei dati è sufficiente?

Come ha detto Jeffery Hantin, ci vorrà un po 'di sperimentazione e analisi per trovare la soluzione giusta. Detto questo, la maggior parte dei database non relazionali disponibili fornisce gli strumenti necessari per risolvere il problema. La tua parte è capire i compromessi di ciascuno e quale compromesso puoi accettare rispetto agli altri.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top