mysql字段约束-索引-外键

字符修饰符

1)null于not null 说明与使用

NULL是空值的意思,就是这个字段没有值

先创建一个数据库,并进入

mysql> create database w1

mysql> use w1;

这里用例子举例,什么时用null和 not null

1.首先是not null的使用

可以看到,两个字段我类型后面,我加了,not null关键词,这就是使用

mysql> create table name(id int(10) not null ,stname char(10) not null);
Query OK, 0 rows affected (0.34 sec)

然后查看一下表结构,可以看到第三列NULL,两个字段都是NO,表示两个字段都不允许为NULL值的意思

mysql> desc name;
+--------+----------+------+-----+---------+-------+
| Field  | Type     | Null | Key | Default | Extra |
+--------+----------+------+-----+---------+-------+
| id     | int(10)  | NO   |     | NULL    |       |
| stname | char(10) | NO   |     | NULL    |       |
+--------+----------+------+-----+---------+-------+
2 rows in set (0.00 sec)

那有什么用呢,作用就是,例如我们想选择性插入数据,只插入一个字段的值

mysql> insert into name (id) values(1);
ERROR 1364 (HY000): Field 'stname' doesn't have a default value

可以看到上面报错了,这就是not null的作用,如果添加的时候只添加一个字段的值,
而这个表有多个字段,那其他字段的值,在查看时就会显示成NULL

而这个 not null的作用就是,不让这个字段显示成 NULL,所以就会插入不成功

2.null的使用

那假如,选择性添加的使用,想要为NULL值,就可以使用 NULL

新创建一个表,看到后面的关键字为 NULL

mysql> create table name1(id int(10) null,name char(10) null);
Query OK, 0 rows affected (0.16 sec)

表结构,可以看到第三列NULL,是为 yes,表示两个字段都可以是NULL

mysql> desc name1;
+-------+----------+------+-----+---------+-------+
| Field | Type     | Null | Key | Default | Extra |
+-------+----------+------+-----+---------+-------+
| id    | int(10)  | YES  |     | NULL    |       |
| name  | char(10) | YES  |     | NULL    |       |
+-------+----------+------+-----+---------+-------+
2 rows in set (0.00 sec)

测试一下,可以

mysql> insert into name1 (id) values(1);
Query OK, 1 row affected (0.04 sec)

可以看到,刚刚没有插入值的字段为 NULL

mysql> select * from name1;
+------+------+
| id   | name |
+------+------+
|    1 | NULL |
+------+------+
1 row in set (0.00 sec)
3.''

那例如上面的第一个表,不允许为NULL值,那就没有别的方法了么,
不是的可以使用''表示·,也是空值的意思,不过不是NULL

还是上面 not null表,插入''值,可以插入成功

mysql> insert into name values(1,'');
Query OK, 1 row affected (0.00 sec)

查看,如下,是一个空值

mysql> select * from name;
+----+--------+
| id | stname |
+----+--------+
|  1 |        |
+----+--------+
1 row in set (0.00 sec)
4.查看NULL''

先插入值,方便看效果

mysql> insert into name1 values (2,'');
Query OK, 1 row affected (0.01 sec
mysql> insert into name1 values(3,'zhangsan');
Query OK, 1 row affected (0.00 sec)

mysql> select * from name1;
+------+----------+
| id   | name     |
+------+----------+
|    1 | NULL     |
|    2 |          |
|    3 | zhangsan |
+------+----------+

查看NULL

而且建议使用''值而不是NULL
而且''NULL值效率要高,因为如果是NULL 值需要一个字节记录这个值是否为NULL,而''不需要

所以生产环境中,尽量给字段使用 not null方式,不允许字段为NULL,
想要填空值的时候填'',这样效率会高

2)default 设置字段的默认值

就是在插入数据的,,如果选择插入,那么没有插入数据的列的值,
可以设置一个默认的值,自动会为这个字段的值写一个设置好的默认值

例如,如下给 name字段设置一个默认值'APACHE'

mysql> create table def(id int(10) not null,name char(10) default 'APACHE');
Query OK, 0 rows affected (0.11 sec)

查看一下表结构,看到第五列DEFAULT, name字段的是 'APACHE'

mysql> desc def;
+-------+----------+------+-----+---------+-------+
| Field | Type     | Null | Key | Default | Extra |
+-------+----------+------+-----+---------+-------+
| id    | int(10)  | NO   |     | NULL    |       |
| name  | char(10) | YES  |     | APACHE  |       |
+-------+----------+------+-----+---------+-------+
2 rows in set (0.00 sec)

插入数据记录,看效果,没有插入name字段的值

mysql> insert into def(id) values(1);
Query OK, 1 row affected (0.00 sec)

查看,可以看到name字段有默认的值,这就是default的作用

mysql> select * from def;
+----+--------+
| id | name   |
+----+--------+
|  1 | APACHE |
+----+--------+
1 row in set (0.00 sec)

3 ) auto_increment 字符约束

自动增长,只能用于int字符,该字段会自动生成一个数字,而且会以升序的形式,从小到大

例子如下

如下,设置id字段为自动增长,然后后面的primary key的意思是设置这个字段为主键,
主键的意思就是这个值必须唯一,因为要自动增长,所以必须设置主键

ysql> create table auto(id int auto_increment primary key,name char(10),age int(10));
Query OK, 0 rows affected (0.12 sec)

最后的Extrat,可以看到id字段设置了自动增长,第四列的KEY,id字段的RPI表示是主键

mysql> desc auto;
+-------+----------+------+-----+---------+----------------+
| Field | Type     | Null | Key | Default | Extra          |
+-------+----------+------+-----+---------+----------------+
| id    | int(11)  | NO   | PRI | NULL    | auto_increment |
| name  | char(10) | YES  |     | NULL    |                |
| age   | int(10)  | YES  |     | NULL    |                |
+-------+----------+------+-----+---------+----------------+
3 rows in set (0.03 sec)

插入数据,不插入id字段

mysql> insert into auto (name,age) values('zhangsan',10);
Query OK, 1 row affected (0.00 sec)

mysql> insert into auto (name,age) values('zhangsan',10);
Query OK, 1 row affected (0.00 sec)

查看效果,自动从1开始排列往下

mysql> select * from auto;
+----+----------+------+
| id | name     | age  |
+----+----------+------+
|  1 | zhangsan |   10 |
|  2 | lisi     |   20 |
+----+----------+------+
2 rows in set (0.00 sec)

当然也不影响正常的插入id字段

mysql> insert into auto  values(6,'lisi',20);
Query OK, 1 row affected (0.00 sec)

mysql> select * from auto;
+----+----------+------+
| id | name     | age  |
+----+----------+------+
|  1 | zhangsan |   10 |
|  2 | lisi     |   20 |
|  6 | lisi     |   20 |
+----+----------+------+
3 rows in set (0.00 sec)

但是后续的id的值,都会以上一个往下,如下

mysql> insert into auto (name,age) values('lisi',20);
Query OK, 1 row affected (0.00 sec)

mysql> select * from auto;
+----+----------+------+
| id | name     | age  |
+----+----------+------+
|  1 | zhangsan |   10 |
|  2 | lisi     |   20 |
|  6 | lisi     |   20 |
|  7 | lisi     |   20 |
+----+----------+------+
4 rows in set (0.00 sec)
可以清除这种记录

有两种方法

1.只清除数据,如果新插入原来的顺序还在

清除表中数据,并查看,已经没有了

mysql> delete from auto;
Query OK, 4 rows affected (0.00 sec)

mysql> select * from auto;
Empty set (0.00 sec)

再次添加数据,不插入id字段,发现id字段还是按照删除之前,往下顺序

mysql> insert into auto (name,age) values('ajbn','10');
Query OK, 1 row affected (0.03 sec)

mysql> select * from auto;
+----+------+------+
| id | name | age  |
+----+------+------+
|  8 | ajbn |   10 |
+----+------+------+
1 row in set (0.00 sec)
第2种方法,删除数据并删除记录的顺序

如果 truncate关键字加上表名删除

mysql> truncate table auto;
Query OK, 0 rows affected (0.06 sec)

mysql> select * from auto;
Empty set (0.00 sec)

再次插入数据不插入id字段,发现id字段顺序从1开始了

mysql> insert into auto (name,age) values('lisi',100);
Query OK, 1 row affected (0.11 sec)

mysql> select * from auto;
+----+------+------+
| id | name | age  |
+----+------+------+
|  1 | lisi |  100 |
+----+------+------+
1 row in set (0.00 sec)

索引

首先解释一下什么是索引
我们可以这么理解,创建索引类似创建一本书中前面的目录,在查找数据的时候,可以提高查询速度

然后,不可以创建很多索引,索引是以文件形式存储的,如果索引过多
会占用过多的磁盘空间

然后索引需要随着表中的数据同步更新才行,降低了效率

所以我们要合理设计索引

有四种索引,我下面会依次介绍

1)普通索引MUL

最基本的索引,不具备唯一性,可以创建多个,就是加快查询速度

方式1:创建表的时候添加

语法如下

create table 表名(字段名  类型 . . . index 索引名称 (字段) . . .)

例子如下,给 (pass)字段设置索引,索引名称默认不指定就是这个字段名pass,通过index关键词设置

mysql> create table record(id int(10),username char(10),pass int(10),index(pass));
Query OK, 0 rows affected (0.10 sec)

查看表类型,可以看到pass字段的keyMUL表示这个字段做了普通索引

mysql> desc record;
+----------+----------+------+-----+---------+-------+
| Field    | Type     | Null | Key | Default | Extra |
+----------+----------+------+-----+---------+-------+
| id       | int(10)  | YES  |     | NULL    |       |
| username | char(10) | YES  |     | NULL    |       |
| pass     | int(10)  | YES  | MUL | NULL    |       |
+----------+----------+------+-----+---------+-------+
3 rows in set (0.00 sec)

也可以给索引起一个名称,叫putindex后面添加的就是名称,注意这里是一个新的表record1

mysql> create table record1(id int(10),username char(10),pass int(10),index put(pass));
Query OK, 0 rows affected (0.09 sec)

通过如下sql语句可以看到,刚刚设置的

mysql> show create table record1;

如下是执行结果
在这里插入图片描述

方法2:当表创建完后,使用alter为表添加索引

语法如下

alter table 表名 add  index 索引名称 (字段1,...)

先删除索引,后面的pass是索引名,而不是字段名

mysql> alter table record drop index pass;
Query OK, 0 rows affected (0.00 sec)
Records: 0  Duplicates: 0  Warnings: 0

mysql> desc record;    #如下已经没有索引了
+----------+----------+------+-----+---------+-------+
| Field    | Type     | Null | Key | Default | Extra |
+----------+----------+------+-----+---------+-------+
| id       | int(10)  | YES  |     | NULL    |       |
| username | char(10) | YES  |     | NULL    |       |
| pass     | int(10)  | YES  |     | NULL    |       |
+----------+----------+------+-----+---------+-------+
3 rows in set (0.01 sec)

添加,uame是索引名称,username是被索引字段

mysql> alter table record add index uame (username);
Query OK, 0 rows affected (0.01 sec)
Records: 0  Duplicates: 0  Warnings: 0

mysql> desc record;
+----------+----------+------+-----+---------+-------+
| Field    | Type     | Null | Key | Default | Extra |
+----------+----------+------+-----+---------+-------+
| id       | int(10)  | YES  |     | NULL    |       |
| username | char(10) | YES  | MUL | NULL    |       |
| pass     | int(10)  | YES  |     | NULL    |       |
+----------+----------+------+-----+---------+-------+
3 rows in set (0.00 sec)

2)唯一索引UNI

与普通索引基本相同,有一个区别:被索引列的所有值只可以出现一次,及必须唯一,用来约束字段,

字段值只能出现一次,应该添加唯一索引,唯一性运行有NULL

方法1:创建表时唯一索引

语法如下

create table 表名(字段1 ... unique index 索引名 (字段));

创建如下,通过unique,关键字,ide是索引名称

mysql> create table iden(id int(10) ,stname char(10),stage int(10),unique index ide (id));
Query OK, 0 rows affected (0.02 sec)

mysql> desc iden;       ##可以看到id的KEY列为NUI是唯一索引的意思
+--------+----------+------+-----+---------+-------+
| Field  | Type     | Null | Key | Default | Extra |
+--------+----------+------+-----+---------+-------+
| id     | int(10)  | YES  | UNI | NULL    |       |
| stname | char(10) | YES  |     | NULL    |       |
| stage  | int(10)  | YES  |     | NULL    |       |
+--------+----------+------+-----+---------+-------+
3 rows in set (0.00 sec)

测试写入一下值,id字段不让写入重复的值

mysql> insert into iden values(1,'zhangsan',1);
Query OK, 1 row affected (0.00 sec)

mysql> insert into iden values(1,'lisi',2);
ERROR 1062 (23000): Duplicate entry '1' for key 'ide'
方法2:修改表时加唯一索引

语法如下

alter table 表名 add unique 索引名 (字段);

添加,如下,名字为 st

mysql> alter table iden add unique st (stname);
Query OK, 0 rows affected (0.08 sec)
Records: 0  Duplicates: 0  Warnings: 0

mysql> desc iden;   
+--------+----------+------+-----+---------+-------+
| Field  | Type     | Null | Key | Default | Extra |
+--------+----------+------+-----+---------+-------+
| id     | int(10)  | YES  | UNI | NULL    |       |
| stname | char(10) | YES  | UNI | NULL    |       |
| stage  | int(10)  | YES  |     | NULL    |       |
+--------+----------+------+-----+---------+-------+
3 rows in set (0.00 sec)

注意创建表的时候,不可以一次创建多个唯一索引,只可以创建一个,
可以通过后面add的方式添加多个

如下删除id字段唯一索引,ide是索引名

mysql> alter table iden drop index ide;
Query OK, 0 rows affected (0.01 sec)
Records: 0  Duplicates: 0  Warnings: 0

3)主键索引PRI

查询的时候,按主键查询是最快的,每个表只能有一个主键列,可以有多个普通索引列。

主键列要求列的所有内容必须唯一,插入的值不能为空

方法1:创建表时创建

主键索引没有关键词,只要创建了一个主键,就会自动创建主键索引

在指定字段后面加入 primary key就是指定当前字段为主键也就是主键索引,主键默认不允许为NULL

mysql> create table key1(id int(10) primary key,name char(10));
Query OK, 0 rows affected (0.07 sec)

mysql> desc key1;    #可以看到类型为RPI
+-------+----------+------+-----+---------+-------+
| Field | Type     | Null | Key | Default | Extra |
+-------+----------+------+-----+---------+-------+
| id    | int(10)  | NO   | PRI | NULL    |       |
| name  | char(10) | YES  |     | NULL    |       |
+-------+----------+------+-----+---------+-------+
2 rows in set (0.00 sec)
方法2:创建表后添加

不推荐这种方式,如果指定字段原来的数据有一样的,
创建主键索引会报错

一般在设计数据库的时候,创建表的时候就创建了

不过也可以在创建过表后创建,
这里以一个例子举例,创建一个新的表, 模拟一下有自动增长

注意这个不是创建表后添加,我模拟一下如果有自动增长要怎么办

mysql> create table key2(pid int(10) auto_increment primary key,pname char(10));
Query OK, 0 rows affected (0.19 sec)

mysql> desc key2;
+-------+----------+------+-----+---------+----------------+
| Field | Type     | Null | Key | Default | Extra          |
+-------+----------+------+-----+---------+----------------+
| pid   | int(10)  | NO   | PRI | NULL    | auto_increment |
| pname | char(10) | YES  |     | NULL    |                |
+-------+----------+------+-----+---------+----------------+
2 rows in set (0.01 sec)
创建表后添加主键索引,如下

先删除主键索引,发现删不掉,是因为自动增长的原因

mysql> alter table key2 drop primary key;   
ERROR 1075 (42000): Incorrect table definition; there can be only one auto column and it must be defined as a key

先取消自动增长,使用change不加自动增长关键字就行了

mysql> alter table key2 change pid pid int(4);
Query OK, 0 rows affected (0.26 sec)
Records: 0  Duplicates: 0  Warnings: 0

mysql> desc key2;
+-------+----------+------+-----+---------+-------+
| Field | Type     | Null | Key | Default | Extra |
+-------+----------+------+-----+---------+-------+
| pid   | int(4)   | NO   | PRI | NULL    |       |
| pname | char(10) | YES  |     | NULL    |       |
+-------+----------+------+-----+---------+-------+
2 rows in set (0.00 sec)
然后再删除主键索引

因为一个表中只有一个主键索引,不用指定索引名,像如下直接删就行

mysql> alter table key2 drop primary key;
Query OK, 0 rows affected (0.25 sec)
Records: 0  Duplicates: 0  Warnings: 0

mysql> desc key2;
+-------+----------+------+-----+---------+-------+
| Field | Type     | Null | Key | Default | Extra |
+-------+----------+------+-----+---------+-------+
| pid   | int(4)   | NO   |     | NULL    |       |
| pname | char(10) | YES  |     | NULL    |       |
+-------+----------+------+-----+---------+-------+
2 rows in set (0.00 sec)
添加主键索引

使用cahge方式添加,也可以同时添加自动增长

mysql> alter table key2 change pid pid int(4) primary key auto_increment;
Query OK, 0 rows affected (0.28 sec)
Records: 0  Duplicates: 0  Warnings: 0

mysql> desc key2;
+-------+----------+------+-----+---------+----------------+
| Field | Type     | Null | Key | Default | Extra          |
+-------+----------+------+-----+---------+----------------+
| pid   | int(4)   | NO   | PRI | NULL    | auto_increment |
| pname | char(10) | YES  |     | NULL    |                |
+-------+----------+------+-----+---------+----------------+
2 rows in set (0.00 sec)

主键索引,唯一索引区别:主键索引不能有NULL,唯一索引可以有NULL 而且主键索引一个表只能有一个,唯一索引一个表可以多个

4)复合索引

索引列可以包含一个,两个或多个列。两个或更多个以上的索引被称为复合索引

例如,创建一个表中有用户的SIDPIDname,要求表中的SID,PID的字段唯一

如下,后面的主键指定了两个

mysql> create table keyid(SID int(10),PID int(10),name char(10),primary key(SID,PID));
Query OK, 0 rows affected (0.08 sec)

mysql> desc keyid;   ##如下SID,PID都是主键,这就是复合索引
+-------+----------+------+-----+---------+-------+
| Field | Type     | Null | Key | Default | Extra |
+-------+----------+------+-----+---------+-------+
| SID   | int(10)  | NO   | PRI | NULL    |       |
| PID   | int(10)  | NO   | PRI | NULL    |       |
| name  | char(10) | YES  |     | NULL    |       |
+-------+----------+------+-----+---------+-------+
3 rows in set (0.00 sec)

这种主键表示,这两个字段的值不可以同时相同,但是一个字段相同可以

如下,两个语句SID字段相同可以插入成功,但是后面的PID要不相同,反之PID相同的话,再插入时SID就要不相同

mysql> insert into keyid values (1,2,'zhangsan');
Query OK, 1 row affected (0.00 sec)

mysql> insert into keyid values (1,1,'zhangsan');
Query OK, 1 row affected (0.01 sec)

如下就不可以,因为上面已经有了 1 ,1

mysql> insert into keyid values (1,1,'zhangsan');
ERROR 1062 (23000): Duplicate entry '1-1' for key 'PRIMARY'

上面这种就是联合主键,这就叫复合索引

5)全文索引MUL

全文索引用在数据量较大,高并发连接的情况使用

例如如果经常要使用上面的%,也就是模糊查询,因为模糊查询时全表查询,很浪费资源

就可以给经常使用被模糊查询的列,使用全文索引

方法1,创建表时创建

语法如下

create table 表名( 字段名 类型 ... fulltext index 索引名 (字段))

如下,创建全文索引名称为 tex1,索引字段为 name

mysql> create table tex(id int (10),name char(10),uname char(10),fulltext index tex1 (name));
Query OK, 0 rows affected (0.08 sec)

mysql> desc tex;   #MUL就是
+-------+----------+------+-----+---------+-------+
| Field | Type     | Null | Key | Default | Extra |
+-------+----------+------+-----+---------+-------+
| id    | int(10)  | YES  |     | NULL    |       |
| name  | char(10) | YES  | MUL | NULL    |       |
| uname | char(10) | YES  |     | NULL    |       |
+-------+----------+------+-----+---------+-------+
3 rows in set (0.00 sec)
方法2:修改表时添加

语法如下

alter table 表名 add fulltext index 索引名 (字段)

如下添加一个 2text全文索引

mysql> alter table tex1 add fulltext index 2text(uname);
Query OK, 0 rows affected (0.26 sec)
Records: 0  Duplicates: 0  Warnings: 0

mysql> desc tex1;
+-------+----------+------+-----+---------+-------+
| Field | Type     | Null | Key | Default | Extra |
+-------+----------+------+-----+---------+-------+
| id    | int(10)  | YES  |     | NULL    |       |
| name  | char(10) | YES  | MUL | NULL    |       |
| uname | char(10) | YES  | MUL | NULL    |       |
+-------+----------+------+-----+---------+-------+
3 rows in set (0.00 sec)

外键约束

1)创建外键约束

外键约束简单来说,就是让两种表的某些字段有硬性关系

例如,一张表是记录用户名,一张表是密码的,当用户不存在了, 那对应的密码也就应该被删除

还有如果这张用户表中没有指定用户,那另一张密码列表中的用户名应该无法创建才对

创建
创建语法如下

 create table 数据表名称(
 ...,
 [CONSTRAINT [约束名称]] FOREIGN KEY [外键字段] 
     REFERENCES [外键表名](外键字段,外键字段2..)
     [ON DELETE  CASCADE ]
     [ON UPDATE CASCADE  ]
 )
然后是创建外键约束的条件

1.确保参照的表和字段存在
2.组成外键(就是主表的指定字段)的字段被索引
3.必须使用ENGINE指定存储引擎为:innodb
4.外键字段(主表字段)和关联字段(被控制字段),数据类型必须一致

主表就是一会要控制另一张表中的某个字段的表

如下是一个例子

先创建一个主表,主表就是普通创建一个表,不加任何外键约束的参数
指定一会控制另一张表的字段必须要索引,这里是username字段

mysql> create table user(id int(10),username char(10),index (username))ENGINE=innodb;
Query OK, 0 rows affected (0.01 sec)

mysql> desc user;
+----------+----------+------+-----+---------+-------+
| Field    | Type     | Null | Key | Default | Extra |
+----------+----------+------+-----+---------+-------+
| id       | int(10)  | YES  |     | NULL    |       |
| username | char(10) | YES  | MUL | NULL    |       |
+----------+----------+------+-----+---------+-------+
2 rows in set (0.00 sec)
创建被控制表pass,被约束字段会自动创建普通索引
mysql> create table pass(username char(10) ,pass int(10),foreign key pass(username) references user(username) on delete cascade on update cascade)ENGINE=innodb; 
Query OK, 0 rows affected (0.01 sec)

mysql> desc user;
+----------+----------+------+-----+---------+-------+
| Field    | Type     | Null | Key | Default | Extra |
+----------+----------+------+-----+---------+-------+
| id       | int(10)  | YES  |     | NULL    |       |
| username | char(10) | YES  | MUL | NULL    |       |
+----------+----------+------+-----+---------+-------+
2 rows in set (0.00 sec)

解释一下
foregign key关键词后面的是主表名称,和字段username,就是控制的那个字段
references关键词后面的是被控制表的名称pass,与字段 就是现在创建的

后面的的delete cascade 是连级删除
update是连级更新的意思

两个表插入数据
mysql> insert into user values(1,'zhangsan'),(2,'lisi'),(3,'wangwu');
Query OK, 3 rows affected (0.00 sec)
Records: 3  Duplicates: 0  Warnings: 0

mysql> insert into pass values('zhangsan',123),('lisi',1230),('wangwu',123);
Query OK, 3 rows affected (0.00 sec)
Records: 3  Duplicates: 0  Warnings: 0

mysql> select * from user;
+------+----------+
| id   | username |
+------+----------+
|    1 | zhangsan |
|    2 | lisi     |
|    3 | wangwu   |
+------+----------+

mysql> select * from pass;
+----------+------+
| username | pass |
+----------+------+
| zhangsan |  123 |
| lisi     | 1230 |
| wangwu   |  123 |
+----------+------+
3 rows in set (0.00 sec)

1.测试连级删除,
删除主表user表中的 'zhangsan‘行,pass表中的'zhangsan'行也会自动删除

mysql> select * from user;
+------+----------+
| id   | username |
+------+----------+
|    2 | lisi     |
|    3 | wangwu   |
+------+----------+
2 rows in set (0.00 sec)

mysql> select * from pass;
+----------+------+
| username | pass |
+----------+------+
| lisi     | 1230 |
| wangwu   |  123 |
+----------+------+
2 rows in set (0.00 sec)

2.测试连级更新
更改user表中的username,lisi改改为bage,pass表中也会同步

mysql> update user set username='bage' where username='lisi';
Query OK, 1 row affected (0.00 sec)
Rows matched: 1  Changed: 1  Warnings: 0

mysql> select * from user;
+------+----------+
| id   | username |
+------+----------+
|    2 | bage     |
|    3 | wangwu   |
+------+----------+
2 rows in set (0.00 sec)

mysql> select * from pass;
+----------+------+
| username | pass |
+----------+------+
| bage     | 1230 |
| wangwu   |  123 |
+----------+------+
2 rows in set (0.00 sec)

3.测试主表唯一性
在从表创建一个主表username字段没有的数据,会报错,提示主表username中没有这个数据

mysql> insert into pass values('ajbn',123);
ERROR 1452 (23000): Cannot add or update a child row: a foreign key constraint fails (`file`.`pass`, CONSTRAINT `pass_ibfk_1` FOREIGN KEY (`username`) REFERENCES `user (`username`) ON DELETE CASCADE ON UPDATE CASCADE)

先在主表user中创建,再在从表pass创建就可以了

mysql> insert into user values (4,'ajbn');
Query OK, 1 row affected (0.00 sec)

mysql> insert into pass values('ajbn',123);
Query OK, 1 row affected (0.00 sec)
方法2:通过alter table 创建外键约束

创建主表 getkey

mysql> create table getkey (id int(10),username char(10),index (username)) ENGINE=innodb;
Query OK, 0 rows affected (0.08 sec)

创建从表putkey

mysql> create table putkey (username char(10),pass int(10)) ENGINE=innodb;
Query OK, 0 rows affected (0.08 sec)

添加外键约束
constraint 是指定外键约束名称 pk , foreign key (username): 其中username是putkey表中的字段,是被控制字段 ,getkey(username)是控制表和字段

mysql> alter table putkey add constraint pk foreign key(username) references getkey(username) on delete cascade on update cascade,ENGINE=innodb;
Query OK, 0 rows affected (0.02 sec)
Records: 0  Duplicates: 0  Warnings: 0

可以看到刚刚创建的外键约束名称,如下

mysql> show create table putkey;

在这里插入图片描述

2)删除外键

语法如下

alter table 数据表名称 drop foreign key 约束(外键)名称

删除putkey表中的pk外键

mysql> alter table putkey drop foreign key pk;
Query OK, 0 rows affected (0.00 sec)
Records: 0  Duplicates: 0  Warnings: 0

查看已经没了
在这里插入图片描述
实验完毕 !!

发布了54 篇原创文章 · 获赞 57 · 访问量 2万+

猜你喜欢

转载自blog.csdn.net/weixin_45308292/article/details/103752586