MySQL之数据类型

目录

一:数据类型分类

二:数值类型

[1. tinyint类型](#1. tinyint类型)

2.bit类型

3.小数类型

[1. float](#1. float)

2.decimal

三:字符串类型

1.char

2.varchar

3.char和varchar比较

4.日期和时间类型

5.enum和set

接下来的日子会顺顺利利,万事胜意,生活明朗-----------林辞忧

一:数据类型分类

二:数值类型

1. tinyint类型

这里int相关类型以tinyint为例,其余皆可同理

1.在MySQL中,整型可以指定是有符号的和无符号的,默认是有符号的。

2.可以通过unsigned来说明某个字段是无符号的

3.越界插入数据测试

sql 复制代码
mysql> create database d1;
Query OK, 1 row affected (0.00 sec)

mysql> use d1;
Database changed
mysql> show tables;
Empty set (0.00 sec)

mysql> create table if not exists t1(
    -> id tinyint
    -> );
Query OK, 0 rows affected (0.02 sec)

mysql> insert into t1 values (-128);
Query OK, 1 row affected (0.00 sec)

mysql> insert into t1 values (127);
Query OK, 1 row affected (0.00 sec)

mysql> insert into t1 values (128);
ERROR 1264 (22003): Out of range value for column 'id' at row 1
mysql> insert into t1 values (-129);
ERROR 1264 (22003): Out of range value for column 'id' at row 1
mysql> select * from t1;
+------+
| id   |
+------+
| -128 |
|  127 |
+------+

mysql> create table if not exists t2(
    -> id tinyint unsigned
    -> );
Query OK, 0 rows affected (0.03 sec)

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

mysql> insert into t2 values (-1);
ERROR 1264 (22003): Out of range value for column 'id' at row 1
mysql> insert into t2 values (255);
Query OK, 1 row affected (0.00 sec)

mysql> insert into t2 values (256);
ERROR 1264 (22003): Out of range value for column 'id' at row 1
mysql> select* from t2;
+------+
| id   |
+------+
|    0 |
|  255 |
+------+

会发现如果我们向mysql特定的类型中插入不合法的数据,MySQL一般都是直接拦截,不让进行对应的操作;相反,如果我们已经有数据被成功插入到mysql中,插入的数据一定是合法的.所以,在mysql中,一般而言,数据类型本身也是一种约束

2.bit类型

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

2.实例:

sql 复制代码
mysql> create table if not exists t3(
    -> id int,
    -> online bit(1)
    -> );
Query OK, 0 rows affected (0.02 sec)

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

mysql> insert into t3 (id,online) values (2,1);
Query OK, 1 row affected (0.01 sec)

mysql> insert into t3 (id,online) values (3,2);
ERROR 1406 (22001): Data too long for column 'online' at row 1
mysql> select* from t3;
+------+--------+
| id   | online |
+------+--------+
|    1 |        |
|    2 |       |
+------+--------+

这里对于插入越界的数据依旧是拦截不让插入,还有这里的0/1不显示,这是因为bit字段在显示时,是按照ASCII码对应的值显示,这里的0/1对应的ASCII码是不显示的

如要显示的话,就应该以十进制的方式显示

sql 复制代码
mysql> select id, hex(online) from t3;
+------+-------------+
| id   | hex(online) |
+------+-------------+
|    1 | 0           |
|    2 | 1           |
+------+-------------+
sql 复制代码
mysql> alter table t3 modify online bit(64);
Query OK, 2 rows affected (0.07 sec)
Records: 2  Duplicates: 0  Warnings: 0

mysql> insert into t3 (id,online) values (1,A);
ERROR 1054 (42S22): Unknown column 'A' in 'field list'
mysql> insert into t3 (id,online) values (1,'A');
Query OK, 1 row affected (0.00 sec)

mysql> insert into t3 (id,online) values (1,98);
Query OK, 1 row affected (0.01 sec)

mysql> select* from t3;
+------+----------+
| id   | online   |
+------+----------+
|    1 |          |
|    2 |         |
|    1 |        A |
|    1 |        b |
+------+----------+

3.小数类型

1. float

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

实例:小数:float(4,2)表示的范围是-99.99 ~ 99.99,MySQL在保存值时会进行四舍五入

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

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

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

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

mysql> insert into t4 (id,salary) values (2,-99.994);
Query OK, 1 row affected (0.01 sec)

mysql> insert into t4 (id,salary) values (2,-99.995);
ERROR 1264 (22003): Out of range value for column 'salary' at row 1
mysql> insert into t4 (id,salary) values (2,99.994);
Query OK, 1 row affected (0.00 sec)

mysql> insert into t4 (id,salary) values (2,99.995);
ERROR 1264 (22003): Out of range value for column 'salary' at row 1
mysql> select* from t4;
+------+--------+
| id   | salary |
+------+--------+
|    1 | -99.99 |
|    2 |  99.99 |
|    2 |  23.14 |
|    2 | -99.99 |
|    2 |  99.99 |
+------+--------+

会发现对于超过指定位数的,会四舍五入进行保存,保存后的数据只要在范围内就可以正常插入,不在范围的就会直接拦截,况且float对于数据有时是不能准确保存的

如果定义的是float(4,2) unsigned 这时,因为把它指定为无符号的数,范围是 0 ~ 99.99

2.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表示的精度不一样

sql 复制代码
mysql> create table if not exists t5(
    -> id int,
    -> s1 float(10,8),
    -> s2 decimal(10,8)
    -> );
Query OK, 0 rows affected (0.02 sec)

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

mysql> select* from t5;
+------+-------------+-------------+
| id   | s1          | s2          |
+------+-------------+-------------+
|    1 | 23.12345695 | 23.12345612 |
+------+-------------+-------------+

float表示的精度大约是7位。

decimal整数最大位数m为65。支持小数最大位数d是30。如果d被省略,默认为0.如果m被省略,默认是10。

建议:如果希望小数的精度高,推荐使用decimal

三:字符串类型

1.char

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

在utf8编码当中,一个汉字为一个字符,一个字符为三字节

实例:

sql 复制代码
mysql> create table t6(
    -> id int,
    -> name char(3)
    -> );
Query OK, 0 rows affected (0.02 sec)

mysql> insert into t6 (id,name) values (1,'中');
Query OK, 1 row affected (0.00 sec)

mysql> insert into t6 (id,name) values (1,'中国');
Query OK, 1 row affected (0.00 sec)

mysql> insert into t6 (id,name) values (1,'中国人');
Query OK, 1 row affected (0.00 sec)

mysql> insert into t6 (id,name) values (1,'中国人民');
ERROR 1406 (22001): Data too long for column 'name' at row 1

2.varchar

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

2.关于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字节)

sql 复制代码
mysql> create table tt11(name varchar(21845))charset=utf8; --验证了utf8确实是不能超过21844
ERROR 1118 (42000): Row size too large. The maximum row size for the used table type,
not counting BLOBs, is 65535. You have to change some columns to TEXT or BLOBs

mysql> create table tt11(name varchar(21844)) charset=utf8;
Query OK, 0 rows affected (0.01 sec)

3.char和varchar比较

4.日期和时间类型

1.常用的日期有如下三个:

date :日期 'yyyy-mm-dd' ,占用三字节

datetime 时间日期格式 'yyyy-mm-dd HH:ii:ss' 表示范围从 1000 到 9999 ,占用八字节

timestamp:时间戳,从1970年开始的 yyyy-mm-dd HH:ii:ss 格式和 datetime 完全一致,占用四字节

时间戳不需要自己维护,会自动更新的

2.实例:

sql 复制代码
mysql> create table t7(
    -> t1 date,
    -> t2 datetime,
    -> t3 timestamp
    -> );
Query OK, 0 rows affected (0.03 sec)

mysql> insert into t7 (t1,t2) values ('2003-08-15','2008-08-10 12:01:01');
Query OK, 1 row affected (0.01 sec)

mysql> select* from t7;
+------------+---------------------+---------------------+
| t1         | t2                  | t3                  |
+------------+---------------------+---------------------+
| 2003-08-15 | 2008-08-10 12:01:01 | 2024-09-13 09:33:34 |
+------------+---------------------+---------------------+
1 row in set (0.01 sec)

mysql> update t7 set t1='1999-12-31'; #更新数据;
Query OK, 1 row affected (0.00 sec)
Rows matched: 1  Changed: 1  Warnings: 0

mysql> select* from t7;
+------------+---------------------+---------------------+
| t1         | t2                  | t3                  |
+------------+---------------------+---------------------+
| 1999-12-31 | 2008-08-10 12:01:01 | 2024-09-13 09:34:30 |
+------------+---------------------+---------------------+
1 row in set (0.00 sec)

mysql> create table if not exists t8(
    -> context text,
    -> time timestamp
    -> );
Query OK, 0 rows affected (0.03 sec)

mysql> insert into t8 (context) values ('中国人民');
Query OK, 1 row affected (0.00 sec)

mysql> select* from t8;
+--------------+---------------------+
| context      | time                |
+--------------+---------------------+
| 中国人民     | 2024-09-13 09:36:39 |
+--------------+---------------------+
1 row in set (0.00 sec)

mysql> update t8 set context='中国人民站起来了'; #更新数据
Query OK, 1 row affected (0.00 sec)
Rows matched: 1  Changed: 1  Warnings: 0

mysql> select* from t8;
+--------------------------+---------------------+
| context                  | time                |
+--------------------------+---------------------+
| 中国人民站起来了         | 2024-09-13 09:37:27 |
+--------------------------+---------------------+
1 row in set (0.00 sec)

3.更新操作 update 表名 set 列名=新内容;

5.enum和set

1.语法:enum:枚举,"单选"类型;

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

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

set:集合,"多选"类型;

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

该设定只是提供了若干个选项的值,最终一个单元格中,设计可存储了其中任意多个值;而且出于效率考虑,这些值

实际存储的是"数字",因为这些选项的每个选项值依次对应如下数字:1,2,4,8,16,32,.... 最多64个。

2.实例:

sql 复制代码
mysql> create table if not exists t9(
    -> name varchar(20),
    -> gender enum('男','女'),
    -> hobby set('代码','羽毛球','乒乓球','足球')
    -> );
Query OK, 0 rows affected (0.03 sec)

mysql> insert into t9 (name,gender,hobby) values ('刘备','男','代码');
Query OK, 1 row affected (0.00 sec)

mysql> insert into t9 (name,gender,hobby) values ('孙尚香','女','代码,羽毛球');
Query OK, 1 row affected (0.00 sec)

#插入enum和set中不存在的值就会报错
mysql> insert into t9 (name,gender,hobby) values ('刘禅','unknown','代码,羽毛球');
ERROR 1265 (01000): Data truncated for column 'gender' at row 1
mysql> insert into t9 (name,gender,hobby) values ('刘禅','unknown','跑步');
ERROR 1265 (01000): Data truncated for column 'gender' at row 1


#enum在插入时可以写枚举常量值,也可以写常量对应下标(从1开始)
mysql> insert into t9 (name,gender,hobby) values ('曹操',1,'代码');
Query OK, 1 row affected (0.01 sec)

mysql> insert into t9 (name,gender,hobby) values ('貂蝉',2,'代码');
Query OK, 1 row affected (0.00 sec)

mysql> select* from t9;
+-----------+--------+------------------+
| name      | gender | hobby            |
+-----------+--------+------------------+
| 刘备      | 男     | 代码             |
| 孙尚香    | 女     | 代码,羽毛球      |
| 曹操      | 男     | 代码             |
| 貂蝉      | 女     | 代码             |
+-----------+--------+------------------+


#set值在用数字时,是按照数字二进制bit位是否为1进行的
mysql> insert into t9 (name,gender,hobby) values ('孙权',1,1);
Query OK, 1 row affected (0.00 sec)

mysql> insert into t9 (name,gender,hobby) values ('周瑜',1,2);
Query OK, 1 row affected (0.00 sec)

mysql> insert into t9 (name,gender,hobby) values ('赵云',1,3);
Query OK, 1 row affected (0.00 sec)

mysql> insert into t9 (name,gender,hobby) values ('张飞',1,4);
Query OK, 1 row affected (0.01 sec)

mysql> insert into t9 (name,gender,hobby) values ('关羽',1,5);
Query OK, 1 row affected (0.00 sec)

mysql> insert into t9 (name,gender,hobby) values ('黄忠',1,6);
Query OK, 1 row affected (0.00 sec)

mysql> insert into t9 (name,gender,hobby) values ('马超',1,15);
Query OK, 1 row affected (0.01 sec)

mysql> select* from t9;
+-----------+--------+-----------------------------------+
| name      | gender | hobby                             |
+-----------+--------+-----------------------------------+
| 刘备      | 男     | 代码                              |
| 孙尚香    | 女     | 代码,羽毛球                       |
| 曹操      | 男     | 代码                              |
| 貂蝉      | 女     | 代码                              |
| 孙权      | 男     | 代码                              |
| 周瑜      | 男     | 羽毛球                            |
| 赵云      | 男     | 代码,羽毛球                       |
| 张飞      | 男     | 乒乓球                            |
| 关羽      | 男     | 代码,乒乓球                       |
| 黄忠      | 男     | 羽毛球,乒乓球                     |
| 马超      | 男     | 代码,羽毛球,乒乓球,足球           |
+-----------+--------+-----------------------------------+

3.查找

使用select* from 表名 where 列名=常量/数字这样查的话,是严格匹配去查找的,有多兴趣的是查不出来的

此时就可以使用find_in_set函数来查询

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

如1:查询爱好中包含乒乓球的人

sql 复制代码
ysql> select* from t9 where find_in_set('乒乓球',hobby);

+--------+--------+-----------------------------------+
| name   | gender | hobby                             |
+--------+--------+-----------------------------------+
| 张飞   | 男     | 乒乓球                            |
| 关羽   | 男     | 代码,乒乓球                       |
| 黄忠   | 男     | 羽毛球,乒乓球                     |
| 马超   | 男     | 代码,羽毛球,乒乓球,足球           |
+--------+--------+-----------------------------------+

如2:查询爱好中有代码和羽毛球的人

sql 复制代码
mysql> select* from t9 where find_in_set('代码',hobby) and find_in_set('羽毛球',hobby);
+-----------+--------+-----------------------------------+
| name      | gender | hobby                             |
+-----------+--------+-----------------------------------+
| 孙尚香    | 女     | 代码,羽毛球                       |
| 赵云      | 男     | 代码,羽毛球                       |
| 马超      | 男     | 代码,羽毛球,乒乓球,足球           |
+-----------+--------+-----------------------------------+
相关推荐
m0_748248021 小时前
Redis 简介与安装指南
数据库·redis·缓存
Elastic 中国社区官方博客6 小时前
在 Elasticsearch 中使用 Mistral Chat completions 进行上下文工程
大数据·数据库·人工智能·elasticsearch·搜索引擎·ai·全文检索
编程爱好者熊浪8 小时前
两次连接池泄露的BUG
java·数据库
南宫乘风9 小时前
基于 Flask + APScheduler + MySQL 的自动报表系统设计
python·mysql·flask
TDengine (老段)9 小时前
TDengine 字符串函数 CHAR 用户手册
java·大数据·数据库·物联网·时序数据库·tdengine·涛思数据
qq74223498410 小时前
Python操作数据库之pyodbc
开发语言·数据库·python
姚远Oracle ACE10 小时前
Oracle 如何计算 AWR 报告中的 Sessions 数量
数据库·oracle
Dxy123931021610 小时前
MySQL的SUBSTRING函数详解与应用
数据库·mysql
码力引擎11 小时前
【零基础学MySQL】第十二章:DCL详解
数据库·mysql·1024程序员节
杨云龙UP11 小时前
【MySQL迁移】MySQL数据库迁移实战(利用mysqldump从Windows 5.7迁至Linux 8.0)
linux·运维·数据库·mysql·mssql