• [MySQL]索引事务


    目录

    1. 索引

    1.1 概念

    1.2 作用

    1.3 使用场景

    1.4 使用

    1.5 案例

     2. 事务

    2.1 为什么使用事务

    2.2 事务的概念

    2.3 使用



    1. 索引

    1.1 概念

    索引是一种特殊的文件,包含着对数据表里所有记录的引用指针。可以对表中的一列或多列创建索引, 并指定索引的类型,各类索引有各自的数据结构实现。

    1.2 作用

    • 数据库中的表、数据、索引之间的关系,类似于书架上的图书、书籍内容和书籍目录的关系。
    • 索引所起的作用类似书籍目录,可用于快速定位、检索数据。
    • 索引对于提高数据库的性能有很大的帮助。

     1.3 使用场景

    要考虑对数据库表的某列或某几列创建索引,需要考虑以下几点:
    • 数据量较大,且经常对这些列进行条件查询。
    • 该数据库表的插入操作,及对这些列的修改操作频率较低。
    • 索引会占用额外的磁盘空间。
    满足以上条件时,考虑对表中的这些字段创建索引,以提高查询效率。
    反之,如果非条件查询列,或经常做插入、修改操作,或磁盘空间不足时,不考虑创建索引。

    1.4 使用

    创建主键约束( 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;

    1.5 案例

    准备测试表:
    1. -- 创建用户表
    2. DROP TABLE IF EXISTS test_user;
    3. CREATE TABLE test_user (
    4. id_number INT,
    5. name VARCHAR(20) comment '姓名',
    6. age INT comment '年龄',
    7. create_time timestamp comment '创建日期'
    8. );

    准备测试数据,批量插入用户数据(操作耗时较长,约在1小时+):

    1. -- 构建一个8000000条记录的数据
    2. -- 构建的海量表数据需要有差异性,所以使用存储过程来创建,
    3. -- 拷贝下面代码就可以了,暂时不用理解
    4. -- 产生名字
    5. drop function if exists rand_name;
    6. delimiter $$
    7. create function rand_name(n INT, l INT)
    8. returns varchar(255)
    9. begin
    10. declare return_str varchar(255) default '';
    11. declare i int default 0;
    12. while i < n do
    13. if i=0 then
    14. set return_str = rand_string(l);
    15. else
    16. set return_str =concat(return_str,concat(' ', rand_string(l)));
    17. end if;
    18. set i = i + 1;
    19. end while;
    20. return return_str;
    21. end $$
    22. delimiter;
    23. -- 产生随机字符串
    24. drop function if exists rand_string;
    25. delimiter $$
    26. create function rand_string(n INT)
    27. returns varchar(255)
    28. begin
    29. declare lower_str varchar(100) default
    30. 'abcdefghijklmnopqrstuvwxyz';
    31. declare upper_str varchar(100) default
    32. 'ABCDEFJHIJKLMNOPQRSTUVWXYZ';
    33. declare return_str varchar(255) default '';
    34. declare i int default 0;
    35. declare tmp int default 5+rand_num(n);
    36. while i < tmp do
    37. if i=0 then
    38. set return_str
    39. =concat(return_str,substring(upper_str,floor(1+rand()*26),1));
    40. else
    41. set return_str
    42. =concat(return_str,substring(lower_str,floor(1+rand()*26),1));
    43. end if;
    44. set i = i + 1;
    45. end while;
    46. return return_str;
    47. end $$
    48. delimiter;
    49. -- 产生随机数字
    50. drop function if exists rand_num;
    51. delimiter $$
    52. create function rand_num(n int)
    53. returns int(5)
    54. begin
    55. declare i int default 0;
    56. set i = floor(rand()*n);
    57. return i;
    58. end $$
    59. delimiter;
    60. -- 向用户表批量添加数据
    61. drop procedure if exists insert_user;
    62. delimiter $$
    63. create procedure insert_user(in start int(10),in max_num int(10))
    64. begin
    65. declare i int default 0;
    66. set autocommit = 0;  
    67. repeat
    68. set i = i + 1;
    69. insert into test_user values ((start+i) ,rand_name(2,
    70. 5),rand_num(120),CURRENT_TIMESTAMP);
    71. until i = max_num
    72. end repeat;
    73. commit;
    74. end $$
    75. delimiter;
    76. -- 执行存储过程,添加8000000条用户记录
    77. call insert_user(1, 8000000);
    查询 id_number 778899 的用户信息:
    1. -- 可以看到耗时4.93秒,这还是在本机一个人来操作,在实际项目中,
    2. -- 如果放在公网中,假如同时有1000个人并发查询,那很可能就死机。
    3. select * from test_user where id_number=556677;

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

    create index idx_test_user_id_number on test_user(id_number);
    换一个身份证号查询,并比较执行时间:
    select * from test_user where id_number=776655;

     2. 事务

    2.1 为什么使用事务

    准备测试表:
    1. drop table if exists accout;
    2. create table accout(
    3. id int primary key auto_increment,
    4. name varchar(20) comment '账户名称',
    5. money decimal(11,2) comment '金额'
    6. );
    7. insert into accout(name, money) values
    8. ('阿里巴巴', 5000),
    9. ('四十大盗', 1000);
    比如说,四十大盗把从阿里巴巴的账户上偷盗了 2000
    1. -- 阿里巴巴账户减少2000
    2. update accout set money=money-2000 where name = '阿里巴巴';
    3. -- 四十大盗账户增加2000
    4. update accout set money=money+2000 where name = '四十大盗';
    假如在执行以上第一句 SQL 时,出现网络错误,或是数据库挂掉了,阿里巴巴的账户会减少 2000 ,但是 四十大盗的账户上就没有了增加的金额。
    解决方案:使用事务来控制,保证以上两句SQL 要么全部执行成功,要么全部执行失败。

    2.2 事务的概念

    事务指逻辑上的一组操作,组成这组操作的各个单元,要么全部成功,要么全部失败。
    在不同的环境中,都可以有事务。对应在数据库中,就是数据库事务。

    2.3 使用

    1. 开启事务:start transaction;
    2. 执行多条SQL语句 ;
    3. 回滚或提交:rollback/commit;
    说明: rollback 即是全部失败, commit 即是全部成功。
    1. start transaction;
    2. -- 阿里巴巴账户减少2000
    3. update accout set money=money-2000 where name = '阿里巴巴';
    4. -- 四十大盗账户增加2000
    5. update accout set money=money+2000 where name = '四十大盗';
    6. commit;
  • 相关阅读:
    y7000p 2020h风扇狂转解决办法
    Docker build报错总结,版本过新大避雷!
    C++中构造函数什么时候会被调用(从本质上理解)
    Python-pptx教程之一从零开始生成PPT文件
    深谈个人对新技术的看法
    react 项目路由配置(react-router-dom 版本 v6.3、v6.4)
    使用 React Flow 构建一个思维导图应用
    云计算基础技术
    Win11缺少dll文件怎么办?Win11系统找不到dll文件修复方法
    【Log日志】springboot项目中集成Log日志详解
  • 原文地址:https://blog.csdn.net/m0_59155415/article/details/125884470