many to many normalization - database

I'm studying Database normalization and I just can't understand one thing.
Suppose we have a Many-to-Many relation. We have a table Course and we have a table Student. Multiple students may take multiple courses.
Suppose we have a "transition" table Course_Student that stores only primary keys of a student and a course he has chosen.
My task is to make all tables in 3NF and if some table is not in 3NF then to explain why.
My question is: are these tables already in 3NF and I'm especially concerned about the "transition" table.
Thanks so much!
Course
id title
1 Math
2 Programming
Student
id name
1 John Stevens
2 Jack Ryan
Course_Student
course_id student_id
1 1
1 2
2 1
CREATE TABLE Course(
id int IDENTITY(1,1) PRIMARY KEY,
title varchar(100) NOT NULL
)
CREATE TABLE Student(
id int IDENTITY(1,1) PRIMARY KEY,
name varchar(50) NOT NULL
)
CREATE TABLE Course_Student(
course_id int FOREIGN KEY REFERENCES Course,
student_id int FOREIGN KEY REFERENCES Student
)

As per my understanding of Normalization, your tables are already in 3.5 NF (BCNF). The design of your table is great.
Over normalization can be bad sometimes but in your case it seems perfectly sane.
For the Table (Course_Student)
Primary Key should be (course_id, student_id)
with 2 foreign keys, referencing the two table :) !

Assessing normal form is something that is done to a database design that includes, for each table, the applicable functional dependencies.
Absent an explicit statement of the latter, all dependencies can only be assumed to be on (all) the keys, and hence the design can only be assumed to satisfy (at least) BCNF, by definition.

Related

Relationship between database tables

I have an existing DB schema like this.Is there a way to create any kind of referential integrity between these two tables. What exactly is the kind of relationship ? Is it many to many with just two classes
Student table:
ID Name CourseID
------------------------
1 Student1 100023
2 Student2 100023
3 Student3 100024
4 Student4 NULL
Course table:
ID CourseID CourseName
--------------------------
1 100023 Course1
2 100022 Course2
3 100024 Course3
4 100023 Course6
ID is the primary key in both the tables. CourseID is the column for the relationships.
Definitely. You can create a Foreign Key constraint between Student.CourseID and Course.CourseID. You can either do it through SQL Server Management studio directly or by using an ALTER TABLE/ADD CONSTRAINT statement. Personally, I find the Management Studio easiest to use.
Do a search on "SQL Foreign Key Constraints" and you should find a W3Schools (or something similar) explaining everything you need to know to get started with them.
Looking the table you have described and assuming CourseID would be unique in Course table it is many to one/zero relation between Student and Course
or can be said zero/one to many relation between Course and Student table.
but I feel this is not a good design it should have three tbales
Course table
Student table
Bridge table for Course and Student

SQL Server choosing foreign key from another foreign key or unique key

In my scenario I have a table tblCity that has two columns as foreign keys CompanyRef and BranchRef, also they together are unique.
And I'd add one unique key to use as primary key [ID]
And in other table called tblCustomer I need to use tblCity as foreign key.
My problem is that I really need that ID column or I should use two foreign keys as primary key? In second case I must use three column as foreign key (CompanyRef, BranchRef, CityRef) in tblCustomer or what?
Which one of these methods is right for my problem?
So, just to make things clear a little bit in your question (I hope I got it right):
tblCity
CityId INT -- is part of the separate PK option
CompanyRef INT, FK -> tblCompany
BranchRef INT, FK -> tblBranch
tblCustomer
CustomerId INT -- not interesting here
CityRef INT FK -> tblCity -- is part of the separate PK option
CompanyRef INT -- part of the alternative
BranchRef INT -- part of the alternative
I can't tell which one is best performance-wise (that's more a DBA question), but from a developer perspective, I would advice for having a single column PK for City:
City sounds like a quite generic concept. It might be needed in the future, so dragging two columns in each other table referencing it, means that each JOIN will be on those two columns.
The final solution could look like this:
tblCity
CityId INT PRIMARY KEY IDENTITY(1, 1),
CompanyRef INT, FK -> tblCompany
BranchRef INT, FK -> tblBranch
UNIQUE (CompanyRef, BranchRef) -- acts as a constraint, but also an index
tblCustomer
CustomerId INT
CityRef INT FK -> tblCity
Side note: Hungarian notation seems quite discouraged these days - see this very popular question and its answers.
Also, I would advice to keep the same column name for the same thing. E.g.
CompanyRef -> CompanyId (or whatever the PK is named)
BranchRef -> BranchId
you need to creat relationship
base of what type of relationship you need to use
primary key and foreign key = one to money
primary key and primary key = one to one
foreign key and foreign key = many to many

Extending SQL Table

I have 4 SQL tables: User, Student, Professor and Publication.
User has the common columns for any kind of user;
Student has columns specific for a student;
Professor has columns specific for a professor;
Publication is only for professors.
So I have:
create table dbo.[User] (
Id int identity not null
constraint PK_User_Id primary key clustered (Id),
-- Other user columns
)
create table dbo.Student (
UserId int not null
constraint PK_Student_UserId primary key clustered (Id),
-- Other student columns
)
create table dbo.Professor (
UserId int not null
constraint PK_Professor_Id primary key clustered (Id),
-- Other student columns
)
create table dbo.Publication (
Id int identity not null
constraint PK_Publication_Id primary key clustered (Id),
UserId int not null
-- Other student columns
)
alter table dbo.Student
add constraint FK_Student_UserId foreign key (UserId) references dbo.[User](Id);
alter table dbo.Professor
add constraint FK_Professor_UserId foreign key (UserId) references dbo.[User](Id);
alter table dbo.Publication
add constraint FK_Publication_UserId foreign key (UserId) references dbo.Professor(Id);
QUESTION
Should I have a column Id as PK in Professor and Student tables?
And make, for example, (Id, UserId) as the PK of Professor (Same for student)
Then Publication would reference Professor.Id and not Professor.UserId.
I am asking this because it sounds strange to have Publication to reference UserId from Professor table which can be confusing when I will have more tables.
Could someone please advice me on this?
In your current schema arrangement and without knowing your use cases (programmatically), one could make the argument that you don't need the Id identity columns for any of the extension tables. I assume this would be a 1 to 1 relationship to the User table anyway, so you'd at least want a unique constraint on the UserID columns, which you'd get by making it a PK anyway.
Things I like to consider are:
Can a professor ever become a different user ?
Is it possible for a professor to exist without an user ?
Is it possible for a single user to be two professors (multiple disciplines?)
If so, why wouldn't you give every professor an unique Id (ProfessorId), and only create a foreign key to the User table (UserId, you could call this UserFk).
In the publication table you can reference the professor by his/her id and call this one ProfessorFk. This way you create very efficient references between tables. The publication table than also gets a single PublicationId as primary key.
Correct me if i'm wrong, i don't know your use case. But it would seem reasonable that a professor can have multiple publications, but a publication can also be written by multiple professors ? This would mean you need an extra table between publication and professor for the n-n relationship.
About creating a professor key that is a combined key (Id, UserId). I personally dislike combined keys, if you want to reference this professor from your publication table you need two columns.
This would also suggest you can have multiple professors for the same user, if so, go for the single Id option.
This means i would create the following setup:
User Table
UserId
Student Table
StudentId
UserFk
Professor Table
ProfessorId
UserFk
ProfessorPublication Table
ProfessorFk
PublicationFk
Publication Table
PublicationId
So, it partly is based on what you want to be able to do with your data, and partly just your preference.

how to implement one to many and many to many relation in database

I have a data for rubber belts where one compound has many chemicals and these many chemicals can be combined in any combination to form a new compound(one chemical in many compounds). I have created one table for compounds and one for chemicals. How do i form a relational table without huge repeat of data?
No doubt there's a huge number of tutorials on the net if you do a search. You should do some research or get a good database text. To help you out here's an example of your many to many relationship realised as one to many tables with an associated CompoundChemical table.
CREATE TABLE Compound
(
CompoundId INT NOT NULL PRIMARY KEY,
Name VARCHAR(100) NOT NULL
);
CREATE TABLE Chemical
(
ChemicalId INT NOT NULL PRIMARY KEY,
Name VARCHAR(100) NOT NULL
)
CREATE TABLE CompoundChemical
(
CompoundId INT NOT NULL,
ChemicalId INT NOT NULL,
PRIMARY KEY (CompoundId, ChemicalId),
FOREIGN KEY fk1 (CompoundId) REFERENCES Compound(CompoundId),
FOREIGN KEY fk2 (ChemicalId) REFERENCES Chemical(ChemicalId)
)
Adding table structures will help but you can probably go with something like this
Creating one table for compounds and one for chemicals is good but you'll most probably need one more table because there is no fixed number of chemicals in each compound.
Maybe table named Substances that has following columns that reference chemicals and compunds. (ChemicalID, CompoundID)

database implementation of data having M:N relation

I have to create a database having only 2 tables student and course. There is no relation between them or say atmost 1 relation is acceptable.
Query that usually runs on it :-
"Get courses registered by a student".
So it should be quick to respond. Please tell how to implement such database?
CREATE TABLE STUDENT
(student_id INT PRIMARY KEY)
CREATE TABLE COURSE
(course_id INT PRIMARY KEY)
CREATE TABLE COURSE_REGISTRATIONS
(
student_id INT,
course_id INT,
)
In COURSE_REGISTRATIONS, the {student_id, course_id} combination is the primary key, and obviously student_id and course_id are foreign keys to their respective table.
You can query COURSE_REGISTRATIONS for the information you need.

Resources