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

数据库关系设计-将两个表在不同的表中关联两次

  •  0
  • bevacqua  · 技术社区  · 15 年前

    我有以下表格:

    Post
    Id int
    
    User
    Id int
    

    那么我有桌子了

    Favorite
    PostId int
    UserId int
    

    还有桌子

    Vote
    PostId int
    UserId int
    IsUpVote bit
    IsDownVote bit
    LastActivity datetime2
    

    问题是,如果我把最爱和投票合并到一张表中,我会得到

    UserPost
    PostId int
    UserId int
    IsFavorited bit
    IsUpVoted bit
    IsDownVoted bit
    LastActivity datetime2
    

    IsDownVote 无法再计算(从现在起,我不能使用“不存在:没有投票;没有投票向上:投票向下”模式)和 LastActivity 只反映上次投票更改的时间(向上、向下或删除)。所以我可能需要更改这个字段的名称或者它的功能。或者两者兼而有之……

    所以,问题基本上是,有两张表和表A和表B相关有多错 (Post,User) 在这种情况下,它是由同一个主键索引的 (PostId,UserId) 在这种情况下,哪一种是为了不同的用途?

    3 回复  |  直到 15 年前
        1
  •  2
  •   FrustratedWithFormsDesigner    15 年前

    最喜欢的和投票似乎是两件不同的事情,所以我想你最好还是把它们作为单独的表格。正如您提到的,如果合并它们,您将失去功能,我看不到合并它们有任何明显的好处。坚持你现有的,除非你能提供 令人惊叹的 合并的理由。

        2
  •  1
  •   PerformanceDBA    15 年前

    没什么问题。

    我不是说DDL提供的显示正确的标准化表,但它们有点标准化。正如您已经确定的那样,这两个表有不同的用途,它们有不同的含义,因此从技术上(理论上、学术上和实践上[代码])来说,它们是正确的。

    • “与同一父对象相关”不是一个标准(在许多情况下,有许多表与同一父对象相关,并且这些表是正确的)
    • 因此,这些表将“具有相同的pks和fks”,因此这也不是一个标准。

    只有那些没有真正的标准化概念,也没有负面表现原因概念的人,才会建议“仅仅因为他们有相同的父母(因此是相同的一对钥匙/索引)”,他们应该被合并。

    投票和最爱是两个不同的东西,实体,行动记录。两张桌子是对的。

    区别:被保护的真正原因是它不适用于喜爱的事物。您已经使用了一个指示器(位)来标识它(尽管名称不正确);它实际上是空列的替代品。空值对性能不好,并且您有标识数据缺失的指示器是一件好事,因此避免了空值,但这与通过划分它们来破坏规范化设计是不同的。

    合并的表将在所有访问上执行较慢的操作。当您从中选择投票时,您必须排除收藏夹,反之亦然,但它将为两者进行I/O,因为它们位于一起(postid,userid)。所以服务器总是读取两倍的行,使用两倍的缓存等,然后您将“添加速度”到 添加 (postid、userid、is-favorited)的索引,使插入和删除更慢(同时“加速”选择)。混乱会变得复杂,有保证;首先最好不要有任何混乱。

    当数据库增长时,您可以独立地将列添加到投票和收藏中的任何一个,而不影响另一个。在合并的表中,它将引入复杂情况。

    你接受答案太快了。

        3
  •  -1
  •   Einar Petersen    15 年前

    虽然我不会说如果您使用in t而不是bit并使用诸如0 1和-1这样的值来进行计算/比较,您应该在表中做些什么,但是这样您可以用一种相对简单的方法来计算所需的值。

    谈到关系数据库,你几乎应该总是针对表的第三种正常形式-试着看一下 http://en.wikipedia.org/wiki/Database_normalization

    干杯!