Je crois que vous trouverez intéressant ce blog: Tags: schémas de Base de données
Le Problème: Vous voulez avoir un schéma de base de données où vous pouvez marquer un
signet (ou un post de blog ou autre) avec autant de tags que vous le souhaitez.
Par la suite, vous souhaitez exécuter des requêtes pour contraindre les signets pour un
l'union ou l'intersection de balises. Vous aussi vous voulez exclure (dire: moins)
certaines balises à partir du résultat de recherche.
"MySQLicious" solution
Dans cette solution, le schéma a obtenu un tableau, il est dénormalisé. Ce type est appelé "MySQLicious solution" parce que MySQLicious importations del.icio.nous les données dans une table avec cette structure.
Intersection (ET)
Requête pour la recherche "de+service+semweb":
SELECT *
FROM `delicious`
WHERE tags LIKE "%search%"
AND tags LIKE "%webservice%"
AND tags LIKE "%semweb%"
De l'Union (OU)
Requête pour "search|webservice|semweb":
SELECT *
FROM `delicious`
WHERE tags LIKE "%search%"
OR tags LIKE "%webservice%"
OR tags LIKE "%semweb%"
Moins
Requête pour la recherche "de+webservice-semweb"
SELECT *
FROM `delicious`
WHERE tags LIKE "%search%"
AND tags LIKE "%webservice%"
AND tags NOT LIKE "%semweb%"
"Saborder" solution
Scuttle organise ses données dans deux tables. Cette table "scCategories" est le "tag"-table et a une clé étrangère à la "signet"-table.
Intersection (ET)
Requête pour "signet+webservice+semweb":
SELECT b.*
FROM scBookmarks b, scCategories c
WHERE c.bId = b.bId
AND (c.category IN ('bookmark', 'webservice', 'semweb'))
GROUP BY b.bId
HAVING COUNT( b.bId )=3
Tout d'abord, tous les signets-tag combinaisons sont recherchées, où la balise est "signet", "webservice" ou "semweb" (c.catégorie ('bookmark', 'webservice', 'semweb')), puis il suffit de les signets qui ont eu tous les trois balises recherchés sont pris en compte (AYANT le compte b.bId)=3).
De l'Union (OU)
Requête pour "signet|webservice|semweb":
Il suffit de laisser la clause HAVING et vous avez de l'union:
SELECT b.*
FROM scBookmarks b, scCategories c
WHERE c.bId = b.bId
AND (c.category IN ('bookmark', 'webservice', 'semweb'))
GROUP BY b.bId
Moins (Exclusion)
Requête pour "signet+webservice-semweb", c'est: signet ET webservice ET PAS semweb.
SELECT b. *
FROM scBookmarks b, scCategories c
WHERE b.bId = c.bId
AND (c.category IN ('bookmark', 'webservice'))
AND b.bId NOT
IN (SELECT b.bId FROM scBookmarks b, scCategories c WHERE b.bId = c.bId AND c.category = 'semweb')
GROUP BY b.bId
HAVING COUNT( b.bId ) =2
En laissant de côté les AYANT COMTE mène à la Requête de "signet|webservice-semweb".
"Toxi" solution
Toxi est venu avec un trois-structure de la table. Via la table "tagmap" les signets et les tags sont des n-m connexes. Chaque balise peut être utilisée avec différents signets et vice versa. Ce DB-schéma est également utilisé par wordpress.
Les requêtes sont tout à fait le même que dans le "saborder" solution.
Intersection (ET)
Requête pour "signet+webservice+semweb"
SELECT b.*
FROM tagmap bt, bookmark b, tag t
WHERE bt.tag_id = t.tag_id
AND (t.name IN ('bookmark', 'webservice', 'semweb'))
AND b.id = bt.bookmark_id
GROUP BY b.id
HAVING COUNT( b.id )=3
De l'Union (OU)
Requête pour "signet|webservice|semweb"
SELECT b.*
FROM tagmap bt, bookmark b, tag t
WHERE bt.tag_id = t.tag_id
AND (t.name IN ('bookmark', 'webservice', 'semweb'))
AND b.id = bt.bookmark_id
GROUP BY b.id
Moins (Exclusion)
Requête pour "signet+webservice-semweb", c'est: signet ET webservice ET PAS semweb.
SELECT b. *
FROM bookmark b, tagmap bt, tag t
WHERE b.id = bt.bookmark_id
AND bt.tag_id = t.tag_id
AND (t.name IN ('Programming', 'Algorithms'))
AND b.id NOT IN (SELECT b.id FROM bookmark b, tagmap bt, tag t WHERE b.id = bt.bookmark_id AND bt.tag_id = t.tag_id AND t.name = 'Python')
GROUP BY b.id
HAVING COUNT( b.id ) =2
En laissant de côté les AYANT COMTE mène à la Requête de "signet|webservice-semweb".