Mysql
 sql >> база данни >  >> RDS >> Mysql

Система за маркиране:Въпроси за решение на Toxi

На първо място "токси" не е стандартен термин. Винаги дефинирайте своите условия! Или поне дайте подходящи връзки.

А сега към самия въпрос...

Не, ще имате 3 маси.

Вие сте почти на прав път, с изключение на това, че можете да използвате базираната на набори природа на SQL, за да "слеете" много от тези стъпки. Например, маркирането на елемент 1 с тагове:'tag1', 'tag2' и 'tag3' може да стане по следния начин...

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

IGNORE позволява това да успее, дори ако елементът вече е свързан с някои от тези тагове.

Това предполага, че всички необходими тагове вече са в tags . Приемаме tag.tag_id е автоматично увеличение, можете да направите нещо подобно, за да сте сигурни, че са:

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

Няма магия. Ако „елементът е свързан с конкретен маркер“ е част от знанията, която искате да запишете, тогава тя ще има да има някакво физическо представяне в базата данни.

Имате предвид повторно маркиране на елементи (не модифициране на самите тагове)?

За да премахнете всички тагове, които не са в списъка, направете нещо подобно:

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

Това ще прекъсне връзката на елемента от всички тагове с изключение на „tag1“ и „tag3“. Изпълнете INSERT по-горе и това DELETE едно след друго, за да „покриете“ както добавянето, така и премахването на маркери.

Можете да играете с всичко това в SQL Fiddle .

вярно. Дъщерна крайна точка на FK няма да задейства референтно действие (като ON DELETE CASCADE), само родителят.

BTW, вие използвате тази схема, защото искате допълнителни полета в tags (до tag_text ), нали? Ако го направите, да не загубите тези допълнителни данни само защото всички връзки са изчезнали, е желано поведение.

Но ако просто искате tag_text , бихте използвали по-проста схема, при която изтриването на всички връзки би било същото като изтриването на самия маркер:

Това не само ще опрости SQL, но също така ще осигури по-добро клъстериране .

На пръв поглед „toxi“ може да изглежда, че спестява място, но това всъщност може да не е така на практика, тъй като изисква допълнителни таблици и индекси (а таговете обикновено са кратки).

Измерете, преди да решите да направите нещо подобно. Моята SQL Fiddle, спомената по-горе, използва много преднамерен ред на полета в tagmap PK, така че данните са групирани по начин, много удобен за този вид броене (запомнете:Таблиците на InnoDB са групирани ). Ще трябва да имате наистина огромно количество артикули (или да изисквате необичайно висока производителност), преди това да се превърне в проблем.

Във всеки случай,меретете върху реалистични количества данни!




  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Как мога да постигна функционалност initcap в MySQL?

  2. Mysql Max с групиране по заявка

  3. Прехвърляне на индекс към временна таблица от обикновена таблица?

  4. Разлика в производителността на Native SQL (използвайки MySQL) спрямо използването на Hibernate ORM?

  5. задаване на mamp портове на 80 и 3306