2010-08-06 57 views
1

数据库表,可以说汉堡,包含一个字段,存储位为整数值,所以它的值为1,2,4,8,16 .. 。多对多的关系,比较明智的比较与链接器表

一种二次表包含值 1 =奶酪,2 =番茄,4 =蛋,8 =莴苣,16 =蛋黄酱

逐位比较然后使任何汉堡具有馅料的任何组合(对于一位24岁的初生汉堡会有mayo和生菜(16 + 8),而val 5的汉堡会有奶酪和鸡蛋等)。

据我所知,这不是一个特别好的主意,你只限于相对较小范围的不同汉堡馅(64?)。唯一的好处是它可以节省数据库空间,因为不需要链接器表。

但是,我接手的是一个技术上非常好的人,那么我是否还有其他好处?在我看来,有两个负面因素:它限制了不同馅料的数量,以及它的奇怪/不寻常(从记忆成为主要考虑的时候挂断了)。

回答

1

我看到的唯一好处是,它可以使返回包含所有汉堡配料和其他数据的逗号分隔字段在一行中的相对容易。不速之客,我不知道如何做到这一点。如果是这种情况,我会很乐意看到那个SQL。

如果前端程序从辅助表中缓存数据并在返回后分析按位字段,它也会消除对数据库的调用。

但是,我没有看到任何其他好处。我只是使用一个链接器表并完成它,因为我认为,比特封装使数据库设计复杂化。

0

以这种方式使用位掩码,您将无法利用SQL参照完整性检查的强大功能。如果以某种方式输入值128,会发生什么?查找表中没有这样的条目。如果我试图加载一个查找表中不存在的值,我会得到一个错误,并且该值将(正确)不会被加载到数据库中。

它可能会更快,更容易(和更有趣的),以实施位运算符,但适当的标准化数据库可以更容易支持了很多,并保持一段时间。

0

你可以通过添加表,将 看起来像绕开这个问题的解决方案:

Table: Fillings 
Id Cheese Tomato Egg Lettuce Mayo 
0  N  N  N  N  N 
1  Y  N  N  N  N 
2  N  Y  N  N  N 
3  Y  Y  N  N  N 
... 
31  Y  Y  Y  Y  Y 

那么你可以说:

select 
    count(1) as WithCheeseButNoTomato 
from Burger as b 
join Fillings as f on f.Id = b.FillingId 
where Cheese = 'Y' 
    and Tomato = 'N' ; 

任何假定的好处是在前端填充选区或在应用程序层。