Progettazione di database non relazionali

Sono interessato a conoscere le strategie di progettazione utilizzate con i databasenosql” non relazionali , ovvero la class (per la maggior parte nuova) di archivi dati che non utilizzano la progettazione relazionale tradizionale o SQL (come Hypertable, CouchDB, SimpleDB, datastore di Google App Engine, Voldemort, Cassandra, SQL Data Services, ecc.). Sono anche spesso definiti “negozi chiave / valore”, e alla base si comportano come enormi tabelle hash persistenti distribuite.

Nello specifico, voglio conoscere le differenze nella progettazione concettuale dei dati con questi nuovi database. Cosa è più facile, cosa è più difficile, cosa non si può fare affatto?

Vengo da uno sfondo DB relazionale SQL, quindi la normalizzazione è nel mio sangue. Detto questo, ottengo i vantaggi dei database non relazionali per semplicità e scalabilità, e il mio istinto mi dice che ci deve essere una sovrapposizione più ricca di capacità di progettazione. Cos’hai fatto?

A proposito, ci sono state discussioni StackOverflow su argomenti simili qui:

  • la prossima generazione di database
  • cambiare gli schemi per lavorare con Google App Engine
  • scegliere un database orientato ai documenti

Penso che devi considerare che i DBMS non relazionali differiscono molto per quanto riguarda il loro modello di dati e quindi anche la progettazione concettuale dei dati sarà molto diversa. Nel thread Data Design nei database non relazionali del gruppo NOSQL Google i diversi paradigmi sono categorizzati in questo modo:

  1. Sistemi bigtable (HBase, Hypertable, ecc.)
  2. Negozi a valore-chiave (Tokyo, Voldemort, ecc.)
  3. Database di documenti (CouchDB, MongoDB, ecc.)
  4. Database di grafici (AllegroGraph, Neo4j, Sesame, ecc.)

Sono principalmente nei database di grafici e l’eleganza del data design che utilizza questo paradigma mi ha portato lì, stanco delle carenze di RDBMS . Ho messo alcuni esempi di progettazione di dati usando un database grafico su questa pagina wiki e c’è un esempio di come modellare anche i dati di base del film / attore / ruolo IMDB .

Le diapositive di presentazione (slideshare) Graph Databases e Future of Large-Scale Knowledge Management di Marko Rodriguez contengono un’introduzione molto interessante alla progettazione dei dati utilizzando anche un database grafico.

Rispondere alle domande specifiche da un punto di vista graphdb:

Disegno alternativo: aggiunta di relazioni tra molti diversi tipi di entity framework senza preoccupazioni o la necessità di predefinire quali quadro possono connettersi.

Colmare il divario: tendo a farlo in modo diverso per ogni caso, in base al dominio stesso, poiché non voglio un “grafico orientato alla tabella” e simili. Tuttavia, ecco alcune informazioni sulla traduzione automatica da RDBMS a graphdb.

Modelli di dati espliciti: lo faccio sempre (stile lavagna), quindi utilizzo il modello così come è nel DB.

Miss dal mondo RDBMS: semplici modi per creare report. Aggiornamento: forse non è così difficile creare report da un database grafico, vedere Creazione di un report per un database di esempio Neo4J .

Ho appena iniziato con DB non relazionali e sto ancora cercando di capirlo e di capire quale sarebbe il miglior modello. E posso solo parlare per CouchDB.

Tuttavia, ho alcune conclusioni preliminari:

Hai ideato disegni alternativi che funzionino molto meglio nel mondo non relazionale?

L’attenzione al design si sposta: il design del modello di documento (corrispondente alle tabelle DB) diventa quasi irrilevante, mentre tutto dipende dalla progettazione delle viste (corrispondente alle query).

Il DB del documento sopporta le complessità: SQL ha dati inflessibili e query flessibili, i DB dei documenti sono il contrario.

Il modello CouchDB è una raccolta di “documenti JSON” (tabelle hash fondamentalmente annidate). Ogni documento ha un ID univoco e può essere facilmente recuperato per ID. Per qualsiasi altra query, scrivi “viste”, che sono denominate insiemi di mappe / riduci le funzioni. Le viste restituiscono un set di risultati come un elenco di coppie chiave / valore.

Il trucco è che non si esegue una query nel database nel senso che si esegue una query su un database SQL: i risultati dell’esecuzione delle funzioni di visualizzazione sono memorizzati in un indice e solo l’indice può essere interrogato. (Come “get everything”, “get key” o “get key range”.)

L’analogia più vicina al mondo SQL sarebbe se si potesse interrogare il DB solo usando stored procedure – ogni query che si desidera supportare deve essere predefinita.

Il design dei documenti è enormemente flessibile. Ho trovato solo due vincoli:

  • Mantieni i dati correlati insieme nello stesso documento, poiché non c’è nulla che corrisponda a un join.
  • Non rendere i documenti così grandi da essere aggiornati troppo di frequente (come mettere tutte le vendite dell’azienda per l’anno nello stesso documento), poiché ogni aggiornamento di documenti triggers una reindicizzazione.

Ma tutto dipende dalla progettazione delle viste.

I disegni alternativi ho trovato che gli ordini di grandezza di lavoro migliori con CouchDB rispetto a qualsiasi database SQL sono a livello di sistema piuttosto che a livello di archiviazione. Se si dispone di alcuni dati e si desidera servirli in una pagina Web, la complessità del sistema totale viene ridotta di almeno il 50%:

  • non progettare tabelle DB (problema minore)
  • nessun livello intermedio ODBC / JDBC, tutte le query e le transazioni su http (problema moderato)
  • semplice mapping DB-to-object da JSON, che è quasi banale rispetto alla stessa in SQL (importante!)
  • è ansible saltare l’intero server delle applicazioni, in quanto è ansible progettare i documenti da recuperare direttamente dal browser utilizzando AJAX e aggiungere un po ‘di lucidatura JavaScript prima che vengano visualizzati come HTML. (ENORME!!)

Per le normali webapps, i DB basati su documenti / JSON sono una grande vittoria e gli svantaggi delle query meno flessibili e di alcuni codici aggiuntivi per la convalida dei dati sembrano un piccolo prezzo da pagare.

Hai colpito la testa contro tutto ciò che sembra imansible?

Non ancora. La mappa / riduzione come mezzo per interrogare un database non è familiare e richiede molto più pensiero che scrivere SQL. Esiste un numero abbastanza piccolo di primitive, quindi ottenere i risultati di cui hai bisogno è principalmente una questione di creatività con il modo in cui specifichi le chiavi.

Esiste una limitazione nel fatto che le query non possono guardare contemporaneamente due o più documenti – nessun join o altri tipi di relazioni multi-documento, ma finora nulla è stato insormontabile.

Come limitazione di esempio, i conteggi e le somme sono facili, ma le medie non possono essere calcolate da una vista / query CouchDB. Correzione: restituire sum e contare separatamente e calcolare la media sul client.

Hai colmato il divario con qualsiasi schema di progettazione, ad esempio per tradurre da uno all’altro?

Non sono sicuro che sia fattibile. È più una riprogettazione completa, come la traduzione di un programma di stile funzionale in uno stile orientato agli oggetti. In generale, ci sono molti meno tipi di documenti rispetto alle tabelle SQL e più dati in ogni documento.

Un modo per pensarci è guardare il tuo SQL per inserti e query comuni: quali tabelle e colonne vengono aggiornate quando un cliente effettua un ordine, per esempio? E quali report mensili sulle vendite? Queste informazioni dovrebbero probabilmente andare nello stesso documento.

Ovvero: un documento per ordine, contenente ID cliente e ID prodotto, con i campi replicati necessari per semplificare le query. Tutto ciò che è contenuto in un documento può essere interrogato facilmente, tutto ciò che richiede un riferimento incrociato tra l’Ordine e il Cliente deve essere fatto dal cliente. Quindi, se vuoi un rapporto sulle vendite per regione, dovresti probabilmente inserire un codice regionale nell’ordine.

Realizzate persino modelli di dati espliciti (es. In UML)?

Scusa, mai fatto molto UML prima dei DB dei documenti 🙂

Ma hai bisogno di una sorta di modello che dica quali campi appartengono a quali documenti e quali tipi di valori contengono. Entrambi per il tuo riferimento in seguito e per assicurarti che everybod che utilizza il DB conosca le convenzioni. Dal momento che non si ottiene più un errore se si memorizza una data in un campo di testo, ad esempio, e chiunque può aggiungere o rimuovere qualsiasi campo che vogliano, è necessario sia il codice di convalida che le convenzioni per riprendere il gioco. Soprattutto se lavori con risorse esterne.

Ti manca uno dei principali servizi extra forniti da RDBMS?

No. Ma il mio background è sviluppatore di applicazioni web, ci occupiamo solo di database nella misura in cui dobbiamo 🙂

Una società per la quale avevo lavorato produceva un prodotto (una webapp) progettato per essere eseguito su database SQL di più fornitori e i “servizi extra” sono così diversi da DB a DB che devono essere implementati separatamente per ogni DB. Quindi è stato meno utile per noi spostare la funzionalità all’esterno dell’RDBMS. Ciò è stato esteso anche alla ricerca full-text.

Quindi qualunque cosa mi arrendo è qualcosa che non ho mai avuto in primo luogo. Ovviamente, la tua esperienza potrebbe essere diversa.


Un avvertimento: ciò su cui sto lavorando ora è una webapp per dati finanziari, quotazioni azionarie e simili. Questa è un’ottima corrispondenza per un DB di documenti, dal mio punto di vista ottengo tutti i vantaggi di un DB (persistenza e query) senza problemi.

Ma questi dati sono abbastanza indipendenti l’uno dall’altro, non ci sono query relazionali complesse. Ottieni le ultime quotazioni per ticker, ottieni quotazioni per ticker e intervallo di date, ottieni meta-informazioni aziendali, è praticamente tutto. Un altro esempio che ho visto è stato un’applicazione per blog, e i blog non sono caratterizzati da schemi di database estremamente complicati.

Quello che sto cercando di dire è che tutte le applicazioni di successo dei DB di documenti che conosco sono state con dati che non avevano molte interrelazioni in primo luogo: Documenti (come in Ricerca Google), post di blog, articoli di notizie, dati finanziari .

Mi aspetto che ci siano dataset che si adattino meglio a SQL rispetto al modello di documento, quindi immagino che SQL sopravviverà.

Ma per quelli di noi che vogliono solo un modo semplice per archiviare e recuperare i dati – e sospetto che ci siano molti di noi – i database di documenti (come in CouchDB) sono una manna dal cielo.

Sto rispondendo a questo con CouchDB nel retro della mia mente, ma presumerei che la maggior parte sarebbe vera anche per altri DB. Abbiamo esaminato l’uso di CouchDB, ma alla fine abbiamo deciso di non accettarlo poiché il nostro accesso ai dati non è noto in anticipo e la scalabilità non è il problema.

Più forte:

  • Riesce a ripensare a livello concettuale, quindi è “più difficile” dal momento che è solo diverso. Poiché devi conoscere in anticipo i tuoi pattern di accesso ai dati, non è ansible applicare la traduzione automatica. Dovresti aggiungere almeno il modello di accesso.
  • La coerenza non viene gestita dal database ma deve essere gestita nell’applicazione. Meno garanzie significa migrazione più semplice, fail-over e una migliore scalabilità al costo di un’applicazione più complicata. Un’applicazione deve gestire conflitti e incongruenze.
  • I collegamenti che attraversano documenti (o chiave / valore) devono essere trattati anche a livello di applicazione.
  • I database SQL hanno IDE molto più maturi. Si ottengono molte librerie di supporto (anche se la stratificazione di quelle librerie rende le cose molto più complesse del necessario per SQL).

Più facile:

  • Più veloce se conosci i tuoi pattern di accesso ai dati.
  • La migrazione / Failover è più facile per il database poiché non vengono fatte promesse come programmatore di applicazioni. Sebbene tu abbia una consistenza finale. Probabilmente. Finalmente. A volte.
  • Una chiave / valore è molto più facile da capire di una riga da un tavolo. Tutte le relazioni (albero) sono già presenti e gli oggetti completi possono essere riconosciuti.

La modellazione dovrebbe essere pressappoco la stessa, ma bisogna fare attenzione a ciò che si mette in un documento: UML può anche essere usato sia per la modellazione OO che per la modellazione DB, che sono già due bestie diverse.

Mi sarebbe piaciuto vedere un buon database OO aperto ben integrato con C # / Silverlight. Giusto per rendere la scelta ancora più difficile. 🙂

I file flat sono stati a lungo considerati arcani e poco pratici per un insieme di dati di qualsiasi dimensione. Tuttavia, i computer più veloci con più memoria consentono di caricare un file in memoria e di ordinarlo in tempo reale, almeno per applicazioni N singolo e locali con un singolo utente ragionevolmente piccole.

Ad esempio, in genere puoi leggere un file di 10.000 record E ordinarlo su un campo in meno di mezzo secondo, un tempo di risposta accettabile.

Naturalmente, ci sono dei motivi per utilizzare un database invece di un file flat: operazioni relazionali, integrità dei dati, capacità multiutente, accesso remoto, maggiore capacità, standardizzazione, ecc. Ma maggiore velocità del computer e capacità di memoria hanno reso la manipolazione in memoria di dati più pratici in alcuni casi.

I database relazionali che vedo nella vita reale tendono a non essere affatto ben normalizzati, contrariamente a quanto sostenuto. Quando richiesto, i progettisti mi dicono che è principalmente a causa delle prestazioni. Gli RDBM non sono adatti a unirsi, quindi le tabelle tendono ad essere troppo larghe rispetto al punto di vista della normalizzazione. I database orientati agli oggetti tendono ad essere molto più efficaci in questo.

Un altro punto in cui gli RDBM hanno problemi è la gestione delle chiavi cronologiche / dipendenti dal tempo.