当前位置: 首页 > news >正文

MySQL数据类型全面解析:从数值精度到字符串优化的最佳实践

目录

    • 1. 数据类型分类
    • 2. 数值类型
      • 2.1 tinyint类型
      • 2.2 bit类型
      • 2.3 小数类型
        • 2.3.1 float类型
        • 2.3.2 decimal类型
    • 3. 字符串类型
      • 3.1 char类型
      • 3.2 varchar类型
      • 3.3 char和varchar比较
    • 4. 日期和时间类型
    • 5. enum和set类型
      • 5.1 enum类型
      • 5.2 set类型

1. 数据类型分类

MySQL中的数据类型主要分为数值类型、字符串类型、日期和时间类型、枚举和集合类型等。

2. 数值类型

2.1 tinyint类型

基本语法:

tinyint[(m)] [unsigned]

数值越界测试:

-- 创建表(默认有符号)
mysql> create table tt1(num tinyint);
Query OK, 0 rows affected (0.02 sec)-- 正常插入
mysql> insert into tt1 values(1);
Query OK, 1 row affected (0.00 sec)-- 越界插入,报错
mysql> insert into tt1 values(128);
ERROR 1264 (22003): Out of range value for column 'num' at row 1-- 查询结果
mysql> select * from tt1;
+------+
| num  |
+------+
|    1 |
+------+

无符号案例:

-- 创建无符号tinyint表
mysql> create table tt2(num tinyint unsigned);-- 插入负数报错
mysql> insert into tt2 values(-1);
ERROR 1264 (22003): Out of range value for column 'num' at row 1-- 正常插入
mysql> insert into tt2 values(255);
Query OK, 1 row affected (0.02 sec)-- 查询结果
mysql> select * from tt2;
+------+
| num  |
+------+
|  255 |
+------+

重要说明:

  • 整型默认是有符号的
  • 可以通过UNSIGNED关键字指定为无符号
  • 建议尽量不使用unsigned,对于存放不下的数据,直接升级为更大的类型(如bigint)

2.2 bit类型

基本语法:

bit[(M)]

M表示每个值的位数,范围从1到64,默认为1。

示例:

-- 创建表
mysql> create table tt4 (id int, a bit(8));
Query OK, 0 rows affected (0.01 sec)-- 插入数据
mysql> insert into tt4 values(10, 10);
Query OK, 1 row affected (0.01 sec)-- 查询显示(按照ASCII码显示)
mysql> select * from tt4;
+------+------+
| id   | a    |
+------+------+
|   10 |      |
+------+------+-- 插入ASCII码为65的数据(对应字符'A')
mysql> insert into tt4 values(65, 65);
mysql> select * from tt4;
+------+------+
| id   | a    |
+------+------+
|   10 |      |
|   65 | A    |
+------+------+

bit使用的注意事项:

  • bit字段显示时按照ASCII码对应的值显示
  • 对于只存放0或1的值,可以定义bit(1)来节省空间
  • 插入越界值会报错
-- 创建存储性别的表
mysql> create table tt5(gender bit(1));-- 正常插入
mysql> insert into tt5 values(0);
mysql> insert into tt5 values(1);-- 越界插入
mysql> insert into tt5 values(2);
ERROR 1406 (22001): Data too long for column 'gender' at row 1

2.3 小数类型

2.3.1 float类型

语法:

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

示例:

-- 创建表
mysql> create table tt6(id int, salary float(4,2));
Query OK, 0 rows affected (0.01 sec)-- 插入数据(自动四舍五入)
mysql> insert into tt6 values(100, -99.99);
mysql> insert into tt6 values(101, -99.991);
Query OK, 1 row affected (0.00 sec)-- 查询结果
mysql> select * from tt6;
+------+--------+
| id   | salary |
+------+--------+
|  100 | -99.99 |
|  101 | -99.99 |
+------+--------+

无符号float:

-- 创建无符号float表
mysql> create table tt7(id int, salary float(4,2) unsigned);-- 插入负数报错
mysql> insert into tt7 values(100, -0.1);
ERROR 1264 (22003): Out of range value for column 'salary' at row 1-- 正常插入
mysql> insert into tt7 values(100, 0);
mysql> insert into tt7 values(100, 99.99);
2.3.2 decimal类型

语法:

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

精度比较:

-- 创建表比较float和decimal精度
mysql> create table tt8 (id int, salary float(10,8), salary2 decimal(10,8));-- 插入数据
mysql> insert into tt8 values(100, 23.12345612, 23.12345612);
Query OK, 1 row affected (0.00 sec)-- 查询比较
mysql> select * from tt8;
+------+-------------+-------------+
| id   | salary      | salary2     |
+------+-------------+-------------+
|  100 | 23.12345695 | 23.12345612 |
+------+-------------+-------------+

重要说明:

  • float表示的精度大约是7位
  • decimal整数最大位数m为65,支持小数最大位数d是30
  • 如果希望小数的精度高,推荐使用decimal

3. 字符串类型

3.1 char类型

语法:

char(L)

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

示例:

-- 创建表
mysql> create table tt9(id int, name char(2));
Query OK, 0 rows affected (0.00 sec)-- 插入英文字符
mysql> insert into tt9 values(100, 'ab');
Query OK, 1 row affected (0.00 sec)-- 插入中文字符
mysql> insert into tt9 values(101, '中国');
Query OK, 1 row affected (0.00 sec)-- 查询结果
mysql> select * from tt9;
+------+--------+
| id   | name   |
+------+--------+
|  100 | ab     |
|  101 | 中国   |
+------+--------+-- 超过最大长度报错
mysql> create table tt10(id int, name char(256));
ERROR 1074 (42000): Column length too big for column 'name' (max = 255)

3.2 varchar类型

语法:

varchar(L)

可变长度字符串,L表示字符长度,最大长度65535个字节。

示例:

-- 创建表
mysql> create table tt10(id int, name varchar(6));-- 插入数据
mysql> insert into tt10 values(100, 'hello');
mysql> insert into tt10 values(100, '我爱你,中国');-- 查询结果
mysql> select * from tt10;
+------+--------------------+
| id   | name               |
+------+--------------------+
|  100 | hello              |
|  100 | 我爱你,中国       |
+------+--------------------+

varchar长度说明:

  • 实际可用字节数:65532(因为有1-3个字节用于记录数据大小)
  • 编码影响:
    • utf8编码:最大长度 = 65532/3 = 21844
    • gbk编码:最大长度 = 65532/2 = 32766
-- 验证utf8编码下的最大长度
mysql> create table tt11(name varchar(21845)) charset=utf8;
ERROR 1118 (42000): Row size too large.mysql> create table tt11(name varchar(21844)) charset=utf8;
Query OK, 0 rows affected (0.01 sec)

3.3 char和varchar比较

选择建议:

类型适用场景特点
char数据长度固定(身份证、手机号、MD5)磁盘空间浪费,但效率高
varchar数据长度变化(名字、地址)磁盘空间节省,但效率低

设计原则:

  • 定长数据使用char:直接开辟对应空间
  • 变长数据使用varchar:用多少开辟多少

4. 日期和时间类型

常用类型:

  • date:日期 ‘yyyy-mm-dd’,占用3字节
  • datetime:时间日期 ‘yyyy-mm-dd HH:ii:ss’,范围1000-9999,占用8字节
  • timestamp:时间戳,从1970年开始,格式同datetime,占用4字节

示例:

-- 创建表
mysql> create table birthday (t1 date, t2 datetime, t3 timestamp);
Query OK, 0 rows affected (0.01 sec)-- 插入数据
mysql> insert into birthday(t1,t2) values('1997-7-1','2008-8-8 12:1:1');
Query OK, 1 row affected (0.00 sec)-- 查询结果(timestamp自动填充当前时间)
mysql> select * from birthday;
+------------+---------------------+---------------------+
| t1         | t2                  | t3                  |
+------------+---------------------+---------------------+
| 1997-07-01 | 2008-08-08 12:01:01 | 2023-11-12 18:28:55 |
+------------+---------------------+---------------------+-- 更新数据(timestamp自动更新)
mysql> update birthday set t1='2000-1-1';
Query OK, 1 row affected (0.00 sec)mysql> select * from birthday;
+------------+---------------------+---------------------+
| t1         | t2                  | t3                  |
+------------+---------------------+---------------------+
| 2000-01-01 | 2008-08-08 12:01:01 | 2023-11-12 18:32:09 |
+------------+---------------------+---------------------+

5. enum和set类型

5.1 enum类型

语法:

enum('选项1','选项2','选项3',...)
  • "单选"类型
  • 实际存储数字(1,2,3,…),最多65535个选项

5.2 set类型

语法:

set('选项值1','选项值2','选项值3',...)
  • "多选"类型
  • 实际存储数字(1,2,4,8,16,32,…),最多64个选项

示例:

-- 创建调查表
mysql> create table votes(-> username varchar(30),-> hobby set('登山','游泳','篮球','武术'),-> gender enum('男','女')
);
Query OK, 0 rows affected (0.02 sec)-- 插入数据
insert into votes values('雷锋', '登山,武术', '男');
insert into votes values('Juse', '登山,武术', 2);  -- 使用数字标识
insert into votes values('LiLei', '登山', '男');
insert into votes values('LiLei', '篮球', '男');
insert into votes values('HanMeiMei', '游泳', '女');-- 查询所有数据
mysql> select * from votes;
+-----------+---------------+--------+
| username  | hobby        | gender |
+-----------+---------------+--------+
| 雷锋      | 登山,武术     ||
| Juse      | 登山,武术     ||
| LiLei     | 登山          ||
| LiLei     | 篮球          ||
| HanMeiMei | 游泳          ||
+-----------+---------------+--------+

集合查询:

-- 错误查询方式(只能查询完全匹配)
mysql> select * from votes where hobby='登山';
+----------+--------+--------+
| username | hobby  | gender |
+----------+--------+--------+
| LiLei    | 登山   ||
+----------+--------+--------+-- 正确查询方式:使用find_in_set函数
mysql> select * from votes where find_in_set('登山', hobby);
+----------+---------------+--------+
| username | hobby         | gender |
+----------+---------------+--------+
| 雷锋     | 登山,武术     ||
| Juse     | 登山,武术     ||
| LiLei    | 登山          ||
+----------+---------------+--------+

find_in_set函数:

-- 语法:find_in_set(sub, str_list)
mysql> select find_in_set('a', 'a,b,c');
+---------------------------+
| find_in_set('a', 'a,b,c') |
+---------------------------+
|                         1 |
+---------------------------+mysql> select find_in_set('d', 'a,b,c');
+---------------------------+
| find_in_set('d', 'a,b,c') |
+---------------------------+
|                         0 |
+---------------------------+
http://www.dtcms.com/a/609576.html

相关文章:

  • 太阳光模拟器应用:汽车太阳能天窗的发电效能动态测试
  • ES踩了一坑 script查询与float类型的精度
  • ASC学习笔记0015:此能力系统组件是否具有此属性?
  • 如何基于DSL脚本进行elasticsearch向量检索示例
  • 如何利用大语言模型(LLM)实现自动标注与内容增强
  • h5网站有哪些网页设计公司的目标客户有哪些
  • 做网站推广合同做标志的网站
  • 【ZeroRange WebRTC】Amazon Kinesis Video Streams WebRTC Data Plane REST API 深度解析
  • 2025从部署到迭代:Deepseek知识库部署服务商如何护航企业知识管理?
  • 检索增强微调(RAFT)如何重塑慢病健康管理?——从技术原理到落地实践
  • 网站开发 工作量评估关于建设网站安全性合同
  • 学Java第四十四天——可变参数、Collections工具类
  • XQuery FLWOR + HTML:深入理解与实际应用
  • 风丘助力优化ADAS测试:多路雷达、视频及车辆总线数据的集成处
  • LeetCode 152. 乘积最大子数组
  • XTDIC-SPARK高速3D测量系统在电子产品跌落测试中的动态变形与可靠性评估
  • Java设计模式之原型模式深度解析
  • 设置网站关键词怎么做高端大气网站源码
  • 网站内链建设不可忽视的地方零基础短视频制作培训
  • php做企业网站管理系统网络营销的特征和功能
  • 【WSL】继承Windows科学流量
  • 可复用的 Vue 3 + TypeScript + Element Plus 的列表请求(列表页/表格)通用方案
  • 安装 Composer
  • 国外做名片的网站网站没有备案
  • 解决VMware Workstation虚拟机中添加硬盘时找不到U盘对应的磁盘physicaldrive3
  • 解决 “Could not locate zlibwapi.dll” 错误全流程分析
  • 第一模板ppt免费下载seo人员工作内容
  • 【高级机器学习】 7. 带噪声数据的学习:从 MLE 到 MAP
  • 横沥镇做网站北京公司注册地址出租
  • 北湖区网站建设哪个好中网互联网站建设