Postgres: two foreign keys to same primary key field - database

create table date_dimension (
id serial primary key,
date_id date,
..... others
);
create table temp (
id serial primary key,
from_date integer,
to_date integer,
value integer,
foreign key (from_date, to_date) references date_dimension(id, id)
);
How can I refer both from_date and to_date to id field in date_dimension?
The current code fails to do that saying
ERROR: there is no unique constraint matching given keys for referenced table "date_dimension"
Thank you

each FOREIGN KEY constraint added to a table will always relate one row in the referencing table to one row* in the referant. If you want to have each row in the referencing to refer to two distinct rows in the referant, you need two, separate foreign key constraints.
you want:
foreign key (from_date) references date_dimension(id)
foreign key (to_date) references date_dimension(id)
You almost always want to have exactly the rows in the foreign key to be the same as the primary key in the referant.
* Actually, there may be more than one row in the referant if the foreign key is smaller than a candidate key of the referant. this is seldom useful, though, and almost certainly unrelated to the problem you're describing

Related

Are composite key attributes also foreign keys?

I am working on an assignment and we are supposed to:
based on this schema:
Underlined = primary key, both underlined = composite key
My question is for the composite keys, are the two attributes that make up the composite key, as in table Borrower, also considered foreign keys?
Yes, it is possible to have a composite primary key for a table that are also considered foreign keys. If you do something like the following in SQL it would work properly.
CREATE TABLE Borrower
(
customerID VARCHAR2(10),
loan_number VARCHAR2(10),
PRIMARY KEY(customerID, loan_number),
FOREIGN KEY customerID REFERENCES Customer(CustomerID),
FOREIGN KEY loan_number REFERENCES Loan(loan_number)
);
The important thing to keep in mind is that the data type of the keys in the Borrower table have to match exactly the data types of the keys in the Customer and Loan tables respectively.

PrImary key or foreign key for a m-to-n relation table

I have a table in my database that models a m-to-n relation. The primary key of this relation is of course the combined primary keys of the 2 entities involved in this relation.
The relation goes like this: m customers have n orders
create table customer(
cid SERIAL PRIMARY KEY,
...
);
create table order(
oid SERIAL PRIMARY KEY,
...
);
create table has(
oid INTEGER REFERENCES order(oid) ON DELETE CASCADE,
cid INTEGER REFERENCES customer(cid) ON DELETE CASCADE,
FOREIGN KEY (oid,cid) or PRIMARY KEY (oid,cid)
);
I'm a bit confused on what to use here: primary key or foreign key to put them in relation?
thanks in advance for any help.
Jaiel
You should be using PRIMARY KEY for the composite key in table has. The combination of the order and customer IDs in the has table is a primary key in that table, because it allows the identification of a unique single record.
Note that both oid and cid in table has are foreign keys, pointing to the order and customer tables, respectively.

Primary and Foreign Key at the same time

Would it be possible in SQL Server 2008 to have a table created with 2 columns that are at the same time primary and foreign keys? If yes, how would such a code look like? I've searched and came up with nothing.
Sure, no problem:
CREATE TABLE dbo.[User]
(
Id int NOT NULL IDENTITY PRIMARY KEY,
Name nvarchar(1024) NOT NULL
);
CREATE TABLE [Group]
(
Id int NOT NULL IDENTITY PRIMARY KEY,
Name nvarchar(1024) NOT NULL
);
CREATE TABLE [UserToGroup]
(
UserId int NOT NULL,
GroupId int NOT NULL,
PRIMARY KEY CLUSTERED ( UserId, GroupId ),
FOREIGN KEY ( UserId ) REFERENCES [User] ( Id ) ON UPDATE NO ACTION ON DELETE CASCADE,
FOREIGN KEY ( GroupId ) REFERENCES [Group] ( Id ) ON UPDATE NO ACTION ON DELETE CASCADE
);
This is quite commonly used to model many-to-many relations.
These are totally different constructs.
A Primary Key is used to enforce uniqueness within a table, and be a unique identifier for a certain record.
A Foreign Key is used for referential integrity, to make sure that a value exists in another table.
The Foreign key needs to reference the primary key in another table.
If you want to have a foreign key that is also unique, you could make a FK constraint and add a unique index/constraint to that same field.
For reference purposes, SQL Server allows a FK to refer to a UNIQUE CONSTRAINT as well as to a PRIMARY KEY field.
It is probably not a good idea since often you want to allow duplicate foreign keys in the table. Even if you don't now, in the future, you might, so best not to do this. See Is it fine to have foreign key as primary key?
Just a quick note - from Microsoft pages (http://msdn.microsoft.com/en-us/library/ms189049.aspx)...
"A foreign key constraint does not have to be linked only to a primary key constraint in another table; it can also be defined to reference the columns of a UNIQUE constraint in another table."
Not used often, but useful in some circumstances.

Foreign Key constraints in SQL Server

I have a database scheme with versioning data rows, e.g.
Table Person has the columns
id (int, PK)
name (String)
current (Bool)
firstid (int)
Current is 0 for previous data, 1 for the latest entry. All rows for the same entity have the same FirstID, which points to the first ID of the set.
Referencing table: Adress with the same principle:
id (int, PK)
street (String)
person_id (int)
current (Bool)
firstid (int)
Person_id points to patient.firstid. So firstid is never unique, only if current=1
My problem is: I would like to add referential integrity to my tables, but this only works, if the referenced column (patient.firstid) is unique...
You should look at refactoring your table structure. But to keep within the current structure, add a self-referencing foreign key to person
firstid references person(id)
Then, reference the "base person" from the address table
address.person_id references person(id) -- which should ONLY store a link to the first id
A FOREIGN KEY constraint does not have
to be linked only to a PRIMARY KEY
constraint in another table; it can
also be defined to reference the
columns of a UNIQUE constraint in
another table. A FOREIGN KEY
constraint can contain null values;
however, if any column of a composite
FOREIGN KEY constraint contains null
values, then verification of the
FOREIGN KEY constraint will be skipped.
Data from two related tables can be combined even if no PRIMARY KEY or FOREIGN KEY constraints are defined between the tables, but a foreign key relationship between two tables indicates that the two tables have been optimized to be combined in a query that uses the keys as its criteria.
reference http://msdn.microsoft.com/en-us/library/aa933117(v=sql.80).aspx

Are foreign keys indexed automatically in SQL Server?

Would the following SQL statement automatically create an index on Table1.Table1Column, or must one be explicitly created?
Database engine is SQL Server 2000
CREATE TABLE [Table1] (
. . .
CONSTRAINT [FK_Table1_Table2] FOREIGN KEY
(
[Table1Column]
) REFERENCES [Table2] (
[Table2ID]
)
)
SQL Server will not automatically create an index on a foreign key. Also from MSDN:
A FOREIGN KEY constraint does not have
to be linked only to a PRIMARY KEY
constraint in another table; it can
also be defined to reference the
columns of a UNIQUE constraint in
another table. A FOREIGN KEY
constraint can contain null values;
however, if any column of a composite
FOREIGN KEY constraint contains null
values, verification of all values
that make up the FOREIGN KEY
constraint is skipped. To make sure
that all values of a composite FOREIGN
KEY constraint are verified, specify
NOT NULL on all the participating
columns.
As I read Mike's question, He is asking whether the FK Constraint will create an index on the FK column in the Table the FK is in (Table1). The answer is no, and generally. (for the purposes of the constraint), there is no need to do this The column(s) defined as the "TARGET" of the constraint, on the other hand, must be a unique index in the referenced table, either a Primary Key or an alternate key. (unique index) or the Create Constraint statment will fail.
(EDIT: Added to explicitly deal with comment below -)
Specifically, when providing the data consistency that a Foreign Key Constraint is there for. an index can affect performance of a DRI Constraint only for deletes of a Row or rows on the FK side. When using the constraint, during a insert or update the processor knows the FK value, and must check for the existence of a row in the referenced table on the PK Side. There is already an index there. When deleting a row on the PK side, it must verify that there are no rows on the FK side. An index can be marginally helpful in this case. But this is not a common scenario.
Other than that, in certain types of queries, however, where the query processor needs to find the records on the many side of a join which uses that foreign key column. join performance is increased when an index exists on that foreign key. But this condition is peculiar to the use of the FK column in a join query, not to existence of the foreign Key constraint... It doesn't matter whether the other side of the join is a PK or just some other arbitrary column. Also, if you need to filter, or order the results of a query based on that FK column, an index will help... Again, this has nothing to do with the Foreign Key constraint on that column.
No, creating a foreign key on a column does not automatically create an index on that column. Failing to index a foreign key column will cause a table scan in each of the following situations:
Each time a record is deleted from the referenced (parent) table.
Each time the two tables are joined on the foreign key.
Each time the FK column is updated.
In this example schema:
CREATE TABLE MasterOrder (
MasterOrderID INT PRIMARY KEY)
CREATE TABLE OrderDetail(
OrderDetailID INT,
MasterOrderID INT FOREIGN KEY REFERENCES MasterOrder(MasterOrderID)
)
OrderDetail will be scanned each time a record is deleted in the MasterOrder table. The entire OrderDetail table will also be scanned each time you join OrderMaster and OrderDetail.
SELECT ..
FROM
MasterOrder ord
LEFT JOIN OrderDetail det
ON det.MasterOrderID = ord.MasterOrderID
WHERE ord.OrderMasterID = #OrderMasterID
In general not indexing a foreign key is much more the exception than the rule.
A case for not indexing a foreign key is where it would never be utilized. This would make the server's overhead of maintaining it unnecessary. Type tables may fall into this category from time to time, an example might be:
CREATE TABLE CarType (
CarTypeID INT PRIMARY KEY,
CarTypeName VARCHAR(25)
)
INSERT CarType .. VALUES(1,'SEDAN')
INSERT CarType .. VALUES(2,'COUP')
INSERT CarType .. VALUES(3,'CONVERTABLE')
CREATE TABLE CarInventory (
CarInventoryID INT,
CarTypeID INT FOREIGN KEY REFERENCES CarType(CarTypeID)
)
Making the general assumption that the CarType.CarTypeID field is never going to be updated and deleting records would be almost never, the server overhead of maintaing an index on CarInventory.CarTypeID would be unnecessary if CarInventory was never searched by CarTypeID.
According to: https://learn.microsoft.com/en-us/sql/relational-databases/tables/primary-and-foreign-key-constraints?view=sql-server-ver16#indexes-on-foreign-key-constraints
Unlike primary key constraints, creating a foreign key constraint does not automatically create a corresponding index

Resources