【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 1

mysql> 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 1

mysql> 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: 0

mysql> 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: 0

mysql> 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: 0

mysql> 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 1

mysql> insert into tb3 values('周肥', -100.00);
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 |
+-----------+--------+
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 1

mysql> 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 1

mysql> insert into tb4 values ('周肥', -1);               --- 越界
ERROR 1264 (22003): Out of range value for column 'score' at row 1

mysql> 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 1

mysql> 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 1

mysql> insert into tb6(name) values('abcde');        --- 五个字符,越界
ERROR 1406 (22001): Data too long for column 'name' at row 1

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('中国人');       --- 三个字符
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: 0

mysql> 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 instead

mysql> 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 BLOBs

mysql> 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: 0

mysql> 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 1

mysql> 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)




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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

0X05

打开题目 点击完登录和注册都没有什么反应,所以先扫一下看看 在出现admin.php后就截止了,访问看看,进入后台。。 尝试一下弱口令 admin/12345 或者是demo/demo 设计中-自定义->右上角导出主题 找到一个导出的点,下载了一个1.zip压缩包…

解析Python爬虫利器 - lxml库

更多资料获取 📚 个人网站:ipengtao.com 在当今信息爆炸的时代,网络上的数据量庞大而繁杂。为了高效地从网页中提取信息,Python爬虫工程师们需要强大而灵活的工具。其中,lxml库凭借其卓越的性能和丰富的功能成为Pytho…

三十九、TCC模式

目录 一、定义 1、需要实现的方法: 2、优点: 3、缺点: 二、原理 1、例子: 2、工作模型图: 3、空回滚和业务悬挂 三、实现TCC模式 1、编写TCC服务接口 2、实现TCC服务接口 一、定义 TCC模式是Translucent Tr…

获客成本高?低成本获客有哪些途径?

获客成本是一个企业在营销中必须考虑的重要因素之一。它指企业在吸引新客户、推广产品或服务时所需要投入的资金、人力、物力等成本。不仅包括直接成本,如广告费用、促销费用等,还包括间接成本,如市场调研费用、销售人员薪酬等。 获客成本不是…

ELK日志分析

ELK是一套完整的日志集中处理方案,由三个开源软件简称组成: E:ElasticSearch ES 是一个开源的,分布式的存储检索引擎(索引型的非关系型数据库)。存储日志 java代码开发的,基于Lucene结构开发的…

【Java 基础】21 多线程同步与锁

文章目录 1.存在的问题2.使用同步解决问题1) synchronized2) volatile3) 锁 总结 用多线程过程中,有可能出现 多个线程同时处理(获取或修改等)同一个数据,这个时候就 会发生数据不同步的问题, 因此出现了同步和锁来…

用js自定义一个(v-model)vModel双向绑定函数

vue中的v-model是双向绑定的, 我们自己用JavaScript实现一个双向绑定vModel函数。 // element 元素或者#id,.class,div 得是input标签 // data 对象 // 将要绑定property 对象中的key<input class"vmodel"/>function vModel(element, data, property) {if (…

【Proteus】绘制简单的电路图

参考书籍&#xff1a;微机原理与接口技术——基于8086和Proteus仿真&#xff08;第3版&#xff09;&#xff08;作者&#xff1a;顾晖等&#xff09;&#xff0c;p111 1.放置元件 以8086为例&#xff1a; 确保处于元件模式&#xff0c;点击对应的按钮&#xff1a; 在元件库中…

自动生成实体类,mapper类和mapper.xml文件(解放双手,定义好数据库表就不要手写啦)

背景 建的表有四十多个字段&#xff0c;建好了已经很累了&#xff0c;映射成Javabean还要再写一次&#xff01;&#xff01; 吐槽 在建立好了sql表之后&#xff0c;我们已经写了一次建表了&#xff0c;难道还要我们自己再一次手写模Java模型吗&#xff0c;我的表有几十个字段…

数据结构——链式二叉树

前言&#xff1a;哈喽小伙伴们&#xff0c;上篇文章我们讲述了一个特殊的二叉树——使用数组实现的堆的基本知识之后呢&#xff0c;从这篇文章开始&#xff0c;我们就正式进入普通二叉树的介绍啦&#xff0c;二叉树真正的难点——递归&#xff0c;即将来临&#xff0c;小伙伴们…

力扣刷题day2(最长公共前缀,有效括号,删除有序数组中的重复元素)

题目1&#xff1a;14.最长公共前缀 思路和解析&#xff1a; #define _CRT_SECURE_NO_WARNINGS //最长公共前缀 char* longestCommonPrefix(char** strs, int strsSize) {// 如果字符串数组为空&#xff0c;则返回空字符串if (strsSize 0){return "";}// 将第一个…

P7 Linux C三种终止进程的方法

前言 &#x1f3ac; 个人主页&#xff1a;ChenPi &#x1f43b;推荐专栏1: 《C_ChenPi的博客-CSDN博客》✨✨✨ &#x1f525; 推荐专栏2: 《Linux C应用编程&#xff08;概念类&#xff09;_ChenPi的博客-CSDN博客》✨✨✨ &#x1f6f8;推荐专栏3: ​​​​​​《 链表_Chen…

基于深度学习面向中医诊断的舌象图像分割系统

1.研究背景与意义 项目参考AAAI Association for the Advancement of Artificial Intelligence 研究背景与意义 中医舌诊是通过观察舌的各种特征来了解人体的健康状况&#xff0c;从而对各种疾病做出诊断及病情评估&#xff0c;是传统中国医学应用最广、最有价值的诊法之一。…

632. 最小区间

632. 最小区间 class Solution {public int[] smallestRange(List<List<Integer>> nums) {int size nums.size();Map<Integer, List<Integer>> indices new HashMap<Integer, List<Integer>>();int xMin Integer.MAX_VALUE, xMax Inte…

什么因素会影响葡萄酒陈酿的能力?

糖、酸和酚类与水的比例是葡萄酒陈酿程度的关键决定因素&#xff0c;收获前葡萄中的水分越少&#xff0c;产生的葡萄酒就越有可能具有一定的陈酿潜力。那么葡萄品种、气候和葡萄栽培实践的过程就相当重要了&#xff0c;对陈酿的时间发挥了重要的作用。皮较厚的葡萄品种&#xf…

iOS ------ 调用高德地图SDK

一&#xff0c;导入第三方库 这里使用CocoaPods安装SDK&#xff0c;方法和前面导入第三方库相同 1.打开终端&#xff0c;cd 文件路径 进入到所创建的项目文件中 2.输入pod init为该项目创建Podfile文件 3.编辑 Podfile 文件 Podfile文件内容如下&#xff1a; platform :ios,…

图形遍历效率低?试试 R 树

大家好&#xff0c;我是前端西瓜哥。 今天我们来看看 R 树是什么&#xff1f;以及它为什么能够提高图形的检索速度。 R 树&#xff08;R-tree&#xff09;是一种 空间索引技术&#xff0c;能够是从大量的节点中&#xff0c;快速找到特定范围的元素集合&#xff0c;而不用一个…

Verilog 入门(八)(验证)

文章目录 编写测试验证程序波形产生值序列重复模式 测试验证程序实例从文本文件中读取向量实例&#xff1a;时序检测器 测试验证程序用于测试和验证设计方法的正确性。Verilog 提供强有力的结构来说明测试验证程序。 编写测试验证程序 测试验证程序有三个主要目的&#xff1a;…

JNPF——强大、高效、易学的低代码开发工具

目录 1.什么是低代码 2.什么是JNPF? 3.推荐JNPF的理由 4.小结 你是否为编程世界的各种挑战感到头痛&#xff1f;想要以更高效、简单的方式开发出专业级的项目&#xff1f;JNPF低代码工具正是你苦心寻找的产品&#xff01;它是一款专为稍微懂一点点编程思想的入门级人员设计…

vue elementUI 上传非空验证

<el-form-item label"照片" prop"staffImg"><template v-slot:label><span v-show"!rules.staffImg[0].required"style"color: #ff4949;margin-right: 4px;">*</span><span>照片</span></temp…