2010-07-22 110 views
6

我正在設計一個角色有很多項目的遊戲,這些項目可以有多種類型。有一個人物表,以及按類型細分的12個不​​同的可能物品表格(例如武器,盔甲和各種其他物品類型)。正常化這個數據庫:在這種情況下什麼是理想的?

我想打一個表來保存這些項目類型(基本上是一個字的情況下,項目表)中的每一行都會有從人物的外鍵表中,指出哪些字符具有該項目的所有權。

起初,我想我會在字符的物品表中製作外鍵 - 每個十二個項目表的一個鍵。但是由於每個項目只能有一個「類型」,這將導致每行有11個空字段,這似乎是錯誤的。

什麼是更好的方法?我還沒有建立數據庫,因此我可以招待其他不使用十二個項目表的庫存創意,但知道這一點:管理界面將允許用戶根據需要添加/刪除/修改每種類型的項目。

此外,我想堅持最好的規範化實踐,所以我會忽略不可避免的「誰在乎?只要做一些有用的工作,並使用無效的領域。」

+1

最好的規範化實踐並不總是最好的編程實踐。特別是,任何需要查詢12個表格的東西,只要你能保證你只返回1個表格的行就不是最好的編程實踐,不管你的數據集有多緊湊和非冗餘。這個系統的優先順序是什麼? – Kylotan 2010-07-22 10:09:45

+0

@Kylotan +1 - 歸一化應該總是應用,但它是一種平衡行爲,理論上你可以正常化到N級,但是到這時你會有很多表,這會降低你的查詢性能。 – Dal 2010-07-28 13:31:33

回答

3

我首先檢查一下你是否可以將這12個表合爲一體。從Single-Table Inheritance開始,因爲它很簡單,我敢打賭在這種情況下就足夠了。

CHARACTER --<- CHAR_ITEMS ->-- ITEM_TYPES_STI 

如果不是,請嘗試Class Table Inheritance。基本上,爲「物品類型」定義一個超類,角色的物品參考它。 12個單獨項目類型的每個子表格也引用項目類型可選:

CHARACTER --<- CHAR_ITEMS ->-- ITEM_TYPES_SUPER --- ITEM_TYPE_SWORDS 

重新評論:我澄清了上面的行。 item_types_super和item_type_swords之間的關係應該是1:1。也就是說,對於劍中的每一行,應該有一個獨特的超級行。做到這一點的方法是讓劍中的外鍵也是它的主要關鍵。

但是並不是每一行都有一排劍。超級中的那一行可以被屏蔽或者座標軸中的任何一行所引用。但只能由一個子類型。這個想法是,通用於所有項目類型的列屬於超,那是特異亞型列在每個亞型表去。

+0

如果我理解你的第二個例子:一個字符有很多char_items,一個item_type_super有很多char_items和item_type_swords。如果管理員在item_type_swords表中插入了幾把劍,並且char_items表中的某行有一個映射到item_types_super表中的「劍」類型的鍵,那麼如何判斷此item的item_type_swords表中的哪一把劍?是? – Stephen 2010-07-22 12:27:53

+0

謝謝,我將與它一起運行,看看會發生什麼! – Stephen 2010-07-22 21:00:54

1

如果您使用了下列表格(我只包括列的關鍵值)。 CHARACTERS_ITEMS表包含每個字符的項目列表。 ItemTypeID和ItemID的組合將用於引用12個項目表中的一個表中的行。

CHARACTERS 
---------- 
CharacterID (PK) 

ITEMS 
----- 
ItemID (PK) 

ITEM_TYPES 
---------- 
ItemTypeID (PK) 

CHARACTERS_ITEMS 
---------------- 
CharacterID (FK) 
ItemTypeID (FK) 
ItemID (FK) 

這是一個視圖的開始,也可能有幫助。它演示瞭如何使用ItemTypeId來引用適當的表。

CREATE VIEW v_character_items 
AS 
SELECT {list of columns} 
FROM character_items 
JOIN character_item_1 on character_items.ItemID = character_item_1.ItemID and character_items.ItemTypeID = 1 

UNION 
SELECT {list of columns} 
FROM character_items 
JOIN character_item_2 ON character_items.ItemID = character_item_2.ItemID and character_items.ItemTypeID = 2 

UNION 
{other tables...} 
+0

我在審查你的設計,看看它是否適用於我,但我必須說:爲什麼要使用'UNION'?我相信你應該研究學習'JOIN'語法。 – Stephen 2010-07-22 12:29:34

+0

謝謝@Stephen。我相信我有很多要向你學習。我不知道你可以在SQL中做JOIN。假設您想要顯示以下列character_items.CharacterID,character_items.ItemId以及表中的字符character_item_1,character_item_2等的列。 如果我用JOINS替換UNION,您能告訴我SELECT語句的樣子嗎? – bobs 2010-07-22 16:32:41

+0

'SELECT character_items.CharacterID,character_items.ItemId,character_item_1。*,character_item_2。* FROM character_items JOIN character_item_1 ON character_items.ItemID = character_item_1.ItemID JOIN character_item_2 ON character_items.ItemID = character_item_2.ItemID;' – Stephen 2010-07-22 20:58:30

1

在你的情況下,我會嘗試將所有十二個表合併到一個表中。

這樣做的原因是不是真的任何與技術表的設計 - 而是將alow你的角色重用以意想不到的方式對象。

例如,你可以擁有一組可丟棄的屬性,比如EFFORT,ACCURACY,DAMAGE,BREAKAGE,所以一把匕首幾乎沒有投擲的精力,如果它的目標卡住了,會造成很大的傷害手高腳杯很容易扔掉,但造成的傷害很小,或者金條很難扔掉,但會造成合理的傷害,即使它不是嚴格的武器。 它也可以讓你有武器也是「寶物」物超所值或神奇的用途(不知道你在計劃什麼樣的遊戲,所以這些例子可能不合適)

+0

+1有趣的想法。 – Stephen 2010-07-22 12:31:30

1

我不知道你是否「重新仍在尋找答覆,但這裏是我怎麼沒我的最近:

CHARACTER -> Char/Item Link Table -> ITEM 

ITEM 
---- 
ID 
NAME 
TYPE 
etc. 

這可以讓你創造出多個人物可以擁有。如果你想要做的個性修改項目基地項目(即創業板插槽,附魔等),可以通過EFFECT表(或類似的東西)輕鬆完成:

ITEM -> Item/Effect Link Table -> EFFECTS 

通過這種方式,你可以讓角色定製自己的武器,並保持周圍的基地。您也可以創建一組效果,而不必一遍又一遍地重複遊戲中的每個項目。

相關問題