Khi nghe những gì tôi làm, mọi người có xu hướng hỏi tôi cùng một câu hỏi: Bạn có thể phát triển một hệ thống dự đoán kết quả trận đấu bóng đá không? Hay kết quả huy chương Olympic? Cá nhân tôi không đặt nhiều niềm tin vào các dự đoán. Tuy nhiên, nếu chúng tôi có một lượng lớn dữ liệu lịch sử và các chỉ số liên quan, chúng tôi chắc chắn có thể thiết kế một hệ thống để giúp chúng tôi đưa ra các giả định chính xác hơn. Trong bài viết này, chúng tôi sẽ xem xét một mô hình có thể lưu trữ kết quả của các trận đấu và giải đấu.
Mô hình này chủ yếu tập trung vào các trận đấu, số liệu thống kê và kết quả của bóng đá châu Âu, nhưng nó có thể dễ dàng được điều chỉnh để phù hợp với nhiều môn thể thao khác. Động lực chính của tôi cho bài viết này là hai sự kiện bóng đá lớn của năm nay:Giải vô địch UEFA Euro 2016 vừa diễn ra và Thế vận hội Olympic mùa hè 2016 đang diễn ra ngay bây giờ.
Chúng ta biết gì trước khi giải đấu bắt đầu?
Trước khi giải đấu bắt đầu, chúng tôi đã biết gần như mọi thứ về nó - ngoại trừ điều quan trọng nhất:ai sẽ chiến thắng. Hãy trình bày ngắn gọn chính xác những gì chúng ta đã biết:
- Ngày bắt đầu và kết thúc giải đấu
- Địa điểm các trận đấu sẽ diễn ra
- Thời gian chính xác các trận đấu sẽ bắt đầu
- Đội nào đã vượt qua vòng loại giải đấu
- Các cầu thủ của mỗi đội này
- Màn trình diễn trong quá khứ của mỗi người chơi và phong độ hiện tại của họ
Chúng tôi muốn lưu trữ chi tiết đối sánh nào?
Các giải đấu bao gồm nhiều trận đấu. Trước khi lưu trữ bất kỳ thông tin chi tiết nào về trận đấu, chúng tôi cần:
- Liên hệ từng trận đấu với giải đấu
- Ghi lại giai đoạn giải đấu khi trận đấu được diễn ra (ví dụ:vòng bảng, bán kết)
Chúng tôi cũng cần lưu trữ thông tin chi tiết về các kết quả phù hợp đơn lẻ, bao gồm:
- Các đội tham gia trận đấu
- Đội hình xuất phát và sự thay thế
- Các sự kiện trong trận đấu (trong bóng đá, đó là:bàn thắng, quả phạt đền, phạm lỗi, thẻ vàng, v.v.)
- Điểm số cuối cùng
- Hành động của người chơi trong trận đấu
Chúng tôi sẽ sử dụng dữ liệu này để nắm bắt tất cả các sự kiện đối sánh quan trọng. So sánh hiệu suất của một cầu thủ trước và trong trận đấu có thể dẫn đến một số kết luận nhất định. Có thể chúng tôi sẽ không thể dự đoán kết quả cuối cùng về hiệu suất của họ (tức là thắng hay thua), nhưng số liệu thống kê chắc chắn có thể giúp chúng tôi đưa ra các giả định với mức độ tin cậy.
Giới thiệu Mô hình
Mô hình được chia thành bốn lĩnh vực chính:
-
Tournament details
-
Match details
-
Events
-
Indicators and Performance
Các bảng bên ngoài các khu vực này là từ điển (sport
, phase
, position
), danh mục (sport_event
, team
, player
) và một quan hệ nhiều-nhiều (plays
).
Trước tiên, chúng tôi sẽ mô tả các bảng chưa được phân loại, sau đó xem xét kỹ từng khu vực.
Các bảng chưa được phân loại
Các bảng này rất quan trọng vì các bảng từ cả bốn lĩnh vực đều sử dụng chúng làm từ điển hoặc danh mục.
sport
bảng liệt kê tất cả các môn thể thao mà chúng tôi sẽ lưu trữ trong cơ sở dữ liệu của mình. Chúng tôi có thể sẽ chỉ có một môn thể thao ở đây, bóng đá nam, nhưng bảng này cho phép chúng tôi linh hoạt thêm các môn thể thao tương tự (ví dụ:bóng đá nữ) nếu cần.
Trong sport_event
bàn, chúng tôi sẽ lưu trữ các sự kiện liên quan đến (các) môn thể thao của chúng tôi. Một ví dụ là “Thế vận hội Olympic 2016”.
phase
bảng là một từ điển chứa tất cả các giai đoạn giải đấu có thể có. Nó chứa các giá trị như “giai đoạn nhóm” , “vòng 16” , “vòng tứ kết” , “bán kết” , “cuối cùng” .
team
như bạn đoán, bảng là một danh sách đơn giản của tất cả các đội. Các giá trị có thể có là “Croatia” , “Ba Lan” , “Hoa Kỳ” v.v ... Nếu chúng tôi sử dụng cơ sở dữ liệu để lưu trữ thông tin về cuộc thi của câu lạc bộ hoặc liên đoàn, chúng tôi cũng sẽ có các giá trị như “Barcelona” , “Real Madrid” , “Bayern” , “Manchester United” vv
Trong player
bảng, chúng tôi sẽ lưu trữ hồ sơ cho tất cả người chơi thuộc các đội liên quan.
plays
bảng là mối quan hệ nhiều-nhiều duy nhất của chúng tôi và nó liên quan đến người chơi và đội. Một cầu thủ có thể thuộc nhiều đội cùng một lúc (ví dụ:đội tuyển quốc gia và câu lạc bộ), nhưng trong một giải đấu, họ rõ ràng sẽ chỉ chơi cho một đội.
Cuối cùng, chúng ta có position
bàn. Từ điển đơn giản này sẽ lưu trữ một danh sách tất cả các vị trí cần thiết. Trong bóng đá, chúng bao gồm thủ môn, trung vệ, tiền đạo, v.v.
Chi tiết Giải đấu
Lưu ý: Nếu bạn chỉ muốn lưu trữ kết quả của các trận đấu đơn lẻ, bạn không cần sử dụng phần này.
Một giải đấu bao gồm nhiều hơn một trận đấu; cả UEFA Euro 2016 và các sự kiện bóng đá trong Thế vận hội Mùa hè 2016 đều là các giải đấu. Như chúng tôi đã nói trước đây, chúng tôi có thể lưu trữ một trận đấu duy nhất trong cơ sở dữ liệu của mình, nhưng chúng tôi cũng có thể liên hệ các trận đấu với các giải đấu liên quan của họ. Các bảng trong phần Giải đấu là:
-
tournament
- Phần này chứa tất cả dữ liệu cơ bản về giải đấu:môn thể thao, ngày bắt đầu, ngày kết thúc, v.v. Chúng tôi cũng cần lưu trữ tên giải đấu và mô tả về nơi diễn ra.sport_event_id
thuộc tính này là tùy chọn vì giải đấu không nhất thiết phải liên kết với một sự kiện lớn hơn (chẳng hạn như Thế vận hội). -
team
- Danh sách này liệt kê tất cả các nhóm trong giải đấu đó. UEFA Euro 2016 có sáu bảng, A đến F. -
participant
- Đây là những đội chơi trong giải đấu; mỗi người tham gia có thể được chỉ định vào một nhóm. Hầu hết các giải đấu bắt đầu bằng vòng bảng và sau đó tiếp tục đến vòng loại trực tiếp (ví dụ:UEFA Euro, UEFA World Cup, Olympic bóng đá). Một số giải đấu sẽ chỉ có vòng bảng (ví dụ:giải quốc gia), trong khi những giải đấu khác sẽ chỉ có vòng loại trực tiếp (ví dụ:cúp quốc gia). -
in_team
- Bảng này cung cấp mối quan hệ nhiều-nhiều lưu trữ thông tin về những người chơi đã đăng ký cho giải đấu đó và vị trí dự kiến của họ. -
tournament_schedule
- Theo tôi, đây là bảng thú vị nhất trong phần này. Danh sách tất cả các trò chơi đã chơi trong giải đấu này được lưu trữ tại đây.tournament_id
thuộc tính biểu thị mỗi trận đấu thuộc về giải đấu nào vàphase_id
thuộc tính xác định giai đoạn mà trận đấu sẽ diễn ra. Chúng tôi cũng sẽ lưu trữ vị trí trận đấu và thời gian trận đấu bắt đầu. Cả hai người tham gia sẽ được mô tả bằng các trường văn bản. Khi vòng bảng kết thúc, chúng ta sẽ biết tất cả các cặp đấu cho vòng loại trực tiếp. Ví dụ, vào đầu VCK Euro 2016, chúng ta đã biết đội thắng ở bảng E (1E) sẽ đấu với đội nhì bảng D (2D). Sau cả 3 lượt trận tại vòng bảng, cặp đấu này là Ý vs Tây Ban Nha.
Chi tiết trận đấu
Match details
khu vực được sử dụng để lưu trữ dữ liệu cho các trận đấu đơn lẻ. Chúng tôi sẽ sử dụng hai bảng:
-
match
- Điều này chứa tất cả các thông tin chi tiết về một trận đấu duy nhất; trận đấu này có thể liên quan đến một giải đấu, nhưng cũng có thể là một trận đấu đơn lẻ. Vì vậy,tournament_schedule_id
thuộc tính này là tùy chọn và chúng tôi sẽ lưu trữsport_id
,start_time
vàlocation
thuộc tính lại ở đây. Nếu trận đấu là một phần của giải đấu, thìtournament_schedule_id
sẽ được gán một giá trị.team_1_id
vàteam_2_id
thuộc tính là tham chiếu đến các đội tham gia vào trận đấu.goals_team_1
vàgoals_team_2
thuộc tính chứa kết quả của trận đấu. Chúng là bắt buộc và phải có "0" làm giá trị mặc định cho cả hai. -
in_match
- Bảng này là danh sách tất cả các cầu thủ đã đăng ký cho trận đấu đó; những người chơi không tham gia sẽ có NULL trongstarted_at
thuộc tính, trong khi những người chơi thay thế sẽ cóstarted_at
> 0 . Nếu một người chơi bị thay thế, họ sẽ cóended_at
thuộc tính phù hợp vớistarted_at
thuộc tính của người chơi đã thay thế họ. Nếu người chơi ở lại cả trận,ended_at
của họ thuộc tính sẽ có cùng giá trị vớiend_time
thuộc tính.
Sự kiện đối sánh
Phần này nhằm mục đích lưu trữ tất cả các chi tiết hoặc sự kiện đã xảy ra trong trò chơi. Và các bảng là:
-
event
- Đây là một từ điển liệt kê tất cả các sự kiện mà chúng ta muốn lưu trữ. Trong bóng đá, đó là những giá trị như “phạm lỗi” , "bị hôi" , “thẻ vàng” , “thẻ đỏ” , “đá phạt” , “hình phạt” , “mục tiêu” , “việt vị” , “thay thế” , “người chơi bị đuổi khỏi trận đấu” . -
match_event
- Điều này liên quan đến các sự kiện với trận đấu. Chúng tôi sẽ lưu trữevent_time
cũng như thông tin người chơi liên quan đến sự kiện đó (in_match_id
). -
related_event
- Đây là những gì mang thông tin sự kiện lại với nhau. Để giải thích, hãy xem ví dụ khi Cầu thủ A phạm lỗi với Cầu thủ B. Chúng tôi sẽ chèn một bản ghi vàomatch_event
bảng chỉ ra rằng Cầu thủ A phạm lỗi và một bảng khác cho biết Cầu thủ B bị phạm lỗi. Chúng tôi cũng sẽ thêm một bản ghi vàorelated_event
bảng, trong đó ‘phạm lỗi đã phạm’ sẽ là cha mẹ và ‘bị phạm lỗi’ sẽ là con. Chúng tôi cũng sẽ ghi lại kết quả của một pha phạm lỗi:thẻ vàng, một quả phạt trực tiếp hoặc một quả phạt đền và có thể là một bàn thắng.
Các chỉ số và Hiệu suất
Phần này sẽ giúp chúng tôi phân tích người chơi và đội trước và sau trận đấu.
indicator
table là một từ điển với bộ chỉ số được xác định trước cho từng cầu thủ trước mỗi trận đấu. Các chỉ số này phải mô tả phong độ hiện tại của người chơi. Danh sách này có thể chứa các giá trị như: “số bàn thắng trong 10 trận đấu gần đây nhất” , “khoảng cách trung bình được thực hiện trong 10 trận đấu gần đây nhất” , “số lần cứu thua cho GK trong 10 trận gần nhất” .
performance
từ điển rất giống với indicator
, nhưng chúng tôi sẽ sử dụng nó để chỉ lưu trữ các giá trị có liên quan đến kết hợp duy nhất: “khoảng cách được bảo hiểm” , “đường chuyền chính xác” , v.v.
player_indicator
và performance_indicator
các bảng có cấu trúc gần như giống hệt nhau:
-
in_match_id
- đề cập đến việc người chơi tham gia vào một trận đấu nhất định -
indicator_id
/performance_id
- tham chiếu đếnindicator
hoặc ”từ điển hiệu suất -
value
- lưu trữ giá trị cho chỉ số đó (ví dụ:một người chơi đi được quãng đường 10,72 km) -
description
- có mô tả bổ sung, nếu cần
Điều gì đã xảy ra trong trận đấu?
Với tất cả dữ liệu này được nhập vào, chúng tôi có thể dễ dàng nhận thông tin chi tiết, sự kiện và thống kê về trận đấu cho mọi trận đấu trong cơ sở dữ liệu của chúng tôi.
Truy vấn đơn giản này sẽ trả về các chi tiết cơ bản cho một trận đấu sắp tới:
SELECT team_1.`team_name`, team_2.`team_name`, `match`.`start_time`, `match`.`location` FROM `match`, `team` AS team_1, `team` AS team_2 WHERE `match`.`team_1_id` = team_1.`id` AND `match`.`team_2_id` = team_2.`id`
Để có danh sách tất cả các sự kiện đang diễn ra trong một trận đấu nhất định, chúng tôi sẽ sử dụng truy vấn bên dưới:
SELECT `event`.`event_name`, `match_event`.`event_time`, `player`.`first_name`, `player`.`last_name` FROM `match`, `match_event`, `event`, `in_match`, `player` WHERE `match_event`.`match_id` = `match`.`id` AND `event`.`id` = `match_event`.`event_id` AND `in_match`.`id` = `match_event`.`in_match_id` AND `player`.`id` = `in_match`.`player_id` AND `match`.`id` = @match ORDER BY `match_event`.`event_time` ASC
Có rất nhiều truy vấn bổ sung mà tôi có thể nghĩ ra; thật dễ dàng để thực hiện phân tích khi bạn có dữ liệu. Nếu bạn đã đo lường và lưu trữ một số lượng lớn các chỉ số và dữ liệu hiệu suất của người chơi, bạn có thể liên hệ các thông số này với kết quả cuối cùng. Cá nhân tôi không tin vào những dự đoán như vậy; có yếu tố may mắn trong các trận đấu, cộng với nhiều yếu tố khác mà bạn không thể biết cho đến khi trận đấu bắt đầu. Tuy nhiên, nếu bạn có một tập dữ liệu lớn và nhiều tham số, cơ hội đưa ra các dự đoán chính xác hơn của bạn sẽ tăng lên.
Mô hình được trình bày trong bài viết này cho phép chúng tôi lưu trữ các trận đấu, thông tin chi tiết về trận đấu và lịch sử hiệu suất của từng người chơi. Chúng tôi cũng có thể thiết lập các chỉ số hình thức cho từng cầu thủ trước trận đấu. Lưu trữ đủ thông tin chi tiết sẽ cung cấp cho chúng tôi nhiều thông số hơn để làm cơ sở cho các giả định của chúng tôi. Tôi không nói rằng chúng tôi có thể dự đoán kết quả của trò chơi, nhưng chúng tôi có thể vui vẻ với nó.
Chúng tôi cũng có thể dễ dàng điều chỉnh mô hình này để lưu trữ dữ liệu cho các môn thể thao khác. Những thay đổi này không nên quá phức tạp. Thêm sport_id
thuộc tính cho các từ điển nên thực hiện thủ thuật. Tuy nhiên, tôi nghĩ sẽ là khôn ngoan nếu có một ví dụ mới cho mỗi môn thể thao khác nhau.