面试Mysql的几个常见问题

1、insert时如果数据重复如何用update?

INSERT INTO table (a,b,c) VALUES (1,2,3) ON DUPLICATE KEY UPDATE c=c+1;

2、一张表,里面有 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 丢失

3 、[SELECT *] 和[SELECT 全部字段]的 2 种写法有何优缺点?

1. 前者要解析数据字典,后者不需要
2. 结果输出顺序,前者与建表列顺序相同,后者按指定字段顺序。
3. 表字段改名,前者不需要修改,后者需要改
4. 后者可以建立索引进行优化,前者无法优化
5. 后者的可读性比前者要高
所以,尽量使用后者来查询

4、若一张表中只有一个字段 VARCHAR(N)类型,utf8 编码,则 N 最大值为多少?

由于 utf8 的每个字符最多占用 3 个字节。而 MySQL 定义行的长度不能超过65535(text和blob不计算在内),因此 N 的最大值计算方法为:(65535-1-2)/3。减去 1 的原因是实
际存储从第二个字节开始,减去 2 的原因是因为要在列表长度存储实际的字符长度(长度大于256用两个字节存储),除以 3 是因为 utf8 限制:每个字符最多占用 3 个字节。

5、MySQL 中 InnoDB 引擎的行锁是通过加在什么上完成(或称实现)的?

InnoDB 行锁是通过给索引上的索引项加锁来实现的,这一点 MySQL 与Oracle 不同,后者是通过在数据块中对相应数据行加锁来实现的。
InnoDB 这种行锁实现特点意味着:只有通过索引条件检索数据,InnoDB 才使用行级锁,否则,InnoDB 将使用表锁

6、 mysql 中 myisam 与 innodb 的区别?

扫描二维码关注公众号,回复: 6575507 查看本文章
1. 事务支持
MyISAM:强调的是性能,每次查询具有原子性,其执行数度比 InnoDB 类型更快,但是不提供事务支持。
InnoDB:提供事务支持事务,外部键等高级数据库功能。具有事务(commit)、回滚(rollback)和崩溃修复能力(crash recovery capabilities)的事务安全(transaction-safe (ACID compliant))型表。
2. InnoDB 支持行级锁,而 MyISAM 支持表级锁. 
用户在操作myisam 表时,selectupdatedeleteinsert 语句都会给表自动加锁,如果加锁以后的表满足 insert 并发的情况下,可以在表的尾部插入新的数据。
3. InnoDB 支持 MVCC, 而 MyISAM 不支持 (MVCC:Multi-Version Concurrency Control 多版本并发控制)
4. InnoDB 支持外键,而 MyISAM 不支持
5. 表主键
MyISAM:允许没有任何索引和主键的表存在,索引都是保存行的地址。
InnoDB:如果没有设定主键或者非空唯一索引,就会自动生成一个 6 字节的主键(用户不可见),数据是主索引的一部分,附加索引保存的是主索引的值。
6. InnoDB 不支持全文索引,而 MyISAM 支持。
7. 可移植性、备份及恢复
MyISAM:数据是以文件的形式存储,所以在跨平台的数据转移中会很方便。在备份和恢复时可单独针对某个表进行操作
InnoDB:免费的方案可以是拷贝数据文件、备份binlog,或者用 mysqldump,在数据量达到几十 G 的时候就相对痛苦了
8. 存储结构
MyISAM:每个 MyISAM 在磁盘上存储成三个文件。第一个文件的名字以表的名字开始,扩展名指出文件类型。.frm 文件存储表定义。数据文件的扩展名为.MYD (MYData)。索引文件的扩展名是.MYI (MYIndex)。
InnoDB:所有的表都保存在同一个数据文件中(也可能是多个文件,或者是独立的表空间文件),InnoDB 表的大小只受限于操作系统文件的大小,一般为 2GB。

7、mysql 的复制原理以及流程

Mysql 内建的复制功能是构建大型,高性能应用程序的基础。将 Mysql 的数据分布到多个系统上去,这种分布的机制,是通过将 Mysql 的某一台主机的数据复制到其它主机(slaves)上,并重新执行一遍来实现的。 
复制过程中一个服务器充当主服务器,而一个或多个其它服务器充当从服务器。主服务器将更新写入二进制日志文件,并维护文件的一个索引以跟踪日志循环。这些日志可以记录发送到从服务器的更新。
当一个从服务器连接主服务器时,它通知主服务器在日志中读取的最后一次成功更新的位置。从服务器接收从那时起发生的任何更新,然后封锁并等待主服务器通知新的更新。
过程如下
1. 主服务器把更新记录到二进制日志文件中。
2. 从服务器把主服务器的二进制日志拷贝到自己的中继日志(replay log)中。
3. 从服务器重做中继日志中的时间,把更新应用到自己的数据库上。

8、请简述常用的索引有哪些种类?

1. 普通索引: 即针对数据库表创建索引
2. 唯一索引: 与普通索引类似,不同的就是:MySQL 数据库索引列的值必须唯一,但允许有空值
3. 主键索引: 它是一种特殊的唯一索引,不允许有空值。一般是在建表的时候同时创建主键索引
4. 组合索引: 将数据库表中的多个字段联合起来作为一个组合索引

9、Mysql的四种事务隔离级别

1. Read Uncommitted(读取未提交内容) 
在该隔离级别,所有事务都可以看到其他未提交事务的执行结果。本隔离级别很少用于实际应用,因为它的性能也不比其他级别好多少。读取未提交的数据,也被称之为脏读(Dirty Read)。
2. Read Committed(读取提交内容)
这是大多数数据库系统的默认隔离级别(但不是 MySQL 默认的)。它满足了隔离的简单定义:一个事务只能看见已经提交事务所做的改变。这种隔离级别也支持所谓的不可重复读(Nonrepeatable Read),
因为同一事务的其他实例在该实例处理其间可能会有新的
commit,所以同一 select 可能返回不同结果。
3. Repeatable Read(可重读)
这是 MySQL 的默认事务隔离级别,它确保同一事务的多个实例在并发读取数据时,会看到同样的数据行。不过理论上,这会导致另一个棘手的问题:幻读(PhantomRead)。
简单的说,幻读指当用户读取某一范围的数据行时,另一个事务又在该范围内插入了新行,当用户再读取该范围的数据行时,会发现 有新的“幻影” 行。InnoDB 和 Falcon 存储引擎通过多版本并发控制(MVCC,Multiversion Concurrency Control 间隙锁)机制解决了该问题。
注:其实多版本只是解决不可重复读问题,而加上间隙锁(也就是它这里所谓的并发控制)才解决了幻读问题。
4. Serializable(可串行化)
这是最高的隔离级别,它通过强制事务排序,使之不可能相互冲突,从而解决幻读问题。简言之,它是在每个读的数据行上加上共享锁。
在这个级别,可能导致大量的超时现象和锁竞争。

10、数据库三范式(老生常谈)

1. 第一范式(1NF):字段具有原子性,不可再分。(所有关系型数据库系统都满足第一范式数据库表中的字段都是单一属性的,不可再分) => 关于列的设计
2. 第二范式(2NF)是在第一范式(1NF)的基础上建立起来的,即满足第二范式(2NF)必须先满足第一范式(1NF)。要求数据库表中的每个实例或行必须可以被惟一地区分。=> 关于的设计
通常需要为表加上一个列,以存储各个实例的惟一标识。这个惟一属性列被称为主关键字或主键。
3. 满足第三范式(3NF)必须先满足第二范式(2NF)。简而言之,第三范式(3NF)要求一个数据库表中不包含已在其它表中已包含的非主关键字信息。 => 关于表的设计
所以第三范式具有如下特征: >>1. 每一列只有一个值 >>2. 每一行都能区分。 >>3. 每一个表都不包含其他表已经包含的非主关键字信息

所以,记住行、列、表三个字即可

猜你喜欢

转载自www.cnblogs.com/roostinghawk/p/11067637.html