parent child table sql issue - mysql

i have 3 tables below which have many to many relation...In student table i have multiple foreign keys sec_id,ad_id but i dont know how to add foreign key as parent-child relation please help me out..
CREATE TABLE student(
s_id int AUTO_INCREMENT,
name varchar(30) NOT NULL,
PRIMARY KEY(s_id)
)
CREATE TABLE section(
sec_id int AUTO_INCREMENT,
name varchar(2) NOT NULL,
PRIMARY KEY(sec_id)
)
CREATE TABLE advisor(
ad_id int AUTO_INCREMENT,
name varchar(2) NOT NULL,
PRIMARY KEY(ad_id)
)

If a student can have at most one advisor, then it's a one-to-many relationship.
The normal pattern for implementing that relationship is to define a foreign key column in the child table, the table on the "many" side of the relationship. For example:
ALTER TABLE student ADD ad_id INT COMMENT 'fk ref advisor';
Further, some storage engines, like InnoDB, support and enforce foreign keys. That is, we can have the database enforce restrictions (constraints) on values that can be stored in columns defined as foreign keys.
For example, we can establish a rule that says that a value stored in the ad_id column in the student table... must be found in a row in the advisor table, in the ad_id column.
For example:
ALTER TABLE student ADD CONSTRAINT fk_student_advisor
FOREIGN KEY (ad_id) REFERENCES advisor(ad_id)
ON DELETE RESTRICT ON UPDATE CASCADE
This also enforces a rule that a row from advisor table cannot be deleted if there are rows in student table that reference it.
That same pattern can be repeated for any one to-to-many relationship. For example, if a student can be related to at most one section we can add a foreign key in the same way.
If there's a many-to-many relationship, then we introduce a relationship table that has foreign keys referencing the two related entity tables.
If a student can be related to zero, one or more section, and a section can be related to zero, one or more student, that's an example of a many-to-many relationship.
We can introduce a new table like this (as an example):
CREATE TABLE student_section
( student_id INT NOT NULL COMMENT 'pk, fk ref student'
, section_id INT NOT NULL COMMENT 'pk, fk ref section'
, PRIMARY KEY (student_id, section_id)
, CONSTRAINT fk_student_section_student
FOREIGN KEY student_id REFERENCES student(s_id)
ON DELETE CASCADE ON UPDATE CASCADE
, CONSTRAINT fk_student_section_section
FOREIGN KEY section_id REFERENCES section(sec_id)
ON DELETE CASCADE ON UPDATE CASCADE
)
With that in place, to establish a relationship between a student and a section, we insert a row to the new student_section table. If the student is related to another section, we add another row to the table, referencing the same student, but a different section.
The value stored in the student_id column refers to a row in the student table; and a value stored in the section_id column refers to a row in the section table.
(The many-to-many relationship is really composed of rows in a new table that has a one-to-many relationship to two other tables.)

Related

In M:N database relationship it's better to reference by a composite PK or two foreign keys

I have a database that involves a table called U and a table called P .
table U
U_Id primary key.
table P
P_Id primary key
There is many to many relationship between the two tables.
I have two ways to create relationship between the two table:
1) create a new table that contains a composite Primary Key (U_Id,P_Id)
2) create a new table that contains references from U table and P table as foreign keys.
(U_id and P_id as foreign keys )
Third_Table
U_id FK not null
P_Id FK not null
What the better option?
Options 1 and 2 aren't opposed. Your relationship table will contain U_Id and P_Id as foreign keys, and the combination of these two columns should at least be marked as a unique key, if not a primary key.
Some DB designers prefer to introduce a surrogate identifier as primary key. Others (including myself) prefer to use the combination of foreign keys as the primary key.
2) create a new table that contains references from U table and P table as foreign keys.
That you need for referential integrity, else the 3rd table could have values that do not refer to anything. (Hurrah for many-to-nothing rows!)
1) create a new table that contains a composite Primary Key (U_Id,P_Id)
If you don't do that, what will be the primary key to the 3rd table? It will have one, right?
A primary key is one form of unique constraint. If a table has more than one unique constraint, the choice of which one to call the primary key is arbitrary. In your case, though, there's only one.
You need some kind of unique constraint on the 3rd table to prevent duplicate rows. Primary Key (U_Id,P_Id) says than any {U_Id,P_Id} pair is unique, and identifies that relationship. From what you say, that's what you want.
I would expect a composite key consisting of two foreign keys. Example code (untested):
CREATE TABLE Q
(u_id INT NOT NULL FOREIGN KEY REFERENCES U (u_id),
p_id INT NOT NULL FOREIGN KEY REFERENCES P (u_id),
PRIMARY KEY (u_id, pi_id));

Creating a parent and child table, does child need its own primary id column?

When we create parent-child tables, does the child table need its own primary key, or should the foreign key of the parent be used as the primary key?
Example:
I have a table that stores users, which is defined like:
CREATE TABLE users (
'id' bigint(20) UNSIGNED NOT NULL AUTO_INCREMENT,
'username' varchar(32),
PRIMARY KEY ('id'))
I want to make a second table that stores some more information about a user, like their favorite animals. Should that table have its own 'id' column as well as a separate foreign key for the linked user?:
CREATE TABLE users_extra_info (
'id' bigint(20) UNSIGNED NOT NULL AUTO_INCREMENT,
'fk_user_id' bigint(20) UNSIGNED NOT NULL,
'fav_mammal' varchar(32),
'fav_reptile' varchar(32),
...
PRIMARY KEY ('id'),
KEY 'fk_user_id' ('fk_user_id'))
or do you usually just drop the 'id' column since the foreign key has to be unique?:
CREATE TABLE users_extra_info (
'fk_user_id' bigint(20) UNSIGNED NOT NULL,
'fav_mammal' varchar(32),
'fav_reptile' varchar(32),
...
PRIMARY KEY ('fk_user_id'))
Thanks
As a matter of principle, not related to other tables, each table should have a PRIMARY KEY in order for you to be able to distinguish one row from another. While it's not always necessary to absolutely identify individual rows that is often a requirement.
In the event of a true one-to-one relationship (or a one-to-zero-or-one relationship, which also occurs), because the foreign key is necessarily unique it can also be used as the primary key of the subsidiary table. There is absolutely no reason at all to introduce a second unique column in that case.
However, one-to-one and one-to-zero-or-one relationships are less common than one-to-many relationships. In that more common case, you cannot use only the foreign key columns as the primary key since they are not unique in the child table. In this case you can choose either to introduce an additional integer key or created a composite primary key using the foreign key column(s) and one or more other columns that, together, are guaranteed to be unique.
You have to understand the normalization rules.
Here's the link http://www.studytonight.com/dbms/database-normalization.php.
If you want to put the additional columns to another table, I don't see a reason to have an extra id column. Below is what I would do. Another benefit from this approach is that you ensure 1 to 1 relationship. If you had a separate ID column, you would be able to have many rows in users_extra_info linked to one row in users.
CREATE TABLE users (
id int,
username varchar(32),
PRIMARY KEY (id));
CREATE TABLE users_extra_info (
fk_user_id int,
fav_mammal varchar(32),
fav_reptile varchar(32),
PRIMARY KEY (fk_user_id),
foreign key (fk_user_id) references users(id));
You can also think about cascading deletion.

Combining Foreign Keys

In MySQL, how do you combine 2 foreign keys in a table to become a primary key?
I have two tables, one Staff, one Roles, each containing their own primary keys, StaffID and RoleID. I have created a third table called StaffRole which will contain the StaffID and RoleID, keeping in mind this is a one to many relationship, as a staff member may have 1 or more roles.
How would you combine the foreign key of StaffID and RoleID to create a new unique primary keys for the table StaffRole.
Technically, what you are describing is not a one-to-many relationship, but instead it is a many-to-many relationship since one Staff record relates to many Role records, but one Role record also relates to many different Staff. Your use of the join table StaffRole is the typical way of handling the relationship.
This is semantics, but it isn't really a matter of combining the two foreign keys, so much as just creating a third key which is the composite of the two and also the primary key. So your table will have two FOREIGN KEY definitions, one each for the two columns, and one composite PRIMARY KEY definition across both of the columns.
CREATE TABLE StaffRole (
StaffID INT NOT NULL,
RoleID INT NOT NULL,
/* Composite primary key on both columns */
PRIMARY KEY (StaffID, RoleID),
/* Two separate foreign keys */
FOREIGN KEY (StaffID) REFERENCES Staff (StaffID),
FOREIGN KEY (RoleID) REFERENCES Roles (RoleID)
) ENGINE=InnoDB;
Note, I have specified InnoDB as the table type, since MySQL will not enforce the FOREIGN KEYs on MyISAM tables.
You can create a StaffRoleID as a primary key, and use StaffID and RoleID as foreign keys.

Primary keys in sql

I have here some problems undersanding how this works.
So I have 2 tables Students and Enrolled like this:
CREATE TABLE Students
(sid CHAR(20),
name CHAR(50),
email CHAR(30),
age INTEGER,
gr INTEGER)
CREATE TABLE Enrolled
(sid CHAR(20),
cid CHAR(20),
grade CHAR(2),
PRIMARY KEY (sid,cid))
So I don't understand this particulary row PRIMARY KEY (sid,cid)
Can someone explain to me how it works? I have to specify that I have another table Courses from where the cid.
Is is equivalent saying like this:
CREATE TABLE Enrolled
(sid CHAR(20) foreign key references Students(sid),
cid CHAR(20) foreign key references Courses(cid)
)
A PRIMARY KEY is used to identify a table. A field or column that is defined as PRIMARY KEY will contains different values on each row in that table, and is mandatory to have a value (so, PRIMARY KEY is equivalent to UNIQUE and NOT NULL).
PRIMARY KEY can be a single field, or multiple fields, but it always satisfy that "each row will have a different PRIMARY KEY".
If you declare as PRIMARY KEY a combination of 2 columns, you will be able to have this for example:
CREATE TABLE Enrolled
(sid CHAR(20),
cid CHAR(20),
grade CHAR(2),
PRIMARY KEY (sid,cid)) --PRIMARY KEY with combination of 2 columns
sid | cid | grade
1 1 XX
1 2 XX
2 1 XX
2 2 XX
2 3 XX
In this example, you can see that the column sid or the column cid has repeated values individually, but there isn't a combination of (sid, cid) that was repeated.
Like a PRIMARY KEY is used to identify a row in a table, when we want to relate two tables we can define a FOREIGN KEY in one table to link this one with the other table.
Your case is that the ENROLLED table is identified by a composite PRIMARY KEY to represent a many-to-many relationship. That is the way to say that:
A student can be enrolled in many courses.
A course can have enrolled many students.
Note*: Is a best practice to define the PRIMARY KEYS as numeric values, such integer, bigint, etc. because it is better to improve the indexes performance (all PRIMARY KEYS have defined inherently an INDEX, and they are faster working with "numeric" values than working with "string" values).
PRIMARY KEY (sid,cid) means composite primary key.. the combination of these field should be unique.
PRIMARY KEY means both UNIQUE and NOT NULL.
If you want sid and cid to also be FOREIGN KEY you have to specify that separately.
Having two fields for a primary key is often used for tables that are the physical representation of a many-to-many relation. In your database design diagram you would have STUDENT and COURSE as entities and ENROLLMENT as a many-to-many relationship between them.
In the physical database diagram many-to-many relationships are modelled as tables, often with a composite PRIMARY KEY and with FOREIGN KEY constraints to the entity tables.

Best MySQL Table Structure: 2 Parents, 1 Child

I have two parent tables, BusinessGroup and SocialGroup, and one child table, Members. A Member can belong to either parent, but not both.
As far as I can see, there are two options for constructing the child table.
Opt 1: Include a field for ParentType, and another for ParentID. The ParentType would be an enum (Business, Social) and the ParentID would be the PK from the respective parent table.
Opt 2: Include a field for BusinessGroupID, and another for SocialGroupID. In this case, the fields would need to be nullable, and only one could contain a value.
Any ideas on which approach is best?
I tried option 1 in MySQL, and created two foreign keys from the child back to the parents. I ran into trouble when inserting values though, since MySQL was expecting a corresponding value in BOTH parent tables.
As a supplementary question: how do things change if I have a larger number of parents, e.g. 6?
Thanks!
CREATE TABLE Group (
GroupID integer NOT NULL
, Name varchar(18)
, Description varchar(18)
, GroupType varchar(4) NOT NULL
-- all columns common to any group type
);
ALTER TABLE Group ADD CONSTRAINT pk_Group PRIMARY KEY (GroupID) ;
CREATE TABLE BusinessGroup (
GroupID integer NOT NULL
-- all columns specific to business groups
);
ALTER TABLE BusinessGroup
ADD CONSTRAINT pk_BusinessGroup PRIMARY KEY (GroupID)
, ADD CONSTRAINT fk1_BusinessGroup FOREIGN KEY (GroupID) REFERENCES Group(GroupID) ;
CREATE TABLE SocialGroup (
GroupID integer NOT NULL
-- all columns specific to social groups
);
ALTER TABLE SocialGroup
ADD CONSTRAINT pk_SocialGroup PRIMARY KEY (GroupID)
, ADD CONSTRAINT fk1_SocialGroup FOREIGN KEY (GroupID) REFERENCES Group(GroupID) ;
CREATE TABLE Person (
PersonID integer NOT NULL
, GroupID integer NOT NULL
);
ALTER TABLE Person
ADD CONSTRAINT pk_Person PRIMARY KEY (PersonID)
, ADD CONSTRAINT fk1_Person FOREIGN KEY (GroupID) REFERENCES Group(GroupID) ;
"parent tables" is probably a misnomer - in the relational model I'd flip your relationship. e.g. make members the master records table, and a join table that allows 1-1 mapping, so have a PK of member_id or whatever the right field is, and map to the FK in either BusinessGroup or SocialGroup.