Can a SERIAL foreign key be set to null? - sql

Question: I have a table with a couple of foreign keys. I want to make two of the foreign keys optional (that is, they can be set to NULL). When I try to run the command to create the table, I get the error:
ERROR: conflicting NULL/NOT NULL declarations for column "activityid" of table "eventassociation"
If I try and create the table without the NULL declaration for the foreign keys, those foreign keys implicitly become NOT NULL.
How can I make it so that the foreign keys activityID and roleID can be null?
Thanks,
hypoz
Extra information:
I am running postgreSQL (version on apt-get) on ubuntu 12.04.
This is the problematic table:
CREATE TABLE eventAssociation (
associationID SERIAL PRIMARY KEY,
studentID VARCHAR(12) references volunteers(studentID),
eventID SERIAL references events(eventID),
activityID SERIAL references activities NULL,
roleID SERIAL references roles(roleID) NULL,
coordinatorConfirmed BOOLEAN,
userRevokeable BOOLEAN
)
And for reference, here is the schema for the activities table. The roles table is pretty much identical except with different field names.
CREATE TABLE activities (
activityID SERIAL PRIMARY KEY,
eventID integer references events(eventID),
name varchar(128),
description TEXT
)

Defining a column that is a FK as serial does not make any sense. It means that whenever you don't supply a value, a new id will be generated - I cannot imagine any situation where that makes sens.
I think you actually want to define those columns as integer:
CREATE TABLE activities
(
activityID SERIAL PRIMARY KEY,
eventID INTEGER REFERENCES events,
name VARCHAR(128),
description TEXT
);
CREATE TABLE eventAssociation
(
associationID SERIAL PRIMARY KEY,
eventID INTEGER REFERENCES events,
activityID INTEGER REFERENCES activities,
coordinatorConfirmed BOOLEAN,
userRevokeable BOOLEAN
);

Related

Design sql tables with list of foreign keys

I want to create an application for rotating pairs in a team every day. I need to store this in the database. Requirments are:
A team should be assigned to one ore more members.
Each team can have multiple tabs and different members allocate in them.(If team consist of 4 members for the particular tab only 3 should be part of it)
Each tab will have a pair of members or list of pairs per day stored.
I have ended up designing something like the example below:
create table if not exists team (
id serial not null primary key,
name text not null
);
create table if not exists member (
id serial not null primary key,
team_id integer references team(id),
nickname text
);
create table if not exists team_tab (
id bigserial not null primary key,
team_id integer references team(id) on delete cascade,
name text not null,
member_ids integer[],
);
create table if not exists team_tab_pairs (
id bigserial not null primary key,
team_tab_id integer not null references team_tab(id) on delete cascade,
tab_date date not null,
pair_ids integer[][],
);
I need an advice and suggestions how could I achieve this without having a list of references ids stored in the 2 tables below.
You need an extra table to design an M:N relationship. This is the case, for example, between "team tab" and "member". In addition to both main entities:
create table member (
id serial not null primary key,
team_id integer references team(id),
nickname text
);
create table team_tab (
id bigserial not null primary key,
team_id integer references team(id) on delete cascade,
name text not null
);
...you'll need to create a table to represent the M:N relationship, as in:
create table team_tab_member (
team_tab_id bigint not null,
member_id int not null,
primary key (team_tab_id, member_id) -- optional depending on the model
);

Why PSQL create table returns [42P01] ERROR: relation does not exist

I'm new to SQL. I was trying to run sql schema, here is a part of code
create table PageColours (
id serial,
userID serial references users(id),
--references users(id),
isTemplate boolean default'false',
name NameValue not null unique,
primary key (id)
);
create table People (
id serial,
email EmailValue not null unique,
givenName NameValue not null,
familyName NameValue,
invitedID serial references Events(id),
attendedID serial references Events(id),
primary key (id)
);
create table users(
id serial
references People(id),
passWord varchar not null,
BillingAddress serial not null
references Places(id),
HomeAddress serial
references Places(id),
ListID serial
references ContactLists(id),
ColorID serial
references PageColours(id),
primary key (id)
);
It returns[2020-07-03 15:28:19] [42P01] ERROR: relation "people" does not exist
[2020-07-03 15:28:19] [42P01] ERROR: relation "users" does not exist
In fact all foreign key reference table reference not exist. When i remove the reference, the table can be created, can someone please help me ?
The script is run sequentially. So when the pagecolours table is created, the users table does not yet exist and thus the references users fails.
You need to re-order the script, so that the users table is created first. But as you have a circular reference (users references pagecolours and pagecolours references users) you need to create the tables without an "inline" reference, and then at the end of the script you need to run an ALTER TABLE to create the foreign keys.
But having a circular reference like that, is usually not a good idea. But if you are 100% sure you need it, you should at least declare the foreign keys as deferrable, to make inserting rows easier.
Also: serial is not a datatype. A foreign key column that references a serial column should be defined as an integer. In general it is recommended to move away from serial and use integer generated always as identity instead.

PostgresQL Foreign Key Syntax Error

When attempting to create the second table in this respective database, I'm getting the following error message:
ERROR: syntax error at or near "REFERENCES"
LINE 3: master_directory REFERENCES auth_table (directory),
Here's the database structure that I attempted to create:
CREATE TABLE auth_table (
id SERIAL PRIMARY KEY,
directory VARCHAR,
image VARCHAR
)
CREATE TABLE master_table (
id SERIAL PRIMARY KEY,
master_directory references auth_table (directory),
master_image references auth_table (image)
)
Any reason why I'm receiving that error? Any help would be appreciated!
You've left the data type off, but that syntax error is the least of your problems.
Your foreign key references need to refer to unique column(s). So "auth_table" probably needs to be declared one of these ways. (And you probably want the second one, if your table has something to do with the paths to files.)
CREATE TABLE auth_table (
id SERIAL PRIMARY KEY,
directory VARCHAR not null unique,
image VARCHAR not null unique
);
CREATE TABLE auth_table (
id SERIAL PRIMARY KEY,
directory VARCHAR not null,
image VARCHAR not null,
unique (directory, image)
);
Those unique constraints mean quite different things, and each requires a different foreign key reference. Assuming that you want to declare "auth_table" the second way, "master_table" probably ought to be declared like one of these. (Deliberately ignoring cascading updates and deletes.)
CREATE TABLE master_table (
master_directory varchar not null,
master_image varchar not null,
primary key (master_directory, master_image),
foreign key (master_directory, master_image)
references auth_table (directory, image)
);
CREATE TABLE master_table (
id integer primary key,
foreign key (id) references auth_table (id)
);

How do I make a serial field auto increment and be a foreign key - Postgres

I have 2 tables and I am trying to create a Foreign Key between the two. Here is the structure of my tables:
create table users (
id serial,
user_name varchar(50)
);
create table playlists (
id serial,
user_id integer references users(id)
);
I keep getting this error:
ERROR: there is no unique constraint matching given keys for referenced table "users"
Why is there not a unique constraint? If I create the id in the users table as integer PRIMARY KEY, then everything works fine. How do I fix this where the users id auto increments and can be the FK in the playlists table?
Creating a column of type serial doesn't make it the primary key or constraint it in any way. serial just creates an integer column, creates a sequence, and attaches the sequence to the column to provide default values. From the fine manual:
In the current implementation, specifying:
CREATE TABLE tablename (
colname SERIAL
);
is equivalent to specifying:
CREATE SEQUENCE tablename_colname_seq;
CREATE TABLE tablename (
colname integer NOT NULL DEFAULT nextval('tablename_colname_seq')
);
ALTER SEQUENCE tablename_colname_seq OWNED BY tablename.colname;
If you want your id serial columns to be primary keys (which you almost certainly do), then say so:
create table users (
id serial not null primary key,
user_name varchar(50)
);
create table playlists (
id serial not null primary key,
user_id integer references users(id)
);

Is my query correct when I set primary key for 3 columns in a table?

In my case, I have only 1 candidate may go with 1 job at the time so they are must be 2 primary key.
Then, a column is as JobApplicationId use for the table CandidateDetail as a foreign key.
Is that correct when I decide to set these 3 columns above as primary key or there are other ways to address my problem here?
CREATE TABLE Candidate(
CandidateId int identity primary key,
FullName nvarchar(50)
)
CREATE TABLE Job(
JobId int identity primary key,
JobTitle nvarchar(50)
)
CREATE TABLE JobApplication(
JobApplicationId int identity,
JobId int,
CandidateId int,
CreatedDate datetime,
primary key(JobApplicationId, JobId, CandidateId)
)
CREATE TABLE CandidateDetail(
CandidateDetailId int identity primary key,
JobApplicationId int,
[Description] nvarchar(300)
)
ALTER TABLE JobApplication ADD CONSTRAINT fk_JobApplication_Job FOREIGN KEY (JobId) REFERENCES Job(JobId)
ALTER TABLE JobApplication ADD CONSTRAINT fk_JobApplication_Candidate FOREIGN KEY (CandidateId) REFERENCES Candidate(CandidateId)
ALTER TABLE CandidateDetail ADD CONSTRAINT fk_CandidateDetail_JobApplication FOREIGN KEY (JobApplicationId) REFERENCES JobApplication(JobApplicationId)
Instead of a primary key with three columns you could just have JobApplicationId as the primary key and a unique constraint on JobId, CandidateId.
Otherwise, two rows with JobApplicationId=1, JobId=1, CandidateId=1 and JobApplicationId=2, JobId=1, CandidateId=1 would still be valid in terms of your current primary key approach, but would be invalid in terms of the business case.
From both a performance and usability perspective, a compound primary key can be a hassle and can create performance issues. Personally, I would choose JobApplicationId as the primary key (because this is an identity column and will be unique for each record). Then, if you need to constrain the table so that JobId and CandidateId are always unique (not allowing more than 1 record for any given candidate and the job they've applied for) then I would use a compound Unique Constraint.
However, I would suggest that you evaluate those requirements more closely because what if a candidate applies for the same position in a different time frame? It might stand to reason that having the same candidate applied to the same job more than once in that table might be valid data.