สิ่งหนึ่งที่ควรพิจารณาคือคีย์หลักและดัชนีแบบคลัสเตอร์นั้นไม่เหมือนกัน คีย์หลักเป็นข้อ จำกัด และจัดการกับกฎที่ข้อมูลมีชีวิตอยู่ (เช่นความสมบูรณ์ของข้อมูล); มันไม่มีส่วนเกี่ยวข้องกับประสิทธิภาพ / ประสิทธิภาพ คีย์หลักกำหนดให้คอลัมน์คีย์ต้องไม่ซ้ำกัน (รวมกัน) และไม่เป็นโมฆะ (แยกกัน) มีการบังคับใช้ PK ผ่านดัชนีที่ไม่ซ้ำแม้ว่ามันจะเป็นแบบคลัสเตอร์หรือแบบไม่เป็นคลัสเตอร์ก็ได้
ดัชนีแบบคลัสเตอร์เป็นวิธีการทางกายภาพ (เช่นบนดิสก์) การเรียงลำดับข้อมูลในตารางและข้อตกลงกับประสิทธิภาพ มันไม่เกี่ยวข้องกับความถูกต้องของข้อมูล ดัชนีแบบคลัสเตอร์สามารถกำหนดให้คอลัมน์คีย์ต้องไม่ซ้ำกัน (รวมกัน) แต่ไม่จำเป็นต้องทำ อย่างไรก็ตามเนื่องจากดัชนีแบบกลุ่มเป็นลำดับทางกายภาพของข้อมูลจึงจำเป็นต้องระบุแต่ละแถวโดยไม่ซ้ำกัน ดังนั้นหากคุณไม่ได้กำหนดให้ต้องมีความไม่ซ้ำกันมันจะสร้างเอกลักษณ์ของตัวเองผ่านคอลัมน์ "uniquifier" 4 ไบต์ที่ซ่อนอยู่ คอลัมน์นั้นจะมีอยู่เสมอในดัชนีที่ไม่ซ้ำแบบคลัสเตอร์ แต่จะไม่ใช้พื้นที่ใด ๆ เมื่อเขตข้อมูลคีย์นั้นไม่ซ้ำกัน (รวมกัน) ในการดูมือแรกว่าคอลัมน์ "uniquifier" นี้ทำงานอย่างไร (ทั้งในดัชนีแบบคลัสเตอร์และผลกระทบต่อดัชนีที่ไม่ใช่แบบคลัสเตอร์)สคริปต์ T-SQL เพื่อทดสอบขนาด
ดังนั้นคำถามหลักของ:
มันจะมีประสิทธิภาพมากขึ้นในการเพิ่มid
เขตข้อมูลที่เพิ่มขึ้นอัตโนมัติและใช้งานร่วมกับcompany_id
เป็นคีย์หลักหรือจะเพิ่มค่าใช้จ่ายที่ไม่จำเป็น
กำลังทำให้ทั้งสองแนวคิดสับสนดังนั้นพวกเขาจึงจำเป็นต้องแก้ไขแยกต่างหากแม้ว่าจะมีบางอย่างทับซ้อนกันอย่างแน่นอน
ควรมีการIDENTITY
เพิ่มคอลัมน์หรือจะเป็นค่าใช้จ่ายที่ไม่จำเป็นหรือไม่?
หากคุณเพิ่มINT IDENTITY
คอลัมน์และใช้เพื่อสร้าง PK สมมติว่ามันเป็น Clustered PK ซึ่งเพิ่ม 4 ไบต์ให้กับทุกแถว คอลัมน์นี้สามารถมองเห็นได้และใช้งานได้ในแบบสอบถาม มันจะถูกเพิ่มเข้าไปในตารางอื่น ๆ เป็นสำคัญต่างประเทศ แต่ในกรณีนี้โดยเฉพาะว่าจะไม่เกิดขึ้น
หากคุณไม่เพิ่มINT IDENTITY
คอลัมน์คุณจะไม่สามารถสร้าง PK ในตารางนี้ อย่างไรก็ตามคุณยังสามารถสร้างดัชนีแบบกลุ่มบนตารางได้ตราบใดที่คุณไม่ได้ใช้UNIQUE
ตัวเลือก ในกรณีนี้ SQL Server จะเพิ่มคอลัมน์ที่ซ่อนอยู่ซึ่งเรียกว่า "uniquifier" ซึ่งจะทำงานตามที่อธิบายไว้ข้างต้น เนื่องจากคอลัมน์ถูกซ่อนอยู่จึงไม่สามารถใช้ในการสืบค้นหรือใช้เป็นข้อมูลอ้างอิงสำหรับ Foreign Keys
เท่าที่มีประสิทธิภาพไปตัวเลือกเหล่านี้จะเหมือนกัน ใช่จะมีพื้นที่น้อยกว่าเล็กน้อยโดยมีดัชนีที่ไม่ซ้ำกันอันเนื่องมาจากบางแถว (แถวที่มีค่าคีย์เฉพาะเริ่มต้น) รับ 0 ไบต์ในขณะที่แถวทั้งหมดในIDENTITY
/ PK จะใช้ 4 ไบต์ แต่จะมีแถว 0 ไบต์ไม่เพียงพอ (โดยเฉพาะอย่างยิ่งเมื่อมีจำนวนแถวน้อย) ที่จะสังเกตเห็นความแตกต่างได้โดยไม่คำนึงถึงความสะดวกในการใช้ID
คอลัมน์ในแบบสอบถาม
INT IDENTITY คอลัมน์หรือแฮชของorg_path
คอลัมน์ที่คำนวณแล้วหรือไม่
ระบุว่าคุณจะไม่ต้องค้นหาแถวตามorg_path
ค่าดังนั้นจึงไม่เหมาะสมที่จะเพิ่มค่าใช้จ่ายของคอลัมน์ที่คำนวณแล้วรวมถึงต้องคำนวณแฮชนั้นในแบบสอบถามเพื่อให้ตรงกับคอลัมน์ที่คำนวณ (นี่คือของฉัน ข้อเสนอแนะดั้งเดิมมีอยู่ในประวัติการแก้ไขที่นี่ซึ่งมีพื้นฐานมาจากถ้อยคำ / รายละเอียดของคำถาม) ในกรณีนี้INT IDENTITY
คอลัมน์ "ID" น่าจะดีที่สุด
สั่งซื้อคอลัมน์คีย์
ระบุว่าID
คอลัมน์จะไม่ค่อยถูกใช้ในการสืบค้นและให้ที่หลักสองกรณีการใช้งานจะได้รับทั้ง "แถวทั้งหมด" หรือ "แถวทั้งหมดสำหรับการรับcompany_id
" ผมจะสร้าง PK company_id, id
บน และเนื่องจากนี่หมายความว่าแถวไม่ได้แทรกตามลำดับฉันจะระบุFILLFACTOR
90 ของคุณจะต้องตรวจสอบให้แน่ใจว่าได้ทำการบำรุงรักษาดัชนีปกติเพื่อลดการกระจายตัว
คำถามที่สอง
ความจริงที่ว่า company_id เป็นคีย์หลักในตารางอื่นมีผลกระทบใด ๆ ที่นี่
เลขที่
ไก
เนื่องจากorg_path
ค่าภายใน a company_id
ไม่ซ้ำกันคุณจึงควรสร้าง Trigger on INSERT, UPDATE
เพื่อบังคับใช้ ในไกทำIF EXISTS
แบบสอบถามที่อาจจะไม่ได้และCOUNT(*)
GROUP BY company_id, org_path
หากพบสิ่งใดให้ออกROLLBACK
เพื่อยกเลิกการดำเนินการ DML แล้วRAISERROR
แจ้งว่ามีการทำซ้ำ
การตรวจทาน
ในคำตอบเริ่มต้นของฉัน (ขึ้นอยู่กับถ้อยคำต้นฉบับ / รายละเอียดของคำถามที่เบาบางและมีอยู่ในประวัติการแก้ไขที่นี่ ) ฉันแนะนำว่าอาจใช้การจัดเรียงไบนารี (เช่น_BIN2
) ตอนนี้เรามีข้อมูลเชิงลึกเกี่ยวกับสิ่งที่แน่นอนorg_path
ฉันจะไม่แนะนำให้ใช้การเปรียบเทียบไบนารี เนื่องจากจะมีการออกเสียงวรรณยุกต์คุณไม่ต้องการที่จะทำให้การใช้งานของ equivalences ภาษา