каскадные удаления в отношениях «многие ко многим», когда нет связанных элементов - PullRequest
0 голосов
/ 25 ноября 2018

У меня есть схема, которая выглядит примерно так:

CREATE TABLE posts(
    id INTEGER PRIMARY KEY,
    txt TEXT,
);
CREATE TABLE tags(
    id INTEGER PRIMARY KEY,
    tag TEXT
);

CREATE TABLE posts_tags(
    id INTEGER PRIMARY KEY,
    tag_id INTEGER NOT NULL REFERENCES tags(id) ON DELETE CASCADE
);

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

Итак, при условии, что есть только один пост о программировании, тег "programming" должен быть удален при удалении этого поста.Однако, если существует несколько сообщений, скажем, о sports, удаление одного должно сохранить тег неизменным и удалить только соответствующие отношения из таблицы posts_tags (я предполагаю, что это делается автоматически каскадом).

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

Мне нужно будет сделать это для нескольких таблиц, поэтому копирование / вставка кода несколько раз будет неэффективной.

Есть ли способ сделать это?

Я исследовал много-много связей и удалений, но нашел только упоминание об использовании триггеров.Тем не менее, я не знаю, какой триггер мне использовать.

1 Ответ

0 голосов
/ 26 ноября 2018

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

Я думаю, что вам нужна схема типа: -

CREATE TABLE posts(
    id INTEGER PRIMARY KEY,
    txt TEXT,
);
CREATE TABLE tags(
    id INTEGER PRIMARY KEY,
    tag TEXT
);

CREATE TABLE posts_tags(
    id INTEGER PRIMARY KEY,
    tag_id INTEGER NOT NULL REFERENCES tags(id) ON DELETE CASCADE,
    post_id INTEGER NOT NULL REFERENCES posts(id) ON DELETE CASCADE
);

Затем вы привязываете теги к сообщениям, если сообщение удалено, то все строки для этого сообщениябудут удалены другие сообщения с использованием этого тега.Если тег будет удален, все строки, использующие этот тег, будут удалены.

PS Вы можете покончить со столбцом id, и тогда вы можете захотеть использовать ПЕРВИЧНЫЙ КЛЮЧ в качестве составной части обоих столбцов, исключая тем самым бесполезный/ сбивает с толку дублирующиеся строки.

Поэтому, возможно, используйте (с другими таблицами буксировки): -

CREATE TABLE posts_tags(
    tag_id INTEGER NOT NULL REFERENCES tags(id) ON DELETE CASCADE,
    post_id INTEGER NOT NULL REFERENCES posts(id) ON DELETE CASCADE,
    PRIMARY KEY (tag_id,post_id)
);

Или, если версия sqlite поддерживает это (3.8.2+): -

CREATE TABLE  posts_tags(
        tag_id INTEGER NOT NULL REFERENCES tags(id) ON DELETE CASCADE,
        post_id INTEGER NOT NULL REFERENCES posts(id) ON DELETE CASCADE,
        PRIMARY KEY (tag_id,post_id) 
        )
    WITHOUT ROWID
    ;
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...