数据库基础操作

'''
1.数据库与表的剩余操作
	编码配置、引擎介绍
2.数据库字段的操作
3.数据库的数据类型
4.数据库字段的约束条件
'''

数据库配置

# 通过配置文件统一配置的目的:统一管理 服务端(mysql),客户端(client)
	配置了mysql(服务端)的编码为utf8,那么在创建的数据库,默认编码都采用utf8
   
# 配置流程
    1.在mysql安装目录下,创建配置文件 my.ini 
    2.配置文件内容并保存
    	[mysqld] # 服务器配置
   		port=3306 # 可以修改数据库默认端口(如果数据库端口被其他软件占用)
        character-set-server=utf8 # 编码格式
        collation-server=utf8_general_ci # 排序方式(默认跟着编码格式走)
        
        [client] # mysql自己的客户端教[mysql],配置[client]即配置了[mysql],也配置了其他存在方式的客户端,比如Navicat可视化客户端
        default-character-set=utf8 # 编码格式
        
        [mysql] # 本地的mysql自己的客户端
        user=root # 账号
        password=123 # 密码
        # 配置了这个之后就不需要输入账号密码,直接在终端输入 mysql 就可以直接进入
	3.重启数据库服务(就可以生效配置)

数据库修改信息

# 修改字符编码
mysql>: alter database 数据库名 charset=编码格式;

用户操作: 重点

# 为特定的数据库分配有这个数据库操作权限的用户
mysql>: grant 权限们 on 数据库.表 to 用户名@'主机名' identified by '密码';

# 1. all:所有权限
# 2. 数据库名.*数据库下所有的表
# 3. 用户名@'localhost':本机可以通过用户名用户登录
# 4. identified by '123':密码为 123
eg>: grant all on db1.* to root@'localhost' identified by '123';


# 撤销权限
mysql>: revoke 权限1,权限2,... on 数据库名.表名 from 用户名@'主机名'
# 禁掉本地cheer用户对数据库所以表的drop权限
eg: mysql> revoke drop on db1.* from cheer@'localhost';

# 删除用户
drop user 用户名@'主机名';

表的修改

# 修改表名
mysql>: alter table 旧表名 rename 新表名;   (最好别使用这种方式)

# 修改字段名
mysql>: alter table 表名 change 旧字段名 新字段名 类型;

# 修改字段属性
mysql>: alter table 表名 modify 表名 修改后类型;

创建表的完整用法

# 长度和约束在某些情况下是可以省略的
mysql>: create table 表名(
	属性名 类型 约束,
    ...
)engine=引擎名 default charset=utf8;

数据库表的引擎:驱动数据的方式-数据库优化

# 前提: 引擎是建表的规定,提供给表使用,不是数据库

# 展示所有引擎
mysql>: show engines; (可以添加一个 G 看的清楚些!)

# innodb(默认): 支持事务,行级锁,外键
mysql>: create table 表名(字段名 类型)engine=innodb;

# myisam:查询效率要优于innodb,当不需要支持事务,行级锁,外键,可以通过设置myisam来优化数据库的查询速度
mysql>: create table 表名(字段名 类型)engine=myisam;

# blackhole:黑洞,存进去的数据全都会消失(可以理解为不存数据)
mysql>: create table 表名(字段名 类型)engine=blackhole;

# memory:表结构是存储在硬盘上的,但是表数据全部存储在内存中(不是很常用)
mysql>: create table 表名(字段名 类型)engine=memory;

数据库的模式

# mysql 5.7 以后默认都是安全模式

# mysql 5.6 版本
sql_model=no_engine_substitution # 非安全性,默认
sql_model=strict_trans_tables # 安全性

# 查看当前数据库模式:
show variables like '%sql_mode%'; # %匹配0~n个任意字符 => 模糊查询

# 临时设置为安全模式,服务器重启后会被重置
mysql>: set global sql_model='strict_trans_tables'; # 在root用户登录状态下
# 在设置后,quit断开你数据后重连(服务器不重启)就会进入安全模式

# 安全模式下,非安全模式下sql执行的警告语句,都会抛异常
eg>: create table t1(name char(2));
eg>: insert into t1 values ('ab') # 正常  两个字符 
eg>: insert into t1 values ('cheer') # 错误  五个字符超过范围,不会像非安全模式一样不会报错和出现数据丢失的插入数据,而是直接报错

mysql支持的数据类型

整型

类型 所占字节数 取值范围
tinyint 1个字节 -128~127
smallint 2个字节 -32768~32767
mediumint 3个字节 -8388608~8388607
int 4个字节 -2147483648~2147483647
bigint 8个字节 -9,223,372,036,854,775,808~9,223,372,036,854,775,807
# 约束
	1.unsigned: 无符号 (负数的数量会加到正数上面)
			eg:	mysql>: create table t2(x int unsigned);
			mysql>: insert into t2 values(10),(-10) # 输出  10 , 0
	2.zerofill: 0填充 (就会在输入的数值前添加一个0)
		eg:	mysql>: create table t2(x int zerofill);
			mysql>: insert into t2 values(10) # 输出  010
			
# 整型的长度由所占的(取值范围)决定,可以自定义长度,但是不影响所占字节(取值范围)
# 所有整型变量的长度一般不写

浮点型

类型 所占字节数 取值范围
float(M, D) 4字节 3.4E–38~3.4E+38
double(M, D) 8字节 1.7E–308~1.7E+308
decimal(M, D) 所在字节M,D大值基础上+2 看M,D值变更取值范围
# 在安全模式下测试浮点类型
- (M,D) => M为位数,D为小数位,M要大于D
float(255,30):精度最低,最常用
double(255,30):精度高,但占位多
decimal(65,30):不同于 float,double 它是按照字符串存的,输入进去什么样,拿出来什么样,全精度

字符串:数据优化-char效率要高于varchar

# 类型
char: 定长,永远采用设置的长度存储数据,就是如果设置4位,但是存的是三位,也会按照4位的长度存
varchar: 不定长,在设置的长度范围内,改变长度的存储数据

# 宽度
- 限制存储宽度
	char(4): 存 "a","ab","abc","abcd"都采用 4 个长度,"abcde"只能存储4位(安全模式下报错)
	varchar(4) :存"a","ab","abc","abcd"分别采用 1,2,3,4 个长度存储,"abcde"只存储前4位(安全模式下报错)
	
# 总结
char就按照定长存储,如果数据长度变化大,通常更占用空间,但是存取数据按照固定长度操作,效率高
varchar存储数据是,会先计算存储数据的长度,动态变长存储数据,所以一般较省空间,但是计算是需要耗时的,所以效率低
varchar计算出的数据长度信息也是需要开辟空间来存储,存储在数据头(数据开始前)中,也需要额外消耗1~2个字节
所以如果数据都是固定长度,或是小范围波动,char相比就不会更占空间,且效率高

时间

# 类型
year: yyyy(1901 / 2155)
date: yyyy-MM-dd(1000-01-01 / 9999-12-31)
time: HH:mm:ss
datetime: yyyy-MM-dd HH:mm:ss(1000-01-01 00:00:00 / 9999-12-31 23:59:59) # 用的最多
timestamp: yyyy-MM-dd HH:mm:ss(1970-01-01 00:00:00/2038-01-19 23:59:59)

# datetime: 8个字节,可以为null
# timestamp: 4个字节,不插入值会有默认值,就是填充系统当前时间

枚举与集合

# 枚举与集合: 为某一个字段提供选项(取值必须在提供的范围内)
	- 枚举就选取 1 个 (enum)
			- 枚举:mysql>:因为就选取 1 个,所以和平常插入没啥区别
	- 集合可以选取 null 或者 多个 (set)
			- 集合插入格式:mysql>: insert into tc2 values('ruakei_1', '女', '男,女,哇塞');  

约束

primary key : 主键,唯一的标识,不设置为默认找第一个,不能为空,为设置数据库则会创建一个隐藏的主键,每个表是必须有一个主键的
foreign key : 外键,是用于多表的约束
unique : 唯一约束,该字段需要保证唯一,不可以重复
auto_increment : 自增约束,只能生效于给key的int类型字段,是一个辅助修饰,一个表中只能增加一个自增字段
not null : 非空约束,不能为空的一个约束
以上是五大约束

unsigned : 无符号-存储从0开始
zerofill : 0填充-存整数时,如果数据长度小于取值范围长度,会在数字左方用0填充

"""
1. 字段的修改,添加,删除
2. 多表关系(外键)
3. 单表详细操作:增删改,查(各种条件)
"""

字段操作

# 修改
alter table 表名 modify 字段名 类型 default ''; #  default 不输入时的返回值
alter table 表名 change 旧字段名 新字段名 类型 default '';

# 增加
alter table 表名 add 字段名 类型 [约束]; # 这个是增加到末尾

alter table 表名 add 字段名 类型 [约束] first # 这个是增加到开头

alter table 表名 add 字段名 类型 [约束] after 指定字段名 # 这个是增加到指定字段名后面

alter table 表名 drop 字段名; # 这个是删除字段名

多表关系

# 一对一: 学生-学号
- 外键在任何一方都可以,但是外键要设置唯一键

1. 解析 学生-学号
	一个学生只有一个学号,一个学号只可以对应一个学生,所以这个关系是一对一.
# 一对多: 学校-学生
- 外键必须放在多的一方,此时外键值不唯一,也就是不需要设置唯一键

1. 解析 学校-学生
	一个学生只可以在一个学校上学,但是一个学校可以包含多个学生上学,所以这个关系是一对多
# 多对多: 课程-学生
- 一定要创建第三张表(关系表),每一个外键值都不唯一,可以看做多个外键值联合唯一,也就是只要数据不完全重复,就可以输入

1.解析 课程-学生
	一个学生可以上多门课,例如语数英,但是一门课程也可以有多可以学生去学,例如小明和小刚都学习数学,所以这是一个多对多关系	

外键

1. 外键的字段名可以自定义(名字随意),通常的命名规范(关联表_关联字段)

2. 外键要通过 foreign key 建立表与表之间的关联

3. 格式: foreign key (所在表的外键字段) references 关联表(关联字段)
	eg: foreign key student_id references course(id)
				  学生表中的id           所在课程表(id)
4. 级联关系:
	- 级联更新: on update cascade
	- 级联删除: on delete cascade
# 重点
	外键字段本身可以唯一也可以不唯一,但是外键关联的字段一定唯一

一对一:无级联关系

# 创键学生表
create table student(
	id int primary key,
    name char(20)
);

# 创建学号表
create table number(
    id int primary key,
    student_id int,
    foreign key(student_id) references student(id)
);


#####  没有设置外键的表(学生表) --> 子表
#####  设置外键的表(学号表) --> 主表

# 创建表操作
1.创建表的时候得按照先后顺序,先创键子表

# 插入数据操作
1.插入值得时候得按照先后顺序,先给子表插入数据
2.如果插入数据的时候,子表中id不存在,主表就插入不了数据

# 修改数据操作
1.如果修改子表中被外键关联起来的数据,就会报错;修改没有关联的数据就可以修改
2.如果修改主表是不可以修改的,因为没有设置级联的关系

# 删除数据操作
1.在子表中删除数据删除不了,会报错
2.在主表中删除数据是可以的,但是子表不会有影响,仅仅删除主表的数据

一对一:有级联关系

# 创键学生表
create table student(
	id int primary key,
    name char(20)
);

# 创建学号表
create table number(
    id int primary key,
    student_id int,
    foreign key(student_id) references student(id)
    on delete cascade
    on update cascade
);


#####  没有设置外键的表(学生表) --> 子表
#####  设置外键的表(学号表) --> 主表

# 创建表操作
1.创建表的时候先创建子表,在创建主表

# 插入数据操作
1.插入数据的时候要先给子表插入数据
2.给主表插入数据的时候,如果子表中没有对应的外键指定的字段,也是插不进去的

# 修改数据操作
1.修改子表中关联的数据,主表中的也会随之改变(设置了更新级联)
2.主表是不可以修改关联的字段值

# 删除数据操作
1.在主表中删除数据,子表中的数据不会有影响
2.在子表中删除数据,主表中关联的数据会一起删除

一对多

# 创建学校表 (学校编号,学校名字)
create table school(
    id int primary key,
	name char(10)
)
# 创建学生表 (学生编号,学生名字,学校编号)
create table student(
	id int primary key,
    name char(10),
    school_id int
    foreign key (school_id) references school(id)
    on delete cascade
    on update cascade
)

#####  没有设置外键的表(学校表) --> 子表
#####  设置外键的表(学生表) --> 主表

# 创建表操作
1.创建表的时候先创建子表,在创建主表

# 插入数据操作
1.插入数据的时候要先给子表插入数据
2.给主表插入数据的时候,如果子表中没有对应的外键指定的字段,也是插不进去的

# 修改数据操作
1.修改子表中关联的数据,主表中的也会随之改变(设置了更新级联)
2.主表是不可以修改关联的字段值

# 删除数据操作
1.在主表中删除数据,子表中的数据不会有影响
2.在子表中删除数据,主表中关联的数据会一起删除

多对多

# 创建学生表(学生编号,学生名字)
create table student(
    id int primary key,
    name char(10)
    );
# 创建课程表(课程编号,课程名字)
create table course(
    id int primary key,
    name char(10)
    ); 
# 创建关系表(关系编号,学生编号,课程编号)
create table tree(
    id int primary key,
    student_id int,
   	foreign key(student_id) references student(id)
    on delete cascade
    on update cascade,
    course_id int ,
    foreign key(course_id) references course(id)
    on delete cascade
    on update cascade,
   	unique(student_id,course_id)
    );
 
#####  没有设置外键的表(学生表,课程表) --> 子表
#####  设置外键的表(关系表) --> 主表

# 创建表操作
1.创建表的时候先创建子表,在创建主表

# 插入数据操作
1.插入数据的时候要先给子表插入数据
2.给主表插入数据的时候,如果子表中没有对应的外键指定的字段,也是插不进去的

# 修改数据操作
1.修改子表中关联的数据,主表中的也会随之改变(设置了更新级联)
2.主表是不可以修改关联的字段值

# 删除数据操作
1.在主表中删除数据,子表中的数据不会有影响
2.在子表中删除数据,主表中关联的数据会一起删除

知识概要

1. 单表查询
2. 多表查询
3. 子查询

单表查询

1.增
insert [into] 表名[字段名] values 字段值;
2.删
delete from 表名 where 条件
# 不加[where 条件]直接清空表的数据
3.改
update 表名 set 字段=值 where 条件
4.查
select 字段 from 表名 where 条件

# import
	- 条件:from,where,group by,having,distinct,order by,limit => 层层筛选后的结果
	- 注: 一条查询语句,可以拥有多种筛选条件,条件的顺序必须按照上方顺序进行逐步筛选,distinct
	稍有特殊(书写位置),条件的种类可以不全
	- 可以缺失,但不能乱序

去重: distinct

# 创建一个简单的表
mysql>: 
create table t1(
    id int,
    x int,
    y int
)
# 插入数据
mysql>: insert into t1 values(1,1,1),(2,1,1),(3,1,2),(4,1,2),(5,2,3),(6,2,3);
# 使用distinct查找数据
mysql>: select distinct x,y from t1;    # 结果:  1,1 1,2 2,3
mysql>: select distinct y from t1;   # 结果: 1 2 3

数据准备

CREATE TABLE `emp`  ( 
  `id` int(0) NOT NULL AUTO_INCREMENT,
  `name` varchar(10) NOT NULL,
  `gender` enum('男','女','未知') NULL DEFAULT '未知',
  `age` int(0) NULL DEFAULT 0,
  `salary` float NULL DEFAULT 0,
  `area` varchar(20) NULL DEFAULT '中国',
  `port` varchar(20) DEFAULT '未知',
  `dep` varchar(20),
  PRIMARY KEY (`id`)
);

INSERT INTO `emp` VALUES 
	(1, '小明', '男', 42, 10.5, '上海', '浦东', '学生会'),
	(2, '小刚', '男', 38, 9.4, '山东', '济南', '学生会'),
	(3, '小红', '女', 30, 3.0, '江苏', '张家港', '自管会'),
	(4, '小刘', '女', 28, 2.4, '广州', '广东', '学生会'),
	(5, '小陈', '男', 28, 2.4, '江苏', '苏州', '自管会'),
	(6, '小赵', '男', 18, 8.8, '中国', '黄浦', '社联'),
	(7, '小懒', '男', 18, 8.8, '安徽', '宣城', '社联'),
	(8, '小喜', '男', 28, 9.8, '安徽', '巢湖', '自管会'),
	(9, '小安', '女', 36, 1.2, '安徽', '芜湖', '学生会'),
	(10, '小仉', '男', 36, 5.8, '山东', '济南', '自管会'),
	(11, '小吴', '女', 28, 1.2, '山东', '青岛', '学生会'),
	(12, '小孙', '男', 30, 9.0, '上海', '浦东', '社联'),
	(13, '小汪', '男', 30, 6.0, '上海', '浦东', '社联'),
	(14, '小艺', '女', 30, 6.0, '上海', '浦西', '学生会'),
	(15, '超哥', '男', 18, 12.0, '上海', '陆家嘴', '校长室');

常用函数

1. # 拼接 - concat(),concat_ws()
- concat(): 改变查询到的数据的输出样式,可以在两个字段间加连接符.
	eg: select 字段1,concat(字段2,'-',字段3) from 表名;
- concat_ws(): 也是改变查询到的数据的输出样式,但是连接符是放在字段名前面的.
	eg: select 字段1,concat_ws('-',字段1,字段2) from 表名;
	- 在concat_ws()中必需写这个连接符,concat()中没必要必须写
	
2. # 大小写 - upper(),lower()
- upper():将查询到的数据输出改为大写
- lower():将查询到的数据输出改为小写

3. # 浮点型操作 - ceil(),flool(),round()
- ceil(): 将查询到的浮点型数据,只要小数点后面的数大于0,就会 "+1"
- flool(): 将查询到的浮点型数据,小数点后面的数不管多少抛弃不要,"只要整数部分"
- round(): 将查询到的浮点型数据"四舍五入"

4. # 整型 
- 如果查询到的数据是整型,就可以"对查询到的数据进行运算"

条件: where

1. # 比较
- 可以使用 '>','<','>=','<=','=','!=' 运算符进行比较运算.
eg: select name from emp where age>30;  # 在emp表中查询age大于30岁的人的名字

2. # 区间
- between 开始 and 结束
- in(自定义容器)
eg: select name from emp where age between 20 and 40; # 在emp表中查询age在20到30岁之间的名字
eg: select name from emp where age in(18,20,30); # 在emp表中查询age为18,20,30岁的名字

3. # 逻辑
- not and or
eg: select name from emp where age=30 and dep='社联'; # 在emp表中查询age为30岁,并且在社联的名字

4. # 相似
- like 配合 <'_':只匹配一个字符;'%':匹配0~n任意个字符> 使用.
eg: select name from emp where age like '_8'; # 在emp表中查询age个位数为8的人的名字

5. # 正则语法
- regexp
- sql只支持部分语法,支持'.','*','[]'
- []:支持 '[0-9]','[a-z]','[A-Z]'
eg: select * from emp where name regexp '.*[0-9]'; # 在emp表中查询数据名字后面带有0到9数字的人的所有数据
'.*[0-9]'分析: 这个的意思是一个名字中必须在末尾有一个数字,并且数字前必须有一个或多个字

分组与筛选: group by,having

where与having

# 表象:在没有分组的情况下,where和having的结果是相同的
# 重点:having可以对聚合函数的结果进行筛选

- 其实就是因为语句有严格的先后顺序, where 必须放在最前面,但是这样就不能对查询到的数据进行再判断,所以就不去使用 having 对数据进行我们需要的处理

聚合函数

1.max():最大值
2.min():最小值
3.avg():平均值
4.sum():和
5.count():计数
6.group_concat():组内字段拼接,用来查看组内包含的所有字段值

分组查询 group by

# 在sql_mode没有 ONLY_FULL_GROUP_BY 限制下,可以执行,但结果没有意义
# 有 ONLY_FULL_GROUP_BY 限制,报错
主要是针对这个语句:
	select * from emp group by dep;
# 分组后,表中的数据考虑的范围就不是单条数据了,因为每个分组包含着多条记录,参照分组字段,对每个分组中的多条记录统一处理
# eg: 按部门分组,每个部门都有哪些人,最高薪资,最低的薪资,平均的薪资,组里一共有多少人

# 将多条数据统一处理,这种方式就叫聚合
# 每个部门都有那些人,最高薪资,最低的薪资,平均的薪资都称之为 聚合结果 - 聚合函数操作的结果
# 注: 参与分组的字段,也归于 聚合结果

mysql>: 
select 
	dep 部门,
	group_concat(name) 成员,
	max(salary) 最高薪资,
	min(salary) 最低薪资,
	avg(salary) 平均薪资,
	sum(salary) 总薪资,
	count(gender) 人数
from emp group by dep;

mysql>: select 
	dep 部门,
	max(age) 最高年龄
from emp group by dep;

# 总结:分组后,查询条件只能为 分组字段 和 聚合函数操作的结果

分组后的having

having 可以对聚合结果在进行筛选, where 不可以
having 一般是配合 group by 和 聚合函数一起使用

排序

排序规则

1. order by 字段1 [asc/desc],字段2 [asc/desc];
- 默认是 asc 升序排序,所以可以不写
- desc 是降序排序
- 如果字段1值中有重复的,就会按照字段2的规则排序,以此往后类推

分组状态下

# eg:查询各部门中的平均薪资按照降序排序
select avg(salary) from emp group by dep order by avg(salary) desc;

限制 limit

1. limit '查询多少条'
	- select * from emp limit 3; # 查询从第一条开始的三条数据
2. limit '跳过几条','查询多少条'
	- select * from emp limit 3,2; # 先跳过3条数据,查询从第四条开始的2条数据

连表查询

连接

1. 连接:将有联系的多张表通过关联(有联系就像,不一定是外键)字段,进行连接,形成一张拼接起来的大表.
2. 连表查询:在大表的基础上进行查询,就称之为连表查询
3. 将表与表建立连接的方式有四种
	- 内连接 '表1' inner join '表2' on 表1.字段名=表2.字段名;
	- 左连接 '表1' left join '表2' on 表1.字段名=表2.字段名;
	- 右连接 '表1' right join '表2' on 表1.字段名=表2.字段名;
	- 全连接 '表1' left join '表2' on 表1.字段名=表2.字段名
			union
			'表1' right join '表2' on 表1.字段名=表2.字段名;

一对多数据准备

mysql>: create database db1;
mysql>: use db1;

mysql>: 
create table dep(
	id int primary key auto_increment,
	name varchar(16),
	work varchar(16)
);
create table emp(
	id int primary key auto_increment,
	name varchar(16),
	salary float,
	dep_id int
);
insert into dep values(1, '市场部', '销售'), (2, '研发部', '研发'), (3, '管理部', '开会');
insert into emp(name, salary, dep_id) values('Anla', 3.0, 2),('Bob', 2.0, 2),('Can', 10.0, 1),('Dear', 88888.0, 2),('Ella', 8.0, 1),('Fly', 1.2, 0);

笛卡尔积

# 笛卡尔积:集合 X{a,b} * Y{q,w,e} => Z{{a,q},{a,w},{a,e},{b,q},{b,w},{b,e}}

select * from emp,dep;  # 像这样查询两张表,就会产生笛卡尔积

# 总结:这个数据没卵用,就只是说一下这种查询过后的现象

内连接

内连接 '表1' inner join '表2' on 表1.字段名=表2.字段名; # inner 可以省略
select 
	emp.id,emp.name,salary,dep.name,work 
from emp inner join dep on emp.dep_id = dep.id 
order by emp.id;
# 查询emp表的id,name,salary,dep表的name,work并且按照emp.id的升序排序,保留有连接的数据

# 总结:只保留两个表有关联的数据

左连接

左连接 '表1' left join '表2' on 表1.字段名=表2.字段名;
select 
	emp.id,emp.name,salary,dep.name,work 
from emp left join dep on emp.dep_id = dep.id 
order by emp.id;
# 查询emp表的id,name,salary,dep表的name,work并且按照emp.id的升序排序,保留左表的数据

# 总结:保留两个表中左表的所有的数据,左表中有的数据,右表没有相应的数据,就会以null代替右表中的数据显示在总的表中.

右连接

右连接 '表1' right join '表2' on 表1.字段名=表2.字段名;
select 
	emp.id,emp.name,salary,dep.name,work 
from emp right join dep on emp.dep_id = dep.id 
order by emp.id;
# 查询emp表的id,name,salary,dep表的name,work并且按照emp.id的升序排序,保留右表的数据

# 总结:保留两个表中右表的所有的数据,右表中有的数据,左表没有相应的数据,就会以null代替左表中的数据显示在总的表中.

全连接

全连接 '表1' left join '表2' on 表1.字段名=表2.字段名
       union
       '表1' right join '表2' on 表1.字段名=表2.字段名;
# 因为mysql中没有全连接的方法,所以我们使用如上方法可以达到相同的效果
select 
	emp.id,emp.name,salary,dep.name,work 
from emp left join dep on emp.dep_id = dep.id 
union
select 
	emp.id,emp.name,salary,dep.name,work 
from emp right join dep on emp.dep_id = dep.id 
order by id;
# 查询emp表的id,name,salary,dep表的name,work并且按照emp.id的升序排序,保留两个表的所有数据.

# 坐标的数据和右表的数据都被保留,彼此没有对应关系则就填充null

一对一与一对多情况一致

# 查询的时候:
# 只有两张表,所以建立连接直接可以建立连接

多对多

# 查询的时候:
# 子表1和关系表建立连接,再子表2和关系表建立连接

联合分组

# 其实就是更加精确的划分组

子查询

1. 增: insert into 表 select子查询
2. 删: delete from 表 where 条件是select子查询(查询的表不能与delete的表相同)
3. 改: update 表 set 字段=值 where 条件是select子查询 (查询的表不能与update的表相同
4. 查:  select 字段 from where 条件是select子查询

all 与 any: 区间修饰条件

# 语法规则
1. where id in (1,2,3) => "id是1或者2或者3"
2. where id not in (1,2,3) => "id不是1,2,3中的任意一个"
3. where money < all(1,2,3) => "money小于1,2,3,就是money小于1"
4. where money > all(1,2,3) => "money大于1,2,3,就是money大于3"
5. where money < any(1,2,3) => "money只要小于其中一个就可以,也就是只要小于3就行"
6. where money > any(1,2,3) => "money只要大于其中一个就可以,也就是大于1就可以"

视图: view

# 视图:
	1. 视图是存在于内存中的临时表
	2. 视图的创建依赖select语句,所以就是select语句操作的结果形成的表
	3. 视图支持对数据的增删改查
	4. 视图不允许对视图表的字段做修改
	5. 视图不仅支持创建,也支持更新和删除

# 创建视图
1. create view 视图名 [这里可以设置字段别名] as select 语句; # 只创建
eg: create view stu_view (学生名字,学生年龄) as select name,age from stu; "查询stu表的学生名字和年龄生成视图"

2. create or replace view 视图名 [字段别名] as select 语句; # 存在视图就替换,不存在就创建

3. alter view 视图名 [字段别名] as select 语句; # 只替换视图,不存在就不可以

# 删除视图
drop view 视图名


# 视图可以作为正常表来完成连查询
" 视图可以作为正常表来完成连查询"
- 视图可以作为正常表来完成连查询

视图的增删改

1. '视图的增删改操作是和原表相互映射的'
2. '视图的存在就是可以隐藏字段名,但是也增加了数据操作的时间,因为需要把数据映射给原表,操作原表也会把数据映射给视图'
3. '视图的表结构存在,真实表也就是原表的数据存在,那么该视图就是可以使用的'

事务

# 事务
- 就是一条业务需要多条sql参加,参与的sql会形成一个整体,这个整体就是事务
- 简单来说: 事务 - 保护多条执行的sql语句
- 事务可以保证数据的安全性

# 事务的四大特性
1. 原子性:'事务中的sql语句是一个不可分割的单位,要么同时成功,要么就不成功'
2. 一致性:'在事务前的数据和事务后的数据必须保持数据的完整性'
3. 隔离性:'就是多个用户并发访问数据的时候,一个用户的事务不能被其他用户的事务干扰,多个并发事务之间的数据要相互隔离'
4. 持久性:'持久性是指事务一旦被提交,他对数据的改变是永久性的,接下里数据库发生故障也不会对数据产生影响'

# mysql中执行事务

mysql>: begin
mysql>: select语句1
mysql>: select语句2
mysql>: ...
mysql>: commit =>'提交数据,数据发生改变' | rollback =>'回滚,上述sql语句作废,数据不变'

原文地址:https://www.cnblogs.com/xiongchao0823/p/11679573.html