数据类型与格式:选型前的必修课

做表格选型,最怕什么?

我最怕的是数据格式不统一。几年前有个项目,客户给的 Excel 里日期字段五花八门——有写“2024-1-5”的,有写“2024/01/05”的,还有写“2024年1月5日”的。导入系统后直接崩了。嗯,从那以后我养成了一个习惯:先搞清楚数据类型,再动手做表。

这一章,咱们就把五种常见数据类型掰开揉碎讲清楚。你想想看,连数据长什么样都没搞明白,选型怎么可能不出错?

文本型数据:最基础也最坑

文本型数据,说白了就是字符串。姓名、地址、备注、产品描述……这些都属于文本型。

但文本型有个大坑:长度和编码。

我曾经踩过的坑: 某次做用户信息表,备注字段只设了 50 个字符。结果用户粘贴了一段 200 字的投诉内容,直接截断了。后来查数据时发现一堆“投诉内容:我非常不满……(此处省略)”,气得我连夜改了表结构。

文本型数据的选型要点:

  • 定长 vs 变长:固定长度的字段(如身份证号 18 位)用 CHAR,长度不固定的用 VARCHAR
  • 编码统一:建议全部用 UTF-8,别混用 GBK 和 UTF-8,否则乱码让你怀疑人生
  • 空值处理:空字符串和 NULL 是两回事,我习惯把“无”写成空字符串,把“未知”写成 NULL
场景 推荐类型 长度建议 备注
姓名 VARCHAR 50 考虑少数民族姓名,别设太短
邮箱 VARCHAR 100 最长邮箱可达 254 字符
身份证号 CHAR 18 固定长度,用 CHAR 更高效
产品描述 TEXT 不限 长文本用 TEXT 或 LONGTEXT

数值型数据:精度就是生命

数值型数据看起来简单,但精度问题能让你吃大亏。

我个人习惯把数值型分成三类:

  • 整数:年龄、数量、ID——用 INT 或 BIGINT
  • 定点数:金额、税率——用 DECIMAL,别用 FLOAT
  • 浮点数:科学计算、百分比——用 FLOAT 或 DOUBLE
核心原则: 涉及钱,永远用 DECIMAL。FLOAT 的精度问题会让你对不上账。

举个例子:

-- 错误的做法:用 FLOAT 存金额
CREATE TABLE orders (
    amount FLOAT(10, 2)  -- 0.1 + 0.2 可能等于 0.30000000000000004
);

-- 正确的做法:用 DECIMAL
CREATE TABLE orders (
    amount DECIMAL(10, 2)  -- 精确到分
);

为什么会这样?因为 FLOAT 是二进制浮点数,0.1 在二进制里是无限循环小数。你想想看,存个 0.1 进去,读出来变成 0.100000001,这账怎么算?

日期型数据:时区是个大麻烦

日期型数据,我建议你记住一句话:存 UTC,显本地。

常见的日期类型:

类型 精度 存储空间 适用场景
DATE 日 3 字节 生日、入职日期
TIME 秒/毫秒 3-5 字节 营业时间、倒计时
DATETIME 秒 8 字节 订单时间、日志时间
TIMESTAMP 秒 4 字节 自动记录创建/更新时间
我的习惯: 跨时区项目一律用 TIMESTAMP,它会自动转换时区。单时区项目用 DATETIME,更直观。

避坑指南:

  • 别用字符串存日期——排序、计算都麻烦
  • 统一格式——我习惯用 YYYY-MM-DD HH:MM:SS
  • 注意闰秒——虽然很少遇到,但金融系统要考虑

布尔型数据:真真假假

布尔型数据最简单,但也最容易出幺蛾子。

不同数据库对布尔型的支持不一样:

  • MySQL:用 TINYINT(1),0 表示假,1 表示真
  • PostgreSQL:原生 BOOLEAN 类型,TRUE/FALSE
  • SQLite:用 INTEGER,0 假 1 真

我个人建议:能用原生布尔就用原生,没有就用 TINYINT。别用 VARCHAR 存 'Y'/'N',查询效率低,还容易写错。

我曾经遇到过: 接手一个老项目,布尔字段用 VARCHAR 存了 'yes'/'no'/'Y'/'N'/'1'/'0' 六种值。查数据时 WHERE is_active = 'yes' 和 WHERE is_active = 'Y' 结果不一样。后来我花了一周时间清洗数据。

混合型数据:现实世界的常态

现实中的数据很少是单一类型。一个订单表里,既有文本(用户名)、数值(金额)、日期(下单时间),还有布尔(是否支付)。

混合型数据的处理原则:

  1. 字段拆分:一个字段只存一种类型,别把“备注:金额 100 元”写在一起
  2. 类型转换:查询时用 CAST 或 CONVERT 显式转换,别依赖隐式转换
  3. 统一规范:团队内部约定好每种类型的格式,写进开发规范
-- 错误:混合存储
CREATE TABLE orders (
    info VARCHAR(255)  -- 存了 "张三,100,2024-01-05,已支付"
);

-- 正确:拆分字段
CREATE TABLE orders (
    user_name VARCHAR(50),
    amount DECIMAL(10, 2),
    order_date DATETIME,
    is_paid TINYINT(1)
);

下面这张图总结了五种数据类型的关系和选型逻辑:

数据类型选型决策图 数据类型 文本型 数值型 日期型 布尔型 混合型 常见类型 CHAR / VARCHAR TEXT / LONGTEXT 注意编码和长度 常见类型 INT / DECIMAL FLOAT / DOUBLE 金额用 DECIMAL 常见类型 DATE / TIME DATETIME / TIMESTAMP 存 UTC,显本地 常见类型 BOOLEAN / TINYINT BIT 别用 VARCHAR 存
总结一下: 选数据类型不是拍脑袋决定的。文本看长度和编码,数值看精度,日期看时区,布尔看数据库支持,混合型看拆分是否合理。把这五点想清楚,你的表结构就稳了。