1

Тема: Питання про кількість таблиць для сайта-гри (PHP+MySQL)

Вітаю!

Розробляю сайт для гри в текстові квести специфічного внутрішнього формату. На стороні сервера використовую PHP і MySQL.

Коли користувач вибирає "квест" і починає нову гру, для цієї ігрової сесії генерується "оточення". Розмір оточення досить великий - близько 5000-10000 елементів. Кожен елемент має набір параметрів/властивостей/станів. Різних параметрів є кілька десятків, хоча для кожного окремого елемента актуальні лише 5-10 з них. "Вага" одного елемента (сума "розмірів" полів) очікується на рівні 100-500 байт.
Структура оточення ієрархічна. Умовний центральний вузел розпадається на кілька великих гілок ("локацій"), всередині яких іде подальше дріблення.
Всі параметри можуть змінюватися, тобто "постійні" параметри звідси вже виділені в окрему "таблицю шаблонів/класів".

На кожному етапі користувачеві відправляється інформація про одну з "локацій" (500-1000 елементів з усіма властивостями і структурою). Користувач вибирає деяку дію і посилає її на сервер. Сервер обробляє дію, оновлює стан деяких елементів (як правило, 10-15 штук, можлива зміна ієрархії). Після цього користувач знову отримує нову порцію інформації.

Сама ігрова сесія не лімітована в часі і може тривати протягом багатьох днів (а то і місяців). Якщо користувач починає нову партію, старе "оточення" видаляється.

Зберігати поточне "оточення" планую в базі даних. Відповідно, у мене виникає питання про структуру бази. Поки бачу два принципових варіанти:
1. Для кожного користувача створювати окрему таблицю, в якій зберігати елементи поточної ігрової сесії.
2. Тримати одну велику таблицю для всіх користувачів, прикладаючи до елементів id користувача або ігрової сесії.

Варіант зберігати всю структуру в одному полі (XML?) відкинув через великі витрати на парсинг. Хіба що для сейвів можна подумати ...

Пошукав в мережі подібні проблеми - майже всюди радять реалізовувати другий варіант. Але тут ніби як специфіка штовхає до першого. По-перше, відразу багато записів на кожну ігрову сесію. По-друге, ігрова сесія окремого гравця взагалі ніяк не пов'язана з іншими. По-третє, обробка оточення на кожному етапі йде досить інтенсивна, робиться вибірка з близько 10% елементів.

Прошу допомогти порадою. До якого варіанту краще схилятися?
І взагалі, наскільки життєздатний план описанної частини з урахуванням оцінок?
Може, підкажіть якісь підводні камні, яких я поки не бачу.

Дякую!

2 Востаннє редагувалося Vo_Vik (15.02.2018 04:51:45)

Re: Питання про кількість таблиць для сайта-гри (PHP+MySQL)

Локація буде незмінна? Тобто не буде зсувів на кілька елементів? Тоді пишіть весь масив даних в json і зберігаєте в одному полі. Парсити там нічого не треба, зразу берете клієнтом і обробляєте. Хіба би ви мали часто змінювати дані в тій локації, тоді треба якось ділити, щоб кожен раз не перезаписувати всю локацію, тоді якось треба її розбити на статичні і динамічні складові і зберігати їх окремо.

3 Востаннє редагувалося deforder (15.02.2018 05:43:31)

Re: Питання про кількість таблиць для сайта-гри (PHP+MySQL)

Та в тому то й справа, що все там може мінятися. Локація - це лише один елемент. Кожен об'єкт, предмент чи інша сутність теж утворюють свій елемент. Предмент можна перенести на іншу локацію. Сутність можна знищити або створити нову. Тобто ієрархія та розподіл дочірніх елементів мід локаціями динамічний. Взаємодія с об'єктом може впливати на елементи з інших локацій. Тому обробка дії не замкнена на поточнії локації.
Є певна частина сутностей, що принципово не може переміщуватись чи знищуватись, але вона погоду не робить. А всі незмінювалі поля та властивості вже і так винесені окремо.

Клієнту-то можна передати локацію в json і парсити там. Але обробка дії все одно має відбуватися на сервері (вся "кухня" і різні приховані дані від клієнта мають бути сховані). Тому локацію (може й не одну) доведеться парсити і на сервері під час обробки дії та застосуванні результатів.

4

Re: Питання про кількість таблиць для сайта-гри (PHP+MySQL)

Таблиця для окремого користувача - це неправильно. Єдина таблиця з індексованим полем "номер користувача" працює із такою самою швидкістю, а вносити будь-які зміни до десяти таблиць буде дуже... незручно, м'яко кажучи.
Загалом, я так розумію, проблему можна переформулювати: є величезна БД, кожному користувачу потрібні дані з великої її частини, і ці частини потроху змінюються. Ви хочете кешувати ті частини, які "належать" окремим користувачам, щоб вони швидко їх отримували, і маєте проблеми з алгоритмом оновленням кешу - що саме додавати, що видаляти. Правильно?

5 Востаннє редагувалося 221VOLT (15.02.2018 14:44:19)

Re: Питання про кількість таблиць для сайта-гри (PHP+MySQL)

серйозно, роздумуєте про XML в 2018 ? лол

ви можете користуватись не вертикальними а горизонтальними таблицями

тобто структура (спрощено) --
айді - ключ - значення

id_row | id_user | key | value

6 Востаннє редагувалося deforder (16.02.2018 01:03:18)

Re: Питання про кількість таблиць для сайта-гри (PHP+MySQL)

To koala.
Значить, одна велика таблиця все ж краще. Добре)
Про переформулювання і кешування трохи Вас не зрозумів.
У меня прогнозується під мегабайт ієрархічних данних (на кілька тисяч сутностей) для кожного користувача. На кожнії ітерацїї буде потрібен доступ до властивотей десятої частини з них.
Хочу зрозути, чи коректно це взагалі реалізовувати таким чином (тобто яку реальну кількість користувачів може витримати така схема). І як потрібно правильніше збегігати дані в рамках критерію кількість/розмір таблиць.

To 221VOLT
Ну про XML це я для прикладу написав. Згоден, що варто використовувти більш економний формат.
Але питання для мене залишається відкритим. Чи розумно записати, скажімо, 500-1000 елементів в одне текстове поле і парсити його на кожній ітерації цього користувача. Чи тримати ці елементи в окремих рядках? Рядки vs парсинг...

7

Re: Питання про кількість таблиць для сайта-гри (PHP+MySQL)

deforder написав:

І як потрібно правильніше зберігати дані в рамках критерію кількість/розмір таблиць.

Майже ніяк, якщо ресурсів достатньо. Складність пошуку по індексу-дереву - O(log(n)), по хеш-таблиці - O(1). Від зростання таблиці удвічі логарифмічна швидкість падає на одиничку. Від необхідності звернутися до іншої таблиці при недостатньому кеші СУБД - значно сильніше.
Зрештою, можете собі уявити це так: БД придумали саме для того, що оптимізувати парсинг файлів у загальному випадку. Парсинг файлу, розроблений некваліфікованим програмістом, працюватиме гірше за стандартні запити до СУБД. Зрештою, всі ці дані все одно лежать одним рядком (чи декількома) десь у файлі, доступ до якого контролює СУБД.

А якщо вже хочете зекономити на копійках, то формуйте BLOB-и із двійковими даними, що відповідають структурам програми, і робіть memcpy.

Подякували: leofun011

8

Re: Питання про кількість таблиць для сайта-гри (PHP+MySQL)

якщо роботи з даними відносно багато --

можна ще не смикати постійно базу,
а в основному працювати з даними в оперативці,
в базу скидати періодично (в залежності від важливості даних)