ใช้ข้อความสูงสุด MAX หรือเฉพาะเจาะจงน้อยกว่านั้น


22

มีคนถูกตรวจสอบรหัส DDL ของการสร้างตารางและแนะนำเมื่อพวกเขาเห็นผมเห็นโดยใช้VARCHAR(256)ฟิลด์สำหรับข้อความที่ผมคาดหวังว่าจะสวยขนาดเล็กเหมือนชื่อหรือสิ่งที่ฉันควรจะเสมอเพียงแค่ใช้VARCHAR(MAX)และเชื่อมโยงทำไมต้องใช้อะไร แต่ (สูงสุด varchar ) . ฉันอ่านมัน แต่ดูเหมือนว่ามันล้าสมัยเพราะมันมุ่งเน้นไปที่ปี 2005 และดูเหมือนจะไม่ได้เสนอเหตุผลที่แท้จริงในการจัดสรรที่อาจเกิดขึ้นถึง 2 GB ต่อแถวในเขตข้อมูลข้อความทั้งหมด

จากมุมมองด้านประสิทธิภาพการจัดเก็บและอื่น ๆ เราควรตัดสินใจอย่างไรว่าจะใช้งานVARCHAR(MAX)หรือใช้SQL Server รุ่นใหม่ที่มีขนาดเฉพาะเจาะจงน้อยลง (เช่น 2008, 2012, 2014)

คำตอบ:


31

ฉันควรใช้(n)varchar(max)สำหรับคอลัมน์ข้อความเสมอหรือไม่

เลขที่

สำหรับ SQL Server maxควรระบุชนิดข้อมูลเฉพาะเมื่อไม่มีทางเลือกอื่น หนึ่งควรเลือกประเภทฐานที่ถูกต้อง ( varcharหรือnvarchar) และระบุความยาวสูงสุดที่ชัดเจนที่เหมาะสมกับข้อมูลที่จะจัดเก็บ

ที่เก็บข้อมูลฟิสิคัลจะเหมือนกันไม่ว่าจะเป็นคอลัมน์ที่พิมพ์varchar(n)หรือvarchar(max)ดังนั้นจึงไม่น่ากังวล

เหตุผลที่ไม่เลือกที่จะ(n)varchar(max)หมุนไปรอบ ๆ คุณสมบัติคุณภาพแผนและประสิทธิภาพ

รายการครบถ้วนสมบูรณ์อาจไม่เป็นประโยชน์ แต่เหนือสิ่งอื่นใดmaxคอลัมน์:

คุณสมบัติ

  • ต้องการข้อ จำกัด แยกต่างหากเพื่อบังคับใช้ความยาวสูงสุด
  • ไม่สามารถเป็นคีย์ในดัชนี (ดังนั้นจึงไม่มีข้อ จำกัด ที่ไม่เหมือนกัน)
  • อาจป้องกัน DDL ออนไลน์ (รวมถึงการสร้างดัชนีใหม่และเพิ่มคอลัมน์ที่ไม่ใช่ค่าว่างใหม่)
  • โดยทั่วไปจะไม่รองรับคุณสมบัติ 'ใหม่กว่า' เช่นคอลัมน์
  • ดูเอกสารประกอบของผลิตภัณฑ์สำหรับคุณสมบัติและข้อ จำกัด เฉพาะเพิ่มเติม รูปแบบทั่วไปคือมีข้อ จำกัด และข้อ จำกัด ที่น่าอึดอัดใจเกี่ยวกับmaxชนิดข้อมูล ไม่ใช่ข้อ จำกัด และผลข้างเคียงทั้งหมดที่มีการบันทึกไว้

ประสิทธิภาพ

  • จำเป็นต้องมีการจัดการเป็นพิเศษในเอ็นจินการดำเนินการเพื่อพิจารณาขนาดที่ใหญ่มาก โดยทั่วไปแล้วสิ่งนี้จะเกี่ยวข้องกับการใช้เส้นทางโค้ดที่มีประสิทธิภาพน้อยกว่าด้วยอินเตอร์เฟสการสตรีม
  • อาจมีผลที่ไม่คาดคิดที่คล้ายกันสำหรับรหัสภายนอก (และส่วนประกอบอื่น ๆ ของ SQL Server เช่น SSIS) ซึ่งจะต้องเตรียมพร้อมในการจัดการข้อมูลขนาดสูงสุด 2GB
  • จะถือว่ามีความกว้าง 4000 ไบต์ในการคำนวณการให้สิทธิ์หน่วยความจำ สิ่งนี้มีแนวโน้มที่จะนำไปสู่การจองหน่วยความจำมากเกินไปซึ่ง จำกัด การทำงานพร้อมกันและผลักดันดัชนีและหน้าข้อมูลที่มีค่าออกจากหน่วยความจำแคช
  • ปิดใช้งานการปรับปรุงประสิทธิภาพที่สำคัญหลายประการ
  • อาจยืดระยะเวลาล็อค
  • อาจป้องกันเครื่องมือเพิ่มประสิทธิภาพการเลือกแผน (ไม่ใช่แบบไดนามิก)
  • ป้องกันตัวกรองที่ถูกผลักเข้าไปในการสแกนและค้นหาเป็นส่วนที่เหลือ
  • อาจเพิ่มแรงกดดัน tempdb และการช่วงชิง (ขึ้นอยู่กับรุ่น) เนื่องจากตัวแปรและพารามิเตอร์มีแนวโน้มที่จะถูกพิมพ์maxเพื่อจับคู่คำจำกัดความของคอลัมน์

โดยสรุปมีผลข้างเคียงมากมาย (และไม่พึงประสงค์) ที่ละเอียดอ่อนของการใช้ตัวmaxระบุโดยไม่จำเป็นซึ่งทำให้ไม่มีเหตุผลที่จะทำเช่นนี้ 'ความสะดวกสบาย' เล็กน้อยของการใช้การประกาศเพียงครั้งเดียวนั้นไม่ใช่การชดเชย

ประเมินแต่ละประเภทในบริบทใช้ประเภทฐานที่ถูกต้อง ( varcharหรือnvarchar) และความยาวที่ชัดเจน

อ่านเพิ่มเติม:


8

สิ่งนี้จะอ่านเหมือนคำตอบของหวาดระแวง แต่ไม่ได้มีเพียงข้อพิจารณาด้านการจัดเก็บและประสิทธิภาพเท่านั้น

ฐานข้อมูลนั้นไม่ได้ควบคุมลูกค้าและไม่สามารถสันนิษฐานได้ว่าลูกค้าจะใส่ข้อมูลผู้ใช้อย่างปลอดภัยเสมอ - แม้ว่าฐานข้อมูลนั้นถูกออกแบบมาเพื่อใช้กับแอพพลิเคชั่น. net ที่ใช้ Entity Framework เพื่อแค็ปซูลธุรกรรม มีการใช้อย่างเป็นระบบคุณไม่สามารถ รู้ว่ามันจะเป็นอย่างนั้นเสมอ

ฉันไม่รู้ว่าจะทำสิ่งนี้ได้อย่างไร แต่โดยการสร้างฟิลด์ข้อความทั้งหมดvarchar(max)หากลูกค้ามีBobby Tablesปัญหาและ / หรือพารามิเตอร์โพรซีเดอร์ที่เก็บไว้ของคุณก็เป็นเช่นvarchar(max)นั้นคุณทำให้ผู้โจมตีเกิดขึ้นได้ง่ายขึ้น ค่าพารามิเตอร์ที่ถูกต้อง แต่ชั่วร้ายอย่างชาญฉลาดที่สามารถทำสิ่งที่ลูกค้าไม่ควรทำ - ไม่ว่าจะเป็นอะไร

โดยการ จำกัด ความยาวกับสิ่งที่คุณจริงต้องคุณไม่ได้ป้องกันตัวเองจากการโจมตีเหล่านี้ฉลาด (ผมไม่ได้แน่ใจว่าสิ่งที่มันเรียกว่าจริง ๆ แล้วผมก็จำได้ว่าอ่านเกี่ยวกับเรื่องนี้ในขณะที่กลับ) แต่คุณไม่ได้พูด " ไปข้างหน้าพยายามที่จะให้สคริปต์ 2GB ให้ฉันทำงาน "อย่างใดอย่างหนึ่ง


สิ่งที่เรียกว่าน่าจะเป็น "การฉีด" ("การฉีด SQL" โดยเฉพาะอย่างยิ่งมากขึ้น)
Andriy M

@AndriyM ใช่ด้วยเหตุผลบางอย่างที่ฉันคิดว่าการโจมตี SQL ถูกตัดทอน (MS ดูเหมือนว่าจะมีการลงลิงค์ที่ฉันได้บุ๊คมาร์ค) แต่ที่โดยทั่วไปแล้วการใช้ประโยชน์จากvarchar(not-max)พารามิเตอร์ดังนั้นฉันติดเท้าในปากของฉันที่นี่ แต่ใช่การฉีด SQL จะสามารถใช้ได้ที่นี่ บางทีฉันควรเรียบเรียงคำตอบนี้ใหม่อีกครั้ง
Mathieu Guindon
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.