MySQL字段类型

  • MySQL字段类型可以分为三大类:
    • 数值类型:整型(TINYINTSMALLINTMEDIUMINTINTBIGINT)、浮点型(FLOATDOUBLE)和定点型(DECIMAL
    • 字符串类型:CHARVARCHARTINYTEXTTEXTMEDIUMTEXTLONGTEXTTINYBLOBMEDIUMBLOBBLOBLONGBLOB
    • 日期时间类型:DATEDATETIMETIMESTAMPTIMEYEAR

MySQL字段类型


MySQL整数类型的UNSIGNED属性

  • MySQL中的整数类型可以使用可选的UNSIGNED属性来表示不允许负值的无符号整数。使用UNSIGNED属性可以将正整数的上限提高一倍,因为它不需要存储负数值。
  • 例如,TINYINT UNSIGNED类型的取值范围是0 ~ 255,而普通的TINYINT类型的值范围是-128 ~ 127INT UNSIGNED类型的取值范围是0 ~ 4,294,967,295,而普通的INT类型的值范围是-2,147,483,648 ~ 2,147,483,647
  • 对于从0开始递增的ID列,使用UNSIGNED属性可以非常适合,因为不允许负值并且可以拥有更大的上限范围,提供了更多的ID值可用。

MySQL中CHAR和VARCHAR的区别

  • CHARVARCHAR都是用于存储字符串的字段类型,但CHAR是定长字符串类型,而VARCHAR是变长字符串类型。
  • CHAR类型会为每个值分配固定的长度,无论实际存储的字符串长度是多少,都会占用指定的长度空间。CHAR在存储时会在右边填充空格以达到指定的长度,检索时会去掉空格。
  • VARCHAR类型会根据实际存储的字符串长度来分配空间,存储时只占用实际字符串长度加上1或2个字节用于记录字符串长度。
  • CHAR(M)VARCHAR(M)M都代表能够保存的字符数的最大值,无论是字母、数字还是中文,每个都只占用一个字符。

DECIMAL和FLOAT/DOUBLE的区别

  • DECIMAL类型用于存储精确的数值,适合存储需要高精度的数值,如货币金额。DECIMAL类型以字符串形式存储数值,可以避免浮点数的精度问题。
  • FLOATDOUBLE类型用于存储近似数值,适合存储科学计算或需要较大范围的数值。FLOATDOUBLE类型以二进制形式存储数值,可能会引入精度误差,尤其是在进行数学运算时。

为什么不推荐使用TEXT和BLOB类型

  • TEXT类型类似于CHAR(0-255字节)和VARCHAR(0-65,535字节),但可以存储更长的字符串,即长文本数据,例如博客内容。

    类型 可存储大小 用途
    TINYTEXT 0-255字节 一般文本字符串
    TEXT 0-65,535字节 长文本字符串
    MEDIUMTEXT 0-16,772,150字节 较大文本数据
    LONGTEXT 0-4,294,967,295字节 极大文本数据
  • BLOB类型主要用于存储二进制大对象,例如图片、音视频等文件。

    类型 可存储大小 用途
    TINYBLOB 0-255字节 短文本二进制字符串
    BLOB 0-65KB 二进制字符串
    MEDIUMBLOB 0-16MB 二进制形式的长文本数据
    LONGBLOB 0-4GB 二进制形式的极大文本数据
  • 不推荐使用的原因:

    • 不能有默认值。
    • 在使用临时表时无法使用内存临时表,只能在磁盘上创建临时表(《高性能MySQL》书中有提到)。
    • 检索效率较低。
    • 不能直接创建索引,需要指定前缀长度。
    • 可能会消耗大量的网络和IO带宽。
    • 可能导致表上的DML操作变慢。

DATE、DATETIME和TIMESTAMP的区别

  • DATE类型用于存储日期,格式为YYYY-MM-DD,范围是1000-01-019999-12-31
  • DATETIME类型用于存储日期和时间,格式为YYYY-MM-DD HH:MM:SS,范围是1000-01-01 00:00:009999-12-31 23:59:59。需要耗费8字节存储。
  • TIMESTAMP类型用于存储时间戳,格式为YYYY-MM-DD HH:MM:SS,范围是1970-01-01 00:00:01 UTC到2038-01-19 03:14:07 UTC。TIMESTAMP类型会根据服务器的时区设置自动转换为UTC时间进行存储,并在查询时转换回本地时间。需要耗费4字节存储。

NULL和’'的区别

  • NULL代表缺失或未知的数据,而''表示一个已知存在的空字符串。
  • 含义
    • NULL代表一个不确定的值,它不等于任何值,包括它自身
    • ''表示一个空字符串,它是一个已知的值。
  • 存储空间
    • NULL在MySQL中需要额外的存储空间来表示字段是否为NULL,通常是1字节。
    • ''只存储一个空字符串的标志,不需要存储实际的字符。
  • 比较运算
    • 任何值与NULL比较(=!=><等)的结果都是NULL,表示结果不确定。要判断一个值是否是NULL,需要使用IS NULLIS NOT NULL
    • ''可以像其他字符串一样进行比较运算。
  • 聚合函数
    • 大多数聚合函数(例如SUM, AVG, MIN, MAX)会忽略NULL值。
    • COUNT(*)会统计所有行数,包括包含NULL值的行。COUNT(列名)会统计指定列中非NULL值的行数。
    • 空字符串''会被聚合函数计算在内。例如SUM会将其视为0MINMAX会将其视为一个空字符串。

BOOLEAN类型如何表示

  • MySQL中没有真正的BOOLEAN类型,BOOLEAN实际上是TINYINT(1)的别名。
  • TINTINT(1)类型使用01来表示布尔值,其中0表示FALSE,非零值(通常是1)表示TRUE

手机号存储用INT还是VARCHAR?

  • 存储手机号,强烈推荐使用VARCHAR类型,而不是INTBIGINT。主要原因如下:
    • 格式兼容性
    • 完整性
    • 非算术性
    • 查询灵活性
    • 加密存储要求
对比维度 VARCHAR 类型(推荐) INT/BIGINT 类型(不推荐) 说明/备注
格式兼容性 ✔ 能存前导零、“+”、“-”、空格等 ✘ 自动丢失前导零,不能存符号 VARCHAR 能原样存储各种手机号格式,INT/BIGINT 只支持单纯数字,且前导零会消失
完整性 ✔ 不丢失任何格式信息 ✘ 丢失格式信息 例如 “013800012345” 存进 INT 会变成 13800012345,“+” 也无法存储
非算术性 ✔ 适合存储“标识符” ✘ 只适合做数值运算 手机号本质是字符串标识符,不做数学运算,VARCHAR 更贴合实际用途
查询灵活性 ✔ 支持 LIKE ‘138%’ 等 ✘ 查询前缀不方便或性能差 使用 VARCHAR 可高效按号段/前缀查询,数字类型需转为字符串或其他复杂处理
加密存储支持 ✔ 可存储加密密文(字母、符号等) ✘ 无法存储密文 加密手机号后密文是字符串/二进制,只有 VARCHAR、TEXT、BLOB 等能兼容
长度设置建议 15~20(未加密),加密视情况而定 无意义 不加密时 VARCHAR(15~20) 通用,加密后长度取决于算法和编码方式