外键上的外键 - SQL 服务器
Foreign key on a Foreign key - SQL Server
我正在为一个项目创建一个数据库,为了检查约束,我需要在另一个外键上声明一个外键。
我有一个 Person
table 和一个 Groups
table,它们都包含一个 DepartmentID
。每当我在 Task
table 中插入新任务时,我想检查 Groups.DepartmentID
是否与 Person.DepartmentID
.
匹配
这个想法是,一个任务与一个人相关联,并且有两种类型,一种定义其数据库工作、财务工作等的组类型,以及定义其维护、培训等的任务类型。当一个人试图添加一个 groupType 不适用于 his/her 部门的任务,它应该会失败。
我尝试将这些属性作为外键添加到 Task
table,但是 Microsoft 不接受在非唯一或非主键上声明外键 SQL 服务器(Person
和 Group
table 中的 DepartmentID
不能是唯一的!)。
有人知道如何解决这个问题吗?
CREATE TABLE Department
(
ID int PRIMARY KEY IDENTITY,
Name varchar(50),
UNIQUE ("Name")
)
CREATE TABLE Groups
(
ID int IDENTITY,
GroupType varchar(50) PRIMARY KEY,
Description varchar(255) DEFAULT ('-'),
DepartmentID int
FOREIGN KEY (DepartmentID) REFERENCES Department(ID),
)
CREATE TABLE Person
(
ID int PRIMARY KEY IDENTITY,
Name varchar(50),
DepartmentID int
FOREIGN KEY (DepartmentID) REFERENCES Department(ID)
)
CREATE TABLE TaskType
(
ID int IDENTITY,
TaskType varchar(50) PRIMARY KEY,
Description varchar(255) DEFAULT ('-'),
)
CREATE TABLE Task
(
ID int IDENTITY,
TimeFrame decimal(4,2),
Yearcount int,
GroupType varchar(50),
TaskType varchar(50),
WeekNr int,
ExceptionDetail varchar(255) DEFAULT ('-'),
PersonID int
)
这些是任务 table 中不被接受的 FK 属性:
GDID int FOREIGN KEY REFERENCES Groups(DepartmentID),
PDID int FOREIGN KEY REFERENCES Person(DepartmentID),
CHECK (GDID = PDID),
UNIQUE ("TaskType", "GroupType", "WeekNr", "Yearcount"),
FOREIGN KEY (TaskType) REFERENCES TaskType(TaskType),
FOREIGN KEY (PersonID) REFERENCES Person(ID),
FOREIGN KEY (GroupType) REFERENCES Groups(GroupType)
向这些包含主键 和 附加列 1 的表添加更宽的 "super keys",然后声明外键使用它们。是否也删除多余的较小外键是个人喜好问题:
CREATE TABLE Groups(
ID int IDENTITY,
GroupType varchar(50) PRIMARY KEY,
Description varchar(255) DEFAULT ('-'),
DepartmentID int FOREIGN KEY (DepartmentID) REFERENCES Department(ID),
constraint Group_Dep_XRef UNIQUE (GroupType,DepartmentID)
)
CREATE TABLE Person(
ID int PRIMARY KEY IDENTITY,
Name varchar(50),
DepartmentID int FOREIGN KEY (DepartmentID) REFERENCES Department(ID),
constraint Person_Dept_XRef UNIQUE (ID,DepartmentID)
)
CREATE TABLE Task(
ID int IDENTITY,
TimeFrame decimal(4,2),
Yearcount int,
GroupType varchar(50),
TaskType varchar(50),
WeekNr int,
ExceptionDetail varchar(255) DEFAULT ('-'),
PersonID int,
DepartmentID int,
constraint FK_Group_Dept_XRef FOREIGN KEY (GroupType,DepartmentID)
references Group (GroupType,DepartmentID),
constraint FK_Person_Dept_XRef FOREIGN KEY (PersonID,DepartmentID)
references Person (ID,DepartmentID),
UNIQUE ("TaskType", "GroupType", "WeekNr", "Yearcount"),
FOREIGN KEY (TaskType) REFERENCES TaskType(TaskType),
FOREIGN KEY (PersonID) REFERENCES Person(ID), --Redundant now
FOREIGN KEY (GroupType) REFERENCES Groups(GroupType) --Also redundant
)
(我还将 GDID
和 PDID
合并为 DepartmentID
- 如果它们总是相等的,为什么要存储两次然后必须有另一个约束来断言他们平等吗?)
1如果主键(或唯一键)足以唯一标识每一行,则包含键列 和 [=25 的任何更宽的键=] 额外的列也必须足以唯一标识每一行。
我正在为一个项目创建一个数据库,为了检查约束,我需要在另一个外键上声明一个外键。
我有一个 Person
table 和一个 Groups
table,它们都包含一个 DepartmentID
。每当我在 Task
table 中插入新任务时,我想检查 Groups.DepartmentID
是否与 Person.DepartmentID
.
这个想法是,一个任务与一个人相关联,并且有两种类型,一种定义其数据库工作、财务工作等的组类型,以及定义其维护、培训等的任务类型。当一个人试图添加一个 groupType 不适用于 his/her 部门的任务,它应该会失败。
我尝试将这些属性作为外键添加到 Task
table,但是 Microsoft 不接受在非唯一或非主键上声明外键 SQL 服务器(Person
和 Group
table 中的 DepartmentID
不能是唯一的!)。
有人知道如何解决这个问题吗?
CREATE TABLE Department
(
ID int PRIMARY KEY IDENTITY,
Name varchar(50),
UNIQUE ("Name")
)
CREATE TABLE Groups
(
ID int IDENTITY,
GroupType varchar(50) PRIMARY KEY,
Description varchar(255) DEFAULT ('-'),
DepartmentID int
FOREIGN KEY (DepartmentID) REFERENCES Department(ID),
)
CREATE TABLE Person
(
ID int PRIMARY KEY IDENTITY,
Name varchar(50),
DepartmentID int
FOREIGN KEY (DepartmentID) REFERENCES Department(ID)
)
CREATE TABLE TaskType
(
ID int IDENTITY,
TaskType varchar(50) PRIMARY KEY,
Description varchar(255) DEFAULT ('-'),
)
CREATE TABLE Task
(
ID int IDENTITY,
TimeFrame decimal(4,2),
Yearcount int,
GroupType varchar(50),
TaskType varchar(50),
WeekNr int,
ExceptionDetail varchar(255) DEFAULT ('-'),
PersonID int
)
这些是任务 table 中不被接受的 FK 属性:
GDID int FOREIGN KEY REFERENCES Groups(DepartmentID),
PDID int FOREIGN KEY REFERENCES Person(DepartmentID),
CHECK (GDID = PDID),
UNIQUE ("TaskType", "GroupType", "WeekNr", "Yearcount"),
FOREIGN KEY (TaskType) REFERENCES TaskType(TaskType),
FOREIGN KEY (PersonID) REFERENCES Person(ID),
FOREIGN KEY (GroupType) REFERENCES Groups(GroupType)
向这些包含主键 和 附加列 1 的表添加更宽的 "super keys",然后声明外键使用它们。是否也删除多余的较小外键是个人喜好问题:
CREATE TABLE Groups(
ID int IDENTITY,
GroupType varchar(50) PRIMARY KEY,
Description varchar(255) DEFAULT ('-'),
DepartmentID int FOREIGN KEY (DepartmentID) REFERENCES Department(ID),
constraint Group_Dep_XRef UNIQUE (GroupType,DepartmentID)
)
CREATE TABLE Person(
ID int PRIMARY KEY IDENTITY,
Name varchar(50),
DepartmentID int FOREIGN KEY (DepartmentID) REFERENCES Department(ID),
constraint Person_Dept_XRef UNIQUE (ID,DepartmentID)
)
CREATE TABLE Task(
ID int IDENTITY,
TimeFrame decimal(4,2),
Yearcount int,
GroupType varchar(50),
TaskType varchar(50),
WeekNr int,
ExceptionDetail varchar(255) DEFAULT ('-'),
PersonID int,
DepartmentID int,
constraint FK_Group_Dept_XRef FOREIGN KEY (GroupType,DepartmentID)
references Group (GroupType,DepartmentID),
constraint FK_Person_Dept_XRef FOREIGN KEY (PersonID,DepartmentID)
references Person (ID,DepartmentID),
UNIQUE ("TaskType", "GroupType", "WeekNr", "Yearcount"),
FOREIGN KEY (TaskType) REFERENCES TaskType(TaskType),
FOREIGN KEY (PersonID) REFERENCES Person(ID), --Redundant now
FOREIGN KEY (GroupType) REFERENCES Groups(GroupType) --Also redundant
)
(我还将 GDID
和 PDID
合并为 DepartmentID
- 如果它们总是相等的,为什么要存储两次然后必须有另一个约束来断言他们平等吗?)
1如果主键(或唯一键)足以唯一标识每一行,则包含键列 和 [=25 的任何更宽的键=] 额外的列也必须足以唯一标识每一行。