首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >单表w/额外列与重复模式的多个表

单表w/额外列与重复模式的多个表
EN

Software Engineering用户
提问于 2014-02-05 17:01:06
回答 2查看 16.7K关注 0票数 13

我正在从事一个项目,在某个时候,我需要决定在数据库中是否应该有一个包含多个列的表,而这些列并不是每个记录都使用的,还是多个表具有重复的模式。

我正在创建一个体育信息应用程序,可以处理多种体育活动。我们可以处理NBA,NHL,MLB,NFL等。每项运动都有非常相似的概念-球队,时间表,伤病,球员信息。

当然,我们的数据源不会在相同的模式中给出每个数据。每项运动都有一个不同的模式,我们从我们的供应商那里接收数据。

由于没有足够的时间(客户需求)对数据提要进行预先分析以确定共性,我对我的赌注进行了对冲,并采取了“安全打赌”,为每项运动分别制作了单独的表,而不是所有体育活动使用的一组表。

结果是在几个表中重复模式,因此也复制到数据库的接口(例如存储过程)。我有NBA_Game,NFL_Game,NBA_Team,NFL_Team等。每个表可能有其他表没有的一些属性,以及一些共享的属性。在4或5项运动中,比如5-10张桌子。我仍然不确定这是否完全是一件坏事--另一种选择是,拥有一组具有属性的表,而并不是所有的运动都会使用这些属性,它本身也可能是笨重的。

有没有人这样做过,遇到这种设计的陷阱,并可以分享他们的经验在这里?什么事情可以帮助我现在知道,而不是学习艰难的道路上的道路?你是否采取了另一种方式,有一个大表/一组表,列并不是每条记录都会用到?你做那件事时遇到了什么陷阱?

是否有其他选择,如您在过去使用过的表继承,效果更好?

谢谢

EN

回答 2

Software Engineering用户

发布于 2014-02-05 18:10:23

归根结底,这取决于使用和架构。

体系结构

系统处理“任何运动”吗?你是否把你的建筑宇航员帽,并建立一个通用的系统,可以处理任何未来类型的运动,甚至可能不存在今天?

如果是这样的话,拥有动态命名的表显然会带来巨大的痛苦,因此,如果需要的话,有一个支持n个体育运动的模式是有意义的。

尽管如此,我对这种方法有很强的偏见:这几乎总是更多的工作,导致更差的结果。为每个项目创建一个单独的UI、模式等最终会带来更好的用户体验和更容易维护代码,即使这确实意味着一些表面上的重复(如何避免/最小化这是一个单独的问题)。

你如何处理玩多项运动的运动员?他们会得到两个条目(例如,你把他们当作不同的人对待),还是你试图对他们做一些具体的事情?

使用

因此,让我们假设您不动态地进行体育活动(例如,如果有人想添加一项新运动,则需要开发工作来添加它)。

你是否曾经一次从多项运动中展示球员(或你提到的任何其他物体)?

我可以在搜索函数中看到这一点,您可以通过球员或团队名称进行搜索(不管是什么运动),但除此之外,我无法想象有多少用例。

如果您不需要这样做,那么您的方法是非常好的。你可以别在这里看书了。

替代模式

视图

我是个接吻迷。在15+年的软件开发中,我继续回到“构建最简单有效的东西”的哲学。

因此,我最初的反应,假设跨体育搜索功能是唯一的用例,就是创建视图:

代码语言:javascript
复制
SELECT PlayerName, 'NFL' as [Sport], TeamName FROM NFL_Players JOIN NFL_Teams ... 
UNION  
SELECT PlayerName, 'NHL' as [Sport], TeamName FROM NHL_Players JOIN NHL_Teams ... 
UNION ....

当然,如果您添加了一项新的运动,您必须添加到视图。包含其他公共信息也可能是有用的,但这实际上取决于需要显示什么。

我会尝试在视图定义中保留所有与体育相关的内容,这样搜索代码就不需要有太多或任何特定的代码(此外,可能知道如何链接到/nhl/players/player-name vs /nfl/...,或者您的应用程序会这样做)。

表继承

表继承可以工作,但非常复杂。我对它没有太多的经验,事实上,我认为每次我参与评估它时,我们都会做一些更简单的事情(就像我在这里建议的那样)。

因此,就我个人而言,我还没有找到为什么这会有用,但也许有一个令人信服的用例(我不知道)证明了复杂性(例如,表继承比任何其他解决方案更好地解决了用例)。

针对运动特定属性的

单独表

您可以执行一个players表,该表具有所有体育项目的所有参与者的公共属性,然后再执行另一组表(如nhl_players_details ),该表包含一个playerId和列,其中包含该播放器的其他信息。如果有很多共同的属性,或者你有很多“所有运动的运动员”的用法,那么这可能是有意义的。

运动特定属性的

键值对

完全可供选择的方法:有一个players表(同样具有名称之类的公共属性),然后有一个包含PlayerIdSportAttributeValueplayer_data表。输入的属性名将是特定于运动的。这允许您在不修改模式的情况下本质上添加新属性(当然,您的代码仍然需要知道如何加载/显示它们)。缺点是您失去了一些完整性:值通常是一个字符串字段,因此您的应用程序代码必须具有弹性,并处理将字符串value转换为特定数据类型(如整数)的潜在故障。

这个概念当然可以适用于团队,游戏等。

票数 12
EN

Software Engineering用户

发布于 2014-02-05 18:17:37

你说的是数据库规范化。了解到没有完美的数据模型,而且更多的规范化并不总是更好,您可能会松一口气。规范化可以在数据模型的清晰性和数据库性能方面增加成本。因此,要选择的最佳模型将取决于您的使用需求。

从表面上看,您的示例在概念上似乎非常相似(X_Game vs Y_Game和X_Team vs Y_Team),因此一些列的额外开销似乎并不不合理。也就是说,如果每项运动都要在桌子上增加几十个栏目,那就太麻烦了。

在这种情况下,您可能希望考虑一种混合模型,其中公共数据保存在一个中央表中,而特定于运动的数据保存在一个链接的数据结构中。类似于:

代码语言:javascript
复制
table Game {
    gameId int,
    teamId1 int fk,
    teamId2 int fk
}

table HockeyGame {
    gameId int fk,
    penaltyMinutes int
}

table BasketballGame {
    gameId int fk,
    freeThrows int
}
票数 5
EN
页面原文内容由Software Engineering提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://softwareengineering.stackexchange.com/questions/227832

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档