Spiegazione di JSONB introdotta da PostgreSQL


346

PostgreSQL ha appena introdotto JSONB ed è già di tendenza sulle notizie degli hacker . Sarebbe bello se qualcuno potesse spiegare come è diverso da Hstore e JSON precedentemente presenti in PostgreSQL. Quali sono i suoi vantaggi e limiti e quando qualcuno dovrebbe considerare di usarlo?


4
Da PGCon2014: youtube.com/…
msanford,

5
L'URL di @CraigRinger non è abbastanza preciso, ora, 1 anno dopo, non punta nemmeno abbastanza vicino al contenuto relativo a JSONB.
Berkus,

2
@berkus Ho pensato di collegarmi al post specifico. Che frustrante.
Craig Ringer,

1
Indica il video specifico.
Talonx,

Risposte:


457

Innanzitutto, hstoreè un modulo contrib, che consente solo di memorizzare coppie key => value, in cui chiavi e valori possono essere solo texts (tuttavia anche i valori possono essere sql NULLs).

Entrambi jsone jsonbti consentono di memorizzare un valore JSON valido (definito nelle sue specifiche ).

F.ex. questi sono rappresentazioni JSON validi: null, true, [1,false,"string",{"foo":"bar"}], {"foo":"bar","baz":[null]}- hstoreè solo un piccolo sottoinsieme rispetto a ciò che è in grado JSON (ma se avete solo bisogno di questo sottoinsieme, va bene).

L'unica differenza tra json& jsonbè il loro spazio di archiviazione:

  • json è memorizzato nel suo formato di testo normale, mentre
  • jsonb è memorizzato in una rappresentazione binaria

Ci sono 3 conseguenze principali di questo:

  • jsonbdi solito richiede più spazio su disco per memorizzare di json(a volte no)
  • jsonb richiede più tempo per costruire dalla sua rappresentazione di input di json
  • jsonle operazioni richiedono molto più tempo di jsonb(e anche l'analisi deve essere eseguita ogni volta che si esegue un'operazione a un jsonvalore tipizzato)

Quando jsonbsarà disponibile con una versione stabile, ci saranno due casi d'uso principali, in cui è possibile selezionare facilmente tra di essi:

  1. Se lavori solo con la rappresentazione JSON nella tua applicazione, PostgreSQL viene utilizzato solo per archiviare e recuperare questa rappresentazione, dovresti usare json.
  2. Se fai molte operazioni sul valore JSON in PostgreSQL o usi l'indicizzazione su un campo JSON, dovresti usare jsonb.

1
ciao, dal momento che ha una rappresentazione binaria, perché jsonbnon supporta questo? UPDATE test SET data->'a' = 123 WHERE id = 1;daCREATE TABLE test(id SERIAL PRIMARY KEY, data JSONB);
Kokizzu,

1
Kokizzu, è possibile in 9.5. wiki.postgresql.org/wiki/…
ChelowekKot

1
Giusto per aggiungere, una delle ragioni per cui potreste utilizzare anche jsonoltre jsonbè che se per motivi di eredità il codice consumare il vostro jsondipende dalla ordinamento dei jsoncampi e non possono essere riordinati.
djdrzzy,

4
Come per i motivi legacy: in JSON non esiste alcuna differenza semantica se le coppie chiave-valore di un oggetto (tabella, mappa, hash, qualunque sia la chiamata nella lingua host) vengono ordinate in modo diverso. Se ti affidi a questo, stai effettivamente usando qualcosa di diverso da JSON. - Per textvs json.: quest'ultimo viene fornito con la convalida JSON, quindi su JSON non valido, non riuscirà solo dopo l'inserimento, anziché ogni volta che l'applicazione lo legge (perché ottiene una rappresentazione non valida). Inoltre, è possibile eseguire il cast sicuro di quest'ultimo jsonbnel database.
Pozs

2
Questo è un ottimo post sulla spiegazione dei dettagli di implementazione di JSONB ( pgeoghegan.blogspot.com/2014/03/what-i-think-of-jsonb.html )
manugupt1

131

Peeyush:

La risposta breve è:

  • Se stai facendo molta manipolazione JSON all'interno di PostgreSQL, come ordinamento, suddivisione, giunzione, ecc., Dovresti usare JSONB per motivi di velocità.
  • Se hai bisogno di ricerche indicizzate per ricerche di chiavi arbitrarie su JSON, allora dovresti usare JSONB.
  • Se non si sta eseguendo nessuna delle operazioni precedenti, è consigliabile utilizzare JSON.
  • Se è necessario conservare l'ordine delle chiavi, gli spazi bianchi e le chiavi duplicate, è necessario utilizzare JSON.

Per una risposta più lunga, dovrai aspettare che io scriva un "HowTo" completo più vicino alla versione 9.4.


74

Una semplice spiegazione della differenza tra json e jsonb ( immagine originale di PostgresProfessional ):

SELECT '{"c":0,   "a":2,"a":1}'::json, '{"c":0,   "a":2,"a":1}'::jsonb;

          json          |        jsonb 
------------------------+--------------------- 
 {"c":0,   "a":2,"a":1} | {"a": 1, "c": 0} 
(1 row)
  • json: memoria testuale «così com'è»
  • jsonb: nessun spazio bianco
  • jsonb: nessuna chiave duplicata, ultima chiave ottenuta
  • jsonb: le chiavi sono ordinate

Altro in video vocali e presentazione di diapositive da sviluppatori jsonb. Inoltre hanno introdotto JsQuery , pg.extension fornisce un potente linguaggio di query jsonb


1
Grazie, l'ho sostituito al testo
ChelowekKot,

56
  • hstore è più un tipo di archiviazione "a colonna larga", è un dizionario piatto (non nidificato) di coppie chiave-valore, sempre memorizzato in un formato binario ragionevolmente efficiente (una tabella hash, da cui il nome).
  • jsonarchivia i documenti JSON come testo, eseguendo la convalida quando i documenti vengono archiviati e analizzandoli sull'output, se necessario (cioè accedendo ai singoli campi); dovrebbe supportare l'intera specifica JSON. Poiché viene memorizzato l'intero testo JSON, la sua formattazione viene preservata.
  • jsonbprende scorciatoie per motivi di prestazioni: i dati JSON vengono analizzati sull'input e archiviati in formato binario, gli ordinamenti delle chiavi nei dizionari non vengono mantenuti e nemmeno le chiavi duplicate. L'accesso ai singoli elementi nel campo JSONB è rapido in quanto non richiede l'analisi costante del testo JSON. All'uscita, i dati JSON vengono ricostruiti e la formattazione iniziale viene persa.

IMO, non vi è alcun motivo significativo per non utilizzare jsonbuna volta che è disponibile, se si lavora con dati leggibili automaticamente.


24

JSONB è una versione "migliore" di JSON.

Diamo un'occhiata a un esempio:

SELECT '{"c":0,   "a":2,"a":1}'::json, '{"c":0,   "a":2,"a":1}'::jsonb;
          json          |        jsonb 
------------------------+--------------------- 
 {"c":0,   "a":2,"a":1} | {"a": 1, "c": 0} 
(1 row)
  1. JSON memorizza gli spazi bianchi, è per questo che possiamo vedere gli spazi quando viene memorizzata la chiave "a", mentre JSONB no.
  2. JSON memorizza tutti i valori di chiave. Questo è il motivo per cui puoi vedere più valori (2 e 1) sulla chiave "a", mentre JSONB "memorizza" solo l'ultimo valore.
  3. JSON mantiene l'ordine in cui sono inseriti gli elementi, mentre JSONB mantiene l'ordine "ordinato".
  4. Gli oggetti JSONB sono archiviati come binari decompressi rispetto ai "dati non elaborati" in JSON, dove non è necessario ripetere la registrazione dei dati durante il recupero.
  5. JSONB supporta anche l'indicizzazione, che può essere un vantaggio significativo.

In generale, si dovrebbe preferire JSONB, a meno che non ci siano esigenze specializzate, come ipotesi legacy sull'ordinamento di chiavi oggetto.


13

Sono stato al pgopen oggi i benchmark sono molto più veloci di mongodb, credo che sia stato circa il 500% più veloce per le selezioni. Praticamente tutto era più veloce almeno del 200% se confrontato con mongodb, al momento un'eccezione è un aggiornamento che richiede una riscrittura completa dell'intera colonna json, qualcosa che mongodb gestisce meglio.

L'indicizzazione del gin su JSONB sembra incredibile.

Anche Postgres persisterà internamente tipi di jsonb e fondamentalmente abbinerà questo con tipi come numerico, testo, booleano ecc.

I join saranno anche possibili usando jsonb

Aggiungi PLv8 per le procedure memorizzate e questo sarà fondamentalmente un sogno diventato realtà per gli sviluppatori node.js.

Il fatto che sia memorizzato come jsonb binario eliminerà anche tutti gli spazi bianchi, cambierà l'ordinamento delle proprietà e rimuoverà le proprietà duplicate usando l'ultima occorrenza della proprietà.

Oltre all'indice quando si esegue una query su una colonna jsonb in contrasto con una colonna json, postgres non deve effettivamente eseguire la funzionalità per convertire il testo in json su ogni riga, il che probabilmente farà risparmiare molto tempo da solo.


8

Per quanto riguarda le differenze tra jsone jsonbtipi di dati, vale la pena menzionare la spiegazione ufficiale:

PostgreSQL offre due tipi di archiviazione dei dati JSON: jsone jsonb. Per implementare meccanismi di query efficienti per questi tipi di dati, PostgreSQL fornisce anche il tipo di dati jsonpath descritto nella Sezione 8.14.6 .

I tipi di dati jsone jsonbaccettano insiemi di valori quasi identici come input. La principale differenza pratica è quella dell'efficienza. Il jsontipo di dati memorizza una copia esatta del testo di input, le cui funzioni di elaborazione devono ripetere l'analisi ad ogni esecuzione; mentre i jsonbdati sono archiviati in un formato binario decomposto che rende leggermente più lento l'input a causa del sovraccarico di conversione aggiunto, ma significativamente più veloce da elaborare, poiché non è necessario il reimpostazione. jsonbsupporta anche l'indicizzazione, che può essere un vantaggio significativo.

Poiché il jsontipo memorizza una copia esatta del testo di input, conserverà uno spazio bianco semanticamente insignificante tra i token, nonché l'ordine delle chiavi all'interno degli oggetti JSON. Inoltre, se un oggetto JSON all'interno del valore contiene la stessa chiave più di una volta, vengono mantenute tutte le coppie chiave / valore. (Le funzioni di elaborazione considerano l'ultimo valore come quello operativo.) Al contrario, jsonbnon preserva lo spazio bianco, non conserva l'ordine delle chiavi dell'oggetto e non mantiene le chiavi duplicate dell'oggetto. Se nell'input vengono specificate chiavi duplicate, viene mantenuto solo l'ultimo valore.

In generale, la maggior parte delle applicazioni dovrebbe preferire archiviare i dati JSON come jsonb, a meno che non ci siano esigenze abbastanza specializzate, come ipotesi legacy sull'ordinamento di chiavi oggetto.

PostgreSQL consente solo una codifica del set di caratteri per database. Pertanto, non è possibile che i tipi JSON si conformino rigidamente alla specifica JSON a meno che la codifica del database non sia UTF8. I tentativi di includere direttamente i caratteri che non possono essere rappresentati nella codifica del database falliranno; al contrario, saranno consentiti caratteri che possono essere rappresentati nella codifica del database ma non in UTF8.

Fonte: https://www.postgresql.org/docs/current/datatype-json.html


7

Un'altra differenza importante, che non è stata menzionata in nessuna risposta sopra, è che non esiste un operatore di uguaglianza per jsontipo, ma ce n'è uno per jsonb.

Ciò significa che non è possibile utilizzare la DISTINCTparola chiave quando si seleziona questo jsontipo e / o altri campi da una tabella (è possibile utilizzare DISTINCT ONinvece, ma non è sempre possibile a causa di casi come questo ).


6

Per quanto posso dire,

  • hstore come esiste attualmente (in Postgresql 9.3) non consente di annidare altri oggetti e matrici come i valori delle sue coppie chiave / valore. tuttavia, una futura patch hstore consentirà l'annidamento. questa patch non sarà nella versione 9.4 e potrebbe non essere inclusa in qualunque momento presto.

  • json nella sua forma attuale non consentire nidificazione, ma è basato su testo, e non consente l'indicizzazione, quindi è "lento"

  • jsonb che sarà rilasciato con 9.4 avrà le attuali capacità di annidamento di json, così come l'indicizzazione GIN / GIST di hstore, quindi sarà veloce

Le persone che lavorano su Postgresql 9.4 sembrano dire che il nuovo tipo di jsonb veloce si rivolge a persone che avrebbero scelto di utilizzare un archivio di dati noSQL come MongoDB, ma ora possono combinare un database relazionale con dati non strutturati che possono essere interrogati sotto lo stesso tetto

http://www.databasesoup.com/2014/02/why-hstore2jsonb-is-most-important.html

I benchmark di postgresql 9.4 jsonb sembrano essere alla pari o in alcuni casi più veloci di MongoDB

http://texture.io/alphabetum/postgresql-incl-hstore-vs-mongodb

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.