Database 如何规范化数据库中的数据?
我正在学习一门数据库管理入门课程,我们正在学习数据规范化(1NF、2NF、3NF等),我对如何实际操作感到非常困惑。我读过这篇文章,查阅过各种网站和youtube视频,但我似乎仍然无法点击它。如果有帮助的话,我正在使用Microsoft Access 2013 这是我正在处理的数据 谢谢 Edit1:好的,我想我已经把桌子摆好了。但现在我在输入数据从一个表到下一个表时遇到了麻烦。这是我的关系表Database 如何规范化数据库中的数据?,database,Database,我正在学习一门数据库管理入门课程,我们正在学习数据规范化(1NF、2NF、3NF等),我对如何实际操作感到非常困惑。我读过这篇文章,查阅过各种网站和youtube视频,但我似乎仍然无法点击它。如果有帮助的话,我正在使用Microsoft Access 2013 这是我正在处理的数据 谢谢 Edit1:好的,我想我已经把桌子摆好了。但现在我在输入数据从一个表到下一个表时遇到了麻烦。这是我的关系表 在非常基本的层面上,表中的任何重复值都是标准化的候选值。复制数据通常是个坏主意。假设您需要更新患者的
在非常基本的层面上,表中的任何重复值都是标准化的候选值。复制数据通常是个坏主意。假设您需要更新患者的姓氏-您现在必须更新此表中的所有事件,以及数据库其余部分中的许多其他事件。最好只在一个地方存储每个患者的详细信息 这就是正常化的意义所在。向下看这些列,您可以看到关于牙医、患者和手术的数据存在重复值,因此我们应该规范化,为这些实体中的每一个实体创建表,以及包含预约的原始表,总共为您提供四个表 将实体提取到它们自己的表中,并为每一行提供一个主键(唯一键)——现在只需使用递增整数即可。(编辑:根据评论中的建议,我们可以使用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
第一步是建立数据模型,反规范化是理解数据。研究它,了解模型中存在的领域“对象”或表。这将给你一个如何开始的想法。有时,单个表或查询示例不足以完全理解数据库,但在您的情况下,我们可以使用示例数据并做出一些假设 其次,寻找重复/冗余数据。如果您看到名称的副本,则很有可能是外键的候选。我们的假设告诉我们,STAFF_NO是牙医的主要关键候选人,因为每个唯一的STAFF_NO都与唯一的牙医名称相关,所以我看到了一个好的候选牙医表(STAFF_NO,牙医名称) 手术表中的示例:
ID STAFF_NO DENTIST_NAME
1 1 Fred Sanford
2 1 Fred Sanford
3 3 Lamont Sanford
4 3 Lamont Sanford
为什么要一遍又一遍地储存这些?当Fred说“但我的正确名字是FredG
Sanford”时会发生什么,所以你必须更新你的数据库。在当前表中,必须更新多行的名称。如果您对其进行了规范化,那么名称将在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
手术台现在指向牙医台
ID STAFF_NO
1 1
2 1
3 3
4 3
现在,您可以创建一个视图,视图以重新加入牙医名称,以满足典型查询的需要
select s.id, d.staff_no, d.dentist_name
from surgery s join dentist d
on s.staff_no = d.staff_no -- join here
所以现在对牙医的唯一更新,由牙医主键将更新一行
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
简而言之,您正在删除冗余
这只是一个示例,也是一种方法。当您有建模工具时,这样的手动规范化并不常见,但关键是,我们可以查看数据,发现冗余并将这些冗余分解到新表中,并通过外键和联接关联这些新表,然后构建视图来表示原始数据。您能否更具体地解释一下规范化的哪些方面没有单击?例如,我可以解释,在您发布的示例中,如何存在依赖于其他列的列,而这些列不属于该表。但这就是你要问的吗?看看这个。。。这里有一个关于规范化的很好的描述:可能是重复的,保罗,对不起。我现在搞不懂的是如何把桌子分成不同的桌子,比如病人、牙医和预约。好吧,酷,这是有道理的。我没想到要为手术做一张单独的桌子。但是,你实际上是在哪里制作的,这样他们就可以互相参照了?因为我必须使用staffNo和patientNo,这如何代替基本的1,2,3?我需要使用S1011、P100等。这有意义吗?是的,如果您愿意,您可以使用员工和患者号码作为主键,并使用这些号码建立关系。这是一个很好的例子。然而,在现实世界中,我们倾向于使用a,正如我上面所做的那样。请阅读这些文章,了解每一篇文章的优点和缺点。非常感谢您的帮助!我如何将它们真正地联系起来?我知道我必须在Access中查看关系。很抱歉有这么多评论,但是主表是预约表还是患者表?我想应该是病人,因为你把所有的信息都放在那里?