ฉันจะไม่เห็นด้วยอย่างอ่อนโยนกับทุกคนและบอกว่าวิธีการเชิงสัมพันธ์มีเหตุผลที่นี่ สิ่งที่น่าสนใจที่นี่คือไอเท็มสามารถมีได้หลายบทบาท ปัญหาหลักคือว่าการแมประหว่างเลย์เอาท์เชิงสัมพันธ์นี้กับเลย์เอาต์ OO ในโค้ดจะไม่รู้สึก“ เป็นธรรมชาติ” แต่ฉันคิดว่าในหลาย ๆ ด้านของฐานข้อมูลสามารถแสดงบทบาทได้อย่างหมดจด (โดยไม่มีการเข้ารหัสแปลก ๆ หรือความซ้ำซ้อน .
สิ่งแรกที่ต้องตัดสินใจคือจำนวนข้อมูลเฉพาะรายการและจำนวนรายการทั้งหมดที่ใช้ร่วมกัน
นี่คือสิ่งที่ฉันจะทำถ้าข้อมูลทั้งหมดเป็นรายการเฉพาะ:
// ITEMS table: attributes common to all items
item_id | name | owner | location | sprite_id | ...
1 | Light Saber | 14 (Tchalvek) | 381 (Tchalvek house) | 5663 | ...
// WEAPONS table: attributes for items that are weapons
item_id | damage | damage_type | durability | ...
1 | 5 | sharp | 13 | ...
// LIGHTING table: attributes for items that serve as lights
item_id | radius | brightness | duration | ...
1 | 3 meters | 50 | 8 hours | ...
ในการออกแบบนี้ทุกรายการอยู่ในตารางรายการพร้อมกับแอตทริบิวต์ที่มี (หรือส่วนใหญ่) รายการทั้งหมด แต่ละบทบาทเพิ่มเติมที่รายการสามารถเล่นได้คือตารางแยกต่างหาก
หากคุณต้องการใช้เป็นอาวุธคุณจะต้องค้นหามันในตารางอาวุธ ถ้ามีก็แสดงว่าเป็นอาวุธ หากไม่มีอยู่ก็ไม่สามารถใช้เป็นอาวุธได้ การมีอยู่ของบันทึกจะบอกคุณว่าเป็นอาวุธหรือไม่ และถ้ามีก็จะเก็บคุณสมบัติเฉพาะอาวุธไว้ที่นั่น เนื่องจากแอตทริบิวต์เหล่านั้นถูกจัดเก็บโดยตรงแทนที่จะอยู่ในรูปแบบที่เข้ารหัสบางอย่างคุณจะสามารถทำการสืบค้น / กรองข้อมูลได้ (ตัวอย่างเช่นสำหรับหน้าตัวชี้วัดของเกมของคุณคุณอาจต้องการรวมผู้เล่นตามประเภทความเสียหายของอาวุธและคุณสามารถทำได้ด้วยการเข้าร่วมและกลุ่มโดย damage_type)
ไอเท็มสามารถมีหลายบทบาทและมีอยู่ในตารางเฉพาะบทบาทมากกว่าหนึ่งตาราง (ในตัวอย่างนี้ทั้งอาวุธและแสง)
หากเป็นเพียงบูลีนอย่าง "เป็นโฮลดิ้งนี้" ฉันจะใส่ลงในตารางไอเท็ม อาจคุ้มค่ากับการแคช "เป็นอาวุธ" และอื่น ๆ ในนั้นเพื่อที่คุณจะได้ไม่ต้องทำการค้นหาอาวุธและโต๊ะแสดงบทบาทอื่น ๆ อย่างไรก็ตามมันเพิ่มความซ้ำซ้อนดังนั้นคุณต้องระมัดระวังในการซิงค์
คำแนะนำของ Ari ที่มีตารางเพิ่มเติมต่อประเภทสามารถใช้กับวิธีนี้ได้หากข้อมูลบางอย่างจะไม่แตกต่างกันไปในแต่ละรายการ ตัวอย่างเช่นหากความเสียหายของอาวุธไม่ได้แตกต่างกันไปในแต่ละไอเท็ม แต่บทบาทยังคงแตกต่างกันไปในแต่ละไอเท็มคุณสามารถแยกแอททริบิวต์อาวุธที่แชร์ออกจากโต๊ะ
// WEAPONS table: attributes for items that are weapons
item_id | durability | weapon_type
1 | 13 | light_saber
// WEAPONTYPES table: attributes for classes of weapons
weapon_type_id | damage | damage_type
light_saber | 5 | energy
อีกวิธีหนึ่งก็คือถ้าบทบาทที่เล่นโดยไอเท็มไม่ได้แตกต่างกันไปตามไอเท็ม แต่เฉพาะตามประเภทไอเท็ม ในกรณีดังกล่าวคุณจะต้องใส่ item_type ลงในตารางรายการและสามารถเก็บคุณสมบัติเช่น "เป็นอาวุธ" และ "เป็นอาวุธที่ถือได้" และ "มันเบา" ในตาราง ItemTypes ในตัวอย่างนี้ฉันยังทำให้ชื่อรายการไม่แตกต่างกันต่อรายการ:
// ITEMS table: attributes per item
item_id | item_type | owner | location
1 | light_saber | 14 (Tchalvek) | 381 (Tchalvek house)
// ITEMTYPES table: attributes shared by all items of a type
item_type | name | sprite_id | is_holdable | is_weapon | is_light
light_saber | Light Saber | 5663 | true | true | true
// WEAPONTYPES table: attributes for item types that are also weapons
item_type | damage | damage_type
light_saber | 5 | energy
อาจเป็นไปได้ว่าไอเท็มและอาวุธไม่เปลี่ยนแปลงในระหว่างเกมดังนั้นคุณสามารถโหลดตารางเหล่านั้นลงในหน่วยความจำหนึ่งครั้งและค้นหาคุณสมบัติเหล่านั้นในตารางแฮชแทนการเข้าร่วมฐานข้อมูล