How can you use a unary relationship on a specialized entity? - sql

I'm trying to create a table for the technician entity in the erd below (with mssql), is it posisble to use unary relationship in a specialized entity?
This is my code but it gives this error : Number of referencing columns in foreign key differs from number of referenced columns, table Technician.
create table Technician
(
Tec_ID int Foreign key references Employee (id_employee),
Primary key (Tec_ID),
Foreign key references Technician (Tec_ID)
);
id_employee is the primary key of the employee entity of course. I wanted it to form a unary relationship.

Sure, you just need a foreign key column:
create table Technician
(
Tec_ID int primary key references Employee(id_employee),
Supervisor_ID int null references Technician(Tec_ID)
);
Assuming only Technicians supervise Technicians because you said you wanted a "unary" relationship. Otherwise the foreign key would reference Employee(id_employee).

Related

Not matched, checked lots of times

Googled quite a lot for the errors but I just can't seems to find the solution.
These are my codes
create table valuation (
propertyNum VARCHAR2(255),
dateInspected DATE,
rent VARCHAR2(255),
deposit VARCHAR2(255),
PRIMARY KEY (propertyNum, dateInspected),
FOREIGN KEY (propertyNum) REFERENCES property,
FOREIGN KEY (dateInspected) REFERENCES inspection
);
create table inspection (
propertyNum VARCHAR2(255),
dateInspected DATE,
staffNum VARCHAR2(255),
comments CHAR(255),
PRIMARY KEY (propertyNum, dateInspected),
FOREIGN KEY (propertyNum) REFERENCES property,
FOREIGN KEY (staffNum) REFERENCES staff
);
The error seems to be at this part:
FOREIGN KEY (dateInspected) REFERENCES inspection);
because I've tried removing this part and it works fine.
Error Message:
ORA-02256: number of referencing columns must match referenced columns
This does not work, because the foreign key, which you are trying to define from the "valuation" table is based on just one column ("dateInspected"), while the primary key of the parent/master table ("inspection") does not have a one-column primary (or unique) key. It has a two-column one (on "propertyNum" and "dateInspected" columns)
The requirement for creating a foreign key is for the master/parent table having a matching primary key or a matching unique constraint.
What you might have wanted is this:
FOREIGN KEY (propertyNum, dateInspected) REFERENCES inspection
As Hilarion points out, the error you're receiving is due to multipart Primary key and single part foreign keys. But try some additional changes that will make the references easier and clean up your relation model.
Add an Identity column to both Valuation and Inspection and try these schema changes.
valuation (
id,
propertyNum,
inspectionId,
rent,
deposit,
PRIMARY KEY (id),
FOREIGN KEY (propertyNum) REFERENCES property,
FOREIGN KEY (inspectionId) REFERENCES inspection )
inspection (
id,
propertyNum,
dateInspected,
staffNum,
comments,
PRIMARY KEY (id),
FOREIGN KEY (propertyNum) REFERENCES property,
FOREIGN KEY (staffNum) REFERENCES staff )
You'll need to plug in your datatypes (I recommend using a numeric field for your rent and deposit instead of varchar)
Also replace the dateInspected field on the property table with lastDateInspected.
I would do this because logically a property could be inspected and valuated more than once. Also, it will clean up your relationships. You'll be able to pull a history of inspections and valuations without changing other property data.
Notice, that your valuations can be linked to an inspection, but an inspection doesn't care at all about a valuation, it doesn't and shouldn't need to.

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.

Can a foreign key reference another foreign key

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.

what is FOREIGN KEY is for?

let's say i have 2 tables:
Department(depNum)
Worker(id,deptNum) - key should be id
now i want dept to reference an existing value in Department.
so i write in create table:
CREATE TABLE Worker(
id integer primary key,
dept integer references Department);
my question is, i've seen in many examples that you also put foreign key with the references statement. i don't understand what is primary key for.
does it mean that dept will be also a key on Worker?
thank you
From Wikipedia:
A primary key is a combination of columns which uniquely specify a
row. It is a special case of unique keys. . . . Primary keys were
added to the SQL standard mainly as a convenience to the application
programmer.
You cannot reference a record in a table without a primary key. A foreign key lets you reference a record in another table within an individual record. This foreign key is usually referencing the primary key in the foreign table.
This post has a lot of great information. In particular, check out the highest ranked answer for a bullet list of do's and do not's.
What's wrong with foreign keys?
This post gives a pretty decent explanation, given the poster's
original example:
What will these foreign keys do?
Let's say that each worker can only work in one department at any one time.
So each department has its own unique ID. This is the department's primary key because two departments should never have the same id.
Now, each individual worker must be tracked so they are also assigned their own unique ID. This is their primary key. You need to link the worker to the department that they work in and since they can only work in one department at a time, you can have their department as a foreign key. The foreign key in the worker table is linked to the ID of the department table.
This has more information: http://www.1keydata.com/sql/sql-foreign-key.html
You have two tables:
PLAYER,
primary key (unique) PK_player_id
player_name
foreignt key to TEAM.team_id FK_team_id
TEAM
primary key (unique) PK_team_id
team_name
Every PLAYER is in exact one TEAM.
The PLAYER has a FOREIGN-KEY to the TEAM (FK_team_id). Also you can delete the TEAM, which will delete all player in it cascading (if configured).
Now you can't create a player without an existing TEAM, because the database ensures this.
EDIT:
Didn't you ask for the foreign key?
The primary key is one or more than one column, which will identify on datarow within your database. If jou want to create a foreign key, you have to use a column or more than one column) which is unique.
In my example, there is a unique key (the primary key) for every table, because the name may change. To identify the 'target' of the foreign key, it has to be unique. so it is liklye to use the prmary key of the second table. (TEAM.PK_team_id)
I am not clear, the requirement should be
Department(dept)
Worker(id,dept) - key should be id
which means dept is the primary key in Department and foreign key in worker.
the foreign key is not unique in worker table but it is unique in Department Table.
The worker table cannot have some unknown department which is not defined in the Department.
Did I make sense ?
To ensure the integrity of the tables, not allowing you to enter values in the table (Worker) without referencing an existing row (at Department)
According to the SQL-92 Standard:
A foreign key (FK) may reference either a PRIMARY KEY or a UNIQUE CONSTRAINT. In the case of a PRIMARY KEY, the referenced columns may be omitted from the foreign key declaration e.g. the following three are all valid:
CREATE TABLE Department ( Department INTEGER NOT NULL PRIMARY KEY, ...);
CREATE TABLE Worker (dept INTEGER REFERENCES Department, ...);
CREATE TABLE Department ( Department INTEGER NOT NULL PRIMARY KEY, ...);
CREATE TABLE Worker (dept INTEGER REFERENCES Department (dept), ...);
CREATE TABLE Department ( Department INTEGER NOT NULL UNIQUE, ...);
CREATE TABLE Worker (dept INTEGER REFERENCES Department (dept), ...);
The following is not valid:
CREATE TABLE Department ( Department INTEGER NOT NULL UNIQUE, ...);
CREATE TABLE Worker (dept INTEGER REFERENCES Department, ...);
...because the referenced columns involved in the foreign key must be declared.
When declaring a simple (single-column) FK in-line the FOREIGN KEY keywords are omitted as above.
A composite (multiple-column) cannot be declared in-line and a simple FK need not be declared in-line: in these cases, the referencing column(s) AND the FOREIGN KEY keywords are required (the rules for the referenced columns remain the same as stated earlier) e.g. here are just a few examples:
CREATE TABLE Department ( Department INTEGER NOT NULL PRIMARY KEY, ...);
CREATE TABLE Worker (dept INTEGER, FOREIGN KEY (dept) REFERENCES Department, ...);
CREATE TABLE Department ( Department INTEGER NOT NULL UNIQUE, ...);
CREATE TABLE Worker (dept INTEGER, FOREIGN KEY (dept) REFERENCES Department (dept), ...);
CREATE TABLE DepartmentHistory
(
dept INTEGER NOT NULL,
dt DATE NOT NULL,
PRIMARY KEY (dt, dept),
...
);
CREATE TABLE Worker
(
dept INTEGER NOT NULL,
dept_dt DATE NOT NULL,
FOREIGN KEY (dept_dt, dept) REFERENCES DepartmentHistory,
...
);

How Can I Reference Multiple Primary Keys For A Vector Type Primary Key

I have the following scenario: a table of projects and a table of persons, working on one or several projects. Also, I have a project id column (of type int), in the first table, which is a primary key there and I have a vector of project ids, as a column of type int, in my second table (persons), that references primary keys from the first table.
What is the correct syntax for referencing multiple primary keys, from a vector foreign key.
This is the way I am trying to create the table, but I am not sure what to place at the indicated line:
CREATE TABLE Persons(
Person_Id int,
...,
ProjectsList int[],
FOREIGN KEY (ProjectsList) REFERENCES Projects(Project_id) -- not sure what how to define the link here
);
I hope my explanations are not over-complicated. Thank you in advance for helping!
I assume you're using PostgreSQL, since that's one of the rare databases that supports array data types.
There is no syntax for declaring a foreign key that applies to the elements of an array.
You could write a trigger or a CHECK constraint as mentioned here.
But the better solution is to add a table to implement the many-to-many relationship between Projects and Persons, as Lukáš Lalinský shows. This supports First Normal Form.
No database I know can do that (using real foreign keys, not some custom triggers). You might want to normalize the tables:
CREATE TABLE Persons (
Person_ID int,
...
PRIMARY KEY (Person_ID)
);
CREATE TABLE PersonProjects (
Person_ID int,
Project_ID int,
PRIMARY KEY (Person_ID, Project_id),
FOREIGN KEY (Person_ID) REFERENCES Persons(Person_ID),
FOREIGN KEY (Project_ID) REFERENCES Projects(Project_ID)
);