MySQL面试题2025 每日20道【其四】
1、你们生产环境的 MySQL 中使用了什么事务隔离级别?为什么? 中等
在生产环境中,MySQL数据库的事务隔离级别通常由开发团队或数据库管理员根据应用的需求来设定。MySQL支持四种标准的事务隔离级别:
-
读未提交(Read Uncommitted):事务中的修改,即使未提交,对其他事务也都是可见的。这个级别会导致很多并发问题,如脏读、不可重复读和幻读。
-
读已提交(Read Committed):一个事务开始时,只能看见已经提交的事务所做的修改。这可以防止脏读,但不可重复读和幻读仍然可能发生。
-
可重复读(Repeatable Read):在整个事务期间,任何外部提交的更改都不会影响该事务的查询结果。这是MySQL默认的隔离级别,它解决了不可重复读的问题,但在某些情况下仍可能出现幻读。
-
序列化(Serializable):提供最严格的隔离级别,所有事务依次逐个执行,这样事务的并发度会很低,但完全避免了脏读、不可重复读以及幻读。
对于为什么选择某一种隔离级别,这取决于应用程序的具体需求。例如,在金融系统中,数据的一致性和准确性是最重要的,因此可能会选择较高的隔离级别如“可重复读”或“序列化”。而在一些对性能要求较高且能容忍一定并发问题的场景下,则可能会选择较低的隔离级别以提高并发性能。
在MySQL的InnoDB存储引擎中,默认使用的是“可重复读(Repeatable Read)”隔离级别。这是因为在这个级别上,InnoDB可以通过多版本并发控制(MVCC)机制很好地平衡并发性能和数据一致性。
如果你需要确切了解某个特定生产环境下的MySQL配置,你应该直接查看那个环境中的配置设置或者咨询负责维护该数据库的管理员。
2、为什么阿里巴巴的 Java 手册不推荐使用存储过程? 中等
阿里巴巴的Java开发手册不推荐使用存储过程,主要是基于以下几个考虑:
-
维护成本:存储过程将业务逻辑部分或全部嵌入到数据库中,这可能会增加维护成本。因为它们通常不是由应用程序的同一团队管理,而是由数据库管理员(DBA)负责。这意味着对于应用开发者来说,理解和修改这些存储过程可能需要额外的学习和沟通成本。
-
移植性问题:不同的数据库系统有不同的存储过程语法和特性。如果你的应用程序未来需要迁移到另一个数据库平台,那么你可能不得不重新编写所有的存储过程。相比之下,如果业务逻辑在应用程序代码中实现,则更容易进行跨数据库移植。
-
调试困难:存储过程的调试往往比普通应用程序代码更复杂。许多现代IDE提供了强大的工具来帮助开发者调试应用程序代码,但对于存储过程的支持则相对较弱。此外,在分布式环境中跟踪事务边界和错误也会变得更加棘手。
-
版本控制挑战:当业务逻辑被编码进存储过程中时,对其进行版本控制就变得复杂了。通常情况下,应用程序代码可以很好地与版本控制系统集成,但存储过程的变更管理则不容易做到这一点。
-
测试不便:单元测试和集成测试存储过程要比测试普通的应用程序代码更加困难。由于存储过程紧密耦合于数据库,所以为了有效地测试它们,通常需要模拟整个数据库环境,这增加了测试的复杂度。
-
性能优化限制:虽然某些操作通过存储过程可以在数据库层面获得性能提升,但这也可能导致对数据库内部机制过度依赖,使得优化选择受到局限。而且,随着数据库技术的发展,很多原本需要通过存储过程实现的性能优化现在可以通过查询优化器自动完成。
-
安全性考量:存储过程的执行权限通常赋予给特定用户,这可能引发安全风险,尤其是在处理敏感数据时。同时,存储过程中的SQL注入漏洞也有可能被利用,尽管这种风险同样存在于直接编写的SQL语句中。
综上所述,阿里巴巴的Java开发手册倾向于鼓励将业务逻辑保持在应用程序层面上,以确保更好的可维护性、移植性和安全性,同时也简化了开发流程。然而,这并不意味着存储过程没有其应用场景;在一些特定的情况下,比如大批量数据处理或者复杂的数据库级逻辑,存储过程仍然是一个有效的工具。每个项目都应该根据自身的需求和技术栈做出最适合的选择。
3、如何实现数据库的不停服迁移? 中等
实现数据库的不停服迁移(即在线迁移)是一个复杂的过程,它要求在不影响现有系统服务的前提下,将数据从一个数据库环境迁移到另一个。以下是实现不停服数据库迁移的一般步骤和策略:
1. 评估与规划
- 需求分析:明确迁移的目的、目标数据库的选择以及业务影响。
- 风险评估:识别潜在的风险,并制定应对措施。
- 资源准备:确保有足够的硬件资源来支持新旧系统的并行运行。
2. 选择适当的迁移工具和技术
- 根据源数据库和目标数据库的类型选择合适的迁移工具,如AWS Database Migration Service, GoldenGate等。
- 如果是同构数据库间的迁移,可以考虑使用备份恢复或复制技术。
3. 架构设计
- 双写机制:在某些情况下,可以在一段时间内同时向旧数据库和新数据库写入数据,确保两个数据库的数据一致性。
- 读写分离:通过代理或中间件实现读写分离,减轻源数据库压力,并为逐步切换到新的数据库做好准备。
4. 数据同步
- 全量迁移:首先进行一次完整的数据迁移,把所有历史数据从源库迁移到目标库。
- 增量同步:利用日志解析或者变更数据捕获(CDC)技术,持续地将新增或修改的数据从源库同步到目标库,保持两者的数据一致。
5. 验证
- 在迁移过程中定期检查数据的一致性和完整性,确保没有遗漏或错误。
- 进行充分的功能测试,以保证应用程序在新环境中能够正常工作。
6. 切换
- 流量切分:逐渐将一部分流量导向新的数据库,观察性能和稳定性。
- 最终切换:当确认一切正常后,可以选择一个合适的时间点完成全部流量的切换,通常会选择业务低峰期。
7. 监控与优化
- 在切换完成后,密切监控新数据库的表现,包括性能指标、错误率等。
- 对应用层代码及数据库配置进行必要的调整,以达到最佳性能。
8. 回滚计划
- 制定详细的回滚方案,以防万一出现问题可以迅速回到原来的环境。
注意事项:
- 沟通协调:在整个迁移过程中,与所有相关方保持良好的沟通非常重要,确保他们了解进度和可能的影响。
- 用户通知:如果有可能的话,提前告知用户可能会出现短暂的服务中断(即使是非常短的时间),以便他们有所准备。
不同的项目和环境可能需要定制化的解决方案,因此上述建议应根据具体情况进行适当调整。
4、MySQL 数据库的性能优化方法有哪些? 中等
MySQL数据库的性能优化可以从多个方面进行,包括但不限于查询优化、索引优化、配置调整、硬件升级等。下面是一些常见的MySQL性能优化方法:
查询优化
- 分析慢查询:使用
slow query log
来识别执行时间过长的SQL语句,并对其进行优化。 - 避免全表扫描:尽量减少或消除不必要的全表扫描操作,确保查询能够利用到索引。
- 优化JOIN操作:尽量减少复杂的多表连接,或者通过适当的索引来加速JOIN。
- 限制返回结果集大小:对于不需要全部数据的情况,使用
LIMIT
来限制返回的结果数量。 - 使用合适的函数和表达式:某些内置函数和表达式的效率较低,可以考虑用更高效的替代方案。
索引优化
- 创建有效的索引:为经常出现在
WHERE
子句中的列创建索引,特别是那些用于过滤、排序或分组的字段。 - 选择合适的索引类型:根据查询的特点选择B树、哈希或其他类型的索引。
- 定期重建索引:随着数据的变化,索引可能会变得不再高效,定期重建可以帮助保持最佳性能。
- 避免过度索引:过多的索引会增加写入成本,并占用额外的存储空间。
配置调整
- 调整缓冲区大小:适当增大InnoDB Buffer Pool Size、Key Buffer Size等内存参数,以提高缓存命中率。
- 优化并发设置:如调整
innodb_thread_concurrency
、max_connections
等参数,以适应应用程序的需求。 - 启用查询缓存(已废弃):尽管MySQL 8.0已经移除了查询缓存功能,但在之前的版本中,它可以在一定程度上提升读密集型应用的性能。
数据库结构优化
- 归档旧数据:将不常访问的历史数据移动到单独的归档表中,减少主表的数据量。
- 分区表:对大型表实施水平或垂直分区,以便更好地管理和访问数据。
- 选择合适的数据类型:尽可能使用较小的数据类型,例如INT代替BIGINT,以节省存储空间并加快处理速度。
硬件与网络优化
- 升级硬件资源:增加CPU核心数、扩展RAM容量、采用SSD硬盘等方式来增强服务器性能。
- 优化网络带宽:确保数据库服务器和客户端之间的网络连接稳定且具有足够的带宽。
应用层优化
- 批量处理:当需要插入大量数据时,尽量采用批量插入而不是逐行插入。
- 异步处理:对于非实时要求的任务,可以考虑使用消息队列等机制来进行异步处理。
日志与监控
- 启用慢查询日志和错误日志:帮助诊断问题。
- 使用监控工具:如Percona Monitoring and Management (PMM)、Prometheus + Grafana等,持续跟踪数据库的运行状态。
以上只是一些基本的优化策略,具体的优化措施应该基于实际的工作负载和业务需求。在进行任何重大变更之前,建议先在一个测试环境中充分验证其效果。
5、MySQL 中 InnoDB 存储引擎与 MyISAM 存储引擎的区别是什么? 中等
MySQL的InnoDB和MyISAM是两种不同的存储引擎,它们在特性、性能、功能等方面存在显著差异。以下是两者的主要区别:
事务支持
- InnoDB:支持ACID兼容的事务处理,提供提交、回滚和崩溃恢复能力,确保数据的一致性和持久性。
- MyISAM:不支持事务,这意味着一旦写入操作开始,即使遇到问题也不能回滚。
锁机制
- InnoDB:使用行级锁(Row-level Locking),允许并发控制更细粒度,在高并发场景下表现出色。
- MyISAM:采用表级锁(Table-level Locking),当一个线程正在写入时,整个表都会被锁定,其他读写请求必须等待,这在高并发环境下可能会导致性能瓶颈。
外键约束
- InnoDB:支持外键约束,可以用来维护不同表之间的参照完整性。
- MyISAM:不支持外键约束,因此不具备这一级别的数据完整性保障。
索引结构
- InnoDB:使用聚集索引(Clustered Index),将主键与数据行一起存储,非主键索引则是指向主键的指针。这种设计有助于加速基于主键的查询。
- MyISAM:使用的是非聚集索引(Non-clustered Index),即索引和数据是分开存储的。
缓存策略
- InnoDB:有专门的缓冲池(Buffer Pool)来缓存数据和索引页,提高了I/O效率。
- MyISAM:只缓存索引,数据文件由操作系统负责缓存。
损坏恢复
- InnoDB:具有自动恢复功能,可以通过重做日志(Redo Log)和撤销日志(Undo Log)进行崩溃恢复。
- MyISAM:缺乏内置的恢复机制,如果发生崩溃,可能需要手动修复损坏的表。
存储限制
- InnoDB:单个表的数据大小理论上没有限制,受限于磁盘空间和操作系统对文件大小的支持。
- MyISAM:单个表的最大容量为256TB(取决于系统参数设置)。
内存使用
- InnoDB:内存消耗通常比MyISAM要大,因为它需要额外的空间来管理事务、锁定和其他内部操作。
- MyISAM:相对较低的内存占用。
全文搜索
- InnoDB:从MySQL 5.6版本开始也支持全文索引,但在此之前只有MyISAM支持。
- MyISAM:早期版本中提供了全文索引的支持。
综上所述,InnoDB更适合那些需要高并发写入、事务支持以及数据完整性的应用;而MyISAM则适用于以读取为主的应用,并且在某些特定情况下(如全文索引需求)可能是一个更好的选择。不过,随着MySQL的发展,许多以前仅限于MyISAM的功能已经被添加到了InnoDB中,使得InnoDB成为了大多数应用场景下的首选。
MySQL 的查询优化器如何选择执行计划? 中等
数据库
MySQL
数据库体系结构
7、什么是数据库的逻辑删除?数据库的物理删除和逻辑删除有什么区别? 简单
数据库中的逻辑删除和物理删除是两种不同的数据删除方式,它们在实现机制、应用场景以及对系统的影响方面都有显著的区别。
逻辑删除(Logical Deletion)
- 定义:逻辑删除并不是真正地从数据库中移除记录,而是通过设置一个或多个字段(如
is_deleted
标志位)来标记这条记录为已删除状态。 - 优点:
- 可以保持数据的完整性,允许恢复误删的数据。
- 减少对外部系统的冲击,因为关联的数据不会立即丢失。
- 对于审计追踪非常有用,可以记录哪些记录被删除了及其删除时间等信息。
- 缺点:
- 需要在查询时额外考虑这些“已删除”但仍然存在于表中的记录,可能会导致性能下降。
- 数据库占用的空间不会因为逻辑删除而减少,长期积累可能导致存储问题。
物理删除(Physical Deletion)
- 定义:物理删除是指直接从数据库中永久移除记录。这通常意味着该记录将不再出现在任何查询结果中,并且无法轻易恢复。
- 优点:
- 简化了数据库结构,减少了存储空间。
- 提升查询性能,因为不需要处理那些被标记为已删除但实际上还存在的记录。
- 缺点:
- 一旦执行,很难恢复数据,除非有定期备份。
- 如果存在外键约束或其他依赖关系,物理删除可能会影响到其他相关表的数据一致性。
区别
- 数据保留与否:逻辑删除保留了原始数据,只是改变了其可见性;物理删除则是彻底清除了数据。
- 性能影响:随着逻辑删除记录数量的增长,查询性能可能会受到影响,而物理删除则有助于提高性能。
- 恢复可能性:逻辑删除后可以较容易地恢复数据,而物理删除后的恢复难度较大,依赖于是否有有效的备份策略。
- 存储需求:逻辑删除会持续占用存储空间,而物理删除可以释放这部分空间。
- 应用适用性:对于需要维护历史记录或支持数据恢复的应用场景,逻辑删除更为合适;而对于确保数据安全性和隐私保护的应用,则更倾向于使用物理删除。
选择哪种删除方式取决于具体的应用需求、业务规则以及对数据完整性和性能的要求。在某些情况下,也可以结合两者的优势,例如先进行逻辑删除,在一定周期后再进行物理删除。
8、什么是数据库的逻辑外键?数据库的物理外键和逻辑外键各有什么优缺点? 中等
在数据库设计中,逻辑外键和物理外键是两种不同的实现方式来维护表间的关系。它们各自有特定的应用场景、优点和缺点。
物理外键(Physical Foreign Key)
- 定义:物理外键是指在数据库模式中正式定义的外键约束。它通过数据库管理系统(DBMS)强制实施参照完整性规则。
- 优点:
- 数据一致性:确保了子表中的记录总是引用父表中存在的有效记录,防止孤立记录的存在。
- 自动维护:当父表的数据发生变化时(如更新或删除),DBMS可以根据设定的行为(如级联更新/删除、设置为NULL等)自动处理相关子表的数据。
- 简化开发:减少了应用程序层面对于维护关系完整性的负担,因为这些规则已经在数据库级别得到了保障。
- 缺点:
- 性能影响:由于每次插入、更新或删除操作都需要检查外键约束,这可能会带来一定的性能开销,尤其是在大规模数据集上。
- 灵活性降低:一旦设置了物理外键,修改或移除这种约束可能需要更多的步骤,并且可能会影响到现有应用的功能。
- 锁定问题:在高并发环境下,对外键的检查可能导致行锁或表锁,进而影响系统的响应速度。
逻辑外键(Logical Foreign Key)
- 定义:逻辑外键不是由数据库系统直接管理的一种约定,而是通过应用程序代码或者业务逻辑来模拟外键行为。这意味着并没有实际的外键约束存在于数据库模式中。
- 优点:
- 更高的灵活性:可以更自由地改变数据模型而不必担心破坏现有的外键关系。
- 减少性能损耗:没有额外的约束检查,理论上可以提高某些操作的速度。
- 适用于跨数据库环境:当涉及到多个数据库之间的关联时,逻辑外键可能是唯一可行的选择。
- 缺点:
- 缺乏内置支持:必须依靠应用程序逻辑来保证数据的一致性,增加了出错的风险。
- 复杂度增加:开发者需要自己编写代码来处理所有与外键相关的规则,包括级联更新、删除等操作,增加了开发和维护的工作量。
- 难以追踪错误:如果违反了所谓的“逻辑外键”规则,错误可能不会立即显现出来,直到出现问题后才被发现。
总结
选择使用物理外键还是逻辑外键取决于具体的需求和技术栈:
- 如果强调数据一致性和完整性,并且对性能的影响是可以接受的,那么应该优先考虑使用物理外键。
- 如果追求更高的灵活性和性能,或者是面对复杂的多数据库集成情况,则可以考虑采用逻辑外键的方式,但同时需要注意加强应用程序级别的验证和控制以弥补缺失的数据库级约束。
9、MySQL 事务的二阶段提交是什么? 中等
在MySQL中,尤其是在使用InnoDB存储引擎时,**二阶段提交(Two-Phase Commit, 2PC)**是分布式事务管理中的一个关键机制。它确保了所有参与节点要么都成功提交事务,要么都回滚事务,从而保持数据的一致性。二阶段提交过程分为两个阶段:准备阶段(Prepare Phase)和提交阶段(Commit Phase)。下面是每个阶段的详细说明:
准备阶段(Prepare Phase)
- 协调者发送准备请求:事务协调者向所有参与者发送
PREPARE
命令,询问它们是否准备好提交事务。 - 参与者响应:
- 如果参与者能够成功完成其本地部分的事务处理,并且有信心可以在后续阶段正式提交,则返回“准备就绪”(Prepared)的状态给协调者。
- 如果任何一个参与者无法完成其工作或不确认能否提交,则返回“未准备”(Not Prepared)状态。
在这个阶段,如果所有的参与者都返回了“准备就绪”的状态,那么整个事务就被认为是可以安全提交的;如果有任何一个参与者报告失败,则整个事务会被回滚。
提交阶段(Commit Phase)
根据准备阶段的结果,提交阶段会有两种不同的路径:
成功路径
- 协调者决定提交:当所有参与者都回复了“准备就绪”,协调者会做出最终决策——提交事务。
- 协调者发送提交请求:协调者向所有参与者发送
COMMIT
命令。 - 参与者执行提交:每个参与者接收到
COMMIT
命令后,正式提交自己的本地事务,并向协调者确认已完成提交。 - 协调者记录日志并结束事务:一旦所有参与者都成功提交,协调者将此次操作记录到持久化日志中,并通知所有参与者事务已经成功结束。
失败路径
- 协调者决定回滚:如果有任何一个参与者在准备阶段报告了“未准备”,或者协调者本身遇到了问题,它就会选择回滚事务。
- 协调者发送回滚请求:协调者向所有参与者发送
ROLLBACK
命令。 - 参与者执行回滚:每个参与者接收到
ROLLBACK
命令后,撤销之前所做的任何更改,并向协调者确认已完成回滚。 - 协调者记录日志并结束事务:协调者同样需要记录此次回滚操作的日志,并告知所有参与者事务已终止。
为什么需要二阶段提交?
二阶段提交的主要目的是为了保证分布式系统中多个节点之间的数据一致性。通过这种方式,即使某个节点发生了故障,只要其他节点都能够正常运作,就可以保证事务要么全部提交,要么全部回滚,避免了部分提交导致的数据不一致问题。
然而,二阶段提交也带来了额外的复杂性和性能开销,因为它要求所有参与者都要等待协调者的指示才能继续前进,这可能会成为系统的瓶颈。此外,如果协调者出现故障,整个事务可能会陷入不确定的状态,直到协调者恢复为止。因此,在设计分布式系统时,需要权衡使用二阶段提交所带来的好处与潜在的风险。
对于单个数据库实例内的事务,MySQL/InnoDB并不需要显式的二阶段提交流程,因为它是基于ACID特性的单节点事务管理系统。但在涉及多个数据库实例或跨服务的分布式事务场景下,二阶段提交就是一个必要的机制。
10、MySQL 为什么使用 B+ ?
MySQL的InnoDB存储引擎选择使用B+树(B Plus Tree)作为其索引结构,主要是因为B+树在数据库操作中提供了优秀的性能和特性。以下是B+树相对于其他数据结构的优势,以及它为什么适合用作MySQL索引的原因:
1. 高效的磁盘访问
- 减少I/O次数:B+树设计为能够有效地利用磁盘块(或页),每个节点可以包含多个键值对,并且通常一个节点的大小与磁盘块相匹配。这意味着每次磁盘读写操作都可以获取尽可能多的数据,从而减少了所需的I/O次数。
- 顺序扫描友好:所有叶子节点都通过指针链接在一起,形成了一个双向链表,这使得范围查询(如
SELECT * FROM table WHERE key BETWEEN value1 AND value2
)可以高效地进行顺序扫描。
2. 良好的并发性
- 行级锁支持:由于B+树的所有记录都位于叶子节点上,而内部节点只存储用于导航的键,因此可以在不影响其他部分的情况下对单个记录加锁,提高了并发处理能力。
3. 平衡性保证
- 高度平衡:B+树是一种自平衡的树形结构,无论插入或删除操作如何频繁,树的高度始终保持在一个较低水平,确保了查找、插入和删除等操作的时间复杂度稳定为O(log n)。
4. 空间利用率高
- 紧凑的存储:相比于B树,B+树将所有实际数据项都放在叶子节点中,非叶子节点仅保存用于搜索的键,这样不仅节省了空间,而且有利于提高缓存命中率。
5. 优化了范围查询
- 连续存储:在B+树中,相同范围内的数据会尽量被存储在同一页面内或者相邻页面上,这对于需要遍历一系列连续记录的操作非常有利。
6. 简化维护
- 易于分裂和合并:当节点中的元素过多时,B+树可以通过简单地分裂成两个节点来保持树的平衡;相反地,当节点变得过于稀疏时,也可以轻松地与其他节点合并。这种机制简化了树的维护工作。
综上所述,B+树因其出色的磁盘访问效率、良好的并发性和空间利用率等特点,成为MySQL InnoDB存储引擎理想的索引结构。此外,它还特别适用于OLTP(在线事务处理)系统,这类系统要求快速响应时间、高并发处理能力和高效的数据检索。
11、MySQL 三层 B+ 树能存多少数据? 中等
在MySQL的InnoDB存储引擎中,三层B+树可以存储的数据量取决于多种因素,包括但不限于页大小、主键类型(如INT
或BIGINT
)、行数据的实际大小等。根据已有资料,我们可以得出以下结论:
-
对于主键为
BIGINT
的情况:假设一页大小为16KB,默认情况下,一个非叶子节点可以存放大约1170个“主键+指针”的组合(每个组合占用约14字节)。因此,在这种设定下,三层B+树可以存储大约21,902,400条记录。- 计算公式为:(1170 \times 1170 \times 16 = 21,902,400) 条记录
-
对于主键为
INT
的情况:同样地,如果一页大小为16KB,那么一个非叶子节点可以存放大约1600个“主键+指针”的组合(每个组合占用约10字节)。在这种设定下,三层B+树可以存储大约40,960,000条记录。- 计算公式为:(1600 \times 1600 \times 16 = 40,960,000) 条记录
需要注意的是,上述计算是基于理想化的假设条件,实际环境中可能会因为行格式、填充因子、是否存在额外索引等因素而有所不同。此外,随着数据库版本和技术的发展,这些参数也可能发生变化。因此,在评估具体应用时,建议参考最新的官方文档和实际情况进行测试与验证。
12、MySQL 在设计表(建表)时需要注意什么? 中等
在设计MySQL表(即建表)时,需要考虑多个方面以确保数据库的性能、可维护性和数据完整性。以下是设计MySQL表时应关注的一些关键点:
1. 明确需求和规划
- 业务理解:深入了解业务逻辑和数据模型,确保设计满足实际应用的需求。
- 规模预测:预估未来几年的数据增长趋势,为表结构预留足够的扩展空间。
2. 选择合适的数据类型
- 最小化存储空间:选用最紧凑的数据类型来表示数据,如使用
TINYINT
代替INT
,除非确实需要更大的范围。 - 避免冗余:不要为同一信息定义多个字段,减少不必要的数据重复。
3. 主键设计
- 唯一标识:每个表应该有一个或一组字段作为主键,用来唯一标识每一条记录。
- 自增ID vs UUID:根据应用场景选择合适的主键生成方式,例如
AUTO_INCREMENT
整数型主键适合大多数情况,而UUID则适用于分布式系统或多租户环境。
4. 索引策略
- 创建必要的索引:基于查询模式分析,对频繁出现在
WHERE
子句中的列建立索引,提高查询效率。 - 避免过度索引:过多的索引会增加写入操作的成本,并占用额外的存储空间。
- 覆盖索引:如果某个查询只需要访问索引中包含的列,则可以构建覆盖索引以加快速度。
5. 外键约束
- 参照完整性:合理利用外键约束来维护不同表之间的关系,保证数据的一致性。
- 性能权衡:虽然外键有助于防止孤立记录的存在,但在高并发写入场景下可能会带来性能开销,需谨慎评估是否启用。
6. 分区与分片
- 水平分区(Sharding):对于非常大的表,可以考虑按某种规则将数据分散到多个物理表或服务器上,减轻单个实例的压力。
- 垂直分区(Partitioning):把不常用的列拆分出去形成新的表,优化常用查询路径。
7. 默认值和非空限制
- 设置合理的默认值:对于某些字段,提供有意义的默认值可以帮助简化插入操作。
- 强制非空检查:通过
NOT NULL
约束确保重要字段不会出现空值,从而保护数据质量。
8. 字符集和排序规则
- 统一字符集:选择一个适合你应用的字符集(如UTF-8),并保持整个数据库的一致性。
- 排序规则(Collation):根据语言和地区习惯选择适当的排序规则,影响字符串比较的结果。
9. 触发器和存储过程
- 适度使用:尽管触发器和存储过程可以在一定程度上简化业务逻辑,但它们也可能增加系统的复杂度,应该只在必要时使用。
10. 文档和注释
- 编写清晰的注释:为表结构添加注释,说明各字段的意义及其取值范围,便于后续维护。
- 维护变更日志:记录每一次重要的结构修改,方便追溯历史版本。
11. 安全性和权限管理
- 最小权限原则:按照最小权限原则分配用户权限,确保只有授权人员才能执行特定的操作。
- 敏感数据保护:对于涉及个人隐私或其他敏感信息的字段,采取加密等措施加以保护。
遵循上述指导原则进行表设计,不仅能够提升数据库的整体性能,还能增强其稳定性和安全性。当然,具体的设计还需要结合项目的实际情况灵活调整。
13、MySQL 插入一条 SQL 语句,redo log 记录的是什么? 中等
在MySQL的InnoDB存储引擎中,当执行一条INSERT
语句时,Redo Log(重做日志)记录的是与该插入操作相关的物理级别的变更信息。具体来说,Redo Log会记录以下内容:
1. 页面分配
- 如果插入操作导致需要分配新的数据页(Page),那么Redo Log会记录新页的分配情况。这包括了页号、页类型等元数据。
2. 行记录的变化
- 插入操作会在某个特定的数据页中添加一行新的记录。Redo Log会详细记录这一变化,包括但不限于:
- 行位置:即新增行在页中的偏移量。
- 行内容:完整的行数据,或者至少是那些被修改或增加的字段值。
- 记录头信息:例如事务ID、回滚指针等辅助信息,这些对于MVCC(多版本并发控制)和崩溃恢复非常重要。
3. 索引更新
- 每次插入新行时,除了数据本身外,相关的二级索引也需要更新。因此,Redo Log还会记录所有受影响的索引页上的变更,确保在崩溃恢复期间能够重建正确的索引结构。
4. 其他元数据变更
- 在某些情况下,可能还会涉及到对段(Segment)、区(Extent)或其他高层级存储结构的调整,这些变动同样会被记录到Redo Log中。
Redo Log的作用
Redo Log的主要作用是在系统发生故障后,可以通过重放这些日志条目来恢复未完成的事务,保证数据库的一致性和持久性。换句话说,即使服务器突然断电或崩溃,只要Redo Log完好无损,就可以利用它来恢复到最近的一个一致点。
写入过程
- 当
INSERT
语句被执行时,相应的变更首先写入内存中的缓冲池(Buffer Pool),同时将描述这些变更的日志条目追加到Redo Log Buffer中。 - 然后,根据配置(如
innodb_flush_log_at_trx_commit
参数),定期地或在每次事务提交时,Redo Log Buffer中的内容会被刷写到磁盘上的Redo Log文件。 - 最终,在适当的时机,脏页(Dirty Pages)也会从缓冲池刷新到磁盘上的实际数据文件中。
总之,Redo Log记录的是与INSERT
操作有关的所有物理层面的具体更改,确保即使在最坏的情况下也能准确地恢复数据库状态。这种机制是实现ACID特性的关键组成部分之一,特别是对于持久性和原子性的保障。
14、MySQL 的基本数据类型有哪些?
MySQL提供了多种基本数据类型,用于定义表中列的数据种类。以下是MySQL中常用的基本数据类型分类及其具体类型:
1. 数值类型
-
整数类型:
TINYINT
:非常小的整数,范围为-128到127(有符号)或0到255(无符号)。SMALLINT
:小整数,范围为-32,768到32,767(有符号)或0到65,535(无符号)。MEDIUMINT
:中等大小的整数,范围为-8,388,608到8,388,607(有符号)或0到16,777,215(无符号)。INT
或INTEGER
:标准整数,范围为-2^31 (-2,147,483,648) 到 2^31 - 1 (2,147,483,647)(有符号)或0到2^32 - 1 (4,294,967,295)(无符号)。BIGINT
:大整数,范围为-2^63 (-9,223,372,036,854,775,808) 到 2^63 - 1 (9,223,372,036,854,775,807)(有符号)或0到2^64 - 1 (18,446,744,073,709,551,615)(无符号)。
-
浮点类型:
FLOAT(M,D)
:单精度浮点数,通常占用4个字节。DOUBLE(M,D)
或DOUBLE PRECISION(M,D)
:双精度浮点数,通常占用8个字节。
-
定点类型:
DECIMAL(M,D)
或NUMERIC(M,D)
:定点数,M是总位数,D是小数点后的位数。它确保了精确的小数表示。
2. 字符串类型
-
定长和变长字符串:
CHAR(N)
:固定长度字符串,最大长度为255个字符。VARCHAR(N)
:可变长度字符串,最大长度可达65,535个字符(取决于行中其他列的大小)。
-
文本类型:
TINYTEXT
:最大长度为255个字符的文本。TEXT
:最大长度为65,535个字符的文本。MEDIUMTEXT
:最大长度为16,777,215个字符的文本。LONGTEXT
:最大长度为4,294,967,295个字符的文本。
-
二进制字符串类型:
BINARY(N)
和VARBINARY(N)
:类似于CHAR
和VARCHAR
,但存储的是二进制数据。
-
枚举类型:
ENUM('value1','value2',...)
:允许在列中存储预定义的一组值中的一个。
-
集合类型:
SET('value1','value2',...)
:可以包含多个来自预定义列表的值。
3. 日期和时间类型
DATE
:只存储日期部分,格式为YYYY-MM-DD
。TIME
:只存储时间部分,格式为HH:MM:SS
或扩展的时间值。DATETIME
:同时存储日期和时间,格式为YYYY-MM-DD HH:MM:SS
,支持的范围从1000年到9999年。TIMESTAMP
:也存储日期和时间,但是具有特定的时间戳特性,默认情况下自动记录创建时间和更新时间,并且与系统时区有关联。YEAR
:专门用于存储年份信息,有两种格式:YEAR(2)
(两位数年份)和YEAR(4)
(四位数年份),默认是后者。
4. JSON 类型
JSON
:自MySQL 5.7版本起引入,用于存储有效的JSON文档。
5. 空间数据类型
GEOMETRY
、POINT
、LINESTRING
、POLYGON
、MULTIPOINT
、MULTILINESTRING
、MULTIPOLYGON
、GEOMETRYCOLLECTION
:这些类型用于地理信息系统(GIS)应用,支持各种几何对象的存储。
选择合适的数据类型对于优化存储空间、查询性能以及确保数据完整性至关重要。在设计数据库表结构时,应根据实际需求来决定使用哪种数据类型。
相关文章:
MySQL面试题2025 每日20道【其四】
1、你们生产环境的 MySQL 中使用了什么事务隔离级别?为什么? 中等 在生产环境中,MySQL数据库的事务隔离级别通常由开发团队或数据库管理员根据应用的需求来设定。MySQL支持四种标准的事务隔离级别: 读未提交(Read Unc…...
maven 微服务项目多 包版本问题
mvn dependency:tree查看jar包直接的关系 找到重复的包!!!! 可以查看包版本问题 [INFO] | - org.jpedal:OpenViewerFX:jar:6.6.14:compile [INFO] | | - org.eclipse.birt.runtime.3_7_1:org.mozilla.javascript:jar:1.7.2:compile [INFO] | | - bouncycastle:bcprov-j…...
skipcrossnets模型详解及代码复现
模型背景 在SkipcrossNets模型提出之前,多模态融合在自动驾驶领域已取得显著进展。然而,传统的两流网络仅在特定层进行融合,需要大量人工尝试来设置,并且随着网络深度增加,模态特征差异增大,容易影响性能。 为解决这些问题,研究人员开发了SkipcrossNets模型,旨在提供…...
【0397】Postgres内核 checkpoint process ⑦ 获取 delaying checkpoint VXIDs(delayChkpt)
1. Top-level transactions 顶级事务(Top-level transactions)通过由 PGPROC 字段 backendId 和 lxid 组成的 VirtualTransactionIDs 来标识。对于已准备的事务,LocalTransactionId 是一个普通的 XID。这些在短期内保证唯一,但在数据库重启或 XID 滚转后会被重新使用;因此…...
Go语言-学习一
简介:Go语言经过多年的快速发展,已经被光广泛应用到各个领域,成为当前最热的计算机语言之一。Go自带许多高级特性及常用工具,使Go一出世就以高并发和高性能为程序员所追捧。 go语言特点 1、静态类型、编译型、开源 2、脚本化&…...
学习记录-统计记录场景下的Redis写请求合并优化实践
学习记录-使用Redis合并写请求来优化性能 1.业务背景 学习进度的统计功能:为了更精确的记录用户上一次播放的进度,采用的方案是:前端每隔15秒就发起一次请求,将播放记录写入数据库。但问题是,提交播放记录的业务太复杂了&#x…...
Java中json的一点理解
一、Java中json字符串与json对象 1、json本质 json是一种数据交换格式。 常说的json格式的字符串 > 发送和接收时都只是一个字符串,它遵循json这种格式。 2、前后端交互传输的json是什么? 前后端交互传输的json都是json字符串 比如:…...
用于牙科的多任务视频增强
Multi-task Video Enhancement for Dental Interventions 2022 miccai Abstract 微型照相机牢牢地固定在牙科手机上,这样牙医就可以持续地监测保守牙科手术的进展情况。但视频辅助牙科干预中的视频增强减轻了低光、噪音、模糊和相机握手等降低视觉舒适度的问题。…...
二、vue智能Ai对话(高仿通义千问)流式进阶版
1、安装依赖、启动 // 安装依赖 npm install // 启动服务 node server.js 2、浏览器运行html 3、流式进阶版视频地址:流式进阶版视频 4、各位如有需要,请下载源码包。...
Python新春烟花
目录 系列文章 写在前面 技术需求 完整代码 下载代码 代码分析 1. 程序初始化与显示设置 2. 烟花类 (Firework) 3. 粒子类 (Particle) 4. 痕迹类 (Trail) 5. 烟花更新与显示 6. 主函数 (fire) 7. 游戏循环 8. 总结 注意事项 写在后面 系列文章 序号直达链接爱…...
《自动驾驶与机器人中的SLAM技术》ch4:基于预积分和图优化的 GINS
前言:预积分图优化的结构 1 预积分的图优化顶点 这里使用 《自动驾驶与机器人中的SLAM技术》ch4:预积分学 中提到的散装的形式来实现预积分的顶点部分,所以每个状态被分为位姿()、速度、陀螺零偏、加计零偏四种顶点&am…...
「2024·我的成长之路」:年终反思与展望
文章目录 1. 前言2.创作历程2.1 摆烂期2.2 转变期3. 上升期 2. 个人收获3.经验分享4. 展望未来 1. 前言 2025年1月16日,2024年博客之星入围公布,很荣幸获得了这次入围的机会。2024年对我个人是里程碑的一年,是意义非凡的一年,是充…...
P8738 [蓝桥杯 2020 国 C] 天干地支
两种方法 #include<bits/stdc.h> using namespace std;int main(){int year;cin>>year;string tg[10] {"geng", "xin", "ren", "gui","jia", "yi", "bing", "ding", "wu&…...
Linux网络 TCP socket
TCP简介 TCP(Transmission Control Protocol)是一种面向连接的、可靠的、基于字节流的传输层通信协议。它位于OSI模型的第四层,主要为应用层提供数据传输服务。TCP通过三次握手建立连接,确保数据在发送和接收过程中的准确性和顺序…...
IntelliJ IDEA 2023.3 中配置 Spring Boot 项目的热加载
IntelliJ IDEA 2023.3 中配置 Spring Boot 项目的热加载 在 IntelliJ IDEA 2023.3 中配置 Spring Boot 项目的热加载,可以让你在不重启应用的情况下看到代码修改的效果。以下是详细的配置步骤: 添加 spring-boot-devtools 依赖 在 pom.xml 文件中添加 …...
【网络协议】【http】【https】RSA+AES-TLS1.2
【网络协议】【http】【https】RSAAES-TLS1.2 https并不是一个协议 而是在传输层之间添加了SSL/TLS协议 TLS 协议用于应用层协议(如 HTTP)和传输层(如 TCP)之间,增加了一层安全性来解决 HTTP 存在的问题,H…...
Java中如何安全地停止线程?
大家好,我是锋哥。今天分享关于【Java中如何安全地停止线程?】面试题。希望对大家有帮助; Java中如何安全地停止线程? 1000道 互联网大厂Java工程师 精选面试题-Java资源分享网 在Java中,安全地停止线程是一项重要的任务,尤其…...
01.04、回文排序
01.04、[简单] 回文排序 1、题目描述 给定一个字符串,编写一个函数判定其是否为某个回文串的排列之一。回文串是指正反两个方向都一样的单词或短语。排列是指字母的重新排列。回文串不一定是字典当中的单词。 2、解题思路 回文串的特点: 一个回文串在…...
[深度学习]多层神经网络
多层神经网络 文章目录 多层神经网络单个神经元人类大脑神经与神经元神经元与矩阵神经元的串联激活函数激活函数位置神经网络的三种表现形式神经网络的参数(可训练的) 深度学习的训练过程全连接网络过拟合和欠拟合 单个神经元 一个神经元实际表示的数据公…...
JavaScript语言的正则表达式
JavaScript语言的正则表达式详解 正则表达式(Regular Expression,简称Regex或RegExp)是一种强大的文本处理工具,可以在字符串中执行模式匹配和替换操作。在JavaScript中,正则表达式是处理字符串时不可或缺的部分&…...
yolo系列模型为什么坚持使用CNN网络?
在深度学习领域,目标检测是一项至关重要的任务,而YOLO(You Only Look Once)系列模型无疑是这一领域的佼佼者。YOLO以其高效、准确的特点,在实时目标检测任务中占据了重要地位。然而,随着Transformer模型在自…...
Kotlin语言的数据结构
Kotlin语言的数据结构导论 Kotlin是一种现代化的编程语言,具有简洁、安全和高效的特点。Kotlin不仅支持面向对象编程,还融入了函数式编程的概念,使得开发者能够以更优雅的方式处理数据。在构建复杂应用时,数据结构的选择及其实现…...
光纤接口、GTX高速收发器基础知识学习、光口眼图测试--FPGA学习笔记28
----素材来源原子哥 一、光纤接口简介 光纤接口是用来连接光纤线缆的物理接口,简称为光口。其原理是利用了光从光密介质进入光疏介质从而发生了全反射。通常有 FC、 SC、 ST、 LC、 D4、 DIN、 MU、 MT 等等各种形式接口。 (1) SC 型光纤接…...
【k8s】k8s部署Argo CD
1、创建 Argo CD 命名空间: 先创建一个专用的命名空间 argocd 用于部署 Argo CD。 kubectl create namespace argocd 2、安装 Argo CD: 使用 kubectl 从 Argo CD 官方 GitHub 仓库安装它。运行以下命令来安装所有的 Argo CD 组件: kubectl a…...
PHP礼品兑换系统小程序
🎁 礼品兑换系统:革新企业礼品管理,专属神器来袭! 💻 一款专为追求高效与个性化的现代企业量身打造的礼品兑换系统,它基于强大的ThinkPHP框架与前沿的Uniapp技术栈深度融合,不仅完美适配礼品卡…...
【SSH端口转发:实现安全的远程端口映射】
SSH端口转发:实现安全的远程端口映射 在网络应用开发和运维过程中,我们经常需要进行端口转发来实现各种网络访问需求。今天我要分享一个使用SSH进行端口转发的实用脚本,并详细讲解其工作原理。 脚本内容 免密 ssh-copy-id -p 20080 rootxx…...
2024年第十五届蓝桥杯青少组国赛(c++)真题—快速分解质因数
快速分解质因数 完整题目和在线测评可点击下方链接前往: 快速分解质因数_C_少儿编程题库学习中心-嗨信奥https://www.hixinao.com/tiku/cpp/show-3781.htmlhttps://www.hixinao.com/tiku/cpp/show-3781.html 若如其他赛事真题可自行前往题库中心查找,题…...
为什么你的 Qt 应用程序会出现 xcb 插件错误
有朋友咨询为什么他们的 Qt 应用程序在统信 UOS ARM 版本下运行,提示如下错误: qt.qpa.plugin: Could not find the Qt platform plugin "xcb" in "" This application failed to start because no Qt platform plugin could be i…...
ANSYS HFSS 中的相控天线阵列仿真方法
概述 相控天线阵列系统广泛使用,从国防雷达应用到商业 5G 应用。设计这些天线阵列涉及复杂的数学运算,需要全波仿真。Ansys HFSS 全场 3D 电磁仿真软件可以在合理的时间内以较低的计算成本仿真复杂的相控阵天线系统,同时考虑复杂激励、环境&…...
【记录】Jenkins版本及JDK关系介绍的官网地址
Redhat Jenkins Packages...
66,【6】buuctf web [HarekazeCTF2019]Avatar Uploader 1
进入靶场 习惯性输入admin 还想用桌面上的123.png 发现不行 看看给的源码 <?php // 关闭错误报告,可能会隐藏一些错误信息,在开发阶段可考虑开启(例如 error_reporting(E_ALL)) error_reporting(0); // 引入配置文件&#x…...
MECD+: 视频推理中事件级因果图推理--VLM长视频因果推理
论文链接:https://arxiv.org/pdf/2501.07227v1 1. 摘要及主要贡献点 摘要: 视频因果推理旨在从因果角度对视频内容进行高层次的理解。然而,目前的研究存在局限性,主要表现为以问答范式执行,关注包含孤立事件和基本因…...
pycharm+pyside6+desinger实现查询汉字笔顺GIF动图
一、引言 这学期儿子语文期末考试有一道这样的题目: 这道题答案是B,儿子做错了选了C。我告诉他“车字旁”和“车”的笔顺是不一样的,因为二者有一个笔画是不一样的,“车字旁”下边那笔是“提”,而“车”字是“横”&am…...
拟合算法 (matlab工具箱)
拟合算法: 1线性最小二乘法拟合 使用matlab进行求解 拟合优度:R^2 拟合优度的matlab代码: 2,Matlab工具箱的教学 一些函数: 拟合算法: 插值算法中,得到的多项式f(x)要经过所有样本点。但是如果样本点太多&#…...
联想电脑怎么用u盘装系统_联想电脑用u盘装win10系统教程
联想电脑怎么重装系统?在当今科技发展迅猛的时代,联想电脑已经成为了人们生活中不可或缺的一部分。然而,随着时间的推移,我们可能会遇到一些问题,例如系统崩溃或者需要更换操作系统。这时,使用U盘来重新安装…...
WPF2-在xaml为对象的属性赋值
1. AttributeValue方式 1.1. 简单属性赋值1.2. 对象属性赋值 2. 属性标签的方式给属性赋值3. 标签扩展 (Markup Extensions) 3.1. StaticResource3.2. Binding 3.2.1. 普通 Binding3.2.2. ElementName Binding3.2.3. RelativeSource Binding3.2.4. StaticResource Binding (带参…...
什么是报文的大端和小端,有没有什么记忆口诀?
在计算机科学中,**大端(Big-Endian)和小端(Little-Endian)**是两种不同的字节序(即多字节数据在内存中的存储顺序)。理解这两种字节序对于网络通信、文件格式解析以及跨平台编程等非常重要。 1…...
【2024 博客之星评选】请继续保持Passion
我尝试复盘自己2024年走的路,希望能给诸君一些借鉴。 文章目录 回头望感想与收获成长与教训今年计划感恩一些体己话 回头望 回望我的2024年,年初拿高绩效,但感觉逐渐被公司一点点剥离出中心;年中一直在学习防患于未然;…...
网络通信---MCU移植LWIP
使用的MCU型号为STM32F429IGT6,PHY为LAN7820A 目标是通过MCU的ETH给LWIP提供输入输出从而实现基本的Ping应答 OK废话不多说我们直接开始 下载源码 LWIP包源码:lwip源码 -在这里下载 ST官方支持的ETH包:ST-ETH支持包 这里下载 创建工程 …...
Redis源码-redisObject
解释 redis中,所有的数据类型最终都转换成了redisObject,该结构体的定义,在文件server.h中。 参数说明 参数名说明unsigned type:4对象对应的数据类型unsigned encoding:4对象的编码方式unsigned lru:LRU_BITSLRU算法清空对象,…...
YOLOv10-1.1部分代码阅读笔记-tuner.py
tuner.py ultralytics\engine\tuner.py 目录 tuner.py 1.所需的库和模块 2.class Tuner: 1.所需的库和模块 # Ultralytics YOLO 🚀, AGPL-3.0 license# 此模块提供用于对象检测、实例分割、图像分类、姿势估计和多对象跟踪的 Ultralytics YOLO 模型的超参数调…...
【数据结构】二分查找
🚩 WRITE IN FRONT 🚩 🔎 介绍:"謓泽"正在路上朝着"攻城狮"方向"前进四" 🔎🏅 荣誉:2021|2022年度博客之星物联网与嵌入式开发TOP5|TOP4、2021|2222年获评…...
iOS-支付相关
支付宝支付 #import <AlipaySDK/AlipaySDK.h> //orderStrAliPay为服务端传的订单信息 //fromScheme为应用配置的schemeUrl标识,用户支付包支付成功后跳转会本应用内 //callback回调需要在- (BOOL)application:(UIApplication *)app openURL:(NSURL *)url 中调…...
ubuntu16.04 VSCode下cmake+clang+lldb调试c++
VSCode下cmakeclanglldb调试c Ubuntu16.04 安装OpenCV4.5.4 文章目录 VSCode下cmakeclanglldb调试c1.安装clangclangdcmake2、打开VSCode,安装扩展插件3、编译4、Debug4.1 创建launch.json。4.2 配置setting.json 5. vscode安装配置clang-format插件5.1 Linux系统安…...
学Python的人…
学Python的人… 一、Python能干什么? 1.爬虫:前几年,深度学习还没发展起来的时候,书店里Python就和爬虫挂钩,因为Python写爬虫确实方便。 2.数据分析:Python有各种的数据分析库可以方便使用࿰…...
GDB相比IDE有什么优点
GDB(GNU Debugger)相比于集成开发环境(IDE)具有一些独特的优点,主要体现在其灵活性、可定制性和低级控制能力。具体来说,GDB有以下几个优点: 1. 轻量级且无依赖 GDB是一个命令行工具,不依赖于任何复杂的图形界面或大型库,这使得它非常适合在资源受限的环境中使用,比…...
Docker 镜像加速的配置
解决拉取镜像报错:Error response from daemon: Get "https://registry-1.docker.io/v2/": net/http: request canceled while 在使用 Docker 过程中,拉取镜像的速度常常会受到网络状况的影响,尤其是在国内网络环境下,…...
分布式多卡训练(DDP)踩坑
多卡训练最近在跑yolov10版本的RT-DETR,用来进行目标检测。 单卡训练语句(正常运行): python main.py多卡训练语句: 需要通过torch.distributed.launch来启动,一般是单节点,其中CUDA_VISIBLE…...
MFC程序设计(一)MFC入门
本MFC教程使用VS2022实现 MFC基本概念 微软基础类库(英语:Microsoft Foundation Classes,简称MFC)是一个微软公司提供的类库(class libraries),以C类的形式封装了Windows API,并且…...
swift Actor并发处理
preconcurrency 使用 /*在 Swift 5.5 引入并发模型后,编译器会对潜在的数据竞争和不安全的并发代码发出警告或错误。然而,某些旧代码或第三方库可能尚未完全适配这些新规则。preconcurrency 提供了一种临时解决方案,允许你在不修改代码的情况…...