2010-07-22 97 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 

通过这种方式,你可以让角色定制自己的武器,并保持周围的基地。您也可以创建一组效果,而不必一遍又一遍地重复游戏中的每个项目。

相关问题