I am trying to add a foreign key constraint to a table in my PostgreSQL 8.4 database, but it is failing as the target field, though part of a multi-column primary key, is not in itself unique.
The database has the following structure:
Table 1 (names of primary IDs):
PrimaryType, Name
[Primary key = "PrimaryType"]
Table 2 (names of child IDs for each type of primary ID):
PrimaryType, SubType, Name
[Primary key = "PrimaryType, SubType"]
[Foreign key = "Table2.PrimaryType = Table1.PrimaryType"]
Table 3 (logs which include a primary and child ID):
PrimaryType, SubType, DATA1, DATA2, ..., DATAN
[Foreign key = "Table3.PrimaryType = Table1.PrimaryType" AND "Table3.SubType = Table2.SubType"]
Obviously, the second part of the foreign key for table 3 is what is causing the problem. I just need to ensure that the primary and subtype ID pair in the log is a valid combination.
Thanks in advance.
For table 3's foreign key, change:
foreign key PrimaryType references Table1(PrimaryType)
foreign key SubType references Table2(Subtype)
to
foreign key (PrimaryType, SubType) references Table2(PrimaryType, SubTYpe)
Related
Is it possible to make a column not primary key, to be foreign key in other table? for example :
-- for master table
create table identity(
id int not null,
name_identity varchar2(100),
primary key(id)
);
--for foreign key
create table class(
class_id int,
name_identity varchar2(100),
primary key(class_id),
foreign key(name_identity) references identity(name_identity)
);
Is it possible to make name_identity as foreign key?
Foreign key doesn't rely on column, it's rely on unique key instead. Primary key is a special case of unique key so it can be used as well.
In your case you should use something like name_identity varchar2(100) unique and you'll can use it in foreign key after that.
I am working on an assignment and we are supposed to:
based on this schema:
Underlined = primary key, both underlined = composite key
My question is for the composite keys, are the two attributes that make up the composite key, as in table Borrower, also considered foreign keys?
Yes, it is possible to have a composite primary key for a table that are also considered foreign keys. If you do something like the following in SQL it would work properly.
CREATE TABLE Borrower
(
customerID VARCHAR2(10),
loan_number VARCHAR2(10),
PRIMARY KEY(customerID, loan_number),
FOREIGN KEY customerID REFERENCES Customer(CustomerID),
FOREIGN KEY loan_number REFERENCES Loan(loan_number)
);
The important thing to keep in mind is that the data type of the keys in the Borrower table have to match exactly the data types of the keys in the Customer and Loan tables respectively.
I have a table in my database that models a m-to-n relation. The primary key of this relation is of course the combined primary keys of the 2 entities involved in this relation.
The relation goes like this: m customers have n orders
create table customer(
cid SERIAL PRIMARY KEY,
...
);
create table order(
oid SERIAL PRIMARY KEY,
...
);
create table has(
oid INTEGER REFERENCES order(oid) ON DELETE CASCADE,
cid INTEGER REFERENCES customer(cid) ON DELETE CASCADE,
FOREIGN KEY (oid,cid) or PRIMARY KEY (oid,cid)
);
I'm a bit confused on what to use here: primary key or foreign key to put them in relation?
thanks in advance for any help.
Jaiel
You should be using PRIMARY KEY for the composite key in table has. The combination of the order and customer IDs in the has table is a primary key in that table, because it allows the identification of a unique single record.
Note that both oid and cid in table has are foreign keys, pointing to the order and customer tables, respectively.
My goal is to have a subtable whose primary key and foreign key both are the same column, and reference to an ID of the main table.
CREATE TABLE main_table(
id integer NOT NULL,
//some fields
)
CREATE TABLE test(
id integer NOT NULL,
name varchar,
CONSTRAINT test_pk PRIMARAY KEY (id),
CONSTRAINT test_fk FOREIGN KEY (fk_id)
REFERENCES main_table (id) MATCH SIMPLE
)
But this will create a table mapping with two columns: id[PK] and test_fk as foreign key column. How can I combine them?
You have misunderstood how the foreign key clause works. You list the names of existing columns in there. And listing the column names will create any new column. Any FK column must have already be defined in the "columns part" of the create table statement.
So your statement wouldn't work at all because the table test does not have a column named fk_id. You need to supply the name of the already defined column id there:
CREATE TABLE test(
id integer NOT NULL,
name varchar,
CONSTRAINT test_pk PRIMARAY KEY (id),
CONSTRAINT test_fk FOREIGN KEY (id) --- <<< this was wrong
REFERENCES main_table (id) MATCH SIMPLE
)
For instance, if I have a students table:
CREATE TABLE student (
student_id NUMBER(8),
student_name VARCHAR2(30),
CONSTRAINT pk_student PRIMARY KEY (student_id)
);
And a subject table:
CREATE TABLE subject (
subject_id NUMBER(8),
subject_name VARCHAR2(30),
CONSTRAINT pk_subject PRIMARY KEY (subject_id)
);
And then I create a third table of student's favorites subjects:
CREATE TABLE fav_sub (
student_id NUMBER(8),
subject_it NUMBER(8),
CONSTRAINT pk_fav_sub PRIMARY KEY (student_id, subject_id),
CONSTRAINT fk_1_fav_sub FOREIGN KEY (student_id) REFERENCES student(student_id),
CONSTRAINT fk_2_fav_sub FOREIGN KEY (subject_id) REFERENCES subject(subject_id)
);
Do I then need to manually create indexes for the foreign keys in the fav_sub table such as:
CREATE INDEX in_1_fav_sub ON fav_sub(student_id);
CREATE INDEX in_2_fav_sub ON fav_sub(subject_id);
Or are the indexes for the foreign keys automatically created by the database, since they're part of the composite key?
Edit: Just to clarify, I'm not asking if an index for a foreign key is automatically created, I'm asking if an index for a foreign key is created WHEN it's part of a composite key, since Oracle automatically indexes primary keys.
The creation of the primary key indexes the combination of [student_id, subject_id]. Adding foreign key constraints to each individual column does not create an index on them, and if you want it (which is probably a good idea), you'd have to manually create it.