patternsqlMajor
Foreign key constraint on array member?
Viewed 0 times
arrayforeignmemberconstraintkey
Problem
Suppose I have a table containing job roles:
Suppose I further have a table, users, and each row (a specific user) can have an arbitrary number of job roles:
I should probably make sure that each member of
This doesn't seem possible with postgres. Am I looking at this the wrong way? What is the suggested "right" way to handle this?
CREATE TABLE roles
(
"role" character varying(80) NOT NULL,
CONSTRAINT "role" PRIMARY KEY (role)
);Suppose I further have a table, users, and each row (a specific user) can have an arbitrary number of job roles:
CREATE TABLE users
(
username character varying(12) NOT NULL,
roles character varying(80)[] NOT NULL,
CONSTRAINT username PRIMARY KEY (username)
);I should probably make sure that each member of
users.roles[] exists in roles.role. It seems to me that what I want is a foreign key constraint on each member of users.roles[] such that if references roles.role.This doesn't seem possible with postgres. Am I looking at this the wrong way? What is the suggested "right" way to handle this?
Solution
Support for array foreign keys was worked on with the goal of getting it into PostgreSQL 9.3, but it didn't make the cut for the release due to performance and reliability problems. It doesn't seem to be being worked on for 9.4.
At this time, you need to stick to the usual relational approach of using a "join table" to model an m:n relationship.
I suggest using surrogate keys in this case, too, rather than storing the usernames/role names directly in the join table. The first time you want to rename a user or role you'll be happy you used surrogate keys. Just place a
At this time, you need to stick to the usual relational approach of using a "join table" to model an m:n relationship.
CREATE TABLE user_roles (
username character varying(12) references users(username),
"role" character varying(80) references roles("role"),
PRIMARY KEY(username, "role")
);I suggest using surrogate keys in this case, too, rather than storing the usernames/role names directly in the join table. The first time you want to rename a user or role you'll be happy you used surrogate keys. Just place a
unique constraint on roles."role" and users.username.Code Snippets
CREATE TABLE user_roles (
username character varying(12) references users(username),
"role" character varying(80) references roles("role"),
PRIMARY KEY(username, "role")
);Context
StackExchange Database Administrators Q#60132, answer score: 24
Revisions (0)
No revisions yet.