【【【【MySQL 键值】】】】】
MySQL 键值
普通索引 index #
唯一索引 unique
主键 primary key #
外键 foreign key #
全文索引 fulltext
每种键值 的
使用规则 创建 删除 查看
一 ## INDEX 普通索引
使用说明
– 一个表中可以有多个 INDEX 字段
– 字段的值允许有重复,切可以赋 NULL 值
– 经常把做查询条件的字段设置为 INDEX 字段
– INDEX 字段的 KEY 标志是 MUL
INDEX 普通索引(续 1 )
• 建表的时候指定索引字段
– INDEX( 字段 1), INDEX( 字段 2) .. ..
INDEX 普通索引(续 2 )
• 在已有的表中设置 INDEX 字段
– CREATE INDEX 索引名 ON 表名 ( 字段名 );
• 删除指定表的索引字段
– DROP INDEX 索引名
ON 表名 ;
INDEX 普通索引(续 3 )
• 查看表的索引信息
– SHOW INDEX FROM 表名 ;
1.
可以建表的时候建索引 也可以已用表的
创建索引】】】
mysql> create table t16(
-> name char(10),
-> age int(2),
-> class char(7),
-> index(name), //为字段添加索引
-> index(class) 为字段添加索引
-> );
mysql> desc t16;
mysql> show index from t16\G
mysql> drop index class on t16; 删除索引
mysql> show index from t16\G
”默认情况你的字段叫什么 你的索引名就叫什么“ 也可以自定义索引名 的名字
----------------
在已有的表中设置 INDEX 字段
mysql> create index class on t16(class);
Query OK, 0 rows affected (0.12 sec)
Records: 0 Duplicates: 0 Warnings: 0
mysql> show index from t16\G
mysql>
mysql> desc stuinfo;
+-------+------------------------------+------+-----+-------------+-------+
| Field | Type | Null | Key | Default | Extra |
+-------+------------------------------+------+-----+-------------+-------+
| name | char(10) | NO | | NULL | |
| sex | enum('boy','girl','no') | YES | | no | |
| level | int(3) unsigned zerofill | YES | | 000 | |
| money | tinyint(2) unsigned zerofill | YES | | 00 | |
| Email | varchar(50) | YES | | stu@163.com | |
+-------+------------------------------+------+-----+-------------+-------+
5 rows in set (0.00 sec)
mysql>
mysql> desc stuinfo;
+-------+------------------------------+------+-----+-------------+-------+
| Field | Type | Null | Key | Default | Extra |
+-------+------------------------------+------+-----+-------------+-------+
| name | char(10) | NO | | NULL | |
| sex | enum('boy','girl','no') | YES | | no | |
| level | int(3) unsigned zerofill | YES | | 000 | |
| money | tinyint(2) unsigned zerofill | YES | | 00 | |
| Email | varchar(50) | YES | | stu@163.com | |
+-------+------------------------------+------+-----+-------------+-------+
5 rows in set (0.00 sec)
mysql> select * from stuinfo;
+------+------+-------+-------+-------------+
| name | sex | level | money | Email |
+------+------+-------+-------+-------------+
| | no | 002 | 19 | stu@163.com |
+------+------+-------+-------+-------------+
1 row in set (0.00 sec)
mysql> create index name on stuinfo(name);
Query OK, 0 rows affected (0.29 sec)
Records: 0 Duplicates: 0 Warnings: 0
mysql> desc stuinfo;
+-------+------------------------------+------+-----+-------------+-------+
| Field | Type | Null | Key | Default | Extra |
+-------+------------------------------+------+-----+-------------+-------+
| name | char(10) | NO | MUL | NULL | |
| sex | enum('boy','girl','no') | YES | | no | |
| level | int(3) unsigned zerofill | YES | | 000 | |
| money | tinyint(2) unsigned zerofill | YES | | 00 | |
| Email | varchar(50) | YES | | stu@163.com | |
+-------+------------------------------+------+-----+-------------+-------+
5 rows in set (0.01 sec)
mysql> create index aaaa on stuinfo(sex);
Query OK, 0 rows affected (0.30 sec)
Records: 0 Duplicates: 0 Warnings: 0
mysql> desc stuinfo;
+-------+------------------------------+------+-----+-------------+-------+
| Field | Type | Null | Key | Default | Extra |
+-------+------------------------------+------+-----+-------------+-------+
| name | char(10) | NO | MUL | NULL | |
| sex | enum('boy','girl','no') | YES | MUL | no | |
| level | int(3) unsigned zerofill | YES | | 000 | |
| money | tinyint(2) unsigned zerofill | YES | | 00 | |
| Email | varchar(50) | YES | | stu@163.com | |
+-------+------------------------------+------+-----+-------------+-------+
5 rows in set (0.00 sec)
mysql> show index from stuinfo\G
*************************** 1. row ***************************
Table: stuinfo
Non_unique: 1
Key_name: name
Seq_in_index: 1
Column_name: name
Collation: A
Cardinality: 1
Sub_part: NULL
Packed: NULL
Null:
Index_type: BTREE
Comment:
Index_comment:
*************************** 2. row ***************************
Table: stuinfo
Non_unique: 1
Key_name: aaaa
Seq_in_index: 1
Column_name: sex
Collation: A
Cardinality: 1
Sub_part: NULL
Packed: NULL
Null: YES
Index_type: BTREE
Comment:
Index_comment:
2 rows in set (0.00 sec)
mysql>
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++--------------------------------------------------------------------------------------------------
[[ primary key 主键 ]]
表t17为例子
mysql> use db1;
Database changed
mysql> show tables ;
+------------------+
| Tables_in_db1 |
+------------------+
| 学生信息表1 |
| stuinfo |
| t14 |
| t16 |
| t166 |
| t2 |
+------------------+
6 rows in set (0.00 sec)
## stu_id 设置为主键
mysql> create table t17(
-> stu_id char(9) primary key,
-> name char(10)
-> );
Query OK, 0 rows affected (0.42 sec)
mysql> desc t17;
+--------+----------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+--------+----------+------+-----+---------+-------+
| stu_id | char(9) | NO | PRI | NULL | |
| name | char(10) | YES | | NULL | |
+--------+----------+------+-----+---------+-------+
2 rows in set (0.00 sec)
mysql>
mysql> insert into t17 values("nsd180301","bob");
Query OK, 1 row affected (0.06 sec)
mysql> insert into t17 values("nsd180301","tom");
ERROR 1062 (23000): Duplicate entry 'nsd180301' for key 'PRIMARY' ##因为已经有了一个nsd180301了 受主键控制,
mysql>
mysql> insert into t17 values("nsd180401","tom"); ## 输入1804 就可以
Query OK, 1 row affected (0.08 sec)
mysql>
mysql> insert into t17 values(null,"tom");
ERROR 1048 (23000): Column 'stu_id' cannot be null ## 受主建影响 也不能为空
mysql>
表t18 为例子
也可以另外一种方法创建主键
mysql> create table t18(
-> stu_id char(9),
-> name char(10),
-> primary key(stu_id)
-> );
Query OK, 0 rows affected (0.33 sec)
mysql> desc t18;
+--------+----------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+--------+----------+------+-----+---------+-------+
| stu_id | char(9) | NO | PRI | NULL | |
| name | char(10) | YES | | NULL | |
+--------+----------+------+-----+---------+-------+
2 rows in set (0.00 sec)
mysql>
mysql> desc t17;
+--------+----------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+--------+----------+------+-----+---------+-------+
| stu_id | char(9) | NO | PRI | NULL | |
| name | char(10) | YES | | NULL | |
+--------+----------+------+-----+---------+-------+
2 rows in set (0.00 sec)
mysql> insert into t17 values("nsd180401","tom"); ## 主键制约,不能重复输入,
ERROR 1062 (23000): Duplicate entry 'nsd180401' for key 'PRIMARY'
mysql>
mysql> alter table t17 drop primary key; ##删除主键
mysql> insert into t17 values("nsd180401","tom"); ## 这样就可以重复输入了
Query OK, 1 row affected (0.07 sec)
mysql> desc t17;
+--------+----------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+--------+----------+------+-----+---------+-------+
| stu_id | char(9) | NO | | NULL | |
| name | char(10) | YES | | NULL | |
+--------+----------+------+-----+---------+-------+
2 rows in set (0.00 sec)
mysql>
mysql> insert into t17 values(null,"tom"); ## 但是空还是不行 虽然删除了主键,但是不能为空还是存在!
ERROR 1048 (23000): Column 'stu_id' cannot be null
mysql>
## 在已有表中添加主键!
在现有的表中添加主键,需要把重复的改成不重复(对应的字段值不允许有重复,且不允许赋 NULL 值)
mysql> alter table t17 add primary key(stu_id);
ERROR 1062 (23000): Duplicate entry 'nsd180401' for key 'PRIMARY'
mysql>
因为是实验 所以可以把整个表都删除了,如果是生产环境中,需要把数据改成不能重复,不能为空!
mysql> delete from t17;
Query OK, 3 rows affected (0.08 sec)
mysql> alter table t17 add primary key(stu_id);
Query OK, 0 rows affected (0.44 sec)
Records: 0 Duplicates: 0 Warnings: 0
mysql> desc t17;
+--------+----------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+--------+----------+------+-----+---------+-------+
| stu_id | char(9) | NO | PRI | NULL | |
| name | char(10) | YES | | NULL | |
+--------+----------+------+-----+---------+-------+
2 rows in set (0.00 sec)
-------------------------------
【【# 复合主键 #】】
mysql> desc mysql.db; 查看一下复合主键
案例: 建立一个复合主键, 上面实验数创建主键的时候,可以有两种方式创建
可以在上面写 也可以再下面写, 但是创建复合主键的时候是不可以的,因为SQL语句的是从上向下依次判断的
错误演示::-->>
mysql> create table t19(
-> cip char(15) primary key,
-> serport smallint(2) primary key,
-> status enum("yes","no")
-> );
ERROR 1068 (42000): Multiple primary key defined
正确演示::--->>
mysql> create table t19(
-> cip char(15),
-> serport smallint(2),
-> status enum("yes","no"),
-> primary key(cip,serport)
-> );
Query OK, 0 rows affected (0.18 sec)
mysql> desc t19;
+---------+------------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+---------+------------------+------+-----+---------+-------+
| cip | char(15) | NO | PRI | NULL | |
| serport | smallint(2) | NO | PRI | NULL | |
| status | enum('yes','no') | YES | | NULL | |
+---------+------------------+------+-----+---------+-------+
3 rows in set (0.00 sec)
mysql> insert into t19 values ("1.1.1.1",22,"no");
Query OK, 1 row affected (0.06 sec)
mysql> insert into t19 values ("1.1.1.1",21,"no");
Query OK, 1 row affected (0.06 sec)
mysql> insert into t19 values ("1.1.1.2",21,"no");
Query OK, 1 row affected (0.11 sec)
mysql> insert into t19 values ("1.1.1.1",22,"no");
ERROR 1062 (23000): Duplicate entry '1.1.1.1-22' for key 'PRIMARY' //因为设置了复合主键,不能两个都相同
mysql> select * from t19;
----------------------------------------------
删除主键 【】 【】
mysql> alter table t19 drop primary key;
mysql> desc t19;
----------------------------------------------
如何在现有的表中添加主键或者复合主键,需要把重复的改成不同(对应的字段值不允许有重复,且不允许赋 NULL 值)
现在 t19表
如果是在生产环境中 设置主建 首先要把 有相同的数据,字段 改成不相同的 才能设置主建(或者复合主键)
但是现在是做实验,可以直接先把表的数据全部情况 然后再设置主键或者复合主键
mysql> delete from t19;
mysql> select * from t19;
mysql> desc t19;
mysql> alter table t19 add primary key(cip,serport);
mysql> desc t19;
mysql>
----------------------------------------------------------------------
AUTO_INCREMENT 字段值自增长 ++ 】】】
必须是主键 类型 是数值
mysql> create table t20(
-> stu_id int(2) primary key
-> auto_increment,
-> name char(10),
-> age tinyint(2)
-> );
mysql> desc t20;
+--------+------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+--------+------------+------+-----+---------+----------------+
| stu_id | int(2) | NO | PRI | NULL | auto_increment |
| name | char(10) | YES | | NULL | |
| age | tinyint(2) | YES | | NULL | |
+--------+------------+------+-----+---------+----------------+
3 rows in set (0.00 sec)
mysql>
mysql> insert into t20(name,age)values ("aaa",19); //如果不给写值,默认就是当前最大数值 +1
mysql> insert into t20(name,age)values ("bbb",19);
mysql> select * from t20;
mysql> select * from t20;
+--------+------+------+
| stu_id | name | age |
+--------+------+------+
| 1 | aaa | 19 |
| 2 | bbb | 19 |
+--------+------+------+
2 rows in set (0.00 sec)
mysql>
mysql> insert into t20(name,age)values ("aba",29); //如果不给写值,默认就是当前最大数值 +1
mysql> insert into t20 values (null,"lil",29); //如果赋予空值,默认就是当前最大数值 +1
mysql> select * from t20;
mysql> select * from t20;
+--------+------+------+
| stu_id | name | age |
+--------+------+------+
| 1 | aaa | 19 |
| 2 | bbb | 19 |
| 3 | aba | 20 |
| 4 | lil | 20 |
+--------+------+------+
4 rows in set (0.00 sec)
mysql> insert into t20 values (10,"ccc",29); //给值的时候 不要与表中数值相同
mysql> select * from t20;
mysql> select * from t20;
+--------+------+------+
| stu_id | name | age |
+--------+------+------+
| 1 | aaa | 19 |
| 2 | bbb | 19 |
| 3 | aba | 20 |
| 4 | lil | 20 |
| 10 | ccc | 20 |
+--------+------+------+
5 rows in set (0.00 sec)
mysql>
mysql> insert into t20 values (2,"bob",20); ## 2 已经存在
ERROR 1062 (23000): Duplicate entry '2' for key 'PRIMARY'
mysql>
mysql> insert into t20 values (null,"ddd",29); //此时的空没有报错 因为空相当于没有给值,就是自增长+1赋值,不是空值;如果不给写值,默认就是当前最大数值 +1
mysql> select * from t20; ##此时的值是11 因为自增长 是依当前最大值+1
+--------+------+------+
| stu_id | name | age |
+--------+------+------+
| 1 | aaa | 19 |
| 2 | bbb | 19 |
| 3 | aba | 20 |
| 4 | lil | 20 |
| 10 | ccc | 20 |
| 11 | ddd | 29 |
+--------+------+------+
6 rows in set (0.00 sec)
--------------------------------------------------
【 给已有的表中添加字段值自增长 】
mysql> alter table stuinfo
-> add
-> id int(2) primary key
-> auto_increment
-> first;
mysql> select * from stuinfo;
案例二
create table t6(
name char(15),
age tinyint unsigned,
pay float(7,2),
sex enum("boy","girl","no"),
likes set("woman","money","game","eat")
);
mysql> desc db1.t6;
mysql> desc db1.t6;
+-------+-----------------------------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+-------+-----------------------------------+------+-----+---------+-------+
| name | char(15) | YES | | NULL | |
| age | tinyint(3) unsigned | YES | | NULL | |
| pay | float(7,2) | YES | | NULL | |
| sex | enum('boy','girl','no') | YES | | NULL | |
| likes | set('woman','money','game','eat') | YES | | NULL | |
+-------+-----------------------------------+------+-----+---------+-------+
5 rows in set (0.00 sec)
mysql>
mysql> desc t6;
mysql> desc t6;
+-------+-----------------------------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+-------+-----------------------------------+------+-----+---------+----------------+
| id | int(2) | NO | PRI | NULL | auto_increment |
| name | char(15) | YES | | NULL | |
| age | tinyint(3) unsigned | YES | | NULL | |
| pay | float(7,2) | YES | | NULL | |
| sex | enum('boy','girl','no') | YES | | NULL | |
| likes | set('woman','money','game','eat') | YES | | NULL | |
+-------+-----------------------------------+------+-----+---------+----------------+
6 rows in set (0.01 sec)
mysql>
mysql> select * from t6;
mysql> alter table t6 add id int(2) primary key auto_increment first;
mysql> desc t6;
mysql> select * from t6;
mysql> insert into t6 values("bob",21,2000,"no","eat,game"); ## id字段 默认字段不能为空!
ERROR 1136 (21S01): Column count doesn't match value count at row 1
mysql> insert into t6 values("li",21,2000,"no","eat,game");
ERROR 1136 (21S01): Column count doesn't match value count at row 1
mysql> insert into t6 values(null,"li",21,2000,"no","eat,game"); ##默认不能为空 可以赋值空 此时的空没有报错 因为空相当于没有给值,就是自增长+1赋值,不是空值;如果不给写值,默认就是当前最大数值 +1
mysql> insert into t6 values(null,"wang",21,2000,"no","eat,game");
mysql> select * from t6;
mysql>
==========================================================================
++++++++++++++++++++++【foreign key 外键】++++++++++++++++++++++++++++++++++==
++++++++++++++++++++++【foreign key 外键】++++++++++++++++++++++++++++++++++==
++++++++++++++++++++++【foreign key 外键】++++++++++++++++++++++++++++++++++==
foreign key 外键
• 什么是外键?
– 让当前表字段的值在另一个表中字段值的范围内选择。
• 使用外键的条件
– 表的存储引擎必须是 innodb
– 字段类型要一致
– 被参照字段必须要是索引类型的一种 (primary key) (通常是主键,因为普通的索引可以为空,可以重复)
foreign key 外键(续 1 )
• 基本用法
– FOREIGN KEY( 表 A 的字段名 )
References 表 B( 字段名 )
ON UPDATE CASCADE #---->同步更新
ON DELETE CASCADE #---->同步删除
注意:建立外键的时候 被参考的表,必须是事先建好的
foreign key 外键(续 2 )
• 删除外键字段
– ALTER TABLE 表名 DROP FOREIGN KEY 约束名 ;
##为什么要用外键?什么场景会用到外键?
比如说: 公司 给员工发工资, 会有一张员工表, 一张工资表
ygb表
yg_id name(姓名) bumen(部门)
1 bob tea
2 bob tea
3 lucy tea
员工名有可能重复,通过编号id可以区分
gzb表
gz_id name(姓名) pay(工资) bumen(部门)
1 bob 2w tea
2 bob 3w tea
3 lucy 5w tea
4 tom 7w tea
发工资就依据编号来发工资!
上述例子中 gzb表中gz_id为4的标号tom的工资就不能发,因为ygb表中没有编号为4的员工。这样就会避免发错工资!
因为gzb表中的gz_id字段做成外键 去参考ygb表中的yg_id 只能在ygb表中字段yg_id 的范围里面选择发放工资,这样就会避免发错工资!
------------------------------------
示例演示::————>>
外键
1## 创建 ygb 员工表
员工编号 姓名 部门
yg_id name bumen
mysql> create table ygb(
-> yg_id int(2) primary key auto_increment,
-> name char(15),
-> bumen char(20)
-> )engine=innodb;
mysql> desc ygb;
+-------+----------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+-------+----------+------+-----+---------+----------------+
| yg_id | int(2) | NO | PRI | NULL | auto_increment |
| name | char(15) | YES | | NULL | |
| bumen | char(20) | YES | | NULL | |
+-------+----------+------+-----+---------+----------------+
3 rows in set (0.00 sec)
mysql> insert into ygb(name,bumen)values("bob","tea"),("jack","tea");
mysql> select * from ygb;
+-------+------+-------+
| yg_id | name | bumen |
+-------+------+-------+
| 1 | bob | tea |
| 2 | jack | tea |
+-------+------+-------+
2 rows in set (0.00 sec)
-----------------------------------
2## 创建 gzb 工资表
员工编号 姓名 工资 部门
gz_id name pay bumen
mysql>
mysql> create table gzb(
-> gz_id int(2),
-> name char(15),
-> pay float(7,2),
-> bumen char(20),
-> foreign key(gz_id) references ygb(yg_id)
-> on update cascade
-> on delete cascade
-> )engine=innodb;
mysql> desc gzb;
+-------+------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+-------+------------+------+-----+---------+-------+
| gz_id | int(2) | YES | MUL | NULL | |
| name | char(15) | YES | | NULL | |
| pay | float(7,2) | YES | | NULL | |
| bumen | char(20) | YES | | NULL | |
+-------+------------+------+-----+---------+-------+
4 rows in set (0.00 sec)
#: 做了外键之后 key 变成 MUL 标志, 这是普通索引的标志 那怎么才知道表里面有没有外键!
mysql> show create table gzb; # 通过这可以看出有没有外建!
mysql> show create table gzb;
+-------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| Table | Create Table |
+-------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| gzb | CREATE TABLE `gzb` (
`gz_id` int(2) DEFAULT NULL,
`name` char(15) DEFAULT NULL,
`pay` float(7,2) DEFAULT NULL,
`bumen` char(20) DEFAULT NULL,
KEY `gz_id` (`gz_id`),
CONSTRAINT `gzb_ibfk_1` FOREIGN KEY (`gz_id`) REFERENCES `ygb` (`yg_id`) ON DELETE CASCADE ON UPDATE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=latin1 |
+-------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
1 row in set (0.00 sec)
mysql>
--------------------
mysql> select * from gzb; //查询一下工资表
Empty set (0.00 sec)
mysql>
---------------------------------
mysql> insert into gzb values(3,"tom",20000,"tea");
ERROR 1452 (23000): Cannot add or update a child row: a foreign key constraint fails (`db1`.`gzb`, CONSTRAINT `gzb_ibfk_1` FOREIGN KEY (`gz_id`) REFERENCES `ygb` (`yg_id`) ON DELETE CASCADE ON UPDATE CASCADE)
mysql>
在工资表中写入 数据 】】
mysql> insert into gzb values(1,"tom","25000","shichang");
mysql> insert into gzb values(2,"libai","25000","jishu");
mysql> select * from gzb;
mysql> insert into gzb values(3,"tom",20000,"tea"); //员工表中yg_id中没有编号3 所以不能写入!受外键约束,因为ygb表中没有编号3的信息
ERROR 1452 (23000): Cannot add or update a child row: a foreign key constraint fails (`db1`.`gzb`, CONSTRAINT `gzb_ibfk_1` FOREIGN KEY (`gz_id`) REFERENCES `ygb` (`yg_id`) ON DELETE CASCADE ON UPDATE CASCADE)
mysql>
mysql>
mysql> insert into ygb(name,bumen) ## 先把tom加入员工表
-> values
-> ("tom","shichang");
Query OK, 1 row affected (0.04 sec)
mysql> select * from ygb;
+-------+------+----------+
| yg_id | name | bumen |
+-------+------+----------+
| 1 | bob | tea |
| 2 | jack | tea |
| 3 | tom | shichang |
+-------+------+----------+
3 rows in set (0.00 sec)
mysql>
mysql>
mysql> insert into gzb values(3,"tom",20000,"tea"); ## 这时候再添加 就可以加入了!
Query OK, 1 row affected (0.06 sec)
mysql> select * from gzb;
+-------+-------+----------+-------+
| gz_id | name | pay | bumen |
+-------+-------+----------+-------+
| 1 | bob | 20000.00 | tea |
| 2 | libai | 20000.00 | tea |
| 3 | tom | 20000.00 | tea |
+-------+-------+----------+-------+
3 rows in set (0.00 sec)
#### gzb表中的gz_id 和ygb表中的yg_id 一样才行
-----------------------------------------------
同步更新,同步删除!!!】】
——————++++| 同步更新——+++++
mysql> select * from ygb;
+-------+------+----------+
| yg_id | name | bumen |
+-------+------+----------+
| 1 | bob | tea |
| 2 | jack | tea |
| 3 | tom | shichang |
+-------+------+----------+
3 rows in set (0.00 sec)
mysql>
mysql> update ygb set yg_id=8 where name="bob";
Query OK, 1 row affected (0.05 sec)
Rows matched: 1 Changed: 1 Warnings: 0
mysql> select * from ygb;
+-------+------+----------+
| yg_id | name | bumen |
+-------+------+----------+
| 2 | jack | tea |
| 3 | tom | shichang |
| 8 | bob | tea |
+-------+------+----------+
3 rows in set (0.01 sec)
mysql> select * from gzb;
+-------+-------+----------+-------+
| gz_id | name | pay | bumen |
+-------+-------+----------+-------+
| 8 | bob | 20000.00 | tea |
| 2 | libai | 20000.00 | tea |
| 3 | tom | 20000.00 | tea |
+-------+-------+----------+-------+
3 rows in set (0.00 sec)
---+++++++++同步删除!+++++++
mysql> select * from ygb;
+-------+------+----------+
| yg_id | name | bumen |
+-------+------+----------+
| 2 | jack | tea |
| 3 | tom | shichang |
| 8 | bob | tea |
+-------+------+----------+
3 rows in set (0.00 sec)
mysql> delete from ygb where yg_id=2;
Query OK, 1 row affected (0.04 sec)
mysql> select * from ygb;
+-------+------+----------+
| yg_id | name | bumen |
+-------+------+----------+
| 3 | tom | shichang |
| 8 | bob | tea |
+-------+------+----------+
2 rows in set (0.00 sec)
mysql> select * from gzb;
+-------+------+----------+-------+
| gz_id | name | pay | bumen |
+-------+------+----------+-------+
| 8 | bob | 20000.00 | tea |
| 3 | tom | 20000.00 | tea |
+-------+------+----------+-------+
2 rows in set (0.00 sec)
mysql>
=========================================================
问题来了:
再不超出ygb表中 yg_id 的数值范围内 添加工资表, 但是新的问题是可以添加重复的 和NULL 的 怎么解决?
mysql> select * from gzb;
+-------+------+----------+-------+
| gz_id | name | pay | bumen |
+-------+------+----------+-------+
| 8 | bob | 20000.00 | tea |
| 3 | tom | 20000.00 | tea |
+-------+------+----------+-------+
2 rows in set (0.00 sec)
mysql> insert into gzb values (3,"tom",35000,"tea");
Query OK, 1 row affected (0.04 sec)
mysql> insert into gzb values (3,"tom",35000,"tea");
Query OK, 1 row affected (0.11 sec)
mysql> select * from gzb;
+-------+------+----------+-------+
| gz_id | name | pay | bumen |
+-------+------+----------+-------+
| 8 | bob | 20000.00 | tea |
| 3 | tom | 20000.00 | tea |
| 3 | tom | 35000.00 | tea |
| 3 | tom | 35000.00 | tea |
+-------+------+----------+-------+
4 rows in set (0.00 sec)
mysql>
mysql> insert into gzb values (null,"lucy",35000,"tea");
Query OK, 1 row affected (0.06 sec)
mysql> insert into gzb values (null,"lucy",35000,"tea");
Query OK, 1 row affected (0.04 sec)
mysql> insert into gzb values (null,"lucy",35000,"tea");
Query OK, 1 row affected (0.03 sec)
mysql> select * from gzb;
+-------+------+----------+-------+
| gz_id | name | pay | bumen |
+-------+------+----------+-------+
| 8 | bob | 20000.00 | tea |
| 3 | tom | 20000.00 | tea |
| 3 | tom | 35000.00 | tea |
| 3 | tom | 35000.00 | tea |
| NULL | lucy | 35000.00 | tea |
| NULL | lucy | 35000.00 | tea |
| NULL | lucy | 35000.00 | tea |
+-------+------+----------+-------+
7 rows in set (0.00 sec)
### 通过上面可以发现gzb表gz_id在不超出ygb表yg_id的范围;但是gzb中却可以重复输入 和null空,在生产环境中是不允许的,那么怎么解决呢?
让gzb当前表,除受外键影响外, 还要让当前gzb表字段不允许重复,不允许为空, 那么gz_id设置主键就可以满足这两个条件!
那么现在gzb表目前里面有重复字段还有空值 是不允许设为主键的, 那么需要把重复的改为不同,或者直接删除此表 重新建一个(那么在生产环境中,是不允许删除表的,可能需要手动更改!)
------------------------------
解决方法: 把gzb删除 重新建一个 gzb 为工资表添加约束条件,为gz_id设置为主键】】】
mysql> delete from gzb;
mysql> select * from ygb;
+-------+------+----------+
| yg_id | name | bumen |
+-------+------+----------+
| 3 | tom | shichang |
| 8 | bob | tea |
+-------+------+----------+
2 rows in set (0.00 sec)
mysql> select * from gzb;
Empty set (0.00 sec)
mysql> select * from ygb;
+-------+------+----------+
| yg_id | name | bumen |
+-------+------+----------+
| 3 | tom | shichang |
| 8 | bob | tea |
+-------+------+----------+
2 rows in set (0.00 sec)
mysql> desc gzb;
+-------+------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+-------+------------+------+-----+---------+-------+
| gz_id | int(2) | YES | MUL | NULL | |
| name | char(15) | YES | | NULL | |
| pay | float(7,2) | YES | | NULL | |
| bumen | char(20) | YES | | NULL | |
+-------+------------+------+-----+---------+-------+
4 rows in set (0.00 sec)
mysql> alter table gzb add primary key(gz_id); ###————>> 添加主键
mysql> desc gzb;
+-------+------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+-------+------------+------+-----+---------+-------+
| gz_id | int(2) | NO | PRI | NULL | |
| name | char(15) | YES | | NULL | |
| pay | float(7,2) | YES | | NULL | |
| bumen | char(20) | YES | | NULL | |
+-------+------------+------+-----+---------+-------+
4 rows in set (0.00 sec)
mysql> insert into gzb
-> values
-> (3,"tom",30000,"tea");
Query OK, 1 row affected (0.04 sec)
mysql> insert into gzb values (8,"bob",35000,"tea");
Query OK, 1 row affected (0.07 sec)
mysql>
mysql> insert into gzb values (8,"lucy",35000,"tea"); ##不能重复添加
ERROR 1062 (23000): Duplicate entry '8' for key 'PRIMARY'
mysql> insert into gzb values (3,"lucy",35000,"tea"); ##不能重复添加
ERROR 1062 (23000): Duplicate entry '3' for key 'PRIMARY'
mysql>
mysql> insert into gzb values (null,"lucy",35000,"tea"); ##不能添加空
ERROR 1048 (23000): Column 'gz_id' cannot be null
mysql>
delete from ygb; 【【如果把ygb清空了 工资表gzb也没有数据了 因为他们 关联了yg_id gz_id】】
mysql> select * from ygb;
+-------+------+----------+
| yg_id | name | bumen |
+-------+------+----------+
| 3 | tom | shichang |
| 8 | bob | tea |
+-------+------+----------+
2 rows in set (0.00 sec)
mysql> select * from gzb;
+-------+------+----------+-------+
| gz_id | name | pay | bumen |
+-------+------+----------+-------+
| 3 | tom | 30000.00 | tea |
| 8 | bob | 35000.00 | tea |
+-------+------+----------+-------+
2 rows in set (0.00 sec)
mysql>
mysql>
mysql> delete from ygb; ## 把ygb表的信息清除了 那么gzb里面的信息也没有了! 反之如果把gzb信息删除了,那么ygb的信息还在!
Query OK, 2 rows affected (0.05 sec)
mysql> select * from ygb;
Empty set (0.00 sec)
mysql> select * from gzb;
Empty set (0.00 sec)
mysql>
=======================================
mysql> drop table ygb; ## ygb表无法删除,
ERROR 1217 (23000): Cannot delete or update a parent row: a foreign key constraint fails
mysql> alter table ygb drop yg_id; ##字段也无法删除!!
ERROR 1829 (HY000): Cannot drop column 'yg_id': needed in a foreign key constraint 'gzb_ibfk_1' of table 'db1.gzb'
mysql>
一旦建立了外键, 被参照的表,不能随意删除表,也不能随意删除字段,除非没有人参考你了 把外键 删掉了才可以不受影响。
mysql> show create table gzb; //查询 CONSTRAINT `gzb_ibfk_1` 中 gzb_ibfk_1 位外键约束名称。
mysql> show create table gzb\G //查询外键
... ...
... ....
CONSTRAINT `gzb_ibfk_1`
mysql> alter table gzb drop foreign key gzb_ibfk_1; //删除外键
mysql> drop table ygb; ## 此时ygb表就可以删除了!
Query OK, 0 rows affected (0.11 sec)
------------------------------------------------------------------------------------------------------------------------------------------------------