Как убедиться, что избыточные данные удаляются в отношении многие ко многим - PullRequest
0 голосов
/ 11 января 2009

Я пытаюсь убедиться, что некоторые данные автоматически удаляются, когда больше нет ссылок, использующих каскадное удаление. Я объясню с поддельной базой данных, основанной на переполнении стека.

У меня есть Post таблица. Каждый пост имеет от нуля до многих тегов.

Так должно выглядеть:

Post <-> PostTags <-> Метки

например.

Пост 1 имеет теги 'A', 'B', 'C' Пост 2 имеет теги 'C', 'D'.

Теперь, что я делаю, так это то, что когда я удаляю все теги для поста 2 (например, DELETE FROM PostTags WHERE PostId = 2), я бы хотел, чтобы тег 'D' также был удален, потому что никто больше, если на него ссылаются. Я думал, что каскадное удаление справится с этим, но, конечно, это только в том случае, если вы каскадно снизитесь с Tag->PostTags или Post->PostTags.

Я не уверен, как справиться с этим.

Боюсь, что люди предложат использовать триггер :( (дополнительная сложность для системы).

Мысли

Примечание: БД - MS Sql2008.

Ответы [ 2 ]

2 голосов
/ 11 января 2009

К сожалению, здесь вы не сможете использовать каскады. Каскады не работают, когда у вас есть отношения многие ко многим, потому что у вас не будет единственного родителя, который ссылается на дочернего элемента (в этом случае у вас есть несколько записей PostTags, которые могут ссылаться на таблицу тегов).

Триггеры были бы способом сделать это, но я бы не рекомендовал это. Скорее, я бы предложил, чтобы в вашем слое данных после удаления записей в таблице PostTags удалили теги, на которые больше нет ссылок. Если у вас есть хранимая процедура, которая выполняет удаление записи, вы можете рассмотреть возможность сделать это там (это было бы относительно просто сделать).

0 голосов
/ 23 января 2009

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

Перед удалением вашего сообщения сохраните этот набор записей:

SELECT tagID, count(*) from PostsTags WHERE postId = 2 group by tagID;

Затем, после того, как вы удалите его, переберите этот набор записей, и если count (*) = 1, то удалите тег.

...