我很难理解处理相对大量表字段的理想方法,以及它们是否应该拆分成单独的关系表。
我有一组用于基于网络的游戏的表格,包含玩家数据,项目数据,班级数据等。对于这些(玩家/项目/班级)中的每一个,我还需要记录一个统计数量(即健康,精神,盔甲等)。目前,该列表是25个统计数据,这意味着除了已有的列之外,每个表还有50个附加列(类型/值对)。
这开始感到麻烦。
另一种方法是将所有统计数据移动到单独的表中。例如,项目统计信息位于“项目统计信息关系”表中,ID链接到项目和统计信息表。
如果我需要更改统计数量,这将简化表格结构并提供灵活性。但是,它也增加了维护数据的复杂性。如果我添加一个新项目,而不是仅在项目表中插入一行,我现在必须在“项目统计关系”表中插入更多行,以包含它所需的所有统计数据。
保持表格简单是否值得付出额外的努力?
编辑:忘记添加我正在考虑的其他替代方法:将所有统计信息序列化为VARCHAR或TEXT列。这也可以让我灵活地添加任意数量的统计信息(特别是如果我使用TEXT),并且不会给处理它的代码增加任何复杂性。但是,根据我的阅读,TEXT块对性能不利,我必须经常访问它,每次都读取和写入整个块。
答案 0 :(得分:1)
另一种方法是将所有统计数据移动到单独的表中。例如,项目统计信息位于“项目统计信息关系”表中,ID链接到项目和统计信息表。
这是处理业务规则的正确方法。
如果我添加一个新项目,而不是仅在项目表中插入一行,我现在必须在“项目统计关系”表中插入更多行,以包含它所需的所有统计数据。
仅当该项目实际使用统计数据时。它允许项目/ etc具有关联的0+统计数据,这意味着您不必为每个新的统计数据更新数据模型以添加列。
风险不佳时,没有性能优势。你会做什么,将被你必须执行的黑客吃掉才能让事情发挥作用。
...在多个项目上使用MySQL功能(即添加玩家拥有的所有项目的“强度”),如果其中一些项目甚至没有该统计数据的记录......
使用:
SELECT IFNULL(SUM(t.value), 0)
FROM PLAYERS p
JOIN ITEM_STAT_RELATION itr ON itr.player_id = t.player_id
LEFT JOIN STATS s ON s.stat_id = itr.stat_id
WHERE p.player_id = ?
AND ...
LEFT JOIN用于表示支持记录可能不存在,而IFNULL用于处理这种情况,因为它的值为空。 SUM可以处理NULL - 它将值解释为零。
...将所有统计信息序列化为VARCHAR或TEXT列。
不要这样做
如果要报告特定统计数据或统计数据组,则连接统计信息列表将很难提取详细信息。由于字符限制,它存在无法将每个统计数据存储在单个列中的风险。
答案 1 :(得分:1)
不确定我理解这条评论:“目前这个列表是25个统计数据,这意味着每个表格都有50个额外的列(类型/值对)”我希望每个统计数据都有一列。或者只有2列(键/值)和许多额外的行
我认为播放器表例如会有如下列: 球员名称,健康,力量,智力等....
然后每行都是:
添加新统计数据只是添加列的一种情况。对于现有玩家,您可能需要对现有行进行数据修复以获得默认值,或者根据其他统计数据修复某些值。
对于玩家可能拥有的物品,您将拥有一个物品表,其中包含每个物品作为单独的行,例如:
然后你会有一个链接表来将每个玩家与他们拥有的物品联系起来,所以如果MyHero同时拥有两个物品且MyOtherHero只有盾牌,我们可能会有一个Wielding表
或者我错过了什么?
答案 2 :(得分:0)
在您的情况下,我认为额外的列属于表。否则,您将得到两个具有相同行数和它们之间的1:1映射的表。这并没有真正简化任何事情!
从概念上讲,我认为它也更正确。所有这些列都是直接链接到其行中项目的数据片段,因此它们属于一起。例如,如果所有的剑都有一套共同的价值观,那就不同了。然后你想说“项目Foo是一个剑,所以请查看类属性表以获取剑项目的统计数据”。
答案 3 :(得分:0)
如果统计数量不会改变,并且您确定不需要新的统计数据,那么您可以使用一个表,多列设计,而不是值/对方法。但是,值/对方法很灵活,允许您在不更改现有数据库架构的情况下添加新统计信息,并节省更多空间。
需要考虑的一些问题
如果您不想使用值对方法,可以尝试序列化。但这会使得统计数据无法搜索(例如,更难,更喜欢列出所有强度大于20的实体)
答案 4 :(得分:0)
多个表更好,它是规范化架构