MySQL学习
1、初始MySQL
1·1、什么是数据库
数据库 (DB,BataBase)
作用:存储数据,管理数据
1·2、数据库分类
关系型数据库:(SQL)
- MySQL、Oracle、sql Server
- 各个表之间、表中行和列之间的关系进行数据存储。
非关系型数据库:(NoSQL) Not Only
- Redis、MongDB
- 对象存储,通过对象的自身属性来决定。
1·3、连接数据库
mysql -h localhost -u root -proot --连接数据库
show databases; -- 查看所有的数据库
use nbrd; -- 切换数据库 use 数据库名
show tables; -- 查看数据库中所有的表
describe t_rduser; -- 显示表中所有的信息
create database wanshy; -- 创建一个数据库
exit; -- 退出连接
-- 单行注释
/*
多行注释
*/
数据库 xxx 语言
DDL : 定义
DML : 操作
DQL : 查询
DCL : 控制
Navicat查看表sql语句:选择一张表,鼠标右键,点击对象信息,然后选择DDL即可看到创建表的sql语句
2、操作数据库
2·1、操作数据库
1、创建数据库
CREATE DATABASE [IF NOT EXISTS] user
2、删除数据库
DROP DATABASE [IF EXISTS] user
3、使用数据库
-- 如果表名或者字段名是一个特殊字符。就需要带``
USE `nbrd`
4、查看数据库
SHOW DATABASES -- 查看所有的数据库
2·2、数据库的数据(列)类型
数值
类型 |
介绍 |
大小 |
tinyint |
十分小的数据 |
1个字节 |
smallint |
较小的数据 |
2个字节 |
mediumint |
中等大小的数据 |
3个字节 |
int(*) |
标准的整数 |
4个字节 |
bigint |
较大的数据 |
8个字节 |
float |
浮点数 |
4个字节 |
double |
浮点数 |
8个字节(精度问题) |
decimal |
字符串形式的浮点数(金融银行使用) |
|
字符串
类型 |
介绍 |
大小 |
char |
字符串固定大小的 |
0-255 |
varchar(*) |
可变字符串 |
0-65535 |
tinytext |
微型文本 |
2^8-1 |
text |
文本串(保存大文本) |
2^16-1 |
时间日期
类型 |
介绍 |
大小 |
date |
YYYY-MM-DD,日期格式 |
|
time |
HH:mm:ss,时间格式 |
|
datetime(*) |
YYYY-MM-DD HH:mm:ss,最常用的时间格式 |
|
timestamp(*) |
时间戳,1970.1.1到现在的毫秒数 |
|
year |
年份表示 |
|
null
没有值,未知
2·3、数据库的字段属性(重点)
Unsigned :
zerofill:
- 0填充的
- 不足的位数,使用0来填充,int(3), 5 — 005
自增:
- 通常理解为自增,自动在上一条记录的基础上 + 1 (默认)
- 通常用来设计唯一的主键,必须是整数类型
- 可以自定义设计主键自增的起始值和步长
==非空:==NULL not null
- 设置了not null, 如果不给它赋值,就会报错
- NULL, 如果不填写,默认就是null
默认:
补充:
int(M) varchar(M)
M代表的不是数据的长度
在开启zerofill(填充零)情况下,若int(M)存储的数字长度是小于M的则会在不足位数的前面补充0,但是如果int(5)中存储的数字长度大于5位的话,则按照实际存储的显示(数据大小在int类型的4个字节范围内即可)
2·4、创建数据库表
-- 注意点:
-- 使用英文的 () ,表的 名称 和 字段 尽量使用 `` 括起来
-- AUTO_INCREMENT 自增
-- 字符串使用 '' 单引号括起来
-- 所有的语句后面加 , (英文的),最后一个不用加
-- PRIMARY KEY 主键,一般一个表只有一个唯一的主键
CREATE TABLE IF NOT EXISTS `student` (
`id` INT(4) NOT NULL AUTO_INCREMENT COMMENT '学号',
`name` VARCHAR(30) NOT NULL DEFAULT '匿名' COMMENT '姓名',
`pwd` VARCHAR(20) NOT NULL DEFAULT '123123' COMMENT '密码',
`sex` VARCHAR(2) NOT NULL DEFAULT '女' COMMENT '性别',
`birthday` datetime DEFAULT NULL COMMENT '出生日期',
`address` VARCHAR(100) DEFAULT NULL COMMENT '家庭住址',
`email` VARCHAR(50) DEFAULT NULL COMMENT '邮箱',
PRIMARY KEY (`id`)
)ENGINE=INNODB DEFAULT CHARSET=utf8
格式
CREATE TABLE [IF NOT EXISTS] `表名` (
`字段名` 列类型 [属性] [索引] [注释],
`字段名` 列类型 [属性] [索引] [注释],
`字段名` 列类型 [属性] [索引] [注释],
`字段名` 列类型 [属性] [索引] [注释],
......
`字段名` 列类型 [属性] [索引] [注释],
`字段名` 列类型 [属性] [索引] [注释]
)[表类型][字符集设置]注释[]
--常用命令
SHOW CREATE DATABASE test -- 查看创建数据库语句
SHOW CREATE TABLE student -- 查看student数据表的定义语句
DESC student -- 显示表结构
2·5、数据表的类型
-- 关于数据库引擎
/*
INNODB 默认使用
MYISAM 早些年使用
*/
|
MYISAM |
INNODB |
事务支持 |
不支持 |
支持 |
数据行锁定 |
不支持 |
支持 |
外键约束 |
不支持 |
支持 |
全文索引 |
支持 |
不支持 |
表空间大小(占内存大小) |
较小 |
较大,约等于前者的2倍 |
好处:
- MYISAM 节约空间,速度较快
- INNODB 安全性高,事物的处理,多表多用户操作
设置数据库表的字符集编码
CHARSET=UTF8
2·6、删除修改表
修改
-- 修改表名 ALTER TABLE 旧表名 RENAME AS 新表名
ALTER TABLE student RENAME AS teacher
-- 增加表字段 ALTER TABLE 表名 ADD 字段名 列属性
ALTER TABLE teacher ADD age INT(11)
-- 修改表字段(重命名,修改约束)
-- ALTER TABLE 表名 MODIFY 字段名 列属性
ALTER TABLE teacher MODIFY age VARCHAR(11) -- 修改约束
-- ALTER TABLE 表名 CHANGE age 字段名 列属性
ALTER TABLE teacher CHANGE age nian INT(2) -- 重命名
-- 删除表字段 ALTER TABLE 表名 DROP 字段名
ALTER TABLE teacher DROP nian
删除
-- 删除表(如存在再删除)
DROP TABLE IF EXISTS teacher
所有创建和删除操作尽量加上判断,以免报错
3、MySQL数据管理
3·1、外键(了解)
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-6BanW3XT-1661237296867)(https://bkimg.cdn.bcebos.com/pic/c83d70cf3bc79f3dd5004319b8a1cd11728b2931?x-bce-process=image/watermark,image_d2F0ZXIvYmFpa2U4MA==,g_7,xp_5,yp_5/format,f_auto)]
【强制】不得使用外键与级联,一切外键概念必须在应用层解决。
3·2、DML语言(*)增删改
DML语言:数据操作语言
3·3、添加
insert
-- 插入语句(添加)
-- 插单个 insert into 表名([字段名1, 字段名2, 字段3])values('值1', '值2', '值3', ......)
-- 插多个 insert into 表名([字段名1, 字段名2, 字段3])values('值1'), ('值2'), ('值3'), (......)
-- 由于主键自增我们可以省略
-- 一般数据和字段一一对应
INSERT INTO `user`(username, age) VALUES ('wanshy', '18')
INSERT INTO `user`(username) VALUES ('zp'), ('王始一')
3·4、修改
update
-- 修改语句,带条件
UPDATE `user` SET `age` = '100' WHERE `username` = 'zp'
-- 不指定条件,会改动所有表
UPDATE `user` SET `age` = '8'
-- 语法
update 表名 set 列名称 = 值, 【列名称 = 值, ......】 where 【条件】
-- 修改多个属性,逗号隔开
UPDATE `user` SET `age` = '8', `username` = '这尼玛8岁' WHERE `id` = 4
条件:where 后面可以跟 子句 运算符
操作符
操作符 |
含义 |
范围 |
结果 |
= |
等于 |
5=6 |
false |
<>或!= |
不等于 |
5<>6 |
true |
> |
|
|
|
< |
|
|
|
>= |
|
|
|
<= |
|
|
|
between … and … |
在某范围内 |
|
[2,5] |
and |
和/并且 |
|
|
or |
或/或者 |
|
|
3·5、删除
delete 命令
语法:delete from 表名 [where] [条件]
-- 删除数据 不加条件会将表里数据全部删除
-- DELETE FROM `user`(不能这样写,写了就准备跑路)
DELETE FROM `user` WHERE `email` = 123
truncate 命令
作用:完全清空一个数据库,表结构和索引约束不会变!!!!!!!!!!!!!
-- 清空表
TRUNCATE TABLE `user`
delete 和 truncate 区别
- 相同点:都能删除数据,都不会删除表结构
- 不同点:
- truncate 重新设置 自增列 计数器会归零
- truncate 不会影响事务
DELETE FROM `user` -- 不会影响自增
TRUNCATE TABLE `user` -- 自增会归零
了解:delete删除问题
,重启数据库,现象
- innoDB 自增列会从1开始 (存在内存当中,断电即失)
- MyISAM 继续从上一个自增量开始 (存在文件中,不会丢失)
4、DQL查询数据(*)
select语法:
select [distinct] [字段] from [表名]
[left | right | inner join 表名 on 等值判断] -- 联合查询
[where] -- 满足的条件
[group by] -- 查询结果按哪个字段分组
[having] -- 分组后满足的条件,跟where一样
[order by] -- 排序
[limit] -- 分页
4·1、DQL(数据查询语言)
- 所有查询都使用它
- 简单复杂查询它都能做
- 数据库最核心语言
- 使用频率最高的语言
4·2、指定查询字段
-- 查询全部学生 SELECT 字段 FROM 表
SELECT * FROM `user`
-- 查询指定字段
SELECT `username`, `age` FROM `user`
-- 别名 字段可以起别名 表也可以起别名
SELECT `username` AS 名字, `age` AS 年龄 FROM `user` AS 用户表
-- 函数 concat(a, b)
SELECT CONCAT('名字:', `username`) AS 姓名 FROM `user`
语法:SELECT 字段, … FROM 表
去重:去除select查询出重复的数据
-- 去重
SELECT DISTINCT `username`, `age` FROM `user`
语法:SELECT DISTINCT 字段, … FROM 表
数据库的小玩法
-- 查询系统版本
SELECT VERSION()
-- 计算
SELECT 100*100+100/100-100 AS 结果
-- 查询自增步长
SELECT @@auto_increment_increment
-- 所有用户年龄加1
SELECT `username`, `age` + 1 AS 变化后 FROM `user`
4·3、where条件子句
逻辑运算符
运算符 |
语法 |
描述 |
and && |
a and b a&&b |
逻辑与,两个都为真,结果为真 |
or || |
a or b a||b |
逻辑或,一个为真,结果为真 |
NOT |
not a !a |
逻辑非,取反 |
模糊查询: 比较运算符
运算符 |
语法 |
描述 |
IS NULL |
a is null |
如果操作符为NULL,结果为真 |
IS NOT NULL |
a is not null |
如果操作符为NOT NULL,结果为真 |
BETWEEN…AND… |
a between b and c |
a在b和c之间,结果为真 |
LIKE |
a like b (%表示0~N, _表示一个) |
a匹配b,结果为真 |
IN |
a in (a1,a2,a3,…) |
a在a1或a2或a3其中一个时,结果为真 |
4·4、联表查询
JOIN ON 对比
操作 |
描述 |
inner join |
如果表中至少有一个匹配,就返回行 |
left join |
即使右表中没有匹配,也会从左表中返回所有的值 |
right join |
即使左表中没有匹配,也会从右表中返回所有的值 |
4·5、分页和排序
排序 order by
-- 排序:升序 ASC 降序 DESC
SELECT `username`, `age` FROM `user` ORDER BY `age` DESC
分页 limit
-- 分页:LIMIT 起始下标, 显示页面大小
-- 规律:limit (N-1)*pageSize, pageSize
-- 【N 当前页】
-- 【(N-1)*pageSize 起始下标】
-- 【pageSize 页面大小】
-- 【数据总数/页面大小 = 总页数】
SELECT `username`, `age` FROM `user` ORDER BY `age` ASC
LIMIT 2, 2
4·6、子查询
本质:在where中嵌套一个子查询语句
语法:(由里及外)
select 字段 from 表名
where (
select 字段 from 表名
where 条件
)
5、MySQL函数
5·1、数学函数
-
ABS(x)
返回x的绝对值
-
BIN(x)
返回x的二进制(OCT返回八进制,HEX返回十六进制)
-
CEILING(x)
返回大于x的最小整数值
-
EXP(x)
返回值e(自然对数的底)的x次方
-
FLOOR(x)
返回小于x的最大整数值
-
GREATEST(x1,x2,...,xn)
返回集合中最大的值
-
LEAST(x1,x2,...,xn)
返回集合中最小的值
-
LN(x)
返回x的自然对数
-
LOG(x,y)
返回x的以y为底的对数
-
MOD(x,y)
返回x/y的模(余数)
-
PI()
返回pi的值(圆周率)
-
RAND()
返回0到1内的随机值,可以通过提供一个参数(种子)使RAND()随机数生成器生成一个指定的值。
-
ROUND(x,y)
返回参数x的四舍五入的有y位小数的值
-
SIGN(x)
返回代表数字x的符号的值
-
SQRT(x)
返回一个数的平方根
-
TRUNCATE(x,y)
返回数字x截短为y位小数的结果
SELECT ABS(-10) -- 绝对值
SELECT CEILING(9.1) -- 向上取整
SELECT FLOOR(9.8) -- 向下取整
SELECT RAND() -- 随机数返回0~1之间的随机数
SELECT SIGN(10.6) -- 判断一个数的符号 0-0 负数返回-1 正数返回1
5·2、聚合函数(常用于GROUP BY从句的SELECT查询中)(常用*)
-
AVG(col)
返回指定列的平均值
-
COUNT(col)
返回指定列中非NULL值的个数
-
MIN(col)
返回指定列的最小值
-
MAX(col)
返回指定列的最大值
-
SUM(col)
返回指定列的所有值之和
-
GROUP_CONCAT(col)
返回由属于一组的列值连接组合而成的结果
5·3、字符串函数
-
ASCII(char)
返回字符的ASCII码值
-
BIT_LENGTH(str)
返回字符串的比特长度
-
CONCAT(s1,s2...,sn)
将s1,s2…,sn连接成字符串
-
CONCAT_WS(sep,s1,s2...,sn)
将s1,s2…,sn连接成字符串,并用sep字符间隔
-
INSERT(str,x,y,instr)
将字符串str从第x位置开始,y个字符长的子串替换为字符串instr,返回结果
-
FIND_IN_SET(str,list)
分析逗号分隔的list列表,如果发现str,返回str在list中的位置
-
LCASE(str)或LOWER(str)
返回将字符串str中所有字符改变为小写后的结果
-
LEFT(str,x)
返回字符串str中最左边的x个字符
-
LENGTH(s)
返回字符串str中的字符数
-
LTRIM(str)
从字符串str中切掉开头的空格
-
POSITION(substr,str)
返回子串substr在字符串str中第一次出现的位置
-
QUOTE(str)
用反斜杠转义str中的单引号
-
REPEAT(str,srchstr,rplcstr)
返回字符串str重复x次的结果
-
REVERSE(str)
返回颠倒字符串str的结果
-
RIGHT(str,x)
返回字符串str中最右边的x个字符
-
RTRIM(str)
返回字符串str尾部的空格
-
STRCMP(s1,s2)
比较字符串s1和s2
-
TRIM(str)
去除字符串首部和尾部的所有空格
-
UCASE(str)
或UPPER(str)
返回将字符串str中所有字符转变为大写后的结果
-- 字符串函数
SELECT CHAR_LENGTH('关于zp一个人过七夕,而wanshy一个人过也在嘲笑zp') -- 字符串长度
SELECT CONCAT('zp','七夕','孤寡') -- 拼接字符串
SELECT INSERT('七夕快乐',1,2,'zp') -- 查询,替换,从某个位置开始替换某个长度
5·4、日期和时间函数
-
CURDATE()
或CURRENT_DATE()
返回当前的日期
-
CURTIME()
或CURRENT_TIME()
返回当前的时间
-
DATE_ADD(date,INTERVAL int keyword)
返回日期date加上间隔时间int的结果(int必须按照关键字进行格式化),如:SELECTDATE_ADD(CURRENT_DATE,INTERVAL 6 MONTH);
-
DATE_FORMAT(date,fmt)
依照指定的fmt格式格式化日期date值
-
DATE_SUB(date,INTERVAL int keyword)
返回日期date加上间隔时间int的结果(int必须按照关键字进行格式化),如:SELECTDATE_SUB(CURRENT_DATE,INTERVAL 6 MONTH);
-
DAYOFWEEK(date)
返回date所代表的一星期中的第几天(1~7)
-
DAYOFMONTH(date)
返回date是一个月的第几天(1~31)
-
DAYOFYEAR(date)
返回date是一年的第几天(1~366)
-
DAYNAME(date)
返回date的星期名,如:SELECT DAYNAME(CURRENT_DATE);
-
FROM_UNIXTIME(ts,fmt)
根据指定的fmt格式,格式化UNIX时间戳ts
-
HOUR(time)
返回time的小时值(0~23)
-
MINUTE(time)
返回time的分钟值(0~59)
-
MONTH(date)
返回date的月份值(1~12)
-
MONTHNAME(date)
返回date的月份名,如:SELECT MONTHNAME(CURRENT_DATE);
-
NOW()
返回当前的日期和时间
-
QUARTER(date)
返回date在一年中的季度(1~4),如SELECT QUARTER(CURRENT_DATE);
-
WEEK(date)
返回日期date为一年中第几周(0~53)
-
YEAR(date)
返回日期date的年份(1000~9999)
5·5、加密函数
-
AES_ENCRYPT(str,key)
返回用密钥key对字符串str利用高级加密标准算法加密后的结果,调用AES_ENCRYPT的结果是一个二进制字符串,以BLOB类型存储
-
AES_DECRYPT(str,key)
返回用密钥key对字符串str利用高级加密标准算法解密后的结果
-
DECODE(str,key)
使用key作为密钥解密加密字符串str
-
ENCRYPT(str,salt)
使用UNIXcrypt()函数,用关键词salt(一个可以惟一确定口令的字符串,就像钥匙一样)加密字符串str
-
ENCODE(str,key)
使用key作为密钥加密字符串str,调用ENCODE()的结果是一个二进制字符串,它以BLOB类型存储
-
MD5()
计算字符串str的MD5校验和
-
PASSWORD(str)
返回字符串str的加密版本,这个加密过程是不可逆转的,和UNIX密码加密过程使用不同的算法。
-
SHA()
计算字符串str的安全散列算法(SHA)校验和
5·6、控制流函数
-
CASE WHEN[test1] THEN [result1]...ELSE [default] END
如果testN是真,则返回resultN,否则返回default
-
CASE [test] WHEN[val1] THEN [result]...ELSE [default]END
如果test和valN相等,则返回resultN,否则返回default
-
IF(test,t,f)
如果test是真,返回t;否则返回f
-
IFNULL(arg1,arg2)
如果arg1不是空,返回arg1,否则返回arg2
-
NULLIF(arg1,arg2)
如果arg1=arg2返回NULL;否则返回arg1
5·7、格式化函数
-
DATE_FORMAT(date,fmt)
依照字符串fmt格式化日期date值
-
FORMAT(x,y)
把x格式化为以逗号隔开的数字序列,y是结果的小数位数
-
INET_ATON(ip)
返回IP地址的数字表示
-
INET_NTOA(num)
返回数字所代表的IP地址
-
TIME_FORMAT(time,fmt)
依照字符串fmt格式化时间time值
5·8、类型转化函数
为了进行数据类型转化,MySQL提供了CAST()
函数,它可以把一个值转化为指定的数据类型。类型有:BINARY
,CHAR
,DATE
,TIME
,DATETIME
,SIGNED
,UNSIGNED
5·9、系统信息函数
-
DATABASE()
返回当前数据库名
-
BENCHMARK(count,expr)
将表达式expr重复运行count次
-
CONNECTION_ID()
返回当前客户的连接ID
-
FOUND_ROWS()
返回最后一个SELECT查询进行检索的总行数
-
USER()或SYSTEM_USER()
返回当前登陆用户名
-
VERSION()
返回MySQL服务器的版本
6、事务
参考博客:数据库难点:脏读、幻读、不可重复读与四种隔离级别
6·1、什么是事务
简单地说就是要么成功,要么失败
……………………
简单例子就是A给B转账,如果其中一个出现问题,那么整个转账都会回滚
……………………
将一组SQL放在一个批次中去执行~~
事务原则:ACID原则,原子性、一致性、隔离性、持久性 (脏读、幻读……)
原子性:(Atomicity)
- 原子性表示A给B转帐这两个步骤要么一起成功,要么一起失败,反正不可能让其中一个成功的
一致性:(Consistency)
- AB转账不管怎么转,最后他们两个的钱之和都是不变的(最终一致性)
隔离性:(Isolation)
- A给B转,B给C转,两个之间互不影响,针对多用户同时操作时
持久性:(Durability)
- 表示事务结束后不会因为宕机或断电等突发状况导致数据丢失
- 事务没有提交前发生意外,恢复到原来状态
- 事务已经提交,就已经持久化到数据库里,一旦提交就不可逆
如果隔离失败就会出现问题
脏读:
- 一个事务读取了另一个事务未提交的数据
- T2时刻,事务B把原来李华的年龄由原数据13改为了23,此后又被T3时刻的事务A读取到了,但是T4时刻事务B发生异常,进行了回滚操作。这个过程,我们称23为脏数据,事务A进行了一次脏读
不可重复读:
- 不可重复读,有时候也会说成“读已提交”。什么意思呢,就是在一个事务内,多次读取同一个数据,却返回了不同的结果。实际上,这是因为在该事务间隔读取数据的期间,有其他事务对这段数据进行了修改,并且已经提交,就会发生不可重复读事故。
- 图示中事务A在T1和T4查询同一语句,却得到了不同的结果,这是因为T2~T3时刻事务B对该数据进行了修改,并提交。这个过程,出现了在一个事务内两次读到的数据却是不一样的,我们称为是不可重复读。
不可重复读和脏读的区别:前者是“读已提交”,后者是“读未提交”
幻读:
- 幻读是指当事务不独立执行时,插入或者删除另一个事务当前影响的数据而发生的一种类似幻觉的现象。举个例子,某事务在检查表中的数据数count时,是10,过一段时间之后再查是11,这就发生了幻读,之前的检测获取到的数据如同幻觉一样。
- 出现幻读和不可重复读的原因很像,都是在多次操作数据的时候发现结果和原来的不一样了,出现了其他事务干扰的现象。**但是,幻读的偏重点是添加和删除数据,多次操作数据得到的记录数不一样;不可重复读的偏重点是修改数据,多次读取数据发现数据的值不一样了。**事务B向表中新插入了一条数据,事务A在T3时刻后查询数据的时候,突然发现数据和以前查询的时候多出了一项,像产生了幻觉一样。
执行事务
-- ========================= 事务 ===================================
-- mysql 默认开启事务的
SET autocommit = 0 /* 关闭 */
SET autocommit = 1 /* 开启(默认) */
-- 手动处理事务
SET autocommit = 0 /* 关闭自动条件 */
-- 事务开启
START TRANSACTION -- 标记一个事务开始,从这个之后的 sql 都在同一个事务内
INSERT xxx
INSERT xxx
-- 提交:持久化(成功!)
COMMIT
-- 回滚:回到原来的样子(失败!)
ROLLBACK
-- 事务结束
SET autocommit = 1 /* 开启自动提交 */
-- 了解 保存点名 设置一个事务的保存点
SAVEPOINT
-- 回滚到保存点
ROLLBACK TO SAVEPOINT
-- 删除保存点 撤销保存点
RELEASE SAVEPOINT
6·2、四种隔离级别
1.读未提交(Read Uncommitted):在该隔离级别,所有事务都可以看到其他未提交事务的执行结果。本隔离级别很少用于实际应用,因为它的性能也不比其他级别好多少。读取未提交的数据,也被称之为脏读(Dirty Read)
2.读已提交(Read Committed):这是大多数数据库系统的默认隔离级别(但不是MySQL默认的)。它满足了隔离的简单定义:一个事务只能看见已经提交事务所做的改变。这种隔离级别也支持所谓的不可重复读(NonrepeatableRead),因为同一事务的其他实例在该实例处理其间可能会有新的commit,所以同一select可能返回不同结果
3.可重复读(Repeatable Read):这是MySQL的默认事务隔离级别,同一事务的多个实例在并发读取数据时,会看到同样的数据。不过理论上,这会导致另一个棘手的问题:幻读(Phantom Read)。简单的说,幻读指当用户读取某一范围的数据行时,另一个事务又在该范围内插入了新行,当用户再读取该范围的数据行时,会发现有新的“幻影” 行。
4.可串行化(Serializable):这是最高的隔离级别,它通过强制事务排序,使之不可能相互冲突,从而解决幻读问题。简言之,它是在每个读的数据行上加上共享锁。在这个级别,可能导致大量的超时现象和锁竞争
这四种隔离级别越往后越影响性能,如何选取根据业务需求而定。以下是四种隔离级别中对脏读、不可重复读、幻读的影响情况。
读未提交(Read Uncommitted)依旧存在脏读、不可重复读和幻读;
读已提交(Read Committed)解决了脏读问题,因为发生脏读的条件就是读未提交的数据;
可重复读(Repeatable Read)进一步解决了不可重复读的问题,从隔离名称就可以看出,但还存在幻读问题;
可串行化(Serializable)解决了脏读、幻读、不可重复读问题,但是设立这种隔离级别会大大消耗性能。
7、索引
MySQL官方对索引的定义为:索引(Index)是帮助MySQL高效获取数据的数据结构。
提取句子主干,就可以得到索引的本质:索引是数据结构。
7·1、索引分类
- 主键索引(primary key)-------对应Navicat( 空空如也~ )
- 唯一索引(unique key)-------对应Navicat(Unique)
- 常规索引(key)-------对应Navicat(Normal)
- 全文索引(full text)-------对应Navicat(Full Text)
7·2、测试索引
-- 插入100万条数据
set global log_bin_trust_function_creators=TRUE;
delimiter $$
CREATE FUNCTION test_data()
RETURNS INT
BEGIN
DECLARE num INT DEFAULT 1000000;
DECLARE i INT DEFAULT 0;
WHILE i < num DO
INSERT INTO student(`name`,`pwd`,`birthday`,`address`,`email`)
VALUES(CONCAT('用户',i), '123321', 20220101, '北京', '000000@00.000');
SET i = i + 1;
END WHILE;
RETURN i;
END$$;
SELECT test_data();
7·3、索引原则
- 索引不是越多越好
- 不要对进程变动数据加索引
- 小数据量的表不需要加索引
幻读、不可重复读问题,但是设立这种隔离级别会大大消耗性能。
7、索引
MySQL官方对索引的定义为:索引(Index)是帮助MySQL高效获取数据的数据结构。
提取句子主干,就可以得到索引的本质:索引是数据结构。
7·1、索引分类
- 主键索引(primary key)-------对应Navicat( 空空如也~ )
- 唯一索引(unique key)-------对应Navicat(Unique)
- 常规索引(key)-------对应Navicat(Normal)
- 全文索引(full text)-------对应Navicat(Full Text)
7·2、测试索引
-- 插入100万条数据
set global log_bin_trust_function_creators=TRUE;
delimiter $$
CREATE FUNCTION test_data()
RETURNS INT
BEGIN
DECLARE num INT DEFAULT 1000000;
DECLARE i INT DEFAULT 0;
WHILE i < num DO
INSERT INTO student(`name`,`pwd`,`birthday`,`address`,`email`)
VALUES(CONCAT('用户',i), '123321', 20220101, '北京', '000000@00.000');
SET i = i + 1;
END WHILE;
RETURN i;
END$$;
SELECT test_data();
7·3、索引原则
- 索引不是越多越好
- 不要对进程变动数据加索引
- 小数据量的表不需要加索引
- 索引一般加在常用来查询的字段上