Как правильно организовать и связать таблицы?
Есть таблица "User" где хранятся все пользователи. Каждый пользователь может отправлять запрос в друзья другому пользователю (статус может быть "принял дружбу" или "заявка не рассмотрена") - поле "status" в таблице "Friendship". Нужно привязывать пользователя к пользователю как друга.
Вот нужно как-то хранить данные о друзьях у каждого пользователя.
Вопрос в том как правильно организовать и связать таблицы. (приложу свои варианты)
Ответы (1 шт):
Очевидно. у вас должно быть отношение многие-ко-многим, но реализованное не между двумя таблицами, а таблица сама с собой.
На первых рисунках наличие поля users.friends_id, ссылающееся на ПК таблицы связи, это нечто странное, в эту парадигму никак не подходящее.
Что делать ключом таблицы связи - вопрос для размышления, пожалуй, самый подходящий кандидат - сама пара user_id, friend_id. Это позволит задавать кластеризацию (а также партцирование при необходимости) данных и исключит лукапы по индексу для извлечения данных. Так что дополнительный инкрементный id тут скорее избыточен.
Потенциально status тут тоже можно включить в первичный ключ, что позволит, например, при партицировании таблицы отдельно хранить друзей и отдельно "заявки/приглашения" в друзья.
Отдельного внимания заслуживает тип данных столбца status, который, конечно, должен иметь явно целочисленную основу минимальной достаточной размерности. Пока что тут проглядывается потребность в 1 байте, в виде BYTE или ENUM поля в зависимости от СУБД.
Также стоит отметить, что для удобной работы при принятии заявки вторым пользователем понадобится добавлять симметричную строку в таблицу, уже с выставленным статусом. Ну и при удалении подумать каике действия необходимы.
Вопрос быстрого поиска входящих заявок тоже можно рассмотреть. Поиск по friend_id с ПК user_id, friend_id, будет не очень быстр поэтому тут нужен либо вспомогательный индекс на friend_id, либо эту симметричную запись вставлять сразу (а не при принятии), но в этом случае надо в статусе как-то разграничивать, что это входящая заявка, а не исходящая.
В общем вещь, казалось бы, тривиальная но пища для размышления имеется. Особенно когда юзеров зайдет миллионы. Но если у вас планируемый объем десятки-сотни, можете в целом не принимать в расчет все что тут написано.
