阅读目录—MySQL常见的建表选项及约束:
2、指定表选项:engine、auto_increment、comment
1、not null:非空约束
2、unique:唯一约束
3、primary key:主键约束
4、foreign key:外键
5、check:检查—enum、set
当插入一个新行到表中并且没有给该列明确赋值时,如果定义了列的默认值,将自动得到默认值 ;如果没有,则为null。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
<span style="font-size: 16px;">mysql><span style="color: rgba(0, 0, 0, 1);"> create table people </span>-><span style="color: rgba(0, 0, 0, 1);"> ( </span>-> id <span style="color: rgba(0, 0, 255, 1);">int</span> not <span style="color: rgba(0, 0, 255, 1);">null</span><span style="color: rgba(0, 0, 0, 1);"> primary key, </span>-> name varchar(<span style="color: rgba(128, 0, 128, 1);">20</span>) not <span style="color: rgba(0, 0, 255, 1);">null</span><span style="color: rgba(0, 0, 0, 1);">, </span>-> sex <span style="color: rgba(0, 0, 255, 1);">char</span>(<span style="color: rgba(128, 0, 128, 1);">1</span>) <span style="color: rgba(0, 0, 255, 1);">default</span> <span style="color: rgba(128, 0, 0, 1);">'</span><span style="color: rgba(128, 0, 0, 1);">m</span><span style="color: rgba(128, 0, 0, 1);">'</span> -><span style="color: rgba(0, 0, 0, 1);"> ); mysql</span>> insert into people(id,name) values(<span style="color: rgba(128, 0, 128, 1);">1</span>,<span style="color: rgba(128, 0, 0, 1);">'</span><span style="color: rgba(128, 0, 0, 1);">张三</span><span style="color: rgba(128, 0, 0, 1);">'</span><span style="color: rgba(0, 0, 0, 1);">); mysql</span>> insert into people values(<span style="color: rgba(128, 0, 128, 1);">2</span>,<span style="color: rgba(128, 0, 0, 1);">'</span><span style="color: rgba(128, 0, 0, 1);">李四</span><span style="color: rgba(128, 0, 0, 1);">'</span>,<span style="color: rgba(128, 0, 0, 1);">'</span><span style="color: rgba(128, 0, 0, 1);">f</span><span style="color: rgba(128, 0, 0, 1);">'</span><span style="color: rgba(0, 0, 0, 1);">); mysql</span>> <span style="color: rgba(0, 0, 255, 1);">select</span> * <span style="color: rgba(0, 0, 255, 1);">from</span><span style="color: rgba(0, 0, 0, 1);"> people; </span>+----+--------+------+ | id | name | sex | +----+--------+------+ | <span style="color: rgba(128, 0, 128, 1);">1</span> | 张三 | m | | <span style="color: rgba(128, 0, 128, 1);">2</span> | 李四 | f | +----+--------+------+</span> |
当然,也可以在INSERT和UPDATE语句中使用DEFAULT关键字显式地给列赋默认值:
1 2 3 4 5 6 7 8 9 10 11 12 |
<span style="font-size: 16px;">mysql> insert into people values(<span style="color: rgba(128, 0, 128, 1);">3</span>,<span style="color: rgba(128, 0, 0, 1);">'</span><span style="color: rgba(128, 0, 0, 1);">王五</span><span style="color: rgba(128, 0, 0, 1);">'</span>,<span style="color: rgba(0, 0, 255, 1);">default</span><span style="color: rgba(0, 0, 0, 1);">); mysql</span>> update people <span style="color: rgba(0, 0, 255, 1);">set</span> sex=<span style="color: rgba(0, 0, 255, 1);">default</span> <span style="color: rgba(0, 0, 255, 1);">where</span> id=<span style="color: rgba(128, 0, 128, 1);">2</span><span style="color: rgba(0, 0, 0, 1);">; mysql</span>> <span style="color: rgba(0, 0, 255, 1);">select</span> * <span style="color: rgba(0, 0, 255, 1);">from</span><span style="color: rgba(0, 0, 0, 1);"> people; </span>+----+--------+------+ | id | name | sex | +----+--------+------+ | <span style="color: rgba(128, 0, 128, 1);">1</span> | 张三 | m | | <span style="color: rgba(128, 0, 128, 1);">2</span> | 李四 | m | | <span style="color: rgba(128, 0, 128, 1);">3</span> | 王五 | m | +----+--------+------+</span> |
函数default(column)可以得到一个列的默认值:
1 2 3 4 5 6 7 8 |
<span style="font-size: 16px;">mysql> <span style="color: rgba(0, 0, 255, 1);">select</span> <span style="color: rgba(0, 0, 255, 1);">default</span>(sex) <span style="color: rgba(0, 0, 255, 1);">from</span><span style="color: rgba(0, 0, 0, 1);"> people; </span>+--------------+ | <span style="color: rgba(0, 0, 255, 1);">default</span>(sex) | +--------------+ | m | | m | | m | +--------------+</span> |
2)comment:用来给列添加注释,最多255个字符,注释会保存到数据字典中。
创建带有列注释的表stu_comment
1 2 3 4 5 6 7 |
<span style="font-size: 16px;">mysql><span style="color: rgba(0, 0, 0, 1);"> create table stu_comment </span>-><span style="color: rgba(0, 0, 0, 1);"> ( </span>-> id <span style="color: rgba(0, 0, 255, 1);">int</span> not <span style="color: rgba(0, 0, 255, 1);">null</span><span style="color: rgba(0, 0, 0, 1);"> primary key </span>-> comment <span style="color: rgba(128, 0, 0, 1);">'</span><span style="color: rgba(128, 0, 0, 1);">学号</span><span style="color: rgba(128, 0, 0, 1);">'</span><span style="color: rgba(0, 0, 0, 1);">, </span>-> name varchar(<span style="color: rgba(128, 0, 128, 1);">20</span>) not <span style="color: rgba(0, 0, 255, 1);">null</span> -> comment <span style="color: rgba(128, 0, 0, 1);">'</span><span style="color: rgba(128, 0, 0, 1);">姓名</span><span style="color: rgba(128, 0, 0, 1);">'</span> -> );</span> |
从数据字典查询注释信息
1 2 3 4 5 6 7 8 9 |
<span style="font-size: 16px;">mysql> <span style="color: rgba(0, 0, 255, 1);">select</span><span style="color: rgba(0, 0, 0, 1);"> column_name,column_comment </span>-> <span style="color: rgba(0, 0, 255, 1);">from</span><span style="color: rgba(255, 0, 0, 1);"> information_schema.columns </span>-> <span style="color: rgba(0, 0, 255, 1);">where</span> table_name=<span style="color: rgba(128, 0, 0, 1);">'</span><span style="color: rgba(128, 0, 0, 1);">stu_comment</span><span style="color: rgba(128, 0, 0, 1);">'</span><span style="color: rgba(0, 0, 0, 1);">; </span>+-------------+----------------+ | column_name | column_comment | +-------------+----------------+ | id | 学号 | | name | 姓名 | +-------------+----------------+</span> |
存储引擎:决定了数据如何存储以及如何访问,还有事务如何处理
MySQL允许对每个表使用不同的存储引擎,如果在create table语句中没有指定存储引擎,则使用默认的存储引擎。
mysql> show engines; #查询所有支持的存储引擎
mysql> CREATE TABLE sexes(sex char(1) NOT NULL) ENGINE = INNODB;
注意:存储引擎是个重点,后面我们详细讲解。
2)auto_increment:决定当向表中插入第一行时,自增列得到的第一个值是多少
3)comment:给表添加注释
1 2 3 4 5 6 7 8 9 10 |
<span style="font-size: 16px;">mysql> create table mycomm(num <span style="color: rgba(0, 0, 255, 1);">int</span>) comment <span style="color: rgba(128, 0, 0, 1);">'</span><span style="color: rgba(128, 0, 0, 1);">测试表</span><span style="color: rgba(128, 0, 0, 1);">'</span><span style="color: rgba(0, 0, 0, 1);">; mysql</span>> <span style="color: rgba(0, 0, 255, 1);">select</span><span style="color: rgba(0, 0, 0, 1);"> table_name,table_comment </span>-> <span style="color: rgba(0, 0, 255, 1);">from</span><span style="color: rgba(0, 0, 0, 1);"> information_schema.tables </span>-> <span style="color: rgba(0, 0, 255, 1);">where</span> table_name=<span style="color: rgba(128, 0, 0, 1);">'</span><span style="color: rgba(128, 0, 0, 1);">mycomm</span><span style="color: rgba(128, 0, 0, 1);">'</span><span style="color: rgba(0, 0, 0, 1);">; </span>+------------+---------------+ | table_name | table_comment | +------------+---------------+ | mycomm | 测试表 | +------------+---------------+</span> |
作用:可以为列定义约束(constraint)
约束主要是防止非法数据进入到表中,确保数据的正确性和一致性(统称数据完整性);
约束也可以防止一个表被删除 。
注意:
1)MySQL中约束保存在information_schema.table_constraints中,可以通过该表查询约束信息;
2)进行约束定义的时间:使用create table语句、使用alter table语句。
常用的约束的类型:5种
①not null:非空约束,指定某列不为空
②unique:唯一约束,指定某列和几列组合的数据不能重复
③primary key:主键约束,指定某列的数据不能重复、唯一
④foreign key:外键,指定该列记录属于主表中的一条记录,参照另一条数据
⑤check:检查,指定一个表达式,用于检验指定数据
约束定义的语法:
1 2 3 4 5 6 7 8 9 10 11 12 13 |
<span style="font-size: 16px;"><span style="color: rgba(0, 0, 0, 1);"><span style="font-family: 'Microsoft YaHei'; color: rgba(255, 0, 0, 1);">列级别:</span> CREATE TABLE table_name(column_name data_type [ [NOT NULL] </span>| <span style="color: rgba(0, 0, 0, 1);">[UNIQUE [KEY] </span>| <span style="color: rgba(0, 0, 0, 1);">PRIMARY KEY] </span> |<span style="color: rgba(0, 0, 0, 1);">CHECK(expr)],…) <span style="font-family: 'Microsoft YaHei'; color: rgba(255, 0, 0, 1);">表级别:</span> CREATE TABLE table_name( column_name data_type [NOT NULL], column_name data_type [not </span><span style="color: rgba(0, 0, 255, 1);">null</span><span style="color: rgba(0, 0, 0, 1);">],…, [CONSTRAINT constraint_name] PRIMARY KEY (col_name,...) </span>|<span style="color: rgba(0, 0, 0, 1);">[CONSTRAINT constraint_name] unique (col_name,...) </span>|<span style="color: rgba(0, 0, 0, 1);">[CONSTRAINT constraint_name] foreign KEY (col_name) REFERENCES tbl_name (index_col_name) </span>|check(expr) </span> |
注意:
1)NOT NULL约束只能在列级别定义,作用在多个列上的约束只能定义在表级别,例如复合主键约束;
2)列级别上不能定义外键约束,并且不能给约束起名字,由MySQL自动命名(NOT NULL除外);
3)表级别上定义的约束可以给约束起名字(CHECK约束除外)
作用:用于确保当前列的值不为空。
1 2 3 4 5 6 7 8 9 10 |
<span style="font-size: 16px;">mysql> create table temp_nn(id <span style="color: rgba(0, 0, 255, 1);">int</span> not <span style="color: rgba(0, 0, 255, 1);">null</span><span style="color: rgba(0, 0, 0, 1);">); <span style="font-family: 'Microsoft YaHei';">约束直接对DML操作带来影响</span> mysql</span>> insert into temp_nn values(<span style="color: rgba(128, 0, 128, 1);">1</span><span style="color: rgba(0, 0, 0, 1);">); Query OK, </span><span style="color: rgba(128, 0, 128, 1);">1</span> row affected (<span style="color: rgba(128, 0, 128, 1);">0.00</span><span style="color: rgba(0, 0, 0, 1);"> sec) mysql</span>> insert into temp_nn values(<span style="color: rgba(0, 0, 255, 1);">null</span><span style="color: rgba(0, 0, 0, 1);">); ERROR </span><span style="color: rgba(128, 0, 128, 1);">1048</span> (<span style="color: rgba(128, 0, 128, 1);">23000</span>): Column <span style="color: rgba(128, 0, 0, 1);">'</span><span style="color: rgba(128, 0, 0, 1);">id</span><span style="color: rgba(128, 0, 0, 1);">'</span> cannot be <span style="color: rgba(0, 0, 255, 1);">null</span><span style="color: rgba(255, 0, 0, 1); font-family: 'Microsoft YaHei';"> 具有非空约束的列不允许有null值</span></span> |
注意:非空约束只能出现在表对象的列上。
1.唯一约束是指定table的列或列组合不能重复,保证数据的唯一性,约束的列不允许有重复值;
2.唯一约束不允许出现重复的值,但是可以为多个null;
3.同一个表可以有多个唯一约束,多个列组合的约束
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
<span style="font-size: 16px;">mysql><span style="color: rgba(0, 0, 0, 1);"> create table temp_uk( </span>-> id <span style="color: rgba(0, 0, 255, 1);">int</span> not <span style="color: rgba(0, 0, 255, 1);">null</span><span style="color: rgba(0, 0, 0, 1);"> unique, </span>-> name varchar(<span style="color: rgba(128, 0, 128, 1);">20</span><span style="color: rgba(0, 0, 0, 1);">) unique); mysql</span>> insert into temp_uk values(<span style="color: rgba(128, 0, 128, 1);">1</span>,<span style="color: rgba(128, 0, 0, 1);">'</span><span style="color: rgba(128, 0, 0, 1);">a</span><span style="color: rgba(128, 0, 0, 1);">'</span><span style="color: rgba(0, 0, 0, 1);">); mysql</span>> insert into temp_uk values(<span style="color: rgba(128, 0, 128, 1);">2</span>,<span style="color: rgba(128, 0, 0, 1);">'</span><span style="color: rgba(128, 0, 0, 1);">a</span><span style="color: rgba(128, 0, 0, 1);">'</span><span style="color: rgba(0, 0, 0, 1);">); ERROR </span><span style="color: rgba(128, 0, 128, 1);">1062</span> (<span style="color: rgba(128, 0, 128, 1);">23000</span>): Duplicate entry <span style="color: rgba(128, 0, 0, 1);">'</span><span style="color: rgba(128, 0, 0, 1);">a</span><span style="color: rgba(128, 0, 0, 1);">'</span> <span style="color: rgba(0, 0, 255, 1);">for</span> key <span style="color: rgba(128, 0, 0, 1);">'</span><span style="color: rgba(128, 0, 0, 1);">name</span><span style="color: rgba(128, 0, 0, 1);">'</span><span style="color: rgba(0, 0, 0, 1);"> mysql</span>> insert into temp_uk values(<span style="color: rgba(128, 0, 128, 1);">2</span>,<span style="color: rgba(0, 0, 255, 1);">null</span><span style="color: rgba(0, 0, 0, 1);">); mysql</span>> insert into temp_uk values(<span style="color: rgba(128, 0, 128, 1);">3</span>,<span style="color: rgba(0, 0, 255, 1);">null</span><span style="color: rgba(0, 0, 0, 1);">); mysql</span>> <span style="color: rgba(0, 0, 255, 1);">select</span> * <span style="color: rgba(0, 0, 255, 1);">from</span><span style="color: rgba(0, 0, 0, 1);"> temp_uk; </span>+----+------+ | id | name | +----+------+ | <span style="color: rgba(128, 0, 128, 1);">2</span> | NULL | | <span style="color: rgba(128, 0, 128, 1);">3</span> | NULL | | <span style="color: rgba(128, 0, 128, 1);">1</span> | a | +----+------+</span> |
可见,唯一性约束的列可以有多个null值,因为null <> null
4.在创建唯一约束时,如果不给唯一约束名称,就默认和列名相同;
5.唯一约束不仅可以在一个表内创建,而且可以同时多表创建组合唯一约束。
1 2 3 4 5 6 7 8 9 10 11 12 |
<span style="font-size: 16px;">mysql><span style="color: rgba(0, 0, 0, 1);"> create table test( </span>-> id <span style="color: rgba(0, 0, 255, 1);">int</span> not <span style="color: rgba(0, 0, 255, 1);">null</span><span style="color: rgba(0, 0, 0, 1);">, </span>-> name varchar(<span style="color: rgba(128, 0, 128, 1);">20</span><span style="color: rgba(0, 0, 0, 1);">), </span>-> password varchar(<span style="color: rgba(128, 0, 128, 1);">16</span><span style="color: rgba(0, 0, 0, 1);">), </span><span style="font-family: 'Microsoft YaHei'; color: rgba(255, 0, 0, 1);">---</span><span style="color: rgba(0, 0, 0, 1);"><span style="font-family: 'Microsoft YaHei'; color: rgba(255, 0, 0, 1);">使用表级约束语法 </span> </span> -><span style="color: rgba(0, 0, 0, 1);"> constraint uk_name_pwd unique(name,password) </span>-><span style="color: rgba(0, 0, 0, 1);"> ); <span style="font-family: 'Microsoft YaHei';"> #表示用户名和密码组合不能重复</span> Query OK, </span><span style="color: rgba(128, 0, 128, 1);">0</span> rows affected (<span style="color: rgba(128, 0, 128, 1);">0.08</span><span style="color: rgba(0, 0, 0, 1);"> sec) <span style="font-family: 'Microsoft YaHei'; color: rgba(255, 0, 0, 1);">查询数据字典,查看唯一键约束的信息</span> mysql</span>> <span style="color: rgba(0, 0, 255, 1);">select</span> * <span style="color: rgba(0, 0, 255, 1);">from</span><span style="color: rgba(0, 0, 0, 1);"> information_schema.table_constraints </span>-> <span style="color: rgba(0, 0, 255, 1);">where</span> table_name=<span style="color: rgba(128, 0, 0, 1);">'</span><span style="color: rgba(128, 0, 0, 1);">test</span><span style="color: rgba(128, 0, 0, 1);">'</span>;</span> |
primary key = not null + unique
主键:用来唯一的标示表中的每一行(类型一般为整型或者字符串)
具有主键约束的列不允许有null值,并且不允许有重复值;
每个表最多只允许一个主键(可定义联合主键),主键名总是PRIMARY。
1 2 3 4 5 6 7 8 9 10 11 12 |
<span style="font-size: 16px;">mysql><span style="color: rgba(0, 0, 0, 1);"> create table temp_pk( </span>-> id <span style="color: rgba(0, 0, 255, 1);">int</span><span style="color: rgba(0, 0, 0, 1);"> primary key); mysql</span>> insert into temp_pk values(<span style="color: rgba(128, 0, 128, 1);">1</span>),(<span style="color: rgba(128, 0, 128, 1);">2</span><span style="color: rgba(0, 0, 0, 1);">); mysql</span>> insert into temp_pk values(<span style="color: rgba(128, 0, 128, 1);">1</span><span style="color: rgba(0, 0, 0, 1);">); ERROR </span><span style="color: rgba(128, 0, 128, 1);">1062</span> (<span style="color: rgba(128, 0, 128, 1);">23000</span>): Duplicate entry <span style="color: rgba(128, 0, 0, 1);">'</span><span style="color: rgba(128, 0, 0, 1);">1</span><span style="color: rgba(128, 0, 0, 1);">'</span> <span style="color: rgba(0, 0, 255, 1);">for</span> key <span style="color: rgba(128, 0, 0, 1);">'</span><span style="color: rgba(128, 0, 0, 1);">PRIMARY</span><span style="color: rgba(128, 0, 0, 1);">'</span><span style="color: rgba(0, 0, 0, 1);"> mysql</span>> update temp_pk <span style="color: rgba(0, 0, 255, 1);">set</span> id=<span style="color: rgba(128, 0, 128, 1);">1</span> <span style="color: rgba(0, 0, 255, 1);">where</span> id=<span style="color: rgba(128, 0, 128, 1);">2</span><span style="color: rgba(0, 0, 0, 1);">; ERROR </span><span style="color: rgba(128, 0, 128, 1);">1062</span> (<span style="color: rgba(128, 0, 128, 1);">23000</span>): Duplicate entry <span style="color: rgba(128, 0, 0, 1);">'</span><span style="color: rgba(128, 0, 0, 1);">1</span><span style="color: rgba(128, 0, 0, 1);">'</span> <span style="color: rgba(0, 0, 255, 1);">for</span> key <span style="color: rgba(128, 0, 0, 1);">'</span><span style="color: rgba(128, 0, 0, 1);">PRIMARY</span><span style="color: rgba(128, 0, 0, 1);">'</span><span style="color: rgba(0, 0, 0, 1);"> mysql</span>> insert into temp_pk values(<span style="color: rgba(0, 0, 255, 1);">null</span><span style="color: rgba(0, 0, 0, 1);">); ERROR </span><span style="color: rgba(128, 0, 128, 1);">1048</span> (<span style="color: rgba(128, 0, 128, 1);">23000</span>): Column <span style="color: rgba(128, 0, 0, 1);">'</span><span style="color: rgba(128, 0, 0, 1);">id</span><span style="color: rgba(128, 0, 0, 1);">'</span> cannot be <span style="color: rgba(0, 0, 255, 1);">null</span></span> |
!!给主键一个新的名字,但在数据字典中,主键名还是显示primary
联合主键(用几个列进行唯一标识一行)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 |
<span style="font-size: 16px;">mysql><span style="color: rgba(0, 0, 0, 1);"> create table temp_pk( </span>-> id <span style="color: rgba(0, 0, 255, 1);">int</span><span style="color: rgba(0, 0, 0, 1);">, </span>-> name varchar(<span style="color: rgba(128, 0, 128, 1);">20</span><span style="color: rgba(0, 0, 0, 1);">), </span>-><span style="color: rgba(255, 0, 0, 1);"> constraint pk_id_name primary key(id,name) </span>-><span style="color: rgba(0, 0, 0, 1);"> ); Query OK, </span><span style="color: rgba(128, 0, 128, 1);">0</span> rows affected (<span style="color: rgba(128, 0, 128, 1);">0.06</span><span style="color: rgba(0, 0, 0, 1);"> sec) mysql</span>><span style="color: rgba(0, 0, 0, 1);"> desc temp_pk; </span>+-------+-------------+------+-----+---------+-------+ | Field | Type | Null | Key | Default | Extra | +-------+-------------+------+-----+---------+-------+ | id | <span style="color: rgba(0, 0, 255, 1);">int</span>(<span style="color: rgba(128, 0, 128, 1);">11</span>) | NO | PRI | NULL | | | name | varchar(<span style="color: rgba(128, 0, 128, 1);">20</span>) | NO | PRI | NULL | | +-------+-------------+------+-----+---------+-------+ <span style="color: rgba(128, 0, 128, 1);">2</span> rows <span style="color: rgba(0, 0, 255, 1);">in</span> <span style="color: rgba(0, 0, 255, 1);">set</span> (<span style="color: rgba(128, 0, 128, 1);">0.00</span><span style="color: rgba(0, 0, 0, 1);"> sec) mysql</span>> insert into temp_pk values(<span style="color: rgba(128, 0, 128, 1);">1</span>,<span style="color: rgba(128, 0, 0, 1);">'</span><span style="color: rgba(128, 0, 0, 1);">张三</span><span style="color: rgba(128, 0, 0, 1);">'</span><span style="color: rgba(0, 0, 0, 1);">); Query OK, </span><span style="color: rgba(128, 0, 128, 1);">1</span> row affected (<span style="color: rgba(128, 0, 128, 1);">0.00</span><span style="color: rgba(0, 0, 0, 1);"> sec) mysql</span>> insert into temp_pk values(<span style="color: rgba(128, 0, 128, 1);">2</span>,<span style="color: rgba(128, 0, 0, 1);">'</span><span style="color: rgba(128, 0, 0, 1);">李四</span><span style="color: rgba(128, 0, 0, 1);">'</span><span style="color: rgba(0, 0, 0, 1);">); Query OK, </span><span style="color: rgba(128, 0, 128, 1);">1</span> row affected (<span style="color: rgba(128, 0, 128, 1);">0.01</span><span style="color: rgba(0, 0, 0, 1);"> sec) mysql</span>> insert into temp_pk values(<span style="color: rgba(128, 0, 128, 1);">1</span>,<span style="color: rgba(128, 0, 0, 1);">'</span><span style="color: rgba(128, 0, 0, 1);">王五</span><span style="color: rgba(128, 0, 0, 1);">'</span><span style="color: rgba(0, 0, 0, 1);">); Query OK, </span><span style="color: rgba(128, 0, 128, 1);">1</span> row affected (<span style="color: rgba(128, 0, 128, 1);">0.00</span><span style="color: rgba(0, 0, 0, 1);"> sec) mysql</span>> insert into temp_pk values(<span style="color: rgba(128, 0, 128, 1);">1</span>,<span style="color: rgba(128, 0, 0, 1);">'</span><span style="color: rgba(128, 0, 0, 1);">张三</span><span style="color: rgba(128, 0, 0, 1);">'</span><span style="color: rgba(0, 0, 0, 1);">); ERROR </span><span style="color: rgba(128, 0, 128, 1);">1062</span> (<span style="color: rgba(128, 0, 128, 1);">23000</span>): Duplicate entry <span style="color: rgba(128, 0, 0, 1);">'</span><span style="color: rgba(128, 0, 0, 1);">1-张三</span><span style="color: rgba(128, 0, 0, 1);">'</span> <span style="color: rgba(0, 0, 255, 1);">for</span> key <span style="color: rgba(128, 0, 0, 1);">'</span><span style="color: rgba(128, 0, 0, 1);">PRIMARY</span><span style="color: rgba(128, 0, 0, 1);">'</span><span style="color: rgba(0, 0, 0, 1);"> mysql</span>> <span style="color: rgba(0, 0, 255, 1);">select</span> * <span style="color: rgba(0, 0, 255, 1);">from</span><span style="color: rgba(0, 0, 0, 1);"> temp_pk; </span>+----+--------+ | id | name | +----+--------+ | <span style="color: rgba(128, 0, 128, 1);">1</span> | 张三 | | <span style="color: rgba(128, 0, 128, 1);">1</span> | 王五 | | <span style="color: rgba(128, 0, 128, 1);">2</span> | 李四 | +----+--------+ <span style="color: rgba(128, 0, 128, 1);">3</span> rows <span style="color: rgba(0, 0, 255, 1);">in</span> <span style="color: rgba(0, 0, 255, 1);">set</span> (<span style="color: rgba(128, 0, 128, 1);">0.00</span> sec)</span> |
外键约束:
参照完整性约束,保证一个或两个表之间的参照完整性,外键是构建于一个表的两个字段或是两个表的两个字段之间的参照关系。
注意:
1)具有外键约束的列的值不能随便给,必须满足外键所引用的主键的取值;
2)一张表中可以定义多个外键;
3)外键列默认可以给null值。
按照定义,外键必须引用一个主键或者唯一键,引用的主键一般在另外一张表中,也可以是本表的主键(后者称为“自引用”)。
父子表:
外键所在的表叫做子表、从表
外键所引用的主键所在的表叫做父表、主表
注意:父子表是相对而言的,表a可以是表b的子表,但同时也可以是表c的父表
示例:创建外键约束
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
<span style="font-size: 16px;"><span style="font-family: 'Microsoft YaHei'; color: rgba(255, 0, 0, 1);">//创建父表</span><span style="color: rgba(0, 0, 0, 1);"> mysql</span>><span style="color: rgba(0, 0, 0, 1);"> create table dept( </span>-> deptid <span style="color: rgba(0, 0, 255, 1);">int</span><span style="color: rgba(0, 0, 0, 1);">, </span>-> dname varchar(<span style="color: rgba(128, 0, 128, 1);">20</span><span style="color: rgba(0, 0, 0, 1);">), </span>-><span style="color: rgba(0, 0, 0, 1);"> constraint dept_deptid_pk primary key(deptid) </span> -><span style="color: rgba(0, 0, 0, 1);"> ); mysql</span>> insert into dept(deptid,dname) values(<span style="color: rgba(128, 0, 128, 1);">10</span>,<span style="color: rgba(128, 0, 0, 1);">'</span><span style="color: rgba(128, 0, 0, 1);">市场部</span><span style="color: rgba(128, 0, 0, 1);">'</span><span style="color: rgba(0, 0, 0, 1);">); mysql</span>> insert into dept(deptid,dname) values(<span style="color: rgba(128, 0, 128, 1);">20</span>,<span style="color: rgba(128, 0, 0, 1);">'</span><span style="color: rgba(128, 0, 0, 1);">销售部</span><span style="color: rgba(128, 0, 0, 1);">'</span><span style="color: rgba(0, 0, 0, 1);">); </span><span style="font-family: 'Microsoft YaHei'; color: rgba(255, 0, 0, 1);">//创建子表(表级别创建外键约束)</span> <span style="color: rgba(0, 0, 0, 1);">mysql</span>><span style="color: rgba(0, 0, 0, 1);"> create table emp( </span>-> id <span style="color: rgba(0, 0, 255, 1);">int</span><span style="color: rgba(0, 0, 0, 1);">, </span>-> name varchar(<span style="color: rgba(128, 0, 128, 1);">20</span><span style="color: rgba(0, 0, 0, 1);">), </span>-> deptid <span style="color: rgba(0, 0, 255, 1);">int</span><span style="color: rgba(0, 0, 0, 1);">, </span>-><span style="color: rgba(0, 0, 0, 1);"> constraint emp_id_pk primary key(id), </span>-><span style="color: rgba(0, 0, 0, 1);"> constraint emp_deptid_fk foreign key(deptid) </span>-><span style="color: rgba(0, 0, 0, 1);"> references dept(deptid) </span>-> );</span> |
查询数据字典,查看外键约束的信息:
上面创建子表的时候给外键约束命名emp_deptid_fk;
如果不给外键约束命名,那么默认的名字是表名_ibfk_n, n是整数,从1开始;
此时,emp表中deptid列(外键约束)受dept主表限制
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
<span style="font-size: 16px;">mysql> insert into emp(id,name,deptid) values(<span style="color: rgba(128, 0, 128, 1);">1</span>,<span style="color: rgba(128, 0, 0, 1);">'</span><span style="color: rgba(128, 0, 0, 1);">张三</span><span style="color: rgba(128, 0, 0, 1);">'</span>,<span style="color: rgba(128, 0, 128, 1);">10</span><span style="color: rgba(0, 0, 0, 1);">); Query OK, </span><span style="color: rgba(128, 0, 128, 1);">1</span> row affected (<span style="color: rgba(128, 0, 128, 1);">0.00</span><span style="color: rgba(0, 0, 0, 1);"> sec) mysql</span>> insert into emp(id,name,deptid) values(<span style="color: rgba(128, 0, 128, 1);">2</span>,<span style="color: rgba(128, 0, 0, 1);">'</span><span style="color: rgba(128, 0, 0, 1);">李四</span><span style="color: rgba(128, 0, 0, 1);">'</span>,<span style="color: rgba(128, 0, 128, 1);">10</span><span style="color: rgba(0, 0, 0, 1);">); Query OK, </span><span style="color: rgba(128, 0, 128, 1);">1</span> row affected (<span style="color: rgba(128, 0, 128, 1);">0.00</span><span style="color: rgba(0, 0, 0, 1);"> sec) mysql</span>> insert into emp(id,name,deptid) values(<span style="color: rgba(128, 0, 128, 1);">3</span>,<span style="color: rgba(128, 0, 0, 1);">'</span><span style="color: rgba(128, 0, 0, 1);">王五</span><span style="color: rgba(128, 0, 0, 1);">'</span>,<span style="color: rgba(128, 0, 128, 1);">50</span><span style="color: rgba(0, 0, 0, 1);">); <span style="font-family: 'Microsoft YaHei'; color: rgba(255, 0, 0, 1);">#insert主表deptid列没有的数据</span> ERROR </span><span style="color: rgba(128, 0, 128, 1);">1452</span> (<span style="color: rgba(128, 0, 128, 1);">23000</span><span style="color: rgba(0, 0, 0, 1);">): Cannot add or update a child row: a foreign key constraint fails (`test`.`emp`, CONSTRAINT `emp_deptid_fk` FOREIGN KEY (`deptid`) REFERENCES `dept` (`deptid`)) mysql</span>> update emp <span style="color: rgba(0, 0, 255, 1);">set</span> deptid=<span style="color: rgba(128, 0, 128, 1);">30</span> <span style="color: rgba(0, 0, 255, 1);">where</span> id=<span style="color: rgba(128, 0, 128, 1);">1</span><span style="color: rgba(0, 0, 0, 1);">; <span style="color: rgba(255, 0, 0, 1); font-family: 'Microsoft YaHei';">#update主表deptid列没有的数据</span> ERROR </span><span style="color: rgba(128, 0, 128, 1);">1452</span> (<span style="color: rgba(128, 0, 128, 1);">23000</span><span style="color: rgba(0, 0, 0, 1);">): Cannot add or update a child row: a foreign key constraint fails (`test`.`emp`, CONSTRAINT `emp_deptid_fk` FOREIGN KEY (`deptid`) REFERENCES `dept` (`deptid`)) <span style="font-family: 'Microsoft YaHei';">外键的update更新操作规则如下删除规则……</span> mysql</span>> delete <span style="color: rgba(0, 0, 255, 1);">from</span> dept <span style="color: rgba(0, 0, 255, 1);">where</span> deptid=<span style="color: rgba(128, 0, 128, 1);">10</span><span style="color: rgba(0, 0, 0, 1);">; <span style="font-family: 'Microsoft YaHei'; color: rgba(255, 0, 0, 1);">#delete父表中的行(子表中有引用的数据行)</span> ERROR </span><span style="color: rgba(128, 0, 128, 1);">1451</span> (<span style="color: rgba(128, 0, 128, 1);">23000</span><span style="color: rgba(0, 0, 0, 1);">): Cannot delete or update a parent row: a foreign key constraint fails (`test`.`emp`, CONSTRAINT `emp_deptid_fk` FOREIGN KEY (`deptid`) REFERENCES `dept` (`deptid`)) <span style="font-family: 'Microsoft YaHei';"><span style="color: rgba(255, 0, 0, 1); font-family: 'Microsoft YaHei'; font-size: 18px; background-color: rgba(255, 255, 0, 1);">外键的默认删除规则:</span> 当删除父表中的行时,如果子表中有依赖于被删除父行的子行存在,那么就不允许删除,并抛出异常(默认对外键使用on delete restrict 或on delete no action选项)</span></span></span> |
外键引用定义:
1 2 3 4 5 6 7 |
<span style="font-size: 16px;"><span style="color: rgba(0, 0, 0, 1);">reference_definition: REFERENCES tbl_name (index_col_name,...) [MATCH FULL </span>| MATCH PARTIAL |<span style="color: rgba(0, 0, 0, 1);"> MATCH SIMPLE] [ON DELETE reference_option] [ON UPDATE reference_option] reference_option: RESTRICT </span>| CASCADE | SET NULL | NO ACTION</span> |
在定义外键约束时,通过使用on delete cascade或者on delete set null选项,可以改变外键的默认删除规则:
①ON DELETE CASCADE:级联删除。当删除父表中的行时,如果子表中有依赖于被删除父行的子行存在,那么连同子行一起删除(很危险!!!)
②ON DELETE SET NULL:当删除父表中的行时,如果子表中有依赖于被删除父行的子行存在,那么不删除,而是将子行的外键列设置为null
……
1 2 3 4 5 6 7 8 9 10 |
<span style="font-size: 16px;">mysql><span style="color: rgba(0, 0, 0, 1);"> create table emp( </span>-> id <span style="color: rgba(0, 0, 255, 1);">int</span><span style="color: rgba(0, 0, 0, 1);">, </span>-> name varchar(<span style="color: rgba(128, 0, 128, 1);">20</span><span style="color: rgba(0, 0, 0, 1);">), </span>-> deptid <span style="color: rgba(0, 0, 255, 1);">int</span><span style="color: rgba(0, 0, 0, 1);">, </span>-><span style="color: rgba(0, 0, 0, 1);"> constraint emp_id_pk primary key(id), </span>-><span style="color: rgba(0, 0, 0, 1);"> constraint emp_deptid_fk foreign key(deptid) </span>-><span style="color: rgba(0, 0, 0, 1);"> references dept(deptid) </span> -><span style="color: rgba(0, 0, 0, 1);"> on delete cascade </span>-> </span> |