Làm thế nào để thực hiện một thực thể với số lượng thuộc tính tối đa không xác định?


12

Tôi đang thiết kế một chương trình mô phỏng bóng chày và tôi đã gặp phải một vấn đề với việc thiết kế lược đồ boxscore. Vấn đề tôi có là tôi muốn theo dõi có bao nhiêu lượt chạy được ghi trong mỗi hiệp. Cách tôi làm điều này trong chương trình thực tế là sử dụng một mảng động phát triển cho mỗi hiệp được chơi.

Đối với những người không quen thuộc với trò chơi bóng chày, các trò chơi thường kéo dài chín hiệp trừ khi trò chơi được buộc yên vào cuối hiệp thứ 9. Do đó, các trận bóng chày có độ dài không xác định, điều đó có nghĩa là tôi không thể thiết kế cơ sở dữ liệu chỉ có 9 cột cho các lượt chạy được ghi trong mỗi hiệp (về mặt kỹ thuật là 18 (9 hiệp * 2 đội). Một ý tưởng tôi có là nối tiếp mảng và mã hóa nó thành Base64 trước khi lưu trữ nó trong cơ sở dữ liệu. Tuy nhiên, tôi không biết liệu đây có phải là một kỹ thuật tốt để sử dụng hay không và tôi đã tự hỏi liệu có ai có ý tưởng tốt hơn không.

Trong trường hợp có vấn đề, cơ sở dữ liệu tôi đang phát triển xung quanh là PostgreSQL.

Bất kỳ đề xuất đều được đánh giá rất cao! Cảm ơn!

Câu trả lời:


7

Bạn có thể làm điều này. Nó sẽ cho phép hiệu suất tốt cho các trò chơi có thời lượng bình thường, đồng thời cho phép bạn lưu trữ các trò chơi chạy dài.

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

Bạn có thể bình thường hóa hơn nữa và có một hàng cho mỗi kết hợp trò chơi, đội và trò chơi độc đáo. Điều này sẽ cho phép bạn có nhiều hiệp như kiểu dữ liệu InningId sẽ cho phép.

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

Chỉnh sửa : Tôi biết PostgreSQL sử dụng Chuỗi thay vì IDENTITY, tôi không nhớ lại cú pháp đúng, vì vậy hãy dịch theo.


haha, tôi thích rằng tôi cố tình không đọc câu trả lời của bạn cho đến khi tôi viết bài của mình và chúng tôi rất thân với người kia. Đẹp.
jcolebrand

Cảm ơn bạn vì câu trả lời này, nó có ý nghĩa và sẽ là cách tôi thực hiện lược đồ điểm số hộp.
Philip Lombardi

4

Tôi không nghĩ có gì sai khi chỉ có một cột

inning_score int[]

cho 1 đến 9 và hơn thế nữa. Đó là một trong số ít nơi sử dụng một mảng có thể hợp lý.


3

Vì vậy, những gì tôi thấy ở đây là một chút mâu thuẫn bởi vì các hiệp đấu không thực sự trực tiếp là một thuộc tính của trò chơi, ngoại trừ một cách gián tiếp. Nhưng có lẽ đó chỉ là tôi. Cá nhân tôi sẽ đề xuất một cái gì đó giống như bảng RunsScored và để nó liên kết trở lại bảng GamesHeader, vì vậy hãy cân nhắc:

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'

Điều đó sẽ cung cấp cho bạn Inning tối đa được chơi cho một trò chơi cụ thể và bạn có thể tinh chỉnh thêm bằng PlayerID -> TeamID để tìm hiểu thêm chi tiết nếu bạn muốn. Những gì có thể là tôi không chắc chắn.

Tôi thực sự có thể tinh chỉnh bảng thứ hai đó không phải là RunsScored mà là một cái gì đó về AtBat bởi vì đó thực sự là những gì bạn đang theo dõi. Tôi chỉ muốn cho thấy làm thế nào bạn có thể làm bất thường hóa các hiệp đấu từ bàn trò chơi. Tôi sẽ điều chỉnh mô hình của mình để lưu chuyển như vậy, đây có phải là dự án của tôi không. HTH. YMMV.

Cũng lưu ý rằng tôi là một người TSQL, nhưng tôi nghĩ các khái niệm được trình bày dưới đây hoạt động khá tốt để giải thích khái niệm của tôi. Ngữ nghĩa ngôn ngữ có lẽ sẽ không xếp hàng.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.