ใช่มีผลกระทบเชิงลบอย่างแน่นอนสำหรับการใช้สตริงแทนที่จะเป็นชนิดตัวเลขสำหรับคีย์หลักและยิ่งกว่านั้นถ้า PK นั้นเป็นกลุ่ม (ซึ่งแน่นอนในกรณีของคุณ) อย่างไรก็ตามระดับที่คุณเห็นผลกระทบของการใช้เขตข้อมูลสตริงคือฟังก์ชันของ a) จำนวนแถวในตารางนี้และ b) จำนวนแถวในตารางอื่น ๆ เป็น Foreign Key ที่มีต่อ PK นี้ หากคุณมี 10k แถวในตารางนี้และ 100k แถวในตารางอื่น ๆ ไม่กี่ตารางที่ FK ไปยังตารางนี้ผ่านเขตข้อมูลนั้นบางทีมันอาจจะไม่เป็นที่สังเกตเห็น แต่ผลกระทบเหล่านั้นจะสังเกตเห็นได้ชัดเจนขึ้นเมื่อจำนวนแถวเพิ่มขึ้น
คุณต้องพิจารณาว่าเขตข้อมูลในดัชนีแบบคลัสเตอร์จะถูกส่งไปยังดัชนีที่ไม่ได้เป็นกลุ่ม ดังนั้นคุณไม่ได้ดูข้อมูลมากถึง 40 ไบต์ต่อแถว แต่ (40 * some_number) ไบต์ และในตาราง FK ใด ๆ ที่คุณมี 40 ไบต์เดียวกันในแถวบวกบ่อยกว่าไม่จะมีดัชนีที่ไม่เป็นคลัสเตอร์บนเขตข้อมูลนั้นเนื่องจากมันถูกใช้ใน JOIN ดังนั้นตอนนี้มันจึงเพิ่มเป็นสองเท่าในตารางใด ๆ ที่ FK อันนี้. ถ้าใครอยากจะคิดว่า 40 ไบต์ * 1 ล้านแถว * 10 สำเนานั้นไม่มีอะไรน่ากังวลโปรดอ่านบทความของฉันDisk is Cheap! ORLY? ซึ่งรายละเอียดทั้งหมด (หรืออย่างน้อยที่สุด) ของพื้นที่ได้รับผลกระทบจากการตัดสินใจครั้งนี้
สิ่งอื่น ๆ ที่ต้องพิจารณาคือการกรองและการเรียงลำดับในสายโดยเฉพาะอย่างยิ่งเมื่อไม่ได้ใช้ไบนารีเปรียบเทียบ (ผมถือว่าคุณกำลังใช้ค่าเริ่มต้นฐานข้อมูลซึ่งเป็นกรณีตายโดยทั่วไป) อยู่ไกลมีประสิทธิภาพน้อยลง (เช่นใช้เวลานานกว่า) เมื่อใช้/INT
BIGINT
สิ่งนี้จะส่งผลต่อคิวรีทั้งหมดที่กรอง / เข้าร่วม / เรียงลำดับในฟิลด์นี้
ดังนั้นการใช้บางสิ่งบางอย่างCHAR(5)
อาจจะเป็นสิ่งที่ดีสำหรับ Clustered PK แต่ส่วนใหญ่ถ้ามันถูกกำหนดด้วยCOLLATE Latin1_General_100_BIN2
(หรือบางอย่างเช่นนั้น)
และคุณค่าของ[CODE]
การเปลี่ยนแปลงที่เคยสามารถ? ถ้าใช่นั่นคือเหตุผลที่จะไม่ใช้มันเป็น PK (แม้ว่าคุณจะตั้งค่า FKs เป็นON UPDATE CASCADE
) หากมันไม่สามารถเปลี่ยนแปลงได้หรือไม่เคยเปลี่ยนแปลง แต่ก็ยังมีเหตุผลมากพอที่จะไม่ใช้มันในแบบของ Clustered PK
แน่นอนคำถามอาจถูกใช้อย่างไม่ถูกต้องเนื่องจากดูเหมือนว่าคุณมีฟิลด์นี้ใน PK ของคุณอยู่แล้ว
โดยไม่คำนึงถึงตัวเลือกที่ดีที่สุดของคุณคือการใช้[ID_CODE]
เป็น Clustered PK ใช้ฟิลด์นั้นในตารางที่เกี่ยวข้องเป็น FK และเก็บไว้[CODE]
เป็นUNIQUE INDEX
(ซึ่งหมายความว่ามันเป็น "คีย์สำรอง")
อัปเดต
ข้อมูลเพิ่มเติมเล็กน้อยตามคำถามนี้ในความคิดเห็นของคำตอบนี้:
[ID_CODE] เป็นคีย์หลักตัวเลือกที่ดีที่สุดหรือไม่ถ้าฉันใช้คอลัมน์ [CODE] เพื่อค้นหาตาราง
ทั้งหมดนี้ขึ้นอยู่กับหลายปัจจัยหลายอย่างที่ฉันได้กล่าวไปแล้ว แต่จะกล่าวซ้ำ:
คีย์หลักคือวิธีระบุแต่ละแถวไม่ว่าจะถูกอ้างอิงโดยคีย์ต่างประเทศใด ๆ ระบบของคุณระบุแถวภายในอย่างไร แต่ไม่จำเป็นต้องเหมือนกับแถวที่ผู้ใช้ระบุตัวเอง / แถวนั้น คอลัมน์ NULL ใด ๆ ที่มีข้อมูลที่ไม่ซ้ำใครสามารถใช้งานได้ แต่มีปัญหาเรื่องการปฏิบัติจริงที่ต้องพิจารณาโดยเฉพาะถ้าในความเป็นจริง PK นั้นอ้างอิงโดย FK ตัวอย่างเช่น GUID นั้นมีเอกลักษณ์และบางคนชอบที่จะใช้มันด้วยเหตุผลต่าง ๆ แต่มันค่อนข้างแย่สำหรับดัชนีแบบกลุ่ม ( NEWSEQUENTIALID
ดีกว่า แต่ไม่สมบูรณ์แบบ) ในทางกลับกัน GUID นั้นดีพอ ๆ กับปุ่มสำรองและใช้โดยแอพเพื่อค้นหาแถว แต่ JOIN ก็ยังคงใช้ PK (หรือคล้ายกัน) ในลักษณะ INT
จนถึงตอนนี้คุณยังไม่ได้บอกเราว่า[CODE]
เขตข้อมูลเข้ากับระบบจากทุกมุมได้อย่างไรนอกเหนือจากตอนนี้ที่กล่าวถึงว่านี่คือวิธีที่คุณค้นหาแถว แต่มันคือการค้นหาทั้งหมด ดังนั้น:
เกี่ยวกับ[CODE]
ค่า:
- มันสร้างขึ้นมาได้อย่างไร?
- มันเพิ่มขึ้นหรือสุ่ม psuedo?
- มันยาวหรือยาวแตกต่างกันหรือไม่?
- ใช้อักขระอะไร
- หากใช้ตัวอักษรตามตัวอักษร: เป็นตัวพิมพ์เล็กหรือตัวพิมพ์เล็กหรือไม่
- มันสามารถเปลี่ยนแปลงได้หลังจากใส่เข้าไปหรือไม่?
เกี่ยวกับตารางนี้:
- ทำตารางอื่น ๆ FK ไปที่ตารางนี้หรือไม่? หรือมีการใช้ฟิลด์เหล่านี้ (
[CODE]
หรือ[ID_CODE]
) ในตารางอื่นแม้ว่าจะไม่ใช่ Foreign Keyed อย่างชัดเจนก็ตาม
- ถ้า
[CODE]
เป็นเพียงฟิลด์เดียวที่ใช้เพื่อรับแถวแต่ละแถว[ID_CODE]
ฟิลด์นั้นมีจุดประสงค์อะไร หากไม่มีการใช้งานทำไมถึงเป็นอันดับแรก (ซึ่งอาจขึ้นอยู่กับคำตอบของ " [CODE]
ฟิลด์สามารถเปลี่ยนแปลงได้หรือไม่")
- มีกี่แถวในตารางนี้
- หากตารางอื่นอ้างอิงตารางนี้มีกี่แถวในแต่ละแถว?
- ดัชนีสำหรับตารางนี้คืออะไร
การตัดสินใจนี้ไม่สามารถทำได้อย่างหมดจดกับคำถามของ "NVARCHAR ใช่หรือไม่" ฉันจะพูดอีกครั้งว่าโดยทั่วไปการพูดฉันไม่คิดว่ามันจะเป็นความคิดที่ดี แต่มีบางครั้งที่มันใช้ได้ เนื่องจากบางฟิลด์ในตารางนี้ไม่น่าเป็นไปได้ที่จะมีดัชนีมากกว่านี้หรืออย่างน้อยก็ไม่มาก ดังนั้นคุณอาจปรับวิธีการ[CODE]
เป็นดัชนีแบบคลัสเตอร์ และถ้าไม่มีตารางอื่นอ้างอิงตารางนี้คุณก็อาจจะทำให้มันเป็น PK แต่ถ้าตารางอื่นอ้างอิงตารางนี้ฉันจะเลือกใช้[ID_CODE]
ฟิลด์เป็น PK แม้ว่าจะไม่เป็นคลัสเตอร์