Mysql data types-official documents-study notes
Table of contents
- 1 Numeric data type
- 2 Date and time data types
- 3 String data type
- 4 spatial data types
- 5 JSON data type
- 6 Data type default value
- 7 Data type storage requirements
- 8 Choose the correct type for the column
- 9 Using data types from other database engines
MySQL supports several types of SQL data types: numeric types, date and time types, string (character and byte) types, spatial types and JSON
data 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, **M
is the total number of bits that can be stored (precision). For string types, *M
is the maximum length.M
The 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 thanM
-2. -
*
fsp
* Applies to theTIME
,DATETIME
andTIMESTAMP
types 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.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.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,
M
represents 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,
M
it 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
- Fixed point:
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. M
Represents the number of digits in each value, from 1
to 64
. If M
omitted, it defaults to 1
.
1.1.2 TINYINT[(M)] [UNSIGNED] [ZEROFILL]
A very small integer, occupying 1
bytes. The signed range is -2[^7] = -128
to 2[^7]-1 = 127
. The unsigned range is 0
to 2[^8]-1 = 255
.
M
Indicates 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 FALSE
are just aliases for 1
and 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 2
not equal to TRUE
and FALSE
because 2
neither is equal to 1
nor equal to 0
.
1.1.4 SMALLINT[(M)] [UNSIGNED] [ZEROFILL]
A small integer, occupying 2
bytes. The signed range is -2[^15] = -32768
to 2[^15]-1 = 32767
. The unsigned range is 0
to 2[^16]-1 = 65535
.
1.1.5 MEDIUMINT[(M)] [UNSIGNED] [ZEROFILL]
A medium-sized integer in 3
bytes. The signed range is -2[^23] = -8388608
to 2[^23]-1 = 8388607
. The unsigned range is 0
to 2[^24]-1 = 16777215
.
1.1.6 INT[(M)] [UNSIGNED] [ZEROFILL]
A normal-sized integer, in 4
bytes. The signed range is -2[^31] = -2147483648
to 2[^31]-1 = 2147483647
. The unsigned range is 0
to 2[^32]-1 = 4294967295
.
1.1.7 INTEGER[(M)] [UNSIGNED] [ZEROFILL]
This type is INT
a synonym for .
1.1.8 BIGINT[(M)] [UNSIGNED] [ZEROFILL]
A large integer, occupying 8
bytes. The signed range is -2[^63] = -9223372036854775808
to 2[^63]-1 = 9223372036854775807
. The unsigned range is 0
to 2[^64]-1 = 18446744073709551615
.
SERIAL
Yes BIGINT UNSIGNED NOT NULL AUTO_INCREMENT UNIQUE
alias.
BIGINT
Some things you should note about columns :
-
All arithmetic is done using signed
BIGINT
OR 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 toDOUBLE
9223372036854775807
BIGINT
DOUBLE
MySQL can handle
BIGINT
the following situations:- When using integers
BIGINT
to store large unsigned values in columns. BIGINT
When columns are used onMIN(*
col_name*)
andMAX(*
col_name*)
- When using an operator where both operands are integers (
+
,-
,*
etc.).
- When using integers
-
BIGINT
It 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 .+
*
BIGINT
9223372036854775807
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. D
is 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 countedM
. If **D
is 0, the value has no decimal point or decimal part.
( DECIMAL
Literal text is also limited in length; see Expression Handling .)
If specified UNSIGNED
, negative values are not allowed.
DECIMAL
All 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 DECIMAL
synonyms for . FIXED
Synonyms 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+38
to -1.175494351E-38
, 0
and 1.175494351E-38
to 3.402823466E+38
. These are theoretical limits based on IEEE standards. Actual range may be slightly smaller depending on hardware or operating system.
M
is the total number of digits and D
is 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 FLOAT
may 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,则数据类型变为FLOAT
无M
*或 *D
*值。如果 *p
*是从 25 到 53,则数据类型变为DOUBLE
无 M
或D
值。结果列的范围与本节前面描述 的单精度FLOAT
或双精度 DOUBLE
数据类型相同。
FLOAT(p)
为 ODBC 兼容性提供了语法。`
1.1.13 DOUBLE[(M,D)] [UNSIGNED] [ZEROFILL]
一个正常大小(双精度)的浮点数。允许的值为 -1.7976931348623157E+308
to -2.2250738585072014E-308
、 0
和 2.2250738585072014E-308
to 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]
- 这些类型是
DOUBLE
的同义词。例外:如果启用了REAL_AS_FLOAT
的 SQL 模式,则REAL
是FLOAT
而不是DOUBLE
的同义词。
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
, MEDIUMINT
and 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
DECIMAL
and NUMERIC
types store exact numeric data values. Use these types when maintaining precise accuracy is important, such as currency data. In MySQL, NUMERIC
is implemented as DECIMAL
, so the following DECIMAL
also applies NUMERIC
.
MySQL DECIMAL
stores 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" .
DECIMAL
Precision and scale can (and usually do) be specified in the column declaration . For example:
salary DECIMAL(5,2)
In this case, 5
it's the precision and 2
it'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 salary
the range of values that can be stored in the column ranges from -999.99
to 999.99
.
In standard SQL, the syntax DECIMAL(M)
is equivalent to DECIMAL(M,0)
. Similarly, the syntax DECIMAL
is equivalent to DECIMAL(M,0)
, which allows the implementation to decide M
the value of . MySQL supports these two different forms of DECIMAL
syntax. M
The default value is 10.
If the decimal is 0, DECIMAL
the value does not contain a decimal point or decimal part.
DECIMAL
The maximum number of digits is 65, but the actual range of a given DECIMAL
column 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
FLOAT
and DOUBLE
types 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 FLOAT
column. Precisions from 24 to 53 produce an 8-byte double DOUBLE
column.
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.M
D
FLOAT(7,4)
-999.9999
999.00009
FLOAT(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 FLOAT
or DOUBLE PRECISION
not specify precision or number of digits.
1.5 bit value type - BIT
BIT
Data type is used to store (binary) "bit" values. A BIT(M)
type allows storage M
of binary digit values. M
The range can be from 1 to 64.
To specify the value of a "bit", binary notation can be used b'value'
. b
Indicates that it is followed by a binary number, enclosed in single quotes, and value
is a binary value written using 0s and 1s. For example, b'111'
and b'10000000'
represent decimal 7
and respectively 128
. See "Place-value literal" .
If a M
value 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 101
there are only 3 binary digits, which is insufficient for the expected 6
digits, the left padding is enough 0
to make up for 6
the digits and the number b'000101'
is stored in mysql.
NDB Cluster : The maximum combined size of NDB
all 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 t1
has 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
, UPDATE
and 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 BIGINT
value 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 DECIMAL
range of values is larger than integers:
mysql> SELECT 9223372036854775807.0 + 1;
+---------------------------+
| 9223372036854775807.0 + 1 |
+---------------------------+
| 9223372036854775808.0 |
+---------------------------+
Subtraction between integer values, one of which is UNSIGNED
of 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_SUBTRACTION
SQL 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 UNSIGNED
an integer column, the result will be clipped to the maximum value of the column type, or NO_UNSIGNED_SUBTRACTION
to 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.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
The date and time data types used to represent time values are DATE
, TIME
, DATETIME
, TIMESTAMP
and 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. TIMESTAMP
and DATETIME
types 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-99
The year values in the range become1970-1999
.00-69
The year values in the range become2000-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
TIME
values are clipped to the appropriateTIME
range. -
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
DATE
or column.DATETIME
This 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 theDATE_SUB()
orDATE_ADD()
functions that require a complete date. To suppress the zero month or day part of the date, enable thisNO_ZERO_IN_DATE
mode. -
MySQL allows you to
'0000-00-00'
store such "zero" values as "dummy dates". In some cases this isNULL
more convenient than using values and uses less data and index space. To disable'0000-00-00'
, enable thisNO_ZERO_DATE
mode. -
"Zero" date or time values used through Connector/ODBC are automatically converted
NULL
because 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 0
to represent the "zero" value. Using these values with time types that contain date parts ( DATE
, DATETIME
and TIMESTAMP
) may produce warnings or errors. The exact behavior depends on NO_ZERO_DATE
which, 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
, TIMESTAMP
and YEAR
.
For range descriptions of DATE
and DATETIME
, "supported" means that while earlier values may be valid (work), they are not guaranteed.
MySQL allows fractional seconds for TIME
, DATETIME
and values with precision up to microseconds (6 digits). TIMESTAMP
To define a column that contains fractional seconds, use the syntax type_name
( fsp
), where type_name
is TIME
, DATETIME
or TIMESTAMP
, fsp
is 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.)
TIMESTAMP
Any column or column in a table DATETIME
can 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 DATE
columns.
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 DATETIME
values in format, but allows values to be assigned to DATETIME
columns 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 DEFAULT
the and ON UPDATE
column definition clauses to specify DATETIME
automatic 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. TIMESTAMP
The 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 TIMESTAMP
is defined depends on explicit_defaults_for_timestamp
the value of a system variable (see "Server System Variables" ).
-
If enabled, the or attribute
explicit_defaults_for_timestamp
is 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_TIMESTAMP
ON UPDATE CURRENT_TIMESTAMP
TIMESTAMP
TIMESTAMP
NOT NULL
NULL
-
If
explicit_defaults_for_timestamp
disabled, the server handlesTIMESTAMP
this as follows:
Unless otherwise specified, if a value is not explicitly assigned to the firstTIMESTAMP
column in a Table, the column is automatically set to the most recently modified date and time. This makes the column usefulTIMESTAMP
for recording timestamps ofINSERT
OR operations.UPDATE
You can also set a column to the current date and time by assigning it aNULL
valueTIMESTAMP
, unless it has been defined to allowNULL
values.
Automatic initialization and updating to the current date and time can be specified using the DEFAULT CURRENT_TIMESTAMP
and ON UPDATE CURRENT_TIMESTAMP
column definition clauses. TIMESTAMP
As mentioned before, the first column has these properties by default. However, TIMESTAMP
any 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 TIME
columns.
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 YYYY
displays YEAR
values in format, but allows values to be assigned to YEAR
columns using strings or numbers. YEAR
Values are displayed as: 1901
, 2155
or 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 columnYEAR(2)
to a 4-bit columnYEAR
, 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 YEAR
the 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
MAXDB
as 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 .TIMESTAMP
DATETIME
TIMESTAMP
DATETIME
DATETIME
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
, DATETIME
and TIMESTAMP
types 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
, DATETIME
and . 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.TIMESTAMP
DATE
DATETIME
DATE
Type is used for values that have a date part but no time part. MySQL 'YYYY-MM-DD'
retrieves and displays DATE
values of type in format. The supported range is '1000-01-01'
to '9999-12-31'
.
DATETIME
Type used for values that contain both date and time components. MySQL 'YYYY-MM-DD hh:mm:ss'
retrieves and displays DATETIME
values in format. The supported range is '1000-01-01 00:00:00'
to '9999-12-31 23:59:59'
.
TIMESTAMP
Type used for values that contain both date and time components. TIMESTAMP
Has a range of '1970-01-01 00:00:01'
UTC to '2038-01-19 03:14:07'
UTC.
An DATETIME
OR TIMESTAMP
value can include a trailing fractional seconds component with precision up to microseconds (6 digits). In particular, any fractional part of the value inserted into DATETIME
the or column will be stored rather than discarded. TIMESTAMP
After including the decimal part, the format of these values is 'YYYY-MM-DD hh:mm:ss[.fraction]'
, DATETIME
type value range is '1000-01-01 00:00:00.000000'
to '9999-12-31 23:59:59.999999'
, TIMESTAMP
type 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” .
TIMESTAMP
and DATETIME
data 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 TIMESTAMP
converts 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 TIMESTAMP
value, 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_zone
a system variable. For more information, see MySQL Server Time Zone Support . If the
SQL schema allows this conversion, an invalid DATE
or 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 .DATETIME
TIMESTAMP
'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, enableALLOW_INVALID_DATES
. For more information, see Server SQL Mode . -
MySQL does not accept
TIMESTAMP
values 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 andNO_ZERO_DATE
which 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-69
become2000-2069
. - The year values in the range
70-99
become1970-1999
.
- The year values in the range
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).TIME
TIME
'-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, TIME
values 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 TIME
value 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 TIME
stricter handling of invalid values, enable strict SQL mode to cause errors. See Server SQL Mode .
2.4 Year type
YEAR
Type is a 1-byte type used to represent year values . It can be declared with YEAR
an 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-bitYEAR(2)
column to a 4-bitYEAR
column, see Section 2.5, “2-Bit YEAR(2) Limitations and Migration to 4-Bit YEAR” .
MySQL YYYY
displays YEAR
values in the format, ranging from 1901
to 2155
and 0000
.
YEAR
Accepts input values in multiple formats:
-
'1901'
A 4- digit string'2155'
in the range to . -
1901
to 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'
2000
2069
YEAR
'70'
'99'
1970
1999
YEAR
-
0
to99
a 1 or 2 digit number in the range . MySQL converts values in1
the to69
range to values in2001
to and values in the to range into values in to .2069
YEAR
70
99
1970
1999
YEAR
Inserting the number
0
has a displayed value of0000
and an internal value of0000
. If you want to insert zeros and have them interpreted2000
, specify it as a string'0'
or'00'
. -
As
YEAR
the result of a function that returns values acceptable in the context,NOW()
e.g.
If strict SQL mode is not enabled, MySQL will YEAR
convert invalid values to 0000
. In strict SQL mode, attempting to insert an invalid YEAR
value 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 YEAR
implicit 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)
1901
2155
0000
YEAR(2)
YEAR(2)
YEAR
YEAR(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 threeYEAR(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
y2
uses the same 2 bits (12
) for all values. If the table is reloaded from the dump file, all generated rows have an internal value of2012
and a displayed value of12
, thus losing the distinction between them. -
Converts a 2-digit or 4-digit
YEAR
data value to string form using its data type to display the width. Assume aYEAR(2)
column and aYEAR
/YEAR(4)
column both contain1970
values. 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
CSV
in a tableYEAR(2)
, values outside the1970
to2069
range are stored incorrectly. For example, inserting2211
would result in a displayed value of11
, but an internal value of2011
.
To avoid these problems, use 4-bit YEAR
or 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
TIMESTAMP
and DATETIME
columns can be automatically initialized and updated to the current date and time (i.e. the current timestamp).
TIMESTAMP
For 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_timestamp
by assigning it a value , unless it has been defined to allow a value.TIMESTAMP
DATETIME
NULL
NULL
To specify automatic properties, use DEFAULT CURRENT_TIMESTAMP
the and ON UPDATE CURRENT_TIMESTAMP
clauses 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_TIMESTAMP
Any synonyms for CURRENT_TIMESTAMP
have 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.3 BINARY and VARBINARY types
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.3 Supported spatial data formats
4.4 Geometric well-formedness and validity
4.8 Optimization spatial analysis
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
JSON
JSON documents stored in columns. Invalid documents generate errors. - Optimized storage format. JSON documents stored
JSON
in 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.
JSON
The space required to store a document is approximately the same as LONGBLOB
or LONGTEXT
; see Section 7, “Data Type Storage Requirements” for details . JSON
It is important to remember that the size of any JSON document stored in a column is limited by max_allowed_packet
the 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 JSON
cannot have non- NULL
default values.
In addition to JSON
data 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 .
JSON
Columns, like other binary type columns, are not directly indexed; instead, you create an index on the generated column to JSON
extract 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 JSON
generated from columns as a workaround for columns that cannot be indexed. Each table supports up to 3 columns.JSON
JSON
NDB
JSON
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, N
the 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
utf8mb4
character set (character set) andutf8mb4_bin
character 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 convertedutf8mb4
to as needed. (For strings inascii
the orutf8
character set, no conversion is required becauseascii
andutf8
isutf8mb4
a subset of.)
Description (add your own)
collation, character sorting rules.
_bin
Indicates using encoded values (binary) for comparison,_ci
indicating case-insensitive (Insensitive),_cs
indicating case-sensitiveYou 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 JSON
a data type, so although it @j
looks 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 JSON
data type. Instead, JSON_OBJECT()
the result is converted to a string when assigned to a variable (I actually measured it to be converted to longtext
type).
The string generated by converting a JSON value has a character set utf8mb4
and a collation utf8mb4_bin
:
mysql> SELECT CHARSET(@j), COLLATION(@j);
+-------------+---------------+
| CHARSET(@j) | COLLATION(@j) |
+-------------+---------------+
| utf8mb4 | utf8mb4_bin |
+-------------+---------------+
Because utf8mb4_bin
is 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
, true
and false
characters, 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
, TRUE
and FALSE
characters, 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 mascot
specific 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. IfJSON_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 key1
element 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. name
For 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 followingpath
means selecting an elementpath
with the subscript of the array name ( ) , which is an integer starting from zero. If the selection is not an array, * *[0] is equivalent to :N
N
path
path
path
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**suffix
Counts all pathsprefix
starting 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 as3
.$[1]
Evaluated as{"a": [5, 6], "b": 10}
.$[2]
Evaluated as[99, 100]
.$[3]
Evaluates toNULL
(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].a
Evaluated as[5, 6]
.$[1].a[1]
Evaluated as6
.$[1].b
Evaluated as10
.$[2][0]
Evaluated as99
.
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 asshark
.$."a bird"
Evaluated assparrow
.
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 $**.b
evaluates to multiple paths ( $.a.b
sum $.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->path
JSON 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]
matchesb
the elementfalse
and 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 N
is 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
, utf8
or character set. utf8mb4
Other 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]**suffix
Represents all pathsprefix
starting with and ending with . is optional, but required; in other words, the path cannot end in .suffix
prefix
suffix
**
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
N
Compares the first bytes of two values , whereN
is the number of bytes in the shorter value. If the firstN
bytes of two values are the same, the shorter value is sorted before the longer value. -
BIT
BLOB
Same rules as . -
OPAQUE
BLOB
Same rules as .OPAQUE
Type 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
DATETIME
andTIMESTAMP
type 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
utf8mb4
first 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.N
N
N
example:
"a" < "ab" < "b" < "bc"
This sorting is equivalent to using
utf8mb4_bin
collation to sort SQL strings. Becauseutf8mb4_bin
of 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
INT
andDOUBLE
numeric 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 NULL
comparison 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 utf8mb4 strings. |
Other character types | Other character encodings are implicitly converted to utf8mb4 character types and processed according to the utf8 character set. |
JSON values are serialized into utf8mb4 strings and then converted to other character encodings. The results may not make sense. |
NULL |
Returns NULL a 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 NULL and generate a warning. |
For JSON values ORDER BY
and GROUP BY
works according to the following principles:
- Scalar JSON values are sorted using the same rules as in the previous discussion.
- For ascending sorting, SQL's
NULL
is sorted before all JSON values, including JSON NULL literals; for descending sorting, SQL's isNULL
sorted after all JSON values, including JSON NULL literals. - The sort key of a JSON value is constrained by
max_sort_length
the value of a system variable, somax_sort_length
it 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 jdoc
a column named contains a JSON object whose members id
consist of keys and non-negative values, use this expression to id
sort by value:
ORDER BY CAST(JSON_EXTRACT(jdoc, '$.id') AS UNSIGNED)
If there happens to be a generated column defined using ORDER BY
the 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 NULL
values are ignored like other data types. Non- NULL
values 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 字节,即使存储引擎能够支持更大的行。此数字不包括 BLOB
或 TEXT
列,它们仅占此大小的 9 到 12 个字节。对于 BLOB
和 TEXT
数据,信息在内部存储在与行缓冲区不同的内存区域中。不同的存储引擎根据它们用于处理相应类型的方法,以不同的方式处理这些数据的分配和存储。有关详细信息,请参阅第 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、 日期和时间类型存储要求
对于TIME
、 DATETIME
和 TIMESTAMP
列,在 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 开始,存储 YEAR
和 DATE
保持不变。但是, TIME
、 DATETIME
和 TIMESTAMP
的表示方式不同。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) 个字节。TIME
与 TIME(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
*字节来存储值加上三个字节来存储值的长度。
要计算用于存储特定 CHAR
、 VARCHAR
或 TEXT
列值的字节数,您必须考虑用于该列的字符集以及该值是否包含多字节字符。特别是,在使用 utf8
Unicode 字符集时,您必须牢记并非所有字符都使用相同的字节数。utf8mb3
和 utf8mb4
字符集每个字符最多分别需要三个和四个字节。有关用于不同类别 utf8mb3
或 utf8mb4
字符的存储细分,请参阅 第 10.9 节,“Unicode 支持”。
VARCHAR
, VARBINARY
, BLOB
和 TEXT
类型是变长类型。对于它们的每个,存储要求取决于以下因素:
- 列值的实际长度
- 列的最大可能长度
- 列使用的字符集,因为有些字符集包含多字节字符
例如,一个 VARCHAR(255)
列可以包含最大长度为 255 个字符的字符串。假设该列使用latin1
字符集(每个字符一个字节),实际需要的存储是字符串的长度(L
),加上一个字节来记录字符串的长度。对于字符串 'abcd'
,*L
*是 4 并且存储要求是 5 个字节。如果同一列改为使用ucs2
双字节字符集,则存储要求为 10 个字节: 'abcd'
的长度为 8 个字节,该列需要两个字节来存储长度,因为最大长度大于 255(最多 510字节)。
一个 VARCHAR
或 VARBINARY
列中可以存储的最大有效字节数取决于最大行大小 65,535 字节,该最大行大小在所有列之间共享。对于存储多字节字符的 VARCHAR
列,最大有效字符数较少。例如, utf8mb3
的每个字符最多需要三个字节,因此可以将使用 utf8mb3
字符集的 VARCHAR
列声明为最多 21,844 个字符。请参阅 第 8.4.7 节,“表列数和行大小的限制”。
InnoDB
将长度大于或等于 768 字节的固定长度字段编码为可变长度字段,可以在页外存储。例如, CHAR(255)
如果字符集的最大字节长度大于 3,则列可以超过 768 个字节,就像utf8mb4
。
NDB
存储引擎支持可变宽度列 。这意味着 VARCHAR
NDB 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
列的存储要求与 LONGBLOB
或 LONGTEXT
列的存储要求大致相同;也就是说,JSON 文档占用的空间与存储在其中一种类型的列中的文档字符串表示所占用的空间大致相同。但是,存储在 JSON 文档中的各个值的二进制编码(包括查找所需的元数据和字典)会产生开销。例如,存储在 JSON 文档中的字符串需要 4 到 10 个字节的额外存储空间,具体取决于字符串的长度以及存储它的对象或数组的大小。
此外,MySQL 对存储在JSON
列中的任何 JSON 文档的大小施加了限制,使其不能大于 max_allowed_packet
.