数据库列(逗号分隔或单个字段)

时间:2014-02-26 16:42:42

标签: sql database database-design

假设您有20个选项希望最终用户选择。根据这些选择,将对它们进行计算以创建百分比。运行查询计算时,在查询性能方面有什么意义呢?

a)构建一列,并在该列中以逗号分隔所有选定的值 b)将每个选项作为表中的自己的列

c)有一个链接表,将选项标记回用户ID吗?

如果应该在其他地方询问,请告诉我,我会将其删除并移至相应位置。

4 个答案:

答案 0 :(得分:1)

这完全取决于我假设我们正在谈论一个sql数据存储。

如果您需要能够快速查询哪些用户选择了哪个选项,那么您将要么在表中使用单独的列,要么需要另外一个表,例如三列。

用户id
optionId
optionValue

optionId将标识选项('option1','option2'等)。此方法的优点是允许您在不修改数据库模式的情况下添加选项类型。这可能是一个优势,具体取决于您的环境(如果添加数据库列需要冗长的更改控制过程)。

可能单独的表格方法会稍慢,但我不认为这是“有所作为的差异”。我几乎总是使用最容易为我的应用程序逻辑使用的表示,

如果你真的只对最终百分比感兴趣并且永远不需要查询选项,那么我认为逗号分隔的字符串列表可能没问题。 DBA可能不同意这种观点:)。

答案 1 :(得分:1)

a)可能违反了atomicity的原则,因此违反了1NF的原则,导致multitude of problems

b)和c)之间的选择取决于值的动态程度:

    如果您希望能够动态“增长”允许值集,
  • c)更合适,
  • 而b)对于静态情况可能更直接(和高效)。

---更新---

好的,让我稍微触摸查询性能方面。

通过使用b)或c),您可以直接在DBMS中执行AVG,SUM和其他聚合函数,然后单独返回结果 。这节省了网络带宽,这往往比CPU更加稀缺。

在a)的情况下,您可能通过将所有“胖”数据提取到客户端并在那里进行计算来实现它(在服务器上解压缩和聚合数据需要一些杂技 - 不是不可能,但肯定更脆弱并且不太可维护)。正如Jonathan Van Matre正确pointed out一样,序列化为字符串而不是使用本机二进制存储格式,并不是表示数据开始时最紧凑的方式。

答案 2 :(得分:1)

这里的关键是你正在对这些数据进行计算。

有多种原因导致您不应通过在其中存储多个数据点的CSV来重载列,但在这种情况下,控制原因是性能

如果您在数据库中基于这些数据点的值进行计算,那么您绝对希望为它们使用单​​独的列。如果将它们存储为单个CSV字符串,则每次计算都会产生解包CSV并将字符转换为数值的成本。第一个操作特别昂贵,在我使用的每个DBMS中都是如此。这就是让DBA诅咒并把事情扔到墙上的事情。

另一方面,如果数据点已作为数值存储在独立列中,则不会产生这些开销成本,您只需进行基本数学运算即可计算出数值结果。

从DBA中获取:存储单独列(甚至是单独的CustomerChoices表)的成本不为零,但仍然小于成本通过处理解压缩重载列和进行数据类型转换而产生的。

(此外,当您存储CSV数据时,您正在存储不必要的字节,甚至不是数据:所有逗号。这也有成本。)

之前的两个答案可能已经调用了查询性能以支持CSV解决方案,但他们忽略了数据必须在数值计算中使用的关键点。

如果您可以在应用程序中执行数字运算并仅将计算的百分比和选项存储到数据库存储中,那么然后您可以将选项存储为CSV。但只有当DBA没有看时。

即使在这种情况下,任何值得他们盐的DBA都会争论单独的数字列,因为在将来的某个时候会有一个请求DBA在数据库中重现应用程序的计算以进行审计查询,并且因为他们已经粉碎了所有他们喜欢的东西,所以他们将无法扔到墙上。

答案 3 :(得分:0)

关于查询性能,我建议您构建一个列,并在该列中以逗号分隔所有选定的值