Kiểu dữ liệu SQL tốt nhất để lưu trữ chuỗi JSON là gì?


127

Kiểu dữ liệu SQL tốt nhất để lưu trữ chuỗi JSON là gì?

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

Loại dữ liệu SQL nào chúng ta nên sử dụng để lưu trữ một chuỗi như vậy có chứa JSON?

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

1
Chỉ là một số nhiễu ngẫu nhiên (nhận xét, không phải dữ liệu): Bạn cũng có thể muốn nén nó. Trong trường hợp đó bạn cần một cái gì đó nhị phân. Mặt khác: tại sao không chỉ thiết kế các bảng thích hợp cho dữ liệu?
The Nail

3
@ The Nail: Đôi khi lưu trữ một cái gì đó dưới dạng JSON (hoặc dưới dạng "tài liệu") là phù hợp với nhu cầu. Giống như đối với công cụ xử lý công việc hoặc quản lý tài liệu, v.v ... Tôi đang thực hiện điều này trong một dự án hiện tại, thực sự đi từ cách tiếp cận quan hệ đến tài liệu cho phía chỉ huy thực hiện CQRS của tôi. Sẽ rất nhanh nếu bạn sử dụng trình tuần tự hóa như ServiceStack hoặc JSON.Net.
swannee

Câu trả lời:


198

Chắc chắn là KHÔNG :

  • TEXT, NTEXT: các loại đó không được dùng cho SQL Server 2005 và không được sử dụng cho phát triển mới. Sử dụng VARCHAR(MAX)hoặc NVARCHAR(MAX)thay thế

  • IMAGE, VARBINARY(MAX): IMAGEkhông được chấp nhận giống như TEXT/NTEXTvà thực sự không có điểm nào trong việc lưu trữ chuỗi văn bản vào cột nhị phân ....

Vì vậy, về cơ bản để lại VARCHAR(x)hoặc NVARCHAR(x): VARCHARlưu trữ các chuỗi không Unicode (1 byte cho mỗi ký tự) và NVARCHARlưu trữ mọi thứ ở chế độ Unicode 2 byte cho mỗi ký tự. Vậy bạn có cần Unicode không? Bạn có tiếng Ả Rập, tiếng Do Thái, tiếng Trung Quốc hoặc các ký tự không thuộc Tây Âu khác trong chuỗi của bạn không? Sau đó đi vớiNVARCHAR

Các (N)VARCHARcột có hai loại: bạn xác định độ dài tối đa dẫn đến 8000 byte hoặc ít hơn ( VARCHARtối đa 8000 ký tự, NVARCHARtối đa 4000) hoặc nếu không đủ, hãy sử dụng các (N)VARCHAR(MAX)phiên bản lưu trữ tối đa 2 GByte dữ liệu.

Cập nhật: SQL Server 2016 sẽ có hỗ trợ JSON gốc - JSONkiểu dữ liệu mới (dựa trên nvarchar) sẽ được giới thiệu, cũng như FOR JSONlệnh chuyển đổi đầu ra từ truy vấn sang định dạng JSON

Cập nhật # 2: trong sản phẩm cuối cùng, Microsoft không bao gồm một JSONkiểu dữ liệu riêng biệt - thay vào đó, có một số hàm JSON (để đóng gói các hàng cơ sở dữ liệu thành JSON hoặc phân tích JSON thành dữ liệu quan hệ) hoạt động trên các cột kiểuNVARCHAR(n)


25
NVARCHAR nên là lựa chọn ưu tiên vì máy chủ sql 2016 sẽ sử dụng nó cho các blog hỗ trợ JSON gốc của nó.msdn.com
jocapc/archive

@marc_s Câu lệnh "cập nhật" của bạn có đúng không? Tôi không thể tìm thấy bất kỳ loại Dữ liệu JSON chính thức nào ...?
Nix

2
@Nix: Tôi nghĩ cuối cùng, SQL Server hỗ trợ các hàm JSON hoạt động trên NVARCHAR(n)các loại dữ liệu
marc_s

2
Bạn có thể muốn cập nhật câu trả lời của mình để không nêu có loại dữ liệu Json
Nix

1
varbinary (max) có thể được sử dụng khi sử dụng nén
Marat Gallyamov

31

Tôi sẽ đi cho nvarchar(max). Điều đó nên phù hợp với yêu cầu.

Cập nhật: Với SQL Server 2016 và Azure SQL, có rất nhiều khả năng JSON gốc. Điều này có thể tác động tích cực đến thiết kế hoặc cách tiếp cận của bạn. Bạn có thể đọc phần này để biết thêm: https://docs.microsoft.com/en-us/sql/relational-database/json/json-data-sql-server


8
Bạn có thực sự cần bộ lưu trữ Unicode 2 byte cho mỗi ký tự không ?? Tùy thuộc vào dữ liệu của bạn - nó chỉ có thể lãng phí gấp đôi byte nhiều khi cần thiết ... (nhưng nếu bạn DO nhu Unicode - thì đó là cách duy nhất để đi, tôi đồng ý!)
marc_s

5
nvarchar - vì dữ liệu không được xác định. Nếu chúng tôi cảm thấy rằng hệ thống sẽ không cần unicode, chúng tôi có thể lưu chuyển sang varchar (max)
Kangkan

5
Ngoài ra, sử dụng nvarcharđể tránh các vấn đề đối chiếu mà cuối cùng bạn sẽ gặp phải khi sử dụng varchar, nhưng nó sẽ chậm hơn trong hiệu năng truy vấn varchar. Câu hỏi DBA tuyệt vời với thông tin thêm.
Scotty.NET

5
Làm thế nào mà câu hỏi này nhận được rất nhiều upvote? Vì vậy, nó nói loại dữ liệu nào sẽ được sử dụng, tốt thôi ... nhưng nó thậm chí không cố gắng giải thích tại sao đó là lựa chọn đúng đắn.
stakx - không còn đóng góp vào

1
Bạn luôn có thể sử dụng varchar và thoát khỏi bất kỳ ký tự unicode nào. Đây là một cách tiếp cận tốt nếu bạn sẽ chỉ có các ký tự unicode không thường xuyên trong văn bản của mình vì nó tiết kiệm không gian hơn bằng cách sử dụng một nvarchar
chrisb

3

Tôi sẽ khuyên bạn nên sử dụng nvarchar(max)nếu bạn dự định sử dụng các tính năng JSON trên SQL 2016 hoặc Azure SQL.

Nếu bạn không có kế hoạch sử dụng các tính năng đó, bạn có thể sử dụng varbinary(max)kết hợp với COMPRESS(và DECOMPRESS) các chức năng. Thêm thông tin: https://bloss.msdn.microsoft.com/sqlserverst Storageengine/2015/11/23/storing-json-in-sql-server/

Các hàm COMPRESS và DECOMPRESS sử dụng nén GZip tiêu chuẩn. Nếu khách hàng của bạn có thể xử lý nén GZip (ví dụ: trình duyệt hiểu nội dung gzip), bạn có thể trực tiếp trả lại nội dung đã nén. Lưu ý rằng đây là sự đánh đổi hiệu năng / lưu trữ. Nếu bạn thường xuyên truy vấn dữ liệu nén, bạn di chuyển có hiệu suất chậm hơn vì văn bản phải được giải nén mỗi lần.


đó là JSON tính năng trên SQL 2016 ?
Kiquenet


0

nvarchar (max) tốt hơn cho việc này, cũng có một điều nữa bạn có thể làm như thế này.

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

   
}
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.