Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Recursive Foreign Key Issue

In my DB design, I need a table with recursive foreign key relation i.e. the foreign key refers to the same table. When I try it with one column it works fine, but when I use two columns it gives an error. Below is the sample code and the resulting error. Your help will be highly appreciated.

CREATE TABLE categories (
categoryID integer ,
parentID integer ,
setID integer REFERENCES categories(categoryID,parentID),
name char(255) NOT NULL,
PRIMARY KEY(categoryID,parentID)
);

ERROR: number of referencing and referenced columns for foreign key disagree

When I use

setID integer REFERENCES categories(categoryID) and 
PRIMARY KEY(categoryID) 

then it gives no error, but that's not what I want.

like image 958
Shehroz Avatar asked Dec 12 '11 23:12

Shehroz


People also ask

What problems do foreign keys introduce?

Foreign key problems. Many database users encounter foreign key errors, often due to referential integrity problems. A foreign key might point to data that no longer exists, or the foreign key's data type doesn't match the primary key data type, eroding referential integrity.

Why you shouldn't use foreign keys?

Having active foreign keys on tables improves data quality but hurts performance of insert, update and delete operations. Before those tasks database needs to check if it doesn't violate data integrity. This is a reason why some architects and DBAs give up on foreign keys at all.

Can a foreign key have repeating values?

A foreign key can contain duplicate values. There is no limitation in inserting the values into the table column. While inserting any value in the foreign key table, ensure that the value is present into a column of a primary key.

What is a foreign key violation?

Foreign key constraint violation occurred, dbname = database_name, table name = table_name, constraint name = constraint_name. 23000. Occurs when an insert or update on a foreign key table is performed without a matching value in the primary key table.


2 Answers

You probably want this:

CREATE TABLE categories (
    categoryID integer,
    parentID integer,
    setID integer,
    name char(255) NOT NULL,
    PRIMARY KEY (categoryID, parentID),
    FOREIGN KEY (categoryID, parentID) REFERENCES categories(categoryID, parentID)
);

Consult the manual about the syntax.

Answer to follow up question in comment:

CREATE TABLE categories (
    categoryID integer,
    parentID integer,
    setID integer,
    name char(255) NOT NULL,
    PRIMARY KEY (categoryID, parentID),
    UNIQUE (setID, parentID) 
    FOREIGN KEY (setID, parentID) REFERENCES categories(setID, parentID)
);

The target of a foreign key needs some kind of uniqueness constraint. I quote the manual:

The referenced columns must be the columns of a non-deferrable unique or primary key constraint in the referenced table.

like image 84
Erwin Brandstetter Avatar answered Oct 07 '22 08:10

Erwin Brandstetter


Yeah, unfortunately, you are trying to say that one numeric field should be equivalent to two numeric fields. Not really going to happen.

Think about your use of SetID. Do you really need it?

Instead, ensure that parentID is a foreign key of categoryID ( i.e. express that any value of parentID HAS to exist as a a corresponding and existing value in parentID ).

like image 26
Paul Alan Taylor Avatar answered Oct 07 '22 08:10

Paul Alan Taylor