我正在通过为库设计数据库来开展学习项目。图书馆提供书籍,视频和音频。我决定将它的乐趣归结为那些为三元关系做贡献的人。这使得Quentin Tarrantino更容易成为同一部电影中的导演,作家和演员,同时也是一些书籍的作者,所有人都没有冗余以及他们在创作作品时所扮演的角色。
我称这三个基本实体涉及贡献者,角色和作品。
我遇到了问题,因为即使是在列出书籍的简单案例中,我也不确定我应该做些什么。对于每个贡献者/角色对,我最终会得到一个单独的行吗?或者有没有办法让结果塔有一些“临时”列(例如作者,插画家,一本书的翻译)。
感觉使用这种三元关系将层次结构注入到我的数据库中,我想知道如何最好地处理这种情况(请不要消除三元关系)。
[尾声] 我的查询工作得很好。 Stefan,我确实有一个中间表,所以你(以及其他阅读本文)知道。看起来三元关系为应用程序员提供了数小时的乐趣。
答案 0 :(得分:2)
您实际上不能拥有ad-hoc列,因为每个列中可能有不同的行数。例如。一本书可能有一位作者,三位插图画家,也没有翻译。
要获取图书的贡献者列表,您必须选择与其相关的所有角色贡献者对,可能首先按角色排序,以便更轻松地进行分组,然后按角色分组贡献者并在页面上显示。
要编辑图书的数据,您必须验证所需角色的贡献者是否存在(例如,至少有一位作者)。这可以部分地通过ON UPDATE和ON DELETE触发器来完成,这些触发器将不允许删除最后剩下的作者;插入时你需要别的东西。
此外,我还会使用一个“模板”表,列出每种工作(work_type, role_type, is_required)
的可能角色。如果is_required
为真,则角色必须存在于有效工作中,如果为false,则允许角色但是可选。仅允许在表格中明确列出给定work_type
的角色(因此您没有用于音乐曲目的书籍或插图画家的作曲家)。
答案 1 :(得分:0)
正如@Stefan H所指出的那样,你还需要一个连接表。您通过使用贡献者表来减少冗余,但看起来您将很难将角色编码到它们之间的连接表中。您也希望抽象出角色,因此您的表应如下所示:
Contributor
ContributorID PK
Role
RoleID PK
Work
WorkID PK
ContributorRoleInWork
ContributorRoleInWorkID PK
(
ContributorID FK
RoleID FK
WorkID FK
) --These three form a unique alternate key as well
要回答您的实际问题,是的,您将为每个ContributorRoleInWork获得一行,但这就是您想要的。当您列出图书的信息时,您需要为每个参与者/角色组合返回一行。为了便于显示信息,您可以按贡献者或角色进行排序/分组,具体取决于您希望如何显示数据。
答案 2 :(得分:0)
要回答这个问题,是的,每个Contribute / Role最终会有一个单独的行,例如,如果 John Doe既是执行制片人又是电影导演Foo。
WORK CONTRIBUTOR ROLE
Foo John Doe Director
Foo John Doe Executive Producer
所以你有四个表(每个实体和链接表一个):
WORKS
CONTRIBUTORS
ROLES
WORKS_CONTRIBUTORS
链接表的主键是三元组:
WORKS_CONTRIBUTORS
workid
contributorid
roleid
答案 3 :(得分:0)
我认为这可能是最简单的解决方案(尽管不是最佳解决方案):
books roles people
ID Role ID
Name BookID Name
[other info] PersonID [Other info]
这样一来,如果你想知道给定书中的所有贡献者和他们的角色你可以使用隐式连接和
SELECT * FROM people,roles WHERE roles.BookID = [your book id] AND people.ID = roles.PersonID
同样,要获得某个人的所有贡献,你可以
SELECT * FROM books, roles WHERE roles.PersonID = [your person id] AND books.ID = roles.BookID
相反,如果你只想获得由某人执导的电影:
SELECT * FROM books, roles WHERE roles.PersonID = [your person id] AND roles.Role = "director" AND books.ID = roles.BookID
有更好的方法来编写这些查询:获取SQL方言的参考手册并查找JOIN。