Quel est le meilleur type de données SQL pour stocker une chaîne JSON?

127

Quel est le meilleur type de données SQL pour stocker une chaîne JSON?

static List<ProductModel> CreateProductList()
{
    string json = @"[
        {
            ProductId: 1, 
            ProductCode: 'A', 
            Product: 'A'
        },
        {
            ProductId: 2, 
            ProductCode: 'B', 
            Product: 'B'
        }
    ]";

    IList<JToken> tokenList = JToken.Parse(json).ToList();
    List<ProductModel> productList = new List<ProductModel>();

    foreach (JToken token in tokenList)
    {
        productList.Add(JsonConvert.DeserializeObject<ProductModel>(token.ToString()));
    }

    return productList;
}

Quel type de données SQL devons-nous utiliser pour stocker une telle chaîne contenant JSON?

  • NVARCHAR(255)?
  • TEXT?
  • VARBINARY(MAX)?
DatPT
la source
1
Juste un bruit aléatoire (le commentaire, pas les données): vous voudrez peut-être le compresser aussi. Dans ce cas, vous avez besoin de quelque chose de binaire. D'un autre côté: pourquoi ne pas simplement concevoir des tableaux appropriés pour les données?
The Nail
3
@The Nail: Parfois, stocker quelque chose en JSON (ou en tant que "document") est approprié pour le besoin. Comme pour un moteur de workflow ou une gestion de documents etc ... Je fais ça sur un projet en cours, passant en fait d'une approche relationnelle à une approche documentaire pour le côté commande de mon implémentation CQRS. C'est très rapide si vous utilisez un sérialiseur tel que ServiceStack ou JSON.Net.
swannee

Réponses:

198

Certainement PAS :

  • TEXT, NTEXT: ces types sont obsolètes à partir de SQL Server 2005 et ne doivent pas être utilisés pour un nouveau développement. Utilisez VARCHAR(MAX)ou à la NVARCHAR(MAX)place

  • IMAGE, VARBINARY(MAX): IMAGEest obsolète comme TEXT/NTEXT, et il n'y a vraiment aucun intérêt à stocker une chaîne de texte dans une colonne binaire ....

Donc, en gros, VARCHAR(x)ou NVARCHAR(x): VARCHARstocke les chaînes non Unicode (1 octet par caractère) et NVARCHARstocke tout dans un mode Unicode de 2 octets par caractère. Alors, avez-vous besoin d'Unicode? Avez-vous des caractères arabes, hébreux, chinois ou autres caractères non occidentaux dans vos chaînes, potentiellement? Alors allez avecNVARCHAR

Les (N)VARCHARcolonnes sont disponibles en deux versions: soit vous définissez une longueur maximale qui donne 8000 octets ou moins ( VARCHARjusqu'à 8000 caractères, NVARCHARjusqu'à 4000), ou si cela ne suffit pas, utilisez les (N)VARCHAR(MAX)versions, qui stockent jusqu'à 2 Go de données.

Mise à jour: SQL Server 2016 aura un support JSON natif - un nouveau JSONtype de données (basé sur nvarchar) sera introduit, ainsi qu'une FOR JSONcommande pour convertir la sortie d'une requête au format JSON

Mise à jour n ° 2: dans le produit final, Microsoft n'a pas inclus de JSONtype de données séparé - à la place, il existe un certain nombre de fonctions JSON (pour regrouper les lignes de base de données en JSON, ou pour analyser JSON en données relationnelles) qui fonctionnent sur des colonnes de typeNVARCHAR(n)

marc_s
la source
25
NVARCHAR devrait être le choix préféré car le serveur sql 2016 l'utilisera pour son support JSON natif blogs.msdn.com/b/jocapc/archive/2015/05/16/…
Loudenvier
@marc_s Votre déclaration "update" est-elle correcte? Je ne trouve aucun type de données JSON officiel ...?
Nix
2
@Nix: Je pense qu'en fin de compte, SQL Server prend en charge les fonctions JSON qui fonctionnent sur NVARCHAR(n)des types de données
marc_s
2
Vous voudrez peut-être mettre à jour votre réponse pour ne pas indiquer qu'il existe un type de données Json
Nix
1
varbinary (max) pourrait être utilisé lors de l'utilisation de la compression
Marat Gallyamov
31

Je vais y aller nvarchar(max). Cela devrait correspondre à l'exigence.

Mise à jour: avec SQL Server 2016 et Azure SQL, il existe de nombreuses fonctionnalités JSON natives supplémentaires. Cela pourrait avoir un impact positif sur votre conception ou votre approche. Vous pouvez lire ceci pour en savoir plus: https://docs.microsoft.com/en-us/sql/relational-databases/json/json-data-sql-server

Kangkan
la source
8
Le faites vous vraiment besoin du stockage Unicode de 2 octets par caractère? En fonction de vos données - il pourrait juste être perdre deux fois plus d' octets au besoin ... (mais si vous VOULEZ besoin Unicode - alors c'est la seule façon d' y aller, je suis d' accord!)
marc_s
5
nvarchar - parce que les données ne sont pas définies. Si nous estimons que le système n'aura pas besoin d'unicode, nous pouvons économiser en passant à varchar (max)
Kangkan
5
En outre, l'utilisation nvarcharévite les problèmes de classement que vous rencontrerez éventuellement lors de l'utilisation varchar, mais les performances des requêtes seront plus lentes que varchar. Grande question DBA avec plus d'informations.
Scotty.NET
5
Comment cette question a-t-elle obtenu autant de votes positifs? Donc, il dit quel type de données utiliser, très bien ... mais il n'essaie même pas d'expliquer pourquoi ce serait le bon choix.
stakx - ne contribue plus
1
Vous pouvez toujours utiliser varchar et échapper tous les caractères Unicode. C'est une bonne approche si vous n'aurez que des caractères Unicode occasionnels dans votre texte car cela économise de l'espace sur l'utilisation d'un nvarchar
chrisb
3

Je recommanderais d'utiliser nvarchar(max)si vous prévoyez d'utiliser les fonctionnalités JSON sur SQL 2016 ou Azure SQL.

Si vous ne prévoyez pas d'utiliser ces fonctionnalités, vous pouvez utiliser varbinary(max)des fonctions combinées avec COMPRESS(et DECOMPRESS). Plus d'informations: https://blogs.msdn.microsoft.com/sqlserverstorageengine/2015/11/23/storing-json-in-sql-server/

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 le contenu compressé. Notez qu'il s'agit d'un compromis performances / stockage. Si vous interrogez fréquemment les données compressées que vous migrez, les performances sont plus lentes car le texte doit être décompressé à chaque fois.

Marat Gallyamov
la source
quelles sont les fonctionnalités JSON sur SQL 2016 ?
Kiquenet
0

nvarchar (max) est meilleur pour cela, vous pouvez également faire une chose de plus comme ça.

public class TableName
{
    [Key]
    [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
    public Guid Id { get; set; }
     
    public string FieldJson { get; set; }   //save json in this field and
      
    [NotMapped]
    public List<FieldList> FieldList  // get return list from this properity
    {
        get => !string.IsNullOrEmpty(FieldJson) ? JsonConvert.DeserializeObject<List<FieldList>>(FieldJson) : null; 
    }

   
}
Davinder Singh
la source