当前位置:首页 > 问答 > 正文

树叶云里说说MySQL那些数据类型到底咋用和区别是什么

树叶云里说说MySQL那些数据类型到底咋用和区别是什么 主要整理自MySQL 8.0官方手册“Data Types”章节以及树叶云在技术社区的个人经验分享)

好,咱们就直接开讲,不说那些弯弯绕,你用MySQL建表,第一个头疼的事儿就是咋给每个字段选个合适的数据类型,选对了,省空间,速度快;选错了,数据存不进去,查起来慢死,还容易出乱子,我把它们分几个大类,一个一个掰扯清楚。

第一大类:数字类型——存数字的,但花样很多

数字类型主要分两类:整型和浮点型。

  1. 整型(就是存整数)

    • 有哪些TINYINT, SMALLINT, MEDIUMINT, INT(或者写成 INTEGER), BIGINT,这几个家伙,说白了就是能存的数字大小不一样。
    • 区别和咋选
      • TINYINT:地盘最小,占1个字节,能存的范围是 -128 到 127,或者无符号的0到255,啥时候用?比如人的年龄(age TINYINT UNSIGNED,总不能有人活超过255岁吧)、性别编码(0男1女)、状态标志(0关闭1开启)。
      • SMALLINT:大一点,占2字节,范围-32768到32767,可以存一些城市编码、小产品的库存数量啥的。
      • INT:这是最常用、最省心的,占4字节,范围够大,几十亿级别,像用户ID(user_id INT)、订单ID、文章ID,闭着眼用INT基本不会错,除非你预感到你的用户量会成为下一个淘宝,那才需要考虑BIGINT
      • BIGINT:巨无霸,占8字节,天文数字都能存,主键ID如果担心INT不够用(比如雪花算法生成的ID),或者要存天文数字、金融里的超大金额(以分为单位时),就用它。
    • 关键点:记得有个UNSIGNED属性,勾选上就表示不要负数,只要正数,这样正数的范围能扩大一倍,比如INT UNSIGNED就能存0到42亿多。
  2. 浮点型(带小数点的数字)

    • 有哪些FLOAT, DOUBLE, DECIMAL
    • 区别和咋选:这是重点,容易混。
      • FLOATDOUBLE:这俩是近似值存储,就是说,你存进去一个数,可能取出来的时候会有极其微小的误差。FLOAT精度低点,DOUBLE精度高点,适合存科学计算数据、地理位置坐标这种对精度要求不是绝对精确的数据,比如商品价格一般不用它,因为钱不能差一分一厘。
      • DECIMAL(也叫 NUMERIC):这是精确存储,你存进去多少,它绝对一分不差地给你存着,底层是当成字符串处理的,所以它占的空间大,计算也慢一些。但是,凡是和钱有关的,比如商品价格(price DECIMAL(10,2),表示一共10位数字,小数点后占2位)、账户余额,必须用它!不然用户因为几分钱误差找你麻烦就坏了。

第二大类:字符串类型——存文本的

  1. 定长和变长

    • CHAR(n):定长,比如你定义 CHAR(10),就算你只存一个字“A”,它也会占满10个字符的空间,不够的用空格补齐,优点是存取速度快(位置固定),适合存长度几乎固定的数据,比如身份证号(CHAR(18))、手机号(CHAR(11))、MD5加密后的密码(CHAR(32))。
    • VARCHAR(n):变长,比如定义 VARCHAR(10),存“A”就只占1个字符的空间,外加一点点长度记录信息,优点是节省空间,这是最最常用的字符串类型,像用户名、文章标题、地址描述这种长度变化很大的,都用它。
  2. 长文本类型

    • TEXT系列:当VARCHAR不够用了(最多能存65535个字符),就需要用TEXT,它分 TINYTEXT, TEXT, MEDIUMTEXT, LONGTEXT,区别就是能存的文本长度一个比一个恐怖,适合存文章内容、产品详细描述、日志详情这种大段文字,树叶云提醒:TEXT类型不能有默认值,而且排序等操作可能会用到临时磁盘文件,慢一些。
  3. 二进制类型

    • BLOB系列:和TEXT对应,但存的是二进制数据,比如图片、音频、视频等文件的原始字节数据,树叶云一般不建议直接把文件存数据库,而是把文件存到硬盘或云存储,然后在数据库里用VARCHAR存文件的访问路径(URL),这样数据库压力小,性能更好。

第三大类:日期和时间类型——记时间的

  • DATE:只存日期,不存时间,格式是‘YYYY-MM-DD’,比如生日、入职日期。
  • TIME:只存时间,不存日期,格式是‘HH:MM:SS’,比如会议时间、打卡时间。
  • DATETIME既存日期,又存时间,格式是‘YYYY-MM-DD HH:MM:SS’,它存的是什么时间就是什么时间,跟时区没关系。
  • TIMESTAMP:时间戳。也是既存日期又存时间,但占的空间比DATETIME小,它有个非常重要的特性:和时区相关,它存的是从1970年1月1日到现在的秒数,查询时会根据当前数据库的时区设置转换成对应的时间,另一个特性是,你可以在定义时设置默认值为 CURRENT_TIMESTAMP,让它在插入数据时自动填入当前时间,非常适合记录“创建时间”、“最后修改时间”这种字段。

咋选:如果业务要跨时区,或者需要自动记录时间,用TIMESTAMP,如果就是单纯记录一个固定的时间点(比如活动开始时间),并且不想受时区影响,用DATETIME

总结一下怎么选

  1. 够用就好:在保证业务需求的前提下,选占用空间最小的类型,比如状态码用TINYINT,别用INT
  2. 避免NULL:尽量让字段设为NOT NULL,并给个默认值(比如数字给0,字符串给空串),因为NULL值会让索引、查询变得更复杂,可能影响性能。
  3. 钱用DECIMAL:这点再强调一遍。
  4. 主键用整型INTBIGINT,自增(AUTO_INCREMENT)或者用雪花算法等,查询效率最高。

说白了,选数据类型就是在空间、速度、精度三者之间做权衡,多练练,多想想数据是干啥用的,自然就熟了,树叶云觉得,这块内容死记硬背没用,实际建几张表,塞点数据试试,感受最深。

树叶云里说说MySQL那些数据类型到底咋用和区别是什么