这或多或少是一个最佳实践问题:
我正在开发一个网站,要求我将一些表与几个不同的表相关联。 例如,我有一个评论表,我想以某种方式关联,例如可以对表A中的实体进行评论,也可以分别对表B进行评论。
同样地,我有一个我想要做同样的评级表,以便可以评估网站中的不同方面。
我已经提到了一种方法,它意味着与具有PrimaryKey(Guid)和ForeignKey(Guid)的Relationships表之间存在松散关系,然后在Comment-table和Rating-中使用Guids作为主键。 table - 但这意味着我还需要Guid作为其他表中的主键。
这里有什么好主意吗?非常感谢:)
PS。如果它很有趣,我正在创建一个带有ORM的ASP.NET MVC2应用程序(EF,Linq2Sql或NHibernate ......并不重要:))
答案 0 :(得分:1)
您可以使用单个评论/评级表,但为每个相关实体使用单独的表来维护对实体关系的评论。如果您有帖子和页面,每个都有评论,它看起来像这样:
Comments
- CommentID
- CommentText
Posts
- PostID
- Other fields
Pages
- PageID
- Other fields
PostComments
- PostID
- CommentID
PageComments
- PageID
- CommentID
答案 1 :(得分:1)
我尽量避免使用单个列链接到不同的表。
我会根据个人喜好选择其中一种可能性:
如果没有特定的理由将所有注释保存在单个表中,我会在需要时创建一个注释表:一个用于TableA的外键,另一个用于TableB的外键,等等。 确保参照完整性,并且外键列的数据类型可能会在表之间发生变化。此外,这允许每个表在将来以不同的方式发展。
如果有理由将所有注释保留在单个表中,我会为每个外键添加一列,但我允许空值。确保参照完整性。我有时会添加另一个列来指示注释的类型(TableA,TableB,...),并带有查找表 - 这对查询很有帮助。
每个表的多对多表需要链接到注释。没有不必要的列,但在创建查询时可以做更多工作。创建注释时有两个插入 - 如果可用,我将使用存储过程和视图。绝对比其他解决方案更多的工作...
答案 2 :(得分:0)
通过在表之间使用“多对多”表,可以建立强大关系的一种方式... 假设您有表'TableA','TableB'和'Comment,您将有两个额外的表,一个用于跟踪表A的注释,一个用于跟踪表B的注释,但仅使用它们的ID。
TableAComment
TableAId
CommentId
TableBComment
TableBId
CommentId
要问自己的另一件事是“我是否只需要一个评论表?”。根据应用程序其余部分的设计,尝试将所有注释强制转换为一个表可能意味着比每个“父”更多的工作。如果此表最终非常大,它可能会导致性能问题。
答案 3 :(得分:0)
如果可能的话,我建议将一些继承放入数据库中 - 为有价值和可评论的实体创建基表,并从评论和评级表中引用这些基表。这将是每种类型继承模式的常用表。请参阅ADO.NET团队博客中的此post,以获取有关使用实体框架进行继承映射的基本概述(但同样适用于大多数其他O / R映射器)。
答案 4 :(得分:0)
是的,正如您指出的那样,如果您愿意放弃某些SQL功能(如FK完整性),那么“松散关系”可能是最简单的选择。但是,为了查询writer / db admin,我还要添加一个列,该列包含与该行相关的表名。例如。联系(ID guid),员工(ID guid),然后是地址(ID 无论,EntityID guid,EntityType string / int)。
这将使您能够将地址附加到任何表而无需维护多对多表(您可能附加检查约束以强制执行一对多)。此外,这种设计还可以让您在客户端编写一些可重复使用的代码 - 例如
public class Address
{
public void Attach(IEntity entity)
{
// do stuff
}
}
public interface IEntity
{
Guid ID { get; }
}
我首先回想一下在MS CRM数据库架构中看到这一点。
您的困难在于强制执行参照完整性。这可以通过EntityID列上的一些检查约束来完成,以基于EntityType列强制存在id。