2014-10-19 98 views
1

說我有這樣的結構:外鍵引用許多表的一個

體育

reference int identity not null, primary key (ID), 
Duration int, --e.g. football is 90 minutes 
Players int, 
SportID int, 
SportType int --0 for football and 1 for tennis 

網球

Reference int IDENTITY NOT NULL, 
TurfType int, 
-- + more fields related to Tennis 

足球

等我能想到這樣做的唯一的辦法就是在 Sport表有個
Reference int IDENTITY NOT NULL, 
-- + more fields related to Football 

Sport.SportID引用無論是網球或足球或體操說什麼表Sport.SportID引用。

雖然這看起來不正確。這是最好的方法嗎?

+0

這是一個可怕的方法。由於你「引用」了幾個表中的一個,你基本上**不能**引用任何東西。你應該改變這種關係:'Tennis'應該參考'Sport','Football'應該參考'Sport'--那麼你將擁有**真實的**,可執行的參考完整性約束! – 2014-10-19 13:04:55

+1

@marc_s,那就意味着Sport有FootballID,TennisID等等。會有很多的空值。 – w0051977 2014-10-19 13:07:41

+1

是的 - 那又怎樣? Null的不會傷害....至少這樣,你有**真正的**完整性 - 不僅僅是一個*看起來像*完整,這是沒有價值的... – 2014-10-19 13:08:15

回答

0

您是否試圖給出一項運動的名稱,以便數據庫顯示詳細信息(持續時間,所使用場的類型,球員數量等)?

+1

是的。這是一條評論,而不是一個答案。 – w0051977 2014-10-19 13:05:11

+0

@ w0051977他無法評論他的名譽 – 2014-10-19 13:36:29

+0

@Begueradj,這很公平。除非你有口水,否則不要回答。 – w0051977 2014-10-19 13:38:03

2

具有SportType列是合理的。您可以使用結構接近這個功能,比如:

create table Sports (
    SportsId int identity not null, primary key (ID), 
    Duration int, --e.g. football is 90 minutes 
    Players int, 
    SportType varchar(10), 
    SportId int, 
    check (SportType in ('Football', 'Tennis'), 
    FootballId as (case when SportType = 'Football' then SportId end), 
    TennisId as (case when SportType = 'Tennis' then SportId end), 
    foreign key (FootballId) references Football(FootballId), 
    foreign key (Tennis) references Tennis(Tennis) 
); 

注意,這裏使用計算列外鍵引用,以確保引用完整性。

+0

謝謝+1。說SportID是一個footballID。我將如何做體育和足球之間的內部聯合,以返回兩個表中的所有字段? – w0051977 2014-10-19 13:11:48

+0

@ w0051977。 。 。您可以使用計算列「FootballId」作爲「連接」。 – 2014-10-19 19:49:20

1

在{Sport}和{Tennis/Fotball}之間有"is-a relationship"。在這種情況下,「體育」代表超級班,網球/足球是分班。使用面向對象的編程語言,可以使用繼承完成此設計。

Sport.SportID引用無論是網球或足球或體操等

這意味着,這種關係是唯一的。

在T-SQL中,因爲沒有繼承,一個溶液來實現獨佔是-的關係是使用Type柱和如下的化合物FK(FOREIGN KEY (SportID, Type)):

-- The "superclass" table 
CREATE TABLE dbo.Sport (
    SportID INT IDENTITY(1,1) PRIMARY KEY, 
    Type CHAR(1) NOT NULL CHECK (Type IN ('T', 'F' /*...*/)), 
    UNIQUE(SportID, Type) 
    -- , ... 
); 
GO 
-- The "subclass" tables 
CREATE TABLE dbo.Tennis (
    SportID INT IDENTITY(1,1) PRIMARY KEY, 
    FOREIGN KEY (SportID) REFERENCES dbo.Sport(SportID), 
    Type CHAR (1) NOT NULL CHECK (Type = 'T'), 
    FOREIGN KEY (SportID, Type) REFERENCES dbo.Sport(SportID, Type) 
    -- , ... 
); 
GO 
CREATE TABLE dbo.Fotball (
    SportTypeID INT IDENTITY(1,1) PRIMARY KEY, 
    FOREIGN KEY (SportTypeID) REFERENCES dbo.SportType(SportTypeID), 
    Type CHAR (1) NOT NULL CHECK (Type = 'F'), 
    FOREIGN KEY (SportID, Type) REFERENCES dbo.Sport(SportID, Type) 
    -- , ... 
); 
+0

感謝+1。說SportID是一個footballID。我將如何做體育和足球之間的內部聯合,以返回兩個表中的所有字段? – w0051977 2014-10-19 13:56:44

+0

@ w0051977:答:簡單:'SELECT ... FROM dbo.Sport s INNER JOIN dbo.Fotball f ON s.SportID = f.SportID'。注意:is-a關係應該從子類讀到超類。例如:一個footballID是一個sportID。 – 2014-10-19 14:02:20

+0

如果我只提供一個ID並希望從運動表和特定表中獲得信息足球,網球等等,我不知道,這項運動來自哪個桌子。 – w0051977 2014-10-19 14:04:27