I have 2 tables in my database:
CREATE TABLE Apartment
(
StreetName char(50) not null,
Number Integer not null,
Door Integer not null,
Type char(30) not null,
SizeSquareMeter Integer not null,
NID Integer not null FOREIGN KEY REFERENCES Neighborhood(NID)
CONSTRAINT Address PRIMARY KEY (StreetName, Number, Door)
);
CREATE TABLE Resident
(
RID Integer not null PRIMARY KEY,
FirstName varchar(30) not null,
LastName varchar(30) not null,
BirthDate date not null,
Address
);
Now the primary key in apartment is Address and is based on constraint. I want to create a foreign key Address in the Resident table referencing the
primary key Address in the Apartment table.
How can I do that?
Since your primary key in Apartment is made up from three columns, any table wanting to reference Apartment will also need to have ALL three columns to establish a foreign key link.
So you need to change your Resident table to:
CREATE TABLE Resident
(
RID Integer not null PRIMARY KEY,
FirstName varchar(30) not null,
LastName varchar(30) not null,
BirthDate date not null,
StreetName char(50) not null,
Number Integer not null,
Door Integer not null,
);
and then you can add the foreign key constraint:
ALTER TABLE Resident
ADD CONSTRAINT FK_Resident_Apartment
FOREIGN KEY (StreetName, Number, Door) REFERENCES Apartment (StreetName, Number, Door);
The other option would be to add a surrogate column (an artificial, additional column) to Apartment - either as primary key, or (for SQL Server) at least with a unique constraint - so that you could establish the FK link to that surrogate column (using that one, single column - instead of having to replicate three columns of "real" data)
Related
I have this table:
CREATE TABLE cars_info.cars
(
id SERIAL,
owner_id INTEGER,
brand VARCHAR(50) NOT NULL,
model VARCHAR(50) NOT NULL,
color VARCHAR(50) NOT NULL,
register_number VARCHAR(50) NOT NULL,
created DATE NOT NULL,
PRIMARY KEY(id, brand, model, color, register_number, created),
CONSTRAINT fk_owner_id
FOREIGN KEY(owner_id)
REFERENCES persons_info.persons(id)
);
But when I tried create another table like this:
CREATE TABLE cars_info.violations
(
id SERIAL PRIMARY KEY,
car_id INTEGER NOT NULL,
message VARCHAR(100) NOT NULL,
active BOOLEAN NOT NULL,
CONSTRAINT fk_car_id
FOREIGN KEY(car_id)
REFERENCES cars_info.cars(id)
);
I get an error about that
Target external table "cars" does not have a unique constraint corresponding to the given keys
How can I fix that? I'm a beginner in SQL and don't know how to go about googling that
Your primary key definition for cars
PRIMARY KEY(id, brand, model, color, register_number, created)
makes no sense: The id column, being serial, is itself unique and it alone should be the primary key.
Delete your primary key definition and change the id column definition to:
id serial not null primary key
Unrelated, but best practice is to name table in the singular; name your tables car and violation rather than cars and violations
CREATE TABLE TEST( course_number INTEGER NOT NULL,
semester INTEGER NOT NULL,
time INTEGER NOT NULL,
room INTEGER NOT NULL,
day INTEGER NOT NULL,
credit_points INTEGER NOT NULL,
UNIQUE(course_number,semester),
CHECK(course_number>0),
CHECK(credit_points>0),
CHECK(room>0));
CREATE TABLE STUDENT (student_id INTEGER NOT NULL,
student_name text NOT NULL,
faculity text NOT NULL,
credit_points INTEGER NOT NULL,
UNIQUE(student_id),
CHECK(student_id>0),
CHECK(credit_points>=0));
CREATE TABLE STUDENT_REG
(student_id INTEGER NOT NULL,
course_number INTEGER NOT NULL,
semester INTEGER NOT NULL,
FOREIGN KEY (student_id) REFERENCES STUDENT(student_id),
FOREIGN KEY (course_number) REFERENCES TEST(course_number),
FOREIGN KEY (semester) REFERENCES TEST(semester));
I have three tables:
Test
Student
Student registration, it's purpose is to a student to a course.
I get this error when I compile the third table:
ERROR: there is no unique constraint matching given keys for referenced table "test"
I have no idea why, any help will be highly appreciated.
You want a compound foreign key rather than two distinct keys:
CREATE TABLE STUDENT_REG (
student_id INTEGER NOT NULL,
course_number INTEGER NOT NULL,
semester INTEGER NOT NULL,
FOREIGN KEY (student_id) REFERENCES STUDENT(student_id),
FOREIGN KEY (course_number semester) REFERENCES TEST(course_number, semester)
);
Why you need that is because table TEST as has compound unique key on these two columns:
UNIQUE(course_number,semester)
So for table STUDENT_REG to unambigously refer to a row in TEST, you need the combination of both columns, which means a 2-columns foreign key rather than two distinct foreign keys.
I'm new to SQL and there are a lot of things going on that I still don't seem to quite understand. I have the following table
CREATE TABLE Person
(
First_Name varchar(20) NOT NULL,
Name varchar(20) NOT NULL,
Address varchar(50) NOT NULL,
PRIMARY KEY (First_Name, Name, Address)
);
I know want to create another table that has the primary key from the table Person as foreign key and also as primary key:
CREATE TABLE Purchase
(
No_Installments int,
Rate int,
Person varchar(50) NOT NULL PRIMARY KEY,
CONSTRAINT PFK
FOREIGN KEY (Person) REFERENCES Person (First_Name, Name, Address)
);
For some reason this doesn't work and I get an error every time. I've already looked up the other threads here on stackoverflow, but they don't really seem to help me. What am I doing wrong?
If you have a compound PK made up from three columns, then any child table that wants to establish a foreign key relationship must ALSO have all those 3 columns and use all 3 columns to establish the FK relationship.
FK-PK relationship is an all or nothing proposal - you cannot reference only parts of a primary key - either you reference all columns - or you don't reference.
CREATE TABLE Purchase
(
No_Installments int,
Rate int,
Person varchar(50) NOT NULL PRIMARY KEY,
First_Name varchar(20) NOT NULL,
Name varchar(20) NOT NULL,
Address varchar(50) NOT NULL,
CONSTRAINT PFK
FOREIGN KEY (First_Name, Name, Address)
REFERENCES Person (First_Name, Name, Address)
);
Have an integer primary key, using identity, auto_increment, serial or whatever for your database:
CREATE TABLE Person (
PersonId int identity PRIMARY KEY
First_Name varchar(20) NOT NULL,
Name varchar(20) NOT NULL,
Address varchar(50) NOT NULL,
CONSTRAINT unq_person_3 UNIQUE (First_Name, Name, Address)
);
Then use the identity column for the reference:
CREATE TABLE Purchase (
PurchaseId int identity PRIMARY KEY,
No_Installments int,
Rate int,
PersonId int,
CONSTRAINT PFK
FOREIGN KEY (PersonId) REFERENCES Person (PersonId)
);
Notes:
You really don't want to have to deal with a composite primary key. Have you thought about what the joins will look like?
You don't want a primary key where the values are subject to change. What happens when someone changes his/her name? When someone moves?
Person should not be the primary key in Purchases. Are you only allowing someone to make one purchase?
As noted initially, how you generate such a column varies by database; identity happens to be the way that SQL Server does this.
You probably want to assign a unique ID to each person, not relying on their name to be unique or for an address to be required. That ID will be your Primary key and foreign key. Your purchase table should also have its own id for its primary key -- otherwise because primary keys must be unique, each person can only have one purchase.
CREATE TABLE Person (
id serial NOT NULL,
First_Name varchar(20) NOT NULL,
Name varchar(20) NOT NULL,
Address varchar(50) NOT NULL,
PRIMARY KEY (id));
CREATE TABLE Purchase (
id serial NOT NULL,
No_Installments int,
Rate int,
Person int NOT NULL,
FOREIGN KEY (Person) REFERENCES Person (id),
PRIMARY KEY (id));
When I run the booking table, it show the message "No unique index found for the referenced field of the primary table".
Create Table Customer
CREATE TABLE CUSTOMER
(
CUSTID INTEGER NOT NULL,
FNAME CHAR(18) NOT NULL,
LNAME CHAR(18) NOT NULL,
STREET CHAR(6) NOT NULL,
CITY CHAR(18) NOT NULL,
PROVINCE CHAR(8) NOT NULL,
COUNTRY CHAR(8) NOT NULL,
POSTCODE CHAR(6) NOT NULL,
GENDER CHAR(6) NOT NULL,
PRIMARY KEY (CUSTID)
);
Create Table Booking
CREATE TABLE BOOKING
(
BKGNO INTEGER NOT NULL,
CUSTID INTEGER NOT NULL,
FNO INTEGER NOT NULL,
STATUSID CHAR(3) NOT NULL,
CLASSID CHAR(4) NOT NULL,
ORIG CHAR(18) NOT NULL,
DEST CHAR(18),
DEPTTIME DATE NOT NULL,
ARRTIME DATE NOT NULL,
BKGCITY CHAR(18) NOT NULL,
PAIDBY CHAR(18) NOT NULL,
FPRICE CURRENCY NOT NULL,
TOTPRICE CURRENCY NOT NULL,
PAIDAMT CURRENCY NOT NULL,
BAL CURRENCY NOT NULL,
BKGDATE DATE NOT NULL,
PRIMARY KEY (BKGNO),
INDEX (ORIG,DEST,DEPTTIME, ARRTIME),
INDEX (CUSTID),
FOREIGN KEY (CUSTID) REFERENCES CUSTOMER,
FOREIGN KEY (FNO) REFERENCES FLIGHT_AVAILABILITY(FNO),
FOREIGN KEY(DEST) REFERENCES FLIGHT_AVAILABILITY(DEST),
FOREIGN KEY(DEPTTIME) REFERENCES FLIGHT_AVAILABILITY(DEPTTIME),
FOREIGN KEY(ARRTIME) REFERENCES FLIGHT_AVAILABILITY(ARRTIME),
FOREIGN KEY(DEST,DEPTTIME,ARRTIME) REFERENCES FLIGHT_AVAILABILITY(DEST, DEPTTIME, ARRTIME),
FOREIGN KEY (ORIG) REFERENCES AIRPORT(AIRPORTCD)
);
Create Table Flight Availability
CREATE TABLE FLIGHT_AVAILABILITY
(
FNO INTEGER NOT NULL,
ORIG CHAR(18) NOT NULL,
DEST CHAR(18),
DEPTTIME DATE NOT NULL,
ARRTIME DATE NOT NULL,
FLENGTH INTEGER NOT NULL,
PRIMARY KEY (FNO,ORIG,DEST,DEPTTIME,ARRTIME)
);
Create TableAirport
CREATE TABLE AIRPORT
(
AIRPORTCD CHAR(18) NOT NULL,
CITYID CHAR(18) NOT NULL,
AIRPORTNM CHAR(18) NOT NULL,
AIRPORTTAX CURRENCY,
PRIMARY KEY (AIRPORTCD)
);
This part causes errors:
FOREIGN KEY (FNO) REFERENCES FLIGHT_AVAILABILITY(FNO),
FOREIGN KEY(DEST) REFERENCES FLIGHT_AVAILABILITY(DEST),
FOREIGN KEY(DEPTTIME) REFERENCES FLIGHT_AVAILABILITY(DEPTTIME),
FOREIGN KEY(ARRTIME) REFERENCES FLIGHT_AVAILABILITY(ARRTIME),
FOREIGN KEY(DEST,DEPTTIME,ARRTIME) REFERENCES FLIGHT_AVAILABILITY(DEST, DEPTTIME, ARRTIME)
A foreign key constraint (also called a referential integrity
constraint) designates a column as the foreign key and establishes a
relationship between that foreign key and a specified primary or
unique key, called the referenced key. A composite foreign key
designates a combination of columns as the foreign key.
So a referenced key should be either unique or primary key.
For example:
FOREIGN KEY (FNO) REFERENCES FLIGHT_AVAILABILITY(FNO)
Referenced key = FNO which is not unique and is not a primary key. Although FNO is part of the composite PRIMARY KEY (FNO,ORIG,DEST,DEPTTIME,ARRTIME), it's not unique (the combination of all the columns of the primary key is unique).
P.S. you really don't need so many columns in your primary key in FLIGHT_AVAILABILITY table. You may create a composite unique index on those columns (if it's really required) and create a NOT NULL constraint on each column. In this case you'll have the same checks as in your current composit primary key. But I don't think you need this.
This is my first table "address".
create table address(
street varchar(32) not null,
city varchar(32) not null,
state varchar(32) not null,
zip_code varchar(32) not null,
primary key(zip_code)
)
This is my second table "customer".
create table customer(
customer_id integer not null,
name varchar(32) not null,
primary key(customer_id)
)
This is my relational table about above two tables. But why cannot I make it? The type matches well. So please.
create table cus_live(
customer_id integer not null,
zip_code varchar(32) not null,
primary key(customer_id, zip_code),
foreign key(customer_id) references customer,
foreign key(zip_code) references address
)
This is the correct way to create a foreign key constraint:
create table cus_live(
cus_live_id int not null,
customer_id int not null,
address_id int not null,
primary key(cus_live_id),
foreign key(customer_id) references customer (customer_id),
foreign key(address_id) references address (address_id)
)
Notice the changes I made:
After references [tableName], added the key name in parentheses. This will tell SQL which column is referenced in the foreign key constrant.
Changed the primary key of the table to its own unique id rather than a composite of two columns. Usually this is better practice.
Changed primary key of address table to address_id instead of zipcode. Otherwise you would have conflicts if two customers have the same zipcode but different addresses within that zipcode.
Made your id's integers instead of strings.
Also, note that this is all assuming that cus_live has some other columns that you have excluded (and cannot be included on either the address or customer table) and hence warrants having this third table in the first place. Otherwise you could just put address_id on the customer table like this:
create table address(
address_id int not null,
street varchar(32) not null,
city varchar(32) not null,
state varchar(32) not null,
zip_code varchar(32) not null,
primary key(address_id)
)
create table customer(
customer_id int not null,
name varchar(32) not null,
address_id int not null,
primary key(customer_id)
foreign key(address_id) references address (address_id)
)