我正在介绍数据库管理课程,我们正在学习如何规范化数据(1NF,2NF,3NF等),而且我对如何真正实现这一目标非常困惑。做到这一点。我已经阅读了这个,咨询了各种网站和YouTube视频,我似乎仍然无法点击它。我正在使用Microsoft Access 2013,如果有任何帮助的话。
这是我正在使用的数据。
感谢。
编辑1:好吧,我想我已正确设置了表格。但是现在我实际上输入数据从一个表到另一个表时遇到了麻烦。这是我的关系表。
答案 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
简而言之,您正在删除冗余。
这只是一个示例,也是一种方法。像这样的手动规范化在建模工具时并不常见,但关键是,我们可以查看数据,发现冗余并将这些冗余计入新表,并通过外键和连接关联这些新表,然后构建视图代表原始数据。