Can one attribute have two foreign keys? - database

Just doing some Relational Database work.
Quick question, can one attribute have two foreign keys?
For example, is this legal:
PERSONAL_RECORDS.Date_of_birth has a foreign key in CASUAL.Date_of_birth as well as a foreign key in MANAGER.Date_of_birth
Basically, can one attribute, have a foreign key from two other attributes?
Thank you in advance! :)

A single column can reference more than one table.
create table t1 (
t1_id integer primary key
);
create table t2 (
t2_id integer primary key
);
create table t3 (
t3_id integer primary key,
foreign key (t3_id) references t1 (t1_id),
foreign key (t3_id) references t2 (t2_id)
);

Tricky question actually, i would read: http://office.microsoft.com/en-us/access-help/design-the-tables-for-a-new-database-RZ101772996.aspx?section=9 for a bit more information on the subject. From what i recall from the schoolbench, it's not possible. But there might be a way to do it?
Multiple Foreign keys to a single table and single key pointing to more than one table also goes into a little detail regarding this.
Good luck though :)

Related

Foreign Key Referencing a Technical Key

So, I've got a table created like so:
create table CharacterSavingThrow
(
CharacterCode int not null,
constraint FK_CharacterSavingThrowCharacterID foreign key (CharacterCode) references Character(CharacterCode),
FortitudeSaveCode int not null,
constraint FK_CharacterSavingThrowFortitudeSaveCode foreign key (FortitudeSaveCode) references SavingThrow(SavingThrowCode),
ReflexSaveCode int not null,
constraint FK_CharacterSavingThrowReflexSaveCode foreign key (ReflexSaveCode) references SavingThrow(SavingThrowCode),
WillSaveCode int not null,
constraint FK_CharacterSavingThrowWillSaveCode foreign key (WillSaveCode) references SavingThrow(SavingThrowCode),
constraint PK_CharacterSavingThrow primary key clustered (CharacterCode, FortitudeSaveCode, ReflexSaveCode, WilSaveCode)
)
I need to know how I would reference the primary key of this table from another table's constraint? Seems like a pretty simple question, either it's possible or not, right? Thanks for your guys's help!
Yes - totally easy - you just have to specify the complete compound index, e.g. your other table also needs to have those four columns that make up the PK here, and then the FK constraint would be:
ALTER TABLE dbo.YourOtherTable
ADD CONSTRAINT FK_YourOtherTable_CharacterSavingThrow
FOREIGN KEY(CharacterCode, FortitudeSaveCode, ReflexSaveCode, WilSaveCode)
REFERENCES dbo.CharacterSavingThrow(CharacterCode, FortitudeSaveCode, ReflexSaveCode, WilSaveCode)
The point is: if you have a compound primary key (made up of more than one column), any other table wanting to reference that table also must have all those columns and use all those columns for the FK relationship.
Also, if you're writing queries that would join those two tables - you would have to use all columns contained in the compound PK for your joins.
That's one of the main drawbacks of using four columns as a PK - it makes FK relationships and JOIN queries awfully cumbersome and really annoying to write and use. For that reason, in such a case, I would probably opt to use a separate surrogate key in the table - e.g. introduce a new INT IDENTITY on your dbo.CharacterSavingThrow table to act as primary key, that would make it a lot easier to reference that table and write JOIN queries that use that table.

Relationships between tables

I have a table called objectives, each objective has zero to many cause-effect relationships with other objectives, these relationships I have to be stored in the database, let me know if there's a way to relate this table records.
There is not a way to relate the records without creating an additional table (you would need N-1 additional columns on your current table to model the N possible effects of a cause).
Creating an additional table like the one below should serve your purpose.
CREATE TABLE cause_effect (
cause integer NOT NULL,
effect integer NOT NULL,
CONSTRAINT cause_effect_pkey PRIMARY KEY (cause, effect),
CONSTRAINT cause_effect_cause_fkey FOREIGN KEY (cause)
REFERENCES yourtable (id),
CONSTRAINT cause_effect_effect_fkey FOREIGN KEY (effect)
REFERENCES yourtable (id)
)
Apply FKey behaviour as applies.

SQLite, how to entities associations without foreign keys?

I am trying to figure out the way of creating table without a foreign key under sqlite. I would like to avoid the use of foreign key due its incompatibility under some applications I am working now.
Could anyone please show a simple example with maybe two tables? Thank you.
Simple example: How do I select all tracks from one specific artist?
CREATE TABLE artist(
artistid INTEGER PRIMARY KEY,
artistname TEXT
);
CREATE TABLE track(
trackid INTEGER,
trackname TEXT,
trackartist INTEGER
);
You can have relationships between tables without declaring a foreign key. You simply do
SELECT a.*, t.* FROM artist a INNER JOIN track t ON a.artistid = t.trackartist;
(substituting the actual columns you want in place of a.*, t.*).
You can do this without declaring that trackartist is a foreign key to artist(artistid). If you do make that declaration, the difference is that SQLite will ensure that you never put a value in trackartist that is not a valid artistid and that you never change or remove an artistid that is used in trackartist.
Foreign keys are a mechanism to maintain the integrity of the association between tables but you can "create" any association you want in a SELECT statement independent of any primary or foreign keys declared in the database.
If you don't specify a foreign key, then there is no foreign key.
SELECT t.trackname, t.trackid
FROM track t
INNER JOIN artist a
ON a.artistid = t.trackartist
WHERE a.artistname = 'Alex'

Database Schema Question

If I use the primary key of a table as the primary key of another table is it still a foreign key?
e.g.
Two tables albums and special offers
AlbumId is the primary key in both
How do I represent this relation using primary key foreign key notation?
Yes, it's still a primary key. It's usually called a one-to-one relation.
You can do something like:
create table albums (
album_id integer primary key,
-- other fields...
);
create table special_offers (
album_id integer primary key references albums(album_id),
-- other fields...
);
if e.g you have several special offers for the same album AlbumId is no longer unique in the special offers table. I would think about adding a SpecialOfferId and design a one-to-many relation.
Pablo Santa Cruz is right - yes, you're allowed to do this. However, philosophically, it's only meaningful if there really is a one-to-one relationship - all albums have one and only one special offer, and all special offers have one and only one album.
Guessing from your problem domain, that's not the case - some albums have no special offers, some have 1, some have many.
If that is indeed true, bw_üezi is right - create a one-to-many relationship.
create table albums (
album_id integer primary key,
-- other fields...
);
create table special_offers (
special_offer_id integer primary key,
album_id integer foreign key references albums(album_id),
-- other fields...
);

constraint on RowParentId within same table?

How do I specify constraint on my field that allows null but if value exists it should be one of values of primary key within existing table?
Take a look at the code:
CREATE TABLE TestTable
(
RowId int IDENTITY NOT NULL PRIMARY KEY,
RowParentId int NULL, -- < how do I specify constraint that RowParentId if not NULL should be RowId (foreign key to existing table?)
RowName nvarchar(30),
RowShortName nvarchar(10)
)
GO
I want to be able to generate parent child view without limiting depth and enforcing constraint on existing parent.
Hope I was able to convey what I'm looking for.
Cheers
Isn't that just a foreign key?
RowParentId int NULL references ParentTable (ParentTableIdColumn),
if it is not null, then it must be a value from the parent table.
ALTER TABLE TestTable
ADD CONSTRAINT fk_testtable_parent
FOREIGN KEY (RowParentId)
REFERENCES TestTable(RowId)
Note that keeping a NULL in the column is a bad idea, as it's not searcheable by indexes.
You better add a surrogate record with id = 0, reference your real root to this record, and exclude it from selects.
You can have a foreign key constraint that references back to the same table. You may want to look into other models for hierarchies though. The linked chain model has a lot of problems in SQL. Do a Google on "Joe Celko hierarchies" and you should be able to find information on other ways to model a hierarchy.
You want to create a foreign key. There are several ways to do this, but the simplest way for a single key like this would be to add the following after the workld "null" for that column:
references table_name (column_name)
You may need to add the words "foreign key" before that, I can't remember. Either way that should take care of it.
ALTER TABLE [dbo].TestTable WITH CHECK ADD CONSTRAINT [FK_TestTable_RowId_TestTable_RowParentId] FOREIGN KEY(RowParentId) REFERENCES TestTable(RowId)

Resources