要想数据库建模,先得找实体,然后再看实体与实体之间的关系,那么首先该怎样确定实体呢?大家先看个简单的学生表
姓名 | 性别 | 年龄 | 出生日期 | 班级 | 成绩 | 科目 |
张三 | 男 | 20 | 19890312 | 一班 | 80 | 语文 |
李四 | 女 | 19 | 1990011 | 一班 | 90 | 数学 |
王五 | 男 | 22 | 19870514 | 二班 | 65 | 物理 |
杨六 | 男 | 18 | 19910306 | 三班 | 75 | 历史 |
如果对其表格的一行进行修改或删除,是必造成表格结构发生变化,引入范式来规范表格的话,从而可以帮助我们有效的找出以上表格的各个实体,范式一(1NF)规定所有的行都不能重复,上面的表格中,如果在增加一个叫张三的人,显然就不满足1NF了,解决这个问题的关键就是添加主键(primary key),此外1NF还规定每个列只能有一个意思,比如说在班级这个列中,我们理解的 ‘一班’ 和 ‘1班’意思是一样的,但是计算机却认为这两个意思完全是两码事,当我们执行select * from 表名 where 班级=‘一班’的时候,就只会显示字段为‘一班’的所有行;2NF中指出非主键列必须依赖于主键列,大家不妨这样理解,一个学生实体中,应找它相关的固有属性,比如它的性别和年龄,对照以上表格我们就比较清楚了,班级并不是一个学生的固有属性吧,万一他转班呢;3NF规定非主键列之间必须相互独立,也就是说不能从一个列中推算出另一个列,所以上面的学生表中年龄和出生日期就不能同时出现了。到这里相信大家能找出以上表格的实体了,这里还要注意的是强实体和弱实体,两者的区别就是强实体能独立存在。结合以上观点首先找出学生这个实体:
建立一个 学生
学号 | 姓名 | 性别 |
(number) | (varchar2) | (char) |
然后第二个实体是 班级
班级编号 | 班级名称 |
(number) | (varchar2) |
第三个实体 科目
科目编号 | 科目名称 |
(number) | (varchar2) |
以上的实体都是强实体,因为它们能够独立存在的,不依赖于其他实体,下来看看 第四个实体 成绩 (弱实体)
建立成绩表 成绩 考试日期 考试科目
学号,
学号 | 考试科目 | 考试成绩 | 考试时间 |
(number) | (number) | (decimal) | (date) |
它依赖于了考试科目和学生这两个实体,所以它是一个弱实体,这个弱实体中引入了考试科目和学生这两个表中的主键,对于弱实体来说用这两个外键作为了自己的复合主键,为了操作方便,我们大可以用一个自动增长的字段来作为主键,所以将成绩表改为:
AUTOID | 学号 | 考试科目 | 考试成绩 | 考试时间 |
找出了实体,下一步就要找这些实体之间的关系了,在ER建模中关系分为1对1,1对多,多对多的关系,那么怎样确定关系呢?如果表A的主键到表B中作为外键的话,表A和表B的关系就是1对多的关系,站在B的角度向A看过去的话,那就是1对1的关系,因为建模中必须从单个实体出发去关联其他实体,这样才能清晰的理出真正的关系。 在成绩表中,科目表和学生表对成绩表就是1对多的关系,而科目表和学生表通过成绩表关联,而且它们对成绩表都是1M的关系,所以科目表和学生表是多对多的关系,也就是说一个学生可以对应多个科目,一个科目也可对应多个学生,这句话没有歧义的话,那么它就是MN的关系,这和现实中是一样的,在确定关系的时候,我们可以先拿现实作参照。
这里在扩充一点小知识:主键分为代理主键和业务主键,业务主键是指含有业务功能的意义,比如学生ID
2009012010101表示这个学生是2009年01月20号入的学,并且101表示他在101班,01表示他的学号是第一个,这样非常方便明了,大大提高了效率,但是一旦这位同学转班了,那么他的ID也就要发生改变,但是他的ID已经关联到其它表中了,改就起来十分麻烦;代理主键它就不具备任何意义,即使我们的业务改变了,它也不用更改。
外键:表一定要有外键才有联系吗?不是的,外键只是起到往表里添加数据时的正确性而已,所以说在表中定义的foreign key(表X_ID) references (表X_ID);只是往当前表中的表X_ID这个字段添加数据时,会检查表X中有没有这个ID,也就是一个检查约束而已。
作为肖老的小弟子,以上是自己理解的一点基础中的基础,可能有些地方还不太清晰,或者是有错误,忘大家指出来,不是肖老教的不好,是我悟性不够高哈,要批就批我吧。