Mysql 如何';我的数据结构是什么?
我建立了一个简单的数据库,用于存储有关奖项和提名的信息。我已尝试尽可能多地删除数据冗余。以下是目前的情况: 之所以有提名表格,是因为我意识到一个提名会有很多被提名人。例如,Mysql 如何';我的数据结构是什么?,mysql,sql,database,database-design,data-structures,Mysql,Sql,Database,Database Design,Data Structures,我建立了一个简单的数据库,用于存储有关奖项和提名的信息。我已尝试尽可能多地删除数据冗余。以下是目前的情况: 之所以有提名表格,是因为我意识到一个提名会有很多被提名人。例如,最佳剧本奖可以授予肯·莱文和大卫·艾萨克斯或伍迪·艾伦或乔斯·惠登、安德鲁·斯坦顿、乔尔·科恩和亚历克·索科洛 注:Award.name是该奖项的名称,例如最佳男主角 感谢您指出任何可能的改进。表中的提名在提名和提名之间创建了m:n关系。删除它的namiteId列,并使用两列namiteId和namitoniId作为主键。这
最佳剧本奖可以授予肯·莱文和大卫·艾萨克斯
或伍迪·艾伦
或乔斯·惠登、安德鲁·斯坦顿、乔尔·科恩和亚历克·索科洛
注:Award.name
是该奖项的名称,例如最佳男主角
感谢您指出任何可能的改进。表中的提名
在提名
和提名
之间创建了m:n关系。删除它的namiteId
列,并使用两列namiteId
和namitoniId
作为主键。这将防止同一人因同一提名而被提名两次
提名候选人
+---------------++-------------+提名
|PK提名ID | | PK提名ID|
|名称|+----------------++------------------+
+---------------+| FK FilmID|
|FK阿瓦尔德|
|FK事件ID|
+------------------+
小注释
我更喜欢表名和列名用单数,因此被提名人
变成被提名人
,奖项
变成奖项
,等等
将奖励
表重命名为@wildplasser在评论中建议的奖励类别
主要注释
正如@Olivier所指出的,m::n
关系中间表,如namified
one,将对复合(namifiedid,namignionid)
具有唯一的约束。因此,最好删除自动生成的(代理)键,并使复合键成为主键。这是关系的关键,使用它作为主键有几个优点。在这种情况下,除了有更宽的行和一个更无用的索引之外,没有任何作用。自然关键点的两个部分将用于连接
同样的事情也适用于提名表!复合(FilmId,AwardCategoryId,EventId)
将是一个唯一的
键,以确保没有任何电影在同一事件中获得同一奖项类别的两项提名,因此最好还是放弃代理键,将此复合键设为主键。重新考虑一下,同一部电影的同一奖项类别可能有两个提名,比如两个“最佳男配角”
,因此我们在主键中添加了一个提名o
(如果我们想限制某个类别的提名,或者让所有人都说常量5,这可能很方便)
现在,(有趣的是)必须重新检查提名的表,并有一个复合(提名的did、FilmId、AwardCategoryId、EventId)
主键,并且只有这4列作为属性
我不确定事件
和仪式
表究竟要存储什么,但假设仪式
表要存储关于不同仪式的信息(例如“奥斯卡奖”
,“草莓奖”
)而事件
表用于存储有关一年庆典的信息(例如('Oscar',2011),('Oscar',2012),('Starwberry Awards',2012)
)。因此,我将年份
移动到事件
表中,并将(CeremonyId,EventYear)
作为事件的Priamry键。(我很可能错了,你更了解你的数据。)
因此,namignment.EventId
被CeremonyId
和EventYear
取代,而namignment
和namigned
的主键变得更长!(这是将自然关键点用作主键的一个缺点)。让我们看看到目前为止我们得到了什么:
您可以轻松添加一个提名获胜者
(作为一个与提名
具有1:1
关系的表)来存储哪个提名赢得了哪个类别(对(CeremonyId、EventYear、AwardCategoryId)的唯一约束将强制执行该约束)。设计如下:
拥有如此复杂的主键可能看起来很笨拙,但在连接表时会有所帮助。想象一下,你想在50年代和60年代的“草莓奖”中找到所有的获奖者,并且只在“女演员”类别中找到,还想展示该奖项是为哪部电影获得的。您不必联接所有中间表。相反,您可以仅使用提名获胜者
、提名者
、典礼
、电影
和获奖类别
表(并且仅使用提名
中间表)检索数据:
如果该奖项是赢家,为什么要将它放在提名者的单独表格中(毕竟,它必须是提名者之一)@RowlandShawAward.name
是该奖项的名称,例如,最佳男主角
@JamWaffles是我使用Photoshop的新手。Lol.在数据模型中经常发生这样的情况,即您同时拥有该类型的“类型”和“实例”。有时候,为这个设计一个命名方案会有所帮助。@JamWaffles:如果您喜欢我的图表,它们是由MySQL Workbench制作的。复合主键的实现往往有点棘手,因为您需要处理两个ID而不是一个ID。如果在这两个字段上放置复合约束,而不是将它们设置为PK,则仍然可以使用表示复合约束的PK引用行。有点干净
SELECT ne.Name AS Winner
, wi.EventYear AS Year
, aw.AwardCategoryTitle AS Category
, fm.Title AS FilmTitle
FROM
NominationWinner AS wi
JOIN
Ceremony AS ce
ON ce.CeremonyId = wi.CeremonyId
JOIN
AwardCategory AS aw
ON aw.AwardCategoryId = wi.AwardCategoryId
JOIN
Film AS fm
ON fm.FilmId = wi.FilmId
JOIN
Nominated nd
ON nd.CeremonyId = wi.CeremonyId
AND nd.EventYear = wi.EventYear
AND nd.AwardCategory = wi.AwardCategory
AND nd.NominationNo = wi.NominationNo
AND nd.FilmId = wi.FilmId
JOIN
Nominee AS ne
ON ne.NomineeId = nd.NomineeId
WHERE
ce.CeremonyTitle = 'Strawberry Awards'
AND wi.EventYear BETWEEN 1950 AND 1969
AND aw.AwardCategoryTitle LIKE '%Actress%'