关于mysql:数据库列中的CSV – 不是一个好主意?

CSVs in database columns - not a good idea?

本问题已经有最佳答案,请猛点这里访问。

不久之前,我意识到我希望在游戏中掌握玩家技能的方式是通过CSV格式。在玩家的统计数据上,我制作了一系列可以存储为CSV的技能。 (1,6,9,10等)我制作了一个"技能"表,其中包含每种技能(名称,效果)的附属统计数据,当需要查看他们拥有的技能时,我所要做的就是查询单个技能列并使用PHP的str_getcsv()来查看是否存在某种技能,因为它将在数组中。

然而,我的同事建议一个优秀的系统是让每个技能只是进入每个玩家将使用的主"技能"表,并且每个技能将具有玩家的ID外键。我只查询此表中的所有行,返回的将是他们的技能!

起初我觉得这根本不会很好,但互联网似乎不同意。我知道它不太可搜索 - 但我不打算说,"玩家是否拥有x技能?"或"向我展示所有具有此技能的玩家!"。在最糟糕的情况下,如果我想要这样的数据,我只会为它做一个PHP报告,诚然,这会很慢。

但似乎这真的更快?!我很难找到一个难以回答的问题,而不仅仅是"它是好的和正常化的"。 Stack Stack Overflow可以帮助我吗?

编辑:谢谢,伙计们!我从来没有意识到这有多糟糕。对于这个骗局感到抱歉,但是相信我,我没有在没有检查欺骗的情况下输入所有内容。 :P


将逗号分隔值放入数据库中的单个字段不仅是一个坏主意,它是撒旦在数据库模型中表达的化身。

它不能准确地表示很多情况(值包含逗号或其他您的CSV消耗代码有问题的其他情况),通常存在嵌套在其他值中的值的问题,无法正确索引,不能用于数据库JOIN,难以重复数据删除,不能添加额外信息(技能获得的次数,在您的情况下,或技能级别),不能参与关系完整性,不能强制类型约束,等等。这个名单几乎无穷无尽。

对于MySQL来说尤其如此,它具有非常方便的group_concat功能,可以在需要时轻松地将此数据显示为逗号分隔的字符串,同时仍保持规范化数据库的完整功能和速度。

使用逗号分隔方法没有任何好处,但却失去了可搜索性和性能。让撒旦在你后面,并规范你的数据。


由于数据库将索引内容(假设您使用索引),因此搜索内容并获得所需内容的速度非常快。请记住:数据库旨在保存大量信息,而mysql是一个关系数据库,它是为关系而创建的。

另一个问题是系统的可维护性。维护一个规范化的系统要容易得多。当你要移除或添加技能时,它会更容易。

当您即将从数据库中获取有关玩家技能的信息时,您可以通过简单的JOIN轻松获得与相关技能相关的信息。

我说:让数据库做最好的事情 - 处理数据。让你的编程做它应该做的事情;)


嗯,有些东西需要考虑可扩展性。如果您需要添加/删除技能怎么办?如何重命名技能?如果技能的数量增加你的领域的大小会发生什么?为了适应这样的事情,必须重新调整字段大小是不好的做法。

那么可维护性呢?可以让另一位开发人员进来了解你做了什么吗?如果给玩家两次相同的技能,会发生什么?

你同事的建议也不正确。在这种情况下,您将有3个表。主要玩家表,技能表和与两者有关系的表,创建多对多关系,允许单个技能与许多玩家相关联,以及许多具有相同技能的玩家。