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

Sql 在RDB模式中,何时将列组合成单个分隔列会更好?,sql,database,schema,relational-database,normalization,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

例如,考虑这样一种情况:您有两组数据,其中一个值很少在没有另一个值的情况下使用。例如,下面是一个保存用户身份验证数据的表:

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


位置
中,存储字符串,例如
7:3:15

您可以在不需要加入、查询、报告或聚合数据的情况下执行此操作

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


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

您遗漏了一个重要选项:创建适当的用户定义数据类型。()

这些实现差别很大

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

关系理论认为数据类型可以是任意复杂的;它们可以有内部结构。最常见的具有内部结构的数据类型是“date”类型。关系理论规定了dbms应该如何处理这样的数据类型。数据库管理系统必须:

  • 完全忽略内部结构,或
  • 提供操作零件的功能
对于日期,每个SQL dbms都提供了操作部件的函数

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


在MySQL中实现类似功能的一个问题是MySQL没有强制执行检查约束。因此,要阻止像“wibble:frog:foo”这样的值进入数据库要困难得多。

这个问题唯一可能的答案是永远不会。永远不要在列中存储分隔的数据。它破坏了用于分隔数据的整个列点,并使数据库的设计工作变得异常困难。这违反了规范化的规定,如此之大,以至于你要花几个小时在堆栈溢出上,试图在几个月内纠正它

永远不要这样做。 然而,“永不说永不”

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

堆栈溢出自身就是一个很好的例子,它以分隔格式存储标记,以便快速读取。问题的标签从数据库中读取的频率远远高于编辑的频率。这些标记存储在一个单独的表PostTags中,然后在更新它们时将其非规范化为post


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

不,我看不出有任何理由这样做。。。容易组合,不容易分割。我的例子可能不好,因为每个坐标实际上都有自己的值(如您所说的用于连接、查询等)。如果我能想到一个例子,其中一件事没有另一件事就毫无意义,那么把它们放在一起会有任何好处(空间、性能、任何东西?)@derekv-好处(如果有的话)会被缺点完全压倒-排序、查询、,聚合和报告将更加困难,需要您首先解析字段。优化和索引也会有问题。我有点不同意我的回答,并且:-)关系模型允许类型任意复杂。它只需要dbms忽略复杂性(将该值视为一个黑匣子,返回并全部更新),或者提供函数来处理这些部分(就像每个SQL dbms处理日期和时间戳的函数一样)。接受此答案是因为最接近问题的精神。感谢提供更多信息,这似乎是此问题的一个重要方面。
CREATE TABLE points
(
id INT PRIMARY KEY,
position STRING
)