MySQL
1、MySQL简介
- MySQL是一个关系型数据库管理系统
- MySQL与Oracle的区别
- MySQL一个实例可以操作多个库,Oracle一个实例只能对应一个库
- 操作区别
2、操作MySQL
2.1 创建与删除数据库
- 创建数据库
CREATE DATABASE test DEFAULT CHARACTER SET utf8;
- 查看数据库
show databases;
- 查看数据库编码
SELECT s.SCHEMA_NAME ,s.DEFAULT_CHARACTER_SET_NAME FROM information_schema.SCHEMATA s WHERE s.SCHEMA_NAME = 'test';
- 选择数据库
use test;
- 删除数据库
drop database test;
2.2 MySQL中的数据类型
- MySQL支持所有标准SQL数值数据类型
- 作为SQL标准的扩展,MySQL也支持整数类型TINYINT、MEDIUMINT、BIGINT
- 浮点型
- 字符串型
- char和varchar
- varchar和text
- char和varchar
- 日期类型
- 二进制数据BLOB
2.3 创建表与删除表
- 创建表
CREATE TABLE employees (employee_id int,last_name varchar(30),salary float(8,2));
- 删除表
drop table employees;
2.4 修改表
- 修改表名
alter table employees rename emp;
- 修改列名
alter table emp change column last_name name vachar(30);
- 修改列类型
alter table emp modify name varchar(40);
- 添加列
alter table emp add column commission_pct float(4,2);
- 删除列
alter table emp drop column commission_pct;
2.5 MySQL的约束
- 查询表中的约束信息
show keys from 表名
CREATE TABLE departments (department_id int PRIMARY KEY AUTO_INCREMENT,department_name varchar(30) UNIQUE,location_id int NOT null);
CREATE TABLE employees(employees_id int PRIMARY KEY AUTO_INCREMENT,last_name varchar(30) NOT NULL,email varchar(40) NOT NULL UNIQUE,dept_id int,CONSTRAINT emp_fk FOREIGN key(dept_id) refereneces departments(department_id));
2.6 MySQL 修改表约束的添加与删除
2.6.1 添加主键约束
alter table 表名 ADD primary key(列名)
- 添加主键
alter table emp add primary key(employee_id);
- 修改自动增长
alter table emp modify employee_id int auto_increment;
- 删除主键约束:删除主键是,如果主键列具备自动增长能力,需要先去掉自动增长,然后在删除主键
--删除自动增长能力
alter table emp modify employee_id int;
--删除主键
alter table emp drop primary key;
2.6.2 添加与删除非空约束
--添加非空约束
ALTER TABLE 表名 MODIFY 列名 类型 NOT NULL
--删除非空约束
ALTER TABLE 表名 MODIFY 列名 类型 NULL;
- 添加非空约束
alter table emp modify salary float(8,2) not null;
- 删除非空约束
ALTER table emp modify salary float(8,2) null;
2.6.3 添加与删除唯一约束
--添加唯一约束
ALTER TABLE 表名 ADD CONSTRAINT 约束名 UNIQUE(列名);
--删除唯一约束
ALTER TABLE 表名 DROP KEY 约束名;
- 添加唯一约束
alter table emp add constraint emp_uk unique(name);
- 删除唯一约束
alter table emp drop key emp_uk;
2.6.4 添加与删除外键约束
--添加外键约束
ALTER TABLE 表名 ADD CONSTRAINT 约束名 FOREIGN KEY(列名) REFERENCES 表名(列名);
--删除外键
ALTER TABLE 表名 DROP FOREIGN KEY 约束名;
--删除外键索引(索引名与约束名相同)
ALTER table 表名 DROP index 索引名;
- 添加外键约束
--添加dept_id列
ALTER table emp ADD column dept_id int;
--添加外键约束
alter table emp add constraint emp_fk foreign key(dept_id) references departments(department_id);
- 删除外键约束(先删除外键,再删除索引)
--删除外键
alter table emp drop foreign key emp_fk;
--删除外键索引
alter table emp drop index emp_fk;
2.7 添加数据
- 选择插入
INSERT INTO 表名(列名1,列名2,列名3.....) values(值1,值2,值3...);
- 完全插入
--如果主键是自动增长,需要使用default或者null或者0占位
INERT INTO 表名 values(值1,值2,值3...);
2.8 自动增长
--添加自动增站
CREATE TABLE emp2(id int PRIMARY KEY,name varchar(30),seq_num int UNIQUE AUTO_INCREMENT);
--删除自动增长
ALTER TABLE emp2 MODIFY seq_num int NULL;
--修改自动增长
ALTER TABLE emp2 MODIFY id int AUTO_INCREMENT;
2.9 默认值处理
--指定默认值
CREATE TABLE emp3(emp_id int PRIMARY KEY AUTO_INCREMENT,name varchar(30),address varchar(50) DEFAULT "Unknown");
--修改默认值
ALTER table emp3 add column job_id int default 0;
ALTER table emp3 modify column address varchar(50) default 'BB';
- 插入 数据时的默认值处理
INSERT INTO emp3 values(DEFAULT,"BB",default);
2.10 更新数据(UPDATE)
- 更新的表不能再set和WHERE中用于子查询
- update后面可以做任意的查询
UPDATE 表名 set 列名=值,列名=值 where 条件;
2.11 删除数据(DELETE)
--删除数据
DELETE FROM 表名 WHERE 条件
- DELETE与TRUNCATE区别
2.12 清空表(TRUNCATE)
--清空数据
TRUNCATE TABLE 表名
3、 MySQL事务处理
- 事务自动提交的
- 关闭事务自动提交
STRAT TRANSACTION
DML语句
--手动提交|回滚
commit|ROLLBACK
--关闭事务
START TRANSACTION;
--DML语句
INSERT INTO emp3 values(DEFAULT,"AAA",DEFAULT,default);
--手动提交
COMMIT;
4、MySQL查询语句
4.1 列选择
SELECT *| 投影列 FROM 表名
4.2 行选择
SELECT *|投影列 FROM 表名 WHERE 选择条件
4.3 算术表达式
SELECT e.employee_id ,e.last_name ,e.email ,12 * (salary + 100) FROM employees e;
4.4 定义空值
- 包含空值的算术表达式计算结果为空
4.5 列别名
--AS可省略
SELECT 列名 AS 列别名 FROM 表名 WHERE 条件;
4.6 连字符
SELECT concat(e.employee_id,'#',e.last_name,'#',e.email,'#',e.salary,'#',e.commission_pct) FROM employees e ;
4.7 去除重复
- 在SELECT语句中用DISTINCT关键字去除相同的行
5、约束和排序数据
5.1 比较条件
5.2 模糊查询
5.3 逻辑运算符
- and
- or
- not
5.4 范围查询
- between…and
- in表示在一个非连续的范围内
5.4 空值判断
- 判断空 is null
- 判断非空 is not null
5.5 ORDER BY排序
- 用ORDER BY子句排序
- ASC:升序排序,默认
- DESC:降序排序
6、MySQL常见函数
6.1 单行函数
6.1.1 大小写控制函数
6.1.2 字符处理
6.1.3 数字函数
6.1.4 日期函数
SELECT dayname(sysdate());
6.1.5 转换函数
SELECT date_format(sysdate(),'%y年%m月%d日');
6.1.6 通用函数
6.2 聚合函数
6.2.1 AVG()
6.2.2 SUM()
6.2.3 MIN()
6.2.4 MAX()
6.2.5 COUNT()
7、多表查询
7.1 等值连接
SELECT d.department_name FROM employees e ,departments d WHERE e.department_id = d.department_id AND e.last_name = 'King';
7.2 非等值连接
SELECT e.last_name ,jg.grade_level FROM employees e ,job_grades jg WHERE e.salary BETWEEN jg.lowest_sal AND jg.highest_sal ;
7.3 自连接
SELECT emp.last_name ,manager.last_name FROM employees emp ,employees manager WHERE emp.manager_id = manager.employee_id ;
7.4 左/右外连接
--左外连接
SELECT e.last_name ,d.department_id FROM employees e LEFT JOIN departments d ON (e.department_id = d.department_id);
7.5 全外连接
- MySQL中不支持FULL OUTER JOIN连接
- 可以使用union实现全外连接
-
- 1、 UNION:可以将两个查询结果集合并,返回的行都是唯一的,如同对整个结果集合使用了DISTINCT
SELECT e.last_name ,d.department_id FROM employees e LEFT JOIN departments d ON (e.department_id = d.department_id)
UNION
SELECT e2.last_name ,d2.department_id FROM employees e2 RIGHT JOIN departments d2 on(e2.department_id = d2.department_id);
-
- 2、 UNION ALL:只是简单的将两个结果合并后就返回。如果返回的两个结果集中有重复的数据,那么返回的结果集就会包含重复的数据
7.6 SQL99中的交叉连接(CROSS JOIN)
-- 交叉连接实际上笛卡尔乘积
SELECT * FROM employees e CROSS JOIN departments d ;
7.7 SQL99中的自然连接(NATURAL JOIN)
SELECT * FROM employees e NATURAL JOIN departments d;
7.8 SQL99中的自然连接(INNER JOIN)
SELECT * FROM employees e INNER JOIN departments d ON e.department_id = d.department_id ;
8、数据分组(GROUP BY)
SELECT avg(e.salary) FROM employees e GROUP BY e.department_id ;
9、 约束分组结果 (HAVING)
SELECT e.department_id ,max(e.salary) FROM employees e GROUP BY e.department_id HAVING max(e.salary) > 5000 ;
10、子查询
- 使用子查询的原则
- 多行子查询
11、MySQL中的正则表达式
- ^ 符号:查询以x开头的数据(忽略大小写)
SELECT 列名 FROM 表名 WHERE 列名 REGEXP '^X';
SELECT e.last_name ,e.salary FROM employees e WHERE e.last_name REGEXP '^k';
- $符号:查询以x结尾的数据(忽略大小写)
SELECT 列名 FROM 表名 WHERE 列名 REGEXP 'x$';
- . 符号:英文的点,它匹配任何一个字符,包括回车、换行等
SELECT 列名 FROM 表名 WHERE 列名 REGEXP 'x.';
- * 符号:星号匹配0个或多个字符,在它之前必须有内容
- +:加号匹配1个或对个字符,在它之前也必须有内容
SELECT 列名 FROM 表名 WHERE 列名 REGEXP 'x+';
- ?符号:问号匹配0次或1次
SELECT 列名 FROM 表名 WHERE 列名 REGEXP 'x?';
- |符号:表示或者含义
SELECT 列名 FROM 表名 WHERE 列名 REGEXP 'abc|bcd';
- [a-z]:
- {n,m}
11、索引
- 索引的类型
11.1 普通索引
- 直接创建索引
CREATE INDEX index_name on table(column(length));
- 修改表添加索引
ALTER TABLE table_name add index index_name (column(length));
+ 创建表时指定索引列
- 删除索引
DROP INDEX index_name on table;
11.2 唯一索引
- 创建唯一索引
CREATE UNIQUE INDEX indexName on table(column(length));
- 修改表添加唯一索引
ALTER TABLE table_name add unique indexname (column(length));
- 创建表时指定唯一索引
11.3 主键索引
- 修改表添加主键索引
ALTER TABLE 表名 ADD PRIMARY KEY(列名);
- 创建表时指定主键索引
11.4 组合索引
- 最左前缀原则
- 修改添加组合索引
- 创建表时创建组合索引
11.5 全文索引
- 修改添加全文索引
- 创建表时创建全文索引
- 删除全文索引
11.6 使用全文索引
- 全文解析器
- 使用全文索引
- 更换全文解析器
12、用户管理
12.1 创建用户
CREATE USER username IDENTIFIED BY 'password';
12.2 查看用户
--该表位于mysql库中
SELECT USER,NOST FROM USER;
12.3 分配权限
12.4 权限列表
12.5 刷新权限
FLUSH PRIVILEGES;
12.6 删除用户
DROP USER username@localhost;
13、分页查询
- 分页查询原则
13.1 LIMIT子句
SELECT 投影列 FROM 表名 WHERE 条件 ORDER BY LIMIT 开始位置,查询数量;
13.2 LIMIT OFFSET 子句
SELECT 投影列 FROM 表名 WHERE 条件 ORDER BY LIMIT 查询数量 OFFSET 开始位置;
14、执行计划
14.1 查询执行过程
14.2 启动执行计划
EXPLAIN SELECT 投影列 FROM 表名 WHERE 条件;
14.3 EXPLAIN列的解释
14.3.1 ID
14.3.2 select_type
14.3.3 table
显示这一行的数据是关于哪张表的
14.3.4 type
14.3.5 possible_keys
- 查询条件字段涉及到的索引,可能没有使用
14.3.6 key
- 实际使用的索引。如果为NULL,则没有使用索引
14.3.7 key_len
14.3.8 ref
14.3.9 rows
14.3.10 fitered
14.3.11 extra
15、存储引擎
- 查看引擎
show engines;
--查看表的引擎
show creata table emp;
15.1 ISAM
15.2 MyISAM
15.3 InnoDB
15.3.1 Innodb与myisam区别
15.3.2 修改数据库级引擎
15.3.3 修改表级引擎
alter table tablename engine = innodb;
16、MySQL数据库和Oracle数据库的区别
- (1) 对事务的提交
MySQL默认是自动提交,而Oracle默认不自动提交,需要用户手动提交,需要在写commit;指令或者点击commit按钮 - (2) 分页查询
MySQL是直接在SQL语句中写"select… from …where…limit x, y",有limit就可以实现分页;而Oracle则是需要用到伪列ROWNUM和嵌套查询 - (3) 事务隔离级别
MySQL是read commited的隔离级别,而Oracle是repeatable read的隔离级别,同时二者都支持serializable串行化事务隔离级别,可以实现最高级别的读一致性。每个session提交后其他session才能看到提交的更改。Oracle通过在undo表空间中构造多版本数据块来实现读一致性,每个session查询时,如果对应的数据块发生变化,Oracle会在undo表空间中为这个session构造它查询时的旧的数据MySQL没有类似Oracle的构造多版本数据块的机制,只支持read commited的隔离级别。一个session读取数据时,其他session不能更改数据,但可以在表最后插入数据。session更新数据时,要加上排它锁,其他session无法访问数据 - (4) 对事务的支持
MySQL在innodb存储引擎的行级锁的情况下才可支持事务,而Oracle则完全支持事务 - (5) 保存数据的持久性
MySQL是在数据库更新或者重启,则会丢失数据,Oracle把提交的sql操作线写入了在线联机日志文件中,保持到了磁盘上,可以随时恢复 - (6) 并发性
MySQL以表级锁为主,对资源锁定的粒度很大,如果一个session对一个表加锁时间过长,会让其他session无法更新此表中的数据。虽然InnoDB引擎的表可以用行级锁,但这个行级锁的机制依赖于表的索引,如果表没有索引,或者sql语句没有使用索引,那么仍然使用表级锁。Oracle使用行级锁,对资源锁定的粒度要小很多,只是锁定sql需要的资源,并且加锁是在数据库中的数据行上,不依赖与索引。所以Oracle对并发性的支持要好很多。 - (7) 逻辑备份
MySQL逻辑备份时要锁定数据,才能保证备份的数据是一致的,影响业务正常的dml使用,Oracle逻辑备份时不锁定数据,且备份的数据是一致 - (8) 复制
MySQL:复制服务器配置简单,但主库出问题时,丛库有可能丢失一定的数据。且需要手工切换丛库到主库。Oracle:既有推或拉式的传统数据复制,也有dataguard的双机或多机容灾机制,主库出现问题是,可以自动切换备库到主库,但配置管理较复杂。 - (9) 性能诊断
MySQL的诊断调优方法较少,主要有慢查询日志。Oracle有各种成熟的性能诊断调优工具,能实现很多自动分析、诊断功能。比如awr、addm、sqltrace、tkproof等 - (10)权限与安全
MySQL的用户与主机有关,感觉没有什么意义,另外更容易被仿冒主机及ip有可乘之机。Oracle的权限与安全概念比较传统,中规中矩。 - (11)分区表和分区索引
MySQL的分区表还不太成熟稳定。Oracle的分区表和分区索引功能很成熟,可以提高用户访问db的体验。 - (12)管理工具
MySQL管理工具较少,在linux下的管理工具的安装有时要安装额外的包(phpmyadmin, etc),有一定复杂性。Oracle有多种成熟的命令行、图形界面、web管理工具,还有很多第三方的管理工具,管理极其方便高效。 - (13)最重要的区别
MySQL是轻量型数据库,并且免费,没有服务恢复数据。Oracle是重量型数据库,收费,Oracle公司对Oracle数据库有任何服务。
17、数据库的三大范式
17.1 第一范式
17.2 第二范式(多对多)
17.3 第三范式(一对多)
17.4 范式的优缺点
18、MySQL日志
--开启MyDSQL日志
show VARIABLES like '%general_log%';
set GLOBAL general_log = on;
set GLOBAL log_output='table';