Normalmente estaría de acuerdo con Yaakov Ellis, pero en este caso especial hay otra solución viable:
Use dos tablas:
Table: Item
Columns: ItemID, Title, Content
Indexes: ItemID
Table: Tag
Columns: ItemID, Title
Indexes: ItemId, Title
Esto tiene algunas ventajas importantes:
Primero, hace que el desarrollo sea mucho más simple: en la solución de tres tablas para insertar y actualizar item
, debe buscar elTag
tabla para ver si ya hay entradas. Entonces tienes que unirlos con otros nuevos. Esta no es una tarea trivial.
Luego hace que las consultas sean más simples (y quizás más rápidas). Hay tres consultas principales en la base de datos que hará: generar todas Tags
para una Item
, dibujar una nube de etiquetas y seleccionar todos los elementos para un título de etiqueta.
Todas las etiquetas para un artículo:
3-mesa:
SELECT Tag.Title
FROM Tag
JOIN ItemTag ON Tag.TagID = ItemTag.TagID
WHERE ItemTag.ItemID = :id
2-mesa:
SELECT Tag.Title
FROM Tag
WHERE Tag.ItemID = :id
Nube de etiquetas:
3-mesa:
SELECT Tag.Title, count(*)
FROM Tag
JOIN ItemTag ON Tag.TagID = ItemTag.TagID
GROUP BY Tag.Title
2-mesa:
SELECT Tag.Title, count(*)
FROM Tag
GROUP BY Tag.Title
Artículos para una etiqueta:
3-mesa:
SELECT Item.*
FROM Item
JOIN ItemTag ON Item.ItemID = ItemTag.ItemID
JOIN Tag ON ItemTag.TagID = Tag.TagID
WHERE Tag.Title = :title
2-mesa:
SELECT Item.*
FROM Item
JOIN Tag ON Item.ItemID = Tag.ItemID
WHERE Tag.Title = :title
Pero también hay algunos inconvenientes: podría tomar más espacio en la base de datos (lo que podría conducir a más operaciones de disco, lo que es más lento) y no está normalizado, lo que podría generar inconsistencias.
El argumento del tamaño no es tan fuerte porque la naturaleza misma de las etiquetas es que normalmente son bastante pequeñas, por lo que el aumento de tamaño no es grande. Se podría argumentar que la consulta del título de la etiqueta es mucho más rápida en una tabla pequeña que contiene cada etiqueta solo una vez y esto ciertamente es cierto. Pero teniendo en cuenta los ahorros por no tener que unirse y el hecho de que puede construir un buen índice sobre ellos podría compensarlo fácilmente. Por supuesto, esto depende en gran medida del tamaño de la base de datos que está utilizando.
El argumento de inconsistencia también es un poco discutible. Las etiquetas son campos de texto libre y no se espera ninguna operación como 'cambiar el nombre de todas las etiquetas "foo" a "bar"'.
Entonces tldr: Yo elegiría la solución de dos tablas. (De hecho, voy a hacerlo. Encontré este artículo para ver si hay argumentos válidos en su contra).