Struktur Database untuk game 2v2

10

Saya secara teratur memainkan permainan 2v2 dengan 12 teman dan saya ingin database untuk melacak pemain, tim, skor dan permainan, dengan tujuan menciptakan sistem peringkat.

Karena kami secara teratur mengganti tim, saya menghasilkan tabel players, teamsdan di gamesmana permainan memiliki dua tim (team1 dan team2) dan tim terdiri dari dua pemain (pemain1 dan pemain2).

Ini menyebabkan beberapa masalah - misalnya jika saya memilih dua pemain (sebut saja mereka A dan B ) untuk bermain bersama, saya harus memeriksa apakah sudah ada tim di mana Player1 adalah A dan Player2 adalah B atau Player1 adalah B dan Player2 adalah.

Kolom gamesdan winsada di kedua playerstabel dan teamstabel - tapi ini karena saya ingin melihat berapa banyak permainan dimenangkan oleh para pemain, tetapi juga seberapa kompatibel pemain dalam tim yang berbeda (seberapa sering seorang pemain menang ketika bergabung dengan pemain spesifik lain).

  1. Papan skor peringkat (saya mungkin akan menggunakan sistem peringkat Elo )
  2. Halaman statistik untuk setiap pemain dengan peringkat, kemenangan, permainan, statistik game terbaru, dan pemain mana yang paling cocok dengannya.

Saya sangat curiga bahwa banyak dari ini melanggar beberapa prinsip dalam normalisasi basis data, dan saya akan senang dengan beberapa saran bagaimana menerapkan desain basis data saya.

Desain Basis Data

Daniel
sumber
Saya pikir ini adalah pertanyaan yang sangat bagus. Senang melihat struktur DB Anda saat ini yang digambarkan dalam pertanyaan. Tidak semua orang tahu Laravel's Schema Builder. Kasing bekas juga bisa lebih baik sehingga kami memahami kebutuhan Anda yang sebenarnya.
candied_orange
Terima kasih banyak @CandiedOrange - Saya telah menambahkan diagram struktur DB, dan akan menambahkan lebih banyak kasus penggunaan :)
Daniel
Pembaruan yang bagus. Apakah saya benar dengan mengasumsikan bahwa setiap pemain hanya akan berada di satu tim pada satu waktu dan hanya dalam satu pertandingan pada satu waktu? Juga, bahwa pemain pergi dan kembali ke tim lama tanpa mengatur ulang info untuk tim itu?
candied_orange
@CandiedOrange Pada dasarnya ketika kita ingin memainkan permainan, kita menemukan 4 pemain (dari total ~ 12 pemain) dan secara acak timkan mereka dalam tim-tim 2.
Daniel
Saya tidak tahu apakah itu ya atau tidak. Saya mencoba memahami bagaimana waktu memengaruhi desain Anda.
candied_orange

Jawaban:

2

Ada dua masalah yang saya lihat dengan skema Anda saat ini, satu adalah masalah harus memeriksa dua bidang dalam tabel untuk menentukan apakah kunci majemuk secara efektif merupakan duplikat, dan, beberapa data agregat digulung ke dalam tabel individual untuk memisahkan entitas (menang, terutama, tetapi juga berpotensi peringkat pemain).

Untuk masalah pertama, tidak ada trik dalam-DB untuk membuat salah satu / setiap bidang kunci majemuk diperlakukan dengan cara ATAU yang Anda cari, tetapi jika DB Anda mendukungnya, Anda bisa membuat fungsi getPlayerTeams(player_id)untuk merangkum kueri.

(Anda juga dapat membuat tampilan dengan sidik jari team_thumb yang dihitung sebagai hash dari id pemain yang disortir, sehingga kombo apa pun dari dua orang yang sama selalu menghasilkan sidik jari yang sama, tetapi itu mungkin agak banyak di sini).

Sejauh normalisasi, pertimbangkan memisahkan entitas dari hasil yang terjadi dengan menggunakan team_resulttabel untuk melacak semua hasil untuk tim tertentu. Normalisasi yang sedikit lebih ekstrem juga akan membutuhkan player_rating_histtabel, yang berisi semua perubahan peringkat untuk pemain. Peringkat mereka saat ini hanyalah yang dengan tanggal terbaru. Tampilan pemain juga dapat digunakan untuk berisi nilai terbaru untuk kueri yang mudah.

Skema yang diajukan (maaf tidak ada diagram):

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

Pertanyaan:

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

Struktur ini memungkinkan memisahkan entitas "basis" (pemain dan tim) dari "konten" yang terjadi akibat sistem berjalan seiring waktu, dan berarti Anda tidak terus-menerus memperbarui salah satu tabel dasar dengan peringkat saat ini, # menang, dll. Itu adalah nilai turunan dan harus diambil dengan mendapatkan peringkat terbaru, peringkat rata-rata, COUNTmenang atau kalah, dll. Jika sistemnya cukup besar, Anda dapat mempertimbangkan mengekstraksi data agregat tersebut ke "gudang" terpisah. (bahkan jika itu hanya seperangkat tabel terpisah dalam DB yang sama) untuk analitik yang lebih mudah.

Dan1701
sumber