【MySQL数据类型】

目录:

  • 前言
  • 数据类型分类
  • 整数类型
    • tinyint
    • bit
  • 小数类型
    • float
    • decimal
  • 字符串类型
    • char
    • varchar
    • 日期和时间
    • enum & set
      • 在集合中查找
      • find_in_set

前言

剑指offer:一年又4天

数据类型分类

在这里插入图片描述


整数类型

这里是引用

tinyint

整数类型都分为有符号和无符号两种,默认是有符号的,在类型后加上unsigned为无符号类型;
tiinyint大小为一个字节,有符号取值范围为-128 ~ 127,无符号取值范围为0 ~ 255;

mysql> create table tb1(num tinyint);       --- num列数据为tinyint类型
Query OK, 0 rows affected (0.03 sec)mysql> show create table tb1\G
*************************** 1. row ***************************Table: tb1
Create Table: CREATE TABLE `tb1` (`num` tinyint(4) DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8
1 row in set (0.00 sec)mysql> insert into tb1(num) values(-128);        --- 左边界测试
Query OK, 1 row affected (0.01 sec)mysql> insert into tb1(num) values(127);         --- 右边界测试
Query OK, 1 row affected (0.00 sec)mysql> insert into tb1(num) values(0);      	 --- 中间值
Query OK, 1 row affected (0.01 sec)mysql> insert into tb1(num) values(-129);        --- 越界测试
ERROR 1264 (22003): Out of range value for column 'num' at row 1
mysql> insert into tb1(num) values(128);
ERROR 1264 (22003): Out of range value for column 'num' at row 1
mysql> insert into tb1(num) values(999);
ERROR 1264 (22003): Out of range value for column 'num' at row 1mysql> select * from tb1;                     --- 越界值不会插入,也就是说已经插入的值都是合法的
+------+
| num  |
+------+
| -128 |
|  127 |
|    0 |
+------+
3 rows in set (0.00 sec)ysql> create table tb2(num tinyint unsigned);            --- 无符号tinyint测试
Query OK, 0 rows affected (0.04 sec)mysql> show create table tb2\G
*************************** 1. row ***************************Table: tb2
Create Table: CREATE TABLE `tb2` (`num` tinyint(3) unsigned DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8
1 row in set (0.00 sec)mysql> insert into tb2(num) values(0);            --- 左边界测试
Query OK, 1 row affected (0.00 sec)mysql> insert into tb2(num) values(255);            --- 右边界测试
Query OK, 1 row affected (0.01 sec)mysql> insert into tb2(num) values(99);            --- 中间值测试
Query OK, 1 row affected (0.01 sec)mysql> insert into tb2(num) values(-1);            ---  越界测试
ERROR 1264 (22003): Out of range value for column 'num' at row 1
mysql> insert into tb2(num) values(-128);
ERROR 1264 (22003): Out of range value for column 'num' at row 1
mysql> insert into tb2 values(256);
ERROR 1264 (22003): Out of range value for column 'num' at row 1mysql> select * from tb2;                    --- 越界值不会插入
+------+
| num  |
+------+
|    0 |
|  255 |
|   99 |
+------+
3 rows in set (0.00 sec)

bit

语法:

bit[(M)] : 位字段类型。M表示每个值的位数,范围从164。如果M被忽略,默认为1

按比特位来分配,最多可分配64个比特位,默认为1bit;

示例:

mysql> alter table tb2 add num2 bit(1);       --- 添加一列num2,类型为bit
Query OK, 0 rows affected (0.08 sec)
Records: 0  Duplicates: 0  Warnings: 0mysql> show create table tb2\G
*************************** 1. row ***************************Table: tb2
Create Table: CREATE TABLE `tb2` (`num` tinyint(3) unsigned DEFAULT NULL,`num2` bit(1) DEFAULT NULL                     --- 添加成功
) ENGINE=InnoDB DEFAULT CHARSET=utf8
1 row in set (0.00 sec)mysql> insert into tb2(num, num2) values(1, 0); 
Query OK, 1 row affected (0.01 sec)mysql> insert into tb2(num, num2) values(1, 1);
Query OK, 1 row affected (0.00 sec)mysql> insert into tb2(num, num2) values(1, 2);     --- 一个bit位只能写入0,1
ERROR 1406 (22001): Data too long for column 'num2' at row 1
mysql> insert into tb2(num, num2) values(1, 3);
ERROR 1406 (22001): Data too long for column 'num2' at row 1
mysql> insert into tb2(num, num2) values(1, -1);
ERROR 1406 (22001): Data too long for column 'num2' at row 1
mysql> select *from tb2;
+------+------+
| num  | num2 |
+------+------+
|    0 | NULL |       --- 没有写入的为空
|  255 | NULL |
|   99 | NULL |
|    1 |      |       --- 我们明明写入了为什么看不到?
|    1 |     |
+------+------+
5 rows in set (0.00 sec)

看不到的原因:bit类型的数据会以它的ASCII码来显示,这里0和1的ASCII码对应的是不可显示字符;
验证:

mysql> alter table tb2 modify num2 bit(10);        ---   修改bit位个数,增加到10
Query OK, 5 rows affected (0.10 sec)
Records: 5  Duplicates: 0  Warnings: 0mysql> show create table tb2\G
*************************** 1. row ***************************Table: tb2
Create Table: CREATE TABLE `tb2` (`num` tinyint(3) unsigned DEFAULT NULL,`num2` bit(10) DEFAULT NULL                     --- 修改成功
) ENGINE=InnoDB DEFAULT CHARSET=utf8
1 row in set (0.00 sec)mysql> insert into tb2 values(2, 97);             ---  插入数字97
Query OK, 1 row affected (0.01 sec)mysql> insert into tb2 values(2, 'a');            --- 插入字符 'a'
Query OK, 1 row affected (0.01 sec)mysql> select * from tb2;
+------+------+
| num  | num2 |
+------+------+
|    0 | NULL |
|  255 | NULL |
|   99 | NULL |
|    1 |      |
|    1 |     |
|    2 |  a   |           --- a的ASCII码就是97
|    2 |  a   |
+------+------+
7 rows in set (0.00 sec)mysql> alter table tb2 modify num2 int;         --- 修改num2列的类型,由bit(10)改为int
Query OK, 7 rows affected (0.10 sec)
Records: 7  Duplicates: 0  Warnings: 0mysql> select * from tb2;                     ---  再次查看
+------+------+
| num  | num2 |
+------+------+
|    0 | NULL |
|  255 | NULL |
|   99 | NULL |
|    1 |    0 |                             ---  整形数据
|    1 |    1 |
|    2 |   97 |
|    2 |   97 |
+------+------+
7 rows in set (0.00 sec)

小数类型

float

语法:

float[(m, d)] [unsigned] : M指定显示长度,d指定小数位数,占用空间4个字节

示例:

mysql> create table tb3(-> name varchar(32),-> score float(4,2)                --- float(长度为4,小数位占2位,范围:-99.99 ~ 99.99)-> );
Query OK, 0 rows affected (0.03 sec)mysql> show create table tb3\G
*************************** 1. row ***************************Table: tb3
Create Table: CREATE TABLE `tb3` (`name` varchar(32) DEFAULT NULL,`score` float(4,2) DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8
1 row in set (0.00 sec)mysql> insert into tb3 values('陈平安', -99.99);     --- 左极限测试
Query OK, 1 row affected (0.01 sec)mysql> insert into tb3 values('宁姚', 99.99);     	--- 右极限测试
Query OK, 1 row affected (0.00 sec)mysql> insert into tb3 values('小米粒', 0);     		--- 中间值测试
Query OK, 1 row affected (0.00 sec)mysql> insert into tb3 values('陈灵均', 100.00);  	---  越界测试
ERROR 1264 (22003): Out of range value for column 'score' at row 1mysql> insert into tb3 values('周肥', -100.00);
ERROR 1264 (22003): Out of range value for column 'score' at row 1mysql> select * from tb3; 
+-----------+--------+
| name      | score  |
+-----------+--------+
| 陈平安    | -99.99 |
| 宁姚      |  99.99 |
| 小米粒    |   0.00 |
+-----------+--------+
3 rows in set (0.00 sec)

扩展1:

mysql> insert into tb3 values('陈如初', 99.994);
Query OK, 1 row affected (0.00 sec)mysql> insert into tb3 values('裴钱', 99.992);
Query OK, 1 row affected (0.01 sec)mysql> insert into tb3 values('老厨子', 99.787998);
Query OK, 1 row affected (0.00 sec)mysql> insert into tb3 values('郑大风', 99.995);         
ERROR 1264 (22003): Out of range value for column 'score' at row 1
mysql> select * from tb3;
+-----------+--------+
| name      | score  |
+-----------+--------+
| 陈平安    | -99.99 |
| 宁姚      |  99.99 |
| 小米粒    |   0.00 |    --- 0
| 陈如初    |  99.99 |    --- 99.994
| 裴钱      |  99.99 |    --- 99.992
| 老厨子    |  99.79 |    --- 99.787998
+-----------+--------+   ---  99.995  插入失败
6 rows in set (0.00 sec)

由此可见,float的位数约束虽然严格,但并不如整数那样一点也不能越界,当小数位不足时会自动补0,小数位过多时会进行四舍五入,
99.995四舍五入变为100.00 ,不符合float(4, 2) 四位的约束,因此插入失败,其他的99.994, 99.992等会被舍去,不会越界。


扩展2:

mysql> create table tb4(-> name varchar(32),-> score float(4, 2) unsigned);           --- 测试无符号float取值范围
Query OK, 0 rows affected (0.05 sec)mysql> show create table tb4\G
*************************** 1. row ***************************Table: tb4
Create Table: CREATE TABLE `tb4` (`name` varchar(32) DEFAULT NULL,`score` float(4,2) unsigned DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8
1 row in set (0.00 sec)mysql> insert into tb4 values ('陈平安', -99.99);            --- 越界
ERROR 1264 (22003): Out of range value for column 'score' at row 1mysql> insert into tb4 values ('宁姚', 99.99);              
Query OK, 1 row affected (0.00 sec)mysql> insert into tb4 values ('小米粒', 0);
Query OK, 1 row affected (0.00 sec)mysql> insert into tb4 values ('陈灵均', 100);              --- 越界
ERROR 1264 (22003): Out of range value for column 'score' at row 1mysql> insert into tb4 values ('周肥', -1);               --- 越界
ERROR 1264 (22003): Out of range value for column 'score' at row 1mysql> select * from tb4;
+-----------+-------+
| name      | score |
+-----------+-------+
| 宁姚      | 99.99 |
| 小米粒    |  0.00 |
+-----------+-------+
2 rows in set (0.00 sec)

结论:无符号float并不像无符号int那样取值范围右移,而是直接在原范围上删去负数部分。


decimal

语法:

decimal (m, d) [unsigned] : 定点数m指定长度,d表示小数点的位数

decimal(5,2) 表示的范围是 -999.99 ~ 999.99
decimal(5,2) unsigned 表示的范围 0 ~ 999.99
decimal和float很像,但是有区别:
float和decimal表示的精度不一样

mysql> create table if not exists tb5(-> num1 float(10, 8),                   --- -99.**** ~ 99.****-> num2 decimal(10, 8)-> );
Query OK, 0 rows affected (0.02 sec)mysql> show create table tb5\G
*************************** 1. row ***************************Table: tb5
Create Table: CREATE TABLE `tb5` (`num1` float(10,8) DEFAULT NULL,`num2` decimal(10,8) DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8
1 row in set (0.00 sec)mysql> insert into tb5 values(10, 10);                           --- 测试1
Query OK, 1 row affected (0.01 sec)mysql> insert into tb5 values(10.1234, 10.1234);                  --- 测试2
Query OK, 1 row affected (0.00 sec)mysql> insert into tb5 values(10.12345678, 10.12345678);          --- 测试3
Query OK, 1 row affected (0.01 sec)mysql> insert into tb5 values(10.123456789, 10.123456789);        --- 测试4
Query OK, 1 row affected, 1 warning (0.01 sec)mysql> insert into tb5 values(100, 100);                       --- 越界测试
ERROR 1264 (22003): Out of range value for column 'num1' at row 1mysql> select * from tb5;
+-------------+-------------+
| num1        | num2        |
+-------------+-------------+
| 10.00000000 | 10.00000000 |    	--- 10
| 10.12339973 | 10.12340000 |    	--- 10.1234
| 10.12345695 | 10.12345678 |    	--- 10.12345678
| 10.12345695 | 10.12345679 |    	--- 10.123456789
+-------------+-------------+
4 rows in set (0.00 sec)

我们会发现,decimal类型的数据完全且正确地保存了起来,而float类型的数据发生了精度损失。

说明:
float表示的精度大约是7位。
decimal整数最大位数m为65。支持小数最大位数d是30。如果d被省略,默认为0.如果m被省略, 默认是10。
建议:
如果希望小数的精度高,推荐使用decimal。


字符串类型

char

语法:

char(L): 固定长度字符串,L是可以存储的长度,单位为字符,最大长度值可以为255,默认为1

示例:

mysql> create table tb6 (name char(3));            --- name列长度为三个字符
Query OK, 0 rows affected (0.03 sec)mysql> show create table tb6\G
*************************** 1. row ***************************Table: tb6
Create Table: CREATE TABLE `tb6` (`name` char(3) DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8
1 row in set (0.00 sec)mysql> insert into tb6(name) values('a');        --- 一个字符
Query OK, 1 row affected (0.01 sec)mysql> insert into tb6(name) values('b');        --- 一个字符
Query OK, 1 row affected (0.01 sec)mysql> insert into tb6(name) values('ab');        --- 两个字符
Query OK, 1 row affected (0.01 sec)mysql> insert into tb6(name) values('abc');       --- 三个字符
Query OK, 1 row affected (0.01 sec)mysql> insert into tb6(name) values('abcd');      --- 四个字符,越界
ERROR 1406 (22001): Data too long for column 'name' at row 1mysql> insert into tb6(name) values('abcde');        --- 五个字符,越界
ERROR 1406 (22001): Data too long for column 'name' at row 1mysql> insert into tb6(name) values('中');        --- 一个字符
Query OK, 1 row affected (0.01 sec)mysql> insert into tb6(name) values('中国');        --- 两个字符
Query OK, 1 row affected (0.01 sec)mysql> insert into tb6(name) values('中国人');       --- 三个字符
Query OK, 1 row affected (0.01 sec)mysql> insert into tb6(name) values('中国人加');      --- 四个字符,越界
ERROR 1406 (22001): Data too long for column 'name' at row 1
mysql> insert into tb6(name) values('中国人加油');      --- 五个字符,越界
ERROR 1406 (22001): Data too long for column 'name' at row 1
mysql> select * from tb6;
+-----------+
| name      |
+-----------+
| a         |
| b         |
| ab        |
| abc       |
||
| 中国      |
| 中国人    |
+-----------+
7 rows in set (0.00 sec)mysql> alter table tb6 modify name char(255);       --- 边界测试
Query OK, 7 rows affected (0.29 sec)
Records: 7  Duplicates: 0  Warnings: 0mysql> alter table tb6 modify name char(256);      ---  越界测试
ERROR 1074 (42000): Column length too big for column 'name' (max = 255); use BLOB or TEXT instead

结论:char的单位是字符,不伦是一个英文字母还是一个汉字等都算是一个字符(注意:是一个字符而不是一个字节)。


varchar

语法:

varchar(L): 可变长度字符串,L表示字符长度,最大长度65535个字节

示例:

mysql> create table tb7(name varchar(7));
Query OK, 0 rows affected (0.04 sec)mysql> show create table tb7\G
*************************** 1. row ***************************Table: tb7
Create Table: CREATE TABLE `tb7` (`name` varchar(7) DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8
1 row in set (0.00 sec)mysql> insert into tb7 values('aaa');
Query OK, 1 row affected (0.01 sec)mysql> insert into tb7 values('中国人,加油!');
Query OK, 1 row affected (0.01 sec)mysql> select * from tb7;
+-------------------+
| name              |
+-------------------+
| aaa               |
| 中国人,加油!      |
+-------------------+
2 rows in set (0.00 sec)

说明:
关于varchar(len),len到底是多大,这个len值,和表的编码密切相关:
varchar长度可以指定为0到65535之间的值,但是有1 - 3 个字节用于记录数据大小,所以说有效字节数是65532。
当我们的表的编码是utf8时,varchar(n)的参数n最大值是65532/3=21844[因为utf中,一个字符占用3个字节],
如果编码是gbk,varchar(n)的参数n最大是65532/2=32766(因为gbk中,一个字符占用2字节)。

mysql> alter table tb7 modify name varchar(65535);          --- 注意:是65535个字节,不是字符
ERROR 1074 (42000): Column length too big for column 'name' (max = 21845); use BLOB or TEXT insteadmysql> select 21845 * 3;  ---  显然,tb7表采用的是utf8编码
+-----------+
| 21845 * 3 |
+-----------+
|    65535  |
+-----------+
1 row in set (0.00 sec)mysql> alter table tb7 modify name varchar(21845);   --- 由于需要保留1-3个字节用来记录字符串长度,因此它上面所说的21845也会越界
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 BLOBsmysql> alter table tb7 modify name varchar(21844);   --- 留出长度位(减一,留了三位)
Query OK, 2 rows affected (0.07 sec)
Records: 2  Duplicates: 0  Warnings: 0

这里是引用

如何选择定长或变长字符串?

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

日期和时间

常用的日期有如下三个:

  • date :日期 ‘yyyy-mm-dd’ ,占用三字节。
  • datetime 时间日期格式 ‘yyyy-mm-dd HH:ii:ss’ 表示范围从 1000 到 9999 ,占用八字节。
  • timestamp :时间戳,从1970年开始的 yyyy-mm-dd HH:ii:ss 格式和 datetime 完全一致,占用四字节。
mysql> create table if not exists tb8( -> date date,-> time datetime,-> modified timestamp-> );
Query OK, 0 rows affected (0.03 sec)mysql> show create table tb8\G
*************************** 1. row ***************************Table: tb8
Create Table: CREATE TABLE `tb8` (`date` date DEFAULT NULL,`time` datetime DEFAULT NULL,`modified` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP
) ENGINE=InnoDB DEFAULT CHARSET=utf8
1 row in set (0.00 sec)mysql> insert into tb8(date, time) values('2003-03-13', '2003-03-13 14:02:18');  --- 写入了date列和time列
Query OK, 1 row affected (0.01 sec)mysql> select * from tb8;
+------------+---------------------+---------------------+
| date       | time                | modified            |    --- modified列自动写入当前时间
+------------+---------------------+---------------------+
| 2003-03-13 | 2003-03-13 14:02:18 | 2023-11-18 14:04:10 | 
+------------+---------------------+---------------------+
1 row in set (0.00 sec)mysql> update tb8 set time = '1970-01-01 0:0:0';            --- 修改timelie数据
Query OK, 1 row affected (0.01 sec)
Rows matched: 1  Changed: 1  Warnings: 0mysql> select * from tb8;
+------------+---------------------+---------------------+
| date       | time                | modified            |     ---  modified列自动修改为当前时间
+------------+---------------------+---------------------+ 
| 2003-03-13 | 1970-01-01 00:00:00 | 2023-11-18 14:05:38 |
+------------+---------------------+---------------------+
1 row in set (0.00 sec)
  • date类型可以用于身份证出生日期的记录;
  • datetime在需要记录更详细的信息时使用;
  • timestamp比如如今在网络上发表评论,就会自动带上发表时间。

enum & set

语法:

enum: 枚举,“单选”类型;

enum('选项1','选项2','选项3',...);

该设定只是提供了若干个选项的值,最终一个单元格中,实际只存储了其中一个值;而且出于效率考虑,这些值实际存储的是“数字”,因为这些选项的每个选项值依次对应如下数字:1,2,3,…最多65535个;
当我们添加枚举值时,也可以添加对应的数字编号。

set:集合,“多选”类型;

set('选项值1','选项值2','选项值3', ...);

该设定只是提供了若干个选项的值,最终一个单元格中,设计可存储了其中任意多个值;而且出于效率考虑,这些值实际存储的是“数字”,因为这些选项的每个选项值依次对应如下数字:1,2,4,8,16,32,… 最多64个。

mysql> create table tb9(-> name varchar(32),-> gander enum('男', '女', '保密'),-> hobby set('代码', '登山', '跑步', '跳绳', '单车')-> );
Query OK, 0 rows affected (0.03 sec)mysql> show create table tb9\G
*************************** 1. row ***************************Table: tb9
Create Table: CREATE TABLE `tb9` (`name` varchar(32) DEFAULT NULL,`gander` enum('男','女','保密') DEFAULT NULL,`hobby` set('代码','登山','跑步','跳绳','单车') DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8
1 row in set (0.00 sec)mysql> insert into tb9 values('张三', '男', '代码');
Query OK, 1 row affected (0.01 sec)mysql> insert into tb9 values('李四', '女', '登山');
Query OK, 1 row affected (0.01 sec)mysql> insert into tb9 values('王五', '男', '代码,登山');  --- set类型可以一次选多个,在引号内使用逗号分割
Query OK, 1 row affected (0.01 sec)mysql> insert into tb9 values('赵六', '未知', '代码,登山'); --- gander列没有‘未知’这个选项值
ERROR 1265 (01000): Data truncated for column 'gander' at row 1mysql> insert into tb9 values('赵六', '男,保密', '代码,登山'); --- gander列为enum类型,一次只能选一个
ERROR 1265 (01000): Data truncated for column 'gander' at row 1
mysql> select * from tb9;
+--------+--------+---------------+
| name   | gander | hobby         |
+--------+--------+---------------+
| 张三   || 代码          |
| 李四   || 登山          |
| 王五   || 代码,登山     |
+--------+--------+---------------+
3 rows in set (0.00 sec)
mysql> insert into tb9 values('赵六', 1, 1);  --- enum可以使用下标进行选择(1,2,3...),set可以使用位图进行选择(1,2,4,8...)
Query OK, 1 row affected (0.01 sec)mysql> select * from tb9;
+--------+--------+---------------+
| name   | gander | hobby         |
+--------+--------+---------------+
| 张三   || 代码          |
| 李四   || 登山          |
| 王五   || 代码,登山     |
| 赵六   || 代码          | 
+--------+--------+---------------+
4 rows in set (0.00 sec)mysql> show create table tb9\G
*************************** 1. row ***************************Table: tb9
Create Table: CREATE TABLE `tb9` (`name` varchar(32) DEFAULT NULL,`gander` enum('男','女','保密') DEFAULT NULL,`hobby` set('代码','登山','跑步','跳绳','单车') DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8
1 row in set (0.00 sec)mysql> insert into tb9 values('孙七', 2, 2);
Query OK, 1 row affected (0.01 sec)mysql> insert into tb9 values('周八', 3, 3);   --- hobby列的3为 1 + 2,既代码和登山
Query OK, 1 row affected (0.01 sec)mysql> insert into tb9 values('吴九', 4, 4);    --- gander列只有3个选项
ERROR 1265 (01000): Data truncated for column 'gander' at row 1
mysql> insert into tb9 values('吴九', 1, 4);
Query OK, 1 row affected (0.01 sec)mysql> insert into tb9 values('郑十', 1, 31);   --- 31 : 1+2+4+8+16
Query OK, 1 row affected (0.00 sec)mysql> select * from tb9;
+--------+--------+------------------------------------+
| name   | gander | hobby                              |
+--------+--------+------------------------------------+
| 张三   || 代码                               |
| 李四   || 登山                               |
| 王五   || 代码,登山                          |
| 赵六   || 代码                               |
| 孙七   || 登山                               |
| 周八   | 保密   | 代码,登山                          |        --- 3
| 吴九   || 跑步                               |       --- 4
| 郑十   || 代码,登山,跑步,跳绳,单车           |          --- 31
+--------+--------+------------------------------------+
8 rows in set (0.00 sec)mysql> show create table tb9\G
*************************** 1. row ***************************Table: tb9
Create Table: CREATE TABLE `tb9` (`name` varchar(32) DEFAULT NULL,`gander` enum('男','女','保密') DEFAULT NULL,`hobby` set('代码','登山','跑步','跳绳','单车') DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8
1 row in set (0.00 sec)

在集合中查找

mysql> select * from tb9 where gander='男';           --- 使用选项
+--------+--------+------------------------------------+
| name   | gander | hobby                              |
+--------+--------+------------------------------------+
| 张三   || 代码                               |
| 王五   || 代码,登山                          |
| 赵六   || 代码                               |
| 吴九   || 跑步                               |
| 郑十   || 代码,登山,跑步,跳绳,单车           |
+--------+--------+------------------------------------+
5 rows in set (0.00 sec)mysql> select * from tb9 where gander=1;          --- 使用下标
+--------+--------+------------------------------------+
| name   | gander | hobby                              |
+--------+--------+------------------------------------+
| 张三   || 代码                               |
| 王五   || 代码,登山                          |
| 赵六   || 代码                               |
| 吴九   || 跑步                               |
| 郑十   || 代码,登山,跑步,跳绳,单车           |
+--------+--------+------------------------------------+
5 rows in set (0.00 sec)mysql> select * from tb9 where hobby='登山';           --- 使用选项
+--------+--------+--------+
| name   | gander | hobby  |
+--------+--------+--------+
| 李四   || 登山   |
| 孙七   || 登山   |
+--------+--------+--------+
2 rows in set (0.00 sec)mysql> select * from tb9 where hobby=2;          --- 使用位图数值
+--------+--------+--------+
| name   | gander | hobby  |
+--------+--------+--------+
| 李四   || 登山   |
| 孙七   || 登山   |
+--------+--------+--------+
2 rows in set (0.00 sec)

有一个问题:使用 = 只能查找完全匹配的,就是爱好只有登山的,但是如果我们想要查找爱好包含登山该如何查找呢?
解决方案:MySQL内置函数:find_in_set

find_in_set

语法:

find_in_set(sub,str_list) :如果 sub 在 str_list 中,则返回下标;如果不在,返回0;
str_list 用逗号分隔的字符串。

示例:

mysql> select find_in_set('a', 'a,b,c');
+---------------------------+
| find_in_set('a', 'a,b,c') |
+---------------------------+
|                         1 |
+---------------------------+
1 row in set (0.00 sec)mysql> select find_in_set('b', 'a,b,c');
+---------------------------+
| find_in_set('b', 'a,b,c') |
+---------------------------+
|                         2 |
+---------------------------+
1 row in set (0.00 sec)mysql> select find_in_set('a,b', 'a,b,c');     --- 该函数一次只能查找一个选项,'a,b'被当做一个整体
+-----------------------------+
| find_in_set('a,b', 'a,b,c') |
+-----------------------------+
|                           0 |                 --- 0,没有找到
+-----------------------------+
1 row in set (0.00 sec)
mysql> select * from tb9 where find_in_set('登山', hobby);     --- 查找hobby包含登山的所有人
+--------+--------+------------------------------------+
| name   | gander | hobby                              |
+--------+--------+------------------------------------+
| 李四   || 登山                               |
| 王五   || 代码,登山                          |
| 孙七   || 登山                               |
| 周八   | 保密   | 代码,登山                          |
| 郑十   || 代码,登山,跑步,跳绳,单车           |
+--------+--------+------------------------------------+
5 rows in set (0.00 sec)mysql> select * from tb9 where find_in_set('代码,登山', hobby);  --- 如果要查找爱好包含代码和登山的所有人呢?
Empty set (0.00 sec)mysql> select * from tb9 where find_in_set('代码', hobby) and find_in_set('登山', hobby);  --- 查找两次,and表示逻辑与
+--------+--------+------------------------------------+
| name   | gander | hobby                              |
+--------+--------+------------------------------------+
| 王五   || 代码,登山                          |
| 周八   | 保密   | 代码,登山                          |
| 郑十   || 代码,登山,跑步,跳绳,单车           |
+--------+--------+------------------------------------+
3 rows in set (0.00 sec)



本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/203583.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Linux重要基本命令

重要基本命令 1.ls命令 语法: ls [选项][目录或文件] 功能:对于目录,该命令列出该目录下的所有子目录与文件。对于文件,将列出文件名以及其他信息。 常见的选项包括: -l:以长格式显示文件信息&#xf…

git 使用记录

远程仓库为空初始化 初始化本地仓库 git init 在本地仓库书写代码(这里可以编辑一个文本文件做测试,如hello.txt) 5)执行:git add 要让git管理的文件(git add hello.txt)>执行完此操作将我…

手持机|三防智能手机_4寸/5寸/6寸安卓系统三防手机PDA手持终端方案

随着科技的不断发展,三防手持机作为一种多功能设备,正逐渐在各行业得到广泛应用。这款手持机采用高性能处理器,支持高精度北斗定位和工业本安防爆功能,并具备IP67级防水防尘性能和1.5米防跌落能力。因此,它在仓储管理、…

【Docker】从零开始:17.Dockerfile基本概念

【Docker】从零开始:17.Dockerfile 概述1.什么是Dockerfile2.Dockerfile构建三大步骤3.Docker执行Dockerfile流程 一张图理解Dockerfile常用保留指令~FROM~~MAINTAINER~~RUN~两种格式 ~EXPOSE~~WORKDIR~~USER~~ENV~~ADD~~COPY~两种格式 ~VOLUME~~CMD~两种格式注意 ~…

Mac端 DevEco Preview 窗口无法展示,提示文件中的node.dir错误

语雀知识库地址:语雀HarmonyOS知识库 飞书知识库地址:飞书HarmonyOS知识库 DevEco版本:Build Version: 3.1.0.501, built on June 20, 2023 环境信息 问题描述 打开 Preview 标签窗口后,提示Preview failed。 Run窗口提示如下 F…

Stable Diffusion AI绘画系列【18】:东方巨龙,威武霸气

《博主简介》 小伙伴们好,我是阿旭。专注于人工智能、AIGC、python、计算机视觉相关分享研究。 ✌更多学习资源,可关注公-仲-hao:【阿旭算法与机器学习】,共同学习交流~ 👍感谢小伙伴们点赞、关注! 《------往期经典推…

PyTorch 基础篇(2):线性回归(Linear Regression)

# 包import torchimport torch.nn as nnimport numpy as npimport matplotlib.pyplot as plt # 超参数设置input_size 1output_size 1num_epochs 60learning_rate 0.001 # Toy dataset # 玩具资料:小数据集x_train np.array([[3.3], [4.4], [5.5], [6.71], [6.…

2024年江苏省职业院校技能大赛信息安全管理与评估 第三阶段学生组(样卷)

2024年江苏省职业院校技能大赛信息安全管理与评估 第三阶段学生组(样卷) 竞赛项目赛题 本文件为信息安全管理与评估项目竞赛-第三阶段样题,内容包括:网络安全渗透、理论技能与职业素养。 本次比赛时间为180分钟。 介绍 GeekSe…

【C++】简单工厂模式

2023年12月6日,周三下午 今天又学习了一次简单工厂模式 每多学习一次,都会加深对设计模式的理解 目录 什么是简单工厂模式简单工厂模式的优缺点举例说明 什么是简单工厂模式 简单工厂模式(Simple Factory Pattern)是一种创建型…

香港科技大学广州|机器人与自主系统学域博士招生宣讲会—北京专场!!!(暨全额奖学金政策)

在机器人和自主系统领域实现全球卓越—机器人与自主系统学域 硬核科研实验室,浓厚创新产学研氛围! 教授亲临现场,面对面答疑解惑助攻申请! 一经录取,享全额奖学金1.5万/月! 时间:2023年12月09日…

虚拟机配置网络(这里以centos为例)

①、点击“编辑”里面的“虚拟网络编辑器”,取消勾选DHCP服务将IP地址分配给虚拟机。 2.点击nat设置,看看对应的子网ip和网关地址还有子网掩码,然后在安装虚拟机生成的vmware8适配器配置中配置和刚刚nat配置中一样的配置 3,然后和第二部一样…

git 面试字节时,老师问:合并分支中 rebase 和 merge 的区别

实际开发工作的时候,我们都是在自己的分支开发,然后将自己的分合并到主分支,那合并分支用2种操作,这2种操作有什么区别呢? git上新建一个项目,默认是有master分支的,将项目克隆到本地&#xff…

聚观早报 |东方甄选将上架文旅产品;IBM首台模块化量子计算机

【聚观365】12月6日消息 东方甄选将上架文旅产品 IBM首台模块化量子计算机 新思科技携手三星上新兴领域 英伟达与软银推动人工智能研发 苹果对Vision Pro供应商做出调整 东方甄选将上架文旅产品 东方甄选宣布12月10日将在东方甄选APP上线文旅产品,受这一消息影…

python二维数组创建赋值问题:更改单个值却更改了所有项的值

test_list [] dic1 {} test_list [dic1 for _ in range(3)] ll [1, 2, 3]for i in range(3):test_list[i][value] ll[i]print(test_list)运行结果:每次赋值都更改了所有项 原因:python的二位数据创建方式就是这样,官方文档中有描述Wha…

打工人副业变现秘籍,某多/某手变现底层引擎-Stable Diffusion图生图

我们都知道,模型在运算时是根据我们提供的提示内容来确定绘图方向,如果没有提示信息,模型只能根据此前的学习经验来自行发挥。在之前的文生图篇,我们介绍了如何通过提示词来控制图像内容,但想要实现准确的出图效果,只靠简短的提示词是很难满足实际需求的。 AI 绘画的随机…

SpringBoot+SSM项目实战 苍穹外卖(4) day4作业

继续上一节的内容,本节是作业课程,要求独立完成套餐管理模块所有业务功能,包括:新增套餐、套餐分页查询、删除套餐、修改套餐、起售停售套餐。 目录 新增套餐根据分类id查询菜品功能新增套餐功能 套餐分页查询删除套餐根据id查询套…

Java二阶知识点总结(一)Maven

一、Maven概念 Maven是一个项目管理工具,其主要作用有2点 依赖管理:管理项目依赖的各种jar包自动构建:项目构建的过程,从编译、测试、运行、打包到安装的过程可以一键执行 二、Maven工程的目录结构 src/main/java:…

【S32K144】MCAL基础工程搭建

目录 一、在S32DS创建Application Project 二、MCAL工程 三、基于MCAL的集成 以下示例基于S32K144EVB开发板进行。 一、在S32DS创建Application Project (1)新建工程Application Project (2)工程配置 (3&#xff…

正则表达式(5):常用符号

正则表达式(5):常用符号 小结 本博文转载自 在本博客中,”正则表达式”为一系列文章,如果你想要从头学习怎样在Linux中使用正则,可以参考此系列文章,直达链接如下: 在Linux中使用正…

二叉平衡树

一直想深入的研究一下,并手写平衡二叉树的插入、删除代码。 二叉树是动态查找的典范,但在极限情况下,二叉树的查找效果等同于链表,而平衡二叉树可以完美的达到 log ⁡ 2 n \log_2 n log2​n。 AVL简称平衡二叉树,缩写…