我把我自己的數據庫和我見過的例子放在一起,Foriegn Key也可以設置爲主鍵。SQL Server 2008:如何將PK設置爲PK?
我正在創建我的表格,以便我所有的FK都是PK。這是錯的嗎? FK何時應該成爲PK?它是否必須是PK?
主鍵在他們自己的表中是有意義的......作爲Id和身份。但是,當使用Id是另一張桌子時,它是否也必須是PK?
我把我自己的數據庫和我見過的例子放在一起,Foriegn Key也可以設置爲主鍵。SQL Server 2008:如何將PK設置爲PK?
我正在創建我的表格,以便我所有的FK都是PK。這是錯的嗎? FK何時應該成爲PK?它是否必須是PK?
主鍵在他們自己的表中是有意義的......作爲Id和身份。但是,當使用Id是另一張桌子時,它是否也必須是PK?
當您試圖創建一個1 to 1
或1 to zero/1
映射時,外鍵只應該是主鍵。
實施例:
我有一個Person表,僱員表,和承包商表。所有員工都是人,所有承包商都是人,每個人都是員工或承包商。
基本上,您最終會得到類似的結果。
在回答你的人有多個地址,你應該建立一個關聯表。這是一張圖。
正如你可以看到現在每個人都可以有多個地址和因爲每個員工是一個人,然後每一位員工都可以有多個地址。承包商也是如此。
編輯:下面是從SQL Server更改腳本
BEGIN TRANSACTION
SET QUOTED_IDENTIFIER ON
SET ARITHABORT ON
SET NUMERIC_ROUNDABORT OFF
SET CONCAT_NULL_YIELDS_NULL ON
SET ANSI_NULLS ON
SET ANSI_PADDING ON
SET ANSI_WARNINGS ON
COMMIT
BEGIN TRANSACTION
GO
CREATE TABLE dbo.Address
(
AddressId bigint NOT NULL,
Address nvarchar(50) NULL,
City nvarchar(50) NULL,
State nvarchar(50) NULL
) ON [PRIMARY]
GO
ALTER TABLE dbo.Address ADD CONSTRAINT
PK_Address PRIMARY KEY CLUSTERED
(
AddressId
) WITH(STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
GO
ALTER TABLE dbo.Address SET (LOCK_ESCALATION = TABLE)
GO
COMMIT
BEGIN TRANSACTION
GO
CREATE TABLE dbo.Person
(
PersonId bigint NOT NULL,
Name nvarchar(50) NULL
) ON [PRIMARY]
GO
ALTER TABLE dbo.Person ADD CONSTRAINT
PK_Person PRIMARY KEY CLUSTERED
(
PersonId
) WITH(STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
GO
ALTER TABLE dbo.Person SET (LOCK_ESCALATION = TABLE)
GO
COMMIT
BEGIN TRANSACTION
GO
CREATE TABLE dbo.PersonAddress
(
PersonId bigint NOT NULL,
AddressId bigint NOT NULL
) ON [PRIMARY]
GO
ALTER TABLE dbo.PersonAddress ADD CONSTRAINT
PK_PersonAddress PRIMARY KEY CLUSTERED
(
PersonId,
AddressId
) WITH(STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
GO
ALTER TABLE dbo.PersonAddress ADD CONSTRAINT
FK_PersonAddress_Person FOREIGN KEY
(
PersonId
) REFERENCES dbo.Person
(
PersonId
) ON UPDATE NO ACTION
ON DELETE NO ACTION
GO
ALTER TABLE dbo.PersonAddress ADD CONSTRAINT
FK_PersonAddress_Address FOREIGN KEY
(
AddressId
) REFERENCES dbo.Address
(
AddressId
) ON UPDATE NO ACTION
ON DELETE NO ACTION
GO
ALTER TABLE dbo.PersonAddress SET (LOCK_ESCALATION = TABLE)
GO
COMMIT
BEGIN TRANSACTION
GO
CREATE TABLE dbo.Employee
(
EmployeeId bigint NOT NULL,
EmployeeNumber nvarchar(50) NULL
) ON [PRIMARY]
GO
ALTER TABLE dbo.Employee ADD CONSTRAINT
PK_Employee PRIMARY KEY CLUSTERED
(
EmployeeId
) WITH(STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
GO
ALTER TABLE dbo.Employee ADD CONSTRAINT
FK_Employee_Person FOREIGN KEY
(
EmployeeId
) REFERENCES dbo.Person
(
PersonId
) ON UPDATE NO ACTION
ON DELETE NO ACTION
GO
ALTER TABLE dbo.Employee SET (LOCK_ESCALATION = TABLE)
GO
COMMIT
BEGIN TRANSACTION
GO
CREATE TABLE dbo.Contractor
(
ContractorId bigint NOT NULL,
ContractorNumber nvarchar(50) NULL
) ON [PRIMARY]
GO
ALTER TABLE dbo.Contractor ADD CONSTRAINT
PK_Contractor PRIMARY KEY CLUSTERED
(
ContractorId
) WITH(STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
GO
ALTER TABLE dbo.Contractor ADD CONSTRAINT
FK_Contractor_Person FOREIGN KEY
(
ContractorId
) REFERENCES dbo.Person
(
PersonId
) ON UPDATE NO ACTION
ON DELETE NO ACTION
GO
ALTER TABLE dbo.Contractor SET (LOCK_ESCALATION = TABLE)
GO
COMMIT
的FK應該只也是一個PK,如果兩個表有一個一對一的關係,第二個表中添加因爲第一個過於寬泛,而且這些都是大多數查詢中不需要的項目。
如果您有一對多關係或多對多關係,它將無法工作。
FKs更經常也不是PK。如果我有人員表和相關的地址表,如果我將PK和FK設置爲同一個地址,那麼我只能存儲一個地址,但大多數地址表允許同一個人或組織使用多個地址。在這種情況下,您將有和AddressID作爲PK和person_id作爲FK到person表。這是最常見的PK/FK情況。
只有一種情況需要FK也是PK。
當表表示一個子類,或子集,在PK表的事,例如,EG,SalariedEmployees表具有FK到僱員表...
甲FK是一個字段指示到另一張桌子的PK。而已。
鏈接到自身的表格可能包含指向其自己的PK的FK。
也是FK的PK只能發生在1對1關係的子表中。
給定列既是PK又是FK的一種情況是gen-spec設計模式的關係模型。在其他答案之一中,「員工」是人員的專業化「僱員表中的PK引用人員表中的PK因此專業表格中的PK也是FK
這允許創建的觀點,即加入員工和個人在一個視圖中提供有關員工的所有數據,無論這些數據是員工特有的數據(如「僱傭日期」)還是所有人共同的數據,無論他們是否是員工(例如「出生日期「)
使每一個PK都成爲FK並不是一個好習慣,FK應該反映數據的邏輯結構,如果邏輯模型不合邏輯,你就會遇到麻煩
因此,例如,如果t這裏是一個用戶表和一個地址表。 UserAddress表是1對1,對嗎?那是什麼時候FK也會成爲PK? – dcolumbus 2010-12-22 20:36:10
假設用戶只有一個地址 – 2010-12-22 20:37:34