达到 1NF

问题描述

阅读有关规范化的内容后,我不确定如何解释 1 NF 要求

根据维基百科,如果“每个属性的域只包含原子不可分割的值”

我的问题是:
谁决定什么是不可分割的? 您可以将日期数据类型划分为年、月、日、秒、纳秒。您也可以将地址划分为精确的纬度坐标。你什么时候才能确定你已经达到了 1NF?

这个表会被认为是 1NF 吗?

全名 完整地址
乔·佐威森 87th Victoria Street London EC96 1MB,14584
梅森汉堡 47th Jeremy Street London EC26 1MB,13584
德德里克·特里 27th Burger Street London EC16 1MB,17584

在这里的解释是,对于列 fullName,值 Joe Zowesson 是不可分割的。而且邮政编码、街道号码和街道名称都是原子与列名 fullAddress 相关的。

我几乎可以肯定我错了,但我还不明白为什么。

问题是关于即将举行的考试,我将需要“证明”当前某事物处于哪种正常形式。根据您对原子一词的解释,我觉得这很困难。

解决方法

你基本上误解了1NF的概念。原子值意味着当你有一列 Name 时,你不应该在它旁边存储任何其他值。换句话说,用于 Name 的列不应与 Name 一起存储 IDAddress 或其他任何内容,这样当您查询 Name 列时,您只会得到 Name,而不是带有 IdAddress 的名称。 姓名可以是您想要的任何形式,无论是名字+姓氏还是名字+姓氏+中间名+前名 .

是否需要为相关数据单独列的决定应在设计期间做出。假设您有 Student 表:

StudentId 全名 地址 平均成绩
1 约翰完成 美国纽约 3.4
2 罗伯特无聊 美国纽约 0
3 学生姓名 美国达拉斯 1
4 另一个LName 德国慕尼黑 2

在这种情况下,这意味着您不需要单独编写查询,也不需要基于名字、姓氏的数据,而是一次性需要所有数据,例如:

SELECT FullName
FROM Student
WHERE StudentId = 1;

约翰完成

而当您单独需要 First name,Last name 时,您将它们分解成几列,例如:

StudentId 全名 姓氏 地址 平均成绩
1 约翰 完成 美国纽约 3.4
2 罗伯特 无聊 美国纽约 0
3 学生 LName 美国达拉斯 1
4 另一个 LName 德国慕尼黑 2

您的查询可能如下所示:

SELECT LastName,AverageGrade
FROM Student
WHERE AverageGrade >= 1 AND FirstName != 'John';

结果将是:

| LastName | AverageGrade |
---------------------------
| LName    |     1        |
| LName    |     2        |

或者类似的东西:

UPDATE Student
SET AverageGrade = 4
WHERE LastName = 'LName' AND FirstName != 'Student'

基本上,该决定取决于您如何操作数据以及您需要它以何种形式。

总结一下。关系是否在 1NF 中取决于您尝试在此表上存储什么值,正如我上面提到的,一个应该只存储一种类型的值 ,例如ID、地址、姓名等。列值的外观取决于设计以及您需要存储数据的方式。如果你不需要分别查询fistname、middlename、lastname、secondname,那么你可以做的就是将它们全部保存在一列FullName中,它仍然是在 1NF。但是如果你分别需要它们,你可以将它们存储在单独的列中,它仍然是 1NF,但它可能违反其他规则。

以下是一些您可能会觉得有用的教程:https://www.studytonight.com/dbms/first-normal-form.php

,

让应用程序及其使用方式指导您将哪些数据进一步拆分为其他字段(或不拆分)。

例如; 如果在您的应用程序中,您不断地将名字与姓氏分开,以便您可以在通信中说“Hi Joe”,那么您应该将 fullName 拆分为两个字段。相反,如果您有两个字段 firstName 和 lastName,并且总是将它们连接起来以便正确寻址信封,那么将这两个字段存储在表中的单个列中会更有意义。

在实践中,考虑到这两种情况的普遍性,数据库显示一些非规范化的情况并不少见,但风险是如果有人更新名字(例如)但没有同步'不更新全名。

考虑诸如如果您决定使用单列 fullName,您将如何强制您的用户遵循特定模式。如果您的应用程序需要“Joe Smith”,您将如何防止“Smith,Joe”?

日期是另一个很好的例子,同样,是否将这些部分分成单独的列取决于它们的使用方式。

指示何时插入行的日期时间字段可能不需要拆分,但如果您有许多只对年份感兴趣的查询(例如),将其拆分可能是有意义的。

这只是触及了表面,这就是为什么这个答案更多地是关于如何思考潜在问题。是的,出于各种原因,标准化您的数据库很重要,但您能走多远取决于您的数据在一天结束时的使用方式。