• Из-за обновления GTA 5 (был добавлен новый патч) может временно не работать вход в RAGE Multiplayer.

    ERROR: Your game version is not supported by RAGE Multiplayer.

    Данная ошибка говорит о том, что GTA V обновилась до новой версии (GTA Online тоже). Вам необходимо обновить саму игру в главном меню вашего приложения (Steam / Epic Games / Rockstar Games).
    Если после этого RAGE:MP все равно не работает - вам нужно дождаться выхода патча для самого мультиплеера (обычно это занимает от нескольких часов до нескольких дней).

    Новости и апдейты Rockstar Games - https://www.rockstargames.com/ru/newswire/
    Статус всех служб для Rockstar Games Launcher и поддерживаемых игр: https://support.rockstargames.com/ru/servicestatus


    Grand Theft Auto 5 (+ GTA Online) последний раз были обновлены:

Вопрос Оптимальное хранение данных в базе

Vermilion

Специалист
Автор темы
29 Сен 2021
317
164
80
33
Приветствую.
Во время разработки назрел вопрос оптимального хранения данных в базе. Для наиболее высокой продуктивности и уменьшения нагрузки.
У меня есть несколько вариантов, но я не могу решить какой будет лучше. Задача - хранение предметов игры (Вещи, оружие, предметы).
Использую Sequelize для работы с данными как с обычными объектами
1. Вариант (Использую на данный момент):
База данных разбита не несколько таблиц
  • Аккаунты
  • Оружие
  • Одежда
  • Предметы


То есть у каждого предмета есть свой владелец, который обозначен через belongsTo.
Из плюсов которые я вижу:
  • Возможность редактирования всех предметов выбранного типа для балансирования виртуального мира
  • Возможность хранения координат предметов, которые можно использовать после рестарта сервера (Они остаются на тех местах, где их выкинули до рестарта)

Минусы которые я вижу:
- При запросах большая нагрузка на БД в связи с тем, что в таблицах может быть тысячи предметов

2. Вариант:
Предметы хранятся непосредственно в аккаунте пользователя в виде JSON
Плюсы которые я вижу:
- При запросах к БД, уменьшается нагрузка на таблицы предметов, которых может быть тысячи

Минусы которые я вижу:
- Большой вес аккаунта

Повторюсь, прямых запросов Пользователь -> БД не делаю, при создании предмета создается "инстанция предмета" с которым взаимодействует игрок.

Если у кого то есть опыт в этом, хотелось бы послушать.
 

Jerry (ChatGPT)

AI-powered language model
VIP
helper
17 Окт 2023
954
1,178
5
Привет! Оба варианта имеют свои плюсы и минусы, и выбор зависит от конкретных требований вашего проекта. Вариант с разделенными таблицами представляется более гибким, т.к. позволяет балансировать предметы и хранить координаты предметов после рестарта сервера. Однако, он может иметь большую нагрузку на БД при запросах. Напротив, вариант с хранением предметов в виде JSON в аккаунте пользователя может снизить нагрузку на таблицы предметов, но может привести к увеличению веса аккаунта. Учитывая, что вы создаете "инстанцию предмета" для каждого пользователя, кажется, что первый вариант может быть более подходящим. Однако, для точного решения лучше обратиться к особенностям вашего проекта и его производительности.
 

enotit

Гуру
13 Ноя 2020
552
239
107
Предметы хранятся непосредственно в аккаунте пользователя в виде JSON
Сразу нет, нарушение первой нормальной формы

Всё зависит от твоих потребностей, если у тебя всё хранится всё в БД и ты обращаешься к ней каждый тик, то это одна история, если при инициализации сервера берешь все данные и хранишь в оперативе - другое.
Вообще, бояться обращаться к БД - не стоит, она для этого и создана. Однако, лучше посмотреть на оптимизацию (нет ли запросов в цикле, не делаешь ли при каждом чихе SELECT *... и т.п.).
Лучшее решение - разбивать на логические таблицы, тогда в последствии будет проще масштабировать (пример редага 1.1 -> редага 3 с её разросшимся main.characters).
Авось когда нибудь выделишь свою бд на отдельный сервер и тебе будет проще не хранить всё в озу, а обращаться каждый тик в бд.

Не жс-ер, но так понимаю у тебя sql в ядре. Тоже дай больше вводных по архитектуре и требований сервера.

ps Соре за бессвязность предложений, немного температура колышит
 
  • Like
Реакции: Vermilion

Vermilion

Специалист
Автор темы
29 Сен 2021
317
164
80
33
Сразу нет, нарушение первой нормальной формы

Всё зависит от твоих потребностей, если у тебя всё хранится всё в БД и ты обращаешься к ней каждый тик, то это одна история, если при инициализации сервера берешь все данные и хранишь в оперативе - другое.
Вообще, бояться обращаться к БД - не стоит, она для этого и создана. Однако, лучше посмотреть на оптимизацию (нет ли запросов в цикле, не делаешь ли при каждом чихе SELECT *... и т.п.).
Лучшее решение - разбивать на логические таблицы, тогда в последствии будет проще масштабировать (пример редага 1.1 -> редага 3 с её разросшимся main.characters).
Авось когда нибудь выделишь свою бд на отдельный сервер и тебе будет проще не хранить всё в озу, а обращаться каждый тик в бд.

Не жс-ер, но так понимаю у тебя sql в ядре. Тоже дай больше вводных по архитектуре и требований сервера.

ps Соре за бессвязность предложений, немного температура колышит
Селекты не делаю. При инициализации сервера храню все в оперативе. Но данные могут добавляться и удаляться и базы в зависимости от действий пользователя.
Требования: Предметов будет очень много, так как решили двигаться в направлении Survive. То есть лута будет более чем достаточно, соответственно транзакций в секунду будет тоже много. Использую MariaDB, sequelize-typescript.

Пример запроса к базе данных для обновления предмета:
Код:
try {
    const item = await Weapons.findOne({ where: { itemId: inventoryId } });
    if (item) {
        await (item as any).update({ characterId: player.accountInstance.id });      
    } else {
        console.log(`Item not found in the database.`);
    }
} catch (error) {
    console.error(`Error handling ${'inventory:grabInventoryItem'}:`, error);
}
 

enotit

Гуру
13 Ноя 2020
552
239
107
Пример запроса к базе данных для обновления предмета:
Слушай, а в твоём примере нельзя сократить до:
JavaScript:
// Change everyone without a last name to "Doe"
await User.update({ lastName: "Doe" }, {
  where: {
    lastName: null,
  },
});
не в два запроса, а в один (пример с док взял).
Но также, делать сразу сохранение - хз хз, спорно. На каптах когда игроки будут просто так туда-сюда оружие кидать - какая нагрузка будет. Советую всё-таки сделать синхронизацию, раз у тебя есть буфер в виде массива из орм.
 

Vermilion

Специалист
Автор темы
29 Сен 2021
317
164
80
33
Слушай, а в твоём примере нельзя сократить до:
JavaScript:
// Change everyone without a last name to "Doe"
await User.update({ lastName: "Doe" }, {
  where: {
    lastName: null,
  },
});
не в два запроса, а в один (пример с док взял).
Но также, делать сразу сохранение - хз хз, спорно. На каптах когда игроки будут просто так туда-сюда оружие кидать - какая нагрузка будет. Советую всё-таки сделать синхронизацию, раз у тебя есть буфер в виде массива из орм.
А если записи не существует? Или она не успела обновиться. Все же лучше сначала проверить её наличие в базе.
 

enotit

Гуру
13 Ноя 2020
552
239
107
А если записи не существует? Или она не успела обновиться. Все же лучше сначала проверить её наличие в базе.
Так where для чего, при отсутствии он тебе ошибку не даст. SQL по дефолту при update возвращает количество измененных строк. По сути ты можешь написать постфактумом, что элемента нет.
Мб ОРМ такая весёлая, но кажется что это сюр какой-то. минус один запрос, + в копилку.
 
  • Haha
Реакции: Vermilion

Sinage

Начинающий специалист
17 Дек 2021
72
19
53
Мне интересно, а почему когда люди пишут на NodeJS, они не используют какую-нибудь документно ориентированную базу или что-то вроде того, такую как MongoDB.
Я просто имел дело с MongoDB и как по мне, эта база очень хорошо подходит для использования в связке с JS, но к сожалению в C# она мне не понравилась из-за тяжелой реализации объектов и тд.
 

Inoi

/dev/null
VIP
15 Окт 2020
2,456
1,455
208
34
лута будет более чем достаточно, соответственно транзакций в секунду будет тоже много
звучит опасно
"транзакции в секунду" по крайней мере для лута - никто не делает если что, это безумие
обычно это всё фиксируется на сервере, который уже раз в какой-то временной период сохраняет свой стейт в базу данных
если ты будешь по каждому взаимодействию с каждым кусочком лута лезть обновлять бд - ты ёбнешься
ну в плане сервер ёбнется
 

Vermilion

Специалист
Автор темы
29 Сен 2021
317
164
80
33
звучит опасно
"транзакции в секунду" по крайней мере для лута - никто не делает если что, это безумие
обычно это всё фиксируется на сервере, который уже раз в какой-то временной период сохраняет свой стейт в базу данных
если ты будешь по каждому взаимодействию с каждым кусочком лута лезть обновлять бд - ты ёбнешься
ну в плане сервер ёбнется
Работать с объектами в оперативе и обращаться к ним а не к БД на прямую. Сохранять их при входе, выходе игрока, и раз в N количество времени. Так и планирую.
 

enotit

Гуру
13 Ноя 2020
552
239
107
Работать с объектами в оперативе, и сохранять их при входе, выходе игрока, и раз в N количество времени. Так и планирую.
Вход выход тоже не желательно, представь запуск сервера, 1000 игроков. И так создание игркоов не дёшево, а так ещё делаешь создание в бд.
 

Inoi

/dev/null
VIP
15 Окт 2020
2,456
1,455
208
34
Работать с объектами в оперативе и обращаться к ним а не к БД на прямую. Сохранять их при входе, выходе игрока, и раз в N количество времени. Так и планирую.
ну при входе сохранять нечего :roflanebalo:
но в целом всё верно :)

тогда на самом деле вся логика того, как и что ты хранишь в бд должна отталкиваться только от твоих дальнейших с этим информейшеном взаимодействий уже
глобально на самом деле скулю до пизды - ты можешь хоть текстовой строкой хуячить всё в одну ячейку (ладно читать не совсем прям уж до пизды)
серверу тоже - ты кинул апдейт в асинк таск и он дальше занимается своими вещами

другой вопрос как тебе потом с этим бредом взаимодействовать и (не дай бог) масштабировать
ето называется проектирование
 
Последнее редактирование:

Vermilion

Специалист
Автор темы
29 Сен 2021
317
164
80
33
Вход выход тоже не желательно, представь запуск сервера, 1000 игроков. И так создание игркоов не дёшево, а так ещё делаешь создание в бд.
Нет, ты не понял. Инстанция создаются при входе игрока основываясь на данных из БД.
Так же инстанции создаются при старте сервера на созданные объекты (ящики с лутом) основываясь на данных из БД.
А при выходе игрока - обновляется база данных основываясь на инстанции этого игрока. Вроде бы логично
 

uvanov

Начинающий специалист
6 Мар 2022
119
51
71
Мне интересно, а почему когда люди пишут на NodeJS, они не используют какую-нибудь документно ориентированную базу или что-то вроде того, такую как MongoDB.
Я просто имел дело с MongoDB и как по мне, эта база очень хорошо подходит для использования в связке с JS, но к сожалению в C# она мне не понравилась из-за тяжелой реализации объектов и тд.
Да в целом пользуются, многие. Но как-то так сложилось, что в сфере ГТА большинство использует именно реляционки.