I'm a bit confused over when I should use a primary or foreign key. I have two tables, and in both of them, some of the columns reference columns that are primary keys in other tables.
Here they are:
CREATE TABLE roles (
movie_id NUMBER(10,0) NOT NULL REFERENCES movies(movie_id),
actor_id NUMBER(10,0) NOT NULL REFERENCES actors(actor_id),
movie_description VARCHAR2(50),
salary NUMBER(10),
CONSTRAINT pk_roles PRIMARY KEY (movie_id, actor_id)
);
CREATE TABLE profits (
movie_id NUMBER(10,0) NOT NULL,
gross_profit NUMBER(9) NOT NULL,
net_profit NUMBER(9) NOT NULL,
CONSTRAINT fk_profits FOREIGN KEY (movie_id) REFERENCES movies(movie_id) ON DELETE CASCADE
);
In the first table I have made a composite primary key from teh two columns that reference columns in other tables. Those columns happen to be primary keys in their respective tables.
In the second table, I've made a foreign key again referencing a primary key in anther table. But what is best practice? Should the key in the first table also be a foreign key since it references primary keys in other tables?
Primary key constraints and unique constraints prevent duplicate rows. Duplicate rows not only waste space, they make it harder to get meaningful answers from your database.
Foreign key constraints restrict values to those that exist in another table. The target of a foreign key constraint is commonly a primary key, but it could be any column(s) that have a unique constraint.
Every table should have a primary key constraint. If the column(s) that make up the primary key also require a foreign key constraint, add the foreign key constraint as well.
Your table "roles" is fine, as far as implementing primary key constraints and foreign key constraints. But "profits" needs a primary key.
To your Question "Should the key in the first table also be a foreign key since it references primary keys in other tables?"
There is no simple answer, as it heavily depends on type of planned usage of data and database being used. If you need a simple answer, yes it is a good idea. Below is the longer version.
Pros :
It helps keep your data clean.
Based on how database is planned to be used and which database you are using, some databases, tend to optimize joins better, if Foreign keys are defined for joins upfront.
Cons :
If you plan to bulk load into your tables frequently, then FK constraints tend to slow down your loads, if that is the case, some databases allow you to define soft constraints, which are only used for query optimization purposes, but are not verified during loads.
Related
I'm creating a couple of Tables for an assignment.
So I created a Gardener Table and an Offering Table, with all the appropriate data types and NULL statuses, as well as the Primary Key constraint for each. In the Gardener table I've included offeringID, and vice versa.
When I try to add Foreign Key constraint offeringID to the Gardener Table I get an error.
After checking online, I realized I had forgotten to make offeringID and gardenerID in each other's tables UNIQUE, hence I altered table to add uniqueness.
Tried adding Foreign Key constraint and I get the same error. I reckon I may be understanding something wrongly, but I can't seem to put my finger on it.
Create Table Gardener
(gardenerID NUMBER(10) NOT NULL,
offeringID NUMBER(10) NOT NULL,
CONSTRAINT gardener_pk PRIMARY KEY(gardenerID)
);
Create Table Offering
(offeringID NUMBER(10) NOT NULL,
gardenerID NUMBER(10) NOT NULL,
CONSTRAINT offering_pk PRIMARY KEY(offeringID)
);
Alter Table Gardener
add CONSTRAINT offering_fk FOREIGN KEY(offeringID)
REFERENCES Offering(offeringID);
Alter Table Gardener
add Unique(offeringID);
Alter Table Offering
add Unique(gardenerID);
This is the error:
ORA-02270: no matching unique or primary key for this column-list
02270. 00000 - "no matching unique or primary key for this column-list"
Cause: A REFERENCES clause in a CREATE/ALTER TABLE statement gives a column-list
for which there is no matching unique or primary key constraint in the referenced table.
Like, I still don't get it. Isn't offeringID a Primary Key hence pointing to it from Gardener shouldn't be an issue still?
Since you're trying to add a a foreign key constraint for offering.offeringID column within the Gardener table, whereas that column has no unique/primary key key when you try to add a foreign key. i.e. operation stops at the 3rd command.
So, just exchange the order of commands as :
Alter Table Gardener
add Unique(offeringID); -- should be prior to the below command
Alter Table Gardener
add CONSTRAINT offering_fk FOREIGN KEY(offeringID)
REFERENCES Offering(offeringID);
Demo
I have two tables with a one-to-one relationship (and relationship is mandatory from one side only). As follows:
create table PRS (
id number(18) not null,
common_code varchar2(10),
constraint pk_prs primary key (id));
create table RLP {
id number(18),
spec_code varchar2(20),
constraint pk_rlp primary key (id),
constraint fk_rlp_prs foreign key (id) references prs(id) on delete cascade);
So the problem is when inserting a record in RLP at least one of common_code or spec_code must have value.
Is it possible to enforce this constraint using a constraint or the only solution is having a trigger?
It seems there is no way to create a constraint on two tables, and the only solution is to create a trigger to throw an exception on desired situation.
I'm a bit confused about this. Must a foreign key always reference a primaryy key? What if there's two foreign key on the same table that refer to the same primary key?
Thanks
"What if there's two foreign key on the same table that refer to the same primary key?
"
Any number of child tables can reference a parent table. There are certain situations in which it is possible for a child table to have more than one foreign key on the same parent.
For instance, any form of sporting contest has opponents of the same type - player, team, etc. So a match will have two instances of that entity, hance the child table will have two columns with foreign keys referencing the same primary key.
create table player (
player_id number not null primary key
, name varchar2(30) not null unique
);
create table match (
match_id number not null primary key
, player_1 number not null
, player_2 number not null
, match_played date not null
, result varchar2(10)
, constraint match_player1_fk foreign key (player_1) references player
, constraint match_player2_fk foreign key (player_2) references player
);
A foreign key can reference a unique constraint rather than a primary key. However this is not standard practice. It is the convention to use unique keys to enforce candidate keys - business keys - and these are not always suitable for use as foreign keys.
For instance in my example, PLAYER.NAME is a unique key: every player must have a distinct name. However, it would not be appropriate to use NAME as the foreign key on MATCH because people can change their name. It is more convenient to use the synthetic primary key, PLAYER_ID because that will not change over the lifetime of the PLAYER record.
A set of columns comprising a foreign key in one table must refer to an equivalent set of columns in a table with either a Primary Key or Unique Key constraint.
You certainly can have 2 or more FKs in the same table that refer to the same PK or UK. This models a relationship where a child record is related to more than one parent record - e.g. a record representing a biological child might have a FK to the record for their father as well as for their mother.
Note that a unique index is not sufficient for this purpose; a unique constraint is required, otherwise you will get "ORA-02270: no matching unique or primary key for this column-list".
table1:
tid(primary key) // no foreign keys here
table2:
sid(primary key) // no foreign keys here too
table3:
Tid
Sid
iid(primary key)
foreign key(Tid,Sid) references table1(tid).table2(sid)
In table3 i want to make a composite foreign key or composite foreign key constraint but failed . there are many questions related to this .But none of them seems helpful to me . How can i do that ? Is it valid ? Then what is the syntax of making composite foreign key from two different tables primary key
It's not possible to have a single foreign key referencing fields on different tables, and it makes no sense at all. A foreign key of two or more fields implies that the combination of values of the fields must be match on a single record of the referenced table, and this can't be done if the referenced fields are on different tables.
What you can do is to create two distinct foreing keys to the two tables, as following:
CREATE TABLE table3(
iid NUMBER,
Tid NUMBER,
Sid NUMBER,
CONSTRAINT pk PRIMARY KEY (iid) USING INDEX TABLESPACE idx,
CONSTRAINT fk001 FOREIGN KEY (tid) REFERENCES table1(tid),
CONSTRAINT fk002 FOREIGN KEY (sid) REFERENCES table2(sid)
);
Not able to create /find the logic to apply FK on a column in child table referencing a column from composite PK of parent table.
create table product(prod_id number,
prod_name varchar2(20),
price number,
constraint PK12 primary key(prod_id,prod_name));
Table created.
create table purchase(prod_id number,
purchase_price number,
constraint FK12 foreign key(prod_id) references product(prod_id));
create table purchase(prod_id number,
purchase_price number,
constraint FK12 foreign key(prod_id) references product(prod_id))
ERROR at line 1:
ORA-02270: no matching unique or primary key for this column-list
Kinldy suggest how i can incorporate this logic.
Thanks.
You can't.
As the error says there's no matching primary key for that column list; you must have one. You have three options:
Remove PROD_NAME from the primary key of PRODUCT. On the face of it this seems like the logical solution, if this is not required in order to make the primary key unique.
Add PROD_NAME to the PURCHASE table.
Create a unique index on PURCHASE.PROD_ID. This seems excessive if it would be a primary key candidate anyway.
I suspect that this is not unique to Oracle. Considering you have a composite primary key in the referenced table, that implies that only one of the columns comprising the composite key is not enough to uniquely identify the record in that table. Therefore, it's impossible to reference only a single column of the primary key in a foreign key relationship that's one-to-many (e.g. one record in the referenced table can have many records in the referencing table--the one with the FK). However, if the relationship to be established is many-to-many, this may be possible.
HTH.