Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/database/8.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Database 如何规范化数据库中的数据?_Database - Fatal编程技术网

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

Database 如何规范化数据库中的数据?,database,Database,我正在学习一门数据库管理入门课程,我们正在学习数据规范化(1NF、2NF、3NF等),我对如何实际操作感到非常困惑。我读过这篇文章,查阅过各种网站和youtube视频,但我似乎仍然无法点击它。如果有帮助的话,我正在使用Microsoft Access 2013 这是我正在处理的数据 谢谢 Edit1:好的,我想我已经把桌子摆好了。但现在我在输入数据从一个表到下一个表时遇到了麻烦。这是我的关系表 在非常基本的层面上,表中的任何重复值都是标准化的候选值。复制数据通常是个坏主意。假设您需要更新患者的

我正在学习一门数据库管理入门课程,我们正在学习数据规范化(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说“但我的正确名字是Fred
G
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中查看关系。很抱歉有这么多评论,但是主表是预约表还是患者表?我想应该是病人,因为你把所有的信息都放在那里?