• 【MySQL】MySQL数据类型


    1. 数据类型总览

    类型类型举例
    整数类型TINYINT、SMALLINT、MEDIUMINT、INT(或INTEGER)、BIGINT
    浮点类型FLOAT、DOUBLE
    定点数类型DECIMAL
    位类型BIT
    日期时间类型YEAR、TIME、DATE、DATETIME、TIMESTAMP
    文本字符串类型CHAR、VARCHAR、TINYTEXT、TEXT、MEDIUMTEXT、LONGTEXT
    枚举类型ENUM
    集合类型SET
    二进制字符串类型BINARY、VARBINARY、TINYBLOB、BLOB、MEDIUMBLOB、LONGBLOB
    JSON类型JSON对象、JSON数组
    空间数据类型单值类型:GEOMETRY、POINT、LINESTRING、POLYGON;
    集合类型:MULTIPONINT、MULTILINESTRING、MULTIPOLYGON、GEOMETRYCOLLECTION;

    2. 整数类型

    整数类型字节有符号数取值范围无符号数取值范围适用场景
    TININT1-128~1270~255一般用于枚举数据,比如系统设定取值范围很小且固定的场景
    SMALLINT2-32768~327670~65535可以用于较小范围的统计数据,比如统计工厂的固定资产库存数量等
    MEDIUMENT3-8388608~83886070~16777215用于较大整数的计算,比如车站每日的客流量等
    INT、INTEGER4-2147483648~21474836470~4294967295取值范围足够大,一般情况下不用考虑超限问题,用得最多。比如商品编号
    BIGINT8-9223372036854775808~92233720368547758070~18446744073709551615只有当你处理特别巨大的整数时才会用到。比如双十一的交易量、大型门户网站点击量、证券公司衍生产品持仓等

    M : 表示显示宽度,M的取值范围是(0, 255)。例如,int(5):当数据宽度小于5位的时候在数字前面需要用字符填满宽度。该项功能需要配合“ ZEROFILL ”使用,表示用“0”填满宽度,否则指定显示宽度无效。

    如果设置了显示宽度,那么插入的数据宽度超过显示宽度限制,会不会截断或插入失败?

    答案:不会对插入的数据有任何影响,还是按照类型的实际宽度进行保存,即 显示宽度与类型可以存储的值范围无关 。从MySQL 8.0.17开始,整数数据类型不推荐使用显示宽度属性

    选用类型标准:

    在实际工作中,系统故障产生的成本远远超过增加几个字段存储空间所产生的成本。因此,我建议你首先确保数据不会超过取值范围,在这个前提之下,再去考虑如何节省存储空间

    3. 浮点数类型

    从MySQL 8.0.17开始,FLOAT(M,D) 和DOUBLE(M,D)用法在官方文档中已经明确不推荐使用,将来可能被移除。另外,关于浮点型FLOAT和DOUBLE的UNSIGNED也不推荐使用了,将来也可能被移除

    浮点数类型有个缺陷,就是不精准。

    MySQL 用 4 个字节存储 FLOAT 类型数据,用 8 个字节来存储 DOUBLE 类型数据。无论哪个,都是采用二进制的方式来进行存储的。比如 9.625,用二进制来表达,就是 1001.101,或者表达成 1.001101×2^3。如果尾数不是 0 或 5(比如 9.624),你就无法用一个二进制数来精确表达。进而,就只好在取值允许的范围内进行四舍五入。

    在编程中,如果用到浮点数,要特别注意误差问题,因为浮点数是不准确的,所以我们要避免使用“=”来判断两个数是否相等。同时,在一些对精确度要求较高的项目中,千万不要使用浮点数,不然会导致结果错误,甚至是造成不可挽回的损失。那么,MySQL 有没有精准的数据类型呢?当然有,这就是定点数类型: DECIMAL

    4. 定点数类型

    定点数类型字节取值范围
    DECIMAL(M,D)M+2字节有效范围由M和D决定
    • 使用 DECIMAL(M,D) 的方式表示高精度小数。其中,M被称为精度,D被称为标度。0<=M<=65,0<=D<=30,D
    • 定点数在MySQL内部是以 字符串 的形式进行存储,这就决定了它一定是精准的
    • 当DECIMAL类型不指定精度和标度时,其默认为DECIMAL(10,0)。当数据的精度超出了定点数类型的精度范围时,则MySQL同样会进行四舍五入处理

    5. 位类型

    BIT类型中存储的是二进制值,类似010110

    二进制字符串类型长度取值范围占用空间
    DECIMAL(M,D)M(默认1)1<=M<=64约为(M + 7)/8个字节
    • 可考虑用来做签到记录功能,如0101表示第一、三天未签到,第二四天有签到

    6. 日期与时间

    类型表示长度(字节)格式表示范围
    YEAR1YYYY或YY1901~2155
    TIME时间3HH:MM:SS-838:59:59~838:59:59
    DATE日期3YYYY-MM-SS1000-01-01~9999-12-03
    DATETIME日期 时间8YYYY-MM-DD HH:MM:SS1000-01-01 00:00:00~9999-12-31 23:59:59
    TIMESTAMP日期 时间4YYYY-MM-DD HH:MM:SS1970-01-01 00:00:00 UTC~2038-01-19 03:14:07 UTC
    • 为什么时间类型 TIME 的取值范围不是 -23:59:59~23:59:59 呢?原因是 MySQL 设计的 TIME 类型,不光表示一天之内的时间,而且可以用来表示一个时间间隔,这个时间间隔可以超过 24 小时

    • 从MySQL5.5.27开始,2位格式的YEAR已经不推荐使用。YEAR默认格式就是“YYYY”,没必要写成YEAR(4),
      从MySQL 8.0.19开始,不推荐使用指定显示宽度的YEAR(4)数据类型

    • TIMESTAMP类型也可以表示日期时间,其显示格式与DATETIME类型相同,都是 YYYY-MM-DD HH:MM:SS ,需要4个字节的存储空间。但是TIMESTAMP存储的时间范围比DATETIME要小很多,只能存储“1970-01-01 00:00:01 UTC”到“2038-01-19 03:14:07 UTC”之间的时间。其中,UTC表示世界统一时间,也叫作世界标准时间

      • TIMESTAMP存储数据的时候需要对当前时间所在的时区进行转换,查询数据的时候再将时间转换回当前的时区。因此,使用TIMESTAMP存储的同一个时间值,在不同的时区查询时会显示不同的时间
      • TIMESTAMP和时区有关。TIMESTAMP会根据用户的时区不同,显示不同的结果。而DATETIME则只能反映出插入时当地的时区,其他时区的人查看数据必然会有误差的
    • 在实际项目中,尽量用 DATETIME 类型。因为这个数据类型包括了完整的日期和时间信息,取值范围也最大,使用起来比较方便。毕竟,如果日期时间信息分散在好几个字段,很不容易记,而且查询的时候,SQL 语句也会更加复杂

    7. 文本字符串类型

    文本字符串类型值的长度长度范围占用的存储空间
    CHAR(M)M0<=M<=255M个字节
    VARCHAR(M)M0<=M<=65535M+1个字节
    TINYTEXTL0<=L<=255L+2个字节
    TEXTL0<=L<=65535L+2个字节
    MEDIUMTEXTL0<=L<=16777215L+3个字节
    LONGTEXTL0<=L<=4294967295L+4个字节
    ENUML1<=L<=655351或2个字节
    SETL0<=L<=641,2,3,4或8个字节

    7.1 CHAR与VARCHAR类型

    字符串类型特点长度占用的存储空间占用的存储空间
    CHAR(M)固定长度M0<=M<=255M个字节
    VARCHAR(M)可变长度M0<=M<=65535(实际长度+1)个字节
    • MySQL5.0版本以上,varchar(20):指的是20字符

    哪些情况使用 CHAR 或 VARCHAR 更好

    类型特点空间上时间上适用场景
    CHAR(M)固定长度浪费存储空间效率高存储不大,速度要求高
    VARCHAR(M)可变长度节省存储空间效率低非CHAR的情况
    • 情况1:存储很短的信息。比如门牌号码101,201……这样很短的信息应该用char,因为varchar还要占个byte用于存储信息长度,本来打算节约存储的,结果得不偿失
    • 情况2:固定长度的。比如使用UUID为主键
    • 情况3:十分频繁改变的column。因为varchar每次存储都要有额外的计算,得到长度等工作,如果一个非常频繁改变的,那就要有很多的精力用于计算,而这些对于char来说是不需要的
    • 情况4:具体存储引擎中的情况
      • MyISAM 数据存储引擎和数据列:MyISAM数据表,最好使用固定长度(CHAR)的数据列代替可变长度(VARCHAR)的数据列。这样使得整个表静态化,从而使数据检索更快 ,用空间换时间
      • MEMORY 存储引擎和数据列:MEMORY数据表目前都使用固定长度的数据行存储,因此无论使用CHAR或VARCHAR列都没有关系,两者都是作为CHAR类型处理的
      • InnoDB 存储引擎,建议使用VARCHAR类型。因为对于InnoDB数据表,内部的行存储格式并没有区分固定长度和可变长度列(所有数据行都使用指向数据列值的头指针),而且主要影响性能的因素是数据行使用的存储总量,由于char平均占用的空间多于varchar,所以除了简短并且固定长度的,其他考虑varchar。这样节省空间,对磁盘I/O和数据存储总量比较好

    7.2 TEXT类型

    文本字符串类型值的长度长度范围占用的存储空间特点
    TINYTEXTL0<=L<=255L+2个字节小文本、可变长度
    TEXTL0<=L<=65535L+2个字节文本、可变长度
    MEDIUMTEXTL0<=L<=16777215L+3个字节中等文本、可变长度
    LONGTEXTL0<=L<=4294967295L+4个字节大文本、可变长度
    • TEXT文本类型,可以存比较大的文本段,搜索速度稍慢,因此如果不是特别大的内容,建议使用CHAR,VARCHAR来代替
    • TEXT类型不用加默认值,加了也没用
    • text和blob类型的数据删除后容易导致“空洞”,使得文件碎片比较多,所以频繁使用的表不建议包含TEXT类型字段,建议单独分出去,单独用一个表

    7.3 ENUM类型

    不推荐使用

    7.4 SET类型

    和枚举类似,用的较少,故暂时跳过,待未来有需求时再考虑深入研究

    7.5 二进制字符串类型

    7.5.1 BINARY与VARBINARY类型

    BINARY和VARBINARY类似于CHAR和VARCHAR,只是它们存储的是二进制字符串

    二进制字符串类型特点值的长度占用空间
    BINARY(M)固定长度M(0<=M<=255)M个字节
    VARBINARY(M)可变长度M(0<=M<=65535)M+1个字节
    7.5.2 BLOB类型

    MySQL中的BLOB类型包括TINYBLOB、BLOB、MEDIUMBLOB和LONGBLOB 4种类型,它们可容纳值的最大长度不同。可以存储一个二进制的大对象,比如 图片音频视频

    需要注意的是,在实际工作中,往往不会在MySQL数据库中使用BLOB类型存储大对象数据,通常会将图片、音频和视频文件存储到 服务器的磁盘上 ,并将图片、音频和视频的访问路径存储到MySQL中

    二进制字符串类型值的长度长度范围占用的存储空间
    TINYBLOBL0 <= L <= 255L + 1 个字节
    BLOBL0 <= L <= 65535(相当于64KB)L + 2 个字节
    MEDIUMBLOBL0 <= L <= 16777215 (相当于16MB)L + 3 个字节
    LONGBLOBL0 <= L <= 4294967295(相当于4GB)L + 4 个字节

    7.6 TEXT和BLOB的使用注意事项

    • BLOB和TEXT值也会引起自己的一些问题,特别是执行了大量的删除或更新操作的时候。删除这种值会在数据表中留下很大的" 空洞 ",以后填入这些"空洞"的记录可能长度不同。为了提高性能,建议定期使用 OPTIMIZE TABLE 功能对这类表进行 碎片整理
    • 如果需要对大文本字段进行模糊查询,MySQL 提供了 前缀索引 。但是仍然要在不必要的时候避免检索大型的BLOB或TEXT值
    • 把BLOB或TEXT列 分离到单独的表 中。在某些环境中,如果把这些数据列移动到第二张数据表中,可以让你把原数据表中的数据列转换为固定长度的数据行格式,那么它就是有意义的。这会 减少主表中的碎片 ,使你得到固定长度数据行的性能优势。它还使你在主数据表上运行 SELECT * 查询的时候不会通过网络传输大量的BLOB或TEXT值

    8. JSON 类型

    不推荐使用,需要使用的话可以使用非关系型数据库如MongoDB/Redis

    9. 空间类型

    MySQL 空间类型扩展支持地理特征的生成、存储和分析。这里的地理特征表示世界上具有位置的任何东西,可以是一个实体,例如一座山;可以是空间,例如一座办公楼;也可以是一个可定义的位置,例如一个十字路口等等。MySQL中使用 Geometry(几何) 来表示所有地理特征。Geometry指一个点或点的集合,代表世界上任何具有位置的事物

    未使用到,且不具有普遍性,暂不深入

  • 相关阅读:
    springcloud相关面试题
    注意力机制的一种卷积替代方式
    Swift 5.7发布!2022年9月12日
    SV-- cast类型转换练习(8/26)
    ElasticSearch(一)
    企业微信员工能私加客户吗?员工私自联系客户企业是否知道?
    freemarker遍历list拼接成字符串(逗号分隔)
    【数据分析】数据分析达人赛2:产品关联分析
    【零基础入门MyBatis系列】第五篇——手写MyBatis框架
    Centos 安装 OpenLDAP
  • 原文地址:https://blog.csdn.net/xxx1276063856/article/details/133964766