我需要为典型的 RDBMS 设计一个数据模型,以模仿典型体育联盟的结构。在架构上我的要求是:
良好归一化
事务性的
应用程序开发人员可以使用流行的 ORM 工具对其进行相当好的建模
所需模式的属性:
可以有很多联赛。
一个联盟中可能存在 1 个或多个分区。
一个部门中可能存在 1 个或多个会议。
一个会议中可能存在 1 个或多个团队。
当且仅当该分区未被划分为联盟时,一个分区中可能存在 1 个或多个团队(换句话说,一个分区不需要拆分为联盟,而是一个团队可以直接引用单个分区而不是会议)
一个团队中可能存在 1 个或多个玩家。
Players存在于 1 个且仅 1 个Team中。
如果联盟结构是严格的,这将很容易做到并保持参考完整性。这就是我的想法,但我想知道这是否是一个好的设计,或者是否有更好的方法来应对这种情况。
联赛表:...
LeagueGroup 表:FK - LeagueId NOT NULL,FK - LeagueGroupParentId NULLABLE,LeagueGroupType
球队:FK - LeagueGroupId NOT NULL
玩家:FK - TeamId NOT NULL
所以基本上我在想 Divisions 和 Conferences 将是同一张表,带有一个向上查找其分组父项的自引用外键。这样做的好处是联赛分组其实可以N深。
缺点是这在 ORM 框架中映射可能不是很容易或有用。此外,应用程序开发人员可能需要编写一些逻辑来将其构建到对他们的目的有用的树状对象结构中。更进一步,如果没有某种触发器,我不知道如何从数据库级别强制团队不能同时存在于分区和会议级别。
您对这种方法有何看法,您是否看到任何可行的替代方法?
我想大多数体育联盟不会经常改变他们的会议、分区等层次结构……所以将每个级别放在自己的表中可能是安全的。
如果您的目标是一个可以处理具有不同层次结构深度的不同联赛的系统,那么递归表方法可能更好。
我不知道用 ORM 来做这件事有多容易,但是除了简单的 CRUD 操作之外,我对 ORM 普遍不信任......为了防止团队存在于层次结构的多个层级,我不确定为什么你的提议
Team.LeagueGroupId
行不通。LeagueGroup
你知道by 指的是什么级别,LeagueGroupID
所以你知道团队存在于那个级别LeagueGroup
。基本思想是将组织结构图的层次结构与实际团队分开。
桌子
Level
看起来像更多注意事项:
(PositionID, LevelID)
传播备用密钥TeamPosition
以允许检查约束 LevelID = 4——实际团队只能填写 Team_Slots。球队在一个赛季内不能更改 Team_Slot。
为简单起见,层次结构在这里使用 leveled-adjacency-list 建模;对于 SQL 层次结构不是最有效的,但足以解释。
有关更高效的层次结构模型,请参阅 Celko 的书或仅谷歌“SQL 层次结构”。