Self Referencing table : UNIQUE constraint failed (SQL) - sql

Architecture
I have the following self referencing table. Every Entity has a relation with 1 to many entities.
Tables
Since it's a 1 to many relationship I representation Relation by a table.
CREATE TABLE ENTITY (ID TEXT PRIMARY KEY NOT NULL, VALUE TEXT);
CREATE TABLE RELATION (ID_SOURCE TEXT NOT NULL, ID_DESTINATION TEXT NOT NULL, PREDICAT TEXT, PRIMARY KEY(ID_SOURCE, ID_DESTINATION), FOREIGN KEY(ID_SOURCE) REFERENCES ENTITE(ID), FOREIGN KEY(ID_DESTINATION) REFERENCES ENTITE(ID));
Problem
When I am inserting the values I am getting the following error:
UNIQUE constraint failed: RELATION_ENTITY.ID,
RELATION_ENTITY.ID_DESTINATION
I know why I am getting this error. I am inserting the same Ids in the table Relation But the value is different. THE entity m.06y3r references the entity m.02jvmvm with two different values. How can I fix this design error?
ID_SOURCE ID_DESTINATION VALUE
m.06y3r m.02jvmvm adopted_child.adoptive
m.06y3r m.02jvmvm people.person.parents

It is all because in Relation table you have PRIMARY KEY(ID_SOURCE, ID_DESTINATION) so this both values have to create unique set. If you change it to PRIMARY KEY(ID_SOURCE, ID_DESTINATION, VALUE), then it should work just fine.
EDIT
example of solution mentioned in comment below:
CREATE TABLE RELATION (
ID INT NOT NULL,
ID_SOURCE TEXT NOT NULL,
ID_DESTINATION TEXT NOT NULL,
VALUE TEXT,
PRIMARY KEY(ID),
UNIQUE (ID_SOURCE, ID_DESTINATION, VALUE)
FOREIGN KEY(ID_SOURCE) REFERENCES ENTITE(ID),
FOREIGN KEY(ID_DESTINATION) REFERENCES ENTITE(ID));

If you want rows with duplicate values for id_source and id_destination you can either use a surrogate primary key (like an autonumber int), maybe id_relation, together with a unique constraint for the three other columns or extend the primary key to include the value column too so that it would be PRIMARY KEY(ID_SOURCE, ID_DESTINATION, VALUE).
If you want to reference this table in joins, using a surrogate key might make your life easier.

Related

Away around Error: There is no unique constraint matching given keys for referenced table

Been at this for some time now. I'm getting this psql error when attepmting to create a joins table (product_type_combo):
There is no unique constraint matching given keys for referenced table product
I'm receiving this because the field (customer) I'm referencing from the table product does not have a UNIQUE constraint.
CREATE TABLE product
(
id SERIAL PRIMARY KEY,
name VARCHAR(128) NOT NULL,
customer VARCHAR,
CONSTRAINT product_c01 UNIQUE (name)
);
CREATE TABLE product_type_combo
(
customer VARCHAR REFERENCES product(customer),
type_id INT REFERENCES type(id),
PRIMARY KEY (customer, type_id),
CONSTRAINT product_type_combo_c01 UNIQUE (customer, type_id)
);
I don't want to have a UNIQUE constraint on the customer field on the product table since I want duplicates to appear there. I only want the customer & type combo in the joins table to have a constraint.
Is there a way around this?
This is silly:
customer VARCHAR REFERENCES product(customer),
You have a primary key on the table, an id column. You should be using that.
You could define customer to be unique -- the lack of a unique constraint on a column used for a foreign key reference is the cause of the error. However, I strongly, strongly recommend that you use the primary key.
The error is coming from the Foreign Key (REFERENCES) constraint, for reasons listed in the PostgreSQL manual:
A foreign key must reference columns that either are a primary key or form a unique constraint.
Since your "customer" column is not unique, it cannot be the target of a foreign key reference. It also suggests a problem in your data model:
If the relationship is between a product and a type, then referencing the "id" from the products table would make sense.
If the relationship is between a customer and a type, then there should be a table listing all the possible customers, and you can create foreign keys referencing that from both "product" and "product_type_combo" (which would presumably be better named "customer_type_combo").

How to manage postgresql foreign keys?

I need some advice on SQL structure on Postgresql.
I have those two tables :
DROP TABLE IF EXISTS "public"."attribute_value";
CREATE TABLE "public"."attribute_value"
(
"id" INTEGER NOT NULL,
"attribute_id" INTEGER NOT NULL,
"value" CHARACTER VARYING(100) NULL
);
--*****************************************************
DROP TABLE IF EXISTS "public"."product_attribute";
CREATE TABLE "public"."product_attribute"
(
"product_id" INTEGER NOT NULL,
"attribute_value_id" INTEGER NOT NULL,
"attribute_id" INTEGER NOT NULL
);
I added no constraints on purpose.
I need a foreign key on the child table product_attribute.attribute_value_id referencing the parent table attribute_value.id. The best practice is to create a primary key on the field attribute_value.id (maybe with a sequence), or to CREATE UNIQUE INDEX on attribute_value.id ?
I first thought indexes were only special lookup tables that the database search engine can use to speed up data retrieval. But when I played with foreign keys, I found that creating an unique index allowed me to avoid error "there is no unique constraint matching given keys for referenced table blablabla" because a foreign key is not supposed to point to a non unique value. Should indexes be used to create foreign keys then ?
I also need a foreign key on the child table product_attribute.attribute_id referencing parent table attribute_value.attribute_id. The problem is that attribute_value.attribute_id is not unique. But all the rows in product_attribute.attribute_id must not take any value out of attribute_value.attribute_id's possible values. How should I do ?
Every table should have a primary key. Don't join the legion of people who complain about duplicate rows in their tables.
So make id the primary key of attribute_value, then you can create a foreign key constraint.
Constraints are implemented by unique indexes, so technically they are almost the same. Still you need a constraint and not just a unique index as the target of a foreign key constraint.
About attribute_id: that should not be a foreign key constraint between the two tables from your question, but both tables should have a foreign key referencing yet another table (attribute?).

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.

Difference Between Unique And Composite Primary key In sql server

I want to know what is the difference between unique key and composite primary key in SQL Server.
According to w3c school:
The UNIQUE constraint uniquely identifies each record in a database table.
The UNIQUE and PRIMARY KEY constraints both provide a guarantee for uniqueness for a column or set of columns.
A PRIMARY KEY constraint automatically has a UNIQUE constraint defined on it.
Note that you can have many UNIQUE constraints per table, but only one PRIMARY KEY constraint per table.
We can create composite primary key by using this:
CREATE TABLE Persons
(
P_Id int NOT NULL,
LastName varchar(255) NOT NULL,
FirstName varchar(255),
Address varchar(255),
City varchar(255),
UNIQUE (P_Id)
)
For composite primary key syntax:
CREATE TABLE Persons
(
P_Id int,
C_Id int,
LastName varchar(255) NOT NULL,
FirstName varchar(255),
Address varchar(255),
City varchar(255),
Primary Key (P_Id,C_Id)
);
The UNIQUE constraint uniquely identifies each record in a database table. This provide a guarantee for uniqueness for a column or set of columns. We can define(point) a single row with this.
A PRIMARY KEY has a UNIQUE constraint by default.
While in some tables, there won't be any columns with a unique value to define a row. In such cases COMPOSITE KEYs are used. In such cases two or more columns are combined together so that this combination is unique.
As you said yourself, the only difference between a unique and a primary key is that there may only be 1 primary key on a table while it can have more unique keys.
Furthermore, the values of a primary key may not be null.
Both unique- and primary keys can be composed of multiple columns (composed key).
By the ways, in your example you had a unique key on the P_Id column and a composed primary key that includes that very same column.
This has no sense.
I would suggest to create only a simple primary key on that P_Id column.
Composite keys are formed of more than one column
Primary key prevents a second row on that table with same key column values.
A Primary key can be formed of a single column and as well as of more than one column. So primary key can be defined as a composite key too.
The primary key does not accept the any duplicate and NULL values.
A primary key of one table can be referenced by foreign key of another table. A table can have more than one unique key unlike primary key. Unique key constraints can accept only one NULL value for column. Unique constraints are also referenced by the foreign key of another table. A composite key is having two or more attributes that together can uniquely identify a tuple in a table. Such a key is also known as Compound Key, where each attribute creating a key is a foreign key in its own right.

create foreign key in oracle

is there anyone who can help me to create a foreign key for my Status table. I need to PLACE a foreign key constraint on the code in the status table, referring to the id in the Building table.
TABLE building
(
build_name VARCHAR2(50,0) NOT NULL,
id NUMBER (38,0) NOT NULL,
mapid NUMBER (10,0) NOT NULL
);
TABLE STATUS
(
code VARCHAR(2 BYTE) NOT NULL,
status_name VARCHAR2(40 BYTE) NOT NULL,
);
Bulding table has constraint building_gmidx with id as primary key.
Here is a quick syntax for your current requirement, however I recommend you to go through the oracle documentation for a proper understanding of what this means.
ALTER TABLE STATUS ADD (
CONSTRAINT status_fk_building FOREIGN KEY (code)
REFERENCES building (id)
ENABLE VALIDATE);
Did you leave out CREATE TABLE *name* to save time when writing the question? The first thing I see is that your Foreign key has to have the same data type and size as your Primary key. If the Tables already exist the code would be:
ALTER TABLE status MODIFY (code NUMBER(38));
From there you would need to
ALTER TABLE status ADD FOREIGN KEY (code) REFERENCES (building_gmidx)
Why is the constraint for building Primary key named building_gmidx and the column plain id?? All Normalized table attributes should be Unique. Wouldn't it be better if you just named the column "id" building_gmidx instead. Just in case there are other types of id's added later you do not have to think about which table "id" pertains to. Let me know if this works.