关系数据库设计 - 多组分配

时间:2017-02-04 21:54:44

标签: sql sql-server database tsql

我正在尝试为数据库系统设计出最佳设计。问题是如何最好地为一个有效的关系创建表。 一个人可以是不同组织的成员。每个组织都在自己的表中,因为该组织属于一组组织。我无法合并不同组织组的表格。

我想知道这个人是哪个组织的成员,以及有关被分配到该组织的其他几个细节。 可以将一个人分配到一个组织,然后结束他在该组织的成员资格。每个作业都应该有一个日期。之后他可以再次被分配到该组织。我想跟踪所有作业。

问题在于我无法将所有组织放在一个表中。它们位于不同的表中,因为它们具有不同的属性,而且有些表并不在我的控制之下。

一些示例表(简化):

TABLE people (
    id INT PRIMARY KEY,
    first_name VARCHAR(50),
    last_name VARCHAR(50)
)

TABLE group_assignments (
    id INT PRIMARY KEY
    person_id INT,
    organiation_id INT, -- This is the problem. How to create the proper relation.
    assignment_date DATETIME,
    assignment_end_date DATETIME
)

-- First group of organizations
TABLE airports (
    id INT PRIMARY KEY,
    airport_name VARCHAR(50)
)

-- Second group of organizations
TABLE restaurants (
    id INT PRIMARY KEY,
    restaurant_name VARCHAR(50)
)

-- Third group of organizations
TABLE schools (
    id INT PRIMARY KEY,
    school_name VARCHAR(50)
)

现在让我们说一个人被分配到:
    [airports] id 3
    [restaurants] id 5

另一个人被分配到:
    [restaurants] id 4
    [schools] id 7

我应该如何定义一个可以正确定义这些关系的表?

1 个答案:

答案 0 :(得分:0)

在这种情况下,我认为"共享主键"方法可能是最好的方法。

创建表组织:

create table Organizations (
    OrganizationId int identity primary key,
    . . .
);

然后创建子表:

create table airports (
    AirportId INT PRIMARY KEY,
    airport_name VARCHAR(50),
    constraint fk_airports_airportid
        foreign key (AirportId) references Organizations(OrganizationId)
);

然后,您可以在group_assignmentsOrganizations中拥有外键关系。实际上,我只是将该表称为PersonOrganizations

这种特殊方法可以保持大部分关系完整性。它不保证一个组织"不在多个子表中。这也可以强制执行。

您可以使用子类型执行此操作。这看起来像是:

create table Organizations (
    OrganizationId int identity primary key,
    OrganizationType varchar(255) not null
    . . .,
    constraint unq_OrganizationId_OrganizationType unique (OrganizationId, OrganizationType)  -- needed for foreign key reference validating type
);

create table airports (
    AirportId INT PRIMARY KEY,
    airport_name VARCHAR(50),
    OrganizationType as ('airport')
    constraint fk_airports_airportid
        foreign key (AirportId, OrganizationType) references Organizations(OrganizationId, OrganizationType),
);