如何处理 sql 中的多用途列?

How to address a multiple purpose column in sql?

场景

我需要从多个来源和目的地设计一个设备运动。我有以下示例表:

CREATE TABLE Area{
    Id INT,
    Name VARCHAR(50),
    //some other fields
}

CREATE TABLE Stowage{
    Id Int,
    Name VARCHAR(50),
    //some other fields
}

CREATE TABLE Movement{
    OriginId INT,
    DestinationId INT,
}

但我需要一些动作,例如:

  1. 产地:面积; 目的地:地区
  2. 产地:面积; 目的地:积载
  3. 产地:积载; 目的地:地区
  4. 产地:积载; 目的地:积载

但是我只有两列,每列需要一个以上的外键。

心中的可能解决方案

  1. 创建 MovementArea、MovementStowage、MovementStowageArea 表并创建其适当的外键。
  2. 不要为 OriginId 和 DestinationId 列创建外键并根据需要进行填充。

最后一个问题

在 sql 中是否有其他方法可以解决此问题,或者提供的解决方案中哪种最适合这种情况?

棘手。你有 4 个外键,所以我 [自然] 创建 4 个外键列,如:

create table movement (

  origin_area int,
  origin_stowage int,
  dest_area int,
  dest_stowage int,

  constraint fk1 foreign key origin_area references area (id),
  constraint fk2 foreign key origin_stowage references stowage (id),
  constraint fk3 foreign key dest_area references area (id),
  constraint fk4 foreign key dest_stowage references stowage (id),

  constraint chk_fk1 check (origin_area is null and origin_stowage is not null
                         or origin_area is not null and origin_stowage is null),
  constraint chk_fk2 check (dest_area is null and dest_stowage is not null
                         or dest_area is not null and dest_stowage is null)
);

现在,如您所见:

  • 有 4 个可空 FK 列。
  • 每个外键列都有对应的外键约束。
  • 此外,origin_areaorigin_stowage 是互斥的。始终其中一个为 null,而另一个指向另一个 table。这是由约束 chk_fk1.
  • 强制执行的
  • dest_areadest_stowage 也是如此。由 chk_fk2.
  • 强制执行

我的第一个想法是这样的:

Create Table MovementEndpoint
(
    ID Int
    , Name Varchar(50)
    , EndpointType Int              -- Area, Stowage, etc
    , EndpointDetailID Int          -- FK to Area, Stowage, etc
)

现在您的移动只是在端点之间进行,MovementEndpoint 记录可让您根据需要到达 Area 或 Stowage 记录。查询逻辑仍然会有些棘手,但不会超过您的初始设计要求。