Mysql data types - official documents - study notes - numerical values, date and time, strings, json

Mysql data types-official documents-study notes

Table of contents

MySQL supports several types of SQL data types: numeric types, date and time types, string (character and byte) types, spatial types and JSONdata types. This chapter provides an overview and more detailed description of the type properties in each category, as well as a summary of the data type storage requirements.

Data type descriptions use the following conventions:

  • For integer types, * M* represents the maximum display width. For floating-point and fixed-point types, ** Mis the total number of bits that can be stored (precision). For string types, * Mis the maximum length. MThe maximum allowed value of * depends on the data type.

  • * D*Applicable to floating-point and fixed-point types, indicating the number of digits after the decimal point (number of decimal places). The maximum possible value is 30, but should not be greater than M-2.

  • * fsp* Applies to the TIME, DATETIMEand TIMESTAMPtypes and represents fractional seconds precision; that is, the number of fractional seconds after the decimal point. The * fsp* value, if given, must be in the range 0 to 6. A value of 0 means no decimal part. If omitted, the default precision is 0. (This is different from the standard SQL default of 6 for compatibility with previous MySQL versions.)

  • Square brackets ( [and ]) represent optional parts of the type definition.

1. Numeric data type

1.1 Numeric data type syntax

1.2 Integer types (exact values) - INTEGER, INT, SMALLINT, TINYINT, MEDIUMINT, BIGINT

1.3 Fixed-point types (exact values) - DECIMAL, NUMERIC

1.4 Floating point types (approximate values) - FLOAT, DOUBLE

1.5 Bit Value Type - BIT

1.6 Numeric type attributes

1.7 Out of range and overflow handling

MySQL supports all standard SQL numeric data types.
These types include exact numeric data types (INTEGER, SMALLINT, DECIMAL, and NUMERIC), and approximate numeric data types (FLOAT, REAL, and DOUBLE PRECISION).
The keyword INT is a synonym of INTEGER,
the keywords DEC and FIXED are synonyms of DECIMAL,
MySQL treats DOUBLE as a synonym of DOUBLE PRECISION (non-standard extension),
MySQL also treats REAL as a synonym of DOUBLE PRECISION (non-standard variant), Unless the REAL_AS_FLOAT SQL mode is enabled.

The data type BIT stores "bit" values ​​and supports MyISAM, InnoDB, MEMORY and NDB tables.

1.1 Syntax of numeric data types

  • For integer data types, Mrepresents the maximum display width. The maximum display width is 255. Display width has nothing to do with the range of values ​​that a type can store. int(M)Example: int(4)Indicates that the maximum display is 4 digits, namely units, tens, hundreds and thousands.
  • For floating-point and fixed-point data types, Mit is the total number of digits that can be stored (including the decimal part). The "bit" here is not the same concept as bit. The "bit" here refers to the number of digits in the number, that is, the units digit. , tens, etc.
    • Fixed point: decimal(M[,D])Example: decimal(1)Indicates that mysql only stores 1-digit integers
    • Floating point: float(M[,D])Example: float(1)Indicates that mysql only stores 1-digit integers

If you specify ZEROFILL for a numeric column, MySQL automatically adds the UNSIGNED attribute to the column.

Numeric data types allow UNSIGNED properties as well as SIGNED. However, these data types are signed by default, so the SIGNED attribute has no effect.

SERIAL DEFAULT VALUE is an alias for NOT NULL AUTO_INCREMENT UNIQUE in the definition of an integer column.

Warning
When you use subtraction between integer values ​​of type UNSIGNED, the result is unsigned unless SQL mode NO_UNSIGNED_SUBTRACTION is enabled.

1.1.1 BIT[(M)]

Bit value type. MRepresents the number of digits in each value, from 1to 64. If Momitted, it defaults to 1.

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

A very small integer, occupying 1bytes. The signed range is -2[^7] = -128to 2[^7]-1 = 127. The unsigned range is 0to 2[^8]-1 = 255.
MIndicates the maximum display width

1.1.3 BOOL, BOOLEAN

These types are TINYINT(1)synonyms for . A value of zero is considered . Non-zero values ​​are considered :

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

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

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

However, the values TRUE​​and FALSEare just aliases for 1and 0, respectively as follows:

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                          |
+--------------------------------+

The last two statements show the result of 2not equal to TRUEand FALSEbecause 2neither is equal to 1nor equal to 0.

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

A small integer, occupying 2bytes. The signed range is -2[^15] = -32768to 2[^15]-1 = 32767. The unsigned range is 0to 2[^16]-1 = 65535.

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

A medium-sized integer in 3bytes. The signed range is -2[^23] = -8388608to 2[^23]-1 = 8388607. The unsigned range is 0to 2[^24]-1 = 16777215.

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

A normal-sized integer, in 4bytes. The signed range is -2[^31] = -2147483648to 2[^31]-1 = 2147483647. The unsigned range is 0to 2[^32]-1 = 4294967295.

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

This type is INTa synonym for .

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

A large integer, occupying 8bytes. The signed range is -2[^63] = -9223372036854775808to 2[^63]-1 = 9223372036854775807. The unsigned range is 0to 2[^64]-1 = 18446744073709551615.

SERIALYes BIGINT UNSIGNED NOT NULL AUTO_INCREMENT UNIQUEalias.

BIGINTSome things you should note about columns :

  • All arithmetic is done using signed BIGINTOR values, so you should not use unsigned big integers larger than (63 bits), except for bit functions! If you do this, some of the last numbers in the result may be wrong because of rounding errors when converting the value toDOUBLE9223372036854775807BIGINTDOUBLE

    MySQL can handle BIGINTthe following situations:

  • BIGINTIt is always possible to store exact integer values ​​by using a string to assign it to a column. In this case, MySQL performs a string-to-number conversion that does not involve an intermediate double representation.

  • The , and operators use arithmetic -when both operands are integer values . This means that if you multiply two large integers (or the result of a function that returns an integer), you may get unexpected results when the result is greater than .+*BIGINT9223372036854775807

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

A compressed "exact" fixed-point number.

  • * M* is the total number of digits (precision), its range is 1 to 65, and the default value is 10.
  • Dis the number of digits (scale) to the right of the decimal point. It ranges from 0 to 30 and cannot be greaterM . The default value is 0.
  • 小数点Signs and -(negative) signs are not counted M. If ** Dis 0, the value has no decimal point or decimal part.

( DECIMALLiteral text is also limited in length; see Expression Handling .)

If specified UNSIGNED, negative values ​​are not allowed.

DECIMALAll basic calculations with columns ( +, -, *, /) are done with 65 digits of precision.

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

These types are DECIMALsynonyms for . FIXEDSynonyms are available for compatibility with other database systems.

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

A small (single precision) floating point number. Allowed values ​​are -3.402823466E+38to -1.175494351E-38, 0and 1.175494351E-38to 3.402823466E+38. These are theoretical limits based on IEEE standards. Actual range may be slightly smaller depending on hardware or operating system.

Mis the total number of digits and Dis the number of digits after the decimal point. IfM and *D* are omitted, the value is stored within the range allowed by the hardware. Single-precision floating point numbers are accurate to approximately 7 decimal places.

FLOAT(M,D)Is a non-standard MySQL extension.

If specified UNSIGNED, negative values ​​are not allowed.

Using FLOATmay cause you some unexpected problems because all calculations in MySQL are done in double precision. See "Resolving No Matching Rows" .

1.1.12 FLOAT(p) [UNSIGNED] [ZEROFILL]

一个浮点数。p 表示以位为单位的精度,但 MySQL 仅使用此值来确定是使用 FLOAT还是 DOUBLE用于生成的数据类型。如果*p是从 0 到 24,则数据类型变为FLOATM*或 *D*值。如果 *p*是从 25 到 53,则数据类型变为DOUBLEMD 值。结果列的范围与本节前面描述 的单精度FLOAT或双精度 DOUBLE 数据类型相同。

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

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

一个正常大小(双精度)的浮点数。允许的值为 -1.7976931348623157E+308to -2.2250738585072014E-30802.2250738585072014E-308to 1.7976931348623157E+308。这些是基于 IEEE 标准的理论限制。根据您的硬件或操作系统,实际范围可能会稍小一些。

M是总位数,D是小数点后的位数。如果省略M 和*D*,则将值存储在硬件允许的范围内。双精度浮点数精确到大约 15 位小数。

DOUBLE(M,D) 是一个非标准的 MySQL 扩展。

如果指定 UNSIGNED,则不允许负值。

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

1.2 整数类型(精确值) - INTEGER、INT、SMALLINT、TINYINT、MEDIUMINT、BIGINT

MySQL supports the SQL standard integer types INTEGER(or INT) and SMALLINT. As an extension to the standard, MySQL also supports the integer types TINYINT, MEDIUMINTand BIGINT. The following table shows the storage space and range required for each integer type.

Table 1.1 Required storage and range of integer types supported by MySQL

type Storage (bytes) Minimum value (signed) Maximum value (signed) Minimum value (unsigned) Maximum value (unsigned)
TINYINT 1 -128 127 0 255
SMALLINT 2 -32768 32767 0 65535
MEDIUMINT 3 -8388608 8388607 0 16777215
INT 4 -2147483648 2147483647 0 4294967295
BIGINT 8 -2[^63] 2[^63]-1 0 2[^64]-1

1.3 Fixed-point types (exact values) - DECIMAL, NUMERIC

DECIMALand NUMERICtypes store exact numeric data values. Use these types when maintaining precise accuracy is important, such as currency data. In MySQL, NUMERICis implemented as DECIMAL, so the following DECIMALalso applies NUMERIC.

MySQL DECIMALstores values ​​in binary format (note: instead of storing numeric characters in strings, because I thought they were strings at first), each 9 numeric characters are segmented and stored in 4 bytes, and integers are The decimal part is stored separately, and the decimal part is also segmented according to every 9 numeric characters. For the part that is less than 9 characters after segmentation, the remaining digits are stored according to the minimum number of bytes principle. For details on how to store it, see "Exact Mathematics" .

DECIMALPrecision and scale can (and usually do) be specified in the column declaration . For example:

salary DECIMAL(5,2)

In this case, 5it's the precision and 2it's the number of decimal places. Precision is expressed as the number of significant digits the value is stored in, and scale is expressed as the number of digits that can be stored after the decimal point.

Standard SQL requires DECIMAL(5,2)the ability to store any value with 5 digits and 2 decimal places, so salarythe range of values ​​that can be stored in the column ranges from -999.99to 999.99.

In standard SQL, the syntax DECIMAL(M)is equivalent to DECIMAL(M,0). Similarly, the syntax DECIMALis equivalent to DECIMAL(M,0), which allows the implementation to decide Mthe value of . MySQL supports these two different forms of DECIMALsyntax. MThe default value is 10.

If the decimal is 0, DECIMALthe value does not contain a decimal point or decimal part.

DECIMALThe maximum number of digits is 65, but the actual range of a given DECIMALcolumn may be limited by the precision or scale of the given column. If a value assigned to such a column has more than a specific number of decimal places allowed, the value is converted to that number of decimal places. (The exact behavior is operating system specific, but usually the effect is to truncate to the number of allowed bits.)

1.4 Floating point types (approximate values) - FLOAT, DOUBLE

FLOATand DOUBLEtypes represent approximate numeric data values. MySQL uses four bytes for single-precision values ​​and eight bytes for double-precision values.

For FLOAT, the SQL standard allows keywords in parentheses to specify the precision of the following decimals (but not the exponent range) in units of bits (note that it is different from the digits of fixed-point numbers, here are binary digits), that is FLOAT(p). MySQL also supports this optional precision specification, but FLOAT(p)the precision value of is only used to determine storage size, and a precision from 0 to 23 will produce a 4-byte single-precision FLOATcolumn. Precisions from 24 to 53 produce an 8-byte double DOUBLEcolumn.

MySQL allows the use of non-standard syntax: FLOAT(M,D)or REAL(M,D)or DOUBLE PRECISION(M,D). Here, it means that a total of up to digits (M,D)can be stored , of which digits may be after the decimal point. For example, a column defined as will look like: . MySQL performs rounding when storing values, so if inserted into the column, the approximate result is that the digit after the 4th decimal place is rounded, and 0.00009 is "rounded" to 0.00010.MD
FLOAT(7,4)-999.9999999.00009FLOAT(7,4)999.0001

Because floating point values ​​are approximate and not stored as exact values, trying to treat them as exact values ​​in comparisons can cause problems. They are also affected by platform or implementation dependencies. See "Floating Point Value Issues" for more information .

For maximum portability, code that needs to store approximate numeric data values ​​should use FLOATor DOUBLE PRECISIONnot specify precision or number of digits.

1.5 bit value type - BIT

BITData type is used to store (binary) "bit" values. A BIT(M)type allows storage Mof binary digit values. MThe range can be from 1 to 64.

To specify the value of a "bit", binary notation can be used b'value'. bIndicates that it is followed by a binary number, enclosed in single quotes, and valueis a binary value written using 0s and 1s. For example, b'111'and b'10000000'represent decimal 7and respectively 128. See "Place-value literal" .

If a Mvalue less than ** bits long is assigned to BIT(M)a column, the value is padded on the left with zeros. For example, b'101'assign the value of to BIT(6)the column. Since 101there are only 3 binary digits, which is insufficient for the expected 6digits, the left padding is enough 0to make up for 6the digits and the number b'000101'is stored in mysql.

NDB Cluster : The maximum combined size of NDBall columns used in a given table must not exceed 4096 bits.BIT

1.6 Numeric type attributes

1.6.1 int(M)

int(6) The 6 in the brackets represents the maximum number of digits that can be "displayed", but it is a different concept from the "number of bits" stored. They have no relationship and do not affect each other.
The int type occupies 4 bytes, 32 binary bits, the maximum value is 2.1 billion, and the number of complete numbers is 10 digits. int(6) means telling the application to display a maximum of 6 digits. This "6 digits" starts counting from right to left and counts to the 6th digit, that is, units, tens, hundreds, thousands, ten thousand, and tens. Thousands of people.
Whether (6) is supported depends on the processing of the application. MySQL only recommends displaying a maximum of 6 digits.
For example: if the number "1234567" is stored in the field of int(6), MySQL recommends displaying 6 digits, that is, "234567" ", but the actual number of displayed digits is determined by the application. The application can accept MySQL's suggestion to display the last 6 digits, or it can ignore this suggestion and display the complete 7-digit number. This width will be returned to the application along with the result set
.

1.6.2 UNSIGNED

All integer types can have an optional (non-standard) UNSIGNED attribute.
Unsigned types can be used to allow only nonnegative numbers in a column, or when you need a larger range of values ​​for the column. For example, if a column is INT UNSIGNED, the size of the column range (the number of representable numbers) is the same, but its endpoints are moved upward, from the original 1 bit for the sign and 31 bits for the value to 0 bits for the sign (i.e. Unsigned bit) and 32 bits represent numerical values, and the representable numerical range changes from -2147483648 to 2147483647 to from 0 to 4294967295.

Floating-point and fixed-point types can also be UNSIGNED. Like integer types, this property prevents negative values ​​from being stored in the column. Unlike integer types, the upper limit of column values ​​remains unchanged.

1.6.3 ZEROFILL

If you specify ZEROFILL for a numeric column, MySQL automatically adds the UNSIGNED attribute.

1.6.4 AUTO_INCREMENT

Integer or floating-point data types can have the AUTO_INCREMENT attribute. When you insert a NULL value into an indexed column with AUTO_INCREMENT, the column is set to the next sequence value. Typically this is value+1, where value is the maximum value of the current column in the table. (AUTO_INCREMENT sequence starts with 1)

Storing 0 in an AUTO_INCREMENT column has the same effect as storing NULL, unless SQL mode NO_AUTO_VALUE_ON_ZERO is enabled.
If the column allows NULL, inserting NULL into the column will not trigger auto-increment, but insert NULL into the column.
If a positive integer is inserted into the column, the positive integer will be used as a new sequence, so that the next incrementing value will be sequentially arranged starting from the new sequence.

Actual operation:

create table tt (
	ID int(2) primary key AUTO_INCREMENT,
	name VARCHAR(1)
);
> OK

insert into tt VALUES (0, 'a'), (3, 'b'), (NULL, 'c');
> Affected rows: 3

select * from tt;
1	a 	# (0, 'a'), 插入id是0,但实际被自动自增为1。因为0与NULL一样都认为是非法的值,这种值遇上 AUTO_INCREMENT 就被认为需要mysql自增得到一个值
3	b 	# (3, 'b'), 指定了3作为id值,实际上3被采纳为ID值了。因为3是一个合法的数值,所以直接采纳,并将 AUTO_INCREMENT 的自增值记录为3,为下次自增做准备
4	c 	# (NULL, 'c'), 插入id是NULL,但实际被自动自增为4。因为上次已经将自增值改为3了,所以本次的自增是3+1=4

AUTO_INCREMENT does not support negative value columns.

1.7 Out of range and overflow handling

When MySQL stores a value in a numeric column outside the range allowed by the column's data type, the results depend on the SQL mode in effect at the time:

  • If strict SQL mode is enabled, MySQL rejects out-of-range values ​​with an error according to SQL standards, and the insert fails.

  • If restricted mode is not enabled, MySQL clips values ​​to the appropriate endpoint of the column's data type range and stores the resulting value.

    When an out-of-range value is assigned to an integer column, MySQL only stores the value in the range corresponding to the range of the column's data type (this sentence is a mouthful, in human language: MySQL will truncate the high bits according to the binary bits and retain the low bits).

    When a value assigned to a floating-point or fixed-point column exceeds the range represented by the specified (or default) precision and scale, MySQL stores only the value corresponding to that range. (I don’t quite understand how to save it?)

Suppose a table t1has this definition:

CREATE TABLE t1 (i1 TINYINT, i2 TINYINT UNSIGNED);

When strict SQL mode is enabled, an out-of-range error occurs:

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)

When strict SQL mode is not enabled, a clipped warning appears:

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 |
+------+------+

When strict SQL mode is not enabled, column allocation conversions due to clipping are reported as warnings for ALTER TABLE, LOAD DATA, UPDATEand multi-row statements. In strict mode, these statements fail and some or all of the values ​​are not inserted or changed, depending on factors such as whether the table is transactional. For more information, see Server SQL Mode .INSERT

Overflow during evaluation of a numeric expression causes an error. For example, the maximum signed BIGINTvalue is 9223372036854775807, so the following expression produces an error:

mysql> SELECT 9223372036854775807 + 1;
ERROR 1690 (22003): BIGINT value is out of range in '(9223372036854775807 + 1)'

To make the operation succeed in this case, convert the value to unsigned;

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

Whether overflow occurs depends on the range of the operands, so another way to handle the above expression is to use exact value arithmetic, since the DECIMALrange of values ​​is larger than integers:

mysql> SELECT 9223372036854775807.0 + 1;
+---------------------------+
| 9223372036854775807.0 + 1 |
+---------------------------+
|     9223372036854775808.0 |
+---------------------------+

Subtraction between integer values, one of which is UNSIGNEDof type, produces an unsigned result by default. If the result is negative, an error will result:

mysql> SET sql_mode = '';
Query OK, 0 rows affected (0.00 sec)

mysql> SELECT CAST(0 AS UNSIGNED) - 1;
ERROR 1690 (22003): BIGINT UNSIGNED value is out of range in '(cast(0 as unsigned) - 1)'

If NO_UNSIGNED_SUBTRACTIONSQL mode is enabled, the result is a negative number without an error:

mysql> SET sql_mode = 'NO_UNSIGNED_SUBTRACTION';
mysql> SELECT CAST(0 AS UNSIGNED) - 1;
+-------------------------+
| CAST(0 AS UNSIGNED) - 1 |
+-------------------------+
|                      -1 |
+-------------------------+

If the result of such an operation is used to update UNSIGNEDan integer column, the result will be clipped to the maximum value of the column type, or NO_UNSIGNED_SUBTRACTIONto 0 if enabled. If strict SQL mode is enabled, an error occurs and the columns remain unchanged.

2. Date and time data types (5 types)

2.1 Date and time data type syntax

2.2 DATE, DATETIME and TIMESTAMP types

2.3 TIME type

2.4 Year type

2.5 2-digit YEAR(2) limitations and migration to 4-digit YEAR

2.6 Automatic initialization and update of TIMESTAMP and DATETIME

2.7 Fractional seconds in time values

2.8 Conversion between date and time types

2.9 2-digit year date

The date and time data types used to represent time values ​​are DATE, TIME, DATETIME, TIMESTAMPand YEAR. Each time type has a range of valid values, as well as a "zero" value that can be used when you specify an invalid value that MySQL cannot represent. TIMESTAMPand DATETIMEtypes have special automatic update behavior, described in Section 2.6, “Automatic initialization and update of TIMESTAMP and DATETIME” .

For information about storage requirements for temporary data types, see Data Type Storage Requirements .

For a description of functions that operate on time values, see Date and Time Functions .

When working with date and time types, keep the following general considerations in mind:

  • MySQL retrieves values ​​of a given date or time type in standard output format, but it attempts to interpret various formats for the input values ​​you provide (for example, when you specify a value to assign to or compare with a date or time type) . See Date and Time Literals for a description of the allowed formats for date and time types . Expecting valid values ​​from you. If you use values ​​in other formats, unpredictable results may occur.

  • Although MySQL attempts to interpret values ​​in a variety of formats, the date part must always be given in year-month-day order (for example, '98-09-04') and not in month-day-year or day-month-year order as is commonly used elsewhere (for example, For example '09-04-98',, '04-09-98'). STR_TO_DATE()This function may be useful to convert strings in other order to year month day order .

  • Dates containing 2-digit year values ​​are ambiguous because the century is unknown. MySQL uses the following rules to interpret 2-digit year values:

    • 70-99The year values ​​in the range become 1970-1999.
    • 00-69The year values ​​in the range become 2000-2069.

    See also Section 2.9, “Two-digit years in dates” .

  • Converts a value from one time type to another according to the rules in Section 2.8, “Conversions between Date and Time Types” .

  • MySQL automatically converts a date or time value to a number if the value is used in a numeric context, and vice versa.

  • By default, when MySQL encounters a value of a date or time type that is out of range or invalid for that type, it converts the value to the "zero" value of that type. The exception is that out-of-range TIMEvalues ​​are clipped to the appropriate TIMErange.

  • By setting the SQL mode to the appropriate value, you can more precisely specify the date types you want MySQL to support. (See "Server SQL Mode."ALLOW_INVALID_DATES ) You can have MySQL accept certain dates by enabling SQL mode, for example '2009-11-31'. This is useful when you want to store user-specified "possibly wrong" values ​​in a database (for example, in a Web form) for future processing. In this mode, MySQL only verifies that the month is in the range 1 to 12 and the day is in the range 1 to 31.

  • MySQL allows you to store day or month and day with zero in the DATEor column. DATETIMEThis is useful for applications that need to store birthdays for which you may not know the exact date. In this case you just store the date as '2009-00-00'or '2009-01-00'. However, you should not expect correct results for these dates, such as the DATE_SUB()or DATE_ADD()functions that require a complete date. To suppress the zero month or day part of the date, enable this NO_ZERO_IN_DATEmode.

  • MySQL allows you to '0000-00-00'store such "zero" values ​​as "dummy dates". In some cases this is NULLmore convenient than using values ​​and uses less data and index space. To disable '0000-00-00', enable this NO_ZERO_DATEmode.

  • "Zero" date or time values ​​used through Connector/ODBC are automatically converted NULLbecause ODBC cannot handle these values.

The following table shows the format of the "zero" value for each type. The "zero" values ​​are special, but you can store or reference them explicitly using the values ​​shown in the table. You can also use the easier-to-write value '0'or 0to represent the "zero" value. Using these values ​​with time types that contain date parts ( DATE, DATETIMEand TIMESTAMP) may produce warnings or errors. The exact behavior depends on NO_ZERO_DATEwhich, if any, strict mode and SQL mode are enabled; see Server SQL Mode .

type of data "zero" value
DATE '0000-00-00'
TIME '00:00:00'
DATETIME '0000-00-00 00:00:00'
TIMESTAMP '0000-00-00 00:00:00'
YEAR 0000

2.1 Date and time data type syntax

The date and time data types used to represent time values ​​are DATE, TIME, DATETIME, TIMESTAMPand YEAR.

For range descriptions of DATEand DATETIME, "supported" means that while earlier values ​​may be valid (work), they are not guaranteed.

MySQL allows fractional seconds for TIME, DATETIMEand values ​​with precision up to microseconds (6 digits). TIMESTAMPTo define a column that contains fractional seconds, use the syntax type_name( fsp), where type_nameis TIME, DATETIMEor TIMESTAMP, fspis the fractional seconds precision. For example:

CREATE TABLE t1 (t TIME(3), dt DATETIME(6), ts TIMESTAMP(0));

The * fsp* value, if given, must be in the range 0 to 6. A value of 0 means no decimal part. If omitted, the default precision is 0. (This is different from the standard SQL default of 6 for compatibility with previous MySQL versions.)

TIMESTAMPAny column or column in a table DATETIMEcan have automatic initialization and update properties; see Section 2.6, “Automatic initialization and update of TIMESTAMP and DATETIME” .

2.1.1 DATE

date. The scope of "supported" is '1000-01-01'to '9999-12-31'. MySQL displays values ​​in ' YYYY-MM-DD' format DATE, but allows the use of strings or numbers to assign values ​​to DATEcolumns.

2.1.2 DATETIME[(fsp)]

Date and time combination. The scope of "supported" is '1000-01-01 00:00:00.000000'to '9999-12-31 23:59:59.999999'. MySQL 'YYYY-MM-DD hh:mm:ss[.fraction]'displays DATETIMEvalues ​​in format, but allows values ​​to be assigned to DATETIMEcolumns using strings or numbers.

Optional values* fsp*A number in the range 0 to 6 can be given to specify fractional seconds precision. A value of 0 means no decimal part. If omitted, the default precision is 0.

You can use DEFAULTthe and ON UPDATEcolumn definition clauses to specify DATETIMEautomatic initialization and updating of columns to the current date and time, as described in Section 2.6, “Automatic initialization and updating of TIMESTAMP and DATETIME” .

2.1.3 TIMESTAMP[(fsp)]

timestamp. The range is '1970-01-01 00:00:01.000000'UTC to '2038-01-19 03:14:07.999999'UTC. TIMESTAMPThe value is stored as the number of seconds since the epoch ( '1970-01-01 00:00:00'UTC) TIMESTAMP. A timestamp cannot represent a value '1970-01-01 00:00:00', since this corresponds to 0 seconds from the epoch, but the value 0 is reserved for representing '0000-00-00 00:00:00'this "zero" value.

Optional values* fsp*A number in the range 0 to 6 can be given to specify fractional seconds precision. A value of 0 means no decimal part. If omitted, the default precision is 0.

The way server processing TIMESTAMPis defined depends on explicit_defaults_for_timestampthe value of a system variable (see "Server System Variables" ).

  • If enabled, the or attribute explicit_defaults_for_timestampis not automatically assigned to any column. They must be explicitly included in the column definition. Additionally, any column that is not explicitly declared as a value is allowed .DEFAULT CURRENT_TIMESTAMPON UPDATE CURRENT_TIMESTAMPTIMESTAMPTIMESTAMPNOT NULLNULL

  • If explicit_defaults_for_timestampdisabled, the server handles TIMESTAMPthis as follows:
    Unless otherwise specified, if a value is not explicitly assigned to the first TIMESTAMPcolumn in a Table, the column is automatically set to the most recently modified date and time. This makes the column useful TIMESTAMPfor recording timestamps of INSERTOR operations. UPDATEYou can also set a column to the current date and time by assigning it a NULLvalue TIMESTAMP, unless it has been defined to allow NULLvalues.

Automatic initialization and updating to the current date and time can be specified using the DEFAULT CURRENT_TIMESTAMPand ON UPDATE CURRENT_TIMESTAMPcolumn definition clauses. TIMESTAMPAs mentioned before, the first column has these properties by default. However, TIMESTAMPany column in the table can be defined to have these properties.

2.1.4 TIME[(fsp)]

time. The range is '-838:59:59.000000'to '838:59:59.000000'. MySQL displays values ​​in ' hh:mm:ss[. fraction]' format TIME, but allows using strings or numbers to assign values ​​to TIMEcolumns.

Optional values* fsp*A number in the range 0 to 6 can be given to specify fractional seconds precision. A value of 0 means no decimal part. If omitted, the default precision is 0.

2.1.5 YEAR[(4)]

Year in 4-digit format. MySQL YYYYdisplays YEARvalues ​​in format, but allows values ​​to be assigned to YEARcolumns using strings or numbers. YEARValues ​​are displayed as: 1901, 2155or 0000.

Notice:

This data type has been deprecated and support has been removed in MySQL 5.7.5 YEAR(2). To convert a 2-bit column YEAR(2)to a 4-bit column YEAR, see Section 2.5, “2-Bit YEAR(2) Limitations and Migration to 4-Bit YEAR” .

See Section 2.4, “YEAR Type” for more information on YEARthe display format and interpretation of input values .

2.1.6 Additional notes on time values

Aggregation functions SUM()and AVG()do not work with time values. (They convert the value to a number, losing everything after the first non-numeric character.) To fix this, convert to numeric units, perform an aggregation operation, and then convert back to a time value. example:

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

Notice:

MySQL server is the same MAXDBas with SQL mode enabled . If this mode is enabled when creating the table, columns are created as columns. Therefore, such columns use the display format, have the same value range, and are not automatically initialized or updated to the current date and time. See Server SQL Mode .TIMESTAMPDATETIMETIMESTAMPDATETIMEDATETIME

Deprecated as of MySQL 5.7.22 MAXDB; will be removed in a future version of MySQL.

2.2 DATE, DATETIME and TIMESTAMP types

DATE, DATETIMEand TIMESTAMPtypes are related. This section describes their characteristics, how they are similar, and how they are different. MySQL can recognize values ​​in multiple formats of DATE, DATETIMEand . For more information, see "Date and Time Literals" . For and range descriptions, "supported" means that while earlier values ​​may be valid, they are not guaranteed.TIMESTAMPDATEDATETIME

DATEType is used for values ​​that have a date part but no time part. MySQL 'YYYY-MM-DD'retrieves and displays DATEvalues ​​of type in format. The supported range is '1000-01-01'to '9999-12-31'.

DATETIMEType used for values ​​that contain both date and time components. MySQL 'YYYY-MM-DD hh:mm:ss'retrieves and displays DATETIMEvalues ​​in format. The supported range is '1000-01-01 00:00:00'to '9999-12-31 23:59:59'.

TIMESTAMPType used for values ​​that contain both date and time components. TIMESTAMPHas a range of '1970-01-01 00:00:01'UTC to '2038-01-19 03:14:07'UTC.

An DATETIMEOR TIMESTAMPvalue can include a trailing fractional seconds component with precision up to microseconds (6 digits). In particular, any fractional part of the value inserted into DATETIMEthe or column will be stored rather than discarded. TIMESTAMPAfter including the decimal part, the format of these values ​​is 'YYYY-MM-DD hh:mm:ss[.fraction]', DATETIMEtype value range is '1000-01-01 00:00:00.000000'to '9999-12-31 23:59:59.999999', TIMESTAMPtype value range is '1970-01-01 00:00:01.000000'to '2038-01-19 03:14:07.999999'. The fractional part should always be separated from the rest of the time by a decimal point; no other fractional seconds separators are recognized. For information about fractional seconds support in MySQL, see Section 2.7, “Fractional Seconds in Time Values” .

TIMESTAMPand DATETIMEdata types provide automatic initialization and updating to the current date and time. For more information, see Section 2.6, “Automatic Initialization and Update of TIMESTAMP and DATETIME” .

MySQL TIMESTAMPconverts values ​​from the current time zone to UTC for storage, and then converts values ​​from UTC back to the current time zone for retrieval. (This does not happen with other types, e.g. DATETIME) By default, the current time zone for each connection is the server's time. The time zone can be set on a per-connection basis. As long as the time zone setting remains unchanged, you can return the same value stored. If you store a TIMESTAMPvalue, then change the time zone and retrieve the value, the value retrieved is different from the value you stored. This happens because the same time zone is not used for conversion in both directions. The current time zone is available as time_zonea system variable. For more information, see MySQL Server Time Zone Support . If the
SQL schema allows this conversion, an invalid DATEor value is converted to a zero value ( or ) of the appropriate type. The exact behavior depends on whether strict SQL mode is enabled and which SQL mode is enabled; see Server SQL Mode .DATETIMETIMESTAMP'0000-00-00''0000-00-00 00:00:00'NO_ZERO_DATE

Please note certain properties of date value interpretation in MySQL:

  • MySQL allows values ​​to be specified as a "relaxed" format of strings, where any punctuation can be used as a separator between date parts or time parts. This syntax can be deceptive in some cases. For example, a value '10:11:12'may look like a time value because is used :, but if used in a date context '2010-11-12'is interpreted as a year. The value '10:45:15'will be converted '0000-00-00'because '45'it is not a valid month.

    The only recognized separator between the date and time parts and the fractional seconds part is the decimal point.

  • The server requires that the month and day values ​​be valid, not just in the ranges 1 to 12 and 1 to 31 respectively. '2004-04-31'With strict mode disabled, this will convert to an invalid date '0000-00-00'and generate a warning because April does not have a 31st. When strict mode is enabled, invalid dates will generate an error. To allow such dates, enable ALLOW_INVALID_DATES. For more information, see Server SQL Mode .

  • MySQL does not accept TIMESTAMPvalues ​​that contain zeros in day or month columns or that are not valid dates. The only exception to this rule is the special "zero" value if the SQL mode allows this value. '0000-00-00 00:00:00'The exact behavior depends on whether strict SQL mode is enabled and NO_ZERO_DATEwhich SQL mode is enabled; see Server SQL Mode .

  • Dates containing 2-digit year values ​​are ambiguous because the century is unknown. MySQL uses the following rules to interpret 2-digit year values:

    • The year values ​​in the range 00-69become 2000-2069.
    • The year values ​​in the range 70-99become 1970-1999.

See also Section 2.9, “Two-digit years in dates” .

2.3 TIME type

MySQL retrieves and displays values ​​in 'hh:mm:ss'format (or 'hhh:mm:ss'format for large "hour" values) . Values ​​can range from to . The hour part can be large, as the type can be used to represent not only a time of day (must be less than 24 hours) but also an elapsed time or a time interval between two events (which can be much greater than 24 hours , even negative numbers).TIMETIME'-838:59:59''838:59:59'TIME

MySQL 可以识别TIME几种格式的值,其中一些可以包括一个尾随小数秒部分,精度高达微秒(6 位)。请参阅 “日期和时间文字”。有关 MySQL 中小数秒支持的信息,请参阅 第 2.7 节,“时间值中的小数秒”。特别是,插入到 TIME 列中的值中的任何小数部分都会被存储而不是被丢弃。包含小数部分后, 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'(11 点后 12 分钟),但 MySQL 将它们解释为'00:11:12'(11 分钟,12 秒)。同样,'12'12被解释为 '00:00:12'。(个人总结:带冒号的时间值从左到右按“时分秒”的顺序解析,不带冒号的纯数字时间值从右到左按“秒分时”的顺序解析)

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

By default, TIMEvalues ​​outside the range that are otherwise valid are clipped to the nearest endpoint of the range. For example, '-850:00:00'and '850:00:00'is converted to '-838:59:59'and '838:59:59'. Invalid TIMEvalue is converted to '00:00:00'. Note that because '00:00:00'it is itself a valid value TIME, there is no way to tell from the value stored in the table '00:00:00'whether the original value was converted to invalid or the original value was '00:00:00'.

For TIMEstricter handling of invalid values, enable strict SQL mode to cause errors. See Server SQL Mode .

2.4 Year type

YEARType is a 1-byte type used to represent year values . It can be declared with YEARan implicit display width of 4 characters, or equivalently with an YEAR(4)explicit display width.

Notice

The 2-bit YEAR(2)data type is deprecated, and support for it was removed in MySQL 5.7.5. To convert a 2-bit YEAR(2)column to a 4-bit YEARcolumn, see Section 2.5, “2-Bit YEAR(2) Limitations and Migration to 4-Bit YEAR” .

MySQL YYYYdisplays YEARvalues ​​in the format, ranging from 1901to 2155and 0000.

YEARAccepts input values ​​in multiple formats:

  • '1901'A 4- digit string'2155' in the range to .

  • 1901to a 4- digit number2155 in the range .

  • '0'A 1-digit or 2-digit string'99' in the range to . MySQL converts values ​​in the to range to values ​​in to and values ​​in the to range into values ​​in to .'0''69'20002069YEAR'70''99'19701999YEAR

  • 0to 99a 1 or 2 digit number in the range . MySQL converts values ​​in 1the to 69range to values ​​in 2001to and values ​​in the to range into values ​​in to .2069YEAR709919701999YEAR

    Inserting the number 0has a displayed value of 0000and an internal value of 0000. If you want to insert zeros and have them interpreted 2000, specify it as a string '0' or '00'.

  • As YEARthe result of a function that returns values ​​acceptable in the context, NOW()e.g.

If strict SQL mode is not enabled, MySQL will YEARconvert invalid values ​​to 0000. In strict SQL mode, attempting to insert an invalid YEARvalue will generate an error.

See also Section 2.9, “Two-digit years in dates” .

2.5 2-digit YEAR(2) limitations and migration to 4-digit YEAR

This section describes issues that may arise when using 2-bit YEAR(2)data types and provides YEAR(2)information on converting an existing column to a 4-digit year value column, either by declaring it to have an YEARimplicit display width of 4 characters, or equivalently YEAR(4)For explicit display width.

Although the internal value ranges of YEAR/ YEAR(4)and deprecated types are the same ( to and ), the display width makes the type inherently ambiguous because the displayed value indicates only the last two digits of the internal value and omits the century digit. In some cases, the result may be a loss of information. For this reason, avoid using / in your application and use it wherever the year value data type is expected . Starting with MySQL 5.7.5, support for is removed and existing 2-bit columns must be converted to 4- bit columns before they are usable.YEAR(2)190121550000YEAR(2)YEAR(2)YEARYEAR(4)YEAR(2)YEAR(2)YEAR

2.5.1 YEAR(2)Limitations

YEAR(2)Issues with data types include ambiguity in displayed values, and possible loss of information when dumping and reloading values ​​or converting to strings.

  • The displayed YEAR(2)value may be ambiguous. Up to three YEAR(2)values ​​with different internal values ​​may have the same displayed value, as in the following example:

    mysql> CREATE TABLE t (y2 YEAR(2), y4 YEAR);
    Query OK, 0 rows affected, 1 warning (0.01 sec)
    
    mysql> INSERT INTO t (y2) VALUES(1912),(2012),(2112);
    Query OK, 3 rows affected (0.00 sec)
    Records: 3  Duplicates: 0  Warnings: 0
    
    mysql> UPDATE t SET y4 = y2;
    Query OK, 3 rows affected (0.00 sec)
    Rows matched: 3  Changed: 3  Warnings: 0
    
    mysql> SELECT * FROM t;
    +------+------+
    | y2   | y4   |
    +------+------+
    |   12 | 1912 |
    |   12 | 2012 |
    |   12 | 2112 |
    +------+------+
    3 rows in set (0.00 sec)
    
  • If you use mysqldump to dump the table created in the previous example, the dump file y2uses the same 2 bits ( 12) for all values. If the table is reloaded from the dump file, all generated rows have an internal value of 2012and a displayed value of 12, thus losing the distinction between them.

  • Converts a 2-digit or 4-digit YEARdata value to string form using its data type to display the width. Assume a YEAR(2)column and a YEAR/ YEAR(4)column both contain 1970values. Then they will each get the string results of '70'and '1970'. That is, the conversion from an internal value to a string loses information.

  • When inserting into a column CSVin a table YEAR(2), values ​​outside the 1970to 2069range are stored incorrectly. For example, inserting 2211would result in a displayed value of 11, but an internal value of 2011.

To avoid these problems, use 4-bit YEARor YEAR(4)data types instead of 2-bit YEAR(2)data types. Recommendations for migration strategies appear later in this section.

(TODO: not completed)

2.6 Automatic initialization and update of TIMESTAMP and DATETIME

TIMESTAMPand DATETIMEcolumns can be automatically initialized and updated to the current date and time (i.e. the current timestamp).

TIMESTAMPFor any or column in the table DATETIME, you can specify the current timestamp as the default, auto-update value:

  • Auto-initialized columns are set to the current timestamp of inserted rows that do not have a value assigned to the column.
  • An auto-updated column automatically updates to the current timestamp when the value of any other column in the row changes from its current value. If all other columns are set to their current values, automatically updated columns remain unchanged. To prevent an automatically updated column from updating when other columns change, explicitly set it to its current value. To update an auto-updated column if other columns have not changed, explicitly set it to the value it should have (for example, set it to CURRENT_TIMESTAMP).

Additionally, if system variables are disabled, you can initialize or update any (but not ) column to the current date and time explicit_defaults_for_timestampby assigning it a value , unless it has been defined to allow a value.TIMESTAMPDATETIMENULLNULL

To specify automatic properties, use DEFAULT CURRENT_TIMESTAMPthe and ON UPDATE CURRENT_TIMESTAMPclauses in the column definition. The order of the clauses does not matter. If both are present in the column definition, either one can appear first. CURRENT_TIMESTAMPAny synonyms for CURRENT_TIMESTAMPhave the same meaning as . They are CURRENT_TIMESTAMP(), NOW(), LOCALTIME, LOCALTIME(), LOCALTIMESTAMP, and LOCALTIMESTAMP().

(TODO: Not completed, the rest is the detailed description of NULL values ​​and default values)

2.7 Fractional seconds in time values

2.8 Conversion between date and time types

2.9 2-digit year date

3. String data type

3.1 String data type syntax

3.2 CHAR and VARCHAR types

3.3 BINARY and VARBINARY types

3.4 BLOB and TEXT types

3.5 ENUM type

3.6 SET type

3.1 String data type syntax

3.2 CHAR and VARCHAR types

3.3 BINARY and VARBINARY types

3.4 BLOB and TEXT types

3.5 ENUM type

3.6 SET type

4. Spatial data types

4.1 Spatial data types

4.2 OpenGIS geometric model

4.3 Supported spatial data formats

4.4 Geometric well-formedness and validity

4.5 Create spatial columns

4.6 Filling spatial columns

4.7 Obtaining spatial data

4.8 Optimization spatial analysis

4.9 Create spatial index

4.10 Using spatial indexes

4.1 Spatial data types

4.2 OpenGIS geometric model

4.3 Supported spatial data formats

4.4 Geometric well-formedness and validity

4.5 Create spatial columns

4.6 Filling spatial columns

4.7 Obtaining spatial data

4.8 Optimization spatial analysis

4.9 Create spatial index

4.10 Using spatial indexes

5. JSON data type

5.1. Creating JSON values
​​5.2. Normalization, merging and automatic packaging of JSON values
​​5.3. Searching and modifying JSON values
​​5.4. JSON path syntax
5.5. Comparison and sorting of JSON values
​​5.6. Converting between JSON and non-JSON values
​​5.7. JSON Aggregation of values
​​5.8, related references

Starting from MySQL 5.7.8, MySQL supports native data types defined by RFC 7159JSON , which can effectively access data in JSON (JavaScript Object Notation) documents. This data type has the following advantages over storing JSON-formatted strings in a string column:

  • Automatically validate JSONJSON documents stored in columns. Invalid documents generate errors.
  • Optimized storage format. JSON documents stored JSONin columns are converted into an internal format that allows fast reading of document elements. When the server must later read a JSON value stored in this binary format, it does not need to parse the value from the textual representation. The structure of the binary format enables the server to look up sub-objects or nested values ​​directly by key or array index without having to read all the values ​​before or after them in the document.

JSONThe space required to store a document is approximately the same as LONGBLOBor LONGTEXT; see Section 7, “Data Type Storage Requirements” for details . JSONIt is important to remember that the size of any JSON document stored in a column is limited by max_allowed_packetthe value of the system variable. (It can be larger than this value when the server manipulates JSON values ​​internally in memory; the limit applies when the server stores it.)

Columns JSONcannot have non- NULLdefault values.

In addition to JSONdata types, there is a set of SQL functions that enable operations on JSON values, such as creating, manipulating, and searching. The following discussion shows examples of these operations. See Section 12.18, “JSON Functions” for details on individual functions .

A set of spatial functions for operating on GeoJSON values ​​is also provided. See Spatial GeoJSON Functions .

JSONColumns, like other binary type columns, are not directly indexed; instead, you create an index on the generated column to JSONextract a scalar value from the column. For a detailed example, see Indexing Generated Columns to Provide JSON Column Indexes.

The MySQL optimizer also looks for compatible indexes on virtual columns that match JSON expressions.

MySQL NDB Cluster 7.5 (7.5.2 and later) supports columns and MySQL JSON functions, including creating indexes on columns JSONgenerated from columns as a workaround for columns that cannot be indexed. Each table supports up to 3 columns.JSONJSONNDBJSON

The next few sections provide basic information about the creation and manipulation of JSON values.

5.1、创建 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.18.2 节,“创建 JSON 值的函数”)以及将其他类型的值使用 CAST(value AS JSON) (请参阅 JSON 之间的转换)和非 JSON 值)转换为JSON类型 。接下来的几段描述了 MySQL 如何处理作为输入提供的 JSON 值。

在 MySQL 中,JSON 值被写为字符串。MySQL 解析在需要 JSON 值的上下文中使用的任何字符串,如果它作为 JSON 无效,则会产生错误。这些上下文包括将值插入到具有 JSON数据类型的列中,并将参数传递给需要 JSON 值的函数(通常显示为 *json_doc*或 *json_val*在 MySQL JSON 函数的文档中显示),如以下示例所示:

  • 如果值是有效的 JSON 值,则尝试将值插入JSON 列能成功,但如果不是,则失败:
mysql> CREATE TABLE t1 (jdoc JSON);
Query OK, 0 rows affected (0.20 sec)

mysql> INSERT INTO t1 VALUES('{"key1": "value1", "key2": "value2"}');
Query OK, 1 row affected (0.01 sec)

mysql> INSERT INTO t1 VALUES('[1, 2,');
ERROR 3140 (22032) at line 2: Invalid JSON text: 
"Invalid value." at position 6 in value (or column) '[1, 2,'.

In such error messages, Nthe position " at position " is 0-based, but this should only be considered a rough indication of where in the value the problem actually occurs.

  • The JSON_TYPE()function expects a JSON parameter and attempts to parse it into a JSON value. If valid, a JSON type value will be returned, otherwise an error will be generated:

    mysql> SELECT JSON_TYPE('["a", "b", 1]');
    +----------------------------+
    | JSON_TYPE('["a", "b", 1]') |
    +----------------------------+
    | ARRAY                      |
    +----------------------------+
    
    mysql> select json_type('{}');
    +-----------------+
    | json_type('{}') |
    +-----------------+
    | OBJECT          |
    +-----------------+
    1 row in set (0.00 sec)
    
    mysql> SELECT JSON_TYPE('"hello"');
    +----------------------+
    | JSON_TYPE('"hello"') |
    +----------------------+
    | STRING               |
    +----------------------+
    
    mysql> SELECT JSON_TYPE('hello');
    ERROR 3146 (22032): Invalid data type for JSON data in argument 1
    to function json_type; a JSON string or JSON type is required.
    

    MySQL uses utf8mb4character set (character set) and utf8mb4_bincharacter order (collation, character sorting rules, bin means using encoded values ​​for comparison) rules to process strings used in the JSON context. Strings in other character sets are converted utf8mb4to as needed. (For strings in asciithe or utf8character set, no conversion is required because asciiand utf8is utf8mb4a subset of.)

Description (add your own)

collation, character sorting rules. _binIndicates using encoded values ​​(binary) for comparison, _ciindicating case-insensitive (Insensitive), _csindicating case-sensitive

You can also specify whether the value of the string is case-sensitive, which is different from whether the table name of MySQL is case-sensitive.

CREATE TABLE `t` (
  `id` int(11) DEFAULT NULL,
  `s1` varchar(255) CHARACTER SET utf8 COLLATE utf8_bin DEFAULT NULL,
  `s2` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

# 插入两个数据,一个大写的Sql,一个小写的sql
mysql> insert into t values (NULL,'Sql','Sql'), (NULL,'sql','sql');
Query OK, 2 rows affected (0.04 sec)

# 查询所有数据:只有两条数据
mysql> select * from t;
+----+------+------+
| id | s1   | s2   |
+----+------+------+
|  1 | Sql  | Sql  |
|  2 | sql  | sql  |
+----+------+------+
2 rows in set (0.00 sec)

# 查询 _bin 编码值的字段,这是区分大小写的,所以只能得到小写sql的那一条数据
mysql> select * from t where s1 = 'sql';
+----+------+------+
| id | s1   | s2   |
+----+------+------+
|  2 | sql  | sql  |
+----+------+------+
1 row in set (0.00 sec)

# 查询 _ci 不区分大小写的字段,所以能查询到大写的Sql和小写的sql,共两条数据
mysql> select * from t where s2 = 'sql';
+----+------+------+
| id | s1   | s2   |
+----+------+------+
|  1 | Sql  | Sql  |
|  2 | sql  | sql  |
+----+------+------+
2 rows in set (0.00 sec)

As an alternative to writing JSON values ​​using literal strings, there are functions for combining JSON values ​​from component elements. JSON_ARRAY()Accepts a (possibly empty) list of values ​​and returns a JSON array containing these values:

mysql> SELECT JSON_ARRAY('a', 1, NOW());
+----------------------------------------+
| JSON_ARRAY('a', 1, NOW())              |
+----------------------------------------+
| ["a", 1, "2015-07-27 09:43:47.000000"] |
+----------------------------------------+

JSON_OBJECT()Gets a (possibly empty) list of key-value pairs and returns a JSON object containing these pairs:

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

JSON_MERGE()Accepts two or more JSON documents and returns the combined result:

mysql> SELECT JSON_MERGE('["a", 1]', '{"key": "value"}');
+--------------------------------------------+
| JSON_MERGE('["a", 1]', '{"key": "value"}') |
+--------------------------------------------+
| ["a", 1, {
   
   "key": "value"}]                 |
+--------------------------------------------+

For information about merging rules, see Normalization, merging, and automatic wrapping of JSON values .

JSON values ​​can be assigned to user-defined variables:

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

# 以下为我自己的测试。结论:@j的类型是longtext,而不是json类型
mysql> create table test select @j;
Query OK, 1 row affected (0.09 sec)
Records: 1  Duplicates: 0  Warnings: 0

mysql> desc test;
+-------+----------+------+-----+---------+-------+
| Field | Type     | Null | Key | Default | Extra |
+-------+----------+------+-----+---------+-------+
| @j    | longtext | YES  |     | NULL    |       |
+-------+----------+------+-----+---------+-------+
1 row in set (0.03 sec)

However, a user-defined variable cannot be JSONa data type, so although it @jlooks like a JSON value in the previous example and has the same character set and collation as a JSON value, it does not have a JSONdata type. Instead, JSON_OBJECT()the result is converted to a string when assigned to a variable (I actually measured it to be converted to longtexttype).

The string generated by converting a JSON value has a character set utf8mb4and a collation utf8mb4_bin:

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

Because utf8mb4_binis a binary collation, comparisons of JSON values ​​are case-sensitive.

# json字段区分大小写,但普通的字符串字段是不区分大小写
mysql> SELECT JSON_ARRAY('x') = JSON_ARRAY('X'), 'x' = 'X';
+-----------------------------------+-----------+
| JSON_ARRAY('x') = JSON_ARRAY('X') | 'x' = 'X' |
+-----------------------------------+-----------+
|                                 0 |         1 |
+-----------------------------------+-----------+
1 row in set (0.00 sec)

Case sensitivity also applies to JSON's null, trueand falsecharacters, which must always be written in lowercase:

mysql> SELECT JSON_VALID('null'), JSON_VALID('Null'), JSON_VALID('NULL');
+--------------------+--------------------+--------------------+
| JSON_VALID('null') | JSON_VALID('Null') | JSON_VALID('NULL') |
+--------------------+--------------------+--------------------+
|                  1 |                  0 |                  0 |
+--------------------+--------------------+--------------------+

mysql> SELECT CAST('null' AS JSON);
+----------------------+
| CAST('null' AS JSON) |
+----------------------+
| null                 |
+----------------------+
1 row in set (0.00 sec)

mysql> SELECT CAST('NULL' AS JSON);
ERROR 3141 (22032): Invalid JSON text in argument 1 to function cast_as_json:
"Invalid value." at position 0 in 'NULL'.

The case-sensitivity of JSON characters differs from the case-sensitivity of SQL NULL, TRUEand FALSEcharacters, which can be in any letter case:

mysql> SELECT ISNULL(null), ISNULL(Null), ISNULL(NULL);
+--------------+--------------+--------------+
| ISNULL(null) | ISNULL(Null) | ISNULL(NULL) |
+--------------+--------------+--------------+
|            1 |            1 |            1 |
+--------------+--------------+--------------+

Sometimes it may be necessary or desirable to insert quote characters (double "or single quotes ') into a JSON document. For this example, assume that you want to insert some JSON objects into a table created using the SQL statements shown here, which contain strings representing the statements that represent some practical facts about MySQL, each relevant to the appropriate Keyword pairing of strings:

mysql> CREATE TABLE facts (sentence JSON);

# 假设要插入json:mascot: The MySQL mascot is a dolphin named "Sakila".
# 使用 MySQL函数 JSON_OBJECT() 将其作为 JSON 对象插入到 facts 表中,必须使用反斜杠转义每个引号字符:
mysql> INSERT INTO facts VALUES
     >   (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 对象后,您可以通过执行简单的 SELECT 来看到反斜杠出现在 JSON 列值中,如下所示:
mysql> SELECT sentence FROM facts;
+---------------------------------------------------------+
| sentence                                                |
+---------------------------------------------------------+
| {
   
   "mascot": "Our mascot is a dolphin named \"Sakila\"."} |
+---------------------------------------------------------+

To find this mascotspecific sentence used as a key, you can use the column-path operator ->as follows:

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

This leaves the backslash intact as well as the surrounding quotes. To display the desired value using as a key mascot, but without surrounding quotes or any escape characters, use the inline path operator ->>as follows:

mysql> SELECT sentence->>"$.mascot" FROM facts;
+-----------------------------------------+
| sentence->>"$.mascot"                   |
+-----------------------------------------+
| Our mascot is a dolphin named "Sakila". |
+-----------------------------------------+

# 我实测报错:
mysql> SELECT sentence->>"$.mascot" FROM facts;
ERROR 1064 (42000): You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '>"$.mascot" FROM facts' at line 1

notes

If server SQL mode is enabled NO_BACKSLASH_ESCAPES, the previous example will not work correctly. If this mode is set, JSON object literals can be inserted using a single backslash instead of a double backslash, and the backslashes are preserved. If JSON_OBJECT()you use this function when performing an insert and this mode is set, you must alternate single and double quotes, as follows:

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

For more information about the effect of this mode on escaped characters in JSON values, see JSON_UNQUOTE()the function description.

5.2. Standardization, merging and automatic packaging of JSON values

5.2.1. Normalized JSON values

When a string is parsed and found to be a valid JSON document, it is also normalized: members with keys that are duplicates of keys previously found in the document are discarded (even if the values ​​are different). The object value generated by the following JSON_OBJECT()call does not include the second key1element because the key appears before the value:

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

Notice

This "first key wins" treatment of duplicate keys is inconsistent with RFC 7159 . This is a known issue in MySQL 5.7 and has been fixed in MySQL 8.0. (Bug #86866, Bug #26369555)

MySQL also discards extra spaces between keys, values, or elements in the original JSON document, and leaves (or inserts, if necessary) a space after each comma ( ,) or colon ( ) when displayed . :This is done to improve readability.

MySQL functions that produce JSON values ​​(see Section 12.18.2, “Functions that Create JSON Values” ) always return normalized values.

To improve search efficiency, it also sorts the keys of JSON objects. You should be aware that the results of this sorting are subject to change and are not guaranteed to be consistent across releases .

5.2.2. Merge JSON values

In the context of combining multiple arrays, multiple arrays are combined into a single array by concatenating the subsequently named array to the end of the first array . In the following example, JSON_MERGE()its parameters are combined into an array:

mysql> SELECT JSON_MERGE('[1, 2]', '["a", "b"]', '[true, false]');
+-----------------------------------------------------+
| JSON_MERGE('[1, 2]', '["a", "b"]', '[true, false]') |
+-----------------------------------------------------+
| [1, 2, "a", "b", true, false]                       |
+-----------------------------------------------------+

Merging is also performed when inserting values ​​into JSON columns, as shown below:

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} |
+-----------+

When multiple objects are combined, one object is produced. If multiple objects have the same key, the value for that key in the resulting merged object is an array containing the key's value:

mysql> SELECT JSON_MERGE('{"a": 1, "b": 2}', '{"c": 3, "a": 4}');
+----------------------------------------------------+
| JSON_MERGE('{"a": 1, "b": 2}', '{"c": 3, "a": 4}') |
+----------------------------------------------------+
| {
   
   "a": [1, 4], "b": 2, "c": 3}                      |
+----------------------------------------------------+

5.2.3. Automatically wrap JSON values

  • Automatic wrapping of non-array values

Non-array values ​​used in contexts that require array values ​​are automatically wrapped : the value is surrounded by [and ]characters to convert it to an array. In the following statements, each argument is automatically wrapped as an array ( [1], [2]). Then combine them to produce a single resulting array:

mysql> SELECT JSON_MERGE('1', '2'); # -> 临时状态: JSON_MERGE([1], [2])
+----------------------+
| JSON_MERGE('1', '2') |
+----------------------+
| [1, 2]               |
+----------------------+
  • Object automatic packaging

Merge array and object values ​​by automatically wrapping the object into an array and merging the two arrays:

mysql> SELECT JSON_MERGE('[10, 20]', '{"a": "x", "b": "y"}');
# -> 临时状态:JSON_MERGE('[10, 20]', '[{"a": "x", "b": "y"}]'); 将后面的{} 自动包装为[{}]
+------------------------------------------------+
| JSON_MERGE('[10, 20]', '{"a": "x", "b": "y"}') |
+------------------------------------------------+
| [10, 20, {
   
   "a": "x", "b": "y"}]                 |
+------------------------------------------------+

5.3. Search and modify JSON values

JSON path expressions select a value in a JSON document.

Path expressions are useful for functions that extract part of a JSON document or modify a JSON document to specify where in the document to operate. nameFor example, the following query extracts the value of a member with a key from a JSON document :

mysql> SELECT JSON_EXTRACT('{"id": 14, "name": "Aztalan"}', '$.name');
+---------------------------------------------------------+
| JSON_EXTRACT('{"id": 14, "name": "Aztalan"}', '$.name') |
+---------------------------------------------------------+
| "Aztalan"                                               |
+---------------------------------------------------------+

The path syntax uses a leading $character to identify the JSON document under consideration, followed by optional expressions following the selector that in turn specify more specific parts of the document:

  • A period followed by the key name names the member in the object using the given key. If the unquoted name is not legal in a path expression (for example, it contains spaces), the key name must be specified within double quotes.

  • [N]Immediately following pathmeans selecting an element pathwith the subscript of the array name ( ) , which is an integer starting from zero. If the selection is not an array, * *[0] is equivalent to :NNpathpathpath

    mysql> SELECT JSON_SET('"x"', '$[0]', 'a');
    +------------------------------+
    | JSON_SET('"x"', '$[0]', 'a') |
    +------------------------------+
    | "a"                          |
    +------------------------------+
    1 row in set (0.00 sec)
    
  • The path can contain *or **wildcard characters:

    • .[*]Calculate the values ​​of all members in a JSON object.
    • [*]Calculate the value of all elements in a JSON array.
    • prefix**suffixCounts all paths prefixstarting with and ending with .suffix
  • Paths that do not exist in the document (evaluate as non-existent data) evaluate to NULL.

Let's $reference this three-element JSON array:

[3, {
    
    "a": [5, 6], "b": 10}, [99, 100]]

Then:

  • $[0]Evaluated as 3.
  • $[1]Evaluated as {"a": [5, 6], "b": 10}.
  • $[2]Evaluated as [99, 100].
  • $[3]Evaluates to NULL(it refers to the fourth array element, which does not exist).

Because $[1]and $[2]evaluate to non-scalar values, they can be used as the basis for more specific path expressions that select nested values. example:

  • $[1].aEvaluated as [5, 6].
  • $[1].a[1]Evaluated as 6.
  • $[1].bEvaluated as 10.
  • $[2][0]Evaluated as 99.

As mentioned before, if the key name is not legal in a path expression, the path components of the key must be enclosed in quotes. Let $refer to this value:

{
    
    "a fish": "shark", "a bird": "sparrow"}

Both keys contain a space and must be enclosed in quotes:

  • $."a fish"Evaluated as shark.
  • $."a bird"Evaluated as sparrow.

A path using wildcards evaluates to an array that can contain multiple values:

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[*]'); # 与'$.c' 等价
+------------------------------------------------------------+
| JSON_EXTRACT('{"a": 1, "b": 2, "c": [3, 4, 5]}', '$.c[*]') |
+------------------------------------------------------------+
| [3, 4, 5]                                                  |
+------------------------------------------------------------+

In the following example, path $**.bevaluates to multiple paths ( $.a.bsum $.c.b) and produces an array of matching path values:

mysql> SELECT JSON_EXTRACT('{"a": {"b": 1}, "c": {"b": 2}}', '$**.b');
+---------------------------------------------------------+
| JSON_EXTRACT('{"a": {"b": 1}, "c": {"b": 2}}', '$**.b') |
+---------------------------------------------------------+
| [1, 2]                                                  |
+---------------------------------------------------------+

In MySQL 5.7.9 and later, you can use column->pathJSON column identifiers and JSON path expressions as JSON_EXTRACT(column, path)synonyms for . For more information, see Section 12.18.3, “Functions to Search JSON Values” . See also Index generated columns to provide JSON column indexes .

Some functions take an existing JSON document, modify it in some way, and return the modified document as the result. Path expressions indicate where changes are made in the document. For example, JSON_SET()the , JSON_INSERT()and JSON_REPLACE()functions each accept a JSON document, plus one or more path/value pairs describing where to modify the document and the values ​​to use. These functions differ in how they handle existing and non-existing values ​​in the document.

Consider this document:

mysql> SET @j = '["a", {"b": [true, false]}, [10, 20]]';

JSON_SET()Replace the value of an existing path and add the value of a path that does not exist:

mysql> SELECT JSON_SET(@j, '$[1].b[0]', 1, '$[2][2]', 2);
+--------------------------------------------+
| JSON_SET(@j, '$[1].b[0]', 1, '$[2][2]', 2) |
+--------------------------------------------+
| ["a", {
   
   "b": [1, false]}, [10, 20, 2]]      |
+--------------------------------------------+

In this case, the path $[1].b[0]selects an existing value ( true), which is replaced by the following path parameter value ( 1). The path $[2][2]does not exist, so the corresponding value ( 2) is added to $[2]the selected values.

JSON_INSERT()Add new values ​​without replacing existing values:

mysql> SELECT JSON_INSERT(@j, '$[1].b[0]', 1, '$[2][2]', 2);
+-----------------------------------------------+
| JSON_INSERT(@j, '$[1].b[0]', 1, '$[2][2]', 2) |
+-----------------------------------------------+
| ["a", {
   
   "b": [true, false]}, [10, 20, 2]]      |
+-----------------------------------------------+
# TODO: 没看明白,为什么 '$[1].b[0]', 1 这个路径/值 对没有被添加到"b"数组的0号下标中

JSON_REPLACE()Replace existing values ​​and ignore new values:

mysql> SELECT JSON_REPLACE(@j, '$[1].b[0]', 1, '$[2][2]', 2);
+------------------------------------------------+
| JSON_REPLACE(@j, '$[1].b[0]', 1, '$[2][2]', 2) |
+------------------------------------------------+
| ["a", {
   
   "b": [1, false]}, [10, 20]]             |
+------------------------------------------------+

Path/value pairs are evaluated from left to right. The document generated by evaluating one pair becomes the new value for evaluating the next pair.

JSON_REMOVE()Accepts a JSON document and one (or more) paths that specify the values ​​to be removed from the document. The return value is the original document minus any path selections that exist in the document:

mysql> SELECT JSON_REMOVE(@j, '$[2]', '$[1].b[1]', '$[1].b[1]');
+---------------------------------------------------+
| JSON_REMOVE(@j, '$[2]', '$[1].b[1]', '$[1].b[1]') |
+---------------------------------------------------+
| ["a", {
   
   "b": [true]}]                              |
+---------------------------------------------------+

Paths have the following effects:

  • $[2]Match [10, 20]and delete it.
  • The first one $[1].b[1]matches bthe element falseand removes it.
  • The second one $[1].b[1]does not match any elements: the element expected to match has been removed, the path no longer exists, and has no effect.

5.4. JSON path syntax

Many of the JSON functions supported by MySQL and described elsewhere in this manual (see Section 12.18, “JSON Functions” ) require path expressions to identify specific elements in a JSON document. A path consists of a range of paths and one or more path branches . For paths used in MySQL JSON functions, the scope is always the document being searched or otherwise manipulated, $represented by the leading character. Path branches (path legs) are separated by period characters ( .). A cell in the array is [N]represented by , where Nis a nonnegative integer. The key name must be a double-quoted string or a valid ECMAScript identifier (see http://www.ecma-international.org/ecma-262/5.1/#sec-7.6). Path expressions (such as JSON text) should be encoded using the ascii, utf8or character set. utf8mb4Other character encodings are implicitly coerced to utf8mb4. The complete syntax is as follows:

pathExpression:
    scope[(pathLeg)*]

pathLeg:
    member | arrayLocation | doubleAsterisk

member:
    period ( keyName | asterisk )

arrayLocation:
    leftBracket ( nonNegativeInteger | asterisk ) rightBracket

keyName:
    ESIdentifier | doubleQuotedString

doubleAsterisk:
    '**'

period:
    '.'

asterisk:
    '*'

leftBracket:
    '['

rightBracket:
    ']'

As mentioned before, in MySQL, the scope of a path is always the document being operated on, expressed as $. You can '$'use it as a synonym for a document in a JSON path expression.

notes

Some implementations support JSON path range column references; currently, MySQL does not support these.

Wildcards *and **tags are used as follows:

  • .*Represents the values ​​of all members in the object.

  • [*]Represents the values ​​of all cells in the array.

  • [prefix]**suffixRepresents all paths prefixstarting with and ending with . is optional, but required; in other words, the path cannot end in .suffixprefixsuffix**

    Additionally, the path may not contain the sequence ***(3 asterisks).

For path syntax examples, see the descriptions of various JSON functions that take paths as arguments, such as JSON_CONTAINS_PATH(), JSON_SET()and JSON_REPLACE(). See the function description for an example of using * the and wildcard characters .**JSON_SEARCH()

5.5. Comparison and sorting of JSON values

You can compare JSON values ​​using =the , <, <=, >, >=, <>, !=and <=>operators.

The following comparison operators and functions are not yet supported for JSON values:

The workaround for the comparison operators and functions just listed is to convert the JSON values ​​to native MySQL numeric or string data types so that they have consistent non-JSON scalar types.

Comparison of JSON values ​​occurs at two levels. The first level comparison is based on the JSON type of the compared value. If the types are different, the result of the comparison depends only on which type has higher precedence. If two values ​​have the same JSON type, a second level comparison is performed using type-specific rules.

The following list shows the priority of JSON types, from highest priority to lowest priority. (The type name is JSON_TYPE()the name returned by the function.) Types that appear together on a line have the same precedence. Any value of type JSON listed earlier in the list is greater than any value of type JSON listed later in the list.

BLOB
BIT
OPAQUE
DATETIME
TIME
DATE
BOOLEAN
ARRAY
OBJECT
STRING
INTEGER, DOUBLE
NULL

For JSON values ​​of the same precedence, the comparison rules are type-specific:

  • BLOB

    NCompares the first bytes of two values , where Nis the number of bytes in the shorter value. If the first Nbytes of two values ​​are the same, the shorter value is sorted before the longer value.

  • BIT

    BLOBSame rules as .

  • OPAQUE

    BLOBSame rules as . OPAQUEType is an unclassified type.

  • DATETIME

    Values ​​from earlier time points are sorted before values ​​representing later time points. Two values ​​are equal if they originally came from MySQL DATETIMEand TIMESTAMPtype respectively, if they represent the same point in time.

  • TIME

    The smaller of the two time values ​​is sorted before the larger one.

  • DATE

    Older dates are sorted before later dates.

  • ARRAY

    Two JSON arrays are equal if they have the same length and the values ​​at corresponding positions in the array are equal.

    If the arrays are not equal, their order is determined by the first element at the position where the difference exists. Arrays with smaller values ​​at that position are sorted first. If all the values ​​of the shorter array are equal to the corresponding values ​​in the longer array, the shorter array is sorted first.

    example:

    [] < ["a"] < ["ab"] < ["ab", "cd", "ef"] < ["ab", "ef"]
    
  • BOOLEAN

    JSON's false characters are smaller than JSON's true characters.

  • OBJECT

    Two JSON objects are equal if they have the same set of keys and each key has the same value in both objects.

    example:

    {"a": 1, "b": 2} = {"b": 2, "a": 1}
    

    The order of two unequal objects is unspecified but deterministic. (Note: I don’t understand this sentence)

  • STRING

    The strings are lexically sorted on the utf8mb4first bytes encoded in the two strings being compared , where is the length of the shorter string. If the first bytes of two strings are the same, the shorter string is considered smaller than the longer string.NNN

    example:

    "a" < "ab" < "b" < "bc"
    

    This sorting is equivalent to using utf8mb4_bincollation to sort SQL strings. Because utf8mb4_binof the binary collation, comparisons of JSON values ​​are case-sensitive:

    "A" < "a"
    
  • INTEGER, DOUBLE

    JSON values ​​can contain exact and approximate numbers. See Section 9.1.2, “Number Literals” for a general discussion of these types of numbers .

    The rules for comparing native MySQL numeric types are discussed in Section 12.3, “Type Conversions in Expression Evaluation” , but the rules for comparing numeric types in JSON values ​​are somewhat different:

    • In comparisons between two columns using native MySQL INTand DOUBLEnumeric types respectively, it is known that all comparisons involve integers and doubles, so for all rows integers are converted to doubles. That is, convert an exact number into an approximate number.

    • On the other hand, if a query compares two JSON columns containing numbers, it cannot know in advance whether the numbers are integers or doubles. To provide the most consistent behavior across all rows, MySQL converts approximate numbers to exact numbers. The resulting ordering is consistent and does not lose the precision of exact value numbers. For example, given the scalars 9223372036854775805, 9223372036854775806, 9223372036854775807, and 9.223372036854776e18, the order is as follows:

    9223372036854775805 < 9223372036854775806 < 9223372036854775807
    < 9.223372036854776e18 = 9223372036854776000 < 9223372036854776001
    

    If the JSON comparison uses non-JSON numeric comparison rules, inconsistent ordering may occur. Common MySQL number comparison rules produce the following order:

    • Integer comparison:

      9223372036854775805 < 9223372036854775806 < 9223372036854775807
      

      (undefined 9.223372036854776e18)

    • Double comparison:

      9223372036854775805 = 9223372036854775806 = 9223372036854775807 = 9.223372036854776e18
      

For any NULLcomparison of JSON values ​​to SQL, the result is UNKNOWN.

For comparisons of JSON and non-JSON values, non-JSON values ​​are converted to JSON according to the rules in the following table, and then the values ​​are compared as described previously.

5.6. Convert between JSON and non-JSON values

The following table summarizes the rules MySQL follows when converting between JSON values ​​and other types of values:

Table 11.3 JSON conversion rules

Other types CAST (other types AS JSON) CAST(JSON AS other types)
JSON Unchanged Unchanged
utf8 character type ( utf8mb4, utf8, ascii) The string is parsed into a JSON value. JSON values ​​are serialized into utf8mb4strings.
Other character types Other character encodings are implicitly converted to utf8mb4character types and processed according to the utf8 character set. JSON values ​​are serialized into utf8mb4strings and then converted to other character encodings. The results may not make sense.
NULL Returns NULLa JSON value of type . not applicable.
GEO type ST_AsGeoJSON()Convert GEO values ​​to JSON documents by calling . Illegal operation. Solution: Pass CAST(json_val AS CHAR)the result of to pass ST_GeomFromGeoJSON()the result of to ST_GeomFromGeoJSON().
all other types Generates a JSON document consisting of a single scalar value. Success if the JSON document contains a single scalar value of the target type and the scalar value can be converted to the target type. Otherwise, return NULLand generate a warning.

For JSON values ORDER BY​​and GROUP BYworks according to the following principles:

  • Scalar JSON values ​​are sorted using the same rules as in the previous discussion.
  • For ascending sorting, SQL's NULLis sorted before all JSON values, including JSON NULL literals; for descending sorting, SQL's is NULLsorted after all JSON values, including JSON NULL literals.
  • The sort key of a JSON value is constrained by max_sort_lengththe value of a system variable, so max_sort_lengthit is considered equal if the first bytes are the same (and only then differ).
  • Sorting non-scalar values ​​is currently not supported and a warning occurs.

For sorting, it might be beneficial to convert the JSON scalar to some other native MySQL type. For example, if jdoca column named contains a JSON object whose members idconsist of keys and non-negative values, use this expression to idsort by value:

ORDER BY CAST(JSON_EXTRACT(jdoc, '$.id') AS UNSIGNED)

If there happens to be a generated column defined using ORDER BYthe same expression as in , the MySQL optimizer will recognize this and consider the index for use in the query execution plan. See Section 8.3.10, “Optimizer Use of Generated Column Indexes” .

5.7. Aggregation of JSON values

For aggregation of JSON values, SQL NULLvalues ​​are ignored like other data types. Non- NULLvalues ​​are converted to numeric types and aggregated, except for MIN(), MAX()and GROUP_CONCAT(). For numeric scalar JSON values, conversion to a number should produce meaningful results, although (depending on the value) truncation and loss of precision may occur. Converting other JSON values ​​to numbers may not produce meaningful results.

5.8. Related references:

Section 8.3.10, “Optimizer Use of Generated Column Indexes”

Section 9.1.2, “Numeric Literals”

Section 11.7, “Data Type Storage Requirements”

Section 12.3, “Type Conversions in Expression Evaluation”

Section 12.17.11, “Spatial GeoJSON Functions”

Section 12.18, “JSON Functions”

Section 12.18.2, “Functions for Creating JSON Values”

Section 12.18.3, “Functions to Search JSON Values”

Section 13.1.18.8, Indexing Generated Columns to Provide JSON Column Indexes

6. Data type default value

7. Data type storage requirements

7.1. InnoDB table storage requirements

7.2、 NDB 表存储要求

7.3、 数字类型存储要求

7.4、 日期和时间类型存储要求

7.5、 字符串类型存储要求

7.6、 空间类型存储要求

7.7、 JSON 存储要求

7.8、相关参考

磁盘上表数据的存储要求取决于几个因素。不同的存储引擎表示数据类型和存储原始数据的方式不同。表数据可能会针对一列或整行进行压缩,从而使表或列的存储要求的计算变得复杂。

尽管磁盘上的存储布局存在差异,但用于通信和交换有关表行信息的内部 MySQL API 使用适用于所有存储引擎的一致数据结构。

本节包括 MySQL 支持的每种数据类型的存储要求的指南和信息,包括使用固定大小表示的数据类型的存储引擎的内部格式和大小。信息按类别或存储引擎列出。

表的内部表示最大行大小为 65,535 字节,即使存储引擎能够支持更大的行。此数字不包括 BLOBTEXT列,它们仅占此大小的 9 到 12 个字节。对于 BLOBTEXT数据,信息在内部存储在与行缓冲区不同的内存区域中。不同的存储引擎根据它们用于处理相应类型的方法,以不同的方式处理这些数据的分配和存储。有关详细信息,请参阅第 15 章,替代存储引擎第 8.4.7 节,“表列数和行大小的限制”

7.1、 InnoDB 表存储要求

有关 InnoDB 表的存储要求的信息, 请参阅第 14.11 节,“InnoDB 行格式”

7.2、 NDB 表存储要求

(跳过)

7.3、 数字类型存储要求

数据类型 需要存储
TINYINT 1 个字节
SMALLINT 2 个字节
MEDIUMINT 3 个字节
INT, INTEGER 4 个字节
BIGINT 8 个字节
FLOAT(p) 4 个字节( 0 <= p<= 24 ) ,8 个字节( 25 <= p<= 53 )
FLOAT 4 个字节
DOUBLE [PRECISION], REAL 8 个字节
DECIMAL(M,D), NUMERIC(M,D) 变长的; 见以下讨论
BIT(M) 大约 ( M+7)/8 字节

DECIMAL( 和 NUMERIC ) 列的值使用二进制格式表示,该格式将九个十进制(以 10 为基数)数字打包成四个字节。每个值的整数和小数部分的存储分别确定。每个九位数字的倍数需要四个字节,而“剩余” 数字需要四个字节的一部分。下表给出了多余数字所需的存储空间。

剩余数字 字节数
0 0
1, 2 1
3, 4 2
5, 6 3
7, 8 4

7.4、 日期和时间类型存储要求

对于TIMEDATETIMETIMESTAMP列,在 MySQL 5.6.4 之前创建的表所需的存储空间与从 5.6.4 开始创建的表不同。这是由于 5.6.4 中的更改允许这些类型具有小数部分,这需要 0 到 3 个字节。

数据类型 MySQL 5.6.4 之前需要存储 MySQL 5.6.4 所需的存储空间
YEAR 1 个字节 1 个字节
DATE 3 个字节 3 个字节
TIME 3 个字节 3 字节 + 小数秒存储
DATETIME 8 个字节 5 字节 + 小数秒存储
TIMESTAMP 4字节 4 字节 + 小数秒存储

从 MySQL 5.6.4 开始,存储 YEARDATE保持不变。但是, TIMEDATETIMETIMESTAMP的表示方式不同。DATETIME打包的效率更高,非小数部分需要 5 个而不是 8 个字节,并且所有3种表示时间的类型的小数部分只需要 0 到 3 个字节,具体取决于存储值的小数秒精度。

小数秒精度 需要存储
0 0 字节
1, 2 1 个字节
3, 4 2 个字节
5, 6 3 个字节

例如,TIME(0)TIME(2)TIME(4)TIME(6)分别使用 3(3+0)、4(3+1)、5(3+2) 和 6(3+3) 个字节。TIMETIME(0)是等效的并且需要相同的存储空间。

有关时间值的内部表示的详细信息,请参阅 MySQL 内部:重要的算法和结构

7.5、 字符串类型存储要求

在下表中,*M*表示非二进制字符串类型的声明列长度(字符长度)和二进制字符串类型的字节数。 *L*表示给定字符串值以字节为单位的实际长度(字节长度)。

数据类型 需要存储
CHAR(M) 紧凑的 InnoDB 行格式系列优化了可变长度字符集的存储。请参阅 COMPACT 行格式存储特性 。否则,M × w 字节 <= M <= 255,其中 w 是字符集中最大长度字符所需的字节数。
BINARY(M) *M*字节,0 <= M <= 255
VARCHAR(M), VARBINARY(M) L+1 个字节(如果列值需要 0 - 255 个字节),L+2 个字节(如果列值超过 255 个字节)
TINYBLOB, TINYTEXT L+ 1 个字节,其中 L< 2[^8] = 256 B
BLOB, TEXT L+ 2 个字节,其中 L< 2[^16] = 64 KB
MEDIUMBLOB, MEDIUMTEXT L+ 3 个字节,其中 L< 2[^24] = 16 MB
LONGBLOB, LONGTEXT L+ 4 个字节,其中 L< 2[^32] = 4 GB
ENUM('value1','value2',...) 1 或 2 个字节,取决于枚举值的数量(最多 65,535 个值)
SET('value1','value2',...) 1、2、3、4 或 8 个字节,取决于集合成员的数量(最多 64 个成员)

可变长度字符串类型使用长度前缀加数据存储。长度前缀根据数据类型需要一到四个字节,数据值需要 L(字符串的字节长度)。例如,一个 MEDIUMTEXT值的存储需要 *L*字节来存储值加上三个字节来存储值的长度。

要计算用于存储特定 CHARVARCHARTEXT列值的字节数,您必须考虑用于该列的字符集以及该值是否包含多字节字符。特别是,在使用 utf8 Unicode 字符集时,您必须牢记并非所有字符都使用相同的字节数。utf8mb3utf8mb4 字符集每个字符最多分别需要三个和四个字节。有关用于不同类别 utf8mb3utf8mb4 字符的存储细分,请参阅 第 10.9 节,“Unicode 支持”

VARCHAR, VARBINARY, BLOBTEXT类型是变长类型。对于它们的每个,存储要求取决于以下因素:

  • 列值的实际长度
  • 列的最大可能长度
  • 列使用的字符集,因为有些字符集包含多字节字符

例如,一个 VARCHAR(255) 列可以包含最大长度为 255 个字符的字符串。假设该列使用latin1字符集(每个字符一个字节),实际需要的存储是字符串的长度(L),加上一个字节来记录字符串的长度。对于字符串 'abcd',*L*是 4 并且存储要求是 5 个字节。如果同一列改为使用ucs2双字节字符集,则存储要求为 10 个字节: 'abcd' 的长度为 8 个字节,该列需要两个字节来存储长度,因为最大长度大于 255(最多 510字节)。

一个 VARCHARVARBINARY 列中可以存储的最大有效字节数取决于最大行大小 65,535 字节,该最大行大小在所有列之间共享。对于存储多字节字符的 VARCHAR 列,最大有效字符数较少。例如, utf8mb3 的每个字符最多需要三个字节,因此可以将使用 utf8mb3 字符集的 VARCHAR 列声明为最多 21,844 个字符。请参阅 第 8.4.7 节,“表列数和行大小的限制”

InnoDB将长度大于或等于 768 字节的固定长度字段编码为可变长度字段,可以在页外存储。例如, CHAR(255)如果字符集的最大字节长度大于 3,则列可以超过 768 个字节,就像utf8mb4

NDB存储引擎支持可变宽度列 。这意味着 VARCHARNDB Cluster 表中的列需要与任何其他存储引擎相同的存储量,除了这些值是 4 字节对齐的。因此,使用字符集 latin1 存储在 VARCHAR(50)列中的 'abcd' 字符串需要 8 个字节(而不是 MyISAM表中相同列值的 5 个字节)。

(此处省略NDB相关的其他描述)NDB_COLUMN有关详细信息,请参阅 NDB_COLUMN 选项

ENUM 对象的大小由不同枚举值的数量决定。一个字节用于最多包含 255 个可能值的枚举。两个字节用于具有 256 到 65,535 个可能值的枚举。请参阅 第 11.3.5 节,“ENUM 类型”

SET 对象的大小由不同集合成员的数量决定。如果设置大小为*N*,则对象占用 (N+7)/8 字节,四舍五入为 1、2、3、4 或 8 个字节。一个 SET 最多可以有 64 个成员。请参阅 第 11.3.6 节,“SET 类型”

7.6、 空间类型存储要求

MySQL 使用 4 个字节存储空间值以指示 SRID,后跟该值的 WKB 表示。该 LENGTH()函数返回值存储所需的空间(以字节为单位)。

有关空间值的 WKB 和内部存储格式的描述,请参阅第 11.4.3 节,“支持的空间数据格式”

7.7、 JSON 存储要求

通常, JSON 列的存储要求与 LONGBLOBLONGTEXT 列的存储要求大致相同;也就是说,JSON 文档占用的空间与存储在其中一种类型的列中的文档字符串表示所占用的空间大致相同。但是,存储在 JSON 文档中的各个值的二进制编码(包括查找所需的元数据和字典)会产生开销。例如,存储在 JSON 文档中的字符串需要 4 到 10 个字节的额外存储空间,具体取决于字符串的长度以及存储它的对象或数组的大小。

此外,MySQL 对存储在JSON列中的任何 JSON 文档的大小施加了限制,使其不能大于 max_allowed_packet.

7.8、相关参考

第 8.4.7 节,“表列数和行大小的限制”

第 10.9 节,“Unicode 支持”

第 11.3.5 节,“ENUM 类型”

第 11.3.6 节,“SET 类型”

第 14.11 节,“InnoDB 行格式”

第 14.11 节,COMPACT 行格式存储特性

第 15 章,替代存储引擎

MySQL 内部:重要的算法和结构

8、为列选择正确的类型

9、使用来自其他数据库引擎的数据类型

Guess you like

Origin blog.csdn.net/booynal/article/details/125705927