I need to construnct a junction table for many-to-many relations between two parent tables. The design is set. How is it possible to constraint my junction table as a child table when FK's will become duplicates by default?
create table FactInternetSalesReason
( SalesOrderNumber int,
SalesOrderLineNumber int,
SalesReasonKey int,
CONSTRAINT FK_SalesOrder FOREIGN KEY (SalesOrderNumber, SalesOrderLineNumber) REFERENCES FactInternetSales (SalesOrderNumber, SalesOrderLineNumber),
CONSTRAINT FK_SalesReason FOREIGN KEY (SalesReasonKey) REFERENCES DimSalesReason (SalesReasonKey)
);
A Foreign Key can contain duplicates (try it). A Primary Key cannot.
Related
I have following question: let's say we have a Chen-Notation 1:n and m:n.
So 1 has a primary key and n also, where do I type the foreign key ? in the n ?
And the second question is about m:n, both have a primary key, and I need 1 more table because it's m:n, do I type the both primary keys as foreign keys in the 3rd table?
Example of a 1:n relationship : customers and orders
One customer may have several orders. In this situation, you want a column in the orders table with a foreign key that references the primary key of the customers table.
Sample DDL:
create table customers (
id int primary key,
name varchar(50),
email varchar(50)
);
create table orders (
id int primary key
price float,
customer_id int foreign key references customer(id)
);
Example of a n:m relationship : books and authors
A book may be written by more than one author. An author may have written more than one book. You create a bridge table, also called junction table, called books_authors, to represent that relationship, and that contains foreign keys to the two other tables.
Sample:
create table books (
id int primary key,
name varchar(50)
);
create table authors (
id int primary key,
name varchar(50)
);
create table books_authors(
book_id int foreign key references books(id),
author_id int foreign key references authors(id),
constraint pk_books_authors primary key(book_id, author_id)
);
So 1 has a primary key and n also, where do I type the foreign key ? in the n ?
The foreign key lives in the n, because 1 can have many keys, but you can't have a field that holds multiple values, you need to have one value per field, so it's in the n.
And the second question is about m:n, both have a primary key, and I need 1 more table because it's m:n, do I type the both primary keys as foreign keys in the 3rd table?
Yes, because that 3rd table in effect has a many-to-one relationship to both tables.
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.
For instance, if I have a students table:
CREATE TABLE student (
student_id NUMBER(8),
student_name VARCHAR2(30),
CONSTRAINT pk_student PRIMARY KEY (student_id)
);
And a subject table:
CREATE TABLE subject (
subject_id NUMBER(8),
subject_name VARCHAR2(30),
CONSTRAINT pk_subject PRIMARY KEY (subject_id)
);
And then I create a third table of student's favorites subjects:
CREATE TABLE fav_sub (
student_id NUMBER(8),
subject_it NUMBER(8),
CONSTRAINT pk_fav_sub PRIMARY KEY (student_id, subject_id),
CONSTRAINT fk_1_fav_sub FOREIGN KEY (student_id) REFERENCES student(student_id),
CONSTRAINT fk_2_fav_sub FOREIGN KEY (subject_id) REFERENCES subject(subject_id)
);
Do I then need to manually create indexes for the foreign keys in the fav_sub table such as:
CREATE INDEX in_1_fav_sub ON fav_sub(student_id);
CREATE INDEX in_2_fav_sub ON fav_sub(subject_id);
Or are the indexes for the foreign keys automatically created by the database, since they're part of the composite key?
Edit: Just to clarify, I'm not asking if an index for a foreign key is automatically created, I'm asking if an index for a foreign key is created WHEN it's part of a composite key, since Oracle automatically indexes primary keys.
The creation of the primary key indexes the combination of [student_id, subject_id]. Adding foreign key constraints to each individual column does not create an index on them, and if you want it (which is probably a good idea), you'd have to manually create it.
I have a language map table that each entry has the possibility of a foreign key relationship with a few different tables. What is the best schema to deal with this configuration?
Tables: LanguageMap, TableA, TableB
These are the two possibility:
1. Lookup Column Method - No Foreign Key Constraints:
Create Table LanguageMap (
Id int not null primary key,
Language nvarchar not null,
Value nvarchar not null,
Type nvarchar not null, -- 'TableA', 'TableB', etc.
ForeignTableId int not null -- Is Foreign key to another table dependent on the type of the row.
)
2. Multiple Foreign Key Columns
create Table LanguageMap(
Id int not null primary key,
Language nvarchar not null,
Value nvarchar not null,
Type nvarchar not null, -- 'Activity', 'Verb', etc.
TableAId int null,
TableBId int null
)
alter table LanguageMap add constraint FK_LanguageMap_TableA
foreign key (TableAId) references TableA (Id)
alter table LanguageMap add constraint FK_LanguageMap_TableA
foreign key (TableBId) references TableB (Id)
alter table LanguageMap add constraint CK_LanguageMap_OneIsNotNull
check (TableAId is not null or TableBId is not null)
go
alter table LanguageMap add constraint CK_LanguageMap_OneIsNull
check (TableAId is null or TableBId is null)
go
The foreign key constraints are based on Foreign Key for either-or column?
There is another alternative, called "Shared Primary Key". You can look this up. If TableA, TableB, TableC, etc. all "inherit" their PK as a copy of the PK from some Master table, called "TableMaster" for example, then you can just use that as an FK in LanguageMap.
The correct joins will select the correct instances.
The shared primary key is often used in conjunction with a design pattern called "Class Table Inheritance". Without knowing what TableA, TableB, TableC, etc. are about, I can't say whether Class Table Inheritance is relevant to your case.
In any event, look up both "Shared Primary Key" and "Class Table Inheritance" for further reading.
There are tags with those names in this area.
I need to introduce a many-to-many relationship between two tables, which both have an integer for primary key, in a SQL Server database. How is this best done in T-SQL?
Consider the following two example table definitions for which there should be a many-to-many relationship:
CREATE TABLE [dbo].[Authors] (
[Id] INT IDENTITY (1, 1) NOT NULL,
CONSTRAINT [PK_Versions] PRIMARY KEY CLUSTERED ([Id] ASC)
);
CREATE TABLE [dbo].[Books] (
[Id] INT NOT NULL,
PRIMARY KEY CLUSTERED ([Id] ASC)
);
The traditional way is to use an additional many:many (junction) table, which links to both tables:
CREATE TABLE [dbo].[AuthorsBooks] (
-- Optionally, we can give the table its own surrogate PK
[Id] INT IDENTITY(1,1) NOT NULL,
AuthorId INT NOT NULL,
BookId INT NOT NULL,
-- Referential Integrity
FOREIGN KEY(AuthorId) REFERENCES Authors(Id),
FOREIGN KEY(BookId) REFERENCES Books(Id),
-- PK is either the surrogate ...
PRIMARY KEY CLUSTERED ([Id] ASC)
-- ... Or the compound key
-- PRIMARY KEY CLUSTERED (AuthorId, BookId)
);
One moot point is whether you want the compound key AuthorId, BookId to be the Primary Key, or whether to add your own new Surrogate - this is usually a subjective preference.
Some of the points to consider whether going for a compound primary key or a new surrogate key for the Junction table:
Without the surrogate, external tables linking to the junction table would need to store both compound keys (i.e. would need to retain both AuthorId and BookId as foreign keys).
So a new surrogate offers the potential benefit of a narrower primary key, which then means any tables linking to this junction table will have a single, narrower foreign key.
However, with the compound keys, there can be an optimisation benefit that tables can join directly to the underlying Books or Authors tables without first joining to the junction table.
The following diagram hopefully makes the case of the compound key clearer (the middle table Nationality is a junction table of PersonCountry):
Edit
Usage is straightforward - if the link exists in the many:many table, then the relationship is deemed to exist. To test the existence, you 'join through' the link table e.g.
-- Find all books written by AuthorId 1234
SELECT b.*
FROM Books b
INNER JOIN AuthorsBooks ab
ON b.Id = ab.BookId
WHERE ab.AuthorId = 1234;