我有PILOT1
和PILOT2
的SIN对。
我不想要这样:
SHIP ID
查看ship1 111 222 4 20 idk 23.33 gop
ship1 222 111 4 20 idk 23.33 gop
是如何相同的,并且相同的飞行员正在操作该船。我想要一种方法来约束这一点。这是有效的,因为飞行员ID不同:
shipID
ship1 111 222 4 20 idk 23.33 gop
ship1 232 111 4 20 idk 23.33 gop
答案 0 :(得分:1)
不幸的是,正如@Barmar所指出的那样,即使在8.0版中,MySQL也完全忽略了任何CHECK CONSTRAINTS
您可以根据建议使用BEFORE INSERT
触发器@TheImpaler
对于开箱即用的解决方案,您可以使用generated column
pilot_check_unique VARCHAR(23) AS (CONCAT(
LEAST(pilot1_SIN,pilot2_SIN), ':', GREATEST(pilot1,pilot2)
)) NOT NULL UNIQUE
如果表不是InnoDB,则必须通过将STORED
放在STORED
之前来创建列UNIQUE
,这当然会增加表使用的磁盘空间>
遗憾的是,这无法验证pilot1
是否等于pilot2
,我想您可以添加
pilot_check_not_equal TINYINT(1) AS (
CASE WHEN pilot1_SIN != pilot2_SIN THEN 1 END CASE
) NOT NULL
但我不是100%肯定会允许使用
NB 说了这么多,我发现在我的项目中总是存在验证问题,这些问题在数据库层很难解决。我很想在应用程序层中验证这种情况。只要您只有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位不同的飞行员
ASIDE
我还会建议以下内容
UNSIGNED
整数类型用于ID UNSIGNED
和num_of_seats
使用years_in_operation
整数,大概不能为负数fuel_type
和manufacturer
中的每一个使用单独的表,并使用UNSIGNED
整数引用它们,而不是重复名称shipID
多次(有不同的飞行员)-正确吗?DECIMAL
使用advertising_revenue
或整数类型答案 1 :(得分:0)
您可以这样做:
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),
);
create unique index IX_Unique on (Ship (least(pilot1_SIN, pilot2_SIN), greatest(pilot1_SIN, pilot2_SIN)));
答案 2 :(得分:0)
这是另一个主意...
DROP TABLE IF EXISTS my_table;
CREATE TABLE my_table (id1 INT NOT NULL,id2 INT NOT NULL,PRIMARY KEY(id1,id2));
INSERT INTO my_table SELECT LEAST(4,9),GREATEST(4,9);
SELECT * FROM my_table;
+-----+-----+
| id1 | id2 |
+-----+-----+
| 4 | 9 |
+-----+-----+
INSERT INTO my_table SELECT LEAST(4,9),GREATEST(4,9);
ERROR 1062 (23000): Duplicate entry '4-9' for key 'PRIMARY'