【数据库】约束(主键、唯一键、外键、非空、默认值、自增约束)

约束


DDL 数据定义语言

DDL

1、查看某个表的约束

SELECT * FROM information_schema.table_constraints WHERE table_name = '表名称';
或
SHOW CREATE TABLE 表名;

从information_schema架构下的系统表查看

mysql> SELECT * FROM information_schema.table_constraints WHERE table_name = 'jobs';
+--------------------+-------------------+-----------------+--------------+------------+-----------------+
| CONSTRAINT_CATALOG | CONSTRAINT_SCHEMA | CONSTRAINT_NAME | TABLE_SCHEMA | TABLE_NAME | CONSTRAINT_TYPE |
+--------------------+-------------------+-----------------+--------------+------------+-----------------+
| def                | myemployees       | PRIMARY         | myemployees  | jobs       | PRIMARY KEY     |
+--------------------+-------------------+-----------------+--------------+------------+-----------------+
1 row in set (0.00 sec)

mysql> SHOW CREATE TABLE jobs;
+-------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| Table | Create Table                                                                                                                                                                                                                           |
+-------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| jobs  | CREATE TABLE `jobs` (
  `job_id` varchar(10) NOT NULL,
  `job_title` varchar(35) DEFAULT NULL,
  `min_salary` int(6) DEFAULT NULL,
  `max_salary` int(6) DEFAULT NULL,
  PRIMARY KEY (`job_id`)
) ENGINE=InnoDB DEFAULT CHARSET=gb2312 |
+-------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
1 row in set (0.00 sec)

mysql>

2、查看某个表的索引

SHOW INDEX FROM 表名称;
mysql> SHOW INDEX FROM jobs;
+-------+------------+----------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+
| Table | Non_unique | Key_name | Seq_in_index | Column_name | Collation | Cardinality | Sub_part | Packed | Null | Index_type | Comment | Index_comment |
+-------+------------+----------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+
| jobs  |          0 | PRIMARY  |            1 | job_id      | A         |          19 |     NULL | NULL   |      | BTREE      |         |               |
+-------+------------+----------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+
1 row in set (0.00 sec)

3、主键约束:primary key

主键分为单列主键和复合主键:

eg: 学生表 PK 学号 包含主键的学生表

成绩表 PK 学号 课程编号 包含两个字段组合主键的成绩表

主键约束:primary key

主键的特点:
(1)一个表有且只能有一个主键约束
(2)主键约束意味着,唯一并且非空
(3)主键约束名PRIMARY primary
(4)创建主键会自动创建对应的索引,同样删除主键对应的索引也会删除

(1)如何在建表时指定主键约束

create table 【数据名.】表名(
	字段名1 数据类型  primary key ,
	....
);
或
create table 【数据名.】表名(
	字段名1 数据类型,
	....,
    primary key(字段名1)
);
或
create table 【数据名.】表名(
    字段名1 数据类型,
    字段名2 数据类型,
	....,
    primary key(复合主键字段列表)#如果是复合主键,那么就需要在所有字段列表后面使用这种形式指定,不能在字段后面直接加primary key
);
mysql> use test;
Database changed
mysql> show tables;
Empty set (0.00 sec)

mysql> create table test.t_stu(
    ->  sid int primary key,
    ->  sname varchar(20),
    ->  gender char
    -> );
Query OK, 0 rows affected (0.03 sec)

mysql> desc t_stu;
+--------+-------------+------+-----+---------+-------+
| Field  | Type        | Null | Key | Default | Extra |
+--------+-------------+------+-----+---------+-------+
| sid    | int(11)     | NO   | PRI | NULL    |       |
| sname  | varchar(20) | YES  |     | NULL    |       |
| gender | char(1)     | YES  |     | NULL    |       |
+--------+-------------+------+-----+---------+-------+
3 rows in set (0.00 sec)

mysql>
mysql> desc t_stu;
+--------+-------------+------+-----+---------+-------+
| Field  | Type        | Null | Key | Default | Extra |
+--------+-------------+------+-----+---------+-------+
| sid    | int(11)     | NO   | PRI | NULL    |       |
| sname  | varchar(20) | YES  |     | NULL    |       |
| gender | char(1)     | YES  |     | NULL    |       |
+--------+-------------+------+-----+---------+-------+
3 rows in set (0.00 sec)

mysql> insert into t_stu values(1,'张三','男'),(1,'徐有容','女');
ERROR 1062 (23000): Duplicate entry '1' for key 'PRIMARY'
mysql> insert into t_stu values(1,'张三','男'),(2,'徐有容','女');
Query OK, 2 rows affected (0.00 sec)
Records: 2  Duplicates: 0  Warnings: 0

mysql>

sid相同 违反了主键约束

insert into t_stu values(1,'张三','男'),(1,'李四','女');#错误的

mysql> insert into t_stu values(1,'张三','男'),(1,'李四','女');
ERROR 1062 (23000): Duplicate entry '1' for key 'PRIMARY'  违反了主键约束

insert into t_stu values(1,'张三','男'),(2,'李四','女');

(2)如何在建表后指定主键约束

alter table 表名称 add primary key (主键字段列表);
建表后如何指定主键约束
alter table 【数据库名.】表名称 add primary key(字段列表);

create table test.t_stu(
	sid int,
	sname varchar(20),
	gender char
);
alter table test.t_stu add primary key(sid);

(3)如何删除主键约束

alter table 表名称 drop primary key;

(4)主键约束分为两种:

(1)单列主键约束
(2)复合主键约束
建表时如何指定复合主键约束:

create table 【数据库名.】表名称(
	字段名1 数据类型,
	字段名2 数据类型,
	。。。。,
	primary key(字段列表)
);
建表后如何指定复合主键约束:
alter table 【数据库名.】表名称 add primary key(字段列表);

create table t_course(
	cid int primary key,
	cname varchar(20)
);

#现在要求sid和cid的组合是主键,是唯一的
create table xuanke(
	sid int,
	cid int,
	score int,
	primary key(sid,cid)
);

4、唯一键约束:unique key

(1)唯一键约束特点

同一个表可以有多个唯一约束。

唯一约束可以是某一个列的值唯一,也可以多个列组合值的唯一。

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

删除唯一键只能通过删除对应索引的方式删除,删除时需要指定唯一键索引名

(2)如何在建表时指定唯一键约束

create table 【数据名.】表名(
	字段名1 数据类型  primary key ,
	字段名2 数据类型 unique key,
	....
);

create table 【数据名.】表名(
    字段名1 数据类型  primary key ,
    字段名2 数据类型,
    字段名3 数据类型,
	....,
    unique key(复合唯一字段列表)#如果是复合唯一键,那么就需要在所有字段列表后面使用这种形式指定,不能在字段后面直接加unique key
);
create table books(
	bid int primary key,
	bname varchar(20) unique key,
	price double
);

insert into books values
(1,'《从入门到放弃》',100),
(2,'《从入门到放弃》',88);
ERROR 1062 (23000): Duplicate entry '《从入门到放弃》' for key 'bname' 

insert into books values
(1,'《从入门到放弃》',100),
(2,'《从入门到成功》',88);

(3)如何在建表后增加唯一键约束

alter table 表名称 add 【constraint 约束名】 unique 【key】 (字段名列表);
#如果没有指定约束名,(字段名列表)中只有一个字段的,默认是该字段名,如果是多个字段的默认是字段名列表的第1个字段名。也可以通过show index from 表名;来查看
create table books(
	bid int primary key,
	bname varchar(20) ,
	price double
);
alter table books add unique key(bname);

(4)如何删除唯一键约束

ALTER TABLE 表名称 DROP INDEX 唯一性约束名;
#注意:如果忘记名称,可以通过“show index from 表名称;”查看
5、删除唯一键约束
alter table 【数据库名.】表名称 drop index 索引名;

alter table books drop index bname;

6、如何查看某个表格的索引名
show index from 【数据库名.】表名称;

show index from books;

5、外键约束:foreign key

(1)外键特点

  • 外键约束是保证一个或两个表之间的参照完整性,外键是构建于一个表的两个字段或是两个表的两个字段之间的参照关系。
  • 在创建外键约束时,如果不给外键约束名称,默认名不是列名,而是自动产生一个外键名(例如 student_ibfk_1;),也可以指定外键约束名。
  • 当创建外键约束时,系统默认会在所在的列上建立对应的普通索引。但是索引名是列名,不是外键的约束名。
  • 删除外键时,关于外键列上的普通索引需要单独删除。

建表时,先建主表,再建从表。
删表时,先删从表,再删主表。

从表、子表:参考别人的,依赖别人的
主表、父表:被参考的,被依赖的

举例:
(1)部门表和员工表
员工表中有一个字段,表示该员工所在的部门
部门表是主表
员工表是从表,说员工选择进入哪个部门
这样的话,外键建立在员工表
部门表中表示部门编号,用did表示,int类型
员工表中表示该员工所在的部门,我用编号表示,可以使用did,也可以使用deptid int类型

(2)学生表,课程表,选课表
主表:学生表和课程表
从表:选课表,这个表有两个外键,一个参考学生表,一个参考课程表

(2)要求

  • 在从表上建立外键,而且主表要先存在。

  • 一个表可以建立多个外键约束

  • 从表的外键列,在主表中引用的只能是键列(主键,唯一键,外键),推荐引用主表的主键。

  • 从表的外键列与主表被参照的列名字可以不相同,但是数据类型必须一样

(3)约束关系:约束是针对双方的

添加了外键约束后,主表的修改和删除受约束

添加了外键约束后,从表的添加和修改受约束

(4)5个约束等级

  • Cascade方式:在父表上update/delete记录时,同步update/delete掉子表的匹配记录

  • Set null方式:在父表上update/delete记录时,将子表上匹配记录的列设为null,但是要注意子表的外键列不能为not null

  • No action方式:如果子表中有匹配的记录,则不允许对父表对应候选键进行update/delete操作

  • Restrict方式:同no action, 都是立即检查外键约束

  • Set default方式(在可视化工具SQLyog中可能显示空白):父表有变更时,子表将外键列设置成一个默认的值,但Innodb不能识别

如果没有指定等级,就相当于Restrict方式

(5)如何在建表时指定外键约束

create table 【数据名.】从表名(
	字段名1 数据类型  primary key ,
	字段名2 数据类型 【unique key】,
	....,
    【constraint 外键约束名】 foreign key (从表字段) references 主表名(主表字段) 【on update 外键约束等级】【on delete 外键约束等级【
    #外键只能在所有字段列表后面单独指定
    #如果要自己命名外键约束名,建议 主表名_从表名_关联字段名_fk
);

create table 【数据名.】表名(
    字段名1 数据类型,
    字段名2 数据类型,
	....,
    primary key(复合主键字段列表),#如果是复合主键,那么就需要在所有字段列表后面使用这种形式指定,不能在字段后面直接加primary key
    unique key(复合唯一字段列表),#如果是复合唯一键,那么就需要在所有字段列表后面使用这种形式指定,不能在字段后面直接加unique key
    foreign key (从表字段) references 主表名(主表字段) 【on update 外键约束等级】【on delete 外键约束等级【
    #外键只能在所有字段列表后面单独指定
);

(6)如何在建表后指定外键约束

alter table表名称 add 【constraint 外键约束名】 foreign key (从表字段名) references 主表名(主表被参照字段名) 【on update xx】[on delete xx];

(7)如何删除外键约束

ALTER TABLE 表名称 DROP FOREIGN KEY 外键约束名;
#查看约束名 SELECT * FROM information_schema.table_constraints WHERE table_name = '表名称';
#删除外键约束不会删除对应的索引,如果需要删除索引,需要用ALTER TABLE 表名称 DROP INDEX 索引名;
#查看索引名 show index from 表名称;

6、非空约束:not null

NOT NULL 非空约束,规定某个字段不能为空

(1)如何在建表时给某个字段指定非空约束

create table 【数据名.】表名(
	字段名1 数据类型  primary key ,
	字段名2 数据类型 【unique key】 【not null】,
	....,
    foreign key (从表字段) references 主表名(主表字段) 【on update 外键约束等级】【on delete 外键约束等级【
    #外键只能在所有字段列表后面单独指定
);

create table 【数据名.】表名(
    字段名1 数据类型 【not null】,
    字段名2 数据类型 【not null】,
	....,
    primary key(复合主键字段列表),#如果是复合主键,那么就需要在所有字段列表后面使用这种形式指定,不能在字段后面直接加primary key
    unique key(复合唯一字段列表),#如果是复合唯一键,那么就需要在所有字段列表后面使用这种形式指定,不能在字段后面直接加unique key
    foreign key (从表字段) references 主表名(主表字段) 【on update 外键约束等级】【on delete 外键约束等级【
    #外键只能在所有字段列表后面单独指定
);

(2)如何在建表后指定某个字段非空

ALTER TABLE 表名称 MODIFY 字段名 数据类型 NOT NULL 【default 默认值】;
#如果该字段原来设置了默认值约束,要跟着一起再写一遍,否则默认值约束会丢失

(3)如何在建表后取消某个字段非空

ALTER TABLE 表名称 MODIFY 字段名 数据类型 【default 默认值】;
#如果该字段原来设置了默认值约束,要跟着一起再写一遍,否则默认值约束会丢失

7、默认值约束:default

(1)如何在建表时给某个字段指定默认约束

create table 【数据名.】表名(
	字段名1 数据类型  primary key ,
	字段名2 数据类型 【unique key】 【not null】 【default 默认值】,
	....,
    foreign key (从表字段) references 主表名(主表字段) 【on update 外键约束等级】【on delete 外键约束等级【
    #外键只能在所有字段列表后面单独指定
);

create table 【数据名.】表名(
    字段名1 数据类型 【not null】 【default 默认值】,
    字段名2 数据类型 【not null】 【default 默认值】,
	....,
    primary key(复合主键字段列表),#如果是复合主键,那么就需要在所有字段列表后面使用这种形式指定,不能在字段后面直接加primary key
    unique key(复合唯一字段列表),#如果是复合唯一键,那么就需要在所有字段列表后面使用这种形式指定,不能在字段后面直接加unique key
    foreign key (从表字段) references 主表名(主表字段) 【on update 外键约束等级】【on delete 外键约束等级【
    #外键只能在所有字段列表后面单独指定
);

(2)如何在建表后指定某个字段的默认值约束

ALTER TABLE 表名称 MODIFY 字段名 数据类型  【default 默认值】 【NOT NULL】;
#如果该字段原来设置了非空约束,要跟着一起再写一遍,否则非空约束会丢失

(3)如何在建表后取消某个字段的默认值约束

ALTER TABLE 表名称 MODIFY 字段名 数据类型 【NOT NULL】;
#如果该字段原来设置了非空约束,要跟着一起再写一遍,否则非空约束会丢失

8、检查约束:check

检查约束,mysql暂不支持

在oracle或sql server中使用

1、检查约束:check
但是mysql暂不支持
在oracle或sql server中使用

create table t_stu(
	sid int primary key,
	sname varchar(20),
	gender char check('男' or '女')
);

insert into t_stu values(1,'张三','男');

insert into t_stu values(2,'李四','妖');

9、自增约束:auto_increment

(1)关于自增长auto_increment:

  • 一个表最多只能有一个自增长列
  • 自增长列必须是键列(主键列,唯一键列,外键列),并且要求非空。
  • 自增列必须是整数类型
  • InnoDB表的自动增长列可以手动插入,但是插入的值如果是空或者0,则实际插入的将是自动增长后的值。

(2)如何在建表时指定自增长列

create table 【数据名.】表名(
	字段名1 数据类型  primary key auto_increment,
	字段名2 数据类型 【unique key】 【not null】 【default 默认值】,
	....
);

或
create table 【数据名.】表名(
	字段名1 数据类型  primary key ,
	字段名2 数据类型 【unique key  not null】 auto_increment,
	....
);

(3)如何在建表后指定自增长列

alter table 【数据名.】表名 modify 自增字段名 数据类型 auto_increment;

(4)如何删除自增约束

alter table 【数据名.】表名 modify 自增字段名 数据类型;

DML

1、如果某列有自增约束,怎么添加该字段的值

添加数据时,对于自增列

insert into 【数据库名.]表名称 values(值列表);#在值列表中,对应自增列可以赋值为null和0

insert into 【数据库名.]表名称(部分字段列表) values(值列表);#自增列在(部分字段列表)中不写就可以

2、如果某列有默认值约束,怎么添加、修改该字段的值

添加数据时,对于有默认值列

insert into 【数据库名.]表名称 values(值列表);#在值列表中,对应默认值列,如果想用默认值,用default

insert into 【数据库名.]表名称(部分字段列表) values(值列表);#对应默认值列,如果想用默认值,在(部分字段列表)中不写就可以

修改数据

update 【数据库名.]表名称 set 字段名1 = 值1, 字段名2 = 值2 。。。 【where 条件】; #对应默认值列,如果想用默认值,写字段名 = default就可以
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章