ประเภทข้อมูล 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
แค่เสียงรบกวนแบบสุ่ม (ความคิดเห็นไม่ใช่ข้อมูล): คุณอาจต้องการบีบอัดด้วย ในกรณีนี้คุณต้องการบางสิ่งบางอย่างไบนารี ในทางกลับกัน: ทำไมไม่ออกแบบตารางให้เหมาะสมกับข้อมูลล่ะ
The Nail

3
@ The Nail: บางครั้งการจัดเก็บบางอย่างเป็น JSON (หรือเป็น "เอกสาร") ก็เหมาะสมกับความต้องการ เช่นเดียวกับเอนจินเวิร์กโฟลว์หรือการจัดการเอกสาร ฯลฯ ... ฉันกำลังทำสิ่งนี้ในโปรเจ็กต์ปัจจุบันซึ่งจริงๆแล้วจะเปลี่ยนจากความสัมพันธ์ไปสู่แนวทางเอกสารสำหรับด้านคำสั่งของการใช้งาน CQRS ของฉัน เร็วมากถ้าคุณใช้ serializer เช่น ServiceStack หรือ JSON.Net
Swannee

คำตอบ:


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 GByte ของข้อมูล

อัปเดต: 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 คำสั่ง "update" ของคุณถูกต้องหรือไม่? ฉันไม่พบประเภทข้อมูล JSON ที่เป็นทางการ ... ?
Nix

2
@Nix: ฉันคิดว่าในท้ายที่สุด SQL Server รองรับฟังก์ชัน JSONที่ทำงานกับNVARCHAR(n)ชนิดข้อมูล
marc_s

2
คุณอาจต้องการอัปเดตคำตอบของคุณเพื่อไม่ระบุว่ามีประเภทข้อมูล Json
Nix

1
varbinary (สูงสุด) สามารถใช้ได้เมื่อใช้การบีบอัด
Marat Gallyamov

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 ไบต์ต่อตัวละคร ?? ทั้งนี้ขึ้นอยู่กับข้อมูลของคุณ - มันก็อาจจะเสียสองเท่าไบต์มากที่สุดเท่าที่จำเป็น ... ( แต่ถ้าคุณทำจำเป็น Unicode - แล้วว่าเป็นวิธีเดียวที่จะไปผมเห็นด้วย!)
marc_s

5
nvarchar - เนื่องจากไม่ได้กำหนดข้อมูล หากเรารู้สึกว่าระบบไม่ต้องการ Unicode เราสามารถบันทึกการย้ายไปยัง varchar (สูงสุด)
Kangkan

5
นอกจากนี้การใช้nvarcharหลีกเลี่ยงปัญหาการเปรียบเทียบในที่สุดคุณจะได้เมื่อใช้แต่มันจะช้าลงในประสิทธิภาพการทำงานแบบสอบถามกว่าvarchar คำถาม DBA ที่ยอดเยี่ยมพร้อมข้อมูลเพิ่มเติม varchar
Scotty.NET

5
คำถามนี้ได้รับการโหวตเพิ่มขึ้นมากมายได้อย่างไร? มันบอกว่าจะใช้ข้อมูลประเภทไหนดี ... แต่ก็ไม่ได้พยายามอธิบายว่าทำไมถึงเป็นตัวเลือกที่ถูกต้อง
stakx - ไม่ร่วมให้ข้อมูล

1
คุณสามารถใช้ varchar และหลีกเลี่ยงอักขระ Unicode ได้ตลอดเวลา นี่เป็นแนวทางที่ดีหากคุณจะมีตัวอักษร Unicode เป็นครั้งคราวในข้อความของคุณเนื่องจากจะช่วยประหยัดพื้นที่ในการใช้ nvarchar
chrisb

3

ฉันอยากจะแนะนำให้ใช้nvarchar(max)หากคุณวางแผนที่จะใช้คุณสมบัติ JSON บน SQL 2016 หรือ Azure SQL

หากคุณไม่ได้วางแผนที่จะใช้คุณสมบัติเหล่านั้นคุณสามารถใช้varbinary(max)ร่วมกับฟังก์ชันCOMPRESS(และDECOMPRESS) ได้ ข้อมูลเพิ่มเติม: https://blogs.msdn.microsoft.com/sqlserverstorageengine/2015/11/23/storing-json-in-sql-server/

ฟังก์ชัน COMPRESS และ DECOMPRESS ใช้การบีบอัด GZip มาตรฐาน หากไคลเอ็นต์ของคุณสามารถจัดการการบีบอัด GZip (เช่นเบราว์เซอร์ที่เข้าใจเนื้อหา gzip) คุณสามารถส่งคืนเนื้อหาที่บีบอัดได้โดยตรง โปรดทราบว่านี่คือการแลกเปลี่ยนประสิทธิภาพ / การจัดเก็บข้อมูล หากคุณค้นหาข้อมูลที่ถูกบีบอัดบ่อยๆคุณจะมีประสิทธิภาพที่ช้าลงเนื่องจากข้อความจะต้องถูกคลายการบีบอัดทุกครั้ง


ซึ่งเป็นJSON ให้บริการใน SQL 2016 ?
Kiquenet


0

nvarchar (สูงสุด) ดีกว่าสำหรับสิ่งนี้และอีกสิ่งหนึ่งที่คุณสามารถทำได้เช่นนี้

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

   
}
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.