我正在为我玩RPG的团队建设工具做准备;我将MySQL用于我的数据库,而InnoDB用于存储引擎。
在游戏中,怪物有5个技能插槽可以通过项目添加,而且他们保留的顺序很重要(如果添加新技能但没有空闲插槽,则最旧技能会被覆盖) - 目前,我有monsters
表设置如下:
monster_id int not null,
species_id int not null,
user_id int not null,
skill1_id int, # (fkey to skills.skill_id)
skill2_id int, # (fkey to skills.skill_id)
skill3_id int, # (fkey to skills.skill_id)
skill4_id int, # (fkey to skills.skill_id)
skill5_id int, # (fkey to skills.skill_id)
# other irrelevant columns...
这使技能保持有序并防止怪物拥有比允许的最大技能更多的技能。但是,它似乎不是一个很好的解决方案 - 这个设置不允许我快速查询"选择所有在任何位置拥有X技能的怪物。"我可以查询所有5个插槽,但这看起来效率很低,因为它依赖于一堆链式连接(它也不会很好地使用我使用的ORM,尽管我可以下载到在我真正需要的地方写自己的查询。
如果我使用联结表monsters_skills
对此关系进行规范化,如下所示:
monster_id int not null,
skill_id int not null,
slot_num int not null,
primary key (monster_id, slot_num) # enforce one skill per-slot
它会查询"所有在任何位置使用X技能的怪物"更容易......但数据库不会强制执行最大数量的技能 - 据我所知,MySQL并不能正确支持CHECK约束,否则这将在很大程度上解决问题。我可以在我的实际应用程序代码中进行检查,但我非常希望数据库在所有可能的情况下处理数据完整性。
我应该坚持使用我当前的解决方案(怪物表中的编号插槽),还是有更好的方法在MySQL中实现它(通过表结构,触发器等)?
答案 0 :(得分:0)
了解如何在SQL中使用触发器。您需要让DBMS强制执行完整性。一般来说,你总是能够使用反常设计和MySQL的可怜的声明性约束集合的子集来逃避。 (你当前的设计并不仅限于有效状态,不是吗?)(你实际上并没有说明一行是如何映射到一个有序的技能列表,用于查询,以及一个有序的技能列表映射到一行,用于更新。但您似乎依赖于用户/程序的正确更新。)