面试题
- 并发事务带来了那些问题
- 脏读:当一个事务正在访问数据并且对数据进行了修改,而这种修改还没有提交到数据库中,这是另外一个事务也访问了这个数据,然后使用了这个数据。因为这个数据还没有提交,那么另外以恶搞事务读取到这个数据是脏数据,依据脏数据所做的操作可能是不正确的
- 丢失修改:指在一个事务读取一个数据的时候,另外一个事务也访问了该数据,那么在第一个事务中修改了这个数据,第二个事务也修改了这个书,这样第一个事务内的修改结果就被丢失,因此称之为丢失修改
- 不可重复读:指在一个事务内多次读取一个数据,这个事务还没有结束的时候,另外一个事务也访问该数据。那么在第一个事务中的两次读取之间由于第二个事务的修改导致第一个事务两次读取的数据可能不太一样。
- 幻读:欢度于不可重复读取类似。他法伤在一个事务读取了几行数据,接着另外一个事务插入了一些数据,在随后的查询中,第一个事务就会发现多了一些原本不存在的记录,就好像发生了幻觉一样,所以称之为幻读
- 为了解决这些问题,数据库管理系统通常实现了各种并发控制机制,如锁定(包括乐观锁悲观锁)时间戳,多版本并发控制等,以实现acid的属性,确保数据库操作的正确性和一致性
- Mysql的默认隔离级别是什么
- MySQL的默认事务隔离级别是可重复读,在这个隔离级别下,事务可以看到自己所作的修改,即使这些修改还没有提交;同时,事务不会看到其他事务所做的未提交的修改。这个级别防止了脏读和不可重复读,单在标准的sql规范中,他不保证防止幻读。然而,mysql的innodb存储引起使用多版本并发控制机制来实现可重读隔离级别,通过这种机制,他能够防止幻读的发生,提供了比标准sql会犯更强的隔离保证。
- mysql中有哪几种锁
- 对数据操作的粒度分
- 表锁:操作时会锁定整个表
- 行锁:操作行时会锁定整行
- 页面锁:会锁定一部分数据(InnoDB不支持)
- 从对数据操作的类型分
- 读锁(共享锁):针对同一份数据,多个读操作可以同时进行而不会相互影响
- 写锁(排他锁):当前操作没有完成之前,他会阻断其他写锁和读锁
- 对数据操作的粒度分
- 将一下MySQL的for update锁
- 在MySQL中,for update 锁是一种行级别的锁,他在使用insert … for updare 语句时进行查询和使用。当一个事务在一个或多个行上执行这样的查询时,他会尝试对这些行加上排他锁。如果锁成功,该事务将对这些行拥有排他访问全,知道事务结束。这意味着,任何其他尝试读取或者修改这些行的事务都必须等待,知道拥有排他锁的事务完成。
- MySQL什么是分库什么是分表
- 在数据库管理和优化中,分库和分表是两种常见的数据分布策略,用于处理大规模数据和高并发的访问的挑战
- 分库
- 分库是指将数据分布在多个数据库中。每个数据库可以部署在不同的服务器上,这样可以分散单一数据库的压力,提高系统的并发处理能力和数据吞吐率。分库策略常常根据业务逻辑或者数据的访问模式来设计,以确保数据分布的合理性和高效的数据访问。
- 例如一个电子商务应用可能根据地理位置将用户数据分布在不同的数据库中,每个地区的用户信息和交易数据存储在相应的地区的数据库服务器上,从而提高数据访问苏苏和减少跨区域数据传输的延迟
- 分表
- 分表是将一个数据中的数据分布在多个表中。这些表具有相同的结构,但存储不同的数据记录。分表可以是水平分表和垂直分表
- 水平分表:按照某一列的值将数据分散存储在多个表中。每个表存储一部分行,但包含完整的列。这样做可以提高查询性能,特别是当表中的数据量非常大的时候
- 垂直分表:将一个表的列分成多个表,每个表存储原表的一部分列。这种方式适合于有些列被频繁访问而其他列访问较少的请开个,通过垂直分表,可以将频繁访问的列集中在一起优化这部分数据的访问性能
- 分库分表的挑战
- 数据的一致性:确保数据一致性变得更负责,特别是在分布式事务的场景下
- 跨库或者跨表的查询,执行设计多个库或者表的联合查询变的困难,可能需要额外的工具或者中渐渐暗支持
- 数据库迁移和扩展:随着数据量的增加,原有的分库分表哦策略可能需要调整,数据迁移和重新分配可能会变的非常复杂
- 应用场景
- 分库适用于大规模的系统,特别是当单个数据库的负载已经达到瓶颈,或者需要地理分布式部署以提高访问的速度和可靠性
- 分表,适用于表数据量极大,单表操作的性能下降的情况,通过分表可以有效的提高查询和更新性能
- 数据库的字段为什么要求定义not null
- 将数据库字段定义为not null 有几个重要的原因,这些原因谁寄到数据的完整性,性能优化,以及避免逻辑错误等方面
- 数据的完整性:确保关键数据的存在:在数据库设计中,某些字段是业务逻辑的关键部分,录入用户的邮箱地址,用户名和密码。这些字段对于每条记录来说都是必须的。通过将这些字段设置为not null 可以确保在加入或者更新数据的时候,这些关键信息不会被遗漏
- 避免逻辑错误
- 简化应用逻辑:允许字段存储null值可能会使应用程序变的更加复杂。开发这需要编写额外的代码来检查null值,并决定如何处理这些情况。将字段定位为not null科技减少这种复杂性,因为应用程序可以预取所有字段都是有效的值
- 提高数据的一致性:在某些情况下,null值可以代表多种含义,例如一个日期字段为null可能标识日期位置,不适用或者尚未设置。这种不明确行可能会导致数据解释上的困难和逻辑错误。
- 性能优化
- 存储优化,在某些数据库系统中,not null 字段可以更有效的存储,因为数据库系统不需要额外的空间来存储每个字段的null状态。这可以在某种程度上提高查询性能,尤其是在处理大量数据的收
- 索引优化:对于定义为not null 的字段,数据库可以更有效的创建和使用索引。在某些数据库中,null值在索引中需要特殊处理,这可能会印象索引的效率和性能
- 提高查询准确性,在使用 count,sum等觉和函数的时候,null值通常被排除在计算之外。如果字段定义为not null 就可以确保这些聚合函数返回准确和预期结果,因为所有的记录都会参与
- MySQL中delete truncate和drop的区别
- delete
- 用途:delete用于删除表中的一行或者多行记录,且可以带有where自居来指定要删除的记录
- 事务:delete操作是可以进行回滚的
- 性能:相对较慢,因为他是逐行删除记录,且会触发表中的触发器
- 日志:delete会记录日志,因为可以恢复数据
- 空间释放:不会立即释放表空间,删除的空间可能会被i数据库稍后重用
- TRYBCATE
- 用途:truncate用于删除表中的所有记录,但不删除表本身。这个命令不能带有where自居
- 事务:在某些数据库系统中,truncate是可以回滚的
- 性能:通常比delete快,因为他不是逐行删除的,而是通过是发放数据也来删除所有的记录,并且不触发触发器
- 日志:truncate通常记录较少的日志信息,因此在大多数情况下不能恢复数据
- 空间释放:释放表空间给数据库系统,以便于重新使用
- DROP
- 用途:drop用于删除整个表,包括表中所有的记录,表结构,索引等
- 事务:在大多数数据库中,drop可以回滚
- 性能:因为是删除整个表,所以相对于delete和truncate来说性能不是主要的考虑点
- 日志:根据数据的具体实现,drop表的操作可能会记录到日志中,但由于表被完全一处,所以恢复数据只能依赖于备份
- 空间释放:释放于表相关联的所有空间
- delete
- 数据库连接池的作用
- 数据库连接池在应用程序和数据库之间发挥着重要的中介作用,其主要目的是提高数据操作的效率和性能。数据库连接是一种昂贵的资源,不仅因为建立和关闭连接本身就消耗资源,还因为每个连接都占用内存和数据服务器上的其他资源
- 减少连接开销:创建和销毁数据库连接需要时间和系统资源。连接池通过重用现有的连接来减少这种开销。当一个应用程序需要访问数据库的时候,他从池中取出一个以及建立的连接,用完后在归还给池,而不是每次都新建和销毁连接 。
- 提高相应速度:由于连接已经预先创建,应用程序从连接池中获取连接的时间远远少于创建新连接的使劲按。这可以显著的提高应用程序的相应速度
- 管理数据库连接数:数据库连接 池可以有效的管理应用程序的并发连接数。他限制了同时打开的连接数,避免了数据库服务器因为同时处理过多连接而过载
- 提高可扩展性:连接池使得应用程序能够使用不同的用户数量和请求量,因为他可以根据需求和配置动态的管理连接。这增强了应用程序处理高负载的能力
- 简化编程模型:开发人员不需要手动管理每个数据库连接的生命周期,因为连接吃提供了标准的方法来获取和返回连接。这降低了编程的复杂性并减少了错误
- 修复连接:连接池允许多个客户端共享一个稳定的连接集,从而就按少了总的连接数量。这种复用可以提高资源利用率和系统整体性能
- 负载平衡:通过分散请求来提高性能和可靠性
- mysql中char和varchar的区别
- 存储方式:
- char:是一种固定长度的类型。当存储在char字段中的字符串长度小于该字段的定义的长度的时候,MySQL会在其后面填充空格以达到指定长度。检索式,这些空格会被移除
- varchar:是一种可变长度类型。他只存储字符串本身的字符,并在字符串前添加一个长度前缀来表示字符串的实际长度
- 性能
- char:类型由于其固定长度的特性,在某些特定场景下(数据经常被修改的情况下)可能比varchar更高效,因为不会导致碎片或者需要额外的空间来存储长度
- varchar :在存包处长度可变的字符串是更加节省使时间。对于长度差异较大字符串,varchar通常是更好的选择
- 空间使用
- char: 字段总是使用相同的存储空间,不论存储的字符串的长度如何,例如:char(10)类型的字段,无论实际存储了多少字符,都会占用10个字符的空间。
- varchar:字段的空间使用取决于实际存储的字符串加上一个长度前缀。长度前缀通常是1字节或者2字节
- 适用场景
- char:char适合存储长度几乎固定的数据,如某些代码,短字符串或者MD5哈希值
- varchar:适合存储长度可变的,如名称,描述或者其他可能变化长度的字符串
- 字符串和字节数:
- varchar和char长度定义了字符的最大数据而不是字节
- 存储方式:
- 说一下MySQL的行锁,表锁,共享锁,排他锁
- 行锁:
- 行锁是在最细的级别上对数据行进行锁定,即一次之锁定一行记录
- 他允许不同的事务并发的访问表中的不同行,从而大大增加了多用户环境下数据库的并发能力
- 行锁的主要缺点是实现起来比表锁复杂,可能导致死锁。
- 表锁:
- 表锁是涉及到对整个表的锁定
- 他简单且开销小,但并发性能较差,因为当一个事务锁定了表后,其他事务就不能对这个表执行写操作。
- 共享锁-读锁:
- 共享锁允许一个事务去读一行数据,并允许其他事务同时读这行数据,但不允许写这行数据。
- 排他锁-写锁
- 排他锁允许事务读取并写入一行数据,并阻止其它事务读取或者修改这行数据
- 这种锁适用于只允许一个事务进行写入,而不允许其他事务同时进行读取或者写入的场景