Progettazione di database non relazionali [chiuso]


114

Mi interessa conoscere le strategie di progettazione che hai utilizzato con i database "nosql" non relazionali , ovvero la classe (per lo più nuova) di archivi dati che non utilizza la progettazione relazionale tradizionale o SQL (come Hypertable, CouchDB, SimpleDB, datastore di Google App Engine, Voldemort, Cassandra, SQL Data Services, ecc.). Sono anche spesso denominati "archivi chiave / valore" e alla base si comportano come tabelle hash persistenti distribuite giganti.

In particolare, desidero conoscere le differenze nella progettazione dei dati concettuali con questi nuovi database. Cosa è più facile, cosa è più difficile, cosa non si può fare affatto?

  • Hai escogitato progetti alternativi che funzionano molto meglio nel mondo non relazionale?

  • Hai sbattuto la testa contro qualcosa che sembra impossibile?

  • Hai colmato il divario con qualsiasi modello di progettazione, ad esempio per tradurre dall'uno all'altro?

  • Realizzi anche modelli di dati espliciti ora (ad esempio in UML) o li hai abbandonati completamente a favore di blob di dati semi-strutturati / orientati ai documenti?

  • Ti manca qualcuno dei principali servizi extra forniti dagli RDBMS, come integrità relazionale, supporto per transazioni arbitrariamente complesse, trigger, ecc.?

Vengo da un background 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 deve esserci una più ricca sovrapposizione di funzionalità di progettazione. Cos'hai fatto?

Cordiali saluti, ci sono state discussioni StackOverflow su argomenti simili qui:


2
database chiave / valore la vecchia cosa nuova.
Christopher,

1
Per chiunque sia interessato a uber, c'è una lunga discussione in corso sul gruppo Google NoSQL, qui: groups.google.com/group/nosql-discussion/browse_thread/thread/…
Ian Varley,

4
Cordiali saluti, ho scritto un rapporto di lunga durata su questo argomento, qui: google.com/url?sa=D&q=http://ianvarley.com/UT/MR/… Grazie a tutti voi per il vostro utile contributo!
Ian Varley

Risposte:


55

Penso che si debba considerare che i DBMS non relazionali differiscono molto per quanto riguarda il loro modello di dati e quindi anche il design concettuale dei dati sarà molto diverso. Nel thread Data Design in Non-Relational Databases del gruppo NOSQL Google i diversi paradigmi sono classificati in questo modo:

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

Mi piacciono principalmente i database a grafo e l'eleganza del design dei dati utilizzando questo paradigma è stato ciò che mi ha portato lì, stanco delle carenze di RDBMS . Ho messo alcuni esempi di progettazione dei dati utilizzando un database a grafo in questa pagina wiki e c'è anche un esempio di come modellare i dati di base di film / attore / ruolo IMDB .

Le diapositive di presentazione (slideshare) Database di grafici e il futuro della gestione della conoscenza su larga scala di Marko Rodriguez contengono una bella introduzione alla progettazione dei dati utilizzando anche un database di grafici.

Rispondere alle domande specifiche dal punto di vista di graphdb:

Progettazione alternativa: aggiunta di relazioni tra molti tipi diversi di entità senza preoccupazioni o la necessità di predefinire quali entità 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: li faccio sempre (stile lavagna), quindi utilizzo il modello così com'è anche nel DB.

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


79

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

Tuttavia, ho alcune conclusioni preliminari:

Hai escogitato progetti alternativi che funzionano molto meglio nel mondo non relazionale?

Il focus del design si sposta: il design del modello del documento (corrispondente alle tabelle DB) diventa quasi irrilevante, mentre tutto dipende dalla progettazione delle viste (corrispondenti alle query).

Il tipo di DB dei documenti scambia le complessità: SQL ha dati non flessibili e query flessibili, i DB dei documenti sono il contrario.

Il modello CouchDB è una raccolta di "documenti JSON" (fondamentalmente tabelle hash annidate). Ogni documento ha un ID univoco e può essere facilmente recuperato tramite ID. Per qualsiasi altra query, scrivi "viste", che sono insiemi denominati di funzioni di mappatura / riduzione. Le visualizzazioni restituiscono un set di risultati come un elenco di coppie chiave / valore.

Il trucco è che non si interroga il database nel senso in cui si interroga un database SQL: i risultati dell'esecuzione delle funzioni di visualizzazione vengono memorizzati in un indice e solo l'indice può essere interrogato. (Come "ottieni tutto", "ottieni chiave" o "ottieni intervallo di chiavi".)

L'analogia più vicina nel mondo SQL sarebbe se fosse possibile interrogare il DB solo utilizzando procedure memorizzate: ogni query che si desidera supportare deve essere predefinita.

Il design dei documenti è estremamente 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 frequentemente (come mettere tutte le vendite dell'azienda per l'anno nello stesso documento), poiché ogni aggiornamento del documento attiva una reindicizzazione.

Ma tutto dipende dalla progettazione delle viste.

I progetti alternativi che ho scoperto che gli ordini di lavoro di grandezza 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 su una pagina Web, la complessità del sistema totale viene ridotta di almeno il 50%:

  • nessuna progettazione di tabelle DB (problema minore)
  • nessun livello intermedio ODBC / JDBC, tutte le query e le transazioni su http (problema moderato)
  • semplice mappatura DB-oggetto da JSON, che è quasi banale rispetto alla stessa in SQL (importante!)
  • puoi potenzialmente saltare l'intero server delle applicazioni, poiché puoi progettare i tuoi documenti per essere recuperati direttamente dal browser utilizzando AJAX e aggiungere un po 'di lucidatura JavaScript prima che vengano visualizzati come HTML. (ENORME!!)

Per le normali webapp, i DB basati su documenti / JSON sono una grande vittoria e gli svantaggi di query meno flessibili e del codice extra per la convalida dei dati sembrano un piccolo prezzo da pagare.

Hai sbattuto la testa contro qualcosa che sembra impossibile?

Non ancora. Mappare / ridurre come mezzo per interrogare un database non è familiare e richiede molte più riflessioni rispetto alla scrittura di SQL. Esiste un numero piuttosto ridotto di primitive, quindi ottenere i risultati di cui hai bisogno è principalmente una questione di creatività nel modo in cui specifichi le chiavi.

Esiste una limitazione in quanto le query non possono esaminare due o più documenti contemporaneamente: 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 visualizzazione / query CouchDB. Correzione: restituire la somma e contare separatamente e calcolare la media sul client.

Hai colmato il divario con qualsiasi modello di progettazione, ad esempio per tradurre dall'uno all'altro?

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

Un modo per pensarci è guardare al tuo SQL per inserimenti e query comuni: quali tabelle e colonne vengono aggiornate quando un cliente effettua un ordine, ad esempio? E quali per i rapporti mensili sulle vendite? Quelle informazioni dovrebbero probabilmente andare nello stesso documento.

Ovvero: un documento per Ordine, contenente ID cliente e ID prodotto, con campi replicati secondo necessità per semplificare le query. Qualsiasi cosa all'interno di un documento può essere interrogata facilmente, tutto ciò che richiede un riferimento incrociato tra l'ordine e il cliente deve essere fatto dal cliente. Quindi, se desideri un rapporto sulle vendite per regione, dovresti probabilmente inserire un codice regione nell'ordine.

Realizzi anche modelli di dati espliciti ora (ad esempio in UML)?

Spiacenti, non ho mai fatto molto UML prima dei DB dei documenti :)

Ma hai bisogno di una sorta di modello che indichi quali campi appartengono a quali documenti e quali tipi di valori contengono. Sia per il tuo riferimento in seguito sia per assicurarti che tutti gli utenti che utilizzano il DB conoscano le convenzioni. Dal momento che non ricevi più un errore se ad esempio memorizzi una data in un campo di testo e chiunque può aggiungere o rimuovere qualsiasi campo a loro piacimento, hai bisogno sia del codice di convalida che delle convenzioni per riprendere il gioco. Soprattutto se lavori con risorse esterne.

Ti manca qualcuno dei principali servizi extra forniti dagli RDBMS?

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

Un'azienda per cui lavoravo ha realizzato un prodotto (una webapp) progettato per funzionare su database SQL di più fornitori, ei "servizi extra" sono così diversi da DB a DB che dovevano essere implementati separatamente per ogni DB. Quindi è stato meno faticoso per noi spostare la funzionalità fuori dall'RDBMS. Ciò si è esteso anche alla ricerca full-text.

Quindi qualunque cosa io stia rinunciando è qualcosa che non ho mai avuto davvero in primo luogo. Ovviamente la tua esperienza potrebbe essere diversa.


Un avvertimento: quello su cui sto lavorando ora è una webapp per dati finanziari, quotazioni di borsa e simili. Questo è un ottimo abbinamento per un DB di documenti, dal mio punto di vista ottengo tutti i vantaggi di un DB (persistenza e query) senza alcun problema.

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, questo è praticamente tutto. Un altro esempio che ho visto è stata un'applicazione per blog, e neanche i blog 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 nella ricerca Google), post di blog, articoli di notizie, dati finanziari .

Mi aspetto che ci siano set di dati che mappano meglio a SQL che 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 ce ne siano molti di noi - i database dei documenti (come in CouchDB) sono una manna dal cielo.


9
Molto utile. Soprattutto "SQL ha dati rigidi e query flessibili, i DB dei documenti sono il contrario" e l'assenza di join.
j_random_hacker

2
+1, questo è stato molto perspicace.
Mas

2
Quindi è vero, lo voterei più di una volta, se possibile.
Ottaviano A. Damiean

Questo era ancora estremamente utile nel 2014, sarebbe fantastico se potessi aggiungere ciò che hai imparato dal 2010 o collegarti a informazioni che potresti avere altrove.
Maggie

11

Sto rispondendo con CouchDB nella parte posteriore della mia mente, ma presumo che la maggior parte sarebbe vera anche per altri DB. Abbiamo esaminato l'utilizzo di CouchDB, ma alla fine abbiamo deciso di non farlo poiché il nostro accesso ai dati non è noto in anticipo e la scalabilità non è il problema.

Più forte:

  • Richiede un ripensamento a livello concettuale, quindi è "più difficile" poiché è solo diverso. Poiché è necessario conoscere in anticipo i modelli di accesso ai dati, non è possibile applicare alcuna 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ù facile, failover e migliore scalabilità al costo di un'applicazione più complicata. Un'applicazione deve affrontare conflitti e incongruenze.
  • I collegamenti che incrociano documenti (o chiave / valore) devono essere trattati anche a livello di applicazione.
  • I database di tipo SQL hanno IDE molto più maturi. Ottieni molte librerie di supporto (sebbene la stratificazione di queste librerie renda le cose molto più complesse del necessario per SQL).

Più facile:

  • Più veloce se conosci i tuoi schemi di accesso ai dati.
  • La migrazione / failover è più semplice per il database poiché non vi viene fatta alcuna promessa come programmatore dell'applicazione. Anche se ottieni eventuale coerenza. Probabilmente. Finalmente. A volte.
  • Una chiave / valore è molto più facile da capire rispetto a una riga di una tabella. Tutte le relazioni (ad albero) sono già presenti e gli oggetti completi possono essere riconosciuti.

La modellazione dovrebbe essere più o meno la stessa, ma devi stare attento a ciò che inserisci 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. Solo per rendere la scelta ancora più difficile. :)


1

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

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

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


1

I database relazionali che vedo nella vita reale tendono a non essere affatto normalizzati molto bene, contrariamente alla tua affermazione. Quando è stato chiesto, i designer mi dicono che è principalmente a causa delle prestazioni. Gli RDBM non sono bravi a unirsi, quindi le tabelle tendono ad essere troppo larghe dal punto di vista della normalizzazione. I database orientati agli oggetti tendono ad essere molto migliori in questo.

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


3
Stephan: hai ragione sul fatto che i sistemi del mondo reale spesso mancano nel reparto di normalizzazione. Ma non è esatto dire che gli RDBM "non sono bravi a unirsi"; la maggior parte dei prodotti commerciali (come Oracle, MS SQL Server, ecc.) dispone di ottimizzatori di query estremamente avanzati e può eseguire un'ampia varietà di algoritmi di join fisici diversi, molto più velocemente di quanto si potrebbero eseguire le stesse operazioni nel codice dell'applicazione. (MySQL è un'eccezione a questo, da quello che ho capito). Nella mia esperienza, la denormalizzazione prematura è, come altre ottimizzazioni premature, spesso un segno di sviluppatori poveri.
Ian Varley

2
Continuando questo pensiero: i join scadenti sono il risultato di una scarsa indicizzazione e statistiche. Se l'ottimizzatore non ha nulla con cui lavorare o le informazioni su ciò che ha non sono aggiornate, farà scelte sbagliate. Molti lo scambiano per "scarsa adesione". I moderni sistemi RDBM hanno una regolazione automatica che maschera la necessità di usare il cervello durante l'impostazione dell'indicizzazione e delle statistiche. Inoltre, le persone confondono lo schema logico (quinta forma normale) e lo schema fisico (spesso denormalizzato in terza normale). Solo perché il DB che vedi è "largo" non significa che sia stato progettato in modo sbagliato.
Godeke
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.