sql >> Databasteknik >  >> RDS >> Mysql

Taggningssystem:Toxilösningsfrågor

För det första är "toxi" inte en standardterm. Definiera alltid dina termer! Eller tillhandahåll åtminstone relevanta länkar.

Och nu till själva frågan...

Nej, du kommer att ha 3 bord.

Du är i stort sett på rätt spår, med undantaget att du kan använda den uppsättningsbaserade karaktären hos SQL för att "sammanfoga" många av dessa steg. Till exempel, att tagga ett objekt 1 med taggar:'tag1', 'tag2' och 'tag3' kan göras så här...

INSERT IGNORE INTO tagmap (item_id, tag_id)
SELECT 1, tag_id FROM tags WHERE tag_text IN ('tag1', 'tag2', 'tag3');

IGNORE tillåter detta att lyckas även om objektet redan är kopplat till några av dessa taggar.

Detta förutsätter att alla obligatoriska taggar redan finns i tags . Förutsatt tag.tag_id är automatisk ökning, kan du göra något så här för att säkerställa att de är:

INSERT IGNORE INTO tags (tag_text) VALUES ('tag1'), ('tag2'), ('tag3');

Det finns ingen magi. Om "objektet är kopplat till en viss tagg" är en kunskap som du vill spela in, kommer den att ha att ha någon form av fysisk representation i databasen.

Du menar att tagga om objekt (inte modifiera själva taggar)?

För att ta bort alla taggar som inte finns i listan, gör något så här:

DELETE FROM tagmap
WHERE
    item_id = 1
    AND tag_id NOT IN (
        SELECT tag_id FROM tags
        WHERE tag_text IN ('tag1', 'tag3')
    );

Detta kommer att koppla bort objektet från alla taggar utom 'tag1' och 'tag3'. Utför INSERT ovan och denna DELETE en efter en för att "täcka" både att lägga till och ta bort taggar.

Du kan leka med allt detta i SQL Fiddle .

Korrekt. En underordnad slutpunkt för en FK kommer inte att utlösa en referensåtgärd (som ON DELETE CASCADE), endast förälder kommer att göra det.

BTW, du använder det här schemat eftersom du vill ha ytterligare fält i tags (bredvid tag_text ), rätt? Om du gör det är det önskat beteende att inte förlora denna ytterligare data bara för att alla anslutningar är borta.

Men om du bara ville ha tag_text , skulle du använda ett enklare schema där att ta bort alla anslutningar skulle vara detsamma som att ta bort själva taggen:

Detta skulle inte bara förenkla SQL, det skulle också ge bättre klustring .

Vid första anblicken kan "toxi" se ut som att det sparar utrymme, men det kanske faktiskt inte är fallet i praktiken, eftersom det kräver ytterligare tabeller och index (och taggar tenderar att vara korta).

Mät innan du bestämmer dig för att göra något liknande. My SQL Fiddle som nämns ovan använder en mycket avsiktlig ordning av fält i tagmap PK, så data är klustrade på ett sätt som är mycket vänligt för denna typ av räkning (kom ihåg:InnoDB-tabeller är klustrade ). Du måste ha en riktigt stor mängd föremål (eller kräva ovanligt hög prestanda) innan detta blir ett problem.

Hur som helst, mät på realistiska mängder data!




  1. Automatisk anslutning till PDO endast vid behov

  2. Återställ tabellstruktur från frm- och ibd-filer

  3. Hur man uppdaterar materialiserad vy i oracle

  4. Ta bort dubbletter av rader i SQL Server