Apa tipe data SQL terbaik untuk menyimpan string JSON?

127

Apa tipe data SQL terbaik untuk menyimpan string 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;
}

Jenis data SQL mana yang harus kita gunakan untuk menyimpan string yang berisi JSON?

  • NVARCHAR(255)?
  • TEXT?
  • VARBINARY(MAX)?
DatPT
sumber
1
Hanya beberapa gangguan acak (komentar, bukan datanya): Anda mungkin ingin mengompresnya juga. Dalam hal ini Anda membutuhkan sesuatu yang biner. Di sisi lain: mengapa tidak mendesain tabel yang tepat untuk data saja?
The Nail
3
@ The Nail: Terkadang menyimpan sesuatu sebagai JSON (atau sebagai "dokumen") sesuai untuk kebutuhan. Seperti untuk mesin alur kerja atau manajemen dokumen dll ... Saya melakukan ini pada proyek saat ini, sebenarnya dari pendekatan relasional ke dokumen untuk sisi perintah implementasi CQRS saya. Ini sangat cepat jika Anda menggunakan serializer seperti ServiceStack atau JSON.Net.
swannee

Jawaban:

198

Tentu TIDAK :

  • TEXT, NTEXT: jenis tersebut tidak digunakan lagi pada SQL Server 2005 dan tidak boleh digunakan untuk pengembangan baru. Gunakan VARCHAR(MAX)atau NVARCHAR(MAX)sebagai gantinya

  • IMAGE, VARBINARY(MAX): IMAGEsudah tidak digunakan lagi TEXT/NTEXT, dan tidak ada gunanya menyimpan string teks ke dalam kolom biner ....

Sehingga pada dasarnya meninggalkan VARCHAR(x)atau NVARCHAR(x): VARCHARmenyimpan string non-Unicode (1 byte per karakter) dan NVARCHARmenyimpan semuanya dalam mode Unicode 2-byte-per-karakter. Jadi, apakah Anda membutuhkan Unicode? Apakah Anda berpotensi memiliki karakter Arab, Ibrani, China, atau non-Eropa Barat lainnya dalam string Anda? Lalu pergi denganNVARCHAR

The (N)VARCHARkolom datang dalam dua rasa: baik Anda menentukan panjang maksimum yang menghasilkan 8000 bytes atau kurang ( VARCHARhingga 8000 karakter, NVARCHARhingga 4000), atau jika itu tidak cukup, gunakan (N)VARCHAR(MAX)versi, yang menyimpan hingga 2 GByte data.

Pembaruan: SQL Server 2016 akan memiliki dukungan JSON asli - JSONtipe data baru (yang didasarkan pada nvarchar) akan diperkenalkan, serta FOR JSONperintah untuk mengonversi keluaran dari kueri ke dalam format JSON

Pembaruan # 2: di produk akhir, Microsoft tidak menyertakan JSONtipe data terpisah - sebagai gantinya, ada sejumlah fungsi JSON (untuk mengemas baris database menjadi JSON, atau untuk mengurai JSON menjadi data relasional) yang beroperasi pada kolom tipeNVARCHAR(n)

marc_s
sumber
25
NVARCHAR harus menjadi pilihan yang lebih disukai karena sql server 2016 akan menggunakannya untuk blog
Loudenvier
@marc_s Apakah pernyataan "update" Anda benar? Saya tidak dapat menemukan tipe Data JSON resmi ...?
Nix
2
@ Nix: Saya pikir pada akhirnya, SQL Server mendukung fungsi JSON yang beroperasi pada NVARCHAR(n)tipe data
marc_s
2
Anda mungkin ingin memperbarui jawaban Anda untuk tidak menyatakan ada tipe data Json
Nix
1
varbinary (maks) dapat digunakan saat menggunakan kompresi
Marat Gallyamov
31

Aku akan pergi nvarchar(max). Itu harus sesuai dengan kebutuhan.

Pembaruan: Dengan SQL Server 2016 dan Azure SQL, ada banyak kemampuan JSON asli tambahan. Ini mungkin berdampak positif pada desain atau pendekatan Anda. Anda dapat membaca ini untuk lebih lanjut: https://docs.microsoft.com/en-us/sql/relational-databases/json/json-data-sql-server

Kangkan
sumber
8
Apakah Anda benar - benar membutuhkan penyimpanan Unicode 2-byte-per-karakter ?? Bergantung pada data Anda - mungkin hanya membuang byte dua kali lebih banyak dari yang dibutuhkan ... (tetapi jika Anda SANGAT memerlukan Unicode - maka itulah satu-satunya cara untuk melakukannya, saya setuju!)
marc_s
5
nvarchar - karena data tidak ditentukan. Jika kita merasa bahwa sistem tidak membutuhkan unicode, kita dapat menyimpan pindah ke varchar (max)
Kangkan
5
Selain itu, penggunaan nvarcharmenghindari masalah pemeriksaan yang pada akhirnya akan Anda alami saat menggunakan varchar, tetapi akan lebih lambat dalam kinerja kueri daripada varchar. Pertanyaan DBA hebat dengan info lebih lanjut.
Scotty.NET
5
Bagaimana pertanyaan ini mendapatkan begitu banyak suara positif? Jadi dikatakan tipe data mana yang akan digunakan, bagus ... tapi bahkan tidak mencoba menjelaskan mengapa itu menjadi pilihan yang tepat.
stakx - tidak lagi berkontribusi
1
Anda selalu dapat menggunakan varchar dan melepaskan karakter unicode apa pun. Ini adalah pendekatan yang baik jika Anda hanya akan memiliki karakter unicode sesekali dalam teks Anda karena ini menghemat ruang menggunakan nvarchar
chrisb
3

Saya akan merekomendasikan untuk digunakan nvarchar(max)jika Anda berencana menggunakan fitur JSON di SQL 2016 atau Azure SQL.

Jika Anda tidak berencana untuk menggunakan fitur tersebut, Anda dapat menggunakan varbinary(max)kombinasi dengan COMPRESS(dan DECOMPRESS) fungsi. Informasi lebih lanjut: https://blogs.msdn.microsoft.com/sqlserverstorageengine/2015/11/23/storing-json-in-sql-server/

Fungsi COMPRESS dan DECOMPRESS menggunakan kompresi GZip standar. Jika klien Anda dapat menangani kompresi GZip (mis. Browser yang memahami konten gzip), Anda dapat langsung mengembalikan konten yang dikompresi. Perhatikan bahwa ini adalah trade-off kinerja / penyimpanan. Jika Anda sering membuat kueri data terkompresi, Anda bermigrasi memiliki kinerja yang lebih lambat karena teks harus didekompresi setiap kali.

Marat Gallyamov
sumber
apa saja fitur JSON di SQL 2016 ?
Kiquenet
0

nvarchar (max) lebih baik untuk ini, juga satu hal lagi yang dapat Anda lakukan seperti ini.

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
sumber