我有 PILOT1
和 PILOT2
SIN 与 SHIP ID
。
我不想要这个:
ship1 111 222 4 20 idk 23.33 gop
ship1 222 111 4 20 idk 23.33 gop
看看 shipID
是如何相同的以及相同的飞行员正在操作这艘船。我想要一种方法来限制这一点。这是有效的,因为飞行员 ID 不同:
ship1 111 222 4 20 idk 23.33 gop
ship1 232 111 4 20 idk 23.33 gop
CREATE TABLE Ship (
shipID varchar(30) NOT NULL,
pilot1_SIN varchar(11) NOT NULL,
pilot2_SIN varchar(11) NOT NULL,
years_in_operation INT,
num_of_seats INT,
manufacturer varchar(30),
advertising_revenue FLOAT,
fuel_type varchar(15)
PRIMARY KEY (shipID, pilot1_SIN, pilot2_SIN),
FOREIGN KEY (pilot1_SIN) REFERENCES Pilot(SINumber),
FOREIGN KEY (pilot2_SIN) REFERENCES Pilot(SINumber),
CONSTRAINT check_pilots CHECK (pilot1_SIN != pilot2_SIN)
);
最佳答案
不幸的是,正如 @Barmar 所指出的,即使在 8.0 版本中,MySQL 也会完全忽略任何 CHECK CONSTRAINTS
您可以按照@TheImpaler的建议使用BEFORE INSERT
触发器
对于开箱即用的解决方案,您可以使用 generated column
pilot_check_unique VARCHAR(23) AS (CONCAT(
LEAST(pilot1_SIN,pilot2_SIN), ':', GREATEST(pilot1,pilot2)
)) NOT NULL UNIQUE
如果表不是 InnoDB,则必须通过在 UNIQUE
之前放置 STORED
来创建列 STORED
,这当然会增加表使用的磁盘空间
遗憾的是,这不会验证 pilot1
不等于 pilot2
,我想你可以添加
pilot_check_not_equal TINYINT(1) AS (
CASE WHEN pilot1_SIN != pilot2_SIN THEN 1 END CASE
) NOT NULL
但我不能 100% 确定它会被允许
注意 说了这么多,我发现在我的项目中总是存在数据库层无法轻松解决的验证问题。我很想在应用程序层验证这种情况。只要您只有一个代码区域可以INSERT
或UPDATE
此代码,就应该没问题。
附录
另一个选项是将您的 Ship
表分成 Ship
和 Ship_pilot
CREATE TABLE Ship (
shipID varchar(30) NOT NULL,
years_in_operation INT,
num_of_seats INT,
manufacturer varchar(30),
advertising_revenue FLOAT,
fuel_type varchar(15)
PRIMARY KEY (shipID)
);
CREATE TABLE Ship_Pilot (
shipID varchar(30) NOT NULL,
pilot_SIN varchar(11) NOT NULL,
position TINYINT(3) UNSIGNED NOT NULL
PRIMARY KEY (shipID, pilot_SIN),
FOREIGN KEY (pilot_SIN) REFERENCES Pilot(SINumber),
UNIQUE KEY (shipID, position)
);
这样您就不会重复一艘船的飞行员或职位,但每艘船将允许 0-256 名不同的飞行员
旁白
我还建议以下内容
- 使用
UNSIGNED
整数类型作为 ID - 对
num_of_seats
和years_in_operation
使用UNSIGNED
整数,大概不能为负数 - 为每个
fuel_type
和manufacturer
使用单独的表,并使用UNSIGNED
整数引用它们,而不是重复的名称 - 您的船舶表有一个复合 PK,这将允许同一个表中多次出现相同的
shipID
(使用不同的飞行员) - 这是正确的吗? - 对
advertising_revenue
使用DECIMAL
或整数类型以提高精度
关于mysql - 如何检查 SQL 表中是否存在一对。约束,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52748892/