文章目录

  • 第一章 SQL语句
  • 1. DDL 数据定义语言
  • 2. DML 数据管理语言
  • insert
  • 蠕虫复制
  • update
  • delete
  • 3. DQL 数据查询语言
  • select
  • and、or、between and
  • in、not in
  • %、_ 通配符
  • 聚合函数
  • group by 分组
  • having
  • order by 排序
  • limit 分页
  • all
  • any
  • 4. DCL 数据控制语言
  • 第二章 数据库约束
  • 1. 主键约束
  • 2. 主键自增
  • 3. 唯一约束
  • 4. 非空约束
  • 5. 默认值
  • 6. 外键约束
  • 第三章 数据库备份
  • 1. 命令行方式
  • 2. 图形界面 DataGrip方式
  • 第四章 多表查询
  • 1. 连接查询
  • 2. 子查询
  • 3. 多表查询规律总结
  • 第五章 事务
  • 1. 事务的四大特性 ACID
  • 1.1 原子性
  • 1.2 一致性
  • 1.3 隔离性
  • 1.4 持久性
  • 2. 操作事务
  • 2.1 SQL实现
  • 2.2 Java实现
  • 2.3 回滚原理(中间文件)
  • 3. 事务并发问题
  • 4. 事务的隔离级别
  • 第六章 存储过程
  • 第七章 索引
  • 1. 先插入大批数据
  • 2. 添加索引
  • 3 索引的优缺点
  • 3.1 优势
  • 3.2 劣势
  • 第七章 参考资料

第一章 SQL语句

1. DDL 数据定义语言

  • 创建、修改、删除 、查看数据库/表
# 创建、删除、修改、查看数据库
#1.创建数据库
create database xin;
create database if not exists xin; 	       			# 没有则创建数据库
create database if not exists xin charset = 'utf8'; #设置字符集utf8
create database if not exists xin character set utf8 collate utf8_general_ci;#设置字符集utf8 并核对
#2.查看
show databases;				#查看所有数据库
show create database xin;	#查看某个数据库定义时的信息
#3.修改数据库
alter database xin default character set utf8;#修改字符集
#4.删除数据库
drop database xin;
#5.切换数据库
use xin;
#6.查看正在使用的数据库
select database();
#创建、删除、修改、查看表
#1. 创建表
create table student
(
  id    int,
  name  varchar(8),
  age   int(3),
  score double(5, 2)
);
create table student2 like student;#快速创建一个表结构相同的表

#2. 删除表
drop table student2;
drop table if exists student2;

#3. 查看表
desc student; 				#查看表结构
show create table student;	#查看创建表时的sql
show tables;				#查看某个库中所有的表

#4. 修改表结构
alter table student add gender char(1); 			# 添加一个字符
alter table student modify id int(8); 				# 修改某个字段的类型
alter table student change name username varchar(8);# 修改某个字段的名字、类型
alter table student character set utf8; 			#修改表的字符集
alter table student rename name; 					# == rename table student to t_student; #重命名表名
  • MySQL 数据类型

2. DML 数据管理语言

insert

insert into student(id, name, age ) value (1,'张三','18');
insert into student(id, name, age, score) value (2,'李四','18',145.50);
insert into student(id, name, age, score) values (3,'王五','18',99.50),(4,'赵六','25',80);
insert into student value (5,'李七','30',101.11);

蠕虫复制

  • 两个表的结构一致
  • 将一个表的部分数据复制到另一个表中
create table man_stuent like student;
insert into man_stuent select * from student where gender = '男';

update

update student set id = 2 where score is null;
update student set age =26,score=97.1 where id = 2;

delete

#3. delete 数据
delete from student where id = 2;
delete from student where age = 18 and score > 100;
delete from student where age between 17 and 20;
delete from student;     #全删,逐条删除
truncate table student;  #全删,drop表,新建一个结构一样的新表
  • 注:update delete时一定要注意带上where条件

3. DQL 数据查询语言

MYSQL 语法检查工具 在线_其他

select

# * 全查,效率慢
-- 1.性能损失  * 需要有mysql程序解析
-- 2.性能损失  * 代表所有字段 不管需要还是不需要都会查询
select * from student;
# 所有字段全查,推荐
select id, name, age , score from student;
# 查询,显示时给与别名
select id ID, name 姓名, age 年龄, score 分数 from student;
# 查询 去除重复数据,一般都是查单列时使用
select distinct age from student;
select distinct name,age from student; #两个字段都一样才算重复
# 字段可以参与运算
select age + 1 from student;#所有人年龄加一
# case when ... then  when ...then else... end
select ename,
       sal,
       case
         when sal >= 3000 then '三级'
         when sal > 2000 then '2级'
         else '1级'
         end
from emp;

and、or、between and

select * from t_student where age>35 and gender='男';
select * from t_student where age>35 or gender='男';
select * from t_student where english between 75 and 90;
select id ,ifnull(salary,'没有工资') from t_student;

in、not in

# id 在(1,2,3)之中的, 等价于 id = 1 or id = 2 or id =3
select * from student where id in (1, 2, 3);
# id 不在(1,2,3)之中的, 等价于 id != 1 and id != 2 and id =3
select * from student where id not in (1, 2, 3);

%、_ 通配符

# %多个占位符
select * from student where name like '%三';
# _单个占位符
select * from student where name like '_三';

聚合函数

-- 聚合函数 select 聚合函数名(列表) from xx表 ....
-- count 数数
-- max 最大值
-- min 最小值
-- sum 求和
-- avg 求平均值
-- 查询所有学生的总数
-- select count(*) from xx表
-- 查询个数 鼓励 select count(*) mysql底层专门做了优化
select count(*) from t_student;

group by 分组

select gender,round(avg(score),2) from student group by gender;
select gender,max(age),avg(score) from student group by gender;
select age,name from student group by age having age = 18;

having

  • having 可以单独跟select
  • 如果有group by 则一定要在group by后面
select * from student having age > 18;
select * from student group by age having age >20;

order by 排序

# order by 字段 asc .   升序
# order by 字段 desc .  降序
# order by 字段1,字段2 . 在字段1升序排的基础上按字段2降序排
select * from student order by age ;
select * from student order by age desc ;
select * from student order by age desc,score desc;

limit 分页

select * from student limit 0,10;  起始索引,查询条目数
计算公式:起始索引=(当前页码-1)* 每页条数

all

select empno from emp
where sal >= all(select sal from emp); sal 大于等于 all()最大值

any

select empno from emp
where sal >= any(select sal from emp); sal >= any()最小值
  • oracle 用rownumber
  • sql server 用top

MySQL中ALL 和 ANY的用法

4. DCL 数据控制语言

# 创建新用户 CREATE USER '用户名'@'主机名' IDENTIFIED BY '密码';
create user 'zhx'@'localhost' identified by '123456';#
create user 'zhx'@'%' identified by '123456'; # 任意远程主机登陆,可以使用通配符%

# 授权 GRANT 权限1, 权限2... ON 数据库名.表名 TO '用户名'@'主机名';
#  grant xx权限(create、drop、alter、insert、update、delete、select...) on 库.表 to 哪个用户
grant select,delete on *.* to 'zhx'@'localhost'; # 给zhx用户授予对所有库所有表的全部权限。

# 移除权限
revoke delete on *.* from 'zhx'@'localhost';

# 删除用户
drop user 'zhx'@'localhost';

# 修改管理员密码
# 要在未登陆MySQL的情况下操作。新密码不需要加上引号
# mysqladmin -u root -p password 新密码

# 修改普通用户密码
set password for '用户名'@'主机名' = password('新密码');


select * from user;

第二章 数据库约束

  • 数据库约束的作用: 对表中的数据进行进一步的限制,保证数据的正确性、有效性和完整性。
  • 约束种类:
  • PRIMARY KEY: 主键约束 (B+ 二分查找树 ,查询快)
  • UNIQUE: 唯一约束
  • NOT NULL: 非空约束
  • DEFAULT: 默认值 了解
  • FOREIGN KEY: 外键约束

1. 主键约束

  • 用来唯一标识一条记录。
  • PRIMARY KEY
  • 主键必须包含唯一的值
  • 主键列不能包含NULL值
# 1. 在创建表的时候给字段添加主键
   字段名 字段类型 PRIMARY KEY
# 2. 在已有表中添加主键(了解)
   ALTER TABLE 表名 ADD PRIMARY KEY(字段名);

2. 主键自增

  • 主键如果让我们自己添加很有可能重复,我们通常希望在每次插入新记录时,数据库自动生成主键字段的值
字段名 字段类型 PRIMARY KEY AUTO_INCREMENT

AUTO_INCREMENT 表示自动增长(字段类型必须是整数类型)

# DELETE和TRUNCATE的区别
- DELETE 删除表中的数据,但不重置AUTO_INCREMENT的值。
- TRUNCATE 摧毁表,重建表,AUTO_INCREMENT重置为1
# insert 失败 主键也会加一

3. 唯一约束

  • 在这张表中这个字段的值不能重复
字段名 字段类型 UNIQUE

4. 非空约束

  • 这个字段必须设置值,不能是NULL
字段名 字段类型 NOT NULL

5. 默认值

  • 往表中添加数据时,如果不指定这个字段的数据,就使用默认值
字段名 字段类型 DEFAULT 默认值

6. 外键约束

  • 两个表之间的关系

说明:如果两张表是多对多的关系,需要创建第三张表,并在第三张表中增加两列,引入其他两张表的主键作为自己的外键。

foreign key( 当前表中的列名 )  references 被引用表名(被引用表的列名);
foreign key( coder_id )  references coder(id);
constraint [外键约束名称] foreign key(当前表中的列名) references  被引用表名(被引用表的列名)
举例:constraint coder_project_id foreign key(coder_id) references coder(id);

关键字解释: constraint: 添加约束,可以不写 foreign key(当前表中的列名): 将某个字段作为外键 references 被引用表名(被引用表的列名) : 外键引用主表的主键外键的级联 在修改和删除主表的主键时,同时更新或删除从表的外键值,称为级联操作ON UPDATE CASCADE – 级联更新,主键发生更新时,外键也会更新ON DELETE CASCADE – 级联删除,主键发生删除时,外键也会删除

-- 添加外键约束,并且添加级联更新和级联删除
constraint c_id_fk foreign key(coder_id) references coder(id) ON UPDATE CASCADE ON DELETE CASCADE,
);

级联更新:ON UPDATE CASCADE 主键修改后,外键也会跟着修改级联删除:ON DELETE CASCADE 主键删除后,外键对应的数据也会删除

第三章 数据库备份

1. 命令行方式

#备份数据,将数据的表、数据,转成sql保存
mysqldump --no-defaults  -u root -p 要备份的数据库名 > 硬盘SQL文件绝对路径
mysqldump --no-defaults -u root -p webdb2 > d:\aa.sql
#恢复数据,其实就是执行sql语句
恢复数据库语法:mysql -u 用户名 -p 导入库名 < 硬盘SQL文件绝对路径
mysql -u root -p webdb2 < d:\aa.sql

2. 图形界面 DataGrip方式

MYSQL 语法检查工具 在线_主键_02

第四章 多表查询

  • 笛卡尔积: 一个表三条数据,另一个表两条数据,联表查询出3*2=6条数据

1. 连接查询

# 内连接
# 隐式内连接
select * from student a,teacher b where a.id = b.id;
# 显式内连接
select * from student a inner join teacher b on a.id = b.id;
select * from student a join teacher b on a.id = b.id;
# 外连接
# 左外连接 左边的是主表
select * from student a left join teacher b on a.id = b.id;
select * from student a left outer join teacher b on a.id = b.id;
# 右外连接 右边的是主表
select * from student a right outer join teacher b on a.id = b.id;

2. 子查询

  • 子查询内部的select的结果相当于一个临时表,在临时表的结果上查询。
# select 嵌套
select * from student where age >(select avg(age) from student);

3. 多表查询规律总结

  1. 不管我们查询几张表,表连接查询会产出笛卡尔积,我们需要消除笛卡尔积,拿到正确的数据。我们需要找到表与表之间通过哪个字段关联起来的(通常是外键=主键)
  2. 消除笛卡尔积规律:2张表需要1个条件,3张表需要2个条件,4张表需要3个条件。(条件数量=表的数量-1),每张表都要参与进来
  3. 多表连接查询步骤: 3.1. 确定要查询哪些表 3.2. 确定表连接条件 3.3. 确定查询字段

第五章 事务

  • 在关系数据库中,一个事务可以是一条SQL语句,一组SQL语句或整个程序。

1. 事务的四大特性 ACID

1.1 原子性

  • 原子性是指事务**包装的一组sql(一组业务逻辑)是一个不可分割的工作单位,事务中的操作要么都发生,要么都不发生。

1.2 一致性

  • 通俗得讲就是事物的结果与预期相符
  • 事务必须是使数据库从一个一致性状态变到另一个一致性状态。一致性与原子性是密切相关的。

1.3 隔离性

  • 多个用户并发的访问数据库时,一个用户的事务不能被其他用户的事务干扰,多个并发的事务之间要相互隔离。
  • 一个事务的成功或者失败对于其他的事务是没有影响。2个事务应该相互独立。

1.4 持久性

  • 指一个事务一旦被提交,它对数据库的改变将是永久性的,哪怕数据库发生异常,重启之后数据亦然存在。

2. 操作事务

事务的操作

MySQL操作事务的语句

手动开启事务

start transaction

手动提交事务

commit

手动回滚事务

rollback

设置回滚点

savepoint 名字

回到回滚点

rollback to 名字

查询事务的自动提交情况

show variables like ‘%commit%’;

设置事务的手动提交方式

set autocommit = 0 – 关闭自动提交

2.1 SQL实现

# commit
start transaction #开启事务
update emp set salary = salary + 500 where id = 1001 and ename = '迪丽热巴';
update emp set salary = salary - 500 where id = 1002 and ename = '杨幂';
...
commit;# 多条sql都执行成功,commit

# rollback
start transaction #开启事务
update emp set salary = salary + 500 where id = 1001 and ename = '迪丽热巴';
update emp set salary = salary - 500 where id = 1002 and ename = '杨幂';
...
rollback;# 有一条sql执行失败就必须rollback回滚,撤销已经成功执行的sql语句,回到开启事务之前的状态.

# 注意:只要提交事务,那么数据就会长久保存了,就不能回滚事务了。即提交或者回滚事务都是代表结束当前事务的操作。
# 使用回滚点
start transaction;
update emp set salary = salary + 1000 where id = 1002;
update emp set salary = salary - 1000 where id = 1003;
savepoint a;
update emp set salary = salary + 2000 where id = 1004;
update emp set salary = salary - 2000 where id = 1005;
rollback to a; //回滚到a
commit ;

2.2 Java实现

package transaction_demo;

import mysql_use.DruidUtil;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.SQLException;

public class Demo01 {
    public static void main(String[] args) throws SQLException {

        //工具类获取连接
        Connection connection = DruidUtil.getConnection();
        try {
            connection.setAutoCommit(false);//开启事务
            addMoney(connection, 500, 1002); //给1002转入500
            subMoney(connection, 500, 1003); // 1003转出500
            connection.commit(); //都成功则提交
        } catch (Exception e) {
            connection.rollback();//异常则回滚,保证原子性,一致性
            e.printStackTrace();
        } finally {
            connection.close();
        }
    }

    public static void addMoney(Connection connection, Object... args) throws SQLException {
        connection = DruidUtil.getConnection();
        String sql = "update emp set salary = salary + ? where id = ?";
        PreparedStatement preparedStatement = connection.prepareStatement(sql);
        for (int i = 0; i < args.length; i++) {
            preparedStatement.setObject(i + 1, args[i]);
        }
        preparedStatement.executeUpdate();
        preparedStatement.close();
    }

    public static void subMoney(Connection connection, Object... args) throws SQLException {
        connection = DruidUtil.getConnection();
        String sql = "update emp set salary = salary - ? where id = ?";
        PreparedStatement preparedStatement = connection.prepareStatement(sql);
        for (int i = 0; i < args.length; i++) {
            preparedStatement.setObject(i + 1, args[i]);
        }
        preparedStatement.executeUpdate();
        preparedStatement.close();
    }
}

2.3 回滚原理(中间文件)

MYSQL 语法检查工具 在线_java_03

  1. 一个用户登录成功以后,服务器会创建一个临时日志文件。日志文件用来保存用户事务状态。
  2. 如果没有使用事务,则所有的操作直接写到
  3. 数据库中,不会使用日志文件。
  4. 如果开启事务,将所有的写操作写到日志文件中。
  5. 如果这时用户提交了事务,则将日志文件中所有的操作写到数据库中。
  6. 如果用户回滚事务,则日志文件会被清空,不会影响到数据库的操作。

3. 事务并发问题

并发访问的问题

含义

脏读

一个事务读取到了另一个事务中尚未提交的数据。最严重,杜绝发生。

不可重复读

一个事务中两次读取的数据内容不一致,这是事务update时引发的问题

幻读(虚读)

一个事务内读取到了别的事务插入或者删除的数据,导致前后读取记录行数不同。这是insert或delete时引发的问题

4. 事务的隔离级别

  • 为了解决事务并发问题。 上面的级别最低,下面的级别最高。“是”表示会出现这种问题,“否”表示不会出现这种问题。

级别

名字

隔离级别

脏读

不可重复读

幻读

数据库默认隔离级别

1

读未提交

read uncommitted




2

读已提交

read committed




Oracle和SQL Server

3

可重复读

repeatable read




MySQL

4

串行化

serializable




2、安全和性能对比

安全性:serializable > repeatable read > read committed > read uncommitted

性能 : serializable < repeatable read < read committed < read uncommitted

3、注意:其实三个问题,开发中最严重的问题就是脏读,这个问题一定要避免,而关于不可重复读和虚读其实只是感官上的错误,并不是逻辑上的错误。就是数据的时效性,所以这种问题并不属于很严重的错误。如果对于数据的时效性要求不是很高的情况下,我们是可以接受不可重复读和虚读的情况发生的。

第六章 存储过程

MySQL 存储过程

第七章 索引

1. 先插入大批数据

# 准备数据,使用存储过程插入10000000条数据
create database itcast01;

use itcast01;

-- 1. 准备表
CREATE TABLE user(
	id INT,
	username VARCHAR(32),
	password VARCHAR(32),
	sex VARCHAR(6),
	email VARCHAR(50)
);

-- 2. 创建存储过程,实现批量插入记录
DELIMITER $$ -- 声明存储过程的结束符号为$$
-- 可以将下面的存储过程理解为java中的一个方法
CREATE PROCEDURE auto_insert()
BEGIN
    DECLARE i INT DEFAULT 1;
	START TRANSACTION; -- 开启事务
    WHILE(i<=10000000)DO
        INSERT INTO user VALUES(i,CONCAT('jack',i),MD5(i),'male',CONCAT('jack',i,'@itcast.cn'));
        SET i=i+1;
    END WHILE;
	COMMIT; -- 提交
END$$ -- 声明结束
DELIMITER ; -- 重新声明分号为结束符号

-- 3. 查看存储过程
SHOW CREATE PROCEDURE auto_insert;

-- 4. 调用存储过程,插入千万条数据
CALL auto_insert();

2. 添加索引

-- 创建普通索引
create index 索引名 on 表名(字段);
-- 创建唯一索引
create unique index 索引名 on 表名(字段);
-- 创建普通组合索引
create index 索引名 on 表名(字段1,字段2,..);
-- 创建唯一组合索引
create unique index 索引名 on 表名(字段1,字段2,..);

# 显示索引
show index from 表名; 

# 删除索引
drop index 索引名 on 表名;
# 修改表时删除
alter table 表名 drop index 索引名;

3 索引的优缺点

3.1 优势

  • 根据索引字段查询,能大幅提高查询速度(数据量越大越明显)
  • 索引底层就是B+ 树(二分查找树),先通过索引字段二分查找,找到某个叶子结点(存储着该条数据的主键值),再通过查找主键的B+树 找到具体的叶子结点拿到数据。
  • 索引走了两次二分查找树,索引B+一次,主键B+一次。

3.2 劣势

  • 增删改操作时需要同步更新索引。
  • 索引需要占用一定的物理空间

第七章 参考资料

MySQL |菜鸟教程

B站黑马程序员

MySQL中ALL 和 ANY的用法

如何理解事务一致性?

百度百科