MVCC 技术是什么?

  • MVCC 技术是什么?MVCC 是多版本控制技术,mysql 的每一行都有一些隐藏字段记录了这一行的 meta 信息。DB_TRX_ID,修改该行的最后一个事务的 ID。DB_POLL_PTR,指向当前行的 undo log 日志。DB_ROW_ID:行标识。DELETE_BIT:删除标志,表示这一行是否被删除。
    数据表中的每条记录,除了我们自定义的字段外,还有数据库隐式定义的 DB_TRX_ID, DB_ROLL_PTR, DB_RAW_ID 等 3 个字段。
  • DB_TRX_ID:最近修改(更新、插入)事务 ID:记录创建这条记录/最后一次修改该记录的事务 ID

  • DB_ROLL_PTR:回滚指针,配合 undo 日志,指向这条记录的上一个版本

  • DB_RAW_ID:隐藏主键(自增 id),如果数据表没有主键,则 InnoDB 会自动以 DB_ROW_ID 产生一个聚簇索引

OLTP 与 OLAP 的介绍

数据处理大致可以分成两大类:联机事务处理 OLTP(on-line transaction processing)、联机分析处理 OLAP(On-Line Analytical Processing)。OLTP 是传统的关系型数据库的主要应用,主要是基本的、日常的事务处理,例如银行交易。OLAP 是数据仓库系统的主要应用,支持复杂的分析操作,侧重决策支持,并且提供直观易懂的查询结果。

  • OLTP 系统强调数据库内存效率,强调内存各种指标的命令率,强调绑定变量、并发操作;
  • OLAP 系统则强调数据分析,强调 SQL 执行时长,强调磁盘 I/O、分区等。

LOTP:MySQL,传统后端。 OLAP:HBase,大数据,推荐、广告。

数据库查询时 join 的几种方式

  • inner join:左右取交集
  • left join:以左边为准
  • right join: 以右边为准
  • outter join:左右取并集

默认是 inner join

冷热分离

冷数据和热数据区分对待,热数据使用缓存。

如何提升SQL执行效率?

  1. 加索引,避免使用导致索引失效的语法,例如like、函数等

  2. 减少查询的数据列

  3. 使用explain分析优化SQL结构,避免全表扫描和子查询等。

  4. 分库分表

  5. 读写分离

select中的where两个范围查询,且两个范围查询都有索引,底层实现是如何查询的?

方式一:先用第一个范围查询,然后for循环结果应用第二个条件。

方式二:同时使用两个查询得到两个id列表,执行merge操作,得到一个新的id列表。

SQL数据类型

整型

TINYINT, SMALLINT, MEDIUMINT, INT, BIGINT 分别使用 8, 16, 24, 32, 64 位存储空间,一般情况下越小的列越好。

INT(11) 中的数字只是规定了交互工具显示字符的个数,对于存储和计算来说是没有意义的。

浮点数

FLOAT 和 DOUBLE 为浮点类型,DECIMAL 为高精度小数类型。CPU 原生支持浮点运算,但是不支持 DECIMAl 类型的计算,因此 DECIMAL 的计算比浮点类型需要更高的代价。

FLOAT、DOUBLE 和 DECIMAL 都可以指定列宽,例如 DECIMAL(18, 9) 表示总共 18 位,取 9 位存储小数部分,剩下 9 位存储整数部分。

字符串

主要有 CHAR 和 VARCHAR 两种类型,一种是定长的,一种是变长的。

VARCHAR 这种变长类型能够节省空间,因为只需要存储必要的内容。但是在执行 UPDATE 时可能会使行变得比原来长,当超出一个页所能容纳的大小时,就要执行额外的操作。MyISAM 会将行拆成不同的片段存储,而 InnoDB 则需要分裂页来使行放进页内。

在进行存储和检索时,会保留 VARCHAR 末尾的空格,而会删除 CHAR 末尾的空格。

时间和日期

MySQL 提供了两种相似的日期时间类型:DATETIME 和 TIMESTAMP。

1. DATETIME

能够保存从 1000 年到 9999 年的日期和时间,精度为秒,使用 8 字节的存储空间。

它与时区无关。

默认情况下,MySQL 以一种可排序的、无歧义的格式显示 DATETIME 值,例如“2008-01-16 22:37:08”,这是 ANSI 标准定义的日期和时间表示方法。

2. TIMESTAMP

和 UNIX 时间戳相同,保存从 1970 年 1 月 1 日午夜(格林威治时间)以来的秒数,使用 4 个字节,只能表示从 1970 年到 2038 年。

它和时区有关,也就是说一个时间戳在不同的时区所代表的具体时间是不同的。

MySQL 提供了 FROM_UNIXTIME() 函数把 UNIX 时间戳转换为日期,并提供了 UNIX_TIMESTAMP() 函数把日期转换为 UNIX 时间戳。

默认情况下,如果插入时没有指定 TIMESTAMP 列的值,会将这个值设置为当前时间。

应该尽量使用 TIMESTAMP,因为它比 DATETIME 空间效率更高。