Який найкращий тип даних SQL для зберігання рядка JSON?


127

Який найкращий тип даних SQL для зберігання рядка 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;
}

Який тип даних SQL слід використовувати для зберігання такої рядки, що містить JSON?

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

1
Просто якийсь випадковий шум (коментар, а не дані): Ви також можете стиснути його. У цьому випадку вам потрібно щось бінарне. З іншого боку: чому б просто не спроектувати належні таблиці для даних?
Цвях

3
@ The Nail: Іноді зберігати щось як JSON (або як "документ") є належним для потреби. Як і для двигуна робочого процесу або управління документами тощо ... Я роблю це на поточному проекті, фактично переходячи від реляційного до документаційного підходу для командної сторони моєї реалізації CQRS. Це дуже швидко, якщо ви використовуєте серіалізатор, такий як ServiceStack або JSON.Net.
лебедя

Відповіді:


198

Звичайно НЕ :

  • TEXT, NTEXT: ці типи застаріли, як у SQL Server 2005, і не повинні використовуватися для нових розробок. Використовуйте VARCHAR(MAX)або NVARCHAR(MAX)замість цього

  • IMAGE, VARBINARY(MAX): IMAGE- застаріло так само TEXT/NTEXT, і насправді немає сенсу зберігати текстовий рядок у двійковий стовпчик ....

Таким чином, це в основному залишає VARCHAR(x)або NVARCHAR(x): VARCHARзберігає рядки Unicode (1 байт на символ) і NVARCHARзберігає все в режимі Unicode 2 байта на символ. Тож вам потрібен Unicode? Чи потенційно у вас є арабські, іврит, китайські та інші не західноєвропейські символи у ваших струнах? Тоді йдіть зNVARCHAR

Ці (N)VARCHARколони в двох варіантах: або визначити максимальну довжину , що приводить до 8000 байт або менше ( VARCHARдо 8000 символів, NVARCHARдо 4000), або , якщо цього недостатньо, використовувати (N)VARCHAR(MAX)версії, які зберігають до 2 Гбайт даних.

Оновлення: SQL Server 2016 матиме вбудовану підтримку JSON - буде представлено новий JSONтип даних (на основі якого nvarchar), а такожFOR JSON команда для перетворення результатів запиту у формат JSON

Оновлення №2: у кінцевому продукті Microsoft не включила окремий JSONтип даних - натомість є ряд функцій JSON (для упаковки рядків баз даних у JSON або для розбору JSON у реляційні дані), які працюють на стовпцях типуNVARCHAR(n)


25
NVARCHAR повинен бути кращим вибором, оскільки сервер sql 2016 буде використовувати його для рідної підтримки JSON blogs.msdn.com/b/jocapc/archive/2015/05/16/…
Loudenvier

@marc_s Правильна ваша заява "оновлення"? Я не можу знайти жодних офіційних типів даних JSON ...?
Нікс

2
@Nix: Я думаю, врешті-решт, SQL Server підтримує функції JSON, які працюють на NVARCHAR(n)типи даних
marc_s

2
Можливо, ви захочете оновити свою відповідь, щоб не вказати, що існує тип даних Json
Nix

1
варбінарний (макс.) може бути використаний при використанні компресії
Марат Галямов

31

Я піду nvarchar(max). Це повинно відповідати вимозі.

Оновлення: для SQL Server 2016 та Azure SQL існує маса додаткових можливостей JSON. Це може позитивно вплинути на ваш дизайн або підхід. Ви можете прочитати це докладніше: https://docs.microsoft.com/en-us/sql/relational-databases/json/json-data-sql-server


8
Вам справді потрібне зберігання Unicode 2-байтним на персонаж ?? Залежно від ваших даних - це може просто витратити вдвічі більше байтів, ніж потрібно ... (але якщо ви DO потреба Unicode - то , що це єдиний шлях, я згоден!)
marc_s

5
nvarchar - тому що дані не визначені. Якщо ми вважаємо, що системі не знадобиться unicode, ми можемо зберегти перехід до varchar (max)
Кангкан

5
Крім того, використання nvarcharдозволяє уникнути проблем зі збіркою, які ви, зрештою, матимете під час використання varchar, але це буде повільніше у виконанні запитів, ніж varchar. Відмінне запитання DBA з додатковою інформацією.
Scotty.NET

5
Як це питання отримало стільки відгуків? Тож там сказано, який тип даних використовувати, добре ... але він навіть не намагається пояснити, чому це був би правильний вибір.
stakx - більше не сприяє

1
Ви завжди можете використовувати varchar і уникати будь-яких символів unicode. Це хороший підхід, якщо у вашому тексті будуть лише випадкові символи унікоду, оскільки це економить місце за допомогою nvarchar
chrisb

3

Я рекомендую використовувати, nvarchar(max)якщо ви плануєте використовувати функції JSON на SQL 2016 або Azure SQL.

Якщо ви не плануєте використовувати ці функції, ви можете їх використовувати varbinary(max) поєднанні з COMPRESSDECOMPRESS) функціями. Більше інформації: https://blogs.msdn.microsoft.com/sqlserverstorageengine/2015/11/23/storing-json-in-sql-server/

Функції COMPRESS та DECOMPRESS використовують стандартну компресію GZip. Якщо ваш клієнт може управляти стисненням GZip (наприклад, браузер, який розуміє вміст gzip), ви можете безпосередньо повернути стислий вміст. Зауважте, що це компроміс продуктивності / зберігання. Якщо ви часто запитуєте стислі дані, миг ви маєте більш низьку продуктивність, оскільки текст потрібно кожного разу декомпресувати.


які є функції JSON у SQL 2016 ?
Кікенет


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

   
}
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.