Dans MySQL 5.7, un nouveau type de données pour stocker des données JSON dans des tables MySQL a été ajouté. Ce sera évidemment un grand changement dans MySQL. Ils ont énuméré certains avantages
Validation de document - Seuls les documents JSON valides peuvent être stockés dans une colonne JSON, vous obtenez ainsi une validation automatique de vos données.
Accès efficace - Plus important encore, lorsque vous stockez un document JSON dans une colonne JSON, il n'est pas stocké en tant que valeur de texte brut. Au lieu de cela, il est stocké dans un format binaire optimisé qui permet un accès plus rapide aux membres d'objet et aux éléments du tableau.
Performances - Améliorez les performances de vos requêtes en créant des index sur les valeurs dans les colonnes JSON. Ceci peut être réalisé avec des «index fonctionnels» sur des colonnes virtuelles.
Commodité - La syntaxe en ligne supplémentaire pour les colonnes JSON rend très naturel l'intégration des requêtes Document dans votre SQL. Par exemple (features.feature est une colonne JSON):
SELECT feature->"$.properties.STREET" AS property_street FROM features WHERE id = 121254;
HOU LA LA ! ils incluent quelques fonctionnalités intéressantes. Il est désormais plus facile de manipuler les données. Il est désormais possible de stocker des données plus complexes en colonne. MySQL est donc désormais parfumé avec NoSQL.
Maintenant, je peux imaginer une requête pour les données JSON quelque chose comme
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 );
Alors, puis-je stocker d'énormes petites relations dans quelques json colum? Est-ce bien? Cela brise-t-il la normalisation. Si cela est possible, je suppose que cela fonctionnera comme NoSQL dans une colonne MySQL . Je veux vraiment en savoir plus sur cette fonctionnalité. Avantages et inconvénients du type de données MySQL JSON.
Now it is possible to store more complex data in column
. Soyez prudentRéponses:
L'utilisation d'une colonne dans une expression ou une fonction comme celle-ci gâche toute chance que la requête utilise un index pour aider à optimiser la requête. La requête présentée ci-dessus est obligée de faire une analyse de table.
L'affirmation relative à un "accès efficace" est trompeuse. Cela signifie qu'après que la requête examine une ligne avec un document JSON, elle peut extraire un champ sans avoir à analyser le texte de la syntaxe JSON. Mais il faut toujours une analyse de table pour rechercher des lignes. En d'autres termes, la requête doit examiner chaque ligne.
Par analogie, si je recherche dans l'annuaire des personnes avec le prénom «Bill», je dois quand même lire toutes les pages de l'annuaire, même si les prénoms ont été mis en surbrillance pour les repérer un peu plus rapidement.
MySQL 5.7 vous permet de définir une colonne virtuelle dans la table, puis de créer un index sur la colonne virtuelle.
Ensuite, si vous interrogez la colonne virtuelle, elle peut utiliser l'index et éviter le balayage de table.
C'est bien, mais cela manque un peu l'intérêt d'utiliser JSON. L'avantage de l'utilisation de JSON est qu'il vous permet d'ajouter de nouveaux attributs sans avoir à faire ALTER TABLE. Mais il s'avère que vous devez tout de même définir une colonne supplémentaire (virtuelle), si vous souhaitez rechercher des champs JSON à l'aide d'un index.
Mais vous n'êtes pas obligé de définir des colonnes et des index virtuels pour chaque champ du document JSON, uniquement ceux sur lesquels vous souhaitez rechercher ou trier. Il peut y avoir d'autres attributs dans le JSON que vous n'avez besoin d'extraire que dans la liste de sélection, comme suit:
Je dirais généralement que c'est la meilleure façon d'utiliser JSON dans MySQL. Uniquement dans la liste de sélection.
Lorsque vous référencez des colonnes dans d'autres clauses (JOIN, WHERE, GROUP BY, HAVING, ORDER BY), il est plus efficace d'utiliser des colonnes conventionnelles, et non des champs dans des documents JSON.
J'ai présenté une conférence intitulée Comment utiliser JSON dans MySQL Wrong lors de la conférence Percona Live en avril 2018. Je mettrai à jour et répéterai la conférence à Oracle Code One à l'automne.
Il y a d'autres problèmes avec JSON. Par exemple, dans mes tests, il a fallu 2-3 fois plus d'espace de stockage pour les documents JSON par rapport aux colonnes conventionnelles stockant les mêmes données.
MySQL fait la promotion de ses nouvelles capacités JSON de manière agressive, en grande partie pour dissuader les gens de migrer vers MongoDB. Mais le stockage de données orienté document comme MongoDB est fondamentalement un moyen non relationnel d'organiser les données. C'est différent du relationnel. Je ne dis pas que l'un est meilleur que l'autre, c'est juste une technique différente, adaptée à différents types de requêtes.
Vous devez choisir d'utiliser JSON lorsque JSON rend vos requêtes plus efficaces.
Ne choisissez pas une technologie simplement parce qu'elle est nouvelle ou pour des raisons de mode.
Edit: L'implémentation de la colonne virtuelle dans MySQL est censée utiliser l'index si votre clause WHERE utilise exactement la même expression que la définition de la colonne virtuelle. Autrement dit, ce qui suit doit utiliser l'index sur la colonne virtuelle, car la colonne virtuelle est définie
AS (JSON_EXTRACT(data,"$.series"))
Sauf que j'ai trouvé en testant cette fonctionnalité qu'elle ne fonctionne PAS pour une raison quelconque si l'expression est une fonction d'extraction JSON. Cela fonctionne pour d'autres types d'expressions, mais pas pour les fonctions JSON.
la source
JOIN
,WHERE
ou d' autres clauses. Récupérez simplement la colonne JSON dans la liste de sélection.Ce qui suit de MySQL 5.7 me ramène sexy avec JSON :
...
Notez le langage concernant la validation des documents car il s'agit d'un facteur important. Je suppose qu'une batterie de tests doit être effectuée pour comparer les deux approches. Ces deux étant:
Le net n'a que des diaporamas peu profonds pour le moment sur le sujet de mysql / json / performance d'après ce que je vois.
Peut-être que votre message peut être une plaque tournante pour cela. Ou peut-être que la performance est une réflexion après coup, pas sûr, et que vous êtes juste excité de ne pas créer un tas de tables.
la source
[citation required]
avez-vous comparé ce lecteur à la RAM?J'ai récemment rencontré ce problème et je résume les expériences suivantes:
1, il n'y a pas de moyen de résoudre toutes les questions. 2, vous devez utiliser le JSON correctement.
Un cas:
J'ai une table nommée:,
CustomField
et elle doit avoir deux colonnes:name
,fields
.name
est une chaîne localisée, son contenu devrait ressembler à:Et
fields
devrait être comme ça:Comme vous pouvez le voir, le
name
et lefields
peuvent être enregistrés au format JSON, et cela fonctionne!Cependant, si j'utilise le
name
pour rechercher très fréquemment dans ce tableau, que dois-je faire? Utilisez leJSON_CONTAINS
,JSON_EXTRACT
...? De toute évidence, ce n'est pas une bonne idée de l' enregistrer comme JSON plus, nous devrions enregistrer à une table indépendante:CustomFieldName
.Dans le cas ci-dessus, je pense que vous devriez garder ces idées à l'esprit:
Merci
la source
D'après mon expérience, l'implémentation JSON au moins dans MySql 5.7 n'est pas très utile en raison de ses mauvaises performances. Eh bien, ce n'est pas si mal pour la lecture des données et la validation. Cependant, la modification JSON est 10 à 20 fois plus lente avec MySql qu'avec Python ou PHP. Imaginons un JSON très simple:
Supposons que nous devions le convertir en quelque chose comme ça:
Vous pouvez créer un script simple avec Python ou PHP qui sélectionnera toutes les lignes et les mettra à jour une par une. Vous n'êtes pas obligé de faire une énorme transaction pour cela, donc d'autres applications pourront utiliser la table en parallèle. Bien sûr, vous pouvez également faire une énorme transaction si vous le souhaitez, vous aurez donc la garantie que MySql effectuera "tout ou rien", mais d'autres applications ne pourront probablement pas utiliser la base de données pendant l'exécution de la transaction.
J'ai une table de 40 millions de lignes et le script Python la met à jour en 3-4 heures.
Maintenant, nous avons MySql JSON, donc nous n'avons plus besoin de Python ou PHP, nous pouvons faire quelque chose comme ça:
Cela a l'air simple et excellent. Cependant, sa vitesse est 10 à 20 fois plus lente que la version Python et il s'agit d'une transaction unique, de sorte que les autres applications ne peuvent pas modifier les données de la table en parallèle.
Donc, si nous voulons simplement dupliquer la clé JSON dans une table de 40 millions de lignes, nous ne devons pas utiliser de table du tout pendant 30 à 40 heures. Cela n'a aucun sens.
À propos de la lecture des données, d'après mon expérience, l'accès direct au champ JSON via
JSON_EXTRACT
inWHERE
est également extrêmement lent (beaucoup plus lentTEXT
qu'avec uneLIKE
colonne non indexée). Les colonnes générées virtuelles fonctionnent beaucoup plus rapidement, cependant, si nous connaissons notre structure de données à l'avance, nous n'avons pas besoin de JSON, nous pouvons utiliser des colonnes traditionnelles à la place. Lorsque nous utilisons JSON là où c'est vraiment utile, c'est-à-dire lorsque la structure des données est inconnue ou change souvent (par exemple, les paramètres de plug-in personnalisés), la création régulière de colonnes virtuelles pour d'éventuelles nouvelles colonnes ne semble pas être une bonne idée.Python et PHP font de la validation JSON un charme, il est donc douteux que nous ayons besoin d'une validation JSON du côté de MySql. Pourquoi ne pas valider également les documents XML, Microsoft Office ou vérifier l'orthographe? ;)
la source