Проблема с ограничениями внешнего ключа и созданием БД Mysql

У меня проблема с размышлением о том, как соединить две таблицы. У меня есть одна таблица с действиями (RAD):

CREATE TABLE RAD (
  rad_id INT NOT NULL AUTO_INCREMENT PRIMARY KEY,
  spec_id INT NULL,
  predp_id INT NULL,
  predf_id INT NULL,
  strp_ID INT NULL,
  strf_ID INT NULL,
---more fileds---
  FOREIGN KEY (spec_id) REFERENCES SPEC(spec_id) ON DELETE SET NULL,    
  FOREIGN KEY (strp_ID) REFERENCES STRANKEP(strp_ID) ON DELETE CASCADE,
  FOREIGN KEY (strf_ID) REFERENCES STRANKEF(strf_ID) ON DELETE CASCADE,
  FOREIGN KEY (predp_id) REFERENCES PREDMETIP(predp_id) ON DELETE CASCADE,
  FOREIGN KEY (predf_id) REFERENCES PREDMETIF(predf_id) ON DELETE CASCADE
) ENGINE=InnoDB COLLATE utf8_general_ci;

И одна таблица спецификаций (SPEC), на основании которой будет выставлен счет:

CREATE TABLE SPEC (
  spec_id INT NOT NULL AUTO_INCREMENT PRIMARY KEY,
   ---more fileds---    
) ENGINE=InnoDB COLLATE utf8_general_ci;

Как видите, строка действия rad_id(RAD) будет удалена, если будет удален какой-либо клиент (strp_ID или strf_ID). То же самое касается случая (predp_id и predf_id).

Теперь я хочу ограничить удаление действия rad_id(RAD row), если оно включено в спецификацию. Поэтому, когда спецификация сделана, он вставляет spec_id(SPEC) в поле spec-id(RAD).

Когда спецификация удаляется, поле возвращается к нулю, и это работает. НО это позволяет мне удалить действие rad_id(RAD), когда оно было включено в спецификацию(SPEC) и этот внешний ключ spec_id включен в таблицу RAD. И я не могу этого допустить. Он должен удаляться только тогда, когда его нуль и ключ спецификации отсутствуют.

Проблема в том, что спецификация будет содержать НЕСКОЛЬКО действий rad_id(RAD), поэтому я не могу связать ее с еще одним столбцом rad_id(RAD) в качестве внешнего ключа.

Я не знаю, как подойти к этой проблеме.

     RAD TABLE  
rad_id  spec_id
1       1
2       1
3       1
4       null

        SPEC TABLE  
spec_id     rad_id-reference
1           1,2,3

Как показано выше, строка таблицы SPEC будет состоять из 3 rad_id, мне нужен способ сказать, что rad_id 1,2 и 3 не могут быть удалены, если spec_id 1 существует. rad_id 4 можно удалить.

Проблема в том, что я не могу сделать rad_id-ссылку на таблицу SPEC ВНЕШНИМ КЛЮЧОМ, состоящим из 3-х rad_id.


person ikiK    schedule 15.03.2020    source источник
comment
Я удалил свой ответ, так как вопрос мне больше не ясен. Пожалуйста, создайте работающий (и простой) пример в SQL Fiddle, чтобы я мог помочь вам лучше.   -  person The Impaler    schedule 15.03.2020
comment
Я сделал небольшую таблицу с объяснением.   -  person ikiK    schedule 15.03.2020
comment
sqlfiddle.com/#!9/50de2/1 Грязно, но работает, если вы есть еще одно предложение, которое я ценю.   -  person ikiK    schedule 16.03.2020
comment
Думаю, теперь я понимаю проблему. Я считаю, что надежное решение состоит в том, чтобы создать триггер перед удалением (BEFORE DELETE) в таблице RAD, который проверяет, что spec_id имеет значение null перед удалением строки. Если он не равен нулю, триггер предотвратит удаление. Это то, что вам нужно? См. dev.mysql.com/doc/refman/8.0/en. /trigger-syntax.html   -  person The Impaler    schedule 16.03.2020
comment
Да, это было бы здорово, но каскадные действия внешнего ключа не активируют триггеры :). stackoverflow.com/questions/6041064/ . И я включил каскадирование по всей базе данных, прежде чем узнал об этом. Но да, вы правы, это сработает в холостых ситуациях. Спасибо за ваш вклад.   -  person ikiK    schedule 16.03.2020


Ответы (1)


Я нашел способ сделать это. http://sqlfiddle.com/#!9/50de2/1 Если вы измените удалить значение в 1, это не удастся.

     RAD TABLE  
rad_id-PK
1       
2       
3       
4       

        SPEC TABLE  
spec_id-PK
1
2

    RESTRICTDEL TABLE
res_id-PK  spec_id-FK  rad_id-FK
1           1           1
2           1           2
3           2           2
4           2           3
5           2           3

Я сделал еще одну таблицу, которая будет содержать оба идентификатора PK в одном столбце, и они являются FK. один из них - PK, и он будет уникальным, как и spec_id из таблицы SPEC. второй — rad_id, который может быть двойным. Мне просто нужно установить SET Foreign_key_checks = 0; и обратно 1, когда я закончу вставлять новую спецификацию. Также нужно будет зациклиться с php и для каждого rad_id сделать новую запись resdel_id. Таким образом, несколько rad_id не будут удалены, если их связывает один spec_id.

person ikiK    schedule 16.03.2020