1. 数据库事务的特性?
- 原子性:即不可分割性,事务要么全部被执行,要么就全部不被执行。
- 一致性或可串性。事务的执行使得数据库从一种正确状态转换成另一种正确状态
- 隔离性。在事务正确提交之前,不允许把该事务对数据的任何改变提供给任何其他事务,
- 持久性。事务正确提交后,其结果将永久保存在数据库中,即使在事务提交后有了其他故障,事务的处理结果也会得到保存。
2. 据库三大范式是什么
- 第一范式:每个列都不可以再拆分。
- 第二范式:在第一范式的基础上,非主键列完全依赖于主键,而不能是依赖于主键的一部分。
- 第三范式:在第二范式的基础上,非主键列只依赖于主键,不依赖于其他非主键。
在设计数据库结构的时候,要尽量遵守三范式,如果不遵守,必须有足够的理由。比如性能。事实上我们经常会为了性能而妥协数据库的设计。
3. SQL 语句有哪些分类?
- DDL:数据定义语言(create alter drop)
- DML:数据操作语句(insert update delete)
- DTL:数据事务语句(commit collback savapoint)
- DCL:数据控制语句(grant revoke)
4. 数据库删除操作中的 delete、drop、 truncate 区别在哪?
答:当不再需要该表时可以用 drop 来删除表;
当仍要保留该表,但要删除所有记录时, 用 truncate 来删除表中记录。
当要删除部分记录时(一般来说有 WHERE 子句约束) 用 delete 来删除表中部分记录。
5. B+ 树的叶子节点链表是单向还是双向?
答:双向链表
6. MVCC 是什么?它的底层原理是什么?
答:MVCC,多版本并发控制,它是通过读取历史版本的数据,来降低并发事务冲突,从而提高并发性能的一种机制。
- 事务版本号
- 表的隐藏列
- undo log
- read view
7. 如何获取当前的 Mysql 版本?
答:用于获取当前 Mysql 的版本。
SELECT VERSION();
8. CHAR 和 VARCHAR 的区别?
答:以下是 CHAR 和 VARCHAR 的区别:
CHAR 和 VARCHAR 类型在存储和检索方面有所不同
CHAR 列长度固定为创建表时声明的长度,长度值范围是 1 到 255
当 CHAR 值被存储时,它们被用空格填充到特定长度,检索 CHAR 值时需删除尾随空格。
9. MyISAM 和 InnoDB 实现 B 树索引方式的区别是什么?
- InnoDB 存储引擎:B+ 树索引的叶子节点保存数据本身,其数据文件本身就是索引文件。
- MyISAM 存储引擎:B+ 树索引的叶子节点保存数据的物理地址,叶节点的 data 域存放的是数据记录的地址,索引文件和数据文件是分离的。
10. InnoDB 为什么设计 B+ 树索引?
- 两个考虑因素:
InnoDB 需要执行的场景和功能需要在特定查询上拥有较强的性能。
CPU 将磁盘上的数据加载到内存中需要花费大量时间。 - 为什么选择 B+ 树:
哈希索引虽然能提供O(1)复杂度查询,但对范围查询和排序却无法很好的支持,最终会导致全表扫描。B 树能够在非叶子节点存储数据,但会导致在查询连续数据可能带来更多的随机 IO。而 B+ 树的所有叶节点可以通过指针来相互连接,减少顺序遍历带来的随机 IO。 - 普通索引还是唯一索引?
由于唯一索引用不上 change buffer 的优化机制,因此如果业务可以接受,从性能角度出发建议你优先考虑非唯一索引。
11. 请简洁描述 Mysql 中 InnoDB 支持的四种事务隔离级别名称
SQL 标准定义的四个隔离级别为:
- read uncommited :读到未提交数据
- read committed:脏读,不可重复读
- repeatable read:可重读
- serializable :串行事物
12. InnoDB 存储引擎的特点
答:自从 MySQL5.1 之后,默认的存储引擎变成了 InnoDB 存储引擎,相对于MylSAM,InnoDB存储引擎有了较大的改变,它的主要特点是:
- 支持事务操作,具有事务 ACID 隔离特性,默认的隔离级别是可重复读(repetable-read)、通过MVCC(并发版本控制)来实现的。能够解决 脏读 和 不可重复读 的问题。InnoDB支持外键操作。 InnoDB 默认的锁粒度行级锁,并发性能比较好,会发生死锁的情况。
- 和 MyISAM 一样的是,InnoDB 存储引擎也有 frm 文件存储表结构定义,但是不同的是,InnoDB 的表数据与索引数据是存储在一起的,都位于 B+数的叶子节点上,而MylSAM的表数据和索引数据是分开的。
- InnoDB 有安全的日志文件,这个日志文件用于恢复因数据库崩溃或其他情况导致的数据丢失问题,保证数据的一致性。
- InnoDB 和 MylSAM 支持的索引类型相同,但具体实现因为文件结构的不同有很大差异。
- 增删改查性能方面,如果执行大量的增删改操作,推荐使用 InnoDB 存储引擎,它在删除操作时是对行删除,不会重建表。
13. 列的字符串类型可以是什么?
字符串类型是:
- SET
- BLOB
- ENUM
- CHAR
- TEXT
- VARCHAR
14. MySQL多表连接有哪些方式?怎么用的?这些连接都有什么区别?
答:连接方式:左连接、右连接、内连接
使用方法:
左连接:select * from A LEFT JOIN B on A.id=B.id;
右连接:select * from A RIGHT JOIN B on A.id=B.id;
内连接:select * from A inner join B on a.xx=b.xx;(其中inner可以省略)
区别:
Inner join 内连接,在两张表进行连接查询时,只保留两张表中完全匹配的结果集left join 在两张表进行连接查询时,会返回左表所有的行,即使在右表中没有匹配的记录。right join 在两张表进行连接查询时,会返回右表所有的行,即使在左表中没有匹配的记录。
15. UNION和UNION ALL的区别?
- Union:对两个结果集进行并集操作,不包括重复行,同时进行默认规则的排序;
- Union All:对两个结果集进行并集操作,包括重复行,不进行排序;
UNION的效率高于UNION ALL
16. MySQL 中有哪几种锁?
- 表级锁:开销小,加锁快;不会出现死锁;锁定粒度大,发生锁冲突的概率最高,并发度最低。
- 行级锁:开销大,加锁慢;会出现死锁;锁定粒度最小,发生锁冲突的概率最低,并发度也最高。
- 页面锁:开销和加锁时间界于表锁和行锁之间;会出现死锁;锁定粒度界于表锁和行锁之间,并发度一般。
17. 索引有哪几种类型?
- 主键索引: 数据列不允许重复,不允许为 NULL,一个表只能有一个主键。
- 唯一索引: 数据列不允许重复,允许为 NULL 值,一个表允许多个列创建唯一索引。
ALTER TABLE table_name ADD UNIQUE (column);
ALTER TABLE table_name ADD UNIQUE (column1,column2);
- 普通索引: 基本的索引类型,没有唯一性的限制,允许为NULL 值。
ALTER TABLE table_name ADD INDEX index_name (column);
ALTER TABLE table_name ADD INDEX index_name(column1, column2, column3);
- 全文索引: 是目前搜索引擎使用的一种关键技术。
ALTER TABLE table_name ADD FULLTEXT (column);
18. 索引有哪些优缺点?
索引的优点:
- 可以大大加快数据的检索速度,这也是创建索引的最主要的原因。 通过使用索引,可以在查询的过程中,使用优化隐藏器,提高系统的性能。索引的缺点
- 时间方面:创建索引和维护索引要耗费时间,具体地,当对表中的数据进行增加、删除和修改的时候,索引也要动态的维护,会降低增/改/删的执行效率;
- 空间方面:索引需要占物理空间。
19. 关心过业务系统里面的sql耗时吗?对慢查询都怎么优化过?
- 分析语句,是否加载了不必要的字段/数据。
- 分析SQL执行语句是否命中索引等。
- 如果SQL很复杂,优化SQL结构
- 如果表数据量太大,考虑分表情况
20. 主键使用自增ID还是UUID,为什么?
答:如果是单机的话,选择自增ID;如果是分布式系统,优先考虑UUID,但还是最好公司自己有一套分布式唯一ID生产方案。
- 自增ID:数据存储空间小,查询效率高。但是如果数据量过大,会超出自增长的值范围,多库合并,也有可能出现问题。
- uuid:适合大量数据的插入和更新操作,但它是无序的,插入数据效率慢,占用空间大。
21. 为什么需要 redo log?
答:redo log 主要用于 MySQL 异常重启后的一种数据恢复手段,确保了数据的一致性。其实是为了配合 MySQL 的 WAL 机制。因为 MySQL 进行更新操作,为了能够快速响应,所以采用了异步写回磁盘的技术,写入内存后就返回。但是这样,会存在 crash后 内存数据丢失的隐患,而 redo log 具备 crash safe 的能力。
22. MySQL 如何做分布式锁?
- 方法一:利用 Mysql 的锁表,创建一张表,设置一个 UNIQUE KEY 这个KEY 就是要锁的KEY,所以同一个 KEY 在 mysql 表里只能插入一次了,这样对锁的竞争就交给了数据库,处理同一个 KEY 数据库保证了只有一个节点能插入成功,其他节点都会插入失败。DB 分布式锁的实现:通过主键 id 的唯一性进行加锁,说白了就是加锁的形式是向一张表中插入一条数据,该条数据的 id 就是一把分布式锁,例如当一次请求插入了一条id为1的数据,其他想要进行插入数据的并发请求必须等第一次请求执行完成后删除这条id为1的数据才能继续插入,实现了分布式锁的功能。
- 方法二:使用流水号+时间戳做幂等操作,可以看作是一个不会释放的锁。
23. 百万级别或以上的数据如何删除
答:关于索引:由于索引需要额外的维护成本,因为索引文件是单独存在的文件,所以当我们对数据的增加,修改,删除,都会产生额外的对索引文件的操作,这些操作需要消耗额外的IO,会降低增/改/删的执行效率。所以,在我们删除数据库百万级别数据的时候,查询MySQL官方手册得知删除数据的速度和创建的索引数量是成正比的。
- 所以我们想要删除百万数据的时候可以先删除索引(此时大概耗时三分多钟)
- 然后删除其中无用数据(此过程需要不到两分钟)
- 删除完成后重新创建索引(此时数据较少了)创建索引也非常快,约十分钟左右。
- 与之前的直接删除绝对是要快速很多,更别说万一删除中断,一切删除会回滚。那更是坑了。
24. 介绍下 MySQL 的主从复制原理?产生主从延迟的原因?
答:主从复制原理: 主库将变更写入 binlog 日志,然后从库连接到主库之后,从库有一个IO 线程,将主库的 binlog 日志拷贝到自己本地,写入一个relay 中继日志中。接着从库中有一个 SQL 线程会从中继日志读取 binlog,然后执行binlog 日志中的内容,也就是在自己本地再次执行一遍 SQL。
主从延迟:
a. 主库的从库太多
b. 从库硬件配置比主库差
c. 慢 SQL 语句过多
d. 主从库之间的网络延迟
e. 主库读写压力大
25. 谈谈你对 SQL 注入式攻击的理解?
答:所谓 SQL 注入式攻击,就是攻击者把 SQL 命令插入到 Web 表单的输入域或页面请求的查询字符串,欺骗服务器执行恶意的 SQL 命令。
如何防范 SQL 注入式攻击?
在利用表单输入的内容构造 SQL 命令之前,把所有输入内容过滤一番就可以了。过滤输入内容可以按多种方式进行。
- 对于动态构造 SQL 查询的场合
a. 替换单引号,即把所有单独出现的单引号改成两个单引号,防止攻击者修改SQL命令的含义。
b. 删除用户输入内容中的所有连字符
c. 对于用来执行查询的数据库帐户,限制其权限。用不同的用户帐户执行查询、插入、更新、删除操作。 - 用存储过程来执行所有的查询。
- 限制表单或查询字符串输入的长度。
- 检查用户输入的合法性。
- 检查提取数据的查询所返回的记录数量。
26. PostgreSQL和mysql数据库的区别
-
数据类型:PostgreSQL支持更多的数据类型,例如数组,json,hstore等,而MySQL则支持空间数据类型(GIS)。
-
扩展性:PostgreSQL相比MySQL具有更强的扩展性,支持自定义数据类型,函数和存储过程等。它还提供了一些高级功能,如异步复制,流复制,热备等。
-
ACID:PostgreSQL具有更严格的ACID(原子性,一致性,隔离性和持久性)兼容性。在默认情况下,PostgreSQL使用更为严格的隔离级别,这有助于保证数据的一致性和完整性。MySQL默认使用更低的隔离级别。
-
性能:MySQL比PostgreSQL更适用于大型的数据集,因为它的性能更好,特别是在读写和并发方面。而PostgreSQL在处理复杂的查询和更大数据集方面的性能表现更优秀。
-
开源协议:MySQL的开源协议是GPL(通用公共许可证),这意味着对MySQL进行修改的衍生产品也必须使用同一协议进行发布。而PostgreSQL的开源协议是BSD,这意味着PostgreSQL可以被商业软件使用,并且修改后的代码可以私有化。
-
跨平台支持:MySQL支持更多的操作系统,如Windows,Linux,macOS,FreeBSD等。PostgreSQL虽然也支持这些操作系统,但它的最初目标是在UNIX操作系统上运行。