如何组织MySQL中相互依赖的变量ID

时间:2013-07-02 00:10:12

标签: mysql sql mysqli database-design

我正在为所有Magic the Gathering卡创建一个数据库...... 卡表如下所示:

  • cardID
  • 姓名
  • text
  • rarityID
  • colorID
  • editionID
  • 其他栏目......

同一张卡可以出现在多个版本中,在某些特殊情况下,在不同的版本中,它将具有不同的稀有度。

我知道如何做的唯一方法是为卡片出现的每个版本创建一个新的卡片条目。 但有时同一张卡出现在10多个版本中而没有任何变化(至少不会出现与此数据库相关的内容),而且我会创建大量不必要的条目。

有更好的解决方案吗?

2 个答案:

答案 0 :(得分:1)

在评论中继续反馈,这是我建议的(它仍然可能会错过更改,但我认为这是一个公平的开始)。确保捕获域模型中的所有内容!以后可以轻松更改数据..如果有的话。

Cards    |-These are common to the card across all Editions*
 CardId, CardName, DeckColor, ..
 |-PK-|  |-Possible Key?  -|

Editions
 EditionId, EditionName, ReleaseDate, ..
 |-PK   -|  |-Key?   -|

CardEditions        |-These are unique per Card/Edition
 CardId, EditionId, Rarity, Rules, ..
 |-PK           -|
 |-FK-|  |-FK   -|

(* Bill Karwin指出有多色卡片,arg!为了捕捉这个要求,像CardEditions一样浮动CardsColors关系。如果版本的颜色也发生变化,那么我只想哭...)

我在上面列出了一个简单的模式(可能没有完全标准化)。但是,为了进一步阅读,请查看“减少变化的数据”,因为有几种不同的方法可以处理它。


评论更新:

如何找到特定版本的卡片,说我们知道卡片名称和版本名称:

SELECT * FROM Cards c
JOIN CardEditions ed
  on ed.cardId = c.cardId
JOIN Edition e
  on e.editionId = ed.editionId
WHERE c.cardName = 'Some Awesome Card'
AND e.editionName = 'Ultimate'

请注意,如果CardName和EditionName用作主键(PK)并且在相应的FK中 - 而不是代理CardId / EditionId - 那么我们可能完全避免了连接。关于哪种方法更好,存在很大争议。我使用代理键来避免复合PK,除了在连接表(例如CardEditions)中,因为我喜欢使查询更简单。但是,这仍然使用/具有EditionId代理键..

可能的键(或“键?”)意味着我怀疑这个字段也应该被视为一个键 - 它应该应用一个唯一约束(可能是索引)。关系可以有多个Keys,其中Key是唯一标识记录所需的列集。主键只是通常用于此目的的“选定”键。

请注意,由于关系中存在多个Key,因此该模型未完全规范化;但是,我发现与代理键一致并定义次要约束是最有效的。这也是因为我喜欢将记录视为驱动模型的实体。

答案 1 :(得分:0)

了解MySQL是关系数据库,要正确利用其功能,您需要将对象关联在一起。因此,您需要做的第一件事就是了解您的不同对象是什么以及它们如何相互关联。根据您的描述,您提到了至少两个对象:卡片和版本。

所以我认为这意味着您需要两个表开始,cardseditions,但它们如何相关?如果存在一对多的关系(即每个版本可以有多张卡,但每张卡只属于一个版本),您可以在卡片中为版本ID设置一个外键。但在这种情况下,你似乎有多对多的关系。传统上,这是通过添加第三个表来解释这种关系来实现的。因此,在这种情况下,您可以添加一个cards_to_editions表,该表只包含两列,即卡ID和版本ID。这些都是它们各自表的外键,并且会形成表的复合主键。

如果存在特定于关系本身的任何属性,您还可以向cards_to_editions表添加属性(就像在这种情况下似乎“稀有”)。