Mysql
 sql >> Baza danych >  >> RDS >> Mysql

System tagowania:pytania dotyczące rozwiązania Toxi

Przede wszystkim „toxi” nie jest pojęciem standardowym. Zawsze określaj swoje warunki! Lub przynajmniej podaj odpowiednie linki.

A teraz do samego pytania...

Nie, będziesz mieć 3 stoły.

Jesteś na dobrej drodze, z wyjątkiem tego, że możesz użyć opartej na zbiorach natury SQL, aby „scalić” wiele z tych kroków. Na przykład oznaczanie elementu 1 tagami:„tag1”, „tag2” i „tag3” można wykonać w ten sposób...

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

IGNORE pozwala to się udać, nawet jeśli element jest już połączony z niektórymi z tych tagów.

Zakłada się, że wszystkie wymagane tagi są już w tags . Zakładając tag.tag_id jest automatyczne, możesz zrobić coś takiego, aby upewnić się, że:

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

Nie ma magii. Jeśli „element jest połączony z określonym tagiem” jest fragmentem wiedzy, który chcesz nagrać, to będzie mieć jakąś fizyczną reprezentację w bazie danych.

Masz na myśli ponowne tagowanie elementów (nie modyfikowanie samych tagów)?

Aby usunąć wszystkie tagi, których nie ma na liście, wykonaj coś takiego:

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

Spowoduje to odłączenie elementu od wszystkich tagów z wyjątkiem „tag1” i „tag3”. Wykonaj INSERT powyżej i to DELETE jeden po drugim, aby „zakryć” zarówno dodawanie, jak i usuwanie tagów.

Możesz bawić się tym wszystkim w SQL Fiddle .

Prawidłowy. Potomny punkt końcowy FK nie wywoła akcji referencyjnej (takiej jak ON DELETE CASCADE), tylko rodzic to zrobi.

BTW, używasz tego schematu, ponieważ potrzebujesz dodatkowych pól w tags (obok tag_text ), Prawidłowy? Jeśli to zrobisz, nie utrata tych dodatkowych danych tylko dlatego, że zniknęły wszystkie połączenia, jest pożądanym zachowaniem.

Ale jeśli chcesz tylko tag_text , użyj prostszego schematu, w którym usunięcie wszystkich połączeń byłoby tym samym, co usunięcie samego tagu:

To nie tylko uprościłoby SQL, ale także zapewniłoby lepsze klastrowanie .

Na pierwszy rzut oka „toxi” może wyglądać na oszczędność miejsca, ale w praktyce może tak nie być, ponieważ wymaga dodatkowych tabel i indeksów (a tagi są zwykle krótkie).

Zmierz, zanim zdecydujesz się zrobić coś takiego. Wspomniany powyżej mój SQL Fiddle używa bardzo przemyślanej kolejności pól w tagmap PK, więc dane są zgrupowane w sposób bardzo przyjazny dla tego rodzaju liczenia (pamiętaj:Tabele InnoDB są zgrupowane ). Musisz mieć naprawdę ogromną liczbę przedmiotów (lub wymagać niezwykle wysokiej wydajności), zanim stanie się to problemem.

W każdym razie zmierz na realistycznych ilościach danych!




  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. mysql szukaj segmentu nazwy tabeli

  2. Nie można poprawnie wstawić greckich znaków w bazie mysql

  3. OperationalError:(2002, Nie można połączyć się z lokalnym serwerem MySQL przez gniazdo '/var/run/mysqld/mysqld.sock' (2))

  4. Projektowanie bazy danych:do EAV czy nie do EAV?

  5. Mysql int(11) liczba poza zakresem