К сожалению, как отмечает @Barmar, даже в версии 8.0 MySQL просто игнорирует любые CHECK CONSTRAINTS
Вы можете использовать триггер BEFORE INSERT
, как предложено @ TheImpaler
Для нестандартного решения вы можете использовать сгенерированный столбец
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
s или UPDATE
s этого кода, у вас все будет в порядке.
ADDENDUM
Другой вариантразделить ваш стол 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
целочисленных типов для идентификаторов - Использование
UNSIGNED
целые числа для num_of_seats
и years_in_operation
, предположительно, они не могут быть отрицательными - Использовать отдельные таблицы для каждого из
fuel_type
и manufacturer
и ссылаться на них с целым числом UNSIGNED
, а не дублировать имена - В вашем корабельном столе есть составной ПК, это позволит использовать одно и то же
shipID
несколько раз в одной и той же таблице (с разными пилотами) - это правильно? - Использовать
DECIMAL
илицелочисленный тип для advertising_revenue
для точности