代码之家  ›  专栏  ›  技术社区  ›  NimChimpsky

多对多关系、逐位比较与链接器表

  •  1
  • NimChimpsky  · 技术社区  · 16 年前

    一个数据库表,比如说burger,包含一个字段,该字段将位存储为整数值,因此它的值为1、2、4、8、16。。。

    1=奶酪,2=番茄,4=鸡蛋,8=生菜,16=蛋黄酱

    据我所知,这不是一个特别好的主意,你被限制在一个相对较小的范围内不同的汉堡馅料(64?)。唯一的优点是它节省了数据库空间,因为不需要链接器表。

    然而,我正在接手一个技术上非常优秀的人;那么,我还缺少其他好处吗?在我看来,有两个缺点:它限制了不同填充物的数量,以及它的怪异/不寻常(当记忆是主要考虑因素时的一个障碍?)。

    3 回复  |  直到 16 年前
        1
  •  1
  •   Mike Cellini    16 年前

    我看到的唯一好处是,它可以相对容易地返回一个逗号分隔的字段,其中包含所有汉堡配料和其他数据都在一行中。不过,我不知道该怎么办。如果是这样的话,我很想看看SQL。

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

    然而,我没有看到任何其他好处。我只需要使用一个链接器表就可以了,因为位打包,我想,只会使数据库设计复杂化。

        2
  •  0
  •   Philip Kelley    16 年前

    以这种方式使用位掩码,您将无法利用SQLs引用完整性检查的功能。如果以某种方式输入值128会发生什么?在查找表中没有这样的条目。在正确实现外键约束的情况下,如果我试图加载一个在查找表中不存在的值,我会得到一个错误,并且该值不会(正确地)加载到数据库中。

    它可能会更快,更容易(和更有趣的)找到 按位运算符,但正确规范化的数据库更容易 支持 并随时间保持。

        3
  •  0
  •   Damir Sudarevic    16 年前

    您可以通过添加一个 看起来像:

    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' ;
    

    任何假定的好处都存在于前端填充选择或应用程序层中。