构建数据库关系以跟踪应用程序设置的不同变化

时间:2019-10-16 03:36:30

标签: database-design foreign-keys relational-database primary-key composite-primary-key

我目前正在设计的一个应用程序允许用户创建自定义的竞争性联赛(认为它类似于幻想体育),并且每个用户可以加入不同的联赛,并且每个联赛都由多个回合组成,其中用户(以下称为球员) )将竞争,并可以为每个联赛建立不同的标准/成就而获得积分。这里是一些要注意的关键信息:

  • 联赛/赛季中所有回合都累积积分
  • 自定义分数标准/权重设置可以在每个回合中更改。我认为大部分情况下,这些回合点设置会在整个联赛(即赛季)内保持相对一致,但一个联赛当然可以选择进行很多切换。通过我目前的设置方式,联赛将建立一组默认的联赛级别积分设置,这将是每一轮的默认设置,但他们始终可以决定更新积分权重,添加新的积分设置或停用/激活他们。由于这些子设置可能会逐轮变化,因此我应该为默认联赛级别积分设置使用一张表格,然后为轮级子设置使用另一张表格,其中将包括针对每个联赛实际实现的所有设置一轮?
  • 与上述类似,每个回合可以由不同的玩家组成;它不一定要在每个回合中都是联盟的成员/球员或同一组球员,所以我目前有一张表代表联盟球员,一张代表回合球员,然后有一张表跟踪每个球员所获得的积分外键链接到其他表,对我来说似乎有点奇怪。

这种方法是否有意义,或者我是否在思索或遗漏某些东西?下面是我制作的实体关系图的图像的链接,这让我感到有些奇怪,尤其是使用Point Earned表时,但这可能是由于我缺乏设计关系数据库的经验所致。请注意,用“ CPK”列出的字段是复合主键,由该表中相应外键的串联组成。任何反馈都是欢迎的,谢谢!

link to image of ERD

1 个答案:

答案 0 :(得分:1)

确认

  

[释义]因为点的设置可能会逐轮变化,所以我应该:

     
      
  • 一个用于默认联赛级别积分设置的表
  •   
  • 然后再进行一次圆点设置
  •   
     

那将记录每轮实际实施的得分设置?

是的。您隐式声明的是,一个回合具有一个设置,即:

  • 两个联盟级别的设置
  • 自定义设置。

这是逻辑上的典型“或”门,有一种在RElational数据库中实现该门的正确方法:排他子类型

  

我目前有一张桌子供联盟玩家使用,一张供圆形游戏玩家使用

是正确的:它们是两个离散的事实,后者与前者相关。这意味着:

  • 玩家必须先注册为League_player
  • 因此,
  • 玩家可以注册为round_player
      在他被注册为League_player的联赛中,
    • 并且
  

然后是一个表,该表跟踪每个基本上具有外键链接到其他表的玩家的得分

您的数据模型此时已脱离轨道。


问题

  1. 显然,您已经了解了数据完整性的价值。例如。您正在尝试确保一个联赛中一轮比赛的球员实际上是该联赛中注册的球员;等。非常好。您正在尝试实现关系完整性,这是合乎逻辑的(与SQL的物理功能“引用完整性”不同)。

    • 您已经知道,做到这一点的唯一方法是使用复合键。优秀。组合键是关系数据库中的普通票价。
  2. 但是,第二个问题是您没有键,而物理Record IDs ...声明为“键”。因此,您要约束的逻辑事物(数据是逻辑的)不受约束。而这种努力,这种尝试导致了数十种关系……没有达到预期的结果。

  3. 关系键

    • 由E F Codd博士在 关系模型 中定义:
      • [关系,逻辑]键是由数据组成
      • 引用是通过逻辑关系键
    • 1960年的记录归档系统,该系统由“理论学家”大量推销,并被欺诈地命名为“关系”:
      • 引用是通过物理Record ID引用的。
      • 这类原始系统没有关系完整性;没有关系权力;而且没有关系速度。
  4. 您正在使用声明为“键”的Record IDs(这会使您感到困惑,因为它不是Key,并且不具有Key的所有属性)。然后尝试通过复合键获得 some 关系完整性(您直觉上只知道 Relational Model 提供)...但是您使用的是声明的Non-Keys,因此它会失败,并会尝试建立一个复杂的模型。

    • 更正是使用逻辑关系键,来避免物理Record IDs
  5. 此外,您的CPK是克服“理论家”局限性的一次伟大尝试,但它没有确切说明由哪些列组成。如果使用IDEF1X(关系数据建模的标准),可以很容易地纠正这一点:构成键(主键或备用键)的列是显式的。

  6. 下一个问题是,您的逻辑行(不同于物理记录)不是唯一的,并且 RM 要求逻辑行是唯一的。

    • 例如在User中,username不是唯一的
      jasonr_user
    • username实际上是逻辑键(它将使行唯一)
    • 您还需要在(first_name, last_name)上具有唯一性,这是第二个逻辑键
    • 如果您了解上述内容,将会了解:
      • user_id是100%无用的(什么也没有实现,它只是一个附加列和一个附加索引,应避免使用)
      • username是真实的逻辑PRIMARY KEY,无论引用到哪里,它都将迁移为FOREIGN KEY
      • 因此,
      • FK引用对事物本身是逻辑的,而不是物理的,指向指向事物 可能的记录的指针>是。
  7. 同样,您可以摆脱所有Record IDs

关系数据模型

您已经在物理上受过教育(错误地命名为“关系”),并且您试图“上移”到逻辑中。好主意,但这行不通。逻辑首先出现,当准备就绪时,一个“下移”到物理中。物理服务于逻辑,而不是相反。

尝试一下。

jasonrTA1

注意•表示法

  • 我所有的数据模型均以IDEF1X(自1993年以来的关系数据库建模标准)呈现。

  • 我的IDEF1X Introduction对于初学者来说是必不可少的阅读

  • IDEF1X Anatomy是那些已经过时的人的复习。

注意•内容

  • 关系键

    • 所有键都是逻辑关系键,它们是复合键
    • 所有数据均受关系键约束(这是关系完整性
    • round_player必须在league所在的round中注册
    • round_default_weight必须是为league_weights所在的league设置的有效round之一
    • 等等
    • 如果您在(a)声明或(b)对作为复合材料的外键进行编码时遇到困难,请告诉我,我将提供它。
  • 专有子类型

    • 每个round具有一个round_default_weight或一个round_custom_weight
    • 有关子类型实现的详细信息,请参见Subtype
  • 我不明白您所说的point_setting是什么意思。我理解这是对得分进行了模拟的权重。

  • 我不明白您为什么将Point Earned作为一个单独的文件(即与多个父母分开的文件)。这似乎是每得分的一项记录。假设只有玩家可以得分,您可以将积分累积到round_player行中。

  • 您的设计允许每个league的多个管理员,而不是一个。请确认。

享受。请随时提出具体问题。可能需要澄清:确定后,我将发布进度数据模型。

评论

  

如果我跟踪round_player表中的积分,我只能跟踪round期间获得的总积分吗?

是的

  

对于每个回合中获得的积分,我想跟踪每个玩家在每个回合中获得的每个积分,以便您可以回头查看特定的积分类型以及为玩家赢得的积分数量。

好的。尝试这个。

jasonrTA2

  • 每个round_player的每个round的每个point都不需要维护一行。我们可以每point_type保留一行,而不是每point_type包含总点。

  • 您需要指定point_types(我以橄榄球点类型为例)。

  • 这是一个普通表,而不是引用表或“查找”表,因为该关系是可识别的。