Следующая структура таблицы делает следующие предположения:
- Подгруппы уникальны и различны для каждой группы и отличаются от фактических групп (отношение один ко многим, а группы не могут использоваться в качестве подгрупп).
Для участия в группе пользователи должны быть членами хотя бы одной подгруппы
GroupTable
GroupID (PK)
GroupName
SubGroupTable
SubGroupID (PK)
GroupID (FK на GroupTable.GroupID)
SubGroupName
UserTable
ИД пользователя (ПК)
UserName
Теперь создайте таблицу отношений «многие ко многим», определяющую участие пользователя в одной или нескольких подгруппах:
User_Sub_Groups
UserID (FK on UserTable.UserID)
SubGroupID (FK on SubGroupTable.SubGroupID)
Если группы также могут быть подгруппами, то пример, предоставленный nulvinge, является одним из вариантов, хотя я бы сделал это немного иначе:
GroupTable
GroupID (PK)
GroupName
UserTable
UserID (PK)
UserName
SubGroupTable
ParentGroupID (Composite Key on GroupsTable.GroupID)
SubGroupID (Composite Key on GroupsTable.GroupID)
UserGroupsTable
UserID (Composite Key on UserTable.UserID)
GroupID (Composite Key on GroupsTable.GroupID)
Отсюда вы просто используете JOIN между различными таблицами для выполнения поиска. Например, чтобы вернуть всех пользователей, принадлежащих к определенной группе:
SELECT
tblUser_Group.GroupID, tblUser.*
FROM
tblUser_Group
INNER JOIN
tblUser ON tblUser_Group.UserID = tblUser.UserID
WHERE
tblUserGroup.GroupID = @GroupID
Чтобы вернуть все подгруппы, членом которых является конкретный пользователь:
SELECT
tblGroup.GroupName AS SubGroupName
FROM
tblUser_Group AS UG
INNER JOIN
tblUser ON UG.UserID = tblUser.UserID INNER JOIN
tblGroup_SubGroup AS GSG ON UG.GroupID = GSG.SubGroupID INNER JOIN
tblGroup ON GSG.SubGroupID = tblGroup.GroupID
WHERE
tblUser.UserID = 1
И так далее. Поначалу может быть сложно продумать различные перестановки JOIN, но это очень гибкая и масштабируемая схема.
Надеюсь, это поможет!