sql中的主键和外键
主键(primary key): 作为数据库当中的一种约束(constraint),主键的值用于唯一标示表(table)中的某项记录。因此,主键的列中既不能含有重复的值,也不能含有空值。主键可以由表中的一列或者多列定义。
另外,一张表中最多只能有一个主键(建议为每张表定义一个主键)。
在mysql中定义与撤销主键方式如下:
- 在创建数据库时定义
-
表中一列作为主键
1 CREATE TABLE IF NOT EXISTS `meeting` ( 2 `id` int(11) NOT NULL AUTO_INCREMENT, 3 `description` char(255) NOT NULL DEFAULT '', 4 `beginning` datetime NOT NULL DEFAULT '0000-00-00 00:00:00', 5 `duration` int(11) NOT NULL DEFAULT '0', 6 PRIMARY KEY (`id`) 7 ) ENGINE=InnoDB DEFAULT CHARSET=utf-8
- 可为主键约束命名,为之后可能出现的修改提供方便。以多列定义的主键为例:
1 CREATE TABLE IF NOT EXISTS `meeting` ( 2 `id` int(11) NOT NULL AUTO_INCREMENT, 3 `description` char(255) NOT NULL DEFAULT '', 4 `beginning` datetime NOT NULL DEFAULT '0000-00-00 00:00:00', 5 `duration` int(11) NOT NULL DEFAULT '0', 6 CONSTRAINT uc_meeting PRIMARY KEY (id,description) 7 ) ENGINE=InnoDB DEFAULT CHARSET=utf-8
-
- 在表创建之后,利用alter table定义
ALTER TABLE meeting ADD CONSTRAINT pk_meeting PRIMARY KEY (id)
注意:如果使用alter table定义主键,必须确保在创建表的时候,主键列被声明为不包含空值(NOT NULL)。
- 撤销主键
ALTER TABLE meeting DROP PRIMARY KEY
外键(foreign key):一张表中的外键指向另一张表中的主键。外键用于建立两个表之间的联系,若表A的外键指向表B的主键,则表B被称为主表,表A为表B的从表。
在表meeting的基础上,再创建另一张表category_meeting通过id_meeting作为外键指向id_meeting的主键id从而建立两表间关系。
- 在创建表时定义
CREATE TABLE IF NOT EXISTS `categoriy_meeting` ( `id` int(11) NOT NULL AUTO_INCREMENT, `id_meeting` int(11) NOT NULL, `id_category` int(11) NOT NULL, PRIMARY KEY (`id`), UNIQUE KEY `category_meeting` (`id_meeting`,`id_category`), KEY `id_meeting` (`id_meeting`), KEY `id_category` (`id_category`) FOREIGN KEY (`id_meeting`) REFERENCE `meeting`(`id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf-8
- 在表创建之后定义
ALTER TABLE `category_meeting` ADD FOREIGN KEY (`id_meeting`) REFERENCES `meeting`(`id`)
同样可以为其命名
ALTER TABLE `category_meeting` ADD CONSTRAINT `fk_cat` FOREIGN KEY (`id_meeting`) REFERENCES `meeting`(`id`)
- 撤销外键
ALTER TABLE `category_meeting` DROP FOREIGN KEY fk_cat
外键应用:关系表的级联删除实现
通过外键建立表间关系后,若要删除主表中某条记录,则必须先删除从表中外键指向该记录主键的记录,否则系统会报错。
然而,如果在定义外键时加上 ON DELETE CASCADE,如:
ALTER TABLE `category_meeting`
ADD CONSTRAINT `fk_cat`
FOREIGN KEY (`id_meeting`)
REFERENCES `meeting`(`id`)
ON DELETE CASCADE
那么就可以在保留从表相关记录的情况下删除主表中的记录。
更重要的是,我们可以通过如下的sql语句实现级联删除:
DELETE * FROM meeting CASCADE
这样 category_meeting 中对应的记录也会同时删除。