Проектирование базы данных - как реализовать таблицу групп пользователей? - PullRequest
5 голосов
/ 14 апреля 2011

Я хочу создать систему групп пользователей, которая имитирует групповую политику в мессенджерах.

Каждый пользователь может создать столько групп, сколько он хочет, но у него не может быть групп с повторяющимися именами, и он может добавить столько друзей, сколько он хочет, в любые группы.

Например, подруга Джона Джен может быть в «школьной» группе Джона и «коллеге» Джона одновременно. И это совершенно не зависит от того, как Джен помещает Джона в свою группу.

Я думаю о двух возможных способах реализации этого в таблице базы данных user_group.

1

user_group (
id INT PRIMARY KEY AUTO_INCREMENT,
user_id INT,
group_name VARCHAR(30),
UNIQUE KEY (user_id, group_name)
)

В этом случае все группы, принадлежащие всем пользователям, будут иметь уникальный идентификатор. Таким образом, один только идентификатор может определить, какой пользователь и название группы.

2

user_group (
user_id INT,
group_id INT AUTO_INCREMENT,
group_name VARCHAR(30),
PRIMARY KEY (user_id, group_id),
UNIQUE KEY (user_id, group_name)
)

В этом случае group_id всегда начинается с 0 для каждого пользователя, поэтому может существовать много групп с одинаковыми значениями group_id. Но пара pk (user_id, group_id) уникальна в таблице.

какой способ лучше реализации и почему? Каковы преимущества и недостатки для каждого случая?

EDIT: добавил AUTO_INCREMENT к group_id во втором сценарии, чтобы гарантировать, что он автоматически назначается от 0 для каждого user_id.

EDIT: «лучше» означает ... - лучшая производительность в SELECT / INSERT / UPDATE друзей в группе, поскольку это будут наиболее часто используемые операции в отношении группы пользователей. - надежность базы данных, например, какая будет более безопасной с точки зрения размера пользователя. - популярность или общее предпочтение одного над другим. - гибкость - расширяемость - удобство использования - проще в использовании.

Ответы [ 3 ]

3 голосов
/ 14 апреля 2011

Лично я бы пошел с 1-м подходом, но это действительно зависит от того, как ваше приложение будет работать.Если когда-либо будет возможно изменить принадлежность группы или объединить профили пользователей, это будет гораздо проще сделать при первом подходе, чем во втором.При втором подходе, если когда-либо случится какая-либо из этих ситуаций, вам придется обновить не только вашу таблицу user_group, но и любые зависимые таблицы, которые имеют отношение внешнего ключа к user_group.Это также будет отношение «многие ко многим» (в группе будет несколько пользователей, а пользователь будет членом нескольких групп), поэтому для этого потребуется отдельная таблица присоединения.В 1-м подходе это довольно просто:

group_member (
  group_id int,
  user_id int
)

Для вашего 2-го подхода потребуется 3-й столбец, который не только будет более запутанным, так как теперь вы включаете user_id дважды, нотакже требует 33% дополнительного пространства для хранения (это может или не может быть проблемой в зависимости от того, насколько большой вы ожидаете, что ваша база данных будет):

group_member (
  owner_id int,
  group_id int,
  user_id int
)

Кроме того, если вы когда-либо планируете перейти с MySQL на другую базу данныхплатформа, это поведение auto_increment может не поддерживаться.Я знаю, что в MS SQL Server поле auto_increment (identity в MSSQL) всегда будет увеличиваться, а не делаться уникальным в соответствии с индексами в таблице, поэтому для получения той же функциональности вам придется реализовать его самостоятельно.

0 голосов
/ 14 апреля 2011

Я не вижу никакой возможной выгоды для номера 2, он более сложный, более хрупкий (он вообще не работает в SQL Server) и ничего не выигрывает. Помните, что groupId не имеет смысла, кроме как однозначно идентифицировать запись, вероятно, пользователь увидит только имя группы, а не идентификатор. Таким образом, не имеет значения, все ли они начинаются с 0 или имеются пропуски, потому что группа была отозвана или удалена.

0 голосов
/ 14 апреля 2011

Пожалуйста, укажите "лучше".

Из моей кишки я бы выбрал 2-й.

Доступные для поиска фрагменты разбиты больше, но я бы этого не выбрал, если бы производительность вставки / обновления была проблемой.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...