在数据库列中存储分隔列表真的那么糟糕吗?
P粉020556231
2023-08-27 19:52:49
<p>想象一个带有一组复选框的 Web 表单(可以选择其中任何一个或全部)。我选择将它们保存在存储在数据库表的一列中的逗号分隔值列表中。</p>
<p>现在,我知道正确的解决方案是创建第二个表并正确规范化数据库。实现简单的解决方案速度更快,我希望快速获得该应用程序的概念验证,而不必在其上花费太多时间。</p>
<p>我认为在我的情况下节省的时间和更简单的代码是值得的,这是一个合理的设计选择,还是我应该从一开始就将其标准化?</p>
<p>更多上下文,这是一个小型内部应用程序,本质上替换了存储在共享文件夹中的 Excel 文件。我问这个问题也是因为我正在考虑清理该程序并使其更易于维护。其中有些事情我不太满意,其中之一就是这个问题的主题。</p>
“原因之一是懒惰”。
这敲响了警钟。您应该做这样的事情的唯一原因是您知道如何“以正确的方式”做这件事,但您得出的结论是有一个切实的理由不这样做。
话虽如此:如果您选择以这种方式存储的数据是您永远不需要查询的数据,那么可能存在以您选择的方式存储它的情况。
(有些用户会对我上一段的说法提出异议,说“你永远不知道将来会增加什么要求”。这些用户要么被误导,要么陈述宗教信仰。有时,努力工作是有利的您面前的要求。)
除了违反第一范式之外,还因为存储在单个值中的重复组值列、逗号分隔列表还有很多其他更实际的问题:
idlist REGEXP '[[:<:>:]]'
或在 MySQL 8.0 中:idlist REGEXP '\\b2\\b'
李>为了解决这些问题,您必须编写大量应用程序代码,重新发明 RDBMS 已经提供的更高效的功能。
逗号分隔的列表是错误的,我将其作为我书中的第一章:SQL 反模式,卷 1 :避免数据库编程的陷阱。
有时您需要采用非规范化,但正如 @OMG Ponies 提到的,这些都是例外情况。任何非关系“优化”都会使一种类型的查询受益,但会牺牲数据的其他用途,因此请确保您知道哪些查询需要特别处理,以便它们值得非规范化。