文章目录

  • 前言
  • 一、数值类型
    • 1.简述
    • 2.选择原则
  • 二、日期时间类型
    • 1.简述
    • 2.选择原则
  • 三、字符串类型
    • 1.简述
    • 2.选择原则
  • 总结

前言

本篇主要介绍MySQL常用的数据类型,并总结了在创建表时应该如何选择数据类型的一些原则。


一、数值类型

1.简述

所有的整数类型都有一个可选属性UNSIGNED(无符号),如果需要在字段里面保存非负数或者需要较大的上限值时,可以用此选项。它的取值方位是正常值是下限取0,上限是原来的上限的2倍

actor_id SMALLINT UNSIGNED NOT NULL AUTO_INCREMENT,

整数类型

类型 字节 最小值 最大值
TINYINT 1 有符号 -128
无符号 0
有符号 127
无符号 255
SMALLINT 2 有符号 -32768
无符号 0
有符号 32767
无符号 65535
MEDIUMINT 3 有符号 -32768
无符号 0
有符号 32767
无符号 65535
INT 4 有符号 -(2^31)
无符号 0
有符号 (2^31)-1
无符号 (2^32)
BIGINT 8 有符号 -(2^63)
无符号 0
有符号 (2^63)-1
无符号 (2^64)

MySQL支持在证书类型后面的小括号内指定显示宽度。如int(5)表示当数值宽度小于5时在数字前面填满宽度,如果不指定宽度则默认为int(11)。一般配合zerofill使用,意思是使用0进行填充。

mysql> create table int_test(id1 int,id2 int(5));
Query OK, 0 rows affected (0.03 sec)mysql> desc int_test;
+-------+---------+------+-----+---------+-------+
| Field | Type    | Null | Key | Default | Extra |
+-------+---------+------+-----+---------+-------+
| id1   | int(11) | YES  |     | NULL    |       |
| id2   | int(5)  | YES  |     | NULL    |       |
+-------+---------+------+-----+---------+-------+
-- 加入zerofill参数
mysql> alter table int_test modify id1 int zerofill;
Query OK, 1 row affected (0.05 sec)
Records: 1  Duplicates: 0  Warnings: 0
mysql> alter table int_test modify id2 int(5) zerofill;
Query OK, 1 row affected (0.06 sec)
Records: 1  Duplicates: 0  Warnings: 0
-- int  有unsigned 位数变为10
mysql> desc int_test;
+-------+---------------------------+------+-----+---------+-------+
| Field | Type                      | Null | Key | Default | Extra |
+-------+---------------------------+------+-----+---------+-------+
| id1   | int(10) unsigned zerofill | YES  |     | NULL    |       |
| id2   | int(5) unsigned zerofill  | YES  |     | NULL    |       |
+-------+---------------------------+------+-----+---------+-------+mysql> select * from int_test;
+------------+-------+
| id1        | id2   |
+------------+-------+
| 0000000001 | 00001 |
+------------+-------+
1 row in set (0.00 sec)

浮点数类型

类型 字节 最小值 最大值
FLOAT 4 +/-1.175494351E-38 +/-3.402823466E+38
DOUBLE 8 +/-2.2250738585072014E-308 +/-1.7976931348623157E+308

定点数类型

类型 字节 描述
DEC(M.D)
DECIMAL(M,D)
M+2 最大取值范围与DOUBLE相同,有效的取值范围由M和D决定

浮点数和定点数都可以用类型名称后加“(M,D)”的方式进行表示,“(M,D)”表示该值一共显示M位数字(整数为+小数位),其中D为位于小数点后面,M和D又称为精度和标度。

定点数在MySQL内部以字符串形式存放,比浮点数更精确,适合用来表示货币等精度高的数据。
float和double在不指定精度时,默认会按照实际的精度(由实际的硬件和操作系统决定)。如果有了精度和标度,则会自动将四舍五入后的结果插入,系统不会报错。
decimal如果不写精度和标度,按照默认值decimal(10,0)来进行操作,如果数值超越了精度和标度值,在默认SQLModel下,数据按照四舍五入后插入,在TRADITIONAL模式下,会报错。

2.选择原则

点数和浮点数的四舍五入

mysql> create table t(f float(8,1),d decimal(8,1));
Query OK, 0 rows affected (0.03 sec)mysql> insert into t values(1.23456,1.23456);
Query OK, 1 row affected, 1 warning (0.01 sec)mysql> insert into t values(1.25456,1.25456);
Query OK, 1 row affected, 1 warning (0.00 sec)mysql> select * from t;
+------+------+
| f    | d    |
+------+------+
|  1.2 |  1.2 |
|  1.3 |  1.3 |
+------+------+

定点数和浮点数区别

mysql> create table test(f float(10,2),d decimal(10,2));
Query OK, 0 rows affected (0.03 sec)mysql> desc test;
+-------+---------------+------+-----+---------+-------+
| Field | Type          | Null | Key | Default | Extra |
+-------+---------------+------+-----+---------+-------+
| f     | float(10,2)   | YES  |     | NULL    |       |
| d     | decimal(10,2) | YES  |     | NULL    |       |
+-------+---------------+------+-----+---------+-------+
2 rows in set (0.01 sec)mysql> insert into test values(131072.32,131072.32);
Query OK, 1 row affected (0.01 sec)
-- 精度丢失
mysql> select * from test;
+-----------+-----------+
| f         | d         |
+-----------+-----------+
| 131072.31 | 131072.32 |
+-----------+-----------+
1 row in set (0.00 sec)

小结

  • 浮点数和定点数存在四舍五入;
  • 浮点数存在误差问题
  • 对货币等对精度敏感的数据,应采用定点数表示。

二、日期时间类型

1.简述

类型 字节 最小值 最大值 零值表示
DATE 4 1000-01-01 9999-12-31 0000-00-00
DATETIME 8 1000-01-01 00:00:00 9999-12-31 23:59:59 0000-00-00 00:00:00
TIMESTAMP 4 19700101080001 2038年某个时刻 00000000000000
TIME 3 -838:59:59 838:59:59 00:00:00
YEAR 1 1901 2155 000
mysql> desc time_test;
+-------+----------+------+-----+---------+-------+
| Field | Type     | Null | Key | Default | Extra |
+-------+----------+------+-----+---------+-------+
| d     | date     | YES  |     | NULL    |       |
| t     | time     | YES  |     | NULL    |       |
| dt    | datetime | YES  |     | NULL    |       |
+-------+----------+------+-----+---------+-------+
3 rows in set (0.00 sec)mysql> insert into time_test values(now(),now(),now());
Query OK, 1 row affected, 1 warning (0.01 sec)mysql> select * from time_test;
+------------+----------+---------------------+
| d          | t        | dt                  |
+------------+----------+---------------------+
| 2021-02-15 | 02:45:49 | 2021-02-15 02:45:49 |
+------------+----------+---------------------+

TIMESTAMP演示

mysql> create table t_stamp(id timestamp);
Query OK, 0 rows affected (0.04 sec)mysql> desc t_stamp;
+-------+-----------+------+-----+-------------------+-----------------------------+
| Field | Type      | Null | Key | Default           | Extra                       |
+-------+-----------+------+-----+-------------------+-----------------------------+
| id    | timestamp | NO   |     | CURRENT_TIMESTAMP | on update CURRENT_TIMESTAMP |
+-------+-----------+------+-----+-------------------+-----------------------------+
mysql> select * from t_stamp;
Empty set (0.00 sec)mysql> insert into t_stamp values(null);
Query OK, 1 row affected (0.01 sec)mysql> select * from t_stamp;
+---------------------+
| id                  |
+---------------------+
| 2021-02-15 06:03:46 |
+---------------------+
1 row in set (0.01 sec)

上面可以看到,系统自动创建了默认值,插入了系统日期。

mysql> alter table t_stamp add column id2 timestamp;
ERROR 1067 (42000): Invalid default value for 'id2'

MySQL规定TIMESTAMP类型字段只能有一列的默认值为CURRENT_TIMESTAMP 。
TIMESTAMP还有一个重要特点,就是和时区相关。当插入日期时,会先转换为本地时区后存储,而从数据库中取出时也同样需要将日期转换成本地时区后显示。

mysql> desc t8;
+-------+-----------+------+-----+-------------------+-------+
| Field | Type      | Null | Key | Default           | Extra |
+-------+-----------+------+-----+-------------------+-------+
| id1   | timestamp | NO   |     | CURRENT_TIMESTAMP |       |
| id2   | datetime  | YES  |     | NULL              |       |
+-------+-----------+------+-----+-------------------+-------+
2 rows in set (0.01 sec)
-- 查看当前时区
mysql> show variables like 'time_zone';
+---------------+--------+
| Variable_name | Value  |
+---------------+--------+
| time_zone     | SYSTEM |
+---------------+--------+
1 row in set (0.01 sec)
-- 修改时区
mysql> set time_zone='+8:00';
Query OK, 0 rows affected (0.00 sec)mysql> select * from t8;
+---------------------+---------------------+
| id1                 | id2                 |
+---------------------+---------------------+
| 2021-02-15 22:13:17 | 2021-02-15 06:13:17 |
+---------------------+---------------------+
mysql> set time_zone='+9:00';
Query OK, 0 rows affected (0.00 sec)mysql> select * from t8;
+---------------------+---------------------+
| id1                 | id2                 |
+---------------------+---------------------+
| 2021-02-15 23:13:17 | 2021-02-15 06:13:17 |
+---------------------+---------------------+

TIMESTAMP的取值范围是1970-01-01 08:00:01到2038年某一天(东八区)。超过该范围时插入异常。

mysql> insert into t8(id1) values('1970-01-01 08:00:01');
Query OK, 1 row affected (0.00 sec)mysql> insert into t8(id1) values('1970-01-01 08:00:00');
ERROR 1292 (22007): Incorrect datetime value: '1970-01-01 08:00:00' for column 'id1' at row 1

2.选择原则

  • 根据需要选择满足应用的最小存储日期类型。如只需要记录年,则可以选择YEAR类型,不需要选择DATE类型。字节越少,节约存储,表的操作效率高
  • 日期存储如果跟时区有关,最好选择TIMESTAMP
  • 需要记录的年份比较久远,最好选择DATETIME。

三、字符串类型

1.简述

MySQL包含有多种字符串类型,如CHAR、VARCHAR、BINARY、VARBINARY、BLOB、TEXT、ENUM和SET等。下面介绍常用的CHAR、VARCHA、BLOB、TEXT。

类型 字节 描述
CHAR(M) M M为0~255之间的整数
VARCHAR(M) M为0~65535之间的整数,值的长度+1个字节
BLOB 允许长度0~65535字节,值的长度+2个字节
TEXT 允许长度0~65535字节,值的长度+2个字节

CHAR列的长度固定为创建表时声明的长度,而VARCHAR的长度为可变长度。在检索时,CHAR列删除了尾部空格,VARCHAR则保留了空格。

CHAR(4) 存储需求 VRACHAR(4) 存储需求
‘’ ‘’ 4个字节 ‘’ 1个字节
‘ab’ 'ab ’ 4个字节 ‘ab’ 3个字节
‘abcd’ ‘abcd’ 4个字节 ‘abcd’ 5个字节
mysql> create table vc(v VARCHAR(4),c CHAR(4));
Query OK, 0 rows affected (0.03 sec)
-- 插入具有空格的字符串
mysql> INSERT INTO vc VALUES('ab  ','ab  ');
Query OK, 1 row affected (0.00 sec)
-- char将尾部空格删除
mysql> select length(v),length(c) from vc;
+-----------+-----------+
| length(v) | length(c) |
+-----------+-----------+
|         4 |         2 |
+-----------+-----------+

BLOB能用来保存二进制数据,比如照片,而TEXT只能保存字符串数据,比如一篇文章或数据。
BLOB和TEXT值会引起一些性能问题,特别是执行大量操作后。

可以使用合成的索引来提高大文本字段(BLOB和TEXT)的查询性能。简单来说就是根据大文本字段的内容建立一个散列值,并把这个值存在单独的数据列中,查找时通过散列值进行查找,不过这样处理后只能使用精确查找。

mysql> create table blob_test(id varchar(100),context blob,hash_value varchar(40));
Query OK, 0 rows affected (0.03 sec)
-- 通过repeat函数重复创建
mysql> insert into blob_test values(1,repeat('helloworld',2),md5(context));
Query OK, 1 row affected (0.00 sec)mysql> insert into blob_test values(2,repeat('helloworld',2),md5(context));
Query OK, 1 row affected (0.01 sec)mysql> insert into blob_test values(3,repeat('sayhelloworld',2),md5(context));
Query OK, 1 row affected (0.01 sec)
mysql> select * from blob_test;
+------+----------------------------+----------------------------------+
| id   | context                    | hash_value                       |
+------+----------------------------+----------------------------------+
| 1    | helloworldhelloworld       | 8be363cf63c20050aaad7dbe737acd73 |
| 2    | helloworldhelloworld       | 8be363cf63c20050aaad7dbe737acd73 |
| 3    | sayhelloworldsayhelloworld | ae47ee207fdec31e2ba91c229f5963b7 |
+------+----------------------------+----------------------------------+-- 下面通过hash_value列查找'sayhelloworld'列
mysql> select * from blob_test where hash_value=md5(repeat('sayhelloworld',2));
+------+----------------------------+----------------------------------+
| id   | context                    | hash_value                       |
+------+----------------------------+----------------------------------+
| 3    | sayhelloworldsayhelloworld | ae47ee207fdec31e2ba91c229f5963b7 |
+------+----------------------------+----------------------------------+

可通过对BLOB或者TEXT字段建立前缀索引,对该字段进行模糊查询

mysql> create index idx_blob on blob_test(context(100));
Query OK, 0 rows affected (0.06 sec)
Records: 0  Duplicates: 0  Warnings: 0mysql> desc select * from blob_test where context like 'hello%'\G;
*************************** 1. row ***************************id: 1select_type: SIMPLEtable: blob_testpartitions: NULLtype: range
possible_keys: idx_blobkey: idx_blob -- 使用了索引key_len: 103ref: NULLrows: 2filtered: 100.00Extra: Using where
1 row in set, 1 warning (0.01 sec)

2.选择原则

  • InnoDB存储引擎下,建议使用VARCHAR类型
  • MyISAM存储引擎建议使用固定长度的数据列
  • BLOB和TEXT注意删除后的性能问题,可通过OPTIMIZE TABLE 命令进行整理
  • BLOB和TEXT,可通过建立前缀索引,为前n为建立索引,增加模糊查询。
  • 在不必要的时候避免检索BLOB和TEXT字段

总结

本文主要介绍了MySQL的常用数据类型,并总结了在创建表时选择数据类型的一些注意事项

MySQL选择合适的数据类型相关推荐

  1. 在mysql中什么情况下不能指定字符集_如何为Mysql选择合适的字符集?

    MySQL服务器可以支持多种字符集,在同一台服务器,同一个数据库,甚至同一个表的不同字段都可以指定使用不同的字符集,相比Oracle等其他数据库管理系统,在同一个数据库只能使用相同的字符集,MySQL ...

  2. 为MySQL选择合适的备份方式

    2019独角兽企业重金招聘Python工程师标准>>> 数据库的备份是极其重要的事情.如果没有备份,遇到下列情况就会抓狂: UPDATE or DELETE whitout wher ...

  3. mysql中辅导方式选择_MYSQL中如何选择合适的数据类型

    数值,典型代表为 tinyint,int,bigint 浮点/定点,典型代表为 float,double,decimal 以及相关的同义词 字符串,典型代表为 char,varchar 时间日期,典型 ...

  4. mysql中的字段如何选择合适的数据类型呢?

    前面两篇我们介绍了很多种数据类型,那么有没有看花眼呢,我们在mysql中创建数据表的时候,到底应该选择哪一种数据类型呢?这次我们就来简单的梳理一下子把. 准则 我们不论要如何创建数据表,首先我们需要一 ...

  5. mysql中gender要用什么类型,如何选择合适的MySQL数据类型

    一.MySQL数据类型选择原则 更小的通常更好:一般情况下选择可以正确存储数据的最小数据类型.越小的数据类型通常更快,占用磁盘,内存和CPU缓存更小. 简单就好:简单的数据类型的操作通常需要更少的CP ...

  6. 如何为MySQL选择更合适的数据类型

    更小的通常更好 在表设计最开始之初,我认为这里的选择合适的数据类型是非常关键的,他可以尽可能减轻数据库的硬盘占用,和在查询的过程中越简单越小的数据类型则需要的占用了更小的cpu缓存,内存,硬盘,和相对 ...

  7. mysql访问类型最好的_【干货满满】最全的MySQL性能指南(一):选择最佳的数据类型...

    对于 MySQL 数据库来说,好的逻辑表和物理表的规划至关重要,我们需要根据查询语句来针对性地设计 Schema ,没有万能好用的 Schema.一个 denormalized 的 schema 可以 ...

  8. MYSQL建表时数据类型的选择

    1.为表中的字段选择合适的数据类型 当一个列可以选择多种数据类型时,应该优先考虑数字类型,其次是日期或二进制类型,最后是字符类型. 对于相同级别的数据类型,应该优先选择占用空间小的数据类型. 2.如何 ...

  9. mysql数据库中文选什么数据类型_数据库MySQL-选择合适的数据类型

    三.数据库结构的优化 1.选择合适的数据类型 1.数据类型选择 数据类型的选择,重点在于"合适"二字,如何确定选择的数据类型是否合适了? 1.使用可以存下你的数据的最小的数据类型. ...

  10. mysql 更新日的数据类型_[每日更新-MySQL基础]5.常用的数据类型-整数和字符串

    1.    数据类型 在学习PHP的时候我们已经讲过数据类型了,所谓数据类型就是数据的格式.每一种数据类型在计算机中存储的方式会有差异,占用的存储容量也有区别,所以选择合适的数据类型可以节约我们的存储 ...

最新文章

  1. java 图片手动切换_JavaScript学习案例之手动切换轮播图片
  2. 循环神经网络-Dropout
  3. 解题报告 『[NOI2014]起床困难综合症』
  4. 用VisualVM和JConsole监控tomcat性能
  5. angular6继承类注意几点:
  6. 查询分析300万笔记录_给你100万条数据的一张表,你将如何查询优化?
  7. 如何区分localhost、127.0.0.1和0.0.0.0等ip地址
  8. 网络编程1-初探winSocket
  9. DatabaseMetaData的用法(转)
  10. 回顾频谱图卷积的经典工作:从ChebNet到GCN
  11. okHttp3自用封装
  12. Lidar Studio点云处理与分析软件V1.1
  13. 怎么用Canoe CAPL发送诊断
  14. 1-10 图灵测试:机器会思考吗? (笔记)
  15. matlab+yalmip+mosek/cplex安装配置
  16. python图像纹理提取_图像处理7 LBP纹理特征提取
  17. 文档透明加密底层安全机制
  18. gogs mail 配置(邮件服务器使用自颁发证书)
  19. Jetson Nano 按键切换摄像头
  20. 铁甲雄心机器人冠军_《铁甲雄心》第二季首播 优必选科技引领中国AI机器人进击之路...

热门文章

  1. MagicAjax C#版试用手记
  2. 使用ts 引入组件_Cocos技术派 | TS版属性面板定义高级篇
  3. Spring IOC源码笔记(二)
  4. 分布式事务解决方案之TX-LCN的使用
  5. Redis实现分布式session功能的共享
  6. Halcon之 Variation Model(转)
  7. Open***服务器端配置文件server.conf的说明
  8. python基础——map/reduce
  9. Python 的 MySQL 模块
  10. 关于vs08生成解决方案慢的解决方法