2

例如,考虑您有两个数据和平的情况,其中一个值很少使用另一个值。作为一个例子,这里是一个包含用户认证数据的表格:

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
)

对比

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

position,存储字符串,如7:3:15

4

3 回答 3

3

当没有机会需要加入、查询、报告或聚合数据时,您可以这样做。

换句话说 - 从来没有。这是糟糕的数据库设计。

第一范式 (NF1) 指出属性应该是不同的——这是基本要求。

于 2013-02-23T15:07:10.123 回答
2

这个问题唯一可能的答案是never。永远不要将分隔数据存储在列中。它破坏了用于分隔数据的列的整个点,并使执行数据库设计的任何事情变得异常困难。这是对规范化的严重违反,以至于您将在 Stack Overflow 上花费数小时试图在几个月内纠正它。

永远不要这样做。

然而,“永不言败”。

在某些极其有限的情况下,这没关系。永远不要假设它没关系,但它可以

一个很好的例子是 Stack Overflow 自己的Posts 表,它以分隔格式存储标签以便快速阅读。从数据库中读取问题的标签比编辑它们的频率要高得多。标签存储在单独的表 PostTags 中,然后在更新时非规范化为 Posts。

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

于 2013-02-23T15:56:43.107 回答
1

您遗漏了一个重要的选项:创建适当的用户定义数据类型。(PostgreSQL 长期以来一直有 2-space 的内在数据类型。)

这些实现有很大不同。

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

关系理论认为数据类型可以任意复杂。它们可以有内部结构。最常见的具有内部结构的数据类型是“日期”类型。关系理论指定了 dbms 应该如何处理此类数据类型。dbms 必须要么

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

在日期的情况下,每个 SQL dbms 都提供了操作这些部分的函数。

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

在 MySQL 中实现类似的一个问题是 MySQL 不强制 CHECK 约束。所以要阻止像“wibble:frog:foo”这样的值进入数据库要困难得多。

于 2013-02-23T15:47:15.823 回答