数据类型与格式:选型前的必修课
做表格选型,最怕什么?
我最怕的是数据格式不统一。几年前有个项目,客户给的 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' 结果不一样。后来我花了一周时间清洗数据。
混合型数据:现实世界的常态
现实中的数据很少是单一类型。一个订单表里,既有文本(用户名)、数值(金额)、日期(下单时间),还有布尔(是否支付)。
混合型数据的处理原则:
- 字段拆分:一个字段只存一种类型,别把“备注:金额 100 元”写在一起
- 类型转换:查询时用 CAST 或 CONVERT 显式转换,别依赖隐式转换
- 统一规范:团队内部约定好每种类型的格式,写进开发规范
-- 错误:混合存储
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)
);
下面这张图总结了五种数据类型的关系和选型逻辑:
总结一下: 选数据类型不是拍脑袋决定的。文本看长度和编码,数值看精度,日期看时区,布尔看数据库支持,混合型看拆分是否合理。把这五点想清楚,你的表结构就稳了。