Каскадный вопрос - PullRequest
       4

Каскадный вопрос

0 голосов
/ 28 июня 2011

У меня есть это:

Foo
Id|BarId

Bar
Id

TableX
Id|FooId|BarId

TableY
Id|FooId|BarId

Мне нужно, чтобы в случае запроса типа

update Foo
set BarId = some bar id
where BarId = some other bar id

он каскадно доходил до TableX и TableY.Возможно ли это с помощью FK с каскадом обновления или только вручную заданными триггерами?

Ответы [ 2 ]

0 голосов
/ 30 июня 2011

Сначала удалите все ограничения внешнего ключа в TableX и TableY.

Тогда:

ALTER TABLE TableX
   ADD CONSTRAINT FK_TableX_FooId_BarID FOREIGN KEY (FooId, BarId)
   REFERENCES Foo (Id, BarId) ON UPDATE CASCADE;

-- Do the same for TableY

Вы не сказали, какую СУБД вы используете (пожалуйста, сделайте), но это наверняка сработает в SQL Server и, вероятно, в MySql. Прежде чем эта ссылка на внешний ключ будет работать, необходимо иметь индекс или ограничение уникальности (неявно создающее индекс) для (Id, BarId) в таблице Foo.

Вы НЕ хотите использовать отдельные внешние ключи для каждого столбца, так как это нарушит иерархические мульти-отношения, которые BarId имеет с FooId. Если вы обновляете конкретный BarId в Foo, вы хотите, чтобы он обновлял только те BarId в TableX, которые связаны с этим конкретным FooId, а не все из них во всей таблице. (То есть, если я вас правильно понимаю).

Я также не могу удержаться, предлагая убрать столбики с именем Id и выстрелить им в голову. Вскоре последовала хотя бы солидная порка для их создателей. :) Вместо этого назовите PK таблицы Foo 1023 *. По мере роста базы данных и усложнения запросов, включающих все больше и больше таблиц, не только раздражает постоянное наложение столбцов (F.Id FooId), но и становится все более вероятным, что вы допустите ошибку и, скажем, случайно введите T.Id там, где вы имеете в виду P.Id, и запрос не выдаст вам ошибок, так как этот столбец находится в обеих таблицах.

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

Я дополнительно предложу, что если на TableX и TableY нет ссылок где-либо еще, то искусственный столбец Id в них может оказаться в пользу другого столбца, который имеет деловое значение. Я не знаю достаточно о таблицах, чтобы на самом деле сказать, но много раз дополнительные искусственные идентификаторы генерируются, когда они не нужны (например, в таблицах промежуточных соединений многие-ко-многим, которые почти никогда не должны иметь отдельные идентификаторы). 1032 *

0 голосов
/ 29 июня 2011

, если вы укажете Каскад обновления, ссылочные значения будут обновлены.Попробуйте этот сценарий создания

CREATE TABLE TableX(
  id INT, 
  FooId INT,
  BarId INT,
  INDEX foo_idx (FooId),
  INDEX bar_idx (BarId),
  FOREIGN KEY (FooId) 
    REFERENCES Foo(Id) 
    ON UPDATE CASCADE
  FOREIGN KEY (BarId) 
    REFERENCES Bar(Id) 
    ON UPDATE CASCADE
) ENGINE=INNODB;
...