如何在简单的书籍表中写下数据库的多个作者?

时间:2012-11-12 23:18:46

标签: mysql database

我想知道如何在简单的数据库中保存作者(如果有多个作者)。

如果一本书有一位作者,一切都很简单。问题是当我想要表图书并希望有可能使用表作者进行简单的选择和连接时:

图书

| id  | Title | ISBN | Authors? | 
---------------------------------
|     |       |      |          |
|     |       |      |          |

作者

| id  | Firs Name | Last Name | Short Name | Pseudonym | 
--------------------------------------------------------
|     |           |           |            |           |
|     |           |           |            |           |

我知道我可以使用具有相同ISBN和TITLE的单独行,但是我想知道在标题有时非常大(255长度UTF字符串/ varchar / char)的情况下这是个好主意。

我知道这可能是非常基本的问题,很遗憾我不得不问:(

4 个答案:

答案 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
  • 更有可能:每本书都有很多作者,每位作者都有很多书。这称为“多对多关系”,并要求您添加另一个表。

所以,让我们考虑一下:一本书有它的所有细节和一个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