如何处理 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,
}
但我需要一些动作,例如:
- 产地:面积; 目的地:地区
- 产地:面积; 目的地:积载
- 产地:积载; 目的地:地区
- 产地:积载; 目的地:积载
但是我只有两列,每列需要一个以上的外键。
心中的可能解决方案
- 创建 MovementArea、MovementStowage、MovementStowageArea 表并创建其适当的外键。
- 不要为 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_area
和 origin_stowage
是互斥的。始终其中一个为 null,而另一个指向另一个 table。这是由约束 chk_fk1
. 强制执行的
dest_area
和 dest_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 记录。查询逻辑仍然会有些棘手,但不会超过您的初始设计要求。
场景
我需要从多个来源和目的地设计一个设备运动。我有以下示例表:
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,
}
但我需要一些动作,例如:
- 产地:面积; 目的地:地区
- 产地:面积; 目的地:积载
- 产地:积载; 目的地:地区
- 产地:积载; 目的地:积载
但是我只有两列,每列需要一个以上的外键。
心中的可能解决方案
- 创建 MovementArea、MovementStowage、MovementStowageArea 表并创建其适当的外键。
- 不要为 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_area
和origin_stowage
是互斥的。始终其中一个为 null,而另一个指向另一个 table。这是由约束chk_fk1
. 强制执行的
dest_area
和dest_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 记录。查询逻辑仍然会有些棘手,但不会超过您的初始设计要求。