11章数据类型

目录

11.1数据类型概述
11.1.1数字类型概述
11.1.2日期和时间类型概述
11.1.3字符串类型概述
11.2
11.2.1整数类型(精确值)整数int、smallint、TINYINT、MEDIUMINT,bigint
11.2.2固定点的类型(精确值)-十进制数字
11.2.3浮点类型(近似值)浮球式、双
11.2.4型位位值
11.2.5数值型属性
11.2.6超出范围和溢出处理
11.3日期和时间类型
11.3.1日期,日期,和时间戳类型
11.3.2时间类型
11.3.3年型
11.3.4迁移年(2)年(4)列
11.3.5自动初始化和更新时间和日期
11.3.6分数秒的时间值
11.3.7之间的转换日期和时间类型
在日期11.3.8两位数的年
11.4字符串类型
11.4.1的char和varchar类型
11.4.2的binary和varbinary类型
11.4.3 BLOB和文本类型
11.4.4枚举类型
11.4.5集合类型
11.5空间数据类型
11.5.1空间数据类型
11.5.2 OpenGIS的几何模型
11.5.3支持空间数据格式
11.5.4几何的合法性和有效性
11.5.5空间参考系统的支持
11.5.6创造空间列
11.5.7填充空间列
11.5.8获取空间数据
11.5.9优化空间分析
11.5.10创建空间索引
11.5.11使用空间索引
11.6 JSON数据类型
数据类型的默认值为
为数据类型的存储要求
11.9为一列选择正确类型
11.10使用其他数据库引擎的数据类型

MySQL支持数SQL在几类数据类型:数值类型,日期和时间类型、字符串(字符和字节)类型、空间类型和JSON数据类型。本章提供了这些数据类型概述,详细描述每个类别中的类型属性和数据类型的存储要求概述。最初是故意简短概述。更详细的描述在本章后面应该为特定数据类型的附加信息的咨询,如您可以在其中指定值允许的格式。

数据类型描述使用这些公约:

11.1数据类型概述

11.1.1数字类型概述

的数值数据类型的总结如下。关于和数值类型存储需求属性的更多信息,参见11.2节,“数字类型”,和11.8节,“数据类型存储的要求”

M表示整数类型的最大显示宽度。最大显示宽度为255。显示宽度无关的类型包含的值的范围,如11.2节,“数字类型”。浮点和定点类型,M是数字存储的总数

如果你指定ZEROFILL一个数字列,MySQL会自动添加无符号属性栏

数字数据类型,允许UNSIGNED属性还允许签署。然而,这些数据类型签名的默认情况下,所以SIGNED属性不起作用

SERIAL是一个别名bigint符号不空auto_increment独特

SERIAL DEFAULT VALUE在整数列的定义是一个别名not null自动增量_单

警告

当你使用整数的值是在类型之间的差UNSIGNED结果是无符号的,除非NO_UNSIGNED_SUBTRACTIONSQL模式启用。看到12.10节,“铸函数和操作符”

  • BIT[(M)]

    一位的值的类型M表示每个值的位数,从1到64。默认值是1如果M省略

  • TINYINT[(M)] [UNSIGNED] [ZEROFILL]

    一个很小的整数。签署的范围-128一百二十七。无符号的范围0二百五十五

  • BOOLBOOLEAN

    论文类型是同义词TINYINT(1)。值为零是错误的。非零的值被认为是真实的:

    MySQL的>SELECT IF(0, 'true', 'false');|;if(0,true,false);| |虚假| >;MySQLSELECT IF(1, 'true', 'false');段(1,| if true,false);| | True | >;MySQLSELECT IF(2, 'true', 'false');的;(2 | if true,false);TRUE;| | |

    然而,价值观TRUE错误的仅仅是别名1,分别如下所示:

    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等于没有也没有0

  • SMALLINT[(M)] [UNSIGNED] [ZEROFILL]

    一个小的整数。签署的范围-32768三万二千七百六十七。无符号的范围0六万五千五百三十五

  • MEDIUMINT[(M)] [UNSIGNED] [ZEROFILL]

    一个中等大小的整数。签署的范围-8388608八百三十八万八千六百零七。无符号的范围0一千六百七十七万七千二百一十五

  • INT[(M)] [UNSIGNED] [ZEROFILL]

    一个正常大小的整数。签署的范围-2147483648二十一亿四千七百四十八万三千六百四十七。无符号的范围0四十二亿九千四百九十六万七千二百九十五

  • INTEGER[(M)] [UNSIGNED] [ZEROFILL]

    这种类型是同义词INT

  • BIGINT[(M)] [UNSIGNED] [ZEROFILL]

    一个大整数。签署的范围-9223372036854775808九十二万二千三百三十七兆二千零三十六亿八千五百四十七万七千五百八十。无符号的范围018446744073709551615

    SERIAL是一个别名bigint符号不空auto_increment独特

    你应该知道的一些事情BIGINT专栏

    • 所有的运算都是通过签署BIGINTDOUBLE值,因此您不应使用无符号整数大于大九十二万二千三百三十七兆二千零三十六亿八千五百四十七万七千五百八十(63位)除位功能!如果你那样做,结果一些最后的数字可能是错误的因为当转换一个舍入误差BIGINT价值一DOUBLE

      MySQL可以处理BIGINT在下列情况下:

    • 你可以在商店一个确切的整数BIGINT通过使用一个字符串列存储。在这种情况下,MySQL执行字符串数转换,不涉及中间双精度表示。

    • 这个-+,和*运营商使用BIGINT当两个操作数都是整数运算。这意味着如果你两个大整数相乘(或结果,返回整数的函数),你可能会得到意想不到的结果,当结果大于九十二万二千三百三十七兆二千零三十六亿八千五百四十七万七千五百八十

  • DECIMAL[(M[,D])] [UNSIGNED] [ZEROFILL]

    一个包装确切定点数M是总位数(精度)和D是小数点后的位数(规模)。小数点(负数)的符号不包括在M。如果D0,价值观没有小数点或分数部分。数字的最大位数(MDECIMAL65。支持小数的最大数量(D)是30。ifD被省略,默认是0。如果M被省略,默认是10

    UNSIGNED,如果规定,不允许负值。

    所有的基本计算(+, -, *, /)与DECIMAL列65位精度完成

  • DEC[(M[,D])] [UNSIGNED] [ZEROFILL]NUMERIC[(M[,D])] [UNSIGNED] [ZEROFILL]FIXED[(M[,D])] [UNSIGNED] [ZEROFILL]

    论文类型是同义词DECIMAL。这个FIXED同义词可以与其他数据库系统的兼容性。

  • FLOAT[(M,D)] [UNSIGNED] [ZEROFILL]

    一个小的(单精度浮点数)。允许值-3.402823466E+38-1.175494351e-380,和1.175494351e-383.402823466E+38。这些都是理论上的限制,基于IEEE标准。实际距离可能稍小的取决于你的硬件或操作系统。

    M是总位数和D是数字的小数点后的位数。如果MD省略值存储到硬件允许的限制。单精度浮点数精确到大约7位小数。

    UNSIGNED,如果规定,不允许负值。

    使用FLOAT也许会给你一些意想不到的问题,因为在MySQL中的所有计算了双精度。看到第b.5.4.7,“没有匹配行解决问题”

  • DOUBLE[(M,D)] [UNSIGNED] [ZEROFILL]

    一个正常大小(双精度浮点数)。允许值-1.7976931348623157E+308-2.2250738585072014e-3080,和2.2250738585072014e-3081.7976931348623157E+308。这些都是理论上的限制,基于IEEE标准。实际距离可能稍小的取决于你的硬件或操作系统。

    M是总位数和D是数字的小数点后的位数。如果MD省略值存储到硬件允许的限制。一个双精度浮点数字精确到小数点后约15。

    UNSIGNED,如果规定,不允许负值。

  • DOUBLE PRECISION[(M,D)] [UNSIGNED] [ZEROFILL]REAL[(M,D)] [UNSIGNED] [ZEROFILL]

    论文类型是同义词DOUBLE。。。。。。。例外:如果REAL_AS_FLOATSQL模式启用,REAL是同义词FLOAT而不是DOUBLE

  • FLOAT(p) [UNSIGNED] [ZEROFILL]

    一个浮点数p代表位的精度,但MySQL使用这个值来确定是否使用FLOATDOUBLE《resulting数据类型。如果p从0到24,数据类型是FLOAT没有MD价值观。如果p从25到53,数据类型是DOUBLE没有MD价值观。结果列的范围为单精度相同FLOAT或双精度DOUBLE数据类型描述本节前面。

    FLOAT(p)语法提供了ODBC兼容。

11.1.2日期和时间类型概述

时态数据的类型总结如下。关于和时态数据类型存储需求属性的更多信息,参见11.3节,“戴特时间类型”,和11.8节,“数据类型存储的要求”。对于功能上的操作时间值的说明,见12.7节,“戴特和时间函数”

对于DATEDATETIME范围描述,支持虽然早期的值可能意味着工作,没有保证。

MySQL允许小数秒TIMEDATETIME,和TIMESTAMP值,以微秒(6位数)精度。定义一个列,包括小数秒部分,使用语法type_namefsp,在那里type_nameTIMEDATETIME,或TIMESTAMP,和fsp是分数秒的精度。例如:

create table T1(t(3小时),DT DateTime(6));

这个fsp值,如果有,必须在范围0到6。值意味着没有小数部分。如果省略,默认精度为0。(这不同于标准的SQL默认,与以前的版本的兼容性)

任何TIMESTAMPDATETIME表中的列可以自动初始化和更新性能。

  • DATE

    一个日期。支持的范围是'1000-01-01'“9999-12-31”。MySQL显示DATE价值观YYYYY - DD格式,但允许分配的值DATE使用字符串或数字列

  • DATETIME[(fsp)]

    日期和时间的组合。支持的范围是'1000-01-01 00:00:00.000000'“9999-12-31 23:59:59. 999999。MySQL显示DATETIME价值观“YYYY-MM-DD HH:MM:SS .fraction [ ]格式,但允许分配的值DATETIME使用字符串或数字列

    一个可选的fsp从0至5月6日给指定小数秒精度的范围值。值为0表示没有小数部分。如果省略,默认精度为0。

    自动初始化和更新为当前的日期和时间DATETIME列可指定使用默认ON UPDATE列定义的条款,如第11.3.5,自动初始化和更新的时间戳和日期时间”

  • TIMESTAMP[(fsp)]

    时间戳。范围'1970-01-01 00:00:01.000000'UTC“2038-01-19 03:14:07. 999999UTCTIMESTAMP值存储为新纪元后的秒数(“1970-01-01 00:00:00”UTC)。的TIMESTAMP不能代表价值“1970-01-01 00:00:00”因为那等于0秒从时代的和值保留为代表'0000-00-00 00:00:00',的TIMESTAMP价值

    一个可选的fsp从0至5月6日给指定小数秒精度的范围值。值为0表示没有小数部分。如果省略,默认精度为0。

    服务器处理方式TIMESTAMP定义取决于你的价值explicit_defaults_for_timestamp系统变量(参见第5.1.7,服务器“系统变量”

    如果explicit_defaults_for_timestamp启用,没有自动的分配默认current_timestampON UPDATE CURRENT_TIMESTAMP属性的任何TIMESTAMP专栏他们必须明确地包含在列定义。另外,任何TIMESTAMP没有显式声明为不为空许可证NULL价值观

    如果explicit_defaults_for_timestamp是残疾人,服务器处理时间戳如下:

    除非另有规定,第一TIMESTAMP表中的列定义为自动设置的日期和最近修改时间如果没有明确指定一个值。这使得TIMESTAMP用于记录的时间戳INSERTUPDATE运营你也可以设置任何TIMESTAMP列为当前的日期和时间,并给它分配一个无效的值,除非它已被定义的NULL属性允许无效的价值观

    自动初始化和更新为当前的日期和时间可以指定使用DEFAULT CURRENT_TIMESTAMP更新current_timestamp列定义条款。默认情况下,第一TIMESTAMP柱具有这些属性,如前所述。然而,任何TIMESTAMP表中的列可以定义为具有这些特性。

  • TIME[(fsp)]

    一时间。范围'-838:59:59.000000'“838:59:59. 000000”。MySQL显示TIME价值观“hh:MM:SS [部分]”。格式,但允许分配的值TIME使用字符串或数字列

    一个可选的fsp从0至5月6日给指定小数秒精度的范围值。值为0表示没有小数部分。如果省略,默认精度为0。

  • YEAR[(4)]

    在一年的4位数字的格式。MySQL显示YEAR价值观yyyy格式,但允许分配的值YEAR使用字符串或数字列。值显示为一千九百零一2155,和0000

    有关更多信息YEAR显示格式和输入值的解释,见11.3.3节,“年”

    笔记

    MySQL 8不支持YEAR(2)在老版本的MySQL数据类型允许的。对于转换YEAR(4),看到11.3.4“迁徙节,今年(2)年(4)列”

这个SUM()AVG()聚合函数不具有时间价值。(他们将这些值的数字,第一个数字字符。在失去一切)要解决这一问题,转换为数值的单位,进行集合运算,并将回到时间的价值。实例:

选择sec_to_time(sum(time_to_sec(time_col)))从tbl_name;选择from_days(和(to_days(date_col)))从tbl_name

11.1.3字符串类型概述

的字符串数据类型的总结如下。关于字符串的类型存储需求属性的更多信息,参见第11.4,“String Types”,和11.8节,“数据类型存储的要求”

在一些情况下,MySQL将字符串列的变化不同,给出了一种CREATE TABLEALTER TABLE声明。看到第13.1.18.7,“沉默的列规范的变化”

MySQL解释长度规格单位的字符列定义的字符。这适用于CHARVARCHAR,和TEXT类型

许多字符串数据类型的列定义可以包括属性指定的列的字符集或整理。这些属性适用于CHARVARCHAR,的TEXT类型,ENUM,和SET数据类型:

  • 这个CHARACTER SET属性指定的字符集,而整理属性指定一个字符集的整理。例如:

    CREATE TABLE t
    (
        c1 VARCHAR(20) CHARACTER SET utf8,
        c2 TEXT CHARACTER SET latin1 COLLATE latin1_general_cs
    );
    

    该表定义创建一个命名列c1有一个字符集UTF8对字符集的默认排序规则,和一个叫作c2有一个字符集latin1和一个敏感的整理

    规则指定的字符集和整理时的一个或两个CHARACTER SET整理属性是失踪了第10.3.5,”列的字符集和字符”

    CHARSET是同义词字符集

  • 指定CHARACTER SET binary一个字符串数据类型属性导致列被创建为相应的二进制字符串数据类型:CHAR成为BINARYVARCHAR成为VARBINARY,和TEXT成为BLOB。对于ENUMSET数据类型,这不会发生;他们创建申报。假设你指定一个表使用这个定义:

    创建表(C1 varchar(10)字符集的文本字符集的二进制二进制,C2、C3型(A,B,C)字符集的二进制);

    由此产生的表定义:

    CREATE TABLE t
    (
      c1 VARBINARY(10),
      c2 BLOB,
      c3 ENUM('a','b','c') CHARACTER SET binary
    );
    
  • 这个BINARY属性用于指定表的默认字符集和二进制速记(_bin该字符集整理)。在这种情况下,比较和排序是基于数字字符代码值。

  • 这个ASCII属性是速记字符集latin1

  • 这个UNICODE属性是速记UCS2字符集

字符列的比较和排序是基于分配给列的排序规则。对于CHARVARCHARTEXTENUM,和SET数据类型,你可以用一个二进制声明一个列(_bincollation)或BINARY属性使比较和排序使用底层字符代码值而不是一个词汇顺序。

有关使用mysql字符集的更多信息,参见10章,字符集Unicode排序规则,

  • [NATIONAL] CHAR[(M)] [CHARACTER SET charset_name] [COLLATE collation_name]

    一个固定长度的字符串,一直用空格填充到指定的长度时。M代表人物列长度。范围M0到255。如果M省略,长度为1

    笔记

    尾随空格时删除CHAR值检索,除非PAD_CHAR_TO_FULL_LENGTHSQL模式启用

    CHAR是速记CHARACTERNATIONAL CHAR(或其等效的缩写形式,NCHAR)是标准的SQL的方式来定义:CHAR柱应该使用一些预定义的字符集。MySQL的使用UTF8这个预定义的字符集第10.3.7,“集”的民族性格

    这个CHAR BYTE数据类型是一个别名为BINARY数据类型。这是一个兼容的特征。

    MySQL允许你创建一列式CHAR(0)。这是很有用,当你必须符合旧的应用程序依赖于一个柱的存在,但没有实际使用价值。字符(0)也很不错,当你需要一个列,只能取两个值:一个被定义为柱CHAR(0) NULL只占用一个点只能值无效的''(空字符串)

  • [NATIONAL] VARCHAR(M) [CHARACTER SET charset_name] [COLLATE collation_name]

    一个可变长度的字符串。M代表人物列的最大长度。范围M0到65535。一个有效的最大长度VARCHAR须行大小的最大值(65535个字节,其中所有列共享)和使用的字符集。例如,UTF8字符需要三字节的每个字符,所以VARCHAR柱的使用UTF8字符集可以声明为最多21844个字符。看到第c.10.4,“限制表的列数和行的大小”

    MySQL存储VARCHAR值为1字节或2字节的prefix length +日期。indicates the number of the prefix length字节the value。在VARCHAR柱使用一个长度字节如果值要求不超过255个字节,如果值可能需要超过255字节长度的字节。

    笔记

    MySQL遵循标准的SQL规范,并从删除尾随空格VARCHAR价值观

    VARCHAR是速记CHARACTER VARYINGNATIONAL VARCHAR是标准的SQL的方式来定义:VARCHAR柱应该使用一些预定义的字符集。MySQL的使用UTF8这个预定义的字符集第10.3.7,“集”的民族性格NVARCHAR是速记NATIONAL VARCHAR

  • BINARY[(M)]

    这个BINARY类型是相似的CHAR型,但保存二进制字节字符串而不是二进制字符串。一个可选的长度M代表字节列长度。如果省略,M默认值为1

  • VARBINARY(M)

    这个VARBINARY类型是相似的VARCHAR类型的商店,但BINARY。多进制字节而不是字符的字符串。M代表字节的列的最大长度。

  • TINYBLOB

    BLOB一个最大长度为255柱(2?1)字节。每个TINYBLOB价值是使用一个字节长度前缀表示的值的字节数存储。

  • TINYTEXT [CHARACTER SET charset_name] [COLLATE collation_name]

    TEXT一个最大长度为255柱(2?1)字符。如果该值包含多字节字符的最大长度是有效的。每个TINYTEXT价值是使用一个字节长度前缀表示的值的字节数存储。

  • BLOB[(M)]

    BLOB一个最大长度为65535柱(2十六?1)字节。每个BLOB价值是使用双字节长度前缀表示的值的字节数存储。

    一个可选的长度M对于这种类型的。如果是这样的话,MySQL创建列为最小BLOB大到足以容纳值类型MLong Bytes .

  • TEXT[(M)] [CHARACTER SET charset_name] [COLLATE collation_name]

    TEXT一个最大长度为65535柱(2十六?1)字符。如果该值包含多字节字符的最大长度是有效的。每个TEXT价值是使用双字节长度前缀表示的值的字节数存储。

    一个可选的长度M对于这种类型的。如果是这样的话,MySQL创建列为最小TEXT大到足以容纳值类型M个字符长

  • MEDIUMBLOB

    BLOB一个最大长度为16777215柱(2二十四?1)字节。每一个MEDIUMBLOB价值是使用3字节长度前缀表示的值的字节数存储。

  • MEDIUMTEXT [CHARACTER SET charset_name] [COLLATE collation_name]

    TEXT一个最大长度为16777215柱(2二十四?1)字符。如果该值包含多字节字符的最大长度是有效的。每个MEDIUMTEXT价值是使用3字节长度前缀表示的值的字节数存储。

  • LONGBLOB

    BLOB用4294967295或4GB的最大长度的柱(2三十二- 1)字节。最大有效长度LONGBLOB列取决于配置的最大数据包大小的客户端/服务器协议和可用内存。每个LONGBLOB价值是使用4字节长度前缀表示的值的字节数存储。

  • LONGTEXT [CHARACTER SET charset_name] [COLLATE collation_name]

    TEXT用4294967295或4GB的最大长度的柱(2三十二?1)字符。如果该值包含多字节字符的最大长度是有效的。有效的最大长度LONGTEXT柱也取决于配置的最大数据包大小的客户端/服务器协议和可用内存。每个LONGTEXT价值是使用4字节长度前缀表示的值的字节数存储。

  • ENUM('value1','value2',...) [CHARACTER SET charset_name] [COLLATE collation_name]

    枚举。一个String对象只能有一个值,从列表中选择值'value1''value2'NULL或特殊' '误差值ENUM值的内部表示为整数

    一个ENUM柱最多可以有65535个不同的元素。

    所支持的最大单个长度ENUM元素M<= 255 and (MXw) <= 1020, whereM是元素的文字长度w是为最大长度的字符在字符集所需的字节数。

  • SET('value1','value2',...) [CHARACTER SET charset_name] [COLLATE collation_name]

    一套。一个String对象可以有零个或多个值,每个值必须从列表中选择'value1'&#39;value2&#39;SET值的内部表示为整数

    SET列可以有一个最大的64不同成员。

    所支持的最大单个长度SET元素M<= 255 and (MXw) <= 1020, whereM是元素的文字长度w是为最大长度的字符在字符集所需的字节数。

11.2

MySQL支持所有标准的SQL数据类型。这些类型包括精确数值数据类型(INTEGERSMALLINTDECIMAL,和NUMERIC),以及近似数字数据类型(FLOATREAL,和DOUBLE PRECISION)。关键词INT是同义词INTEGER,和关键词DECFIXED是同义词DECIMAL。MySQL的对待DOUBLE作为一个同义词DOUBLE PRECISION(非标准扩展)。MySQL也治REAL作为一个同义词DOUBLE PRECISION(一个非标准的变化),除非REAL_AS_FLOATSQL模式启用

这个BIT数据类型存储的位值和支持MyISAMMEMORY,和InnoDB

关于MySQL如何处理分配超出范围的值的列和溢出在表达式求值,看第11.2.6,“超出范围和溢出处理”

有关数值类型存储要求的信息,参见11.8节,“数据类型存储的要求”

用于对数字操作数的计算结果的数据类型取决于类型的操作数和操作上进行。有关更多信息,参见第12.6.1,“算子”

11.2.1整数类型(精确值)整数int、smallint、TINYINT、MEDIUMINT,bigint

MySQL支持SQL标准的整数类型INTEGER(或国际的)和SMALLINT。作为标准的一个扩展,MySQL也支持整数类型TINYINTMEDIUMINT,和bigint。下表显示了每个整数类型所需的存储范围。

表11.1所需的存储范围的整数类型支持MySQL

类型暴风雨最小值签署最小值符号最大值签署最大值符号
TINYINT-1280127255
SMALLINT-3276803276765535
MEDIUMINT-83886080838860716777215
INT-2147483648021474836474294967295
BIGINT-2630263-1264-1

11.2.2固定点的类型(精确值)-十进制数字

这个DECIMAL数字类型存储的精确数值数据值。这些类型时使用的是保持准确的精度非常重要,例如货币数据。在MySQL,NUMERIC实施十进制的,所以下面的评论DECIMAL同样适用于数字

MySQL存储DECIMAL二进制格式的值。看到第12,“精确数学”

在一个DECIMAL柱宣言,精度和规模可以(通常)指定;例如:

工资小数(5,2)

在这个例子中,5是精度和是规模。精度表示存储的值的有效位数,和规模是可以存储的小数点后的位数。

标准SQL要求DECIMAL(5,2)能够存储任何值以五个数字和两位小数,所以值可以存储在工资列的范围从-999.99九百九十九点九九

在标准的SQL语法DECIMAL(M)相当于(小数点M,0)。Sinlarly,SYNTAX十进制的相当于DECIMAL(M,0),在实施许可决定的价值M。MySQL支持这两种变异形式十进制的语法。默认值M10

如果规模0,DECIMALValues Contain不要决定一部分。

数字的最大位数DECIMAL是65,但实际的范围,对于一个给定的十进制的柱可以约束的精度和规模对于一个给定的列。当这样的列分配一个值更多位数的小数点后比指定的规模允许的值转换成规模。(精确的行为是特定于操作系统的,但总体效果是截断数字。允许的数量)

11.2.3浮点类型(近似值)浮球式、双

这个FLOAT近似数值数据类型的值。MySQL使用四个字节为双精度值的单精度值和八字节。

FLOAT,SQL标准允许的精度可选规格(但不是指数的范围)位以下的关键词在括号中。MySQL也支持这个可选的精度要求,但精度值仅用于确定存储大小。从0到4字节单精度23结果的精度FLOAT专栏从24到53,结果在一个字节的双精度精度专栏

MySQL允许非标准语法:FLOAT(M,D)真实的MD双精度(MD。在这里,MD意味着比值可以存储多达M总的数字,D数字可能是小数点后。例如,一个列定义为浮(7,4)看起来像-999.9999在显示的时候。MySQL进行舍入时存储的值,所以如果你插入九百九十九点零零零零九FLOAT(7,4)柱,近似结果九百九十九点零零零一

因为浮点值是近似的,不存储为精确值,试图把他们当作精确比较可能导致的问题。他们也受到平台或实现的依赖性。有关更多信息,参见第b.5.4.8,“浮点数”的问题

为了获得最大的可移植性,代码需要近似数字数据存储应用价值FLOAT双精度没有规范的精度位数

11.2.4型位位值

这个BIT数据类型用于存储位的值。一种位(M使存储M位的值M可以从1到64的范围内。

指定的位值,b'value'符号可以用value是一个二进制值写入使用0和1。例如,B,“111”b'10000000'代表7和128,分别。看到第9.1.5,“位值文字”

如果你到一个指定值BIT(M)柱比M位长,价值是在左侧用零填充。例如,分配一个值B,“101”一个BIT(6)柱,在效果上,作为分配相同“B”000101

11.2.5数值型属性

MySQL支持任意指定的整数数据类型在括号中的类型的基关键字后面的显示宽度的延伸。例如,INT(4)指定一个INT用一个四位数的显示宽度。这个可选的显示宽度可以被应用程序用来显示整数的值有一个宽度小于左填充他们的空间指定的列的宽度。(那是,这个宽度是返回结果集的元数据。无论是用不到的应用。)

显示的宽度限制的范围内的值,可以存储在列。它也没有阻止值被正确显示大于列显示宽度。例如,一列SMALLINT(3)有通常的SMALLINT范围- 3276832767,和外面的三位值在允许的范围内充分利用超过三位数字显示。

当使用与选择连词(非标)属性ZEROFILL,空间的默认填充替换为零。例如,一列声明为INT(4) ZEROFILL,一个值检索0005

笔记

这个ZEROFILL属性被忽略,当一列参与表达UNION查询

如果你存储的值大于显示宽度的整数列,有ZEROFILL属性,您可能会遇到问题,当MySQL生成临时表的一些复杂的连接。在这些情况下,MySQL假定数据值与列显示宽度内。

所有的整数类型可以有一个可选的(非标)属性UNSIGNED。无符号类型可以用来允许一列中只有非负数或当你需要一个更大的数值范围为柱上。例如,如果一个INT无符号,该列的范围大小是相同的但其端点的转变-2147483648二十一亿四千七百四十八万三千六百四十七高达0四十二亿九千四百九十六万七千二百九十五

浮点和定点类型也可以UNSIGNED。与整数类型,此属性可防止负的值被存储在列。不同的整数类型的列值上限不变。

如果你指定ZEROFILL一个数字列,MySQL会自动添加无符号属性栏

整数或浮点数据类型可以有额外的属性AUTO_INCREMENT。当你插入一个值无效的为索引AUTO_INCREMENT列,列设置为下一个序列值。这通常是value,在那里value是最大的value for the column currently in the table。(汽车_增量序列的开始1。)

存储0为一个汽车_增量列存储具有相同的效果NULL,除非NO_AUTO_VALUE_ON_ZEROSQL模式启用

插入NULL生成汽车_增量价值观要求列被声明NOT NULL。如果该列声明无效的,插入NULL商店无效的。当你插入任何其他值为AUTO_INCREMENT列,列设置为该值与序列进行复位,以便下次自动生成的值如下顺序从插入的值。

在MySQL 8,负价值AUTO_INCREMENT不支持列

11.2.6超出范围和溢出处理

当MySQL存储一个值,在数值列以外的列的数据类型所允许的范围内,结果取决于当时生效的SQL模式:

  • 如果严格的SQL模式启用,MySQL拒绝越界值有误差,和插入失败,符合SQL标准。

  • 如果没有严格的模式被启用,MySQL夹值的列的数据类型的范围内适当的端点和存储的值代替。

    当一个超出范围的值赋给一个整数列,MySQL存储表示的列的数据类型的范围相应的端点值。

    当一个浮点或定点列分配超出范围由指定的默认值(或违约)精度和规模,MySQL存储表示这个范围的相应端点的值。

假设一个表t1这个定义:

创建表T1(I1 tinyint、I2 tinyint unsigned);

以严格的SQL模式启用,超出范围的错误发生:

mysql> SET sql_mode = 'TRADITIONAL';
mysql> INSERT INTO t1 (i1, i2) VALUES(256, 256);
ERROR 1264 (22003): Out of range value for column 'i1' at row 1
mysql> SELECT * FROM t1;
Empty set (0.00 sec)

以严格的SQL模式不启用,裁剪警告发生:

mysql> SET sql_mode = '';
mysql> INSERT INTO t1 (i1, i2) VALUES(256, 256);
mysql> SHOW WARNINGS;
+---------+------+---------------------------------------------+
| Level   | Code | Message                                     |
+---------+------+---------------------------------------------+
| Warning | 1264 | Out of range value for column 'i1' at row 1 |
| Warning | 1264 | Out of range value for column 'i2' at row 1 |
+---------+------+---------------------------------------------+
mysql> SELECT * FROM t1;
+------+------+
| i1   | i2   |
+------+------+
|  127 |  255 |
+------+------+

当严格的SQL模式未启用,列分配转换的发生是由于裁剪报告为警告ALTER TABLELOAD DATA INFILEUPDATE,和多行INSERT声明.在严格的模式,这些语句失败,和一些或所有的值都不能插入或改变,这取决于表的事务表和其他因素。详情见第5.1.10,”服务器的SQL模式”

在一个错误的数字表达评价结果溢出。例如,最大的签署BIGINT值是922337203685477580,那么下面的表达式产生一个错误:

MySQL的&#62;SELECT 9223372036854775807 + 1;错误1690(22003):bigint值超出范围”(922337203685477580 1)”

为了使操作成功,在这种情况下,将该值转换为无符号;

mysql> SELECT CAST(9223372036854775807 AS UNSIGNED) + 1;
+-------------------------------------------+
| CAST(9223372036854775807 AS UNSIGNED) + 1 |
+-------------------------------------------+
|                       9223372036854775808 |
+-------------------------------------------+

是否发生溢出取决于操作数的范围,所以另一种方式来处理前面的表达是用精确值算法因为DECIMAL值有一个比整数范围较大:

MySQL的&#62;SELECT 9223372036854775807.0 + 1;--------------------------- | 9223372036854775807.0 1 | --------------------------- | 9223372036854775808.0 | ---------------------------

之间的整数值相减,其中一个是类型UNSIGNED,默认情况下产生一个无符号的结果。如果结果会是负面的,一个错误的结果:

MySQL的&#62;SET sql_mode = '';查询行,0行受影响(0秒)MySQL &#62;SELECT CAST(0 AS UNSIGNED) - 1;错误1690(22003):bigint无符号值超出范围”(铸造(0为无符号)- 1)”

如果NO_UNSIGNED_SUBTRACTIONSQL模式被启用,结果为阴性:

MySQL的&#62;SET sql_mode = 'NO_UNSIGNED_SUBTRACTION';MySQL的&#62;SELECT CAST(0 AS UNSIGNED) - 1;------------------------- |铸造(0为无符号)-1 | ------------------------- | -1 | -------------------------

如果这样操作的结果是用来更新UNSIGNED整数列,结果是夹到的列类型的最大值,或夹在0如果NO_UNSIGNED_SUBTRACTION启用。如果严格的SQL模式启用时,发生了一个错误,列不变。

11.3日期和时间类型

代表时间值的日期和时间类型DATETIMEDATETIMETIMESTAMP,和YEAR。每个时态类型有一个范围的有效值,以及值,可当你指定一个无效的值,MySQL不能代表。这个TIMESTAMP型具有特殊的自动更新行为,稍后介绍。时间类型的存储要求,见11.8节,“数据类型存储的要求”

记住这些一般考虑工作时的日期和时间类型:

  • MySQL检索一个给定的日期和时间类型在标准输出格式的值,但它试图解释各种格式的输入值,你供应(例如,当您指定要分配给或与日期或时间型值)。为说明允许格式的日期和时间类型,看第9.1.3、戴特和时间的文字”。预计你供应的有效值。不可预知的结果,如果你在其他格式使用价值发生。

  • 虽然MySQL试图解释几种格式的值,日期,必须在年月日的命令(例如,'98-09-04'),而不是在年月日或日、月、年订单常用的其他地方(例如,“09-04-98”'04-09-98'

  • 含两位数年份值的日期是模糊的因为世纪是未知的。MySQL解释两位数年份值使用这些规则:

    • 在今年的范围值70-99转换为1970

    • 在今年的范围值00-69转换为2000-2069

    参见第11.3.8,“约会”两位数字的年份

  • 从一个时间到另一个值类型转换发生根据规则第11.3.7,“日期和时间类型之间的转换

  • MySQL会自动转换为日期或时间值一个数如果值用于数字环境,反之亦然。

  • 默认情况下,当MySQL遇到值的日期或时间,超出范围或无效的类型,将价值的这种类型的值。唯一的例外是,超出范围TIME价值观是夹在相应的终端TIME范围

  • 由SQL模式设置为适当的值,您可以指定更多的到底是什么样的日子你需要MySQL支持。(见第5.1.10,”服务器的SQL模式”。)你可以得到MySQL接受特定的日期,如'2009-11-31',使ALLOW_INVALID_DATESSQL模式。当你想存储这是有用的可能是错误的用户指定的值(例如,在Web窗体)未来处理数据库中。在这种模式下,MySQL验证只有月的范围从1到12,这一天的范围是从1到31。

  • MySQL允许你储存的日期在一天或一个月,一天中的零DATEDATETIME专栏这对需要存储的生日,你可能不知道确切的日期是非常有用的应用程序。在这种情况下,你只需存储日期“2009-00-00”'2009-01-00'。如果你存储日期等,你不应该期望得到正确的结果等功能DATE_SUB()DATE_ADD()要求完成日期。不允许零月或一天的部分时间,使NO_ZERO_IN_DATE模式

  • MySQL允许你保存价值'0000-00-00'作为一个虚拟的日期这是在某些情况下比使用更方便NULL值,并使用较少的数据和索引空间。不允许“0000-00-00”,使NO_ZERO_DATE模式

  • 日期或时间通过连接器/ ODBC的值自动转换为NULL由于ODBC不能处理这样的价值观。

下表显示的格式每种类型的值。这个价值观是特殊的,但你可以存储或引用它们显式使用表中所示的值。您还可以使用价值做这个'0',这是很容易的。时间类型,包括日期部分(DATEDATETIME,和TIMESTAMP如果您发现有错误,请尽管发表评论!NO_ZERO_DATESQL模式启用

数据类型价值
DATE'0000-00-00'
TIME'00:00:00'
DATETIME'0000-00-00 00:00:00'
TIMESTAMP'0000-00-00 00:00:00'
YEAR0000

11.3.1日期,日期,和时间戳类型

这个DATE日期时间,和TIMESTAMP类型相关。本节描述了他们的特点,他们是如何相似,和他们不同。MySQL的识别日期DATETIME,和时间戳几种格式的值,描述第9.1.3、戴特和时间的文字”。对于DATE日期时间把描述;支持虽然早期的值可能意味着工作,没有保证。

这个DATE型用于日期部分值,但没有时间的一部分。MySQL检索并显示日期价值观'YYYY-MM-DD'格式支持的范围是“1000-01-01”'9999-12-31'

这个DATETIME类型是用于价值的价值,其中包括日期和时间部分。MySQL retrieves和显示器日期时间价值观'YYYY-MM-DD HH:MM:SS'格式支持的范围是“1000-01-01 00:00:00”'9999-12-31 23:59:59'

这个TIMESTAMP数据类型用于值包含日期和时间部分。时间戳有一个范围'1970-01-01 00:00:01'UTC“2038-01-19 03:14:07”UTC

DATETIME时间戳值可以包括尾随小数秒参与到微秒(6位数)精度。特别是,在一个值插入到任何小数部分DATETIME时间戳列存储而不是丢弃。与分数的一部分,这些值的格式'YYYY-MM-DD HH:MM:SS[.fraction]'的范围内,日期时间价值观是'1000-01-01 00:00:00.000000'“9999-12-31 23:59:59. 999999,和范围TIMESTAMP价值观是“000000”00:00:01. 1970-01-01'2038-01-19 03:14:07.999999'。小数部分应该由小数点从休息的时间分开;没有其他分数秒分隔符是公认的。关于分数秒支持MySQL,看第11.3.6,“小数秒的时间价值”

这个TIMESTAMP日期时间数据类型提供自动初始化和更新为当前的日期和时间。有关更多信息,参见第11.3.5,自动初始化和更新的时间戳和日期时间”

MySQL转换TIMESTAMP从当前时区为UTC存储值,并返回到当前的UTC时区检索。(这不发生其他类型如日期时间。)默认情况下,每个连接的当前时区的时间服务器。时区可以设置每个连接的基础上。只要带设置保持不变的时候,你回到相同的价值你的店。如果你的店TIMESTAMP值,然后更改时区和检索值,检索到的值不同于你存储的值。这是因为同一时区不用于双向转换。当前时区的可用的价值time_zone系统变量。有关更多信息,参见第5.1.12,MySQL服务器的时区支持”

无效DATE日期时间,或TIMESTAMP值转换为适当类型的值('0000-00-00'“0000-00-00 00:00:00”

注意在MySQL日期值解释的某些性质:

  • MySQL允许轻松的对于指定为字符串值的格式,其中任何一个标点符号可以用作分隔符之间的日期部分或大部分时间。在某些情况下,这个语法可以欺骗。例如,一个值,如'10:11:12'可能看起来像一个时间值的,但被解释为年'2010-11-12'if used in context的日期。the value“10:45:15”转换为'0000-00-00'因为“45”不是一个有效的月

    唯一的分隔符识别之间的日期和时间部分和小数秒部分是小数点。

  • 服务器要求,月和日的值是有效的,而不仅仅是在范围1到12和1到31,分别。严格的模式,无效的日期如'2004-04-31'转换为“0000-00-00”生成一个警告。严格的模式下,无效的日期生成错误。允许这样的日期,使ALLOW_INVALID_DATES。看到第5.1.10,”服务器的SQL模式”为更多的信息

  • MySQL不接受TIMESTAMP值,包括在日或月柱或值不是有效的日期10。这个规则的唯一例外是特殊的价值'0000-00-00 00:00:00'

  • 含两位数年份值的日期是模糊的因为世纪是未知的。MySQL解释两位数年份值使用这些规则:

    • 在今年的范围值00-69转换为2000-2069

    • 在今年的范围值70-99转换为1970

    参见第11.3.8,“约会”两位数字的年份

11.3.2时间类型

MySQL检索并显示TIME价值观“hh:MM:学生格式(或'HHH:MM:SS'宽格式for hours values)。时间值的范围可以从'-838:59:59'“838:59:59”。时间可能是如此之大,因为TIME型不仅可以用来代表一天中的时间(必须小于24h),而且经过时间或两个事件之间的时间间隔(这可能远远大于24h,甚至负)。

MySQL的识别TIME几种格式的值,其中可以包括尾随小数秒参与到微秒的精度(6位)。看到第9.1.3、戴特和时间的文字”。关于分数秒支持MySQL,看第11.3.6,“小数秒的时间价值”。特别是,在一个值插入到任何小数部分TIME列存储而不是丢弃。与分数的一部分,范围时间价值观是'-838:59:59.000000'“838:59:59. 000000”

被指派的缩写值仔细TIME专栏MySQL解释缩写时间值与冒号作为一天的时间。这是,'11:12'方法“11:12:00”,不'00:11:12'。MySQL解释缩写值不使用假设,最右边的两个数字代表秒冒号(即为逝去的时间而不是时间)。例如,你可能会认为“1112”1112作为意义“11:12:00”(十一点后12分钟),但MySQL它们解释为'00:11:12'(11分钟,12秒)。同样,“12”12被解释为“00:00:12”

唯一的分隔符识别时间与小数秒之间的部分是小数点。

默认情况下,值之外TIME但是其他有效剪到接近终点的范围。例如,“850:00:00”'850:00:00'转换为“838:59:59”'838:59:59'。无效时间值转换为'00:00:00'。注意,因为“00:00:00”本身是一个有效的TIME价值,有没有办法告诉,从价值“00:00:00”存储在一个表中,无论初始值被指定为'00:00:00'或者它是否是无效的

对于无效的更严格的处理TIME值,使严格的SQL模式导致错误的发生。看到第5.1.10,”服务器的SQL模式”

11.3.3年型

这个YEAR类型是一个用来表示年值字节型。它可以被声明为YEAR(4)有一个四个字符的显示宽度。

笔记

MySQL 8不支持YEAR(2)在老版本的MySQL数据类型允许的。对于转换YEAR(4),看到11.3.4“迁徙节,今年(2)年(4)列”

MySQL显示YEAR价值观yyyy格式,与一系列1901二千一百五十五,或0000

您可以指定输入YEAR在各种格式的值:

  • 范围内的数字1901二千一百五十五

  • 范围内的4位字符串'1901'“2155”

  • 作为一个1位的数字或范围1九十九。MySQL转换值的范围1六十九70九十九YEAR在范围值二千零一2069一千九百七十1999

  • 作为1或2位数的范围中的字符串'0'“99”。MySQL转换值的范围'0'“69”'70'“99”YEAR在范围值二千2069一千九百七十1999

  • 插入一个数值结果0有一个显示值0000和内部价值0000。插入零,它被解释为二千它作为一个字符串,指定'0'“点”

  • 作为一个函数,返回一个值,在一个可以接受的结果YEAR语境,如NOW()

MySQL将无效YEAR价值观0000

参见第11.3.8,“约会”两位数字的年份

11.3.4迁移年(2)年(4)列

MySQL 8不支持YEAR(2)在老版本的MySQL数据类型允许的。现有的YEAR(2)列必须转换为YEAR(4)再次成为可用。本节提供有关执行转换信息。

除去一年(2)在MySQL 8的支持

MySQL软件处理YEAR(2)列如下:

迁移从去年(2)年(4)

转换YEAR(2)YEAR(4),你可以随时手动不升级。或者,你可以升级到一个版本的降低或不再支持MySQLYEAR(2)(MySQL 5.6.6或以后),然后有MySQL转换YEAR(2)列自动。在后者的情况下,尽量避免升级倾倒并重装数据因为可以改变数据值。另外,如果你使用复制,有升级的考虑,你必须考虑。

转换YEAR(2)YEAR(4)手动,使用ALTER TABLEREPAIR TABLE。假设一个表T1这个定义:

CREATE TABLE t1 (ycol YEAR(2) NOT NULL DEFAULT '70');

修改列的使用ALTER TABLE如下:

修改表T1的力量;

这个ALTER TABLE语句将表不改变YEAR(2)价值观。如果服务器的复制,这ALTER TABLE语句复制到每一个奴隶和做相应的更改表。

另一个方法是进行二进制升级:没有倾销和重装安装MySQL数据。然后运行mysql_upgrade,它使用REPAIR TABLE转换YEAR(2)YEAR(4)在不改变数据的值。如果服务器的复制,这REPAIR TABLE报表复制到每一个奴隶,做出相应的变化,除非你调用mysql_upgrade--skip-write-binlog选项

升级复制服务器通常需要升级的奴隶到新版本的MySQL,然后升级主。例如,如果一个主机和从机运行MySQL 5.5,一个典型的升级序列包括升级从5.6升级到5.6,然后主。对于不同的治疗YEAR(2)在MySQL 5.6.6,升级序列的结果是一个问题:假设奴隶已经升级,但尚未掌握。然后创建一个表包含YEAR(2)表中包含一个总体结果列YEAR(4)在奴隶柱。因此,这些操作都会对主、从一个不同的结果,如果你使用基于语句的复制:

  • 插入数字0。由此产生的价值有一个内部的价值二千在主但0000在奴隶

  • 转换YEAR(2)串。此操作使用的显示值YEAR(2)在主但YEAR(4)在奴隶

为了避免这种问题,修改所有YEAR(2)柱大师YEAR(4)在升级之前。(使用ALTER TABLE,如前所述。)然后你可以升级通常(从第一,然后师父)不引入任何YEAR(2)YEAR(4)主人和奴隶之间的差异。

一个移民法应避免:不要把你的数据mysqldump并重新加载转储文件升级后。这有可能改变YEAR(2)价值观,如前所述

从迁移YEAR(2)YEAR(4)还应包括检查应用程序代码的行为可能改变这些条件下:

  • 代码需要选择YEAR柱产生两个位数

  • 代码不用于插入数字不同处理帐户0:插入进入之内YEAR(2)YEAR(4)在内部价值的结果二千0000,分别

11.3.5自动初始化和更新时间和日期

TIMESTAMPDATETIME列可以自动初始化和更新为当前的日期和时间(即当前时间戳)。

对于任何TIMESTAMPDATETIME表中的列,您可以将当前时间戳作为默认值,自动更新的值,或两者:

  • 自动初始化列设置为当前插入的行,指定列无值的时间戳。

  • 自动更新的列自动更新到当前时间戳时,行中其他列的值是由其当前值。自动更新的栏目保持不变,如果所有其他列设置为当前值。为了防止自动更新栏目更新其他栏目变化时,显式地设置它的当前值。更新自动更新列即使其他列不改变,明确地把它应有的价值(例如,设置为CURRENT_TIMESTAMP

此外,如果explicit_defaults_for_timestamp系统变量是残疾人,你可以初始化或更新任何TIMESTAMP(但不日期时间)列为当前的日期和时间,并指派NULL值,除非它已被定义的无效的属性允许NULL价值观

指定自动属性,使用DEFAULT CURRENT_TIMESTAMP更新current_timestamp在列定义条款。该条款的顺序并不重要。如果是在一个列定义,也可以先发生。任何的同义词CURRENT_TIMESTAMP具有相同的含义CURRENT_TIMESTAMP。这些都是CURRENT_TIMESTAMP()NOW()LOCALTIMELOCALTIME()LOCALTIMESTAMP,和LOCALTIMESTAMP()

使用DEFAULT CURRENT_TIMESTAMP更新current_timestamp具体到TIMESTAMPDATETIME。这个默认条款还可以用来指定一个常数(非自动)默认值;例如,DEFAULT 0默认的2000-01-01 00:00:00”

笔记

下面的示例使用DEFAULT 0,默认可以生成警告或错误取决于严格的SQL模式或NO_ZERO_DATESQL模式启用。要知道,TRADITIONALSQL模式包括严格的模式NO_ZERO_DATE。看到第5.1.10,”服务器的SQL模式”

TIMESTAMPDATETIME可以指定当前时间戳列定义为默认的自动更新值,一但不是其他,或不。不同的列可以有不同的组合的自动性能。下面的规则描述的可能性:

  • DEFAULT CURRENT_TIMESTAMP更新current_timestamp目前,列为其默认值的时间戳和自动更新到当前时间戳。

    CREATE TABLE t1 (
      ts TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
      dt DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP
    );
    
  • 用一个DEFAULT条款但没有更新current_timestamp条款,列的默认值是不会自动更新到当前时间戳。

    默认值取决于DEFAULT子句指定current_timestamp或一个恒定值。与CURRENT_TIMESTAMP,默认是当前时间戳

    创建表T1(TS时间戳默认current_timestamp,DT DateTime默认current_timestamp);

    一个常数,默认是给定值。在这种情况下,列没有自动属性。

    CREATE TABLE t1 (
      ts TIMESTAMP DEFAULT 0,
      dt DATETIME DEFAULT 0
    );
    
  • 一个ON UPDATE CURRENT_TIMESTAMP条款和常数默认条款,列是自动更新到当前时间戳和具有给定的默认值。

    CREATE TABLE t1 (
      ts TIMESTAMP DEFAULT 0 ON UPDATE CURRENT_TIMESTAMP,
      dt DATETIME DEFAULT 0 ON UPDATE CURRENT_TIMESTAMP
    );
    
  • 一个ON UPDATE CURRENT_TIMESTAMP条款但没有默认条款,列是自动更新到当前时间戳,但是没有当前的默认值的时间戳。

    在这种情况下,默认的类型依赖。TIMESTAMP0除非有一个默认的定义与无效的属性,在这种情况下,默认是NULL

    创建表T1(TS1的时间戳更新current_timestamp,默认0 TS2时间戳空更新current_timestamp --默认为空);

    DATETIME有一个默认的无效的除非定义与NOT NULL属性,在这种情况下,默认是0。

    创建表T1(DT1 DateTime更新current_timestamp --默认为空,不current_timestamp DT2 DateTime更新默认0空);

TIMESTAMPDATETIME列没有自动属性除非明确指定,这个例外:如果explicit_defaults_for_timestamp系统变量是禁用的第一TIMESTAMP塔都有默认current_timestampON UPDATE CURRENT_TIMESTAMP如果没有显式指定。抑制自动属性为第一TIMESTAMP柱,使用这些策略:

  • 使explicit_defaults_for_timestamp系统变量。在这种情况下,的默认current_timestampON UPDATE CURRENT_TIMESTAMP子句指定自动初始化和更新是可用的,但不分配给任何TIMESTAMP除非明确地包含在列列定义。

  • 另外,如果explicit_defaults_for_timestamp是残疾人,做以下:

    • 定义一个顶柱DEFAULT子句指定一个恒定的默认值。

    • 指定NULL属性。这也导致列证无效的值,这意味着你不能通过设置列指定当前时间戳NULL。分配无效的套柱NULL,不是当前的时间戳。将当前时间戳,设置栏CURRENT_TIMESTAMP或同义词等NOW()

考虑到这些表的定义:

CREATE TABLE t1 (
  ts1 TIMESTAMP DEFAULT 0,
  ts2 TIMESTAMP DEFAULT CURRENT_TIMESTAMP
                ON UPDATE CURRENT_TIMESTAMP);
CREATE TABLE t2 (
  ts1 TIMESTAMP NULL,
  ts2 TIMESTAMP DEFAULT CURRENT_TIMESTAMP
                ON UPDATE CURRENT_TIMESTAMP);
CREATE TABLE t3 (
  ts1 TIMESTAMP NULL DEFAULT 0,
  ts2 TIMESTAMP DEFAULT CURRENT_TIMESTAMP
                ON UPDATE CURRENT_TIMESTAMP);

这些性能表:

  • 在每个表定义,第一TIMESTAMP列没有自动初始化或更新。

  • 表不同,如何ts1列句柄无效的价值观。为t1TS1NOT NULL并给它分配一个值无效的将其设置为当前时间戳。为t2T3ts1许可证无效的并给它分配一个值NULL将其设置为无效的

  • t2T3不同的默认值ts1。为T2ts1定义允许无效的,所以默认是也NULL在一个没有明确默认条款.为t3TS1许可证NULL但有一个明确的默认0。

如果一个TIMESTAMPDATETIME列定义包含一个明确的分数秒精度值的地方,相同的值必须在列定义中使用。这是允许的:

创建表T1(TS时间戳(6)默认current_timestamp(6)更新current_timestamp(6));

这是不允许的:

CREATE TABLE t1 (
  ts TIMESTAMP(6) DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP(3)
);

时间戳的初始化和空属性

如果explicit_defaults_for_timestamp系统变量被禁用,TIMESTAMP列的默认不为空,不能包含NULL价值与分配无效的将当前时间戳。允许一个TIMESTAMP列包含无效的明确声明,它与NULL属性。在这种情况下,默认值也成为无效的除非重写一个DEFAULT子句指定不同的默认值。默认为空可以显式地指定NULL作为默认值。(一TIMESTAMP列不使用无效的属性,DEFAULT NULL如果是无效的。)TIMESTAMP列证无效的价值分配NULL将其设置为无效的,不到当前时间戳

下表包含几个TIMESTAMP列证无效的价值观:

CREATE TABLE t
(
  ts1 TIMESTAMP NULL DEFAULT NULL,
  ts2 TIMESTAMP NULL DEFAULT 0,
  ts3 TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP
);

TIMESTAMP列证无效的价值观是在当前时间戳在插入时除根据下列条件之一:

换句话说,一个TIMESTAMP列定义为允许无效的自动初始化值只有其定义包括DEFAULT CURRENT_TIMESTAMP

创建表(TS时间戳零违约current_timestamp);

如果TIMESTAMP列证无效的值,但它的定义不包括DEFAULT CURRENT_TIMESTAMP,你必须明确地插入对应当前的日期和时间值。假设表T1t2这些定义:

创建表T1(TS时间戳零违约的0000-00-00 00:00:00”);创建表T2(TS时间戳空默认为空);

设置TIMESTAMP列在表的当前时间戳在插入时,明确指定值。例如:

插入的T2值(current_timestamp);插入T1值(now());

如果explicit_defaults_for_timestamp系统变量是启用,TIMESTAMP列证无效的只有使用价值NULL属性。也,TIMESTAMP列不允许分配无效的将当前时间戳,宣布与NULL不为空属性。将当前时间戳,设置栏CURRENT_TIMESTAMP或同义词等NOW()

11.3.6分数秒的时间值

MySQL 8秒的小数部分的支持TIMEDATETIME,和TIMESTAMP值,以微秒(6位数)精度:

  • 定义一个列,包括小数秒部分,使用语法type_name(fsp),在那里type_nameTIMEDATETIME,或TIMESTAMP,和fsp是分数秒的精度。例如:

    create table T1(t(3小时),DT DateTime(6));

    这个fsp值,如果有,必须在范围0到6。值为0表示没有小数部分。如果省略,默认精度为0。(这不同于标准的SQL默认为6,与以前的版本的兼容性)

  • 插入一个TIMEDATE,或TIMESTAMP值与小数秒部分成一列同类型但舍入少小数数字的结果,如本例所示:

    MySQL的&#62;CREATE TABLE fractest( c1 TIME(2), c2 DATETIME(2), c3 TIMESTAMP(2) );查询行,0行受影响(0.33秒)MySQL &#62;INSERT INTO fractest VALUES&#62;('17:51:04.777', '2014-09-08 17:51:04.777', '2014-09-08 17:51:04.777');查询行,1行的影响(0.03秒)MySQL &#62;SELECT * FROM fractest;------------- ------------------------ ------------------------ | C1 C2 C3 | | | ------------- ------------------------ ------------------------ | 17:51:04.78 | 2014 09 08 17:51:04.78 | 2014 09 08 17:51:04.78 | ------------- ------------------------ ------------------------ 1行在设定(0.00秒)

    没有警告或错误时发生了舍入。这种行为遵循SQL标准,并不是由服务器的影响sql_mode设置

  • 带时间参数的值函数接受分数秒。从时间的函数的返回值包括小数秒为宜。例如,NOW()没有参数返回当前的日期和时间没有小数部分,但作为一个可选的参数从0到6来指定返回值包括小数秒的一部分,许多数字。

  • 时间文字语法产生的时间价值:DATE 'str'时间”str&#39;,和时间戳”str&#39;,和ODBC语法等价物。由此产生的价值包括尾部分如果指定分数秒。此前,时态类型关键字被忽略,这些结构产生的字符串值。看到标准的SQL和ODBC日期和Time Literals

11.3.7之间的转换日期和时间类型

在某种程度上,你可以将一个值从一种类型到另一个时空。然而,可能会有一些变更信息的价值或损失。在所有的情况下,之间的时间类型的转换是受有效值的范围为产生式。例如,虽然DATEDATETIME,和TIMESTAMP价值观都可以用同一套指定格式,类型各不相同的值的范围。TIMESTAMP价值不能早于一千九百七十UTC或晚于'2038-01-19 03:14:07'UTC。这意味着一个日期等“1968-01-01”同时,为有效DATEDATETIME价值,为无效TIMESTAMP值转换为

转换DATE价值观:

  • 转换到一个DATETIMETIMESTAMP价值增加了时间的一部分“00:00:00”因为DATE值不包含时间信息

  • 转换到一个TIME价值是没有用的;结果是“00:00:00”

转换DATETIMETIMESTAMP价值观:

  • 转换到一个DATE值取小数秒到最后的一部分。例如,“1999-12-31 23:59:59.499”成为'1999-12-31',而“1999-12-31 23:59:59.500”成为'2000-01-01'

  • 转换到一个TIME价值报废日期部分因为TIME类型包含日期信息

转换TIME其他时间类型的值,值CURRENT_DATE()is used for the日期。theTIME被解释为经过的时间(没有时间)和添加到日期。这意味着结果的日期部分不同于当前日期如果时间值超出范围“00:00:00”'23:59:59'

假设当前日期是'2012-01-01'TIME“12”'24:00:00',和“12”,当转换为DATETIMETIMESTAMP值,导致“2012年1月1日12:00:00”'2012-01-02 00:00:00',和&#39;知识&#39; 12:00:00,分别

转换TIMEDATE冰discards相似,但从我方的结果:“2012年1月1日”'2012-01-02',和&#39;知识&#39;,分别

显式转换可用于重写的隐式转换。例如,在比较DATEDATETIME价值观的DATE价值是强制的DATETIME通过添加一个时间部分型“00:00:00”。通过忽略时间的部分进行比较DATETIME而不是使用价值,CAST()在下面的功能:

date_col= CAST(datetime_col日期)

转换TIMEDATETIME值以数字形式(例如,通过添加)部分取决于是否值包含一个小数秒。TIME(N)DATETIME(N)转换为整数时N0(或略)和一个十进制的价值N小数位数时N大于0:

MySQL的&#62;SELECT CURTIME(), CURTIME()+0, CURTIME(3)+0;——————| curtime()()| curtime | curtime(3 0 0 |)——————| 09∶28∶00 | 92800 | 92800.887 |——&#62;——MySQL。SELECT NOW(), NOW()+0, NOW(3)+0;--------------------- ---------------- -------------------- |现在(现在)|()(3)0 0 |现在| --------------------- ---------------- -------------------- | 2012 - 08 - 15 9:28点| 20120815092800 | 20120815092800.889 | --------------------- ---------------- --------------------

在日期11.3.8两位数的年

两位数年份日期值是模糊的因为世纪是未知的。这样的价值观必须被解释为4位形式因为MySQL存储年内使用4位。

DATETIMEDATE,和TIMESTAMP类型,MySQL对使用这些规则模糊的年值指定的日期:

  • 在今年的范围值00-69转换为2000-2069

  • 在今年的范围值70-99转换为1970

YEAR,规则是一样的,这一例外:一个数字00插入YEAR(4)结果0000而不是2000。指定零年(4)和它被解释为2000它作为一个字符串,指定“0”'00'

记住这些规则只启发式提供合理的猜测你的数据值是什么意思。如果使用MySQL的规则不产生你需要的值,你必须提供明确的输入包含四位数年份值。

ORDER BY正确的分类YEAR有两位数的年值

一些功能如MIN()MAX()转换YEAR一个数。这意味着一个有两位数年份值不具有这些功能正常工作。在这种情况下,解决方法是将YEAR四位数年份格式

11.4字符串类型

字符串类型CHARVARCHARBINARYVARBINARYBLOBTEXTENUM,和SET。本节介绍如何将这些类型的工作,以及如何使用它们在您的查询。字符串类型的存储要求,见11.8节,“数据类型存储的要求”

11.4.1的char和varchar类型

这个CHARvarchar类型是相似的,但不同的是存储和读取的方法。他们也有不同的最大长度和空格是否保留。

这个CHARvarchar类型和长度表示的最大字符数你想存储声明。例如,CHAR(30)可容纳30字

一个长度CHAR柱固定的长度,你说当你创建表。长度可以从0到255的任何值。什么时候烧焦值存储,他们就用空格填充到指定的长度。什么时候CHAR检索值,空格删除除非PAD_CHAR_TO_FULL_LENGTHSQL模式启用

价值观VARCHAR列是可变长度的字符串。长度可以被指定为从0到65535的一个值。一个有效的最大长度varchar须行大小的最大值(65535个字节,其中所有列共享)和使用的字符集。看到第c.10.4,“限制表的列数和行的大小”

与…对比CHARvarchar值存储为一个字节或字节长度前缀加上数据。长度前缀表示的值的字节数。一列使用一个长度字节如果值要求不超过255个字节,如果值可能需要超过255字节长度的字节。

如果严格的SQL模式不启用,你去分配一个值CHARvarchar柱超过列的最大长度,该值被截断拟合生成警告。对于非空格字符截断,可以导致错误发生(而不是警告),采用严格的SQL模式抑制值插入。看到第5.1.10,”服务器的SQL模式”

VARCHAR列的尾随空格的列长度超过截断之前插入和生成警告,无论在使用SQL模式。为烧焦列,多余的空格插入值截断进行默默的SQL模式。

VARCHAR值不填充保存时。尾随空格时保留值存储和检索,与标准SQL的一致性。

下表说明了之间的差异CHARvarchar通过展示存放各种字符串值为结果CHAR(4)varchar(4)列(假定柱采用单字节字符集等latin1

价值CHAR(4)存储要求VARCHAR(4)存储要求
''' '4字节''1字节
'ab''ab '4字节'ab'3字节
'abcd''abcd'4字节'abcd'五个字节
'abcdefgh''abcd'4字节'abcd'五个字节

显示的值存储在表的最后一行申请只有当不使用严格的模式;如果MySQL是严格模式运行,超过柱长度值不存储,和一个错误的结果

InnoDB固定长度字段大于或等于768字节长度的变长字段的编码,它可以存储页。例如,一个char(255)柱可以超过768字节如果字符集的最大字节长度大于3,因为它是utf8mb4

如果一个给定的值存储到CHAR(4)varchar(4)列,从列检索的值是不一样的,尾随的空格去掉CHAR列在检索。下面的例子说明了这种差异:

MySQL的&#62;CREATE TABLE vc (v VARCHAR(4), c CHAR(4));查询好,为受影响的行(0.01秒)MySQL &#62;INSERT INTO vc VALUES ('ab  ', 'ab  ');查询行,1行的影响(0秒)MySQL &#62;SELECT CONCAT('(', v, ')'), CONCAT('(', c, ')') FROM vc;|,意图,意图concat((V)是| concat()(,,C,|),意图,意图|)(AB)(AB)| |,意图,意图在1行集(0.06秒)

价值观CHARvarchar列排序和比较,根据分配给列的字符集整理。

大多数的MySQL排序规则有一个垫垫属性空间。例外的是Unicode排序规则基于UCA 9.0.0高,其中有没有垫垫属性。(见第10.10.1,“Unicode字符集”

要确定一个整理垫属性,使用INFORMATION_SCHEMACOLLATIONS表,其中有一个pad_attribute专栏

垫属性决定尾随空格是多进制的字符串比较治疗(CHARvarchar,和TEXT值)。没有垫治疗空间排序字符串像任何其他字符结束。PAD的空间排序,尾随空格在比较是微不足道的;字符串比较不考虑任何尾随空格。比较在这种情况下,不包括LIKE模式匹配操作,而尾随的空格是重要的。例如:

MySQL的&#62;CREATE TABLE names (myname CHAR(10));查询行,0行受影响(0.03秒)MySQL &#62;INSERT INTO names VALUES ('Monty');查询行,1行的影响(0秒)MySQL &#62;SELECT myname = 'Monty', myname = 'Monty  ' FROM names;+------------------+--------------------+| myname = 'Monty' | myname = 'Monty  ' |+------------------+--------------------+|                1 |                  1 |+------------------+--------------------+1 row in set (0.00 sec)mysql>SELECT myname LIKE 'Monty', myname LIKE 'Monty  ' FROM names;我的意思是,我的意思是,我的意思是,我的意思是我的意思。

这对所有MySQL版本是真实的,而不是由服务器的SQL模式的影响。

笔记

关于mysql字符集和排序规则的更多信息,参见10章,字符集Unicode排序规则,。有关存储要求的更多信息,参见11.8节,“数据类型存储的要求”

对于那些尾随填充字符被剥离或比较忽略他们,如果列有一个索引,需要独特的价值观,插入的列值,差异仅在数尾垫字符将导致重复键错误。例如,如果一个表包含'a',企图店&#39; &#39;原因有重复的键的错误。

11.4.2的binary和varbinary类型

这个BINARYvarbinary类型是相似的CHARVARCHAR,除了它们包含二进制字符串而不是二进制字符串。那就是,它们包含的字节字符串而不是字符串。这意味着他们有二元的字符集和整理、比较和排序是基于值的字节数值。

允许的最大长度是相同的BINARYvarbinary因为它是CHARVARCHAR,除了长度二元的VARBINARY是一个长度字节而不是字符。

这个BINARYvarbinary数据类型是不同的CHAR BINARYvarchar二进制日期类型。后者for the types,theBINARY属性不会引起柱被视为一个二进制串柱。相反,它使二进制(_bin)设置要使用的列的字符排序,与柱本身所包含的非二进制字符串而不是二进制字节串。例如,CHAR(5) BINARY作为char(5)字符集utf8mb4整理utf8mb4_bin,假设默认字符集utf8mb4。这不同于二进制(5)商店5字节二进制字符串,其中有binary字符集和整理。对于非二进制字符串二进制字符串和二进制排序规则之间的差异信息,看第10.8.5“二进制排序规则相比,_bin排序规则”

如果严格的SQL模式不启用,你去分配一个值BINARYvarbinary柱超过列的最大长度,该值被截断拟合生成警告。为例,截断,可以导致错误发生(而不是警告),采用严格的SQL模式抑制值插入。看到第5.1.10,”服务器的SQL模式”

什么时候BINARY值存储,他们是正确的垫垫值为指定长度。垫的价值0x00(零字节)。价值观是正确的垫0x00在插入,并没有尾随字节删除选择。所有字节比较显著,包括顺序DISTINCT运营0x00字节和空间是不同的比较,与0x00< space.

例子:是BINARY(3)柱,&#39; &#39;成为'a \0'当插入“的”0“成为'a\0\0'当插入。插入值保持不变时,选择。

VARBINARY,有插入和没有字节无填料被选择。所有字节比较显著,包括顺序DISTINCT运营0x00字节和空间是不同的比较,与0x00< space.

对于那些尾随填充字节剥离或比较忽略他们,如果列有一个索引,需要独特的价值观,插入的列值只有数尾垫字节将导致重复键错误不同。例如,如果一个表包含'a',企图店“的”0“导致重复键错误

你应该考虑前面的填充和溶出特性仔细如果你计划使用BINARY数据类型用于存储二进制数据,你需要检索的值完全相同的值存储。下面的示例说明了如何0x00-填充BINARY价值观影响的列值的比较:

MySQL的&#62;CREATE TABLE t (c BINARY(3));查询好,为受影响的行(0.01秒)MySQL &#62;INSERT INTO t SET c = 'a';查询行,1行的影响(0.01秒)MySQL &#62;SELECT HEX(c), c = 'a', c = 'a\0\0' from t;+--------+---------+-------------+| HEX(c) | c = 'a' | c = 'a\0\0' |+--------+---------+-------------+| 610000 |       0 |           1 |+--------+---------+-------------+1 row in set (0.09 sec)

如果值检索必须指定存储没有填充的值相同,它可能是最好使用VARBINARY或在一个BLOB数据类型而不是

11.4.3 BLOB和文本类型

BLOB是一个二进制大型对象可以保存一个可变的数据量。四斑点类型TINYBLOB斑点MEDIUMBLOB,和longblob。这些仅在不同的值的最大长度可容纳。四TEXT类型tinytextTEXTmediumtext,和LONGTEXT。这相当于四斑点类型和具有相同的最大长度和存储要求。看到11.8节,“数据类型存储的要求”

BLOB值被视为二进制字符串(字节串)。他们有二元的字符集和整理、比较和排序是基于列值的字节的数值。TEXT值被视为非二进制字符串(字符串)。他们有一个字符集以外的二元的,和值进行排序和基于角色的排序规则设置比较。

如果严格的SQL模式不启用,你去分配一个值BLOB文本柱超过列的最大长度,该值被截断拟合生成警告。对于非空格字符截断,可以导致错误发生(而不是警告),采用严格的SQL模式抑制值插入。看到第5.1.10,”服务器的SQL模式”

从价值观到插入多余的空格截断TEXT列总是产生一个警告,无论SQL模式。

TEXT斑点列,在插入和没有字节没有填充被选择。

如果一个TEXT列建立索引,索引项比较空间填充结束时。这意味着,如果指数需要独特的价值,重复键错误将发生只有数量的不同值的尾随空格。例如,如果一个表包含&#39; &#39;,企图店'a '导致重复键错误。这是不正确的斑点专栏

在很多方面,你可以把一个BLOB列为VARBINARY柱能随你所愿。同样的,你可以把一个文本列为VARCHAR专栏斑点TEXT不同于VARBINARYVARCHAR在以下几个方面:

  • 索引BLOB文本列,您必须指定一个索引前缀长度。为CHARVARCHAR,一个前缀长度可选。看到第8.3.5,“列索引”

  • BLOB文本列不能有DEFAULT价值观

如果你使用BINARY属性有文本数据类型的列分配二进制(_bin)列的字符集整理

LONGLONG VARCHAR地图的MEDIUMTEXT数据类型。这是一个兼容的特征。

MySQL连接器/ ODBC定义BLOB价值观longvarbinaryTEXT价值观longvarchar

因为BLOB文本值可以是非常长的,你可能会遇到一些限制使用:

每个BLOB文本价值是由一个单独的对象的内部表示。这与所有其他数据类型,用于存储分配每列表时打开。

在某些情况下,可能需要存储二进制数据,如媒体文件BLOB文本专栏你可能会发现MySQL的字符串处理函数用于这样的数据工作。看到12.5节,“字符串函数”。出于安全和其他原因,通常使用这样的应用程序代码而不是让应用程序的用户FILE特权。你可以在MySQL的论坛讨论各种语言和平台的细节(forums.mysql.com http:/ / /

11.4.4枚举类型

一个ENUM是一个从一个列表中的允许值,明确列举在列规范在创建表时选择的值的字符串对象。它具有这些优点:

  • 在这种情况下,列有一组有限的可能值,紧凑的数据存储。指定输入值自动编码为数字的字符串。看到11.8节,“数据类型存储的要求”对于存储要求ENUM类型

  • 可读的查询和输出。数字翻译回查询结果中对应的字符串。

这些潜在的问题需要考虑:

  • 如果你让枚举值,看起来像数字,很容易混淆的字面值与内部指数,解释enumeration限制

  • 使用ENUM顺序条款要求额外的照顾,解释枚举排序

创建和使用枚举列

枚举的值必须是一个引用字符串。例如,你可以用创建一个表ENUM柱像这样:

CREATE TABLE shirts (    name VARCHAR(40),    size ENUM('x-small', 'small', 'medium', 'large', 'x-large'));INSERT INTO shirts (name, size) VALUES ('dress shirt','large'), ('t-shirt','medium'),  ('polo shirt','small');SELECT name, size FROM shirts WHERE size = 'medium';+---------+--------+| name    | size   |+---------+--------+| t-shirt | medium |+---------+--------+UPDATE shirts SET size = 'small' WHERE size = 'large';COMMIT;

插入100万行到这表值'medium'需要100万字节的存储,而不是600万字节,如果你存储的字符串“中”在一个VARCHAR专栏

Enumeration Literals指标值

每个枚举值的指标:

  • 在列规范列出的元素分配指标数,从1开始。

  • 的空字符串错误值的索引值为0。这意味着,你可以使用下面的SELECT声明中找到行为无效枚举价值分配:

    mysql> SELECT * FROM tbl_name WHERE enum_col=0;
    
  • 该指数NULL无效的

  • 术语指数这里指的是一个位置在枚举值的列表。它无关表索引。

例如,一列ENUM('Mercury', 'Venus', 'Earth')可以有任意的值显示在这里。每个值的指标也显示。

价值指数
NULLNULL
''
'Mercury'
'Venus'
'Earth'

一个ENUM柱最多可以有65535个不同的元素。

如果你得到一个ENUM在数字环境中的值,该列的值的索引返回。例如,你可以从一个检索数字值枚举柱像这样:

mysql> SELECT enum_col+0 FROM tbl_name;

等功能SUM()AVG()期待一个数字参数将参数数量如果必要。为枚举值,该指数是用来计算。

Enumeration Literals处理

自动删除空格ENUM成员表中的值的定义,当一个表创建。

在检索时,值存储到一个ENUM柱是用lettercase所用的列定义显示。请注意,枚举列可以被指定一个字符集和整理。二进制或敏感的排序规则,lettercase考虑分配值的列。

如果你存储数为ENUM列数作为指标纳入可能的值,并存储的值是与指数的枚举成员。(然而,这并工作LOAD DATA,它把所有的输入字符串。)如果数值是引用,它仍然是解释为一个指数,如果没有匹配的字符串在枚举值的列表。由于这些原因,这是不可取的定义枚举用枚举值,看起来像数字列,因为这很容易变得混乱。例如,以下列枚举成员的值与字符串'0'“1”,和'2',但数字索引值2,和

numbers ENUM('0','1','2')

如果你的商店2,它被解释为一个索引值,并成为“1”(与指数的值)。如果你的商店'2',它匹配一个枚举值,所以它是存储为“2”。如果你的商店'3',它不匹配任何枚举值,因此它被视为一个指标成为“2”(指数值3)

mysql> INSERT INTO t (numbers) VALUES(2),('2'),('3');
mysql> SELECT * FROM t;
+---------+
| numbers |
+---------+
| 1       |
| 2       |
| 2       |
+---------+

确定所有可能的值ENUM柱,使用SHOW COLUMNS FROM tbl_name LIKE 'enum_col'与解析枚举定义在Type该输出列

在C API,ENUM返回的字符串值。有关使用结果集元数据信息,以区别于其他字符串,看第27.7.5,“C API的数据结构”

空枚举值

枚举的值也可以是空字符串('')或无效的在某些情况下:

  • 如果你将一个无效的值为ENUM(即在允许值列表中不存在的字符串),空字符串插入而不是作为一种特殊的误差值。这个字符串可以区分正常空字符串通过这串数字值0。看到Enumeration Literals指标值关于数字索引的细节为枚举值。

    如果严格的SQL模式启用,试图插入无效ENUM在一个错误的价值观的结果。

  • 如果一个ENUM柱申报许可证无效的,的NULL值列的有效值,默认值是无效的。如果一个ENUM列的声明不为空,其默认值是允许值的列表的第一个元素。

枚举排序

ENUM价值观是基于指数排序,这取决于秩序中,枚举成员在列规范上市。例如,“B”各种各样的前'a'枚举(B,A)。在非空字符串的空字符串类型,和NULL在所有其他枚举值的排序值。

为了防止意外的结果时使用ORDER BY条款上枚举柱,使用这些技术:

  • 指定ENUM按字母顺序列表

  • 确保列进行排序的词汇而不是指数编码ORDER BY CAST(col AS CHAR)为了通过concat(col

enumeration限制

枚举值不能表达,甚至一个计算一个字符串值。

例如,这CREATE TABLE声明并因为工作的CONCAT函数不能被用来构建一个枚举值:

创建表的大小(大小枚举(小,concat(&#39;med &#39;,&#39;ium &#39;),&#39;大&#39;));

你也不能用一个用户变为一个枚举值。这对做报表工作

SET @mysize = 'medium';

CREATE TABLE sizes (
    size ENUM('small', @mysize, 'large')
);

我们强烈建议你做使用数字作为枚举值,因为它不保存在存储在适当的TINYINTSMALLINT式,它是易混淆的字符串和底层的数值(不可能是相同的)如果你的报价枚举价值观不正确。如果你使用一个数作为一个枚举值,总是括在引号。如果引号省略,数量是一个指标。看到Enumeration Literals处理看到一个引用数可能将被作为一个数字索引值。

在定义重复的值会导致一个警告,或者一个错误如果严格的SQL模式启用。

11.4.5集合类型

SET是一个字符串对象可以有零个或多个值,每个必须选择从列表中的允许值指定在创建表时。配置列的值,包括多个集合的成员是由逗号分隔的成员指定的(,)。这样做的后果是,配置成员价值观本身不应该包含逗号。

例如,一列SET('one', 'two') NOT NULL能有这些价值观:

“&#39;&#39;one &#39;&#39;two &#39;&#39;one,两

SET柱最多可以有64个不同的成员。

在定义重复的值会导致一个警告,或者一个错误如果严格的SQL模式启用。

自动删除空格SET成员表中的值的定义,当一个表创建。

在检索时,储存在一个值SET柱是用lettercase所用的列定义显示。请注意,配置列可以被指定一个字符集和整理。二进制或敏感的排序规则,lettercase考虑分配值的列。

MySQL存储SET值的数值,与存储的值对应于第一集成员的低阶位。如果你检索配置在数字环境中的价值,价值的检索有位设置相应的组成员组成的列值。例如,你可以从一个检索数字值SET柱像这样:

MySQL的&#62;SELECT set_col+0 FROM tbl_name;

如果一个数存储到SET柱位,设置的数的二进制表示形式确定列值的集合成员的。为列指定为集(A,B,C,D),成员有下列十进制和二进制值。

SET会员十进制值二进制值
'a'10001
'b'20010
'c'40100
'd'81000

如果你指定一个值9此列,即一千零一在二进制,所以第一和第四SET值的成员&#39; &#39;'d'选择和结果值A,D

对于一个价值包含多于一个SET元,不要紧的要素列出当你插入的值的顺序。它也没有多少给定元素在列出的值。当该值返回后,在值的每个元素出现一次,与列出的元素根据它们的顺序在创建表时指定。例如,假设一个列指定为集(A,B,C,D)

mysql> CREATE TABLE myset (col SET('a', 'b', 'c', 'd'));

如果你插入的值'a,d'“D,”'a,d,d'A,D,&#39;,和'd,a,d'

MySQL的&#62;INSERT INTO myset (col) VALUES -&#62;(A,D),(想,&#39;),(A,D,A),(A,D,D),(会,A,D);查询行,5行受影响(0.01秒)记录:5份:0警告:0

那么所有这些值显示为'a,d'当检索:

MySQL的&#62;SELECT col FROM myset;------ | Col | ------ | A、D | | A、D | | A、D | | A、D | | A、D | ------ 5行集(0.04秒)

如果你设定了一个SET列为不支持的值,该值被忽略并发出警告:

MySQL的&#62;INSERT INTO myset (col) VALUES ('a,d,d,s');查询行,1行的影响,1报警(0.03秒)MySQL &#62;SHOW WARNINGS;--------- ------ ------------------------------------------ |水平|代码|消息| --------- ------ ------------------------------------------ |警告| 1265 |数据截断柱Col在连续1 | --------- ------ ------------------------------------------ 1行集(0.04秒)MySQL &#62;SELECT col FROM myset;------ | Col | ------ | A、D | | A、D | | A、D | | A、D | | A、D | | A、D | ------ 6行集(0.01秒)

如果严格的SQL模式启用,试图插入无效SET在一个错误的价值观的结果。

SET值按数值排序无效的在非排序值—NULL配置价值观

等功能SUM()AVG()期待一个数字参数将参数数量如果必要。为配置价值观,铸造操作导致的数值被用。

Normally,you search forSET值的使用FIND_IN_SET()函数或LIKE运营商:

MySQL的&#62;SELECT * FROM tbl_name WHERE FIND_IN_SET('value',set_col)>0;MySQL的&#62;SELECT * FROM tbl_name WHERE set_col LIKE '%value%';

第一个语句找到行set_col包含value集成员。二是相似的,但不一样:它发现行set_col包含value在任何地方,即使作为一个字符串的另一组成员。

下面的语句也是允许的:

mysql> SELECT * FROM tbl_name WHERE set_col & 1;
mysql> SELECT * FROM tbl_name WHERE set_col = 'val1,val2';

这些声明首先包含第一组成员的值。为精确匹配第二看起来。小心第二类型比较。设定值比较'val1,val2'返回不同的结果比对照值&#39;val2val1&#39;。你要他们在列定义中列出的值指定相同的顺序。

确定了所有可能的值SET柱,使用显示列tbl_name喜欢set_col与解析配置定义在Type该输出列

在C API,SET返回的字符串值。有关使用结果集元数据信息,以区别于其他字符串,看第27.7.5,“C API的数据结构”

11.5空间数据类型

这个开放地理空间联盟(OGC)是250多家企业、机构的一个国际财团,和大学参与公开概念的解决方案,可以是有用的各种应用,空间数据管理的发展。

开放地理空间联盟发布OpenGIS标准?实现地理信息的简单功能接入2部分:SQL选项文件提出,扩展SQL数据库支持空间数据概念的若干方法。本规范可从OGC的网站http:/ / / / www.opengeospatial.org标准SFS

遵循OGC规范,MySQL实现空间扩展的子集SQL与几何类型环境这个术语指的是一个SQL环境已经扩展了一套几何类型。一个几何值的SQL列为列有几何类型的实现。该规范描述了一组SQL几何类型,以及这些类型的创建和分析几何值函数。

MySQL空间的扩展使生成,存储,和地理特征分析:

  • 为代表的空间值的数据类型

  • 操纵空间的价值功能

  • 改进的访问时间空间柱空间索引

空间数据类型和函数可用于MyISAMInnoDB,和ARCHIVE表索引空间列,MyISAMInnoDB支持空间与非—SPATIAL指标。其他存储引擎支持非—空间指标,如第13.1.14,“创建索引的语法”

地理特征是什么在世界上有一个位置。一个功能可以:

  • 一个实体。例如,一座山,一个池塘,一个城市。

  • 一个空间。例如,城镇地区,热带地区。

  • 一个自定义的位置。例如,一个十字路口,作为一个特殊的地方,两街相交。

一些文档使用的术语地理特征指地理特征

几何是另一个词表示的地理特征。原来的词几何意味着大地测量。另一种含义是指制图、几何特征,制图员用世界地图。

这里的讨论,认为这些术语的同义词:地理特征地理特征功能特色,或几何。这个词最常用的是几何,定义为一个点或代表任何东西在世界上有一个定位点的集合

以下材料覆盖这些话题:

  • 在MySQL模型实现了空间数据类型

  • 在OpenGIS的几何模型的空间扩展的基础

  • 用于表示空间数据的数据格式

  • 如何在MySQL中使用空间数据

  • 利用空间数据索引

  • 从MySQL OpenGIS规范的差异

关于功能上的操作空间数据,看12.15节,“空间分析功能”

额外资源

这些标准对空间操作mysql执行很重要:

如果你有关于MySQL扩展空间的使用问题,你可以在他们的GIS论坛讨论:forums.mysql.com http:/ / / list.php?23

11.5.1空间数据类型

MySQL有空间数据类型对应的类的类型。对于这些类型的基础上进行了第11.5.2,“空间几何模型”

一些持有单一的几何空间数据类型值:

  • GEOMETRY

  • POINT

  • LINESTRING

  • POLYGON

GEOMETRY可以存储任何类型的几何值。其他的单值类型(LINESTRING,和多边形限制值)的一个特定的几何型。

其他空间数据类型值的集合:

  • MULTIPOINT

  • MULTILINESTRING

  • MULTIPOLYGON

  • GEOMETRYCOLLECTION

GEOMETRYCOLLECTION可以存储任何类型的对象的集合。其他集合类型(多点MULTILINESTRINGmultipolygon,和GEOMETRYCOLLECTION)限制收集会员对那些具有特定几何型。

例如:创建一个表名geom有一个叫作G可以存储任何几何类型的值,用这个语句:

CREATE TABLE geom (g GEOMETRY);

SPATIAL索引可以创建不为空空间列,所以如果你计划指标列,宣布NOT NULL

create table(G槽几何尺寸空);

随着空间数据类型的列可以有一个SRID属性,明确表示的空间参考系统(SRS)存储在列中的值。例如:

创建表空间(P点不空SRID 0,几何不空SRID 4326);

InnoDB表证SRIDcartesian values for SRSS和地理。MyISAM表证SRID笛卡尔的SRSS方法的价值。

这个SRID属性使得空间柱SRID的限制,具有这些含义:

  • 列只能包含与给定的SRID值。试图插入值具有不同的扩散产生一个错误。

  • 优化器可以使用SPATIAL在列索引。看到第8.3.3,“空间索引优化”

没有空间列SRID属性不扩散限制和接受任何方案的价值。然而,优化器不能使用空间索引到列定义被修改为包括一个SRID属性,它可能需要的栏目内容第一被修改后,所有的值都有相同的扩散。

其他的例子展示了如何在MySQL中使用的空间数据类型,看第11.5.6,“创造空间列”。关于空间参考系统的信息,参见第11.5.5,“空间参考系统的支持”

11.5.2 OpenGIS的几何模型

OGC提出的几何类型的设置SQL与几何类型环境是基于OpenGIS几何模型。在这个模型中,每个几何对象具有以下基本特性:

  • 这是一个空间参考系统有关,它描述的坐标空间中定义的对象。

  • 它属于一些几何课

11.5.2.1几何类层次结构

几何类定义一个层次结构如下:

  • Geometry(不可抗拒的)

    • Point(可承受)

    • Curve(不可抗拒的)

      • LineString(可承受)

        • Line

        • LinearRing

    • Surface(不可抗拒的)

      • Polygon(可承受)

    • GeometryCollection(可承受)

      • MultiPoint(可承受)

      • MultiCurve(不可抗拒的)

        • MultiLineString(可承受)

      • MultiSurface(不可抗拒的)

        • MultiPolygon(可承受)

这是不可能建立在noninstantiable类的对象。它可以在实例化的类创建对象。所有的班级都有属性,并可实例化的类也可以有断言(规则定义有效的类的实例)。

Geometry是基类。它是一个抽象类。子类的实例化几何被限制到零,一,二维几何对象在二维坐标空间的存在。所有实例化的几何类的定义,一个几何级的有效实例闭(即所有定义的几何形状包括边界)。

基地Geometry类的子类Curve表面,和GeometryCollection

  • Point代表零维物体

  • Curve代表一维物体,具有类线子类,Linelinearring

  • Surface设计了二维对象和类多边形

  • GeometryCollection有专门的零,一,二维集合类命名多点MultiLineString,和多面对应于集合的几何建模Points线要素,和Polygons,分别多重MultiSurface介绍了抽象类,推广了采集接口处理曲线Surfaces

Geometry曲线Surface多重,和MultiSurface被定义为noninstantiable类。他们为自己的子类定义的方法,包括一套通用的可扩展性。

Point线Polygon混合数据类型MultiPoint线集合,和MultiPolygon是可实例化的类

11.5.2.2几何课

Geometry是层次结构的根类。这是一个noninstantiable类,但有一些性质,以下列表中所描述的,是从任何的创造共同价值几何几何子类。特定的子类都有自己特定的属性,描述。

几何性质

一个几何的价值具有以下特性:

  • 它的类型。每个几何属于其中的一个实例化的类层次结构。

  • 它的SRID,或空间参考标识符。这个值确定的几何相关的空间参考系统,介绍了坐标空间中定义的几何对象。

    在MySQL的SRID值与几何值相关联的一个整数。最大可用SRID值是2三十二?1。如果一个更大的值,只使用较低的位。

    SRID 0表示无限平面直角平面没有单位分配给它的轴。为了确保SRID 0行为,使用SRID 0创建几何值。SRID 0是新几何值如果没有指定默认SRID。

    在多个几何值计算,所有的值必须具有相同的扩散或发生错误。

  • 它的协调在其空间参考系统,作为双精度数(字节)。所有非空的几何形状包括至少一对(x,y)坐标。空的几何形状不包含坐标。

    坐标的SRID相关。例如,在不同的坐标系统,两个物体之间的距离甚至当对象具有相同的坐标系不同,因为在距离平面坐标系上的距离大地系统(在地球的表面坐标)是不同的东西。

  • 它的内部边界,和外部

    每一个几何占据空间位置。一个几何外观都不是由几何占据空间。内部是由几何空间。边界是几何的内部和外部之间的接口。

  • 它的膜生物反应器(最小边界矩形),或信封。这是几何边界,由最小值和最大值(x,y)坐标的形成:

    ((MINX MINY, MAXX MINY, MAXX MAXY, MINX MAXY, MINX MINY))
    
  • 是否值简约不简单。。。。。。。几何类型(值)LineString多点MultiLineString)或简单或复杂。各类型决定简单或复杂的断言。

  • 是否值关闭不封闭。。。。。。。几何类型(值)LineString)是封闭或不封闭。各类型决定关闭或不关闭自己的断言。

  • 是否值空的非空如果它没有任何点的几何是空的。外观,内饰,和一个空的几何边界是未定义的(也就是说,他们是由一个NULL值)。一个空的几何定义总是简单,零区。

  • 它的。一个几何可以有?1,0,1或2维:

    • 一个空的几何?

    • 0对于一个没有长度,没有面积几何。

    • 1一个非零的几何长度和零区。

    • 2一个非零区域几何

    Point对象有一个零维线对象1维Polygon对象有两个维度。尺寸多点MultiLineString,和多面对象是作为他们组成元件的尺寸相同。

11.5.2.3点类

Point是一个几何表示在坐标空间中的一个位置。

Point实例

  • 想象一下,一个大型的世界地图,许多城市。一Point对象可以代表每个城市。

  • 在一个城市地图,一Point对象可以代表一个公共汽车站。

Point性能

  • X坐标值

  • 的Y坐标值

  • Point被定义为10维几何

  • 一个边界Point是空集

11.5.2.4曲线类

Curve是一个一维的几何形状,通常由一系列点。特定的子类曲线定义的类型的插值点之间。Curve是一个noninstantiable类。

Curve性能

  • Curve有它的点的坐标

  • Curve被定义为一个一维几何。

  • Curve如果它不通过同一点的两次简单,除一曲线仍然可以简单,如果起点和终点都是一样的。

  • Curve如果它的出发点,等于其端点闭合。

  • 一个封闭的边界Curve是空的

  • 一个非闭合的边界Curve由它的两个端点

  • Curve这是简单的和封闭的是linearring

11.5.2.5线类

LineString是一个曲线点与点之间的线性插值。

LineString实例

  • 在世界地图上,LineString对象可以代表河流

  • 在一个城市地图,LineString对象可以代表街道

LineString性能

  • LineString坐标有段,每个连续的点对的定义。

  • LineString是一个线如果它由两个点

  • LineString是一个linearring如果它是封闭的,简单的。

11.5.2.5表面层

Surface是一个二维几何。这是一个noninstantiable类。它的唯一可实例化的类多边形

Surface性能

  • Surface被定义为一个二维几何。

  • OpenGIS规范定义了一个简单的Surface作为一个几何体,由一个单一的补丁这是一个单一的外部边界和零个或多个内部边界相关的。

  • 一个简单的边界Surface是对应于其外部和内部边界封闭曲线的设置。

11.5.2.7多边形类

Polygon是一个平面表面多边的几何表示。它是由一个单一的外部边界和零个或多个内部边界的定义,其中每个内部边界定义的一个洞里Polygon

Polygon实例

  • 在区域地图,Polygon对象可以代表森林区,等等。

Polygon断言

  • 一个边界Polygon由一组linearring对象(即,LineString这是简单的和封闭的对象),使其内部和外部的界限。

  • Polygon没有戒指,交叉。在一个边界环多边形可能相交于Point,但只是作为一个切线。

  • Polygon没有台词,穗状花序,或刺。

  • Polygon有一个内部是一个连接点集。

  • Polygon好吧外部的多边形孔不连接。每个孔的定义了一个连接的组件的外观。

前面的断言使Polygon一个简单的几何图形

11.5.2.8 geometrycollection舱

GeomCollection是一个几何,是一个集零个或更多的任何类别的几何形状。

GeomCollection混合数据类型是同义词,与GeomCollection首选的类型名称

在一个几何集合中的所有元素必须在同一个空间参考系统(即在同一坐标系统)。有一个几何集合的元素没有其他限制,虽然子类GeomCollection在下面的章节中描述可能限制会员。限制是基于:

  • 元素类型(例如,一个MultiPoint可能只包含元素)

  • 在元素之间的空间重叠度约束

多点11.5.2.9类

MultiPoint是一个由几何集合元素点是不以任何方式连接或命令。

MultiPoint实例

  • 在世界地图上,一个MultiPoint可能是一个小岛屿链

  • 在一个城市地图,一MultiPoint可以代表一个售票网点。

MultiPoint性能

  • MultiPoint是一个零维几何

  • MultiPoint很简单,如果没有它的两的值是相等的(具有相同的坐标值)。

  • 一个边界MultiPoint是空集

11.5.2.10多重类

MultiCurve是一个由几何集合曲线元素MultiCurve这是一种不可抗拒的语言。

MultiCurve性能

  • MultiCurve是一个一维的几何

  • MultiCurve很简单,当且仅当其所有的元素都是简单的;之间的任何两个元素出现在点,对这两个元素的边界唯一的路口。

  • MultiCurve边界是通过采用国防部2联盟规则(也被称为奇偶律):一个点是在一个边界MultiCurve如果它是一个奇数的界限曲线元素

  • MultiCurve如果所有的元素都关闭。

  • 一个封闭的边界MultiCurve永远是空的

11.5.2.11 multilinestring类

MultiLineString是一个多重几何集合组成LineString元素

MultiLineString实例

  • 在一个地区的地图,一MultiLineString可以代表河流或公路系统。

11.5.2.12多面类

MultiSurface是一个由表面的几何元素的集合。多面是一个noninstantiable类。它的唯一可实例化的类MultiPolygon

MultiSurface断言

  • 内的表面MultiSurface没有内部相交

  • 内的表面MultiSurface有相交的最在一个有限数量的分界线。

11.5.2.13 multipolygon类

MultiPolygon是一个多面对象组成的Polygon元素

MultiPolygon实例

  • 在一个地区的地图,一MultiPolygon可以代表一个湖泊系统。

MultiPolygon断言

  • MultiPolygon没有两多边形元素的内部,相交

  • MultiPolygon没有两多边形元素的交叉(交叉也由以前的断言禁止),或碰在了无数个点。

  • MultiPolygon可能没有切割线,穗状花序,或刺。一多面是一个普通的、封闭的点集。

  • MultiPolygon有一个以上的多边形有一个内部没有连接。对内部连接组件的数量MultiPolygon数量相等的多边形中的值MultiPolygon

MultiPolygon性能

  • MultiPolygon是一个二维几何

  • MultiPolygon边界是一组闭合曲线(线值)对应的边界Polygon元素

  • 每个Curve在边界多面在一个确切的边界Polygon元素

  • 每一个Curve在一个边界多边形元中的边界MultiPolygon

11.5.3支持空间数据格式

两个标准的空间数据格式来表示几何对象查询:

  • 著名的文字(WKT)格式

  • 众所周知的二进制(WKB)格式

在内部,MySQL存储几何值的格式,要么是不相同的WKT或WKB格式。(内部格式如WKB但与最初的4个字节表示SRID。)

可以有不同的数据格式之间的转换功能;看第12.15.6,几何格式转换功能”

以下各节描述空间数据格式MySQL使用:

著名的文字(WKT)格式

著名的文本(WKT)几何值表示的是专为ASCII形式的几何数据交换。OpenGIS规范提供了一个Backus Naur的语法指定正式生产书写规则WKT值(见11.5节,“数据类型”

对几何对象的WKT表示例子:

  • Point

    (15分)

    点的坐标是没有分隔逗号指定。这不同于SQL语法Point()功能,这就需要一个逗号之间的坐标。注意使用适当的一个给定的空间操作的上下文的语法。例如,下面的语句都使用ST_X()从提取的x坐标目标第一个产生的对象直接使用Point()功能。第二采用WKT表示转换成ST_GeomFromText()

    MySQL的&#62;SELECT ST_X(Point(15, 20));| ST _ ------------------------ X(点(15,20)| ------------------------ |>15 | ------------------------ MySQLSELECT ST_X(ST_GeomFromText('POINT(15 20)'));| --------------------------------------- _ X(ST ST _ geomfromtext(点(15)15)| --------------------------------------- | | ---------------------------------------
  • LineString四分:

    线(0 0,10 10,20 25,50 60)

    点坐标对用逗号分隔

  • Polygon一个外环和内环:

    多贡((0 010 010 10人10,0 0 0 0 0),(5 5.7 5.7 7.5 7,5 5))
  • MultiPoint3价值观:

    MULTIPOINT(0 0, 20 20, 60 60)
    

    空间等功能ST_MPointFromText()ST_GeomFromText()接受WKT格式表示多点值允许个人点的值是括号包围。例如,下面的函数调用都是有效的:

    ST_MPointFromText('MULTIPOINT (1 1, 2 2, 3 3)')
    ST_MPointFromText('MULTIPOINT ((1 1), (2 2), (3 3))')
    
  • MultiLineString线价值观:

    MULTILINESTRING((10 10, 20 20), (15 15, 30 15))
    
  • MultiPolygon多边形价值观:

    MULTIPOLYGON(((0 0,10 0,10 10,0 10,0 0)),((5 5,7 5,7 7,5 7, 5 5)))
    
  • GeometryCollection由两值一LineString

    geometrycollection(点,点(10)(30),linestring(15,20))

众所周知的二进制(WKB)格式

著名的二进制(WKB)几何值表示用于几何数据为二进制流为代表的交换BLOB含几何WKB信息值。这种格式是由OpenGIS规范的定义(见11.5节,“数据类型”)。也正是在ISO定义第3部分:SQL / mm的空间标准

WKB使用字节无符号整数,4字节无符号整数,字节和双精度数(IEEE 754格式)。一个8位字节。

例如,一个参数的值对应于POINT(1 -1)由这21个字节的序列,每个代表的两个十六进制数:

0101000000000000000000f03f000000000000f0bf

序列由下表中显示的组件。

表11.2 WKB组件的例子

组件大小价值
字节顺序1字节01
WKB型4字节01000000
X坐标8字节000000000000F03F
Y坐标8字节000000000000F0BF

构件表示如下:

  • 字节顺序标志是1或0表示小端或大端存储。小端和大端字节顺序也被称为网络数据表示(NDR)和外部数据表示(XDR),分别。

  • WKB型是一个代码,表示的几何型。从1到7的值,MySQL的使用说明Point线Polygon多点MultiLineString多面,和GeometryCollection

  • Point值为X和Y坐标,各表示一个双精度值。

WKB近似值为更复杂的几何值有更复杂的数据结构,如在OpenGIS规范详细。

内部几何存储格式

MySQL存储几何值使用4个字节表示SRID遵循价值的WKB表示。为说明WKB格式,见众所周知的二进制(WKB)格式

为WKB的一部分,这些MySQL特定的注意事项:

  • 字节顺序标志字节是1因为MySQL存储几何小终止值。

  • MySQL支持几何类型Point线Polygon多点MultiLineString多面,和GeometryCollection。不支持其他几何类型。

  • 只有GeometryCollection可以是空的。这样一个值存储0元。

  • 可指定多边形环顺时针或逆时针。MySQL的翻转环自动读取数据时。

直角坐标存储在空间参考系统的长度单位,随着x值的x坐标和y值在Y坐标。轴方向的空间参考系统指定。

地理坐标存储在空间参考系统的角度单位,在Y在X坐标经度和纬度坐标。轴方向和经络的空间参考系统指定。

这个LENGTH()函数返回值存储在所需的字节空间。例子:

MySQL的&#62;SET @g = ST_GeomFromText('POINT(1 -1)');MySQL的&#62;SELECT LENGTH(@g);------------ |长度(@ G)| ------------ | 25 | ------------ MySQL &#62;SELECT HEX(@g);---------------------------------------------------- |十六进制(@(G)| ---------------------------------------------------- | 101000000000000000000f03f000000000000f0bf | ---------------------------------------------------- 000000000

的值的长度是25个字节,由这些组件(可以从十六进制值显示):

  • 4字节整数标识(0)

  • 1 byte for integer byte order (1 = little-endian)

  • 4 bytes for integer type information (1 =Point

  • 8字节的双精度X坐标(1)

  • 8字节的双精度Y坐标(?1)

11.5.4几何的合法性和有效性

几何值,MySQL之间的概念语法形成几何有效区分。

一个几何语法如果它满足如在这种条件下形成的(不完全)列表:

  • 线要素至少有两点

  • 多边形至少有一个环

  • 多边形环是封闭的(第一个和最后一个点相同)

  • 多边形环至少有4点(最小多边形是一个与第一个和最后一个点相同的三角形)

  • 集合不是空的(除GeometryCollection

如果是语法形成满足这个条件如几何几何有效(-)列表:

  • 不自相交多边形

  • 多边形的内部环内外环

  • multipolygons不重叠的多边形

如果一个图形是不合乎语法的空间功能失败。空间导入函数分析WKT或WKB值提高一个错误尝试创建一个几何不合乎语法。句法格式也是检查试图存储的几何形状的表。

它允许插入、选择和更新几何无效的几何形状,但必须合乎语法。由于计算的费用,MySQL不检查明确的几何性。空间计算可以检测一些无效的几何形状案件引发错误,但他们也可能未定义的结果没有检测无效退货。需要有效的几何形状的几何应用应该检查他们使用ST_IsValid()功能

11.5.5空间参考系统的支持

空间参考系统(SRS)的空间数据是一个基于地理位置的坐标系统。

有不同类型的空间参考系统:

  • 预计的SRS是一个投影的地球仪固定在一个平面上,平面图。例如,在一个全球照耀着纸圆筒周围的地球工程图纸上一个灯泡。结果是:每个点的地理坐标映射到地球上的一个地方。在平面坐标系统是使用的长度单位(米、英尺、直角等等),而不是经纬度。

    在这种情况下,地球是椭球体;即扁球。地球的南北轴比其东西轴线短一点,所以稍扁平球体是比较正确的,但完美的球体允许更快的计算。

  • 一个地理SRS是一nonprojected SRS代表经度纬度(或经纬度)椭球面上的坐标,在任何角度单位。

  • SRS表示在SRID 0 MySQL是一个无限平面笛卡尔平面没有单位分配给它的轴。不像预计的SRSs,这是不匹配,这并不一定代表地球。这是一个抽象的平面,可用于任何。SRID 0是在MySQL数据库中空间数据的默认SRID。

MySQL保持信息可用的空间参考系统的数据字典中的空间数据mysql.st_spatial_reference_systems表,可以存储项投影和地理SRSs。这一数据字典表是无形的,但SRS词条内容都可以通过information_schemaST_SPATIAL_REFERENCE_SYSTEMS表观,为实现mysql.st_spatial_reference_systems(见24.25节,“information_schema st_spatial_reference_systems表”

下面的示例显示什么SRS进入看起来像:

mysql> SELECT *
       FROM INFORMATION_SCHEMA.ST_SPATIAL_REFERENCE_SYSTEMS
       WHERE SRS_ID = 4326\G
*************************** 1. row ***************************
                SRS_NAME: WGS 84
                  SRS_ID: 4326
            ORGANIZATION: EPSG
ORGANIZATION_COORDSYS_ID: 4326
              DEFINITION: GEOGCS["WGS 84",DATUM["World Geodetic System 1984",
                          SPHEROID["WGS 84",6378137,298.257223563,
                          AUTHORITY["EPSG","7030"]],AUTHORITY["EPSG","6326"]],
                          PRIMEM["Greenwich",0,AUTHORITY["EPSG","8901"]],
                          UNIT["degree",0.017453292519943278,
                          AUTHORITY["EPSG","9122"]],
                          AXIS["Lat",NORTH],AXIS["Long",EAST],
                          AUTHORITY["EPSG","4326"]]
             DESCRIPTION:

本条目描述用于GPS系统SRS。它有一个名字(SRS_NAMEWGS 84)和AP(IDSRS _ ID)4326,这是用的ID欧洲石油调查组(EPSG)

SRS定义在DEFINITION柱WKT值,表示为指定的开放地理空间联盟文件OGC 12-063r5

SRS_ID值代表的是同一种价值观为空间功能的扩散参数传递。SRID 0(无单位的直角平面)是特殊的。它始终是一个合法的空间参考系统ID可用于对空间数据依赖SRID值计算。

在多个几何值计算,所有的值必须具有相同的扩散或发生错误。

SRS定义解析发生在需求时,定义由GIS功能的需要。解析定义缓存在数据字典缓存以便解析开销不是每个语句需要SRS信息发生。

使存储在数据字典中的条目的SRS操作,MySQL提供了这些SQL语句:

11.5.6创造空间列

MySQL提供了一个标准的几何类型,创造空间列为例,与CREATE TABLEALTER TABLE。空间列支持MyISAMInnoDBNDB,和ARCHIVE表又见注释空间指标下部分11.5.10,创建空间索引”

随着空间数据类型的列可以有一个srID属性,明确表示的空间参考系统(SRS)存储在列中的值。对于一个srID限制柱的影响,见第11.5.1,“数据类型”

  • 使用CREATE TABLE声明一个列创建一个表空间:

    create table(G的几何尺寸);
  • 使用ALTER TABLE语句来添加或删除一个空间列或从现有的表:

    修改表的几何加PT点;改变表几何滴PT;

11.5.7填充空间列

在您创建空间栏目,你可以用数据填充它们。

值应存储在内部的几何形式,但是你可以将它们的格式,从著名的文字(WKT)或众所周知的二进制(WKB)格式。下面的示例演示如何插入几何值插入表中的值的内部几何格式转换WKT:

  • 直接在执行转换INSERT声明:

    INSERT INTO geom VALUES (ST_GeomFromText('POINT(1 1)'));SET @g = 'POINT(1 1)';INSERT INTO geom VALUES (ST_GeomFromText(@g));
  • 在执行转换INSERT

    SET @g = ST_GeomFromText('POINT(1 1)');INSERT INTO geom VALUES (@g);

下面的例子将更复杂的几何形状的表:

SET @g = 'LINESTRING(0 0,1 1,2 2)';
INSERT INTO geom VALUES (ST_GeomFromText(@g));

SET @g = 'POLYGON((0 0,10 0,10 10,0 10,0 0),(5 5,7 5,7 7,5 7, 5 5))';
INSERT INTO geom VALUES (ST_GeomFromText(@g));

SET @g =
'GEOMETRYCOLLECTION(POINT(1 1),LINESTRING(0 0,1 1,2 2,3 3,4 4))';
INSERT INTO geom VALUES (ST_GeomFromText(@g));

前面的示例使用ST_GeomFromText()创建几何值。你也可以使用特定类型的功能:

SET @g = 'POINT(1 1)';INSERT INTO geom VALUES (ST_PointFromText(@g));SET @g = 'LINESTRING(0 0,1 1,2 2)';INSERT INTO geom VALUES (ST_LineStringFromText(@g));SET @g = 'POLYGON((0 0,10 0,10 10,0 10,0 0),(5 5,7 5,7 7,5 7, 5 5))';INSERT INTO geom VALUES (ST_PolygonFromText(@g));SET @g ='GEOMETRYCOLLECTION(POINT(1 1),LINESTRING(0 0,1 1,2 2,3 3,4 4))';INSERT INTO geom VALUES (ST_GeomCollFromText(@g));

客户端应用程序要使用的几何值WKB表示负责发送正确形成WKB在查询服务器。有几种方法来满足这一要求。例如:

  • 插入一个POINT(1 1)进制文字语法价值:

    插入到一个值(ST _ geomfromwkb(X 0101000000000000000000f03f000000000000f03f);
  • ODBC应用程序可以发送一个WKB表示,占位符的使用参数绑定BLOB类型:

    插入一个值(st_geomfromwkb(?))

    其他的编程接口可以支持类似占位符机制。

  • 在C程序中,你可以逃避一个二进制值的使用mysql_real_escape_string_quote()包括一个发送到服务器的查询字符串的结果。看到第27.7.7.56,“mysql_real_escape_string_quote()”

11.5.8获取空间数据

表中存储的几何值可以在内部格式读取。你也可以将其转换为WKT或WKB格式。

  • 获取空间数据的内部格式:

    取几何值使用的内部格式可以在表表调剂是有用的:

    CREATE TABLE geom2 (g GEOMETRY) SELECT g FROM geom;
    
  • 获取空间数据的WKT格式:

    这个ST_AsText()函数将从内部格式的几何到WKT字符串。

    选择st_astext(G)从几何;
  • 获取空间数据的WKB格式:

    这个ST_AsBinary()函数将从内部格式的几何的一个BLOB回答WKB Value

    选择st_asbinary(G)从几何;

11.5.9优化空间分析

MyISAMInnoDB表,搜索业务列包含空间数据可以优化使用SPATIAL指标。最典型的操作是:

  • 这包含一个给定的点的所有对象的搜索点查询

  • 区域查询,搜索所有对象的重叠的某一区域

MySQL的使用二次劈树SPATIAL空间列的索引。一空间指数用最小边界矩形(MBR)建立的几何。对于大多数的几何形状,MBR是一个最小矩形包围的几何形状。用于水平或垂直线,MBR是矩形退化为线。一点,MBR是矩形退化为点。

它也可能在正常空间列创建索引。在一个非—SPATIAL指数,你必须指定一个前缀的除了任何空间柱专栏

MyISAMInnoDB支持SPATIAL与非—空间指标。其他存储引擎支持非—SPATIAL指标,如第13.1.14,“创建索引的语法”

11.5.10创建空间索引

InnoDBMyISAM表,MySQL可以使用类似语法创建普通索引创建空间索引,但使用SPATIAL关键词空间索引的列必须声明不为空。下面的示例演示如何创建空间索引:

  • CREATE TABLE

    create table(G槽几何尺寸的空的空间指数(G));
  • ALTER TABLE

    创建表的几何(几何不为空);改变表几何添加空间索引(G);
  • CREATE INDEX

    create table(G槽几何尺寸空);创建在线空间几何指数G(g);

SPATIAL INDEX创建一个索引。存储引擎,支持空间柱空间索引引擎创建一个B-树索引。对空间价值的B树索引是有用的精确值的查找,而不是范围扫描。

优化器可以使用空间索引的列定义,扩散限制。有关更多信息,参见第11.5.1,“数据类型”,和第8.3.3,“空间索引优化”

在索引空间列的更多信息,参见第13.1.14,“创建索引的语法”

下降的空间索引,使用ALTER TABLEDROP INDEX

例如:假设一个表geom包含超过32000几何,这是存储在列G类型GEOMETRY。桌子上也有一个汽车_增量专栏fid储存在对象的ID值

MySQL的&#62;DESCRIBE geom;------- ---------- ------ ----- --------- ---------------- |场|型|空|关键|默认|额外| ------- ---------- ------ ----- --------- ---------------- | FID | int(11)| | PRI |空| auto_increment | | G |几何| | | | | ------- ---------- ------ ----- --------- ---------------- 2行集(0.001秒)MySQL &#62;SELECT COUNT(*) FROM geom;---------- |计数(*)| ---------- | 32376 | ---------- 1行集(0秒)

在列添加索引g使用此语句:

MySQL的&#62;ALTER TABLE geom ADD SPATIAL INDEX(g);查询行,32376行受影响(4.05秒)记录:32376份:0警告:0

11.5.11使用空间索引

优化器调查是否可用空间索引可以参与使用功能如查询搜索MBRContains()MBRWithin()哪里条款.下面的查询发现,在给定的矩形对象:

mysql> SET @poly =
    -> 'Polygon((30000 15000,
                 31000 15000,
                 31000 16000,
                 30000 16000,
                 30000 15000))';
mysql> SELECT fid,ST_AsText(g) FROM geom WHERE
    -> MBRContains(ST_GeomFromText(@poly),g);
+-----+---------------------------------------------------------------+
| fid | ST_AsText(g)                                                  |
+-----+---------------------------------------------------------------+
|  21 | LINESTRING(30350.4 15828.8,30350.6 15845,30333.8 15845,30 ... |
|  22 | LINESTRING(30350.6 15871.4,30350.6 15887.8,30334 15887.8, ... |
|  23 | LINESTRING(30350.6 15914.2,30350.6 15930.4,30334 15930.4, ... |
|  24 | LINESTRING(30290.2 15823,30290.2 15839.4,30273.4 15839.4, ... |
|  25 | LINESTRING(30291.4 15866.2,30291.6 15882.4,30274.8 15882. ... |
|  26 | LINESTRING(30291.6 15918.2,30291.6 15934.4,30275 15934.4, ... |
| 249 | LINESTRING(30337.8 15938.6,30337.8 15946.8,30320.4 15946. ... |
|   1 | LINESTRING(30250.4 15129.2,30248.8 15138.4,30238.2 15136. ... |
|   2 | LINESTRING(30220.2 15122.8,30217.2 15137.8,30207.6 15136, ... |
|   3 | LINESTRING(30179 15114.4,30176.6 15129.4,30167 15128,3016 ... |
|   4 | LINESTRING(30155.2 15121.4,30140.4 15118.6,30142 15109,30 ... |
|   5 | LINESTRING(30192.4 15085,30177.6 15082.2,30179.2 15072.4, ... |
|   6 | LINESTRING(30244 15087,30229 15086.2,30229.4 15076.4,3024 ... |
|   7 | LINESTRING(30200.6 15059.4,30185.6 15058.6,30186 15048.8, ... |
|  10 | LINESTRING(30179.6 15017.8,30181 15002.8,30190.8 15003.6, ... |
|  11 | LINESTRING(30154.2 15000.4,30168.6 15004.8,30166 15014.2, ... |
|  13 | LINESTRING(30105 15065.8,30108.4 15050.8,30118 15053,3011 ... |
| 154 | LINESTRING(30276.2 15143.8,30261.4 15141,30263 15131.4,30 ... |
| 155 | LINESTRING(30269.8 15084,30269.4 15093.4,30258.6 15093,30 ... |
| 157 | LINESTRING(30128.2 15011,30113.2 15010.2,30113.6 15000.4, ... |
+-----+---------------------------------------------------------------+
20 rows in set (0.00 sec)

使用EXPLAIN检查的方式执行此查询:

MySQL的&#62;SET @poly =-&#62;'Polygon((30000 15000,
                 31000 15000,
                 31000 16000,
                 30000 16000,
                 30000 15000))';MySQL的&#62;EXPLAIN SELECT fid,ST_AsText(g) FROM geom WHERE-&#62;MBRContains(ST_GeomFromText(@poly),g)\G*************************** 1。行***************************编号:1 select_type:简单表:几何类型:rangepossible_keys:G键:G key_len:32编号:空50行:额外的:用其中1行集(0秒)

检查没有空间索引会发生什么:

mysql> SET @poly =
    -> 'Polygon((30000 15000,
                 31000 15000,
                 31000 16000,
                 30000 16000,
                 30000 15000))';
mysql> EXPLAIN SELECT fid,ST_AsText(g) FROM g IGNORE INDEX (g) WHERE
    -> MBRContains(ST_GeomFromText(@poly),g)\G
*************************** 1. row ***************************
           id: 1
  select_type: SIMPLE
        table: geom
         type: ALL
possible_keys: NULL
          key: NULL
      key_len: NULL
          ref: NULL
         rows: 32376
        Extra: Using where
1 row in set (0.00 sec)

执行SELECT声明没有空间索引产生相同的结果,但使得执行时间从0秒增加到0.46秒:

MySQL的&#62;SET @poly =-&#62;'Polygon((30000 15000,
                 31000 15000,
                 31000 16000,
                 30000 16000,
                 30000 15000))';MySQL的&#62;SELECT fid,ST_AsText(g) FROM geom IGNORE INDEX (g) WHERE-&#62;MBRContains(ST_GeomFromText(@poly),g);----- --------------------------------------------------------------- | FID | st_astext(G)| ----- --------------------------------------------------------------- | 1 |线(30250.4 15129.230248.8 15138.430238.2 15136。…| | 2 |线(30220.2 15122.830217.2 15137.830207.6 15136,…| | 3 |线(30179 15114.430176.6 15129.430167 151283016…| | 4 |线(30155.2 15121.430140.4 15118.630142 15109,30…| | 5 |线(30192.4 1508530177.6 15082.230179.2 15072.4,…| | 6 |线(30244 1508730229 15086.230229.4 15076.43024…| | 7 |线(30200.6 15059.430185.6 15058.630186 15048.8,…| | 10 |线(30179.6 15017.830181 15002.830190.8 15003.6,…| | 11 |线(30154.2 15000.430168.6 15004.830166 15014.2,…| | 13 |线(30105 15065.830108.4 15050.830118 150533011…| | 21 |线(30350.4 15828.830350.6 1584530333.8 15845,30…| | 22 |线(30350.6 15871.430350.6 15887.830334 15887.8,…| | 23 |线(30350.6 15914.230350.6 15930.430334 15930.4,…| | 24 |线(30290.2 1582330290.2 15839.430273.4 15839.4,…| | 25 |线(30291.4 15866.230291.6 15882.430274.8 15882。…| | 26 |线(30291.6 15918.230291.6 15934.430275 15934.4,…| | 154 |线(30276.2 15143.830261.4 1514130263 15131.4,30…| | 155 |线(30269.8 1508430269.4 15093.430258.6 15093,30…| | 157 |线(30128.2 1501130113.2 15010.230113.6 15000.4,…| | 249 |线(30337.8 15938.630337.8 15946.830320.4 15946。…| ----- --------------------------------------------------------------- 20行集(0.46秒)

11.6 JSON数据类型

MySQL支持本土JSON数据类型定义RFC 7159能够高效地访问数据以JSON(JavaScript对象符号)文件。这个JSON数据类型提供对字符串列存储json格式字符串的这些优势:

  • JSON文件存储在自动验证JSON专栏无效的文件产生一个错误。

  • 优化的存储格式。JSON文件存储在JSON列转换为一种允许快速访问文档元素读取内部格式。当服务器之后,必须读存储在二进制格式JSON值,价值不需要从文本表示的解析。二进制格式的结构,使该服务器查找子对象或嵌套的数组的索引值直接键或没有阅读所有的值之前或之后,他们的文件。

MySQL 8还支持JSON合并补丁格式定义RFC 7396,使用JSON_MERGE_PATCH()功能。看到这个功能的描述,以及规范化,合并,和autowrapping JSON值进一步的信息,例如

笔记

讨论使用JSON在蒙纳表示具体的JSON数据类型JSON常规字体表示一般的JSON数据。

所需要的存储空间JSON文件大致相同LONGBLOBLONGTEXT它;11.8节,“数据类型存储的要求”为更多的信息。它是重要的是要记住,任何JSON文档存储在一个尺寸JSON柱是有限的价值max_allowed_packet系统变量。(当服务器处理JSON值在内部存储器,它可以比这个更大;限制适用于服务器存储它。)你可以得到的空间需要存储一个JSON文件使用JSON_STORAGE_SIZE()注意一个函数;JSON列存储大小因此价值函数返回的是由柱用于可能进行的任何部分更新之前(在本节稍后看到JSON部分更新优化的讨论)。

JSON柱不能有默认值

随着JSON数据类型的一组SQL函数可以使对JSON值的操作,如创建、操作、搜索。下面的讨论表明,这些操作的例子。有关各个功能的详细信息,参见12.16节,“JSON功能”

一套操作空间功能在GeoJSON值也可。看到第12.15.11,“空间GeoJSON功能”

JSON列,像其他二进制数据类型的列的索引,不直接;相反,你可以创建一个生成的柱从提取物的标量值指数JSON专栏看到索引生成的列提供一个JSON列索引For example,a detailed。

MySQL优化器也找上虚拟列,JSON表达式匹配兼容指标。

JSON值部分更新

在MySQL 8中,优化器可以执行部分,在一个地方更新JSON而不是删除旧文件并写入新的文件在其整体柱。这种优化可以为符合下列条件的更新完成:

  • 被更新的列被声明为JSON

  • 这个UPDATE语句使用任何三个功能JSON_SET()JSON_REPLACE(),或JSON_REMOVE()更新的列。该列的值直接赋值(例如,UPDATE mytable SET jcol = '{"a": 10, "b": 25'})作为一个局部更新无法完成。

    更新的多JSON在单柱更新语句可以以这种方式优化;MySQL可以进行部分更新的列的值更新使用三功能刚刚上市。

  • 输入列和目标列必须具有相同的列;这样一个语句UPDATE mytable SET jcol1 = JSON_SET(jcol2, '$.a', 100)作为部分的更新无法完成。

    更新可以使用嵌套调用任何在前一项列出的功能,任意组合,只要输入和目标列是相同的。

  • 所有的变化,取代现有的数组或对象的值,用新的、不添加任何新的元素到父对象或数组。

  • 被替换的值必须至少为重置价值大。换句话说,新的值不能大于任何旧的。

    这个要求可能发生异常时,前一部分更新留有足够的空间为较大的值。你可以使用这个功能JSON_STORAGE_FREE()看见多少空间已被释放的任何部分更新JSON专栏

这种局部的更新可以写使用一个紧凑的格式,节省空间的二进制日志;这可以通过设置binlog_row_value_options系统变量偏_ JSON。更多信息请查看该变量的描述。

接下来的几节提供有关创建和操纵JSON值基本信息。

创建JSON值

JSON数组包含一个列表,以逗号分隔的值的和封闭的内[]人物

["abc", 10, null, true, false]

一个JSON对象包含一个键值对集合以逗号分隔和包围{}人物

{"k1": "value", "k2": 10}

作为例子说明,JSON数组和对象可以包含在字符串或数字的标量值,JSON空文字,或JSON布尔真实或虚假的文字。JSON对象的键必须是字符串。时间(日期,时间,或时间)的标量值是允许的:

["12:18:29.000000", "2015-07-29", "2015-07-29 12:18:29.000000"]

嵌套在JSON数组元素和JSON对象关键的允许值:

[99, {"id": "HK500", "cost": 75.99}, ["hot", "cold"]]
{"k1": "value", "k2": [10, 20]}

你也可以从一些提供MySQL为此函数获取JSON值(见第12.16.2,”功能,创建JSON值”)以及其他类型的铸造价值JSON类型使用CAST(value AS JSON)(见JSON和非JSON值之间的转换)。接下来的几段描述MySQL处理JSON值作为输入提供。

在MySQL中,JSON值写为字符串。MySQL将用在需要使用JSON值的任何字符串,并产生一个错误,如果不是有效的JSON。这些情况包括插入一个值为柱,有JSON数据类型和传递函数的参数,期望一个JSON值(通常表现为json_docjson_val在文档的功能),MySQL JSON以下实例演示:

  • 试图插入一个值为JSON柱成功如果值是一个有效的JSON值,但失败如果不是:

    MySQL的&#62;CREATE TABLE t1 (jdoc JSON);查询行,0行受影响(0.20秒)MySQL &#62;INSERT INTO t1 VALUES('{"key1": "value1", "key2": "value2"}');查询行,1行的影响(0.01秒)MySQL &#62;INSERT INTO t1 VALUES('[1, 2,');错误3140(22032)2行:无效的JSON文本:“无效值。”在价值6的位置(或列)”[ 1,2,”。

    位置在位置N在这样的错误信息是0,但应考虑粗糙的迹象在价值问题上发生。

  • 这个JSON_TYPE()函数接受一个JSON参数并试图将其解析为一个JSON值。它返回的值的JSON类型如果它是有效的,产生一个错误,否则:

    MySQL的&#62;SELECT JSON_TYPE('["a", "b", 1]');| ---------------------------- JSON _型([“A”,“B”,1 ])| ---------------------------- |阵列| MySQL &#62; ----------------------------SELECT JSON_TYPE('"hello"');| ---------------------- JSON _型(“你好”)| ---------------------- |字符串&#62; | ---------------------- MySQLSELECT JSON_TYPE('hello');错误3146(22032):在争论1to功能json_type JSON数据的数据类型无效;JSON字符串或JSON类型是必需的。

MySQL处理字符串使用JSON的上下文中使用utf8mb4字符集和最喜爱的电视节目整理。其他字符集的字符串转换为utf8mb4是必要的。(字符串中ASCII码utf8字符集转换,不需要因为ASCII码utf8是亚utf8mb4。)

作为一个可选择使用的字符串写入JSON值,从组成要素构成JSON值存在功能。JSON_ARRAY()作为一个(可能为空)的值并返回一个包含这些值的JSON数组列表:

MySQL的&#62;SELECT JSON_ARRAY('a', 1, NOW());_ ---------------------------------------- | JSON数组(“A”,(1),现在| ---------------------------------------- |)[“”,1,“2015年7月27日09:43:| ---------------------------------------- 47.000000”]

JSON_OBJECT()作为一个(可能为空)和返回键-值对列表包含那些对JSON对象:

MySQL的&#62;SELECT JSON_OBJECT('key1', 1, 'key2', 'abc');_ --------------------------------------- | JSON对象(1 key2 KEY1是,是,是,是| --------------------------------------- |(ABC)“1”key2 KEY1,“:”:“ABC”} | ---------------------------------------

JSON_MERGE_PRESERVE()以两个或两个以上的JSON文件并返回结果组合:

MySQL的&#62;SELECT JSON_MERGE_PRESERVE('["a", 1]', '{"key": "value"}');----------------------------------------------------- | json_merge_preserve(“[”“]”,1,“{“钥匙”:“价值”}”)| ----------------------------------------------------- | [“一”,1,{“钥匙”:“价值”} ] | ----------------------------------------------------- 1行集(0秒)

关于合并规则的信息,参见规范化,合并,和autowrapping JSON值

(MySQL 8.0.3后来也支持JSON_MERGE_PATCH()具有不同的行为。看到json_merge_patch()相比json_merge_preserve(),关于这两个功能之间的差异的信息。)

JSON值可以分配给用户定义的变量:

mysql> SET @j = JSON_OBJECT('key', 'value');
mysql> SELECT @j;
+------------------+
| @j               |
+------------------+
| {"key": "value"} |
+------------------+

然而,用户定义的变量不能JSON数据类型,所以虽然“J在前面的例子中看起来像一个JSON值具有相同的字符集和整理为一个JSON值,它JSON数据类型。相反,由于JSON_OBJECT()转换为字符串时,分配给变量。

字符串由转换JSON值有一个字符集utf8mb4和整理最喜爱的电视节目

mysql> SELECT CHARSET(@j), COLLATION(@j);
+-------------+---------------+
| CHARSET(@j) | COLLATION(@j) |
+-------------+---------------+
| utf8mb4     | utf8mb4_bin   |
+-------------+---------------+

因为utf8mb4_bin是一个二进制排序规则,JSON值比较是区分大小写的。

MySQL的&#62;SELECT JSON_ARRAY('x') = JSON_ARRAY('X');+-----------------------------------+| JSON_ARRAY('x') = JSON_ARRAY('X') |+-----------------------------------+|                                 0 |+-----------------------------------+

案例的敏感性也适用于JSONnull真正的,和false文字,都必须使用小写:

MySQL的&#62;SELECT JSON_VALID('null'), JSON_VALID('Null'), JSON_VALID('NULL');——————————————————————————————————————SELECT CAST('null' AS JSON);---------------------- |铸(&#39;null作为JSON)| ---------------------- |空| ---------------------- 1行集(0秒)MySQL &#62;SELECT CAST('NULL' AS JSON);错误3141(22032):无效的JSON文本参数1功能cast_as_json:“无效值。”在0位“空”。

JSON的文本案例的敏感性不同,SQLNULL真的,和FALSE文字,它可以写在任何lettercase:

MySQL的&#62;SELECT ISNULL(null), ISNULL(Null), ISNULL(NULL);isnull -------------- -------------- -------------- |(null)| isnull(null(空)| isnull)| -------------- -------------- -------------- | | | 1 1 1 | -------------- -------------- --------------

有时,它可能是必要的或可取的插入引号字符("&#39;)为一个JSON文档。这个例子假定你想插入一些JSON对象包含代表的句子,国家关于MySQL的一些事实的字符串,每个配对与一个合适的关键词,为表创建使用所示的SQL语句:

mysql> CREATE TABLE facts (sentence JSON);

这些关键词句对在这一:

mascot: The MySQL mascot is a dolphin named "Sakila".

将这作为一个JSON对象的一个方法facts表是使用MySQLJSON_OBJECT()功能。在这种情况下,你必须逃脱每个引号字符使用一个反斜杠,如下所示:

MySQL的&#62;INSERT INTO facts VALUES&#62;(JSON_OBJECT("mascot", "Our mascot is a dolphin named \"Sakila\"."));

这不如果你插入的值作为一个JSON对象文字以同样的方式工作的,在这种情况下,你必须使用双反斜杠转义序列,这样:

mysql> INSERT INTO facts VALUES
     >   ('{"mascot": "Our mascot is a dolphin named \\"Sakila\\"."}');

使用双反斜杠转义序列保持MySQL执行处理,而使其通过字符串来存储引擎处理。无论是上面的方法插入JSON对象后,你可以看到,反斜杠在JSON列值现状做一个简单的SELECT,像这样:

MySQL的&#62;SELECT sentence FROM facts;--------------------------------------------------------- |句| --------------------------------------------------------- | {“吉祥物”:“我们的吉祥物是一只海豚命名为“sakila \“。”} | ---------------------------------------------------------

看这句话用mascot为关键,你可以使用列路径算子->,如下所示:

mysql> SELECT col->"$.mascot" FROM qtest;+---------------------------------------------+| col->"$.mascot"                             |+---------------------------------------------+| "Our mascot is a dolphin named \"Sakila\"." |+---------------------------------------------+1 row in set (0.00 sec)

这使得反斜杠的完整,随着周围的引号。显示所需的值使用mascot作为重点,但不包括周围的引号或任何逃脱,使用内联路径算子->>,像这样:

MySQL的&#62;SELECT sentence->>"$.mascot" FROM facts;+-----------------------------------------+| sentence->>"$.mascot"                   |+-----------------------------------------+| Our mascot is a dolphin named "Sakila". |+-----------------------------------------+
笔记

前面的例子所示,如果不工作NO_BACKSLASH_ESCAPES服务器的SQL模式启用。如果这种模式设置,一个反斜杠代替双反斜杠可以用来插入JSON对象的文字,和反斜杠被保存。如果你使用_ JSON对象()功能在执行插入和这种模式设置,您必须交替单双引号,像这样:

mysql> INSERT INTO facts VALUES
     > (JSON_OBJECT('mascot', 'Our mascot is a dolphin named "Sakila".'));

看到的描述JSON_UNQUOTE()有关此模式对转义字符的JSON值的影响的更多信息功能。

规范化,合并,和autowrapping JSON值

当一个字符串解析和发现是一种有效的JSON文件,也是规范。这意味着钥匙复制关键发现在文档后面的成员,从左到右读,丢弃。通过下面的物体所产生的价值JSON_OBJECT()电话只包括第二key1因为名字的关键元素值出现较早,如下所示:

mysql> SELECT JSON_OBJECT('key1', 1, 'key2', 'abc', 'key1', 'def');
+------------------------------------------------------+
| JSON_OBJECT('key1', 1, 'key2', 'abc', 'key1', 'def') |
+------------------------------------------------------+
| {"key1": "def", "key2": "abc"}                       |
+------------------------------------------------------+

正常时也要做值插入到JSON列,如下所示:

mysql> CREATE TABLE t1 (c1 JSON);

mysql> INSERT INTO t1 VALUES
     >     ('{"x": 17, "x": "red"}'),
     >     ('{"x": 17, "x": "red", "x": [3, 5, 7]}');

mysql> SELECT c1 FROM t1;
+------------------+
| c1               |
+------------------+
| {"x": "red"}     |
| {"x": [3, 5, 7]} |
+------------------+

最后重复的关键胜利行为的建议RFC 7159而且大多数JavaScript解析器的实现。(错误# 86866,错误# 26369555)

在MySQL版本之前8.0.3,键,复制的关键发现在文档前面被丢弃的成员。通过下面的物体所产生的价值JSON_OBJECT()电话不包括第二key1因为名字的关键元素值出现较早:

mysql> SELECT JSON_OBJECT('key1', 1, 'key2', 'abc', 'key1', 'def');
+------------------------------------------------------+
| JSON_OBJECT('key1', 1, 'key2', 'abc', 'key1', 'def') |
+------------------------------------------------------+
| {"key1": 1, "key2": "abc"}                           |
+------------------------------------------------------+

MySQL 8.0.3之前,这第一份关键胜利归一化进行插入值为JSON列。

mysql> CREATE TABLE t1 (c1 JSON);

mysql> INSERT INTO t1 VALUES
     >     ('{"x": 17, "x": "red"}'),
     >     ('{"x": 17, "x": "red", "x": [3, 5, 7]}');

mysql> SELECT c1 FROM t1;
+-----------+
| c1        |
+-----------+
| {"x": 17} |
| {"x": 17} |
+-----------+

MySQL也丢弃多余的空格键之间,价值观,或在原有的JSON文档元素。为了让查找更高效,也各种各样的JSON对象的键。你应该知道,这个排序的结果是随时变化的,不能保证在所有的版本是一致的。

MySQL的功能,生成JSON值(见第12.16.2,”功能,创建JSON值”)总是返回值

将JSON值

两种算法在MySQL 8.0.3支持合并(后来),以实现的功能JSON_MERGE_PRESERVE()JSON_MERGE_PATCH()。这些不同,他们如何处理重复键:JSON_MERGE_PRESERVE()保留值重复关键字,而JSON_MERGE_PATCH()丢弃所有但最后的价值。接下来的几段解释这两个函数处理JSON文件的不同组合的合并(即对象和数组)。

笔记

JSON_MERGE_PRESERVE()是一样的JSson MERGE()功能在MySQL找到的以前的版本(在MySQL 8.0.3改名)。JSON_MERGE()还支持别名JSON _ MERGE _(preserve)在MySQL 8中,但已过时,须在未来的版本中去除。

合并数组的情况下,将多个数组的数组合并成一个单一的阵列。JSON_MERGE_PRESERVE()这是通过串联阵列命名后的第一阵列的末端。_合并_补丁(JSON)考虑每个参数是由单一元素的数组(有0为指标),然后应用最后重复的关键胜利逻辑只选择最后的论点。你可以比较这个查询的结果显示:

mysql> SELECT
    ->   JSON_MERGE_PRESERVE('[1, 2]', '["a", "b", "c"]', '[true, false]') AS Preserve,
    ->   JSON_MERGE_PATCH('[1, 2]', '["a", "b", "c"]', '[true, false]') AS Patch\G
*************************** 1. row ***************************
Preserve: [1, 2, "a", "b", "c", true, false]
   Patch: [true, false]

多个对象合并时产生一个单一的对象。JSON_MERGE_PRESERVE()处理多个对象结合数组中,密钥的所有独特的值具有相同的密钥;然后使用该数组作为结果的关键价值。_合并_补丁(JSON)丢弃值发现重复键,从左到右的工作,这样的结果只包含关键的最后一个值。下面的查询说明了对重复关键结果的差异a

MySQL的&#62;SELECT-&#62;JSON_MERGE_PRESERVE('{"a": 1, "b": 2}', '{"c": 3, "a": 4}', '{"c": 5, "d": 3}') AS Preserve,-&#62;JSON_MERGE_PATCH('{"a": 3, "b": 2}', '{"c": 3, "a": 4}', '{"c": 5, "d": 3}') AS Patch\G*************************** 1。行***************************保存:{“”:[ 1,4 ],“B”:2,“C”:[ 3,5 ],“D”:3 }补丁:{“”:4,“B”:2,“C”:5,“D”:3 }

nonarray值用在需要使用一个数组的值是autowrapped:价值被[]字符转换为一个数组。在随后的声明中,每个参数都是autowrapped为数组([1][ 2 ])。然后这些合并到一个单一的结果数组;在前两例,JSON_MERGE_PRESERVE()结合值具有相同的键时_合并_补丁(JSON)丢弃值的所有重复键除了最后,如下所示:

mysql> SELECT
	  ->   JSON_MERGE_PRESERVE('1', '2') AS Preserve,
	  ->   JSON_MERGE_PATCH('1', '2') AS Patch\G
*************************** 1. row ***************************
Preserve: [1, 2]
   Patch: 2

数组和对象的值是由autowrapping对象数组结合值或通过合并数组合并最后重复的关键胜利根据合并功能的选择(JSON_MERGE_PRESERVE()_合并_补丁(JSON),分别),可以看到在这个例子:

mysql> SELECT
	  ->   JSON_MERGE_PRESERVE('[10, 20]', '{"a": "x", "b": "y"}') AS Preserve,
	  ->   JSON_MERGE_PATCH('[10, 20]', '{"a": "x", "b": "y"}') AS Patch\G
*************************** 1. row ***************************
Preserve: [10, 20, {"a": "x", "b": "y"}]
   Patch: {"a": "x", "b": "y"}

搜索和修改JSON值

一个JSON路径表达式选择JSON文档中的价值。

路径表达式是有用的功能,提取部分或修改一个JSON文件,指定在文件中的操作。例如,下面的查询提取一个JSON文档的成员与价值name钥匙

MySQL的&#62;SELECT JSON_EXTRACT('{"id": 14, "name": "Aztalan"}', '$.name');--------------------------------------------------------- | json _提取物(“{“id”:14,“名字”:“aztalan“}”,“美元”.name)| --------------------------------------------------------- |”aztalan”| ---------------------------------------------------------

路径语法使用领先$字符代表的JSON文档的考虑下,后跟选择器表明越来越具体文件的部分:

  • 一期的关键名称与给定键的对象的成员。关键必须指定名称用双引号如果没有引号的名字是不合法的路径表达式(例如,如果它包含一个空间)。

  • [N]添加到path选择一个数组名位置的价值N在阵列。阵列的位置是整数从零开始。如果path不选择一个数组的值,path[零]评估的价值相同path

    MySQL的&#62;SELECT JSON_SET('"x"', '$[0]', 'a');------------------------------ | JSON _集(“X”,〔0〕美元,在| ------------------------------ |)”到“| ------------------------------ 1行集(0秒)
  • [M to N]指定的一个子集或数组的值的范围从价值定位M,和结束与价值定位N

    last支持为最右边的数组元素的索引的同义词。数组元素的相对寻址也支持。如果path不选择一个数组的值,path[上]评估的价值相同path如图所示,在本节稍后(参见右边的数组元素

  • 路径可以包含** *通配符:

    • .[*]评价在一个JSON对象的所有成员的值。

    • [*]结果在一个JSON数组中所有元素的值。

    • prefix**suffix结果,与指定的前缀和后缀结尾的命名开始的所有路径。

  • 路径不存在的文件(对不存在的数据)的评估NULL

$参考这个JSON数组构成要素:

[ 3,{“”:[ 5, 6 ],“B”:10 },[ 99, 100 ] ]

然后:

  • $[0]评价

  • $[1]评价{“”:[5,6],“B”:10 }

  • $[2]评价[ 99, 100 ]

  • $[3]评价无效的(指的是四阵元,这是不存在的)。

因为$[1]$ [ 2 ]评估非标量值,可以作为更具体的路径表达式的值的基础上,选择嵌套。实例:

  • $[1].a评价[ 5,6 ]

  • $[1].a[1]评价

  • $[1].b评价

  • $[2][0]评价九十九

如前所述,路径组件名称键必须引用如果在路径表达式的引号键名称是不合法的。让$参考这个值:

{“鱼”:“鲨鱼”,“鸟”:“麻雀”}

钥匙都包含一个空间,必须引用:

  • $."a fish"评价鲨鱼

  • $."a bird"评价麻雀

路径中使用通配符来评价一个数组可以包含多个值:

mysql> SELECT JSON_EXTRACT('{"a": 1, "b": 2, "c": [3, 4, 5]}', '$.*');
+---------------------------------------------------------+
| JSON_EXTRACT('{"a": 1, "b": 2, "c": [3, 4, 5]}', '$.*') |
+---------------------------------------------------------+
| [1, 2, [3, 4, 5]]                                       |
+---------------------------------------------------------+
mysql> SELECT JSON_EXTRACT('{"a": 1, "b": 2, "c": [3, 4, 5]}', '$.c[*]');
+------------------------------------------------------------+
| JSON_EXTRACT('{"a": 1, "b": 2, "c": [3, 4, 5]}', '$.c[*]') |
+------------------------------------------------------------+
| [3, 4, 5]                                                  |
+------------------------------------------------------------+

在下面的例子中,路径$**.b对多路径(.a.b美元$.c.b)和产生的匹配路径值的数组:

MySQL的&#62;SELECT JSON_EXTRACT('{"a": {"b": 1}, "c": {"b": 2}}', '$**.b');* * * * * * * * * * * * * * * *

从阵列你可以使用的范围to关键词指定JSON数组的子集。例如,$ [ 1-3 ]包括第二、第三、和第四元素的数组,如下所示:

mysql> SELECT JSON_EXTRACT('[1, 2, 3, 4, 5]', '$[1 to 3]');
+----------------------------------------------+
| JSON_EXTRACT('[1, 2, 3, 4, 5]', '$[1 to 3]') |
+----------------------------------------------+
| [2, 3, 4]                                    |
+----------------------------------------------+
1 row in set (0.00 sec)

语法是M to N,在那里MN是的,分别从JSON数组的元素范围的第一个和最后一个指标。N必须大于MM必须大于或等于0。数组元素的索引从0开始。

你可以使用范围的情况下支持通配符。

右边的数组元素这个last关键词是支持在一个数组中的最后一个元素的索引的同义词。表达式的形式的孩子N可用于相对寻址,并在范围定义,这样:

MySQL的&#62;SELECT JSON_EXTRACT('[1, 2, 3, 4, 5]', '$[last-3 to last-1]');-------------------------------------------------------- | json_extract(&#39; [ 1,2,3,4,5 ],[ last-3美元来last-1 ]”)| -------------------------------------------------------- | [ 2,3,4 ] | -------------------------------------------------------- 1行集(0.01秒)

如果路径是对的值不是一个数组,其评估结果是如果值被包裹在一个元素的数组相同:

mysql> SELECT JSON_REPLACE('"Sakila"', '$[last]', 10);
+-----------------------------------------+
| JSON_REPLACE('"Sakila"', '$[last]', 10) |
+-----------------------------------------+
| 10                                      |
+-----------------------------------------+
1 row in set (0.00 sec)

你可以使用column->path一个JSON列标识符和JSON路径表达式作为一个同义词JSON_EXTRACT(column, path)。看到第12.16.3,“搜索JSON值函数”为更多的信息。参见索引生成的列提供一个JSON列索引

一些功能将现有的JSON文档,修改它的一些方法,并返回结果修改的文档。路径表达式中的文件进行更改。例如,在JSON_SET()JSON_INSERT(),和JSON_REPLACE()功能各取一个JSON文档,加上一个或多个路径值对描述对文档的修改和使用价值。功能不同,他们如何处理现有的和不存在的值在文档。

考虑到这个文件:

mysql> SET @j = '["a", {"b": [true, false]}, [10, 20]]';

JSON_SET()替换值的路径存在和添加路径不存在的价值:。

MySQL的&#62;SELECT JSON_SET(@j, '$[1].b[0]', 1, '$[2][2]', 2);-------------------------------------------- | JSON _集(@美元〔1〕J〕.b〔0,1,2〔2〕〔元〕,〔2 | -------------------------------------------- |)“A”,“B”:{ } [假] [ 1,2,10,20,| -------------------------------------------- ]

在这种情况下,路径$[1].b[0]选择一个现有的价值(真正的),取而代之的是与价值的路径参数(1)。路径$ [ 2 ] [ 2 ]不存在,所以相应的值(2)添加到选定的值$ [ 2 ]

JSON_INSERT()增加了新的价值,但不能取代现有的价值观:

MySQL的&#62;SELECT JSON_INSERT(@j, '$[1].b[0]', 1, '$[2][2]', 2);----------------------------------------------- | JSON _ insert(@美元〔1〕J〕.b〔0,1,2〔2〕〔元〕,〔2 | ----------------------------------------------- |)“A”,“B”:{ } [假],[真正的,10,20,2 | ----------------------------------------------- ]

JSON_REPLACE()替换现有的价值观和对新的价值观:

MySQL的&#62;SELECT JSON_REPLACE(@j, '$[1].b[0]', 1, '$[2][2]', 2);------------------------------------------------ | JSON _ replace(@美元〔1〕J〕.b〔0,1,2〔2〕〔元〕,〔2 | ------------------------------------------------ |)“A”,“B”:{ } [ 1 ],[假],10,20 | ------------------------------------------------

路径值对评估左到右。该文件由一对新的价值评估成为对未来对评价。

JSON_REMOVE()以一个JSON文件和一个或多个路径,指定的值是从文档中删除。返回值是原始文档的文档内减去存在路径选择的价值:

MySQL的&#62;SELECT JSON_REMOVE(@j, '$[2]', '$[1].b[1]', '$[1].b[1]');--------------------------------------------------- | JSON _ remove(@美元J,[ 2 ],[ 1 ] .b美元美元〔1〕,〔1〕〔1〕.b)| --------------------------------------------------- | [“A”,“B”:{ } [真] | --------------------------------------------------- ]

这些影响的路径:

  • $[2]比赛[ 10, 20 ]并删除它

  • 第一个实例$[1].b[1]比赛b元和删除它

  • 二审$[1].b[1]比赛什么元素已被删除,不再存在的路径,并没有影响。

比较和JSON值排序

JSON值可以比较使用=<<=>>=<>!=,和<=>运营商

以下的比较运算符和函数还没有与JSON值支持:

解决比较运算符和函数刚上市是把JSON值到本地MySQL数值或字符串数据类型,所以他们有一个一致的非JSON标量类型。

JSON值比较采用两水平的地方。比较的第一级是基于比较值的JSON类型。如果类型不同,比较的结果是唯一确定的类型具有更高的优先级。如果两值具有相同的JSON类型,第二级比较时使用特定类型的规则。

下面的列表显示了JSON类型的优先级,从最高优先级最低。(类型名称是那些返回的JSON_TYPE()功能。)类型一起显示在一行有相同的优先级。任何值列在列表前面一个JSON类型比较大于任何价值有一个JSON类型的清单后上市。

blobbitopaquedatetimetimedatebooleanarrayobjectstringinteger,doublenull

对于同一优先级的JSON值,比较规则的特定类型:

  • BLOB

    第一N这两个值的字节相比,在N在较短的值的字节数。如果第一N这两个值的字节是相同的,较短的值是有序的长值之前。

  • BIT

    相同的规则为BLOB

  • OPAQUE

    相同的规则为BLOB不透明价值观是不分为另一个类型的值。

  • DATETIME

    表示一个较早的时间点是有序的,是在以后的某个时间值前值。如果两值最初来自MySQLDATETIME时间戳类型,分别,如果他们是在同一时间点他们是平等的。

  • TIME

    两时间值较小的命令之前,较大的一个。

  • DATE

    提前订购更近的日期之前。

  • ARRAY

    两JSON数组相等,如果他们有相同的长度和值在数组中的位置对应相等。

    如果数组是不相等的,它们的顺序是由在第一的位置,那里是一个不同的因素决定的。在那个位置的较小的值的数组排序第一。如果短阵的所有值都等于在较长的阵列的相应值,较短的数组排序第一。

    例子:

    [] < ["a"] < ["ab"] < ["ab", "cd", "ef"] < ["ab", "ef"]
    
  • BOOLEAN

    JSON错误的文字比JSON真实的文字。

  • OBJECT

    如果他们有相同的一组键两JSON对象是相等的,每个键有两个对象的值相同。

    例子:

    {"a": 1, "b": 2} = {"b": 2, "a": 1}
    

    两个不相等的对象的顺序是不确定的,确定的。

  • STRING

    字符串命令中的第一个N字节的utf8mb4两字符串的比较表示,在Nis the length of the短字符串。if the firstN两字符串的字节数是相同的,较短的字符串被认为是比较长的字符串。

    例子:

    "a" < "ab" < "b" < "bc"
    

    这个命令相当于SQL字符串排序规则排序utf8mb4_bin。因为最喜爱的电视节目是一个二进制排序规则,JSON值比较是区分大小写的:

    "A" < "a"
    
  • INTEGER

    JSON值可以包含数字和数字的精确值的近似值。对于这些类型的数的一般讨论,看9.1.2节,“Numeric Literals”

    比较本地MySQL数值类型进行了规定第二节,“表达评价类型转换”,但在JSON值比较数字的规则有所不同:

    • 在两列使用本地MySQL的比较INTDOUBLE数值类型,分别是已知的,所有的比较都包含一个整数和一个双,所以整数转换为行双。即准确值的数字转换成数字的近似值。

    • 另一方面,如果查询比较两个JSON列包含数字,不能预先知道是否号码将整数或双。在所有的行提供最一致的行为,MySQL将近似值数的确切值数。产生的顺序是一致的,并没有确切的值数丢失精度。例如,给定标量922337203685477580, 922337203685477580, 922337203685477580和9.223372036854776e18,顺序是这样的:

      9223372036854775805 < 9223372036854775806 < 9223372036854775807
      < 9.223372036854776e18 = 9223372036854776000 < 9223372036854776001
      

    在JSON比较使用非JSON数值比较规则,排序不一致可能发生。通常的MySQL比较规则数产生这些排序:

    • 整数的比较:

      9223372036854775805 < 9223372036854775806 < 9223372036854775807
      

      (不确定9.223372036854776e18)

    • 双重对比:

      9223372036854775805 = 9223372036854775806 = 9223372036854775807 = 9.223372036854776e18
      

对于SQL任何JSON值比较NULL,结果是未知

对于JSON和非JSON值比较,非JSON值转换为JSON根据下表中的规定值,然后比较先前所描述的。

JSON和非JSON值之间的转换

下表提供了一个简要的规则:当MySQL铸造JSON值和其它类型的值之间:

表11.3 JSON转换规则

其他类型的铸造(其他类型的JSON)铸造(JSON作为其他类型)
JSON没有变化没有变化
UTF8字符类型(utf8mb4UTF8ascii字符串解析成JSON值。JSON值序列化为一个utf8mb4字符串
其他性格类型其他的字符编码是隐式转换为utf8mb4作为描述为utf8字符类型。JSON值序列化为一个utf8mb4字符串,然后转换为其他字符的编码。结果可能没有意义。
NULL结果在一个NULLJSON值类型不适用
几何类型几何值是通过调用转换成JSON文档ST_AsGeoJSON()非法操作。解决方法:通过结果CAST(json_val AS CHAR)ST_GeomFromGeoJSON()
所有其他类型的在一个JSON文件由单个标量值结果。成功如果JSON文档由一个单一的目标类型和标量值的标量值可以转换为目标类型。否则,返回NULL你在和预警

ORDER BY对于JSON值作品根据这些原则:

  • 标量JSON值排序使用相同的规则,在前面的讨论。

  • 为提升类,SQLNULL在所有的JSON值订单,包括JSON空文字为降序排序,SQL;无效的JSON的订单后的空值,including the literal JSON。

  • 对于JSON值排序键的值绑定max_sort_length系统变量,所以不同后的第一个键max_sort_length字节相等

  • 非标量值的排序是目前不支持和警告出现。

排序,可以铸造一个JSON标量其他一些本地MySQL型。例如,如果一个命名列jdoc包含有一个由成员JSON对象身份证件键和一个非负的值,用这个词来排序id价值观:

以铸造(json_extract(JDoc,“美元。ID)为无符号)

如果碰巧有一个生成的列定义中使用相同的表达ORDER BYMySQL的优化器,承认并考虑使用索引的查询执行计划。看到第8.3.11,“优化器使用生成的列索引”

JSON值聚集

对于JSON值聚集,SQLNULL值被忽略为其他数据类型。非—无效的值转换为数值类型和聚合,除了MIN()MAX(),和GROUP_CONCAT()。转换数应该是数字标量JSON值产生有意义的结果,虽然(取决于价值观)截断和精度损失可能发生。转换到其他JSON值数量不可能产生有意义的结果。

数据类型的默认值为

数据类型可以显式或隐式的默认值。

DEFAULT value子句中的数据类型规范明确表示列的默认值。实例:

创建表T1(我int默认1,C varchar(10)违约”,价格翻番(16)默认为0);

SERIAL DEFAULT VALUE是一个特殊的情况下。在一个整数列的定义,它是一个别名not null自动增量_单

明确的几个方面DEFAULT条款处理依赖版本,描述如下。

处理显式默认为MySQL 8.0.13

指定一个默认值DEFAULT子句可以字面常量或表达式。有一个例外,附上表达默认值在括号来区分字面常量的默认值。实例:

创建表T1(--文字默认我int默认0,C varchar(10)默认”--表达默认F浮默认(rand() * rand()),B(16)二进制默认(uuid_to_bin(uuid()))、D(current_date日期默认间隔1年),P点的默认(点(0,0)),J JSON默认(json_array()));

例外的是,对TIMESTAMPDATETIME列,您可以指定CURRENT_TIMESTAMP作为默认,没有圆括号。看到第11.3.5,自动初始化和更新的时间戳和日期时间”

这个BLOBTEXT几何,和JSON数据类型只能如果值是写成一个表达式指定一个默认值,如果表达式的值是一个文字:

  • 这是允许的(文字默认指定为表达):

    CREATE TABLE t2 (b BLOB DEFAULT ('abc'));
    
  • 这产生一个错误(文字默认不指定为表达):

    CREATE TABLE t2 (b BLOB DEFAULT 'abc');
    

表达的默认值必须遵守以下规则。发生错误,如果表达式包含无效的构建。

  • 文字、内置函数(确定性和非确定性的),和运营商允许。

  • 子查询、参数、变量、存储功能,和用户定义的函数都是不允许的。

  • 一个表达式的默认值不依赖于一个列有AUTO_INCREMENT属性

  • 一柱一个表达式默认值可以参考其他表中的列,除生成的列或列的默认值与表达的引用必须是发生在前柱表定义。即表达默认值不能包含了生成的列或列的默认值引用的表达。

    顺序约束也适用于使用ALTER TABLE重新排序表中的列。如果得到的表格就有表达,包含默认值生成的列或列的表情默认值向前参考,该语句将失败。

笔记

如果一个表达式的任何组件的默认值取决于SQL模式,不同的结果可能出现的不同用途,除非在表的SQL模式是相同的使用。

CREATE TABLE ... LIKECREATE TABLE ... SELECT,目标表保留默认值从原始表中的表达。

如果一个表达式默认值指的是一个非确定性函数,任何导致用于计算表达式语句是基于语句的复制不安全。这包括诸如INSERTUPDATE,和ALTER TABLE

插入新的一行时,一个表达默认列的默认值可以通过省略的列名称或指定列的插入DEFAULT(正如列文字默认):

MySQL的&#62;CREATE TABLE t4 (uid BINARY(16) DEFAULT (UUID_TO_BIN(UUID())));MySQL的&#62;INSERT INTO t4 () VALUES();MySQL的&#62;INSERT INTO t4 () VALUES(DEFAULT);MySQL的&#62;SELECT BIN_TO_UUID(uid) AS uid FROM t4;-------------------------------------- | UID | -------------------------------------- | f1109174 - 94c9 - 11e8 - 971d - 3bf1095aa633 | | f110cf9a - 94c9 - 11e8 - 971d - 3bf1095aa633 | --------------------------------------

然而,使用DEFAULT(col_name)指定一个命名列的缺省值是唯一的,有文字的缺省值的列不允许,那有一个默认值的列的表达。

不是所有的存储引擎允许表达的默认值。对于那些不这样做,一个ER_UNSUPPORTED_ACTION_ON_DEFAULT_VAL_GENERATED错误发生

如果默认值计算得出的数据类型,不同于声明的列类型,隐式强制声明的类型按照通常的MySQL的类型转换规则。看到第二节,“表达评价类型转换”

显式默认MySQL 8.0.13优先处理

有一个例外,指定一个默认值DEFAULT条款必须是一个字面常量;它不可能是一个函数或表达式。这意味着,例如,你不能为一个日期列为一个功能如值设置默认NOW()CURRENT_DATE。例外的是,对TIMESTAMPDATETIME列,您可以指定CURRENT_TIMESTAMP作为默认的。看到第11.3.5,自动初始化和更新的时间戳和日期时间”

这个BLOBTEXT几何,和JSON数据类型不能被分配一个默认值。

如果默认值计算得出的数据类型,不同于声明的列类型,隐式强制声明的类型按照通常的MySQL的类型转换规则。看到第二节,“表达评价类型转换”

隐性违约的处理

如果一个数据类型包括没有明确规范DEFAULT价值决定,MySQL默认值如下:

如果该列可以NULL作为一种价值,列一个明确的定义默认为空条款.

如果柱不能NULL作为一种价值,MySQL没有明确定义的列默认条款.例外:如果列定义的一部分PRIMARY KEY但不明确不为空MySQL创建的,它作为一个NOT NULL柱(因为主键列必须NOT NULL

数据进入NOT NULL柱,没有显式的默认条款,如果INSERTREPLACE声明包括柱没有价值,或UPDATE语句集的列无效的MySQL处理柱,根据影响SQL模式时:

  • 如果严格的SQL模式启用时,发生了一个错误的事务表和语句回滚。对于非事务表,发生了一个错误,但如果这发生在一个多行语句的后续行,前一行被插入。

  • 如果没有启用严格模式,MySQL设置列的列的数据类型的隐式的默认值。

假设一个表t定义如下:

创建表的T(I型不为空);

在这种情况下,i没有明确的违约,所以严格模式下面的语句产生一个错误,没有插入行。当不使用严格的模式,只有三语句产生一个错误;隐式的默认插入的第一个语句,但三失败因为DEFAULT(i)不能产生价值:

插入T values();插入T值(默认);插入T值(默认(我));

看到第5.1.10,”服务器的SQL模式”

对于一个给定的表,SHOW CREATE TABLE声明显示,列有一个明确的默认条款.

隐式的默认值定义如下:

为数据类型的存储要求

表格数据在磁盘上存储的要求取决于几个因素。不同的存储引擎代表的数据类型和不同存储原始数据。表中的数据可以被压缩,或者一列或一整行,复杂的存储要求的表或列的计算。

尽管在磁盘上的存储布局差异,API,沟通和交流信息的表行使用一致的数据结构,适用于所有存储引擎内部MySQL。

这一部分包括每一个数据的存储要求的指南和信息类型支持MySQL,包括内部格式和存储引擎使用一个固定大小的表示数据类型的大小。信息是按类别列出或存储引擎。

一个表的内部表示一个65535字节的行大小的最大值,即使存储引擎能够支持更大的行。这个数字不包括BLOBTEXT列,这有助于只有9字节大小对这12。为BLOBTEXT数据,信息被存储在不同的存储区域的行缓冲区。不同的存储引擎处理该数据以不同的方式分配和存储,根据他们处理相应类型的方法。有关更多信息,参见16章,选择存储引擎,和第c.10.4,“限制表的列数和行的大小”

InnoDB表的存储要求

看到第15.8.1.2,“物理行结构的InnoDB表”关于信息存储的要求InnoDB

数值类型的存储要求

数据类型存储要求
TINYINT1字节
SMALLINT2字节
MEDIUMINT3字节
INTINTEGER4字节
BIGINT8字节
FLOAT(p)4 bytes if 0 <=p<= 24, 8 bytes if 25 <=p<= 53
FLOAT4字节
DOUBLE [PRECISION]REAL8字节
DECIMAL(M,D)numeric(MD看下面的讨论有所不同;
BIT(M)约(M7)/ 8字节

DECIMAL(和NUMERIC)柱使用二进制格式,包九的十进制表示(基地10)数字为四字节。对于整数和小数部分存储每个值分别确定。每一个九位数需要四个字节,和残存物数字需要一些分数为四字节。多余的数字存储空间由下表给出。

剩下的数字字节数

日期和时间类型的存储要求

TIMEDATETIME,和TIMESTAMP列为表创建MySQL 5.6.4不同于之前创建的表的存储要求5.6.4。这是由于改变5.6.4允许这些类型有分数的一部分,这就需要从零到三字节。

数据类型存储前需要MySQL 5.6存储需要MySQL 5.6
YEAR1字节1字节
DATE3字节3字节
TIME3字节3个字节存储分数秒
DATETIME8字节5个字节存储分数秒
TIMESTAMP4字节4个字节存储分数秒

在MySQL 5.6.4,存储YEARDATE保持不变。然而,TIMEDATETIME,和TIMESTAMP不同的方式表示DATETIME包装更有效,需要5个而不是8个字节的非分离的一部分,和所有三个部分有一个小数部分需要0到3个字节,这取决于所存储的值小数秒的精度。

小数秒的精度存储要求
0字节
1, 21字节
3, 42字节
5, 63字节

例如,TIME(0)TIME(2)TIME(4),和TIME(6)使用3, 4, 5,6字节,分别。TIMETIME(0)是等效的,需要相同的存储。

有关时间值的内部表示的细节,看MySQL内核:重要的算法和结构

字符串类型的存储要求

在下面的表格中,M代表声明的列长度字符的二进制字符串类型和字节的二进制字符串类型。L代表一个给定的字符串值的实际字节长度。

数据类型存储要求
CHAR(M)InnoDB的行格式紧凑型家庭优化可变长度的字符集存储。看到紧凑的行格式的特点。。。。。。。否则,M×w字节,<=M<=255,wherew是为最大长度的字符在字符集所需的字节数。
BINARY(M)M字节,0<=M<=二百五十五
VARCHAR(M)varbinary(ML1个字节,如果列值需要0?255字节,L如果2字节的值可能需要超过255个字节
TINYBLOBTINYTEXTL1 Bytes,whereL< 2
BLOBTEXTL2 Bytes,whereL< 2十六
MEDIUMBLOBMEDIUMTEXTL3字节,whereL< 2二十四
LONGBLOBLONGTEXTL4字节,whereL< 2三十二
ENUM('value1','value2',...)1或2个字节,这取决于枚举值的数目(65535值的最大值)
SET('value1','value2',...)1, 2, 3,4,或8个字节,取决于集合成员数(64成员的最大值)

可变长度的字符串类型是使用长度前缀加上数据存储。长度前缀需要一到四个字节,取决于数据类型和值的前缀L(字符串的字节长度)。例如,存储一个MEDIUMTEXT价值需要L字节存储的值加三个字节来存储值的长度。

计算用于存储特定的字节数CHARVARCHAR,或TEXT列的值,你必须考虑用于柱是否值包含多字节字符的字符集。特别是,当使用UTF8Unicode字符集,你必须记住,并不是所有的汉字使用的字节数相同。utf8mb3utf8mb4字符集可能需要多达三个,每字符四字节,分别。一种用于不同类别的存储故障utf8mb3utf8mb4字,看10.9节,“Unicode支持”

VARCHARVARBINARY,和BLOBTEXT类型是可变长度的类型。一、存储需求依赖于这些因素:

  • 该列的值的实际长度

  • 列的最大长度

  • 用于列的字符集,因为一些字符集包含多字节字符

例如,一个VARCHAR(255)列可以有255个字符的最大长度保存字符串。假设立柱采用latin1字符集(每个字符一个字节),实际所需的存储是字符串的长度(L),加上一个字节来记录字符串的长度。对于字符串“ABCD”L4,存储量为五字节。如果同一列而宣布使用UCS2双字节字符集,存储量是10字节的长度'abcd'是八个字节,列需要两个字节存储长度,最大长度大于255(510字节)。

有效的最大数量字节可以存储在一个VARCHARVARBINARY柱有65535字节的行大小的最大值,这是在所有列共享。对于一个VARCHAR列存储多字节字符的最大数量,有效人物少。例如,utf8mb4字符需要四字节的每个字符,所以VARCHAR柱的使用utf8mb4字符集可以声明为最多16383个字符。看到第c.10.4,“限制表的列数和行的大小”

InnoDB固定长度字段大于或等于768字节长度的变长字段的编码,它可以存储页。例如,一个char(255)柱可以超过768字节如果字符集的最大字节长度大于3,因为它是utf8mb4

一个尺寸ENUM对象是由不同的枚举值的数目决定。一个字节用于多达255个可能的值的枚举。两字节用于有256和65535个可能的值的枚举。看到第11.4.4,“类型”

一个尺寸SET对象是由不同的集合成员数确定。如果设置的大小是N占有的对象,N7)/ 8字节,调高至1,2,3,4,或8个字节。一SET最多可以有64个成员。看到第11.4.5,“集合式”

空间类型的存储要求

MySQL存储几何值使用4个字节表示SRID遵循价值的WKB表示。这个LENGTH()函数返回值存储在所需的字节空间。

对空间价值的WKB和内部存储格式的描述,参见11.5.3节,“支持空间数据格式”

JSson Stock requirements

一般来说,对于一个存储要求JSON柱是大致相同的一个longblobLONGTEXT柱;即通过JSON文件占用的空间大致相同,这将对文件的字符串表示形式存储在列这些类型之一。然而,有一个架空的二进制编码的限制,包括需要查找元数据字典,个人的值存储在JSON文档。例如,一个字符串存储在一个JSON文件需要4到10个字节的额外存储,根据字符串的长度和它的对象或数组的大小存储。

此外,MySQL对任何JSON文档存储在一个大小限制JSON柱,它不能被任何大于价值max_allowed_packet

11.9为一列选择正确类型

最佳的存储,你应该试着在所有的情况下,用最精确的类型。例如,如果一个整数列用于值的范围从1九万九千九百九十九MEDIUMINT UNSIGNED是最好的类型。表示所有所需的值的类型,该类型使用的存储量最少。

所有的基本计算(+*,和/)与DECIMAL列了65位小数精度(基地10)。看到第11.1.1,“数字类型概述”

如果精度不太重要或如果速度是最高优先级,这DOUBLE型可能是不够好。高精度,你总是可以转换为定点类型存储在BIGINT。这使你能够做所有的计算与64位整数,然后将结果返回浮点值是必要的。

11.10使用其他数据库引擎的数据类型

为了方便其他厂商的SQL实现代码的使用,MySQL的地图数据类型如下表所示。这些映射,使它更容易从其他数据库表定义导入到MySQL。

数据类型映射发生在创建表时,在原来的类型被丢弃。如果你创建与使用其它厂商类型表并出具DESCRIBE tbl_name报告声明,MySQL表结构用等效MySQL类型。例如:

MySQL的&#62;CREATE TABLE t (a BOOL, b FLOAT8, c LONG VARCHAR, d NUMERIC);查询行,0行受影响(0秒)MySQL &#62;DESCRIBE t;------- --------------- ------ ----- --------- ------- |场|型|空|关键|默认|额外| ------- --------------- ------ ----- --------- ------- |一| tinyint(1)|是| |空| | | B |双|是| |空| | | C | mediumtext |是| |空| | | D |十进制(10,0)|是| |空| | ------- --------------- ------ ----- --------- ------- 4行集(0.01秒)