【mysql练习一】复习数据库面试常考概念和基础知识

一、Mysql中有哪几种锁?

数据库锁分为行级锁(INNODB引擎)表级锁(MYISAM引擎)页级锁(BDB引擎 )

1.表级锁

开销小,加锁快;不会出现死锁;锁定粒度大,发生锁冲突的概率最高,并发度最低。
解释:表示对当前操作的整张表加锁,它实现简单,资源消耗较少,被大部分MySQL引擎支持。最常使用的MYISAM与INNODB都支持表级锁定。表级锁定分为表共享读锁(共享锁)与表独占写锁(排他锁)。MyISAM中是不会产生死锁的,因为MyISAM总是一次性获得所需的全部锁,要么全部满足,要么全部等待。而在InnoDB中,锁是逐步获得的,就造成了死锁的可能。
在MySQL中,行级锁并不是直接锁记录,而是锁索引。索引分为主键索引和非主键索引两种,如果一条sql语句操作了主键索引,MySQL就会锁定这条主键索引;如果一条语句操作了非主键索引,MySQL会先锁定该非主键索引,再锁定相关的主键索引。 在UPDATE、DELETE操作时,MySQL不仅锁定WHERE条件扫描过的所有索引记录,而且会锁定相邻的键值,即所谓的next-key locking。
当两个事务同时执行,一个锁住了主键索引在等待其他相关索引,一个锁定了非主键索引,在等待主键索引。这样就会发生死锁。
发生死锁后,InnoDB一般都可以检测到,并使一个事务释放锁回退,另一个获取锁完成事务。
参考:mysql锁表和解锁语句分享
Mysql中的行级锁、表级锁、页级锁

<?php
//执行SQL语句 锁掉stat_num表 
$sql = "LOCK TABLES stat_num WRITE"; //表的WRITE锁定,阻塞其他所有mysql查询进程 
$DatabaseHandler->exeCute($sql); 
//执行更新或写入操作 
$sql = "UPDATE stat_num SET `correct_num`=`correct_num`+1 WHERE stat_date='{$cur_date}'"; 
$DatabaseHandler->exeCute($sql); 
//当前请求的所有写操作做完后,执行解锁sql语句 
$sql = "UNLOCK TABLES"; 
$DatabaseHandler->exeCute($sql); 
?>
2.行级锁

开销大,加锁慢;会出现死锁;锁定粒度最小,发生锁冲突的概率最低,并发度也最高。
行级锁分为共享锁排他锁
InnoDB行锁是通过给索引上的索引项加锁来实现的,这一点MySQL与Oracle不同,后者是通过在数据块中对相应数据行加锁来实现的。InnoDB这种行锁实现特点意味着:只有通过索引条件检索数据,InnoDB才使用行级锁,否则,InnoDB将使用表锁!
在实际应用中,要特别注意InnoDB行锁的这一特性,不然的话,可能导致大量的锁冲突,从而影响并发性能。
行级锁都是基于索引的,如果一条SQL语句用不到索引是不会使用行级锁的,会使用表级锁。行级锁的缺点是:由于需要请求大量的锁资源,所以速度慢,内存消耗大。

3 . 页面锁

开销和加锁时间界于表锁和行锁之间;会出现死锁;锁定粒度界于表锁和行锁之间,并发度一般。一次锁定相邻的一组记录。

二、如何避免死锁?

1、如果不同程序会并发存取多个表,尽量约定以相同的顺序访问表,可以大大降低死锁机会。
2、在同一个事务中,尽可能做到一次锁定所需要的所有资源,减少死锁产生概率;
3、对于非常容易产生死锁的业务部分,可以尝试使用升级锁定颗粒度,通过表级锁定来减少死锁产生的概率;

三、什么是乐观锁悲观锁,如何用mysql实现?

之前写的博客有对乐观锁悲观锁稍微进行了描述:链接点击访问

总结:

在实际生产环境里边,如果并发量不大且不允许脏读,可以使用悲观锁;
但如果系统的并发非常大的话,悲观锁定会带来非常大的性能问题,
所以我们就要选择乐观锁定的方法
乐观锁悲观锁的数据库mysql语句实现:点此访问 或者:阅读原文

四、什么是事务?如何实现??

之前写的博客有举出一个例子,附有java代码实现:点击链接访问
事务要保证操作的原子性。如果非原子就要回滚,回到之前的状态,
例如: 往表中插入100条数据,到了76条的时候,服务器网络断了,此时报错,之前的76条就要全部删除,恢复到没有进行任何操作的状态才行,否则就出现了异常。
原子性即:要么成功,要么失败,不能只做一半

五、mysql有哪些引擎?简述在MySQL数据库中MyISAM和InnoDB的区别。

共有5种类型的表格:
. MyISAM
. Heap
. Merge
. INNODB
. ISAM

查看引擎:

 show engines;

可以查看各个引擎
在这里插入图片描述
查看当前表格引擎:

show table status from [数据库名] where name='[表格名]'
show table status from test where name='test1'

默认是innodb
在这里插入图片描述
在这里插入图片描述

MyISAM:

  • 不支持事务,但是每次查询都是原子的;(不过我们可以在自己的java代码里保证多条操作一起执行的原子性)
  • 支持表级锁,即每次操作是对整个表加锁;
  • 存储表的总行数;
  • 一个MYISAM表有三个文件:索引文件、表结构文件、数据文件;frm 文件存放表格定义;数据文件是MYD (MYData);索引文件是MYI (MYIndex)。
  • 采用非聚集索引,索引文件的数据域存储指向数据文件的指针。辅索引与主索引基本一致,但是辅索引不用保证唯一性。对于非聚簇索引存储来说,主键B+树在叶子节点存储指向真正数据行的指针,而非主键。
  • MyISAM是MySQL的默认存储引擎,基于传统的ISAM类型,支持全文搜索,但不是事务安全的,而且不支持外键。

InnoDb:

  • InnoDB是事务型引擎,支持回滚、崩溃恢复能力、多版本并发控制、ACID事务,支持行级锁定(InnoDB表的行锁不是绝对的,如果在执行一个SQL语句时MySQL不能确定要扫描的范围或者不是在索引上搜索,InnoDB表同样会锁全表,如like操作时的SQL语句),以及提供与Oracle类型一致的不加锁读取方式。
  • 支持ACID的事务,支持事务的四种隔离级别;
  • 支持行级锁及外键约束:因此可以支持写并发;
  • 不存储总行数;
  • 一个InnoDb引擎存储在一个文件空间(共享表空间,表大小不受操作系统控制,一个表可能分布在多个文件里),也有可能为多个(设置为独立表空,表大小受操作系统文件大小限制,一般为2G),受操作系统文件大小的限制;
  • 主键索引采用聚集索引(索引的数据域存储数据文件本身),辅索引的数据域存储主键的值;因此从辅索引查找数据,需要先通过辅索引找到主键值,再访问辅索引;最好使用自增主键,防止插入数据时,为维持B+树结构,文件的大调整。

区别参考网址:详细基础版

核心区别

  • MyISAM是非事务安全型的,而InnoDB是事务安全型的。
  • MyISAM锁的粒度是表级,而InnoDB支持行级锁定。
  • MyISAM支持全文类型索引,而InnoDB不支持全文索引。
  • MyISAM相对简单,所以在效率上要优于InnoDB,小型应用可以考虑使用MyISAM。
  • MyISAM表是保存成文件的形式,在跨平台的数据转移中使用MyISAM存储会省去不少的麻烦。
  • InnoDB表比MyISAM表更安全,可以在保证数据不会丢失的情况下,切换非事务表到事务表(alter table tablename type=innodb)。

应用场景

  • MyISAM管理非事务表。它提供高速存储和检索,以及全文搜索能力。如果应用中需要执行大量的SELECT查询,那么MyISAM是更好的选择。
  • InnoDB用于事务处理应用程序,具有众多特性,包括ACID事务支持。如果应用中需要执行大量的INSERT或UPDATE操作,则应该使用InnoDB,这样可以提高多用户并发操作的性能。

六、Mysql中InnoDB支持的四种事务隔离级别名称,以及各级之间的区别?

SQL标准定义的四个隔离级别为:

  • read uncommited :读到未提交数据
  • read committed:脏读,不可重复读
  • repeatable read:可重读
  • serializable :串行事物

快速理解脏读、不可重复读、幻读和MVCC

七、CHAR和VARCHAR的区别?

  • CHAR和VARCHAR类型在存储和检索方面有所不同
  • CHAR列长度固定为创建表时声明的长度,长度值范围是1到255
  • 当CHAR值被存储时,它们被用空格填充到特定长度,检索CHAR值时需删除尾随空格。

八、主键和候选键有什么区别?

表格的每一行都由主键唯一标识,一个表只有一个主键。
主键也是候选键。按照惯例,候选键可以被指定为主键,并且可以用于任何外键引用。
a.超键: 在关系模式中,能 唯一标识 元组的属性集称为超键。
b.候选键 : 如果一个属性集能唯一标识元组,且有不包含多余属性,那么这个属性集称为候选键;也即:候选键是没有多余属性的超键。超键可以看作是带有其他有多余属性的候选键,也即候选键带上任意个其他属性可被视为超键
c.主键: 关系模式中用户正在使用的候选键称主键(primary key)。一般如不加说明,键是指主键。
举例:

1.(假设姓名无重复)   
姓名,学号,年龄   
a,1,20   
b,2,30   
c,3,23   
姓名唯一,是个超键
学号唯一,是个超键
(姓名,年龄)唯一 ,是个超键
(学号,努力)唯一,是个超键
姓名唯一,且没有其他多余属性,是个候选键
学号唯一,且没有其他多余属性,是个候选键
考虑方便查询,我们使用学号作为主键;
也可以根据习惯,使用姓名作为主键;即选中的候选键就是主键

d.外键
在关系模式R中,如果某属性集是其他模式的候选键,那么该属性集对模式R来说就是外键。

九、MyISAM Static和MyISAM Dynamic有什么区别?

在MyISAM Static上的所有字段有固定宽度。动态MyISAM表将具有像TEXT,BLOB等字段,以适应不同长度的数据类型。MyISAM Static在受损情况下更容易恢复。

十、如果一个表有一列定义为TIMESTAMP,将发生什么?

每当行被更改时,时间戳字段将获取当前时间戳。

十一、列设置为AUTO INCREMENT时,如果在表中达到最大值,会发生什么情况?

它会停止递增,任何进一步的插入都将产生错误,因为这个值已被使用。但是可以修改int unsigned类型为bigint类型, 这是64位的整数,使得永远不会达到最大值。

十二、怎样才能找出最后一次插入时分配了哪个自动增量?

LAST_INSERT_ID 将返回由 Auto_increment 分配的最后一个值,并且不需要指定表名称。

十三、一张表,里面有ID自增主键,当insert了17条记录之后,删除了第15,16,17条记录,再把Mysql重启,再insert一条记录,这条记录的ID是18还是15 ?

(1)如果表的类型是MyISAM,那么是18 
因为MyISAM表会把自增主键的最大ID记录到数据文件里,重启MySQL自增主键的最大ID也不会丢失
(2)如果表的类型是InnoDB,那么是15 
InnoDB表只是把自增主键的最大ID记录到内存中,所以重启数据库或者是对表进行OPTIMIZE操作,都会导致最大ID丢失

十四、如何对语句进行优化,使之效率更高?

1)Where子句中:where表之间的连接必须写在其他Where条件之前,那些可以过滤掉最大数量记录的条件必须写在Where子句的末尾.HAVING最后。
(2)用EXISTS替代IN、用NOT EXISTS替代NOT IN。
(3) 避免在索引列上使用计算
(4)避免在索引列上使用IS NULL和IS NOT NULL
(5)对查询进行优化,应尽量避免全表扫描,首先应考虑在 where 及 order
by 涉及的列上建立索引。
(6)应尽量避免在 where 子句中对字段进行 null 值判断,否则将导致引擎放
弃使用索引而进行全表扫描
(7)应尽量避免在 where 子句中对字段进行表达式操作,这将导致引擎放弃使用索引而进行全表扫描

发布了140 篇原创文章 · 获赞 114 · 访问量 18万+

猜你喜欢

转载自blog.csdn.net/qinglingLS/article/details/105252697
今日推荐