#sql #scaling
#sql #масштабирование
Вопрос:
я приведу пример, чтобы проиллюстрировать свой вопрос.
у вас есть таблица группового чата, в которой хранятся данные о групповом чате.
-------------------
id | name |owner_id|
-------------------
33 | code | 45
у вас есть таблица сообщений, в которой хранятся сообщения
-------------------------------------
id | content | user_id | chat_room_id
-------------------------------------
5 | "hello" | 41 | 33
2 | "hi" | 43 | 33
у вас есть таблица users, в которой содержится информация о пользователях и о том, в каком групповом чате они участвуют:
-------------------------------------
id | name | chat_room_id
-------------------------------------
5 |"nick"| 33
2 |"mike"| 33
- это правильный способ настройки базы данных?
- без соединений или внешних ключей. какой наиболее эффективный способ загрузить все сообщения и пользовательские данные и представить их в форме, позволяющей создать пользовательский интерфейс, в котором пользовательские данные отображаются рядом с сообщением?
Мои решения:
если вы запросите базу данных сообщений и получите все сообщения, в которых идентификатор комнаты чата равен 33, вы получите массив, который выглядит так
[
{
id : 5,
user_id : 41,
content : "hello"
},
{
id : 2,
user_id : 43,
content : "hi"
}
]
как вы можете видеть, идентификаторы пользователей являются частью объекта message.
решение 1: (наивное): перебрать массив сообщений и запросить базу данных, используя идентификатор пользователя. это плохое решение, поскольку запрос к базе данных из цикла никогда не является хорошей идеей.
решение 2: (эффективное, но меньше данных для отправки в ответе): перебираем массив сообщений и создаем массив идентификаторов пользователей и используем его в запросе WHERE user_id IN
, затем перебираем массив пользователей и создаем хэш-таблицу, используя идентификатор пользователя в качестве ключа, поскольку он уникален. во внешнем интерфейсе просто просмотрите массив сообщений и найдите пользователя.
это решение будет очень медленным, если у вас большое количество сообщений. будет ли он хорошо масштабироваться, поскольку он равен O (n).
решение 3: (эффективное, но больше данных для отправки в ответе): то же самое, что и раньше, но разница здесь заключается в добавлении свойств к объекту messages, в котором хранятся пользовательские данные. проблема с этим решением заключается в том, что у вас будут дублирующиеся данные, поскольку один пользователь может публиковать несколько сообщений.
это мои решения, которые я надеюсь услышать от вас.
для контекста: видеоролики о разработке системы на YouTube не затрагивают эту часть приложений для чата. если вы нашли тот, который делает, пожалуйста, разместите ссылку.
Комментарии:
1. Клиент чата, скорее всего, уже знает общую информацию о пользователях в комнате. Предполагая, что вы не можете получать сообщения от пользователей, не участвующих в групповом обсуждении, клиент может просто сопоставить имя из списка участников? Честно говоря, вы не должны заботиться о преждевременной оптимизации этого. Сначала выберите то, что легко поддерживать, и оптимизируйте оттуда.
2. да, я понимаю, что вы говорите.
3. Что значит «без использования
join
«? Зачем хранить данные в базе данных, если вы не собираетесь использовать функциональность базы данных?4. ну, сначала я подразумеваю под «суставами» наличие отношения «один ко многим» (один пользователь: много сообщений). в архитектуре микросервисов база данных пользователей и база данных сообщений принадлежат разным службам, поэтому невозможно иметь внешний ключ, который указывает на другую таблицу. обе таблицы должны запрашиваться независимо.