최대 속성 수를 알 수없는 엔터티를 구현하는 방법은 무엇입니까?


12

나는 야구 시뮬레이션 프로그램을 디자인하고 있고 박스 스코어 스키마 디자인에 문제가 생겼다. 내가 가진 문제는 각 이닝에서 얼마나 많은 런이 득점되는지 추적하고 싶다는 것입니다. 실제 프로그램 에서이 작업을 수행하는 방법은 재생 시마다 증가하는 동적 배열을 사용하는 것입니다.

야구 경기에 익숙하지 않은 사람들은 게임이 9 이닝이 끝날 때까지 묶이지 않는 한 일반적으로 9 이닝 길이입니다. 따라서 야구 게임은 길이가 정해지지 않았기 때문에 매 이닝마다 득점이 9 회 밖에되지 않도록 데이터베이스를 설계 할 수 없습니다 (기술적으로 18 (9 이닝 * 2 팀)). 데이터베이스에 저장하기 전에 Base64로 인코딩해야하지만이 기술을 사용하는 것이 좋은지 모르겠으며 더 좋은 아이디어가 있는지 궁금합니다.

중요한 경우, 내가 개발중인 데이터베이스는 PostgreSQL입니다.

어떤 제안이라도 대단히 감사합니다! 감사!

답변:


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 대신 Sequences를 사용한다는 것을 알고 있습니다. 올바른 구문을 기억하지 못하므로 적절하게 번역하십시오.


haha, 나는 내가 내 것을 쓸 때까지 고의적으로 당신의 대답을 읽지 않았고 우리는 다른 것에 매우 가깝습니다. 좋은.
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 사람이지만 아래에 표시된 개념은 내 개념을 설명하는 데 매우 효과적이라고 생각합니다. 언어 의미론이 정렬되지 않을 수 있습니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.