0

我在作者和书籍之间有一个 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

假设我想为特定作者(ID 为 1 的 Ken Follett)找出他出版的第一本书。

在第一种情况下,查询看起来像:

    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 存储在上层系统中,以避免与作者表进一步连接。我从不对作者的细节感兴趣。预计系统中的书籍比作者多得多。

我倾向于第一个选项,因为它“更干净”(编辑:不需要重复的书籍条目),但我在证明这个决定时遇到了一些麻烦。

性能的角度推荐什么?我猜想加入应该导致第一个选项变慢。

可以创建索引以使第一个选项更快?

4

2 回答 2

4

您所描述的不是解决同一问题的两种选择。您的第一个版本是:m 关系,它只是建模这种关系的“默认”方式。您的第二个版本只是一个 1:m 映射。不同之处在于,在第一种情况下,书籍可以由多个作者编写。在第二种情况下,每本书仅由一位作者撰写。

因此,绝对明确:您的两个“选项”是两个完全不同的用例。如果它真的是 m:n,你必须使用第一个!

于 2012-10-13T08:56:12.543 回答
1

第一个选项是多对多关系。如果一本书的作者不止一个(或一本书的零个作者),您将使用它。

第二个选项是一对多关系。如果一本书只有一个作者,你会使用它。

因此,您应该选择适合您尝试做的解决方案。当第二个选项适合时使用第一个选项只会导致不一致,即您最终可能会得到没有作者的书籍或有多个作者的书籍。

关于性能,要么工作正常。只要有要使用的索引(通常是为键创建的),连接就不是问题。对于第二个选项,您将为该AuthorId字段添加一个索引以提高查找效率。

于 2012-10-13T09:08:32.237 回答