3

我正在尝试限制字段中的输入错误。我正在构建的站点包含有关汽车的数据。

一辆车可以有一个列表中的多个设备(空调、ABS、真皮座椅等),我想以某种方式防止数据输入出错,或者至少将其最小化。

第一种错误情况是为 2 个或更多互斥设备输入数据时。例如,汽车不能有手动空调和自动空调和自动空调双区。只有其中一个可以存在于汽车中。

第二种错误情况是在没有先决条件的情况下为设备输入数据。例如,在没有所需 ABS 的情况下输入紧急制动辅助 (BA)。一辆汽车可以有 ABS 没有 BA,但 BA 只存在于有 ABS 的汽车中。

输入数据的表格很简单。每辆车( version_id )都有多个设备(装饰)或 trim_ids。Version_id 和 trim_id 分别是表版本和修剪的 FK。所以不存在的 trim_id 或 version_id 的错误已经在表 versiontrim 中处理了。

表版本修剪(我想最小化数据错误的地方)

version_id    trim_id

餐桌装饰:

trim_id    trim    trimtype

表版本

version_id    model_id    version    active    bodytype    places    motor_id    etc...

我感谢任何帮助。

4

2 回答 2

1
For each selected trim,
    Retrieve the set of mutually exclusive trims.
    Check if any of those are also selected.
    Retrieve the set of prerequisite trims.
    Check that each of those are also selected.
create table prerequisites (
    trim_id1 int not null references trims ( trim_id ),
    trim_id2 int not null references trims ( trim_id ),
    primary key ( trim_id1, trim_id2 )
);

create table exclusives (
    exclusive_group int not null,
    trim_id int not null references trims ( trim_id ),
    primary key ( exclusive_group, trim_id ),
    index ( trim_id, exclusive_group )
);

-- Retrieve all prerequisites of selected trims
select p.trim_id1, p.trim_id2
from versions v
inner join versiontrim vt on vt.version_id = v.version_id
inner join prerequisites p on p.trim_id1 = vt.trim_id
where v.version_id = ?;

-- Retrieve all mutually exclusive trims of selected trims
select vt.trim_id as trim_id1, e2.trim_id as trim_id2
from versions v
inner join versiontrim vt on vt.version_id = v.version_id
inner join exclusives e1 on e1.trim_id = vt.trim_id
inner join exclusives e2 on e2.exclusive_group = e1.exclusive_group
where e1.trim_id <> e2.trim_id
and v.version_id = ?;

您可以更进一步,只返回冲突:

-- Retrieve any missing prerequisites of the selected trims
select p.trim_id1, p.trim_id2
from versions v
inner join versiontrim vt1 on vt1.version_id = v.version_id
inner join prerequisites p on p.trim_id1 = vt1.trim_id
left join versiontrim vt2
    on vt2.version_id = v.version_id
    and vt2.trim_id = p.trim_id2
where vt2.version_id is null
and v.version_id = ?;

-- Retrieve any selected mutually exclusive trims
select vt.trim_id as trim_id1, e2.trim_id as trim_id2
from versions v
inner join versiontrim vt on vt.version_id = v.version_id
inner join exclusives e1 on e1.trim_id = vt.trim_id
inner join exclusives e2 on e2.exclusive_group = e1.exclusive_group
inner join versiontrim vt2 on vt2.version_id = v.version_id
where e1.trim_id <> e2.trim_id
and vt2.trim_id = e2.trim_id
and v.version_id = ?;
于 2013-06-30T00:11:17.297 回答
0

如果要在数据库级别对这些依赖项进行建模,则应将这些选项中的每一个视为不同的实体。

由于您当前的结构对 NN 关系进行建模,因此它还允许将相同的选项多次附加到给定的version. 对于所有选项,您应该采用与以下相同的方法。

互斥期权构成期权的“类型”。例如,您描述的空调选项是“空调类型”。

为此,创建一个新实体(例如。aircond_type):

空调类型:
    +----+------------+
    | 编号 | 标签 |
    +----+------------+
    | 1 | 没有 |
    +----+------------+
    | 2 | 手册 |
    +----+------------+
    | 3 | 自动 |
    +----+------------+
    | 4 | 双区 |
    +----+------------+

然后在versions这个新表中添加一个外键。

至于相互依赖的选项,表达依赖关系的关系方式是外键约束。这意味着谓词“版本 X 具有选项 BA”依赖于“版本 X 具有选项 ABS”,这意味着在其自己的表中对每个谓词进行建模,并在这两者之间使用外键约束:

CREATE TABLE version_has_abs (
    version_id INT NOT NULL PRIMARY KEY,
    CONSTRAINT version_fk FOREIGN KEY version_fk_idx(version_id)
        REFERENCES version(version_id)
);

CREATE TABLE version_has_ba (
    version_id INT NOT NULL PRIMARY KEY,
    CONSTRAINT version_fk FOREIGN KEY version_fk_idx(version_id)
        REFERENCES version_has_abs(version_id)
);

这显然是不切实际的,或者至少不灵活。一个简单的验证触发器可以在没有“ABS”选项的情况下进行检查并防止“BA”选项的归属。

或者,对于这个简单的 1-1 依赖关系,您可以将“BA”选项视为“ABS”选项的变体。这样,您将拥有三个“制动”选项:“标准”、“ABS”、“带 BA 的 ABS”。

于 2013-06-30T01:29:10.197 回答