Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/mysql/57.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/string/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Mysql 如何';我的数据结构是什么?_Mysql_Sql_Database_Database Design_Data Structures - Fatal编程技术网

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年代的“草莓奖”中找到所有的获奖者,并且只在“女演员”类别中找到,还想展示该奖项是为哪部电影获得的。您不必联接所有中间表。相反,您可以仅使用
    提名获胜者
    提名者
    典礼
    电影
    获奖类别
    表(并且仅使用
    提名
    中间表)检索数据:


    如果该奖项是赢家,为什么要将它放在提名者的单独表格中(毕竟,它必须是提名者之一)@RowlandShaw
    Award.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%'