首页 > 数据库 >【MySQL】第五章 数据类型

【MySQL】第五章 数据类型

时间:2025-01-10 22:57:51浏览次数:3  
标签:insert into MySQL 数据类型 第五章 sec mysql values row

系列文章目录

《【MySQL】第一章 MySQL 5.7的安装与卸载》
《【MySQL】第二章 初识数据库》
《【MySQL】第三章 库的操作》
《【MySQL】第四章 表的操作》
《【MySQL】第五章 数据类型》


文章目录


环境准备

本节将学习 MySQL 数据类型及其应用,为了更好的演示每种数据类型的具体用途。

此处会创建一个名为 data_type 的数据库,这个数据库专门用于存放本节所涉及到的各个表结构和示例数据。

环境准备的步骤:

  1. 登录 MySQL 客户端。

    LJH@iZ7xvhuhaslv4h5dm1d1svZ:~$ mysql -uroot -p
    Enter password: 
    Welcome to the MySQL monitor.  Commands end with ; or \g.
    Your MySQL connection id is 2
    Server version: 5.7.42 MySQL Community Server (GPL)
    
    Copyright (c) 2000, 2023, Oracle and/or its affiliates.
    
    Oracle is a registered trademark of Oracle Corporation and/or its
    affiliates. Other names may be trademarks of their respective
    owners.
    
    Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.
    
    mysql>
    
  2. 创建data_type数据库

    mysql> create database if not exists data_type;
    Query OK, 1 row affected (0.00 sec)
    
    mysql> show databases;
    +--------------------+
    | Database           |
    +--------------------+
    | information_schema |
    | data_type          |
    | gomoku             |
    | mysql              |
    | performance_schema |
    | sys                |
    +--------------------+
    6 rows in set (0.00 sec)
    

数据类型分类

下面是一张关于MySQL数据类型的分类及其说明的表格,其中标红的数据类型是后续讲解的解释说明的重点。

分类相同的数据类型之间用法类似,其中一个其他的也就都会了。举个例子,数值类型分类中整数类型分类中一共有5种,分别是tinyintsmallintmediumintintbigint。它们之间的差别仅在于数据所占存储空间的大小(单位为字节)以及存储的数据范围大小,其余都是一样的,了解其中一个的用法,其他的就都会了。

数值类型

数值类型分类

分类类型
整数类型tinyintsmallintmediumintintbigint
浮点数类型floatdoubledecimal
布尔类型bool
位类型bit(M)

整数类型

类型字节符号最小值最大值
TINYINT1有(默认)-128127
0255
SAMLLINT2有(默认)-32,76832,767
065535
MEDIUMINT3有(默认)-8,388,6088,388,607
016,777,215
INT4有(默认)-2,147,483,6482,147,483,647
04,294,967,295
BIGINT8有(默认)-9,223,372,036,854,775,8089,223,372,036,854,775,808
018,446,744,073,709,551,615

在下面就以TINYINT类型为例介绍整数类型的特点以及用法。

案例一:创建t1表并查看表结构的详细信息。

mysql> create table if not exists t1(
  -> n1 tinyint,
  -> n2 smallint,
  -> n3 mediumint,
  -> n4 int,
  -> n5 bigint
  -> );
Query OK, 0 rows affected (0.01 sec)

mysql> desc t1;
+-------+--------------+------+-----+---------+-------+
| Field | Type         | NULL | Key | Default | Extra |
+-------+--------------+------+-----+---------+-------+
| n1    | tinyint(4)   | YES  |     | NULL    |       |
| n2    | smallint(6)  | YES  |     | NULL    |       |
| n3    | mediumint(9) | YES  |     | NULL    |       |
| n4    | int(11)      | YES  |     | NULL    |       |
| n5    | bigint(20)   | YES  |     | NULL    |       |
+-------+--------------+------+-----+---------+-------+
5 rows in set (0.01 sec)

案例一内容说明:

  1. desc t1;语句执行结果中,我们能够看到Type中显示出来的各个数据类型后面都会跟着(数字)这么一个东西,其实括号中的数字表示该类型的数据默认的显示宽度,这部分内容涉及字段级别约束条件中的zerofill修饰符,属于是表的约束中的一部分,后续会详细介绍,这里不是本节的重点。

案例二:signed修饰符的省略与数据范围

mysql> show create table t1 \G
*************************** 1. row ***************************
       Table: t1
Create Table: CREATE TABLE `t1` (
  `n1` tinyint(4) DEFAULT NULL,
  `n2` smallint(6) DEFAULT NULL,
  `n3` mediumint(9) DEFAULT NULL,
  `n4` int(11) DEFAULT NULL,
  `n5` bigint(20) DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8
1 row in set (0.00 sec)

mysql> insert into t1 (n1) values (-128); # 插入 -128
Query OK, 1 row affected (0.01 sec)

mysql> insert into t1 (n1) values (-1); # 插入 -1
Query OK, 1 row affected (0.01 sec)

mysql> insert into t1 (n1) values (0); # 插入 0
Query OK, 1 row affected (0.00 sec)

mysql> insert into t1 (n1) values (1); # 插入 1
Query OK, 1 row affected (0.00 sec)

mysql> insert into t1 (n1) values (127); # 插入 127
Query OK, 1 row affected (0.01 sec)

mysql> insert into t1 (n1) values (128); # 插入 128,失败
ERROR 1264 (22003): Out of range value for column 'n1' at row 1
mysql> insert into t1 (n1) values (-129); # 插入 -129,失败
ERROR 1264 (22003): Out of range value for column 'n1' at row 1

案例二说明:

  1. MySQL定义了signedunsigned修饰符,它们只适用除了boolbit(M)之外的其余数值类型,用于指定字段是否允许存储负数。
  2. MySQL会默认将数值类型字段设置为有符号,n1 tinyint等同于n1 tinyint signed
  3. insert into t1 (n1) values (128);:指定向n1字段(列)插入一个数字128(插入语句的语法后续文章会专门介绍,此处了解是插入数据即可)。
  4. MySQL规定好了每个整数类型字段所能存储的数据范围,这个范围是根据该类型字段所占存储空间的大小(单位是字节)决定的,例如tinyint signed的范围是-128127tinyint unsigned的范围是0255,一旦数据大小超过类型规定范围时,数据的插入就会被MySQL拦截,然后报越界错误。
  5. 在C/C++或Java中,我们也遇到过将一个大数据存储到小空间的情况,但是C/C++编译器没有报错,而是通过数据截断或者隐式类型提升等手段来处理,这是因为编程语言中这样的设计是为了满足应用开发不同需求。而MySQL主要职责是对数据进行安全、可靠的管理,严格的数据类型和数据范围的检测保证了数据库中存储的数据一定是安全、可靠的。
  6. (尝试初步理解约束)“MySQL的数据类型”,或者说“MySQL对数据类型和数据范围的严格检测”本身就是一种约束,约束MySQL的使用者每次都要尽可能地执行正确的插入,所以什么是约束——约束就是通过不断加条件让数据变得是可预期的、完整的。

案例三:unsigned修饰符的使用

mysql> CREATE TABLE if not exists `t2` (
    ->   `n1` tinyint(4) unsigned DEFAULT NULL,
    ->   `n2` smallint(6) unsigned DEFAULT NULL,
    ->   `n3` mediumint(9) unsigned DEFAULT NULL,
    ->   `n4` int(11) unsigned DEFAULT NULL,
    ->   `n5` bigint(20) unsigned DEFAULT NULL
    -> ) ENGINE=InnoDB DEFAULT CHARSET=utf8;

mysql> desc t2;
+-------+-----------------------+------+-----+---------+-------+
| Field | Type                  | NULL | Key | Default | Extra |
+-------+-----------------------+------+-----+---------+-------+
| n1    | tinyint(4) unsigned   | YES  |     | NULL    |       |
| n2    | smallint(6) unsigned  | YES  |     | NULL    |       |
| n3    | mediumint(9) unsigned | YES  |     | NULL    |       |
| n4    | int(11) unsigned      | YES  |     | NULL    |       |
| n5    | bigint(20) unsigned   | YES  |     | NULL    |       |
+-------+-----------------------+------+-----+---------+-------+
5 rows in set (0.00 sec)

mysql> insert into t2 (n1) values (0);
Query OK, 1 row affected (0.00 sec)

mysql> insert into t2 (n1) values (255);
Query OK, 1 row affected (0.00 sec)

mysql> insert into t2 (n1) values (256);
ERROR 1264 (22003): Out of range value for column 'n1' at row 1
mysql> insert into t2 (n1) values (-1);
ERROR 1264 (22003): Out of range value for column 'n1' at row 1

案例三的说明:

  1. signed修饰符和unsigned修饰符的区别其实就在于数据的取值范围不同而已,其余都是一样的。
  2. 有些地方对于unsigned修饰符的观点是这样的“尽量不使用unsigned,对于int类型可能存放不下的数据,int unsigned同样可能存放不下,与其如此,还不如设计时将int类型提升为bigint类型”,这个说法不完全正确,unsigned修饰符的使用与否完全取决于使用场景,例如年龄、商品库存、ID等数据进行字段定义时天然就是适合使用unsigned修饰符。
  3. MySQL为什么要提供这么的数据类型——这主要是MySQL设计时在“提供应用场景”和“节省资源”当中的取舍,还是以年龄为例,年龄的类型有必要用bigint吗,显然是没有的,使用tinyint消耗1个字节就已经满足需求了,没有必要多浪费7个字节使用bigint类型。

浮点数

float[(M, D)] [unsigned] M--指定浮点数长度,D--小数位数,占用空间4个字节
double[(M, D)] [unsigned] M--指定浮点数长度,D--小数位数,占用空间4个字节
decimal(M, D) [unsigned] M--指定浮点数长度,D--小数位数,占用空间4个字节

浮点数类型一共有三个,分别是floatdoubledecimal(M, D)

floatdouble这两个类型的差别仅在于可存储的数据范围和数据的精度,所以只会针对性地了解其中的一个,这里选择的是float

换言之,下面内容分成两部分,第一部分是关于float的介绍,第二部分是关于decimal(M, D)类型的介绍。

FLOAT

cloumn_name float[(M, D)] [unsigned]
  • [(M, D)]:可选项,
    • M用于指定浮点数的总位数(包括小数点前后)。
    • D用于表示小数点后的位数。
  • [unsigned]:可选项,不写默认浮点数是有符号的。
  • float类型所占据的存储空间大小是4个字节。

案例一:有符号浮点数的插入以及边界的了解

mysql> create table if not exists t3(
    -> id int,
    -> salary float(4, 2)
    -> );
Query OK, 0 rows affected (0.01 sec)

mysql> desc t3;
+--------+------------+------+-----+---------+-------+
| Field  | Type       | NULL | Key | Default | Extra |
+--------+------------+------+-----+---------+-------+
| id     | int(11)    | YES  |     | NULL    |       |
| salary | float(4,2) | YES  |     | NULL    |       |
+--------+------------+------+-----+---------+-------+
2 rows in set (0.00 sec)

mysql> insert into t3 (id, salary) values (1, -99.99); -- 下边界
Query OK, 1 row affected (0.00 sec)

mysql> insert into t3 (id, salary) values (2, 99.99); -- 上边界
Query OK, 1 row affected (0.00 sec)

mysql> insert into t3 (id, salary) values (3, -10.1); -- 小数点部分不足2位会补零
Query OK, 1 row affected (0.01 sec)

mysql> insert into t3 (id, salary) values (4, -100.00);
ERROR 1264 (22003): Out of range value for column 'salary' at row 1
mysql> insert into t3 (id, salary) values (5, -100.0);
ERROR 1264 (22003): Out of range value for column 'salary' at row 1
mysql> insert into t3 (id, salary) values (6, 100.0);
ERROR 1264 (22003): Out of range value for column 'salary' at row 1
mysql> insert into t3 (id, salary) values (7, 100.00);
ERROR 1264 (22003): Out of range value for column 'salary' at row 1

mysql> select * from t3;
+------+--------+
| id   | salary |
+------+--------+
|    1 | -99.99 |
|    2 |  99.99 |
|    3 | -10.10 |
+------+--------+
3 rows in set (0.00 sec)

案例一的说明:

  • salary float(4, 2)字段定义的时候没用指明使用unsigned修饰符修饰,说明该字段能够存储负数。
  • float(4, 2)表示字段的总位数为4位,其中2位用于小数部分。因此,整数部分最多允许2位。因此,该字段可以存储的范围是-99.9999.99。任何超出这个范围的值(例如-100.00100.00)都会触发 “Out of range” 错误。这就是为什么尝试插入-100.00100.00时,MySQL 会报错。
  • 在小数部分不满足精度要求时(如 -10.1 只有 1 位小数),MySQL 会自动在小数部分补零以满足 float(4, 2) 的格式要求。插入时,即使提供的浮点数不精确到 2 位小数,MySQL 也会确保输出格式符合定义。

案例二:浮点数插入时的四舍五入

mysql> insert into t3 (id, salary) values (4, -10.999);
Query OK, 1 row affected (0.01 sec)

mysql> insert into t3 (id, salary) values (4, 10.999);
Query OK, 1 row affected (0.00 sec)

mysql> select * from t3;
+------+--------+
| id   | salary |
+------+--------+
|-- 略					|
|    4 | -11.00 |
|    4 |  11.00 |
+------+--------+
5 rows in set (0.00 sec)

mysql> insert into t3 (id, salary) values (5, 12.455);
Query OK, 1 row affected (0.00 sec)

mysql> insert into t3 (id, salary) values (5, 12.454);
Query OK, 1 row affected (0.00 sec)

mysql> insert into t3 (id, salary) values (4, 99.999);
ERROR 1264 (22003): Out of range value for column 'salary' at row 1

mysql> select * from t3;
+------+--------+
| id   | salary |
+------+--------+
|-- 略					|
|    4 | -11.00 |
|    4 |  11.00 |
|    5 |  12.46 |
|    5 |  12.45 |
+------+--------+
7 rows in set (0.00 sec)

案例二说明:

  • 四舍五入规则:当插入的浮点数小数位数超过定义的小数位数时(如 2 位),MySQL 会自动对值进行四舍五入来调整浮点数的值,以符合定义的精度。例如:
    • -10.999 被四舍五入为 -11.00
    • 10.999 被四舍五入为 11.00
    • 12.455 被四舍五入为 12.46
    • 12.454 被四舍五入为 12.45
  • 四舍五入可能导致的边界问题:当四舍五入后值超出定义的范围,仍会引发 “Out of range” 错误。例如,如果插入 99.995,四舍五入后变为 100.00,将超出 float(4, 2) 的范围,从而导致插入失败。

案例三:无符号的浮点数的插入以及边界的了解

mysql> create table if not exists t4(
    -> id int,
    -> salary float(4, 2) unsigned
    -> );
Query OK, 0 rows affected (0.02 sec)

mysql> desc t4;
+--------+---------------------+------+-----+---------+-------+
| Field  | Type                | NULL | Key | Default | Extra |
+--------+---------------------+------+-----+---------+-------+
| id     | int(11)             | YES  |     | NULL    |       |
| salary | float(4,2) unsigned | YES  |     | NULL    |       |
+--------+---------------------+------+-----+---------+-------+
2 rows in set (0.00 sec)

mysql> insert into t4 (id, salary) values (1, 0);
Query OK, 1 row affected (0.00 sec)

mysql> insert into t4 (id, salary) values (2, 99.99);
Query OK, 1 row affected (0.00 sec)

mysql> insert into t4 (id, salary) values (3, 99.994);
Query OK, 1 row affected (0.00 sec)

mysql> insert into t4 (id, salary) values (3, 99.996);
ERROR 1264 (22003): Out of range value for column 'salary' at row 1
mysql> insert into t4 (id, salary) values (3, -0.0001);
ERROR 1264 (22003): Out of range value for column 'salary' at row 1
mysql> insert into t4 (id, salary) values (3, 100);
ERROR 1264 (22003): Out of range value for column 'salary' at row 1

mysql> select * from t4;
+------+--------+
| id   | salary |
+------+--------+
|    1 |   0.00 |
|    2 |  99.99 |
|    3 |  99.99 |
+------+--------+
3 rows in set (0.00 sec)

案例三的说明:

  • 无符号浮点数的取值范围:在定义了float(4, 2) unsigned后,salary字段只能存储非负数,其取值范围是[0.00, 99.99]。和整数类似,移除符号限制后,负数的支持被取消,但与整数不同的是,无符号浮点数不会扩大数值上限。例如,float(4, 2) 的有符号范围为 [-99.99, 99.99],无符号后范围变为 [0.00, 99.99],上限依旧没有变化。
  • 边界处理:
    • 0 是合法的最小值,因此 insert into t4 (id, salary) values (1, 0); 成功。
    • 99.99 是最大合法值,因此insert into t4 (id, salary) values (2, 99.99);成功。
    • 插入负值(如 -0.0001)会立即触发 “Out of range” 错误,因为无符号字段不允许负数。
  • 四舍五入的处理:float(4, 2)在插入99.994时,MySQL自动四舍五入为99.99,结果符合精度要求,并不会超出范围。但 99.996 则会被视为 100.00,超出上限,从而触发 “Out of range” 错误。这说明无符号浮点数也是符合四舍五入规则的。、

案例四:精度损失

在此案例中,t5 表的设计用于测试 MySQL 中浮点数类型 float 的精度损失情况。表结构定义如下:

  • 字段 s1:为浮点类型 float,用于测试当整数部分过大时可能造成的精度损失。
  • 字段 s2:定义为 float(10,8),用于测试当小数部分位数过多时的精度损失。
mysql> create table if not exists t5(
  -> id int,
  -> s1 float comment '用于测试整数部分过大时造成的精度损失',
  -> s2 float(10, 8) comment '用于测试小数部分位数过多时的精度损失'
  -> );
Query OK, 0 rows affected (0.01 sec)

测试数据及其查询结果:

mysql> insert into t5 (id, s1, s2) values (1, 2.12345, 2.12345);
Query OK, 1 row affected (0.00 sec)

mysql> insert into t5 (id, s1, s2) values (1, 123456789, 1.23456789);
Query OK, 1 row affected (0.01 sec)

mysql> insert into t5 (id, s1, s2) values (1, 123456789, 12.3456789);
Query OK, 1 row affected (0.00 sec)

mysql> select * from t5;
+------+-----------+-------------+
| id   | s1        | s2          |
+------+-----------+-------------+
|    1 |   2.12345 |  2.12345004 |
|    1 | 123457000 |  1.23456788 |
|    1 | 123457000 | 12.34567928 |
+------+-----------+-------------+

案例说明:

  1. 字段 s1:测试整数部分较大时的精度损失
    • 插入 s1 的值为 123456789,但在查询结果中,s1 显示为 123457000
    • 这表明,当浮点数的整数部分位数较大时,float 类型会由于精度限制对数值进行近似存储,从而出现数据损失,这是由于 float 类型采用 IEEE 754 标准的单精度浮点表示,无法精确表示非常大的整数,从而导致存储时的数据变动。
  2. 字段 s2:测试小数部分位数过多时的精度损失
    • 插入 s2 的值为 2.12345,查询显示 2.12345004;插入 1.23456789 显示为 1.23456788,插入 12.3456789 显示为 12.34567928。这些结果说明,当小数部分的位数超过 float 的精度限制时,MySQL 会近似存储这些数据,而非精确存储。
    • 即使字段定义了 float(10,8),也无法完全保证八位小数精度,因为 float 类型的底层存储结构限制了数值的精确度。
  3. 以上测试结果中,大概体现了float类型能大概只能保证7位(从左往右)的精度,如果对数字的精度要求较高时不应该使用float类型。

DECIMAL(M, D)

下面是关于decimal数据的语法:

column_name decimal(M, D) [unsigned]
  • M
    • 名称:精度。
    • 含义:数字的总位数(包括小数点左右两侧的所有数字)。
    • 取值范围:[1~65],缺省值为10。
  • D
    • 名称:标度。
    • 含义:小数点右侧数字的位数。
    • 取值范围:[0, 30],缺省值为0,注意:MySQL要求D <= M
  • [unsigned]可选项,类型修饰符,使用之后只能该列不能存储负数。
  • 举例:decimal(4, 2)表示该列可以存储小数有2位,总共有4位的浮点数,如12.34

  1. 字段定义时,decimaldecimal(0)decimal(0, 0)三种写法都会被MySQL认为M、D缺省。
-- 缺省状态的定义
mysql> create table if not exists t8 (
    -> d1 decimal,
    -> d2 decimal(0),
    -> d3 decimal(0, 0)
    -> );
Query OK, 0 rows affected (0.01 sec)

mysql> desc t8;
+-------+---------------+------+-----+---------+-------+
| Field | Type          | NULL | Key | Default | Extra |
+-------+---------------+------+-----+---------+-------+
| d1    | decimal(10,0) | YES  |     | NULL    |       |
| d2    | decimal(10,0) | YES  |     | NULL    |       |
| d3    | decimal(10,0) | YES  |     | NULL    |       |
+-------+---------------+------+-----+---------+-------+
3 rows in set (0.00 sec)

  1. 只有当M、D(精度、标度)取值正确,表的创建SQL才能正常执行。
-- M最大值是65
mysql> create table if not exists t8 ( d1 decimal(66, 30) );
ERROR 1426 (42000): Too-big precision 66 specified for 'd1'. Maximum is 65.

-- D最大值是30
mysql> create table if not exists t8 ( d1 decimal(65, 31) );
ERROR 1425 (42000): Too big scale 31 specified for column 'd1'. Maximum is 30.

-- M最小值为1,D最小值为0
mysql> create table if not exists t8 (
    -> d1 decimal(1, 0),
    -> d2 decimal(65, 30)
    -> );
Query OK, 0 rows affected (0.02 sec)

mysql> desc t8;
+-------+----------------+------+-----+---------+-------+
| Field | Type           | NULL | Key | Default | Extra |
+-------+----------------+------+-----+---------+-------+
| d1    | decimal(1,0)   | YES  |     | NULL    |       |
| d2    | decimal(65,30) | YES  |     | NULL    |       |
+-------+----------------+------+-----+---------+-------+
2 rows in set (0.00 sec)

  1. decimalfloat的差别就在于decimal能够精确存储数值。
    1. 字段f,插入值是23.12345612,查询值是23.12345695,存在误差。
    2. 字段d,插入值是23.12345612,查询值是23.12345612,不存在误差。
mysql> create table if not exists t8(
    -> f float(10, 8),
    -> d decimal(10, 8)
    -> );
Query OK, 0 rows affected (0.01 sec)

mysql> desc t8;
+-------+---------------+------+-----+---------+-------+
| Field | Type          | NULL | Key | Default | Extra |
+-------+---------------+------+-----+---------+-------+
| f     | float(10,8)   | YES  |     | NULL    |       |
| d     | decimal(10,8) | YES  |     | NULL    |       |
+-------+---------------+------+-----+---------+-------+
2 rows in set (0.00 sec)

mysql> insert into t8 values (23.12345612, 23.12345612);
Query OK, 1 row affected (0.01 sec)

mysql> select * from t8;
+-------------+-------------+
| f           | d           |
+-------------+-------------+
| 23.12345695 | 23.12345612 |
+-------------+-------------+
1 row in set (0.00 sec)

BIT(M)类型

以下是关于bit类型的语法:

column_name bit[(M)]
  • 位类型
  • M
    • 名称:位宽或者位长度。
    • 含义:可用的比特位数(结合存储空间理解)。
    • 取值范围:[1, 64],缺省值为1。
  • 存储空间: ⌈ M 8 ⌉ \lceil \frac{M}{8} \rceil ⌈8M​⌉ 字节(向上取整)。
    举例,M==1时,字段所占存储空间是1个字节,但是只会使用1个比特位。

  1. 字段的定义

    -- M不能为0
    mysql> create table if not exists t( id int, online bit(0) );
    ERROR 3013 (HY000): Invalid size for column 'online'.
    
    -- M的最大值为64
    mysql> create table if not exists t( id int, online bit(65) );
    ERROR 1439 (42000): Display width out of range for column 'online' (max = 64)
    
    mysql> create table if not exists t (
        ->   id int comment '当前用户的标识符',
        ->   online bit(1) comment '当前用户是否在线'
        -> );
    Query OK, 0 rows affected (0.02 sec)
    
    mysql> desc t;
    +--------+---------+------+-----+---------+-------+
    | Field  | Type    | NULL | Key | Default | Extra |
    +--------+---------+------+-----+---------+-------+
    | id     | int(11) | YES  |     | NULL    |       |
    | online | bit(1)  | YES  |     | NULL    |       |
    +--------+---------+------+-----+---------+-------+
    2 rows in set (0.00 sec)
    

  1. 插入数据
    字段定义时,指定可用比特位数为1,那么只能存储1个比特位的数据。
    0的二进制为0,1的二进制位1,这两个能够正常插入。
    2的二进制为10,需要使用两个比特位,而可用比特位为1,插入失败。

    mysql> insert into t (id, online) values (1, 0);
    Query OK, 1 row affected (0.00 sec)
    
    mysql> insert into t (id, online) values (2, 1);
    Query OK, 1 row affected (0.00 sec)
    
    mysql> insert into t (id, online) values (3, 2);
    ERROR 1406 (22001): Data too long for column 'online' at row 1
    

  1. 查询数据

    1. 现象:查询t表数据的时候发现online列什么也看不到。
    2. 原因:bit(M)类型数据显示的时候默认按照数字对应的ASCII字符进行显示,数字0、1对应的字符都是不可打印的字符。
    3. 验证:
      1. 修改online列的数据类型为bit(8).
      2. id列、online列分别插入数据65。
      3. 再次查询发现有一行数据中,id列值为65online列值为A
      4. 查询ASCII表发现,字符A的ASCII码值就是65
    mysql> select * from t;
    +------+--------+
    | id   | online |
    +------+--------+
    |    1 |        |
    |    2 |       |
    +------+--------+
    2 rows in set (0.00 sec)
    
    mysql> alter table t modify column online bit(8);
    Query OK, 2 rows affected (0.04 sec)
    Records: 2  Duplicates: 0  Warnings: 0
    
    mysql> desc t;
    +--------+---------+------+-----+---------+-------+
    | Field  | Type    | NULL | Key | Default | Extra |
    +--------+---------+------+-----+---------+-------+
    | id     | int(11) | YES  |     | NULL    |       |
    | online | bit(8)  | YES  |     | NULL    |       |
    +--------+---------+------+-----+---------+-------+
    2 rows in set (0.00 sec)
    
    mysql> insert into t (id, online) values (65, 65);
    Query OK, 1 row affected (0.00 sec)
    
    mysql> select * from t;
    +------+--------+
    | id   | online |
    +------+--------+
    |    1 |        |
    |    2 |       |
    |   65 | A      |
    +------+--------+
    3 rows in set (0.00 sec)
    

  1. bit(M)类型不支持存储负数。

    1. 在MySQL中,bit(M)被设计存储无符号二进制数据的类型,即它没有负数的概念。
    2. 负数的处理机制是,但凡是负数都会被转换成64位二进制补码,例如-1就会被转换成11111111 11111111 11111111 11111111 11111111 11111111 11111111 11111111,一共64个1。
    3. 由于 BIT 类型不直接转换为十进制或 ASCII 字符串,MySQL 会尝试将 11111111...111 的位解释为字符,因此显示为 ÿÿÿÿÿÿÿÿ,因为 ÿ 是 8 位全 1 的二进制(即 255)的 ASCII 表示。
    mysql> alter table t modify column online bit(63);
    Query OK, 3 rows affected (0.03 sec)
    Records: 3  Duplicates: 0  Warnings: 0
    
    mysql> insert into t (id, online) values (-1, -1);
    ERROR 1406 (22001): Data too long for column 'online' at row 1
    --------------------------------------------------------------------
    mysql> alter table t modify column online bit(64);
    Query OK, 3 rows affected (0.03 sec)
    Records: 3  Duplicates: 0  Warnings: 0
    
    mysql> insert into t (id, online) values (-1, -1);
    Query OK, 1 row affected (0.00 sec)
    --------------------------------------------------------------------
    mysql> select * from t;
    +------+----------+
    | id   | online   |
    +------+----------+
    |    1 |          |
    |    2 |         |
    |   65 |        A |
    |   -1 | ÿÿÿÿÿÿÿÿ         |
    +------+----------+
    4 rows in set (0.00 sec)
    --------------------------------------------------------------------
    mysql> insert into t (id, online) values (255, 255);
    Query OK, 1 row affected (0.00 sec)
    
    mysql> select * from t;
    +------+----------+
    | id   | online   |
    +------+----------+
    |    1 |          |
    |    2 |         |
    |   65 |        A |
    |   -1 | ÿÿÿÿÿÿÿÿ         |
    |  255 |        ÿ  |
    +------+----------+
    5 rows in set (0.00 sec)
    

字符串类型

定长字符串类型char

语法

语法:

column_name char(L)

说明:

  • 作用是定义固定长度的字符串。
  • L 是可以存储的字符串的长度,单位是字符。
  • L 的最大值是 255。

要点说明

长度单位是字符
  1. 定义一张名为 t8 的表结构,其中 name 字段类型为 char(2),最多可以存储 2 个字符。

    mysql> create table if not exists t8 (
        -> id int,
        -> name char(2)
        -> );
    Query OK, 0 rows affected (0.01 sec)
    
  2. 插入英文字符。

    -- 一个字符插入成功
    mysql> insert into t8 (id, name) values (1, 'a');
    Query OK, 1 row affected (0.00 sec)
    
    -- 两个字符插入成功
    mysql> insert into t8 (id, name) values (1, 'ab');
    Query OK, 1 row affected (0.00 sec)
    
    -- 三个字符插入失败
    mysql> insert into t8 (id, name) values (1, 'abc');
    ERROR 1406 (22001): Data too long for column 'name' at row 1
    
  3. 插入中文字符。

    -- 一个中文字符插入成功
    mysql> insert into t8 (id, name) values (1, '中');
    Query OK, 1 row affected (0.00 sec)
    
    -- 两个中文字符插入成功
    mysql> insert into t8 (id, name) values (1, '中国');
    Query OK, 1 row affected (0.00 sec)
    
    -- 三个中文字符插入失败
    mysql> insert into t8 (id, name) values (1, '中国的');
    ERROR 1406 (22001): Data too long for column 'name' at row 1
    

总结:

  1. MySQL 对字符一视同仁,不管是英文字符还是中文字符,无论存储该字符需要消耗多少存储空间,都统一当成一个字符来看待。
  2. 当插入的字符串的字符个数超过预设的字符长度时,插入操作会被拦截。
预设字符长度不能超过 255

定义一张名为 t9 的表结构,其中,name 字段的类型为 char(256)

mysql> create table if not exists t9 (
    -> id int,
    -> name char(256)
    -> );
ERROR 1074 (42000): Column length too big for column 'name' (max = 255); 
  use BLOB or TEXT instead

SQL 语句执行失败,MySQL 提示 char 类型字符长度最大值为 255,当长度超过最大值时,表结构创建失败。

另外,MySQL 提示,想要使用更大的字符长度,请用 BLOB 或者 TEXT 类型。

关于固定长度的字符串的理解:这个类型的空间你用多少是你的事,我(MySQL)给你多少由L决定。

变长字符串类型varchar

语法

语法:

column_name varchar(L)

说明:

  • 作用是定义长度可变的字符串。
  • L 是可以存储的字符串的字符长度的最大预设值,单位是字符。
  • varchar(L) 类型的最大字节长度为 65535 字节。

要点介绍

长度单位是字符
  1. 定义一张名为 t9 的表结构,其中 name 字段的类型为 varchar(2),最多存储 2 个字符。

    mysql> create table if not exists t9 (
        -> id int,
        -> name varchar(2)
        -> );
    Query OK, 0 rows affected (0.02 sec)
    
  2. 插入英文字符。

    -- 一个字符插入成功
    mysql> insert into t9 (id, name) values (1, 'a');
    Query OK, 1 row affected (0.01 sec)
    
    -- 两个字符插入成功
    mysql> insert into t9 (id, name) values (1, 'ab');
    Query OK, 1 row affected (0.00 sec)
    
    -- 三个字符插入失败
    mysql> insert into t9 (id, name) values (1, 'abc');
    ERROR 1406 (22001): Data too long for column 'name' at row 1
    
  3. 插入中文字符。

    -- 一个字符插入成功
    mysql> insert into t9 (id, name) values (1, '中');
    Query OK, 1 row affected (0.00 sec)
    
    -- 两个字符插入成功
    mysql> insert into t9 (id, name) values (1, '中国');
    Query OK, 1 row affected (0.00 sec)
    
    -- 三个字符插入失败
    mysql> insert into t9 (id, name) values (1, '中国人');
    ERROR 1406 (22001): Data too long for column 'name' at row 1
    

总结:这一部分和 char(L) 在使用上没有区别。

字符长度与编码相关

这里建立一个共识:

  • 我们把一个字符串中有多少个字符称为“字符长度”。
  • 该字符串存储在计算机当中占据了多少个字节,称为“字节长度”。

MySQL 规定,varchar 类型的最大字节长度为 65535 字节,但是这 65535 字节中会有 1 ~ 3 个字节会被用于记录字符串的实际字节长度(具体会用到多少个字节,得看字符串的字节长度是多少)

总之,排除 3 个记录字节外,实际上能够用于存储字符串的有效字节长度为 65532。

另外,一个字符占据的字节数受到表结构的编码的影响,所以一个字符串的字符长度上限与编码强相关,例如:

  • utf8 编码中一个字符占 3 个字节,最大字符长度为 65532 / 3 = 21844
  • gbk 编码中一个字符占 2 个字节,最大字符长度为 65532 / 2 = 32766

接下来尝试对字符长度与编码的关系进行验证:

  • 创建 t_utf8 设置字符编码为 utf8,字符长度设置为 100000。
    当字符集为utf8并且预设字符长度超过 21845(65525 / 3)时,报错并提示最大可用字符长度为21845。

    mysql> create table if not exists t_utf ( name varchar(100000) ) charset=utf8;
    ERROR 1074 (42000): Column length too big for column 'name' (max = 21845); 
      use BLOB or TEXT instead
    

    当字符集为utf8并且预设字符长度等于 21845(65525 / 3)时,报错提示字节长度超过65535。

    mysql> create table if not exists t_utf ( name varchar(21845) ) charset=utf8;
    ERROR 1118 (42000): Row size too large. 
      The maximum row size for the used table type, not counting BLOBs, is 65535. 
      This includes storage overhead, check the manual. 
      You have to change some columns to TEXT or BLOBs
    

    回到开始提到的,“有3个字节用于记录字符串字节长度”。

    L 值为 21845 时,实际花费(65535 + 3)个字节超过规定的 65535。

    所以实际上,当字符集为utf8时,最大字符长度只能为21844。

    mysql> create table if not exists t_utf ( name varchar(21844) ) charset=utf8;
    Query OK, 0 rows affected (0.02 sec)
    
  • 创建 t_gbk 设置字符编码为 gbk,字符长度设置为 100000。

    当字符集为gbk并且预设字符长度超过 32767(65525 / 2)时,报错并提示最大可用字符长度为32767。

    mysql> create table if not exists t_gbk ( name varchar(100000) ) charset=gbk;
    ERROR 1074 (42000): Column length too big for column 'name' (max = 32767); 
      use BLOB or TEXT instead
    

    当字符集为gbk并且预设字符长度等于 32767(65525 / 2)时,报错提示字节长度超过65535。

    mysql> create table if not exists t_gbk ( name varchar(32767) ) charset=gbk;
    ERROR 1118 (42000): Row size too large. 
      The maximum row size for the used table type, not counting BLOBs, is 65535. 
      This includes storage overhead, check the manual. 
      You have to change some columns to TEXT or BLOBs
    

    当字符长度设置为32766,SQL 语句执行成功。

    mysql> create table if not exists t_gbk ( name varchar(32766) ) charset=gbk;
    Query OK, 0 rows affected (0.01 sec)
    

总结:varchar 类型的字符长度上限等于“(65535-3)/ 一个字符占据的字节数”,设置长度时只需要注意一下即可。

char 和 varchar 区别

char类型

  • 不管字符串实际的字符长度是多少,都会消耗固定字节长度的存储空间来存储字符串。
  • 好处是存储长度是固定值,存储时效率相较更高一点。
  • 坏处是可能会浪费大量存储空间。

varchar类型:

  • 先计算实际消耗的字节长度,然后给字符串分配合适的存储空间。
  • 好处是会节省存储空间。
  • 坏处是在插入和更新数据时可能涉及额外的存储计算开销。

char 和 varchar 的选择
  • 如果数据确定长度都一样,就使用定长(char),比如:身份证,手机号,md5。
  • 如果数据长度有变化,就使用变长(varchar),比如:名字,地址,但是要保证最长的能存的进去。
  • 定长的磁盘空间比较浪费,但是效率高。
  • 变长的磁盘空间比较节省,但是效率低。
  • 定长的意义是,直接开辟好对应的空间。
  • 变长的意义是,在不超过自定义范围的情况下,用多少,开辟多少。

日期和时间类型

这里先来建立一个共识:

  • “年月日”定义为“日期(date)”
  • “时分秒”定义为“时间(time)”

以上就是 MySQL 对于时间的划分,目的是能够针对性地处理日期和时间相关的数据。

日期相关类型

date

  • 大小:3 字节。
  • 用途:表示日期(年月日)。
  • 格式:'YYYY-MM-DD'(例如 '2025-01-10')。
  • 范围:从 '1000-01-01''9999-12-31'
  • 特点:适用于仅需要存储日期、不需要时间信息的场景,如生日、注册日期、评论日期等。

year

  • 大小:1 字节。
  • 用途:表示年份。
  • 格式:'YYYY'(例如 '2025')。
  • 范围:从 '1901''2155'
  • 特点:存储单独的年份,适合处理年份维度的数据,如财年、学年等。

时间相关类型

time

  • 大小:3 字节。
  • 用途:表示一天中的时间点或时间间隔。
  • 格式:'HH:MM:SS'(例如 '15:30:00')。
  • 范围:从 '-838:59:59''838:59:59'
  • 特点:可用于存储时间点,也可以表示时长,例如航班时长、工时记录等。

日期与时间的结合类型

datetime

  • 大小:8 字节。
  • 用途:表示日期和时间(精确到秒)。
  • 格式:'YYYY-MM-DD HH:MM:SS'(例如 '2025-01-10 15:30:00')。
  • 范围:从 '1000-01-01 00:00:00''9999-12-31 23:59:59'
  • 特点:与时区无关,适用于不需要与时区转换的时间记录。

timestamp

  • 大小:4 字节。
  • 用途:表示时间戳(日期和时间,带时区)。
  • 格式:与 DATETIME 相同,即 'YYYY-MM-DD HH:MM:SS'
  • 范围:从 '1970-01-01 00:00:01''2038-01-19 03:14:07'
  • 特点:
    • 与时区相关:存储时会转换为 UTC,查询时会根据会话的时区设置转换回本地时间。
    • 通常用于记录事件发生的具体时间点,如日志记录。
    • 自动更新。

案例

创建名为 t10 的表结构,SQL 语句如下:

create table if not exists t10 (
  t1 year,
  t2 date,
  t3 time,
  t4 datetime,
  t5 timestamp
);

查看表结构信息。

mysql> desc t10;
+-------+-----------+------+-----+-------------------+-----------------------------+
| Field | Type      | Null | Key | Default           | Extra                       |
+-------+-----------+------+-----+-------------------+-----------------------------+
| t1    | year(4)   | YES  |     | NULL              |                             |
| t2    | date      | YES  |     | NULL              |                             |
| t3    | time      | YES  |     | NULL              |                             |
| t4    | datetime  | YES  |     | NULL              |                             |
| t5    | timestamp | NO   |     | CURRENT_TIMESTAMP | on update CURRENT_TIMESTAMP |
+-------+-----------+------+-----+-------------------+-----------------------------+
5 rows in set (0.00 sec)

前四列指定插入数据。

mysql> insert into t10 (t1, t2, t3, t4) 
    -> values (2025, 2025-1-10, 00:00:01, 2025-1-10 00:00:01);

由于插入的数据不是字符串格式,插入失败。

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 ':00:01, 2025-1-10 00:00:01)' at line 1

将数据修改为字符串格式,插入成功。

mysql> insert into t10 (t1, t2, t3, t4)
    -> values ('2025', '2025-1-10', '00:00:01', '2025-1-10 00:00:01');
Query OK, 1 row affected (0.00 sec)

在使用上可以认为:日期、时间相关类型就是一个特定长度、特定格式的字符串而已。

执行查询SQL语句,查询表格内容发现,t5 字段明明没有手动插入,却已经被填入了一个数据。

这就是 timestamp 类型的特点:当该行记录被修改或者新增时,由 MySQL 自动填充。

mysql> select * from t10;
+------+------------+----------+---------------------+---------------------+
| t1   | t2         | t3       | t4                  | t5                  |
+------+------------+----------+---------------------+---------------------+
| 2025 | 2025-01-10 | 00:00:01 | 2025-01-10 00:00:01 | 2025-01-10 15:16:41 |
+------+------------+----------+---------------------+---------------------+
1 row in set (0.00 sec)

枚举类型 enum

语法

create table table_name (
  column_name enum('选项值1', '选项值2', '选项值3', ...)
);

要点说明

选项值只能是字符串。

创建表结构 t11,字段 s 的类型是 enum,枚举值不是字符串,表结构创建失败。

mysql> create table if not exists t11 ( 
    ->  s enum(1, 2, 3) 
    ->);
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 '1, 2, 3) )' at line 1

创建表结构 t11,字段 s 的类型是 enum,枚举值是字符串,表结构创建成功。

mysql> create table if not exists t11 (
    -> 	s enum('选项值1', '选项值2', '选项值3')
    -> );
Query OK, 0 rows affected (0.01 sec)

mysql> desc t11;
+-------+----------------------------------------------+------+-----+---------+-------+
| Field | Type                                         | Null | Key | Default | Extra |
+-------+----------------------------------------------+------+-----+---------+-------+
| s     | enum('选项值1','选项值2','选项值3')          | YES  |     | NULL    |       |
+-------+----------------------------------------------+------+-----+---------+-------+
1 row in set (0.00 sec)

不能插入非选项值

现在向 t11s 插入 '不是选项值'

insert into t11 (s) values ('不是选项值');

SQL语句执行失败。

ERROR 1265 (01000): Data truncated for column 's' at row 1

插入选项值或者选项值索引

这里解释一下什么是选项值索引。

在定义表结构时,MySQL 会将 enum 类型字段的选项值(枚举值)用一个类似于顺序表之类的结构存储起来。

然后按照定义时,从左到右的顺序依次分配一个索引值,索引值从1开始65535个。

插入选项值索引。

mysql> insert into t11 (s) values (0);	-- 插入 0 失败,因为从 1 开始
ERROR 1265 (01000): Data truncated for column 's' at row 1

mysql> insert into t11 (s) values (1);	-- 插入 1 成功
Query OK, 1 row affected (0.00 sec)

mysql> insert into t11 (s) values (2);	-- 插入 2 成功
Query OK, 1 row affected (0.00 sec)

mysql> insert into t11 (s) values (3);	-- 插入 3 成功
Query OK, 1 row affected (0.01 sec)

mysql> insert into t11 (s) values (4);	-- 插入 4 失败,因为没有第四个选项值
ERROR 1265 (01000): Data truncated for column 's' at row 1

mysql> select * from t11;
+------------+
| s          |
+------------+
| 选项值1    |
| 选项值2    |
| 选项值3    |
+------------+
6 rows in set (0.00 sec)

插入选项值本身。

mysql> insert into t11 (s) values ('选项值1');
Query OK, 1 row affected (0.00 sec)

mysql> insert into t11 (s) values ('选项值2');
Query OK, 1 row affected (0.01 sec)

mysql> insert into t11 (s) values ('选项值3');
Query OK, 1 row affected (0.01 sec)

mysql> select * from t11;
+------------+
| s          |
+------------+
| 选项值1    |
| 选项值2    |
| 选项值3    |
| 选项值1    |
| 选项值2    |
| 选项值3    |
+------------+
6 rows in set (0.00 sec)

对比看到:无论是插入选项值索引还是插入选项值本身,都是一致的效果。

实际上,在 MySQL 中,ENUM 类型字段虽然表面上存储的是字符串值,但其底层实际上存储的是对应字符串枚举值的索引值(以 1 为起始的整数索引)。在插入和查询时,MySQL 会自动在字符串值和索引值之间进行转换。

换言之,当你插入数据时,无论插入的是字符串还是索引值,MySQL 都选项值对应的索引值。

条件查询

(看懂这部分需要对 select 的条件查询有一定了解)

enum 类型可以直接使用 = 运算符进行条件查询。

mysql> select * from t11 where s = '选项值1';
+------------+
| s          |
+------------+
| 选项值1    |
| 选项值1    |
+------------+
2 rows in set (0.00 sec)

集合类型 set

语法

create table table_name (
  column_name set('选项值1', '选项值2', '选项值3', ...)
);

要点说明

选项值只能是字符串。

创建表 t12 字段 hobby 类型为 set,选项值不是字符串,表结构创建失败。

mysql> create table if not exists t12 ( hobby set(1, 2, 3, 4, 5) );
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 '1, 2, 3, 4, 5) )' at line 1

创建表 t12 字段 hobby 类型为 set,选项值是字符串,表结构创建成功。

mysql> create table if not exists t12 (
    -> 	hobby set('登山','游泳','篮球','武术')
    -> );
Query OK, 0 rows affected (0.01 sec)

mysql> desc t12;
+-------+------------------------------------------+------+-----+---------+-------+
| Field | Type                                     | Null | Key | Default | Extra |
+-------+------------------------------------------+------+-----+---------+-------+
| hobby | set('登山','游泳','篮球','武术')          | YES  |     | NULL    |       |
+-------+------------------------------------------+------+-----+---------+-------+

不能插入非选项值

t12 插入定义时不存在的 '羽毛球'

mysql> insert into t12 values ('羽毛球');

SQL语句执行失败。

ERROR 1265 (01000): Data truncated for column 'hobby' at row 1

可以插入多个选项值

set 的特点是相比 enum 可以插入多个选项值。

插入时,字符串格式:'选项值1,选项值2,...',选项值之间用 , 分割。

mysql> insert into t12 values('登山,武术');
Query OK, 1 row affected (0.00 sec)

mysql> select * from t12;
+---------------+
| hobby         |
+---------------+
| 登山,武术     |
+---------------+
1 row in set (0.00 sec)

使用索引值替换字符串插入

ENUM 类型不同,set 类型在 MySQL 中使用的是位图存储。对于 set 类型,每个可能的值都会分配一个唯一的二进制位,字段的存储值是所有选定值对应的二进制位的按位“或”操作结果。

t12 为例:

create table if not exists t12 (
	hobby set('登山','游泳','篮球','武术')
);

MySQL 会按照定义的顺序从左往右依次给给每个枚举值分配一个比特位:

  • '登山' -> 第 1 位(值:1,二进制:0001)
  • '游泳' -> 第 2 位(值:2,二进制:0010)
  • '篮球' -> 第 3 位(值:4,二进制:0100)
  • '武术' -> 第 4 位(值:8,二进制:1000)
插入值二进制表示十进制索引值
'登山'00011
'游泳'00102
'登山,游泳'00113
'篮球'01004
'登山,篮球'01015
'游泳,篮球'01106
'登山,游泳,篮球'01117
mysql> insert into t12 values(1);		-- 插入一个选项值
Query OK, 1 row affected (0.01 sec)

mysql> select * from t12;
+---------------+
| hobby         |
+---------------+
| 登山,武术     |
| 登山          | -- 新插入的
+---------------+
2 rows in set (0.00 sec)

mysql> insert into t12 values(7);	-- 插入三个选项值
Query OK, 1 row affected (0.00 sec)

mysql> select * from t12;
+----------------------+
| hobby                |
+----------------------+
| 登山,武术            |
| 登山                 |
| 登山,游泳,篮球       | -- 新插入的
+----------------------+
3 rows in set (0.00 sec)

find_in_set(‘选项值’, column) 查询

(看懂这部分需要对 select 的条件查询有一定了解)

这是 t12 表目前存储的内容。

mysql> select * from t12;
+----------------------+
| hobby                |
+----------------------+
| 登山,武术            |
| 登山                 |
| 登山,游泳,篮球       |
+----------------------+
3 rows in set (0.00 sec)

需求:想要查询所有包含【登山】爱好的记录(行)。

但是发现使用 = 运算符进行条件查询【选项值本身】就只能找到【爱好仅为登山】的记录(行)。

mysql> select * from t12 where hobby = '登山';
+--------+
| hobby  |
+--------+
| 登山   |
+--------+
1 row in set (0.00 sec)

这时候就可以使用 find_in_set 内置函数进行查询。

find_in_set(substring, string)的作用。

  • 如果 substringstring 中,则返回下标。
  • 如果不在,返回0。
  • string 用逗号分隔的字符串。

SQL 语句修改如下:

mysql> select * from t12 where find_in_set('登山', hobby);
+----------------------+
| hobby                |
+----------------------+
| 登山,武术            |
| 登山                 |
| 登山,游泳,篮球       |
+----------------------+
3 rows in set (0.00 sec)

需求:查询爱好包含【登山】和【篮球】的记录(行)。

SQL 语句如下:

mysql> select * from t12 where find_in_set('登山', hobby) and find_in_set('篮球', hobby);
+----------------------+
| hobby                |
+----------------------+
| 登山,游泳,篮球       |
+----------------------+
1 row in set (0.00 sec)

标签:insert,into,MySQL,数据类型,第五章,sec,mysql,values,row
From: https://blog.csdn.net/ljh1257/article/details/145066867

相关文章

  • MySQL索引原理及慢查询优化13
    背景MySQL凭借着出色的性能、低廉的成本、丰富的资源,已经成为绝大多数互联网公司的首选关系型数据库。虽然性能出色,但所谓“好马配好鞍”,如何能够更好的使用它,已经成为开发工程师的必修课,我们经常会从职位描述上看到诸如“精通MySQL”、“SQL语句优化”、“了解数据库原理”等......
  • MySQL 学习指南与资料分享
    MySQL学习资料https://pan.quark.cn/s/4102ccd1336dMySQL学习资料https://pan.quark.cn/s/4102ccd1336dMySQL学习资料https://pan.quark.cn/s/4102ccd1336d在如今数据驱动发展的大趋势下,MySQL作为开源关系型数据库管理系统的佼佼者,广泛应用于各个领域,从个人博客搭建到......
  • 【MySQL8】压缩包方式卸载
    版本:v8.0.26今天mysql启动的时候报错,跟着网上的教程排查了几次,最后决定卸了重装,反正是学习环境备份数据(可选)如果是生产环境/开发环境,第一步是备份数据,我不备份你可以选择更简单的方式:复制data文件夹,但是版本兼容性很差,会出现各种毛病,导致数据无法展示也无法恢复,不推荐我......
  • 【CentOS7】安装MySQL
    检查是否安装过MySQL检查是否用yum安装过mysqlyumlistinstalled|grep-imysql检查是否用过rpm安装过mysqlrpm-qa|grep-imysql检查有没有mysql服务开启systemctlstatusmysqld.service卸载MySQL(可选)1.关闭mysql服务systemctlstopmysqld.service2.......
  • MySQL 安装部署
    概述本文主要介绍如何在Linux中以RPM包的方式安装MySQL并进行相关的初始化配置,文中方案均已实践验证。操作系统CentOS7.6数据库版本MySQL8.4.3LTS[!NOTE]说明本文主要介绍RPM包的安装方式,其他安装方法可查阅官网:MySQL::MySQL8.4ReferenceManua......
  • (免费送源码)计算机毕业设计原创定制:Java+ssm+MySQL SSM 超市外卖系统小程序
     摘 要随着我国经济迅速发展,人们对手机的需求越来越大,各种手机软件也都在被广泛应用,但是对于手机进行数据信息管理,对于手机的各种软件也是备受用户的喜爱,超市外卖系统小程序被用户普遍使用,为方便用户能够可以随时进行超市外卖系统小程序的数据信息管理,特开发了基于微信小程......
  • (免费送源码)计算机毕业设计原创定制:Java+ssm+MySQL SSM母婴用品交流系统
     摘  要随着社会的发展,社会的各行各业都在利用信息化时代的优势。计算机的优势和普及使得各种信息系统的开发成为必需。母婴用品交流系统,主要的模块包括查看首页、轮播图管理、通知公告管理、资源管理(母婴资讯、资讯分类)、交流管理(交流论坛、论坛分类)、用户管理(管理员、普......
  • 05、Docker学习,常用安装:Mysql、Redis、Nginx、Nacos
    Docker学习,常用安装:Mysql、Redis、Nginx、Nacos一、Docker安装Mysql1、dockersearchmysql ##查找mysql版本都有哪些2、dockerpullmysql:5.6 ##下载5.6版本的mysql镜像3、dockerrun-p13306:3306--namemysql ##运行镜像生成容器-v/opt......
  • 第五章 保护模式进阶,向内核迈进
    第五章保护模式进阶,向内核迈进本文是对《操作系统真象还原》第五章学习的笔记,欢迎大家一起交流。a获取物理内存知识部分为了在后期做好内存管理工作,咱们先得知道自己有多少物理内存才行。所以现在的工作是为了获取物理内存,一共介绍三种方法,都是利用的BIOS0x15中断,三种方......
  • Ubuntu安装MySQL-5.7.44
    一、下载MySQL::DownloadMySQLCommunityServer(ArchivedVersions) MySQL::MySQLDownloads 下滑 二、卸载ubuntu18.04彻底卸载mysql5.7,图文详解_ubuntu卸载mysql-CSDN博客1、查看MySQL的依赖项dpkg--list|grepmysql2、删除所有MySQL工作......