概述

MySQL支持很多数据类型,以便我们能在复杂的业务场景中支持各种各样的数据格式,存储适当的数据内容。我们在设计数据库时,正确的使用数据库类型对整个数据库的整洁和高效,会有很大的帮助。

目前常用的数据类型大致上可以分为4大类:整数类型、浮点数类型、字符串(字符)类型、日期/时间类型。详细如下

4大类 主要类型
整数类型 tinyint 、 smallint 、 mediumint 、 int 、 bigint

浮点数类型

float 、 double 、 decimal
字符串(字符)类型 char 、 varchar 、 tinyblob 、 blob 、 mediumblob 、 longblob 、tinytext 、 text 、 mediumtext 、 longtext

日期/时间类型 Date 、 DateTime 、 TimeStamp 、 Time 、 Year

数值类型

MySQL支持所有标准SQL数值数据类型,包括严格数值数据类型(INTEGER、SMALLINT、DECIMAL和NUMERIC),还有近似数值数据类型(FLOAT、REAL和DOUBLE PRECISION),所以MySQL中数据类型是丰富且完整的。

而作为SQL标准的扩展,MySQL也支持整数类型TINYINT、MEDIUMINT和BIGINT。在下面的表格中,我们总结了5个整数类型的存储大小和取值范围。

类型 字节数 有符号值范围 无符号值范围 作用
TINYINT 1 byte (-128,127)   (0,255) 小整数值
SMALLINT 2 bytes (-32 768,32 767) (0,65 535) 大整数值
MEDIUMINT 3 bytes (-8 388 608,8 388 607) (0,16 777 215) 大整数值
INT或INTEGER 4 bytes (-2 147 483 648,2 147 483 647) (0,4 294 967 295) 大整数值
BIGINT 8 bytes (-9,223,372,036,854,775,808,9 223 372 036 854 775 807) (0,18 446 744 073 709 551 615) 极大整数值

我们创建表赋予的类型默认是有符号类型的,无符号的需要在类型需要后面跟上unsigned 标记,上面的数据范围是根据字节对应二进制换算,比如一个字节转化为十进制最大为255(11111111),最小为0(00000000),具体可以去查下二进制表示相关资料。

测试一下:

 1 mysql> create table tinyintdemo(
2 tiny TINYINT,
3 tinyunsi TINYINT UNSIGNED
4 );
5 Query OK, 0 rows affected
6
7 mysql> insert into tinyintdemo values(-128,-128);
8 1264 - Out of range value for column 'tinyunsi' at row 1
9 mysql> insert into tinyintdemo values(-128,0);
10 Query OK, 1 row affected
11
12 mysql> insert into tinyintdemo values(255,255);
13 1264 - Out of range value for column 'tiny' at row 1
14 mysql> insert into tinyintdemo values(127,255);
15 Query OK, 1 row affected

上面我们故意输入不正确的值,无符号下我们输入-128,默认有符号情况下我们输入255,都会提示 Out of range,超出范围。

1 mysql> select *  from  tinyintdemo;
2 +------+----------+
3 | tiny | tinyunsi |
4 +------+----------+
5 | -128 | 0 |
6 | 127 | 255 |
7 +------+----------+
8 2 rows in set

另外需注意的点:我们经常在创建表的时候定义字段为int(n),比如int(11) , 或者bitint(19) , 其实这不是描述字段长度的意思,在int(n)中,int占据的字节是固定4个,所以他的范围也固定是在 (-2 147 483 648,2 147 483 647) 之间,

并不会因为n的长度是多少而改变,而n的目的是为了表实显示宽度用的,在显示宽度不足的时候补充0。

再测试一下:

 1 mysql> CREATE TABLE lengthdemo (
2 `nor` int,
3 `norlen` int(8),
4 `norfill` int(8) zerofill
5 );
6 Query OK, 0 rows affected
7
8 mysql> insert into lengthdemo values(12345,12345,12345);
9 Query OK, 1 row affected
10
11 mysql> select * from lengthdemo;
12
13 +-------+--------+---------+
14 | nor | norlen | norfill |
15 +-------+--------+---------+
16 | 12345 | 12345 |00012345 |
17 +-------+--------+---------+
18 1 row in set
19
20 mysql> show create table lengthdemo;
21 +------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
22 | Table | Create Table |
23 +------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
24 | lengthdemo | CREATE TABLE `lengthdemo` (
25 `nor` int(11) DEFAULT NULL,
26 `norlen` int(8) DEFAULT NULL,
27 `norfill` int(8) unsigned zerofill DEFAULT NULL
28 ) ENGINE=InnoDB DEFAULT CHARSET=latin1 |
29 +------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
30 1 row in set

从这个执行结果中,我们可以总结如下:

1、n的值不管填写多少,int类型只占据4个字节。

2、如果设置了n的显示宽度之后,再加上unsigned zerofill,显示宽度不足的用0补足,超过则直接显示完整数值。

3、加 zerofill属性的字段,会默认为 unsigned 无符号类型。

浮点类型

float数值类型表示单精度浮点数值,double数值类型表示双精度浮点数值,float和double都是浮点型,而decimal是定点型。浮点型和定点型可以用类型名称后加(M,D)来表示,M表示该值的总共长度,D表示小数点后面的长度,M和D又称为精度和标度。

float和double在不指定精度时,默认会按照实际的精度来显示,而DECIMAL在不指定精度时,默认整数为10,小数为0。

类型 大小 有符号值范围 无符号值范围 作用
FLOAT 4 bytes (-3.402 823 466 E+38,-1.175 494 351 E-38),0,(1.175 494 351 E-38,3.402 823 466 351 E+38) 0,(1.175 494 351 E-38,3.402 823 466 E+38) 单精度
浮点数值
DOUBLE 8 bytes (-1.797 693 134 862 315 7 E+308,-2.225 073 858 507 201 4 E-308),0,(2.225 073 858 507 201 4 E-308,1.797 693 134 862 315 7 E+308) 0,(2.225 073 858 507 201 4 E-308,1.797 693 134 862 315 7 E+308) 双精度
浮点数值
DECIMAL 对DECIMAL(M,D) ,如果M>D,为M+2否则为D+2 依赖于M和D的值 依赖于M和D的值 小数值

浮点型和定点型可以用类型名称后加(M,D)来表示,M表示该值的总共长度,D表示小数点后面的长度,M和D又称为精度和标度。

float和double在不指定精度时,默认会按照实际的精度来显示,而DECIMAL在不指定精度时,默认只取整数,小数丢弃。

同样的,我们来测试下三个类型的使用:

 1 mysql> insert into accuracy values (1,1,1),(2.124,2.124,2.124),(3.125,3.125,3.125),(4.115,4.115,4.115),(5.136,5.136,5.136);
2 Query OK, 5 rows affected, 4 warnings (0.07 sec)
3 Records: 5 Duplicates: 0 Warnings: 4
4
5 mysql> select * from accuracy;
6 +------+------+------+
7 | a | b | c |
8 +------+------+------+
9 | 1.00 | 1.00 | 1.00 |
10 | 2.12 | 2.12 | 2.12 |
11 | 3.12 | 3.12 | 3.13 |
12 | 4.12 | 4.12 | 4.12 |
13 | 5.14 | 5.14 | 5.14 |
14 +------+------+------+
15 5 rows in set (0.00 sec)

从这个执行结果,总结如下:

1、c是decimal类型,采用的是四舍五入

2、a和b分别为float 和double,采用的是四舍六入五成双

说明下四舍六入五成双:5以下舍弃,5以上进位,遇到5的时候,如果5后面还有不为0的任何数字,进位,如果没有,需要检查5前面的数字,奇数进位,偶数丢弃,观察结果中 3.125和4.115,可以得到规律。

我们再将浮点类型的(M,D)精度和标度都去掉,结果如下:

 1 mysql> create table accuracy2(a float,b double,c decimal);
2 Query OK, 0 rows affected
3
4 mysql> insert into accuracy2 values (1,1,1),(1.23,1.23,1.23);
5 Query OK, 2 rows affected
6 Records: 2 Duplicates: 0 Warnings: 1
7
8 mysql> select * from accuracy2;
9 +------+------+---+
10 | a | b | c |
11 +------+------+---+
12 | 1 | 1 | 1 |
13 | 1.23 | 1.23 | 1 |
14 +------+------+---+
15 2 rows in set

总结如下:

如果浮点数float、double如果不写精度和标度,则会按照实际的结果显示,而decimal会将小数四舍五入,并且插入时发出警告信息。

float,double等非标准类型,在DB中保存的是近似值,而decimal则以字符串的形式保存准确的数值,比如银行、金融系统之类的对统计精度要求比较高的,建议采用decimal。

日期和时间类型

表示时间值的日期和时间类型为DATETIME、DATE、TIMESTAMP、TIME和YEAR。每个时间类型有一个有效值范围和一个"零"值,当指定不合法的MySQL不能表示的值时使用"零"值。

TIMESTAMP类型有专有的自动更新特性,将在后面描述。

类型 大小 值范围 格式 作用
DATE 3 bytes 1000-01-01/9999-12-31 YYYY-MM-DD 日期值
TIME 3 bytes '-838:59:59'/'838:59:59' HH:MM:SS 时间值或持续时间
YEAR 1 bytes 1901/2155 YYYY 年份值
DATETIME 8 bytes 1000-01-01 00:00:00/9999-12-31 23:59:59 YYYY-MM-DD HH:MM:SS 混合日期和时间值
TIMESTAMP 4 bytes

1970-01-01 00:00:00/2038

结束时间是第 2147483647 秒,北京时间 2038-1-19 11:14:07,格林尼治时间 2038年1月19日 凌晨 03:14:07

YYYYMMDD HHMMSS 混合日期和时间值,时间戳

字符串类型

字符串类型指CHAR、VARCHAR、BINARY、VARBINARY、BLOB、TEXT、ENUM和SET。

类型 大小 作用
CHAR 0-255 bytes 定长字符串
VARCHAR 0-65535 bytes 变长字符串
TINYBLOB 0-255 bytes 不超过 255 个字符的二进制字符串
TINYTEXT 0-255 bytes 短文本字符串
BLOB 0-65 535 bytes 二进制形式的长文本数据
TEXT 0-65 535 bytes 长文本数据
MEDIUMBLOB 0-16 777 215 bytes 二进制形式的中等长度文本数据
MEDIUMTEXT 0-16 777 215 bytes 中等长度文本数据
LONGBLOB 0-4 294 967 295 bytes 二进制形式的极大文本数据
LONGTEXT 0-4 294 967 295 bytes 极大文本数据

注意点:

1、CHAR(N) 和 VARCHAR(N) 中N代表字符的个数,但并不代表字节个数,比如 CHAR(10) 代表可以存储 10 个字符。

2、CHAR 和VARCHAR类型类似,但它们保存和检索的方式不同,最大长度和是否尾部空格被保留等方面也不同,同时在存储或检索过程中不进行大小写转换。

如果存放的数据为固定长度的建议使用char类型,如:手机号码、身份证等固定长度的信息。

3、BINARY 和 VARBINARY 类似于 CHAR 和 VARCHAR,不同的是它们包含二进制字符串而不要非二进制字符串。它们包含字节字符串而不是字符字符串。这说明它们没有字符集,并且排序和比较基于列值字节的数值。

4、BLOB是一个二进制大对象,可以容纳可变数量的数据,包含4 种类型:TINYBLOB、BLOB、MEDIUMBLOB 和 LONGBLOB,区别是可容纳存储范围不同。

5、TEXT 类型:TINYTEXT、TEXT、MEDIUMTEXT 和 LONGTEXT。对应的这 4 种 BLOB 类型,可存储的最大长度不同,可根据实际业务场景的选择。

MySQL、Java类型对照

MySQL Type Name Return value
ofGetColumnClassName
Returned as Java Class
BIT(1) (new in MySQL-5.0) BIT java.lang.Boolean
BIT( > 1) (new in MySQL-
5.0)
BIT byte[]
TINYINT TINYINT java.lang.Boolean if the configuration
property tinyInt1isBit is set to true (the
default) and the storage size is 1,
or java.lang.Integer if not.
BOOL, BOOLEAN TINYINT See TINYINT, above as these are aliases
forTINYINT(1), currently.
SMALLINT[(M)]
[UNSIGNED]
SMALLINT [UNSIGNED] java.lang.Integer (regardless if
UNSIGNED or not)
MEDIUMINT[(M)]
[UNSIGNED]
MEDIUMINT [UNSIGNED] java.lang.Integer, if
UNSIGNED java.lang.Long
INT,INTEGER[(M)]
[UNSIGNED]
INTEGER [UNSIGNED] java.lang.Integer , if
UNSIGNED java.lang.Long
BIGINT[(M)] [UNSIGNED] BIGINT [UNSIGNED] java.lang.Long , if
UNSIGNED java.math.BigInteger
FLOAT[(M,D)] FLOAT java.lang.Float
DOUBLE[(M,B)] DOUBLE java.lang.Double
DECIMAL[(M[,D])] DECIMAL java.math.BigDecimal
a
DATE DATE java.sql.Date
Ja
DATETIME DATETIME java.sql.Timestamp
TIMESTAMP[(M)] TIMESTAMP java.sql.Timestamp
TIME TIME java.sql.Time
YEAR[(2|4)]
YEAR
If yearIsDateType configuration property
is set to false, then the returned object type
is java.sql.Short . If set to true (the
default) then an object of type
java.sql.Date (with the date set to
January 1st, at midnight).
CHAR(M) CHAR java.lang.String (unless the character
set for the column is BINARY, then byte[] is
returned.
VARCHAR(M) [BINARY] VARCHAR java.lang.String (unless the character
set for the column is BINARY, then byte[] is
returned.
BINARY(M) BINARY byte[]
VARBINARY(M) VARBINARY byte[]
TINYBLOB TINYBLOB byte[]
TINYTEXT VARCHAR java.lang.String
BLOB BLOB byte[]
MySQL Type Name Return value
ofGetColumnClassName
Returned as Java Class
TEXT VARCHAR java.lang.String
MEDIUMBLOB MEDIUMBLOB byte[]
MEDIUMTEXT VARCHAR java.lang.String
LONGBLOB LONGBLOB byte[]
LONGTEXT VARCHAR java.lang.String
ENUM('value1','value2',...) CHAR java.lang.String
SET('value1','value2',...) CHAR java.lang.String

使用建议

不建议选择较大的数值范围,尽量选择合适的数据范围,越小的数据类型会更快,占用磁盘,内存和CPU缓存也更小。

越简单的类型执行的成本越低,比如整型比字符类型操作代价要小得多,很多固定范围的文本内容字段可以用整型表示。

尽量制定列为NOT NULL,有NULL的列值会使得索引、索引统计和值比较更加复杂。

浮点类型的建议统一选择decimal,精度会好很多。

记录时间的建议使用时间戳格式,存储方便,索引高效

MySQL全面瓦解3:数据类型介绍与分析的更多相关文章

  1. Mysql Binlog三种格式介绍及分析【转】

    一.Mysql Binlog格式介绍       Mysql binlog日志有三种格式,分别为Statement,MiXED,以及ROW! 1.Statement:每一条会修改数据的sql都会记录在 ...

  2. Mysql Binlog 三种格式介绍及分析

    一.Mysql Binlog格式介绍       Mysql binlog日志有三种格式,分别为Statement,MiXED,以及ROW! 1.Statement:每一条会修改数据的sql都会记录在 ...

  3. MySQL Binlog三种格式介绍及分析

    Mysql binlog日志有三种格式,分别为Statement,MiXED,以及ROW! 1.Statement:每一条会修改数据的sql都会记录在binlog中. 优点:不需要记录每一行的变化,减 ...

  4. MySQL全面瓦解25:构建高性能索引(案例分析篇)

    回顾一下上面几篇索引相关的文章: MySQL全面瓦解22:索引的介绍和原理分析 MySQL全面瓦解23:MySQL索引实现和使用 MySQL全面瓦解24:构建高性能索引(策略篇) 索引的十大原则 1. ...

  5. MySQL:数据类型介绍

    数据类型介绍 一.整数类型(可以添加自增约束条件) 数据类型 存储需要 有符号 无符号 tinyint 1个字节 -2^7~2^7-1 0~2^8 smallint 2个字节 -2^15~2^15-1 ...

  6. MySQL全面瓦解24:构建高性能索引(策略篇)

    学习如果构建高性能的索引之前,我们先来了解下之前的知识,以下两篇是基础原理,了解之后,对面后续索引构建的原则和优化方法会有更清晰的理解: MySQL全面瓦解22:索引的介绍和原理分析 MySQL全面瓦 ...

  7. mysql基础之基本数据类型

    原文:mysql基础之基本数据类型 列类型学习 mysql三大列类型 整型 Tinyint/ smallint/ mediumint/int/ bigint(M) unsigned zerofill ...

  8. MySQL 通用查询日志和慢查询日志分析

    MySQL中的日志包括:错误日志.二进制日志.通用查询日志.慢查询日志等等.这里主要介绍下比较常用的两个功能:通用查询日志和慢查询日志. 1)通用查询日志:记录建立的客户端连接和执行的语句.2)慢查询 ...

  9. 关于MySQL 通用查询日志和慢查询日志分析

    MySQL中的日志包括:错误日志.二进制日志.通用查询日志.慢查询日志等等.这里主要介绍下比较常用的两个功能:通用查询日志和慢查询日志. 1)通用查询日志:记录建立的客户端连接和执行的语句. 2)慢查 ...

随机推荐

  1. Mac 系统下如何显示和隐藏文件

    苹果Mac OS X操作系统下,隐藏文件是否显示有很多种设置方法,最简单的要算在Mac终端输入命令.显示/隐藏Mac隐藏文件命令如下(注意其中的空格并且区分大小写): 第一种方式: 显示Mac隐藏文件 ...

  2. 2020 CiGA Game Jam活动总结

    CiGA Game Jam 总结 今年8月14.15.16号,48小时游戏开发--Game Jam开始了.蠢新第一次参加Game Jam,今年还是线上开展,情绪复杂= = 还有一个坏消息,晓航旅游缺席 ...

  3. nginx 1.12 负载均衡配置

    负载均衡策略有以下几种: 请求轮询:round-robin,是默认策略,应用服务器的请求以循环方式分发,可以设置权重weight,默认权重均为1,因此每台后端服务器接受的请求数相同. 最少连接:lea ...

  4. Python-去除字符串中不想要的字符

    问题: 过滤用户输入中前后多余的空白字符 '    ++++abc123---    ' 过滤某windows下编辑文本中的'\r': 'hello world \r\n' 去掉文本中unicode组 ...

  5. Clover 引导 Windows 及 Linux 双系统

    Clover 引导 Windows 及 Linux 双系统UEFI cnblogs @ Orcim  此 文比较详细地介绍了通过修改 Clover 的配置文件,添加 Clover 启动项的方法(添加 ...

  6. 002 01 Android 零基础入门 01 Java基础语法 01 Java初识 02 Java简介

    002 01 Android 零基础入门 01 Java基础语法 01 Java初识 02 Java简介 学习Java的基础语法 Java是一门编程语言,学习的逻辑其实和现实世界的语言是一样的,需要了 ...

  7. JavaScript innerTHML和createElement效率对比

    前言: 在DOM节点操作中,innerTHML和createElement都可以实现创建元素.它们实现的功能类似,但是效率却相差很大.本文分别统计用innerTHML字符串拼接方式.innerTHML ...

  8. 【小白学PyTorch】21 Keras的API详解(上)卷积、激活、初始化、正则

    [新闻]:机器学习炼丹术的粉丝的人工智能交流群已经建立,目前有目标检测.医学图像.时间序列等多个目标为技术学习的分群和水群唠嗑答疑解惑的总群,欢迎大家加炼丹兄为好友,加入炼丹协会.微信:cyx6450 ...

  9. php curl 获取请求头与DNS解析

    1 php-curl方法相关设置具体方法在最下方的示例函数有相关编著, 这里主要描述两个小众需求a 设置访问DNS解析问题点: get请求网页获取返回值速度很快, 但是使用curl请求数据时, 响应速 ...

  10. day11 Pyhton学习

    一.昨日内容回顾 函数的进阶 动态传参 *args : 位置参数的动态传参 **kwargs: 关键字参数的动态传参 形参:聚合 实参:打散 顺序:位置参数>*args >默认值 > ...