由于现在大多数数据库都是基于关系模型建立起来的数据库,所以理解关系模型是有很大价值的,这次我就结合自己的学习历程谈谈关系模型。
首先要理解关系需要理解集合、序偶、笛卡尔积的概念,这些在《离散数学》中相信都有接触,集合一般来说就是把具有共同性质的一些东西聚在一起就构成了一个整体,这个就可以叫做集合,而域就是一组具有相同数据类型的值得集合,例如说java里的int,float等等……序偶的概念稍微抽象一点,举个简单的例子,初高中时我们经常写的坐标,如果把x,y分别定义成两个集合,那么序偶就可以看成这两个元素的集合<x,y>,但是它与集合是有区别的,集合是没有次序的,但序偶是有确定的顺序的,比如坐标<2,3>,<3,2>就是不同的概念,那再来理解笛卡尔积,加入我们给定一组域D1,D2,D3……Dn,这些域具有共同的域。那么D1,D2,D3……Dn的笛卡尔积为:
D1*D2*D3*……*Dn={(d1,d2,d3……dn)|d1∈Di,i=1,2,3……,n},那么每一个元素(d1,d2,d3……dn)就可以叫做n元组,好了介绍到这你有没有什么感觉呢,对了,那就是数据库中的表:
学号 | 姓名 | 性别 | 年龄 | 所在学院 |
20105111 | 张三 | 男 | 11 | XX |
20105112 | 李四 | 女 | 23 | XX |
…… | …… | …… | …… | …… |
我们看这张表,学号、姓名、性别、年龄、所在学院像不像是一组域?而(20105111,‘张三’,‘男’,‘年龄’,‘XX’)正像是一个5元组,好了,由此我们可以引出关系的概念,D1*D2*D3*……*Dn的一个有限子集叫做所在域D1,D2,D3……Dn的一个关系,例如,
我们使用SELECT 学号,姓名 FROM student语句就得到这么一个表:
学号 | 姓名 |
20105111 | 张三 |
20105112 | 李四 |
…… | …… |
那么这个操作其实就是投影出表student的一个子集,这是其中的一个关系。OK,那我们表示一下这个关系模型,就是:学生(学号,姓名,性别,年龄,所在学院)……
好了,下面说下主码与外码的事,这个很多时候大家是弄不太清楚,其实很简单,我们知道关系是一个集合,大家在高中都学过集合是不能存放相同元素的,比如java中的set接口下HashSet,TreeSet都是无法存放相同的元素的,那么可以判断一定是有一个属性组使得每个元组在这组属性上的取值不同于其他元组,那如果去掉任何一个属性后元组取值不再具有唯一性,那这个属性组就成为候选码,而主码就是我们从多个(如果是这样的话)候选码中选定的一个,比如上表我们就可以选定学号为主码,因为每个学生的学号是唯一的,不可能重复的,而外码的含义比较抽象,举个例子说,如果现在再有一个表,是学生的选课表,
学号 | 所选课程 | 成绩 |
20105111 | 高数 | 60 |
20105112 | 英语 | 70 |
…… | …… | …… |
好,我们看到这个表中也有学号这个域,那对于student来说,学号是主码,而对于选课表则是外码(其实不能这么说,但你可以先这样理解下),而关系模型的完整性约束,它的参照性约束就要求对于一个表A中的外码,它要么为空,要么就必须是表B中主码中的某一个值,不能是一个不存在的值,那我们继续说下完整性约束吧(比较乱),它还有两个约束,一个是实体完整性,一个是用户定义的完整性,实体完整性简单说就是主码上不允许有空值,否则就存在不可标识的实体,比如说如果学号为空,现在有两个姓名,年龄,性别都一样的同学,我们就没办法从表中判断谁是谁了,所以主码不能为空。用户定义的完整性就是用户根据实际情况的不同定义的一些约束条件,那比如说我知道我们班的学号都是从20105111到20105115,那么我在定义表时就可以这样写,学号 int check(学号 >=20105111 AND 学号<= 20105115)……好了,简单介绍到这吧,其中的那些投影,选择,并,交运算等等大家可以自己查下资料学习下,这里就不详细说了,你需要知道的是,一系列的SQL语言其实都是基于这些基本操作的……