数据类型

数据类型说明:

Data type descriptions use these conventions:

  • For integer types, M indicates the maximum display width. For floating-point and fixed-point types, M is the total number of digits that can be stored (the precision). For string types, M is the maximum length. The maximum permissible value of M depends on the data type.
  • D applies to floating-point and fixed-point types and indicates the number of digits following the decimal point (the scale). The maximum possible value is 30, but should be no greater than *M*−2.
  • fsp applies to the TIME, DATETIME, and TIMESTAMP types and represents fractional seconds precision; that is, the number of digits following the decimal point for fractional parts of seconds. The fsp value, if given, must be in the range 0 to 6. A value of 0 signifies that there is no fractional part. If omitted, the default precision is 0. (This differs from the standard SQL default of 6, for compatibility with previous MySQL versions.)
  • Square brackets ([ and ]) indicate optional parts of type definitions.

TEXT

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

A TEXT column with a maximum length of 65,535 (216 − 1) characters. The effective maximum length is less if the value contains multibyte characters. Each TEXT value is stored using a 2-byte length prefix that indicates the number of bytes in the value.

An optional length M can be given for this type. If this is done, MySQL creates the column as the smallest TEXT type large enough to hold values M characters long.

——MySQL :: MySQL 8.0 Reference Manual :: 11.3.1 String Data Type Syntax

MySQL 的 TEXT 类型可以指定一个 M 参数,MySQL 根据 M 的大小选择能保存对应字符的最小 TEXT 类型,如果不足就依次升级为 MEDIUMTEXTLONGTEXT 等。

资料

  1. Understanding Storage Sizes for MySQL TEXT Data Types | Tutorial by Chartio
  2. mysql - How many multibyte characters can fit into a TEXT column? - Stack Overflow

TINYTEXT

最多保存 255 字节的字符内容。

FLOAT

11.1.4 Floating-Point Types (Approximate Value) - FLOAT, DOUBLE

FLOAT 占 4 个字节,DOUBLE 占 8 个字节。

允许使用 FLOAT(p) 来声明类型,但是 p 仅仅用来判断,如果 0 <= p <= 23,那么实际创建的字段为 4 字节,如果 24 <= p <= 53,那么实际创建的字段为 8 字节。

支持 FLOAT(M, D) 的写法,但是从 MySQL 8.0.17 开始已经不建议使用,后续可能彻底不支持。

As of MySQL 8.0.17, the nonstandard FLOAT(M,D) and DOUBLE(M,D) syntax is deprecated and you should expect support for it to be removed in a future version of MySQL.

——MySQL :: MySQL 8.0 Reference Manual :: 11.1.4 Floating-Point Types (Approximate Value) - FLOAT, DOUBLE

M 最大为 255,D 最大为 30。

ENUM

定义时候指定一组值,写入数据的时候只能从预设的值中选一个

值只能是字符串。

SET

定义时候指定一组值,写入数据的时候只能从预设的值中选若干个组合,中间用逗号分隔。

值只能是字符串。

DECIMAL

文档:MySQL :: MySQL 5.7 Reference Manual :: 11.1.3 Fixed-Point Types (Exact Value) - DECIMAL, NUMERIC

简介:DECIMAL 用于保存定点数。MySQL 中 DECIMALNUMERIC 是同义词。

语法:DECIMAL(M,D)DECIMAL(M)DECIMALM 最大 65,D 最大 30

整数部分的长度最大是 M-D,小数部分最大长度是 D

不指定 M,默认为 10。不指定 D,默认为 0。即 DECIMAL 等价于 DECIMAL(10)DECIMAL(10,0)。M 最大为 65。DECIMAL(M) 等价于 DECIMAL(M,0)

根据实际测试,整数部分超过允许的最大长度时会报错 Data truncation: Out of range value for column 'xxx'。小数部分超过允许的最大长度,会截断到指定精度(一般是四舍五入,不同操作系统可能不一样)。

四舍五入后如果数据超过了字段类型允许保存的最大值也会报错 Data truncation: Out of range value for column 'xxx'

BIT

BIT 类型

BIT[(M)],M 取值范围是 1~64,如果不指定 M,默认为 1。

TINYINT

TINYINT[(M)] [UNSIGNED] [ZEROFILL],M 是 display width,不影响数据大小。

TIMESTAMP

MySQL converts TIMESTAMP values from the current time zone to UTC for storage, and back from UTC to the current time zone for retrieval. (This does not occur for other types such as DATETIME.

——MySQL :: MySQL 5.7 Reference Manual :: 11.2.2 The DATE, DATETIME, and TIMESTAMP Types

MySQL 内部是把数据统一转换成 UTC 时间进行保存的,客户端取数的时候,再根据客户端的 Connection 的时区设置进行转换。

会受到 serverTimezoneconnectionTimeZone 等)参数影响。(参考【关于 MySQL JDBC 相关】一文)

其他资料:

MySQL 时间字段用 int 、 datetime 还是 timestamp? - 知乎

类型映射关系

com.mysql.cj.MysqlType 中有 MySQL 数据库中各种类型和 Java 中各种类型的映射关系。

1
2
3
4
5
6
7
8
9
public enum MysqlType implements SQLType {
DECIMAL("DECIMAL", 3, BigDecimal.class, 64, true, 65L, "[(M[,D])] [UNSIGNED] [ZEROFILL]"),
DECIMAL_UNSIGNED("DECIMAL UNSIGNED", 3, BigDecimal.class, 96, true, 65L, "[(M[,D])] [UNSIGNED] [ZEROFILL]"),
TINYINT("TINYINT", -6, Integer.class, 64, true, 3L, "[(M)] [UNSIGNED] [ZEROFILL]"),
TINYINT_UNSIGNED("TINYINT UNSIGNED", -6, Integer.class, 96, true, 3L, "[(M)] [UNSIGNED] [ZEROFILL]"),
BOOLEAN("BOOLEAN", 16, Boolean.class, 0, false, 3L, ""),
SMALLINT("SMALLINT", 5, Integer.class, 64, true, 5L, "[(M)] [UNSIGNED] [ZEROFILL]"),
// ...
}

数据类型变化历史

  1. 5.7.5 之前支持 year(2) 写法,之后不再支持。(MySQL :: MySQL 8.0 Reference Manual :: 11.2.4 The YEAR Type
  2. 8.0.19 之前支持 year(4) 写法,之后不再支持。(MySQL :: MySQL 8.0 Reference Manual :: 11.2.4 The YEAR Type
  3. 8.0.17 之后 FLOAT(M,D)DOUBLE(M,D) 写法已废弃,未来可能移除。(MySQL :: MySQL 8.0 Reference Manual :: 11.1.1 Numeric Data Type Syntax
  4. 8.0.17 之后,FLOATDOUBLEDECIMALUNSIGNED 声明已废弃,未来可能移除。(MySQL :: MySQL 8.0 Reference Manual :: 11.1.1 Numeric Data Type Syntax
  5. 8.0.17 之后,ZEROFILL 声明已废弃,未来可能移除。(MySQL :: MySQL 8.0 Reference Manual :: 11.1.1 Numeric Data Type Syntax

参考资料

  1. MySQL :: MySQL 5.7 Reference Manual :: 11.1 Numeric Data Types
  2. MySQL :: MySQL Connector/J 5.1 Developer Guide :: 5.3 Configuration Properties for Connector/J