【问题标题】:normalization in database数据库中的规范化
【发布时间】:2015-11-18 08:46:11
【问题描述】:

我有一张桌子。我怎样才能使它正常化。

【问题讨论】:

  • 你读过所有不同形式的标准化吗?
  • 是的,我读过它,我认为它应该是 3nf 但不确定我为什么在这里。
  • 从长远来看,任何答案都对您没有帮助。更好地学习自己,尝试然后带着你面临的疑问/问题回到这里。
  • 这个表的key和依赖是什么?是什么让您认为它尚未满足 3NF?
  • 请说明您应该对 toa 进行“规范化”的最小范式以及为什么该表“应该 [in] 3nf”以及为什么您“不确定”。否则,您的问题只是要求教科书的规范化章节。

标签: database-design database-normalization


【解决方案1】:

鉴于您的数据集,这是个好问题。请记住,标准化的全部意义在于减少重复。 3NF 通常是最好的方法。但根据我的经验,我发现非常如果重复值将是该表中的唯一值,则将其提取到另一个表中几乎没有什么好处。以您最重复的列 emp_type 为例。如果你要将它规范化为一个单独的表,它看起来像这样:

Emp_Type_Id | Emp_type
------------------------
1           | Manager
2           | Engineer
3           | Tech Support

您当前的表格如下所示:

Emp_ID | Emp_Name | Salary | Emp_Type_Id | Emp_Skill
----------------------------------------------------
1      | raj      | 90000  | 1           | Department
2      | ravi     | 50000  | 2           | Software
3      | shyam    | 70000  | 2           | Hardware
.
.
.

这在技术上比以前更加规范化,因为 emp_type 值不再在您的数据库中重复。但是处理单独的表和单个值的关系要麻烦得多。如果 emp_type 还包括其他信息,例如 Valid_Salary_Range、Department_Location 等,那么最好将其规范化到单独的表中。但是,如果它只是您要标准化的单个值,那么存储该值与存储指向该值的 ID 有什么区别?在我看来,这是一个毫无意义的额外步骤。

长话短说,我根本不会规范化您的表格,它已经规范化到足够的水平。

【讨论】:

  • 标准化到更高的 NF 不涉及引入新的列名。这也表明不了解规范化。
【解决方案2】:

在我们开始之前,我会先提到每个步骤的规则。为什么这样?因为我不知道你表中的依赖关系。因此,提出规则和我对您的数据的假设将阐明我是如何得出最终解决方案的。

最后,如果您对答案不满意,至少您会失去对标准化工作原理的理解,并且可以继续自己对只有您最了解的数据进行处理。



数据库设计的自然顺序

  1. 首先指定实体(这些是表格)
  2. 指定您的实体所需的属性(这些是列)
  3. 指定实体的唯一属性(表的主键)。如果没有,请自己给一个(也称为合成主键或代理主键)。
  4. 最后指定这些实体之间的关系(主键-外键关系和1-N、N-N关系等)

---------

现在,基本的设计规则已经到位,很容易看出您的单个表实际上有四个独立的实体融合在一起。它们是:

1.员工 - 有身份证和姓名的人

2。角色 - 可以是工程师、技术支持等

3.部门 - 可以是软件、硬件、部门(虽然可以使用更好的词)、语音等。

4. Salary - 包含 EmpId、DateOfChange 和 Amount。这是因为员工的薪水不同,而且同一员工的薪水也会随着时间而变化。

因此,如上所述,我们将把这张桌子分成四张桌子。在四个表中,Employee 表以 id 作为主键,Role 和 Department 需要合成(甚至可能是自动递增)键,Salary 将 {EmpId, DataOfChange} 一起作为主键。这看起来像:

Table Name    Columns
Employee      Id, Name, RoleId, DeptId
Role          RoleId, RoleType
Department    DeptId, DeptName
Salary        EmpId, DateOfChange, Amount

上面的所有表格都可以有更多的项目。我正在尝试与您已经给出的那张桌子有极简差异的设计。像 Salary 表一样,也可以有一个像 ReasonOfSalaryChange 这样的字段,它可以有像 NewHiring、Promotion 等这样的值......但我们将更改保持在最小限度。

希望到目前为止一切都好。如果是这样,我们将继续进行您所要求的实际标准化。



常用规范化

我之所以提到常用规则,是因为老实说,我在实践中从来不需要 BCNF、4th 和 5th NF。

规则 -

1NF: 只是声明所有列都必须具有原子值。如果一列需要多个值,请创建另一个表。您的新表通过了该测试。表列中的所有值都是原子的。

2NF: 需要 1NF 限定,并且任何非键字段都应依赖于整个主键。您的所有非键字段(员工中的姓名、角色中的角色类型、部门中的部门名称、工资中的金额)取决于相应表的主键(Id、RoleId、DeptId 和 {EmpId、DateOfChange})。所以这些表符合 2NF 标准。

3NF: 需要 2NF 资格,并且任何非关键字段都不应依赖于任何其他非关键字段。这意味着除了主键之外,表的列之间不应存在依赖关系。 Role、Department 和 Salary 表是默认的 3NF 限定的,因为它们只有一个非键列并且它依赖于 PK。 Employee 表,您可以自己验证,没有依赖于任何其他非关键元素的非关键元素。因此,这些表完全符合目前的 3NF 标准。



现在剩下的就是指出 RoleId、DeptId 和 EmpId 分别是 Role、Department 和 Employee 表中的外键。这将是我最后一次重新设计和规范化的数据库提交给您。

【讨论】:

  • 我要补充一点,在现实世界中,可能需要将工资提取到工资历史表中,其中包含工资的开始和结束日期,因为它随着时间的推移而变化。这是时间数据,可能需要过去的值来研究问题和报告。
  • @HLGEM:我已经很多年没有做过任何数据库工作了,所以对这些细节失去了兴趣。你的建议是+10。如果 OP 说需要它,将合并。否则将保持原样。非常感谢您指出。
  • @HLGEM:再三考虑,我会做出你建议的改变。
  • 人们忘记了我们不只是为了存储数据而存储数据。如果它要有价值,我们必须了解数据将用于什么,而不仅仅是它如何进入数据库。太多人的设计只是为了让应用程序更容易插入数据,而从不考虑他们为什么首先需要这些数据。当你不提前思考为什么时,你不会发现大多数时候它会被用在“这个日期的薪水是多少?”中。查询类型。如果您没有以这种方式存储数据,那么您将无法回答用户需要询问的有关数据的问题。
  • 反对永久实体/表合并。实体由表示,表表示谓词。
猜你喜欢
  • 2012-10-08
  • 2012-06-21
相关资源
最近更新 更多