2013-09-03 13 views
18

Ho preso in considerazione la creazione di una tabella di vertici e di una tabella di bordi ma la creazione di grafici in memoria e la visualizzazione di grafici secondari richiedono un numero elevato di ricerche? Mi piacerebbe evitare letture eccessive del database. C'è un altro modo per mantenere un grafico?Come mantenere una struttura di dati del grafico in un database relazionale?

Nota a margine: ho sentito parlare di Neo4j ma la mia domanda è davvero come rappresentare graficamente un grafico in un database standard. Sono aperto ad alcune soluzioni NoSQL come mongodb però.

+0

Per darti un consiglio prezioso avrò bisogno di più informazioni dalla tua parte. Quanti nodi e quante relazioni stiamo parlando? –

+0

Beh, direi miliardi di nodi. Come ho detto, questo è per lo più concettuale, ma sono curioso di come ridimensionare per un sacco di record. Ho in mente grafici molto grandi, credo. –

+1

Non è open source ma è esattamente quello che stai cercando: il nuovo Aster 6.0 è dotato di un motore grafico all'interno del database relazionale - si chiama SQL-GR e si propone di utilizzare le funzioni esistenti e nuove su grafici memorizzati in tabelle relazionali (in Aster): rappresentato con la tabella dei nodi e la tabella dei bordi. – topchef

risposta

20

La risposta è sfortunatamente: la tua considerazione è completamente corretta in ogni punto. È necessario memorizzare Nodi (Vertices) in una tabella e Bordi che fanno riferimento a un DaNodo e un ToNodo per convertire una struttura di dati del grafico in una struttura dati relazionale. E hai anche ragione, che questo finisce in un gran numero di ricerche, perché non sei in grado di suddividerlo in sottografi, che potrebbero essere interrogati contemporaneamente. Devi passare da un nodo all'altro, da un nodo all'altro, da un nodo all'altro ... e così via (in modo ricorsivo, mentre SQL sta lavorando con gli insiemi).

Il punto è ...

relazionale, grafo orientato, object oriented, Documento base sono diversi tipi di strutture di dati che soddisfano i requisiti differenti. Ecco di cosa si tratta e perché così tanti diversi database NoSQL (la maggior parte di essi sono semplici archivi di documenti), perché non ha senso organizzare grandi dati in modo relazionale.

1 Alternativa - Grafico del database orientati

Ma ci sono anche grafo orientato database NoSQL, che rendono il modello di dati grafico un primo cittadino di classe come OrientDB che sto giocando intorno con un po 'in questo momento. La cosa bella è che, sebbene persista come un grafico, può ancora essere utilizzato in modo relazionale o anche orientato agli oggetti o orientato al documento (cioè interrogando con un semplice vecchio SQL). Ciononostante, Traversing the graph è il modo ottimale per ricavarne i dati di sicuro.

Alternativa 2 - lavorare con i grafici in memoria

Quando si tratta di instradamento veloce, quadri di instradamento come Graphhopper costruire il grafo completo (miliardi di nodi) all'interno della memoria. Perché Graphhopper utilizza un'implementazione MemoryMapped del suo GraphStore, che funziona anche su dispositivi Android con solo alcuni MB di memoria necessari. Il grafico completo viene letto dal database in memoria all'avvio, quindi il routing viene eseguito lì, quindi non è necessario cercare il database.

+6

+1 BTW: l'unica differenza tra "DB grafico" e "DB relazionale" è l'implementazione ** ** della ricerca. Se l'elenco di spigoli a cui si fa riferimento nella tabella dei nodi viene raggiunto attraverso un puntatore diretto, è possibile chiamarlo DB grafico anche se i dati possono ancora essere organizzati in tabelle! Quindi, se questa ricerca è log (n) per elenco di spigoli o anche per spigolo, allora la gente la chiama "DB relazionale" e attraversare il grafico è piuttosto costoso (indipendentemente dal fatto che la memoria sia stampata o in memoria o altro) . – Karussell

+1

@Karussell è degno di nota il fatto che la maggior parte dei database SQL supportano indici basati su hash, con il risultato che la ricerca edge/vertex è O (1), proprio come per un database grafico. O (log (n)) il tempo di interrogazione è solitamente associato agli indici basati su albero B, che sono usati principalmente quando l'ordinamento dei dati è importante (che per gli ID bordo/vertice di solito non è rilevante). – ThePhysicist

+1

Probabilmente hai ragione. Ancora un indice basato su hash ha overhead (spazio e tempo) in pratica IMO rispetto a un puntatore diretto. Ma probabilmente la tecnologia utilizzata è molto simile per entrambi i DB e solo il marketing blabla li fa apparire molto diversi :) – Karussell

3

Ho affrontato questo stesso problema e ha deciso di andare, infine, con la seguente struttura, che richiede 2 query di database, poi il resto del lavoro è in memoria:

nodi Conservare in un tavolo e di riferimento il grafico con ogni annotazione nodo:

Table Nodes 

id | title | graph_id 
--------------------- 
105 | node1 | 2 
106 | node2 | 2 

negozio anche bordi in un'altra tabella e nuovamente riferimento grafico questi bordi appartengono ad ogni fronte:

Table Edges 

id | from_node_id | to_node_id | graph_id 
----------------------------------------- 
1 | 105   | 106  | 2 
2 | 106   | 105  | 2 

Ottieni tutti i nodi con una query, quindi ottieni tutti i bordi con un altro.

Ora crea il tuo modo preferito per memorizzare il grafico (ad es. Elenco di adiacenza) e procedi con il flusso dell'applicazione.

Problemi correlati