我制作了一个幻想名称生成器,而且我在规划数据库表时遇到了麻烦。到目前为止,我的列是ID(主键),名称,类型(第一个,最后一个或任何一个),性别(男女皆宜,男性或女性),然后我为每个种族(Dragonborn,Dwarf,Elf等)都有一个列)。
我为我的朋友和我制作一个PHP表单输入名称,其中比赛将是复选框,然后它将显示在公共表格上。我无法找到一种方法来显示公共表的Race单元格中每个名称/行的非空列名。目前,如果您选择比赛,数据库会选择“是”'在每个相应的比赛栏中,将其他比赛留空。
我应该继续制作一个可以在我的数据库中拥有多个字符串的Race列吗?例如,如果一个名字可能是人,半身和侏儒,那么竞赛栏目将是"人,半身,侏儒"。这会比每场比赛都有一个专栏更好吗?我不知道它的设计是否好,而且我也很难找到类似的问题。
答案 0 :(得分:-1)
您希望多久更新一次可能的比赛列表?如果您希望它会频繁出现,或者可能的种族列表应该被视为数据,那么可能会考虑多对多关系。也就是说,您应该有一个种族表(可能是id
和name
),以及一个字符表(至少id
和name
),然后是人物 - 种族关系表(charid,raceid)。
当你有一个人类半身精灵的角色时,你可以在这个角色竞赛表中输入三行:( characterid,humanraceid),(characterid,halflingid)和(characterid-elfid)
关于如何更好地设计数据库的更一般性问题,有大量文献可供使用。此特定问题的主题名称是"基数":如何将某些项目的关系映射到某些其他项目。在这种情况下,许多角色都可以有很多种族。
一旦你理解了你想要解决的问题的基数,就可以使用众所周知的模式作为第二种性质来设计表并进行查询。他们绝对值得学习!
答案 1 :(得分:-1)
使用逗号分隔列表的单个列是SQL Antipattern。不要那样做。
Bill Karwin在第2章中对这个问题进行了很好的概述:Jaywalking在他出色的着作“SQL AntiPatterns:避免数据库编程的陷阱”中
(可从亚马逊https://www.amazon.com/SQL-Antipatterns-Programming-Pragmatic-Programmers/dp/1934356557和其他优质书商处购买。)
如果数据库从不需要将该列视为单个值以外的任何内容,只存储一个无意义的数据blob,则只存储以逗号分隔的列表。也就是说,如果您永远不会要求数据库在列中找到包含“Elf”的行。
如果您需要数据库来强制对值进行约束,请特别注意不要这样做。如果您希望数据库识别'Dragonseed'
,'Dwarf,,Dragginborn,Dragonseed,Elf,,'
或'Dwarf,,Elf,Hobbit,Dwarf,Dwarf'
是无效值。如果您要求数据库在列中添加或删除或替换Race,尤其是不要这样做,例如将'Dwarf,Elf,Hobbit'
转换为'Elf,Hobbit'
或'Dwarf,Ent,Hobbit'
。
话虽如此,如果可以列出的值的域是预定义的,并且不可变(固定)在模式定义中,那么我可能会考虑使用SET
数据类型
否则,我只会将逗号分隔的列表存储为数据库列,如果它只被视为一个数据块。类似于我如何处理作为BLOB的.jpg图像。我永远不会查询BLOB内容的“匹配”,我只会完整地检索或存储BLOB。 (我永远不会要求数据库执行定位/识别/检索/插入/修改/删除BLOB的部分的操作。)