如何规范化数据库中的数据?

时间:2014-10-11 04:43:14

标签: database

我正在介绍数据库管理课程,我们正在学习如何规范化数据(1NF,2NF,3NF等),而且我对如何真正实现这一目标非常困惑。做到这一点。我已经阅读了这个,咨询了各种网站和YouTube视频,我似乎仍然无法点击它。我正在使用Microsoft Access 2013,如果有任何帮助的话。

https://i.imgur.com/vZ3QNjr.jpg

这是我正在使用的数据。

感谢。

编辑1:好吧,我想我已正确设置了表格。但是现在我实际上输入数据从一个表到另一个表时遇到了麻烦。这是我的关系表。

enter image description here

2 个答案:

答案 0 :(得分:1)

在最基本的层面上,表格中的任何重复值都是标准化的候选值。重复数据通常是个坏主意。假设您需要更新患者的姓氏 - 您现在必须更新此表中的所有事件,并且可能更新数据库其余部分中的所有其他事件。将每位患者的详细信息存储在一个地方要好得多。

这是标准化的用武之地。向下看列,您可以看到有关牙医,患者和手术的数据有重复值,因此我们应该规范化每个实体的表格以及原始数据包含约会的表,总共提供四个表。

将实体提取到自己的表中,并为每一行提供一个主(唯一)键 - 现在只使用递增整数。 (编辑:,如评论中所建议的,我们可以使用PatientNo,StaffNo和SurgeryNo的自然键,而不是创建代理人。)

然后,我们只在患者表中引用主记录的密钥,而不是在约会表中多次出现每个患者的姓名和号码。这称为外键。

然后,为牙医和外科做同样的事。

你最终会看到类似这样的表:

APPOINTMENT

AppointmentID  DentistID  PatientID  AppointmentTime   SurgeryID
----------------------------------------------------------------
1              1          1          12 Aug 03 10:00   1
2              1          2          ...               2
3              2          3          ...               1
4              2          3          ...               1
5              3          2          ...               2
6              3          4          ...               3


DENTIST

DentistID  Name             StaffNo
--------------------------------------
1          Tony Smith       S1011
2          Helen Pearson    S1024
3          Robin Plevin     S1032


PATIENT

PatientID  Name              PatientNo
---------------------------------------
1          Gillian White     P100
2          Jill Bell         P105
3          Ian MackKay       P108
4          John Walker       P110


SURGERY

SurgeryID  SurgeryNo
-------------------------
1          S10
2          S15
3          S13

答案 1 :(得分:1)

第一步是数据建模和非规范化是了解您的数据。研究它可以理解模型中存在的域“对象”或表。那会让你知道如何开始。有时单个表或查询示例不足以完全理解数据库,但在您的情况下,我们可以使用示例数据并做出一些假设。

其次,查找重复/冗余数据。如果您看到名称的副本,则很有可能是外键的候选者。我们的假设告诉我们STAFF_NO是DENTIST的主要候选人,因为每个唯一的STAFF_NO与唯一的DENTIST_NAME相关联,所以我看到一个好的候选人DENTIST表(STAFF_NO,DENTIST_NAME)

一些SURGERY表中的示例:

ID     STAFF_NO    DENTIST_NAME
1      1           Fred Sanford
2      1           Fred Sanford
3      3           Lamont Sanford
4      3           Lamont Sanford

为什么一遍又一遍地存放这些?弗雷德说“但我正确的名字是弗雷德G桑福德”会发生什么,所以你必须更新你的数据库。在当前表中,您必须更新名称是多行。如果您已将其标准化,则DENTIST表中的名称只有一个位置。

所以我可以把独特的牙医带到DENTIST

create table DENTIST(staff_no integer primary key, dentist_name varchar(100));

-- One possible way to populate our dentist table is to use a distinct query from surgery

insert into DENTIST
    select distinct staff_no, dentist_name from surgery;

STAFF_NO    DENTIST_NAME
1           Fred Sanford
3           Lamont Sanford

SURGERY表现在指向DENTIST表

ID     STAFF_NO
1      1       
2      1       
3      3       
4      3       

现在您可以创建一个视图VIEW_SURGERY来加入DENTIST_NAME,以满足典型查询的需求。

select s.id, d.staff_no, d.dentist_name
  from surgery s join dentist d
    on s.staff_no = d.staff_no   -- join here

所以现在牙医主键的DENTIST唯一更新将更新一行。

update dentist set name = 'Fred G Sanford' where staff_no = 1;

添加查询视图将显示N行的更新名称:

select * from view_surgery

ID     STAFF_NO    DENTIST_NAME
1      1           Fred G Sanford
2      1           Fred G Sanford
3      3           Lamont Sanford
4      3           Lamont Sanford

简而言之,您正在删除冗余。

这只是一个示例,也是一种方法。像这样的手动规范化在建模工具时并不常见,但关键是,我们可以查看数据,发现冗余并将这些冗余计入新表,并通过外键和连接关联这些新表,然后构建视图代表原始数据。