含互斥列的foo表结构是否违反数据库第三范式(3NF)?
互斥列与违反第三范式(3NF)
首先看这个表的创建语句:
CREATE TABLE foo ( id SERIAL PRIMARY KEY, a TEXT, b TEXT )
该表有一个业务规则:列a仅能在列b为空时取值,反之亦然,数据示例如下:
id | a | b ---+-------+------ 1 | NULL | 'abc' 2 | 'cba' | NULL
可以看到a和b之间存在约束关系——不知道另一列的内容时,无法随意给这两列赋值。那这个表结构是否违反第三范式(3NF)?
结论是:不违反3NF。
原因如下:
- 3NF的核心要求是:表中所有非主键列必须直接依赖于主键,且不存在传递依赖(即非主键列不能依赖于其他非主键列)。
- 此表的主键是
id,列a和b的取值都直接由id唯一确定,属于对主键的直接依赖。 a和b之间的互斥是业务约束,并非函数依赖。函数依赖要求“确定一个列的值就能唯一确定另一个列的具体值”,但这里只是“非此即彼”的空值约束,不属于函数依赖范畴,因此不违反3NF的定义。
不过从设计合理性来说,这种互斥列的写法并不推荐。更优的设计是拆分出类型标识列(比如content_type)和内容列(比如content_value),用一行存储一组完整的类型+内容数据,这样能避免冗余空值,也更符合归一化的设计思路,但这和是否违反3NF是两个独立的问题。
内容的提问来源于stack exchange,提问作者Prosto_Oleg
相关产品推荐
相关产品推荐

