Reputation: 121
I can imagine that it is unlikely that this question has never been answered. However, I have not found it, so in any case here is my problem:
I am migrating from MySQL.
I am getting an error when I try to create a table with one single data field with 2 foreign keys referencing another table.
My goal is to simply have a phone directory for employees.
The directory table must reference the employee id as well as the phone number type.
I get this error when trying to do so:
ERROR: There is no unique constraint matching given keys, for referenced table: Employees!
Here is my current sql dump:
-- ----------------------------
-- Table structure for EmployeeGroups
-- ----------------------------
DROP TABLE IF EXISTS "public"."EmployeeGroups";
CREATE TABLE "public"."EmployeeGroups" (
"Id" int8 DEFAULT nextval('"EmployeeGroups_Id_seq"'::regclass) NOT NULL,
"EmployeeGroup" varchar(255) COLLATE "default"
)
WITH (OIDS=FALSE)
;
-- ----------------------------
-- Table structure for Employees
-- ----------------------------
DROP TABLE IF EXISTS "public"."Employees";
CREATE TABLE "public"."Employees" (
"Id" int8 DEFAULT nextval('"Employees_Id_seq"'::regclass) NOT NULL,
"EmployeeGroupId" int8 DEFAULT
nextval('"Employees_EmployeeGroupId_seq"'::regclass) NOT NULL,
"FirstName" varchar(255) COLLATE "default",
"LastName" varchar(255) COLLATE "default",
"CivicNumber" int4,
"CivicNumberAlias" int4,
"StreetName" varchar(255) COLLATE "default",
"City" varchar(255) COLLATE "default",
"PostalCode" varchar(255) COLLATE "default",
"UserAcessLevel" int8 DEFAULT
nextval('"Employees_UserAcessLevel_seq"'::regclass) NOT NULL,
"Username" varchar(255) COLLATE "default",
"Password" varchar(255) COLLATE "default",
"Timestamp" date
)
WITH (OIDS=FALSE)
;
-- ----------------------------
-- Table structure for PhoneNumberType
-- ----------------------------
DROP TABLE IF EXISTS "public"."PhoneNumberType";
CREATE TABLE "public"."PhoneNumberType" (
"Id" int8 DEFAULT nextval('"PhoneNumberType_Id_seq1"'::regclass) NOT NULL,
"PhoneNumberType" varchar(150) COLLATE "default" NOT NULL
)
WITH (OIDS=FALSE)
;
-- ----------------------------
-- Table structure for SystemAcessLevel
-- ----------------------------
DROP TABLE IF EXISTS "public"."SystemAcessLevel";
CREATE TABLE "public"."SystemAcessLevel" (
"Id" int8 DEFAULT nextval('"SystemAcessLevel_Id_seq"'::regclass) NOT NULL,
"AcessLevel" varchar(255) COLLATE "default" NOT NULL
)
WITH (OIDS=FALSE);
Here is my error generating statement:
CREATE TABLE "public"."NewTable" (
"Id" serial8 NOT NULL,
"EmployeeId" int8 NOT NULL,
"PhoneNumberTypeId" int8 NOT NULL,
"PhoneNumber" varchar(16) NOT NULL,
PRIMARY KEY ("Id"),
CONSTRAINT "phone_fk_emp_id" FOREIGN KEY ("EmployeeId")
REFERENCES "public"."Employees" ("Id") ON DELETE NO ACTION ON UPDATE
CASCADE,
CONSTRAINT "phone_fk_type_id" FOREIGN KEY ("PhoneNumberTypeId")
REFERENCES "public"."PhoneNumberType" ("Id") ON DELETE NO ACTION ON
UPDATE CASCADE
)
WITH (OIDS=FALSE)
;
Upvotes: 1
Views: 491
Reputation: 121
As it turns out the problem was identifying the
EmployeeGroupId
field that was referenced in the Employees
table as a second primary key created a conflict when adding the EmployeeDirectory
table referencing the same foreing key as a second primary key of the Employees.GroupId
field.
In other word seems like PostgreSQL considers second primary key as unique identifiers creating a one to one relationship therefore it considers it as an error to have an additional table referencing the same identifier as a foreing key stated as a second primary key, and please correct me if I am wrong since not an expert when it comes to PostgreSQL.
This however is accepted by Mysql; this is why I was having a hard time figuring out this error.
Upvotes: 1
Reputation: 246403
Every column (or set of columns) that you reference in a foreign key must have a primary key or unique constraint on it.
Otherwise, how could you identify which row the foreign key points to?
Upvotes: 0