MySQL索引事务

news/2024/10/23 9:32:58/

一 、 索引

索引是一种特殊的文件,包含着对数据表里所有记录的引用指针。

可以对表中的一列或多列创建索引, 并指定索引的类型,各类索引有各自的数据结构实现。

索引保存的数据结构主要为B+树,及hash的方式。

1. 作用

数据库中的表、数据、索引之间的关系,类似于书架上的图书、书籍内容和书籍目录的关系。

索引所起的作用类似书籍目录,可用于快速定位、检索数据。

索引对于提高数据库的性能有很大的帮助。
在这里插入图片描述

2. 使用场景

要考虑对数据库表的某列或某几列创建索引,
需要考虑以下几点:

数据量较大,且经常对这些列进行条件查询。
该数据库表的插入操作,及对这些列的修改操作频率较低。
索引会占用额外的磁盘空间。

满足以上条件时,考虑对表中的这些字段创建索引,以提高查询效率。
反之,如果非条件查询列,或经常做插入、修改操作,或磁盘空间不足时,不考虑创建索引。

3. 使用

创建主键约束(PRIMARY KEY)、唯一约束(UNIQUE)、外键约束(FOREIGN KEY)时,会自动创建对应列的索引。

  • 查看索引
show index from 表名;// 查看学生表已有的索引
show index from student;
  • 创建索引
// 对于非主键、非唯一约束、非外键的字段,可以创建普通索引
create index 索引名 on 表名(字段名);// 创建班级表中,name字段的索引
create index idx_classes_name on classes(name);
  • 删除索引
drop index 索引名 on 表名;// 删除班级表中name字段的索引
drop index idx_classes_name on classes;

4. 示例

// 准备测试表
-- 创建用户表
DROP TABLE IF EXISTS test_user;
CREATE TABLE test_user (id_number INT,name VARCHAR(20) comment '姓名', age INT comment '年龄', create_time timestamp comment '创建日期' );// 准备测试数据,批量插入用户数据(操作耗时较长,约在1小时+):-- 构建一个8000000条记录的数据
-- 构建的海量表数据需要有差异性,所以使用存储过程来创建, 拷贝下面代码就可以了-- 产生名字
drop function if exists rand_name;
delimiter $$
create function rand_name(n INT, l INT) returns varchar(255)
begindeclare return_str varchar(255) default ''; declare i int default 0;while i < n doif i=0 thenset return_str = rand_string(l);elseset return_str =concat(return_str,concat(' ', rand_string(l))); end if;set i = i + 1;end while;return return_str;end $$
delimiter ;-- 产生随机字符串
drop function if exists rand_string;
delimiter $$
create function rand_string(n INT)
returns varchar(255)
begindeclare lower_str varchar(100) default 'abcdefghijklmnopqrstuvwxyz';declare upper_str varchar(100) default 'ABCDEFJHIJKLMNOPQRSTUVWXYZ';declare return_str varchar(255) default '';declare i int default 0;declare tmp int default 5+rand_num(n);while i < tmp doif i=0 thenset return_str =concat(return_str,substring(upper_str,floor(1+rand()*26),1)); elseset return_str =concat(return_str,substring(lower_str,floor(1+rand()*26),1)); end if;set i = i + 1; end while; return return_str; end $$
delimiter ;
-- 产生随机数字
drop function if exists rand_num; delimiter $$
create function rand_num(n int) returns int(5)
begindeclare i int default 0;set i = floor(rand()*n);
return i;
end $$
delimiter ;-- 向用户表批量添加数据
drop procedure if exists insert_user;
delimiter $$
create procedure insert_user(in start int(10),in max_num int(10)) begin
declare i int default 0;set autocommit = 0;repeatset i = i + 1;insert into test_user values ((start+i) ,rand_name(2, 5),rand_num(120),CURRENT_TIMESTAMP);until i = max_numend repeat;commit;
end $$
delimiter ;-- 执行存储过程,添加8000000条用户记录 
call insert_user(1, 8000000);

查询 id_number 为778899的用户信息:

-- 可以看到耗时4.93秒,这还是在本机一个人来操作,在实际项目中,如果放在公网中,假如同时有1000 个人并发查询,那很可能就死机。
select * from test_user where id_number=556677;

在这里插入图片描述
可以使用explain来进行查看SQL的执行:

explain select * from test_user where id_number=556677; *************************** 1. row *************************** id: 1select_type: SIMPLEtable: test_usertype: ALL
possible_keys: NULLkey: NULL  <== key为null表示没有用到索引key_len: NULLref: NULLrows: 6Extra: Using where
1 row in set (0.00 sec)

为提供查询速度,创建 id_number 字段的索引:

create index idx_test_user_id_number on test_user(id_number);

换一个身份证号查询,并比较执行时间:

select * from test_user where id_number=776655;

在这里插入图片描述
可以使用explain来进行查看SQL的执行:

explain select * from test_user where id_number=776655; *************************** 1. row *************************** id: 1select_type: SIMPLEtable: test_usertype: ref
possible_keys: idx_test_user_id_numberkey: idx_test_user_id_number <= key用到了idx_test_user_id_number key_len: NULLref: constrows: 1Extra: Using where
1 row in set (0.00 sec)

二 、事务

事务指逻辑上的一组操作,组成这组操作的各个单元,要么全部成功,要么全部失败。

在不同的环境中,都可以有事务。
对应在数据库中,就是数据库事务。

1. 为什么使用事务

// 准备测试表:
drop table if exists accout;
create table accout(id int primary key auto_increment, name varchar(20) comment '账户名称', money decimal(11,2) comment '金额' );insert into accout(name, money) values('阿里巴巴', 5000),('四十大盗', 1000);// 比如说,四十大盗把从阿里巴巴的账户上偷盗了2000元
-- 阿里巴巴账户减少2000
update accout set money=money-2000 where name = '阿里巴巴'; 
-- 四十大盗账户增加2000
update accout set money=money+2000 where name = '四十大盗';

假如在执行以上第一句SQL时,出现网络错误,或是数据库挂掉了,阿里巴巴的账户会减少2000,但是四十大盗的账户上就没有了增加的金额。

解决方案:
使用事务来控制,保证以上两句SQL要么全部执行成功,要么全部执行失败。

2. 使用

  1. 开启事务:start transaction;
  2. 执行多条SQL语句
  3. 回滚或提交:rollback/commit;

说明:rollback即是全部失败,commit即是全部成功。

start transaction;
-- 阿里巴巴账户减少2000
update accout set money=money-2000 where name = '阿里巴巴'; 
-- 四十大盗账户增加2000
update accout set money=money+2000 where name = '四十大盗'; commit;

http://www.ppmy.cn/news/1123305.html

相关文章

中秋国庆内卷之我爱学习C++

文章目录 前言Ⅰ. 内联函数0x00 内联函数和宏的比较0x01 内联函数的概念0x02 内联函数的特性 Ⅱ. auto&#xff08;C 11)0x00 auto的概念0x01 auto的用途 Ⅲ. 范围for循环(C11)0x00 基本用法0x01 范围for循环(C11)的使用条件 Ⅳ. 指针空值nullptr(C11)0x00 概念 前言 亲爱的夏…

gitee生成公钥和远程仓库与本地仓库使用验证

参考文档&#xff1a; https://help.gitee.com/base/account/SSH%E5%85%AC%E9%92%A5%E8%AE%BE%E7%BD%AE(1)通过命令ssh-keygen 生成SSH key -t key类型 -c注释 ssh-keygen -t ed25519 -C "Gitee SSH Key" (2)按三次回车 (3)查看生成的 SSH 公钥和私钥&#xff1a; …

新增MariaDB数据库管理、支持多版本MySQL数据库共存,1Panel开源面板v1.6.0发布

2023年9月18日&#xff0c;现代化、开源的Linux服务器运维管理面板1Panel正式发布v1.6.0版本。 在这个版本中&#xff0c;1Panel新增MariaDB数据库管理&#xff1b;支持多版本MySQL数据库共存&#xff1b;支持定时备份系统快照和应用商店中已安装应用&#xff1b;支持为防火墙…

elementui实现表格(el-table)默认选中

方法: 创建一个空数组用来存放默认数据 遍历表格的数据&#xff0c;再遍历需要在表格中反显的数据&#xff0c;两者的id一致&#xff08;两者之间共同的标识即可&#xff0c;一般以id做判断&#xff09; 把判断出来的默认表格数据push到创建的数组中 再遍历数组&#xff0c;将数…

5、SpringBoot_热部署

六、热部署 1.热部署概述 概述&#xff1a;程序更改后&#xff0c;不需要重新启动服务器也能够实现动态更新 springboot 项目如何实现热部署&#xff1f; tomcat 已经内置到项目容器中了希望tomcat监听外部程序变化通过新建一个程序来监控你代码的变化 2.依赖导入 依赖 <…

爬虫获取接口数据

上一讲讲的是获取静态网页数据的教程&#xff0c;适用于我们要爬取的数据在网页源代码中出现&#xff0c;但是还是有很多的数据是源代码中没有的&#xff0c;需要通过接口访问服务器来获得&#xff0c;下面我就来讲讲如何爬取这类数据。 以巨潮资讯网爬取比亚迪企业年报为例。…

五、数学建模之层次分析法

1.概念 2.例题 一、概念 1.提出 层次分析法&#xff08;Analytic Hierarchy Process&#xff0c;AHP&#xff09;是一种多标准决策分析方法&#xff0c;用于帮助人们在面对复杂的决策问题时进行定量和定性的比较和评估。它最初由美国运筹学家和管理学家托马斯萨蒙&#xff08…

PyCharm 手动下载插件

插件模块一直加载失败&#xff0c;报错信息&#xff1a; Marketplace plugins are not loaded. Check the internet connection and refresh. 尝试了以下方法&#xff0c;均告失败&#xff1a; pip 换源Manage Plugin Repositories...HTTP 代理设置...关闭三个防火墙 最后选…