什么是用于存储JSON字符串的最佳SQL数据类型?


127

存储JSON字符串的最佳SQL数据类型是什么?

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

我们应该使用哪种SQL数据类型来存储包含JSON的字符串?

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

1
只是一些随机噪声(注释,而不是数据):您可能也想压缩它。在这种情况下,您需要二进制文件。另一方面:为什么不仅仅为数据设计合适的表呢?
钉子2012年

3
@The Nail:有时将某些内容存储为JSON(或作为“文档”)是合适的。就像用于工作流引擎或文档管理等...我正在当前项目中执行此操作,实际上是从关系到文档方法实现CQRS实现的命令端。如果使用序列化程序(例如ServiceStack或JSON.Net),则速度非常快。
swannee,2012年

Answers:


198

当然不是

  • TEXT, NTEXT:这些类型从SQL Server 2005开始不推荐使用,不应用于新开发。使用VARCHAR(MAX)NVARCHAR(MAX)代替

  • IMAGEVARBINARY(MAX)IMAGE就像一样被弃用TEXT/NTEXT,将文本字符串存储到二进制列中实际上没有任何意义。

这样基本上就可以离开VARCHAR(x)NVARCHAR(x)VARCHAR存储非Unicode字符串(每个字符1个字节),并NVARCHAR以2个字符/字符的Unicode模式存储所有内容。那么,您需要Unicode吗?您的字符串中是否可能包含阿拉伯语,希伯来语,中文或其他非西欧字符?然后去NVARCHAR

这些(N)VARCHAR列有两种形式:您定义的最大长度导致8000个字节或更少(VARCHAR最多8000个字符,NVARCHAR最多4000 个字符),或者如果这不够用,请使用(N)VARCHAR(MAX)最多存储2 GB数据的版本。

更新: SQL Server 2016将具有本机JSON支持- 将引入新的JSON数据类型(基于nvarchar),以及FOR JSON将查询的输出转换为JSON格式的命令

更新#2:在最终产品中,Microsoft没有包括单独的JSON数据类型-而是有许多JSON函数(用于将数据库行打包为JSON或将JSON解析为关系数据),它们对类型的列进行操作NVARCHAR(n)


25
NVARCHAR应该是首选,因为sql server 2016会将其用于其本机JSON支持blogs.msdn.com/b/jocapc/archive/2015/05/16/…–
Loudenvier

@marc_s您的“更新”语句正确吗?我找不到任何官方的JSON数据类型...?
Nix

2
@Nix:我认为到最后,SQL Server支持JSON功能上操作NVARCHAR(n)的数据类型
marc_s

2
您可能需要更新答案,以不声明存在Json数据类型
Nix

1
使用压缩时可以使用varbinary(max)
Marat Gallyamov

31

我去nvarchar(max)。那应该符合要求。

更新: 使用SQL Server 2016和Azure SQL,还有很多其他本机JSON功能。这可能会对您的设计或方法产生积极影响。您可以阅读以下内容以了解更多信息:https : //docs.microsoft.com/zh-cn/sql/relational-databases/json/json-data-sql-server


8
您是否真的需要每个字符2个字节的Unicode存储?根据您的数据- (但如果你很可能就是尽可能多字节需要...浪费两次DO -那么这就是要走的必经之路,我同意!需要的Unicode)
marc_s

5
nvarchar-因为未定义数据。如果我们觉得系统将不再需要统一,我们可以节省移动为varchar(最大)
Kangkan

5
另外,使用nvarchar可以避免使用时最终会出现的排序规则问题varchar,但是查询性能会比慢varchar有关更多信息的DBA重大问题
Scotty.NET 2013年

5
这个问题如何得到如此多的支持?因此它说要使用哪种数据类型,很好...但是它甚至没有试图解释为什么这是正确的选择。
stakx-不再贡献

1
您始终可以使用varchar并转义任何unicode字符。如果您的文本中仅偶尔包含Unicode字符,这是一种好方法,因为它可以节省使用nvarchar的空间
chrisb 2015年

3

nvarchar(max)如果您打算在SQL 2016或Azure SQL上使用JSON功能,我建议使用。

如果您不打算使用这些功能,则可以varbinary(max)COMPRESS(和DECOMPRESS)函数结合使用。详细信息:https : //blogs.msdn.microsoft.com/sqlserverstorageengine/2015/11/23/storing-json-in-sql-server/

COMPRESS和DECOMPRESS函数使用标准的GZip压缩。如果您的客户端可以处理GZip压缩(例如,了解gzip内容的浏览器),则可以直接返回压缩的内容。请注意,这是性能/存储权衡。如果您经常查询压缩数据,则mig的性能会降低,因为每次都必须对文本进行解压缩。


SQL 2016上的JSON功能有哪些?
Kiquenet '18


0

为此,nvarchar(max)更好,这样您还可以做一件事。

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

   
}
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.