数据库设计 Step by Step (3)——基本ER模型构件

阅读原文 转自博客园 知行思新

引言:数据库设计 Step by Step (2)在园子里发表之后,收到了一些邮件,还有朋友直接电话我询问为什么不包含数据库物理设计方面的内容。我在这里解释一下,数据库物理设计与数据库产品是密切相关的,本系列的专注点是较为通用的数据库设计理念与方法,这也是国内软件项目中容易被忽视的一块。今天我们将学习实体关系(ER)模型构件及其语义,这是数据库逻辑设计的基础。内容可能有些枯燥,但却非常重要和有用。

由于内容比较多,我们将分两讲来学习实体关系模型构件。

今天我们先来学习基本实体关系模型。

实体关系(ER)模型的目标是捕获现实世界的数据需求,并以简单、易理解的方式表现出来。ER模型可用于项目组内部交流或用于与用户讨论系统数据需求。

ER模型中的基本元素

基本的ER模型包含三类元素:实体、关系、属性

图1 实体、关系、属性的ER构图

实体(Entities):实体是首要的数据对象,常用于表示一个人、地方、某样事物或某个事件。一个特定的实体被称为实体实例(entity instance或entity occurrence)。实体用长方形框表示,实体的名称标识在框内。一般名称单词的首字母大写。

关系(Relationships):关系表示一个或多个实体之间的联系。关系依赖于实体,一般没有物理概念上的存在。关系最常用来表示实体之间,一对一,一对多,多对多的对应。关系的构图是一个菱形,关系的名称一般为动词。关系的端点联系着角色(role)。一般情况下角色名可以省略,因为实体名和关系名已经能清楚的反应角色的概念,但有些情况下我们需标出角色名来避免歧义。

属性(Attributes):属性为实体提供详细的描述信息。一个特定实体的某个属性被称为属性值。Employee实体的属性可能有:emp-id, emp-name, emp-address, phone-no……。属性一般以椭圆形表示,并与描述的实体连接。属性可被分为两类:标识符(identifiers)描述符(descriptors)。Identifiers可以唯一标识实体的一个实例(key),可以由多个属性组成。ER图中通过在属性名下加上下划线来标识。多值属性(multivalued attributes)用两条线与实体连接,eg:hobbies属性(一个人可能有多个hobby,如reading,movies…)。复合属性(Complex attributes)本身还有其它属性。

辨别强实体与弱实体:强实体内部有唯一的标识符弱实体(weak entities)的标识符来自于一个或多个其它强实体。弱实体用双线长方形框表示,依赖于强实体而存在。

深入理解关系

关系在ER模型中扮演了非常重要的角色。通过ER图可以描述实体间关系的度连通数存在性信息

我们一一来解释这些概念。首先我们来看一下关系在ER图中的各种语义。

图2 关系的度、连通数、存在性

图2 关系的度、连通数、存在性

关系的度(Degree of a Relationship)

表示关系所关联的实体数量。二元关系与三元关系的度分别为2和3,以此可以类推至n元。二元关系是最常见的关系。

一个Employee与另一个Employee之间的领导关系称为二元回归关系。如图2中所示,Employee实体通过关系manages与自身连接。由于Employee在这一关系中扮演两个角色,故标出了角色名(manager和subordinate)。

三元关系联系三个实体。当二元关系无法准确描述关联的语义时,就需要使用三元关系。我们来看下面这个例子,下图(1)能反映出一个Employee在某个Project中使用了什么Skill。下图(2)只能看出Employee有什么Skill,参与了哪些Project,但无法知道在某个Project中使用的特定Skill。

图3 三元关系蕴含的语义

需要注意的是有些情况下会错误的定义三元关系。这些三元关系可分解为2个或3个二元关系,来达到化简与语义的纯净。以后的博文中会进一步详细讨论三元关系。

一个实体可以参与到任意多个关系中。每个关系可以联系任意多个元(实体),而且两个实体之间也能有任意多个二元关系。

3 三元关系蕴含的语义

关系的连通数(Connectivity of a Relationship)

表示关系所关联的实例数量的约束。

连通数的值可以是“一”或“多”。“一”这一端,在ER图中通过在实体与关系间标记“1”表示。“多”一端标记“N”表示。如图2中关系连通数部分,“一”对“一”:Department is managed by Employee;“一”对“多”:Department has Employees;“多”对“多”:Employee may work on many Projects and each Project may have many Employees。

有些情况下最大连通数是确定的,可以用数值代替N。如:田径队队员有12人。

关系的属性

关系也能有属性。如下图4所示,某员工参与某项目的起始日期,某员工在某项目中被分配的任务只有放在关系works-on上才有意义。

图4 关系的属性

需要注意的是关系的属性一般出现在“多”对“多”的二元关系或三元关系上。一般“一”对“一”或“一”对“多”关系上不会放属性(会引起歧义,通俗说法就是没有中间表)。而且这些属性可以移至一端的实体中。如下图5所示,如果部门与员工(经理)之间是“一”对“一”关系,在建模中可能把start-date作为关系is managed by的属性(表示被接管的时间),这个属性可以移至Department或Employee实体中。

大家可以思考一下如果部门和经理之间是“多”对“多”关系,即交叉管理,那又会怎样?

图5 部门与经理之间的一对一管理关系

关系中实体的存在性(Existence of an Entity in a Relationship)

关系中实体的存在性可以是强制的或可选的。当关系中的某一边实体(无论是“一”或“多”端)必须总是存在,则该实体为强制的。反之,该实体为可选的。

在实体与关系之间的连接线上标识“0”来表示可选存在性。含义是最小连通数为0。

强制存在性表示最小连通数为1。在存在性不确定或不可知的情况下,默认最小连通数为1。

在ER图中最大连通数显式地标识在实体旁边。如图6所示,其蕴含的语义为一个Department有且只有一个Employee来当经理,一个Employee可能是一个Department的经理,也可能不是。

图6 关系中实体的存在性

其他概念数据模型标记法

前文中使用的ER构图方法是Peter Chen 1976年提出的。在现代数据库设计领域,还有其他多种ER模型标记法。

我们来看一下另一种使用较多的标记法,“crow’s-foot”(鱼尾纹)标记法,并与前面介绍的标记法进行一个简单对比。

学习每一种标记法没有意义。在你的组织中推广应用一种标记法,使其成为大家共通的“语言”。

图7 Chen式标记法与crow’s-foot标记法对照

主要内容回顾

1. 组成ER模型的基本元素包括:实体、关系、属性

2. 深入理解关系中包含的语义:关系的度、关系的连通数、关系的存在性

3. 了解ER模型的不同标记法,掌握其中一种标记法,并在你的项目中推广使用

实体关系模型参考

1. Entity-relationship model(http://en.wikipedia.org/wiki/Entity-relationship_model

2.  Entity-relationship modelling(http://www.inf.unibz.it/~franconi/teaching/2000/ct481/er-modelling/

下一篇:数据库设计 Step by Step (4)——高级ER模型构件

数据库设计 Step by Step (2)——数据库生命周期

阅读原文  转自博客园  知行思新

引言:数据库设计 Step by Step (1)得到这么多朋友的关注着实出乎了我的意外。这也坚定了我把这一系列的博文写好的决心。近来工作上的事务比较繁重,加之我期望这个系列的文章能尽可能的系统、完整,需要花很多时间整理、思考数据库设计的各种资料,所以文章的更新速度可能会慢一些,也希望大家能够谅解。

系列的第二讲我们将站在高处俯瞰一下数据库的生命周期,了解数据库设计的整体流程

数据库生命周期

大家对软件生命周期较为熟悉,数据库也有其生命周期,如下图所示。

图(1)数据库生命周期

数据库的生命周期主要分为四个阶段:需求分析、逻辑设计、物理设计、实现维护

这个系列的博文将主要关注数据库生命周期中的前两个阶段(需求分析、逻辑设计)。如图中红色框出的部分。

数据库的物理设计,包括索引的选择与优化、数据分区等内容。这些内容也非常丰富,而且可以自成体系,园子里也有很多好文章,故在本系列中不作主要关注。本文最后将给出一些链接供大家参考。

数据库生命周期的四个阶段又能细分为多个小步骤,我们配合图(1)来看看每一小步包含的内容。

阶段1 需求分析

数据库设计与软件设计一样首先需要进行需求分析。

我们需要与数据的创造者和使用者进行访谈。对访谈获得的信息进行整理、分析,并撰写正式的需求文档。

需求文档中需包含:需要处理的数据数据的自然关系数据库实现的硬件环境软件平台等;

阶段2 逻辑设计

使用ERUML建模技术,创建概念数据模型图,展示所有数据以及数据间关系。最终概念数据模型必须被转化为范式化的表

数据库逻辑设计主要步骤包括:

a) 概念数据建模

在需求分析完成后,使用ER图或UML图对数据进行建模。使用ER图或UML图描述需求中的语义,即得到了数据概念模型(Conceptual Data Model),例如:三元关系(ternary relationships)、超类(supertypes)、子类(subtypes)等。

eg:  零售商视角,产品/客户数据库的ER模型简图

图(3)阶段2(a) 概念数据建模

b) 多视图集成

当在大型项目设计或多人参与设计的情况下,会产生数据和关系的多个视图。这些视图必须进行化简与集成,消除模型中的冗余与不一致,最终形成一个全局的模型。多视图集成可以使用ER建模语义中的同义词(synonyms)、聚合(aggregation)、泛化(generalization)等方法。多视图集成在整合多个应用的场景中也非常重要。

eg: 集成零售商ER图与客户ER图
图(4)以客户为关注点绘制的ER图

注:现在市面上有许多辅助建模工具可以绘制ER图。使用Sybase的PowerDesigner绘制与图(4)相同语义的ER图如下:

其标记法与图(4)中略有不同,这将在今后的博文中加以说明。

这里需要指出的是辅助软件的使用不是设计的核心,大家不要被这些工具迷惑。所以后文中我们将主要使用手绘。只要掌握了ER图的语义,使用这些软件都不会是件难事。

集成零售商ER图与客户ER图

图(5) 阶段2(b) 多视图集成

c) 转化概念数据模型为SQL表

根据映射规则,把ER图中的实体与关系转化为SQL表结构。在这一过程中我们将识别冗余的表,并去除这些表。



图(6) 阶段2(c)转化概念数据模型为SQL表

d) 范式化

范式化是数据库逻辑设计中的重要一步。范式化的目标是尽可能去除模型中的冗余信息,从而消除关系模型更新、插入、删除异常(anomalies)。

讲到范式化就会引出函数依赖(Functional Dependency)这一概念。函数依赖(FDs)源自于概念数据模型图,反映了需求分析中的数据关系语义。不同实体之间的函数依赖表示各个实体唯一键之间的依赖。实体内部也有函数依赖,反映了实体中键属性与非键属性之间的依赖。在保证数据完整性约束的前提下,基于函数依赖对候选表进行范式化(分解、降低数据冗余)。

图(7) 阶段2(d)范式化

阶段3 物理设计

数据库物理设计包括选择索引,数据分区与分组等。

逻辑设计方法学通过减少需要分析的数据依赖,简化了大型关系数据库的设计,这也减轻了数据库物理设计阶段的压力。

1. 概念数据建模和多视图集成准确地反映了现实需求场景

2. 范式化在模型转化为SQL表的过程中保留了数据完整性

数据库物理设计的目标是尽可能优化性能。

物理设计阶段,全局表结构可能需要进行重构来满足性能上的需求,这被称为反范式化。

反范式化的步骤包括:

1. 辨别关键性流程,如频繁运行、大容量、高优先级的处理操作

2. 通过增加冗余来提高关键性流程的性能

3. 评估所造成的代价(对查询、修改、存储的影响)和可能损失的数据一致性

阶段4 数据库的实现维护

当设计完成之后,使用数据库管理系统(DBMS)中的数据定义语言(DDL)来创建数据结构。

数据库创建完成后,应用程序或用户可以使用数据操作语言(DML)来使用(查询、修改等)该数据库。

一旦数据库开始运行,就需要对其性能进行监视。当数据库性能无法满足要求或用户提出新的功能需求时,就需要对该数据库进行再设计与修改。这形成了一个循环:监视 –> 再设计 –>  修改 –> 监视…

在进行数据库设计之前,我们先回顾一下关系数据库的相关基本概念。

这里只做一个提纲挈领的简介,大家可以根据相应的线索进行扩展。

表、行、列

关系数据库可以想象成表的集合,每个表包含行与列。(可以想象成一个Excel workbook,包含多个worksheet)。

表在关系代数中被称为关系,这也是关系数据库名称的起源(不要与表之间的外键关系混淆)。

列在关系代数中被称为属性(attribute)。列中允许存放的值的集合称为列的域(域与数据类型密切相关,但并不完全相同)。

行在关系代数中的学名是元组(tuple)。

关系数据库的理论基础来自于“关系代数”。但在关系代数中,一个集合的各个元组没有次序的概念,在关系数据库中为了方便使用,定义了行的次序。

键、索引

键是一种约束,目的是保证数据完整性

索引是数据的物理组织形式,目的是提高查询的性能

约束

基本约束

not null constraint, domain constraint

检查约束(Check Constraints)

eg: Salary > 0

主键约束(Primary Key Constraints)

实体完整性(entity integrity),没有两条记录是完全相同的,组成主键的字段不能为null

唯一性约束(Unique Constraints)

外键约束(Foreign Key Constraints)

也被称为引用完整性约束,eg:

关系数据库操作

1.选择(Selection)

2.映射(Projection)

3.联合(Union)

4.交集(Intersection)

5.差集(Difference)

6.笛卡尔积(Cartesian Product)

7.连接(Join)

上述7种是最基本的关系数据库操作,对应于集合论中的关系运算。

有些书籍中还会加入改名(Rename),除(Divide)等关系操作。


主要内容回顾

1. 数据库生命周期的四个阶段:需求分析、逻辑设计、物理设计、实现维护。

2. 关系数据库的理论基础是关系代数。

数据库物理设计参考资料

第一个链接是我针对查询优化作的读书笔记,后三个链接是SQLServerCentral中几篇关于索引的文章(需要简单注册后才能看到全文)

1. 查询优化系列(查询优化(1)查询优化(2)查询优化(3)查询优化(4)查询优化(5)——总结

2. Part 1 – The basics of indexes

3. Part 2 – The Clustered Index

4. Part 3 – The Non-clustered index

关联阅读

数据库设计 Step by Step (3)——基本ER模型构件

数据库设计 Step by Step (1)——扬帆启航

阅读原文 转自博客园 知行思新

引言:一直在从事数据库开发和设计工作,也看了一些书籍,算是略有心得。很久之前就想针对关系数据库设计进行整理、总结,但因为种种原因迟迟没有动手,主要还是惰性使然。今天也算是痛下决心开始这项卓绝又令我兴奋的工作。这将是一个系列的文章,我将以讲座式的口吻展开讨论(个人偷懒,这里的总结直接拿去公司培训新人用)。

系列的第一讲我们先来回答下面几个问题

数据库是大楼的根基

大多数程序员都很急切,在了解基本需求之后希望很快的进入到编码阶段(可能只有产出代码才能反映工作量),对于数据库设计思考得比较少。

这给系统留下了许多隐患。许多软件系统的问题,如:输出错误的数据,性能差或后期维护繁杂等,都与前期数据库设计有着密切的关系。到了这个时候再想修改数据库设计或进行优化等同于推翻重来。

我经常把软件开发比作汽车制造。汽车制造会经过图纸设计,模型制作,样车制造,小批量试生产,最后是批量生产等步骤。整个过程环环相扣,后一过程是建立在前一过程正确的前提基础之上的。如果在图纸设计阶段发现了一个纰漏,我们可以重新进行图纸设计,如果到了样车制造阶段发现这个错误,那么我们就要把从图纸设计到样车制造的阶段重来,越到后面发现设计上的问题,所付出的代价越大,修改的难度也越大。

数据库是整个应用的根基,没有坚实的根基,整个应用也就岌岌可危了。

强大的数据库面对不良设计也无能为力

现代数据库管理系统(DBMS)提供了方便的图形化界面工具,通过这些工具可以很方便的创建表、定义列,但我们设计出的结构好吗?

关系数据库有许多非常好的特性,但设计不当会使这些特性部分或完全的丧失。

我们来看看以下几个数据库不良设计造成的场景:

1. 数据一致性的丧失

一个订单管理系统,维护着客户和客户下的订单信息。使用该系统的用户在接到客户修改收货地址的电话后,在系统的客户信息页面把该客户的收货地址进行了修改,但原先该客户的订单还是送错了地址。

2. 数据完整性的丧失

公司战略转移,准备撤出某地区。系统操作人员顺手把该地区的配置信息在系统中进行删除,系统提示删除成功。随后问题就来了,客服人员发现该地区的历史订单页面一打开就出错。

3. 性能的丧失

一个库存管理系统,仓库管理员使用该系统记录每一笔进出货情况,并能查看当前各货物的库存情况。在系统运行几个月后,仓库管理员发现打开当前库存页面变得非常慢,而且整个趋势是越来越慢。

上面这些场景都是由于数据库设计不当造成的,根源包括:设计时引入了冗余字段,没有设计合理的约束,对性能没有进行充足设计等,上面的例子也只是沧海一粟。

数据库平台无关性

我在这个系列博客里讨论的数据库设计不针对任何一个关系数据库产品。无论你使用的是Oracle,SQL Server,Sybase,亦或是开源数据库如:MySQL,SQLite等,都可以用来实践我们这里讨论的设计方法和设计理念,设计是这个系列博文的核心和灵魂。

注:在文中我会选用一个数据库产品来进行演示,大家可以选用自己熟悉的数据库产品来实验。本文最后会给出一些免费数据库产品的链接,大家可以下载学习。

一起学习共同进步

无论你是数据库设计师,应用架构师,软件工程师,数据库管理员(DBA),软件项目经理,软件测试工程师等项目组成员,都能从该系列博文中有所收获。大家一起讨论,共同进步。

内容涉及领域

我对这一系列博文现在的设想是涉及数据库设计的整个过程。从需求分析开始,到数据库建模(概念数据建模),进行范式化,直至转化为SQL语句。

在我们一头扎进数据库设计之前,我们先了解一下除了关系型数据库之外的数据存储方式。

平面文件(Flat File)

包括以.txt和.ini结尾的文件。

eg: 一个.ini文件的内容:

————————————————————

[WebSites]

MyBlog=http://www.cnblogs.com/DBFocus

[Directorys]

Image=E:\DBFocus Project\Img

Text=E:\DBFocus Project\Documents

Data=E:\DBFocus Project\DB

————————————————————

优点:

文件的存储形式非常简单,普通的编辑器都能对其进行打开、修改

缺点:

无法支持复杂的查询

没有任何验证功能

对平面文件中间的内容进行插入、删除操作其实是重新生成了一个新文件

适用场景:

存放小量,修改不频繁的数据,如应用配置信息

Windows注册表

错误的修改Windows注册表会引起系统的紊乱,故不建议把很多数据存放在注册表中。

Windows注册表为树形结构,存放着一些系统配置信息和应用配置信息。

通过把不同的配置存放在注册表的不同分支上,使得应用程序公共配置信息与用户个人配置信息分离。

eg:某文档版本管理系统,能通过配置与本主机上安装的文件比较器建立关联进行文档比较。这是一个公共配置信息,文件比较器路径可以存放在注册表的HKEY_LOCAL_MACHINE\SOFTWARE分支下。

同时该文档版本管理系统能记录用户最近打开的10个文档路径。这是用户个人配置信息,对于不同的Windows用户最近打开的10个文档可以不同,这些配置信息可存放在注册表的HKEY_CURRENT_USER\Software分支下。

Excel表单(Spreadsheets)

优点:

Excel 非常普及,用户对于Spreadsheet的表现形式非常熟悉

可以进行简单统计,方便出各种图表

缺点:

不适用于许多Spreadsheet之间关系复杂的情况

无法应对复杂查询

数据验证功能弱

适用场景:

数据量不是非常大的办公自动化环境

XML

XML是一种半结构化的数据。相比于超文本标记语言(HTML),其标签是可以自行定义的,即可扩展的。

eg:一个XML文件内容

—————————————————–

<?xml version=”1.0” encoding=”UTF-8” ?>

<ClassSchedule>

<Class Name=“Psychology” Room=”Field 3”>

<Instructor>Richard Storm</Instructor>

<Students>

<Student>

<FirstName>Ben</FirstName>

<LastName>Breaker</LastName>

</Student>

<Student>

<FirstName>Carol</FirstName>

<LastName>Enflame</LastName>

<NickName>Candy</NickName>

</Student>

</Students>

</Class>

</ClassSchedule>

—————————————————–

XML文件有几个特点。

首先,XML标签要求严格对应,且不能出现交错的现象。

其次,XML文件必须有一个根节点,该节点包含所有其他元素。

第三,同级别的不同节点内不必包含相同的元素,如上例中第二个学生Carol有一个特别的节点NickName。这个特性使得在某些场景中XML比关系数据库更能应对变化。

优点:

自然的层次型结构

文本内容通过标签是自解释的

通过XSD(XML Schema语言)可以验证XML的结构

有许多辅助型技术如:XPath, XQuery, XSL, XSLT等

一些商业数据库(如Oracle,SQL Server)已支持XML数据的存储与操作

缺点:

数据的冗余信息较多

无法支持复杂的查询

验证功能有限

对XML中间的内容进行插入、删除操作其实是重新生成一个新文件

适用场景:

适合存放数据量不大,具有层次型结构的数据,如树形配置信息

NoSQL数据库

非关系型数据库我接触的不是很多,除了给出一些产品名称之外不做很多展开。园子里已有一些文章,本文最后也给出了链接供大家学习、研究。

1. Key-Value数据库

Redis, Tokyo Cabinet, Flare

2. 面向文档的数据库

MongoDB, CouchDB

3. 面向分布式计算的数据库

Cassandra, Voldemort

这几年NoSQL非常热。我认为NoSQL并不是“银弹”,在某些SNS应用场景中NoSQL显示了其优越性,但在如金融行业等对数据的一致性、完整性、可用性、事务性高要求的场景下,现在的NoSQL就未必适用。我们应充分分析应用的需求,非常谨慎地选择技术和产品。

主要内容回顾

1.数据库设计对于软件项目成功的关键作用

2.本课程与数据库产品无关,核心是设计的理念和方法

3.各种数据存储所适用的场景

参考资料

1. Oracle Database 10g Express Edition

2. SQL Server 2008 R2 Express – Overview

3. SQLite Home Page

4. NoSQL数据库笔谈

下一篇:数据库设计 Step by Step (2)——数据库生命周期

关于

我是谁

后端和运维为主程序员,面向业务和问题编程,专业:计算机网络技术

爱好写代码,研究技术,学习科普知识,K歌,宅

我的Github https://github.com/yangliuan 自己的业务总结和学习项目和常用工具

我的简历 https://hacknical.com/yangliuan/resume

做一些总结备忘和笔记

职业规划

编程语言以php+javascript为主,业务方向以服务端开发+运维+网络安全的综合型应用程序员

扎实的基础:

数据结构+算法 网络协议tcp udp http websocket webrtc

面向对象相关知识:

设计模式 SOLID设计原则

需要掌握的技术栈

php: laravel swoole workman 和各种常用库 要具备开发库的能力 系统设计 网络编程能力

javascript: vue vue-element-admin electron 要具备开发后台管理的能力

web服务器

nignx openresty tengine 掌握熟练使用 apache

数据库

mysql 数据库设计 锁机制 查询优化 分库分表和读写分离的实际应用(有具备该功能的云数据库)

elasticsearch 熟练使用 关系型数据库的实体度和实体连通数 如何对应在es中存储和查询

redis memcached 熟练使用 常见需求的应用案例和使用方式

队列和消息中间件

kafka rabbitmq 熟练使用 常见需求的应用案例和使用方式

运维

linux docker kubernetes 生产环境的部署和运维 2台服务器用云镜像 3台以上用容器

掌握基本的压测工具和方法

网络安全

网络安全基础知识 常见WEB漏洞和攻击方式 如何更安全的设计接口 掌握基本的渗透测试工具