MySQL之约束

来源:互联网 发布:php网页代码 编辑:程序博客网 时间:2024/06/09 18:36

通常数据库约束有五类:

1.not null:非空约束,指定某列不为空;

2.unique:唯一性约束,指定某列或者某几列的组合值在数据表中的唯一性(不重复);

3.primary key:主键约束,指定某列数据不重复;

4.foreign key:外键约束,指定某列关联其他表的列;

5.check:检查约束,根据表达式检验数据是否符合规则;

注意:MySQL不支持check约束,使用check约束不报错,但没效果;

约束主要完成对数据的检验,保证数据库数据的完整性;如果有相互依赖数据,保证该数据不被删除;

MySQL的约束保存在information_schema数据库的table_constraints表中,可通过该表查看约束信息。

1.NOT NULL:

CREATE TABLE `user2`(`user_name` VARCHAR(20) NOT NULL,`age` INT(3) NOT NULL,`mental_age` INT(3) NOT NULL,`salary` DECIMAL(5,2) NOT NULL,`birthday` DATE NOT NULL,`address` VARCHAR(200),`remark` VARCHAR(100));-- show CREATE TABLE `user2`;CREATE TABLE `user2` (  `user_name` VARCHAR(20) NOT NULL,  `age` INT(3) NOT NULL,  `mental_age` INT(3) NOT NULL,  `salary` DECIMAL(5,2) NOT NULL,  `birthday` DATE NOT NULL,  `address` VARCHAR(200) DEFAULT NULL,  `remark` VARCHAR(100) DEFAULT NULL) ENGINE=INNODB DEFAULT CHARSET=utf8;

增加NOT NULL约束:

1.在创建表时指定(如上);

2.alter table时增加字段not null属性;

数值型的字段not null,则必须指定默认值;否则添加数据时,否则报错 Error code:1364  Field 'age' doesn't have a default value(字段类型后设置默认值,并不是插入数据NOT NULL就行)

ALTER TABLE `user2` MODIFY `age` INT(3) DEFAULT 0 NOT NULL;ALTER TABLE `user2` MODIFY `mental_age` INT(3) DEFAULT 0 NOT NULL;ALTER TABLE `user2` MODIFY `salary` DECIMAL(5,2) DEFAULT 0 NOT NULL;

所有类型的值都可以为NULL,未设置NOT NULL约束的字段,默认值都是NULL

int、float类型和空字符串都不等于null;

删除NOT NULL约束:

ALTER TABLE `user2` MODIFY age INT(3)

2. UNIQUE

新增唯一性约束(UNIQUE)

CREATE TABLE `user3`(`user_name` VARCHAR(20) UNIQUE,`age` INT(3) UNIQUE,`mental_age` INT(3),`salary` DECIMAL(5,2),`birthday` DATE,`address` VARCHAR(200),`remark` VARCHAR(100)  NOT NULL,CONSTRAINT UNIQUE(remark),CONSTRAINT UNIQUE(age,mental_age),CONSTRAINT UNIQUE(mental_age,salary));-- SHOW CREATE TABLE `user3`;CREATE TABLE `user3` (  `user_name` VARCHAR(20) DEFAULT NULL,  `age` INT(3) DEFAULT NULL,  `mental_age` INT(3) DEFAULT NULL,  `salary` DECIMAL(5,2) DEFAULT NULL,  `birthday` DATE DEFAULT NULL,  `address` VARCHAR(200) DEFAULT NULL,  `remark` VARCHAR(100) NOT NULL,  UNIQUE KEY `remark` (`remark`),  UNIQUE KEY `user_name` (`user_name`),  UNIQUE KEY `age` (`age`),  UNIQUE KEY `age_2` (`age`,`mental_age`),  UNIQUE KEY `mental_age` (`mental_age`,`salary`)) ENGINE=INNODB DEFAULT CHARSET=utf8

唯一性约束的列或者组合的列值不能重复,但可以为多个NULL;

如果不给唯一约束名称,就默认和列同名(组合列和第一个列同名,该列参与多个UNIQUE则会添加_下标区分);

MySQL会给唯一约束的列上默认创建一个唯一索引;

如果列或者组合列的值存在重复,则无法为其添加UNIQUE约束;

ALTER TABLE `user3` ADD UNIQUE(`salary`);-- 只适用于给单列增加UNIQUE
下面的方式可为组合列增加UNIQUE
ALTER TABLE `user3` MODIFY `salary` DECIMAL(5,2) UNIQUE;

删除唯一性约束:

ALTER TABLE `user3` DROP INDEX salary

3. PRIMARY KEY

主键相当于NOT NULL + UNIQUE;一张表只能有一个主键;

CREATE TABLE `user4`(`id` INT PRIMARY KEY,`user_name` VARCHAR(20),`age` INT(3),`birthday` DATE,`address` VARCHAR(200),`remark` VARCHAR(100));-- SHOW CREATE TABLE `user4`;CREATE TABLE `user4` (  `id` INT(11) NOT NULL,  `user_name` VARCHAR(20) DEFAULT NULL,  `age` INT(3) DEFAULT NULL,  `birthday` DATE DEFAULT NULL,  `address` VARCHAR(200) DEFAULT NULL,  `remark` VARCHAR(100) DEFAULT NULL,  PRIMARY KEY (`id`)) ENGINE=INNODB DEFAULT CHARSET=utf8
组合模式:
CREATE TABLE `user5`(`id` INT,`user_name` VARCHAR(20),`age` INT(3),`birthday` DATE,`address` VARCHAR(200),`remark` VARCHAR(100),CONSTRAINT PRIMARY KEY(id,user_name));-- show create table `user5`;CREATE TABLE `user5` (  `id` INT(11) NOT NULL DEFAULT '0',  `user_name` VARCHAR(20) NOT NULL DEFAULT '',  `age` INT(3) DEFAULT NULL,  `birthday` DATE DEFAULT NULL,  `address` VARCHAR(200) DEFAULT NULL,  `remark` VARCHAR(100) DEFAULT NULL,  PRIMARY KEY (`id`,`user_name`)) ENGINE=INNODB DEFAULT CHARSET=utf8

删除主键:

ALTER TABLE `user4` DROP PRIMARY KEY;

增加主键:

也可以在新增时增加主键,见上面SQL;

ALTER TABLE `user4` ADD PRIMARY KEY(user_name);-- 主键并非只能是int类型,ADD 和 PRIMARY KEY之间可以增加CONSTRAINT关键字

组合主键:

见于本文的`class_02`表;

修改列为主键:

alter table `user4` modify `user_name` varchar(20) primary key;

4.FOREIGN KEY

主表:

CREATE TABLE `class_01`(id INT PRIMARY KEY AUTO_INCREMENT,class_name VARCHAR(20));
从表:
CREATE TABLE `student_01`(student_id INT,student_name VARCHAR(20),class_id INT NOT NULL REFERENCES class_01(id));
-- show create table `student_01`;CREATE TABLE `student_01` (  `student_id` INT(11) DEFAULT NULL,  `student_name` VARCHAR(20) DEFAULT NULL,  `class_id` INT(11) NOT NULL) ENGINE=INNODB DEFAULT CHARSET=utf8
由student_01表可见,这种方式并未创建外键;

在表内新建外键:

CREATE TABLE `student_02`(student_id INT,student_name VARCHAR(20),class_id INT,CONSTRAINT FOREIGN KEY(class_id) REFERENCES class_01(id));-- show create table `student_02`;CREATE TABLE `student_02` (  `student_id` INT(11) DEFAULT NULL,  `student_name` VARCHAR(20) DEFAULT NULL,  `class_id` INT(11) DEFAULT NULL,  KEY `class_id` (`class_id`),  CONSTRAINT `student_02_ibfk_1` FOREIGN KEY (`class_id`) REFERENCES `class_01` (`id`)) ENGINE=INNODB DEFAULT CHARSET=utf8

根据`student_02`的外键列可知外键值仍可为空,如果不允许为空,需要自己给`class_id`列增加NOT NULL;

注意:外键约束的参照列,在主表中引用的只能是主键或唯一键约束的列,假定引用的主表列不是唯一的记录, 那么从表引用的数据就不确定记录的位置,则无法创建外键。

在表外新增外键:

ALTER TABLE `student_02` ADD CONSTRAINT FOREIGN KEY(`class_id`) REFERENCES `class_01`(`id`);
增加外键时如果不指定名称,数据库会默认给一个CONSTRAINT名称;

删除外键:

ALTER TABLE `student_02` DROP FOREIGN KEY `student_02_ibfk_1`;

因一张表可有多个外键,删除外键要根据外键名称删除;

多外键:

CREATE TABLE `teacher_01`(teacher_id INT PRIMARY KEY AUTO_INCREMENT,teacher_name VARCHAR(20));CREATE TABLE `student_03`(student_id INT,student_name VARCHAR(20),class_id INT,teacher_id INT,CONSTRAINT `student_03_fk_1` FOREIGN KEY(class_id) REFERENCES class_01(id),CONSTRAINT `student_03_fk_2` FOREIGN KEY(teacher_id) REFERENCES teacher_01(teacher_id));-- show create table `student_03`;CREATE TABLE `student_03` (  `student_id` INT(11) DEFAULT NULL,  `student_name` VARCHAR(20) DEFAULT NULL,  `class_id` INT(11) DEFAULT NULL,  `teacher_id` INT(11) DEFAULT NULL,  KEY `student_03_fk_1` (`class_id`),  KEY `student_03_fk_2` (`teacher_id`),  CONSTRAINT `student_03_fk_1` FOREIGN KEY (`class_id`) REFERENCES `class_01` (`id`),  CONSTRAINT `student_03_fk_2` FOREIGN KEY (`teacher_id`) REFERENCES `teacher_01` (`teacher_id`)) ENGINE=INNODB DEFAULT CHARSET=utf8

多列组合外键:

CREATE TABLE `class_02`(id INT AUTO_INCREMENT,class_name VARCHAR(20),PRIMARY KEY(id,class_name));CREATE TABLE `student_04`(student_id INT,student_name VARCHAR(20),class_id INT,class_name VARCHAR(20));ALTER TABLE `student_04` ADD CONSTRAINT FOREIGN KEY(class_id,class_name) REFERENCES class_02(id,class_name)-- show create table `student_04`;CREATE TABLE `student_04` (  `student_id` INT(11) DEFAULT NULL,  `student_name` VARCHAR(20) DEFAULT NULL,  `class_id` INT(11) DEFAULT NULL,  `class_name` VARCHAR(20) DEFAULT NULL,  KEY `class_id` (`class_id`,`class_name`),  CONSTRAINT `student_04_ibfk_1` FOREIGN KEY (`class_id`, `class_name`) REFERENCES `class_02` (`id`, `class_name`)) ENGINE=INNODB DEFAULT CHARSET=utf8

自关联、自引用

(如菜单目录树、递归表)

CREATE TABLE `sys_menu`(         id INT AUTO_INCREMENT PRIMARY KEY,         menu_name VARCHAR(50),         parent_id INT,         FOREIGN KEY(parent_id) REFERENCES sys_menu(id) );

级联删除:

设置外键后的表,删除主表记录:如果从表有外键值对应主表行记录,则无法删除该主表记录;

删除主表数据时,从表数据也删除,则需要在建立外键的后面增加on delete set null或者on delete cascade;

CREATE TABLE `student_05` (  `student_id` INT(11),  `student_name` VARCHAR(20),  `class_id` INT(11),  CONSTRAINT `student_05_fk_1` FOREIGN KEY (`class_id`) REFERENCES `class_01` (`id`) ON DELETE SET NULL);-- 删除主表数据,从表对应行的外键值设置为NULL
CREATE TABLE `student_06` (  `student_id` INT(11),  `student_name` VARCHAR(20),  `class_id` INT(11),  CONSTRAINT `student_06_fk_1` FOREIGN KEY (`class_id`) REFERENCES `class_01` (`id`) ON DELETE CASCADE);-- 删除主表数据,从表对应行数据也会被删除

5.CHECK约束

CREATE TABLE `student_07`(id INT AUTO_INCREMENT,student_name VARCHAR(20),age INT,PRIMARY KEY(id),CHECK(age > 20));-- show CREATE TABLE `student_07`CREATE TABLE `student_07` (  `id` INT(11) NOT NULL AUTO_INCREMENT,  `student_name` VARCHAR(20) DEFAULT NULL,  `age` INT(11) DEFAULT NULL,  PRIMARY KEY (`id`)) ENGINE=INNODB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8
加check约束,实际语句中并没有check约束,不会对数据行进行check;即MySQL不支持CHECK约束,但无任何作用。


参考:http://blog.csdn.net/kqygww/article/details/8882990#comments

原创粉丝点击