这是我参与「第五届青训营 」伴学笔记创作活动的第 17 天
介绍MySQL
什么是MySQL
MySQL是一个关系型数据库管理系统
什么是关系型数据库
是指采用了关系模型来组织数据的数据库,其以行和列的形式存储数据
安装配置
方式1 直接安装
方式2 docker安装
docker是什么
Docker 是一个开源的应用容器引擎,容器是完全使用沙箱机制(运行隔离环境之中),相互之间不会有任何接口。
docker如何安装
进入官网 下载docker desktop版本Docker: Accelerated, Containerized Application Development
一些常见的docker命令
-
docker pull <image>拉取镜像- 以拉取mysql5.7镜像为例 docker pull mysql:5.7
- 如果要拉取最新版本的镜像 docker pull muysql:latest
-
docker run <image>运行镜像-
-itd使容器在后台运行 -
-p映射容器端口到主机 我要映射容器中的3306端口到主机上的3307端口-p 3307:3306 -
--name为容器命名 为容器命名为mysql5.7--name mysql5.7 -
--restart重启策略 如果让容器每次都自动重启 参数为--restart=always -
-v映射容器中的磁盘到本地 如映射mysql文件到本地-v /docker/MySQL/5.7/data:/var/lib/mysql -
设置容器环境变量
- 如mysql设置默认root密码
-e MYSQL_ROOT_PASSWORD 123456
- 如mysql设置默认root密码
-
安装数据库管理工具
navicat 自行查找
增删改查
创建一个数据库
方式1 使用命令行创建
-
登录mysql
-
mysql -uroot -p登录数据库 -
show databases;显示数据库列表 -
use <数据库名>;打开数据库 -
show tables;查看数据库的表 -
describe <表名>;展示表结构 -
create database <数据库名>;新建数据库 -
create table <表名> (表中的列及其类型);例如create table user (id int AUTO_INCREMENT,age int,height double,PRIMARY KEY (id));-
不一定只有主键才能够自动递增
-
一个表 只有一个字段可以自动递增
-
在设置自动递增字段前 需要设定好唯一索引
uniqueUNIQUE和PRIMARY KEY的区别:PRIMARY KEY=UNIQUE+NOT NULL
-
-
方式2 使用navicat创建
演示
增(INSERT)
INSERT INTO <表名> (字段名1,字段名2,…) VALUES (值1,值2,…);
查(SELECT)
SELECT * FROM user;
SELECT age FROM user;
SELECT age FROM user WHERE id=1;
改(UPDATE)
UPDATE <表名> SET 字段名1=值1,字段名2=值2,字段名n=值n WHERE 条件;
删(DELETE)
DELETE FROM <表名> WHERE 条件;
多表联查
使用JOIN进行多表联查
SELECT * FROM <表名1> INNER JOIN <表名2> on 链接条件 WHERE 条件;
- RIGHT JOIN
- LEFT JOIN
- INNER JOIN
函数
-
COUNT() 计数函数
SELECT COUNT(*) as <自定义列名> FROM <表名> WHERE 条件;SELECT COUNT(age) as <自定义列名> FROM <表名> WHERE 条件;
-
AVG() 平均值
SELECT ARG(age) as <自定义列名> FROM <表名> WHERE 条件;
用户与权限
-
用户表存在mysql当中
-
权限表
- db表:数据库层权限
- tables_priv表:表层权限
- columns_priv表:字段层权限
-
赋予权限可以采用命令方式 也可以采用图形化界面 这里推荐phpmyadmin【演示】
事务
什么是事务
事务是一个整体,在这个整体中,每个sql语句都是相关联的。里面的语句要么都执行成功,要么都不成功。
为什么要有事务
例子:
比如前几天胡桃的池子不是开了嘛,我要氪金抽胡桃。那这里就涉及到了充钱问题。假设,我开始充钱,选择了要充的创世结晶,然后用支付宝扫码付款。这个时候刚好米哈游的服务器出现了问题,他的服务端刚准备在我的账号上将创世结晶+6480的时候,服务器断电了,这就导致了我钱花出去了,但是创世结晶没到账。这个时候就需要用事务解决这个问题。用事务的什么特性呢?原子性。
事务的四个特性
- 原子性:指事务是一个不可分割的最小工作单位,事务中的操作只有都发生和都不发生两种情况
- 一致性:事务必须使数据库从一个一致状态变换到另外一个一致状态
- 隔离性:一个事务的执行不能被其他事务干扰,即一个事务内部的操作及使用的数据对并发的其他事务是隔离的,并发执行的各个事务之间不能互相干扰
- 持久性:一个事务一旦提交成功,它对数据库中数据的改变将是永久性的,接下来的其他操作或故障不应对其有任何影响
事务的分类
-
隐式事务:该事务没有明显的开启和结束标记,它们都具有自动提交事务的功能(默认的增删改查)
-
显示事务:该事务具有明显的开启和结束标记
set autocommit=0;关闭自动提交事务commit;提交事务
事务的并发时会出现的问题
- 脏读:对于两个事务T1,T2,T1读取了已经被T2更新但还没有被提交的字段之后,若T2回滚,T1读取的内容就是临时且无效的
- 不可重复读 :对于两个事务T1,T2,T1读取了一个字段,然后T2更新了该字段之后,T1在读取同一个字段,值就不同了
- 幻读:对于两个事务T1,T2,T1在A表中读取了一个字段,然后T2又在A表中插入了一些新的数据时,T1再读取该表时,会读多出几行
为了解决以上问题,就出现了事务的隔离级别
事务的隔离级别
- read uncommitted(读未提交数据):允许事务读取未被其他事务提交的变更。(脏读、不可重复读和幻读的问题都会出现)
- read committed(读已提交数据):只允许事务读取已经被其他事务提交的变更。(可以避免脏读,但不可重复读和幻读的问题仍然可能出现)
- repeatable read(可重复读):确保事务可以多次从一个字段中读取相同的值,在这个事务持续期间,禁止其他事务对这个字段进行更新(update)。(可以避免脏读和不可重复读,但幻读仍然存在)
- serializable(串行化):确保事务可以从一个表中读取相同的行,在这个事务持续期间,禁止其他事务对该表执行插入、更新和删除操作,所有并发问题都可避免,但性能十分低下(因为你不完成就都不可以弄,效率太低)
JDBC(简单演示)
什么是JDBC
JDBC (Java DataBase Connectivity),也就是java数据库连接,是一种用于执行SQL语句的Java API,可以为多种关系型数据库提供统一访问,它是由一组用Java语言编写的类和接口组成的。
如何使用
- 安装驱动
public class Test {
public static void main(String[] args) throws ClassNotFoundException, SQLException {
Class.forName("com.mysql.cj.jdbc.Driver");
//获取数据库连接
Connection con= DriverManager.getConnection("jdbc:mysql://localhost:3307/learn","root","123456");
//获取执行者对象
Statement stat=con.createStatement();
//执行sql语句并返回结果
String sql="select * from user";
ResultSet re=stat.executeQuery(sql);
//处理结果
while (re.next()){
System.out.println(re.getString("id"));
}
//释放资源
con.close();
}
}
扩展
与Redis结合工作
Redis是什么
Redis是一种非关系型数据库,是一个高性能的 key-value 数据库。
和mysql的关系
mysql是关系型数据库,主要用于存放持久化数据,将数据存储在硬盘中,读取速度较慢。
redis是NOSQL,即非关系型数据库,也是缓存数据库,即将数据存储在缓存中,缓存的读取速度快,基于内存,能够大大的提高运行效率,但是保存时间有限。
mysql作为持久化存储的关系型数据库,相对薄弱的地方在于每次请求访问数据库时,都存在着I/O操作
mysql和redis一般都是配合使用。 需要高性能的地方使用Redis,不需要高性能的地方使用MySQL。存储数据在MySQL和Redis之间做同步。
演示
通过最近写的项目 演示mysql与redis的结合