假设您的数据库中包含以下实体:
Image http://lh6.ggpht.com/_UpGtM3B8h1U/Sa7SqfWmgDI/AAAAAAAAAHE/epqtm7EnoFg/test.gif
您希望能够为所有其他三个实体表(用户,客户端和项目)添加注释。你会如何设置它?
我似乎在选项2和3之间来回走动,但如果有一个优雅的实现,我会为1。选项2很有吸引力,因为没有空值。选项3很有吸引力,因为无论它与什么相关,音符都会像一个音符。
有什么想法?
答案 0 :(得分:1)
我通常会使用选项2.我不会在合理范围内强调数据库中表的数量。
最大的问题是,这些笔记是作为单个项目处理的吗?例如,您是否会说:“向我显示所有注释,无论是客户,用户还是项目。”我无法想到任何有用的情况。你通常会说,“给我看这个客户的笔记”或“给我看这个项目的笔记。”
因为它们在逻辑上不是一个项目,所以我建议不要将它们作为一个项目进行物理建模。
答案 1 :(得分:0)
我经常看到这种处理的方式是选项1.最重要的是,这对于参与其中的人来说是一种相当简单的方法来查看正在发生的事情。正如你所说,缺点是SQL变得不那么优雅了。
但是,这只是一种方式。实际上,即使它可能感觉有点笨拙,但结果查询清晰可读。您只需要在添加新表的区域中将sql添加到新代码中。当你实际上直接操作笔记时,你只需要处理一个表格。
答案 2 :(得分:0)
还有第四种方法(我建议):在Note表中添加一个唯一的id,在User,Client和Project中添加一个字段noteId
答案 3 :(得分:0)
做什么可能取决于您需要的备注字段在实体之间是否真的相同。如果它们是相同的话,我可能会有一个Notes表(如果需要更改所有注释获得修订日期字段,例如,一步添加)与Notetype(用户,客户端,项目),noteID和来自相应表格的ID以及您需要的所有相关字段。最大的问题是必须通过触发器而不是FK来管理FK关系。您不希望输入无效的用户标识,但由于整个列不包含用户标识,因此您不能只设置FK关系。另一方面,如果您稍后添加另一个实体,则可以在不影响表结构的情况下执行(尽管您仍然需要修改触发器),这是在单独的字段中具有ID的问题。这也意味着您将无法使用级联更新或删除,这会使删除记录(或更改自然键(颤抖))更加困难。
如果您对笔记的哪些字段的需求在实体之间有所不同,我会为每个权利创建单独的Notes表。
如果要在所有enitite之间的每个查询中访问Notes表,您可能还需要为每个实体分别使用表来减少锁定和阻塞问题。但是,注意事项可能不需要经常被击中,因此情况可能不会太糟糕。
答案 4 :(得分:0)
选项3.将标识作为主键,并为共享Note表的任何表创建外键列。我用这种方式处理电子邮件,电话,地址等。
我知道的唯一缺点是,如果你有10个表链接到Note - 你有10个外键列。
我在选项1中遇到的问题是,您感觉自己正在创建一个人工外键(使用TableName / Pkid,它实际上不是User / Project主键的一部分,只是Pkid)。这可能只是我个人的偏见,我从来没有觉得这是好的设计,但我不能确切地说出原因。
答案 5 :(得分:0)
我认为,在这种情况下你应该明确地避免使用解决方案1 如果没有动态SQL,则无法查询整个数据库,并且总是需要2个查询来选择一些注释! 在这种简单的情况下,你绝不应该使用这种方式。
在我看来,我选择了4(在项目,客户和用户上添加了一个字段note_id)。如果你需要一行多个笔记,这不是问题。你只需添加一个额外的表(比如说note_set)就可以产生n-1关系。
客户端(client_id,note_set_id) user(user_id,note_set_id) project(project_id,note_set_id)
note_set(note_set_id) 注意(note_id,note_set_id,标题,正文)
这个解决方案的主要问题是,给出一个注释,如果不在三个表上创建UNION,就无法找到初始的“实体”。这对我来说似乎不是一个大问题,但如果是的话,请选择3。
最后,选项2也很好,但它不是我所说的“重用”。
请原谅我的英语。