web-dev-qa-db-fra.com

Quand puis-je sauvegarder des données JSON ou XML dans une table SQL

Lorsque vous utilisez SQL ou MySQL (ou toute autre base de données relationnelle), je comprends que l'enregistrement des données dans des colonnes normales est préférable pour l'indexation et d'autres objectifs ...

Le problème est de charger et d’enregistrer JSON les données sont parfois beaucoup plus simples. et facilite le développement.

Existe-t-il des "règles d'or" pour la sauvegarde des données brutes JSON dans la base de données?

est-ce une pratique absolument fausse de le faire?

SOMMAIRE

De très jolies réponses ont été données, mais la plus organisée est sans aucun doute la réponse donnée par @Shnugo qui mérite la prime.

J'aimerais également souligner les réponses données par @Gordon Linoff et @Amresh Pandey pour expliquer d'autres cas d'utilisation spéciaux.

Dieu merci, et bon travail à tous!

49
levi

Les principales questions sont

  • Qu'allez-vous faire avec ces données? et
  • Comment filtrez-vous/triez-vous/joignez-vous/manipulez-vous ces données?

JSON (comme XML) est idéal pour l'échange de données, le stockage réduit et les structures définies de manière générique, mais il ne peut pas participer aux actions typiques que vous exécutez dans votre SGBDR. Dans la plupart des cas, il est préférable de transférer vos données JSON dans des tables normales et de recréer le JSON lorsque vous en avez besoin.

XML/JSON et 1.NF

La première règle de normalisation impose de ne jamais stocker plus d'un bit d'information dans une colonne. Vous voyez une colonne "PersonName" avec une valeur comme "Mickey Mouse"? Vous pointez ceci et criez: Modifiez cela immédiatement!

Qu'en est-il de XML ou de JSON? Est-ce que ces types cassent 1.NF? Eh bien oui et non ...

Il est parfaitement correct de stocker une structure complète sous la forme d’un bit d’information s’il s’agit d’un bit d’information en fait. Vous obtenez une réponse SOAP et souhaitez la stocker, car vous en aurez peut-être besoin comme référence ultérieure (mais vous n'utiliserez pas ces données pour vos propres processus )? Il suffit de le stocker tel quel !

Imaginons maintenant une structure complexe (XML ou JSON) représentant une personne (avec son adresse, plus de détails ...). Maintenant, vous mettez ceci dans une colonne sous la forme PersonInCharge. Est-ce faux? Cela ne devrait-il pas plutôt vivre dans des tables liées correctement conçues avec une référence de clé étrangère au lieu de XML/JSON? Surtout si la même personne peut apparaître dans plusieurs rangées différentes, il est définitivement faux d'utiliser une approche XML/JSON.

Mais maintenant, imaginez la nécessité de stocker des données historiques. Vous souhaitez persister les données de la personne pour un moment donné. Quelques jours plus tard, la personne vous dit une nouvelle adresse? Aucun problème! L'ancienne adresse réside dans un XML/JSON si vous en avez besoin ...

Conclusion: Si vous stockez les données simplement pour les conserver, c'est bon. Si cette donnée est une partie unique , ça va ...
Mais si vous avez besoin des pièces internes régulièrement ou si cela signifie un stockage redondant en double, cela ne va pas ...

Stockage physique

Ce qui suit est pour SQL Server et peut être différent sur d'autres RDBM.

XML n'est pas stocké en tant que texte que vous voyez, mais sous forme d'arborescence. Interroger cela est étonnamment performant! Cette structure n'est pas analysée au niveau des chaînes!
JSON dans SQL Server (2016+) vit dans une chaîne et doit être analysé. Il n'y a pas de type JSON natif réel (comme il existe un type XML natif). Cela pourrait arriver plus tard, mais pour le moment je suppose, JSON ne sera pas aussi performant que XML sur SQL Server (voir la section UPDATE 2 ). Tout besoin de lire une valeur hors JSON nécessitera un sacré tas d'appels de méthodes de chaîne cachée ...

Qu'est-ce que cela signifie pour toi?

votre adorable artiste de base de données :-D sait que stocker JSON tel quel , va à l’encontre des principes communs des RDBM. Il sait,

  • qu'un JSON casse probablement 1.NF
  • jSON peut changer dans le temps (même colonne, contenu différent).
  • jSON n’est pas facile à lire, et il est très difficile de filtrer/rechercher/rejoindre ou de trier par lui.
  • que de telles opérations déplaceront une charge supplémentaire sur un petit serveur DB médiocre

Il existe certaines solutions (en fonction du SGBDR que vous utilisez), mais la plupart d'entre elles ne fonctionnent pas comme vous le souhaitez ...

La réponse à votre question en bref

OUI

  • Si vous ne souhaitez pas utiliser de données, celles-ci sont stockées dans votre JSON pour des opérations coûteuses (filtre/rejoindre/trier).
    Vous pouvez le stocker comme n'importe quel autre contenu n’existe que . Nous stockons beaucoup d'images sous forme de BLOB, mais nous n'essaierions pas de filtrer toutes les images avec une fleur ...
  • Si vous ne vous souciez pas du tout de ce qui se trouve à l'intérieur (stockez-le et lisez-le comme un élément d'information)
  • Si les structures sont variables, il serait plus difficile de créer des tables physiques que de travailler avec des données JSON.
  • Si la structure est profondément imbriquée, le stockage dans les tables physiques est beaucoup trop onéreux

NON

  • Si vous souhaitez utiliser les données internes comme vous utiliseriez les données d'une table relationnelle (filtre, index, jointures, etc.)
  • Si vous voulez stocker des doublons (créer une redondance)
  • En général: Si vous rencontrez des problèmes de performances (vous serez certainement confrontés à de nombreux scénarios typiques!)

Vous pouvez commencer par le code JSON dans une colonne de chaîne ou en tant que BLOB et le remplacer par des tables physiques lorsque vous en avez besoin. Ma boule de cristal magique me dit que cela pourrait être demain :-D

MISE À JOUR

Trouvez quelques idées sur les performances et l'espace disque ici: https://stackoverflow.com/a/47408528/5089204

UPDATE 2: Plus sur la performance ...

Les adresses suivantes prennent en charge JSON et XML dans SQL-Server 2016

Utilisateur @ mike123 a indiqué un article sur un blog officiel de Microsoft qui semble prouver dans une expérience que interroger un JSON est 10 x plus rapide puis interroge un XML dans SQL-Server.

Quelques réflexions à ce sujet:

Quelques recoupements avec "l'expérience":

  • le "test" mesure beaucoup, mais pas les performances de XML par rapport à JSON . Faire la même action contre la même chaîne (inchangée) à plusieurs reprises n'est pas un scénario réaliste
  • Les exemples testés sont bien trop simples pour un énoncé général !
  • La valeur lue est toujours la même et n'est même pas utilisée. L'optimiseur verra cela ...
  • Pas un seul mot sur le puissant support XQuery! Trouver un produit avec un identifiant donné dans un tableau? JSON doit lire la totalité du texte et utiliser un filtre à l'aide de WHERE, alors que XML autoriserait un XQuery predicate interne. Sans parler de FLWOR...
  • le code "expérimental" tel quel sur mon système s'affiche: JSON semble être 3 fois plus rapide (mais pas 10 fois).
  • Ajouter /text() au XPath réduit ce nombre à moins de 2x . Dans l'article lié, l'utilisateur "Mister Magoo" l'a déjà souligné, mais le titre de click-bait reste inchangé ...
  • Avec un JSON aussi simple que celui indiqué dans l '"expérience", l'approche T-SQL pure la plus rapide consistait à associer SUBSTRING et CHARINDEX :-D.

Le code suivant montrera une expérience plus réaliste

  • Utilisation d'un JSON et d'un XML identique avec plusieurs Product (un tableau JSON par rapport à des nœuds frères)
  • JSON et XML changent légèrement (10 000 numéros en cours d'exécution) et sont insérés dans des tableaux.
  • Il y a un appel initial contre les deux tables pour éviter le biais du premier appel
  • Toutes les 10000 entrées sont lues et les valeurs extraites sont insérées dans une autre table.
  • Utiliser GO 10 parcourra ce bloc dix fois pour éviter le biais du premier appel

Le résultat final montre clairement que JSON est plus lent que XML (pas beaucoup, environ 1,5x sur un exemple encore très simple).

La déclaration finale:

  • Avec un exemple trop simplifié dans des circonstances excessives, JSON peut être plus rapide que XML
  • Traiter avec JSON est une action de chaîne pure , tandis que XML est analysé et transformé. Cela coûte assez cher lors de la première action, mais accélérera tout, une fois que cela sera fait.
  • JSON peut être préférable dans une action unique (évite la surcharge liée à la création d'une représentation hiérarchique interne d'un XML)
  • Avec un exemple encore très simple mais plus réaliste, XML sera plus rapide en lecture simple
  • Chaque fois qu'il est nécessaire de lire un élément spécifique dans un tableau, de filtrer toutes les entrées contenant un ID de produit donné ou de naviguer dans le chemin, JSON ne peut pas résister. Il faut l’analyser complètement dans une chaîne - à chaque fois que vous devez la saisir ...

Le code de test

USE master;
GO
--create a clean database
CREATE DATABASE TestJsonXml;
GO
USE TestJsonXml;
GO
--create tables
CREATE TABLE TestTbl1(ID INT IDENTITY,SomeXml XML);
CREATE TABLE TestTbl2(ID INT IDENTITY,SomeJson NVARCHAR(MAX));
CREATE TABLE Target1(SomeString NVARCHAR(MAX));
CREATE TABLE Target2(SomeString NVARCHAR(MAX));
CREATE TABLE Times(Test VARCHAR(10),Diff INT)
GO
--insert 10000 XMLs into TestTbl1
WITH Tally AS(SELECT TOP 10000 ROW_NUMBER() OVER(ORDER BY (SELECT NULL))*2 AS Nmbr FROM master..spt_values AS v1 CROSS APPLY master..spt_values AS v2)
INSERT INTO TestTbl1(SomeXml)
SELECT 
N'<Root>
    <Products>
    <ProductDescription>
        <Features>
            <Maintenance>' + CAST(Nmbr AS NVARCHAR(10)) + ' year parts and labor extended maintenance is available</Maintenance>
            <Warranty>1 year parts and labor</Warranty>
        </Features>
        <ProductID>' + CAST(Nmbr AS NVARCHAR(10)) + '</ProductID>
        <ProductName>Road Bike</ProductName>
    </ProductDescription>
    <ProductDescription>
        <Features>
            <Maintenance>' + CAST(Nmbr + 1 AS NVARCHAR(10)) + ' blah</Maintenance>
            <Warranty>1 year parts and labor</Warranty>
        </Features>
        <ProductID>' + CAST(Nmbr + 1 AS NVARCHAR(10)) + '</ProductID>
        <ProductName>Cross Bike</ProductName>
    </ProductDescription>
    </Products>
</Root>'
FROM Tally;

--insert 10000 JSONs into TestTbl2
WITH Tally AS(SELECT TOP 10000 ROW_NUMBER() OVER(ORDER BY (SELECT NULL)) AS Nmbr FROM master..spt_values AS v1 CROSS APPLY master..spt_values AS v2)
INSERT INTO TestTbl2(SomeJson)
SELECT 
N'{
    "Root": {
        "Products": {
            "ProductDescription": [
                {
                    "Features": {
                        "Maintenance": "' + CAST(Nmbr AS NVARCHAR(10)) + ' year parts and labor extended maintenance is available",
                        "Warranty": "1 year parts and labor"
                    },
                    "ProductID": "' + CAST(Nmbr AS NVARCHAR(10)) + '",
                    "ProductName": "Road Bike"
                },
                {
                    "Features": {
                        "Maintenance": "' + CAST(Nmbr + 1 AS NVARCHAR(10)) + ' blah",
                        "Warranty": "1 year parts and labor"
                    },
                    "ProductID": "' + CAST(Nmbr + 1 AS NVARCHAR(10)) + '",
                    "ProductName": "Cross Bike"
                }
            ]
        }
    }
}'
FROM Tally;
GO

--Do some initial action to avoid first-call-bias
INSERT INTO Target1(SomeString)
SELECT SomeXml.value('(/Root/Products/ProductDescription/Features/Maintenance/text())[1]', 'nvarchar(4000)')
FROM TestTbl1;
INSERT INTO Target2(SomeString)
SELECT JSON_VALUE(SomeJson, N'$.Root.Products.ProductDescription[0].Features.Maintenance')
FROM TestTbl2;
GO

--Start the test
DECLARE @StartDt DATETIME2(7), @EndXml DATETIME2(7), @EndJson DATETIME2(7);

--Read all ProductNames of the second product and insert them to Target1
SET @StartDt = SYSDATETIME();
INSERT INTO Target1(SomeString)
SELECT SomeXml.value('(/Root/Products/ProductDescription/ProductName/text())[2]', 'nvarchar(4000)')
FROM TestTbl1
ORDER BY NEWID();
--remember the time spent
INSERT INTO Times(Test,Diff)
SELECT 'xml',DATEDIFF(millisecond,@StartDt,SYSDATETIME());

--Same with JSON into Target2
SET @StartDt = SYSDATETIME();
INSERT INTO Target2(SomeString)
SELECT JSON_VALUE(SomeJson, N'$.Root.Products.ProductDescription[1].ProductName')
FROM TestTbl2
ORDER BY NEWID();
--remember the time spent
INSERT INTO Times(Test,Diff)
SELECT 'json',DATEDIFF(millisecond,@StartDt,SYSDATETIME());

GO 10 --do the block above 10 times

--Show the result
SELECT Test,SUM(Diff) AS SumTime, COUNT(Diff) AS CountTime
FROM Times
GROUP BY Test;
GO
--clean up
USE master;
GO
DROP DATABASE TestJsonXml;
GO

Le résultat (SQL Server 2016 Express sur un processeur Acer Aspire v17 Intel i7, 8 Go)

Test    SumTime 
------------------
json    2706    
xml     1604    
64
Shnugo

C'est trop long pour un commentaire.

S'il était "absolument faux", la plupart des bases de données ne le prendraient pas en charge. D'accord, la plupart des bases de données prennent en charge les virgules dans la clause FROM et je considère cela comme "absolument faux". Mais la prise en charge de JSON est un nouveau développement et non une "fonctionnalité" compatible avec les versions antérieures.

Un cas évident est lorsque la structure JSON est simplement un BLOB qui est renvoyé à l'application. Ensuite, il n’ya pas de débat - autre que la surcharge liée au stockage de JSON, qui est inutilement détaillé pour les données structurées avec des champs communs dans chaque enregistrement.

Un autre cas est celui des colonnes "clairsemées". Vous avez des lignes avec beaucoup de colonnes possibles, mais celles-ci varient d'une ligne à l'autre.

Vous pouvez également stocker des enregistrements "imbriqués" dans un enregistrement. JSON est puissant.

Si le JSON comporte des champs communs aux enregistrements sur lesquels vous souhaitez interroger, il est généralement préférable de les placer dans les colonnes de base de données appropriées. Cependant, les données sont compliquées et il existe une place pour des formats tels que JSON.

12
Gordon Linoff

Je vais agiter ma baguette magique. Pouf! Règles d'or sur l'utilisation de JSON:

  • Si MySQL n'a pas besoin de regarder à l'intérieur du JSON et que l'application a simplement besoin d'une collection de choses, alors JSON va bien, peut-être même mieux.

  • Si vous recherchez des données à l'intérieur et , vous avez MariaDB 10.0.1 ou MySQL 5.7 (avec un type de données et des fonctions JSON), puis JSON pourrait être pratique. Les colonnes "dynamiques" de MariaDB 5.3 en sont une variante.

  • Si vous faites des choses "Entity-Attribute-Value", alors JSON n'est pas bon, mais c'est le moindre de plusieurs maux. http://mysql.rjweb.org/doc.php/eav

  • Pour rechercher dans une colonne indexée, ne pas avoir la valeur enfouie dans JSON est un gros plus.

  • Pour la recherche par plage dans une colonne indexée, ou FULLTEXT recherche ou SPATIAL, JSON n'est pas possible.

  • Pour WHERE a=1 AND b=2 l'index "composite" INDEX(a,b) est génial; ne peut probablement pas être proche avec JSON.

  • JSON fonctionne bien avec les données "clairsemées"; INDEXing fonctionne, mais pas aussi bien, avec tel. (Je fais référence à des valeurs qui sont "manquantes" ou NULL pour beaucoup de lignes.)

  • JSON peut vous donner des "tableaux" et des "arbres" sans recourir à des tables supplémentaires. Mais creuser dans ces tableaux/arbres seulement dans l'application, pas dans SQL.

  • JSON est un monde meilleur que XML. (Mon avis)

  • Si vous ne voulez pas entrer dans la chaîne JSON sauf à partir de l'application, je vous recommande de le compresser (dans le client) pour le stocker dans un BLOB. Pensez-y comme un fichier .jpg - il y a des choses là-dedans, mais SQL ne s'en soucie pas.

Énoncez votre demande. peut-être pouvons-nous être plus précis.

11
Rick James

Nouveau SQL Server fournit des fonctions pour le traitement de texte JSON. Les informations au format JSON peuvent être stockées sous forme de texte dans des colonnes SQL Server standard. SQL Server fournit des fonctions permettant d'extraire des valeurs de ces objets JSON.

    DROP TABLE IF EXISTS Person

 CREATE TABLE Person 
 ( _id int identity constraint PK_JSON_ID primary key,
 value nvarchar(max)
 CONSTRAINT [Content should be formatted as JSON]
 CHECK ( ISJSON(value)>0 )
 )

Cette structure simple est similaire à la collection NoSQL standard que vous pouvez créer dans des bases de données NoSQL (Azure DocumentDB ou MongoDB, par exemple) dans laquelle vous ne disposez que d'une clé représentant l'ID et d'une valeur représentant le JSON.

Notez que NVARCHAR n'est pas simplement un texte brut. SQL Server possède un mécanisme de compression de texte intégré capable de compresser de manière transparente les données stockées sur le disque. La compression dépend de la langue et peut aller jusqu'à 50% en fonction de vos données (voir Compression UNICODE).

La principale différence entre SQL Server et les autres bases de données NoSQL simples réside dans le fait que SQL Server vous permet d'utiliser un modèle de données hybride dans lequel vous pouvez stocker plusieurs objets JSON dans la même "collection" et les combiner avec des colonnes relationnelles classiques.

Par exemple, imaginons que nous savons que chaque personne de votre collection aura FirstName et LastName, et que vous pouvez stocker des informations générales sur la personne sous la forme d'un objet JSON, ainsi que des numéros de téléphone/adresses électroniques sous la forme d'objets distincts. Dans SQL Server 2016, nous pouvons facilement créer cette structure sans aucune syntaxe supplémentaire:

DROP TABLE IF EXISTS Person

CREATE TABLE Person (

 PersonID int IDENTITY PRIMARY KEY,

 FirstName nvarchar(100) NOT NULL,

 LastName nvarchar(100) NOT NULL,

 AdditionalInfo nvarchar(max) NULL,

 PhoneNumbers nvarchar(max) NULL,

 EmailAddresses nvarchar(max) NULL
 CONSTRAINT [Email addresses must be formatted as JSON array]
 CHECK ( ISJSON(EmailAddresses)>0 )

 )

Au lieu d'un seul objet JSON, vous pouvez organiser vos données dans cette "collection". Si vous ne souhaitez pas vérifier explicitement la structure de chaque colonne JSON, il n'est pas nécessaire d'ajouter une contrainte de vérification JSON à chaque colonne (dans cet exemple, j'ai ajouté la contrainte CHECK uniquement à la colonne EmailAddresses).

Si vous comparez cette structure à la collection NoSQL standard, vous remarquerez peut-être que vous aurez un accès plus rapide aux données fortement typées (Prénom et Nom). Par conséquent, cette solution constitue un choix judicieux pour les modèles hybrides dans lesquels vous pouvez identifier certaines informations répétées sur tous les objets, tandis que d'autres informations variables peuvent être stockées au format JSON. De cette façon, vous pouvez combiner flexibilité et performance.

Si vous comparez cette structure avec le schéma de la base de données AdventureWorks de la table Person, vous remarquerez peut-être que nous avons supprimé de nombreuses tables associées.

Outre la simplicité du schéma, vos opérations d’accès aux données seront simplifiées par rapport à une structure relationnelle complexe. Vous pouvez maintenant lire une seule table au lieu de joindre plusieurs tables. Lorsque vous devez insérer une nouvelle personne avec des informations associées (adresses e-mail, numéros de téléphone), vous pouvez insérer un seul enregistrement dans une table au lieu de l'insérer dans la table AdventureWorks, en prenant la colonne identité pour trouver la clé étrangère utilisée pour stocker les téléphones. , adresses e-mail, etc. En outre, dans ce modèle, vous pouvez facilement supprimer une ligne à une seule personne sans les supprimer en cascade à l'aide de relations de clé étrangère.

Les bases de données NoSQL sont optimisées pour des opérations simples, de lecture, d'insertion et de suppression - SQL Server 2016 vous permet d'appliquer la même logique dans une base de données relationnelle.

Contraintes JSON Dans les exemples précédents, nous avons vu comment ajouter une contrainte simple qui valide que le texte stocké dans la colonne est correctement formaté. Bien que JSON n'ait pas de schéma solide, vous pouvez également ajouter des contraintes complexes en combinant des fonctions lisant les valeurs à partir de JSON et des fonctions T-SQL standard:

ALTER TABLE Person
 ADD CONSTRAINT [Age should be number]
 CHECK ( ISNUMERIC(JSON_VALUE(value, '$.age'))>0 )

 ALTER TABLE Person
 ADD CONSTRAINT [Person should have skills]
 CHECK ( JSON_QUERY(value, '$.skills') IS NOT NULL)
First constraint will take the value of $.age property and check is this numeric value. Second constraint will try to find JSON object in $.skills property and verify that it exists. The following INSERT statements will fail due to the violation of constraints:



INSERT INTO Person(value)
 VALUES ('{"age": "not a number", "skills":[]}')

 INSERT INTO Person(value)
 VALUES ('{"age": 35}')

Notez que les contraintes de vérification peuvent ralentir vos processus d’insertion/mise à jour et vous éviter de les éviter si vous avez besoin de performances d’écriture plus rapides.

Stockage JSON compressé Si vous avez un texte JSON volumineux, vous pouvez compresser explicitement le texte JSON à l'aide de la fonction COMPRESS intégrée. Dans l'exemple suivant, le contenu JSON compressé est stocké sous forme de données binaires et nous avons calculé une colonne qui décompresse JSON en tant que texte d'origine à l'aide de la fonction DECOMPRESS:

CREATE TABLE Person

 ( _id int identity constraint PK_JSON_ID primary key,

 data varbinary(max),

 value AS CAST(DECOMPRESS(data) AS nvarchar(max))

 )



 INSERT INTO Person(data)

 VALUES (COMPRESS(@json))

Les fonctions COMPRESS et DECOMPRESS utilisent la compression GZip standard. Si votre client peut gérer la compression GZip (par exemple, un navigateur qui comprend le contenu gzip), vous pouvez directement renvoyer un contenu compressé. Notez qu'il s'agit d'un compromis performances/stockage. Si vous interrogez fréquemment des données compressées, vos performances sont ralenties car le texte doit être décompressé à chaque fois.

Remarque: les fonctions JSON sont disponibles uniquement dans SQL Server 2016+ et dans la base de données Azure SQL.

Plus peut être lu de la source de cet article

https://blogs.msdn.Microsoft.com/sqlserverstorageengine/2015/11/23/storing-json-in-sql-server/

9
AMRESH PANDEY

La "règle d'or" que j'utilise, de manière très vague, est que si j'ai besoin de JSON dans son format brut, le stockage est acceptable. Si je dois accorder une attention particulière à l'analyse, ce n'est pas le cas.

Par exemple, si je crée une API qui envoie du JSON brut, et pour une raison quelconque, cette valeur ne changera pas, il est alors okay de le stocker en tant que JSON brut. Si je dois l'analyser, le modifier, le mettre à jour, etc., alors pas tant que ça.

4
piisexactly3

La question que vous devez poser est la suivante:

Suis-je lié à l'utilisation de cette base de données uniquement?

FAIRE

  1. Si vous pouvez utiliser une autre base de données pour stocker JSON, utilisez une solution de stockage de documents telle que CouchDB, DynamoDB ou MongoDB.
  2. Utilisez cette capacité de la base de données de stockage de documents pour indexer et rechercher des données hiérarchiques.
  3. Utilisez une base de données relationnelle pour vos données relationnelles.
  4. Utilisez une base de données relationnelle pour la création de rapports, l’entreposage et l’exploration de données.

Ne pas

  1. Stockez JSON en tant que chaîne si possible.
  2. Essayez de définir une longueur maximale de données JSON.
  3. Utilisez varchar pour stocker JSON (utilisez text/blob si vous devez).
  4. Essayez de rechercher des valeurs dans JSON stocké.
  5. S'inquiéter d'échapper à JSON pour le stocker en tant que chaîne.
4
Anand

Les Json ne sont pas géniaux dans les db relationnels. Si vous déployez le JSON en colonnes et le stockez dans une base de données, c'est génial, mais le stockage d'un JSON sous la forme d'un blob est le prochain moyen de l'utiliser comme système d'archivage de données.

Il peut y avoir plusieurs raisons de ne pas déplier un JSON et de le stocker dans une seule colonne, mais la décision aurait été prise car les valeurs de ce champ Json ne seraient pas utilisées pour une interrogation (ou les valeurs avaient déjà été dépliées en colonnes).

En outre, la plupart des traitements JSON, si le champ demandé était interrogé, seraient en dehors de l'environnement SQL, car SQL n'est tout simplement pas destiné au traitement JSON. La vraie question devient alors: où dois-je stocker ce JSON, puis-je le laisser être sous forme de fichiers plats et, le cas échéant, les interroger via un autre système (spark/Hive/etc.).

Je suis d'accord avec votre artiste DB, n'utilisez pas de SGBDR pour l'archivage. Il y a des options moins chères. De plus, les blobs JSON peuvent devenir énormes et commencer à encombrer l'espace disque de la base de données avec le temps.

2
Satyadev

PostgreSQL a un type de données json et jsonb intégré

Voici quelques exemples:

CREATE TABLE orders (
 ID serial NOT NULL PRIMARY KEY,
 info json NOT NULL
);

INSERT INTO orders (info)
VALUES
 (
 '{ "customer": "Lily Bush", "items": {"product": "Diaper","qty": 24}}'
 ),
 (
 '{ "customer": "Josh William", "items": {"product": "Toy Car","qty": 1}}'
 ),
 (
 '{ "customer": "Mary Clark", "items": {"product": "Toy Train","qty": 2}}'
 );

PostgreSQL fournit deux opérateurs natifs -> et ->> pour interroger les données JSON.

L'opérateur -> renvoie le champ d'objet JSON par clé.

L'opérateur ->> renvoie le champ d'objet JSON par le texte.

SELECT
 info -> 'customer' AS customer
FROM
 orders;

SELECT
 info ->> 'customer' AS customer
FROM
 orders
WHERE
 info -> 'items' ->> 'product' = 'Diaper'
0