sql语句规范

sql是Structured Query Language(结构化查询语言)的缩写。SQL是专为数据库而建立的操作命令集,是一种功能齐全的数据库语言。

在使用它时,只需要发出“做什么”的命令,“怎么做”是不用使用者考虑的。SQL功能强大、简单易学、使用方便,已经成为了数据库操作的基础,并且现在几乎所有的数据库均支持sql。

<1> 在数据库系统中,SQL语句不区分大小写(建议用大写) 。但字符串常量区分大小写。建议命令大写,表名库名小写;

<2> SQL语句可单行或多行书写,以“;”结尾。关键词不能跨多行或简写。

<3> 用空格和缩进来提高语句的可读性。子句通常位于独立行,便于编辑,提高可读性。

1
2
SELECT * FROM tb_table
WHERE NAME="YUAN";
<4> 注释:单行注释:--

多行注释:/*......*/

<5>sql语句可以折行操作

回到顶部
数据类型

数值类型

  作用:存储年龄,等级,id,手机号,身高,薪水等数字

无符号类型

View Code
显示长度和存储字节

复制代码
mysql> create table test(id int);
Query OK, 0 rows affected (0.01 sec)

mysql> desc test;
+-------+---------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+-------+---------+------+-----+---------+-------+
| id | int(11) | YES | | NULL | |
+-------+---------+------+-----+---------+-------+
1 row in set (0.00 sec)
复制代码
int(11)是默认的显示宽度,因为int是用4个字节存储,所以能存储的最大数就是4294967295,是一个十位数字,对于无符号类型,所以默认显示宽度就是11;
同理:tinyint的默认显示宽度是4位。
decimal类型

float:浮点型,含字节数为4,32bit, 数值范围为-3.4E38~3.4E38(7个有效位)

double:双精度实型,含字节数为8,64bit 数值范围-1.7E308~1.7E308(15个有效位)

decimal:数字型,128 数值范围 ±1.0 × E28 to ±7.9 × E28(28个有效位)
decimal的精度比double大,所能储存的最大数却比double要小 。decimal是存在精度损失的,只不过较小而已!

BIT

  BIT(M)可以用来存放多位二进制数,M范围从1~64,如果不写默认为1位。
  注意:对于位字段需要使用函数读取
      bin()显示为二进制
      hex()显示为十六进制

复制代码
mysql> create table t(id bit);
Query OK, 0 rows affected (0.03 sec)

mysql> desc t;
+-------+--------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+-------+--------+------+-----+---------+-------+
| id | bit(1) | YES | | NULL | |
+-------+--------+------+-----+---------+-------+
1 row in set (0.00 sec)

mysql> insert t values (1);
Query OK, 1 row affected (0.00 sec)

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

mysql> select bin(id) from t;
+---------+
| bin(id) |
+---------+
| 1 |
+---------+
1 row in set (0.00 sec)
复制代码
复制代码
mysql> alter table t modify id bit(5);
Query OK, 1 row affected (0.02 sec)
Records: 1 Duplicates: 0 Warnings: 0

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

mysql> select bin(id),hex(id) from t;
+---------+---------+
| bin(id) | hex(id) |
+---------+---------+
| 1 | 1 |
| 1000 | 8 |
+---------+---------+
2 rows in set (0.00 sec)
复制代码
字符串类型

存储字符串:

CHAR系列 :CHAR VARCHAR
TEXT系列 : TINYTEXT TEXT MEDIUMTEXT LONGTEXT

存储二进制数据:

BINARY系列: BINARY VARBINARY
BLOB 系列 : TINYBLOB BLOB MEDIUMBLOB LONGBLOB

解析:

View Code
注意:

复制代码
在查询的时候,CHAR列删除了尾部的空格,而VARCHAR则保留这些空格。
mysql> create table t1(x char(5),y varchar(5));
mysql> insert into t1 values('你瞅啥 ','瞅你妹 ');
mysql> select x,length(x),y,length(y) from t1;
+--------+-----------+----------+-----------+
| x | length(x) | y | length(y) |
+--------+-----------+----------+-----------+
| 你瞅啥 | 9 | 瞅你妹 | 11 |
+--------+-----------+----------+-----------+
复制代码
日期类型

表示时间值的日期和时间类型为DATETIME、DATE、TIMESTAMP、TIME和YEAR。

每个时间类型有一个有效值范围和一个"零"值,当指定不合法的MySQL不能表示的值时使用"零"值。

作用:存储用户注册时间,文章发布时间,员工入职时间,出生时间,过期时间等

year

复制代码
============year===================

create table t_year(born_year year);
insert into t_year values (1901),
(2155);

select * from t_year;
+-----------+
| born_year |
+-----------+
| 1901 |
| 2155 |
+-----------+
2 rows in set (0.00 sec)
复制代码
date time datetime

mysql> select now();
+---------------------+
| now() |
+---------------------+
| 2017-08-01 19:38:54 |
+---------------------+
1 row in set (0.00 sec)

复制代码
============date,time,datetime===========

create table t_mul(d date,t time,dt datetime);

insert into t_mul values(now(),now(),now());

select * from t_mul;

mysql> select * from t_mul;
+------------+----------+---------------------+
| d | t | dt |
+------------+----------+---------------------+
| 2017-08-01 | 19:42:22 | 2017-08-01 19:42:22 |
+------------+----------+---------------------+
1 row in set (0.00 sec)
复制代码
timestamp

复制代码
create table t_stamp(t TIMESTAMP);

insert into t_stamp values();
insert into t_stamp values(NULL );

select * from t_stamp;

+---------------------+
| t |
+---------------------+
| 2017-08-01 19:46:24 |
| 2017-08-01 19:46:24 |
+---------------------+
2 rows in set (0.00 sec)
复制代码
datetime与timestamp
枚举类型与集合类型

字段的值只能在给定范围中选择,如单选框,多选框
enum 单选 只能在给定的范围内选一个值,如性别 sex 男male/女female
set 多选 在给定的范围内可以选择一个或一个以上的值(爱好1,爱好2,爱好3...)

解析:

View Code
回到顶部
数据库操作

复制代码
-- 1.创建数据库(在磁盘上创建一个对应的文件夹)
create database [if not exists] db_name [character set xxx]

-- 2.查看数据库
show databases;查看所有数据库
show create database db_name; 查看数据库的创建方式

-- 3.修改数据库
alter database db_name [character set xxx]

-- 4.删除数据库
drop database [if exists] db_name;

-- 5.使用数据库
切换数据库 use db_name; -- 注意:进入到某个数据库后没办法再退回之前状态,但可以通过use进行切换
查看当前使用的数据库 select database();
复制代码
回到顶部
数据表操作

创建表

复制代码
-- 语法
CREATE TABLE tab_name(
field1 type[完整性约束条件],
field2 type,
...
fieldn type
)[character set xxx];
复制代码
示例:

View Code
查看表信息

desc tab_name           查看表结构
show columns from tab_name 查看表结构
show tables             查看当前数据库中的所有的表
show create table tab_name 查看当前数据库表建表语句
修改表结构

复制代码
-- (1)增加列(字段)
alter table tab_name add [column] 列名 类型[完整性约束条件][first|after 字段名];

#添加多个字段
alter table users2
add addr varchar(20),
add age int first,
add birth varchar(20) after name;

-- (2)修改一列类型
alter table tab_name modify 列名 类型 [完整性约束条件][first|after 字段名];
-- (3)修改列名
alter table tab_name change [column] 列名 新列名 类型 [完整性约束条件][first|after 字段名];
-- (4)删除一列
alter table tab_name drop [column] 列名;-- (5)修改表名
rename table 表名 to 新表名;

-- (6)修该表所用的字符集
alter table student character set utf8;
复制代码
删除表

drop table tab_name;
回到顶部
表记录操作

增加表记录

复制代码
/*
<1>插入一条记录:

  insert [into] tab_name (field1,filed2,.......) values (value1,value2,.......);
    

<2>插入多条记录:
  insert [into] tab_name (field1,filed2,.......) values (value1,value2,.......),
                             (value1,value2,.......),
                             ... ;

<3>set插入:
  insert [into] tab_name set 字段名=值

*/
复制代码
示例:

View Code
修改表记录

1
update tab_name set field1=value1,field2=value2,......[where 语句]
示例:

View Code
删除表记录

复制代码
方式1:
delete from tab_name [where ....]

方式2:
truncate table emp_new;

/*
如果不跟where语句则删除整张表中的数据
delete只能用来删除一行记录
delete语句只能删除表中的内容,不能删除表本身,想要删除表,用drop
TRUNCATE TABLE也可以删除表中的所有数据,词语句首先摧毁表,再新建表。此种方式删除的数据不能在
事务中恢复。
*/
复制代码
示例:

View Code
回到顶部
查询表记录(select)

复制代码
-- 查询语法:

SELECT *|field1,filed2 ... FROM tab_name
WHERE 条件
GROUP BY field
HAVING 筛选
ORDER BY field
LIMIT 限制条数

-- Mysql在执行sql语句时的执行顺序:
-- from where select group by having order by

复制代码
准备表和数据

View Code
复制代码
mysql> SELECT * FROM emp;
+----+-----------+--------+------+-----------+-----------+----------+
| id | name | gender | age | dep | city | salary |
+----+-----------+--------+------+-----------+-----------+----------+
| 1 | yuan | male | 24 | 教学部 | 河北省 | 8000.00 |
| 2 | egon | male | 34 | 保安部 | 山东省 | 8000.00 |
| 3 | alex | male | 28 | 保洁部 | 山东省 | 10000.00 |
| 4 | 景丽阳 | female | 22 | 教学部 | 北京 | 9000.00 |
| 5 | 张三 | male | 24 | 教学部 | 河北省 | 6000.00 |
| 6 | 李四 | male | 32 | 保安部 | 北京 | 12000.00 |
| 7 | 王五 | male | 38 | 教学部 | 河北省 | 7000.00 |
| 8 | 赵六 | male | 19 | 保安部 | 河北省 | 9000.00 |
| 9 | 猪七 | female | 24 | 保洁部 | 北京 | 9000.00 |
+----+-----------+--------+------+-----------+-----------+----------+
9 rows in set (0.00 sec)
复制代码
where子句: 过滤查询

复制代码
-- where字句中可以使用:

-- 比较运算符:
> < >= <= <> !=
between 80 and 100 值在10到20之间
in(80,90,100) 值是10或20或30
like 'yuan%'
/*
pattern可以是%或者_,
如果是%则表示任意多字符,此例如唐僧,唐国强
如果是_则表示一个字符唐_,只有唐僧符合。两个_则表示两个字符:__
*/

-- 逻辑运算符
在多个条件直接可以使用逻辑运算符 and or not
复制代码
示例:

-- 查询年纪大于24的员工
SELECT * FROM emp WHERE age>24;

-- 查询教学部的男老师信息
SELECT * FROM emp WHERE dep="教学部" AND gender="male";
order:排序

按指定的列进行,排序的列即可是表中的列名,也可以是select语句后指定的别名。

-- 语法:

select *|field1,field2... from tab_name order by field [Asc|Desc]

-- Asc 升序、Desc 降序,其中asc为默认值 ORDER BY 子句应位于SELECT语句的结尾。
示例:

-- 按年龄从高到低进行排序
SELECT * FROM emp ORDER BY age DESC ;

-- 按工资从低到高进行排序
SELECT * FROM emp ORDER BY salary;
group by:分组查询(*****)

GROUP BY 语句根据某个列对结果集进行分组。在分组的列上我们可以使用 COUNT, SUM, AVG等函数进行相关查询。

-- 语法:
SELECT column_name, function(column_name)
      FROM table_name
      WHERE column_name operator value
      GROUP BY column_name;
示例:

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
-- 查询男女员工各有多少人

SELECT gender 性别,count(*) 人数 FROM emp5 GROUP BY gender;

-- 查询各个部门的人数

SELECT dep 部门,count(*) 人数 FROM emp5 GROUP BY dep;

-- 查询每个部门最大的年龄

SELECT dep 部门,max(age) 最大年纪 FROM emp5 GROUP BY dep;

-- 查询每个部门年龄最大的员工姓名

SELECT * FROM emp5 WHERE age in (SELECT max(age) FROM emp5 GROUP BY dep);

-- 查询每个部门的平均工资

SELECT dep 部门,avg(salary) 最大年纪 FROM emp GROUP BY dep;

-- 查询教学部的员工最高工资:

SELECT dep,max(salary) FROM emp11 GROUP BY dep HAVING dep="教学部";

-- 查询平均薪水超过8000的部门

SELECT dep,AVG(salary) FROM emp GROUP BY dep HAVING avg(salary)>8000;

-- 查询每个组的员工姓名
SELECT dep,group_concat(name) FROM emp GROUP BY dep;

-- 查询公司一共有多少员工(可以将所有记录看成一个组)

SELECT COUNT(*) 员工总人数 FROM emp;

             -- KEY: 查询条件中的每个后的词就是分组的字段
limit记录条数限制

SELECT * from ExamResult limit 1;
SELECT * from ExamResult limit 2,5; -- 跳过前两条显示接下来的五条纪录
SELECT * from ExamResult limit 2,2;
正则表达式

SELECT * FROM employee WHERE emp_name REGEXP '^yu';

SELECT * FROM employee WHERE emp_name REGEXP 'yun$';

SELECT * FROM employee WHERE emp_name REGEXP 'm{2}';
回到顶部
多表查询

创建表

View Code
复制代码
mysql> select * from emp;
+----+--------+----------+--------+
| id | name | salary | dep_id |
+----+--------+----------+--------+
| 1 | 张三 | 8000.00 | 2 |
| 2 | 李四 | 12000.00 | 1 |
| 3 | 王五 | 5000.00 | 2 |
| 4 | 赵六 | 8000.00 | 3 |
| 5 | 猪七 | 9000.00 | 1 |
| 6 | 周八 | 7000.00 | 4 |
| 7 | 蔡九 | 7000.00 | 2 |
+----+--------+----------+--------+
7 rows in set (0.00 sec)

mysql> select * from dep;
+----+-----------+
| id | name |
+----+-----------+
| 1 | 教学部 |
| 2 | 销售部 |
| 3 | 人事部 |
+----+-----------+
3 rows in set (0.00 sec)
复制代码
1.笛卡尔积查询

1
select * from emp,dep;
复制代码
mysql> select * from emp,dep;
+----+--------+----------+--------+----+-----------+
| id | name | salary | dep_id | id | name |
+----+--------+----------+--------+----+-----------+
| 1 | 张三 | 8000.00 | 2 | 1 | 教学部 |
| 1 | 张三 | 8000.00 | 2 | 2 | 销售部 |
| 1 | 张三 | 8000.00 | 2 | 3 | 人事部 |
| 2 | 李四 | 12000.00 | 1 | 1 | 教学部 |
| 2 | 李四 | 12000.00 | 1 | 2 | 销售部 |
| 2 | 李四 | 12000.00 | 1 | 3 | 人事部 |
| 3 | 王五 | 5000.00 | 2 | 1 | 教学部 |
| 3 | 王五 | 5000.00 | 2 | 2 | 销售部 |
| 3 | 王五 | 5000.00 | 2 | 3 | 人事部 |
| 4 | 赵六 | 8000.00 | 3 | 1 | 教学部 |
| 4 | 赵六 | 8000.00 | 3 | 2 | 销售部 |
| 4 | 赵六 | 8000.00 | 3 | 3 | 人事部 |
| 5 | 猪七 | 9000.00 | 1 | 1 | 教学部 |
| 5 | 猪七 | 9000.00 | 1 | 2 | 销售部 |
| 5 | 猪七 | 9000.00 | 1 | 3 | 人事部 |
| 6 | 周八 | 7000.00 | 4 | 1 | 教学部 |
| 6 | 周八 | 7000.00 | 4 | 2 | 销售部 |
| 6 | 周八 | 7000.00 | 4 | 3 | 人事部 |
| 7 | 蔡九 | 7000.00 | 2 | 1 | 教学部 |
| 7 | 蔡九 | 7000.00 | 2 | 2 | 销售部 |
| 7 | 蔡九 | 7000.00 | 2 | 3 | 人事部 |
+----+--------+----------+--------+----+-----------+
21 rows in set (0.00 sec)
复制代码
2、内连接

查询两张表中都有的关联数据,相当于利用条件从笛卡尔积结果中筛选出了正确的结果。

1
SELECT * FROM emp,dep WHERE emp.dep_id=dep.id;
OR

1
SELECT * FROM emp INNER JOIN dep ON emp.dep_id=dep.id;
查询结果:

复制代码
+----+--------+----------+--------+----+-----------+
| id | name | salary | dep_id | id | name |
+----+--------+----------+--------+----+-----------+
| 1 | 张三 | 8000.00 | 2 | 2 | 销售部 |
| 2 | 李四 | 12000.00 | 1 | 1 | 教学部 |
| 3 | 王五 | 5000.00 | 2 | 2 | 销售部 |
| 4 | 赵六 | 8000.00 | 3 | 3 | 人事部 |
| 5 | 猪七 | 9000.00 | 1 | 1 | 教学部 |
| 7 | 蔡九 | 7000.00 | 2 | 2 | 销售部 |
+----+--------+----------+--------+----+-----------+
6 rows in set (0.00 sec)
复制代码
这时,我们就可以利用两张表中所有的字段进行查询了

示例:

复制代码
-- 查询李四所在的部门名称

SELECT emp.name,dep.name FROM emp INNER JOIN dep ON emp.dep_id=dep.id WHERE emp.name="李四";

-- 查询销售部所有员工姓名以及部门名称

-- SELECT name FROM emp WHERE dep_id in (SELECT id FROM dep WHERE name="销售部");

SELECT emp.name,dep.name FROM emp INNER JOIN dep ON emp.dep_id=dep.id WHERE dep.name="销售部";
复制代码
3、外连接

1
2
3
--(1)左外连接:在内连接的基础上增加左边有右边没有的结果

SELECT * FROM emp LEFT JOIN dep ON dep.id=emp.dep_id;
复制代码
+----+--------+----------+--------+------+-----------+
| id | name | salary | dep_id | id | name |
+----+--------+----------+--------+------+-----------+
| 2 | 李四 | 12000.00 | 1 | 1 | 教学部 |
| 5 | 猪七 | 9000.00 | 1 | 1 | 教学部 |
| 1 | 张三 | 8000.00 | 2 | 2 | 销售部 |
| 3 | 王五 | 5000.00 | 2 | 2 | 销售部 |
| 7 | 蔡九 | 7000.00 | 2 | 2 | 销售部 |
| 4 | 赵六 | 8000.00 | 3 | 3 | 人事部 |
| 6 | 周八 | 7000.00 | 4 | NULL | NULL |
+----+--------+----------+--------+------+-----------+
7 rows in set (0.00 sec)
复制代码
1
2
3
--(1)外右连接:在内连接的基础上增加右边有左边没有的结果

SELECT * FROM emp RIGHT JOIN dep ON dep.id=emp.dep_id;
复制代码
mysql> SELECT * FROM emp RIGHT JOIN dep ON dep.id=emp.dep_id;
+------+--------+----------+--------+----+-----------+
| id | name | salary | dep_id | id | name |
+------+--------+----------+--------+----+-----------+
| 1 | 张三 | 8000.00 | 2 | 2 | 销售部 |
| 2 | 李四 | 12000.00 | 1 | 1 | 教学部 |
| 3 | 王五 | 5000.00 | 2 | 2 | 销售部 |
| 4 | 赵六 | 8000.00 | 3 | 3 | 人事部 |
| 5 | 猪七 | 9000.00 | 1 | 1 | 教学部 |
| 7 | 蔡九 | 7000.00 | 2 | 2 | 销售部 |
+------+--------+----------+--------+----+-----------+
6 rows in set (0.00 sec)
复制代码
回到顶部
完整性约束

完整性约束是对字段进行限制,从而符合该字段达到我们期望的效果比如字段含有默认值,不能是NULL等 。直观点说:如果插入的数据不满足限制要求,数据库管理系统就拒绝执行操作

唯一约束

唯一约束可以有多个但索引列的值必须唯一,索引列的值允许有空值。

如果能确定某个数据列将只包含彼此各不相同的值,在为这个数据列创建索引的时候就应该使用关键字UNIQUE。

复制代码
CREATE TABLE t5(
id INT AUTO_INCREMENT,
name VARCHAR(20) DEFAULT NULL,
PRIMARY KEY (id),
UNIQUE KEY UK_t5_name (name)
);
-- 建表后添加约束:

alter table t5 add constraint UK_t5_name unique (name);

-- 如果不需要唯一约束,则可以这样删除

ALTER TABLE t5 DROP INDEX UK_t5_name;
复制代码
添加约束和删除约束

1
2
3
4
5
6
7
8
9
10
-- 创建唯一约束:
create unique index UK_t5_name on t5 (name);

-- 建表后添加约束:

alter table t5 add constraint UK_t5_name unique (name);

-- 如果不需要唯一约束,则可以这样删除

ALTER TABLE t5 DROP INDEX UK_t5_name;
自增约束

MySQL 每张表只能有1个自动增长字段,这个自动增长字段通常作为主键,也可以用作非主键使用,但是请注意将自动增长字段当做非主键使用时必须必须为其添加唯一索引,否则系统将会报错。

复制代码
mysql> CREATE TABLE t4(
-> id INT NOT NULL,
-> name VARCHAR(20),
-> age INT AUTO_INCREMENT
-> );

ERROR 1075 (42000): Incorrect table definition; there can be only one auto column and it must be defined as a key
复制代码
可以改为

mysql> CREATE TABLE t4(
-> id INT NOT NULL,
-> name VARCHAR(20),
-> age INT UNIQUE AUTO_INCREMENT
-> );
Query OK, 0 rows affected (0.13 sec)
主键约束

主键是用于唯一标识一条记录的约束,如同身份证。

主键有两个约束:非空且唯一!

创建主键

复制代码
-- 方式1

CREATE TABLE t1(
id INT PRIMARY KEY AUTO_INCREMENT,
name VARCHAR(20)
);

-- 方式2

CREATE TABLE t2(
id INT NOT NULL,
name VARCHAR(20)
);
复制代码
注意:

1、一张表中最多只能有一个主键

2、表中如果没有设置主键,默认设置NOT NULL的字段为主键;此外,表中如果有多个NOT NULL的字段,则按顺序将第一个设置NOT NULL的字段设为主键。

结论:主键一定是非空且唯一,但非空且唯一的字段不一定是主键。

3、主键类型不一定必须是整型

添加主键和删除主键

1
2
-- 添加主键<br>alter table tab_name add primary key(字段名称,...) <br>
-- 删除主键<br>alter table users drop primary key;
注意,如果主键是AUTO_INCREMENT,需要先取消AUTO_INCREMENT,因为AUTO_INCREMENT只能加在KEY上。

1
2
3
4
CREATE TABLE test(num INT PRIMARY KEY AUTO_INCREMENT);<br>
-- 思考,如何删除主键?
ALTER TABLE test modify id int; -- auto_increment没了,但这样写主键依然存在,所以还要加上下面这句
ALTER TABLE test drop primary key;-- 仅仅用这句也无法直接删除主键
复合主键

所谓的复合主键 就是指你表的主键含有一个以上的字段。

如果一列不能唯一区分一个表里的记录时,可以考虑多个列组合起来达到区分表记录的唯一性,形式

①创建时:

1
2
3
4
5
6
create table sc (
studentid int,
courseid int,
score int,
primary key (studentno,courseid)
);
②修改时:

1
alter table tb_name add primary key (字段1,字段2,字段3);
外键约束

外键语法

1
2
3
4
5
外键的定义语法:
[CONSTRAINT symbol] FOREIGN KEY [id] (index_col_name, ...)
REFERENCES tbl_name (index_col_name, ...)
[ON DELETE {RESTRICT | CASCADE | SET NULL | NO ACTION | SET DEFAULT}]
[ON UPDATE {RESTRICT | CASCADE | SET NULL | NO ACTION | SET DEFAULT}]
该语法 可以在 CREATE TABLE 和 ALTER TABLE 时使用,如果不指定CONSTRAINT symbol,MYSQL会自动生成一个名字。

准备表和数据

复制代码
-- 子表
CREATE TABLE emp(
id INT PRIMARY KEY AUTO_INCREMENT,
name VARCHAR(20),
dep_id INT
-- CONSTRAINT emp_fk_emp FOREIGN KEY (dep_id) REFERENCES dep(id) -- 注意外键字段的数据类型必须与关联字段一致
);

-- 主表
CREATE TABLE dep(
id INT PRIMARY KEY AUTO_INCREMENT,
name VARCHAR(20)
);

INSERT emp (name,dep_id) VALUES ("alex",1),
("egon",2),
("alvin",2),
("莎莎",1),
("wusir",2),
("女神",2),
("冰冰",3),
("姗姗",3);

INSERT dep (name) VALUES ("市场部"),
("教学部"),
("销售部");
复制代码
添加外键

现在,删除市场部:

1
2
mysql> DELETE FROM dep WHERE name="市场部";
Query OK, 1 row affected (0.01 sec)
居然删除成功了,不可思议,现在问题来了: alex和莎莎两个人怎么办?

所以,为了避免类似操作,我们需要给两张表建立约束,这种约束称为外键约束。外键的好处:可以使得两张表关联,保证数据的一致性和实现一些级联操作

1
2
3
4
5
6
INSERT dep (id,name) VALUES (1,"市场部"); -- 思考为什么加这一句?

ALTER TABLE emp ADD CONSTRAINT dep_fk_emp
FOREIGN KEY (dep_id)
REFERENCES dep(id);
<br><br>mysql> DELETE FROM dep WHERE name="市场部";<br><br>ERROR 1451 (23000): Cannot delete or update a parent row: a foreign key constraint fail
INNODB支持的ON语句

外键约束对子表的含义: 如果在主表中(比如dep)找不到候选键,则不允许在子表(比如emp)上进行insert/update

外键约束对父表的含义: 在主表上进行update/delete以更新或删除在子表中有一条或多条应匹配行的候选键时,父表的行为取决于:在定义子表的外键时指定的 -- on update/on delete子句

复制代码
-- ------------------------innodb支持的四种方式---------------------------------

cascade方式 在父表上update/delete记录时,同步update/delete掉子表的匹配记录外键的级联删除:如果父表中的记录被删除,则子表中对应的记录自动被删除

FOREIGN KEY (charger_id) REFERENCES ClassCharger(id)
ON DELETE CASCADE;

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

FOREIGN KEY (charger_id) REFERENCES ClassCharger(id)
ON DELETE SET NULL;

Restrict方式 :拒绝对父表进行删除更新操作(了解)

No action方式 在mysql中同Restrict,如果子表中有匹配的记录,则不允许对父表对应候选键 ; 进行update/delete操作(了解)
复制代码
表与表之间的关系

转载于:https://www.cnblogs.com/dbkeeper/p/7524811.html

mysql sql相关推荐

  1. php mysql sql mode_Mysql之SQL Mode用法详解_MySQL

    一.Mysql SQL Mode简介 通常来说MySQL服务器能够工作在不同的SQL模式下,并能针对不同的客户端以不同的方式应用这些模式.这样,应用程序就能对服务器操作进行量身定制以满足自己的需求.这 ...

  2. Atitit.软件GUI按钮与仪表盘--db数据库区--导入mysql sql错误的解决之道

    Atitit.软件GUI按钮与仪表盘--db数据库区--导入mysql sql错误的解决之道 Keyword::截取文本文件后部分 查看提示max_allowed_packet限制 Target Se ...

  3. Mysql SQL Mode详解

    Mysql SQL Mode简介 MySQL服务器能够工作在不同的SQL模式下,并能针对不同的客户端以不同的方式应用这些模式.这样,应用程序就能对服务器操作进行量身定制以满足自己的需求.这类模式定义了 ...

  4. 导出mysql sql语句吗_mysql sql语句导入与导出

    mysql sql语句导入与导出 导入: mysql -u root -p 数据库名 如: C:/mysql/bin>mysql -u root -p house < c:/1-1.txt ...

  5. mysql sql语句大全

    1.说明:创建数据库 CREATE DATABASE database-name 2.说明:删除数据库 drop database dbname 3.说明:备份sql server --- 创建 备份 ...

  6. mysql sql优化书籍_MySQL SQL优化的正确姿势

    大家好,我是知数堂SQL 优化班老师 网名:骑龟的兔子 已经很久没写文章了 今天分享一篇优化SQL 案例 slow query 里有如下 SQL 看下执行计划如下 从执行计划可以看出C表全表扫描了 那 ...

  7. mysql inception web_基于Inception搭建MySQL SQL审核平台Yearing

    Inception 1. Inceptionj简介 Inception是一款针对MySQL的SQL语句审核自动化运维工具.使用Inception,将会给DBA带来更大的便利性,将DBA从繁冗的工作中解 ...

  8. oracle rds 运维服务_从运维的角度分析使用阿里云数据库RDS的必要性–你不应该在阿里云上使用自建的MySQL/SQL Server/Oracle/PostgreSQL数据库...

    开宗明义,你不应该在阿里云上使用自建的MySQL or SQL Server数据库,对了,还有Oracle or PostgreSQL数据库. 云数据库 RDS(Relational Database ...

  9. mybatis mysql merge_使用Mybatis和druid连接池报错 merge sql error, dbType mysql, sql

    在项目中用mybatis查询的时候遇到一个这样的问题,抛错详情如下: merge sql error, dbType mysql, sql : select r.id from role r inne ...

  10. mysql sql归类_带有归类SQL强制转换SQL Server归类介绍

    mysql sql归类 SQL Server collation refers to a set of character and character encoding rules, and infl ...

最新文章

  1. Java项目:化妆品商城系统(java+Springboot+ssm+mysql+jsp+maven)
  2. 什么是Python?好学吗?
  3. golang库context学习
  4. Java学习笔记30
  5. 想体验从活火山上滑下来的刺激感?VR来成全你
  6. 【集合论】关系闭包 ( 关系闭包相关定理 )
  7. ftp主要完成与远程计算机的连接,2015计算机三级《网络技术》复习重点:远程登录服务和FTP服务...
  8. mongodb java and or,【MongoDB】-Java实现对mongodb的And、Or、In操作
  9. 全球1/10女性受到盆腔脏器脱垂困扰
  10. ISO7637-2测试case汇总
  11. S3接口访问华为云OBS
  12. 题目 2260: 求arccos值
  13. android:layout_weight=1,Android中的Layout_weight(权重)详解
  14. Cortex-M3/M4(5)-软件移植
  15. wps 字体对系统无效_linux版WPS系统缺失字体的解决办法
  16. 购买服务器 操作系统选什么区别吗,购买服务器选择什么操作系统
  17. 电商专题-电商项目开发规模
  18. 微信小程序请求及封装请求方式
  19. Selenium浏览器自动化测试工具
  20. 孕妇不能吃哪些食物?(协和妇产权威版)

热门文章

  1. mysql 主从 外部连接_集群之MYsql主从服务之引伸出Mysql互为主从(环形结构)外加简单实现自己个人的负载均衡器(3)-阿里云开发者社区...
  2. JDBC学习(九、连接池技术)
  3. docker-compose部署nacos 集群超过2个容器的问题
  4. 串口 浮点数 结构体_quot;结构体quot;和quot;共用体quot;在单片机中的妙用
  5. python中文列名报错__mssql.MSSQLDatabaseException:(207,b“无效列名'Hello'。DBLib错误消息20018...
  6. 阶段5 3.微服务项目【学成在线】_day02 CMS前端开发_02-vuejs研究-vuejs基础-MVVM模式...
  7. MVN TEST指定运行脚本
  8. (转载)Jvm工作原理学习笔记
  9. python解决一些错误换行问题
  10. HDU-1716 排列2 组合数