一、MySQL 数据类型概述
MySQL 数据类型主要分为数值类型、日期时间类型、字符串类型、二进制类型、JSON 类型与空间数据类型六大类,合理选择数据类型对数据库性能和存储效率至关重要。
MySQL 中的数据类型丰富多样,主要分为以下几大类:
- 数值类型:
-
- 整数类型:包括 TINYINT、SMALLINT、MEDIUMINT、INT、BIGINT 等,用于存储整数值,范围和存储大小各不相同。例如,TINYINT 占用 1 个字节,BIGINT 占用 8 个字节。
-
- 浮点数和定点数类型:FLOAT、DOUBLE 用于存储浮点数值,即带有小数点的数值。DECIMAL 则用于存储定点数值,适合用于需要精确计算的场景。
- 日期时间类型:DATE、DATETIME、TIMESTAMP、TIME、YEAR 等用于存储日期和时间信息。
- 字符串类型:
-
- CHAR 和 VARCHAR:CHAR 类型用于存储定长字符串,VARCHAR 则用于存储变长字符串。
-
- TEXT 系列类型:用于存储大量文本数据。
- 二进制类型:BINARY、VARBINARY 用于存储二进制数据。
- JSON 类型:用于存储 JSON 格式的数据。
- 空间数据类型:用于存储空间数据。
选择合适的数据类型对于数据库性能优化至关重要。以下是一些选择数据类型的建议:
- 根据数据范围选择整数类型:如果数据范围较小,可以选择较小的整数类型,以节省存储空间和提高查询效率。反之,如果数据范围较大,则应选择更大的整数类型。
- 根据精度要求选择浮点数或定点数类型:如果需要存储近似值,并且对精度要求不高,可以选择 FLOAT 或 DOUBLE 类型。如果需要存储精确值,则应选择 DECIMAL 类型。
- 根据字符串长度和变化性选择字符串类型:如果字符串长度固定且较短,可以选择 CHAR 类型。如果字符串长度可变或较长,则应选择 VARCHAR 或 TEXT 系列类型。
- 合理利用日期和时间类型:根据实际需求选择合适的日期和时间类型。例如,如果只需要存储日期信息,可以选择 DATE 类型;如果需要同时存储日期和时间信息,则可以选择 DATETIME 或 TIMESTAMP 类型。
- 避免使用不必要的大型数据类型:尽量选择能够满足需求的最小数据类型,以减少存储空间占用和提高查询效率。例如,如果一个字段的值永远不会超过 255 个字符,那么就没有必要选择 TEXT 类型,VARCHAR (255) 就足够了。
通过合理选择数据类型,可以减少存储空间占用、提高查询效率和数据处理速度,从而实现数据库性能的优化。
二、数值类型
1. 整型
MySQL 中有五种整型数据类型,分别是 TINYINT、SMALLINT、MEDIUMINT、INT 和 BIGINT。
取值范围:
- 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 个字节,取值范围是 -9223372036854775808 到 9223372036854775807(有符号),0 到 18446744073709551615(无符号)。
可选属性:
- 显示宽度:可以在类型名称的小括号内指定显示宽度,比如 INT (5) 表示数值宽度小于 5 的时候在数字前面填满宽度,如果不指定显示宽度默认为 INT (11)。
- 无符号属性:所有整型类型都有一个可选的 unsigned 属性,如果声明此属性,则值最小为 0,最大为原值的 2 倍。
- 零填充:如果一个列声明为 zerofill,则自动为该列添加 unsigned 属性,并且用 0 填充不足的位数。
应用场景:
- 如果数据范围较小,可以选择较小的整数类型,以节省存储空间和提高查询效率。例如,存储用户的年龄可以使用 TINYINT。
- 如果数据范围较大,则应选择更大的整数类型。例如,存储商品的库存数量可以使用 INT 或 BIGINT。
2. 浮点型
MySQL 中的浮点型数据类型包括 FLOAT、DOUBLE、REAL。
单精度和双精度浮点数的区别:
- 存储大小:FLOAT 占用 4 个字节,DOUBLE 占用 8 个字节。
- 有效数字位数:FLOAT 单精度小数部分只能精确到后面 6 位,加上小数点前的一位,即有效数字为 7 位;DOUBLE 双精度小数部分能精确到小数点后的 15 位,加上小数点前的一位,有效位数为 16 位。
- 数值取值范围:根据 IEEE 标准来计算,DOUBLE 的取值范围比 FLOAT 大。
- 处理速度:在一些处理器上,CPU 处理单精度浮点数的速度比处理双精度浮点数快。
非标准语法 FLOAT (M,D) 或 DOUBLE (M,D) 的含义和用法:
这里的 M 代表可以使用的数字位数,D 则代表小数点后的小数位数。比如语句 float (7,3) 规定显示的值不会超过 7 位数字,小数点后面带有 3 位数字。在 MySQL 中,在定义表字段的时候,unsigned 和 zerofill 修饰符也可以被 FLOAT、DOUBLE 和 DECIMAL 数据类型使用,并且效果与 INT 数据类型相同。
3. DECIMAL
DECIMAL 是 MySQL 中用于表示精确小数值的数据类型。
用法:
在 MySQL 数据库中,DECIMAL 的使用语法是 DECIMAL (M,D),其中,M 的范围是 1~65,D 的范围是 0~30,而且 D 不能大于 M。例如,DECIMAL (5,2),则该字段可以存储 -999.99~999.99,最大值为 999.99。也就是说 D 表示的是小数部分长度,(M-D) 表示的是整数部分长度。
计算所占用的字节数:
MySQL 使用二进制格式存储 DECIMAL 值。它将 9 位数字包装成 4 个字节。对于每个部分,需要 4 个字节来存储 9 位数的每个倍数。剩余数字所需的存储如下表所示:
Leftover Digits | Number of Bytes |
0 | 0 |
1–2 | 1 |
3–4 | 2 |
5–6 | 3 |
7–9 | 4 |
例如,DECIMAL (18,9),18 - 9 = 9,这样整数部分和小数部分都是 9,那两边分别占用 4 个字节。在实际的企业级开发中,经常遇到需要存储金额(3888.00 元)的字段,这时候就需要用到数据类型 DECIMAL。
三、日期时间类型
1. 日期
MySQL 中的日期类型主要有 YEAR 和 DATE 两种。
YEAR 类型:
- 插入方式:可以使用数字或字符串插入年份值,例如 insert into test5(mydate) values(2018);insert into test5(mydate) values('2017');也可以使用函数插入,如 insert into test5(mydate) values(year(now())) 和 insert into test5(mydate) values(year(curdate()))。
- 取值范围:取值范围为 “1901——2155”。可以以 4 位字符串或者 4 位数字格式表示的 YEAR,范围为 '1901'~'2155';以 2 位字符串格式表示的 YEAR,范围为 '00' 到 '99','00'~'69' 和 '70'~'99' 范围的值分别被转换为 2000~2069 和 1970~1999 范围的 YEAR 值;以 2 位数字表示的 YEAR,范围为 1~99,1~99 和 70~99 范围的值分别被转换为 2001~2069 和 1970~1999 范围的 YEAR 值,注意这里 0 值将被转换为 0000,而不是 2000。非法 YEAR 值将被转换为 0000。
DATE 类型:
- 插入方式:可以使用字符串类型或者数字类型的数据插入,只要符合 DATE 的日期格式即可。例如以 'YYYY-MM-DD' 或者 'YYYYMMDD' 字符中格式表示的日期,取值范围为 '1000-01-01'~'9999-12-3';以 'YY-MM-DD' 或者 'YYMMDD' 字符串格式表示日期,YY 表示两位的年值,'00~69' 范围的年值转换为 '2000~2069','70~99' 范围的年值转换为 '1970~1999';以 YYMMDD 数字格式表示的日期,与前面相似,00~69 范围的年值转换为 2000~2069,80~99 范围的年值转换为 1980~1999;还可以使用 CURRENT_DATE 或者 NOW(),插入当前系统日期。
- 取值范围:日期格式为 'YYYY-MM-DD',取值范围为 '1000-01-01'~'9999-12-31'。MySQL 允许 “不严格” 语法,任何标点符号都可以用作日期部分之间的间隔符。例如,'98-11-31'、'98.11.31'、'98/11/31' 和 '98@11@31' 是等价的,这些值也可以正确地插入数据库。
2. 时间
TIME 类型在存储时需要 3 个字节。格式为 HH:MM:SS。
- 字节数和取值范围:TIME 类型的取值范围为 -838:59:59~838:59:59,小时部分如此大的原因是 TIME 类型不仅可以用于表示一天的时间(必须小于 24 小时),还可能是某个事件过去的时间或两个事件之间的时间间隔(可大于 24 小时,或者甚至为负)。
- 插入方式:可以使用各种格式指定 TIME 值,如'D HH:MM:SS'格式的字符串,这里的D表示日,可以取 0~34 之间的值,在插入数据库时,D被转换为小时保存,格式为 “D*24+HH”;也可以是'HH:MM:SS'、'HH:MM'、'D HH' 或 'SS'等形式;还可以使用'HHMMSS'格式、没有间隔符的字符串或者 HHMMSS格式的数值,假定是有意义的时间;使用 current_time或者 current_time()或者 now()输入当前系统时间。如果输入 0 或者'0',那么 TIME类型会转换为 0000:00:00。
3. 日期 + 时间
DATETIME 和 TIMESTAMP 类型用于存储日期和时间信息。
DATETIME 类型:
- 表示方式:日期格式为 'YYYY-MM-DD HH:MM:SS',在存储时需要 8 个字节。
- 插入默认值的方法:在给 DATETIME 类型的字段赋值时,可以使用字符串类型或者数字类型的数据插入,只要符合 DATETIME 的日期格式即可。例如以 'YYYY-MM-DD HH:MM:SS' 或者 'YYYYMMDDHHMMSS' 字符串格式表示的日期;以 'YY-MM-DD HH:MM:SS' 或者 'YYMMDDHHMMSS' 字符串格式表示的日期,在这里 YY 表示两位的年值,'00~79' 范围的年值转换为 '2000~2079','80~99' 范围的年值转换为 '1980~1999';以 YYYYMMDDHHMMSS 或者 YYMMDDHHMMSS 数字格式表示的日期和时间。MySQL 允许 “不严格” 语法,任何标点符号都可用作日期部分或时间部分之间的间隔符。
- 存储形式:存储日期和时间信息,范围为 '1000-01-01 00:00:00'~'9999-12-3 23:59:59'。
TIMESTAMP 类型:
- 表示方式:显示格式与 DATETIME 相同,显示宽度固定在 19 个字符,日期格式为 YYYY-MM-DD HH:MM:SS,在存储时需要 4 个字节。
- 插入默认值的方法:可以使用 DEFAULT CURRENT_TIMESTAMP 为 TIMESTAMP 字段设置默认值,当插入新记录时,如果未提供 TIMESTAMP 字段的值,则默认值将被插入。例如创建表时 CREATE TABLE users (id INT PRIMARY KEY,name VARCHAR(50),created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP),在插入新记录时,如果没有显式指定 created_at 的值,它将自动设置为当前时间戳。
- 存储形式:存储日期和时间信息,范围为 '1970-01-01 00:00:01'~'2038-01-19 03:14:07',并且在存储和显示时会考虑时区的影响。此外,TIMESTAMP 还有一个特殊之处,就是会自动更新为当前时间戳。
四、字符串类型
1. CHAR/VARCHAR
- 特点:
-
- CHAR 是定长字符串类型,无论存储的字符串实际长度是多少,都会占用固定的字节数。存储时会在字符串右侧填充空格以达到指定长度,检索时会自动去除尾部空格。例如,CHAR (10) 存储字符串 'char' 时,会在 'char' 后面填充六个空格,实际存储为 'char ',但查询结果为 'char'。对于英文字符(ASCII)占用 1 字节,对一个汉字使用 2 字节。
-
- VARCHAR 是可变长度字符串类型,根据实际存储的字符串长度分配存储空间,并在数据开头使用额外 1 - 2 个字节存储字符串长度(列长度小于 255 字节时使用 1 字节表示,否则 2 字节),结尾使用 1 字节表示字符串结束。对每个字符均使用 2 字节。
- 插入失败的情况:如果插入的数据长度超过定义的长度,对于 CHAR 类型,会截断数据;对于 VARCHAR 类型,会报错。
- 如何根据数据特点选择使用:对于经常变更的数据来说,CHAR 比 VARCHAR 更好,因为 CHAR 不容易产生碎片。对于非常短的列或固定长度的数据如 MD5,CHAR 比 VARCHAR 在存储空间上更有效率。对于长度不固定的字符串,如用户姓名、电子邮件地址等,VARCHAR 更加合适。使用时要注意只分配需要的空间,更长的列排序时会消耗更多内存。尽量避免使用 TEXT/BLOB 类型,查询时会使用临时表,导致严重的性能开销。
2. TEXT
- 不同长度的 TEXT 类型介绍:
-
- TINYTEXT:最高存储 255 字节,适用于简短的描述、标题、注释等场景。
-
- TEXT:最高存储 65,535 字节(约 64 KB),适用于常见的文章、评论、消息等场景。
-
- MEDIUMTEXT:最高存储 16,777,215 字节(约 16 MB),适用于长篇文章、大量评论、大型文档等场景。
-
- LONGTEXT:最高存储 4,294,967,295 字节(约 4 GB),适用于超长文章、大型文本文件、日志数据等场景。
- 插入失败的情况:如果插入的数据长度超过对应类型的最大长度,会报错。
- 适用场景:存储大量文本数据,如文章内容、评论、用户输入等。数据库表中需要存储的文本数据长度不确定时,根据文本的长度范围选择合适的 TEXT 类型。
3. ENUM
- 创建方式:属性名 ENUM (' 值 1',' 值 2',' 值 3'...' 值 n'),其中 “属性名” 参数指字段的名称;“值 n” 参数表示列表中的第 n 个值,这些值末尾的空格将会被系统直接删除。
- 取值范围:列表中的值,最多可以有 65535 个值。
- 占用字节数:对 1 - 255 个成员的枚举需要 1 个字节存储;对于 256 - 65535 个成员,需要 2 个字节存储。
- 存储编号的方式:列表中的每个值都有一个顺序排列的编号,MySQL 中存入的是这个编号,而不是列表中的值。例如,ENUM (' 男 ',' 女 '),如果插入 ' 男',实际存储的是编号 1;插入 ' 女',实际存储的是编号 2。ENUM 有 NOT NULL 属性,其默认值为取值列表的第一个元素;ENUM 无 NOT NULL,则 ENUM 类型将允许插入 NULL,并且 NULL 为默认值。
4. SET
- 创建方式:属性名 SET (' 值 1',' 值 2',' 值 3'...,' 值 n'),其中,“属性名” 参数指字段的名称;“值 n” 参数表示列表中的第 n 个值,这些值末尾的空格将会被系统直接删除。
- 占用字节数:1 - 8 成员的集合,占 1 个字节;9 - 16 成员的集合,占 2 个字节;17 - 24 成员的集合,占 3 个字节;25 - 32 成员的集合,占 4 个字节;33 - 64 成员的集合,占 8 个字节。
- 可存储的元素数量:最多可以有 64 个元素构成的组合。
- 查询方法:可以使用 FIND_IN_SET () 函数来查询特定元素是否在 SET 类型的字段中。例如,SELECT * FROM table_name WHERE FIND_IN_SET (' 元素值 ', set_column_name)。
五、二进制类型
1. BIT
BIT 类型用于存储位值,可以使用 BIT (n) 来定义,其中 n 表示位的长度,最大为 64。创建 BIT 类型的列较为简单,例如:CREATE TABLE example (id INT NOT NULL AUTO_INCREMENT, flag BIT(1), PRIMARY KEY (id));。插入数据时可以使用 0 或 1 作为值进行赋值,如 INSERT INTO example (flag) VALUES(1);。查询结果以整数形式显示,例如查询 BIT (1) 的列,结果可能为 0 或 1。
2. BLOB
MySQL 中有不同长度的 BLOB 类型,包括 TINYBLOB、BLOB、MEDIUMBLOB 和 LONGBLOB。这些类型用于存储二进制数据,特点如下:
- TINYBLOB:最高存储 255 字节,适用于存储较小的二进制数据,如简短的图像缩略图等。
- BLOB:最高存储 65,535 字节(约 64 KB),可以存储一些中等大小的二进制数据,如小型文档的二进制内容。
- MEDIUMBLOB:最高存储 16,777,215 字节(约 16 MB),适合存储较大的二进制数据,如较大的图片文件等。
- LONGBLOB:最高存储 4,294,967,295 字节(约 4 GB),可用于存储非常大的二进制数据,如高清视频文件等。
在实际使用中,应根据需要存入的数据大小定义不同的 BLOB 类型。如果存储的文件过大,数据库的性能会下降。插入 BLOB 类型的数据必须使用 PreparedStatement,例如:
Connection conn = JDBCUtils.getConnection();
String sql = "insert into customers(name,email,birth,photo)values(?,?,?,?)";
PreparedStatement ps = conn.prepareStatement(sql);
// 填充占位符
ps.setString(1, "楚仙子888");
ps.setString(2, "[email protected]");
ps.setDate(3, new Date(new java.util.Date().getTime()));
// 操作 Blob 类型的变量
FileInputStream fis = new FileInputStream("xhq.png");
ps.setBlob(4, fis);
// 执行
ps.execute();
fis.close();
JDBCUtils.closeResource(conn, ps);
如果在指定了相关的 Blob 类型以后,还报错 “xxx too large”,那么在 mysql 的安装目录下,找 my.ini 文件加上如下的配置参数:max_allowed_packet=16M。同时注意:修改了 my.ini 文件之后,需要重新启动 mysql 服务。
3. BINARY/VARBINARY
BINARY 和 VARBINARY 的字节长度概念与字符集的关系以及与 CHAR/VARCHAR 在比较时的不同如下:
- 字节长度概念:BINARY 和 VARBINARY 的长度是以字节而不是字符度量的。BINARY 和 VARBINARY 类类似于 CHAR 和 VARCHAR,不同的是它们包含二进制字符串,即它们包含字节字符串而不是字符字符串。例如,BINARY(10)可存储的字节固定为 10,而对于 CHAR(10),其可存储的字节视字符集的情况而定。
- 与字符集的关系:BINARY 和 VARBINARY 没有字符集的概念,排序和比较基于列值字节的数值值。而 CHAR 和 VARCHAR 有字符集,并且根据字符集的校对规则对值进行排序和比较。
- 与 CHAR/VARCHAR 在比较时的不同:CHAR 和 VARCHAR 在进行字符比较时,比较的只是字符本身存储的字符,忽略字符后的填充字符。对于 BINARY 和 VARBINARY 来说,由于是按照二进制值来进行比较的,所以结果会非常不同。例如,对于 CHAR 和 VARCHAR,“a” 和 “a ” 比较结果为 1;而对于 BINARY 和 VARBINARY,“a” 的十六进制为 61,“a ” 的十六进制为 612020,比较结果为 0。另外,对于 BINARY 字符串,其填充字符是 0x00,而 CHAR 的填充字符为 0x20。
六、JSON 类型
JSON(JavaScript Object Notation)类型是从 MySQL 5.7 版本开始支持的功能,在 8.0 版本中解决了更新 JSON 的日志性能瓶颈。如果要在生产环境中使用 JSON 数据类型,强烈推荐使用 MySQL 8.0 版本。
1. 特点
- 存储数据的限制:在 InnoDB 存储引擎中,JSON 数据类型可以存储最大 65,535 字节的数据;而在 MyISAM 存储引擎中,JSON 数据类型可以存储最大 4GB 的数据。当 JSON 数据超过存储引擎的限制时,MySQL 会报错并拒绝插入或更新操作。
- 操作 JSON 的函数:MySQL 提供了丰富的内置函数来处理 JSON 数据,如 JSON_ARRAY、JSON_OBJECT、JSON_EXTRACT、JSON_INSERT、JSON_REPLACE、JSON_SET 等。这些函数可以用于创建、操作和查询 JSON 数据。
-
- JSON_EXTRACT 函数:用来从 JSON 数据中提取所需要的字段内容。例如,SELECT id,JSON_UNQUOTE(JSON_EXTRACT(info,"$.telephone")) telephone,JSON_UNQUOTE(JSON_EXTRACT(info,"$.wxchat")) wxchat FROM user;,MySQL 还提供了 ->>表达式,使用该表达式可以实现与 JSON_UNQUOTE (JSON_EXTRACT 相同的功能需求,如SELECT id,info->>"$.telephone" telephone,info->>"$.wxchat" wxchat FROM user;。当 JSON 数据量非常大,用户希望对 JSON 数据进行有效检索时,可以利用 MySQL 的函数索引功能对 JSON 中的某个字段进行索引。
-
- JSON_CONTAINS () 函数:功能是判断 JSON 文档是否在路径中包含特定对象。格式为JSON_CONTAINS(target, candidate[, path]),通过返回 1 或 0 来指示给定的候选 JSON 文档是否包含在目标 JSON 文档中。
-
- JSON_ARRAY_APPEND 函数:给指定的节点,添加元素,如果节点不是数组,则先转换成 [doc]。例如,SELECT json_Array_append('[1,2]','$','456')结果为[1,2,456]。
-
- JSON_MERGE 函数:将多个 doc 合并。例如,SELECT json_merge('[1,2,3]','[4,5]')结果为[1,2,3,4,5]。数组简单扩展,两个对象直接融合。特殊的还是在数组,目标碰到数组,先转换成 [doc],非数组都追加到数组后面。
-
- MEMBER OF () 函数:比较特定变量值是否能够匹配 JSON 数组中某个元素数据。如果当前 value 值匹配 JSON 数组中元素,那么返回 1,否则返回 0。在 WHERE 子句中对 InnoDB 表的 JSON 列使用 MEMBER OF () 的查询可以使用多值索引进行优化。
- 适用场景:
-
- JSON 类型比较适合存储一些修改较少、相对静态的数据。
-
- 有些列可能是比较稀疏的,一些列可能大部分都是 NULL 值;如果要新增一种登录类型,如微博登录,则需要添加新列,而 JSON 类型无此烦恼。
2. 使用示例
- 创建表及插入数据:
CREATE TABLE `user`(`id` bigint NOT NULL AUTO_INCREMENT,`info` json DEFAULT NULL,PRIMARY KEY(`id`)USING BTREE)ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci;
SET @a='{\"telephone\" : \"13812345678\",\"wxchat\" : \"微信号1\",\"address\" : \"安徽合肥\",\"idcard\" : \"34242711111111\"}';
insert into user values(1,@a);
SET @b='{\"telephone\" : \"13112345678\",\"wxchat\" : \"微信号2\",\"address\" : \"上海\",\"idcard\" : \"32434343\"}';
insert into user values(2,@b);
- 数据查询:
SELECT id,JSON_UNQUOTE(JSON_EXTRACT(info,"$.telephone")) telephone,JSON_UNQUOTE(JSON_EXTRACT(info,"$.wxchat")) wxchat FROM user;
JSON 数据类型的引入使得处理 JSON 数据变得更加便捷和高效,为开发人员提供了更多选择。在选择使用 JSON 数据类型时,需要根据具体场景和需求来决定是否使用,以达到最佳的性能和效果。
七、空间数据类型
在 MySQL 中,空间数据类型主要用于存储空间数据,如点、线、面等几何对象。其中,POINT 是一种常见的空间数据类型,代表二维空间中的一个点。此外,还有 GEOMETRY、LINESTRING、POLYGON 等类型。
GEOMETRY 类型:
GEOMETRY 是一种通用的几何类型,可以用来存储点、线、多边形等各种几何对象。使用 GEOMETRY 类型时,需要在创建表时指定具体的几何对象类型,例如 POINT、LINESTRING、POLYGON 等。优点是可以存储不同类型的几何对象,但缺点是在查询时需要额外的处理来区分不同类型的几何对象。例如:
CREATE TABLE spatial_data (id INT PRIMARY KEY, geom GEOMETRY);
INSERT INTO spatial_data (id, geom) VALUES(1, POINT(1,1)),(2, LINESTRING(0,0, 1, 1, 2, 2)),(3, POLYGON((0 0,0 10, 10 10, 10 0, 0 0)));
POINT 类型:
POINT 数据类型用于存储一个二维坐标点,其格式为 (X, Y),其中 X 和 Y 分别表示该点在二维平面上的横坐标和纵坐标。注意,在用 POINT 存储经纬度时,X 为经度,Y 为纬度,不要弄反了。因为将经纬度存储到 POINT 时并没有循序限制,但是使用 POINT 相关函数时就有限制了。比如 ST_Distance_Sphere。例如:
-- 创建表含 POINT 字段
createtable group_ride_info(id bigint unsigned not null comment'主键id' primary key,create_time datetime not null comment'创建时间',update_time datetime default CURRENT_TIMESTAMP null on update CURRENT_TIMESTAMP comment'修改时间',create_by int unsigned default'0' not null comment'创建人',update_by int unsigned default'0' not null comment'修改人',is_delete tinyint unsigned default'0' not null comment'是否删除。默认0,1-是,0-否',create_point point not null comment'创建时坐标') comment'团信息表';
create spatial index create_point on group_ride_info (create_point);
在 Java 中,我们可以使用 JDBC 来连接和操作 MySQL 数据库中的 POINT 类型。以下是一个简单的示例代码,演示了如何创建一个包含 Point 类型的表,并插入一些数据:
import java.sql.*;
public class PointExample {
public static void main(String[] args) {
String url = "jdbc:mysql://localhost:3306/mydatabase";
String username = "root";
String password = "password";
try (Connection conn = DriverManager.getConnection(url, username, password);
Statement stmt = conn.createStatement()) {
// 创建表
String createTableQuery = "CREATE TABLE locations (id INT PRIMARY KEY, name VARCHAR(100), position POINT)";
stmt.executeUpdate(createTableQuery);
// 插入数据
String insertDataQuery = "INSERT INTO locations VALUES(1, 'Point A', POINT(1.5, 2.5))";
stmt.executeUpdate(insertDataQuery);
System.out.println("数据插入成功!");
} catch (SQLException e) {
e.printStackTrace();
}
}
}
查询 POINT 列的值需要使用 ST_X 和 ST_Y 函数来从 POINT 值中提取经度和纬度:
SELECT name, X(position), Y(position) FROM locations;
LINESTRING 类型:
LINESTRING 表示由多个点组成的线段。例如:
INSERT INTO spatial_data (id, geom) VALUES(2, LINESTRING(0,0, 1, 1, 2, 2));
POLYGON 类型:
POLYGON 是一种特定的几何类型,用于存储封闭的多边形。使用 POLYGON 类型时,存储的几何对象必须是多边形,不能存储其他类型的几何对象。优点是更具体地表示了存储的几何对象类型,且在查询时不需要额外的处理来区分几何对象类型。例如:
CREATE TABLE polygons (id INT PRIMARY KEY,polygon_geom POLYGON);
INSERT INTO polygons (id, polygon_geom) VALUES(1, POLYGON((0 0,0 10, 10 10, 10 0, 0 0)));
空间数据类型在地理信息系统(GIS)、图形处理、空间数据分析等领域有广泛的应用。例如,在 GIS 中,可以使用这些类型来表示地图上的点、线、面等地理要素,进行地图分析、空间查询和空间数据可视化等操作。在图形处理中,可以用于表示多边形图形,进行几何运算和图形的裁剪、变换和渲染等操作。在空间数据分析中,可以表示地理区域的边界和形状,进行空间查询和分析。