• A lot depends on how frequently new groups are defined, how frequently group definitions change (whether by adding new members or removing existing members or adding new subgroups or removing existing subgroups), and how deeply nested are your groups. I imagine the nesting depth will be fairly small, so it's fairly easy to design a structure in which it is easy to update group membership and to introduce new groups, and easy to provide the three functions you mention.

    Since groups are potentially very large (there are a lot of red stars, for example) and since a star can be a member of many groups, it's probably a good idea to use something shorter than names to make links within the data structure (but this, of course, should be made invisible to users). That just needs a table for each star/group which uses its name and provides its identifier, perhaps as a bigint (I can't remember whether there are enough stars to need that) which can be automatically generated

    You will need an additional table in addition to those in the code you posted to represent the subgroup relationship.

    It is then straightforward to build total group membership from subgroups and individual members using a recursive CTE, and creating groups which are built from other groups, with or without additional individually specified elemets, becomes trivial. Subtraction is trivial too.

    Tom