needing some help setting up some tables and their foreign key constraints.
3 total tables:
UserTable – contains:
- UserID
- Other Fields
ShapeTable – contains:
- ShapeID
- UserID (from UserTable)
- Other Fields
RecipientTable – contains:
- RecipientID
- UserID (from UserTable)
A user is able to draw a shape, or many shapes. A user can also add potentially many recipients. A shape can have 0 or many user's recipients added to it.
If a recipient is deleted by user, it should be removed from all stored shapes. If a shape is deleted by user, it should not delete recipients.
I'm struggling with how to design the "mappings" between the Shapes and the Recipients for each user.
When a user draws a shape, I want to present all the recipients for the user that drew the shape. The user will then be able to select 0, 1, or many of those recipients for that given shape. I'll need to be able to retrieve this later on as well. When a shape is deleted, I want it to delete the "mappings" to any recipients as well, but not necessarily delete the actual recipient record.
What is the best way to arrange the tables, should there be an additional "mappings" type table created, and what foreign key constraints should exist to enforce cascading and referential integrity?
Let me know if there's a better way to present the question if I left something out. I am using MySQL (InnoDB) and PHP (if that matters).
Best Answer
With a many-to-many relationship (each shape can be associated with many recipients, and each recipient can be associated with many shapes).
Here's the create statements for the mapping table (plus my dummy definitions for the three tables you've already got):
You'd probably want the same
ON DELETE
andON UPDATE
for theshape
andrecipient
foreign keys, but you didn't specify, so I left that out.Tested via db-fiddle; that has the four
CREATE TABLE
statements, some sample data, and shows what happens in the mapping table when a shape or a recipient is removed.NOTE: Presumably, a recipient and a shape should only be associated if they belong to the same user.
You might be able to make the primary keys of
shape
andrecipient
the unique ID from the table combined with theUserID
.map_shape_recipient
would require theUserID
column too, and (if there's only one and it's part of the foreign keys toshape
and torecipient
) they'd have to have the sameUserID
.Technically at least, this would be a denormalization (the map table wouldn't need the
UserID
becauseShapeId
andRecipientID
both uniquely identify one row in their respective tables).A more solution would be an
INSERT
trigger on the map table, that prevents a row from being inserted unless theUserID
from theshape
row and theUserID
from therecipient
row match.In your case, your application should prevent associating a shape with a recipient that doesn't have the same
UserID
. I would still recommend some mechanism to ensure relational integrity, in case someone directly interacts with the database outside of the application.