这几天复习了一下范式,顺便总结了一下,欢迎交流。
主键、外键、实体完整性、部分依赖、传递依赖的定义如下:
1,主键(Primary Key):它是关系数据库表中的某一列或某几列的组合,能够唯一地标识关系数据库表中的任意一行。
2,外键(Forgein Key):是关系型数据库中的某一列(一般为主键)或某几列的组合,它的值或者与另一个表中(有时也可能是同一个表中)的某一列相匹配,或者为空值(NULL)。
3,实体完整性(Entity Integrity):主键不能包含空值(NULL),并且主键必须能够唯一地标识任意一行。
4,部分依赖:是指只依赖于部分主键的依赖关系。
5,传递依赖:是指一个或多个列依赖于非主键的列。
引用完整性的定义如下:
1,外键必须为空值或都有相匹配的项。
2,外键可以没有相对应的列,但不可以有无效的项。
主键和外键一般是由表的设计者来定义的,而实体完整性和引用完整性是由关系型数据库管理系统(如:oracle或mysql)负责维护的。
一,第一范式(1NF):
定义:
1,所有的列(键属性)都已定义:
2,所有的列都依赖于主键。
3,每行和每列的交汇处只能包含一个值。
orderId |
comId |
comName |
comDesc |
comUn |
supId |
supName |
订单号码 |
产品号码 |
产品名称 |
产品描述 |
产品单价 |
厂家号码 |
厂家名称 |
create table ordert
(
orderId int(16) not null auto_increment,
comId int(16) not null,
comName varchar(80) default null,
comDesc varchar(100) default null,
comUn int not null,
supId int not null,
supName varchar(100) default null,
primary key (orderId,comId)
);
mysql> desc ordert;
+---------+--------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+---------+--------------+------+-----+---------+----------------+
| orderId | int(16) | NO | PRI | NULL | auto_increment |
| comId | int(16) | NO | PRI | NULL | |
| comName | varchar(80) | YES | | NULL | |
| comDesc | varchar(100) | YES | | NULL | |
| comUn | int(11) | NO | | NULL | |
| supId | int(11) | NO | | NULL | |
| supName | varchar(100) | YES | | NULL | |
+---------+--------------+------+-----+---------+----------------+
7 rows in set (0.01 sec)
insert into ordert values (101,2560,'显示器','19英寸宽屏',800,1001,'宏基电脑公司');
insert into ordert values (101,2561,'显示器','20英寸宽屏',900,1002,'联想电脑公司');
insert into ordert values (102,2561,'显示器','19英寸宽屏',800,1001,'宏基电脑公司');
insert into ordert values (103,2561,'显示器','19英寸宽屏',800,1001,'宏基电脑公司');
mysql> select * from ordert;
+---------+-------+-----------+----------------+-------+-------+--------------------+
| orderId | comId | comName | comDesc | comUn | supId | supName |
+---------+-------+-----------+----------------+-------+-------+--------------------+
| 101 | 2560 | 显示器 | 19英寸宽屏 | 800 | 1001 | 宏基电脑公司 |
| 101 | 2561 | 显示器 | 20英寸宽屏 | 900 | 1002 | 联想电脑公司 |
| 102 | 2561 | 显示器 | 19英寸宽屏 | 800 | 1001 | 宏基电脑公司 |
| 103 | 2561 | 显示器 | 19英寸宽屏 | 800 | 1001 | 宏基电脑公司 |
+---------+-------+-----------+----------------+-------+-------+--------------------+
4 rows in set (0.00 sec)
分析第一范式后发现,只要知道了某一显示器的商品号码(comId)就能知道该产品的详细信息,也就是说显示器的其他信息只依赖于商品号码(也就是comName、comDesc 、comUn这三项依赖于comId),因为商品号只是主键的一部分,所以这种关系叫做部分依赖。可以把存在部分依赖关系的列拿出来生成一个新的表,而把商品号作为新表的主键,同时把商品号也保留在原表中作为外键,现在把ordert表拆分为ordert表和product表,结构如下所示:
第二范式(2NF):
定义:
1,表为首先满足第一范式(这句话其实是废话了,呵呵)。
2,不包含部分依赖的表为第二范式。
注:如果一个表是第一范式的表,并且它的主键由只有一列(也就是单一属性)组成,那么该表就会自动的成为第二范式的表。
create table ordert
(
orderId int(16) not null auto_increment,
comId int(16) not null,
supId int not null,
supName varchar(100) default null,
primary key (orderId)
);
mysql> desc ordert;
+---------+--------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+---------+--------------+------+-----+---------+----------------+
| orderId | int(16) | NO | PRI | NULL | auto_increment |
| comId | int(16) | NO | | NULL | |
| supId | int(11) | NO | | NULL | |
| supName | varchar(100) | YES | | NULL | |
+---------+--------------+------+-----+---------+----------------+
4 rows in set (0.00 sec)
create table product
(
comId int(16) not null auto_increment,
comName varchar(80) default null,
comDesc varchar(100) default null,
comUn int not null,
primary key (comId)
);
mysql> desc product;
+---------+--------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+---------+--------------+------+-----+---------+----------------+
| comId | int(16) | NO | PRI | NULL | auto_increment |
| comName | varchar(80) | YES | | NULL | |
| comDesc | varchar(100) | YES | | NULL | |
| comUn | int(11) | NO | | NULL | |
+---------+--------------+------+-----+---------+----------------+
4 rows in set (0.00 sec)
第三范式(3NF):
定义:
1, 表为第二范式(2NF)的表。
2,表中不包含传递依赖。
分析第二范式后发现,知道了某一显示器的厂商号码,就能知道该厂商的全部信息,也就是厂商的其他部分只依赖于厂商号码,但是厂商号码不是主键,所以它不属于部分依赖,而是属于传递依赖。
下面的newoder表、ordert表、product表都有主键,并且不包含重复的数据,同时也不包括部分依赖和传递依赖,所以全部符合第三范式。
mysql> desc newoder;
+---------+--------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+---------+--------------+------+-----+---------+-------+
| supId | int(11) | NO | PRI | NULL | |
| supName | varchar(100) | YES | | NULL | |
+---------+--------------+------+-----+---------+-------+
2 rows in set (0.00 sec)
mysql> desc ordert;
+---------+---------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+---------+---------+------+-----+---------+----------------+
| orderId | int(16) | NO | PRI | NULL | auto_increment |
| comId | int(16) | NO | | NULL | |
| supId | int(11) | NO | | NULL | |
+---------+---------+------+-----+---------+----------------+
3 rows in set (0.00 sec)
mysql> desc product;
+---------+--------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+---------+--------------+------+-----+---------+----------------+
| comId | int(16) | NO | PRI | NULL | auto_increment |
| comName | varchar(80) | YES | | NULL | |
| comDesc | varchar(100) | YES | | NULL | |
| comUn | int(11) | NO | | NULL | |
+---------+--------------+------+-----+---------+----------------+
4 rows in set (0.01 sec)