跳转至

MySQL

(4)数据库三范式

数据库三范式包括:原子性、消除部分依赖(唯一性)、消除传递依赖(独立性)

  1. 第一范式(1NF):原子性。要求表中的每个字段都是不可分割的最小数据单位,即字段值必须是原子的
  2. "联系方式" 字段包含了两个完全不同的信息:电话号码地址(或者 邮箱地址)。这违反了原子性,因为一个字段混合了多个属性。正确的做法是拆分为多个字段精确描述
  3. 第二范式(2NF):唯一性。第二范式建立在第一范式的基础上,要求表中的所有非主键字段完全依赖于主键整体
  4. (订单明细表): 假设主键是 订单ID + 产品ID,"数量" 是完全依赖于整个主键的,"产品名称" 和 "单价" 只依赖于 "产品ID",而不依赖于 "订单ID".带来的后果是 数据冗余(同一个产品的名称和单价在多个订单记录中重复)、更新异常(如果鼠标价格变成 160,需要更新所有包含鼠标的订单记录)、删除异常(如果删除了最后一个包含 P200 键盘的订单记录,该键盘的产品信息也会丢失).正确的做法是拆分为多表,然后使用外键依赖关联.
  5. 第三范式(3NF):独立性。第三范式要求,一个表中的非主键字段不仅要完全依赖于主键,而且还不能依赖于其他非主键字段,这是为了消除传递依赖
  6. 确保表中 所有非主键列 都必须直接、完全依赖于主键,不能存在非主键列(B)依赖于另一个非主键列(C)的情况(即 主键 -> C, C -> B,导致 主键 -> B 是通过 C 传递完成的)
    1. "部门电话" 依赖于 "部门名称",而 "部门名称" 依赖于主键 "员工ID"。这形成了一个传递依赖:员工ID -> 部门名称 -> 部门电话。容易造成数据冗余,更新异常

(8)介绍一下MySQL索引、索引底层结构以及索引有哪些类型?mysql的底层,b+树b树区别,b树用在哪里比较适合,为什么mysql用b+树不用b树

索引分为普通索引、唯一索引、主键索引、组合索引和全文索引

在数据库中,B+树的高度一般为24层,同时Innodb存储引擎在设计的时候会将根节点常驻在内存中,也就是说,在查找的时候**最多只需要13次I/O操作、**

mysql常见的索引存储结构有二叉树、红黑树、哈希表、B树和B+树

mysql的默认存储引擎Innodb就是用B+树实现索引结构的

  • B+树就是在B树基础上的一种优化
  • B树中每个节点不仅包含数据的key值,还有 data 值,而每一页的存储空间是有限的(16KB),如果data数据较大时,将会导致一页能存储的节点较少,这样会导致B树的深度较大,因此会增大查询的磁盘I/O次数, 影响查询效率
  • 在B+树中,所有数据记录都是按照键值大小顺序存放在叶子节点上, 而非叶子节点只存储键值信息,这样可以加大每页存储的节点数量,降低B+树的高度, 减少磁盘IO。

?(3)MySQL查询数据怎么优化?

MySQL 中索引失效的原因

  1. 查询条件中使用函数或表达式:如果对索引列使用函数或表达式,索引可能无法被使用。例如 SELECT * FROM table_name WHERE UPPER(column_name) = 'VALUE'; ,此时应该尽量避免在索引列上使用函数,改为 SELECT * FROM table_name WHERE column_name = 'value';
  2. 类型不匹配:当查询条件中的数据类型和索引列的数据类型不一致时,索引可能失效。如索引列是 int 类型,查询时传入字符串类型数据,并且没有进行正确的类型转换。
  3. 使用 LIKE** 以通配符开头**:当 LIKE 条件以通配符 % 开头时,如 SELECT * FROM table_name WHERE column_name LIKE '%value'; ,索引无法有效利用,因为这种情况下MySQL需要扫描全表。改为 SELECT * FROM table_name WHERE column_name LIKE 'value%'; 则可能使用索引。
  4. 使用 OR** 连接条件**:如果 OR 连接的条件中有一个列没有索引,那么整个查询可能不会使用索引。例如 SELECT * FROM table_name WHERE column1 = 'value1' OR column2 = 'value2'; ,若 column2 没有索引,MySQL可能会放弃使用索引进行全表扫描。
  5. 数据分布不均匀:当索引列的数据分布非常不均匀时,MySQL优化器可能会认为使用索引效率不高,而选择全表扫描。比如某列大部分值都是同一个,只有少数几个不同值的情况。
  6. 索引列参与了运算:若在查询条件中对索引列进行了算术运算,如 SELECT * FROM table_name WHERE column_name + 1 = 5; ,索引无法正常使用。
  7. 覆盖索引被破坏:如果查询中所需要的列没有被索引覆盖,即需要回表查询数据,并且查询的列较多时,MySQL可能会放弃使用索引而进行全表扫描。
  8. 索引被重建或更新不及时:在大量数据插入、更新或删除后,索引可能变得碎片化或统计信息不准确,导致MySQL优化器做出错误的执行计划,索引失效。此时可以考虑重建索引或更新索引统计信息。

开窗函数有哪些?以及他们的区别,比如row_number,rank等

有两类:一类是聚合开窗函数,一类是排序开窗函数

  • 聚合开窗函数:SQL 标准允许将所有聚合函数用作开窗函数,用 OVER 关键字区分开窗函数和聚合函数。
  • 排序开窗函数:rownumber() over()、rank() over()、denserank() over()

为什么不用跳表

平常怎么设计数据库表

(6)数据库事务acid

一个事务是由一条或者多条sql语句组成的不可分割的单元,要么全部执行成功,要么全部执行失败。

事务有四个基本特性,分别是原子性,一致性,隔离性,持久性,也被称作“ACID”

  1. 原子性是说一个事务中的所有操作要么全部完成,要么全部不完成,一个事务是一个整体(原子)
  2. 一致性是说一个事务执行之前和执行之后都必须处于一致性状态(数据整体保持一致,增减平衡)
  3. 隔离性的意思是同一时间,只允许一个事务请求同一数据,事务间互不干扰
  4. 持久性则是指一个事务一旦被提交了,那么对数据库中的数据的改变就是永久性的。

(6)数据库事务并发会引发哪些问题

主要会有四个问题,分别是脏读、不可重复读、幻读、丢失更改

○ 脏读就是一个事务读取到了另外一个事务未提交的数据(A事务读取B事务尚 未提交的数据并在此基础上操作,而B事务执行回滚,那么A读取到的数据就是 脏数据)

○ 不可重复读就是一个事务两次执行同一条查询语句,读取到的结果不一致,可 能因为另外一个事务更新了数据 ○ 幻读就是一个事务两次执行同一条查询语句,莫名多出了一些之前不存在的数 据,或莫名少了一些原先存在的数据,可能因为另外一个事务新增或者删除了数据 ○ 丢失修改就是两个事务都对同一记录进行修改操作,结果后修改的记录将会覆 盖前面修改的记录,因此前面的修改就丢失掉了

(6)事务的四个隔离级别有哪些

InnoDB 的默认事务隔离级别是可重复读 • read uncommitted(读未提交):一个事务可以读取另外一个事务未提交的数据,隔 离级别最低。 • read committed(读提交):一个事务只能读取另外一个事务提交的数据。 • repeatable read(可重复读):一个事务多次读取同一条记录,返回的结果是一致的 (即使有其他事务对该条记录进行了修改)。 • serializable(序列化):要求事务序列化执行,也就是只能一个接着一个地执行, 隔离级别最高。

※MVCC 讲一下(怎么实现)

• MVCC多版本并发控制,就是同一条记录在系统中存在多个版本。其存在目的是在 保证数据一致性的前提下提供一种高并发的访问性能。对数据读写在不加读写锁的情况 下实现互不干扰,从而实现数据库的隔离性,在事务隔离级别为读提交和可重复读中使 用到 • MVCC通过维持一个数据的多个版本,在不加锁的情况下,使读写操作没有冲突。 主要由三个隐式字段(事务ID,回滚指针,聚集索引ID)、undo log(存放了数据修改 之前的快照)和read view(存放开始了还未提交的事务)去实现。在InnoDB中,事务 在开始前会向事务系统申请一个事务ID,同时每行数据具有多个版本,我们每次更新 数据都会生成新的数据版本,而不会直接覆盖旧的数据版本。每行数据中包含多个隐式 字段,其中实现MVCC的主要涉及最近更改该行数据的事务ID和可以找到历史数据版

本的指针。InnoDB在每个事务开启瞬间会为其构造一个记录当前已经开启但未提交的 事务ID的readview视图数组。通过比较链表中的事务ID与该行数据的值对应的 DBTRXID,并通过回滚指针找到历史数据的值以及对应的DBTRXID来决定当前 版本的数据是否应该被当前事务所见。最终实现在不加锁的情况下保证数据的一致性。

事务操作,怎么加锁?

※※MySQL存储引擎和隔离级别,以及如何实现这样的隔离级别,能解决什么样的问题

SQL优化

Mysql索引,什么时候回表?

在MySQL中,当使用索引查询时,如果查询条件或返回的数据列无法完全由索引覆盖,则需要通过索引定位到对应的数据行,这个过程称为"回表”。具体来说,以下几种情况会发生回表;

1.非覆盖索引查询:当查询的列不全部在紫引中时,例如,索引是建立在列A上的,但查询语句需要返回列B的值,此时需要通过索引找到对应的主键值,再根据主键值去主键索引(聚索引)中查找完整的数据行。2.使用素引进行范围查询:当使用索引进行范围查询(如WHEREcoumn>x)时,索引扫描会返回一系列符合条件的主键值,这些主键值可能需要回表去获取完整的数据行。

3.索引列不唯一:如果索引列不唯一,且查询条件不能唯一确定一条记录,也需要回表获取完整数据行。

总结来说,当索引无法覆盖查询所需的所有列,或者查询条件需要访问的数据量较大时,会发生回表操作。

※Update主键索引、辅助索引、联合索引,数据都是怎么变的?

当执行UPDATE语句时,涉及到的索引变化如下:

1.主键索引(聚族索引):

如果UPDATE语句修改了主键列的值,那么原来的素引记录会被制除,新的记录会被插入到新的位置,因为主键索引决定了数据行的物理存储位置。

。如果修改其他列的值,索引记录本身不会改变位置,但索引记录中对应的数据列会更新。2.辅助索引(非聚簇索引):

如果修改的列是辅助索引的一部分,那么该索引记录会被更新,可能涉及索引记录的移动或重新排序,取决于索引列的值变化是否导致索引顺序改变。

如果修改的是其他列,辅助索引本身不会变化,但对应的指向主键的记录可能需要更新(因为主键可能变化导致指向主键的指针需要更新)。3.联合素引:

如果修改的列是联合索引的一部分,索引记录会根据联合索引的规则进行更新,可能涉及索引记录的移动或重新排序。

如果修改的是其他列,联合索引本身不会变化,但对应的指向主键的记录可能需要更新。总结来说,UPDATE操作会更新所有相关的案引记录,确保引与数据表的一致性。主键素引的更新可能影响数据行的物理位置,而辅助索引和联合索引的更新主要涉及索引记录的更新和可能的位置调整。

※说下undolog,是不是只有rollback才会触发undolog?

Undo Log(回滚日志)是数据库中用于记录事务修改前的数据状态的日志,主要用于事务的回滚和一致性读(MVCC)。以下是关于Undo Log的几点说明:

1.作用:

。事务回滚:当事务执行过程中需要回滚时,可以通过UndoLog将数据恢复到修改前的状态。

。一致性读:在多版本并发控制(MVCC)中,读事务可以通过UndoLog读取数据的历史版本,避免速到未交的数据,确保数据的一致性。

2.触发条件:

RollbacK操作:星式的ROLLBACK语句会触发UndoLog的使用,将事务修改的数据回浪到之前的状态。事务提交失败:当事务由于某种原因(如系统崩溃、事务冲突等)无法正常提交时,系统会自动利用UndoLog进行回滚。

。一致性读:在快照读(如READCOMMITTED隔离级别)中,读事务可需要通过UndoLog获取数据的历史版本。即使没有显式的ROLLBACK操作。

因此,不是只有ROLLBACK操作才会触发UndoLog的使用。只要事务惨改了效据,系统就会生成对应的UndoLog记录用于支持事务的回滚和一致性读。

※※binlog 日志是 master 推的还是 salve 来拉的?

在MySQL的主从复制中,binog(二进制日志)的传输是由master主动推送的,但具体的传输过程是由slave来拉取的。以下是详细解释:

1.Master的角色:

。Master服务器在事务提交后,会将二进制日志(binlog)写入磁盘。当有slave连接到master并请求复制时,master会启动一个binlogdump线程,负费将binlog中的内容发送给

slave.

2.slave的角色:

Slave服务器启动一个I/O线程,连接到master并请求复制binlog。

1/0线程从master接收bin0g,并将其写入到本地的中继日志(relaylog)中。

Slave上的SQL线程读取中继日志,并在本地执行相应的SQL语句,从而实现数据的同步。

因此,binlog的传输过程可以描述为:master在slave请求时主动推送binl0g内容,而slave则通过I/O线程主动从master拉取binlog井写入中继日志,最终由SQL线程执行同步。这种机制确保了数据复制的实时性和一致性。

评论