Explicación de JSONB introducido por PostgreSQL

346

PostgreSQL acaba de presentar JSONB y ya está en tendencia en las noticias de hackers . Sería genial si alguien pudiera explicar cómo es diferente de Hstore y JSON previamente presentes en PostgreSQL. ¿Cuáles son sus ventajas y limitaciones y cuándo alguien debería considerar usarlo?

Peeyush
fuente
44
Desde PGCon2014: youtube.com/…
msanford
55
La URL de @CraigRinger no es lo suficientemente precisa, ahora, 1 año después, ni siquiera apunta lo suficientemente cerca del contenido relacionado con JSONB.
berkus
2
@berkus pensé que estaba vinculado a la publicación específica. Que frustrante.
Craig Ringer
1
Señala el video específico.
talonx

Respuestas:

457

Primero, hstorees un módulo contrib, que solo le permite almacenar pares clave => valor, donde las claves y los valores solo pueden ser texts (sin embargo, los valores también pueden ser sql NULLs).

Tanto json& le jsonbpermite almacenar un valor JSON válido (definido en su especificación ).

F.ex. estos son representaciones JSON válidos: null, true, [1,false,"string",{"foo":"bar"}], {"foo":"bar","baz":[null]}- hstorees sólo un poco en comparación con lo subconjunto JSON es capaz (pero si sólo necesita este subconjunto, está bien).

La única diferencia entre json& jsonbes su almacenamiento:

  • json se almacena en su formato de texto plano, mientras
  • jsonb se almacena en alguna representación binaria

Hay 3 consecuencias principales de esto:

  • jsonbgeneralmente toma más espacio en el disco para almacenar que json(a veces no)
  • jsonb toma más tiempo construir desde su representación de entrada que json
  • jsonlas operaciones toman mucho más tiempo que jsonb(y el análisis también debe hacerse cada vez que realiza alguna operación en un jsonvalor escrito)

Cuando jsonbesté disponible con una versión estable, habrá dos casos de uso principales, en los que puede seleccionar fácilmente entre ellos:

  1. Si solo trabaja con la representación JSON en su aplicación, PostgreSQL solo se usa para almacenar y recuperar esta representación, debe usarla json.
  2. Si realiza muchas operaciones en el valor JSON en PostgreSQL, o usa la indexación en algún campo JSON, debe usar jsonb.
pozs
fuente
1
hola, ya que tiene representación binaria, ¿por qué jsonbno admite esto? UPDATE test SET data->'a' = 123 WHERE id = 1;desdeCREATE TABLE test(id SERIAL PRIMARY KEY, data JSONB);
Kokizzu
1
Kokizzu, es posible en 9.5. wiki.postgresql.org/wiki/…
ChelowekKot
1
Sólo para añadir, una de las razones por las que también puede utilizar jsonsobre jsonbes si por razones de herencia su código consumiendo su jsondepende del orden de los jsoncampos y no pueden ser reordenado.
djdrzzy
44
Como, por las razones heredadas: en JSON, no hay diferencia semántica, si los pares clave-valor de un objeto (tabla, mapa, hash, como se llame en el idioma del host) se ordenan de manera diferente. Si confía en eso, en realidad está usando algo diferente a JSON. - Para textvs json.: este último viene con validación JSON, por lo que ante un JSON no válido, solo fallará al insertarlo, en lugar de cada vez que su aplicación lo lea (porque obtiene una representación no válida). Además, puede transmitir este último de forma segura a jsonbla base de datos.
pozs
2
Esta es una excelente publicación para explicar los detalles de implementación de JSONB ( pgeoghegan.blogspot.com/2014/03/what-i-think-of-jsonb.html )
manugupt1
131

Peeyush:

La respuesta corta es:

  • Si está haciendo mucha manipulación JSON dentro de PostgreSQL, como ordenar, cortar, empalmar, etc., debe usar JSONB por razones de velocidad.
  • Si necesita búsquedas indexadas para búsquedas de claves arbitrarias en JSON, entonces debe usar JSONB.
  • Si no está haciendo nada de lo anterior, probablemente debería usar JSON.
  • Si necesita preservar el orden de las claves, el espacio en blanco y las claves duplicadas, debe usar JSON.

Para obtener una respuesta más larga, deberá esperar a que haga una redacción completa de "Cómo hacer" más cerca de la versión 9.4.

FuzzyChef
fuente
74

Una explicación simple de la diferencia entre json y jsonb ( imagen original de 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: almacenamiento de texto «tal cual»
  • jsonb: sin espacios en blanco
  • jsonb: sin claves duplicadas, última clave ganada
  • jsonb: las claves están ordenadas

Más en video de presentación y presentación de diapositivas por desarrolladores jsonb. También presentaron JsQuery , pg.extension proporciona un potente lenguaje de consulta jsonb

ChelowekKot
fuente
1
Gracias, lo he reemplazado por texto
ChelowekKot
56
  • hstore es más un tipo de almacenamiento de "columna ancha", es un diccionario plano (no anidado) de pares clave-valor, siempre almacenado en un formato binario razonablemente eficiente (una tabla hash, de ahí el nombre).
  • jsonalmacena documentos JSON como texto, realiza la validación cuando se almacenan los documentos y los analiza en la salida si es necesario (es decir, accede a campos individuales); Debería admitir toda la especificación JSON. Como se almacena todo el texto JSON, se conserva su formato.
  • jsonbtoma accesos directos por razones de rendimiento: los datos JSON se analizan en la entrada y se almacenan en formato binario, no se mantienen los ordenamientos de las teclas en los diccionarios y tampoco se duplican las claves. Acceder a elementos individuales en el campo JSONB es rápido ya que no requiere analizar el texto JSON todo el tiempo. En la salida, los datos JSON se reconstruyen y se pierde el formato inicial.

En mi opinión, no hay una razón importante para no usar jsonbuna vez que esté disponible, si está trabajando con datos legibles por máquina.

Ivan Voras
fuente
24

JSONB es una versión "mejor" de JSON.

Veamos un ejemplo:

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 almacena espacios en blanco, es por eso que podemos ver espacios cuando se almacena la clave "a", mientras que JSONB no.
  2. JSON almacena todos los valores de clave. Esta es la razón por la que puede ver múltiples valores (2 y 1) contra la clave "a", mientras que JSONB solo "almacena" el último valor.
  3. JSON mantiene el orden en que se insertan los elementos, mientras que JSONB mantiene el orden "ordenado".
  4. Los objetos JSONB se almacenan como binarios descomprimidos en lugar de "datos sin procesar" en JSON, donde no se requiere volver a analizar los datos durante la recuperación.
  5. JSONB también admite indexación, lo que puede ser una ventaja significativa.

En general, uno debería preferir JSONB, a menos que haya necesidades especializadas, como suposiciones heredadas sobre el pedido de claves de objeto.

subodhkarwa
fuente
13

Estuve en el pgopen hoy, los puntos de referencia son mucho más rápidos que mongodb, creo que fue alrededor de un 500% más rápido para los seleccionados. Casi todo fue más rápido al menos en un 200% en comparación con mongodb, que una excepción en este momento es una actualización que requiere reescribir por completo toda la columna json, algo que mongodb maneja mejor.

La indexación de gin en jsonb suena increíble.

También postgres persistirá internamente en tipos de jsonb y básicamente coincidirá con tipos como numérico, texto, booleano, etc.

Las uniones también serán posibles usando jsonb

Agregue PLv8 para los procedimientos almacenados y esto será básicamente un sueño hecho realidad para los desarrolladores de node.js.

Al estar almacenado como binario, jsonb también eliminará todos los espacios en blanco, cambiará el orden de las propiedades y eliminará las propiedades duplicadas utilizando la última aparición de la propiedad.

Además del índice cuando se consulta contra una columna jsonb en contraste con una columna json, los postgres no tienen que ejecutar la funcionalidad para convertir el texto a json en cada fila, lo que probablemente ahorrará una gran cantidad de tiempo solo.

Juan
fuente
8

En cuanto a las diferencias jsony jsonbtipos de datos, vale la pena mencionar la explicación oficial:

PostgreSQL ofrece dos tipos para almacenar datos JSON: jsony jsonb. Para implementar mecanismos de consulta eficientes para estos tipos de datos, PostgreSQL también proporciona el tipo de datos jsonpath descrito en la Sección 8.14.6 .

Los tipos de datos jsony jsonbaceptan conjuntos de valores casi idénticos como entrada. La principal diferencia práctica es la de la eficiencia. El jsontipo de datos almacena una copia exacta del texto de entrada, que las funciones de procesamiento deben analizar en cada ejecución; mientras que los jsonbdatos se almacenan en un formato binario descompuesto que hace que la entrada sea un poco más lenta debido a la sobrecarga de conversión agregada, pero es significativamente más rápido de procesar, ya que no se necesita volver a analizar. jsonbTambién es compatible con la indexación, que puede ser una ventaja significativa.

Debido a que el jsontipo almacena una copia exacta del texto de entrada, conservará espacios en blanco semánticamente insignificantes entre los tokens, así como el orden de las claves dentro de los objetos JSON. Además, si un objeto JSON dentro del valor contiene la misma clave más de una vez, se conservan todos los pares clave / valor. (Las funciones de procesamiento consideran el último valor como el operativo). Por el contrario, jsonbno conserva el espacio en blanco, no conserva el orden de las claves de objeto y no conserva las claves de objeto duplicadas. Si se especifican claves duplicadas en la entrada, solo se conserva el último valor.

En general, la mayoría de las aplicaciones deberían preferir almacenar datos JSON como jsonb, a menos que haya necesidades bastante especializadas, como los supuestos heredados sobre el pedido de claves de objeto.

PostgreSQL solo permite la codificación de un juego de caracteres por base de datos. Por lo tanto, no es posible que los tipos JSON se ajusten rígidamente a la especificación JSON a menos que la codificación de la base de datos sea UTF8. Los intentos de incluir directamente caracteres que no se puedan representar en la codificación de la base de datos fallarán; por el contrario, se permitirán caracteres que se puedan representar en la codificación de la base de datos pero no en UTF8.

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

Dinei
fuente
7

Otra diferencia importante, que no se mencionó en ninguna respuesta anterior, es que no hay un operador de igualdad para el jsontipo, pero sí hay uno para jsonb.

Esto significa que no puede usar la DISTINCTpalabra clave al seleccionar este jsontipo y / u otros campos de una tabla (puede usarlo DISTINCT ONen su lugar, pero no siempre es posible debido a casos como este ).

vlasiak
fuente
6

Por lo que yo puedo decir,

  • hstore como existe actualmente (en Postgresql 9.3) no permite anidar otros objetos y matrices como los valores de sus pares clave / valor. sin embargo, un futuro parche de hstore permitirá anidar. Este parche no se incluirá en la versión 9.4 y es posible que no se incluya pronto.

  • json, tal como existe actualmente , permite el anidamiento, pero está basado en texto y no permite la indexación, por lo tanto, es "lento"

  • jsonb que se lanzará con 9.4 tendrá las capacidades de anidamiento actuales de json, así como la indexación GIN / GIST de hstore, por lo que será rápido

Las personas que trabajan en postgresql 9.4 parecen estar diciendo que el nuevo tipo jsonb rápido atraerá a las personas que habrían optado por usar un almacén de datos noSQL como MongoDB, pero ahora pueden combinar una base de datos relacional con datos no estructurados que se pueden consultar bajo un mismo techo

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

Los puntos de referencia de postgresql 9.4 jsonb parecen estar a la par o, en algunos casos, más rápido que MongoDB

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

erik swedberg
fuente