MySql的锁有哪些?什么是间隙锁?

从锁的粒度来区分

1.行锁:加锁粒度小,但是加锁资源开销比较大,InnoDB支持;

   共享锁:读锁,多个事务可以对同一数据共享同一把锁。持有锁的事务都可以访问数据,但是只能读不能修改。select xxx LOCK IN SHARE MODE.

   排他锁:写锁,只有一个事务能够获得排他锁,其他事务都不能获取该行的锁。InnoDB会对update\delete\insert语句自动添加排他锁。SELECT xxx FOR UPDATE.

   自增锁:通常是针对MySql当中的自增字段,如果有事务回滚这种情况,数据会回滚,但是自增序列不会回滚。

2.表锁:加锁粒度大,加锁资源开销比较小,MyISAM和InnoDB都支持。

   表共享读锁

   表排他写锁

   意向锁:是InnoDB自动添加的一种锁,不需要用户干预。

3.全局锁:Flush tables with read lock。加锁之后整个数据库实例都处于只读状态。所有的数据表更操作都会被挂起。一般用于全库备份的时候。

    常见的锁算法:user.userid(1,4,9) update user set xxx where userid=5; REPEATABLE READ间隙锁锁住(5,9)

1.记录锁:锁一条具体的数据。

2.间隙锁:RR隔离级别下,会加间隙锁,锁一定的范围,而不是锁具体的记录,是为了防止幻读。(-xx,1)(1,4)(4,9)(9,xxx)

3.Next-key:间隙锁+有记录锁。(-xx,1)(1,4] (4,9] (9,xx)

数据库表设计时,字段你会如何选择?

1.字段类型优先级

整型> date,time >enum char > varchar > blob,text

    选用字段长度最小,优先使用定长型,数值型字段中避免使用“ZEROFILL”

    time:定长运算快,节省时间,考虑时区,写sql不方便

    enum:能约束值的目的,内部用整型来存储,但与char联查时,内部要经历串与值的转化

    char:定长,考虑字符集和校对集

    varchar:不定长,要考虑字符集的转换与排序的校对集,速度慢

    text,blob:无法使用内存临时表(排序操作只能在磁盘上进行)

2.可以选整型就不选字符串

    整型是定长的,没有国家/地区之分,没有字符集差异。

3.够用就行不要慷慨

    大的字段会影响内存影响速度。以varchar(10),varcha(300)存储的内容相同,但在表中查询时,varchar(300)要花用更多内存。

4.尽量避免使用NULL

   NULL不利于索引,也不利于查询。=null或者!=null都查询不到值,只有使用is null或者is not null才可以。因此可以在创建字段时候使用not null defalt "" 的形式。

5.char与varchar选择

   char长度固定,处理速度要比varchar快很多,但是相对较费存储空间;所以对存储空间要求不大,但在速度上有要求的可以使用char类型,反之可以用varchar类型。

事务并发可能引发什么问题?

脏读

1.在事务A执行过程中,事务A对数据资源进行了修改,事务B读取了事务A修改后的数据。

2.由于某些原因,事务A并没有完成提交,发生了RollBack操作,则事务B读取的数据就是脏数据。

这种读取到另一个事务未提交的现象就是脏读(Dirty Read)

不可重复读

事务B读取了两次数据资源,在这两次读取的过程中事务A修改了数据,导致事务B在这两次读取出来的数据不一致。

这种在同一事务中,前后两次读取的数据不一致的现象就是不可重复读(NonrepeatableRead)

幻读

       事务B前后两次读取同一个范围的数据,在事务B两次读取的过程中事务A新增了数据,导致事务B后一次读取到前一次查询没有看到的行。

幻读和不可重复读有些类似,但是幻读强调的是集合的增减,而不是单条数据的更新

B树和B+树的区别,为什么Mysql使用B+树

B树的特点:

   1.节点排序

   2.一个节点可以存多个元素,多个元素也排序了

B+树的特点:

   1.拥有B树的特点

   2.叶子节点之间有指针

   3.非叶子节点上的元素在叶子节点上都冗余了,也就是叶子节点中存储了所有的元素,并且排好顺序

Mysql索引使用的是B+树,因为索引是用来加快查询的,而B+树通过对数据进行排序是可以提高查询速度的,然后通过一个节点中可以存储多个元素,从而可以使B+树的高度不会太高,在Mysql中一个Innodb页就是一个B+树节点,一个Innodb页默认是16kb,所以一般情况下一颗两层的B+树可以存2000万左右的数据,然后通过利用B+树叶子节点存储了所有数据并且进行了排序,并且叶子节点之间有指针,可以很好的支持全表扫描,范围查找等SQL语句;

MySql的索引结构是什么样的?聚簇索引和非聚簇索引又是什么?

二叉树 -> AVL树 -> 红黑树 -> B-树 -> B+树

二叉树:每个节点最多只有两个子节点,左边的子节点都比当前节点小,右边的子节点都比当前节点大。

AVL树:树中任意节点的两个子树的高度差最大为1

红黑树:1.每个节点都是红色或者黑色,2.根节点是黑色,3.每个叶子节点都是黑色的空节点,4.红色节点的父子节点都必须是黑色,5.从任一节点到其每个叶子节点的所有路径包含相同的黑色节点。

B-树:1.B-树的每个非叶子节点的子节点个数都不会超过D(这个D就是B-树的阶)2.所有的子节点都在同一层,3.所有的节点关键字都是按照递增顺序排列。

B+树:1.非叶子节点不存储数据,只进行数据索引,2.所有数据都存储在叶子节点当中,3.每个叶子节点都存有相邻叶子节点的指针,4.叶子节点按照本身关键字从小到大排序。

聚簇索引就是数据和索引是在一起的。

MyISAM使用的是非聚簇索引,树的子节点上的data不是数据本身,而是数据存放的地址,InnoDB采用的是聚簇索引,树的叶子节点上的data就是数据本身。

聚簇索引的数据物理存放顺序和索引顺序是一致的,所以一个表当中只有一个聚簇索引,而非聚簇索引可以有多个。

   InnoDB中,如果表定义了PK,那PK就是聚簇索引,如果没有PK,就会找第一个非空的unique列作为聚簇索引,否则,InnoDB会创建一个隐藏的row-id作为聚簇索引。