Q: Database users and groups model I have 2 entities: users and groups. Easiest model is user(id,name,etc...), group(id,name), user_group_rel(user_id,group_id). But I need to include groups into other groups. One user can be in many groups and groups can include users and subgroups with own users and subgroups!
Need help with database model!


A: While I agree with Ken Down's nomenclature, I don't necessarily agree that users and roles are the same entity.  
Base Entities:
Users     (user_id, user name, real name, user_status, etc)
Role      (role_id, role name, role_password, etc)
Privilege (priv_id, base object, functionality, what have you)

Associative entities:
User has Role (0 - n) (user_id, role_id)
Role has Role (0 - n) (role_id, has_role_id)
User has Privilege (0 - n) (user_id, priv_id)
Role has Privilege (0 - n) (role_id, priv_id)


A: These days this is done by collapsing both users and groups into "Roles".  All you have are roles, and a linking of roles into other roles.  Some roles have a "login" flag set to true which makes them in effect users, while roles that do not have the "login" flag set are more like groups.
The main idea is this makes everything simpler.  You don't have to maintain two separate concepts or entities (user and group), but only one concept: role.  Then you use that "login" flag for users.
EDIT: For table structure look at the first option provided by @XIVSolutions, he spells out what I referred to above.  It answers your question about putting one role into any number of other roles.  The second table, the cross-reference, lists a role and its parent.  If a role has multiple parents, meaning multiple entries in that table, then this is like having one user in many groups.  
#DIT: Also re:@XIVSolutions table design, that third table is a perfectly legitimate way to have users (logins) as separately managed entities.

A: re: Ken Downs solution:
I've played with two versions of this (and would LOVE to hear if this is on-target or not . . .):
Option 1:
**tblRole**
RoleID PK
RoleName

**tblRoleIndex**
ParentRoleID FK on tblRole  
ChildRoleID FK ON tblRole

NOTE: ParentRoleID and ChildRoleID form a composite Primary key in the above table.

**tblLogIns**
LogInID PK
RoleID
PassWord

Or, option 2:
**tblRole**
RoleID
ParentRoleID Recursive FK on tblRole.RoleID
RoleName

NOTE: A top-level role in the table above has a default ParentRoleID of -1 or 0

**tblLogIns**
LogInID PK
RoleID
PassWord


A: The main sticking point for modelling this is how to treat both users and groups as members of groups. Ken Downs's approach will solve this problem. Another approach is to treat users and and groups as a derived type of a common base type:
create table groupmemberbase
(
  memberid int,
--optional flag to idicate the type of the derived entity
--this is similar to the login flag used by Ken Downs 
  membertype int,
  primary key (memberid)
)

create table users
{
  memberid int,
--more user attributes here
  primary key (memberid),
  foreign key (memberid) references groupmemberbase (memberid)
)

create table groups
(
  memberid int,
--more group attributes here
  primary key (memberid),
  foreign key (memberid) references groupmemberbase (memberid)
)

create table groupmembers
(
  groupid int,
  memberid int,
  primary key (groupid, memberid),
  foreign key (groupid) references groups (memberid)
  foreign key (memberid) references groupmemberbase (memberid)
)

One advantage of this approach is that it prevents a user or group from accidentally becoming a member of a user - this restriction is enforced at the schema level.

A: What Paul Keister's scheme looks like. This is an auto generated diagram from JetBrains DataGrip IDE.

