sql—为每个表中的主主键存储外键

2ekbmq32  于 2021-07-26  发布在  Java
关注(0)|答案(1)|浏览(242)

假设我们有table Users 带着一个 ID 作为主键,用户具有以下相关实体:

UserSubjects(SubjectId <PK>,UserId <FK>)
SubjectPapers(PaperId<PK>,SubjectId<FK>)

现在根据上表,出于安全原因 userId 必须作为参数传递才能获取所有 SubjectPapers 为了一个 Subject 与用户相关的,而不仅仅是传递 SubjectId .
以该方法为例:

public List<SubjectPaper> GetBySubject(int userId, int subjectId)
 {
     return _context.SubjectPapers
         .Include(k => k.UserSubject)
         .Where(k => k.SubjectId == subjectId && k.UserSubject.UserId == userId)
         .ToList();
 }

在上面的方法中,用户必须包含在查询中,以验证他是否正在请求获取一个主题。
如果还有呢 SubjectPapers 理论上有更多的相关实体。是否要存储 UserId 外键通过在两列(userid和subjectid)上添加非聚集索引来提高查询的性能?有什么副作用吗?或者有没有其他方法可以避免将父用户包括在每个相关实体中?任何建议都将不胜感激。

ippsafx7

ippsafx71#

如果需要userid来查找主题,那么subject是一个“弱实体”,userid应该是它的复合主键中的前导列。

UserSubjects(UserId <PK,FK>,SubjectId <PK>)

我喜欢

public class User
{
    public int UserId { get; set; }
    public virtual ICollection<Subject> Subjects { set; } = new HashSet<Subject>();
}
public class Subject
{
    public int UserID { get; set; }
    public int SubjectId { get; set; }
    public virtual User UserId { get; set; }
}

配置如下:

modelBuilder.Entity<Subject>().HasKey(s => new { s.UserID, s.SubjectId });
modelBuilder.Entity<Subject>().Property(s => s.SubjectId).ValueGeneratedOnAdd();

这优化了按userid检索,并防止subject表需要多个索引。它在(userid,subjectid)上有一个聚集索引,而不需要在两列上有两个单独的索引。

相关问题