วิธีการสร้างแบบจำลอง“ ใช้” หลายอย่าง (เช่นอาวุธ) สำหรับสินค้าคงคลังวัตถุ / รายการ (เช่นคาตานะ) ภายในฐานข้อมูลเชิงสัมพันธ์


10

ดังนั้นฉันจึงพยายามขยายการใช้รายการต่างๆที่www.ninjawars.netและฉันไม่แน่ใจว่าจะนำเสนอสิ่งเหล่านี้ได้อย่างยืดหยุ่นในฐานข้อมูลเชิงสัมพันธ์ที่เราใช้

ฉันอาจเห่าต้นไม้ที่ไม่ถูกต้องดังนั้นอย่าลังเลที่จะให้คำแนะนำในทิศทางอื่น แต่ขณะนี้ฉันคิดว่าแต่ละรายการควรมี "แท็ก" ที่เกี่ยวข้อง

ตัวอย่างเช่น Katana ปัจจุบันเป็นแถวในฐานข้อมูล "items" เพื่อให้เป็นอาวุธและสิ่งที่สามารถเก็บได้ฉันคิดว่าฉันจะมีฐานข้อมูล "ลักษณะ" และตาราง item_traits ที่เชื่อมโยงระหว่างพวกเขา

// Objects and their basic data

item_id | item
1 | Naginata


// Things that objects can do

trait_id | trait
1 | weapon
2 | holdable

// How those objects do those things, e.g. powerfully, weakly, while on fire

_item_id | _trait_id | item_trait_data
1 | 1 | damage: 5, damage_type: sharp, whatever, etc

ฉันไม่แน่ใจจริงๆว่าจะจำลองข้อมูลเสริมที่เกิดขึ้นได้อย่างไร (เช่นความเสียหายที่ดาบจะทำ, ดาเมจความเสียหาย)

ฉันไม่มีความสุขโดยเฉพาะอย่างยิ่งที่จะเก็บสิ่งของทั้งหมดไว้ในที่เดียวเช่นเพื่อสร้างสำเนาของรายการที่มีชื่อแตกต่างกันเช่น "ดาบสั้น" ฉันจะต้องคัดลอกจาก หลายตารางเพื่อสร้างรายการที่ซ้ำกัน

มีวิธีที่ดีกว่าในการจัดวางสิ่งนี้ว่าฉันพลาดหรือไม่

แก้ไข:ฉันควรทราบว่าฉันมีฐานข้อมูล postgresql ที่ใช้งานบนไซต์อยู่แล้วซึ่งเป็นสาเหตุที่ฉันต้องการใช้สำหรับการจัดเก็บข้อมูลของฉัน

แก้ไข:ฉันได้เพิ่มคำตอบสำหรับการนำไปใช้ที่ฉันกำลังดูอยู่

คำตอบ:


10

ฉันจะไม่เห็นด้วยอย่างอ่อนโยนกับทุกคนและบอกว่าวิธีการเชิงสัมพันธ์มีเหตุผลที่นี่ สิ่งที่น่าสนใจที่นี่คือไอเท็มสามารถมีได้หลายบทบาท ปัญหาหลักคือว่าการแมประหว่างเลย์เอาท์เชิงสัมพันธ์นี้กับเลย์เอาต์ 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

อาจเป็นไปได้ว่าไอเท็มและอาวุธไม่เปลี่ยนแปลงในระหว่างเกมดังนั้นคุณสามารถโหลดตารางเหล่านั้นลงในหน่วยความจำหนึ่งครั้งและค้นหาคุณสมบัติเหล่านั้นในตารางแฮชแทนการเข้าร่วมฐานข้อมูล


+1 นี่เป็นคำตอบเดียวที่ใช้ฐานข้อมูลเชิงสัมพันธ์เป็นฐานข้อมูลเชิงสัมพันธ์ สิ่งอื่นใดนอกเหนือจากสิ่งนี้หรือสิ่งที่รุนแรงที่สุดของคำแนะนำหยดของ Nevermind และการใช้ฐานข้อมูลเป็นแหล่งข้อมูลเป็นแผนการที่น่ากลัว

+1 แต่วิธีการเหล่านี้ดูเหมือนจะไม่ยืดหยุ่น ฉันขอโทษถ้าฉันเสียงไม่สอดคล้องกัน แต่ฉันต้องการที่จะสามารถสร้างโครงสร้างฐานข้อมูลสำหรับรายการเป็นหลักครั้งเดียว ... ... แล้วรหัสคุณสมบัติเพิ่มเติมสำหรับรายการทำแทรกเพิ่มเติมลงในฐานข้อมูลสำหรับรายการ แต่ไม่ต้องเปลี่ยน ฐานข้อมูลอีกครั้งในอนาคต (แน่นอนว่ามีข้อยกเว้นไม่บ่อยนัก)
Kzqai

หากคุณต้องการให้ฐานข้อมูลเชิงสัมพันธ์รู้เกี่ยวกับเขตข้อมูลของคุณและเพิ่มประสิทธิภาพการเป็นตัวแทนของเขตข้อมูลเหล่านั้นคุณต้องเพิ่มบางส่วน มันก็เหมือนประเภทคงที่ ถ้าคุณต้องการให้คอมไพเลอร์รู้เกี่ยวกับฟิลด์ของคุณและปรับการแสดงให้เหมาะสมคุณต้องประกาศประเภท ทางเลือกเป็นวิธีพิมพ์แบบไดนามิกใช้โดยฐานข้อมูลเอกสารบางส่วนหรือโดยการเข้ารหัสข้อมูลของคุณลงในฐานข้อมูลเชิงสัมพันธ์ในบางวิธี ฐานข้อมูลจะไม่ทราบว่าเขตข้อมูลคืออะไรหรือสามารถเพิ่มประสิทธิภาพการจัดเก็บของพวกเขา แต่คุณจะได้รับความยืดหยุ่นบางอย่าง
amitp

4

น่าเสียดายที่สถานการณ์เช่นนี้เป็นที่ที่ฐานข้อมูลเชิงสัมพันธ์ (เช่น SQL) ขาดช่วงเวลาสั้น ๆ และฐานข้อมูลที่ไม่ใช่เชิงสัมพันธ์ (เช่นMongoDB ) นั้นยอดเยี่ยม ที่ถูกกล่าวว่ามันเป็นไปไม่ได้ที่จะสร้างแบบจำลองข้อมูลในฐานข้อมูลเชิงสัมพันธ์และเนื่องจากดูเหมือนว่า codebase ของคุณพึ่งพา SQL อยู่แล้วนี่คือแบบจำลองที่ฉันจะไปด้วย:

แทนที่จะสร้างรายการและใช้ตารางให้สร้างตารางและตารางอ้างอิง "[รายการ] _type" สำหรับแต่ละประเภทรายการ

นี่คือตัวอย่างบางส่วน:

weapon_type_id | weapon_type
1 | sharp

weapon_id | weapon| weapon_type_id | damage
1 | Short Sword | 1 | 5

potion_type_id | potion_type
1 | HP
2 | Mana

potion_id | potion| potion_type_id | modifier
1 | Healing Elixer | 1| 5
2 | Mana Drainer | 2| -5

โซลูชันนี้ให้ความยืดหยุ่นและความยืดหยุ่นในระยะยาวมากช่วยลดพื้นที่ที่สูญเปล่า (ถ้าไม่กำจัด) และจัดทำเอกสารด้วยตนเอง (ไม่เหมือนกับ "item_use_data") มันเกี่ยวข้องกับการตั้งค่าเพิ่มเติมเล็กน้อยในตอนท้ายของนักพัฒนา แต่ในความคิดของฉันมันเป็นโซลูชั่นที่หรูหราที่สุดสำหรับสถานการณ์ที่คุณต้องใช้ฐานข้อมูลเชิงสัมพันธ์เพื่อจัดเก็บข้อมูลของคุณ โดยทั่วไปแล้วฐานข้อมูลที่ไม่สัมพันธ์จะดีกว่ามากสำหรับการพัฒนาเกมเนื่องจากมีความยืดหยุ่นมากกว่าในการสร้างแบบจำลองข้อมูลในขณะที่มีประสิทธิภาพมากกว่าฐานข้อมูล SQL ทำให้เป็นตัวเลือก "win-win"

แก้ไข 1:แก้ไขข้อผิดพลาดด้วยฟิลด์ potion_type_id

แก้ไข 2:เพิ่มรายละเอียดเพิ่มเติมเกี่ยวกับฐานข้อมูลที่ไม่สัมพันธ์กับเชิงสัมพันธ์เพื่อให้มุมมองเพิ่มเติม


ฉันไม่เห็นความยืดหยุ่นอย่างมากจากระบบนั้น ตัวอย่างเช่นถ้าฉันต้องการขวดแก้วสามารถใช้เป็นอาวุธและเป็น 'คม' ... ... ฉันจะไม่โชค นอกจากนี้สำหรับรายการใหม่ทุกประเภทฉันจะต้องสร้างโครงสร้างฐานข้อมูลจริง แม้ว่าจะมีเพียงหนึ่งหรือสองประเภทเท่านั้น
Kzqai

จุดที่คุณนำมาใช้นั้นถูกต้องมากและเน้นตัวอย่างเพิ่มเติมว่าทำไมฐานข้อมูลเชิงสัมพันธ์จึงไม่เหมาะสมสำหรับสถานการณ์เฉพาะนี้ แบบจำลองที่ฉันนำเสนอแสดงเพียงวิธีที่ดีที่สุดในการจัดวางข้อมูลในลักษณะที่หน่วยความจำได้รับการอนุรักษ์และฟังก์ชันการทำงานของ SQL ยังคงอยู่ เพื่อจัดเก็บรายการที่มีหลายประเภทวิธีที่ดีที่สุดในการแสดงข้อมูลภายใต้โมเดลนี้คือการสร้างตาราง potion_weapon ที่มีคุณสมบัติการปรุงยาและอาวุธที่เหมาะสม อีกครั้งโซลูชันนี้ไม่เหมาะ แต่เป็นโซลูชันที่หรูหราที่สุดเมื่อใช้ฐานข้อมูลเชิงสัมพันธ์
Ari Patrick

@Ari: ไม่มีเจตนาดูหมิ่น แต่ปัญหาของเขาคือเหตุผลที่แม่นยำว่าวิธีการเชิงสัมพันธ์มีความถูกต้องมากกว่าไม่น้อย เป็นที่ทราบกันดีว่าฐานข้อมูล NoSQL (หรือ NoRel) นั้นยอดเยี่ยมสำหรับการอ่านในปริมาณมาก, การกระจาย / ข้อมูลที่พร้อมใช้งานสูงหรือสกีมาที่มีการกำหนดไม่ดี กรณีนี้เป็นเพียงการเชื่อมโยงหลายต่อหลายคลาสสิกและ dbs เช่น Mongo ไม่ทำเช่นนี้รวมถึง RDBMS ดูstackoverflow.com/questions/3332093/…
alphadogg

@alphadogg นี่เป็นความสัมพันธ์แบบกลุ่มต่อกลุ่มได้อย่างไร? ในฐานข้อมูลอาวุธรู้เกี่ยวกับประเภทอาวุธ แต่ประเภทอาวุธไม่จำเป็นต้องรู้เกี่ยวกับอาวุธที่เกี่ยวข้อง หากด้วยเหตุผลบางอย่างที่คุณต้องการทราบอาวุธทั้งหมดที่เป็นอาวุธชนิดใดชนิดหนึ่งคุณเพียงแค่เขียนแบบสอบถามที่วนซ้ำในการรวบรวมเอกสารอาวุธ
Ari Patrick

@Ari: ในคำถามของ OP หนึ่งอาวุธอาจมีหลายประเภทและประเภทหนึ่งอาจเชื่อมโยงกับอาวุธหลายชนิด ตัวอย่างเช่นน้ำยาและดาบนั้นสามารถยึดได้ ดาบมีทั้งแบบถือได้และอาวุธ
alphadogg

3

ออกก่อนการถ่ายโอนข้อมูลวิธีการรับมรดกเชิงวัตถุและไปกับระบบ component-based

เมื่อคุณทำเช่นนั้นเลย์เอาต์ SQL ก็จะง่ายขึ้นกว่าเดิม คุณมีหนึ่งตารางสำหรับส่วนประกอบแต่ละประเภทที่มีหมายเลข ID ที่แชร์ หากคุณต้องการรายการ # 17 คุณจะต้องค้นหา "รหัสรายการ 17" ในทุกตาราง ตารางใด ๆ ที่มีคีย์จะได้รับการเพิ่มส่วนประกอบ

ตารางรายการของคุณมีข้อมูลที่จำเป็นทั้งหมดสำหรับรายการโดยทั่วไป (ชื่อ, ราคาขาย, น้ำหนัก, ขนาด, สิ่งอื่น ๆ ที่ใช้ร่วมกันระหว่างรายการทั้งหมด) ตารางอาวุธของคุณมีข้อมูลที่เหมาะสมทั้งหมดสำหรับอาวุธตาราง Potion ของคุณมีข้อมูลที่เหมาะสมทั้งหมด สำหรับ potion ตารางชุดเกราะของคุณมีข้อมูลที่เหมาะสมสำหรับชุดเกราะ ต้องการเกราะกันกระสุนนั่นคือรายการในรายการและรายการในชุดเกราะ ต้องการดาบช่วยให้คุณดื่มได้คุณแค่ใส่ข้อความลงในแต่ละโต๊ะและทำเสร็จแล้ว

โปรดจำไว้ว่ารูปแบบเดียวกันนี้ไม่เฉพาะเจาะจงรายการ - คุณสามารถใช้สิ่งนี้กับสิ่งมีชีวิตโซนสิ่งอื่นที่คุณอาจต้องการ มันอเนกประสงค์อย่างแปลกใจ


2

การใช้ SQL เป็นความผิดพลาดร้ายแรงของคุณ มันไม่เหมาะสำหรับการจัดเก็บข้อมูลการออกแบบเกมแบบคงที่

หากคุณไม่สามารถย้ายออกจาก SQL ฉันจะพิจารณาจัดเก็บรายการในแบบอนุกรม กล่าวคือ

item_id (int) | item (BLOB)
1             | <binary data>

แน่นอนว่ามันน่าเกลียดและขว้าง "niceties" ของ SQL ทั้งหมดออกไปนอกหน้าต่าง แต่คุณต้องการมันจริงหรือ? ส่วนใหญ่อาจคุณอ่านข้อมูลทั้งหมดของรายการของคุณที่เกมเริ่มต้นอยู่แล้วและไม่เคยโดยสิ่งอื่นที่ไม่ใช่SELECTitem_id


3
ตั้งแต่ (จากความเข้าใจของฉัน) เกมนี้เป็นแบบผู้เล่นหลายคนและสนับสนุน PvP มีความเป็นไปได้ที่ข้อมูลการเล่นเกมส่วนใหญ่จะไม่ถูกเก็บไว้ในไคลเอนต์ หากข้อมูลนั้นถูกต้องข้อมูลทุกครั้งที่อ่านจากตารางจะต้องทำการดีซีเรียลไลซ์ก่อนใช้ประโยชน์จากระยะไกล ดังนั้นรูปแบบนี้ทำให้การค้นหารายการโดยคุณสมบัติของพวกเขามีราคาแพงมาก ตัวอย่างเช่น: หากคุณต้องการดึงไอเท็มทั้งหมดที่เป็นประเภท "อาวุธ" คุณจะต้องดึงทุกไอเท็มออกจากตำแหน่งแต่ละรายการจากนั้นกรองด้วยตนเองสำหรับประเภท "อาวุธ" เมื่อเทียบกับการเรียกใช้แบบสอบถามอย่างง่าย .
Ari Patrick

1
จากประสบการณ์ของฉันรายการทั้งหมดจะถูกอ่านในแคชหน่วยความจำในตอนเริ่มเกม ดังนั้นคุณจะต้องทำการแยกพวกมันออกมาเพียงครั้งเดียวเมื่อเริ่มต้นและอย่าใช้ฐานข้อมูลเลยหลังจากนั้น หากไม่เป็นเช่นนั้นในกรณีนี้ฉันเห็นด้วยว่าการจัดเก็บวัตถุที่ต่อเนื่องเป็นความคิดที่ไม่ดี
ไม่เป็นไร

อืมมมมมมมมมมมมมมมมมมมมมมมมมมมมมมมมมมมมมมมมีเกียวกับอย่างรวดเร็วสิ่งเดียวคือที่นี่ทำให้ฉันมีอินเทอร์เฟซที่จำเป็นในการแก้ไขข้อมูลซึ่งจะไม่สะดวก
Kzqai

2

ขึ้นอยู่กับจำนวนคุณลักษณะที่คุณต้องการคุณสามารถใช้ bitmask แบบง่าย ๆ สำหรับวัตถุที่มีบิตแตกต่างกันตามลักษณะที่แตกต่างกัน:

000001 = holdable
000010 = weapon
000100 = breakable
001000 = throwable
010000 = solids container
100000 = liquids container

จากนั้นคุณสามารถทำการทดสอบบิตง่าย ๆ เพื่อดูว่าสามารถใช้วัตถุสำหรับฟังก์ชันบางอย่างได้หรือไม่

ดังนั้น "ขวดแก้ว" อาจมีค่า 1,01111 ซึ่งหมายความว่าสามารถเก็บไว้ได้สามารถใช้เป็นอาวุธมันแตกง่ายคุณสามารถขว้างมันและมีของเหลวได้

ตัวแก้ไขใด ๆ ที่คุณสร้างขึ้นสำหรับไอเท็มจะมีกล่องกาเครื่องหมายที่เรียบง่ายเพื่อเปิด / ปิดการใช้งานคุณสมบัติบนวัตถุ


1
ฉันชอบความคิด 'เพราะทำให้รายการสามารถเก็บลักษณะของตัวเองและฉันไม่รู้ว่าฉันจะต้องค้นหาฐานข้อมูลสำหรับลักษณะ แต่ฉันไม่แน่ใจว่าจะทำงานอย่างไร ในบริบทเชิงสัมพันธ์ ฉันเดาว่าแต่ละบิตจะแมปไปยังรหัสที่เพิ่มขึ้นของลักษณะในฐานข้อมูล ...
Kzqai

ฉันเดาว่า bitmasking มีประโยชน์มากกว่าสำหรับจำนวนคุณลักษณะที่กำหนดใช่ไหม
Kzqai

เป็นอย่างมาก จะเกิดอะไรขึ้นถ้าคุณใช้ "บิต" ครั้งสุดท้าย มันง่ายแค่ไหนที่จะเพิ่มประเภทข้อมูลเพื่อให้ได้ bit และ percolating ที่ผ่านเลเยอร์แอปของคุณหรือเพื่อเพิ่มคอลัมน์และทำเช่นเดียวกัน? นอกจากนี้เอ็นจิ้นฐานข้อมูลเฉพาะของคุณยังได้รับการปรับแต่งอย่างดีสำหรับการทำดัชนีสำหรับการทำงานของบิต เป็นการดีที่สุดในฐานข้อมูลเชิงสัมพันธ์ที่จะคงอะตอมมิกไว้กับคอลัมน์ข้อมูล อย่ารวบรวมหลายโดเมนไว้ในหนึ่งคอลัมน์ คุณไม่สามารถเข้าถึงประโยชน์ของแพลตฟอร์มได้
alphadogg

1
หากคุณต้องการตารางการค้นหาในฐานข้อมูลสำหรับคุณลักษณะ (อาจเป็นความคิดที่ดีเนื่องจากคุณสามารถเพิ่มตารางแบบไดนามิกในตัวแก้ไขใดก็ได้) จากนั้นมันจะมีลักษณะดังนี้: id, bitmask, คำอธิบาย 1,1 "Holdable"; 2,2 "อาวุธ"; 3,4, "เปราะบาง" ฯลฯ เกี่ยวกับหมายเลขคงที่ใช่เป็นจริง แต่ถ้าคุณใช้ 64 บิต int คุณควรมีขอบเขตมากมาย
Muttley

1

ในโครงการของเราเรามีitem_attributesสำหรับ "ข้อมูลพิเศษ" ที่แตกต่างกันซึ่งรายการอาจมี มันเป็นแบบนี้:

item_id | attribute_id    | attribute_value | order 
1        25 (attackspeed)       50             3    

จากนั้นเรามีตารางคุณลักษณะที่มีลักษณะดังนี้:

id |   name       | description
1    attackspeed    AttackSpeed:

Ari Patrick นั้นถูกต้อง แต่สุดท้ายแล้วฐานข้อมูลเชิงสัมพันธ์ไม่ได้ถูกสร้างขึ้นเพื่อสิ่งนี้ ข้อเสียคือเรามีขั้นตอนที่ค่อนข้างซับซ้อนในการสร้างรายการใหม่ (ทำผ่านเครื่องมือภายนอก - ซึ่งฉันขอแนะนำอย่าพยายามเพิ่มสิ่งเหล่านี้ด้วยตนเองคุณจะสับสนเอง)

ตัวเลือกอื่น ๆ ที่คุณใช้คือภาษาสคริปต์ในการสร้างเทมเพลตรายการจากนั้นคุณสามารถแยกวิเคราะห์สิ่งเหล่านั้นในและใช้เพื่อสร้างรายการใหม่ได้ แน่นอนว่าคุณยังต้องบันทึกข้อมูลรายการในฐานข้อมูล แต่ ณ จุดนี้คุณไม่ต้องกังวลเกี่ยวกับการสร้างรายการใหม่คุณสามารถคัดลอกและสคริปต์ไฟล์เก่าเปลี่ยนข้อมูลและคุณก็ทำได้ดี ไป.

สุจริตถ้าเราต้องทำใหม่วิธีที่เราสร้างรายการคงที่ใหม่เราอาจจะไปสำหรับวิธีที่ง่ายมากโดยใช้แม่แบบรายการสคริปต์


1

นี่คือความสัมพันธ์แบบกลุ่มต่อกลุ่มของคุณไม่มีอะไรที่ลึกลับเกินไปสำหรับฐานข้อมูลเชิงสัมพันธ์ที่มีความสามารถ คุณมีคุณสมบัติหลายอย่างสำหรับวัตถุใดวัตถุหนึ่งและคุณลักษณะใด ๆ หนึ่งอาจถูกใช้โดยประเภทวัตถุหนึ่งชนิดหรือมากกว่านั้น แบบจำลองความสัมพันธ์สาม (ตาราง) โดยที่หนึ่งเป็นการเชื่อมโยงความสัมพันธ์และคุณเสร็จแล้ว การจัดทำดัชนีที่เหมาะสมจะช่วยให้คุณมั่นใจได้ว่าการอ่านข้อมูลที่รวดเร็ว

ชั้น ORM ในรหัสของคุณและคุณควรมีปัญหาน้อยมากที่จะไปมาระหว่าง DB และมิดเดิลแวร์ ORM จำนวนมากสามารถสร้างคลาสอัตโนมัติได้เช่นกันและกลายเป็น "ล่องหน" มากยิ่งขึ้น

สำหรับฐานข้อมูล NoSQL นั้นไม่มีเหตุผลอะไรที่คุณไม่สามารถทำได้กับฐานข้อมูลเหล่านั้น ขณะนี้มันกำลังเป็นที่นิยมสำหรับเทคโนโลยีในการค้าผ้าขี้ริ้วและบล็อก แต่พวกเขามาพร้อมกับปัญหาของตัวเอง: แพลตฟอร์มค่อนข้างอ่อนเหมาะสำหรับการอ่านที่เปลี่ยนแปลงบ่อยครั้งง่าย (เช่น twits หนึ่งต่อหลายในโปรไฟล์) แต่ ยากจนสำหรับการอ่านหรือการปรับปรุงแบบไดนามิกที่ซับซ้อน, เครือข่ายสนับสนุนที่ไม่ดี, ข้อมูลซ้ำซ้อนและปัญหาความสมบูรณ์ที่มาพร้อมกับ ฯลฯ เป็นต้นอย่างไรก็ตามพวกเขาเสนอให้มีความยืดหยุ่นที่ดีขึ้นเพราะพวกเขาหลบหลีกความสามารถในการทำธุรกรรมระดับต่างๆ .

hobgoblin ปกติของฐานข้อมูลเชิงสัมพันธ์เทียบกับฐานข้อมูล NoSQL คือประสิทธิภาพ RDMBS ที่แตกต่างกันนั้นมีค่าใช้จ่ายที่เกี่ยวข้องกับองศาที่แตกต่างกันซึ่งทำให้พวกเขาไม่ต้องการปรับขนาดตามระดับของ Facebook หรือ Twitter อย่างไรก็ตามมันไม่น่าเป็นไปได้มากที่คุณจะต้องเผชิญกับปัญหาเหล่านั้น ถึงกระนั้นก็ตามระบบเซิร์ฟเวอร์ที่ใช้ SSD ก็สามารถทำให้ประสิทธิภาพการถกเถียงเป็นไปอย่างไร้ประโยชน์

ให้ชัดเจน: ฐานข้อมูล NoSQL ส่วนใหญ่มีการกระจายตารางแฮชพื้นฐานและจะ จำกัด คุณเช่นเดียวกับตารางแฮชในรหัสของคุณเช่น ไม่ใช่ว่าข้อมูลทั้งหมดจะพอดีกับโมเดลนั้น ตัวแบบเชิงสัมพันธ์นั้นมีประสิทธิภาพมากกว่าสำหรับการสร้างแบบจำลองความสัมพันธ์ระหว่างข้อมูล (ปัจจัยที่ทำให้สับสนคือ RDBMS ส่วนใหญ่เป็นระบบดั้งเดิมที่ปรับจูนไม่ดีสำหรับความต้องการของ 0.0001% ที่เป็นที่นิยมของเว็บนั่นคือ Facebook และอื่น ๆ )


หากคุณจะอ้างถึงพวกเขาโดยรวมไม่ต้องพูดถึงฐานข้อมูล NoSQL ไม่ใช่เอนทิตีที่สามารถพูดคุยอย่างมีความหมายมันเป็นการอ้างอิงไร้ประโยชน์ที่ SQL fanbois ใช้เพื่อใช้ตรรกะที่มีข้อบกพร่องว่าถ้าฐานข้อมูลหนึ่งของกลุ่มที่กำหนดนี้ขาดคุณสมบัติดังนั้นพวกเขาทั้งหมดขาดคุณลักษณะนั้น
aaaaaaaaaaaa

NoSQL เป็นคำที่ NoSQL pushers เลือกที่จะปรับใช้ ฉันไม่รู้ว่าทำไมมันไม่ได้อธิบายอะไรมาก แต่มันไม่ได้ดูถูก ฉันคิดว่าคำอธิบายของ alphadogg มีความยุติธรรม

บางทีความคิดเห็นของฉันค่อนข้างรุนแรง แต่ฉันเกลียดชื่อและการจัดกลุ่มมันเป็นไปไม่ได้ที่จะมีการอภิปรายที่มีคุณสมบัติเหมาะสมเกี่ยวกับรายละเอียดปลีกย่อยของระบบฐานข้อมูลที่แตกต่างกันเมื่อผู้คนมองโลกนี้ง่ายขึ้น
aaaaaaaaaaaa

@eBusiness: ฉันพบความคิดเห็นของคุณน่าขบขันเนื่องจากเป็นค่าย anti-RDBMS หากมีหนึ่งกลุ่มที่เจิมกลุ่มของตนเองด้วยเทคโนโลยี "NoSQL" เป็นที่ยอมรับหลายคนอยากเห็นชื่อนั้นเลิกใช้ในการเข้าใจถึงปัญหาหลังเหตุการณ์ โดยเฉพาะอย่างยิ่งเมื่อมีหลายคนใช้ SQL ในการปรับใช้ทางกายภาพ สำหรับการพูดคุยเกี่ยวกับพวกเขาฉันไม่ได้แสดงความคิดเห็นของคุณว่ารุนแรงหรือมีผิวหนาตัวเลือกของคุณ! :) ฉันหมายความว่ามีใครสามารถพูดคุยเกี่ยวกับ Tea Party ทำไมไม่กลุ่ม NoSQL ของฐานข้อมูล?
alphadogg

มันยุติธรรมฉันรู้ว่าความสัมพันธ์นั้นมีมากมายหลายต่อหลายคน สิ่งที่ทำให้ฉันหยุดการสร้างมันในรูปแบบที่เป็นมาตรฐานอย่างแท้จริงคือความคิดที่ว่า "สิ่งของ" ที่จะประกอบเป็นไอเท็มจากนั้นจะกระจายไปทั่วตารางอย่างน้อยสองตาราง ฉันไม่ชอบความคิดที่จะสร้างเม็ดมีดปรมาณูไม่ได้ฉันคิดว่า
Kzqai

0

ซึ่งเป็นที่ที่ฉันพบที่ทันสมัยมากขึ้นหรือทำแผนที่ที่จะเป็นประโยชน์จริงๆเช่น Entity Framework 4 และ (CTP) ของคุณลักษณะรหัสแรก คุณเพียงแค่เขียนคลาสและความสัมพันธ์ของพวกเขาในรหัสปกติและโดยไม่ต้องตกแต่งหรือเรียกใช้เครื่องมือใด ๆ ด้วยตนเอง EF จะสร้างที่จัดเก็บสำรองในรูปแบบ SQL สำหรับคุณด้วยตารางการเชื่อมโยงที่จำเป็นและทั้งหมด ... ^^


ฉันจะสร้างรหัสและคลาสและสิ่งที่อยู่ในรหัสเท่านั้นก่อน ... ... แค่ต้องแปลมันลงในโครงสร้างฐานข้อมูลที่มีอยู่หลังจากนั้น
Kzqai

0

นี่คือสิ่งที่ฉันกำลังพิจารณา:

เนื่องจาก "คุณลักษณะ" ทุกอย่างจำเป็นต้องมีการเปลี่ยนแปลงในโค้ดอยู่แล้วดังนั้นฉันจึงตัดสินใจที่จะเก็บลักษณะไว้ (และข้อมูลเริ่มต้นใด ๆ ที่ต้องการ) ไว้ในโค้ดเอง (อย่างน้อยตอนนี้)

เช่น $traits = array('holdable'=>1, 'weapon'=>1, 'sword'=>array('min_dam'=>1, 'max_dam'=>500));

จากนั้นรายการจะได้รับฟิลด์ "trait_data" ในฐานข้อมูลที่จะใช้json_encode()ฟังก์ชันเพื่อจัดเก็บในรูปแบบ JSON

item_id | item_name | item_identity | traits
1 | Katana | katana | "{"holdable":1,"weapon":1,"sword":{"min_dam":1,"max_dam":1234,"0":{"damage_type":"fire","min_dam":5,"max_dam":50,"type":"thrown","bob":{},"ids":[1,2,3,4,5,6,7]}}}"

แผนคือไอเท็มจะได้รับค่าสถานะเริ่มต้นทั้งหมดจากคุณลักษณะหลักของพวกเขาและจะมีเฉพาะคุณลักษณะแบบ over-ride ที่ระบุความแตกต่างจากสิ่งที่คุณสมบัติตั้งเป็นค่าเริ่มต้น

ข้อเสียของฟิลด์ลักษณะคือขณะที่ฉันสามารถแก้ไขส่วน json ด้วยมือ ... ... มันจะไม่ง่ายหรือปลอดภัยจริงๆที่จะทำเช่นนั้นกับข้อมูลที่อยู่ในฐานข้อมูล


1
จะเกิดอะไรขึ้นเมื่อคุณแนะนำคุณลักษณะใหม่ สิ่งนี้เกิดขึ้นบ่อยแค่ไหน? ผลกระทบดาวน์สตรีมของภาระงานบำรุงรักษารหัสของคุณเป็นอย่างไร ตรงกันข้ามกับการจัดเก็บเป็นจำนวนมากโดยที่อินสแตนซ์วัตถุของคุณถูกสร้างขึ้นแบบไดนามิก (ผ่านทางเลือกของ ORM) เพื่อเก็บข้อมูลนั้น
alphadogg

ขอบคุณนั่นเป็นจุดที่ดีการเพิ่มคุณสมบัติใหม่จะไม่เป็นเรื่องเล็กน้อย คุณได้เพิ่มการวิเคราะห์ของฉันเป็นอัมพาต : p
Kzqai

ขออภัย แต่นี่สำคัญมาก คุณแค่ต้องคิดผ่าน ทำแบบจำลองการออกกำลังกายในใจของคุณว่าคุณต้องทำอะไรเมื่ออาวุธบางอย่างจำเป็นต้องได้รับการปรับปรุงเพื่อเพิ่มคุณสมบัติใหม่เพื่อให้การปรับปรุงเกมของคุณสามารถทำงานได้
alphadogg

-1

นี่เป็นเรื่องที่ค่อนข้างยุ่งและฉันไม่รับประกันว่ามันจะเป็นการออกแบบฐานข้อมูลที่ดี เมื่อไม่นานมานี้คลาส DB ของฉันและพวกเขาไม่ได้มาเร็ว แต่ถ้ารายการมีการรับประกันว่าจะพูดน้อยกว่า 10 รายการคุณสามารถให้แต่ละรายการฟิลด์ attribute1 และฟิลด์ attribute2 และอื่น ๆ ได้ถึง attribute10 มันจะกำจัดความต้องการของคุณสำหรับตาราง item-attribute หลายต่อหลายค่าใช้จ่ายของการ จำกัด จำนวนของคุณลักษณะ

เมื่อมองย้อนกลับไปฉันค่อนข้างมั่นใจว่ามันเป็นงานออกแบบที่แย่มาก แต่นั่นก็หมายความว่าคุณสามารถติดอยู่กับฐานข้อมูลเชิงสัมพันธ์ที่สะดวกสบายและไม่ต้องเข้าไปในอาณาเขตที่ไม่ได้จด ขึ้นอยู่กับคุณที่จะตัดสินใจว่าการแลกเปลี่ยนนั้นคุ้มค่าหรือไม่


นี่คือการออกแบบที่แย่มากไม่เคยทำ คุณน่าจะดีกว่าไม่ได้ใช้ฐานข้อมูล
ZorbaTHut

-1

ไม่เป็นไรให้คำตอบที่ดี แต่ฉันสงสัยว่าคุณต้องการฐานข้อมูลสำหรับสิ่งนี้หรือไม่? การจัดเก็บข้อมูลทั้งหมดในไฟล์ธรรมดาและโหลดลงในโปรแกรมเมื่อเปิดตัวดูเหมือนจะเป็นวิธีที่ฉลาดที่สุดในการทำเช่นนี้

แก้ไข:
ใช่ในสภาพแวดล้อมที่ขับเคลื่อนด้วยคำขอไร้สัญชาติคุณควรเก็บข้อมูลไว้ในฐานข้อมูล เขียนข้อมูลของคุณในไฟล์และเขียนรหัสเพื่อแปลงเป็นฐานข้อมูลประเภทที่ไม่แนะนำ

อีกวิธีหนึ่งถ้าจำนวนวัตถุไม่ใหญ่เกินไปการประกาศล็อตตัวอักษรในไฟล์รหัสอาจเป็นวิธีที่เร็วที่สุด


ก่อนหน้านี้ฉันมีฐานข้อมูลที่ใช้งานอยู่แล้วและรวมเข้ากับส่วนที่เหลือของไซต์
Kzqai
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.