postgresql: ОБНОВЛЕНИЕ КАСКАДА внутри массива - PullRequest
0 голосов
/ 03 октября 2011

У меня есть естественный первичный ключ в таблице A.

В таблице B я хочу иметь массив ссылок на внешний ключ для A.

Можно ли указать ON UPDATECASCADE для элементов массива, так что при изменении значения первичного ключа в таблице A массивы в B изменяются.Или я должен просто нормализовать массив в отдельную таблицу?

Ответы [ 2 ]

2 голосов
/ 03 октября 2011

Нормализация этого позволит вам использовать стандарт ON UPDATE CASCADE в ограничении внешнего ключа. Это будет намного быстрее, потому что система может использовать для этого простые индексы. Это должно дать вам 3 таблиц. Требуется несколько больше дискового пространства. Но стоит каждого бита:

  • таблица
  • стол b
  • таблица a_b - для реализации отношения n: m

В противном случае вам придется написать триггерную функцию, чтобы найти и заменить все ссылки в B на значения мастера A.

0 голосов
/ 03 октября 2011

Можно ли указать ОБНОВЛЕНИЕ КАСКАДА для элементов массив, такой, что, когда значение первичного ключа в таблице A изменяется, Массивы в B модифицируются.

Только если

  • и ссылочный столбец, и ссылочный столбец являются массивами одного типа, а
  • значения имеют одинаковое количество элементов.

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

OTOH, это работает , но только частично.

create table a (
  str varchar[2] primary key
);

create table b (
  -- Room for two values from table a . . .
  str varchar[4] primary key references a (str) on update cascade
);

insert into a values 
('{''A'', ''B''}'),
('{''C'', ''D''}'),
('{''E'', ''F''}');

insert into b values 
('{''A'', ''B''}');

update a set str = '{''A'',''C''}'
where str = '{''A'',''B''}';

select * from b;
{'A','C'}

Это много работает. Но если вы попытаетесь сохранить два массива в таблице b, вы получите ошибку.

insert into b values
('{{"C", "D"}, {"E", "F"}}');
ERROR:  insert or update on table "b" violates foreign key constraint "b_str_fkey"
DETAIL:  Key (str)=({{C,D},{E,F}}) is not present in table "a".

И, когда вы щурились и наклоняли голову, это имеет смысл. В реляционной модели пересечение каждой строки и столбца содержит только одно значение. Таким образом, вы не сможете обновить половину значения на ON UPDATE CASCADE.

...