mysql面试题

目录

索引相关

mysql的inndb索引?

mysql索引为什么使用B+树?

索引为什么不使用二叉查找树?

索引为什么不使用平衡二叉树?

索引为什么不使用B树?

索引为什么不使用红黑树?

索引树是如何维护的?

索引失效场景(mysql)?

密集索引与稀疏索引的区别?

mysql的单列索引、联合索引、主键索引?

Mysql聚簇索引和非聚簇索引说明?

索引覆盖和回表?

事物相关

MVCC?更新的数据的时候怎么确定版本的?幻读怎么解决的?

mysql是如何实现事务的?

嵌套事务如何实现?

JDBC如何实现事务?

Mysql的事物隔离级别?

分布式事务的实现?

数据库崩溃时事务的恢复机制(Redo日志和Undo日志)?

可重复读、脏度、幻读?

优化相关

使用explain优化sql?

mysql的Join原理?

sql代码中如何定义一个事务?应该是如何定义一个事务的隔离级别?

MySQL的几种优化?

如何优化数据库性能?

mysql的sql语句执行顺序?

内连接、外连接、交叉连接、笛卡儿积?

SQL的整个解析、SQL行转列?

手写SQL让其产生死锁?

引擎相关

mysql的存储引擎?

mysql的三大引擎是啥?

myisam和innodb的区别(innodb是行级锁,myisam是表级锁)?

MySQL InnoDB存储的文件结构?

数据库自增主键可能产生的问题?

行存储和列存储的区别?

日志相关

MySQL有哪几种日志?redo log主要有什么用?提交之后100%落盘吗?为什么MySQL要写到redo log buff内存?

MySQL记录binlog的方式主要包括三种模式?每种模式的优缺点是什么?

数据库三范式?

集群相关

mysql的一致性和CAP的一致性有什么区别?

高并发下如何做到安全的修改同一行数据,INNODB的行级锁有哪2种,解释其含义(mysql)?

MySQL主从同步的基本原理?

MySQL主从复制,从服务器有几个线程?

如何保证数据库集群中ID的唯一性,假设每秒钟并发20万次?

锁相关

mysql的乐观锁和悲观锁?

行锁,表锁?

死锁判定原理和具体场景,死锁怎么解决?

mysql的行级锁加在哪个位置?

myisam和innodb支持锁的粒度是怎样的?

数据库锁表的相关处理(mysql)?


索引相关

mysql的inndb索引?

      答:InnoDB使用页存储结构,

页存储格式:1)页头分为最小和最大,记录夜的控制信息,指针、空间等;其本身不存储数据;2)记录堆:用来存储索引的区域,,分为有效索引和已删除索引;3)未分配空间:随着页的增加,未分配空间会越来越小;5)slot(槽)区:存储有效页数据的指针和页首地址的偏移量;6)页尾:存储页面的校验信息;

索引采用B+树:是自平衡的树,具有数据的有序性、扁平化等,非叶子节点相当于是叶子节点的索引,不存储数据,叶子节点用于存储关键字以及数据,且叶子节点之间通过指针指向另一个的地址,形成了一个有序链表,由于数据全部存在叶子节点,所以无论查找哪个数据,花费的磁盘I/O次数都是一样的;

mysql索引为什么使用B+树?

答:B+树是文件系统产生的一种变形树只保存索引,不保存实际的数据,数据都保存在叶子节点中。 B+树的特点:1)非叶子节点的子树指针与关键字个数相同;2)B+树不允许关键字重复; 3)所有叶子节点都有一个链指针;4)所有关键字都在叶子节点出现(稠密索引); 5)非叶子节点相当于是叶子节点的索引(稀疏索引),叶子节点相当于是存储(关键字)数据的数据层;

索引为什么不使用二叉查找树?

        答:可能出现高高瘦瘦“一条龙”的景象,把二叉查找树退化为一个链表,相当于全表扫描,查找元素发挥不了二叉排序树的优势,只能按照链表的形式查找,高度太高了,查找效率不稳定。

索引为什么不使用平衡二叉树?

        答:平衡二叉树解决了二叉树高度太高,查找效率不稳定的问题。但是,平衡二叉树的每个节点只存储一个键值和数据,如果数据非常的多(大多数情况下数据是海量的),二叉树的结点将会非常多,高度也会及其高,去磁盘取数据的次数就多,查找效率降低。

索引为什么不使用B树?

        答:B树相对于平衡二叉树,优势在于每个节点存储了更多的键值(key)和数据(data),并且每个节点拥有更多的子结点,高度就会降低,B树在提高了IO性能的同时并没有解决元素遍历效率低下的问题,在找数据时需要遍历整个B树,为解决这个问题引出了B+树。
而且和B树相比,B+树的非叶子节点是值存储键值的,不存储数据,这样的话B+树的一个节点就可以存储更多的节点,使得树变得更加矮胖,从而查找效率更高。

索引为什么不使用红黑树?

答:红黑树是一种自平衡的二叉查找树,其每个节点最多有两个子节点,且它的高度较高。而数据库中的索引可能需要存储大量的数据记录,红黑树的高度会随着数据量的增加而快速增长。在查询数据时,磁盘 I/O 操作次数和树的高度有关,树越高,I/O 次数可能越多,导致查询效率降低。

索引树是如何维护的?

 答:1)页存储格式:a)页头分为最小和最大,记录夜的控制信息,指针、空间等;其本身不存储数据;b)记录堆:用来存储索引的区域,,分为有效索引和已删除索引;c)未分配空间:随着页的增加,未分配空间会越来越小;d)slot(槽)区:存储有效页数据的指针和页首地址的偏移量;e)页尾:存储页面的校验信息;2)索引采用B+树:是自平衡的树,具有数据的有序性、扁平化等,非叶子节点相当于是叶子节点的索引,不存储数据,叶子节点用于存储关键字以及数据,且叶子节点之间通过指针指向另一个的地址,形成了一个有序链表,由于数据全部存在叶子节点,所以无论查找哪个数据,花费的磁盘I/O次数都是一样的;

索引失效场景(mysql)?

   答:1)WHERE字句的查询条件里有不等于号;2)如果WHERE字句的查询条件里使用了函数;3)在JOIN操作中,MYSQL只有在主键和外键的数据类型相同时才能使用索引,否则即使建立了索引也不会使用; 4)如果WHERE子句的查询条件里使用了比较操作符LIKE和REGEXP; 5)如果某个数据列里有许多重复的值,就算为它建立了索引也不会有很好的效果; 7)对于多列索引,不是使用的第一部分; 8)如果条件中有or,除非连个字段都有索引才会生效,否则不会生效;9)如果列类型是字符串,那一定要在条件中将数据使用引号引用起来,否则不使用索引;10)如果mysql估计使用全表扫描要比使用索引快,则不使用索引。

密集索引与稀疏索引的区别?

  答:密集索引文件中每个搜索码都对应一个索引值,稀疏索引只为某些索引码的某些值建立索引项; 1.稠密索引是InnoDB引擎,比稀疏索引更快地定位一条记录; 2.稀疏索引是MyIsam引擎,所占空间小;

mysql的单列索引、联合索引、主键索引?

  答:单列索引:一个索引只包含单个列,一个表可以有多个单列索引,但这不是组合索引;联合索引:从左到右的使用索引中的字段,一个查询可以只使用索引中的一部份, 但只能是最左侧部分;主键索引:主键是一种唯一性索引,但它必须指定为“PRIMARY KEY”。

Mysql聚簇索引和非聚簇索引说明?

 答:聚簇索引:InnoDB表中主键,唯一索引,mysql自动创建一个隐藏的GEN_CLUST_INDEX所有不是聚簇索引的都是非聚簇索引;

索引覆盖和回表?

答:首先要知道聚集索引(主键索引)和辅助索引(二级索引)如果表设置了主键,则主键就是聚簇索引如果表没有主键,则会默认第一个NOT NULL,且唯一的列作为聚簇索引以上都没有, 则会默认创建一个隐藏的row_id作为聚簇索引;innoDB的聚簇索引的叶子节点存储的是行记录(其实是页结构,一个页包含多行数据), InnoDB必须要有至少一个聚簇索引; 辅助索引:除聚簇索引外的索引,即非聚簇索引;索引覆盖:创建一个索引,该索引包含查询中用到的所有字段,只需要通过索引就可以查找和返回查询所需要的数据,而不必在使用索引处理数据之后再进行回表操作,覆盖索引可以一次性完成查询工作,有效减少IO,提高查询效率; 回表查询:先通过普通索引的值定位聚簇索引值,再通过聚簇索引的值定位行记录数据,需要扫描两次索引B+树,它的性能较扫一遍索引树更低;

事物相关

MVCC?更新的数据的时候怎么确定版本的?幻读怎么解决的?

 答:MVCC是解决事务并发时数据不一致的问题,MVCC的特点:1)每行数据都存在一个版本;2)修改时Copy出当前版本;3)保存时比较版本号;4)保存时根据版本号决定是否成功; 通过MVCC解决幻读:通过next-key lock 是行锁的一种,相当于 record lock(记录锁) + gap lock(间隙锁); 其特点是不仅会锁住记录本身( record lock 的功能),还会锁定一个范围( gap lock 的功能),当InnoDB扫描索引记录的时候, 会首先对索引记录加上行锁(Record Lock),再对索引记录两边的间隙加上间隙锁(Gap Lock)。  加上间隙锁之后,其他事务就不能在这个间隙修改或者插入记录。

mysql是如何实现事务的?

 答:1)redo log(重做日志):用来实现事务持久性的,记录数据修改后的信息,该文件由重做日志缓冲和重做日志文件组成, 缓冲存在内存中,文件存在磁盘上, mysql为了提高性能不会把每次的修改都实时同步到磁盘,而是会先存到缓冲池里, 然后使用后台线程去做缓冲池和磁盘之间的同步; 2) undo log(回滚日志):用来回滚数据的,用于保障未提交事务的原子性,记录数据被修改前的信息,为了在发生错 误时回滚之前的操作;

嵌套事务如何实现?

答:就是事务方法A调用事务方法B,外层调用方法和内层被调用方法都是事务方法的情况。1) 外层调用方法和内层被调用方法,有异常一起回滚,没问题一起提交。(共用一个事务);  2)内层被调用方法回滚与否,不会影响外层调用方法。而外层调用方法出异常回滚,也不会回滚内层被调用方法(两个独立的事务); 3)内层被调用方法回滚与否,不会影响外层调用方法。而外层调用方法出异常回滚,也会回滚内层被调用方法(嵌套事务)。 

JDBC如何实现事务?

答:在JDBC中同一事务中所有的操作,都在使用同一个Connection对象。  Connection中的方法,1)setAutoCommit(boolean):设置是否为自动提交事务;2)commit():提交结束事务;3)rollback():回滚结束事务。

Mysql的事物隔离级别?

  答:Mysql的事物隔离级别 其实跟 Spring的事物隔离级别一样,1、Read Uncommitted(读取未提交内容),2、Read Committed(读取提交内容),3、Repeatable Read(可重读),4、Serializable(可串行化) 

分布式事务的实现?

答:1)两阶段提交(2PC):两阶段提交(Two-phase Commit,2PC),通过引入协调者(Coordinator)来协调参与者的行为,并最终决定这些参与者是否要真正执行事务;  2)补偿事务(TCC):TCC 其实就是采用的补偿机制,其核心思想是:针对每个操作,都要注册一个与其对应的确认和补偿(撤销)操作;  3)本地消息表(异步确保):本地消息表与业务数据表处于同一个数据库中,这样就能利用本地事务来保证在对这两个表的操作满足事务特性,并且使用了消息队列来保证最终一致性;4)MQ 事务消息。

数据库崩溃时事务的恢复机制(Redo日志和Undo日志)?

答:1)Redo日志:用来实现事务持久性的,记录数据修改后的信息,主要分为两阶段,首先是日志扫描阶段,扫描阶段按照数据页的space_id和 page_no分发redo日志到hash_table中,保证同一个数据页的日志被分发到同一个哈希桶中,且按照lsn大小从小到大排序。扫描完后,再遍历整个哈希表,依次应用每个数据页的日志,应用完后,在数据页的状态上至少恢复到了崩溃之前的状态; 2)Undo日志:数据库有似撤销的功能,当你发现修改错误时,可以使用rollback指令回滚之前的操作。这个功能需要undo日志来支持。undo日志主要分为两种:TRX_UNDO_INSERT是提供给insert操作用的,TRX_UNDO_UPDATE是给update和delete操作使用;第二步,只需要遍历所有链表,重建起事务的状态;第三步,一个是在recv_recovery_from_checkpoint_finish是回滚DDL语句的操作,recv_recovery_rollback_active是回滚DML语句。

可重复读、脏度、幻读?

  答:可重复读:事务A在读到一条数据之后,此时事务B对该数据进行了修改并提交,那么事务A再读该数据,读到的还是原来的内容;  脏度:一个事务读取了另一个事务未提交的数据;  幻读:同样条件的查询结果集变多或变少仿佛出现幻觉;

优化相关

使用explain优化sql?

答:1)id:数字越大越先执行,如果说数字一样大,那么就从上往下依次执行,id列为null的这是一个结果集,不需要使用它来进行查询;2)select_type:simpl表示不需要union操作或者不包含子查询的简单select查询。;3)table:显示的查询表名,如果查询使用了别名,那么这里显示的是别名,如果不涉及对数据表的操作,那么这显示为null; 4)type:依次从好到差:system,const,eq_ref,ref,fulltext,ref_or_null,unique_subquery, index_subquery,range,index_merge,index,ALL,除了all之外,其他的type都可以使用到索引; 5)possible_keys:查询可能使用到的索引都会在这里列出来;6)key:查询真正使用到的索引;7)key_len:用于处理查询的索引长度,;8)ref:如果是使用的常数等值查询,这里会显示const,如果是连接查询,被驱动表的执行计划这里会显示驱动表的关联字段, 如果是条件使用了表达式或者函数,或者条件列发生了内部隐式转换,这里可能显示为func;9)rows:这里是执行计划中估算的扫描行数,不是精确值;10)extra:有很多查询数据字典库,执行计划过程中就发现不可能存在结果的一些提示信息;

mysql的Join原理?

答:Join原理:join的实现采用Nested Loop Join(嵌套循环连接)算法,就是通过驱动表的结果集作为循环基础数据,然后一条一条的通过该结果集中的数据作为过滤条件到下一个表中查询数据,然后合并结果。如果有多个join,则将前面的结果集作为循环数据,再一次作为循环条件到后一个表中查询数据。

sql代码中如何定义一个事务?应该是如何定义一个事务的隔离级别?

答: 1.开启SNAPSHOT事务隔离级别,需要预先设置ALLOW_SNAPSHOT_ISOLATION为ON,且目前只能修改会话级别的事务隔离级别。 ALTER DATABASE [dbname] SET ALLOW_SNAPSHOT_ISOLATION ON; 2.然后执行如下语句修改事务隔离级别:(修改后只在会话级别生效,无法修改全局级别的事务隔离级别) SET TRANSACTION ISOLATION LEVEL{ READ UNCOMMITTED|READ COMMITTED|REPEATABLE READ|SNAPSHOT|SERIALIZABLE}

MySQL的几种优化?

答:1)选取最适用的字段属性;  2)应该尽量把字段设置为NOTNULL;  3)使用联合(UNION)来代替手动创建的临时表; 4)事务;5)使用外键; 6)使用索引; 

如何优化数据库性能?

  答:索引、分库分表、批量操作、分页算法、升级硬盘SSD、业务优化、主从部署;

mysql的sql语句执行顺序?

 答:from,join,on ,where,group by(开始使用select中的别名,后面的语句中都可以使用),avg,sum,having,   select, distinct, ,order by,limit

内连接、外连接、交叉连接、笛卡儿积?

 答:内连接:select * from A INNER JOIN B ON A.A1=B.B1;   外链接分为:左外链接 select * from A LEFT JOIN B ON A.A1=B.B1; 右外链接select * from A RIGHT JOIN B ON A.A1=B.B1;完全链接 select * from A FULL JOIN B ON A.A1=B.B1;  笛卡尔积(又称交叉链接):select * from A,B​;

SQL的整个解析、SQL行转列?

  答:from,join,on ,where,group by(开始使用select中的别名,后面的语句中都可以使用),avg,sum,having,    select, distinct, ,order by,limit ;  行转列:表结构:test(user_name,course、score);
       SELECT user_name ,
        MAX(CASE course WHEN '数学' THEN score ELSE 0 END ) 数学,
        MAX(CASE course WHEN '语文' THEN score ELSE 0 END ) 语文,
        MAX(CASE course WHEN '英语' THEN score ELSE 0 END ) 英语
        FROM test
        GROUP BY user_name;

手写SQL让其产生死锁?

答:t1:begin tran select * from table lock in share mode update table set column1='hello';  t2:begin tran select * from table lock in share mode update table set column1='world'; 假设 T1 和 T2 同时达到 select,T1 对 table 加共享锁,T2 也对 table 加共享锁,当 T1 的 select 执行完,   准备执行 update 时,根据锁机制,T1 的共享锁需要升级到排他锁才能执行接下来的 update.在升级排他锁前,  必须等 table 上的其它共享锁(T2)释放,同理,T2 也在等 T1 的共享锁释放。于是死锁产生了;   解决办法:直接使用排它锁;  select * from table for update  table set column1='hello';  当 T1 的 select 执行时,直接对表加上了排他锁,T2 在执行 select 时,就需要等 T1 事物完全执行完才能执行,排除了死锁发生。

引擎相关

mysql的存储引擎?

  答:1)InnoDB:是一个事务型的存储引擎,有行级锁定和外键约束。MySQL运行时Innodb会在内存中建立缓冲池,用于缓冲数据和索引。但是该引擎不支持FULLTEXT类型的索引,而且它没有保存表的行数。 2)MyIsam:是mysql默认引擎,它没有提供对数据库事务的支持,也不支持行级锁和外键,因此当INSERT(插入)或UPDATE(更新)数据时即写操作需要锁定整个表。 3)Memory:创建的表数据只能保存在内存,MySQL宕机、硬件故障或者意外掉电,都会造成MEMORY引擎表丢失数据,只适应度操作。 4)Blackhole:一个并不保存任何数据的引擎,其表现就像一个黑洞,只进不出,进来就消失,可作为主从复制的中介。

mysql的三大引擎是啥?

 答:mysql常用的引擎有InnoDB,MyISAM,Memory,  默认是InnoDB;InnoDB:磁盘表,支持事务,支持行级锁,B+Tree索引;优点:具有良好的ACID特性。适用于高并发,更新操作比较多的表。需要使用事务的表。

myisam和innodb的区别(innodb是行级锁,myisam是表级锁)?

 答:1)存储结构:MyISAM在磁盘上存储三个文件分别为:frm表信息、myd数据文件、myi索引文件。InnoDB:所有的表都保存在同一个数据文件中,表的大小一般只有2GB。  2)存储空间:MyISAM:可被压缩支持三种存储方式:静态表、动态表、压缩表。InnoDB:在主内存中建立其专用的缓冲池用于高速缓冲数据和索引。 3)可移植性、备份及恢复:MyISAM:数据是以文件的形式存储,在备份和恢复时可单独针对某个表进行操作。InnoDB:可以是拷贝数据文件、备份 binlog,或者用 mysqldump。   4)事务支持:MyISAM不支持事务。InnoDB:支持事务、回滚、修复、事务安全。 5)AUTO_INCREMENT(唯一):MyISAM:可以和其他字段一起建立联合索引。InnoDB中必须包含只有该字段的索引。 6)表锁差异:MyISAM:只支持表级锁。InnoDB:支持事务和行级锁。 7)全文索引:MyISAM:支持 FULLTEXT类型的全文索引。InnoDB:不支持FULLTEXT类型的全文索引(可以用sphinx插件)。 8)表主键:MyISAM:允许没有任何索引和主键的表存在。InnoDB:如果没有设定主键或者非空唯一索引,就会自动生成一个6字节的主键。 9)表的具体行数:MyISAM:保存有表的总行数。InnoDB:没有保存表的总行数。  10)CURD操作:MyISAM:对大量的SELECT性能较好。InnoDB:对大量的INSERT或UPDATE性能较好。 11)外键:MyISAM:不支持。InnoDB支持。

MySQL InnoDB存储的文件结构?

 答:在 InnoDB 存储引擎中,所有的数据都被逻辑地存放在表空间中; 1)表空间:单独表空间只存放数据、索引和插入缓冲。 2)段:表空间有若干各段组成,常见的有数据段、索引段、回滚段等。 3)区:每64个连续的页组成区,因此区大小正好为1M。4)页:页是InnoDB磁盘管理的最小单位,固定大小为16K,不可以更改。 5)行:InnoDB表中数据按行存储。  所有的存储引擎都会在硬盘上创建.frm文件(描述表格格式);.ibd文件(描述存储数据)。

数据库自增主键可能产生的问题?

 答:如果使用自增主键的话,会造成数据库是单点,不可拆库,因为id会重复。

行存储和列存储的区别?

  答:列存储由于需要把一行记录拆分成单列保存,写入次数明显比行存储多,再加上磁头需要在盘片上移动和定位花费的时间,实际时间消耗会更大,所以,行存储在写入上占有很大的优势;数据的修改,行存储是在指定位置写入一次,列存储是将磁盘定位到多个列上分别写入;行存储在查询  数据时会有很多冗余数据,出于缩短处理时间的考量,消除冗余列的过程通常是在内存中进行的,列存储每次读取的数据是集合的一段或者全部, 不存在冗余性问题;行存储比较复杂,在一行记录中保存了多种类型的数据,数据解析需要在多种数据类型之间频繁转换,这个操作很消耗CPU,  增加了解析的时间,而列存储每一列保存的都是相同类型的数据,所以列存储的解析过程更有利于分析大数据;由于列存储的数据类型是一致的,  可以进行压缩。比如有增量压缩、前缀压缩算法都是基于列存储的类型定制的,有利于存储和网络输出数据带宽的消耗。

日志相关

MySQL有哪几种日志?redo log主要有什么用?提交之后100%落盘吗?为什么MySQL要写到redo log buff内存?

 答:1:重做日志(redo log):确保事务的持久性,redo日志记录事务执行后的状态,用来恢复未写入data file的已成功事务更新的数据,在事务的执行过程中便开始写入redo log文件中,日志缓存可用空间 少于一半时,重做日志缓存被刷新到重做日志文件; 2:回滚日志(undo log)保证数据的原子性,保存了事务发生之前的数据的一个版本,可以用于回滚,同时可以提供多版本并发控制下的读(MVCC),也即非锁定读;3:二进制日志(binlog):用于复制,在主从复制中,从库利用主库上的binlog进行重播,实现主从同步;4:错误日志(errorlog);5:慢查询日志(slow query log);6:一般查询日志(general log):记录了服务器接收到的每一个查询或是命令,无论这些查询或是命令是否正确甚至是否包含语法错误,general log 都会将其记录下来;7:中继日志(relay log):  中继日志用于主从复制架构中的从服务器上,从服务器的 slave 进程从主服务器处获取二进制日志的内容并写入中继日志,然后由 IO 进程读取并执行中继日志中的语句;  

MySQL记录binlog的方式主要包括三种模式?每种模式的优缺点是什么?

  答:1)RowLevel行模式:日志中会记录每一行数据被修改的形式,然后在slave端再对相同的数据进行修改; 优点:该模式可以不记录执行的sql语句的上下文相关的信息,只需要记录哪一条被修改, 不会出现某些特定的情况下的存储过程或function,以及trigger的调用和触发无法被正确复制的问题; 缺点:所有的执行的语句当记录到日志中的时候,都将以每行记录的修改来记录,会产生大量的日志内容。 2)Statement Level(默认):每一条会修改数据的sql都会记录到master的bin-log中。 slave在复制的时候sql进程会解析成和原来master端执行过的相同的sql来再次执行; 优点:只需要在Master上锁执行的语句的细节,以及执行语句的上下文的信息;  缺点:会造成MySQL的复制出现问题,主要是修改数据的时候使用了某些定的函数或者功能的时候会出现。 3) Mixed 自动模式:MySQL会根据执行的每一条具体的sql语句来区分对待记录的日志格式,也就是在Statement和Row之间选择一种。如果sql语句确实就是update或者delete等修改数据的语句,那么还是会记录所有行的变更。

数据库三范式?

答:第一范式:是指数据库表的每一列都是不可分割的基本数据项,同一列中不能有多个值,即实体中的某个属性不能有多个值或者不能有重复的属性。如果出现重复的属性,就可能需要定义一个新的实体, 新的实体由重复的属性构成,新实体与原实体之间为一对多关系。在第一范式中表的每一行只包含一个实例的信息。在任何一个关系数据库中,第一范式是对关系模式的基本要求,不满足第一范式的数据库就不是关系数据库; 第二范式:第二范式是在第一范式的基础上建立起来的,即满足第二范式必须先满足第一范式。 第二范式要求数据库表中的每个实例或行必须可以被惟一的区分。为实现区分通常需要为表加上一个列,以存储各个实例的惟一标识。要求实体的属性完全依赖于主关键字。一张表存在组合主键时,其他非主键字段不能部分依赖;第三范式:要求一个数据库表中不包含已在其它表中已包含的非主关键字信息。除主键外,其他字段必须依赖主键。

集群相关

mysql的一致性和CAP的一致性有什么区别?

 答:CAP:特性有:一致性、分区容忍性、可用性;在CAP定理中,三种特性不可能全部兼顾,最合理的是分区容忍和可用性,其中一致性分为强一致性和最终一致性,无论客户端在任何情况或任何时间访问数据都是一致的,最终一致性也叫 弱一致性,也就是说不能时时刻刻保证数据的一致性,只能最终保证数据的一致性,这个时间对客户端来说会非常短; mysq的一致性:也叫强一致性,是通过事务实现的,当并发修改统一份数据时就会有重复读,脏度等问题,通过锁来解决,当并发添加数据时是无法加锁的,所以通过事务的串行化来解决;

高并发下如何做到安全的修改同一行数据,INNODB的行级锁有哪2种,解释其含义(mysql)?

 答:1)行级锁:是MySQL中锁定粒度最细的一种锁,表示只针对当前操作的行进行加锁。 行级锁能大大减少数据库操作的冲突,其加锁粒度最小,但加锁的开销也最大。行级锁分为共享锁和排他锁; 该锁开销大,加锁慢;会出现死锁;锁定粒度最小,发生锁冲突的概率最低,并发度也最高。  2)表级锁:当前操作的整张表加锁,它实现简单,资源消耗较少,表级锁定分为表共享读锁(共享锁)与表独占写锁(排他锁);开销小,加锁快;不会出现死锁;锁定粒度大,发出锁冲突的概率最高,并发度最低。 3)页级锁:是 MySQL 中锁定粒度介于行级锁和表级锁中间的一种锁采取了折衷的页级锁,一次锁定相邻的一组记录; 开销和加锁时间界于表锁和行锁之间;会出现死锁;锁定粒度界于表锁和行锁之间,并发度一般。   

MySQL主从同步的基本原理?

            答:工作原理其实就是一个完全备份加上二进制日志备份的还原。不同的是这个二进制日志的还原是实时的, 1)主库接收客户端发送的一条SQL语句,执行内部事务逻辑,同时写binlog;2)备库通过 change master 命令,  设置主库的IP、端口、用户名和密码,以及要从哪个位置开始请求 binlog,这个位置包含文件名和偏移量; 3)在备库上执行start slave命令,启动两个线程 io_thread 和 sql_thread,其中 io_thread  负责与主机进行连接;4)主库校验完用户名和密码,按照接收到的位置去读取binlog,发给备库; 5)备库接收到binlog后,写到本地文件(relay log,中转文件);6)备库读取中转文件,解析出命令,然后执行;

MySQL主从复制,从服务器有几个线程?

  答:2个线程,一个负责读取二进制日志并将其保存为中继日志,另外一个负责执行SQL;

如何保证数据库集群中ID的唯一性,假设每秒钟并发20万次?

   答: 有多种:1)使用数据库自增Id:缺点:大表分表时不能用自增ID、高并发时不加事务会出现ID重复、表关联时需要获取父表ID插入到子表中;  2)单独开一个数据库,获取全局唯一的自增序列号或各表的MaxId:缺点:查询序列号是一个性能损耗;如果这个序列号列暴了,就会出现序列错误。  3)GUID(Globally Unique Identifier,全局唯一标识符):缺点: 存储占了32位且无可读性、占用了珍贵的聚集索引。  4)COMB(组合GUID/时间截):缺点:生成的Id不够友好,占据了32位。  COMB设计思路:通过组合的方式,保留GUID的10个字节,用另6个字节表示GUID生成的时间(DateTime),这样我们将时间信息与GUID组合起来,在保留GUID的唯一性的同时增加了有序性,以此来提高索引效率。适合大型应用。 即保留GUID的唯一性的同时增加了GUID有序性,提高了索引效率;解决了关联表业务问题。

锁相关

mysql的乐观锁和悲观锁?

答: 悲观锁(Pessimistic Lock):就是打开事务,当启动事务时,如果事务中的sql语句涉及到索引并用索引进行了条件判断, 那么会使用行级锁锁定所要修改的行,否则使用表锁锁住整张表。 乐观锁(Optimistic Lock):我们在使用乐观锁时会假设在极大多数情况下不会形成冲突,只有在数据提交的时候,  才会对数据是否产生冲突进行检验。如果数据产生冲突了,则返回错误信息,进行相应的处理。

行锁,表锁?

 答:行锁:开销大,加锁慢;会出现死锁;锁定粒度最小,发生锁冲突的概率最低,并发度也最高。 表锁:开销小,加锁快;不会出现死锁;锁定粒度大,发生锁冲突的概率最高,并发度最低

死锁判定原理和具体场景,死锁怎么解决?

 答:数据库是一个多用户使用的共享资源,1)如果两个用户分别访问A表和B表,并锁住当前表,  但是双方都需要访问对方锁住的表,都在等待对方释放锁;解决办法:使用乐观锁, 1)在表的字段中增加version字段,更新时进行查询version是否为当前取到version; 2)SQL语句中不要使用太复杂的关联多表的查询;

mysql的行级锁加在哪个位置?

答:我们知道mysql自身是不支持行锁,是由其他存储引擎(InnoDB、分布式存储引擎NDBCluster)实现的;InnoDB是给索引项加锁,只有通过索引条件检索数据时才是行锁,否则就是表锁。 如果使用了相同的索引键,也是会出现锁冲突的。不论是使用主键索引、唯一索引或普通索引,InnoDB都会使用行锁来对数据加锁。

myisam和innodb支持锁的粒度是怎样的?

 答:MyISAM:只支持表级锁:该引擎不适合大量读写操作的场景,会导致读请求长时间的等待出现线程饿死状态。InnoDB:支持事务和行级锁:该引擎可能会出现死锁情况,当发现程序有高并发的访问某一个表时, 尽量对该表的执行操作串行化,或者锁升级,一次性获取所有的锁资源。

数据库锁表的相关处理(mysql)?

 答:死锁:用户A访问A表并锁住,然后访问B表,用B访问B表并锁住,然后访问A表,两个必须同时等待对方释放锁。这就是死锁。 解决办法: 尽量按照相同的顺序进行处理,尽量避免同时锁定两个资源。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值