【问题标题】:How can I design these two tables to prevent corrupt data?如何设计这两个表以防止损坏数据?
【发布时间】:2017-06-21 22:10:18
【问题描述】:

我有一个comments 表,评论可以引用答案或问题作为外键:

id primary key not null,
question_id  references questions(id),
answer_id references answers(id),

answer_idquestion_id 将被填充,另一个将为空。

现在另一个表是notifications,每当创建评论时,我都会创建一个通知:

id primary key not null,
comment_id references comments(id),
question_id references questions(id),
answer_id references answers(id),

question_idanswer_id 将被填充,但我想确保它与为该 comment 记录填充的内容一致。

如何确保通知引用评论本身引用的相同资源?换句话说,如果我有一个引用问题的评论,然后我想为该评论创建一个通知但让它引用一个答案,那么数据库不应该允许这样做。我该如何施加这样的约束?

【问题讨论】:

  • 我认为您可以使用继承和三种不同类型的通知表来解决问题。
  • 您当前的设计似乎没有标准化。
  • @TimBiegeleisen 你能建议一种方法来规范化 cmets 表吗?
  • 如果您确实希望将question_idanswer_id 保留在notifications 表中,则创建一个由三列(comment_id, question_id, answer_id) 和仅引用comments 表组成的外键。 Postgres supports it.
  • @TimBiegeleisen 您在滥用“规范化”。这意味着一个表不能被连接到它的投影有效地替换。

标签: sql postgresql database-design


【解决方案1】:

您应该规范化表格并使用通知中对 cme​​ts 的引用来查找 question_id 和 answer_id。

create table comments (
  id serial primary key,
  question_id int references questions(id),
  answer_id int references answers(id)
);

create table notifications (
  id primary key not null,
  comment_id int references comments(id)
);

使用连接访问日期:

select question.*
from notifications
join comments on comments_id = comments.id
join questions on question_id = questions.id;

【讨论】:

  • 有趣,您认为在通知中添加一个新的type 来判断此评论是指问题还是答案是否也是一个好主意?
  • NVM 我的评论,很好的答案,非常感谢!
  • Id' 说不,那将是另一个可能不一致的数据点(标记为 question 的行,但仅链接到答案)。如果对您有帮助,您可以定义一个包含计算类型字段的视图。
  • 谢谢,我想我从这个答案中学到了我从阅读多个博客中没有学到的东西。
  • 我误读了您的评论,通知中的type 是个坏主意,一个不错的主意(但仍然不好)将其添加到 cmets。
【解决方案2】:

我认为你把这件事弄得太复杂了。 您应该有一个表,其中包含 cmets 以及类型。不需要空值并且已标准化

CREATE TABLE comments (
 id INT PRIMARY KEY,
 comment VARCHAR,
 is_answer BOOLEAN
);

【讨论】:

    猜你喜欢
    • 2017-12-03
    • 1970-01-01
    • 2021-09-20
    • 1970-01-01
    • 2014-01-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-02-17
    相关资源
    最近更新 更多