2012-10-13 80 views
0

我在作者和書籍之間存在n到m的關係。我正在考慮對此進行建模的兩種可能性。SQL性能建模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),他出版的第一本書。

第一種情況下查詢看起來像:

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; 

我儲存的作者在IDS覆蓋系統,以避免進一步加入作者表。我從不對作者的細節感興趣。預計系統中的書籍比作者要多得多。

由於「清潔」(編輯:不需要重複的書籍條目),我趨向於第一個選項,但是我有一些麻煩證明這個決定是正確的。

什麼是從性能角度推薦?我猜測連接應該導致第一個選項變慢。

那麼爲了使第一個選項更快就可以創建索引呢?

回答

1

第一個選項是多對多關係。如果可以有多本書的作者(或書的零作者),則可以使用它。

第二種選擇是一對多關係。如果只有一本書的作者,你會使用它。

所以,你應該選擇適合你想要做的解決方案。當第二個選項適合時,使用第一個選項只會導致不一致,即,最終可能會出現沒有作者或書籍的作者多書的情況。

關於性能或者正常工作。只要有索引可用(通常是爲鍵創建的),聯接就不成問題。對於第二個選項,您可以添加AuthorId字段的索引以使查找效率更高。

+0

我澄清了這個問題,對不起。 – taranaki

+0

@taranaki:在這種情況下,您需要第一個選項。 – Guffa

+0

嗨,你能解釋一下爲什麼我需要第一個選擇嗎?我很清楚第二種選擇是非常「醜陋」的SQL,但我最感興趣的是兩種選擇的性能方面。我從不想從一本書中得到所有的作者。 (作者書的例子僅僅是提問的目的簡化)。感謝您的幫助。 – taranaki

4

你所描述的並不是解決相同問題的兩種選擇。你的第一個版本是一個n:m關係,它只是模型化這種關係的「默認」方式。你的第二個版本只是1:m的映射。不同之處在於,第一本書可以由多位作者撰寫。在第二種情況下,每本書都由一位作者撰寫。

因此,請絕對避免:您的兩個「選項」是兩個完全不同的用例。如果它真的是m:n,你必須使用第一個!

+0

我會編輯消息使其更清晰,對不起,我的壞。 – taranaki

+0

我的答案保持不變。如果使用索引來加快查詢的速度,但這是獨立於所選的選項的。如果它有多個作者,多次輸入一本書將是一個非常糟糕的主意。如果你不得不改變例如書的標題?您將不得不更改該書的所有記錄。但在這種情況下,「全部」意味着什麼?如果是n:m,請使用第一個選項。 – Achim