我有以下表格:
用户表:
id | username | password | join_date | avatar_image_id
图像表:
id | url | user_owner_id
图像表包含帖子、文章和用户头像的所有图像。每个图像都属于可以编辑它的用户。所以user_owner_id
是必要的,但仅仅知道哪个图像是用户的头像是不够的,所以我需要avatar_image_id
.
这个交叉外键有问题吗?这是一个糟糕的设计吗?有什么办法可以解决吗?
我有以下表格:
用户表:
id | username | password | join_date | avatar_image_id
图像表:
id | url | user_owner_id
图像表包含帖子、文章和用户头像的所有图像。每个图像都属于可以编辑它的用户。所以user_owner_id
是必要的,但仅仅知道哪个图像是用户的头像是不够的,所以我需要avatar_image_id
.
这个交叉外键有问题吗?这是一个糟糕的设计吗?有什么办法可以解决吗?
这里有几个选项。
选项1
您在 IMAGE 表中执行此操作:-
id
url
user_owner_id
user_avatar_id
user_avatar_id
column 是 USER 表的外键user_avatar_id
允许 NULL,表示图像不是任何人的头像user_avatar_id
所以应该是唯一的这样做的好处是您可以继续在只需要前三列的代码中通用地处理所有图像。只有当您有用于 Avatar 图像的特定代码时,您才需要考虑最后一列。
这有效地执行了“每个用户有 0 个或 1 个头像”的规则。也许当第一次创建用户时,他们还没有头像,所以可以吗?如果每个用户都必须有一个头像,并且您想在数据库中强制执行此操作,则需要选项 2。
选项 2
所有图像都放在同一张表中的必要性有多大?您是否经常使用同一段代码来处理头像图像和其他图像?如果没有,您可以考虑在 USER 表中添加以下列:-
avatar_url
这将使查找给定用户的头像图像变得快速和容易。但是,它可能会使图像编辑代码复杂化,因为现在您必须考虑存储在image
表格中的内容以及这些特殊的头像图像。
总的来说,我可能会选择选项 1。
一般来说,是Cross Foreign Keys
的很痛苦,特别是在您想删除(或存档)的情况下。这是因为您将无法删除任何行。
处理这个问题的一种方法就是定义FOREIGN KEY
withNOCHECK
约束到avatar_image_id
另一种方法是向BIT
table 添加一列 IMAGE
IsAvatarImage
。使用正确的索引,这种方法对性能的影响应该是最小的。