JSON dizesini depolamak için en iyi SQL veri türü nedir?


127

JSON dizesini depolamak için en iyi SQL veri türü nedir?

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;
}

JSON içeren böyle bir dizeyi depolamak için hangi SQL veri türünü kullanmalıyız?

  • NVARCHAR(255)?
  • TEXT?
  • VARBINARY(MAX)?

1
Sadece biraz rastgele gürültü (veriler değil, yorum): Onu da sıkıştırmak isteyebilirsiniz. Bu durumda ikili bir şeye ihtiyacınız var. Öte yandan: neden veriler için uygun tablolar tasarlamayasınız?
The Nail

3
@ The Nail: Bazen bir şeyi JSON (veya "belge") olarak depolamak ihtiyaca uygundur. Bir iş akışı motoru veya belge yönetimi vb. İçin olduğu gibi ... Bunu mevcut bir projede yapıyorum, aslında CQRS uygulamamın komut tarafı için ilişkisel yaklaşımdan belgeye geçiyorum. ServiceStack veya JSON.Net gibi bir serileştirici kullanıyorsanız çok hızlıdır.
swannee

Yanıtlar:


198

Kesinlikle DEĞİL :

  • TEXT, NTEXT: bu türler SQL Server 2005 itibariyle kullanımdan kaldırılmıştır ve yeni geliştirme için kullanılmamalıdır. Kullanım VARCHAR(MAX)veya NVARCHAR(MAX)yerine

  • IMAGE, VARBINARY(MAX): IMAGEgibi kullanımdan kaldırılmıştır TEXT/NTEXTve bir metin dizesini ikili bir sütuna depolamanın hiçbir anlamı yoktur ....

Böylece, temelde Unicode olmayan dizeleri (karakter başına 1 bayt) VARCHAR(x)veya NVARCHAR(x): bırakır VARCHARve NVARCHARher şeyi karakter başına 2 bayt Unicode modunda saklar. Öyleyse Unicode'a ihtiyacınız var mı? Dizelerinizde potansiyel olarak Arapça, İbranice, Çince veya Batı Avrupalı ​​olmayan diğer karakterler var mı? O zaman gitNVARCHAR

(N)VARCHARKolonlar iki çeşidi bulunuyor: Ya 8000 bayt veya daha az (sonuçlanır yani maksimum uzunluğu tanımlamak VARCHARkadar 8000 karakterden NVARCHARbu yeterli değilse 4000 adede kadar) ya da kullanmak (N)VARCHAR(MAX)verilerin 2 GB'lık depolayabilir sürümleri.

Güncelleme: SQL Server 2016 , yerel JSON desteğine sahip olacak - yeni bir JSONveri türü (buna dayalı nvarchar) FOR JSONve bir sorgudaki çıktıyı JSON formatına dönüştürmek için bir komut sunulacak

Güncelleme # 2: son üründe Microsoft ayrı bir JSONveri türü içermedi - bunun yerine, türdeki sütunlarda çalışan bir dizi JSON işlevi (veritabanı satırlarını JSON'a paketlemek veya JSON'u ilişkisel verilere ayrıştırmak için) vardır.NVARCHAR(n)


25
Sql sunucusu 2016, yerel JSON destek blogları
Loudenvier

@marc_s "Güncelleme" ifadeniz doğru mu? Herhangi bir resmi JSON Veri türü bulamıyorum ...?
Nix

2
@Nix: Sonunda, SQL Server'ın veri türleri üzerinde çalışan JSON işlevlerini desteklediğini düşünüyorumNVARCHAR(n)
marc_s

2
Cevabınızı bir Json veri türü olmadığını belirtmeyecek şekilde güncellemek isteyebilirsiniz
Nix

1
varbinary (maks.) sıkıştırma kullanılırken kullanılabilir
Marat Gallyamov

31

Ben gideceğim nvarchar(max). Bu gereksinimi karşılamalıdır.

Güncelleme: SQL Server 2016 ve Azure SQL ile birçok ek yerel JSON özelliği vardır. Bu, tasarımınızı veya yaklaşımınızı olumlu yönde etkileyebilir. Bunu daha fazlası için okuyabilirsiniz: https://docs.microsoft.com/en-us/sql/relational-databases/json/json-data-sql-server


8
Karakter başına 2 baytlık Unicode depolamaya gerçekten ihtiyacınız var mı ? Verilerinize bağlı olarak - (eğer varsa ama sadece çok gerekli olduğu bayt ... iki kat israf olabilir DO - o zaman gitmek için tek yol Kabul ediyorum, bu! İhtiyaç Unicode)
Marc_s

5
nvarchar - çünkü veriler tanımlanmamıştır. Sistemin unicode'a ihtiyaç duymayacağını hissedersek,
varchar'a

5
Ayrıca, kullanmak, kullanırken nvarcharsonunda yaşayacağınız harmanlama sorunlarını önler varchar, ancak sorgu performansında olduğundan daha yavaş olacaktır varchar. Daha fazla bilgi içeren harika DBA sorusu .
Scotty.NET

5
Bu soru nasıl bu kadar çok olumlu oy aldı? Yani hangi veri türünün kullanılacağını söylüyor, iyi ... ama bunun neden doğru seçim olduğunu açıklamaya bile çalışmıyor .
stakx -

1
Her zaman varchar kullanabilir ve herhangi bir unicode karakterinden çıkabilirsiniz. Metninizde yalnızca ara sıra unicode karakterler olacaksa bu iyi bir yaklaşımdır, çünkü bir nvarchar kullanarak yerden tasarruf sağlar
chrisb

3

nvarchar(max)JSON özelliklerini SQL 2016 veya Azure SQL üzerinde kullanmayı planlıyorsanız kullanmanızı tavsiye ederim .

Bu özellikleri kullanmayı planlamıyorsanız, (ve ) işlevleriyle varbinary(max)birlikte kullanabilirsiniz . Daha fazla bilgi: https://blogs.msdn.microsoft.com/sqlserverstorageengine/2015/11/23/storing-json-in-sql-server/COMPRESSDECOMPRESS

COMPRESS ve DECOMPRESS işlevleri standart GZip sıkıştırmasını kullanır. İstemciniz GZip sıkıştırmasını işleyebiliyorsa (örneğin, gzip içeriğini anlayan tarayıcı), sıkıştırılmış içeriği doğrudan döndürebilirsiniz. Bunun performans / depolama değiş tokuşu olduğunu unutmayın. Sıkıştırılmış verileri sık sık sorgularsanız, metnin her seferinde sıkıştırmasının açılması gerektiğinden, geçiş performansı daha düşük olur.


SQL 2016'daki JSON özellikleri hangileridir ?
Kiquenet


0

nvarchar (max) bunun için daha iyidir, ayrıca bunun gibi yapabileceğiniz bir şey daha var.

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; 
    }

   
}
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.