Cấu trúc cơ sở dữ liệu cho trò chơi 2v2


10

Tôi thường xuyên chơi một trò chơi 2v2 với 12 người bạn và tôi muốn có cơ sở dữ liệu để theo dõi người chơi, đội, điểm số và trò chơi, với mục đích tạo ra một hệ thống xếp hạng.

Kể từ khi chúng tôi thường xuyên thay đổi đội tôi đã đi lên với các bảng players, teamsgamesnơi mà các trò chơi có hai đội (Đội 1 và TEAM2) và các đội gồm hai người chơi (player1 và player2).

Điều này gây ra khá nhiều vấn đề - ví dụ: nếu tôi chọn hai người chơi (hãy gọi họ là AB ) để chơi cùng nhau, tôi phải kiểm tra xem đã tồn tại một đội trong đó Player1 là A và Player2 là B hay Player1 là B và Player2 là một.

Các cột gameswinscó mặt trong cả playersbảng và teamsbảng - nhưng điều này là do tôi muốn xem cả hai người chơi giành được bao nhiêu trò chơi, nhưng cũng có khả năng người chơi tương thích trong các đội khác nhau như thế nào (tần suất người chơi chiến thắng khi hợp tác với một người chơi cụ thể khác).

  1. Bảng xếp hạng (tôi có thể sẽ sử dụng hệ thống xếp hạng Elo )
  2. Một trang thống kê cho mọi người chơi có xếp hạng, chiến thắng, trò chơi, số liệu thống kê trò chơi gần đây và người chơi nào anh ta tương thích nhất.

Tôi nghi ngờ rằng phần lớn điều này vi phạm một số nguyên tắc trong chuẩn hóa cơ sở dữ liệu và tôi sẽ thích một số đề xuất như cách triển khai thiết kế cơ sở dữ liệu của tôi.

Thiết kế cơ sở dữ liệu


Tôi nghĩ rằng đây là một câu hỏi rất hay. Rất thích xem cấu trúc DB hiện tại của bạn được sơ đồ hóa trong câu hỏi. Không phải ai cũng biết Schema Builder của Laravel. Các trường hợp sử dụng cũng có thể được bổ sung tốt hơn để chúng tôi hiểu nhu cầu thực sự của bạn.
candied_orange

Cảm ơn bạn rất nhiều @CandiedOrange - Tôi đã thêm sơ đồ cấu trúc DB và sẽ thêm nhiều trường hợp sử dụng :)
Daniel

Cập nhật tốt đẹp. Tôi có đúng không khi cho rằng mỗi người chơi sẽ chỉ ở một đội một lần và chỉ một trò chơi tại một thời điểm? Ngoài ra, người chơi đó rời đi và trở về đội cũ mà không đặt lại thông tin cho đội đó?
candied_orange

@CandiedOrange Về cơ bản khi chúng tôi muốn chơi một trò chơi, chúng tôi tìm thấy 4 người chơi (trong tổng số ~ 12 người chơi) và ngẫu nhiên lập nhóm chúng trong các đội 2.
Daniel

Tôi không thể biết đó là có hay không. Tôi đang cố gắng hiểu thời gian tác động đến thiết kế của bạn.
candied_orange

Câu trả lời:


2

Có hai vấn đề mà tôi thấy với lược đồ hiện tại của bạn, một là vấn đề phải kiểm tra hai trường trong một bảng để xác định xem khóa ghép có thực sự trùng lặp hay không, và một số dữ liệu tổng hợp được cuộn thành các bảng riêng lẻ các thực thể (đặc biệt là chiến thắng, nhưng cũng có khả năng là xếp hạng của người chơi).

Đối với vấn đề đầu tiên, không có thủ thuật trong DB để làm cho / bất kỳ trường nào của khóa ghép được xử lý theo cách OR mà bạn đang tìm kiếm, nhưng nếu DB của bạn hỗ trợ nó, bạn có thể tạo một hàm getPlayerTeams(player_id)để đóng gói các truy vấn.

(Bạn cũng có thể tạo chế độ xem với team_thumbprint được tính là hàm băm của id người chơi được sắp xếp, sao cho mọi kết hợp của hai người giống nhau luôn dẫn đến cùng một dấu vân tay, nhưng điều đó có thể hơi nhiều ở đây).

Theo như bình thường hóa, hãy xem xét tách các thực thể khỏi các kết quả xảy ra bằng cách sử dụng team_resultbảng để theo dõi tất cả các kết quả cho một nhóm nhất định. Một chút bình thường hóa cực đoan hơn cũng sẽ gọi cho một player_rating_histbảng, chứa tất cả các thay đổi về xếp hạng cho người chơi. Đánh giá hiện tại của họ chỉ đơn giản là một trong những ngày gần đây nhất. Một khung nhìn người chơi cũng có thể được sử dụng để chứa giá trị gần đây nhất để truy vấn dễ dàng.

Lược đồ đề xuất (xin lỗi không có sơ đồ):

player
    id
    name
    created_on
    updated_on

player_rating_hist
    player_id (FK)
    rating
    rating_date

team
    id
    player1_id (FK)
    player2_id (FK)
    created_on
    updated_on

game
    id
    team1_id (FK)
    team2_id (FK)

team_game
    team_id (FK)
    game_id (FK)
    result
    score
    rating_change

team_rating_hist
    team_id (FK)
    rating
    rating_date

Truy vấn:

--Results for the game, should only ever be two rows for any given game
SELECT * FROM team_game WHERE game_id = 101

--All results for a team
SELECT * FROM team_game WHERE team_id = 123456 

Cấu trúc này cho phép tách các thực thể "cơ sở" (người chơi và đội) khỏi "nội dung" xảy ra do hệ thống chạy theo thời gian và có nghĩa là bạn không liên tục cập nhật một trong các bảng cơ sở với xếp hạng hiện tại, # của chiến thắng, v.v ... Đó là các giá trị xuất phát và nên được truy xuất bằng cách nhận xếp hạng gần đây nhất, xếp hạng trung bình, COUNTthắng hoặc thua, v.v. Nếu hệ thống đủ lớn, bạn có thể xem xét trích xuất dữ liệu tổng hợp đó vào một "kho" riêng biệt (ngay cả khi đó chỉ là một tập hợp các bảng riêng biệt trong cùng một DB) để phân tích dễ dàng hơn.

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.