【问题标题】:1NF: Repeating Groups, what are they? [duplicate]1NF:重复组,它们是什么? [复制]
【发布时间】:2014-12-09 00:55:15
【问题描述】:

对于什么是“重复组”似乎存在误解,就其在第一范式 (1NF) 中的删除而言,任何人都可以清楚地阐明它实际上是什么以及如何识别它吗?

我发现,这里进一步讨论了这个误解:https://stackoverflow.com/a/23202535/4011506。然而,这让我更加困惑。

关于以下视频(4:30 起),https://www.youtube.com/watch?v=HHDH6N_qjm4

姓名、地址、城镇、邮政编码和性别字段不是重复组吗?

而不是这个视频的作者建议的(最后 5 个字段)?

此外,如果有人能够提供示例来证明重复组的误解,以及实际答案是什么,那也很好。

谢谢

编辑: 我得到的回答让我更加困惑……所以我有另一个例子来帮助查询:

https://hostr.co/file/970/ITiHuyVyCmPr/UNF.png

鉴于未规范化的表,我的文字建议要“删除”重复组,请删除 NULL(通过将适当的数据值添加到 NULL 字段中)。结果是这样的:(请将上面'970'之后的链接替换为:/6QWYWR8FtxFD/1NF.png

因此,本质上,在这种情况下,重复组是什么? (根据我刚刚从回复中读到的内容,不是每个实例/行包含相同数据的字段,即使从字面上看,它们本质上是“重复”,这是正确的吗?不直观...)

根据“删除”重复组的建议,是从字面上删除重复组(如原始帖子的视频中所述)还是“删除”空值(通过向其中添加值) ?还是视情况而定……?

【问题讨论】:

  • “姓名、地址、城镇、邮政编码和性别字段不是重复组吗?” 不,男性每行重复“M”,重复“F” ' 在每一行中,女性并不构成重复组。重复组的概念适用于单行,部分键依赖 (2NF) 的概念、传递依赖 (3NF) 的概念等也是如此。
  • 感谢迈克的回复。好的,如果我正确理解您的断言,即使学生可能注册多门课程(因此,他们的姓名、地址、城镇、邮政编码和性别)将被“重复”(在这个意义上),它并不构成重复组?
  • 如果您假设 hostr.co/file/970/ITiHuyVyCmPr/UNF.png 显示 4 个元组,则第一个元组 (PROJ_NAME Evergreen) 有一个由 5 个整数 (101,102,103,105,106) 组成的 EMP_NUM 重复组,其他列也类似。如果重复组被删除,如hostr.co/file/970/6QWYWR8FtxFD/1NF.png,则有 21 个元组,每个元组都有一个 EMP_NUM 的整数值。
  • 谢谢。因此,您在 hostr.co/file/970/6QWYWR8FtxFD/1NF.png 中提到的重复组的“删除”基本上没有被删除?也就是说,您记为重复组 101、102、103、105、106 的某些 EMP_NUM 值本身并没有从表中删除(或转移到另一个表),而是不再被描述为重复团体?此外,1NF 图像,实际上在 1NF 中了吗?通过创建单独的表来“移动”重复组的字段不是很好的做法吗?请问您是否也可以回答这个问题?感谢您的帮助。

标签: database database-design normalization database-normalization


【解决方案1】:

就我而言,这些误解至少可以追溯到我在 1980 年代初学习关系数据库时。我在 1NF 中最简单的概念处理是位于行和列交叉处的值必须是简单值。然而,“简单”的定义并不是那么简单(开个玩笑)。

字符串是一个简单的值,尽管它是由组件(即字符)组成的。时间戳很简单,尽管它是由日期和时间组成的,每个时间都由年、月等组成。

我将用逗号分隔的值列表视为违反 1NF,尽管这可能只是意味着我使用了非正式定义。

就关系和关系数据模型而言,关系数学中没有任何内容禁止元组和属性的交集本身就是关系。我认为 E.F. Codd 在提出规范化时打算排除这种结构。 (后来命名为第一个范式,一旦发现了第二个范式。)

他为什么使用“标准化”这个词。好吧,这就是他的目标,IMO。对于任何已定义的信息需求集合,都有一组关系模型可以充分表达这些需求。从这个意义上说,该集合的成员可以被认为是“等价的”。人们可以想出一个规则来选择该集合中的一个成员并将其称为整个集合的“正常”表示。 Codd 提出的规则就是后来的 1NF 规则:没有子关系。

在计算中较早出现“标准化”概念的另一个地方是浮点数。数字 0.1 和 1e-1 都代表同一个数字,并且有无数种表示同一个数字的方式。其中之一可以称为“规范化”表示。一旦计算机指令集中开始支持(二进制)浮点数,就有一种方法可以“规范化”二进制浮点数,使尾数始终在二分之一和一之间,除非数字为零。了解这些细节并不重要。我的意思是,在 1970 年 Codd 撰写论文时,“规范化”一词已经是计算机术语的一部分。

IMO,一个更大的问题是“违反 1NF 有什么不好?为什么 1NF 很重要?”

这个问题的答案有两个部分:一个与逻辑模型有关,一个与第一个关系 DBMS 的物理实现有关,它直到 1978 年左右才出现。

在逻辑模型中,最好说指定元组(通过提供键值)和指定属性(通过名称)应该足以将指定的值确定为单个值,在DBMS 处理的详细程度。早期文献将此称为“对所有数据的键控访问”。

在物理模型中,为了对所有出现的简单值进行简单搜索,必须避免进行整个表扫描,这一点很重要。索引应该在几次磁盘读取中完成,而不是在一次表扫描中可能需要数百万次磁盘读取。据我所知,没有一个 DBMS 可以为存储在列中的 CSV 文本中的单个值创建索引。在构建第一个关系 DBMS 时,Codd 肯定希望避免对此类索引的需求。

正是这最后一点让我回到了对我非常有帮助的“理论就是实践”的座右铭。新手数据库设计人员总是来这里,问为什么在学生表中存储课程代码列表不会“更有效”,而不是诉诸使用两个外键创建联结表的“复杂性” , 学生 ID 和课程 ID。让新手信服的答案通常与执行表扫描以及相关延迟有关,因为良好的 DBMS 将通过索引执行操作,前提是已创建适当的索引。 IMO,我认为 Codd 也是这么想的。

为了进一步搅浑水,可以(至少在 Oracle 中)定义一个表,该表在其中一列中包含子表。可能会出现这样的数据库是否在 1NF 中的问题。我的答案是否定的。

(对不起,这太长了。)

【讨论】:

  • 如果我理解正确的话,Chris Date 的观点是位于行和列交叉点的值可以是任意复杂的(如文档或电影),但是 dbms a) 处理它们作为没有内部结构的任何其他值,或 b) 提供操作部件的函数。例如,dbms 提供了一些函数来操作时间戳的各个部分。
  • 我认为你是对的。但是,b) 部分可以用两种方式解释。一方面,DBMS 可能会提供一个内置函数,例如 month(D),它可以从时间戳 D 中提取月份。到目前为止,一切都很好。几个 DBMS 产品做这种事情。第二级操作将允许通过某种索引解析像“where month(DateColumn) = month(3)”这样的查询规范。很可能有一些 DBMS 为日期的子结构提供这种支持。 CSV 结构的索引支持完全不同。
  • PostgreSQLOracle 和 DB2 支持“基于函数的索引”或“基于表达式的索引”,它们允许像 create index on your_table (extract(month from DataColumn)) 这样的东西。我相信他们通常要求您在 WHERE 子句中使用相同的表达式。像where extract(month from DateColumn) = 3 这样的表达式可以使用索引,但where DateColumn between '2014-03-01' and '2014-03-31' 不会。
【解决方案2】:

重复组是数据库表中的多值结构:没有单个值但由多个值组成的属性,这些值通常通过位置索引而不是名称访问。 Codd 最初的第一范式避开了具有重复组的表,而支持仅由单值属性组成的关系。大多数现代 DBMS 不允许多值属性,因此这种禁止并不特别重要。

Codd 后来修改/改写了他对 1NF 的定义,指出它排除了 relation-valued 属性(请注意,他从未将关系值属性称为“重复组” - 关系是另一回事共)。对关系值属性 (RVA) 的禁令比 1NF 的原始定义更具争议性。关系原则上是一个值,可以像访问任何其他单个值一样访问。出于清晰和简单的“明显”原因,通常可以避免 RVA。但这并不一定意味着必须始终避免它们。由于 RVA 是单个值(与重复组不同),它们可以像其他其他单个值一样进行关系操作。说关系应该由关系的任何类型的单值属性except组成,这似乎是不必要的限制,而且有点武断。

以简单(无向、无环、非多边)图为例。假设一个图用 relvar 表示,每条边都有一个元组,用 lt, rt 属性来标识节点:

G {lt,rt}

图由 G 的关系值表示。现在假设我们需要在关系数据库中对此类图的任意集合进行建模。显然,一个图必须与另一个图区分开来,因为它由一组不同的节点和边组成,但不同的图也可能有一些共同的节点和边。最自然的表示(也许是唯一可能的表示)不是由图形值组成的新关系 - 即与 G 相同类型的 relation 值吗?

Graphs { G {lt,rt} }

这个 Graphs relvar 有一个属性 G,它是一个带有标题 {lt,rt} 的关系值属性。如果我们希望不惜一切代价避免 RVA,那么一个可能的替代方案是通过添加一个新属性来扩展我们原来的 G relvar,以通过节点和边以外的其他东西来识别图。

Gnam {graphname,lt,rt}

这可能是一个有用的解决方案,但为什么必须它是 1NF 下的解决方案?如果在我们试图建模的现实中不存在这样的属性,那么仅仅为了数据库表示而发明一个新属性可能非常不方便。规范化过程通常不需要发明新的属性来满足任何规范形式。如果 RVA 被理解为被 1NF 排除,那么作为设计程序的规范化似乎可能会被“破坏”——我们的图形表示确实无法被规范化;只有它的替代 Gnam 形式才能成功规范化。我同意 RVA 在大多数情况下可能是不可取的。我不太相信将 1NF 解释为完全排除它们是个好主意。

只是重申一下,RVA 与重复组不同

【讨论】:

    【解决方案3】:

    关系是一组n元组,其中每个n元组的第j个属性取自关系的第 j 个域。

    第一范式是一个定义问题,即确保数据库仅包含关系。所以一个数据库是第一范式当且仅当它只包含关系

    如果数据库处于第一正常状态,则意味着每个关系的每个属性都是在域上定义的。域指定可以分配给属性的一组允许值可以对这些值执行的操作。

    例如您可以定义一个域 StringUpper(10),它由值 A 和 Z 之间的 0 到 10 个字符组成。可以对该域中的值执行的操作包括 SubString( Start, End) 提取从 Start 开始到 End 结束的字符。

    域可能是“任意复杂的”,例如 MPEG-4PortableNetworkGraphic;只需要确保分配给在此类域上定义的属性的任何值确实在该域的允许值集中,例如是一个有效的 MPEG-4。这些域中的值可能具有可以对其执行的特定操作,例如播放查看

    域可能包含某些人可能认为重复的组,例如您可以定义一个域 ListStringUpper(10),它由 0 个或多个元素组成,其中每个元素由值 A 和 Z 之间的 0 到 10 个字符组成。在可以对值执行的操作中在此域中是 GetElement(Index),它提取列表中的第 Index 个元素。 (请注意,这与作为字符列表的字符串没有太大区别)

    但是,如果其中一个域将自身关系作为允许值,则会出现潜在问题。如果是这种情况,那么就不能使用一阶逻辑来操作数据库中的关系,而是必须使用二阶逻辑。这会使操作更加复杂。为了消除这种复杂性,并确保始终可以使用一阶逻辑,可以对第一范式的定义进行细化:

    数据库处于第一范式当且仅当它仅包含关系并且关系的属性不存在域本身具有作为允许值的关系

    【讨论】:

    • 我很抱歉,但似乎有相当复杂的反应,虽然非常有见地,但导致了我无法理解的进一步混乱。是否有可能您可以根据我的原始查询将其改写为 Layman 的术语,如果不是,我刚刚添加到原始帖子中的新示例?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2014-03-16
    • 1970-01-01
    • 2019-05-27
    • 2016-02-09
    • 2014-10-24
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多