2009-11-08 14 views
5

Sto sviluppando un'applicazione che memorizzerà un numero considerevole di record. Questi record saranno qualcosa di simile (URL, data, titolo, origine, {dati facoltativi ...})Quale database dovrei usare per memorizzare i record e come dovrei usarlo?

Poiché questa è un'app lato client, non voglio utilizzare un server di database, voglio solo le informazioni memorizzate nei file.

Voglio che i file siano leggibili da vari linguaggi (almeno Python e C++), quindi qualcosa di specifico del linguaggio come il pickle di python è fuori dal gioco.

Sto vedendo due possibilità: sqlite e BerkeleyDB. Poiché il mio caso d'uso non è chiaramente relazionale, sono tentato di andare con BerkeleyDB, tuttavia non so davvero come utilizzarlo per archiviare i miei record, poiché memorizza solo coppie chiave/valore.

Il mio ragionamento è corretto? In tal caso, come dovrei usare BDB per archiviare i miei record? Puoi collegarmi a informazioni pertinenti? O mi manca una soluzione migliore?

+0

Grazie a tutti voi ragazzi per le vostre risposte molto utili! Scegliere uno migliore è stato davvero difficile: -/ –

risposta

5

Sto vedendo due possibilità: sqlite e BerkeleyDB. Come il mio caso d'uso è chiaramente non relazionale, sono tentato di andare con BerkeleyDB, però io non so davvero come dovrei usarlo per negozio i miei dischi, in quanto memorizza solo coppie chiave/valore.

Quello che stai descrivendo è esattamente ciò di cui parla il rapporto, anche se hai solo bisogno di un tavolo. SQLite probabilmente renderà questo molto facile da fare.

MODIFICA: Il modello relazionale non ha nulla a che fare con le relazioni tra tabelle. Una relazione è un sottoinsieme del prodotto cartesiano di altri set. Ad esempio, il prodotto cartesiano dei numeri reali, numeri reali e numeri reali (sì, tutti e tre uguali) produce lo spazio delle coordinate 3d e potresti definire una relazione su quello spazio con una formula, ad esempio x*y = z. ogni possibile insieme di coordinate (x0,y0,z0) sono nella relazione se soddisfano la formula data, altrimenti non lo sono.

Un database relazionale utilizza questo concetto con alcuni requisiti aggiuntivi. Innanzitutto, e la cosa più importante, la dimensione della relazione deve essere finita. La relazione di prodotto sopra riportata non soddisfa questo requisito, perché ci sono infinitamente più tuple di 3 che soddisfano la formula.Ci sono una serie di altre considerazioni che hanno più a che fare con ciò che è pratico o utile su computer reali che risolvono problemi reali.

Un modo migliore di pensare al problema è pensare a dove ogni tipo di meccanismo di persistenza funziona in modo specifico meglio dell'altro. Si riconosce già che una soluzione relazionale ha senso quando si hanno molti dataset separati (tabelle) che devono supportare le relazioni tra di essi (vincoli di chiave esterna), che è quasi impossibile applicare con un archivio di valori-chiave. Un altro vantaggio reale per le relazioni è il modo in cui rende possibili query ad hoc complete con l'uso di indici appropriati. Questa è una conseguenza del livello del database che comprende effettivamente i dati che rappresenta.

Un archivio di valori-chiave ha il proprio insieme di vantaggi. Uno dei più importanti è il modo in cui i negozi di valore-chiave si ridimensionano. Nessuna conseguenza è che memcached, couchdb, hadoop utilizzino tutti gli archivi con valori-chiave, poiché è facile distribuire la ricerca di valori-chiave su più server. Un'altra area in cui l'archiviazione dei valori-chiave funziona bene è quando la chiave o il valore è opaco, ad esempio quando l'elemento memorizzato viene crittografato, per essere solo leggibile dal proprietario.


a guidare questo punto a casa, che un database relazionale funziona bene anche quando proprio non c'è bisogno più di una tabella, considerare quanto segue (non originale)

SELECT t1.actor1 
FROM workswith AS t1, 
    workswith AS t2, 
    workswith AS t3, 
    workswith AS t4, 
    workswith AS t5, 
    workswith AS t6 
WHERE t1.actor2 = t2.actor1 AND 
     t2.actor2 = t3.actor1 AND 
     t3.actor2 = t4.actor1 AND 
     t4.actor2 = t5.actor1 AND 
     t5.actor2 = t6.actor1 AND 
     t6.actor2 = "Kevin Bacon"; 

Il che, ovviamente, utilizza una singola tabella: workswith per calcolare ogni attore con un numero di bacon di 6

+0

Potresti elaborare? Per me relazionale ha senso solo se hai diverse tabelle con relazioni tra loro ... –

1

Che dire di MongoDB? Non l'ho ancora provato, ma sembra interessante.

+0

Sembra interessante ... Non sembra essere ancora maturo, però. –

2

BerkeleyDB è buono, guarda anche le * incarnazioni DBM (ad esempio GDBM). La grande domanda però è: per cosa hai bisogno di cercare? Devi cercare in base a quell'URL, in base a un intervallo di URL o alle date che elenchi?

È anche possibile mantenere gruppi di record come file semplici nel filesystem locale, raggruppati per date o termini di ricerca, & c.

Rispondere alla domanda "cerca" è l'inizio più grande.

Per quanto riguarda la chiave/valore cosa, ciò che è necessario assicurarsi è che il KEY stesso sia ben definito come per le proprie ricerche. Se, ad esempio, è necessario cercare a volte date e altri per titolo, è necessario mantenere una riga "record" e quindi probabilmente 2 o più righe "indice" facendo riferimento al record originale. Puoi modellare quasi tutto in un archivio di chiavi/valori.

+0

"È possibile modellare quasi tutto in un archivio di chiavi/valori." Potresti consigliare qualcosa da leggere su questo? Posso vedere che questo modello è molto generale, ma leggere alcuni esempi sarebbe utile. –

+1

Riesco a vedere cosa riesco a trovare, ma le basi tradizionali di un archivio DB sottostante sono effettivamente un archivio di chiavi/valori in un meccanismo o in un altro. Una tabella heap è solo righe scritte in una chiave/valore con la riga come valore e la chiave ROWID generata di sorta. Un indice non composto su tale tabella elenca i valori dell'indice come chiave e ROWID come valore. Certo, diventa più complicato di così ma * niente non può essere risolto senza un altro livello di riferimento indiretto * si applica qui. Risponderò se riesco a trovare alcuni articoli. – Xailor

2

Personalmente userei sqlite comunque. Ha sempre funzionato per me (e per gli altri con cui lavoro). Quando la tua app cresce e improvvisamente vuoi fare qualcosa di un po 'più sofisticato, non dovrai riscriverlo.

D'altra parte, ho visto vari commenti sulla lista dev di Python su Berkely DB che suggeriscono che è meno che meraviglioso; si ottiene solo l'accesso in stile dettato (cosa succede se si desidera selezionare determinati intervalli di date o titoli invece di URL); e non è nemmeno nel set di librerie standard di Python 3.

+0

"non è nemmeno nel set di librerie standard di Python 3". Non lo sapevo, questo è un ottimo punto, grazie! –

+0

Si prega di controllare. Ho dato un'occhiata e posso vedere (g | n) il supporto per dbm, ma penso che sia diverso, giusto? Forse la discussione che ricordo nella lista dev era relativa alla sua caduta. –

1

Se si sta solo utilizzando un campo singolo per cercare i record, un semplice archivio di valori-chiave sarebbe una buona scelta. Archivia quel singolo campo (o qualsiasi altro ID univoco) come chiave, serializza ogni record come una stringa (usando JSON o simile) e memorizza quella stringa come valore. Berkeley DB è certamente una scelta ragionevole per un negozio chiave-valore, ma ci sono molte alternative tra cui scegliere: http://en.wikipedia.org/wiki/Dbm

Se si desidera cercare i record da uno qualsiasi dei diversi campi, SQLite potrebbe essere più semplice per scopi di sviluppo. Scriverete query in SQL ma non dovrete mantenere un server di database. Tutte le macchine multi-chiave sono già state scritte per te.

Se si vuole davvero evitare SQL o spremere ogni bit di prestazioni dal vostro archivio dati, e si desidera l'accesso multi-chiave, prendere in considerazione uno strato di logica extra in cima di un negozio di valori-chiave. È possibile creare un comportamento simile a una colonna in cima agli archivi di valori-chiave serializzando i record e inserendo i valori di "colonna" di ciascun record come chiavi aggiuntive i cui valori contengono la chiave "primaria" del record. (Stai utilizzando efficacemente l'archivio di valori-chiave sia come dizionario di record sia come dizionario di indici per trovare quei record.) App Engine di Google fa qualcosa del genere. Puoi farlo tu stesso o utilizzare uno dei vari database orientati ai documenti che lo faranno per te. Per alcune letture interessanti, prova a usare google "nosql". http://www.google.com/search?&q=nosql

+1

P.S. L'accordo con Berkeley DB nella distribuzione python è semplicemente che gli interni della libreria bdb stavano cambiando più frequentemente di quanto gli sviluppatori di Python volevano tenere il passo. Non è che Berekeley DB fosse cattivo, solo scomodo da integrare direttamente nelle versioni di Python. È ancora possibile ottenere i binding python bdb come modulo separato. –

0

Ok, quindi dici di aver archiviato i dati ..? Hai solo bisogno di un DB per il recupero, la ricerca, il riepilogo, ecc. Quindi, per la memorizzazione, basta usare semplici file di testo e aggiungere righe. Comprimi i dati se necessario, usa delimitazioni tra i campi - praticamente qualsiasi lingua sarà in grado di leggere tali file. Se si desidera recuperare, concentrarsi sulle esigenze di recupero, per data, per chiave, quali chiavi, ecc. Se si desidera un client semplice, è necessario un db client semplice. SQLite è molto più semplice di BDB, ma guarda cose come Sybase Advantage (molto veloce e gratuito per i client locali ma non open-source) o VistaDB o firebird ... ma tutto richiederà configurazione, configurazione e manutenzione locali. Se vai su XML locale per un numero "considerevole" di record ti daranno dei file inutilmente gonfiati ...!

Problemi correlati