【问题标题】:Handling Database Cross Foreign Keys处理数据库交叉外键
【发布时间】:2013-07-18 15:34:52
【问题描述】:

我有以下表格:

USER 表:

id | username | password | join_date | avatar_image_id

图像表:

id | url | user_owner_id

图像表包含帖子、文章和用户头像的所有图像。每个图像都属于可以编辑它的用户。所以user_owner_id是必要的,但仅仅知道哪个图像是用户的头像是不够的,所以我需要avatar_image_id

这个交叉外键有问题吗?这是一个糟糕的设计吗?有什么办法可以解决吗?

【问题讨论】:

    标签: database database-design database-schema


    【解决方案1】:

    这里有几个选项。

    选项 1

    您在 IMAGE 表中执行此操作:-

    id
    url
    user_owner_id
    user_avatar_id
    
    • user_avatar_id 列是 USER 表的外键
    • user_avatar_id 允许 NULL,表示该图像不是任何人的头像
    • 由于每个用户只有一个头像,user_avatar_id 应该是唯一的

    这样做的好处是,您可以继续在只需要前三列的代码中通用地处理所有图像。只有当您有用于 Avatar 图像的特定代码时,您才需要考虑最后一列。

    这有效地执行了“每个用户有 0 或 1 个头像”的规则。也许当第一次创建用户时,他们还没有头像,所以可以吗?如果每个用户都必须有一个头像,并且您想在数据库中强制执行此操作,则需要选项 2。

    选项 2

    所有图像都放在同一张桌子上的必要性有多大?您是否经常使用同一段代码来处理头像图像和其他图像?如果没有,您可以考虑在 USER 表中添加以下列:-

    avatar_url
    

    这样可以快速轻松地找到给定用户的头像图像。但是,这可能会使图像编辑代码复杂化,因为现在您必须考虑存储在 image 表中的内容以及这些特殊的头像图像。

    总的来说,我可能会选择选项 1。

    【讨论】:

      【解决方案2】:

      通常是的Cross Foreign Keys 很痛苦,特别是在您想删除(或存档)的情况下。这是因为您将无法删除任何一行。

      解决这个问题的方法就是将FOREIGN KEYNOCHECK 约束定义为avatar_image_id

      另一种方法是将BIT 列添加到表IMAGEIsAvatarImage。使用正确的索引,这种方法对性能的影响应该是最小的。

      【讨论】:

      • user_owner_id从外键改成普通行怎么样?我不需要搜索那么多。通常的连接是从用户表到图像,反之亦然。
      • @sheno 。你的问题是关于design :-) 。 user_owner_id 是更强的FOREIGN KEY。在概念数据库设计中搜索是不同的东西。
      • 澄清一下,当我写得更强大时,我的意思是user_owner_id无论如何都不能被替换,而avatar_image_id可以被替换为IMAGE.IsAvatarImageBIT
      猜你喜欢
      • 2018-07-13
      • 2016-12-23
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-03-31
      • 1970-01-01
      • 2012-01-29
      • 2015-09-30
      相关资源
      最近更新 更多