Отличный вопрос. Интеграция данных из разных разрозненных источников — это всегда вызов. Именно для решения этой проблемы я заложил в архитектуру абстракцию через внутренний UUID.
Давай посмотрим на предложенную таблицу players еще раз. Ключевой момент в том, что наша база данных не полагается на чужие ID как на фундамент.
У каждого игрока есть внутренний id (UUID), который генерирует наша база. И все таблицы (games, turns) ссылаются только на этот наш внутренний UUID.
А вот для связи с внешним миром у нас есть колонка external_id типа VARCHAR (строка). И вот как мы элегантно уложим в нее все твои сценарии:
Сценарий 1: Импорт с сайта Dice Chess (ID 163)
Когда скрипт парсит JSON с сайта Dice Chess, он видит игрока 163. Он ищет в нашей таблице players запись, где external_id = 'dicechess:163'.
Если её нет, он создает нового игрока:
id=[автоматический UUID]external_id='dicechess:163'username='rabestro'(или как ты там записан)player_type='human'
Сценарий 2: Партии роботов в терминале
Роботы тоже являются “игроками” в нашей системе. Когда ты заливаешь партию между двумя ботами, мы создаем их профили:
external_id='bot:expectimax_v1'username='Expectimax Depth 3'player_type='engine'
В таблице games эта партия будет иметь source = 'terminal_analysis', а белыми и черными будут UUID этих двух ботов.
Сценарий 3: Анонимный посетитель на твоем веб-сайте играет с роботом
Тут у нас есть два варианта (оба поддерживаются схемой):
- NULL-игрок. В таблице
gamesколонкиwhite_player_idиblack_player_idмогут быть пустыми (NULL). Мы просто записываем партию:source = 'web_guest', белый игрок —NULL, черный игрок — UUID робота. - Общий профиль Анонима. Мы можем создать в базе одного “вечного” игрока с
external_id = 'system:anonymous'иusername = 'Guest'. Все анонимные игры будут привязываться к этому профилю. Это удобно, если ты захочешь потом посмотреть общую статистику: “Как часто гости выигрывают у бота?”
Сценарий 4: Зарегистрированный пользователь твоего сайта
Если в будущем у тебя на сайте появится авторизация (например, через Google, как сейчас в Dice Chess Trainer), у этого юзера появится свой профиль:
external_id='google:10493...'username='JohnDoe'player_type='human'
Почему это удобно?
Строковый external_id с префиксами (dicechess:, bot:, google:, system:) позволяет нам хранить в одной таблице сущности любой природы и из любых систем, не боясь, что ID 163 с сайта Dice Chess случайно пересечется с ID 163 из твоей локальной системы авторизации.
В таблице games у нас также есть колонка source ('imported', 'terminal', 'web_live'), которая сразу дает понять, в каком контексте была сыграна партия.
Закрывает ли это твои потребности по работе с игроками из разных источников?