使用带有NOT NULL的虚拟行来解决DEFAULT NULL

时间:2010-12-24 21:48:32

标签: database schema

我知道有DEFAULT NULLS不是一个好习惯,但我有很多可选的查找值,它们是系统中的FK所以解决这个问题就是我正在做的事情:我对每个FK /查询组使用NOT NULL。我在每个查找表中都有第一行PK id = 1作为虚拟行,所有列中只有“none”。这样我就可以在我的模式中使用NOT NULL,如果需要,可以为没有任何查找值的FK引用无行值PK = 1。

这是一个好的设计还是其他任何工作?


编辑: 我有:
邻居表
邮政桌。

每个街区都有一个城市,所以FK可以不是NULL。 但并非每个邮政编码都属于一个社区。有的做,有些不依赖于国家。因此,如果我在邮政和邻居之间的FK使用NOT NULL,那么我将被搞砸,因为必须输入一些值。所以我在本质上做的是:在每个表中都有一行作为一个虚拟行,只是为了链接FK。

这样,邻居表中的第一行将是:
n_id = 1
name = none
等...

在邮政表中我可以:
postal_code = 3456A3
FK(市)=莫斯科
FK(neighborhood_id)= 1为NOT NULL。

如果我在邻居查找表中没有虚拟行,那么我必须将FK(neighborhood_id)声明为Default null列并在表中存储空白。这是一个例子,但是有很多值会在许多表格中出现空白。

4 个答案:

答案 0 :(得分:0)

  

这是一个好的设计还是其他任何工作?

ISNULLCOALESCELEFT JOIN

答案 1 :(得分:0)

“无”通常与选项列表中的任何其他选项一样。为它设置一个特殊的行可能是完全合理的;它简化了事情。如果您将其他信息与选项相关联,则可能尤其实用,例如:一个人类可读的名字。

答案 2 :(得分:0)

这似乎是数据库中过早优化的简单情况:

alt text

如果您的架构是这样的,那么我没有看到问题。有些邮政编码在附近,有些则没有。对于可以为空的列来说,这是一个很好的例子。

关于避免空值的建议是关于避免不属于表的信息。例如,如果您有另外五列仅涉及邻域中的邮政编码,那么对于不在邻域中的邮政编码,这些列将为空。这是一个很好的理由,为附近的邮政编码设置第二个并行表,其中可能包含其他五列。

更重要的是,如果性能是一个问题,那么解决方案是尝试两种方式,测试性能,并查看哪种性能最佳。然后,这种性能考虑将与设计的简单性和可读性相竞争,并且性能可能会获胜。


说明问题的一个例子。我从一个对象角色建模模型开始,就像我用来生成早期的ER图一样。但是,我创建了PostalCode的子类型,并为子类型添加了两个强制性角色:

ORM Model

这可以产生与第一种非常相似的ER模型:

ER Model Adsorbed

但是,只要PostalCode是NeighborhoodPostalCode,这个模型就无法显示有必要的列。以下模型 表明:

ER Model Separated

我想说如果你有一组在某些情况下是强制性的可选列,那么你应该创建一个“子类型”,它总是将那些列设为NOT NULL。但是,如果您只是随机列可能随机不为空,则将它们保留为主表中的NULL列。

答案 3 :(得分:0)

您始终可以使用左连接来加入可能不存在的邮政编码。

select * from from table_a 
  left join table_b    
  on table_a.postalcode_id = table_b.postalcode_id
无论postalcode_id是否为null,

都会选择行。当您使用幻数来指定空值时,查询的可读性就会降低。

明确:

select count(*) from table_a where postalcode_id is null;

不太清楚:

 select count(*) from table_a where postalcode_id = 1;

使用空值会使您的查询显式处理空案​​例,但它也会自我记录您正在处理空值的意图。