索引是一种特殊的文件,包含着对数据表里所有记录的引用指针。可以对表中的一列或多列创建索引,并指定索引的类型,各类索引有各自的数据结构实现。
索引的特点:
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;
索引保存的数据结构主要为B+树,及hash的方式 。
数据库的事务:很多时候,进行的多个操作,期望能够“打包”到一起,共同执行。
举例:张三向李四转账100,先执行第一个sql语句,将张三的钱减少100:
update accout set money=money-100 where name = '张三';
再执行第二个sql语句,将李四的钱增加100:
update accout set money=money+100 where name = '李四';
若在执行完第一个sql语句后,数据库挂了,张三的钱减少了,但李四的钱并未增多!这肯定是不行的!
事务指逻辑上的一组操作,组成这组操作的各个单元,要么全部成功,要么全部失败。在不同的环境中,都可以有事务。对应在数据库中,就是数据库事务。
对于事务如何保证要么全部执行成功,要么全部执行失败呢?
就如上述例子,希望数据库挂了以后,张三的钱能还回去,怎么恢复回去的(回滚)? 数据库咋知道之前的数据是多少呢?
这是数据库对于事务有特殊的机制(undo log + redo log):数据库中间挂了,但是日志已经记录下来了之前的数据、进行的操作。等到数据库重启之后,读取之前的日志,看看是否有这种执行了一半的事务,如果有,就会把这前面的操作进行回滚。
谈到事务,往往涉及4个核心特性:
对于隔离性的并发执行事务时,可能会产生以下典型问题:
解决幻读问题:串行化,不再进行任何并发了,每个事务都是串行执行的。
mysql 在配置中,提供了“隔离级别”这样的选项,人们就可以根据需要,调整隔离级别,适应不同的情况:
- read uncommitted(读未提交):并行程度是最高的,隔离程度是最低的,效率是最高的,数据是最不靠谱的。此时可能出现脏读问题+不可重复读问题+幻读问题。
- read committed(读已提交):相当于对写操作加锁,并行程度降低了,隔离程度提高了,效率会降低些,数据会靠谱一些,此时可能出现不可重复读问题+幻读问题。
- repeatable read(可重复读):相当于对读操作和写操作都加锁,并行程度降低了,隔离程度提高了,效率又降低了,数据又更靠谱了,此时可能出现幻读问题。
- serializable(串行化):让所有事务都是串行执行,并行程度最低,隔离程度最高,效率最低,数据最靠谱。
(1)开启事务:start transaction;
(2)执行多条SQL语句
说明:rollback即是全部失败,commit即是全部成功。
start transaction;-- 阿里巴巴账户减少 2000update accout set money=money- 2000 where name = ' 阿里巴巴 ' ;-- 四十大盗账户增加 2000update accout set money=money+ 2000 where name = ' 四十大盗 ' ;commit;
start transaction;
...rollback/commit;