首页 > 数据库 >如何定义数据库表之间的关系

如何定义数据库表之间的关系

时间:2023-10-29 16:33:46浏览次数:43  
标签:关系 定义 数据表 数据库 外键 如何 Books FK 主键

特别说明
数据库的正规化是关系型数据库理论的基础。随着数据库的正规化工作的完成,数据库中的各个数据表中的数据关系也就建立起来了。

在设计关系型数据库时,最主要的一部分工作是将数据元素如何分配到各个关系数据表中。一旦完成了对这些数据元素的分类,对于数据的操作将依赖于这些数据表之间的关系,通过这些数据表之间的关系,就可以将这些数据通过某种有意义的方式联系在一起。例如,如果你不知道哪个用户下了订单,那么单独的订单信息是没有任何用处的。但是,你没有必要在同一个数据表中同时存储顾客和订单信息。你可以在两个关系数据表中分别存储顾客信息和订单信息,然后使用两个数据表之间的关系,可以同时查看数据表中每个订单以及其相关的客户信息。如果正规化的数据表是关系型数据库的基础的话,那么这些数据表之间的关系则是建立这些基础的基石。

出发点
下面的数据将要用在本文的例子中,用他们来说明如何定义数据库表之间的关系。通过Boyce-Codd Normal Form(BCNF)对数据进行正规化后,产生了七个关系表:

Books: {Title*, ISBN, Price}
Authors: {FirstName*, LastName*}
ZIPCodes: {ZIPCode*}
Categories: {Category*, Description}
Publishers: {Publisher*}
States: {State*}
Cities: {City*}

现在所需要做的工作就是说明如何在这些表之间建立关系。

关系类型
在家中,你与其他的成员一起存在着许多关系。例如,你和你的母亲是有关系的,你只有一位母亲,但是你母亲可能会有好几个孩子。你和你的兄弟姐妹是有关系的——你可能有很多兄弟和姐妹,同样,他们也有很多兄弟和姐妹。如果你已经结婚了,你和你的配偶都有一个配偶——这是相互的——但是一次只能有一个。在数据表这一级,数据库关系和上面所描述现象中的联系非常相似。有三种不同类型的关系:


  • 一对一:在这种关系中,关系表的每一边都只能存在一个记录。每个数据表中的关键字在对应的关系表中只能存在一个记录或者没有对应的记录。这种关系和一对配偶之间的关系非常相似——要么你已经结婚,你和你的配偶只能有一个配偶,要么你没有结婚没有配偶。大多数的一对一的关系都是某种商业规则约束的结果,而不是按照数据的自然属性来得到的。如果没有这些规则的约束,你通常可以把两个数据表合并进一个数据表,而且不会打破任何规范化的规则。
  • 一对多:主键数据表中只能含有一个记录,而在其关系表中这条记录可以与一个或者多个记录相关,也可以没有记录与之相关。这种关系类似于你和你的父母之间的关系。你只有一位母亲,但是你母亲可以有几个孩子。
  • 多对多:两个数据表里的每条记录都可以和另一个数据表里任意数量的记录(或者没有记录)相关。例如,如果你有多个兄弟姐妹,这对你的兄弟姐妹也是一样(有多个兄弟姐妹),多对多这种关系需要引入第三个数据表,这种数据表称为联系表或者连接表,因为关系型系统不能直接实现这种关系。
    建立关系
    在开始着手考虑建立关系表之间的关系之前,你可能需要对数据非常熟悉。只有在熟悉数据之后,关联会比你刚开始的时候更明显。你的数据库系统依赖于在两个数据表中找到的匹配值来建立关系。如果在数据库系统中发现了一个匹配值,系统将从两个数据表中提取数据并创建一个虚拟的记录。例如,你可能想要查看某个特定的作者所写的全部书籍,在本文中,系统将从“Books”和“Authors”这两个数据表中查找相关的匹配值。需要注意的是,在大多数情况下,查询的结果是动态的,这意味着对这条虚拟记录所做的任何改动都将可能作用到底层的数据表上,这一点是非常重要的。
    进行匹配的值都是主键和外键的值。(关系模型不要求一个关系必须对应的使用一个主键来确定。你可以使用数据表中的任何备选关键字来建立关系,但是使用主键是大家都已经接受的标准。)主键(primary key)唯一的识别表中的每个记录。而外键(foreign key)只是简单的将一个数据表中的主键存放在另外一个数据表中。同样地,对于你来说也不需要做太多的工作——只是简单地将主键加到关系表中,并将其定义为外键。
    唯一需要注意的是,外键字段的数据类型必须和主键的数据类型相同。但是有些系统可以允许这条规则有一个例外,它允许在数字和自动编号(autonumbering)字段(例如在SQL服务器系统中访问Identity和AutoNumber)之间建立关系。此外,外键的值可以是空(Null),尽管强烈建议在没有特别原因的情况下,不要让外键为空。你有可能永远都不会有机会来使用需要这项功能的数据库。
    现在回到我们的示例关系表,并开始输入合适的外键。(请继续在纸上打草稿——在你的数据库系统中创建真正的数据表还为时过早。要知道在纸上纠正错误要容易得多。)要记住,你正在把主键的值添加到关系表里。只要调用实体之间的关系就行了,而其他的就简单了:
  • 书籍和分类是有关系的。
  • 书籍和出版社是有关系的。
  • 书籍和作者是有关系的。
  • 作者和邮政编码(ZIP)是有关系的。
  • 邮政编码和城市是有关系的。
  • 城市和州是有关系的。
    这一步并不是一成不变的,你可能会发现在规范化的过程中加入外键会更容易一些。在把字段移动到一个新的数据表时,你可能要把这个新数据表的主键添加到原来的数据表里,将其作为外键。但是,在你继续规范化剩余数据的时候,外键常常会发生改变。你会发现在所有这些数据表被全部规范化之后,一次添加所有的外键,这样效率会更高。
    操作数据表
    现在让我们一次操作一个数据表,就从Books数据表开始,它在这个时候只有三个字段。很明显,Authors、Categories和Publishers数据表的主键会被添加到Books里。当你完成的时候,Books数据表就有了七个字段:
    Books
    Title (PK)
    ISBN (PK)
    Price
    FirstNameFK (FK) Authors.FirstName many-to-many
    LastNameFK (FK) Authors.LastName many-to-many
    CategoryFK (FK) Categories.Category many-to-many
    PublisherFK (FK) Publishers.Publisher one-to-many
    要记住,Authors数据表里的主键是一个基于姓和名两个字段的复合关键字。所以你必须要把这个两个字段都添加到Books数据表里。要注意,外键字段名的结尾包含有FK这个后缀。加入这个后缀有助于提高可读性和自我归档。通过名称这种方式来区别外键会使得追踪它们更简单。如果主键和外键的名称不同,这没有关系。
    这里出现了三种关系:Books和Authors、Books和Categories,以及Books和Publishers。这三种关系中所存在的两种问题可能没有那么明显:
  • Books和Authors之间的关系:一本书可以有多个作者。
  • Books和Categories之间的关系:一本书可以被归入多个类。
    这两者的关系是多对多的关系。先前我告诉过你,数据表不能直接实现这样的关系,而需要第三个联系表来实现。(Books和Publishers的关系是一对多的关系,就像现在所说的,这样是没有问题的。)
    这两个新发现的多对多关系将需要一个联系表来包含来自每个数据表的主键,并将其作为外键。新的联系表是:
    BooksAuthorsmmlink
    TitleFK (FK) Books.Title one-to-many
    ISBNFK (FK) Books.ISBN one-to-many
    FirstNameFK (FK) Authors.FirstName one-to-many
    LastNameFK (FK) Authors.LastName one-to-many
    BooksCategoriesmmlink
    TitleFK (FK) Books.Title one-to-many
    ISBNFK (FK) Books.ISBN one-to-many
    CategoryFK (FK) Categories.Category one-to-many
    没有必要更改Categories、Authors或者Publishers数据表。但是,你必须把FirstNameFK、LastNameFK和CategoryFK这三个外键从Books里移走:
    Books
    Title (PK)
    ISBN (PK)
    Price
    PublisherFK (FK) Publishers.Publisher one-to-many
    现在,让我们转到Authors数据表上来,它现在有两个字段。每个作者都和ZIPCodes数据表中的邮政编码的值相关。但是,每个邮政编码会和多个作者相关。要实现这种一对多的关系,就要把ZIPCodes数据表中的主键添加进Authors数据表作为外键:
    Authors
    FirstName (PK)
    LastName (PK)
    ZIPCodeFK (FK) ZIPCodes.ZIPCode one-to-many
    至此,你已经准备好了处理剩下的地址部分了。看到它们被分在不同的数据表里是很让人奇怪的,但是这是遵照BCNF正确规范化数据的结果。每个邮政编码的值只会有一个对应的城市值和州值。每个城市和州的值只会被输入进其对应的数据表里一次。ZIPCodes和Cities数据表需要外键字段来实现这些关系:
    ZIPCodes
    ZIPCode (PK)
    CityFK (FK) Cities.City one-to-many
    Cities
    City (PK)
    StateFK (FK) States.State one-to-many
    States
    State (PK)
    从一个到九个
    最后,你有了九个数据表:Books、Authors、Categories、Publishers、ZIPCodes、Cities、States、BooksAuthorsmmlink和BooksCategoriesmmlink。图A是这个示例数据表的数据库最终的图形形式。很难想像一个简单的数据表会被分成九个数据表。

    图A

    最初的一个数据表现在需要九个数据表了

由于这个示例数据库很简单,你可能会问这些关系有什么作用。看起来仍在保存冗余的数据,只不过形式不同罢了——通过外键来实现。这是因为我们的数据表现在只有很少几个字段。试想一下有十几个字段的数据表,会是什么样的一个情形。需要承认的是,你仍然需要把数据表的主键作为外键保存进关系表里,但是至多可能最多增加一到两个字段。比较一下为这个数据表里的每一条记录都添加十几个条目的情形吧。

标签:关系,定义,数据表,数据库,外键,如何,Books,FK,主键
From: https://blog.51cto.com/u_14682436/8080620

相关文章

  • SAP UI5 官网上提供的例子,如何下载到本地运行试读版
    上个月的时候,有个朋友问了我这个问题,SAPUI5官网上的例子,如何下载到本地运行呢?本文就来介绍详细步骤。我们打开SAPUI5官方帮助文档,点击Samples:然后从左边随便选一个Samples,比如Breadcrumbs:然后在屏幕右侧看到的区域,就是这个例子渲染出来的动态效果:点击Download......
  • javaweb--数据库连接池
    数据库连接池是一个容器,负责分配、管理数据库连接(Connection)它允许应用程序重复使用一个现有的数据库连接,而不是重新建立一个;释放空闲时间超过最大空闲时间的数据库连接来避免因为没有释放数据库连接而引起的数据库连接遗漏好处:资源重用提升系统响应速度避免数据库连接遗漏......
  • 转岗项目经理后,我是如何分析需求的
    项目经理有一项工作就是需求分析,需求的本质是根据认知进行假设,然后给出判断。如果需求分析的结果出了问题,那么产品也必然会失败。本文针对如何进行需求分析展开分析,希望能对你有所启发。一、什么是需求为什么要明确需求的定义,因为需求很容易被误解。在这里我们要区分下用户需求和产......
  • 转岗项目经理后,我是如何做竞品分析的
    竞品分析无论作为产品经理、运营岗位还是UE交互体验设计师,都是其必备技能和工作范畴之一。但是如何通过竞品分析提炼出有效信息,为业务或是设计决策提供有力的数据支撑,仍然值得我们进行更多的思考。在本文中 我整理了竞品分析的全过程,希望能帮到你。一、明确概念竞品分析是指对:现有......
  • 如何使用scp从远程复制文件夹到本地?
    内容来自DOChttps://q.houxu6.top/?s=HowdoIcopyafolderfromremotetolocalusingscp?如何使用scp从远程复制文件夹到本地主机?我使用ssh登录到我的服务器。然后,我想要将远程文件夹foo复制到本地/home/user/Desktop。我该如何实现这一点?[email protected]......
  • 系统架构案例分析( 数据库类型填空题)
    21年某医药销售企业因业务发展,需要建立线上药品销售系统,为用户提供便捷的互联网药品销售服务、该系统除了常规药品展示、订单、用户交流与反馈功能外,还需要提供当前热销产品排名、评价分类管理等功能。通过对需求的分析,在数据管理上初步决定采用关系数据库(MySQL)和数据库缓存(R......
  • 【Shell】环境变量 自定义变量 特殊变量
    Shell变量:环境变量目标1、理解什么是系统环境变量?2、掌握常用的系统环境变量都有哪些?Shell变量的介绍变量用于存储管理临时的数据,这些数据都是在运行内存中的.变量类型系统环境变量自定义变量特殊符号变量系统环境变量介绍是系统提供的共享变量.是linux系统加载Shell的配置文件中......
  • YouTrack 中如何设置邮件通知
    在YouTrack中,默认是不会邮件通知的。你可以为你的账号设置邮件通知。设置的方法为单击用户属性,然后在弹出的小窗口中选择属性选项。设置邮件通知在通知Tab页面中,选择发送邮件的方式,默认这个选项是不选择的。用户可以为自己选择发送邮件的方式。我们这里选择的是HTML。下面就是......
  • VisionPro如何在ToolBlock的输入输出中新增特定类型的集合
    现在系统类型下方定位到泛型集合(下图的HashSet)然后在代码中进行赋值即可改变泛型的具体类型  ......
  • SharePoint 2019开发:如何通过脚本来变更SharePoint Group的 Permission Level
    Blog链接:https://blog.51cto.com/13969817很多企业出于安全管理需要,ITadmin需要根据SecurityPolicy或者审计要求定期批量的修改SharePoint权限,比如添加或者删除某个用户,或者更换某个Group的Permissionlevel等等,如果单纯的修改一个网站,那么我们可以直接到SiteSettings的Permiss......