MySQL选择合适的数据类型
文章目录
- 前言
- 一、数值类型
- 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选择合适的数据类型相关推荐
- 在mysql中什么情况下不能指定字符集_如何为Mysql选择合适的字符集?
MySQL服务器可以支持多种字符集,在同一台服务器,同一个数据库,甚至同一个表的不同字段都可以指定使用不同的字符集,相比Oracle等其他数据库管理系统,在同一个数据库只能使用相同的字符集,MySQL ...
- 为MySQL选择合适的备份方式
2019独角兽企业重金招聘Python工程师标准>>> 数据库的备份是极其重要的事情.如果没有备份,遇到下列情况就会抓狂: UPDATE or DELETE whitout wher ...
- mysql中辅导方式选择_MYSQL中如何选择合适的数据类型
数值,典型代表为 tinyint,int,bigint 浮点/定点,典型代表为 float,double,decimal 以及相关的同义词 字符串,典型代表为 char,varchar 时间日期,典型 ...
- mysql中的字段如何选择合适的数据类型呢?
前面两篇我们介绍了很多种数据类型,那么有没有看花眼呢,我们在mysql中创建数据表的时候,到底应该选择哪一种数据类型呢?这次我们就来简单的梳理一下子把. 准则 我们不论要如何创建数据表,首先我们需要一 ...
- mysql中gender要用什么类型,如何选择合适的MySQL数据类型
一.MySQL数据类型选择原则 更小的通常更好:一般情况下选择可以正确存储数据的最小数据类型.越小的数据类型通常更快,占用磁盘,内存和CPU缓存更小. 简单就好:简单的数据类型的操作通常需要更少的CP ...
- 如何为MySQL选择更合适的数据类型
更小的通常更好 在表设计最开始之初,我认为这里的选择合适的数据类型是非常关键的,他可以尽可能减轻数据库的硬盘占用,和在查询的过程中越简单越小的数据类型则需要的占用了更小的cpu缓存,内存,硬盘,和相对 ...
- mysql访问类型最好的_【干货满满】最全的MySQL性能指南(一):选择最佳的数据类型...
对于 MySQL 数据库来说,好的逻辑表和物理表的规划至关重要,我们需要根据查询语句来针对性地设计 Schema ,没有万能好用的 Schema.一个 denormalized 的 schema 可以 ...
- MYSQL建表时数据类型的选择
1.为表中的字段选择合适的数据类型 当一个列可以选择多种数据类型时,应该优先考虑数字类型,其次是日期或二进制类型,最后是字符类型. 对于相同级别的数据类型,应该优先选择占用空间小的数据类型. 2.如何 ...
- mysql数据库中文选什么数据类型_数据库MySQL-选择合适的数据类型
三.数据库结构的优化 1.选择合适的数据类型 1.数据类型选择 数据类型的选择,重点在于"合适"二字,如何确定选择的数据类型是否合适了? 1.使用可以存下你的数据的最小的数据类型. ...
- mysql 更新日的数据类型_[每日更新-MySQL基础]5.常用的数据类型-整数和字符串
1. 数据类型 在学习PHP的时候我们已经讲过数据类型了,所谓数据类型就是数据的格式.每一种数据类型在计算机中存储的方式会有差异,占用的存储容量也有区别,所以选择合适的数据类型可以节约我们的存储 ...
最新文章
- java 图片手动切换_JavaScript学习案例之手动切换轮播图片
- 循环神经网络-Dropout
- 解题报告 『[NOI2014]起床困难综合症』
- 用VisualVM和JConsole监控tomcat性能
- angular6继承类注意几点:
- 查询分析300万笔记录_给你100万条数据的一张表,你将如何查询优化?
- 如何区分localhost、127.0.0.1和0.0.0.0等ip地址
- 网络编程1-初探winSocket
- DatabaseMetaData的用法(转)
- 回顾频谱图卷积的经典工作:从ChebNet到GCN
- okHttp3自用封装
- Lidar Studio点云处理与分析软件V1.1
- 怎么用Canoe CAPL发送诊断
- 1-10 图灵测试:机器会思考吗? (笔记)
- matlab+yalmip+mosek/cplex安装配置
- python图像纹理提取_图像处理7 LBP纹理特征提取
- 文档透明加密底层安全机制
- gogs mail 配置(邮件服务器使用自颁发证书)
- Jetson Nano 按键切换摄像头
- 铁甲雄心机器人冠军_《铁甲雄心》第二季首播 优必选科技引领中国AI机器人进击之路...