2014-12-30 9 views
7

Sto cercando di utilizzare il tipo jsonb colonna di PostgreSQL per un nuovo progetto backend che servirà principalmente come JSON API REST-ful. Credo che PostgreSQL jsonb sia adatto per questo progetto in quanto mi darà oggetti JSON senza bisogno di conversione sul back-end.jsonb e chiavi primarie/esterne: quali prestazioni migliori in PostgreSQL?

Tuttavia, ho letto che il tipo di dati jsonb rallenta man mano che vengono aggiunti i tasti, e il mio schema avranno bisogno di utilizzare le chiavi primarie e riferimenti chiave esterna.

Mi chiedevo se avere le chiavi primarie/chiavi esterne nelle proprie colonne (nel modo standard del database relazionale) e quindi avere una colonna jsonb per il resto dei dati sarebbe vantaggioso, o potrebbe causare problemi (se ora o lungo la strada)?

In breve, sarebbe:

table car(id int, manufacturer_id int, data jsonb) 

eseguire meglio o peggio di:

table car(data jsonb) 

Soprattutto quando alzando lo sguardo chiavi esterne di frequente?
Ci sarebbero degli svantaggi per il primo, dal punto di vista delle prestazioni o dello schema?

+0

Perché vuoi usare 'jsonb' a tutti? Sembra che tu abbia uno schema più o meno fisso e convertire le righe in JSON dovrebbe essere abbastanza veloce da non doverti preoccupare. –

+0

Buona domanda: ho una buona idea delle relazioni che il mio schema avrà bisogno, ma in questo momento non ho una conoscenza concreta delle informazioni che ogni tabella avrà bisogno, e mentre potrei fare migrazioni di database ogni volta Lo capisco, penso che l'utilizzo di jsonb mi consentirebbe buone prestazioni e un modo semplice per aggiungere rapidamente le cose. Forse in futuro, una volta che avrò una comprensione più concreta dei dati necessari, potrò tornare ad una buona impostazione relazionale. Ma questo è oltre il punto della domanda, che è: si esegue meglio/peggio rispetto agli altri? –

+1

Ma dovrai comunque eseguire una serie di migrazioni per riscrivere il tuo JSON, un paio di ALTER TABLE qui e là non dovrebbero essere spaventosi e se poi stanno riscrivendo tutti i tuoi dati e codice per tenere traccia di uno schema che cambia costantemente essere più spaventoso Per quanto riguarda la risposta alla domanda, per prima cosa è necessario porre la domanda giusta. Penso che tu debba capire come sono i tuoi dati prima di iniziare a imbrogliare i dati. Se pensate di volerlo schierare e poi tornare indietro e ridisegnare il database, quasi sicuramente si sbaglia, non succederà. –

risposta

12

Tutti i valori coinvolti in un PRIMARY KEY o FOREIGN KEY vincolo mosto essere memorizzati come colonne dedicate (best in forma normalizzata). Vincoli e riferimenti non funzionano per valori annidati all'interno una colonna json/jsonb.

quanto riguarda il resto dei dati: Dipende. Inserirli all'interno di un valore jsonb (preferibilmente) comporta i noti vantaggi e svantaggi della memorizzazione di dati di tipo documento non strutturati.

Per gli attributi che sono presenti per tutti o la maggior parte le righe, sarà molto probabilmente essere meglio (più veloce, più pulito, più piccolo di stoccaggio) per memorizzarli come colonne separate. Indicizzazione più semplice e query più semplici. Anche se il nuovo jsonb ha amazing index capabilities, l'indicizzazione di colonne dedicate è ancora più semplice/veloce.

Per gli attributi raramente utilizzati o visualizzati in modo dinamico o se si desidera archiviare e recuperare i valori JSON senza molta gestione all'interno del DB, consultare jsonb.

Per base EAV structures principalmente con dati di carattere, senza nidificazione e nessuna connessione a JSON, prenderei in considerazione hstore. Vi sono anche i tipi di dati xml (più complessi e dettagliati) e json (per lo più sostituiti da jsonb), che stanno perdendo terreno.

+1

Sì ... "dipende". Un problema non affrontato qui è che se si aggiorna * qualsiasi * sottocampo di un valore jsonb, la * intera tupla * deve essere riscritta e qualsiasi/tutti gli indici che puntano ad essa devono essere aggiornati.Se hai decomposto i tuoi dati in entità con relazioni pk/fk questo non è più il caso, puoi inserire/aggiornare/eliminare solo parti di esso senza forzare la riscrittura dell'intera faccenda. –

+0

@CraigRinger È ancora vero in Postgres 9.5? Chiedo dopo aver letto questa sezione nei documenti di rilascio https://wiki.postgresql.org/wiki/What's_new_in_PostgreSQL_9.5#JSONB-modifying_operators_and_functions – t1m0

+3

@ t1m0 Sì. È inerente allo storage out-of-line TOAST e a MVCC. PostgreSQL ora può modificare un oggetto jsonb senza doverlo decostruire e ricostruire completamente, ma questa è una modifica in memoria. Deve ancora leggere tutto da disco e deve ancora scrivere la nuova versione modificata nella nuova tupla. –

2

Quali prestazioni migliori? Dipende dall'uso È la stessa domanda, quando si confrontano i database SQL (relazionale) e NoSQL (KeyValue o Document). Per alcuni casi d'uso, un database NoSQL funziona molto bene, per altri no.

Il concetto relazionale (schema normalizzato) è ottimizzato per l'utilizzo tipico di OLTP: 70% di lettura/30% di scrittura, multiutente, molti aggiornamenti, calcolo di report, alcune query ad hoc. Il concetto relazionale è relativamente ampio.con usabilità molto ampia (prove, contabilità, supporto di elaborazione, ...). Di solito non è male dappertutto.

E 'chiaro, quindi i database specializzati (Documento, KeyValue, Grafico) possono essere significativamente migliori (un ordine più veloce) su casi d'uso specializzati. Ma il loro utilizzo è significativamente più stretto. Quando si è fuori dal caso d'uso ottimizzato, le prestazioni possono essere negative.

Un'altra domanda è la dimensione del database: numeri di record. La differenza di prestazioni nei database di produzione può essere significativa in centinaia di migliaia di righe. Per alcuni database più piccoli l'impatto può non essere significativo.

Postgres è un database relazionale e la mia preferenza è di utilizzare uno schema normalizzato per tutti i dati importanti nel database. Quando lo usi bene, è terribilmente veloce. I tipi non relazionali sono perfetti per alcuni dati fuzzy (HStore, JSON, XML, Jsonb) - è significativamente migliore dello schema EAV (peggiora con dati più grandi).

Se è necessario prendere una decisione importante, preparare il prototipo, riempirlo per i dati previsti (3 anni) e verificare la velocità di alcune query importanti per il proprio sistema. Attenzione: il forte impatto su questi benchmark ha utilizzato hw, carico corrente, corrente sw.