Как реализовать объект с неизвестным максимальным количеством атрибутов?

Я разрабатываю программу моделирования бейсбола, и я столкнулся с проблемой разработки схемы boxscore. Проблема заключается в том, что я хочу отслеживать, сколько прогонов забито в каждом тайме. То, как я делаю это в реальной программе, - использовать динамический массив, который растет для каждого входящего воспроизведения.

Для тех, кто не знаком с игрой в бейсбол, игры обычно состоят из девяти подач, если игра не связана еще в конце девятого иннинга. Поэтому игры в бейсбол имеют неопределенную длину, что означает, что я не могу создать базу данных, чтобы иметь только 9 столбцов для прогонов, набранных для каждого иннинга (хорошо технически 18 (9-подач * 2 команды). Одна из моих идей - сериализовать массив и кодировать его как Base64, прежде чем хранить его в базе данных. Однако я не знаю, насколько это хорошая техника для использования, и мне было интересно, есть ли у кого-то лучшее представление.

В случае, если это имеет значение, база данных, которую я разрабатываю, - PostgreSQL.

Любые предложения приветствуются! Спасибо!

12 голосов | спросил Philip Lombardi 14 FebruaryEurope/MoscowbMon, 14 Feb 2011 14:25:04 +0300000000pmMon, 14 Feb 2011 14:25:04 +030011 2011, 14:25:04

3 ответа


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)
)

Вы можете нормализовать и иметь строку для каждой уникальной комбинации игры, команды и amp; нечего. Это позволит вам столько подач, сколько позволит тип данных 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 использует Sequences вместо IDENTITY, я не помню правильный синтаксис, поэтому переведите соответственно.

ответил Eric Humphrey - lotsahelp 14 FebruaryEurope/MoscowbMon, 14 Feb 2011 15:37:19 +0300000000pmMon, 14 Feb 2011 15:37:19 +030011 2011, 15:37:19
4

Я не думаю, что что-то не так, просто имея столбец

inning_score int[]

с 1 по 9 и далее. Это одно из немногих мест, где использование массива может быть разумным.

ответил Peter Eisentraut 16 FebruaryEurope/MoscowbWed, 16 Feb 2011 13:42:01 +0300000000pmWed, 16 Feb 2011 13:42:01 +030011 2011, 13:42:01
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'

Это даст вам максимальную комбинацию Inning, играемую для определенной игры, и вы можете дополнительно уточнить PlayerID -> TeamID, чтобы узнать больше, если хотите. Что это может быть, я не уверен.

Я бы, вероятно, на самом деле уточнил эту вторую таблицу, чтобы не быть RunsScored, а что-то об AtBat, потому что это действительно то, что вы отслеживаете. Я просто хотел показать, как можно денормализовать иннинге подальше от игрового стола. Я бы подстроил мою модель, чтобы течь так, это был мой проект. НТН. YMMV.

Также обратите внимание, что я парень TSQL, но я думаю, что приведенные ниже концепции работают очень хорошо для объяснения моей концепции. Вероятно, семантика языка не будет выстраиваться в линию.

ответил jcolebrand 14 FebruaryEurope/MoscowbMon, 14 Feb 2011 18:35:09 +0300000000pmMon, 14 Feb 2011 18:35:09 +030011 2011, 18:35:09

Похожие вопросы

Популярные теги

security × 330linux × 316macos × 2827 × 268performance × 244command-line × 241sql-server × 235joomla-3.x × 222java × 189c++ × 186windows × 180cisco × 168bash × 158c# × 142gmail × 139arduino-uno × 139javascript × 134ssh × 133seo × 132mysql × 132