在我的情况下分离常见数据是好的吗?

时间:2011-09-17 06:45:46

标签: mysql sql database postgresql database-design

所以,例如,我有City专栏。 95%的City值为NULL。制作像city_names(Id PK,City)这样的表并用新列City_id(FK引用city_names(id))替换City是个好主意吗?以下是我对此的看法。它们基于一般的计算思想。请纠正我,这不适用于RDMS。

第一种方式:O(n)存储O(n)批量操作O(1)随机访问

第二种方式:O(n)存储O(n * logn)批量操作由于n个索引结构请求(B树,例如)O(lon n)随机访问

以下是完整图片。我有1M行表。它成长。有像城市这样的80列。他们几乎都是NULL。但是,它们是社区可编辑的。因此,我必须提供全文搜索,快速编辑时间和复杂查询(针对高级用户或机器人)。在某些将来,根本就没有NULL。那么绞盘方案我必须用于编辑阶段和巫婆的桌子在它的最终形状?

如果重要的话我使用postgres \ mysql。

2 个答案:

答案 0 :(得分:1)

在PostgreSQL中,NULLS几乎没有任何成本(每个1位,一次8位,加上字对齐,所以有> 1 NULL,它们比价值更便宜,更便宜)。

对于像你这样稀疏填充的列,将列移动到自己的表中没有任何好处,并且在连接所有时间以获得稀疏数据时都有相当大的损失。

答案 1 :(得分:0)

  

所以,例如,我有City专栏。 95%的City值为NULL。是   这个好主意让像city_names(Id PK,City)这样的表并替换   城市新列City_id(FK引用city_names(id))?

如果用city_id列替换city列,95%的行仍为NULL,不是吗?您将减少磁盘空间,但是对于必须返回城市名称的每个查询,您都需要连接。

用ID号替换文本与规范化无关。规范化总是减少原始表中的列数。

还有一个问题,“城市”本身通常不是城市的全名。实际上,您可能需要将两列或三列移动到另一个表中。在美国有很多名为“华盛顿”的城市。事实上,在19世纪,有两个城市被命名为“华盛顿,加利福尼亚,美国”。对于美国的城市,将城市,州和国家合并为一个新表可能是有意义的。同样,这将减少磁盘空间,但是每个必须返回任何列的查询都需要连接。

现在,任何查询都可以使用无连接返回所有80列人类可读文本。如果用一些外键引用其他表中的id号替换一半的文本列,则可能必须编写带有40个连接的查询,以便将所有数据恢复到人们可以再次读取它的位置。

在进行需要40次连接的更改之前,请仔细思考。

说了这么多,一个80列的95%NULL的表不可能在BCNF中,并且正常化到BCNF或5NF可能对你有所帮助。请记住,规范化并不意味着“用id号替换该文本”。