MySQL5.7

1 基本信息

1.4 新特性

  • SQL mode changes. 默认会设置为STRICT_TRANS_TABLES,NO_ENGINE_SUBSTITUTION删除了几个,其中NO_ENGINE_SUBSTITUTION表示若是新建表的引擎不存在,则提示报错 ,若是不设置NO_ENGINE_SUBSTITUTION,指定表的引擎不存在时默认使用InnoDB;STRICT_TRANS_TABLES表示批量 Insert是若是第一条失败则都失败。
  • Online ALTER TABLE. 不须要再经过复制表就能够直接修改索引名称。
  • JSON support. 支持JSON类型,
  • 空间类型
  • 移除YEAR(2)

7 备份与恢复

7.1 备份与恢复类型

11 Data Types

包含:python

  • 数值类型
  • 时间日期类型
  • 字符类型,String,Char,Byte
  • 空间类型
  • JSON类型

11.1 数据类型概述

11.1.1 数值类型

对于整数,M表示显示的最大宽度;
对于浮点与定点数,M表示能够存储的总位数;
若是对表字段设定ZEROFILL,该字段默认加上无符号类型属性;
默认为有符号类型;
序列号SERIAL:无符号,Not NULL,自增,BIGINT,UNIQUEmysql

Warning
2个数字作减法,其中有一个为无符号类型,则结果也为无符号类型。但设置 NO_UNSIGNED_SUBTRACTION (SQL mode)时,结果为有符号类型。sql

  • BIT [(M))]
    BIT类型,M表示位数,默认为1,M范围为[1,64]
  • TINYINT [(M)] [UNSIGNED] [ZEROFILL]
    小整数(8bit),有符号范围为[-128, 127],无符号范围为[0,255]
  • BOLL BOOLEAN
    TINYINT(1)的同义词,值为0表示false,非0表示true
mysql> SELECT IF(0, 'true', 'false');
+------------------------+
| IF(0, 'true', 'false') |
+------------------------+
| false                  |
+------------------------+

mysql> SELECT IF(1, 'true', 'false');
+------------------------+
| IF(1, 'true', 'false') |
+------------------------+
| true                   |
+------------------------+

mysql> SELECT IF(2, 'true', 'false');
+------------------------+
| IF(2, 'true', 'false') |
+------------------------+
| true                   |
+------------------------+
复制代码

然而,TRUE与FALSE仅仅分表表示1与0,实例以下:安全

mysql> SELECT IF(0 = FALSE, 'true', 'false');
+--------------------------------+
| IF(0 = FALSE, 'true', 'false') |
+--------------------------------+
| true                           |
+--------------------------------+

mysql> SELECT IF(1 = TRUE, 'true', 'false');
+-------------------------------+
| IF(1 = TRUE, 'true', 'false') |
+-------------------------------+
| true                          |
+-------------------------------+

mysql> SELECT IF(2 = TRUE, 'true', 'false');
+-------------------------------+
| IF(2 = TRUE, 'true', 'false') |
+-------------------------------+
| false                         |
+-------------------------------+

mysql> SELECT IF(2 = FALSE, 'true', 'false');
+--------------------------------+
| IF(2 = FALSE, 'true', 'false') |
+--------------------------------+
| false                          |
+--------------------------------+
复制代码

最后2段示例结果是由于2既不等于0也不等于1,也间接说明TRUE,FALSE的值为1,0。服务器

  • SMALLINT[(M)] [UNSIGNED] [ZEROFILL]
    小整数(16bit),有符号范围为[-32768,327670],无符号范围为[0,65535]数据结构

  • MEDIUMINT[(M)] [UNSIGNED] [ZEROFILL]
    中等大小整数(24bit),有符号范围为[-8388608,8388607],无符号范围为[0,16777215]并发

  • INT[(M)] [UNSIGNED] [ZEROFILL]
    整数(32bit),有符号范围为[-2147483648,2147483647],无符号范围为[0,4294967295]函数

  • INTEGER[(M)] [UNSIGNED] [ZEROFILL]
    INT的同义类型性能

  • BIGINT[(M)] [UNSIGNED] [ZEROFILL]
    大整数(64bit),有符号范围为[-9223372036854775808,9223372036854775807],无符号范围为[0,18446744073709551615]
    SERIAL:BIGINT UNSIGNED NOT NULL AUTO_INCREMENT UNIQUE.
    关于BITINT字段你应该注意以下事项:ui

    • 全部算术运算都是使用有符号的BITINT或者DOUBLE,因此不该该使用超过9223372036854775807 (63 bits)的无符号BITINT,BIT运算可使用64bit;另外BITINT转换为DOUBLE出现舍入可能致使结果错误。
      在如下状况下,MYSQL能够处理BITINT:
      • 存储无符号整数数值
      • MIN(col_name)或者MAX(col_name)
      • 使用操做符(+,-,*等),2个操做数都为整数
    • 能够存储一个字符串(能转换为整数)到BITINT,MYSQL会执行字符串到整形的转换。
    • 运算溢出,若是对2个很大的数进行相乘,可能获取到非预期的值。
  • DECIMAL[(M[,D])] [UNSIGNED] [ZEROFILL]
    定点数,十进制数。M为总位数(精度),D为小数点后位数(复数),M不包含小数点与符号位(-)。若是D为0,则没有小数点或小数部分。十进制数的最大位数(M)为65,D支持的最大值为30,若是省略D,则默认为0,若是省略M,则默认为10。
    设定为无符号,则不容许负数。
    针对十进制字段的全部基本操做(+,-,*,/)以65位精度来完成。

  • FLOAT[(M,D)] [UNSIGNED:] [ZEROFILL]
    单精度浮点数。值范围-3.402823466E+38 to -1.175494351E-38, 0, and 1.175494351E-38 to 3.402823466E+38. 这是理论限值,实际范围依赖于CPU硬件与操做系统。
    FLOAT(M,D)是非标准的MYSQL扩展。
    若是指定了UNSIGNE,则不容许负数。
    M表示总位数,D表示小数点后位数。若是省略M与D,则可存储的大小依赖于硬件。单精度浮点数精确到约7位小数。D,则不容许负数。
    使用FLOAT时,由于MYSQL中以DOUBLE精度来运算,因此可能会出现一些非预期的问题。

  • DOUBLE[(M,D)] [UNSIGNED] [ZEROFILL]
    双精度浮点数。范围为:-1.7976931348623157E+308 to -2.2250738585072014E-308, 0, and 2.2250738585072014E-308 to 1.7976931348623157E+308.这是理论限值,实际范围依赖于CPU硬件与操做系统。
    M表示总位数,D表示小数点后位数。若是省略M与D,则可存储的大小依赖于硬件。单精度浮点数精确到约15位小数。
    DOUBLE(M,D)是非标准的MYSQL扩展。
    若是指定了UNSIGNE,则不容许负数。

11.1.2 时间日期类型

时间类型概述。关于时间类型的属性与存储要求的更新信息,请参见11.3节 “Date and Times Types”,11.8节“Date Type Storage Requirements”;关于时间的运算操做,见12.7节“Date and Times Functions”。
对于DATE与DATETIME范围描述中,“supported”意味着即便早期版本的值可能有效,但没有保证。
MYSQL容许TIME,DATETIME,TIMESTAMP的秒带有小时部分,即微秒(6位)精度,经过type_name(fsp)来定义微妙,例如:

create table t1 (t TIME(3), dt datatime(6));

mysql> select * from t1;
+--------------+----------------------------+
| t            | dt                         |
+--------------+----------------------------+
| 11:38:59.000 | 2019-08-03 11:39:05.000000 |
+--------------+----------------------------+
1 row in set (0.00 sec)
复制代码

fsp值范围为[0,6],0表示没有微秒,若是忽略,默认为0。(与MYSQL标准不一样的是,标准默认是6,这是为了兼容早期版本)
任何TIMESTAMP或者DATETIME表字段都有自动初始化与更新属性。

  • DATE
    范围为‘1000-01-01’到‘9999-12-31’。MYSQL以‘YYYY-MM-DD’显示DATE字段,但容许使用字符串或者数值来赋值。
  • DATETIME[(fsp)]
    范围为‘1000-01-01 00:00:00.000000’到‘9999-12-31 23:59:59.999999’。MYSQL以‘YYYY-MM-DD hh:mm:ss[.fsp]’显示DATETIME字段,但容许使用字符串或者数值来赋值。 经过设置DEFAULT与ON UPDATE属性能够自动初始化以及自动更新为当前时间,将在11.35节“Automatic Initialization and Updating For TIMESTAMP and DATETIME”中描述。
  • TIMESTAMP[(fsp)]
    时间戳。范围为:'1970-01-01 00:00:01.000000' UTC to '2038-01-19 03:14:07.999999' UTC。TIMESTAMP存储的是从('1970-01-01 00:00:00' UTC)开始的秒数。TIMESTAMP不能表示'1970-01-01 00:00:00',由于该值等于0(从起始时间计算的秒数),而0被保留用来表示'0000-00-00 00:00:00'。
    (TODO 还有小部分未翻译)
  • TIME[(fsp)]
    范围:'-838:59:59.000000' to '838:59:59.000000'。MYSQL以‘hh:mm:ss[.fraction]’显示TIME字段,但容许使用字符串或者数值来赋值。
    选项fsp范围为[0,6]用来指定微秒部分,若是不指定默认为0。
  • YEAR[(4)]
    范围:1901到2155, and 0000。MYSQL以‘YYYY’显示YEAR字段,但容许使用字符串或者数值来赋值。

时间类型不能使用SUM(),AVG()聚合函数,由于转换为数值的时候遇到第一个非数字字符后丢失后面的全部内容。为了规避这个问题,先转换为数字,而后执行聚合函数,而后再转换回时间类型。

SELECT SEC_TO_TIME(SUM(TIME_TO_SEC(time_col))) FROM tbl_name;
SELECT FROM_DAYS(SUM(TO_DAYS(date_col))) FROM tbl_name;

11.1.3 字符类型
  • [NATIONAL] CHAR[(M)] [CHARACTER SET charset_name] [COLLATE collation_name]
    一个固定长度的字符串,在存储时老是用空格填充到指定的长度。m以字符表示列长度。m的范围是0到255。若是省略m,则长度为1。

    检索char值时会删除尾随空格,除非启用pad-char-to-full-length SQL模式。

  • [NATIONAL] VARCHAR(M) [CHARACTER SET charset_name] [COLLATE collation_name]
    可变长度字符串。m以字符表示最大列长度。m的范围是0到65535。使用1-2个字节来存储长度字段,若是不超过255长度,则一个字符,若是超过这2个字节。

    MySQL遵循标准的SQL规范,不会从varchar值中删除尾随空格。

11.2 数字类型

11.2.1 整数类型
11.2.2 定点数类型(DECIMAL, NUMERIC)

小数和数字类型存储精确的数字数据值。当须要保持精确的精度时,例如货币数据时,可使用这些类型。在MySQL中,numeric被实现为decimal,所以下面关于decimal的注释一样适用于numeric。
MySQL以二进制格式存储十进制值。见第12.22节“Precision Math”。
在十进制列声明中,能够(一般)指定精度和小数位数。例如:

salary DECIMAL(5,2)
复制代码

在本例中,5表示精度,2表示刻度。精度表示为值存储的有效位数,小数位数表示小数点后能够存储的位数。
标准SQL要求decimal(5,2)可以存储5位和2位小数的任何值,所以能够存储在salary列中的值范围为-999.99到999.99。

11.6 JSON

14 InnoDB 存储引擎

14.6 InnoDB 磁盘数据结构

14.6.1 表格
14.6.1.1 TODO
14.6.1.2 TODO
14.6.1.3 TODO
14.6.1.4 InnoDB中的自动增量处理
InnoDB自动增量锁模式

Insert的集中方式:

  • “INSERT-like” 语句,全部INSERT语句,包含:INSERT, INSERT ... SELECT, REPLACE, REPLACE ... SELECT, and LOAD DATA. Includes “simple-inserts”, “bulk-inserts”, and “mixed-mode” .
  • Simple inserts 可肯定插入行数数量的,插入单行或多行,包含 INSERT and REPLACE,但不包含INSERT ... ON DUPLICATE KEY UPDATE.
  • Bulk inserts 不肯定插入行数的批量添加。包含INSERT ... SELECT, REPLACE ... SELECT, LOAD DATA语句。
  • Mixed-mode inserts 批量插入中有部分是自增,有部分是指定的,好比:
    INSERT INTO t1 (c1,c2) VALUES (1,'a'), (NULL,'b'), (5,'c'), (NULL,'d');
    复制代码
    另外也包含INSERT ... ON DUPLICATE KEY UPDATE,由于在更新阶段可能会使用或不使用自动增量列的分配值。

(之因此先列出上面4中Insert方式,是由于不一样锁模式对不一样Insert方式影响不同s)

参数innodb_autoinc_lock_mode设置自动增量锁模式,0:传统;1:连续;2:交错。

  • innodb_autoinc_lock_mode = 0 (“traditional” lock mode)
    针对上面4中Insert方式,都是基于表级别的AUTO-INC锁,语句执行完就释放锁,不用等事务完成时才释放锁。但锁表性能相对较差,好处是分配的ID连续,确保以可预测和可重复的顺序为给定的插入语句序列分配自动增量值,并确保由任何给定语句分配的自动增量值连续的。

    基于语句的复制的状况下,这意味着在从属服务器上复制SQL语句时,自动递增列的值与主服务器上的值相同。多个insert语句的执行结果是肯定性的,从系统复制与主系统相同的数据。若是多个insert语句生成的自动增量值是交错的,那么两个并发insert语句的结果将是不肯定的,而且不能使用基于语句的复制可靠地传播到从属服务器。

  • innodb_autoinc_lock_mode = 1 (“consecutive” lock mode)
    这是默认锁定模式。
    对于“bulk inserts”,使用表级别的AUTO-INC锁,一次只能执行一个保存auto-inc锁的语句。

    对于“Simple inserts”,使用互斥量(一个轻量级锁mutex),分配过程当中持有锁并分配预先须要的数量,分配后释放而不用等到整条语句执行完成,这有助于提升性能。若是另外一个事务持有auto-inc锁,“简单插入”将等待auto-inc锁。

    这种锁定模式确保,在不预先知道行数的INSERT语句(以及在语句进行时分配自动递增数的状况下)的状况下,由任何“insert like”语句分配的全部自动递增值都是连续的,能够保证基于语句的主从复制是安全的。

    简单地说,这种锁定模式显著提升了可伸缩性,同时能够安全地用于基于语句的复制。此外,与“传统”锁模式同样,由任何给定语句分配的自动增量数是连续的。对于任何使用自动增量的语句,与“传统”模式相比,语义没有任何变化,但有一个重要的例外。

    “mixed-mode inserts”是例外状况。用户为多行“简单插入”中的某些(而不是所有)行的自动增量列提供显式值。对于此类插入,InnoDB分配的自动增量值比要插入的行数更多。可是,自动分配的全部值都是连续生成(所以高于)最近执行的前一条语句生成的自动增量值。“超额”数字丢失。

  • innodb_autoinc_lock_mode = 2 (“interleaved” lock mode)
    在这种锁模式下,不使用表级auto-inc锁而是都是要信号量,多个语句能够同时执行。这是最快和最可扩展的锁模式,但在使用基于语句的复制或恢复方案时,若是从二进制日志重放SQL语句,则不安全。

    在这种锁定模式下,自动增量值保证在全部并发执行的“insert-like”语句中都是惟一的且单调地递增的。可是,因为多个语句能够同时生成数字(也就是说,数字的分配是跨语句交错的),所以为任何给定语句插入的行生成的值可能不是连续的。

    若是惟一执行的语句是“简单插入”,其中要插入的行数是提早知道的,那么为单个语句生成的数字中没有间隙,除了“混合模式插入”。可是,当执行“大容量插入”时,任何给定语句分配的自动增量值中可能存在间隙。

14.6.1.5 TODO
14.6.1.6 TODO
14.6.2 索引
14.6.2.1 汇集索引与辅助索引

每一个innodb表都有一个称为汇集索引的特殊索引,用于按索引大小顺序存储行的数据。

  • 若是有主键,则为汇集索引
  • 若是没有主键,找第一个UNIQUE索引列做为汇集索引
  • 若是也没有UNIQUE索引,则使用隐藏的ROW_ID列为汇集索引

14.7 Innodb 锁与事务模型

14.7.1 锁
  • Shared and Exclusive Locks
  • Intention Locks
  • Record Locks
  • Gap Locks
  • Next-Key Locks
  • Insert Intention Locks
  • AUTO-INC Locks
  • Predicate Locks for Spatial Indexes
Shared and Exclusive Locks (共享锁与排他锁)

Innodb实现了标准的行锁,共享锁(S)与排他锁(X)

  • 共享锁(S)容许持有锁的事务读取行。
  • 排他锁(X)容许持有锁的事务更新或删除行。

若是事务T1在R行上持有共享锁,那么来自某些不一样事务T2的请求对R行进行以下处理:

  • 读请求:t2能够当即获取到S锁。结果,T1和T2都在R上保持S锁。
  • 写请求:t2不能获取到X锁。

若是事务T1在R行上持有独占(X)锁,则不能当即授予来自某个不一样事务T2的请求R上任何一种类型的锁的权限。相反,事务t2必须等待事务t1释放对行r的锁。

Intention Locks (意向锁)

InnoDB 支持粒度锁即容许行锁与表锁共存。例如LOCK TABLES ... WRITE语句在指定的表上设置表级别的独占锁。为了实现多粒度锁,InnoDB使用intention locks。Intention locks是表级别的锁,指示稍后须要对表中的行使用哪一种类型的锁(X或者S),有2种意向锁:

  • intention shared lock (IS)表示事务打算在指定行上设置共享锁。
  • intention exclusive lock (IX)表示事务打算在指定的行上设置独占锁。
相关文章
相关标签/搜索