何时将列组合成单个分隔列在RDB模式中更好?

时间:2013-02-23 15:02:07

标签: sql database schema relational-database normalization

例如,假设您有两个数据和平的情况,其中一个值很少使用而另一个很少。作为一个示例,这是一个包含用户认证数据的表:

CREATE TABLE users
(
id INT PRIMARY KEY, 
auth_name STRING,
auth_password STRING,
auth_password_salt STRING
)

我认为没有盐就没有密码,反之亦然。我也可以选择以这种方式表示数据:

CREATE TABLE users
(
id INT PRIMARY KEY, 
auth_name STRING,
auth_secret STRING,
)

auth_secret中,存储D5SDfsuuAedW:unguessable42

等字符串

一般情况下,是否存在将列合并为一个分隔列的更好选择的情况?

即使它永远不是一个“更好的选择”整体,有没有成本(性能,空间,任何东西)有更多的列与更少的列(对于相同的数据)?我的动机是更好地理解,并且当有人提出这样的事情时能够更有力地反对它。

<小时/> - 已编辑 我更改了示例...原始示例如下:

CREATE TABLE points
(
id INT PRIMARY KEY, 
x_coordinate INT,
y_coordinate INT,
z_coordinate INT
)

VS

CREATE TABLE points
(
id INT PRIMARY KEY,
position STRING
)

position中,存储7:3:15

等字符串

3 个答案:

答案 0 :(得分:3)

当您无法加入,查询,报告或汇总数据时,就可以这样做。

换句话说 - 永远不会。这是糟糕的数据库设计。

第一范式(NF1)表明属性应该是不同的 - 这是基本要求。

答案 1 :(得分:2)

这个问题的唯一可能答案是从不。永远不会将分隔数据存储在列中。它击败了列的整个点,这些列用于分隔您的数据,并且使得执行数据库设计的任何操作变得异常困难。这违反了规范化程度如此巨大,以至于你花费数小时在Stack Overflow上试图在几个月内纠正它。

永远不要这样做。

然而,“永远不要说永远”。

在某些非常有限的情况下,没关系。永远不要认为它没关系,但可以

一个很好的例子是Stack Overflow自己的Posts table,它以分隔格式存储标签,以便快速读取。问题所具有的标签比编辑它们的频率更高。标签存储在单独的表PostTags中,然后在更新时非常规化为Posts。

简而言之,即使您可以通过这种方式对数据进行非规范化,也不要这样做。尽一切可能避免它。如果你遇到过几天你一直在优化的情况,而获得更快速的东西的唯一方法就是非规范化,那么它没关系。只需确保您只是从该列中读取数据,并且您有一个辅助流程来确保它保持最新。如果非规范化数据的更新失败,请回滚所有内容以确保数据一致。

答案 2 :(得分:1)

您遗漏了一个重要选项:创建适当的用户定义数据类型。 (PostgreSQL has long had an intrinsic data type for 2-space。)

这些实现差异很大。

但是你可能没有使用其中一个平台的奢侈。例如,您可能必须使用MySQL,它不支持用户定义的数据类型。

关系理论认为数据类型可以是任意复杂的;他们可以有内部结构。具有内部结构的最常见数据类型是“日期”类型。关系理论规定了dbms应该对数据类型做什么。 dbms必须

  • 完全忽略内部结构,或
  • 提供操作零件的功能。

对于日期,每个SQL dbms都提供了操作部件的功能。

你可以为在MySQL中存储3空格坐标的单个列(例如“7:3:15”)创建一个很好的参数。为了与关系理论保持一致,你希望dbms忽略结构,只返回单个值“7:3:15”;部件的操作留给应用程序代码。

在MySQL中实现类似事件的一个问题是MySQL不强制执行CHECK约束。所以要防止像“wibble:frog:foo”这样的价值观点进入数据库是很困难的。