уникальное ограничение (без триггера) для отношения «один ко многим» - PullRequest
1 голос
/ 21 апреля 2010

Чтобы проиллюстрировать проблему, я приведу пример:

Tag_bundle состоит из одного или нескольких тегов. Уникальная комбинация тегов может быть сопоставлена ​​с уникальным тегом tag_bundle, и наоборот.

 tag_bundle                   tag            tag_bundle_relation
 +---------------+        +--------+      +---------------+--------+
 | tag_bundle_id |        | tag_id |      | tag_bundle_id | tag_id |
 +---------------+        +--------+      +---------------+--------+
 |       1       |        | 100    |      |       1       |  100   |
 +---------------+        +--------+      +---------------+--------+
 |       2       |        | 101    |      |       1       |  101   |
 +---------------+        +--------+      +---------------+--------+ 
                          | 102    |      |       2       |  101   |
                          +--------+      +---------------+--------+  
                                          |       2       |  102   |
                                          +---------------+--------+

Не может быть другого tag_bundle, имеющего точно такую ​​же комбинацию из тега 100 и тега 101. Не может быть другого tag_bundle, имеющего точно такую ​​же комбинацию из тега 101 и тега 102.

Как я могу обеспечить такое уникальное ограничение при выполнении SQL "одновременно" !! то есть, чтобы не допустить одновременного добавления 1011 * двух пакетов с ровно одинаковой комбинацией тегов

Добавление простого уникального ограничения на любую таблицу не работает, Есть ли какое-либо решение, кроме триггера или явной блокировки.

Я пришел только к такому простому способу: сделать комбинацию тегов в строку, и пусть это будет уникальный столбец.

tag_bundle  (unique on tags)         tag            tag_bundle_relation
 +---------------+-----------+      +--------+      +---------------+--------+
 | tag_bundle_id |  tags     |      | tag_id |      | tag_bundle_id | tag_id |
 +---------------+-----------+      +--------+      +---------------+--------+
 |       1       | "100,101" |      | 101    |      |       1       |  101   |
 +---------------+-----------+      +--------+      +---------------+--------+
                                    | 100    |      |       1       |  100   |
                                    +--------+      +---------------+--------+ 

но, похоже, не очень хороший путь: (

Ответы [ 2 ]

1 голос
/ 21 апреля 2010

Почему ограничение «без триггера»? С ним, в сочетании с небольшим дублированием данных, вы можете получить то, что вам нужно. Измените поле «теги» в вашем решении на поле массива INTEGER (или любого другого типа tag_id)

Признавая неприятность решения, я не вижу пути его обхода. Хотя я бы использовал массив вместо строки для «тегов», поместил его в отдельную таблицу из tag_bundle, по-прежнему сделал его уникальным и включил триггер для tag_bundle_relation для обновления поля тегов с помощью array_agg (tag_id) (> 8.4) если это не помогло, не удалось обновить триггер.

0 голосов
/ 21 апреля 2010

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

...