Update

如何實現標籤的多對多關係的插入、更新、刪除?

  • December 7, 2021

我正在創建一個應用程序來管理一些電子書,並且我想要標記功能。我發現最好的數據庫設計是多對多關係。我知道如何設置我的表,但由於我沒有經驗,我無法完全弄清楚插入、更新、刪除的樣子。

Ebook Table:
- id
- name

Tags Table:
- id
- name

TagsToEbooks
- ebook_id
- tag_id

我正在使用 C++ 和 Sqlite。假設我有一個帶有標籤數組的 C++ 函式,我想將它們與某個電子書相關聯。我將如何實現或編寫它?我應該如何使用佔位符?我是否遍歷數組並為每個標籤執行 SQL 語句?此外,如果我要刪除與電子書關聯的所有標籤,它們可能會保留在標籤表中,而連結表中沒有關聯(具有 ebook_id 和 tag_id)。

請教我如何涵蓋這些場景。

我使用虛擬碼的一些想法:

// When I want to insert a books tags
insert or select id if  it exists
then insert association


// When I want to update a books tags
delete associations of book
then do the insert function


// When I want to delete a books tags
DELETE FROM tasglink WHERE book_id in (SELECT id FROM ebooks WHERE name = :name)

//Create a trigger After delete on tagslink
DELETE FROM tags WHERE id NOT IN (SELECT id FROM tagslink WHERE GROUP BY id)

實現可能是:

-- books table
CREATE TABLE Ebook (ebook_id INTEGER PRIMARY KEY AUTOINCREMENT,
                   name VARCHAR(255) UNIQUE);

-- tags table
CREATE TABLE Tags (tag_id INTEGER PRIMARY KEY AUTOINCREMENT,
                  name VARCHAR(255) UNIQUE);

-- adjacency table
PRAGMA foreign_keys = ON;
CREATE TABLE TagsToEbooks (ebook_id INT,
                          tag_id INT,
                          PRIMARY KEY (ebook_id, tag_id),
                          FOREIGN KEY (ebook_id) REFERENCES Ebook (ebook_id) 
                              ON DELETE CASCADE ON UPDATE CASCADE,
                          FOREIGN KEY (tag_id) REFERENCES Tags (tag_id)
                              ON DELETE CASCADE ON UPDATE CASCADE);

-- Trigger which will delete unused tags after book deletion
CREATE TRIGGER delete_unused_tags
AFTER DELETE ON Ebook
BEGIN
   DELETE 
   FROM Tags 
   WHERE NOT EXISTS ( SELECT NULL
                      FROM TagsToEbooks
                      WHERE Tags.tag_id = TagsToEbooks.tag_id);
END;

展示小提琴

引用自:https://dba.stackexchange.com/questions/303596