SQL Foreign Key Redundancy - sql

This is a question about foreign key redundancy
redundant foreign key? <- Similar Question
In General:
A Foreign Key from TABLE C references a Primary Key from Table B
A Foreign Key From Table C references a Primary Key from Table A
A Foreign Key from Table B references a Primary Key from Table A
Is the Foreign Key from C -> A necessary since C is connected through B to A?
Specific: 3 tables
Supplier Info Table A
Supplier ID - PK
Person Contact Info (for supplier) Table B
Part # - PK
Date Received - PK
Supplier ID - FK
Part Rprt Table C
Part # - PK & FK
Date - PK & FK
Supplier ID - FK
Thanks - Suggestions for reworking all the table are also welcome

The key would technically be redundant if you assume that the supplier for a person is always the supplier represented by the part. Remember, that things can change over time. Presumably, suppliers could merge, persons could change the supplier they are associated with, and the supplier associated with a part could change.
The data structure, however, does not look properly normalized. I would think that you would want a person table with information only about the person. I don't get the relationship between parts and persons.
So, I think you should rework your data structure. I would suggest that you start with the entities you have identified -- suppliers, persons, and parts. Then create association tables for them, if necessary. It is quite possible that each person should just have a SupplierId and each part should have a SupplierId and that models the relationships. If there is a relationship between parts and persons, then you might be able to satisfy that with just a PersonId field in parts.

Related

Creating Association between two entries in SQL table

I have a piece of work to do setting up a database for a small enterprise.
Currently I have 5 tables set up:
Customers
Accounts
Associations
Security(Collateral)
References (Reference Codes relating to a Job type)
One of the tasks I have is to create an association table that will link to the Customers table and show the association between 2 customers.
Columns for Association table:
AssociationID
Customer1
AssociationType
Customer2
The output should be "Customer1 is AssocationType of Customer2" eg "Dave is Accountant for Jim"
How do I set it up so that Customer1 & Customer2 are from the Customer's table? I think it might be with Foreign Keys but I am unsure.
You can set up foreign keys:
alter table associations add constraint fk_associations_customer1
foreign key (customer1_id) references customers (customer_id);
alter table associations add constraint fk_associations_customer2
foreign key (customer2_id) references customers (customer_id);
Foreign keys should be made to the primary key, so you need to define customers so:
create table customers (
customer_id int primary key, -- perhaps identity, serial or autoincrement depending on your database
. . .
);
You'll note the naming conventions:
Tables are in the plural (the contain multiple examples of something).
The primary key is the singular followed by _id.
The foreign key is either the same name as, or very similar to, the primary key of the referenced table.

Relation from one table to another with two columns in the primary key in SQL Server

I am trying to make a relation from a table to another like the following :
Books
IdBook (primary)
SerialNumber (primary)
NameBook
The other table is :
Qtt
IdQtt (primary)
IdBook
Qtt
How can I make a relation only between Qtt.IdBook and Books.IdBook ?
You meant to create a FOREIGN KEY relationship between the tables on that column like
CONSTRAINT FK_idbook FOREIGN KEY (IdBook)
REFERENCES Books (IdBook)
ON DELETE CASCADE
ON UPDATE CASCADE
But that will not work since you have composite PK in your Books table on IdBook, SerialNumber and thus you need another key column in your Qtt table to refer to both PK column else it would be a PFD (partial functional dependency)
constraint FK_book FOREIGN KEY (IdBook,IdQtt) references Books (IdBook,SerialNumber)
Although it is technically possible to create a UNIQUE constraint on Books.IdBook and a FOREIGN KEY constraint on Qtt.Book referencing that column, this probably won't work with your data model because IdBook alone doesn't uniquely identify a Books row. You need a table like BookTitle keyed by IdBook, with a one-to-many relationship to Books and another one-to-many relationship from BookTitle to Qtt on IdBook.

Relationship between composite keyed table & non primary key table

I have two tables named ORDER_HEAD and ORDER_DETAIL, following is their structure.
ORDER_HEAD:
ORD_ID (PK)
ORD_TYPE (PK)
ORD_DATE
ORD_NET_TOTAL
ORDER_DETAIL:
ODD_ID
ODD_LINE_NO
ODD_PRODUCT_ID
ODD_QTY
I want to form a relationship between the ORD_ID in ORDER_HEAD & ODD_ID in ORDER_DETAIL table. But SQL Server shows an error message:
primary key or unique constraint must be defined for table before it can participate in a relationship
Why am I getting this error ? Is there a way to perform a join between these two columns or is there a problem in my db design ?
If you want to create a relationship from Composite primary key then any reference should also include all the column's in Composite primary key
Schema of ORDER_DETAIL should be
ORDER_DETAIL
============
ODD_ID (Fk)
ORD_TYPE(Fk) -- you need to add this column
ODD_LINE_NO
ODD_PRODUCT_ID
ODD_QTY
Create Foreign key like this.
ALTER TABLE ORDER_DETAIL
ADD CONSTRAINT FK_ORDER_DETAIL
FOREIGN KEY(ODD_ID, ORD_TYPE) REFERENCES ORDER_HEAD(ODD_ID, ORD_TYPE)
UPDATE
After rethinking the problem I think you should achieve your goal by adding reference column ODD_TYPE (like user #NoDisplayName stated) and creating composite PK for your table ORDER_DETAIL consisting of 3 columns (ODD_ID, ODD_TYPE, ODD_LINE_NO), then it would be:
ORDER_DETAIL
============
ODD_ID (PK)
ODD_TYPE (PK)
ODD_LINE_NO (PK)
ODD_PRODUCT_ID
ODD_QTY
in SQL it could be:
ALTER TABLE ORDER_DETAIL ADD CONSTRAINT PK_Order_Detail PRIMARY KEY NONCLUSTERED (ODD_ID, ODD_TYPE, ODD_LINE_NO)
Then, in ORDER_DETAIL table for specific pair (ODD_ID, ODD_TYPE) you would have records being its order lines.
I think that after removing the previous PK, adding the column and setting the above key (even in visual editor) you shouldn't have problems when creating FK between the two tables and mapping the proper columns together.

SQL: can many to many relationship have a PK in addition to the FKs from the other entities

I'm having problem in inserting the values of an exam in the DB, and the reason is that every question that have been taking in the exam need to be unique which is not the case, we want the system to allow us to duplicate questions in the 60 question exam. what can I do to make this happened?
Exam (ExamID, Student.UID, ExamFB, Evaluated, ExamLevel)
Primary key (ExamID)
Foreign Key (Student.UID)
Contains (ExamID, QID, X, Y, StdAnswer, CorrectAnswer, QuestionFB)
Primary key (ExamID, QID)
Question (QID, SecID, Supervisor.UID, QBody, LawID)
Primary key (QID)
Foreign key (SecID, Supervisor.UID)
Yes, a many to many junction table does not have to be unique, although in your scenario I imagine it should be, I don't see why you would have the same question more than once on an exam, however it is quite a common scenario, to pick a slightly different scenario, imagine a service history of a car, you might have a table of mechanics, and a table of cars, and a table to store each service:
Mechanics - MechanicID (PK) Name
Cars - CarID (PK), RegistrationNumber, Make, Model
It is possible that the same mechanic will service the same car more than once, so you can't make the primary key (CarID, MechanicID), so you would either need to just assign a surrogate primary key to the service table:
Services - ServiceID (PK), CarID (FK), MechanicID(FK), ServiceDate
Or add an additional column to your table that will make the composite key unique, e.g in the above make the key (CarID, MechanicID, ServiceDate).
In your case you could have an additional column QuestionNumber (1 - 60 in your case) that identifies where the question appears in your exam, then your PK would just be (ExamID, QuestionNumber), and keep the foreign key to QuestionID.
So your database diagram would look something like one of the below:
Add an IDENTITY Attribute with the FKs together will be your PK

Designing 1:1 and 1:m relationships in SQL Server

In SQL Server 2008, how does one design a 1:1 and 1:m relationship?
Any relationship requires that the "parent" table (the one side) have a Primary (or unique) Key (PK), that uniquely identifies each row, and the "child" table (the other side) have a Foreign Key column or columns, that must be populated with values that are the same as some existing value[s] of the Primary Key in the parent table. If you want a one to many (1-M) relationship then the Foreign Key should be an ordinary attribute (column or columns) in the child table that can repeat (there can be many rows with the same value)
If you want a one to one (1-1) relationship then the Foreign key should itself be a Primary Key or unique index in the child table that guarantees that there may be at most one row in the child table with that value.
A 1-1 relationship effectively partitions the attributes (columns) in a table into two tables. This is called vertical segmentation. This is often done for sub-classing the table entities, or, for another reason, if the usage patterns on the columns in the table indicate that a few of the columns need to be accessed significantly more often than the rest of the columns. (Say one or two columns will be accessed 1000s of times per second and the other 40 columns will be accessed only once a month). Partitioning the table in this way in effect will optimize the storage pattern for those two different queries.
Sub-Classing. The above actually creates a 1 to zero or one relationship, which is used for what is called a sub-class or subtype relationship. This occurs when you have two different entities that share a great number of attributes, but one of the entities has additional attributes that the other does not need. A good example might be Employees, and SalariedEmployees. The Employee table would have all the attributes that all employees share, and the SalariedEmployee table would exist in a (1-0/1) relationship with Employees, with the additional attributes (Salary, AnnualVacation, etc.) that only Salaried employees need.
If you really want a 1-1 relationship, then you have to add another mechanism to guarantee that the child table will always have one record for each record/row in the parent table. Generally the only way to do this is by enforcing this in the code used to insert data (either in a trigger, stored procedure or code outside the database). This is because if you added referential integrity constraints on two tables that require that rows always be in both, it would not be possible to add a row to either one without violating one of the constraints, and you can't add a row to both tables at the same time.
One-to-One Relationship
Create Table ParentTable
(
PrimaryKeyCol ... not null Primary Key
, ...
)
Create Table ChildTable
(
, ForeignKeyCol ... [not] null [Primary Key, Unique]
, ...
, Constraint FK_ChildTable_ParentTable
Foreign Key ( ForeignKeyCol )
References ParentTable( PrimaryKeyCol )
)
In this case, I can never have more than one row in the ChildTable for a given ParentTable primary key value. Note that even in a One-to-One relationship, one of the tables is the "parent" table. What differentiates a One-to-One relationship from a One-to-Many relationship purely in terms of implementation is whether the ChildTable's foreign key value has a Unique or Primary Key constraint.
One-to-Many Relationship
Create Table ParentTable
(
PrimaryKeyCol ... not null Primary Key
, ...
)
Create Table ChildTable
(
, ForeignKeyCol ... [not] null
, ...
, Constraint FK_ChildTable_ParentTable
Foreign Key ( PrimaryKeyCol )
References ParentTable( PrimaryKeyCol )
)
In this scenario, I can have multiple rows in the ChildTable for a given ParentTable primary key value.
A 1:1 relationship exists where table A and table B only exist once in regards to each other.
Example: A student has 1 master student record. The student would be table A and the record in table B. Table B would contain a foreign key to the student record in table A (and possibly vice-versa)
A 1:m relationship exists where table A can be referenced or linked to by many entries in table B.
Example: A student can take several books out from the library. The student again would be table A and the book could be the entry in table B. The entry in table B would contain a foreign key to who checked the book out, and many books could reference the same student.