数据库MySql
1.基础知识
1.主键和外键有什么区别?
主键是用来唯一标识一条记录的,不能为空也不能重复,一张表只能有一个主键。在 InnoDB 中,主键索引是聚簇索引,数据本身存放在主键索引的叶子节点中。
外键主要用于建立表与表之间的关联关系,用来约束子表中的字段必须来自于父表的主键或唯一键,从而保证数据一致性。外键字段可以重复,也可以为空,一张表可以有多个外键。
在实际生产环境中,一般不直接使用数据库外键,而是在业务层通过逻辑外键来维护数据一致性,以避免外键带来的性能开销和维护复杂度问题。
2.为什么不推荐使用外键与级联?
外键和级联主要用于在数据库层面保证数据一致性,但在实际生产环境中通常不推荐使用。
一方面,外键和级联在插入、更新和删除时会带来额外的性能开销,尤其是在高并发场景下影响明显;另一方面,级联操作存在较大的误操作风险,一次错误删除可能导致大量数据被级联删除。
此外,外键不适用于分库分表和微服务架构,会增加系统的耦合度和维护成本。
因此,在实际项目中通常采用逻辑外键,在业务层通过代码和事务来保证数据一致性,而不是依赖数据库外键和级联机制。
什么是存储过程
存储过程是一组预先编译并存储在数据库中的 SQL 语句集合,可以像函数一样被调用执行,主要用于封装复杂的数据库操作逻辑。
存储过程的优点是执行效率较高、可以减少网络交互,并且能够在一定程度上复用数据库逻辑。
但在实际生产环境中通常不推荐大量使用存储过程,因为它会导致业务逻辑与数据库强耦合,可维护性和可扩展性较差,也不利于分布式和微服务架构的发展。
因此,当前主流做法是将业务逻辑放在应用层,数据库只负责数据的存储和查询。
drop、delete 与 truncate 区别?
delete、truncate 和 drop 都用于删除数据,但作用和使用场景不同。
delete 属于 DML 操作,可以删除表中部分或全部数据,支持事务和回滚,也会触发行级操作,但执行效率相对较低。
truncate 属于 DDL 操作,用于快速清空整张表的数据,不支持事务回滚,会重置自增主键,执行效率较高。
drop 同样是 DDL 操作,会直接删除整张表,包括表结构和数据,是不可恢复的操作。
在实际生产环境中,通常优先使用 delete 或逻辑删除方式,避免直接使用 truncate 和 drop。
为什么索引用 B+ 树?
MySQL 索引使用 B+ 树,主要是因为它在磁盘 I/O 和范围查询方面具有明显优势。
B+ 树的非叶子节点只存储索引键,不存储数据,使得单个节点可以容纳更多的索引项,从而降低树的高度,减少磁盘 I/O 次数。同时,所有数据都存放在叶子节点,查询路径长度一致,查询性能更加稳定。
此外,B+ 树的叶子节点通过链表连接,天然支持高效的范围查询和排序操作,非常符合数据库的使用场景,因此成为 MySQL 索引的主流数据结构。
什么时候需要 / 不需要创建索引?
索引通常创建在经常作为查询条件、连接条件、排序或分组字段上,尤其是区分度较高、查询频率高的字段,可以显著提升查询性能。
同时,如果索引能够覆盖查询字段,还可以避免回表,进一步提高效率。
但并不是所有字段都适合建索引,对于数据量较小的表、更新频繁的字段、区分度很低或几乎不参与查询条件的字段,一般不建议创建索引。此外,索引过多也会增加写操作的成本。
因此,索引的创建需要结合具体业务场景,在读写性能之间进行权衡。
索引优化的核心目标是减少数据扫描范围和回表次数。常见的优化方式包括合理使用联合索引并遵循最左前缀原则,将等值查询和区分度高的字段放在前面,同时通过覆盖索引避免回表操作。
在实际使用中,还需要避免索引失效的场景,如在索引列上使用函数或隐式类型转换,并控制索引数量,防止对写性能造成过大影响。此外,通过 EXPLAIN 分析执行计划,对慢 SQL 持续优化索引结构,是常用的索引优化手段。
