En MySQL 5.7 se ha agregado un nuevo tipo de datos para almacenar datos JSON en tablas MySQL . Obviamente, será un gran cambio en MySQL. Enumeraron algunos beneficios
Validación de documentos : solo se pueden almacenar documentos JSON válidos en una columna JSON, por lo que obtiene la validación automática de sus datos.
Acceso eficiente : lo que es más importante, cuando almacena un documento JSON en una columna JSON, no se almacena como un valor de texto sin formato. En cambio, se almacena en un formato binario optimizado que permite un acceso más rápido a los miembros del objeto y los elementos de la matriz.
Rendimiento : mejore el rendimiento de su consulta creando índices sobre valores dentro de las columnas JSON. Esto se puede lograr con "índices funcionales" en columnas virtuales.
Conveniencia : la sintaxis en línea adicional para columnas JSON hace que sea muy natural integrar las consultas de documentos en su SQL. Por ejemplo (features.feature es una columna JSON):
SELECT feature->"$.properties.STREET" AS property_street FROM features WHERE id = 121254;
GUAUU ! incluyen algunas características excelentes. Ahora es más fácil manipular los datos. Ahora es posible almacenar datos más complejos en columna. Entonces MySQL ahora tiene sabor a NoSQL.
Ahora puedo imaginar una consulta para datos JSON algo como
SELECT * FROM t1
WHERE JSON_EXTRACT(data,"$.series") IN
(
SELECT JSON_EXTRACT(data,"$.inverted")
FROM t1 | {"series": 3, "inverted": 8}
WHERE JSON_EXTRACT(data,"$.inverted")<4 );
Entonces, ¿puedo almacenar grandes relaciones pequeñas en pocas columnas json? ¿Esta bien? ¿Rompe la normalización? Si esto es posible, supongo que actuará como NoSQL en una columna MySQL . Realmente quiero saber más sobre esta función. Pros y contras del tipo de datos MySQL JSON.
Now it is possible to store more complex data in column
. Tenga cuidadoRespuestas:
El uso de una columna dentro de una expresión o función como esta arruina cualquier posibilidad de que la consulta utilice un índice para ayudar a optimizar la consulta. La consulta que se muestra arriba se ve obligada a realizar un escaneo de tabla.
La afirmación sobre el "acceso eficiente" es engañosa. Significa que después de que la consulta examina una fila con un documento JSON, puede extraer un campo sin tener que analizar el texto de la sintaxis JSON. Pero todavía se necesita un escaneo de tabla para buscar filas. En otras palabras, la consulta debe examinar cada fila.
Por analogía, si estoy buscando en una guía telefónica personas con el nombre de pila "Bill", todavía tengo que leer todas las páginas de la guía telefónica, incluso si los nombres se han resaltado para que sea un poco más rápido detectarlos.
MySQL 5.7 le permite definir una columna virtual en la tabla y luego crear un índice en la columna virtual.
Luego, si consulta la columna virtual, puede usar el índice y evitar el escaneo de la tabla.
Esto es bueno, pero pierde el sentido de usar JSON. La parte atractiva de usar JSON es que le permite agregar nuevos atributos sin tener que hacer ALTER TABLE. Pero resulta que tienes que definir una columna adicional (virtual) de todos modos, si quieres buscar campos JSON con la ayuda de un índice.
Pero no tiene que definir índices y columnas virtuales para cada campo en el documento JSON, solo aquellos en los que desea buscar u ordenar. Podría haber otros atributos en el JSON que solo necesita extraer en la lista de selección como el siguiente:
En general, diría que esta es la mejor manera de usar JSON en MySQL. Solo en la lista de selección.
Cuando hace referencia a columnas en otras cláusulas (JOIN, WHERE, GROUP BY, HAVING, ORDER BY), es más eficiente usar columnas convencionales, no campos dentro de documentos JSON.
Presenté una charla titulada Cómo usar JSON en MySQL incorrectamente en la conferencia Percona Live en abril de 2018. Actualizaré y repetiré la charla en Oracle Code One en el otoño.
Hay otros problemas con JSON. Por ejemplo, en mis pruebas requirió de 2 a 3 veces más espacio de almacenamiento para documentos JSON en comparación con las columnas convencionales que almacenan los mismos datos.
MySQL está promocionando agresivamente sus nuevas capacidades JSON, en gran parte para disuadir a las personas de que no migren a MongoDB. Pero el almacenamiento de datos orientado a documentos como MongoDB es fundamentalmente una forma no relacional de organizar datos. Es diferente a relacional. No digo que una sea mejor que la otra, es solo una técnica diferente, adecuada para diferentes tipos de consultas.
Debe optar por usar JSON cuando JSON hace que sus consultas sean más eficientes.
No elija una tecnología solo porque es nueva o por el bien de la moda.
Editar: Se supone que la implementación de la columna virtual en MySQL usa el índice si su cláusula WHERE usa exactamente la misma expresión que la definición de la columna virtual. Es decir, lo siguiente debe usar el índice en la columna virtual, ya que la columna virtual está definida
AS (JSON_EXTRACT(data,"$.series"))
Excepto que, al probar esta función, descubrí que NO funciona por alguna razón si la expresión es una función de extracción JSON. Funciona para otros tipos de expresiones, pero no para funciones JSON.
fuente
JOIN
,WHERE
u otras cláusulas. Simplemente busque la columna JSON en la lista de selección.Lo siguiente de MySQL 5.7 trae de vuelta lo sexy con JSON me suena bien:
...
Tenga en cuenta el lenguaje sobre la validación de documentos, ya que es un factor importante. Supongo que es necesario realizar una serie de pruebas para comparar los dos enfoques. Esos dos son:
La red tiene slideshares poco profundos a partir de ahora sobre el tema de mysql / json / performance por lo que estoy viendo.
Quizás tu publicación pueda ser un centro para ello. O tal vez el rendimiento es un pensamiento posterior, no estoy seguro, y simplemente está emocionado de no crear un montón de tablas.
fuente
[citation required]
¿ha comparado esa unidad con la RAM?Me metí en este problema recientemente y resumo las siguientes experiencias:
1. No hay forma de resolver todas las preguntas. 2, debes usar el JSON correctamente.
Un caso:
Tengo una tabla llamada:,
CustomField
y debe tener dos columnas:name
,fields
.name
es una cadena localizada, su contenido debería gustar:Y
fields
debería ser así:Como puede ver, tanto el
name
como elfields
se pueden guardar como JSON, ¡y funciona!Sin embargo, si utilizo el
name
para buscar en esta tabla con mucha frecuencia, ¿qué debo hacer? Utilice elJSON_CONTAINS
,JSON_EXTRACT
...? Obviamente, no es una idea buena para guardarlo como JSON más, debemos guardarlo en una tabla independiente:CustomFieldName
.Del caso anterior, creo que debes tener en cuenta estas ideas:
Gracias
fuente
Desde mi experiencia, la implementación de JSON al menos en MySql 5.7 no es muy útil debido a su bajo rendimiento. Bueno, no es tan malo para la lectura de datos y la validación. Sin embargo, la modificación de JSON es de 10 a 20 veces más lenta con MySql que con Python o PHP. Imaginemos JSON muy simple:
Supongamos que tenemos que convertirlo en algo así:
Puede crear un script simple con Python o PHP que seleccionará todas las filas y las actualizará una por una. No está obligado a realizar una gran transacción para ello, por lo que otras aplicaciones pueden utilizar la tabla en paralelo. Por supuesto, también puede realizar una gran transacción si lo desea, por lo que tendrá la garantía de que MySql realizará "todo o nada", pero otras aplicaciones probablemente no podrán utilizar la base de datos durante la ejecución de la transacción.
Tengo una tabla de 40 millones de filas y la secuencia de comandos de Python la actualiza en 3-4 horas.
Ahora tenemos MySql JSON, por lo que ya no necesitamos Python o PHP, podemos hacer algo como eso:
Parece simple y excelente. Sin embargo, su velocidad es de 10 a 20 veces más lenta que la versión de Python, y es una transacción única, por lo que otras aplicaciones no pueden modificar los datos de la tabla en paralelo.
Por lo tanto, si solo queremos duplicar la clave JSON en una tabla de 40 millones de filas, no necesitamos usar la tabla en absoluto durante 30-40 horas. No tiene sentido.
Acerca de la lectura de datos, desde mi experiencia, el acceso directo al campo JSON a través de
JSON_EXTRACT
inWHERE
también es extremadamente lento (mucho más lento queTEXT
conLIKE
una columna no indexada). Las columnas generadas virtuales funcionan mucho más rápido, sin embargo, si conocemos nuestra estructura de datos de antemano, no necesitamos JSON, podemos usar columnas tradicionales en su lugar. Cuando usamos JSON donde es realmente útil, es decir, cuando la estructura de datos es desconocida o cambia con frecuencia (por ejemplo, la configuración de complementos personalizados), la creación de columnas virtuales de forma regular para cualquier posible nueva columna no parece una buena idea.Python y PHP hacen que la validación de JSON sea un encanto, por lo que es cuestionable si necesitamos la validación de JSON en el lado de MySql. ¿Por qué no también validar XML, documentos de Microsoft Office o revisar la ortografía? ;)
fuente