ฉันกำลังพัฒนาแอพพลิเคชั่นใน Ruby on Rails ด้วยฐานข้อมูล PostgreSQL (9.4) สำหรับกรณีการใช้งานของฉันคอลัมน์ในตารางจะถูกค้นหาบ่อยมากเนื่องจากทั้งจุดของแอปพลิเคชันกำลังค้นหาแอตทริบิวต์ที่เฉพาะเจาะจงมากในแบบจำลอง
ฉันกำลังตัดสินใจว่าจะใช้integer
ชนิดหรือเพียงแค่ใช้ประเภทสตริงทั่วไป (เช่นcharacter varying(255)
, ซึ่งเป็นค่าเริ่มต้นใน Rails ) สำหรับคอลัมน์ที่เป็นผมไม่แน่ใจว่าสิ่งที่แตกต่างของประสิทธิภาพการทำงานจะอยู่ในดัชนี
คอลัมน์เหล่านี้เป็น enums มีขนาดคงที่สำหรับจำนวนค่าที่เป็นไปได้ที่สามารถมีได้ ส่วนใหญ่ความยาว enum ไม่เกิน 5 หมายถึงดัชนีจะมีมากขึ้นหรือน้อยคงที่ตลอดอายุการใช้งานของโปรแกรม ; ดังนั้นจำนวนเต็มและดัชนีสตริงจะเหมือนกันในจำนวนโหนด
อย่างไรก็ตามสตริงที่จะทำดัชนีอาจมีความยาวประมาณ 20 ตัวอักษรซึ่งในหน่วยความจำประมาณ 5x ของจำนวนเต็ม (ถ้าจำนวนเต็ม 4 ไบต์และสตริงนั้นเป็น ASCII บริสุทธิ์ที่ 1 ไบต์ต่อตัวอักษรดังนั้นสิ่งนี้จะเก็บไว้) ฉันไม่รู้ว่าเอ็นจิ้นฐานข้อมูลทำการค้นหาดัชนีอย่างไร แต่ถ้ามันจำเป็นต้อง "สแกน" สตริงจนกว่าจะตรงกันทั้งหมดดังนั้นในสาระสำคัญซึ่งหมายความว่าการค้นหาสตริงจะช้ากว่าการค้นหาจำนวนเต็ม 5 เท่า "สแกน" จนกระทั่งตรงกับการค้นหาจำนวนเต็มจะเป็น 4 ไบต์แทน 20 นี่คือสิ่งที่ฉันจินตนาการ
ค่าการค้นหาคือ (จำนวนเต็ม) 4:
สแกน ............................ พบ | กำลังรับบันทึก ... | BYTE_1 | BYTE_2 | BYTE_3 | BYTE_4 | BYTE_5 | BYTE_6 | BYTE_7 | BYTE_8 | ... | |
ค่าการค้นหาคือ (สตริง) "some_val" (8 ไบต์):
สแกน ................................................. พบ .................................... กำลังรับบันทึก ... | BYTE_1 | BYTE_2 | BYTE_3 | BYTE_4 | BYTE_5 | BYTE_6 | BYTE_7 | BYTE_8 | ... | |
ฉันหวังว่านั่นสมเหตุสมผล โดยทั่วไปเนื่องจากจำนวนเต็มใช้พื้นที่น้อยกว่าจึงสามารถ "จับคู่" ได้เร็วกว่าสตริงคู่ บางทีนี่อาจเป็นการคาดเดาที่ผิด แต่ฉันไม่ชำนาญดังนั้นฉันจึงถามพวกนาย! ฉันคิดว่าคำตอบที่ฉันเพิ่งพบนั้นดูเหมือนจะสนับสนุนสมมติฐานของฉัน แต่ฉันต้องการที่จะแน่ใจ
จำนวนค่าที่เป็นไปได้ในคอลัมน์จะไม่เปลี่ยนแปลงโดยใช้ค่าใดค่าหนึ่งดังนั้นดัชนีจะไม่เปลี่ยนแปลง (เว้นแต่ฉันจะเพิ่มค่าใหม่ให้กับ enum) ในกรณีนี้จะมีความแตกต่างด้านประสิทธิภาพในการใช้งานinteger
หรือvarchar(255)
หรือใช้ประเภทจำนวนเต็มเหมาะสมหรือไม่
เหตุผลที่ฉันถามก็คือenum
ประเภทของ Rails จับคู่จำนวนเต็มกับคีย์สตริง แต่ไม่ได้หมายความว่าจะต้องเป็นคอลัมน์ที่ผู้ใช้หันเข้าหากัน โดยพื้นฐานแล้วคุณไม่สามารถทำการตรวจสอบว่าค่า enum เป็นค่าที่ถูกต้องเพราะค่าที่ไม่ถูกต้องจะทำให้เกิดArgumentError
ก่อนที่การตรวจสอบความถูกต้องใด ๆ จะสามารถทำงานได้ การใช้string
ประเภทจะอนุญาตให้มีการตรวจสอบความถูกต้อง แต่หากมีค่าใช้จ่ายในการปฏิบัติงานฉันควรที่จะแฮ็กข้อมูลเกี่ยวกับปัญหาการตรวจสอบความถูกต้อง
varchar(255)
varchar(260)
อาจมีเรื่องดังกล่าวกับ SQL Server 6.x แต่สิ่งนี้ไม่เป็นความจริงเป็นเวลานาน