外键上的外键 - SQL Server

时间:2015-09-18 09:27:11

标签: sql sql-server foreign-keys constraints

我正在为一个项目创建一个数据库,我需要为了检查约束而在另一个外键上声明一个外键。

我有一个Person表和一个Groups表,这两个表都包含DepartmentID。每当我在Task表中插入新任务时,我想检查Groups.DepartmentID是否与Person.DepartmentID匹配。

这个想法是一个任务链接到一个人,有两种类型,一个grouptype定义它的数据库是否工作,财务工作等,以及一个任务类型,它定义了它的维护,培训等。当一个人试图添加一个使用不适合他/她部门的groupType的任务应该失败。

我尝试将这些属性作为外键添加到Task表中,但是在Microsoft SQL Server中不接受在非唯一或非主键上声明外键({{1} DepartmentIDPerson表中的{}不能是唯一的!)。

任何人都知道如何解决这个问题?

Group

这些是任务表中不接受的FK属性:

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
)

1 个答案:

答案 0 :(得分:1)

向这些表添加更宽的“超级密钥”,其中包括主键附加列 1 ,然后使用它们声明外键。你是否也删除了多余的小外键是一个品味问题:

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
)

(我还将GDIDPDID合并到DepartmentID中 - 如果它们总是平等的,为什么要存储两次,然后必须有另一个约束来断言它们的平等?)

1 如果主键(或唯一键)足以唯一标识每一行,那么包含键列其他列的任何更宽的键也必须足够唯一地标识每一行。