I am working on a group management page with a variable number of tabs from which the admin(s) of each group on the site can choose for their page. Admins shall also be able to create group member roles, assign privileges on the tabs to those roles, and assign roles to the members. Any member can also belong to one or more groups.
I have sketched out some tables for the database to this. Here are the three of interest:
groups
----------------
GroupID <- PRIMARY KEY
GroupName
GroupDescription
group_member_records
--------------------
GroupMemberRecordID <- PRIMARY KEY
GroupID <- FOREIGN KEY: references groups.GroupID
GroupMemberID <-FOREIGN KEY: references group_members.GroupMemberID
GroupMemberRoleID <- FOREIGN KEY: references group_member_roles.GroupMemberRoleID
group_member_roles
-----------------------
GroupMemberRoleID <- PRIMARY KEY
GroupID <- FOREIGN KEY: references groups.GroupID
GroupMemberRoleName
// NOTE: GroupID,GroupMemberRoleName UNIQUE
I initially decided to just give group_members a GroupMemberRoleID foreign key, but the problem with that is that it would be possible for a member to belong to multiple groups, and have a group member role, and that group member role would be different for at least two of the groups of which that member belongs to! Thus, I moved the GroupMemberRoleID foreign key to group_member_records.
Before I finally implement that table that records all the tab privileges for the groups, I would like to know a couple of things:
Is there any risk of circular reference? I have seen closely related question answered here, but am unsure what they mean by:
This is not a circular reference.
It would be if emails would have a strong integrity relationship to
invitations and invitations an independent strong integrity
relationship back to emails (for example).
(my bold on what was unclear to me)
Is this, at all, bad design or bad practice?
Related
Skip down for TL:DR version
Currently designing a Horse-riding class booking function for a Club's website.
Designing the SQL database from scratch using phpMyAdmin. Members join the club as per family basis - Meaning each unique "Family_ID" would contain multiple members within each one.
The club only wants users to login with their Family_ID and through that one login the user would be able to book a riding class for any of the members within the family. was wondering if it's possible to give each member a unique ID by referencing the Foreign Key (Family_ID). So each member would have a unique ID based on their Family_ID. Example Listed below.
When a new family registers for the club - they fill in paper forms which an admin will enter their details into the existing database, currently the members don't have an ID, just details kept within each Family_ID. Was thinking of a work-around where when a new member is being added the form would have an auto-fill input box that adds '01'/'02'/etc to the ends of family_id.
TL:DR
SQL - phpMyAdmin
Multiple Members within a "Family_ID"
Multiple Members share a "Family_ID" (Foreign Key from "Family" Table)
Each Member to have a Unique ID - "Member_ID" (That uses the Family_ID as a prefix)
Example
Family_ID = 0024
Member_ID = 002401 (Unique Member_ID Auto_increment using last two digits)
My first post so I apologize if I left out any necessary information, Thank you for your answers.
I have a doubt about the way of relating some tables. I have these tables:
User table: username (primary key)
Team table: team_name(primary key), username (foreign key references User(username))
With this relationship, I get that an user can have more than one team.
Group table: group_name (primary key)
I want that a group can have many teams, but these teams have to be of different users, so two teams of a user cannot be in the same group.
I have thought to do a relationship with the three tables of this way:
Group_teams table: (group_name, username, team_name). This table would have a composite primary key (group_name and username), in this way I would be sure that an user cannot has more than one team in a same group.
In addition, I think that I should create a composite foreign key references User(username) and Team (team_name) to be able to control that the team of a user exists. Finally, I should create another foreign key references Group (group_name) to control that a group exists.
I'm not sure that it would be of this way because I have errors when I try to do it. Could yo help me and tell me your opinions?
If a user can be on (at most) only one team, then you have a 0/1 - many relationship.
The easiest approach is to have TeamId in the Users table. This would be a foreign key reference to Teams.
There is no need for a third table to represent this relationship.
There's no need to reproduce the username field in the Group_teams table, just have group_name & team_name.
Create a trigger on the Group_teams table to fire before a new row is inserted, checking for more other teams with the same username.
Have a look at the question "How do you check constraints from another table when entering a row into a table?", specifically this answer from Jim V describing such a setup.
I want to create a database scheme and don't really know a solution for the following scenario:
I have users, teams and projects. I want to enable to create projects as a user, but also as a team. What I thought of, was to include two foreign keys in the projects table. One for 'userId' and one for 'teamId'. But in this case for each entitiy either userId or teamId would be null.
Is this a good solution or is there a better possibility to solve that?
You can create a constraint that would force userId != null OR teamId != null.
Alternatively, you can require each project to have a non null foreign key userId (some user in the team had to actively create the project, right?), and then create an associatedTeam foreign key (which can be optional).
Its just a quick question :
I have user table and it has fields name, address and books_bought. books_bought is foreign key and its value is some PK from other table. Now after 1st insert, I will fill out all of this fields , but after second INSERT I want only to add a additional books_bought, so that am creating array of books_bought values?
You're doing it the wrong way around - this is a one-to-many relationship i.e. many books bought to one user. You need to have the foreign key on the many side of the relationship, so instead of having a foreign key to books_bought on the users table, add a foreign key to users on the books_bought table.
If you have a books table and a users table, then this is a many-to-many relationship and you will need a link table to go between them to hold the foreign keys.
You should not have more than one book in the books_bought cell because it will violate the atomicity constraint fo the database tables. You have to have a separate entry for each book_bought. This would cause a lot of redundant information as name, address would be repeated for each book bought by a specific person.
To solve this, you have to split the table into something like this:
R1(primary_key , name , address) and R2(foreign_key , books_bought)
Here foreign_key refers to primary_key of R1
I've decided for the first time to switch to InnoDB and experiment with foreign keys and other InnoDB features.
When creating relationships, should I declare them only on 1 table? Or both tables?
For example, for each cases below, where and how would you declare the relationships?
1 User has many widgets
widget belongs to 1 user (is that same as above?)
1 user has 1 widget
user [many-to-many] widgets
many users share 1 widget
Those are just some random examples, I'm just trying to understand which directions relationships should be declared.
Also, on the same note, which direction do "ON CASCADE" stuff work?
Thanks
1 User has many widgets
Assuming a widget is exclusive to one user (because you have a seperate point for many to many): user_id on table widget that references the primary key on user
widget belongs to 1 user
see above.
1 user has 1 widget
widget_id in user table that references primary key on widget table, with unique index on widget_id, or the other way around, doesn't really matter. If it is a 1-to-1 and not a 0 or 1-to-1 relationship, you should consider putting widget and user in one table.
user [many-to-many] widgets
Introduce a third table, user_widget, with 2 fields user_id and widget_id referencing the corresponding primary keys in user and widget table.
many users share 1 widget
same as "1 user has 1 widget", but without a unique index on the widget_id
The ON CASCADE option works from parent (primary key) to child (foreign key/reference). So if you have a ON DELETE CASCADE in your first scenario (1 User has many widgets), delete a user deletes all his widgets, but deleting all widgets doesn't delete the user.