我在作者和书籍之间有一个n到m的关系。我正在考虑对此进行建模有两种可能性。
第一种可能性是明确的n到m关系。
表作者
ID Name
1 Follett
2 Rowling
3 Martin
表书
ID Title Category Logic Time
1 A Dance with Dragons Fantasy 1
2 Harry Potter Fantasy 3
3 The Key to Rebecca Thriller 2
4 World without end Drama 4
表book_author
authorId bookId
1 3
2 2
3 1
1 4
第二种可能性是将作者ID存储在书中。 编辑如果每本书有多位作者,我必须为每位作者输入一次。
表作者
ID Name
1 Follett
2 Rowling
3 Martin
表书
ID Title Category Logic Time AuthorId
1 A Dance with Dragons Fantasy 1 3
2 Harry Potter Fantasy 3 2
3 The Key to Rebecca Thriller 2 1
4 World without end Drama 4 1
假设我想找一位特定作者(Ken Follett,身份证1)他出版的第一本书。
在第一种情况中,查询将如下所示:
select * from books b join
book_author ba on b.id = ba.book_id
where ba.author_id = 1
order by b.logic_time asc;
在第二种情况中,查询将如下所示:
select * from books b
where a.author_id = 1
order by b.logic_time asc;
我将作者的ID存储在上层系统中,以避免与作者表进一步连接。我从不对作者的细节感兴趣。预计系统中的书籍数量远多于作者。
我正倾向于第一个选项,因为它更“清洁”(编辑:不需要重复的书籍条目),但我有一些麻烦证明这个决定。
从效果的角度推荐什么?我猜测连接应该导致第一个选项变慢。
为了使第一个选项更快,可以创建哪些索引?
答案 0 :(得分:4)
您所描述的不是解决同一问题的两种选择。你的第一个版本是n:m关系,它只是模拟这种关系的“默认”方式。你的第二个版本只是一个1:m的映射。不同之处在于,第一个案例书可以由多位作者撰写。在第二种情况下,每本书都只由一位作者撰写。
因此,绝对明确地说:你的两个“选项”是两个完全不同的用例。如果它真的是m:n,你必须使用第一个!
答案 1 :(得分:1)
第一个选项是多对多关系。如果一本书的作者不止一个(或一本书的零作者),你就可以使用它。
第二种选择是一对多关系。如果只有一本书的作者,你可以使用它。
因此,您应该选择适合您尝试的解决方案。当第二个选项适合时,使用第一个选项只会打开不一致的地方,即你最终会得到没有作者或书籍的书籍,而且会有多位作者。
关于性能要么正常。只要有一个索引要使用(通常是为密钥创建),连接就不是问题。对于第二个选项,您将为AuthorId
字段添加索引以使查找更有效。