How do I create a Foreign Key? - sql

I am working on my assignment. It has 8 tables. Each table has a primary key. What do i do to generate a foreign key to a table?
My reason for asking is that when I generate a primary key, a key symbol appears on the left.
What do i do to make something a foreign key?

Here's the MySQL docs for the subject -- you might wanna take a look at it. Basically, here's an example of what you do:
CREATE TABLE `table_1` (
`id` INT(11) NOT NULL AUTO_INCREMENT,
`name` VARCHAR(32) NOT NULL,
PRIMARY KEY (`id`)
)
CREATE TABLE `table_2` (
`id` INT(11) NOT NULL AUTO_INCREMENT,
`name` VARCHAR(32) NOT NULL,
`table1_id` INT(11) NOT NULL REFERENCES table_1(`id`)
)
This should basically make table_2.table1_id reference table_1.id as a foreign key.

The SQL to add a foreign key between table1 (the referencing table) and table2 (the primary table) is:
ALTER TABLE table1
ADD CONSTRAINT FOREIGN KEY table1_table2_FK
REFERENCES table2 (intId) ON (intTable2Id)

Your confusion is arising from the fact that you think a foreign key is a modified version of a primary key. It is not, it is a separate item.
For instance, CustomerID in the Customers table would have a primary key, but CustomerID in the Orders table would be a foreign key referencing (pointing back to) the primary key in the Customers table.
In the Customers table, the primary key serves to uniquely identify each customer. In the Orders table the foreign key on CustomerID serves to guarantee that each order belongs to an existing record from the customer table.
You can have the primary key without establishing any foreign keys, it will still serve it's role in identifying records. But you cannot have a foreign key without a primary key in a different table (or, in rare occurrences, in the same table) because the primary key name is part of the definition of the foreign key. And you can have as many foreign keys as you want in different tables (in rare cases in the same tables) pointing back to a single primary key.

Related

Why is my create table failing? - does not match primary key

This is what I am trying to create:
CREATE TABLE VEHICLEREPORT
(
DeptID char(2) not null,
Vin# char(3) not null,
Miles varchar(6) not null,
Bill# char(3) not null,
EID char(3) not null,
PRIMARY KEY (DeptID, Vin#),
FOREIGN KEY (bill#) REFERENCES billing,
FOREIGN KEY (EID) REFERENCES Employee
);
The issue is with my reference to billing. The error says:
The number of columns in the referencing column list for foreign key 'FK__VEHICLERE__Bill#__5AEE82B9' does not match those of the primary key in the referenced table 'Billing'.
but my billing table entered fine:
CREATE TABLE BILLING
(
VIN# char(3),
BILL# char(3),
PRIMARY KEY (VIN#, Bill#),
FOREIGN KEY (VIN#) REFERENCES vehicle
);
What am i missing with this?
Appreciate the help.
If you think of the foreign key as establishing a parent-child relationship between two tables, then the parent side column(s) need to be unique.
From Wikipedia:
In the context of relational databases, a foreign key is a field (or collection of fields) in one table that uniquely identifies a row of another table or the same table. ... In simpler words, the foreign key is defined in a second table, but it refers to the primary key or a unique key in the first table.
In your example, there is no guarantee that VIN# is unique in VEHICLEREPORT. Below are your options
VIN# is guaranteed to be unique in VEHICLEREPORT. In this case add a UNIQUE constraint on VIN# on the VEHICLEREPORT table. The error will go away.
VIN# is not unique in VEHICLEREPORT (doesn't seem likely). If this is the case, then likely there is a flaw in the design of your BILLING table as it could likely point to more than one row in VEHICLEREPORT. You should consider adding DeptID column to BILLING and creating a composite foreign key.
Also if VIN# is unique (case 1 above), you should think of why DeptID is present in the PK. Maybe the right fix at the end is to drop DeptID from the primary key.

Composite key for a one-to-many relationship?

For a store I have many store_offers which is a one-to-many relationship.
However, for a table
create table store (
id bigserial primary key
);
I can use a single primary key id (SQLfiddle):
create table store_offer (
id bigserial primary key,
store_id bigint not null,
constraint fk__store_offer__store
foreign key (store_id)
references store(id)
);
or a composite primary key (id, store_id) (SQLFiddle):
create table store_offer (
id bigserial not null,
store_id bigint not null,
constraint fk__store_offer__store
foreign key (store_id)
references store(id),
primary key(id, store_id)
);
My question is "what does make more sense here?". Imho the composite key should be the correct way to do it since a store_offer is actually "bound" to as store. But one can argue that this is already the case since the first version has a foreign key. On the other hand a store_offer primary key actually must not change once it's created. You have to create a new store_offer and delete the old one if you want discard one. But you cannot simply change store_id in the second approach.
So what is the correct answer here?
Using primary key(id, store_id) is a bad idea. This will make many queries more complicated and more prone to error. It sounds like what you are really trying to make is a many-to-many relationship between stores and offers. If this is the case you should have a store table with unique store_id as a primary key, an offer table with unique offer_id as a primary key and a store_offer table that has a primary key of store_id and offer_id.

How to use two columns in a foreign key constraint

I have two tables:
Article
Subscription
In the Article table I have two columns that make up the primary key: id, sl. In the Subscription table I have a foreign key 'idsl`.
I use this constraint :
constraint FK_idsl
foreign key (idsl) references CSS_SubscriptionGroup(id, sl)
But when I run the query, I getting this error:
Number of referencing columns in foreign key differs from number of referenced columns, table X
In Article Table I have two fields that are the primary key: id,sl. In the Subscription Table I have a foreign key 'idsl`
This design is broken - it is apparent that the composite primary key in Article(id, sl) has been mangled into a single compound foreign key in table Subscription. This isn't a good idea.
Instead, you will need to change the design of table Subscription to include separate columns for both id and sl, of the same type as the Article Table, and then create a composite foreign key consisting of both columns, referencing Article in the same order as the primary key, e.g:
CREATE TABLE Article
(
id INT NOT NULL,
sl VARCHAR(50) NOT NULL,
-- Other Columns
CONSTRAINT PK_Article PRIMARY KEY(id, sl) -- composite primary key
);
CREATE TABLE Subscription
(
-- Other columns
id INT NOT NULL, -- Same type as Article.id
sl VARCHAR(50) NOT NULL, -- Same type as Article.sl
CONSTRAINT FK_Subscription_Article FOREIGN KEY(id, sl)
REFERENCES Article(id, sl) -- Same order as Article PK
);
Edit
One thing to consider here is that by convention a column named table.id or table.tableid should be unique, and is the primary key for the table. However, since table Article requires an additional column sl in the primary key, it implies that id isn't unique.
correct syntax for relation:
CONSTRAINT FK_OtherTable_ParentTable
FOREIGN KEY(OrderId, CompanyId) REFERENCES dbo.ParentTable(OrderId, CompanyId)
You must try like this:
constraint FK_idsl foreign key (id,sl) references CSS_SubscriptionGroup(id,sl)

creating table having foreign key that reference another table

I am using PGAdminIII database.
I have one table named STOCKREGISTER which contains composite primary key consisting of three fields ie stockregisterId,applicationId and date.
I have to create another table STOCK which has a foreignkey field that reference the field stockregisterId of STOCKREGISTER.If I am trying to create STOCK table,an error message is shown.The error message is "there is no unique contraint matching keys for referenced table STOCKREGISTER".What another step I have to take next
this first table
CREATE TABLE stock_register
(
stock_register_id bigint NOT NULL,
application_id bigserial NOT NULL,
production_date date NOT NULL,
opening_bal bigint DEFAULT 0,
quantity_produced bigint,
total_quantity bigint
CONSTRAINT primarykey PRIMARY KEY (stock_register_id, application_id, production_date),
CONSTRAINT "foreignKey" FOREIGN KEY (application_id)
REFERENCES application (application_id) MATCH SIMPLE
ON UPDATE NO ACTION ON DELETE NO ACTION
)
below is second table.Here I cannot make stock_register_id as a foreign key
CREATE TABLE Stock
(
stock_id bigint NOT NULL,
stock_register_id bigint,
dimension bigserial NOT NULL,
CONSTRAINT "stockid" PRIMARY KEY (stock_id)
)
I guess that syntax should be:
CREATE TABLE Stock
(
stock_id bigint NOT NULL,
stock_register_id bigint,
dimension bigserial NOT NULL,
CONSTRAINT "stockid"
FOREIGN KEY (stock_id)
REFERENCES stock_register (stock_register_id)
)
CREATE TABLE Stock
(
stock_id bigint NOT NULL,
stock_register_id bigint,
dimension bigserial NOT NULL,
CONSTRAINT primaryKey PRIMARY KEY (stock_id),
CONSTRAINT foreignKey FOREIGN KEY(stock_register_id)
REFERENCES stock_register (stock_register_id)
)
That should be everything you need. You'll also have to make sure the DB table engines, collations and charsets match up when using Foreign Keys.
For the unique constraint issue, there doesn't seem to be a problem with your stock_register_id PK in the stock_register table. Based on the name STOCKREGISTER in the error message I suspect it wasn't finding the table stock_register in your second Create statement.
What is a foreign key? A pointer to a specific record in another table.
How is a specific record in stock_register identified according to your DDL? By the unique combination of (stock_register_id, application_id, production_date).
Therefore stock_register_id = 1 could appear on a thousand different records so long as application_id and production_date are different.
Therefore, if all you have is a stock_register_id, there is no way to know which stock_register record it is pointing to and therefore no way for the DBMS to enforce the foreign key.
You must either add application_id and production_date to the stock table and make all three columns together the FK to the composite key on stock_register, or you must remove application_id and production_date from the PK on stock_register so the FK and PK columns match.

SQL Table Foreign Key that is part of a Composite Primary Key

Is it possible to have a table's foreign key be part of another table's composite primary key?
For example, if I have two tables, one contains information on all active projects of different users and another containing information on what equipment is being used by the projects:
Project Table:
Composite Primary Keys: UserId, ProjectId (neither are unique by themselves)
Equipment Table:
Composite Primary Keys: UserId, ProjectId, EquipmentId (neither are unique by themselves)
Now is it possible to set the ProjectId in the equipment table to be a foreign key from the project table? When I try, I get an error saying that the column in Project Table do not match an existing primary key or unique constraint?
No.
When you create a foreign key, the key that you "point to" in the other table must be a UNIQUE or PRIMARY KEY constraint. You cannot establish a foreign key that points to a column that allow duplicate values. It would be very hard to imagine how the data should "act" if you update one of the duplicate values in the other table (for instance).
To do what you want you must establish a Projects table in which ProjectID is UNIQUE or a PRIMARY KEY and then point foreign keys in both the other tables to that table.
Parenthetically, you use the term "Primary Keys" to describe the columns in each table that make up the primary key. In fact, each table can have one and only one primary key. That key can be composed of one or more columns, but the key itself is still referred to in the singular. This is an important difference when using the primary key to optimize searches.
It do not know if that's a good design practice but for sure it is possible to have a composite foreign key of one table that is the part of the composite primary key of other table.
Say we have a table test1 having a composite primary key (A, B)
Now we can have a table say test2 having primary key (P, Q, R) where in (P,Q) of test2 referencing (A,B) of test2.
I ran the following script in the MySql database and it works just fine.
CREATE TABLE `test1` (
`A` INT NOT NULL,
`B` VARCHAR(2) NOT NULL,
`C` DATETIME NULL,
`D` VARCHAR(45) NULL,
PRIMARY KEY (`A`, `B`));
CREATE TABLE `test2` (
`P` INT NOT NULL,
`Q` VARCHAR(2) NOT NULL,
`R` INT NOT NULL,
`S` DATETIME NULL,
`T` VARCHAR(8) NULL,
PRIMARY KEY (`P`, `Q`, `R`),
INDEX `PQ_idx` (`P`,`Q` ASC),
CONSTRAINT `PQ`
FOREIGN KEY (`P`, `Q`)
REFERENCES `test1` (`A`,`B`)
ON DELETE CASCADE
ON UPDATE CASCADE);
In the above mentioned case, the database is expecting the combination of (A,B) to be unique and it is, being a primary key in test1 table.
But if you try to do something like following, the script would fail. The database would not let you create the test2 table.
CREATE TABLE `test2` (
`P` INT NOT NULL,
`Q` VARCHAR(2) NULL,
`R` DATETIME NULL,
`S` VARCHAR(8) NULL,
`T` VARCHAR(45) NULL,
INDEX `P_idx` (`P` ASC),
INDEX `Q_idx` (`Q` ASC),
CONSTRAINT `P`
FOREIGN KEY (`P`)
REFERENCES `test1` (`A`)
ON DELETE CASCADE
ON UPDATE CASCADE,
CONSTRAINT `Q`
FOREIGN KEY (`Q`)
REFERENCES `test1` (`B`)
ON DELETE CASCADE
ON UPDATE CASCADE);
In the above mentioned case database would expect the column A to be unique individually and the same follows for column B. It does not matter if combination of (A,B) is unique.
#Larry Lustig
The foreign key can be part of primary key in the other table.
source: Dependent relationship
Check relationship between tables: Zdarzenie(Event) and TypZdarzenia (type of event)