具体介绍见博客:https://www.cnblogs.com/wsg25/p/9615100.html
InnoDB 表只会把自增主键的最大id记录在内存中,所以重启之后会导致最大的 id 丢失。
使用 select version() 获取当前 MySQL 的数据库版本。
char优点:效率高; char缺点:占用空间; 适用场景:存储密码的md5值,固定长度的,适用char非常合适。
varchar(n):可变长度,存储的值是每个值占用的字节再加上一个用来记录其长度的字节的长度。所以,从空间上考虑varchar比较合适;从效率 考虑char比较合适,二者适用需要权衡。
内连接关键字:inner join; 左连接关键字:left join; 右连接关键字:right join;
内连接是把匹配的关联数据显示出来;左连接是左边的表全部显示出来,右边的表显示出符合条件的数据;右连接正好相反。
索引是满足某种特定查找算法的数据结构,而这些数据结构会以某种方式指向数据,从而实现高效查找数据。
具体来说 MySQL 中的索引,不同的数据引擎实现偶不同,但目前主流的数据库引擎索引就是 B+数实现的,B+数的搜索效率,可以达到二分法 性能,找到数据区域之后就找到了完整的数据结构了,所以索引的性能也是更好的。
使用 explain 查看SQL是如何执行查询语句的,从而分析你的索引是否满足需求。
explain 语法: explain select * from table where type=1;
MySQL 的事务隔离是在 MySQL.ini配置文件里添加的,在文件的最后添加
transaction-isolation = REPEATABLE-READ
可用的配置值:READ-UNCOMMITED、READ-COMMINTTED、REPEATABLE-READ、SERIALIZABLE.
READ-UNCOMMITED:读未提交,最低的隔离级别。事务未提交前,就可以被其他事务读取(会出现幻读,脏读,不可重复读)READ-COMMINTTED:读已提交,一个事务提交后才能被其他事务读取到(会出现幻读,不可重复读)REPEATABLE-READ:可重复读,默认级别,保证多次读取同一个数据时,其值都和事务开始时候的内容是一致的,禁止读取到别的事务未提交的数据(会出现幻读)SERIALIZABLE:串行化,代价最高最可靠的隔离级别,该隔离级别能防止脏读,不可重复读,幻读。脏读:表示一个事务能够读取另一个还未提交的数据。比如,某个事务尝试插入记录A,此时此事务还未提交,然后另外一个事务尝试读到了记录A。
不可重复读:表示一个事务范围内两个相同的查询却返回了不同数据。
幻读:表示一个事务多次查询返回的结果集不一样。比如同一个事务A第一次查询时有n条记录,但是第二次同等条件下查询却有n+1条记录,这就好像产生了幻觉。发生幻读的原因也是另外一个事务新增或者删除或者修改了第一个事务结果集里面的数据,同一个记录的数据内容被修改了,所有数据行的记录就变多或者变少了。
幻读的重点在于新增或者删除,不可重复读的重点是修改
如果使用锁机制来实现这两种隔离级别,在可重复读中,该sql第一次读取到数据后,就将这些数据加锁,其它事务无法修改这些数据,就可以实现可重复读了。但这种方法却无法锁住insert和delete的数据,所以当事务A先前读取了数据,或者修改了全部数据,事务B还是可以insert数据提交,这时事务A就会发现莫名其妙多了一条之前没有的数据,这就是幻读,不能通过行锁来避免。需要Serializable隔离级别 ,读用读锁,写用写锁,读锁和写锁互斥,这么做可以有效的避免幻读、不可重复读、脏读等问题,但会极大的降低数据库的并发能力。
所以说不可重复读和幻读最大的区别,就在于如何通过锁机制来解决他们产生的问题。
上文说的,是使用悲观锁机制来处理这两种问题,但是MySQL、ORACLE、PostgreSQL等成熟的数据库,出于性能考虑,都是使用了以乐观锁为理论基础的MVCC(多版本并发控制)来避免这两种问题。
InnoDB 引擎:InnoDB引擎提供了对数据库acid事务的支持,并且还提供了行级锁和外键的约束,它的设计的目的就是处理大数据量的数据库系统。MySQL 运行的时候,InnoDB会在内存中建立缓冲池,用于缓冲数据和索引。但是该引擎不支持全文搜索,同时启动也比较慢,它是不会保存表的行数的,所以当进行 select count(*) from table 指令的时候,需要进行扫描全表。由于锁的粒度小,写操作是不会锁定全表的,所以在并发度较高的场景下使用会提升效率。MySQL5.5以后默认使用InnoDB存储引擎。
MyIASM 引擎:不提供事务的支持,也不支持行级锁和外键。因此当执行插入和更新语句时,即执行写操作的时候需要锁定这个表,所以会导致效率降低。不过和InnoDB不同的是,MyIASM 引擎保存了表的行数,于是当进行 select count(*) from table 语句时,可以直接读取已经保存的值而不需要进行扫描全表。所以,如果表的读操作远远多于写操作时,并且不需要事务的支持的,可以将 MyIASM 作为数据库引擎的首选。
MyIASM 只支持表锁,InnoDB支持表锁和行锁,默认为行锁。
表级锁:开销小,加锁快,不会出现死锁。锁定力度大,发生锁冲突的概率最高,并发量最低。行级锁:开销大,加锁慢,会出现死锁。锁粒度小,发生锁冲突的概率小,并发度最高。数据库的乐观锁需要自己实现,在表里添加一个version字段,每次修改成功值加1,这样每次修改的时候先对比一下,自己拥有的version和数据库现在的version是否一致,如果不一致就不修改,这样就实现了乐观锁。
两种锁的使用场景 从上面对两种锁的介绍,我们知道两种锁各有优缺点,不可认为一种好于另一种,像乐观锁适用于写比较少的情况下(多读场景),即冲突真的很少发生的时候,这样可以省去了锁的开销,加大了系统的整个吞吐量。但如果是多写的情况,一般会经常产生冲突,这就会导致上层应用会不断的进行retry,这样反倒是降低了性能,所以一般多写的场景下用悲观锁就比较合适。
