Reputation: 1954
I just started applying everything that I read about table relationships but I'm kind of confused on how to insert data on tables with MANY-TO-MANY
relationship considering there's a third table.
Right now I have these tables.
subject
name
code PK
units
description
schoolyear
schoolyearId PK
yearStart
yearEnd
schoolyearsubjects (MANY TO MANY table)
id PK
code FK
schoolyearId FK
But the problem with the above schoolyearsubjects table is that, I don't know how I can insert the schoolyearId
from the GUI. On the GUI screenshot, as soon as "Save" button is clicked, a TRANSACTION
containing 2 INSERT
statements (to insert on subject
) and (to insert on schoolyearsubjects
) will execute. If I stick with the above, I'll have to insert the schoolyearId. schoolyearId
definitely won't come from GUI.
I'm thinking of changing the columns of schoolyearsubjects
and schoolyear
to this:
schoolyear
--composite keys (yearStart, yearEnd)
yearStart (PK)
yearEnd (PK)
schoolyearsubjects(MANY TO MANY table)
id PK
code (FK)
yearStart (FK) --is this possible?
yearEnd (FK) --is this possible?
1.) Is the solution to change the columns and make a composite key so I can just insert yearStart
and yearEnd
values instead of schoolyearId
?
2.) Is my junction / linking table schoolyearsubjects correct?
3.) What can you advise?
I'd appreciate any help.
Thanks.
Upvotes: 2
Views: 124
Reputation: 2240
For me schoolyear is a period, and as such, there is no need to use a surrogate key here. This always makes things more confusing, and it is always more difficult to develop a graphical interface for it (I'm talking about how we model periods as developers).
If you stop to think, periods are seen itself as something unique. Will you have a period equal to the other? Stop and think. Even if you have, this will occur in years or different times. So we already have a primary key for schoolyear. Eliminate "schoolyard PK" from schoolyear. Use composite key here with yearStart and yearend. So, your schoolyear entity (in future, table) will be like:
In the intermediate table, you will have 3 fields as composite primary key (also foreign key!):
This will permit that a period have only a single subject. If, on the other hand, you want a period with more than one subject, you would have to put a surrogate key here.
Now, to draw the graphical interface, you will only have to use a select box (combo box). In this case you will have each item as a text, something like "from year X to Y" (a period). Your users can very well understand and select it.
Note: In anyway, you may not have the ID of a record in an interface, but the values that identify it. This is permissible to be seen, and identifies a record of their remaining.
If, however, you do not have periods as something unique, then "yearStart" and "yearEnd" are fields in subject entity, and there is no schoolyear entity. To be honest, the entity "schoolyear" should only exist if you want to reuse it's records to relationships with other records of other(s) table(s). I'm not saying this is or is not the case. Watch out as well. If you do this you say that every period has only one subject (as fields). I do not know if this is exactly what you want. We must always remember the most important thing in shaping an ER-Diagram:
Check your context. What does it ask? If you have any questions, please comment. If you can offer me some more context here, I can help you more.
Upvotes: 1
Reputation: 1288
With your current scheme you can insert the schoolyearId with a request as follows:
INSERT INTO schoolyearsubjects (id, code, schoolyearId)
VALUES ( ${id},
${code_from_GUI},
( SELECT schoolyearId
FROM schoolyear
WHERE yearStart=${start_from_GUI} AND yearEnd=${end_from_GUI})
);
For this to work, the unique constraint on (yearStart, yearEnd) in the schoolyear table is required.
As to the rest of your questions:
1) You can use a composite key in the schoolyear table it will work either way.
2) The schoolyearsubjects is correct as it allows to write join queries. If you get rid of the schoolyearId columns than you will not probably need the schoolyear table alltogether as all data you may want to get will be in the schoolyearsubjects table.
3) This article may help to deside what type of key to use.
Upvotes: 0
Reputation: 57023
Assuming you have parameters @code
, @yearStart
and @yearEnd
with values from the UI:
INSERT INTO schoolyearsubjects ( code, yearStart, yearEnd )
SELECT @code, y.yearStart, y.yearEnd
FROM schoolyear y
WHERE @yearStart <= y.yearStart
AND y.yearEnd <= @yearEnd;
...but I think you have a design flaw with your schoolyearsubjects
because it allows duplicates e.g. doing this:
INSERT INTO schoolyearsubjects VALUES ( 'code red', '2016', '2017' );
INSERT INTO schoolyearsubjects VALUES ( 'code red', '2016', '2017' );
INSERT INTO schoolyearsubjects VALUES ( 'code red', '2016', '2017' );
looks like it would result in three de facto duplicate rows.
Upvotes: 0