MySQL总结

MySQL总结_第1张图片

文章目录

  • 前言
  • 一、MySQL中的数据类型
  • 二、MySQL数据类型与Java数据类型对照
  • 三、DQL语句顺序
  • 四、常用函数
  • 五、group by(分组)
  • 六、order by(排序)
  • 七、连接查询
  • 八、常用查询
    • 多行子查询
    • 行查询
    • select后面
    • from后面
    • exists后面
    • limit分页查询
    • union联合查询
  • 九、CRUD操作
  • 十、库表约束操作
  • 十一、index(索引)
  • 十二、事务(Transaction)的操作
  • 十三、视图
  • 十四、DBA命令
  • 十五、数据库设计三范式
  • 十六、DDL/DML/DQL/DCL
  • 总结


前言

  • 数据库(Database,DB):是按照数据结构来组织,存储和管理数据的仓库
  • 典型特征:数据的结构化、数据间的共享、减少数据的冗余度,数据的独立性
  • 数据表:数据表是关系数据库的基本存储结构,二维数据表有行(Row),和列(Column)组成,也叫作记录(行)和字段(列)

一、MySQL中的数据类型

MySQL中的数据类型

二、MySQL数据类型与Java数据类型对照

MySQL数据类型与Java数据类型对照

三、DQL语句顺序

– 完整的DQL语句顺序:
select

from

where

group by

having

order by

limit …

四、常用函数

MySQL常用函数

五、group by(分组)

代码如下(示例):

use myemployees;
-- 查询邮箱中包含a字符的每个部门的平均工资
select avg(salary),department_id
from employees
where email like '%a%'
group by department_id;

-- 查询有奖金的每个领导手下员工的最高工资
select max(salary),manager_id
from employees
where commission_pct is not null
group by manager_id;

-- 查询每个部门的员工个数>2
select count(*),department_id
from employees
group by department_id
having count(*)>2

-- 查询每个工种有奖金的员工的最高工资>12000的工作编号和最高工资
select job_id,max(salary)
from employees
where commission_pct is not null
group by job_id
having max(salary) > 12000;

-- 查询领导编号>102的每个领导手下的最低工资>5000的领导编号是哪个,以及其最低工资
select manager_id,min(salary)
from employees
where manager_id > 102
group by manager_id
having min(salary) > 5000;

六、order by(排序)

代码如下(示例):

-- 查询员工信息,要求先按工资排序,再按员工编号排序,由高到低
select * from employees
order by salary desc,employee_id desc;

-- 查询员工的姓名和部门号和年薪,按年薪降序,按姓名升序
select last_name,department_id,salary*12*(1+ifnull(commission_pct,0)) 年薪
from employees
order by 年薪 desc,last_name asc;

-- 选择工资不在8000到17000的员工的姓名和工资,按工资降序
select last_name,salary
from employees
where salary not between 8000 and 17000
order by salary desc;

-- 查询邮箱中包含e的员工信息,并先按邮箱的字节数降序,再按部门号升序
select *
from employees
where email like '%e%'
order by length(email) desc,department_id asc;

-- 按年薪的高低显示员工的信息和年薪 【按表达式排序】
select *,salary*12*(1+ifnull(commission_pct,0)) 年薪
from employees
order by salary*12*(1+ifnull(commission_pct,0)) desc;

-- 按员工姓名的长度显示员工的姓名和工资【按函数排序】
select length(last_name) 长度,last_name,salary
from employees
order by length(last_name) desc;

七、连接查询

MySQL连接查询

八、常用查询

多行子查询

代码如下(示例):

-- in() any()其中任意一个 all()所有 exists()

-- 查询location_id是1400或1700的部门编号
select distinct department_id
from departments
where location_id in(1400,1700);

-- 查询工种比job_id为“IT_PROG"工种'任一'工资低的员工的员工号、姓名、job_id 以及 salary
select employee_id,last_name,job_id,salary
from employees 
where salary < any( -- 小于工种为“IT_PROG"其中一个则满足条件
	select salary from employees where job_id = 'IT_PROG'
) and job_id <> 'IT_PROG';

-- 查询工种比job_id为“IT_PROG"工种'所有'工资低的员工的员工号、姓名、job_id 以及 salary
select employee_id,last_name,job_id,salary
from employees 
where salary < all( -- 小于所有工种为“IT_PROG"则满足条件
	select salary from employees where job_id = 'IT_PROG'
) and job_id <> 'IT_PROG';

行查询

代码如下(示例):

-- 查询员工表中编号最小,工资最高的员工
select *
from employees
where employee_id = (
	select min(employee_id) from employees
) and salary = (
	select max(salary) from employees
);

select后面

代码如下(示例):

-- 查询每个部门的员工个数 (行查询)
select d.*,(
	select count(*) 
	from employees e
	where e.department_id = d.department_id
) 个数
from departments d;

-- 查询每个部门的员工个数 (外连接)
select d.*,count(employee_id) 个数
from employees e
right join departments d
on e.department_id = d.department_id
group by d.department_id;

from后面

代码如下(示例):

-- 查询每个部门的平均工资的工资等级
select ag_dep.*,g.grade_level
from (
	select avg(salary) ag,department_id
	from employees
	group by department_id
) ag_dep	-- 给表取别名
inner join job_grades g
on ag_dep.ag between lowest_sal and highest_sal;

exists后面

代码如下(示例):

-- 查询有员工的部门名
select department_name
from departments d
where exists(  -- 判段符合里面内容
	select * 
	from employees e
	where d.department_id = e.department_id
);

-- 查询没有女朋友的男神信息 (not exists)
select b.*
from boys b
where not exists(	-- 判段不符合里面内容
	select boyfriend_id
	from beauty g
	where g.id = b.boyfriend_id
)

-- 查询没有女朋友的男神信息 (not in)
select b.*
from boys b
where b.id not in (
	select boyfriend_id from  beauty
);

limit分页查询

代码如下(示例):

-- limit 起始位置,每页条数
-- 起始位置是从0开始算起!

-- 标准的分页sql
每页显示3条记录
第1页:0,32页:3,33页:6,34页:9,35页:12,3

每页显示pageSize条记录
第pageNum页:(pageNum-1)*pageSize,pageSize

-- 查询前5名学生
select studentno,studentname
from student
limit 5;

select studentno,studentname
from student
limit 0,5;

-- 查询6-10名学生
select studentno,studentname
from student
limit 5,5;

union联合查询

代码如下(示例):

#union可以去重
#union all 不去重

-- 查询并且的三种方法:
select username from user where username = 'zhangsan' or username = 'lisi';

select username from user where username in ('zhangsan','lisi');

select username from user where username = 'zhangsan'
union
select username from user where username = 'lisi';

-- 查询部门编号>90或邮箱包含a的员工信息
select * from employees where department_id > 90
union
select * from employees where email like '%a%'; 

-- 查询中国用户中男性的信息以及外国用户中男性的信息
select id,cname,csex from t_ca where csex = '男'
union
select t_id,t_name,t_gender from t_ua where t_gender = 'male';

-- 查询中国用户中男性的信息以及外国用户中男性的信息
select id,cname from t_ca where csex = '男'
union all	-- 查询两个表的id和name相同的话也会显示
select t_id,t_name from t_ua where t_gender = 'male';

九、CRUD操作

代码如下(示例):

-- 往boys表中同时插入多个数据
insert into boys (boyName,userCP)
values('张三',200),('李四',400),('王五',700);

-- 修改没有男朋友的女神的男朋友编号都为2号
update boys b
right join beauty g
on g.boyfriend_id = b.id
set g.boyfriend_id = 2
where b.id is null;

-- 删除黄晓明的信息以及他女朋友的信息
delete b,g
from boys b
inner join beauty g on b.id = g.boyfriend_id
where b.boyName = '黄晓明';

#delete删除表后自增从断点继续,有返回值
#truncate删除表后自增从1开始,没有返回值
delete from boys;
truncate table boys;

扩展:

-- =或<>不能用于判断null值,is null或is not null可以判断null值

-- 由于更新的数据中没有主键会报错,更新前面加上这一句
SET SQL_SAFE_UPDATES = 0;

-- 查询员工表的job_id中包含a和e的,并且a在e的前面
select job_id from employees where job_id like '%a%e%';

-- 分组函数不可直接使用在where子句中
select name from user where sal > avg(sal); -- 会发生语法错误!!!
-- 分组函数自动忽略NULL
select sum(sal) from user where sal is not null; -- 后面不需要写is not null判断,因为分组函数自动忽略NULL!

count(*):统计总记录条数
count(字段):统计字段中不为NULL的数据总条数

-- where和having
	能使用where的就使用,因为效率高,对原始数据进行过滤,having效率低
	不能使用where的就使用having,可以对分组后的数据进行过滤
查询每个部门的最高薪资,要求显示薪资大于2900的部门编号:
	select deptno,max(sal) from emp where sal > 2900 group by deptno;  -- 效率高
	select deptno,max(sal) from emp group by deptno having sal > 2900; -- 效率低
查询每个部门的平均薪资,要求显示平均薪资大于2000的部门编号:
	select deptno,avg(sal) from emp group by deptno having avg(sal) > 2000;	-- 可行
	select deptno,avg(sal) from emp where avg(sal) > 2000 group by deptno;	-- 不可行,where后不能分组函数

十、库表约束操作

代码如下(示例):

-- 创建数据库
create database if not exists test;

-- 删除数据库
drop database if exists test;

-- 创建表
drop table if exists stuinfo;
CREATE TABLE stuinfo (
    id INT PRIMARY KEY,#主键
    stuName VARCHAR(20) NOT NULL,#非空
    gender CHAR(1) CHECK (gender = '男' OR gender = '女'),#检查
    seat INT UNIQUE,#唯一
    age INT DEFAULT 18,#默认
    majorId INT,
    CONSTRAINT fk_stuinfo_major FOREIGN KEY (majorId)#外键约束
        REFERENCES major (id)
);

CREATE TABLE IF NOT EXISTS major (
    id INT PRIMARY KEY,
    majorName VARCHAR(20)
);

-- 查看表结构
desc stuinfo;

-- 查看表的索引
show index from stuinfo;

-- 修改列的约束
alter table stuinfo modify column stuName varchar(20) not null;	#非空
alter table stuinfo modify column age int default 18;	#默认
alter table stuinfo modify column id int primary key;	#主键
alter table stuinfo add constraint fk_stuinfo_major FOREIGN KEY(majorId) references major(id);	#主键

十一、index(索引)

什么是索引?

  • 索引就相当于一本书的目录,通过目录有快速的找到对应的资源。
  • 查询一张表有两种检索方式:
    1、全表扫描
    2、根据索引检索
  • 索引为什么可以提供检索效率呢?
    最根本的原理就是缩小了扫描的范围
  • 索引虽然提供检索效率,但不能随便添加索引,因为索引也需要维护,有维护成本的。比如:表中数据经常被修改就不适合添加索引,因为数据一旦被修改,索引需要重新排序,进行维护。
  • 添加索引是给某一个字段或某些字段添加
    当字段没有添加索引会进行全表扫描,扫描字段所有的值
    当字段添加了索引会根据索引扫描,快速定位

怎么创建索引对象?删除索引对象?

  1. 通过创建:create index 索引名 on 表名(字段名)
  2. 通过修改表结构创建:alter table 表名 add index 索引名 on column(字段名)
  3. 通过创建表的同时创建:index 索引名 字段名

 删除索引对象:drop index 索引名 on 表名

什么时候考虑给字段添加索引?

  1. 数据量庞大
  2. 该字段很少DML操作(insert update delete)
  3. 该字段经常出现在where子句中

主键和具有unique约束的字段会自动添加索引

 根据主键查询效率较高

索引底层采用的数据结构是:B+Tree

索引的实现原理?

 通过B+Tree缩小扫描范围,底层索引进行了排序、分区,索引会携带数据在表中的“物理地址”,最终通过索引检索到数据之后,获取到关联的”物理地址“,通过“物理地址”定位表中的数据,效率是最高的。

索引的分类

  1. 普通索引:给单个字段添加索引
  2. 主键索引:主键上会自动添加索引
  3. 唯一索引:有unique约束的字段上会自动添加索引
  4. 组合索引:给多个字段联合起来添加1个索引
  5. 全文索引

索引什么时候失效?

  • select name from student where email like ‘%a%’;
  • 模糊查询,第一个通配符是%时,索引就会失效。

练习

代码如下(示例):

use school;
-- 插入100万数据.
DELIMITER $$	-- 写函数之前必须要写,标志
CREATE FUNCTION mock_data ()
RETURNS INT
BEGIN
	DECLARE num INT DEFAULT 1000000;
	DECLARE i INT DEFAULT 0;
	WHILE i<num DO
		INSERT INTO app_user(`name`,`email`,`phone`,`gender`,`password`,`age`)VALUES(CONCAT('用户',i),'[email protected]',CONCAT('18',FLOOR(RAND()*(999999999-100000000)+100000000)),FLOOR(RAND()*2),UUID(),FLOOR(RAND()*100));
		SET i=i+1;
	END WHILE;
	RETURN i;
END $$

SELECT mock_data();	-- 查看函数

-- 未创建索引查询
SELECT * FROM app_user where name = '用户9999';	--2.031 sec / 0.000 sec
-- 创建索引
create index app_user_name on app_user(name);
-- 查看执行计划
explain SELECT * FROM school.app_user where name = '用户9999';
-- 创建索引后执行效率提高很多
SELECT * FROM app_user where name = '用户9999';	--0.031 sec / 0.000 sec

十二、事务(Transaction)的操作

MySQL事务的操作

十三、视图

什么是视图

 视图就是站在不同角度去看到数据。(同一张表的数据通过不同的角度去看待)

视图操作

 创建视图只能是查询语句(DQL), 对视图进行CRUD操作,会影响到原表数据。

create view 视图名 as select 字段名 from 表名

drop view 视图名

代码如下(示例):

-- 创建视图
CREATE VIEW myview1 AS SELECT username,age FROM user;

-- 查看视图
SELECT * FROM myview1;

-- 通过视图操作表数据
INSERT INTO myview1 (username,age) VALUES('zhangsan',18);
INSERT INTO myview1 (username,age) VALUES('lisi',18);
INSERT INTO myview1 (username,age) VALUES('wangwu',18);

SET SQL_SAFE_UPDATES = 0; 	-- 由于更新的数据中没有主键
UPDATE myview1 SET age = 19 WHERE username = 'lisi';

DELETE FROM myview1 WHERE username = 'wangwu';

-- 查看原表数据
SELECT * FROM user;

视图的作用

 视图可以隐藏表的实现细节。保密级别较高的系统,数据库只对外提供相关的视图,程序员只对视图对象进行CRUD操作。

 比如:视图对字段进行取别名,隐藏原表字段名

十四、DBA命令

数据导出

 直接在CMD中输入命令:(当然文件名可以随便)

  • 导出整个数据库:

    mysqldump -u root -p 数据库名 > 数据库名.sql

    mysqldump -u root -p 数据库名 > D:\数据库名.sql

  • 导出数据库中指定的表数据:

    mysqldump -u root -p 数据库名 表名 > D:\数据库名.sql

数据导入

 进入mysql中先创建数据库再导入数据

create database test;

use test;

source D:\数据库名.sql


十五、数据库设计三范式

什么是设计范式?

 设计表的依据,按照三范式设计的表不会出现数据冗余。

三范式

  1. 第一范式(1NF):强调的是列的原子性,任何一张表都应该有主键,数据库中每一列都是不可分割的原子数据项

  2. 第二范式(2NF):建立在第一范式的基础上,要求全部非主关键字段完全依赖于主键,不能产生部分依赖

    多对多,三张表,关系表要加外键

    student(学生表) teacher(教师表) student_teacher_relation(学生教师关系表)


  sno(pk) sname  tno(pk) tname  id(pk) sno(pk)  tno(fk)

  ———————————— ———————————— ———————————————————

  1     张三   1   李老师   1   1    3

  2    李四    2   王老师   2    1    1

  3     王五   3   张老师   3    2    2

                     4   2    3

                     5   3    2

  1. 第三范式(3NF):建立在第二范式的基础上,任何非主关键字段依赖于主键,不能产生传递依赖

    一对多,两张表,多的表要加外键

     class(班级表)     student(学生表)


   cno(pk)  cname     sno(pk)  sname   classno(fk)

   ———————————— ———————————————————

   1     班级1     101    张三   1

   2     班级2     102    李四   1

                103    王五   2

                104    赵六   2

提醒

 实际开发中,以满足客户的需求为主,有的时候会拿冗余换执行速度(以空间换时间)。

一对一如何设计

 有两种方案:主键共享和外键唯一

  • 主键共享:
    MySQL总结_第2张图片
  • 外键唯一:
    MySQL总结_第3张图片

十六、DDL/DML/DQL/DCL

  • DDL(Data Definition Language):数据定义语言,主要是进行定义/改变表的结构、数据类型、表之间的链接等操作。常用的语句关键字有 CREATE、DROP、ALTER 等。
  • DML(Data Manipulation Language):数据操纵语言,主要是对数据进行增加、删除、修改操作。常用的语句关键字有 INSERT、UPDATE、DELETE 等。
  • DQL(Data Query Language):数据查询语言,主要是对数据进行查询操作。常用关键字有 SELECT、FROM、WHERE 等。
  • DCL(Data Control Language):数据控制语言,主要是用来设置/更改数据库用户权限。常用关键字有 GRANT、REVOKE 等。

总结

MySQL总结_第4张图片

你可能感兴趣的:(MySQL,1024程序员节,mysql,数据库,database)