Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/mysql/68.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Mysql 如何避免在字段中输入互斥数据_Mysql - Fatal编程技术网

Mysql 如何避免在字段中输入互斥数据

Mysql 如何避免在字段中输入互斥数据,mysql,Mysql,我试图限制字段中的输入错误。我正在建设的网站包含汽车数据 一辆汽车可以有一个列表中的多个设备(空调、ABS、真皮座椅等),我希望以某种方式防止数据输入出错,或者至少将其最小化 第一种错误情况是为两个或多个互斥设备输入数据。例如,一辆汽车不能有手动空调和自动空调以及自动空调两个区域。车里只能有一个 第二种错误情况是在没有先决条件的情况下为设备输入数据。例如,在没有所需ABS的情况下进入紧急制动辅助系统(BA)。汽车可以有ABS 没有BA,但BA将只存在于配备ABS的汽车中 输入数据的表格是直接的。

我试图限制字段中的输入错误。我正在建设的网站包含汽车数据

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

第一种错误情况是为两个或多个互斥设备输入数据。例如,一辆汽车不能有手动空调和自动空调以及自动空调两个区域。车里只能有一个

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

输入数据的表格是直接的。每辆车(版本号)都有多个设备(饰件)或饰件号。版本id和修剪id分别是FK到表格版本和修剪。因此,不存在trim_id或version_id的错误已经在VersionTim表中得到处理

表versiontrim(我希望在其中最小化数据错误)

表饰件:

trim_id    trim    trimtype
表格版本

version_id    model_id    version    active    bodytype    places    motor_id    etc...
非常感谢您的帮助。

对于每个选定的装饰,
检索互斥修剪集。
检查是否也选择了其中任何一项。
检索先决条件修剪集。
检查是否也选择了其中的每一项。
创建表先决条件(
trim_id1 int not null引用trims(trim_id),
trim_id2 int not null引用trims(trim_id),
主键(trim_id1,trim_id2)
);
创建表格专用项(
独占组int不为空,
修剪id int not null引用修剪(修剪id),
主键(专用组,微调id),
索引(修剪id,独占组)
);
--检索所选TRIM的所有先决条件
选择p.trim_id1、p.trim_id2
从第五版开始
内部联接版本在vt.version\u id=v.version\u id上运行
p.trim_id上的内部连接先决条件p=vt.trim_id
其中v.version_id=?;
--检索所选修剪的所有互斥修剪
选择vt.trim_id作为trim_id 1,选择e2.trim_id作为trim_id 2
从第五版开始
内部联接版本在vt.version\u id=v.version\u id上运行
e1.trim\u id=vt.trim\u id上的内部连接专用e1
e2上的内部联接独占e2。独占组=e1。独占组
其中e1.trim_id e2.trim_id
和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 = ?;
--检索所选饰件缺少的任何先决条件
选择p.trim_id1、p.trim_id2
从第五版开始
内部联接版本vt1上的IM vt1.version\u id=v.version\u id
p.trim_id上的内部连接先决条件p=vt1.trim_id
左连接版本TM vt2
在vt2.version\u id=v.version\u id上
和vt2.trim_id=p.trim_id2
其中vt2.version\u id为空
和v.version_id=?;
--检索任何选定的互斥修剪
选择vt.trim_id作为trim_id 1,选择e2.trim_id作为trim_id 2
从第五版开始
内部联接版本在vt.version\u id=v.version\u id上运行
e1.trim\u id=vt.trim\u id上的内部连接专用e1
e2上的内部联接独占e2。独占组=e1。独占组
内部联接版本vt2上的IM vt2.version\u id=v.version\u id
其中e1.trim_id e2.trim_id
和vt2.trim_id=e2.trim_id
和v.version_id=?;

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

由于您当前的结构模拟了N-N关系,因此它还允许将同一选项多次附加到给定的
版本
。对于所有选项,您应采用与下面相同的方法

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

为此,创建一个新实体(例如,
aircond\u type
):

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


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

将业务需求与数据混合在一起……这类事情应该由GUI应用程序或应用程序服务器处理,而不是数据库。您可以使用存储过程插入数据,而不是直接访问表,在这种情况下,您可以在实际插入或插入任何先决条件之前进行任何检查。我在想你的第一句话。在某种程度上,数据库中的所有内容都是由业务需求驱动的,在特定情况下,它与数据的一致性有关。根据存储过程,我仍然需要被介绍给它。在数据库级别进行一些检查是可以的,但在理想情况下,这些检查应该是一个以防万一的防线,你永远不会真正击中它。您的UI和/或应用程序代码应该在更高的级别上执行类似的检查,以提供更好的用户体验,而不仅仅是将用户输入的内容推送到数据库中,然后捕获数据库错误。谢谢jcsanyi,但我不能再多说了。没有其他人能在更高或更低的层次上拿着这个包。后台人员将通过表单或其他方式输入数据,并会犯错误,如果不被发现,我的客户(即网站访问者)将看到这些错误。对我来说,创建或找到一个新的系统来防止这些错误是毫无意义的。mysql中肯定有工具可以做到这一点。顺便说一下,我喜欢Markus Jarderot的建议。这是关于解决问题,而不是把问题传给别人。谢谢。就你对同一个选项被多次附加到同一个版本上的评论而言,我没有提到这一点
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 = ?;
aircond_type: +----+-----------+ | id | label | +----+-----------+ | 1 | none | +----+-----------+ | 2 | manual | +----+-----------+ | 3 | automatic | +----+-----------+ | 4 | bi-zone | +----+-----------+
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)
);