MySQL字段默认值为NULL时的避坑指南
目录
- 坑一:逻辑混乱 —— NULL ≠ 空值
- 示例
- 坑二:索引命中率低
- 示例
- 坑三:唯一索引失效
- 示例
- 坑四:聚合函数行为不一致
- 示例
- 推荐实践
- 总结
坑一:逻辑混乱 —— NULL ≠ 空值
你可能以为 NULL = ''
是真,实际却是假或未知。这是三值逻辑的典型陷阱。
示例
CREATE TABLE users ( id INT PRIMARY KEY, name VARCHAR(50) DEFAULT NULL ); INSERT INTO users (id) VALUES (1); -- 看似查空名,其实查不到 SELECT * FROM users WHERE name = ''; -- 查 NULL 必须显式写: SELECT * FROM usphpers WHERE name IS NULL;
坑二:索引命中率低
mysql 在执行查询时,会基于统计信息判断是否使用索引。当某字段大量为 NULL
,即使建了索引,也可能不走索引。
示例
CREATE TABLE orders ( id INT PRIMARY KEY, status VARCHAR(10) DEFAULT NULL ); CREATE INDEX idx_status ON orders(status); -- 插入数据,其中 90% 是 NULL INSERT INTO orders (id, status) SELECT t1.a, IF(t1.a % 10 = 0, 'PAID', NULL) FROM mysql.help_topic t1 LIMIT 1000; -- 编程客栈查询 NULL 值可能不走 idx_status EXPLAIN SELECT * FROM orders WHERE status IS NULL;
坑三:唯一索引失效
在唯一索引中,多个 NULL
是允许的,这意味着你不能依赖唯一约束阻止重复插入。编程客栈
示例
CREATE TABLE email_users ( id INT PRIMARY KEY, email VARCHAR(255) DEFAULT NULL, UNIQUE KEY uniq_email(email) ); INSERT INTO email_users (id, email) VALUES (1, NULL); INSERT INTO email_users (id, email) VALUES (2, NULL); -- 成功!
坑四:聚合函数行为不一致
当你做统计时,NULL
会被自动忽略,导致结果不一致。
示例
CREATE TABLE survey ( id INT PRIMARY KEY, age INT DEFjavascriptAULT NULL ); INSERT INTO survey (id, age) VALUES (1, 20), (2, NULL), (3, 30); SELECT COUNT(age) AS count_age, AVG(age) AS avg_age FROM survey;
推荐实践
场景 | 推荐做法 |
---|---|
字符字段 | 默认值设为 '' ,加 NOT NULL |
数值字段 | 默认值设为 0 ,加 NOT NULL |
时间字段 | 使用 CURRENT_TIMESTAMP |
是否布尔值 | 使用 TINYINT(1) ,默认值为 0 |
CREATE TABLE users ( id INT PRIMARY KEY, is_active TINYINT(1) NOT NULL DEFAULT 0 );
总结
字段默认值为 NULL
看似灵活,但它隐藏的问题远多于你预期的:
- 查询难写
- 索引不稳
- 统计不准
- 唯一性失效
所以,除非你真的需要表示“未知”或“无意义”,强烈建议避免使用 NULL 作为默认php值。
到此这篇关于MySQL字段默认值为NULL时的避坑指南的文章就介绍到这了,更多相关MySQL字段默认值为NULL内容请搜索编程客栈(www.devze.com)以前的文章或继续浏览下面的相关文章希望大家以后多多支持编程客栈(www.devze.com)!
精彩评论