MySQL学习过程&测试代码

MySQL学习过程【待补充】

1.1 删除 delete 和 truncate

-- delete 和 truncate 的区别
-- delete删除后 表自增不变
-- truncate删除后 同时删除表自增
-- innodb引擎下 delete 后 重启数据库,自增重新计数。 (存在内存中,断电即失  ||  8.0 版本的数据库测试没有重新计数。8.0 之前的数据库计数器失效)
-- myisam 引擎下 继续从上个自增开始。(存在文件中,不会丢失)

CREATE TABLE `test`(
	`id` INT(4) NOT NULL AUTO_INCREMENT,
	`value` INT(4) NOT NULL,
	PRIMARY KEY (`id`)
)ENGINE=INNODB DEFAULT CHARSET=utf8

INSERT INTO `test`(`value`) VALUES('1'),('1'),('1')

DELETE FROM `test`

TRUNCATE TABLE `test`

1.2 查询操作

-- 查询全部学生
SELECT * FROM student

-- 别名  给结果起别名 可以给字段起名字 也是可以给表起别名
SELECT `id` AS 学号,`name` AS 学生名字 FROM student AS 学生表

-- 函数 Concat(a,b)
SELECT CONCAT('姓名: ',studentName) AS 学生姓名 FROM student


-- ----------------------------------------------------------------------


-- 去重查询  DISTINCT distinct
-- 查询是否有成绩
SELECT * FROM result 
SELECT DISTINCT `studentNum` FROM result  -- 去除重复数据 只显示一条

-- 查询系统版本 -函数
SELECT VERSION()

-- 查询加减乘除 用来计算  -表达式
SELECT 100*3-1 AS 计算结果

-- 查询自增的步长 -变量
SELECT @@auto_increment_increment

-- 学生考试成绩 +1 分查看
SELECT `studentNo`,`studentResult`+ 1 AS '提分后' FROM result
SELECT `id`,`value`+ 1 AS '提分后' FROM test

-- ----------------------------------------------------------------------


-- 逻辑运算符
-- 运算符  					语法						描述
-- and  &&			 a and b |||| a && b  			   逻辑与
-- or ||			 a or b |||| a || b				   逻辑或	
-- not !			not b ||||  !b					  逻辑非
-- ----------------------------------------------------------------------
-- 查询区间内数据  BETWEEN  AND 进行区间查询的时候 是包含两边的数据的
SELECT studentNO,studentresult FROM result 
	WHERE studentReslut >=95 AND studentResult <=100
	
SELECT studentNO,studentresult FROM result 
	WHERE studentReslut >=95 && studentResult <=100

SELECT studentNO,studentresult FROM result 
	WHERE studentReslut BETWEEN 95 AND 100
	
	
-- ----------------------------------------------------------------------

-- 模糊查询
-- 通过like 结合 %(代表0 到任意个字符) _(代表一个字符)
SELECT `studentName` FROM student 
	WHERE studentName LIKE '王%'
	
SELECT `studentName` FROM student 
	WHERE studentName LIKE '王_'
	
-- 查询名字中含有 文 字的同学
SELECT `studentName` FROM student 
	WHERE studentName LIKE '%文%'
	
-- 通过in 进行查询
SELECT `studentNO` FROM student 
	WHERE studentNO IN(1001,1002,1003)
	
SELECT `studentNO` FROM student 
	WHERE studentNO IN('安徽','江苏')
	
-- null 和 not null
SELECT studentNO,studentresult FROM result 
	WHERE studentReslut = '' OR studentReslut IS NULL
	
SELECT studentNO,studentresult FROM result 
	WHERE studentReslut IS NOT NULL

-- ----------------------------------------------------------------------
/*  查询关键字的入参顺序
select
from
join
on
where 中不可使用聚合函数
group by
having  对结果集进行筛选,可以使用聚合函数
order by
limit
*/
-- ----------------------------------------------------

1.3 索引

1.3.1 索引的介绍

  • 主键索引 (PRIMARY KEY)
    • 唯一的标识,主键不可重复
  • 唯一索引 (UNIQUE KEY)
    • 避免重复的列出现,唯一索引可以重复多个列都可以标识为唯一索引
  • 常规索引 (KEY/INDEX)
    • 默认的,不写就是默认的索引。使用index,或者key来进行设置
  • 全文索引 (FULL TEXT)
    • 在特定的数据库引擎下才有,比如MyISAM
    • 快速定位数据

1.3.2 索引的使用

  • 在创建的时候 给字段加索引
  • 在创建完毕后,增加索引
-- 显示所有的索引信息
show index from student

-- 增加索引  `studentName`(`studentName`)--- 索引名(列名)
alter table school.`student` add fulltext index `studentName`(`studentName`)

-- explain 分析sql执行的状况
explain select * from student;-- 常规索引,非全文索引

explain select * from student where match(studentName) against('王')

1.3.3测试索引

-- 创建表
CREATE TABLE `app_user`(
	`id` BIGINT(20) UNSIGNED NOT NULL AUTO_INCREMENT,
	`name` VARCHAR(50) DEFAULT '' COMMENT '用户昵称',
	`email` VARCHAR(50) NOT NULL COMMENT '用户邮箱',
	`phone` VARCHAR(20) DEFAULT '' COMMENT '手机号',
	`gender` TINYINT(4) UNSIGNED DEFAULT '0' COMMENT '性别(0:男;1:女)',
	`password` VARCHAR(50) DEFAULT '' COMMENT '密码',
	`age` VARCHAR(50) DEFAULT '' COMMENT '年龄',
	`create_time` DATETIME DEFAULT CURRENT_TIMESTAMP,
	`update_time` TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
	PRIMARY KEY (`id`)
)ENGINE=INNODB DEFAULT CHARSET=utf8mb4 COMMENT='app用户表'

-- 插入100万 的数据
delimiter $$  -- 写函数之前必写的标识符
create function mock_data()
return int
begin
	declare num int default 1000000;
	declare i int default 0;
	where i<num do
		-- 插入语句
		insert into app_user(`name`,`email`,`phone`,`gender`,`password`,`age`)
		values (concat('用户',i),'123123@qq.com',concat('18',floor(rand()*(999999999-100000000)+100000000)),floor(rand()*2),uuid(),floor(rand()*2)*100))
		set i =i+1;
	end where
end;

创建函数的报错

-- 报错
-- This function has none of DETERMINISTIC, NO SQL, 
-- or READS SQL DATA in its declaration and binary logging is enabled 
-- (you *might* want to use the less safe log_bin_trust_function_creators variable)
-- 解决方式
SET GLOBAL log_bin_trust_function_creators=TRUE;

运行函数

-- 创建函数后 选择运行函数
SELECT mock_data();
-- 删除函数 mock_data();也是可以删除存储过程 
DROP  FUNCTION mock_data

创建索引进行查询测试

SELECT * FROM app_user WHERE `name`='用户99999'
SELECT * FROM app_user WHERE `name`='用户99989'

EXPLAIN SELECT * FROM app_user WHERE `name`='用户99999' -- 查询了 993799 条数据  耗时 0.006 sec

-- 创建索引 id_表名_字段名
-- create index 索引名 on 表(字段)
CREATE INDEX id_app_uer_name ON `app_user`(`name`) -- 创建耗时 4.005 sec


-- 查询表的索引
SHOW INDEX FROM app_user

-- 索引后测试查询
EXPLAIN SELECT * FROM app_user WHERE `name`='用户99999' -- 查询了 1 条数据  耗时 0.003 sec

1.3.4索引原则

  • 索引不是越多越好
  • 不用对经常变动的数据加索引
  • 小数据量的表不需要加索引
  • 索引一般加在常用来查询的字段上

索引的数据结构

Hash 类型的索引

Betree:InnoDB的默认索引类型是为Betree

1.3.5事务

1.3.5.1数据库事务实测

-- mysql 是自动开启事务自动提交的 
SET autocommit=0 -- 关闭自动提交

-- 标记事务开始
START TRANSACTION 
	UPDATE category SET pid=pid-500 WHERE categoryid = 2;
	UPDATE category SET pid=pid+500 WHERE categoryid = 3;
COMMIT -- 提交
ROLLBACK -- 回滚
-- 事务结束
SET autocommit=1 -- 开启自动提交

SAVEPOINT -- 事务中间的保存点
ROLLBACK TO SAVEPOINT -- 回滚到某个保存点
RELEASE SAVEPOINT -- 删除保存点

1.3.5.2事务的隔离级别

在MySQL数据库中查看当前事务的隔离级别: select@@tx_isolation; (我测试是没有测试成的)

  • RU (Read Uncommitted:读取未提交 [ 脏读 ] )
    • 在该隔离级别,所有事务都可以看到其他未提交事务的执行结果。本隔离级别很少用于实际应用,因为它的性能也不比其他级别好多少。读取未提交的数据,也被称之为脏读(Dirty Read);
  • RC (Read Committed:读取提交内容)
    • 这是大多数数据库系统的默认隔离级别(但不是MySQL默认的)。它满足了隔离的简单定义:一个事务只能看见已经提交事务所做的改变。这种隔离级别 也支持所谓的不可重复读(Nonrepeatable Read),因为同一事务的其他实例在该实例处理其间可能会有新的commit,所以同一select可能返回不同结果;
  • RR (Repeatable Read:可重复读 [ 幻读 ] )
    • 这是MySQL的默认事务隔离级别,它确保同一事务的多个实例在并发读取数据时,会看到同样的数据行。不过理论上,这会导致另一个棘手的问题:幻读 (Phantom Read)。
      简单的说,幻读指当用户读取某一范围的数据行时,另一个事务又在该范围内插入了新行,当用户再读取该范围的数据行时,会发现有新的“幻影” 行。
      InnoDB和Falcon存储引擎通过多版本并发控制(MVCC,Multiversion Concurrency Control)机制解决了该问题
  • Serializable (可串行化)
    • 这是最高的隔离级别,它通过强制事务排序,使之不可能相互冲突,从而解决幻读问题。简言之,它是在每个读的数据行上加上共享锁。在这个级别,可能导致大量的超时现象和锁竞争。
不同隔离级别导致问题的情形示例

脏读(Drity Read):某个事务已更新一份数据,另一个事务在此时读取了同一份数据,由于某些原因,前一个RollBack了操作,则后一个事务所读取的数据就会是不正确的。
不可重复读(Non-repeatable read):在一个事务的两次查询之中数据不一致,这可能是两次查询过程中间插入了一个事务更新的原有的数据。
幻读(Phantom Read):在一个事务的两次查询中数据笔数不一致,例如有一个事务查询了几列(Row)数据,而另一个事务却在此时插入了新的几列数据,先前的事务在接下来的查询中,就会发现有几列数据是它先前所没有的。

不同隔离级别,可能导致的问题

① Serializable (串行化):可避免脏读、不可重复读、幻读的发生。
  ② Repeatable read (可重复读):可避免脏读、不可重复读的发生。
  ③ Read committed (读已提交):可避免脏读的发生。
  ④ Read uncommitted (读未提交):最低级别,任何情况都无法保证。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值