数据类型

2020-12-25

整数

UNSIGNED无符号  SIGNED有符号(负号)

TINYINT(3)             -128 到127 无符号为0到255 (存储空间1字节)
SMALLINT(6)          -32768到32769  无符号为65535 (存储空间2字节)
MEDIUMINT(9)     -8388608到8388607 无符号为0到16777215 (存储空间3字节)
INT(11)                -2147483648到2147483647 无符号为0到4294967295 (存储空间4字节)
BIGINT(20)           -9223372036854775808到9223372036854775807(2^63-1) 无符号为0到18446744073709551615(2^64-1) (存储空间8字节)

对于BIGINT所有算术都是使用有符号的BIGINT或DOUBLE值完成的,不要使用大于9223372036854775807(63位)的无符号大整数,除非使用位函数!如果这样做,由于将BIGINT值转换为DOUBLE时的舍入错误,结果中的最后几位可能是错误的。
BIGINT使用的-,+和*运算时,当两个操作数是整数值运算。这意味着,如果将两个大整数相乘(或返回整数的函数的结果),则当结果大于9223372036854775807时,可能会得到意外的结果。

浮点数

UNSIGNED无符号  SIGNED有符号(负号)

DECIMAL(M,D)      精确精度

M为总位数(精度),D为小数点后的位数(小数位数)。小数点和-符号不计入M。如果D为0,则值没有小数点或小数部分。支持的最大位数(M)为65。小数位数(D)的最大值为30。D默认为0。M默认为10
所有+, -, *, /的基本计算的精度为65位
DECIMAL列的值使用二进制格式存储,该格式将9个十进制数字打包为4个字节,每个值的整数和小数部分的存储要求分别确定。9个数字的每一个倍数需要4个字节,剩余的任何数字需要4个字节的一部分,规则如下
剩余数字 1-2位占1字节 3-4位占2字节 5-6位占3字节 7-8位占4字节
例如:DECIMAL(18,9)列在小数点的任一侧都有9位数字,因此整数部分和小数部分每个都需要4个字节。DECIMAL(20,6)列有十四个整数数字和六个小数位数。整数位中的9位需要4个字节,其余5位需要3个字节。六个小数位需要3个字节

FLOAT(M,D)   单精度 (以4字节存储)

M是位数的总和,D是小数点后的位数。如果M和D省略,则将值存储到硬件允许的极限,单精度浮点数的精度约为小数点后7位。
允许值是-3.402823466E+38 对-1.175494351E-38,0以及1.175494351E-38对3.402823466E+38。这些是基于IEEE标准的理论限制。实际范围可能会略小,具体取决于您的硬件或操作系统。
FLOAT的计算可能会出现意想不到的问题,因为mysql中的所有计算都是以双精度计算的

FLOAT(p)      浮点数

p代表精度(以位为单位),但是MySQL仅使用此值来确定是使用FLOAT还是DOUBLE用于结果数据类型。如果p从0到24,则数据类型将变为FLOAT(M,D) 如果p从25到53,则数据类型将变为DOUBLE(M,D)
如果0 <= p <= 24 则存储为4个字节,如果25 <= p <= 53 则存储为8个字节

DOUBLE(M,D)    双精度 (以8字节存储)

M是位数的总和,D是小数点后的位数。如果M和D省略,则将值存储到硬件允许的极限。双精度浮点数精确到大约15个小数位。
允许值是-1.7976931348623157E+308对-2.2250738585072014E-308,0以及2.2250738585072014E-308到1.7976931348623157E+308,这些是基于IEEE标准的理论限制。实际范围可能会略小。

日期

DATE (以3个字节存储)
支持的范围是'1000-01-01'到'9999-12-31',尽管较早的值可能有效,但不能保证

TIME[(fsp)] (3字节+小数秒存储)
范围是'-838:59:59.000000' 至'838:59:59.000000',默认情况下,超出TIME范围但有效的值将被裁剪到范围的最近端点

DATETIME[(fsp)] (以5字节+小数秒存储)
尽管较早的值可能有效,但不能保证
支持的范围是 '1000-01-01 00:00:00.000000'到 '9999-12-31 23:59:59.999999'

TIMESTAMP[(fsp)] (以4字节+小数秒存储)
支持的范围是'1970-01-01 00:00:01.000000'UTC到'2038-01-19 03:14:07.999999'UTC TIMESTAMP值存储为自纪元('1970-01-01 00:00:00'UTC)以来的秒数,不能代表值'1970-01-01 00:00:00';
DEFAULT CURRENT_TIMESTAMP 默认值为当前时间戳
DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP  默认值为当前时间戳,并自动更新为当前时间戳。

YEAR(以1字节存储)
4位数字格式的年份。MySQL YEAR以YYYY格式显示值 ,但允许YEAR使用字符串或数字将值分配给列。值显示为1901到2155或0000。
可以将其声明为YEAR具有4个字符的隐式显示宽度,或YEAR(4)显式显示宽度

TIME,DATETIME和 TIMESTAMP值使用小数秒,精度最高为微秒(fsp介于0到6之间的可选值),以指定小数秒表示精度。值0表示没有小数部分。默认为0
SUM()和AVG()聚合函数不具有时间价值的计算(它们将值转换为数字,第一个非数字字符后会丢失所有内容),如果要使用SUM()和AVG(),要转换为数字单位,计算后再转换为时间

小数秒部分都需要0到3个字节,具体取决于存储值的小数秒精度。 1-2 1字节 3-4 2字节 5-6 3字节

字符串

CHAR(m) 
一个固定长度的字符串,在存储时总是用空格填充到指定的长度。 M代表以字符为单位的列长。范围M为0到255。M默认为1。

VARCHAR(m)
可变长度的字符串。M代表以字符为单位的最大列长度。M的范围是0到65535;
VARCHAR有效最大长度取决于最大行大小(65,535字节,在所有列之间共享)和所使用的字符集。例如,utf8字符每个字符最多需要三个字节,因此VARCHAR使用该utf8字符集的列可以声明为最多21,844个字符;
VARCHAR值使用1字节或2字节的前缀存储值的字节数。VARCHAR值如果不超过255个字节,则一列使用一个长度字节;如果值可能需要超过255个字节,则一列使用两个长度字节

TINYTEXT
最大长度为255(2^8 − 1)个字符。如果该值包含多字节字符,则有效最大长度会更少。每个TINYTEXT值都使用1字节长度的前缀存储值的字节数。

TEXT(m)
最大长度为65,535(2^16 − 1)个字符。如果该值包含多字节字符,则有效最大长度会更少。每个TEXT值使用2字节长度的前缀存储值的字节数。
M可以为此类型指定 一个可选的长度。如果这样做,MySQL将创建该列为最小的TEXT类型,该类型的大小足以容纳值M字符。

MEDIUMTEXT
最大长度为16,777,215(2^24 − 1)个字符。如果该值包含多字节字符,则有效最大长度会更少。每个MEDIUMTEXT值都使用3字节长度的前缀存储值的字节数。

LONGTEXT
最大长度为4,294,967,295(2^32 − 1)字节或4GB。如果该值包含多字节字符,则有效最大长度会更少。LONGTEXT列的有效最大长度还取决于客户端/服务器协议中配置的最大数据包大小和可用内存。每个LONGTEXT值使用4字节长度的前缀存储值的字节数。

BINARY(m)
类似于CHAR类型,但是存储二进制字节字符串而不是非二进制字符串。可选长度M表示以字节为单位的列长度。M默认为1。

VARBINARY(m)
类似于VARCHAR类型,但是存储二进制字节字符串而不是非二进制字符串。M表示最大列长度(以字节为单位)

TINYBLOB
最大长度为255(2^8 − 1)个字节。每个TINYBLOB值使用1字节长度的前缀存储值的字节数。

BLOB(m)
最大长度为65,535(2^16 − 1)个字节。每个BLOB值使用2字节长度的前缀存储值的字节数。
M可以为此类型指定一个可选的长度。如果这样做,MySQL将列创建为最小的BLOB类型,该类型的大小足以容纳值M字节长

MEDIUMBLOB
最大长度为16,777,215(2^24 - 1)个字节。每个MEDIUMBLOB值都使用3字节长度的前缀存储值的字节数。

LONGBLOB
最大长度为4,294,967,295(2^32 − 1)字节或4GB。LONGBLOB列的有效最大长度还取决于客户端/服务器协议中配置的最大数据包大小和可用内存。每个LONGBLOB值使用4字节长度的前缀存储值的字节数。

ENUM('value1','value2',...) (以1或2个字节存储,取决于枚举值的数量)
枚举,一个字符串对象,只能有一个值,从值列表中'value1','value2',…,NULL选择或特殊的错误值''。值在内部以整数表示,最多可包含65,535个不同的元素。(实际限制是小于3000)
优点:
在列的可能值集有限的情况下压缩数据存储。指定为输入值的字符串将自动编码为数字。
可读的查询和输出。这些数字将转换回查询结果中的相应字符串
问题:
如果您的枚举值看起来像数字,则很容易将文字值与其内部索引号混合使用,在ORDER BY子句中使用ENUM列需要特别小心。如枚举排序中解释的那样
排序:
ENUM值根据其索引号排序,索引号取决于列规范中列出的枚举成员的顺序,空字符串排在非空字符串之前,NULL值排在所有其他枚举值之前
为了防止在使用列ORDER BY上的子句时出现意外结果,使用一下技术:
确保通过编码或将该列按词法而不是按索引号排序。 ORDER BY CAST(col AS CHAR)  ORDER BY CONCAT(col)
限制:
枚举值不能是表达式,即使是求值为字符串值的表达式。
强烈建议您不要使用数字作为枚举值,因为它不保存在适当的INYINT或SMALLINT类型,很容易混淆


SET('value1','value2',...) (以1、2、3、4或8个字节存储)
一个字符串对象,该对象可以具有零个或多个值,每个都必须从值的列表中选择,值在内部表示为整数。最多可包含64个不同的成员。
由多个set成员组成的列值用用逗号(,)分隔。这样的结果使SET成员值本身不应包含逗号。

一个表最多可以包含255个唯一的ENUM和SET定义。对于这种限制,具有相同元素列表的列被认为是相同的。例如,如果一个表包含这两列,由于定义相同,它们将计为该限制的一(而不是两)
唯一名称ENUM和SET定义中元素名称长度的总和计入64KB限制,因此尽管给定ENUM列中元素数量的理论限制为65,535,但实际限制小于3000。
可变长度字符串类型使用长度前缀加数据存储。长度前缀需要一到四个字节;

JSON类型

与在字符串列中存储JSON格式的字符串相比,JSON数据类型有以下优点:
1、会自动验证存储在JSON列中的JSON文档,无效的文档会产生错误。优化的存储格式。
2、JSON列中存储的JSON文档将转换为内部格式,从而可以快速读取文档元素

特点

存储JSON文档所需的空间与LONGBLOB或LONGTEXT大致相同
存储在JSON列中的任何JSON文档的大小都限于max_allowed_packet系统变量的值(当服务器内部在内存中操作JSON值时,该值可以大于此值;该限制在服务器存储时适用)
JSON列不能有非NULL默认值
JSON像其他二进制类型的列一样,列也不直接建立索引;相反,您可以在生成的列上创建索引,以从该JSON列中提取标量值 
MySQL使用utf8mb4字符集和utf8mb4_bin排序规则处理JSON上下文中使用的字符串。其他字符集中的字符串将根据需要转换为utf8mb4(对于ascii或utf8字符集中的字符串,无需进行转换,因为ascii和utf8是utf8mb4的子集。)
用户定义的变量不能是JSON数据类型,所以虽然自定义变量获取的值看起来像一个JSON值,并且具有相同的字符集并归类为JSON值,但它不具有JSON数据类型。相反,来自JSON_OBJECT()的结果在分配给变量时会转换为字符串。
JSON值的比较区分大小写,区分大小写也适用于null,true和false,它们必须始终以小写形式编写
JSON值可以使用的比较运算符 =, <, <=, >, >=, <>, !=,和 <=>
尚不支持以下比较运算符和函数:BETWEEN,IN(),GREATEST(),LEAST()
存储在JSON文档中的字符串需要4到10个字节的额外存储空间,具体取决于字符串的长度以及存储该字符串的对象或数组的大小。另外,MySQL对JSON列中存储的任何JSON文档的大小施加了限制,以使其不能大于max_allowed_packet的值。

JSON类型的优先级

类型名称是JSON_TYPE()函数返回的名称,从最高优先级到最低优先级。一起显示在一行上的类型具有相同的优先级。
列表前面列出的JSON类型的任何值都比列表后面列出的JSON类型的任何值的大。

BLOB
比较两个值的前N个字节,其中N是较短值中的字节数。如果两个值的前N个字节相同,则较短的值排在较长的值之前

BIT
与BLOB的规则相同

OPAQUE
与BLOB的规则相同。OPAQUE值是指未分类为其他类型之一的值

DATETIME
表示较早时间点的值排序在表示较晚时间点的值之前。如果两个值最初分别来自MySQL DATETIME和TIMESTAMP类型,则如果它们表示相同的时间点,则它们相等

TIME
两个时间值中较小的一个排序在较大的一个之前

ARRAY
如果两个JSON数组的长度相同并且数组中对应位置的值相等,则它们相等。如果数组不相等,则它们的顺序由存在差异的第一个位置的元素确定。在该位置具有较小值的数组将首先排序。如果较短数组的所有值都等于较长数组中的相应值,则首先对较短数组进行排序。

BOOLEAN
flase值小于true值

OBJECT
如果两个JSON对象具有相同的键集,并且两个键中的每个键具有相同的值,则它们相等。两个不相等的对象的顺序是未知的,但是确定的

STRING
字符串按照比较的两个字符串的utf8mb4表示的前N个字节进行词法排序,其中N是较短字符串的长度。如果两个字符串的前N个字节相同,则认为较短的字符串小于较长的字符串
这个排序等价于排序规则为utf8mb4_bin的SQL字符串的排序。因为utf8mb4_bin是一个二进制排序规则,JSON值的比较是区分大小写的 "A" < "a"

INTEGER, DOUBLE
JSON值可以包含精确值数字和近似值数字
在分别使用INT和DOUBLE数字类型的两列之间的比较中,对于所有行,该整数都将转换为双精度数。即,将精确值数字转换为近似值数字。
另一方面,如果查询比较两个包含数字的JSON列,则无法事先知道数字是整数还是双精度。为了在所有行中提供最一致的行为,MySQL将近似值数字转换为精确值数字。所得的顺序是一致的,并且不会丢失精确值数字的精度

排序

对于升序排序,NULL在所有JSON值(包括JSON空文字)之前进行排序。对于降序排序,SQL对NULL所有JSON值(包括JSON空文字)之后进行排序。
JSON值的排序键受max_sort_length系统变量的值限制,因此只有在第一个相等的键的max_sort_length字节比较之后

{/if}