我想知道如何在简单的数据库中保存作者(如果有多个作者)。
如果一本书有一位作者,一切都很简单。问题是当我想要表图书并希望有可能使用表作者进行简单的选择和连接时:
图书
| id | Title | ISBN | Authors? |
---------------------------------
| | | | |
| | | | |
作者
| id | Firs Name | Last Name | Short Name | Pseudonym |
--------------------------------------------------------
| | | | | |
| | | | | |
我知道我可以使用具有相同ISBN和TITLE的单独行,但是我想知道在标题有时非常大(255长度UTF字符串/ varchar / char)的情况下这是个好主意。
我知道这可能是非常基本的问题,很遗憾我不得不问:(
答案 0 :(得分:8)
删除authors
中的books
列。
书籍和作者之间有很多关系:有些书籍有多位作者,有些作者写过不止一本书。而且,书籍有第一,第二和第三作者,等等。您无法以某种不可预测的顺序呈现图书的作者姓名。作者和出版商决定作者的顺序,而不是dbms程序员。
因此,您需要一个包含以下列的books_authors
表
book_id
author_id
author_ordinal (a number like 1,2,3 to denote the order of authors)
您可以使用此查询获取特定图书的作者列表:
SELECT isbn, title, author_ordinal, first, last
FROM books b
LEFT JOIN books_authors ba ON (b.id = ba.book_id)
LEFT JOIN authors a ON (ba.author_id = a.id)
WHERE isbn = '978whatever'
ORDER BY author_ordinal
如果您希望使您的软件以书目形式完成,那么在books_authors表中放置一个名为role
的文本字段也是明智之举。人们在创作诸如“作家”,“插画家”,“编辑”,“系列编辑”,“撰稿人”,“前言作家”等书籍中扮演着各种各样的角色。 role
列可让您捕获该信息。
顺便说一下,如果你在整个过程中一致地命名你的id列,那么大多数dbms逆向工程工具会更加快乐。所以你应该使用books.book_id和authors.author_id而不仅仅是books.id和authors.id。
答案 1 :(得分:7)
由于一本书可以有多位作者,而作者可以写一本以上的书,我建议在书籍和作者表之间建立多对多的关系。
添加另一个链接两者的表,如下所示:
<强> BookAuthors 强>
| BookID | AuthorID |
BookID是Books.id的外键,AuthorID是Authors.id的外键。
如果你想归还给定书籍的所有作者,你可以做以下几点:
SELECT Authors.id, Authors.FirstName, Authors.LastName
FROM Authors INNER JOIN BookAuthors ON Authors.id = BookAuthors.AuthorID
WHERE BookAuthors.BookID = '123'
答案 2 :(得分:3)
你有两个真正的可能性:
所以,让我们考虑一下:一本书有它的所有细节和一个ID。每位作者都有许多细节和一个ID。如果要将作者与书籍相关联,可以在另一个表格中添加一行,我们称之为“Credits”。
这样你就有两个一对多的关系(从作者到学分,从书到学分),并且可以代表你需要的东西,而不会有任何尴尬的多值。
答案 3 :(得分:1)
您需要另一个名为BookAuthor
的表格,您不需要图书中的Authors
列
BookAuthor
------------
BookID
AuthorID
BookID引用Books和AuthorID上的PK(BookID)引用作者上的PK(AuthorID)
Select b.Title, CONCAT(a.[First Name], a.[Last Name]) As AuthorName
From Books b
JOIN BookAuthor ba ON b.ID = ba.BookID
JOIN Authors a ON ba.AuthorID = a.ID