Foreign Key - Alias viability? - amazon-redshift

Are you able to assign an alias to a foreign key?
e.g. "foreign key(campaign_id) references campaigns_Cmprsed (id)"
Since Campaign_id does not exist in the references table is there something like this that would exist?
"foreign key(campaign_id) references campaigns_Cmprsed (id as campaign_id)"

Related

use one part of composite primary key as foreign key

I'm using PostgreSQL.
I have a table accounts with account_id as the primary key. I also have a second table called relations with a composite primary key (follower_id, following_id). Each relation must be unique.
ALTER TABLE accounts ADD CONSTRAINT users_pk PRIMARY KEY (account_id);
ALTER TABLE relations ADD CONSTRAINT relations_pk PRIMARY KEY (follower_id, following_id);
I want to create a foreign key constraint from follower_id (relations) -> account_id (accounts), and the same with following_id.
ALTER TABLE relations ADD CONSTRAINT follower_id_fk FOREIGN KEY (follower_id) REFERENCES accounts (account_id) ON DELETE CASCADE
This foreign key is not accepted by the database. I get the following error:
ERROR: insert or update on table "relations" violates foreign key constraint "follower_id_fk"
DETAIL: Key (follower_id)=(4) is not present in table "accounts".
I understand this, because it's a composite primary key.
What I want to achieve:
When an account is deleted, I want to delete all the records where the account_id is the follower_id (ON DELETE CASCADE) AND where it is the following_id.
I could do this in my nodejs code or with a trigger function, but I don't know what will be the best performance-wise. Does anyone knows a/the best solution?

How to add foreign key in PostgreSQL

I created this first table named 'bookstore' where Primary Key is book_name:
create table bookstore (book_name varchar primary key, author varchar, price decimal);
I am trying to create a second table named 'name' where name is primary key. I want to make this primary key- author.name as a foreign key of bookstore.author.
create table author (name varchar primary key, place varchar,
constraint fk_author_bookstore foreign key(name) references bookstore(author));
But the error is: ERROR: there is no unique constraint matching given keys for referenced table "bookstore"
SQL state: 42830
I am new to SQL, so, hoping to get some help. If you can, please write the correct code.
Thanks
Name column in author table is primary key and it's referenced as foreign key in bookstore table.
-- PostgreSQL (v11)
create table author (name varchar primary key, place varchar);
create table bookstore (book_name varchar primary key, author varchar, price decimal
, CONSTRAINT fk_author_bookstore
FOREIGN KEY(author)
REFERENCES author(name));
Please check from url https://dbfiddle.uk/?rdbms=postgres_11&fiddle=8394f796433ed8bc170c2889286b3fc2
Add foreign key after table creation
-- PostgreSQL(v11)
ALTER TABLE bookstore
ADD CONSTRAINT fk_author_bookstore FOREIGN KEY (author)
REFERENCES author (name);
Please check from url https://dbfiddle.uk/?rdbms=postgres_11&fiddle=d93cf071bfd0e3940dfd256861be813c

Dropping unique constraint on foreign key reference of junction table

I'm creating a database in PostgreSQL and want to include a many-to-many relationship between the tables. The two tables I want to include are as follows:
CREATE TABLE "meter" (
"id" integer PRIMARY KEY,
"nmi" integer,
"next_scheduled_read_date" timestamp
);
CREATE TABLE "register" (
"id" text PRIMARY KEY,
"value" text
);
The many-to-many relationship I want to have is between meter id and register id. I have then created the junction table below:
CREATE TABLE "meter_registers" (
"meter_id" integer NOT NULL,
"register_id" text NOT NULL,
PRIMARY KEY ("meter_id", "register_id"),
FOREIGN KEY ("meter_id") REFERENCES "meter" ("id") ON UPDATE CASCADE,
FOREIGN KEY ("register_id") REFERENCES "register" ("id") ON UPDATE CASCADE
);
I then want to create a table that references the meter_id and register_id values from the junction table above which is structured as follows:
CREATE TABLE "demand_data" (
"upload_id" integer PRIMARY KEY,
"nmi" integer,
"meter" integer,
"register" text,
"start" timestamp,
"end" timestamp,
"duration" Time,
"demand" double precision
);
Where the meter and register reference the corresponding junction table columns. However, as the values of the junction table will not be unique I can't simply add a foreign key for the meter and register columns so I run into an error when I run the following:
ALTER TABLE "demand_data" ADD FOREIGN KEY ("meter") REFERENCES "meter_registers" ("meter_id");
ALTER TABLE "demand_data" ADD FOREIGN KEY ("register") REFERENCES "meter_registers" ("register_id");
ERROR: there is no unique constraint matching given keys for referenced table "meter_registers"
Is there a way to possibly reference the junction table columns in the demand_data table without the foreign key constraint? I know it's possible to do with a separate query once some data has been added using inner joins however, is it possible to do it through database table set up?
Yes. A compound foreign key.
ALTER TABLE "demand_data"
ADD FOREIGN KEY ("meter","register")
REFERENCES "meter_registers"( "meter_id", "register_id");
Note: Not directly related you should avoid those dreaded double quotes.
If demand_data references meter_registers, it should reference its primary key. So add a single foreign key constraint on both columns.
If you want two separate foreign keys,you should probably reference meter and register directly.

Adding primary key changes column type

Our database currently doesn't define primary keys on any tables. All of the id columns are simply unique indexes. I'm dropping those indexes and replacing them with proper primary keys.
My problem: In Postgres 8.4.7, one table in particular changes the data type from bigint to integer when I add the primary key to the table.
I've got the following table definition:
psql=# \d events
Table "public.events"
Column | Type | Modifiers
-----------------------+--------------------------+-----------------------------------------------------
id | bigint | not null default nextval('events_id_seq'::regclass)
[more columns omitted]
Indexes:
"events_id_unique_pk" UNIQUE, btree (id)
Foreign-key constraints:
"events_clearing_event_ref_fk" FOREIGN KEY (clearing_event_id) REFERENCES events(id)
"events_event_configs_id_fk" FOREIGN KEY (event_config_id) REFERENCES event_configs(id)
"events_pdu_circuitbreaker_id_fk" FOREIGN KEY (pdu_circuitbreaker_id) REFERENCES pdu_circuitbreaker(id)
"events_pdu_id_fk" FOREIGN KEY (pdu_id) REFERENCES pdus(id) ON DELETE CASCADE
"events_pdu_outlet_id_fk" FOREIGN KEY (pdu_outlet_id) REFERENCES pdu_outlet(id)
"events_sensor_id_fk" FOREIGN KEY (sensor_id) REFERENCES sensors(id)
"events_user_id_fk" FOREIGN KEY (clearing_user_id) REFERENCES users(id)
Referenced by:
TABLE "events" CONSTRAINT "events_clearing_event_ref_fk" FOREIGN KEY (clearing_event_id) REFERENCES events(id)
TABLE "event_params" CONSTRAINT "events_params_event_id_fk" FOREIGN KEY (event_id) REFERENCES events(id) ON DELETE CASCADE
Triggers:
event_validate BEFORE INSERT OR UPDATE ON events FOR EACH ROW EXECUTE PROCEDURE event_validate()
This is what happens:
psql=# ALTER TABLE events ADD PRIMARY KEY (id);
NOTICE: ALTER TABLE / ADD PRIMARY KEY will create implicit index "events_pkey" for table "events"
ALTER TABLE
psql=# \d events
Table "public.events"
Column | Type | Modifiers
-----------------------+--------------------------+-----------------------------------------------------
id | integer | not null default nextval('events_id_seq'::regclass)
[more columns omitted]
Indexes:
"events_pkey" PRIMARY KEY, btree (id)
"events_id_unique_pk" UNIQUE, btree (id)
Foreign-key constraints:
"events_clearing_event_ref_fk" FOREIGN KEY (clearing_event_id) REFERENCES events(id)
"events_event_configs_id_fk" FOREIGN KEY (event_config_id) REFERENCES event_configs(id)
"events_pdu_circuitbreaker_id_fk" FOREIGN KEY (pdu_circuitbreaker_id) REFERENCES pdu_circuitbreaker(id)
"events_pdu_id_fk" FOREIGN KEY (pdu_id) REFERENCES pdus(id) ON DELETE CASCADE
"events_pdu_outlet_id_fk" FOREIGN KEY (pdu_outlet_id) REFERENCES pdu_outlet(id)
"events_sensor_id_fk" FOREIGN KEY (sensor_id) REFERENCES sensors(id)
"events_user_id_fk" FOREIGN KEY (clearing_user_id) REFERENCES users(id)
Referenced by:
TABLE "events" CONSTRAINT "events_clearing_event_ref_fk" FOREIGN KEY (clearing_event_id) REFERENCES events(id)
TABLE "event_params" CONSTRAINT "events_params_event_id_fk" FOREIGN KEY (event_id) REFERENCES events(id) ON DELETE CASCADE
Triggers:
event_validate BEFORE INSERT OR UPDATE ON events FOR EACH ROW EXECUTE PROCEDURE event_validate()
I considered a few workarounds, but I'd really rather know why it's happening. There are a few other tables that also use bigint, so I don't want to just hack a solution in place.
This is scripted with Liquibase, but it happens directly in the Postgres console too.
Update
Two other points:
I can create a simple table with a bigint id and a unique index on id, add the primary key, and the column type stays the same.
All tables are empty at the time execution.
Could it have something to do with the constraints?
That's pretty interesting. I can't reproduce it with version 9.1.0 (yes, I should upgrade too!). But then I don't know precisely how the original table and sequence were created.
This page seems to allude to a similar automatic change of types between SERIAL and INTEGER: http://grover.open2space.com/content/migrate-data-postgresql-and-maintain-existing-primary-key
Could it be something like creating the table using SERIAL instead of BIGSERIAL, and then forcing the type to BIGINT? Something in between the sequence and primary key manipulations might have reset it.
I wasn't able to reproduce this the next day, even after reproducing it multiple times with witnesses the first time it occurred. I'm chalking it up to gremlins.

T-SQL: foreign key that's not referencing a primary key

I have the following database:
CREATE TABLE ContentNodes
(
Id UNIQUEIDENTIFIER NOT NULL,
Revision INT IDENTITY(1,1) NOT NULL,
ParentId UNIQUEIDENTIFIER NULL
PRIMARY KEY (Id, Revision)
)
How do I limit ParentId to only contain values from the Id column. Trying to make ParentId a foreign key gives me:
PRINT 'FK_ContentNodes_ParentId_ContentNodes';
ALTER TABLE ContentNodes
ADD CONSTRAINT FK_ContentNodes_ParentId_ContentNodes FOREIGN KEY (ParentId) REFERENCES ContentNodes(Id);
GO
Error:
There are no primary or candidate keys in the referenced table
'ContentNodes' that match the
referencing column list in the foreign
key
'FK_ContentNodes_ParentId_ContentNodes'.
Since you have a compound primary key (Id, Revision) on your ContentNodes, you have to use both columns in a foreign key relation.
You cannot reference only parts of a primary key - simply cannot be done.
You have to either introduce a surrogate primary key into your table which is just a simple INT IDENTITY and then you can self-reference that single PK column, or you can (if it's possible in your data model) put a UNIQUE INDEX on that one column you want to reference:
CREATE UNIQUE NONCLUSTERED INDEX UIX_ID
ON ContentNodes(Id)
Once you have a UNIQUE INDEX on that column, then you can use it as a FK reference.