Normalement, je serais d'accord avec Yaakov Ellis, mais dans ce cas particulier, il existe une autre solution viable:
Utilisez deux tableaux:
Table: Item
Columns: ItemID, Title, Content
Indexes: ItemID
Table: Tag
Columns: ItemID, Title
Indexes: ItemId, Title
Cela présente des avantages majeurs:
Tout d'abord, cela rend le développement beaucoup plus simple: dans la solution à trois tables pour l'insertion et la mise à jour, item
vous devez rechercher la Tag
table pour voir s'il y a déjà des entrées. Ensuite, vous devez les rejoindre avec de nouveaux. Ce n'est pas une tâche triviale.
Ensuite, cela rend les requêtes plus simples (et peut-être plus rapides). Il y a trois requêtes de base de données principales que vous allez faire: Tout générer Tags
pour un Item
, dessiner un nuage de tags et sélectionner tous les éléments pour un titre de tag.
Toutes les étiquettes pour un article:
3 tables:
SELECT Tag.Title
FROM Tag
JOIN ItemTag ON Tag.TagID = ItemTag.TagID
WHERE ItemTag.ItemID = :id
2 tables:
SELECT Tag.Title
FROM Tag
WHERE Tag.ItemID = :id
Tag-Cloud:
3 tables:
SELECT Tag.Title, count(*)
FROM Tag
JOIN ItemTag ON Tag.TagID = ItemTag.TagID
GROUP BY Tag.Title
2 tables:
SELECT Tag.Title, count(*)
FROM Tag
GROUP BY Tag.Title
Articles pour une étiquette:
3 tables:
SELECT Item.*
FROM Item
JOIN ItemTag ON Item.ItemID = ItemTag.ItemID
JOIN Tag ON ItemTag.TagID = Tag.TagID
WHERE Tag.Title = :title
2 tables:
SELECT Item.*
FROM Item
JOIN Tag ON Item.ItemID = Tag.ItemID
WHERE Tag.Title = :title
Mais il y a aussi quelques inconvénients: cela pourrait prendre plus d'espace dans la base de données (ce qui pourrait entraîner plus d'opérations sur le disque, ce qui est plus lent) et il n'est pas normalisé, ce qui pourrait entraîner des incohérences.
L'argument de la taille n'est pas si fort car la nature même des balises est qu'elles sont normalement assez petites, donc l'augmentation de la taille n'est pas grande. On pourrait faire valoir que la requête pour le titre de la balise est beaucoup plus rapide dans un petit tableau qui ne contient chaque balise qu'une seule fois et c'est certainement vrai. Mais compte tenu des économies réalisées pour ne pas avoir à adhérer et du fait que vous pouvez construire un bon indice sur elles, cela pourrait facilement compenser cela. Cela dépend bien sûr fortement de la taille de la base de données que vous utilisez.
L'argument de l'incohérence est également un peu théorique. Les balises sont des champs de texte libres et il n'y a aucune opération attendue comme 'renommer toutes les balises "foo" en "bar"'.
Donc tldr: Je choisirais la solution à deux tables. (En fait, je vais le faire. J'ai trouvé cet article pour voir s'il existe des arguments valables contre.)