如何实现具有最大属性数量未知的实体?


12

我正在设计一个棒球模拟程序,但是在设计boxscore模式时遇到了问题。我的问题是我想跟踪每个局得分多少次。我在实际程序中执行此操作的方法是使用一个动态数组,该数组随所播放的每个局而增长。

对于那些不熟悉棒球比赛的人,通常比赛会长9局,除非比赛在第9局结束时并列。因此,棒球比赛的长度没有确定,这意味着我不能设计数据库仅将9列记录为每一局的得分(技术上来说是18列(9局* 2队)。我不得不想到的是序列化数组并在将其存储到数据库之前将其编码为Base64,但是,我不知道这是否是一种很好的技术,我想知道是否有人有更好的主意。

万一重要,我正在开发的数据库是PostgreSQL。

任何建议,不胜感激!谢谢!

Answers:


7

你可以做到这一点。对于正常时间的游戏,它可以提供良好的性能,同时还可以存储长时间运行的游戏。

CREATE TABLE InningRuns (
    GameId INT NOT NULL REFERENCES [...],
    Team CHAR(4) NOT NULL, --'Home','Away'
    Inning1 TINYINT, --Seeing how more than 255 runs are not really possible in an inning
    Inning2 TINYINT,
    [...],
    Inning9 TINYINT,
    ExtraInnings XML | TINYINT[] | VARBINARY | ETC., --Use to hold any runs in extra innings.
    PRIMARY KEY (GameId, Team)
)

您可以进一步规范化,并为游戏,团队和比赛的每个独特组合排一行。这将允许您使用InningId数据类型所允许的尽可能多的局。

CREATE TABLE InningRuns (
    InningRunId INT IDENTITY PRIMARY KEY,
    GameId INT NOT NULL REFERENCES [...],
    Team CHAR(4) NOT NULL, --'Home','Away'
    InningId TINYINT, --Seeing how more than 255 innings might be excessive
    Runs TINYINT,
    UNIQUE (GameId, Team, InningId)
)

编辑:我知道PostgreSQL使用序列而不是IDENTITY,我记不清正确的语法,因此进行相应的翻译。


哈哈,我喜欢那样,我故意直到我写完我的信才读到你的答案,而我们彼此之间的关系非常密切。真好
jcolebrand

谢谢您的回答,这很有意义,这将成为我实现盒式评分方案的方式。
菲利普·隆巴迪

4

我不认为只有专栏有什么问题

inning_score int[]

1到9及以后。那是使用数组可能是合理的少数几个地方之一。


3

所以我在这里看到的有点矛盾,因为局限并不是间接地真正地直接构成游戏的属性。但是也许就是我。我个人建议使用类似RunsScored表的表,并将其链接回某种形式的GamesHeader表,因此请考虑:

CREATE TABLE GamesHeader (
    GameID     INT IDENTITY(1,1),
    HomeTeamID INT,  --FK to teams table, naturally
    AwayTeamID INT,  --FK to teams table, naturally
    FinalInningsCount BYTE,  -- for faster reporting after the game is over
    FinalHomeScore BYTE,     -- for faster reporting after the game is over
    FinalAwayScore BYTE,     -- for faster reporting after the game is over
    --Other attribs
)

CREATE TABLE RunsScored (
    RunsScoredID BIGINT IDENTITY(1,1), -- for faster reverse traversal, possibly. May not be needed, this depends on your setup, as the normalization will show a composite key anyways
    PlayerID INT,   --FK to players table naturally
    GameID INT,     --FK to GamesHeader table naturally
    Inning BYTE, --wait for the payoff
    RunsEarned,     --because you may want to track this by the player ... really the problem is that there's not a single naturalized setup for this, so you may be intersecting this table to another stats table elsewhere. idk, it depends on your model. I'm going for fairly simplistic atm. Wanted to demonstrate something else entirely, but this needs to be accounted for.
     -- other attribs
)

SELECT MAX(r.Inning) FROM RunsScored r JOIN GamesHeader g ON g.GameID = r.GameID WHERE GameID = 'x'

这将为您提供特定游戏的最大局限性,如果需要,您可以通过PlayerID-> TeamID进一步完善以找出更多细节。我不确定那些可能是什么。

我实际上可能会优化第二张表,而不是RunsScored,而是关于AtBat的东西,因为这正是您要跟踪的内容。我只是想说明如何从游戏桌中取消局数的标准化。我将模型调整为像我的项目那样流动。HTH。YMMV。

另请注意,我是TSQL专家,但我认为以下表达的概念可以很好地解释我的概念。语言语义可能不会对齐。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.