Is it possible to have a foreign key that references another foreign key in a different table, or can it only reference primary and unique keys?
A foreign key can reference any field defined as unique. If that unique field is itself defined as a foreign key, it makes no difference. A foreign key is just to enforce referential integrity. Making a field a foreign key doesn't change the field itself in any way. If it is a unique field, it can also be the target of another FK.
For example:
create table Table1(
PK int identity primary key,
...
);
create table Table2( -- 1-1 relationship with Table1
PKFK int primary key,
...,
constraint FK_Table2_1 foreign key( PKFK ) references Table1( PK )
);
create table Table3( -- relates to Table2
PKFKFK int primary key,
...,
constraint FK_Table3_2 foreign key( PKFKFK ) references Table2( PKFK )
);
I know of no DBMS where this is not the case. And I agree with Horse, there is nothing wrong with the practice.
Is it possible to have a foreign key that references another foreign key in a different table
Yes. In fact contrary to accepted answer, the referenced FK column doesn't even have to be unique! - at least in MySQL. see https://www.db-fiddle.com/f/6RUEP43vYVkyK2sxQQpBfj/0 for a demo of the same.
which brings up the question that if the FK is not unique in the parent table, then who is the parent row? The purpose of FKs is to establish parent-child relationship.
Related
For this question, I am referring to the specific case where you have table T, it has primary key K, but K is a foreign key. Is this valid? And how would you write it in SQL99?
All the other questions I've seen on here are just asking whether or not a primary key can be a foreign key for another table. That's not what I'm asking about. I'm asking about a table which has a foreign key where that is the primary key of that table.
If I understand you correctly, you want to create a hierarchical table, for instance:
create table hierarchical
(
id number primary key,
parent_id number
);
alter table hierarchical add constraint
fk_parent_id foreign key(parent_id) references hierarchical(id);
This kind of table can contain employees/managers for instance.
A column can be a primary key as well foreign key. For example, refer to the following:
A column can be both a primary key and a foreign key. For example:
create table A
(
id int not null
, constraint PK_A primary key (id)
);
create table B
(
id int not null
,constraint PK_B primary key (id)
,constraint FK_B_ID foreign key (id) references A(id)
);
Though, this requires data to be present in Table B first.
In a junction table made up of only foreign keys (e.g. ShopSupplier in the example below), must we also declare those columns as primary keys in the DDL create statement? If yes, what would be the point of doing so? I would argue that these are NOT primary keys in the example below
CREATE TABLE Shop
(
ShopID TEXT PRIMARY KEY UNIQUE,
ShopName TEXT
);
CREATE TABLE Supplier
(
SupplierID TEXT PRIMARY KEY UNIQUE,
SupplierName TEXT
);
CREATE TABLE ShopSupplier
(
ShopID TEXT,
SupplierID TEXT,
FOREIGN KEY(ShopID) REFERENCES Shop(ShopID),
FOREIGN KEY(SupplierID) REFERENCES Supplier(SupplierID)
);
The question again: Should I also declare PRIMARY KEY(ShopID, SupplierID) for the ShopSupplier table. If so, why? I would argue that there should be no primary key for that table.
Both columns are foreign key, because they are referencing to other tables. In the case that only single connection between specific rows of Shopand Supplier may exit, you can use a unique constraint or create a combined primary key:
CREATE TABLE ShopSupplier(
ShopID TEXT,
SupplierID TEXT,
PRIMARY KEY(ShopID, SupplierID),
FOREIGN KEY(ShopID) REFERENCES Shop(ShopID),
FOREIGN KEY(SupplierID) REFERENCES Supplier(SupplierID));
Then, both columns are foreign keys and belonging to the primary key.
In general setting the columns of a (pure) junction table as primary key isn't necessary. You may use it as a constraint to prohibit duplicates.
I have 4 tables:
ConditionalOffer (PK ID, Description,...)
UnconditionalOffer (PK ID, Description,...)
Offer (PK ID,
Offer FOREIGN KEY REFERENCES ConditionalOffer.ID,
Offer FOREIGN KEY REFERENCES UnconditionalOffer.ID)
Applicant (ID, Offer FOREIGN KEY REFERENCES Offer.ID,...)
I know that my codes were wrong at table Offer because of a column be cannot referencing multiple tables. How can I fix this?
A column can be part of more than one foreign key constraint, but your syntax isn't correct as you specify the source column twice.
Instead either use inlined constraints like this:
create table Offer (
ID int primary key,
Offer int
FOREIGN KEY (offer) REFERENCES ConditionalOffer (ID),
FOREIGN KEY (offer) REFERENCES UnconditionalOffer (ID)
);
Or use explicitly named constraints (which might be cleaner):
create table Offer (
ID int primary key,
Offer int,
constraint fk_cond FOREIGN KEY (offer) REFERENCES ConditionalOffer (ID),
constraint fk_uncond FOREIGN KEY (offer) REFERENCES UnconditionalOffer (ID)
);
While this is possible, it does however raise questions about the database design: are the IDs in ConditionalOffer and UnconditionalOffer really the same? How are they kept in sync? Shouldn't those tables be one entity if they share primary key (with the differences refactored to other tables)?
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)
can we define a primary key in a table as a foreign key in that table . I mean,
PRIMARY KEY(ssn),
FOREIGN KEY (ssn) REFERENCES Cust(cust_ssn)
And If we have a table that has some parameters that refers to some other table parameters and to some other 3rd table too. Then Do we need to define those parameters as foreign key referencing to both the tables or Just only one.
Yes. Any field or combination of fields can be a foreign key.