Francesco Tisiot:在PostgreSQL®中使用NULL值的11个经验教训
内容提要
本文讨论了布尔值和数据库中的NULL值,重点介绍了在PostgreSQL数据库中使用NULL值的方法和教训。文章强调了正确处理NULL值的重要性。
延伸解读
NULL 与主键约束
在 PostgreSQL 中,主键列默认具有 NOT NULL 约束,因此尝试插入 NULL 会直接报错。这提醒我们,设计表时应明确主键的不可为空性,避免依赖默认行为。对于其他列,若未显式添加 NOT NULL,则允许 NULL 存在,可能影响数据完整性。
添加 NOT NULL 约束的注意事项
向已有数据的表添加 NOT NULL 列时,必须为现有行提供默认值,否则操作会失败。同样,为现有列添加 NOT NULL 约束前,需先处理已有的 NULL 值,例如使用 COALESCE 替换。直接修改可能锁表,建议拆分操作以减少影响。
DEFAULT 与 NOT NULL 的区别
DEFAULT 值仅在插入语句未指定该列时生效,若显式插入 NULL,DEFAULT 不会阻止。因此,要确保列值非空,必须同时使用 NOT NULL 约束。仅靠 DEFAULT 无法防止 NULL 插入,可能破坏数据一致性。
查询与运算中的 NULL 处理
查询 NULL 值应使用 IS NULL 或 IS NOT NULL,而不是 = 或 <>。在数学运算中,NULL 值会被忽略,仅计算非 NULL 值,这可能影响聚合结果。使用 COALESCE 替换 NULL 时,需确保替换值不会与现有数据混淆,以免引入错误。
Q&A
在PostgreSQL中,主键列可以插入NULL值吗?
不可以。主键默认具有NOT NULL约束,尝试插入NULL会报错,提示违反非空约束。
如何为已有数据的表添加一个NOT NULL列?
必须指定默认值,例如:ALTER TABLE users ADD COLUMN points INT DEFAULT 0 NOT NULL; 这样现有行会填充默认值,之后插入新行时若未指定该列也会使用默认值。
在PostgreSQL中,如何正确查询包含NULL值的列?
应使用IS NULL和IS NOT NULL条件,例如:SELECT * FROM users WHERE surname IS NULL; 不能使用等号(=)或不等号(<>)与NULL比较,因为NULL不等于任何值。
在PostgreSQL中,对包含NULL的列进行数学运算(如AVG)会如何处理NULL值?
数学运算只会计算非NULL值,NULL会被忽略。例如AVG(age)只计算非NULL的age的平均值。
在PostgreSQL中,使用COALESCE函数处理NULL值时需要注意什么?
需要注意替换值不能与表中已有的值冲突,否则可能意外包含额外数据。例如,用COALESCE(surname, 'Verona')时,如果'Verona'已存在,则查询会包含原本为'Verona'的行。
在PostgreSQL中,连接包含NULL值的列时会出现什么问题?如何解决?
NULL值不会匹配任何行,导致连接结果丢失数据。简单的COALESCE替换可能产生笛卡尔积,更安全的方法是在表设计时使用NOT NULL约束和外键,避免在查询时修复数据质量问题。