เหตุใดการผสมการเรียงคอลัมน์ในฐานข้อมูลเดียวจึงถือว่าไม่ดี


11

มีสองเหตุผลที่ทำให้ฉันถามคำถามนี้:

tSQLt
เฟรมเวิร์กการทดสอบ T-SQL tSQLt พิจารณาว่าเป็นปัญหาของ"High Severity"เมื่อมีคอลัมน์ที่มีการจัดเรียงที่ไม่ใช่ค่าเริ่มต้น ผู้เขียนการทดสอบระบุสิ่งต่อไปนี้:

ฉันไม่แนะนำให้ทุกคอลัมน์สตริงควรมีการเปรียบเทียบที่ตรงกับการเปรียบเทียบเริ่มต้นสำหรับฐานข้อมูล ฉันขอแนะนำว่าเมื่อมันแตกต่างกันควรมีเหตุผลที่ดี

กระนั้นความรุนแรงของการทดสอบที่ล้มเหลวก็ถือว่าสูง

การปรับใช้ Octopus
ในขณะที่กำหนดค่าเซิร์ฟเวอร์การปรับใช้ Octopus การตั้งค่าล้มเหลวด้วยข้อผิดพลาด FATAL ในระหว่างการเริ่มต้นของ OctopusServer-instance บทความที่เกี่ยวข้องกับข้อผิดพลาดข้อความไม่ได้อธิบายว่าทำไมนี้เป็นความต้องการ แต่เพียงระบุว่ามันจะเป็นความจำเป็นสำหรับการใช้งานในอนาคตจากการรวมทั้งปลาหมึกรุ่น 3.8

ในฐานะที่เป็นกล่องด้านข้างแพคเกจ CI-tool ของ RedGate นั้นเป็นชุดDLM Automation Suiteรองรับการปรับใช้ที่มีการเปรียบเทียบที่หลากหลายโดยไม่มีการร้องเรียน

คำแนะนำในการคงการเรียงคอลัมน์ทั้งหมดไว้เป็นค่าเริ่มต้นของฐานข้อมูลดูเหมือนจะเป็นแนวทางหรือแนวทางปฏิบัติที่ดีที่สุดสำหรับฉัน เหตุใดจึงถือว่าข้อผิดพลาดร้ายแรงบางรายการ


คุณกำลังอ้างถึงการแปลง tSQLt ของการทดสอบ SQL Cop เนื่องจากการทดสอบ tSQLt ผ่านหรือล้มเหลวสิ่งเหล่านี้จะต้องเสนอค่าเริ่มต้นที่แนะนำ ผู้ใช้คาดหวังอย่างเต็มที่ว่าจะปรับการทดสอบ SQLCop ให้ตรงกับความต้องการของตนเองเนื่องจากไม่เกินขั้นตอนการจัดเก็บในสกีมา SQLCop ที่เลือกโดยกรอบงาน tSQLt
David Atkinson

คำตอบ:


19

คำแนะนำในการคงการเรียงคอลัมน์ทั้งหมดไว้เป็นค่าเริ่มต้นของฐานข้อมูลดูเหมือนจะเป็นแนวทางหรือแนวทางปฏิบัติที่ดีที่สุดสำหรับฉัน

คุณถูกต้องทั้งหมดที่นี่

เหตุใดจึงถือว่าข้อผิดพลาดร้ายแรงบางรายการ

ด้วยเหตุผลเดียวกับที่คุณมักจะได้ยิน / อ่านว่า "คุณไม่ควรใช้:"

  • CURSORs
  • GOTO งบ
  • SQLCLR
  • WITH (NOLOCK)
  • ฯลฯ ฯลฯ ฯลฯ

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

ในกรณีของ Collations นี่เป็นหัวข้อที่ซับซ้อนและสับสนและคุณสามารถเรียกใช้ทั้งข้อผิดพลาดที่ยาก (สิ่งเหล่านี้เป็นปัญหา แต่น้อยกว่าปัญหาเนื่องจากมีความชัดเจนและง่ายต่อการแก้ไข) และเป็น "คี่" พฤติกรรมที่เป็นการยากที่จะอธิบายว่าทำไมสิ่งต่าง ๆ จึงแสดงออกมาอย่างที่เป็นอยู่ (เหตุใดบางรายการจึงถูกกรองหรือไม่ถูกกรองนอกความคาดหวังหรือเหตุใดการเรียงลำดับจึงกระทำนอกความคาดหมาย) และน่าเศร้าที่ดูเหมือนว่าจะมีข้อมูลที่ผิดจำนวนมากลอยอยู่รอบ ๆ ซึ่งทำให้เกิดความสับสนมากขึ้น จริง ๆ แล้วฉันกำลังทำงานในโครงการเพื่อเพิ่มความรู้ทั่วไปเกี่ยวกับการเรียงและการเข้ารหัส ฯลฯ และหวังว่าจะแก้ไขข้อมูลที่ผิดและตำนาน แต่ยังไม่พร้อมที่จะเผยแพร่

สำหรับการจัดเรียงคุณต้องใช้สิ่งที่เหมาะสมที่สุดสำหรับกรณีศึกษาทางธุรกิจ แนวคิดของการไม่รวม Collations ในตารางหรือฐานข้อมูลเป็นวิธีการเริ่มต้น แต่ถ้าคุณดู Collations ที่ใช้สำหรับคอลัมน์ต่าง ๆ ของมุมมองแคตตาล็อกระบบคุณจะสังเกตเห็นการใช้ Collation ที่หลากหลาย ดังนั้นฉันจึงเห็นด้วยกับข้อความอ้างอิงหลักในคำถามที่ว่าหากการเปรียบเทียบจะแตกต่างกันมันควรจะตั้งใจ แต่ไม่มีอะไรผิดปกติกับมัน


เกี่ยวกับเรื่องนี้จากคำถาม (เน้นที่เพิ่ม):

ขณะกำหนดค่า Octopus Deploy Server การตั้งค่าล้มเหลวด้วยข้อผิดพลาด FATAL ในระหว่างการเริ่มต้นของ OctopusServer-instance บทความที่เกี่ยวข้องกับข้อความแสดงข้อผิดพลาดไม่ได้อธิบายว่าทำไมจึงเป็นข้อกำหนด

ฉันตรวจสอบหน้าเอกสารที่เชื่อมโยงและมันไม่ได้อธิบายว่าทำไมมันถึงเป็นข้อกำหนด ฉันได้คัดลอกข้อมูลที่เกี่ยวข้องจากเอกสารด้านล่างแล้ว:

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

พวกเขากำลังบอกว่ารหัสของพวกเขาในฐานข้อมูล Octopus มีการเข้าร่วมระหว่างคอลัมน์สตริงและน่าจะมีรหัสใหม่ที่นำมาใช้ในการอัพเกรดในอนาคตที่มี JOIN เพิ่มเติมในคอลัมน์สตริงใหม่ คอลัมน์ใหม่ไม่ว่าจะผ่านCREATE TABLEหรือALTER TABLE ... ADDจะได้รับการกำหนดการเรียงหน้าเริ่มต้นของฐานข้อมูลหากCOLLATEไม่ได้ระบุคำหลักสำหรับคอลัมน์สตริงใหม่ และเข้าร่วมระหว่างคอลัมน์สตริงที่ไม่มี Collation เดียวกันจะสร้างข้อผิดพลาด Collation ที่ไม่ตรงกัน พวกเขาดูเหมือนจะอนุญาตให้ผู้ใช้เลือก Collation ของตนเอง (อาจจะรองรับตำแหน่งที่ตั้งต่าง ๆ ) เนื่องจากพวกเขาพูดที่ด้านบนสุดว่าข้อกำหนดเพียงอย่างเดียวคือ Collation นั้นไม่คำนึงถึงขนาดตัวพิมพ์ และเนื่องจากการจัดเรียงของฐานข้อมูลที่รหัสของพวกเขาอาศัยอยู่ไม่ได้รับประกันว่าจะเหมือนกันพวกเขาไม่สามารถใช้COLLATEคำหลักเพื่อบังคับให้มีการเรียงหน้าเดียวกันในคอลัมน์สตริงใหม่ทั้งหมด (ดีพวกเขาสามารถทำได้ในทางเทคนิค SQL ไม่ใช่เรื่องง่ายที่จะจัดการเมื่อสร้างสคริปต์อัพเดต) หากพวกเขาสามารถใช้COLLATEคำหลักได้พวกเขาก็สามารถทำได้หลีกเลี่ยงการให้ Collation เริ่มต้นของฐานข้อมูลแตกต่างจากคอลัมน์สตริง ที่จะหลีกเลี่ยงข้อผิดพลาด "Collation mismatch" ที่ยาก แต่จะยังคงเปิดความเป็นไปได้ของการดำเนินการเปรียบเทียบที่เกี่ยวข้องกับหนึ่งในคอลัมน์สตริงเหล่านั้นและสตริงตัวอักษรหรือตัวแปรที่ทำให้เกิดพฤติกรรม "แปลก" เนื่องจากจะใช้ Collation ของคอลัมน์ไม่ใช่ฐานข้อมูล การตรวจทาน แน่นอนว่าอาจเป็นพฤติกรรมที่คาดหวังได้เป็นอย่างดี แต่เนื่องจากนี่เป็นแอปของบุคคลที่สามพฤติกรรมควรเป็นสิ่งที่พวกเขาตั้งใจจะมีมากกว่า 50/50 โอกาสระหว่าง a) สิ่งที่ผู้ใช้ต้องการ (หรือไม่คัดค้าน) และ b) สิ่งที่ผู้ใช้พิจารณาข้อบกพร่อง (และจากนั้น ทำให้เสียเวลาสนับสนุนของผู้ขายในการไล่ล่าห่านและ / หรือบล็อกเกี่ยวกับซอฟต์แวร์ของพวกเขาว่าเป็นบั๊กกี้)


เฮ้มีข่าวเกี่ยวกับโครงการ Collations ไหม?
Yaroslav

10

ในประโยคสั้น: การเปรียบเทียบ กำหนดเรียงลำดับและการเปรียบเทียบ

ดังนั้นการเปรียบเทียบจะกำหนดกฎที่ SQL Server ใช้เพื่อเปรียบเทียบและจัดเรียงข้อมูลอักขระ กฎเหล่านี้ทราบถึงภาษา / สถานที่และอาจมีความอ่อนไหวต่อตัวพิมพ์เล็กตัวพิมพ์ใหญ่สำเนียงคะนะและความกว้าง คำต่อท้ายการเรียงหน้าระบุกฎของพจนานุกรม (ใน) ความไว: _CS (ตัวพิมพ์เล็กและตัวพิมพ์ใหญ่), _CI (ตัวพิมพ์เล็กและตัวพิมพ์ใหญ่), _AS (เน้นความอ่อนไหว), _AI (เน้นความรู้สึกอ่อนไหว) และ _KS ( การเปรียบเทียบไบนารีที่ระบุโดยส่วนต่อท้าย _BIN (ไบนารี) และ _BIN2 (จุดรหัสไบนารี) มีความไวในทุกเรื่อง

การเปรียบเทียบที่แตกต่างกันจะเรียกใช้วิธีแก้ไขปัญหาเพื่อหลีกเลี่ยงข้อผิดพลาด "ไม่สามารถแก้ไขข้อขัดแย้งการเรียง" และสามารถฆ่าประสิทธิภาพเนื่องจากการแสดงออกที่ไม่สามารถระบุได้ การรับมือกับการเปรียบเทียบที่แตกต่างกันอาจเป็นฝันร้าย (อยู่ที่นั่น) ดังนั้นจึงเป็นเหตุผลที่คำแนะนำในการเลือกหนึ่งและติดกับมัน

การอ้างอิงเพิ่มเติม:


1

เช่นเดียวกับหลาย ๆ สิ่งใน SQL เวอร์ชันก่อนหน้าอาจทำให้เกิดปัญหาที่สำคัญได้ ดูบทความนี้จาก SQL7 / 2000

การจัดเรียง SqlServerCentral

ตอนนี้มีความแข็งแกร่งมากขึ้นและมีสถานการณ์ที่ความชอบธรรมในระบบที่ทันสมัยมากขึ้น แต่ก็ยังมีข้อแม้ที่น่าสนใจพอสมควรสำหรับการเปลี่ยนแปลง

นี่เป็นอีกซีรีย์ที่มีประโยชน์ในเวอร์ชั่นที่ทันสมัยกว่า โดย Dan Guzman ที่ฉันเชื่อว่าโพสต์ที่นี่เป็นประจำเพื่อเขาจะไปป์เร็ว ๆ นี้ :)

SQL Collation Hell

กล่าวโดยย่อความเข้ากันได้มาตรฐานและความนิยมของประสิทธิภาพเป็นสาเหตุหลักที่จะไม่ใช้การเปรียบเทียบแบบผสม


0

การถ่ายโอนข้อมูลระหว่างการเปรียบเทียบสามารถเปลี่ยนแปลงข้อมูลได้ถ้าเป็นอักขระ (ข้อความ 8 บิต) แทน nchar (16 บิต)

ฉันเชื่อจากหน้านี้https://the.agilesql.club/blogs/Blogs/Ed-Elliott/What-collation-variables-take-on-inT-SQL ว่าเมื่อตัวแปรถูกกำหนดด้วยข้อความจากตารางมันเป็น แปลโดยนัยไปยัง / ถือว่าเป็นการเปรียบเทียบฐานข้อมูลปัจจุบัน แต่เกิดอะไรขึ้นกับข้อความในตัวแปรเมื่อคุณย้ายไปยังฐานข้อมูลอื่น ไบต์เหล่านั้นได้รับการแปลอีกครั้ง (ถ้าจำเป็น) ในการเปรียบเทียบใหม่หรือไม่?

ฉันเลือกเคล็ดลับการจัดเรียงเพื่อลบเครื่องหมายเน้นเสียงตัวอักษร "ละติน" และออกจากข้อความ ASCII เท่านั้นซึ่งฉันต้องการเพราะซอฟต์แวร์ของ บริษัท อื่นสำลักเสียงเน้นเสียง - ฉันใส่ข้อความลงในการเปรียบเทียบที่มีเฉพาะ ASCII และตัวอักษรกรีกสมัยใหม่ Collate SQL_Latin1_General_CP1253_CI_AI. "Slán" เพื่อเน้นตัวอักษรโรมัน! ;-)

แต่ข่าวร้ายถ้าฉันต้องการเก็บไว้!

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