MySQL数据库应用全解

常用引擎的区别

mysql有三种存储引擎分别为

InnoDB 、MyiSAM、Memory

三种存储引擎的区别

InnoDBMyiSAMMemory
mysql5.5之后默认的存储引擎mysql5.5之前默认的存储引擎内存存储引擎(很少用到)
支持事务不支持事务
支持外键(是mysql众多存储引擎中唯一支持外键的)不支持外键
行级锁(仅对指定行记录进行加锁)表级锁(对指定表进行加锁)

如何选择存储引擎

首选InnoDB
MySQL5.5之后默认的存储引擎
支持事务,支持外键,支持行级锁
保证数据的完整性,一致性
如果对表的操作有插入和查询,还有更新,删除等操作,建议使用InnoDB

数据库的五种分类

DDL(Data Definition Language)数据定义语言

创建
create database 数据库名;
create database 数据库名 charset 字符集;
create table 表名(列名(字段名) 数据类型,…)
create table 新表 like 老表;
查询
show databases;
show create database 数据库名; 查看建库语句
show tables;
show create table 表名;
desc 表名 ;查看表结构;
修改
alter database 数据库名 charset 字符集;
alter table 表名 add 列名 类型;
alter table 表名 modify 列名 新类型;
alter table 表名 change 旧列名 新列名 新类型;
alter table 表名 drop 列名;
alter table 表名 charset 字符集;
rename table 旧表名 to 新表名;
删除
drop database 数据库名;
drop table 表名;
使用数据库
select database();查看当前使用的数据库
use 数据库; 切换(使用)数据库

DML(Data Manipulation Language)数据操作语言

添加记录
insert into 表名 (列名1,列名2…)values(值1,值2…);
insert into 表名 values(值1,值2…);必须与表列顺序一致,查看desc表名
注意:字符串可以插入一切类型,MySQL底层进行了隐式转换
修改记录
update 表名 set 列名1=新值,列名2=新值…[where条件]
删除记录
delete from 表名 [where 条件] 【这里最好要加上条件
注意:[ ]中的内容可写可不写

DQL(Data Query Language) 数据查询语言

基本查询用法
select * from 表名;
select distinct 列名 from 表名; 去重的关键字distinct
ifnull(列名,默认值)如果该列有值那么就直接返回,如果为null返回默认值
select 列名[as] 列别名 from 表名 [as] 表别名;

高级查询用法
条件查询
select … from 表名 where 条件
关系运算符 > < =…
逻辑运算符 && and , || or ,! not
select … from 表名 where 列名 in(值1,…);
select… from 表名 where 列名 between 较小的值 and 较大的值
select …from 表名 where 列名 is 【not】null
select …from 表名 where 列名 like ‘通配符字符串’
select …from 表名 order by 排序列[asc|desc],排序列[asc|desc]
注意:多字段排序,后面的排序结果是在前面排序的基础之上
聚合函数:count、max、min、sum、avg
select 分组列from 表名 group by 分组列 having 分组后条件过滤
注意:where在分组前进行条件过滤,不能使用聚合函数
having在分组后进行条件过滤,可以使用聚合函数
select …from 表名 limit 开始索引,每页显示个数;

sql执行先后问题

select … from 表名 where 条件 group by 分组 having 分组后条件 order by 排序列[asc|desc] limit 分页;

内连接

  1. 隐式内连接
    select … from 左表,右表 where 连接条件;
  2. 显示内连接
    select…from 左表[inner] join 右表 on 连接条件;

外连接

  1. 左外连接
    select …from 左表 left [outer] join 右表 on 连接条件;
  2. 右外连接
    select …from 右表 right [ outer] join 左表 on 连接条件;

子查询

注意:
子查询结果为单列,肯定作为条件在where后面使用
select …from 表名 where 字段 in(子查询);
子查询结果为多列,肯定作为虚拟表在from后面使用
select …from (子查询) as 表别名;

查询实际应用

首先添加数据库名,数据库表,基本数据

create database text;
use text;
-- 部门表
CREATE TABLE dept (
  id INT PRIMARY KEY auto_increment, -- 部门id
  dname VARCHAR(50), -- 部门名称
  loc VARCHAR(50) -- 部门位置
);

-- 添加4个部门
INSERT INTO dept(id,dname,loc) VALUES 
(10,'教研部','北京'),
(20,'学工部','上海'),
(30,'销售部','广州'),
(40,'财务部','深圳');

-- 职务表
CREATE TABLE job (
  id INT PRIMARY KEY,
  jname VARCHAR(20), -- 职务名称
  description VARCHAR(50) -- 职务描述
);

-- 添加4个职务
INSERT INTO job (id, jname, description) VALUES
(1, '董事长', '管理整个公司,接单'),
(2, '经理', '管理部门员工'),
(3, '销售员', '向客人推销产品'),
(4, '文员', '使用办公软件');

-- 员工表
CREATE TABLE emp (
  id INT PRIMARY KEY, -- 员工id
  ename VARCHAR(50), -- 员工姓名
  job_id INT, -- 职务id  外键
  mgr INT , -- 上级领导
  joindate DATE, -- 入职日期
  salary DECIMAL(7,2), -- 工资 99999.99
  bonus DECIMAL(7,2), -- 奖金 99999.99
  dept_id INT, -- 所在部门编号  外键
  CONSTRAINT emp_jobid_ref_job_id_fk FOREIGN KEY (job_id) REFERENCES job (id),
  CONSTRAINT emp_deptid_ref_dept_id_fk FOREIGN KEY (dept_id) REFERENCES dept (id)
);

-- 添加员工
INSERT INTO emp(id,ename,job_id,mgr,joindate,salary,bonus,dept_id) VALUES 
(1001,'孙悟空',4,1004,'2000-12-17','8000.00',NULL,20),
(1002,'卢俊义',3,1006,'2001-02-20','16000.00','3000.00',30),
(1003,'林冲',3,1006,'2001-02-22','12500.00','5000.00',30),
(1004,'唐僧',2,1009,'2001-04-02','29750.00',NULL,20),
(1005,'李逵',4,1006,'2001-09-28','12500.00','14000.00',30),
(1006,'宋江',2,1009,'2001-05-01','28500.00',NULL,30),
(1007,'刘备',2,1009,'2001-09-01','24500.00',NULL,10),
(1008,'猪八戒',4,1004,'2007-04-19','30000.00',NULL,20),
(1009,'罗贯中',1,NULL,'2001-11-17','50000.00',NULL,10),
(1010,'吴用',3,1006,'2001-09-08','15000.00','0.00',30),
(1011,'沙僧',4,1004,'2007-05-23','11000.00',NULL,20),
(1012,'李逵',4,1006,'2001-12-03','9500.00',NULL,30),
(1013,'小白龙',4,1004,'2001-12-03','30000.00',NULL,20),
(1014,'关羽',4,1007,'2002-01-23','13000.00',NULL,10);

-- 工资等级表
CREATE TABLE salarygrade (
  grade INT PRIMARY KEY,  -- 等级
  losalary INT, -- 最低工资
  hisalary INT -- 最高工资
);

-- 添加5个工资等级
INSERT INTO salarygrade(grade,losalary,hisalary) VALUES 
(1,7000,12000),
(2,12010,14000),
(3,14010,20000),
(4,20010,30000),
(5,30010,99990);

练习

--简单查询
--查询emp表
select * from emp;
--查询emp表吴用的信息
select * from emp where ename="吴用";
--查询emp表的salary的最大值是谁
--1.子查询
SELECT ename,salary from emp WHERE salary=(SELECT MAX(salary) from emp)
--2.直接查询
SELECT ename,salary FROM emp ORDER BY salary DESC LIMIT 1;
--查询emp中的数据工薪在40000到50000之间的数据
SELECT * FROM emp WHERE salary BETWEEN 40000 AND 50000;
--多表查询
-- 1 查询所有员工信息。显示员工编号,员工姓名,工资,职务名称,职务描述
-- 1.1 确定几张表?
SELECT * FROM emp e INNER JOIN job j;
-- 1.2 确定连接条件
SELECT * FROM emp e INNER JOIN job j ON e.job_id = j.id;
-- 1.3 确定显示字段(列)
SELECT e.id,e.ename,e.salary,j.jname,j.description FROM emp e INNER JOIN job j ON e.job_id = j.id;
-- 2 查询所有员工信息。显示员工编号,员工姓名,工资,职务名称,职务描述,部门名称,部门位置
-- 2.1 确定几张表?
SELECT * FROM emp e INNER JOIN job j INNER JOIN dept d;
-- 2.2 确定连接条件
SELECT * FROM emp e INNER JOIN job j INNER JOIN dept d ON e.job_id = j.id AND e.dept_id = d.id; -- 了解
SELECT     -- 推荐
  * 
FROM
  emp e 
  INNER JOIN job j 
    ON e.job_id = j.id 
  INNER JOIN dept d 
    ON e.dept_id = d.id ; 
    
 -- 2.3 确定显示字段
SELECT     
  e.id,
  e.ename,
  e.salary,
  j.jname,
  j.description,
  d.dname,
  d.loc
FROM
  emp e 
  INNER JOIN job j 
    ON e.job_id = j.id 
  INNER JOIN dept d 
    ON e.dept_id = d.id ; 
-- 3 查询所有员工信息。显示员工姓名,工资,职务名称,职务描述,部门名称,部门位置,工资等级
-- 3.1 确定几张表?
SELECT * FROM emp e INNER JOIN job j INNER JOIN dept d INNER JOIN salarygrade sg; 
-- 3.2 确定连接条件
SELECT 
  * 
FROM
  emp e 
  INNER JOIN job j 
    ON e.job_id = j.id 
  INNER JOIN dept d 
    ON e.dept_id = d.id 
  INNER JOIN salarygrade sg 
    ON e.salary BETWEEN sg.losalary 
    AND sg.hisalary ;
-- 3.3 确定显示字段
SELECT 
  e.id,
  e.ename,
  e.salary,
  j.jname,
  j.description,
  d.dname,
  d.loc,
  sg.grade
FROM
  emp e 
  INNER JOIN job j 
    ON e.job_id = j.id 
  INNER JOIN dept d 
    ON e.dept_id = d.id 
  INNER JOIN salarygrade sg 
    ON e.salary BETWEEN sg.losalary 
    AND sg.hisalary ;
-- 4 查询经理的信息。显示员工姓名,工资,职务名称,职务描述,部门名称,部门位置,工资等级
-- 4.1 确定几张表
SELECT * FROM emp e 
	INNER JOIN job j
	INNER JOIN dept d
	INNER JOIN salarygrade;
-- 4.2 确定连接条件 
SELECT * FROM emp e 
	INNER JOIN job j ON e.job_id = j.id
	INNER JOIN dept d ON e.dept_id = d.id
	INNER JOIN salarygrade sg ON e.salary  BETWEEN sg.losalary AND sg.hisalary; 
-- 4.3 确定显示字段
SELECT e.id,e.ename,e.salary,j.jname,j.description,d.dname,d.loc,sg.grade FROM emp e 
	INNER JOIN job j ON e.job_id = j.id
	INNER JOIN dept d ON e.dept_id = d.id
	INNER JOIN salarygrade sg ON e.salary  BETWEEN sg.losalary AND sg.hisalary; 
-- 4.4 确定业务条件
SELECT e.id,e.ename,e.salary,j.jname,j.description,d.dname,d.loc,sg.grade FROM emp e 
	INNER JOIN job j ON e.job_id = j.id
	INNER JOIN dept d ON e.dept_id = d.id
	INNER JOIN salarygrade sg ON e.salary  BETWEEN sg.losalary AND sg.hisalary
	WHERE j.jname = '经理'; 
-- 5 查询出所有部门编号、部门名称、部门位置、部门人数
-- 5.1 查询出部门人数  分组+聚合
SELECT dept_id,COUNT(*) AS total FROM emp GROUP BY dept_id;
-- 5.2 查询的结果作为虚拟表与部门表建立关联
SELECT d.id,d.dname,d.loc,e.total FROM dept d
	LEFT OUTER JOIN (SELECT dept_id,COUNT(*) AS total FROM emp GROUP BY dept_id) AS e
		ON d.id = e.dept_id;

DCL(Data Control Language)数据控制语言

创建用户
create user ‘用户名‘@’ 主机名’ identified by ‘密码’;
注意:
主机名:限定客户端登录ip
指定ip:127.0.0.1
任意ip:%
查看权限
show grants for ‘用户名’@ ‘主机名’;
撤销权限
revoke 权限1,权限2…on 数据库名.表名 from ’ 用户名’ @’ 主机名’
删除用户
drop user ‘用户名’@‘主机名’
密码管理
set password for ‘用户名’@‘主机名’=password(‘新密码’)【超级管理员】
普通用户
set password=password(‘新密码’)

TCL(Transaction Control Language) 事务控制语言

开启事务 start transaction
提交事务 commit
回滚事务 rollback

事务特性

四个属性解释
原子性:A(atomicity)如果一个包含多个步骤的业务,被事务管理,那么这些操作要么同时成功,要么同时失败。
一致性:C(consistency)事务执行前后,保证数据的完整性
隔离性:I(isolation)多个事务之间,相互独立,不能干扰
持久型:D(durability)事务一旦提交,同步到数据库磁盘文件,不可逆

事务的隔离性

三种隔离级别解释
脏读一个事务中,读取到另一个事务未提交的数据(这个在数据库中是不能让它发生的)
不可重复读一个事务中,二次读取的内容不一致(在进行修改时)
幻读一个事务中,二次读取的数量不一致(在进行新增和删除时)

MySQL数据库的隔离级别

级别名字隔离级别脏读不可重复读幻读数据库默认隔离级别
读未提交read uncommitted
读已提交read committedOracle和SQL Server
可重复读repeatable readMySQL
串行化serializable

数据库慢查询日志

查看慢查询日志开启情况(mysql默认是关闭的)
show variables like ‘%show_query_log%’;
开启慢查询日志
set global show_query_log=on;
查看慢查询时间配置
show variables like ‘%long_query_time’;
修改慢查询的记录时间
set long_query_time=5
注意:
如果设置变量有global全局更改 ,下次打开生效

数据库的索引

– 创建 普通 索引
create index 索引名 on 表名(列名);
– 创建唯一索引
create unique index 索引名 on 表名(列名);
– 创建普通组合索引
create index 索引名 on 表名(列名1,列名2);
– 创建唯一组合索引
create unique index 索引名 on 表名(列名1,列名2);
– 直接删除
drop index 索引名 on 表名;
– 修改表时删除 【掌握】
alter table 表名 drop index 索引名;
– 添加一个主键,这意味着索引值必须是唯一的,且不能为NULL
alter table 表名 add primary key(列名); – 主键索引名 primary
– 添加唯一索引(除了NULL外,NULL可能会出现多次)
alter table 表名 add unique(列名); – 列名就是索引名
– 添加普通索引,索引值可以出现多次。
alter table 表名 add index(列名); – 列名就是索引名

索引的创建原则

  1. 存储的文本内容可识别率70%以上
  2. 经常作为条件搜索的字段,建议设置索引
  3. 经常作为多表主外建连接字段,建议设置索引
  4. 经常需要排序的字段,建议设置索引
    注意:不是所有的字段都适合做索引,创建索引也是需要占用磁盘空间的

索引的失效情况

  1. 使用like关键字有遵循左前缀匹配规则
  2. 尽量避免使用or,如果条件有一个没有索引,那么会进行全表扫描
  3. 在索引列上进行计算
  4. 在索引列上进行隐式转换
  5. 使用!=、<>、not in、is not null时

索引的数据结构

有哪些数据结构及特点

  1. 数组:遍历查找快,适用于内存小量数据
  2. 链表:增删快,查找慢,适用于内存小量数据
  3. 二叉树:一个父节点下只有二个子节点,特点:左边子节点比父节点小,右表的子节点比父节点大
  4. 红黑树:平衡二叉树(左旋和右旋),保证每一个父节点都有二个子节点
  5. BTree:多路(多叉)平衡搜索树,可以有效控制树的高度
  6. B+Tree:MySQL用的这个数据结构,(非叶子节点不存储数据,叶子节点没有指针)
  7. Hash:散列 key-value (无序,根据key查找value超快,范围查找速度慢)
    1.7:数组+链表
    1.8:数组+红黑树(如果碰撞数量 <8 ,还是使用链表 )
    hash碰撞

目的只有一个控制树高度,减少磁盘IO

MySQL中的B+Tree

在这里插入图片描述
查看mysql中索引节点的大小
show global status like ‘innodb_page_size’;
在这里插入图片描述

MySQL函数

字符串函数

  1. 函数:CONCAT(s1,s2…sn)
    描述:字符串 s1,s2 等多个字符串合并为一个字符串
    实例:SELECT CONCAT(“传”, “智”, “播”, “客”);
  2. 函数:CHAR_LENGTH(str)
    描述:返回字符串 str 的字符数
    实例:SELECT CHAR_LENGTH(“传智播客”);
  3. 函数:LENGTH(str)
    描述:返回字符串 s 的字节数
    注意:mysql编码UTF8 中文占用3个字节
    实例:SELECT LENGTH(“传智播客”) ;
  4. 函数:UCASE(s) | UPPER(s)
    描述:将字符串转换为大写
    实例:SELECT UCASE(“itcast”);
  5. 函数:LCASE(s) | LOWER(s)
    描述:将字符串转换为小写
    实例:SELECT LCASE(“ITCAST”);
  6. 函数:LOCATE(s1,s)
    描述:从字符串 s 中获取 s1 的开始位置
    实例:SELECT LOCATE(‘he’,‘itheima’);
  7. 函数:TRIM(str) | LTRIM(str) | RTRIM(str)
    描述:字符串去空格
    实例:SELECT TRIM(" 传智人 ");
  8. 函数:REPLACE(s,s1,s2)
    描述:将字符串 s2 替代字符串 s 中的字符串 s1
    实例:SELECT REPLACE(‘abc’,‘a’,’*’);
  9. 函数:SUBSTR(s, start, length)
    描述:从字符串 s 的 start 位置截取长度为 length 的子字符串
    实例:SELECT SUBSTR(“itcast”, 2, 3);
  10. 函数:STRCMP(str1,str2)
    描述:比较字符串大小,左大于右时返回1,左等于右时返回0,,左小于于右时返回-1,
    实例:SELECT STRCMP(“a”,“b”);

日期函数

  1. 函数:NOW() | CURDATE() | CURTIME()
    描述:获取系统当前日期时间、日期、时间
    实例:SELECT NOW();
  2. 函数:YEAR(DATE) | MONTH(DATE) | DAY(DATE)
    描述:从日期中选择出年、月、日
    实例:SELECT YEAR(NOW());
  3. 函数:LAST_DAY(DATE)
    描述:返回月份的最后一天
    实例:SELECT LAST_DAY(NOW())
  4. 函数:ADDDATE(DATE,n) | SUBDATE(DATE,n)
    描述:计算起始日期 DATE 加(减) n 天的日期
    实例:SELECT ADDDATE(NOW(),10);
  5. 函数:QUARTER(DATE)
    描述:返回日期 DATE 是第几季节(季度),返回 1 到 4
    实例:SELECT QUARTER(NOW());
  6. 函数:DATEDIFF(d1,d2)
    描述:计算日期 d1->d2 之间相隔的天数
    实例:SELECT DATEDIFF(‘2019-08-01’,‘2019-07-01’);
  7. 函数:DATE_FORMAT(d,f)
    描述:按表达式 f的要求显示日期 d
    实例:SELECT DATE_FORMAT(NOW(),’%Y-%m-%d’);

数据函数

  1. 函数:ABS(x)
    描述:返回 x 的绝对值  
    实例:SELECT ABS(-1);
  2. 函数:CEIL(x) | FLOOR(x)
    描述:向上(下)取整
    实例:SELECT CEIL(1.5);
  3. 函数:MOD(x,y)
    描述:返回x mod y的结果,取余
    实例:SELECT MOD(5,4);
  4. 函数:RAND()
    描述:返回 0 到 1 的随机数
    实例:SELECT RAND();
  5. 函数:ROUND(x)
    描述:四舍五入
    实例:SELECT ROUND(1.23456);
  6. 函数:TRUNCATE(x,y)
    描述:返回数值 x 保留到小数点后 y 位的值
    实例:SELECT TRUNCATE(1.23456,3);

高级函数

case表达式【相当于java中swtich语句】

– 语法
SELECT
CASE [字段,值]
WHEN 判断条件1
THEN 希望的到的值1
WHEN 判断条件2
THEN 希望的到的值2
ELSE 前面条件都没有满足情况下得到的值
END
FROM
table_name;

if表达式

– 语法
SELECT IF(1 > 0,‘true’,‘false’) from table_name;

cast(显示)类型转换【了解】

– 语法
SELECT CAST(参数 AS 类型);

– 类型
字符型:CHAR
日期 : DATE
时间: TIME
日期时间型 : DATETIME
浮点数 : DECIMAL
整数 : SIGNED

数据库的优化

  1. 硬件:更快的IO,更多的内存
  2. 系统配置(my.ini):可以通过配置MySQL的一些参数来提高MySQL性能,例如:最大连接数,数据库能占的内存大小,内存使用什么算法,是否支持线程池
  3. 数据库表结构:

表设计:根据数据三范式来进行表的设计

  1. 第一范式(1NF)
    要求:
    每一列不能再拆分
  2. 第二范式(2NF)
    要求:
    1.一张表只描述一件事情
    2.表中的每一个普通列都依赖于主键
  3. 第三范式(3NF)
    要求:
    从表的外键必须使用主表的主键

表字段类型的选择
1.选择更小的数据类型(数据库类型越小,占用的磁盘空间,内存和cpu缓存更少)
2.选择简单的数据类型(越简单的数据类型,需要的cpu周期越少,时间,IP都可以用数值类型来表述)
3.尽量避免null,null在查询的时候会比较复杂
4.如果对象数值有进度要求,建议使用decimal

数据库5大约束
primary key:主键约束(唯一识别一条记录)
unique:唯一索引(数据唯一)
default:默认值(提供默认值)
not null:非空约束(不能为null)
forgein key:设置外键约束

SQL语句的优化
1.对每一条sql查询都进行优化,尽量避免全表扫描(explain sql 查询语句),考虑在where子句后或者order by 后的列进行建立索引
2.在where子句后尽量避免对null值的判断,以及!=,or,in,ont in,like,表达式函数,这些操作会导致放弃索引查询,而采用全表扫描
3.不要在where子句=左边进行函数,算数运算或者其他的表达式运算,否则MySQL就无法正确的使用索引
4.在使用索引查询时,如果是多列索引,必须要使用最左前缀,没有使用,就会用全表扫描
5.不要写没有意义的查询

  • 7
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值