powered by simpleCommunicator - 2.0.51     © 2025 Programmizd 02
Форумы / Firebird, InterBase [игнор отключен] [закрыт для гостей] / foreign key on update cascade
25 сообщений из 45, страница 1 из 2
foreign key on update cascade
    #39599942
Polesov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Привет.

Вопрос по каскадным обновлениям внешнего ключа.

Структура БД:

Таблица поставщиков:
Код: sql
1.
2.
3.
4.
5.
6.
7.
create table SUPPLIER (
    SUPPLIER  varchar( 10 ) not null
);

alter table SUPPLIER
  add constraint PK_SUPPLIER
      primary key ( SUPPLIER );



Таблица продукции (обновляемый внешний ключ на поставщиков):
Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
create table PRODUCT (
    SUPPLIER  varchar( 10 ) not null,
    PRODUCT   varchar( 10 ) not null
);

alter table PRODUCT
  add constraint PK_PRODUCT
      primary key ( SUPPLIER, PRODUCT );

alter table PRODUCT
  add constraint FK_PRODUCT_SUPPLIER
      foreign key ( SUPPLIER )
      references SUPPLIER ( SUPPLIER ) on update cascade;



Таблица поставок продукции (обновляемый внешний ключ на поставщиков):
Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
create table DELIVERY (
    SUPPLIER     varchar( 10 ) not null,
    DELIVERY_NO  integer not null
);

alter table DELIVERY
  add constraint PK_DELIVERY
      primary key ( SUPPLIER, DELIVERY_NO );

alter table DELIVERY
  add constraint FK_DELIVERY_SUPPLIER
      foreign key ( SUPPLIER )
      references SUPPLIER ( SUPPLIER ) on update cascade;



Таблица стоимости продукции в рамках поставок (обновляемый внешний ключ на поставки и продукцию):
Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
create table COST (
    SUPPLIER     varchar( 10 ) not null,
    PRODUCT      varchar( 10 ) not null,
    DELIVERY_NO  integer not null,
    PRICE        float
);

alter table COST
  add constraint PK_COST
      primary key ( DELIVERY_NO, PRODUCT, SUPPLIER );

alter table COST
  add constraint FK_COST_DELIVERY
      foreign key ( SUPPLIER, DELIVERY_NO )
      references DELIVERY ( SUPPLIER, DELIVERY_NO ) on update cascade;

alter table COST
  add constraint FK_COST_PRODUCT
      foreign key ( SUPPLIER, PRODUCT )
      references PRODUCT ( SUPPLIER, PRODUCT ) on update cascade;



Добавим данные:
Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
insert into SUPPLIER (
    SUPPLIER )
values ( 'ITNEL' );

insert into PRODUCT (
    SUPPLIER,
    PRODUCT )
values ( 'ITNEL', 'PENTIUM-1' );

insert into PRODUCT (
    SUPPLIER,
    PRODUCT )
values ( 'ITNEL', 'CORE I7' );

insert into DELIVERY (
    SUPPLIER,
    DELIVERY_NO )
values ( 'ITNEL', 1 );

insert into COST (
    SUPPLIER,
    PRODUCT,
    DELIVERY_NO,
    PRICE )
values ( 'ITNEL', 'PENTIUM-1', 1, 100 );

insert into COST (
    SUPPLIER,
    PRODUCT,
    DELIVERY_NO,
    PRICE )
values ( 'ITNEL', 'CORE I7', 1, 280 );

commit;



Ошибка в имени поставщика, пытаемся исправить 'ITNEL' на 'INTEL':
Код: sql
1.
2.
3.
update SUPPLIER
   set SUPPLIER = 'INTEL'
 where SUPPLIER = 'ITNEL';



Ошибка:
Код: powershell
1.
2.
3.
4.
5.
6.
violation of FOREIGN KEY constraint "".
violation of FOREIGN KEY constraint "FK_COST_DELIVERY" on table "COST".
Foreign key reference target does not exist.
Problematic key value is ("SUPPLIER" = 'INTEL', "DELIVERY_NO" = 1).
At trigger 'CHECK_4'
At trigger 'CHECK_1'.



Видимо, при последовательном обновлении одного из внешних ключей таблицы COSTS возникает "violation of FOREIGN KEY constraint" для другого внешнего ключа.

Удаляем любой из внешних ключей (например, FK_COST_DELIVERY), обновляем поставщика, восстанавливаем внешний ключ:
Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
alter table COST
  add drop FK_COST_DELIVERY;

update SUPPLIER
   set SUPPLIER = 'INTEL'
 where SUPPLIER = 'ITNEL';

alter table COST
  add constraint FK_COST_DELIVERY
      foreign key ( SUPPLIER, DELIVERY_NO )
      references DELIVERY ( SUPPLIER, DELIVERY_NO ) on update cascade;


Ошибок не возникает, внешний ключ накладывается.

Скрипт воспроизведения:

create table SUPPLIER (
SUPPLIER varchar( 10 ) not null
);

alter table SUPPLIER
add constraint PK_SUPPLIER
primary key ( SUPPLIER );

create table PRODUCT (
SUPPLIER varchar( 10 ) not null,
PRODUCT varchar( 10 ) not null
);

alter table PRODUCT
add constraint PK_PRODUCT
primary key ( SUPPLIER, PRODUCT );

alter table PRODUCT
add constraint FK_PRODUCT_SUPPLIER
foreign key ( SUPPLIER )
references SUPPLIER ( SUPPLIER ) on update cascade;

create table DELIVERY (
SUPPLIER varchar( 10 ) not null,
DELIVERY_NO integer not null
);

alter table DELIVERY
add constraint PK_DELIVERY
primary key ( SUPPLIER, DELIVERY_NO );

alter table DELIVERY
add constraint FK_DELIVERY_SUPPLIER
foreign key ( SUPPLIER )
references SUPPLIER ( SUPPLIER ) on update cascade;

create table COST (
SUPPLIER varchar( 10 ) not null,
PRODUCT varchar( 10 ) not null,
DELIVERY_NO integer not null,
PRICE float
);

alter table COST
add constraint PK_COST
primary key ( DELIVERY_NO, PRODUCT, SUPPLIER );

alter table COST
add constraint FK_COST_DELIVERY
foreign key ( SUPPLIER, DELIVERY_NO )
references DELIVERY ( SUPPLIER, DELIVERY_NO ) on update cascade;

alter table COST
add constraint FK_COST_PRODUCT
foreign key ( SUPPLIER, PRODUCT )
references PRODUCT ( SUPPLIER, PRODUCT ) on update cascade;


insert into SUPPLIER (
SUPPLIER )
values ( 'ITNEL' );

insert into PRODUCT (
SUPPLIER,
PRODUCT )
values ( 'ITNEL', 'PENTIUM-1' );

insert into PRODUCT (
SUPPLIER,
PRODUCT )
values ( 'ITNEL', 'CORE I7' );

insert into DELIVERY (
SUPPLIER,
DELIVERY_NO )
values ( 'ITNEL', 1 );

insert into COST (
SUPPLIER,
PRODUCT,
DELIVERY_NO,
PRICE )
values ( 'ITNEL', 'PENTIUM-1', 1, 100 );

insert into COST (
SUPPLIER,
PRODUCT,
DELIVERY_NO,
PRICE )
values ( 'ITNEL', 'CORE I7', 1, 280 );

commit;

update SUPPLIER
set SUPPLIER = 'INTEL'
where SUPPLIER = 'ITNEL';

/*
violation of FOREIGN KEY constraint "".
violation of FOREIGN KEY constraint "FK_COST_DELIVERY" on table "COST".
Foreign key reference target does not exist.
Problematic key value is ("SUPPLIER" = 'INTEL', "DELIVERY_NO" = 1).
At trigger 'CHECK_4'
At trigger 'CHECK_1'.
*/

alter table COST
add drop FK_COST_DELIVERY;


update SUPPLIER
set SUPPLIER = 'INTEL'
where SUPPLIER = 'ITNEL';

alter table COST
add constraint FK_COST_DELIVERY
foreign key ( SUPPLIER, DELIVERY_NO )
references DELIVERY ( SUPPLIER, DELIVERY_NO ) on update cascade;


Вопрос: это ошибка каскадного обновления внешних ключей или кривая структура БД?

Если кривая структура БД, какой структурой можно обеспечить каскадное обновление внешних ключей?

С уважением, Poleosv.
...
Рейтинг: 0 / 0
foreign key on update cascade
    #39599945
Ivan_Pisarevsky
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
PolesovЕсли кривая структура БД, какой структурой можно обеспечить каскадное обновление внешних ключей?Если в принципе требуется каскадный апдейт ключей - такая структура никуда не годится.

Первичный ключ не должен нести на себе никаких других функций, кроме ключа, никаких названий, намеков, ИНН-ов и прочей ерунды. Ключ это просто 64 битной число - идентификатор. Его апдейтить не надо ни при каких обстоятельствах.
...
Рейтинг: 0 / 0
foreign key on update cascade
    #39599950
Polesov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Ivan_PisarevskyЕсли в принципе требуется каскадный апдейт ключей - такая структура никуда не годится.
Понятно, в такой структуре исправление ошибки э-э-э ... весьма затруднительно.

Заменим primary key на unique not null - смена шила на мыло?
...
Рейтинг: 0 / 0
foreign key on update cascade
    #39599951
Polesov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Polesovсмена шила на мыло?

Вовсе нет.

Но вопрос остается открытым - каскадное обновление внешних ключей на некоторых структурах не возможно?

P.S. Вопрос прямоты/кривизны структуры не рассматривается.
...
Рейтинг: 0 / 0
foreign key on update cascade
    #39599957
Фотография kdv
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Polesov,

бывают случаи, что так увлекаются каскадами, что зацикливают каскадные ФК, например на удаление. Эффект потрясающий - удаляем одну запись, и в результате удаляется почти ВСЁ.

Сам вопрос про каскадные ключи, конечно, интересный, но так не делают, потому что
- в реальной БД изменение одного значения в SUPPLIER приводит к каскадному апдейту миллионов записей в разных таблицах
- потому естественные ПК и не используют. Абстрактный ПК нет смысла изменять, потому что он ничего не значит. А следовательно, необходимость в каскадном обновлении отпадает.
...
Рейтинг: 0 / 0
foreign key on update cascade
    #39599959
Фотография kdv
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Polesov,

собственно, ошибка структуры в том, что COST ссылается на ДВЕ таблицы, которые зависят от SUPPLIER, и при каскадном обновлении от SUPPLIER не могут быть обновлены ОДНОВРЕМЕННО.
Так что тут нет ошибки с ФК, есть ошибка структуры.
...
Рейтинг: 0 / 0
foreign key on update cascade
    #39599960
Polesov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
kdvбывают случаи, что так увлекаются каскадами
Вопрос не про излишнее увлечение каскадными обновлениями, а про факт возникновения ошибки при каскадном обновлении внешних ключей.

P.S. Вопрос - при использовании некой фичи FB возникает ошибка. Ответ - не используй эту фичу. (!!!!!!!)

Народ, вопрос не про ошибки в структуре БД, а про ошибки FB.
Feel difference, какгриться.
...
Рейтинг: 0 / 0
foreign key on update cascade
    #39599961
Polesov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
kdvCOST ссылается на ДВЕ таблицы, которые зависят от SUPPLIER
FB каскадное обновление таки внешних ключей не поддерживает?
Это отображено где-нибудь в документации?
...
Рейтинг: 0 / 0
foreign key on update cascade
    #39599969
Фотография kdv
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
PolesovFB каскадное обновление таки внешних ключей не поддерживает?
а кто поддерживает? Что значит "поддерживает"? Я вот тебя спрашиваю - как ты обновишь две таблицы одновременно?
Или как - парсер должен отвергать второй ФК на таблицу COST, потому что парсер обнаружит ссылку на одну и ту же таблицу через 2 косвенных ФК? А через 3 ФК?
С точки зрения ФК вообще - он построен нормальным образом. Другое дело, что ты связал таблицы таким образом, что каскадное обновление ФК в данном случае приводит к ошибке.
PolesovЭто отображено где-нибудь в документации?
мне интересно, каким образом это может или должно быть отражено.
...
Рейтинг: 0 / 0
foreign key on update cascade
    #39599970
Polesov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
kdvмне интересно, каким образом...Понятно - не используй эту фичу.


Я думаю, ответ на этот вопрос могут дать только разработчики.

Все остальные - от лукавого.
...
Рейтинг: 0 / 0
foreign key on update cascade
    #39599971
Фотография kdv
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
PolesovНарод, вопрос не про ошибки в структуре БД, а про ошибки FB.
это не ошибка ФБ. ФК в данном случае отрабатываются поочередно. Потому что это "системные триггеры". Если на таблице 5 триггеров, то они не срабатывают все одновременно. Они отрабатывают по одному. Да, у ФБ вот такая реализация. Ты напоролся на нее.
PolesovОтвет - не используй эту фичу.
да, потому что в такой схеме, которую ты построил, так - не работает.

Даже если бы работало, у тебя все равно, с моей точки зрения, ФК с COST неправильные.
...
Рейтинг: 0 / 0
foreign key on update cascade
    #39599972
Polesov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
kdvс моей точки зрения, ФК с COST неправильные
Polesovкакой структурой можно обеспечить каскадное обновление внешних ключей?
...
Рейтинг: 0 / 0
foreign key on update cascade
    #39599973
Dimitry Sibiryakov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Каскадные ФК - зло. Их не надо использовать нигде и никогда.
Posted via ActualForum NNTP Server 1.5
...
Рейтинг: 0 / 0
foreign key on update cascade
    #39599977
Polesov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Dimitry SibiryakovКаскадные ФК - зло. Их не надо использовать нигде и никогда.

Я бы не рискнул так заявить моему начальнику.
...
Рейтинг: 0 / 0
foreign key on update cascade
    #39599978
Polesov,

у вас "ромб": таблица cost будет обноалвять двумя каскадами.
В ФБ такой DDL молча пропускается и проблемы лезут позже, а вот в m$ sql - облом сразу .

В общем, это скорее не ошибка, а особенность реализации СУБД.
...
Рейтинг: 0 / 0
foreign key on update cascade
    #39599979
Polesov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Да кто его разберёт...В ФБ такой DDL молча пропускается и проблемы лезут позжеАпчемиречь...

Да кто его разберёт...В общем, это скорее не ошибка, а особенность реализации СУБД.Понятно, что можно изменить структуру БД (суррогатный PK + not null unique по наименованию), но в случае с естественным PK ...
...
Рейтинг: 0 / 0
foreign key on update cascade
    #39599980
Dimitry Sibiryakov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
PolesovЯ бы не рискнул так заявить моему начальнику.

Твоя трусость - твоя проблема.
Posted via ActualForum NNTP Server 1.5
...
Рейтинг: 0 / 0
foreign key on update cascade
    #39599982
Polesov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Да кто его разберёт...
http://www.sql.ru/forum/899636/introducing-foreign-key-constraint-on-table-may-cause-cycles-or-multiple-cascade-paths

Хороший вопрос:
Ex_SoftЭто M$ SQL такую структуру штатными средствами одолеть не может или вопрос плавно переходит в Проектирование БД?
...
Рейтинг: 0 / 0
foreign key on update cascade
    #39599983
Polesov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Dimitry SibiryakovТвоя трусость - твоя проблема.
Предлагаешь сменить меcто работы, храбрец?
...
Рейтинг: 0 / 0
foreign key on update cascade
    #39599984
Фотография kdv
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
PolesovЯ бы не рискнул так заявить моему начальнику.
хочешь, я рискну?
Собственно, я уже сказал - 21181802

к тому же, MS SQL сразу посылает с такой хренью. 21181894

PolesovПонятно, что можно изменить структуру БД (суррогатный PK + not null unique по наименованию), но в случае с естественным PK
да не использует никто естественные ПК в здравом уме. Разве что те, кто еще не напоролся на проблемы "начальной школы проектирования БД".
http://www.ibase.ru/natural-keys-versus-atrificial-keys-by-tentser/
https://habrahabr.ru/company/oleg-bunin/blog/348172/#choice

И правило тут простое - если значение столбца может со временем меняться, то это уже не ПК.
...
Рейтинг: 0 / 0
foreign key on update cascade
    #39599986
Polesov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
kdvда не использует никто естественные ПК
Можно ли сказать, что в системных таблицах FB поля RDB$RELATION_NAME, RDB$FIELD_NAME являются суррогатными, а не естественными ключами?
...
Рейтинг: 0 / 0
foreign key on update cascade
    #39599987
Dimitry Sibiryakov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Polesovnot null unique по наименованию

Все нубы стремятся наложить ограничение уникальности на название, имя и т.п. С опытом
эксплуатации таких систем приходит понимание, что это плохая идея и в реальности не работает.
Posted via ActualForum NNTP Server 1.5
...
Рейтинг: 0 / 0
foreign key on update cascade
    #39599988
d7i
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Структура БД неверна, грубо говоря, в корне.
Если субъект (поставщик, клиент и т.п.) имеет цифровое имя (код) и он может изменяться, это имя должно быть представлено отдельным полем. Его использование в качестве ФК совершенно не нужно.

Внутренний же идентификатор субъекта обычно является первичным ключом (AUTOINCREMENT) и никогда не модифицируется.
Поэтому все ФК на него не должны быть UPDATE, только DELETE. С DELETE тоже есть масса нюансов, но это уже другая песня...
...
Рейтинг: 0 / 0
foreign key on update cascade
    #39599989
Dimitry Sibiryakov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
PolesovПредлагаешь сменить меcто работы, храбрец?

Предлагаю разобраться: кто именно проектирует БД - ты или начальник. Если начальник, то
почему на форуме ты а не он?
Posted via ActualForum NNTP Server 1.5
...
Рейтинг: 0 / 0
foreign key on update cascade
    #39599990
Polesov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Dimitry SibiryakovPolesovnot null unique по наименованию

Все нубы стремятся наложить ограничение уникальности на название, имя и т.п. С опытом
эксплуатации таких систем приходит понимание, что это плохая идея и в реальности не работает.

Ну, сказать, что "все нубы..."
Тогда уж озвучь, как правильно.
...
Рейтинг: 0 / 0
25 сообщений из 45, страница 1 из 2
Форумы / Firebird, InterBase [игнор отключен] [закрыт для гостей] / foreign key on update cascade
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]