เมื่อคุณเริ่มต้นไปที่ "เขตข้อมูลที่ผู้ใช้กำหนด" ซึ่งมักพบในเครื่องมือติดตามข้อผิดพลาดการจัดการทรัพยากรลูกค้าและเครื่องมือทางธุรกิจที่คล้ายคลึงกันคือพวกเขาไม่ได้รับการสนับสนุนด้วยตารางที่มีเขตข้อมูลที่มีมูลค่ามากถึงพันล้าน (หากเป็นเช่นนั้น ของตัวเอง)
สิ่งที่คุณค้นหาคือการออกแบบตารางค่าเอนทิตีของเอนทิตีและเครื่องมือการดูแลระบบที่เกี่ยวข้องเพื่อจัดการคุณสมบัติที่ถูกต้อง
พิจารณาตารางต่อไปนี้:
+ + --------------
| สิ่ง |
| -------------- |
| id |
| ประเภท |
| desc |
| attr1 |
| attr2 |
| attr3 |
| attr4 |
| attr5 |
+ + --------------
นี่คือหลังจากที่คุณได้เพิ่มคุณสมบัติบางอย่าง แทนการattr1
แสร้งทำเป็นว่ามันอ่านartist
หรือtracks
หรือgenre
หรืออะไรก็ตามแอตทริบิวต์สิ่งที่มี และแทนที่จะเป็น 5 จะเกิดอะไรขึ้นถ้าเป็น 50 เห็นได้ชัดว่าไม่สามารถจัดการได้ นอกจากนี้ยังต้องการการอัปเดตโมเดลและการปรับใช้แอปพลิเคชันอีกครั้งเพื่อจัดการฟิลด์ใหม่ ไม่เหมาะ
พิจารณาโครงสร้างตารางต่อไปนี้:
+ -------------- + + --------------- + + ------------- +
| สิ่ง | | สิ่ง | attr |
| -------------- | | --------------- | | ------------- |
| id | <--- + | thing_id (fk) | +> | id |
| ประเภท | | attr_id (fk) | + - + | ชื่อ |
| desc | | ค่า | | |
+ -------------- + + --------------- + + ------------- +
คุณได้สิ่งที่มีพื้นฐานของมัน คุณมีอีกสองตาราง หนึ่งที่มีคุณสมบัติ แต่ละเขตข้อมูลเป็นแถวในattr
ตาราง แล้วก็มีthing_attr
ปุ่มต่างประเทศคู่หนึ่งที่สัมพันธ์กับthing
ตารางและattr
โต๊ะ และนี่มีเขตข้อมูลค่าที่คุณเก็บค่าใด ๆ ของเขตข้อมูลสำหรับเอนทิตีนั้น
และตอนนี้คุณมีโครงสร้างที่สามารถอัปเดตตาราง attr ที่รันไทม์และสามารถเพิ่มฟิลด์ใหม่ (หรือลบ) ได้ทันทีโดยไม่กระทบกับแอปพลิเคชันโดยรวมอย่างมีนัยสำคัญ
คิวรีมีความซับซ้อนขึ้นเล็กน้อยและการตรวจสอบก็มีความซับซ้อนมากขึ้นเช่นกัน (ทั้งโพรซีเดอร์ที่เก็บไว้ที่ขี้ขลาดหรือฝั่งไคลเอ็นต์ทั้งหมด) มันเป็นการแลกเปลี่ยนในการออกแบบ
พิจารณาสถานการณ์ที่บางวันคุณต้องทำการย้ายข้อมูลและกลับมาที่แอปพลิเคชันเพื่อค้นหาว่าขณะนี้มีครึ่งโหลหรือมากกว่านั้นมีคุณลักษณะมากกว่าสกีมาที่คุณเผยแพร่ สิ่งนี้ทำให้การโยกย้ายและอัปเกรดที่น่าเกลียดที่ตารางค่าแอตทริบิวต์ของเอนทิตีเมื่อใช้อย่างถูกต้องสามารถทำความสะอาดได้ (ไม่เสมอไป แต่สามารถเป็นได้)
มีข้อเสียใด ๆ เพียงแค่ปรับเปลี่ยน schema ที่รันไทม์? หากผู้ใช้คิดว่าจำเป็นต้องมีแอตทริบิวต์ใหม่ให้เพิ่มคอลัมน์ในตารางแบบไดนามิกหรือไม่
หากคุณกำลังทำงานกับรสชาติที่เหมาะสมของฐานข้อมูล nosql คุณอาจทำเช่นนี้ได้ (โปรดทราบว่ารสชาติที่เหมาะสมของ nosql สำหรับเรื่องนี้น่าจะเป็นที่เก็บคีย์ - ค่าซึ่งก็คือตาราง EAV สำหรับคนที่สัมพันธ์กันที่อธิบายไว้ข้างต้น) ไม่มีปัญหามากเกินไป อย่างไรก็ตามมันมาพร้อมกับการประนีประนอมทั้งหมดสำหรับ nosql ซึ่งมีการอธิบายที่อื่นในรายละเอียดที่ดี
หากคุณกำลังทำงานกับฐานข้อมูลเชิงสัมพันธ์ - คุณต้องมีสคีมา การเพิ่มคอลัมน์แบบไดนามิกหมายถึงบางส่วนของสิ่งต่อไปนี้เป็นจริง:
- คุณกำลังเขียนโปรแกรมเมตาดาต้า แทนที่จะสามารถแมปคอลัมน์นี้กับฟิลด์นั้นด้วย ORM ที่ดีคุณอาจทำสิ่งต่าง ๆ เช่น
select *
แล้วทำโค้ดที่ซับซ้อนเพื่อค้นหาว่าข้อมูลคืออะไรจริง ๆ (ดูที่ResultSetMetaData ของ Java ) จากนั้นเก็บไว้ในแผนที่ ( หรือประเภทข้อมูลอื่น - แต่ไม่ใช่เขตข้อมูลที่ดีในรหัส) สิ่งนี้จะละทิ้งประเภทของงานพิมพ์และความปลอดภัยของการพิมพ์ผิดที่คุณมีอยู่ด้วยวิธีการดั้งเดิม
- คุณน่าจะละทิ้ง ORM ซึ่งหมายความว่าคุณกำลังเขียน sql ดิบสำหรับรหัสทั้งหมดแทนที่จะปล่อยให้ระบบทำงานแทนคุณ
- คุณเลิกใช้การอัปเกรดที่สะอาดหมดจดแล้ว จะเกิดอะไรขึ้นเมื่อลูกค้าเพิ่มเขตข้อมูลด้วยชื่อเดียวที่รุ่นถัดไปของคุณใช้ด้วย ในเว็บไซต์จับคู่การอัปเกรดที่ต้องการเพิ่ม
hasdate
เขตข้อมูลสำหรับการจัดเก็บเวลาประทับได้ถูกกำหนดไว้แล้วเช่นเดียวhasdate
กับบูลีนสำหรับการจับคู่ที่ประสบความสำเร็จ ... และตัวแบ่งการอัปเกรดของคุณ
- คุณเชื่อมั่นว่าลูกค้าจะไม่ทำลายระบบโดยใช้คำที่สงวนไว้บางคำซึ่งทำลายการสืบค้นของคุณด้วย ... บางแห่ง
- คุณผูกพันกับฐานข้อมูลหนึ่งแบรนด์ DDLของฐานข้อมูลที่แตกต่างกันจะแตกต่างกัน ประเภทฐานข้อมูลเป็นตัวอย่างที่ง่ายที่สุดของสิ่งนี้
varchar2
vs text
และไม่ชอบ รหัสของคุณเพื่อเพิ่มคอลัมน์จะทำงานบน MySQL แต่ไม่ใช่ Postgres หรือ Oracle หรือ SQL Server
- คุณให้ความไว้วางใจของลูกค้าที่จริงเพิ่มข้อมูลดี ? แน่นอนว่า EAV นั้นห่างไกลจากอุดมคติ แต่ตอนนี้คุณมีชื่อตารางที่คลุมเครือที่น่ากลัวซึ่งคุณผู้พัฒนาไม่ได้เพิ่มด้วยดัชนีชนิดผิด (ถ้ามี) โดยไม่มีข้อ จำกัด ในรหัสที่จำเป็นต้อง เป็นและอื่น ๆ
- คุณได้รับสิทธิ์การแก้ไขสคีมาให้กับผู้ใช้ที่เรียกใช้แอปพลิเคชัน Bobby Drop Tables เล็ก ๆ น้อย ๆเป็นไปไม่ได้เมื่อคุณถูก จำกัด ให้ใช้ SQL แทนที่จะเป็น DDL (แน่นอนว่าคุณสามารถทำ
delete * from students
แทนได้ จำนวนของสิ่งต่าง ๆ ที่ผิดไปจากการเข้าถึงสคีมาทั้งจากอุบัติเหตุหรือกิจกรรมที่เป็นอันตราย
สิ่งนี้ทำให้เดือดร้อนอย่างมากที่ "อย่าทำ" หากคุณต้องการสิ่งนี้จริงๆให้ไปกับรูปแบบที่รู้จักของโครงสร้างตาราง EAV หรือฐานข้อมูลที่อุทิศให้กับโครงสร้างนี้ทั้งหมด อย่าปล่อยให้คนสร้างเขตข้อมูลเองในตาราง อาการปวดหัวก็ไม่คุ้ม