最高效,可扩展的mysql数据库设计

时间:2014-08-23 19:16:17

标签: mysql database database-design

我对数据库设计有一个有趣的问题:

我想出了以下设计:

第一张表:

**Survivors:**

Survivor_Id | Name | Strength | Energy

第二张表:

**Skills:**

Skill_Id | Name

第三张表:

**Survivor_skills:**

Surviror_Id |Skill_Id | Level

在第一张表幸存者中,会有很多记录并且会不时增长。 在第二个表中,只有很少的技能可以幸存者学习(例如:recoon(更高的视图范围),狙击手(更准确),...)。 Theese技能不像所有幸存者所拥有的力量或能量。 第三表是最有趣的,有幸存者和技能连在一起。一切都会好起来但我担心数据重复。

例如:身份1的幸存者将拥有5种技能,因此第一个表看起来像这样:

// survivor_id | level_id | level
1 | 1 | 2
1 | 2 | 3
1 | 3 | 1
1 | 4 | 5
1 | 5 | 1

第一条记录:身份1的幸存者在第2级具有身份1的技能 第二个记录......

这是正确的方法,还是我应该使用不同的东西。

2 个答案:

答案 0 :(得分:0)

对我来说很好看。如果您担心数据重复:

1)你的服务器端代码应该不会发生这种情况

2)你可以在插入之前检查它是否已经存在

3)您可以使用MYSQL:REPLACE INTO - 如果配置为proerply,则会替换重复的行,或者插入新的行(http://dev.mysql.com/doc/refman/5.0/en/replace.html

4)在您只想要唯一行的列上设置唯一索引,例如level_id,等级

答案 1 :(得分:0)

我同意其他人 - 这是正确的方法。

但是,还有一个方面尚未讨论过:复合键{Surviror_Id,Skill_Id}中的列顺序,它将受您需要运行的查询类型的控制......

  • 如果你需要找到特定幸存者的技能,那么订单必须是:{Surviror_Id,Skill_Id}。
  • 如果您需要找到具有特定技能的幸存者,则订单必须为:{Skill_Id,Surviror_Id}。
  • 如果您需要两者,您需要{Surviror_Id,Skill_Id} 上的密钥(和隐含索引)以及 1 <上的索引 / SUP>。由于InnoDB tables are clustered,通过secondary index访问级别需要双重查找 - 为避免这种情况,请考虑使用covering索引{Skill_Id,Surviror_Id,Level}。

1 或反之亦然。