• MySQL数据类型


    前言

    在一些小项目,对于性能要求不高的项目,可能不会太去在意数据类型的优化,能用就行,毕竟在小数据量目前这点消耗不大。

    但是,需要数据库大的话,千万、亿、十亿...,再往上往往一个很小的优化都能有较大的效果。高性能MySQL中有这么一句话:良好的逻辑设计和物理设计是高性能的基石。

    数据类型优化

    MySQL支持大量的数据类型,要设计一个优秀的表结构,需要选择正确的数据类型,来获得更高得性能。在数据类型选择时可以参考以下几个原则:

    • 最小数据类型:尽量使用可以正常存储数据得最小数据类型,可以用bool不要用int,可以int不用char。数据类型小,磁盘、内存、CPU占用就会小。
    • 简单就好:简单的数据类型CPU周期更少,比如日期应该使用mysql内置时间类型,ip地址应该使用int。
    • 避免null:可为null的列,会使得索引、索引统计和值比较都变得更加复杂,而且会占用更多的空间。

    整数类型

    MySQL中一共有以下几种保存整数的类型:

    • TINYINT:8位
    • SMALLINT:16位
    • MEDIUMINT:24位
    • INT:32位
    • BIGINT:64位

    整数类型可以选择UNSIGNED属性,表示不可以是负数。没有属性可以存储的值范围是-2^(N-1) - 2^(N-1)-1,选择了这属性的话就是0 - 2^N-1。有无UNSIGNED属性,使用相同的存储空间,具有相同的性能,根据实际情况进行选择。

    注意:MySQL可以位整数类型指定宽度(INT(11)),但是对于大多数应用这是没意义的,并不会限制值的范围或减少占用空间,它只是规定了一些交互工具显示字符的长度。

    小数类型

    MySQL支持精确类型,也支持不精确类型,在MySQL中一共有以下三种小数类型:

    • FLOAT:4字节
    • DOUBLE:8字节
    • DECIMAL:不定
      DECIMAL用于保存精确小数,支持精确计算。相对来说,CPU直接支持原生浮点计算,所以浮点计算速度会更快。

    注意:DECIMAL存储同意范围数据时,空间占用较高,计算开销较大。在不需要保证精确的情况下介意使用浮点型,在数据量大的时候,可以考虑使用整数代替。

    字符串类型

    CHAR与VARCHAR

    CHAR与VARCHAR是最重要的两种字符串类型
    ,但是这两种类型的存储读取和存储引擎相关,所以如果需要深入了解的话,需要参考使用的存储引擎文档。下面基于InnoDB与MyISAM简单记录一下这两种类型的不同:

    • VARCHAR:用于存储可变长字符串,相比CHAR定长字符串更加节省空间,但是更新的话需要做一些额外的工作。VARCHAR会使用1-2字节来记录字符串长度。
    • CHAR:定长字符串,适合存储较短字符串或者经常修改的字符串。

    注意:

    • 重要的放第一,尽量给字符串少分配空间。
    • 如果ROW_FORMAT被设置成了FIXED的话,VARCHAR也会成为定长字符串。
    • InnoDB存储引擎中,可以把过长的VARCHAR存储为BLOB。
    • CHAR类型存储时,MySQL会删除末尾空格。

    BLOB与TEXT

    BLOB与TEXT都是MySQL用来保存很大数据的字符串类型,其中BLOB以二进制方式存储,TEXT以字符方式存储。

    BLOB与TEXT其实属于不同数据类型家族,分别为TINYTEXT、SMALLTEXT、TEXT、MEDIUMTEXT、LONGTEXT的TEXT家族,和TINYBLOB、SMALLBLOB、BLOB、MEDIUMBLOB、LONGBLOB的BLOB家族。

    BLOB、TEXT类型和其他类型不同,MySQL会将它们作为一个独立对象处理,存储引擎在存储的时候通常也会做一些特殊处理。当值太大的时候,InnoDB会使用外部存储保存数据,内部保存指针。

    BLOB与TEXT类型的不同主要就是存储类型不一样,BLOB以二进制保存,没有排序规则和字符集,TEXT以字符串保存,有排序规则和字符集。

    这两类型还有以下两点需要注意的地方:

    • MySQL的排序,不会对整个字符串进行排序,只会对max_sort_leng配置的长度进行排序。需要的话可以修改max_sort_leng配置的值或者使用ORDER BY SUSTRING(COLUME, LENGTH)来指定排序的长度。
    • MySQL不能使用TEXT、BLOB整个字符串来建立索引,也不能使用这些索引消除排序。

    ENUM代替字符串

    在平时业务中,比如需要保存订单状态的时候,为了节省空间,提高速度,会使用TINYINT来保存。这确实是一个很好的方法,但是MySQL中还有一种类型也可以实现,各有利弊,下面进行简单介绍。

    ENUM是MySQL中的枚举类型,MySQL存储ENUM是很紧凑,会根据枚举数量压缩到1-2字节中,MySQL在内部将以整数的形式保存,将整数和枚举值的映射关系保存在表的frm文件中。

    枚举类型有以下两点需要特别注意:

    • 枚举值的排序是根据对应整数进行的,而不是字符串排序。所以有排序要求的话,需要在设置时与整数相对应,或者使用Field进行排序,但是Field排序无法利用索引消除排序。
    • 枚举的字符串列表是固定的,修改特别不方便,除非可以接受只在队尾添加元素。

    个人建议:如果不能一开始就确定枚举列表的话,使用TINYINT保存,自己维护映射表较好。

    日期和时间类型

    MySQL提供了两种类似的数据类型保存时间,分别是DATETIME和TIMESTAMP,大部分场景,这两者都可以很好的工作,只是部分场景可能需要选择一个更加适合的。

    注意:MySQL可以保存的最小时间粒度为秒,MariaDB最小时间粒度为毫秒。(MariaDB常用于大数据集群场景)

    DATETIME

    DATETIME可以保存1001到9999年的时间范围,时间精度为秒。它将时间数据保存在YYYYMMDDHHMMSS的整数中,使用8字节存储空间,未保存时区数据。默认情况下,MySQL以ASNI标准定义显示时间值(2021-05-21 20:40:34)。

    TIMESTAMP

    TIMESTAMP只使用4字节空间,只能保存1970到2037的时间,时间精度为秒,保存方式与UNIX时间戳相同。MySQL提供了FROM_UNIXTIME函数将时间戳转化为日期,提供了UNIX_TIMESTAMP函数将日期转换为时间戳。TIMESTEAMP保存了时区信息,它的显示数据与时区相关。

    其他

    除非有特殊需要,不然尽量使用TIMESTAMP,因为它空间占用小,计算速度快。虽然使用整数来保存时间十分常见,但是这没有如何的好处,一般不推荐。

    如果需要时间精度需要达到毫秒的话,可以选择使用MariaDB。或者使用刚刚说的不推荐方法,使用BIGINT或者DOUBLE来保存时间数据。

    位数据类型

    MySQL有少数的数据类型使用位存储数据,这两个应用较少,只简单了解一下。

    BIT

    bit类型用来在同一列保存多个true/false值,通过指定长度来决定占用位数,最大长度为64.

    注意:如果bit(8)中保存了b''00111001',检索时你会得到字符码为57的字符串,也就是字符''9',但是在数字上下文中,得到的将会是数字57。

    SET

    没怎么看明白,不过简单来说就是,这数据类型不好使!!!

    作者:红雨
    出处:https://www.cnblogs.com/52why
    微信公众号: 红雨python
  • 相关阅读:
    Mining of Massive Datasets – Link Analysis
    在web.config里修改配置从而对匿名用户拒绝提供某资源
    SharePoint 2010中的lockdown模式
    Managed Metadata Service介绍系列 之二
    Managed Metadata Service介绍系列 之一
    ASP.NET基础再出发系列 之一
    SharePoint的web.config文件中的validateRequest
    创建Business Data Connectivity Service之后遇报错“There are no addresses available for this application”
    [经典文章翻译] [未完工] [96更新] 在.NET Framework中针对RealTime技术的性能注意事项
    SharePoint 2010中, SPEventReceiverBase.EnableEventFiring和DisableEventFiring都已废弃(obsolete), 应使用SPEventReceiverBase.EventFiringEnabled
  • 原文地址:https://www.cnblogs.com/52why/p/14763909.html
Copyright © 2020-2023  润新知