Sign Up

Sign Up to our social questions and Answers Engine to ask questions, answer people’s questions, and connect with other people.

Have an account? Sign In

Have an account? Sign In Now

Sign In

Login to our social questions & Answers Engine to ask questions answer people’s questions & connect with other people.

Sign Up Here

Forgot Password?

Don't have account, Sign Up Here

Forgot Password

Lost your password? Please enter your email address. You will receive a link and will create a new password via email.

Have an account? Sign In Now

You must login to ask a question.

Forgot Password?

Need An Account, Sign Up Here

Please briefly explain why you feel this question should be reported.

Please briefly explain why you feel this answer should be reported.

Please briefly explain why you feel this user should be reported.

Sign InSign Up

The Archive Base

The Archive Base Logo The Archive Base Logo

The Archive Base Navigation

  • Home
  • SEARCH
  • About Us
  • Blog
  • Contact Us
Search
Ask A Question

Mobile menu

Close
Ask a Question
  • Home
  • Add group
  • Groups page
  • Feed
  • User Profile
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Buy Points
  • Users
  • Help
  • Buy Theme
  • SEARCH
Home/ Questions/Q 6234873
In Process

The Archive Base Latest Questions

Editorial Team
  • 0
Editorial Team
Asked: May 24, 20262026-05-24T10:34:11+00:00 2026-05-24T10:34:11+00:00

I am developing a system which needs to allow users to be placed into

  • 0

I am developing a system which needs to allow users to be placed into groups. These groups can be freely created, edited, and deleted by other privileged users in the system. That part is easy; just create a group_users table that links users into groups. (If you’re a stickler for normalization then you may create a group table that just lists off groups and then have a group_users table that links them together — that’s fine too)

Here’s where it gets tricky. The client wants groups to also contain groups, to arbitrary depth and with arbitrary overlap (groups can be in multiple groups, and groups can contain multiple groups). That’s easy enough to store (with a group_groups table), but it’s difficult to query against without some sort extension like Oracle’s CONNECT BY.

This recursive hierarchy also needs to be retroactive — meaning that if group A contains group B, and group B is modified, then group A will be modified too — so I can’t cheat and just flatten out the structure. If you don’t believe me that it can’t simply be flattened, consider this situation. You have a group called “cool people” which contains users 1 and 2. Someone creates a group called “REALLY cool people” which contains user 3 and contains the group “cool people”. When I query against “REALLY cool people” I should conclude that users 1, 2, and 3 are in the group. Now say that someone decides that user 2 isn’t a cool person anymore and removes user 2 from “cool people”. After that point in time, “REALLY cool people” only contains users 1 and 3. If I had originally flattened out the structure, I wouldn’t know to remove user 2 from “REALLY cool people” when I removed him from “cool people”.

So a trivial flattening won’t work in this scenario. Other options I’ve considered:

  • Doing the recursion in code.
    • Too slow for complex groups, and also requires you to then do related joins in memory rather than on the database
  • Flatten the structure out into group_users_flattened, but also maintain a group_groups table. Create a trigger for group_users_flattened on INSERT/UPDATE/DELETE that will go to the group_groups table, find all groups that contain this group, and dynamically make the appropriate changes to group_users_flattened.
    • I can imagine this working, but it seems convoluted and error-prone, and I have a feeling there’s a gotcha that I’m not seeing.

Are there other ideas that I haven’t considered?

  • 1 1 Answer
  • 0 Views
  • 0 Followers
  • 0
Share
  • Facebook
  • Report

Leave an answer
Cancel reply

You must login to add an answer.

Forgot Password?

Need An Account, Sign Up Here

1 Answer

  • Voted
  • Oldest
  • Recent
  • Random
  1. Editorial Team
    Editorial Team
    2026-05-24T10:34:13+00:00Added an answer on May 24, 2026 at 10:34 am

    See my answer to What is the most efficient/elegant way to parse a flat table into a tree?. I describe a design I call Closure Table.

    In your case, you’d have your tables Users and Groups and UserGroupMembers that is the intersection table (many-to-many) between Users and Groups.

    Then you’d need another table to describe how groups are nested. Call it SubgroupPaths for instance. This records every path relating a given group to its subgroups.

    CREATE TABLE SubgroupPaths (
      supergroup INT UNSIGNED NOT NULL,
      subgroup   INT UNSIGNED NOT NULL,
      pathlength SMALLINT UNSIGNED NOT NULL DEFAULT 0,
      PRIMARY KEY (supergroup, subgroup),
      FOREIGN KEY (supergroup) REFERENCES Groups(groupid),
      FOREIGN KEY (subgroup) REFERENCES Groups(groupid)
    );
    

    You may also need some permutations of compound indexes to support certain queries you’d run against this table.

    This design allows you to have multiple hierarchies, so you could have group "cool people" be a descendant of each of its supergroups.

    INSERT INTO Groups (groupid, groupname) VALUES
    (1, 'REALLY cool people'),
    (2, 'slightly cool people'),
    (3, 'cool people');
    
    INSERT INTO SubgroupPaths (supergroup, subgroup, pathlength) VALUES
    (1,1,0), (2,2,0), (3,3,0), -- every group points to itself
    (1,3,1), -- REALLY is parent of cool people
    (2,3,1); -- slightly is also parent of cool people
    

    Now you can get the list of all users who should be considered cool people, regardless of whether they are members of cool people, slightly cool people, or REALLY cool people. We can even throw in a DISTINCT in case some users are associated with more than one of these groups.

    SELECT DISTINCT u.*
    FROM SubgroupPaths AS cool
    JOIN SubgroupPaths AS supercool ON cool.subgroup=supercool.subgroup
    JOIN Groups AS g ON supercool.supergroup = g.groupid
    JOIN UserGroupMembers AS m ON m.groupid = g.groupid
    JOIN Users AS u ON u.userid = m.userid
    WHERE cool.subgroup = 3;
    

    I prefer Closure Table over the Nested Sets design suggested by other answers, because Closure Table supports referential integrity constraints, and there are some queries that are hard in Nested Sets but easier in Closure Table.

    For more on Closure Table, check out my book SQL Antipatterns Volume 1: Avoiding the Pitfalls of Database Programming.


    Footnote to all this: be careful about violating the YAGNI principle.

    I once implemented a database to store arbitrary-depth groups like this, and all the PHP code to display, report, and administer hierarchies. Also I had to clone hierarchical collections when they were used, because the hierarchy could be reorganized later, and we needed to keep historical data of how the elements in the hierarchy were used. It took weeks to code and test. And when it was all done, the user of the application never actually stored any hierarchy more one one level deep.

    Some decision-makers will change their minds about the scope of requirements if you tell them how much work (i.e. budget) it will take to implement and test.

    • 0
    • Reply
    • Share
      Share
      • Share on Facebook
      • Share on Twitter
      • Share on LinkedIn
      • Share on WhatsApp
      • Report

Sidebar

Related Questions

I'm developing an embedded system which currently boots linux with console output on serial
I'm developing a Ruby on Rails application that needs to allow the user to
I'm developing a XAML system which at present involves an icon in the taskbar
I am developing a system which selects questions from a database to generate a
I am developing a system as an aid to musicians performing transcription. The aim
When developing on a system with dual monitors, I like to make the most
I'm developing an operating system and rather than programming the kernel, I'm designing the
I am developing a PHP-based login system. Each user has an ID(a number) and
I am developing a custom control derived from System.Windows.Controls.ContentControl. In the controls default template
We are developing a considerably big application using Ruby on Rails framework (CRM system)

Explore

  • Home
  • Add group
  • Groups page
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Users
  • Help
  • SEARCH

Footer

© 2021 The Archive Base. All Rights Reserved
With Love by The Archive Base

Insert/edit link

Enter the destination URL

Or link to existing content

    No search term specified. Showing recent items. Search or use up and down arrow keys to select an item.