สมมติว่าฉันมีบริการ 4 ประเภทที่ฉันเสนอให้ (พวกเขาไม่น่าจะเปลี่ยนแปลงบ่อย):
- การทดสอบ
- ออกแบบ
- การเขียนโปรแกรม
- อื่น ๆ
สมมติว่าฉันมีบริการจริง 60-80 รายการที่แต่ละบริการจัดอยู่ในหมวดหมู่ข้างต้น ตัวอย่างเช่น 'บริการ' สามารถเป็น "โปรแกรมทดสอบโดยใช้เทคนิค A" และเป็นประเภท "การทดสอบ"
ฉันต้องการเข้ารหัสให้เป็นฐานข้อมูล ฉันมากับตัวเลือกไม่กี่:
ตัวเลือก 0:
ใช้VARCHAR
โดยตรงเพื่อเข้ารหัสประเภทบริการโดยตรงเป็นสตริง
ตัวเลือกที่ 1:
enum
ฐานข้อมูลการใช้งาน แต่enum นั้นชั่วร้าย
ตัวเลือก 2:
ใช้สองตาราง:
service_line_item (id, service_type_id INT, description VARCHAR);
service_type (id, service_type VARCHAR);
ฉันยังสามารถเพลิดเพลินกับ Referential Integrity:
ALTER service_line_item
ADD FOREIGN KEY (service_type_id) REFERENCES service_type (id);
ฟังดูดีใช่มั้ย
แต่ฉันยังคงต้องเข้ารหัสสิ่งต่าง ๆ และจัดการกับจำนวนเต็มเช่นเมื่อเติมตาราง หรือฉันต้องสร้างการเขียนโปรแกรมอย่างละเอียดหรือสร้าง DB เมื่อเติมหรือจัดการกับตาราง กล่าวคือเข้าร่วมเมื่อจัดการกับฐานข้อมูลโดยตรงหรือสร้างเอนทิตีวัตถุที่มุ่งเน้นใหม่ในด้านการเขียนโปรแกรมและทำให้แน่ใจว่าฉันทำงานได้อย่างถูกต้อง
ตัวเลือก 3:
อย่าใช้enum
อย่าใช้สองตาราง แต่เพียงใช้คอลัมน์จำนวนเต็ม
service_line_item (
id,
service_type INT, -- use 0, 1, 2, 3 (for service types)
description VARCHAR
);
นี่เป็นเหมือน 'ปลอม enum' ที่ต้องการค่าใช้จ่ายมากขึ้นในด้านโค้ดของสิ่งต่าง ๆ เช่นรู้{2 == 'Programming'}
และจัดการกับมันอย่างเหมาะสม
คำถาม:
ขณะนี้ฉันได้นำไปใช้โดยใช้ตัวเลือกที่ 2ภายใต้แนวคิด
- ห้ามใช้ enum (ตัวเลือก 1)
- หลีกเลี่ยงการใช้ฐานข้อมูลเป็นสเปรดชีต (ตัวเลือก 0)
แต่ฉันอดไม่ได้ที่จะรู้สึกว่ามันไร้ประโยชน์สำหรับฉันในแง่ของการเขียนโปรแกรมและค่าใช้จ่ายด้านความคิด - ฉันต้องระวังสองตารางและจัดการกับสองตารางเทียบกับหนึ่ง
สำหรับ 'วิธีที่สิ้นเปลืองน้อย' Option 3
ฉันกำลังมองหาที่ ไอทีมีน้ำหนักเบาและจำเป็นต้องใช้รหัสเดียวกันเพื่อสร้างการทำงาน (ด้วยการปรับเปลี่ยนเล็กน้อย แต่ความซับซ้อนและโครงสร้างนั้นเหมือนกัน แต่มีโต๊ะเดียว)
ฉันคิดว่ามันไม่สิ้นเปลืองเสมอไปและมีกรณีที่ดีสำหรับตัวเลือกทั้งสอง แต่มีแนวทางที่ดีว่าควรใช้ตัวเลือกที่ 2 และตัวเลือกที่ 3 เมื่อใด
เมื่อมีเพียงสองประเภท (ไบนารี)
ในการเพิ่มคำถามนี้อีกเล็กน้อย ... ในสถานที่เดียวกันฉันมีตัวเลือกไบนารีของบริการ "มาตรฐาน" หรือ "ยกเว้น" ซึ่งสามารถใช้กับรายการโฆษณาบรรทัดบริการได้ ฉันได้เข้ารหัสว่าการใช้ตัวเลือกที่ 3
ฉันเลือกที่จะไม่สร้างตารางใหม่เพื่อเก็บค่า {"Standard", "Exception"} ดังนั้นคอลัมน์ของฉันเพิ่งจะถือ {0, 1} และชื่อคอลัมน์ของฉันถูกเรียกexception
และรหัสของฉันกำลังทำการแปลจาก{0, 1} => {STANDARD, EXCEPTION}
(ซึ่งฉันเข้ารหัสเป็นค่าคงที่ในภาษาการเขียนโปรแกรม)
จนถึงตอนนี้ไม่ชอบวิธีนั้น ..... (ไม่ใช่ตัวเลือกที่ชื่นชอบ 2 หรือตัวเลือก 3) ฉันค้นหาตัวเลือก 2 ที่เหนือกว่า 3 แต่มีค่าใช้จ่ายมากกว่าและยังคงฉันไม่สามารถหลีกเลี่ยงการเข้ารหัสสิ่งต่าง ๆ เป็นจำนวนเต็มไม่ว่าตัวเลือกใดที่ฉันใช้จาก 2 และ 3
ออม
ในการเพิ่มบริบทหลังจากอ่านคำตอบ - ฉันเพิ่งเริ่มใช้ ORM อีกครั้ง (เมื่อเร็ว ๆ นี้) ในกรณีของฉัน Doctrine 2 หลังจากกำหนด DB schema ผ่านคำอธิบายประกอบฉันต้องการเติมฐานข้อมูล เนื่องจากชุดข้อมูลทั้งหมดของฉันมีขนาดค่อนข้างเล็กฉันจึงอยากลองใช้การเขียนโปรแกรมโครงสร้างเพื่อดูว่ามันทำงานอย่างไร
ฉันเติมข้อมูลservice_type
s ก่อนแล้วจึงservice_line_item
s เนื่องจากมีรายการที่มีอยู่จากสเปรดชีตจริง ดังนั้นสิ่งต่างๆเช่น 'มาตรฐาน / ข้อยกเว้น' และ 'การทดสอบ' จึงเป็นสตริงทั้งหมดในสเปรดชีตและจะต้องเข้ารหัสเป็นประเภทที่เหมาะสมก่อนที่จะเก็บไว้ในฐานข้อมูล
ฉันพบคำตอบ SO นี้: คุณใช้อะไรแทน ENUM ในหลักคำสอน 2 ซึ่งแนะนำให้ไม่ใช้การสร้าง Enum ของ DB แต่ใช้INT
ฟิลด์และเข้ารหัสชนิดโดยใช้โครงสร้าง 'const' ของภาษาโปรแกรม
แต่ดังที่ระบุไว้ในคำถาม SO ข้างต้นฉันสามารถหลีกเลี่ยงการใช้จำนวนเต็มโดยตรงและใช้โครงสร้างภาษา - ค่าคงที่ - เมื่อมีการกำหนด ....
แต่ยังคง .... ไม่ว่าคุณจะเลี้ยวอย่างไรถ้าฉันเริ่มต้นด้วยstring
ประเภทฉันต้องแปลงมันเป็นประเภทที่เหมาะสมก่อนแม้ว่าจะใช้ ORM
ดังนั้นถ้าพูดว่า$str = 'Testing';
ฉันยังต้องมีบล็อกอยู่ที่ไหนสักแห่งที่ทำสิ่งที่ชอบ:
switch($str):
{
case 'Testing': $type = MyEntity::TESTING; break;
case 'Other': $type = MyEntity::OTHER; break;
}
สิ่งที่ดีคือคุณไม่ได้จัดการกับจำนวนเต็ม / เลขเวทย์มนตร์ [แทนการจัดการกับปริมาณคงที่ที่เข้ารหัส] แต่สิ่งที่เลวร้ายคือคุณไม่สามารถดึงสิ่งที่เข้าและออกจากฐานข้อมูลโดยอัตโนมัติโดยไม่มีขั้นตอนการแปลงนี้ ความรู้
และนั่นคือสิ่งที่ฉันหมายถึงในส่วนของการพูดสิ่งต่าง ๆ เช่น "ยังต้องเข้ารหัสสิ่งต่างๆและจัดการกับจำนวนเต็ม" (ได้รับตอนนี้หลังจากความคิดเห็นของ Ocramius ฉันไม่ต้องจัดการกับจำนวนเต็มโดยตรง แต่จัดการกับค่าคงที่ที่มีชื่อและการแปลงค่าเป็น / จากค่าคงที่ตามต้องการ)