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

Posted

技术标签:

【中文标题】如何在简单的书籍表中写入数据库多个作者?【英文标题】:How write down to database multiple authors in simple books table? 【发布时间】:2012-11-12 23:18:45 【问题描述】:

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

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

书籍

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

作者

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

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

我知道这可能是一个非常基本的问题,很抱歉我不得不问这个问题:(

【问题讨论】:

【参考方案1】:

去掉books中的authors列。

书籍和作者之间存在多对多关系:有些书籍有多个作者,有些作者写了不止一本书。而且,书籍有第一作者、第二作者和第三作者,依此类推。您无法以某种不可预测的顺序呈现一本书的作者姓名。作者和出版商决定作者顺序,而不是 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。

【讨论】:

【参考方案2】:

由于一本书可以有多个作者,而一个作者可以写多本书,我建议在 Books 和 Authors 表之间建立多对多关系。

添加另一个链接这两者的表,如下所示:

图书作者

|书号 |作者ID |

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'

【讨论】:

【参考方案3】:

你有两种真正的可能性:

每本书有许多作者,但每个作者最多只能拥有一本书(极不可能) - 这样,您将在 Author 表中放置一个 外键,将该作者链接到该书.您可以让两个这样的作者拥有相同的图书 ID,但这意味着您不必复制图书详细信息,实际上,无需复制图书 ID 以外的任何内容 更有可能:每本书有很多作者,每个作者有很多书。这称为“多对多关系”,需要您添加另一个表。

所以,让我们考虑一下:一本书包含所有详细信息和一个 ID。每个作者都有许多详细信息和一个 ID。如果您想将作者与一本书相关联,您可以在另一个表中添加一行,比如说“Credits”。

每个作者可以有多个学分,但每个学分只属于一个作者。 同样,每本书的封面上可以有很多学分,但每个学分只针对那本书。

这样你就有了两个一对多的关系(从作者到学分,从书到学分),并且可以代表你需要的东西,而没有任何尴尬的多值。

【讨论】:

【参考方案4】:

您需要另一个名为 BookAuthor 的表,您不需要 Books 中的 Authors

BookAuthor
------------
BookID
AuthorID

BookID 引用 Books 上的 PK (BookID) 和 AuthorID 引用 Authors 上的 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

【讨论】:

以上是关于如何在简单的书籍表中写入数据库多个作者?的主要内容,如果未能解决你的问题,请参考以下文章

如何在从另一个表中提取数据时创建具有约束的表

使用 GROUP BY 从多个表中选择

什么测试以及如何测试使用 JPA 实现的存储层

如何避免命名管道中的多个作者?

如何解析微服务世界中书籍的作者姓名?

CakePHP 显示所有作者不在作者表中的书籍