超详细的MySQL入门教程(二)

数据类型

与其它编程语言类似,在MySQL中,每张表中的每个字段都有它的数据类型。MySQL中的数据类型分为数字类型、字符串类型、地理空间类型、JSON类型和日期时间类型

数字类型

在MySQL中,数字类型可以分为整数类型浮点数类型。对于数字类型,可以为其设置UNSIGNED(无符号)ZEROFILL(自动填充0)UNIQUE(唯一性)AUTO_INCREMENT(自动增长列)DEFAULT(指定默认值)NOT NULL(非空)进行限制。

整数类型

数据类型 字节数 有符号 无符号
TINYINT 1字节 -128127 0255
SMALLINT 2字节 -3276832767 065535
MEDIUMINT 3字节 -83886088388607 016777215
INT 4字节 -21474836482147483647 04294967295
BIGINT 8字节 -263263-1 0264-1

使用如下SQL表达式描述一个INT类型:

INT(5)	// 括号中为有效数字长度

浮点数类型

数据类型 字节数 范围
DECIMAL 自定义 最长有效位数65位
需指定数字精度小数位数
FLOAT 4或8字节 (±3.402823466E)+38
DOUBLE 8字节 (±1.7976931348623157E)+308
(±2.2250738585072014E)-308

使用如下SQL表达式描述一个DECIMAL类型:

DECIMAL(5,2)	// 5为数字精度,2为小数位数

注:由于使用FLOATDOUBLE会出现数值不精确问题,需要使用浮点数据类型时一定要选DECIMAL

超出数值范围的后果

如果插入的数值超出了字段的数值范围,则MySQL会报如下错误:

在这里插入图片描述

字符串类型

MySQL中的字符串可以分为三种类型:普通字符串可变字符串特殊字符串

注:普通字符串类型和变长字符串类型的区别是——普通字符串类型的长度不会改变,而不同可变字符串类型的长度不同。例如:可变字符串类型BLOB就有TINYBLOBMEDIUMBLOBLONGBLOB三种不同的版本,每个版本的最大长度也不同

普通字符串类型

普通字符串有以下四种类型:CHARVARCHARBINARYVARBINARY。其中CHARVARCHAR用于存储普通字符串,BINARYVARBINARY用于存储二进制字符串。

CHARBINARY是定长字符串,即如果字符串长度未达到定义的长度就要使用空格或0x00进行补全。下面的表格说明了CHARVARCHAR之间的区别:

原值 CHAR(7) VARCHAR(7)
Liyue 'Liyue  '2个空格 ‘Liyue’0个空格
Inazuma ‘Inazuma’0个空格 ‘Inazuma’0个空格
Mondstadt ‘Mondsta’缺2字符 ‘Mondsta’缺2字符
CREATE DATABASE test;
CREATE TABLE IF NOT EXISTS `charlist` (var VARCHAR(7), chr CHAR(7));
INSERT INTO `charlist`(var,chr) VALUES('liyue  ','liyue  ');
SELECT CONCAT('(',var,')') AS 'VARCHAR',CONCAT('(',chr,')') AS 'CHAR' FROM `charlist`;

在这里插入图片描述

注:在通常情况下,MySQL执行SELECT语句时会删除CHAR类型值的追加空格

下面列出了普通字符串类型的名称和取值范围:

数据类型 建议字符串长度 注释
CHAR 255 定长
VARCHAR 255 变长
BINARY 同上,
但是以字节为单位
定长二进制
VARBINARY 同上,
但是以字节为单位
变长二进制

使用下面的SQL表达式描述一个字符串类型:

VARCHAR(255)

注:如果字符串长度超过255字符,建议使用TEXT作为存储数据类型。

可变字符串类型

MySQL中可变字符串类型的特点是最大长度会变化。(即有多个不同长度的相同类型版本

下面列出了一些常见的可变字符串类型:

数据类型 最长字节数 解释
TEXT 65535 普通文本类型
TINYTEXT 255 缩小版文本类型
MEDIUMTEXT 16777215 加长版文本类型
LONGTEXT 232-1 超长版文本类型
BLOB 65535 普通二进制类型
TINYBLOB 255 缩小版二进制类型
MEDIUMBLOB 16777215 加长版二进制类型
LONGBLOB 232-1 超长版二进制类型

注:可变字符串类型通常用于存储一些非常长的数据。如TEXT类型可以存储HTML文本,常用于博客、论坛帖子等;BLOB类型可以用于存储二进制数据,常用于存储音乐、视频、Word甚至可执行文件等。在MySQL中,可变字符串一般不受本表的行长度(65535字节)限制。

使用下面的SQL表达式描述一个可变类型:

BLOB(65535)

特殊字符串

在MySQL中还有两种特殊字符串:ENUM枚举类)和SET枚举类,可以存入多个值)。
具体可以参考大佬的文章:MySQL中的enum和set类型 - SlowIsFastLemon

地理空间类型

除了几种传统的数据类型,MySQL还支持用于对数学几何关系进行处理的地理空间类型。使用该类型可以便捷地对几何对象(包括点、线、面和各种几何对象的集合)进行查询、运算。

所有MySQL的地理空间类型都是由一个个坐标值组成的,即坐标值在地理空间类型中具有原子性,不可再分。地理空间类型支持DECIMAL小数类型。
MySQL的地理空间类型分为单值类型集合类型。下面介绍一些常见的地理空间类型:

单值类型

MySQL中的单值地理空间类型有:GEOMETRYPOINT(点)、LINESTRING(线)、POLYGON(多边形,即面),其中GEOMETRY类型是所有地理空间类型的基类

1.POINT类型

POINT类型用于表示一个坐标点,经度(X轴)在前,纬度(Y轴)在后,使用空格进行分隔,同一格中有且只有一个坐标值。例如:

POINT(30 10)	// 示例值,外面的POINT()不能丢

在这里插入图片描述
2.LINESTRING类型

LINESTRING类型用于表示由多个点组成的一条线段,所以该类型的数据由多个点的坐标值组成,不同坐标值之间用英文逗号分隔,同一格中至少有两个点。例如:

LINESTRING(30 10,32 12,32.2 12.8,32.1 14,31.6 16.2,29 20,22 24,14 25)

在这里插入图片描述
3.POLYGON类型

POLYGON类型用于表示一个几何图形(即),它由多个点坐标组成,点坐标之间用英文逗号分隔。对于该类型的语法有如下规定:

  1. POLYGON至少有一个环
  2. POLYGON所有的环全部是闭合的。(第一个值与最后一个值相同
  3. 每一个环至少有4个点
  4. 集合不为空,GeometryCollection类型除外。
POLYGON(16 18,30 20,30 10,20 12,16 18)

在这里插入图片描述

集合类型

MySQL地理空间类型的集合类型是各种单值类型(POINTLINESTRINGPOLYGON)的组合。MySQL中有如下集合类型:MULTIPOINTMULTILINESTRINGMULTIPOLYGONGEOMETRYCOLLECTION

1.MULTIPOINT类型

顾名思义,该类型是多个POINT类型的集合多个坐标值之间用逗号分隔

MULTIPOINT(30 10,50 43,47 9)

在这里插入图片描述
2.MULTILINESTRING类型

顾名思义,该类型是多个LINESTRING类型的集合每条线段至少要有两个点

MULTILINESTRING((30 10,60 40),(20 50,60 10))

在这里插入图片描述
3.MULTIPOLYGON类型

顾名思义,该类型是POLYGON类型的集合。该复合类型必须遵守如下语法要求:

  1. MultiPolygon类型没有两个Polygon元素的内部相交
  2. MultiPolygon没有两个Polygon元素交叉或在无数个点处接触。
  3. MultiPolygon是常规的封闭点集
  4. 具有多个Polygon的MultiPolygon内部没有连接
  5. MultiPolygon内部的连接组件的数量等于MultiPolygon中的Polygon值的数量
MULTIPOLYGON(((10 10,20 40,30 30,10 10)),((50 40,60 10,40 30,50 40)))

在这里插入图片描述
4.GeometryCollection类型

GeometryCollection类型是由多个POINTLINESTRINGPOLYGON元素组合起来的复合几何类型,用户可以使用该类型记录复杂的、由点线面等组合的几何图形(例如地形等)。

GEOMETRYCOLLECTION(POINT(40 20),LINESTRING(40 20,50 50),POLYGON((50 50,20 20,80 20,50 50)))

在这里插入图片描述

JSON类型

在MySQL 5.7.8之后,MySQL实现了对JSON数据类型的存储支持。在存储JSON数据时,可以使用内置的JSON类型而不必使用字符串类型。存储在JSON类型中的数据将转化为MySQL内部的存储格式,还有很多原生函数提供了对JSON数据进行增删改查的功能,极大地方便了数据的提取与存储。

JSON类型又分为字符串数字JSON数组JSON对象。JSON数组是一组以列表形式存储的数据,而JSON对象是以键值对形式存储、有上下级关系的字典

"Sakana~"										// JSON String
1145.14											// JSON Number
[1,2,"3","abcd"]								// JSON Array
{
   
   "a":1,"b":2,"c":{
   
   "ab":1,"ac":2},"d":"aaa"}		// JSON Object

如果要访问JSON类型中的元素,SQL表达式的语法如下:

  • JSON字符串:字段名->>“$”
  • JSON数字:字段名->“$”
  • JSON数组:字段名->>“$[索引编号]”
  • JSON对象:字段名->>“$.键名”
  • JSON多维对象:字段名->>“$.一维键名.二维键名.N.最后一维键名”

注:JSON路径中的“$”符号代表整个JSON数据

例如:

json1->>"$"			// Access JSON String
json1->"$"			// Access JSON Number
json1->>"$[0]"		// Access JSON Array
json1->>"$.c.ad.bd"	// Access JSON Object

在这里插入图片描述

日期时间类型

MySQL中有五种日期时间类型:YEARDATETIMEDATETIMETIMESTAMP。下面介绍它们的取值范围和单位等信息:

数据类型 格式 取值范围 字节数 说明
YEAR YYYY 1901 - 2155 1 只保存年份
DATE YYYY-MM-DD 1000/01/01
-
9999/12/31
3 保存年月日
TIME hh:mm:ss -838:59:59
-
838:59:59
3 保存时分秒
DATETIME YYYY-MM-DD
hh:mm:ss
1000/01/01 00:00:00
-
9999/12/31 23:59:59
8 年月日时分秒
TIMESTAMP YYYY-MM-DD
hh:mm:ss Time_Zone
1970/01/01 00:00:01 UTC
-
2038/01/19 03:14:07 UTC
4 时间戳
共2147483647秒

如果给日期时间类型赋一个不合法的时间值,那么该值会被0取代

注:在实际生产环境中,如果一个时间值需要被大量地计算,那么推荐使用TIMESTAMP类型;如果该时间值仅是用于被展示的,那么推荐使用DATETIME类型

MySQL的行长度限制

在MySQL的数据表中,为了防止一行记录字节数过多导致效率变慢、引发系统错误等一系列问题,MySQL的各种存储引擎对单行记录的定义长度进行了限制,这种限制就叫MySQL行长度限制

该限制只对以下数据类型生效:

  • CHAR
  • VARCHAR
  • BINARY
  • VARBINARY

MySQL的单行长度限制为65535字节。如果一行的定义长度超过了65535字节,MySQL就会报出如下错误:
在这里插入图片描述
若想解决该问题,只有以下两种方法:

1. 调小字段长度。
2. 将字段类型变为TEXT或者BLOB

下面举例说明该问题(请先执行SET GLOBAL sql_mode='';关闭严格模式):

假设我有一个数据库test,现在要创建一张表testtbl表的结构如下所示:

# 第一种情况
CREATE TABLE IF NOT EXISTS `testtbl`(
	id INT(5) UNSIGNED UNIQUE AUTO_INCREMENT NOT NULL,
	a VARCHAR(10000) DEFAULT NULL,	// a字段长度10000字符
	b VARCHAR(10000) DEFAULT NULL,	// b字段长度10000字符
	c VARCHAR(10000) DEFAULT NULL,	// c字段长度10000字符
	PRIMARY KEY (id)
)ENGINE=InnoDB DEFAULT CHARSET=utf8;	// 使用InnoDB存储引擎和utf8字符集

# 第二种情况
CREATE TABLE IF NOT EXISTS `testtbl`(
	id INT(5) UNSIGNED UNIQUE AUTO_INCREMENT NOT NULL,
	a VARCHAR(30000) DEFAULT NULL,	// a字段长度30000字符
	b VARCHAR(30000) DEFAULT NULL,	// b字段长度30000字符
	c VARCHAR(30000) DEFAULT NULL,	// c字段长度30000字符
	PRIMARY KEY (id)
)ENGINE=InnoDB DEFAULT CHARSET=utf8;	// 使用InnoDB存储引擎和utf8字符集

先说结论,第一种情况(每字段1万字符)失败,第二种情况(每字段3万字符)成功

  1. 首先我们要知道,一个字符包含几个字节是根据使用的字符集来决定的。在utf8字符集中,一个字符包含3个字节
  2. 在MySQL的宽松模式中,一个VARCHAR字段的定义长度超过65535字节后,会自动转为TEXT类型。
  3. MySQL还需要额外的几个字节来存储VARCHAR字段的长度。

在第一种情况中,因为每个字段最大定义了10000个字符,采用了utf8字符集(每个字符3字节),所以每个字段的定义长度为30000个字节,不会被转为TEXT类型。这样一行的定义长度就是10000\*3\*3=90000字节,明显超过了65535字节,所以报错。

而在第二种情况中,每个字段定义了30000个字符,采用了utf8字符集,所以每个字段的定义长度为90000字节,明显超过了单个字段的限制,于是MySQL在非严格模式下会将其转为TEXT类型(严格模式直接报错),又因为TEXT类型不受行长度限制,所以会创建成功但抛出警告。

综上,我们可以总结出计算行长度的公式:
行 长 度 > ( 字 段 1 字 符 数 + . . . + 字 段 n 字 符 数 ) ∗ 字 符 集 位 数 行长度>(字段1字符数+...+字段n字符数)*字符集位数 >1+...+n

下面列出常用字符集的位数:

字符集 字符集位数
Lantin 1字节
GB2312 英文字符1字节
非英文字符2字节
ASCII 1字节
utf8 3字节
utf8mb4 4字节
GB18030 4字节

猜你喜欢

转载自blog.csdn.net/qwe304/article/details/127858741
今日推荐