Управление тегами изображений в SQL - PullRequest
3 голосов
/ 20 июля 2010

Я хотел бы создать базу данных изображений. Каждое изображение может иметь 1 или более тегов, например: Paris, April 2010, David.

Как бы вы сохранили эту информацию? Я думал, что у меня есть таблица Files с 1 строкой на файл, и один из столбцов будет идентификатором тегов, разделенных запятыми, например: 2,4,14,15

В другой таблице с именем Tags Я думал, что в каждом теге будет по 1 строке, например:

Tag ID    Tag Name
------    --------
   1       April
   2       David
   3       Paris

Как вы думаете, это хорошая идея для управления такими тегами? Например, как я могу легко получить все теги имен конкретной картинки?

Ответы [ 6 ]

11 голосов
/ 20 июля 2010

У вас должно быть 3 стола.Файлы, теги и теги файлов.

Теги файлов должны иметь идентификатор файла и идентификатор тега.Одна строка для одного назначения тега.

Вы можете легко запросить все файлы с определенным тегом:

select distinct f.* from Files f 
join FileTags ft on f.FileID = ft.FileID 
join Tags t on ft.TagID = t.TagID
where t.TagName = 'Paris'

Или все теги для любого файла:

select distinct t.* from Files f 
join FileTags ft on f.FileID = ft.FileID 
join Tags t on ft.TagID = t.TagID
where f.FileID = 7
4 голосов
/ 20 июля 2010

То, что вы предлагаете (идентификаторы тегов, разделенные запятыми), считается отклоненным для большинства проектов реляционных баз данных, поскольку это не нормализовано .

У вас должно быть еще много-to-many таблица со столбцами TagId и FileId.

Это означает, что вы можете хранить один тег (скажем, Paris) и связывать его со многими изображениями.И для каждой картинки вы сможете хранить множество тегов.

2 голосов
/ 20 июля 2010

По моему мнению, если вы запустите отдельные значения в столбце, в будущем вам будет очень сложно выполнить поиск типа "получить все изображения с заданным тегом". Я уверен, что есть много способов, но стандартный способ справиться с этим - иметь промежуточную таблицу сопоставления «многие ко многим», в которой хранятся PhotoID и TagID, которые определяют, какой тег принадлежит какому изображению.

1 голос
/ 20 июля 2010

Я бы имел 3 таблицы:

  1. Файл с колонками "Id", "Path", ...
  2. Метка со столбцами «Id», «Имя» ...
  3. FileTag со столбцами "FileId", "TagId", ...

Тогда я бы создал внешние ключи:

  • «FileId» - это внешний ключ от File table
  • "TagId" будет внешним ключом от Tag table

Конечно, детали реализации соответствуют СУБД по вашему выбору.

1 голос
/ 20 июля 2010

Mysql позволяет легко получить все теги даже из нормализованного формата

SELECT f.FileID, group_concat(t.tag_name) 
FROM Files f 
     JOIN FileTags ft ON f.FileID = ft.FileID 
     JOIN Tags t on ft.TagID = t.TagID
GROUP BY f.FileID

Подробнее здесь .

Если вы гоняетесь за последней долей производительности и готовы подписать, что вы не будете возражать против недостатков, вы можете рассмотреть возможность использования set types .

Предостережение: обе эти опции блокируют вас в специфике конкретной реализации СУБД (в данном случае mysql), поскольку другие СУБД могут не использовать тот же синтаксис или даже не иметь вышеуказанные функции (поэтому в идеальном мире ни одно из вышеприведенных предложений не годится) .

Обязательно ознакомьтесь с ограничениями , касающимися установленного типа данных, например, не очень интересно иметь обширный редизайн приложения, потому что вы понимаете, что вам нужно иметь более 64 тегов.

1 голос
/ 20 июля 2010

Я бы, вероятно, имел бы одну таблицу для изображений и одну для тегов, чем использовать таблицу «многие ко многим», связывающую их вместе.Таким образом, можно легко найти все теги для изображения или все изображения для тега.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...