MySQL 字段类型很多,我从 phpMyAdmin 5.1.1
(一种开源的 MySQL 可视化工具)里找到了配置的所有 MySQL 字段类型,一共有 41 种。MySQL 有一些字段类型是用同一个 C++ 类或通过继承同一个 C++ 类的方式实现的。截止目前为止,我写的十几篇公众号文章,有多篇文章里写到了 MySQL 对于大对象(BLOB)
、定长字符串
、变长字符串
的特殊处理逻辑。每次写到这些特殊处理逻辑,都需要说明哪些字段类型属于大对象、定长 & 变长字符串。
今天我们就来详细说说大对象、定长 & 变长字符串对应着 MySQL 中的哪些字段类型?
本文内容基于 MySQL 5.7.35 源码。
提前声明: 本文中对于文本类型字段,字符集都默认为
utf8
,后面就不再单独说明了。
大对象比较厉害,和它有关的字段类型有 17 个,其中 8 个字段类型的实现类是 Field_blob
,9 个字段类型的实现类继承了 Field_blob。
实现类是 Field_blob 的字段类型有这些:
实现类继承了 Field_blob 的字段类型有这些:
实现类继承了 Field_blob 的字段类型中,JSON 类型的实现类为 Field_json
,其它 8 种类型都是空间类型
(spatial type),其实现类为 Field_geom
。
Field_blob、Field_json、Field_geom 承载了 17 个字段类型的实现,那 MySQL 怎么区分这 3 个类实例化之后,到底对应着哪种类型的字段呢?
Field_blob 通过类的实例属性 field_charset
中保存的字符集是 binay
还是其它文本字符集
来区分字段是二进制字段还是文本字段。
Field_blob 通过类的实例属性 packlength
区分二进制字段类型是 TINYBLOB、BLOB、MEDIUMBLOB、LONGBLOB 中的哪一种,区分文本字段类型是 TINYTEXT、TEXT、MEDIUMTEXT、LONGTEXT 中的哪一种。
Field_json 只对应 JSON 这一种字段类型,不需要区分。
Field_geom 通过类的实例属性 geom_type
区分字段类型是 GEOMETRY、POINT、LINESTRING、POLYGON、GEOMETRYCOLLECTION、MULTIPOINT、MULTILINESTRING、MULTIPOLYGON 中的哪一种。
Field_blob 类的实例属性 flags 包含 BLOB_FLAG
(值为 8),字段内容长度占用 1 字节
(packlength = 1),字符集为 binary
(field_charset.name = binary)表示这是一个 TINYBLOB
字段。
tinyblob
Field_blob 类的实例属性 flags 包含 BLOB_FLAG
(值为 8),字段内容长度占用 2 字节
(packlength = 2),字符集为 binary
(field_charset.name = binary)表示这是一个 BLOB
字段。
blob
Field_blob 类的实例属性 flags 包含 BLOB_FLAG
(值为 8),字段内容长度占用 3 字节
(packlength = 3),字符集为 binary
(field_charset.name = binary)表示这是一个 MEDIUMBLOB
字段。
mediumblob
Field_blob 类的实例属性 flags 包含 BLOB_FLAG
(值为 8),字段内容长度占用 4 字节
(packlength = 4),字符集为 binary
(field_charset.name = binary)表示这是一个 LONGBLOB
字段。
longblob
Field_blob 类的实例属性 flags 包含 BLOB_FLAG
(值为 8),字段内容长度占用 1 字节
(packlength = 1),字符集为 utf8
(field_charset.name = utf8)表示这是一个 TINYTEXT
字段。
tinytext
Field_blob 类的实例属性 flags 包含 BLOB_FLAG
(值为 8),字段内容长度占用 2 字节
(packlength = 2),字符集为 utf8
(field_charset.name = utf8)表示这是一个 TEXT
字段。
text
Field_blob 类的实例属性 flags 包含 BLOB_FLAG
(值为 8),字段内容长度占用 3 字节
(packlength = 3),字符集为 utf8
(field_charset.name = utf8)表示这是一个 MEDIUMTEXT
字段。
mediumtext
Field_blob 类的实例属性 flags 包含 BLOB_FLAG
(值为 8),字段内容长度占用 4 字节
(packlength = 4),字符集为 utf8
(field_charset.name = utf8)表示这是一个 LONGTEXT
字段。
longtext
JSON
字段的实现类为 Field_json
,继承了 Field_blob 类,Field_json 类没有定义自己的实例属性,只定义了处理 json 格式的方法。
Field_json 继承的 Field_blob 类的实例属性 flags 包含 BLOB_FLAG
(值为 8),字段内容长度占用 4 字节
(packlength = 4),字符集为 binary
(field_charset.name = binary)表示这是一个 JSON
字段。
JSON 字段相当于 LONGBLOB 字段。
json
空间类型是一个大类,有 8 种字段类型:
GEOMETRY
,该类型字段存储的内容可以是 POINT、LINESTRING、POLYGON 这 3 种类型中的任意一种。POINT
,表示一个点,如 POINT(15 20)
是 x = 15、y = 20 的点。LINESTRING
,表示一条由多个点连成的线(可以是直线或曲线),如 LINESTRING(0 0, 10 10, 20 25, 50 60)
是 x = y = 0;x = y = 10;x = 20、y = 25;x = 50、y = 60 这 4 个点连成的一条线。POLYGON
,表示多边形,如 POLYGON((0 0,10 0,10 10,0 10,0 0),(5 5,7 5,7 7,5 7, 5 5))
是包含一个外环和一个内环的多边形。GEOMETRYCOLLECTION
,该类型字段存储的是一个图形集合,可以是 POINT、LINESTRING、POLYGON 中的任意一个或多个,如 GEOMETRYCOLLECTION(POINT(10 10), POINT(30 30), LINESTRING(15 15, 20 20))
是包含 2 个点和 1 条线的图形集合。MULTIPOINT
,表示多个点,如 MULTIPOINT(0 0, 20 20, 60 60)
。MULTILINESTRING
,表示多条线,如 MULTILINESTRING((10 10, 20 20), (15 15, 30 15))
。MULTIPOLYGON
,表示多边形集合,如 MULTIPOLYGON(((0 0,0 3,3 3,3 0,0 0),(1 1,1 2,2 2,2 1,1 1)))
。空间类型的实现类为 Field_gemo
,继承了 Field_blob 类,Field_gemo 类定义了实例属性 geom_type
,用于区分 8 种字段类型,该属性值对应上面列出的 8 种字段类型的枚举值。
Field_gemo 继承的 Field_blob 类的实例属性 flags 包含 BLOB_FLAG
(值为 8),字段内容长度占用 4 字节
(packlength = 4),字符集为 binary
(field_charset.name = binary)表示这是一个空间类型
字段。
空间类型的 8 种字段都相当于 LONGBLOB 字段。
geometry
定长字符串的实现类为 Field_string
,有 2 种字段类型:
CHAR
,存储文本
内容,字段长度固定
,创建表时指定的长度不是字节数,而是字符数
,实际占用字节数取决于该字段的字符集。例如,对于 utf8 字符集,字段 c1 CHAR(10)
需要占用 10 * 3(utf8 单字符最大占用字节数)= 30 字节。BINARY
,存储二进制
内容,字段长度固定
,创建表时指定的长度为字节数
。例如,字段 bin1 BINARY(10)
需要占用 10 字节。Field_string 既支持二进制类型字段,又支持文本类型字段,Field_string 类实例化之后具体对应哪种字段,是通过 field_charset 来区分的。
Field_string 类的实例属性保存的字符集为 utf8
(field_charset.name = utf8)表示这是一个 CHAR
字段。
char
Field_string 类的实例属性保存的字符集为 binary
(field_charset.name = binary)表示这是一个 BINARY
字段。
binary
变长字符串的实现类为 Field_varstring
,有 2 种字段类型:
VARCHAR
,存储文本
内容,字段长度不固定
,创建表时指定的长度不是字节数,而是字符数
,最大占用字节数取决于该字段的字符集。例如:对于 utf8 字符集,字段 str1 VARCHAR(32)
最大占用 32 * 3(utf8 单个字符最大占用字节数)= 96 字节。VARBINARY
,存储二进制
内容,字段长度不固定
,创建表时指定的长度为字节数
。例如:字段 varbin1 VARBINARY(32)
最大占用 32 字节。Field_varstring 既支持二进制类型字段,又支持文本类型字段,Field_varstring 类实例化之后具体对应哪种字段,是通过类的实例属性 field_charset
来区分的,实例属性 field_length
表示字段内容的实际长度,length_bytes
表示存储字段内容长度占用的字节数(1 字节
或 2 字节
)。
Field_varstring 类的实例属性保存的字符集为 utf8
(field_charset.name = utf8)表示这是一个 VARCHAR 字段。
varchar
Field_varstring 类的实例属性保存的字符集为 binary
(field_charset.name = binary)表示这是一个 VARBINARY 字段。
varbinary
本文介绍了 4 种 BLOB 类型(TINYBLOB、BLOB、MEDIUMBLOB、LONGBLOB),4 种 TEXT 类型(TINYTEXT、TEXT、MEDIUMTEXT、LONGTEXT)都是以 Field_blob 类实现的。
JSON 类型以 Field_json 类实现,继承了 Field_blob 类,字段内容为二进制,用 4 字节存储内容长度,相当于 LONGBLOB 类型。
MySQL 中有 8 种类型(GEOMETRY、POINT、LINESTRING、POLYGON、GEOMETRYCOLLECTION、MULTIPOINT、MULTILINESTRING、MULTIPOLYGON)都是空间类型(spatial type)。空间类型以 Field_geom 类实现,也继承了 Field_blob 类,字段内容为二进制,用 4 字节存储内容长度,相当于 LONGBLOB 类型。
定长字符串以 Field_string 类实现,通过类的实例属性 field_charset 区分字段类型是 CHAR 还是 BINARY。
变长字符串以 Field_varstring 类实现,通过类的实例属性 field_charset 区分字段类型是 VARCHAR 还是 VARBINARY。
Copyright© 2013-2020
All Rights Reserved 京ICP备2023019179号-8