Explication de JSONB introduite par PostgreSQL

346

PostgreSQL vient d'introduire JSONB et il fait déjà partie des nouvelles des hackers . Ce serait formidable si quelqu'un pouvait expliquer en quoi il diffère de Hstore et JSON précédemment présents dans PostgreSQL. Quels sont ses avantages et ses limites et quand devrait-on envisager de l'utiliser?

Peeyush
la source
4
De PGCon2014: youtube.com/…
msanford
5
L'URL @CraigRinger n'est pas assez précise, maintenant, un an plus tard, elle ne pointe même pas assez près du contenu lié à JSONB.
berkus
2
@berkus Je pensais avoir lié au message spécifique. Quelle frustration.
Craig Ringer
1
Cela pointe vers la vidéo spécifique.
talonx

Réponses:

457

Tout d'abord, hstoreest un module contrib, qui vous permet uniquement de stocker des paires clé => valeur, où les clés et les valeurs ne peuvent être que texts (mais les valeurs peuvent également être des sql NULL).

Les deux json& jsonbvous permettent de stocker une valeur JSON valide (définie dans ses spécifications ).

F.ex. ceux - ci sont des représentations JSON valides: null, true, [1,false,"string",{"foo":"bar"}], {"foo":"bar","baz":[null]}- hstoreest juste un peu sous - ensemble par rapport à ce que JSON est capable (mais si vous avez seulement besoin ce sous - ensemble, il va bien).

La seule différence entre json& jsonbest leur stockage:

  • json est stocké dans son format de texte brut, tandis que
  • jsonb est stocké dans une représentation binaire

Il y a 3 conséquences majeures à cela:

  • jsonbprend généralement plus d'espace disque pour stocker que json(parfois non)
  • jsonb prend plus de temps à construire à partir de sa représentation d'entrée que json
  • jsonles opérations prennent beaucoup plus de temps jsonb(et l'analyse doit également être effectuée chaque fois que vous effectuez une opération avec une jsonvaleur tapée)

Lorsque jsonbsera disponible avec une version stable, il y aura deux cas d'utilisation majeurs, lorsque vous pourrez facilement choisir entre eux:

  1. Si vous ne travaillez qu'avec la représentation JSON dans votre application, PostgreSQL n'est utilisé que pour stocker et récupérer cette représentation, vous devez l'utiliser json.
  2. Si vous effectuez de nombreuses opérations sur la valeur JSON dans PostgreSQL, ou utilisez l'indexation sur un champ JSON, vous devez utiliser jsonb.
pozs
la source
1
salut, car il a une représentation binaire, pourquoi jsonbne prend pas en charge cela? UPDATE test SET data->'a' = 123 WHERE id = 1;deCREATE TABLE test(id SERIAL PRIMARY KEY, data JSONB);
Kokizzu
1
Kokizzu, c'est possible en 9.5. wiki.postgresql.org/wiki/…
ChelowekKot
1
Juste pour ajouter, l' une des raisons pour lesquelles vous pouvez également utiliser jsonplus jsonbest si pour des raisons historiques votre code consumait votre jsondépend de l'ordre des jsonchamps et ils ne peuvent être réorganisées.
djdrzzy
4
Comme pour les raisons héritées: en JSON, il n'y a pas de différence sémantique, si les paires clé-valeur d'un objet (table, carte, hachage, quel qu'il soit appelé dans le langage hôte) sont ordonnées différemment. Si vous vous en remettez à cela, vous utilisez en fait quelque chose de différent de JSON. - Pour textvs json: ce dernier est livré avec une validation JSON, donc en cas de JSON invalide, il échouera uniquement lors de l'insertion, au lieu de chaque fois que votre application le lira (car il obtient une représentation non valide). De plus, vous pouvez caster ces derniers en toute sécurité jsonbdans la base de données.
pozs
2
Ceci est un excellent article expliquant les détails de l'implémentation de JSONB ( pgeoghegan.blogspot.com/2014/03/what-i-think-of-jsonb.html )
manugupt1
131

Peeyush:

La réponse courte est:

  • Si vous faites beaucoup de manipulation JSON dans PostgreSQL, comme le tri, le découpage, l'épissage, etc., vous devez utiliser JSONB pour des raisons de vitesse.
  • Si vous avez besoin de recherches indexées pour des recherches de clés arbitraires sur JSON, vous devez utiliser JSONB.
  • Si vous ne faites rien de ce qui précède, vous devriez probablement utiliser JSON.
  • Si vous devez conserver l'ordre des clés, les espaces et les clés en double, vous devez utiliser JSON.

Pour une réponse plus longue, vous devrez attendre que je rédige un "HowTo" complet plus proche de la version 9.4.

FuzzyChef
la source
74

Une explication simple de la différence entre json et jsonb ( image originale par 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: stockage textuel «tel quel»
  • jsonb: pas d'espaces blancs
  • jsonb: pas de clés en double, dernière victoire de clé
  • jsonb: les clés sont triées

Plus d'informations sur les discours vidéo et les diaporamas présentés par les développeurs de jsonb. Ils ont également introduit JsQuery , pg.extension fournit un puissant langage de requête jsonb

ChelowekKot
la source
1
Merci, je l'ai remplacé par texto
ChelowekKot
56
  • hstore est plus un type de stockage "large colonne", c'est un dictionnaire plat (non imbriqué) de paires clé-valeur, toujours stocké dans un format binaire raisonnablement efficace (une table de hachage, d'où le nom).
  • jsonstocke les documents JSON sous forme de texte, en effectuant une validation lorsque les documents sont stockés et en les analysant sur la sortie si nécessaire (c'est-à-dire en accédant à des champs individuels); il devrait prendre en charge l'intégralité de la spécification JSON. Étant donné que l'intégralité du texte JSON est stockée, sa mise en forme est préservée.
  • jsonbprend des raccourcis pour des raisons de performances: les données JSON sont analysées en entrée et stockées au format binaire, les ordres de touches dans les dictionnaires ne sont pas conservés, et les clés en double non plus. L'accès aux éléments individuels dans le champ JSONB est rapide car il ne nécessite pas d'analyser le texte JSON tout le temps. En sortie, les données JSON sont reconstruites et le formatage initial est perdu.

OMI, il n'y a aucune raison importante de ne pas l' utiliser jsonbune fois qu'il est disponible, si vous travaillez avec des données lisibles par machine.

Ivan Voras
la source
24

JSONB est une "meilleure" version de JSON.

Regardons un exemple:

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 stocke des espaces blancs, c'est pourquoi nous pouvons voir des espaces lorsque la clé "a" est stockée, contrairement à JSONB.
  2. JSON stocke toutes les valeurs de key. C'est la raison pour laquelle vous pouvez voir plusieurs valeurs (2 et 1) par rapport à la clé "a", tandis que JSONB "stocke" uniquement la dernière valeur.
  3. JSON conserve l'ordre dans lequel les éléments sont insérés, tandis que JSONB maintient l'ordre "trié".
  4. Les objets JSONB sont stockés sous forme de fichiers binaires décompressés par opposition aux "données brutes" dans JSON, où aucune nouvelle analyse des données n'est requise pendant la récupération.
  5. JSONB prend également en charge l'indexation, ce qui peut être un avantage significatif.

En général, on devrait préférer JSONB, sauf s'il existe des besoins spécialisés, tels que des hypothèses héritées sur l'ordre des clés d'objet.

subodhkarwa
la source
13

J'étais au pgopen aujourd'hui, les benchmarks sont bien plus rapides que mongodb, je crois que c'était environ 500% plus rapide pour les selects. À peu près tout était plus rapide d'au moins 200% par rapport à mongodb, à l'exception d'une seule mise à jour qui nécessite de réécrire complètement la colonne json entière, ce que mongodb gère mieux.

L'indexation de gin sur jsonb semble incroyable.

Postgres conservera également les types de jsonb en interne et les associera essentiellement à des types tels que numérique, texte, booléen, etc.

Les jointures seront également possibles en utilisant jsonb

Ajoutez PLv8 pour les procédures stockées et ce sera essentiellement un rêve devenu réalité pour les développeurs de node.js.

Le fait qu'il soit stocké en tant que jsonb binaire supprimera également tous les espaces, modifiera l'ordre des propriétés et supprimera les propriétés en double en utilisant la dernière occurrence de la propriété.

En plus de l'index lors d'une requête sur une colonne jsonb contrairement à une colonne json, postgres n'a pas à exécuter la fonctionnalité pour convertir le texte en json sur chaque ligne, ce qui économisera probablement beaucoup de temps seul.

John
la source
8

En ce qui concerne les différences entre les types de données jsonet jsonb, il convient de mentionner l'explication officielle:

PostgreSQL propose deux types de stockage des données JSON: jsonet jsonb. Pour implémenter des mécanismes de requête efficaces pour ces types de données, PostgreSQL fournit également le type de données jsonpath décrit dans la Section 8.14.6 .

Les types de données jsonet jsonbacceptent des ensembles de valeurs presque identiques en entrée. La principale différence pratique est celle de l'efficacité. Le jsontype de données stocke une copie exacte du texte d'entrée, que les fonctions de traitement doivent réanalyser à chaque exécution; tandis que les jsonbdonnées sont stockées dans un format binaire décomposé qui le rend légèrement plus lent à entrer en raison de la surcharge de conversion ajoutée, mais beaucoup plus rapide à traiter, car aucune nouvelle analyse n'est nécessaire. jsonbprend également en charge l'indexation, ce qui peut être un avantage significatif.

Étant donné que le jsontype stocke une copie exacte du texte d'entrée, il préservera l'espace blanc sémantiquement insignifiant entre les jetons, ainsi que l'ordre des clés dans les objets JSON. De plus, si un objet JSON dans la valeur contient plusieurs fois la même clé, toutes les paires clé / valeur sont conservées. (Les fonctions de traitement considèrent la dernière valeur comme opérationnelle.) En revanche, jsonbne conserve pas d'espace blanc, ne préserve pas l'ordre des clés d'objet et ne conserve pas les clés d'objet en double. Si des clés en double sont spécifiées dans l'entrée, seule la dernière valeur est conservée.

En général, la plupart des applications devraient préférer stocker les données JSON sous la forme jsonb, sauf s'il existe des besoins assez spécialisés, tels que des hypothèses héritées sur l'ordre des clés d'objet.

PostgreSQL autorise un seul codage de jeu de caractères par base de données. Il n'est donc pas possible pour les types JSON de se conformer de manière rigide à la spécification JSON à moins que le codage de la base de données soit UTF8. Les tentatives visant à inclure directement des caractères qui ne peuvent pas être représentés dans le codage de la base de données échoueront; à l'inverse, les caractères qui peuvent être représentés dans l'encodage de la base de données mais pas en UTF8 seront autorisés.

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

Dinei
la source
7

Une autre différence importante, qui n'a été mentionnée dans aucune réponse ci-dessus, est qu'il n'y a pas d'opérateur d'égalité pour le jsontype, mais il y en a un pour jsonb.

Cela signifie que vous ne pouvez pas utiliser de DISTINCTmot-clé lors de la sélection de ce jsontype et / ou d'autres champs d'une table (vous pouvez utiliser à la DISTINCT ONplace, mais ce n'est pas toujours possible à cause de cas comme celui-ci ).

vlasiak
la source
6

Autant que je sache,

  • hstore tel qu'il existe actuellement (dans Postgresql 9.3) ne permet pas d'imbriquer d'autres objets et tableaux en tant que valeurs de ses paires clé / valeur. cependant, un futur patch hstore permettra l'imbrication. ce correctif ne sera pas dans la version 9.4 et pourrait ne pas être inclus de sitôt.

  • JSON tel qu'il existe actuellement ne permet pour la nidification, mais est basé sur le texte, et ne permet pas d'indexation, il est donc « lent »

  • jsonb qui sera publié avec 9.4 aura les capacités d'imbrication actuelles de json, ainsi que l'indexation GIN / GIST de hstore, donc ce sera rapide

Les personnes travaillant sur postgresql 9.4 semblent dire que le nouveau type jsonb rapide plaira aux personnes qui auraient choisi d'utiliser un magasin de données noSQL comme MongoDB, mais peuvent désormais combiner une base de données relationnelle avec des données non structurées interrogeables sous un même toit

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

Les repères de postgresql 9.4 jsonb semblent être comparables ou dans certains cas plus rapides que MongoDB

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

erik swedberg
la source