Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Conditional foreign key in SQL

i have one table called as PartyChannel having following columns

 ID, ChannelID, ChannelType

ChannelID stores MailID or PhoneID or EmailID depending on the ChannelType.

so how can i create a foreign key between PartyChannel and all three tables (Mail, Email and Phone) depending on the channelType.

like image 336
Khuzema Kamaal Avatar asked Dec 23 '10 14:12

Khuzema Kamaal


People also ask

Can two foreign keys reference each other?

It is perfectly fine to have two foreign key columns referencing the same primary key column in a different table since each foreign key value will reference a different record in the related table.

How do I reference a foreign key in SQL?

Using SQL Server Management Studio Open the Table Designer for the table containing the foreign key you want to view, right-click in the Table Designer, and choose Relationships from the shortcut menu. In the Foreign Key Relationships dialog box, select the relationship with properties you want to view.

Can you reference a foreign key?

A foreign key can reference any field defined as unique. If that unique field is itself defined as a foreign key, it makes no difference. A foreign key is just to enforce referential integrity.

Can SQL have two foreign keys?

A table can have multiple foreign keys based on the requirement.


1 Answers

You can use PERSISTED COMPUTED columns with a case statement but in the end, it buys you nothing but overhead.

The best solution would be to model them as three distinct values to start with.

CREATE TABLE Mails (MailID INTEGER PRIMARY KEY)
CREATE TABLE Phones (PhoneID INTEGER PRIMARY KEY)
CREATE TABLE Emails (EmailID INTEGER PRIMARY KEY)

CREATE TABLE PartyChannel (
  ID INTEGER NOT NULL
  , ChannelID INTEGER NOT NULL
  , ChannelType CHAR(1) NOT NULL
  , MailID AS (CASE WHEN [ChannelType] = 'M' THEN [ChannelID] ELSE NULL END) PERSISTED REFERENCES Mails (MailID)
  , PhoneID AS  (CASE WHEN [ChannelType] = 'P' THEN [ChannelID] ELSE NULL END) PERSISTED REFERENCES Phones (PhoneID)
  , EmailID AS  (CASE WHEN [ChannelType] = 'E' THEN [ChannelID] ELSE NULL END) PERSISTED REFERENCES Emails (EmailID)
)

Disclaimer

just because you can doesn't mean you should.

like image 74
Lieven Keersmaekers Avatar answered Oct 15 '22 01:10

Lieven Keersmaekers