Есть ли согласованная идеальная схема для маркировки

У меня есть веб-сайт с фотографиями, и я хочу поддерживать теги, так как моя первоначальная группировка категорий начинает давать сбой (некоторые фотографии - это семья и отпуск или школа и друзья). Есть ли согласованная схема базы данных тегов?

Я по-прежнему хочу, чтобы фотографии были частью альбома.

Прямо сейчас у меня есть несколько таблиц:

Фото

  • Регистрационный номер фото
  • PhotoAlbumID
  • Подпись
  • Дата

Фотоальбом

  • AlbumID
  • AlbumName
  • АльбомДата

person leora    schedule 05.10.2008    source источник


Ответы (7)


Существуют различные эффективные схемы, каждая из которых имеет свои собственные последствия для производительности общих запросов, которые вам понадобятся по мере роста количества помеченных элементов:

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

Вы также можете добавить некоторые денормализованные данные, если вы чувствуете себя резвым и хотите, чтобы простые выборки происходили за счет дополнительного обслуживания данных, необходимого для хранения счетчиков использования в таблице тегов или сохранения имен тегов, которые использовались в самой таблице элементов, чтобы избежать попадания таблица ссылок и таблица тегов для каждого элемента, которая полезна для отображения нескольких элементов со всеми их тегами и для простого управления версиями тегов ... если вам нравятся такие вещи;)

person Jonny Buchanan    schedule 05.10.2008
comment
Вы не имеете в виду «нормализованный (без дублирования имен тегов)»? - person Navin; 05.06.2018

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

Поскольку это отношения «много-много» (каждый тег может принадлежать любому количеству фотографий - каждая фотография может иметь много тегов), теория реляционных баз данных предполагает создание таблицы фотографий, таблицы тегов и таблицы перекрестных ссылок для их связывания.

photos
  photoid
  caption
  filename
  date

tags
  tagid
  tagname

phototags
  photoid
  tagid

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

Еще одна проблема, с которой вам придется столкнуться, - это проблема нормализации тегов. Это не имеет ничего общего с нормализацией базы данных - просто нужно убедиться, что (например) теги «StackOverflow», «stackoverflow» и «stack overflow» совпадают. Во многих местах пробелы запрещены или автоматически удалены. Иногда вы увидите то же самое с пунктуацией - сделайте "StackOverflow" таким же, как "Stack-Overflow". Авто-нижний регистр довольно стандартен. Вы даже увидите нормализацию для особых случаев - например, когда "c #" будет таким же, как "csharp".

Удачной маркировки!

person Neall    schedule 05.10.2008
comment
какой лучший ответ для нормализации тегов? - person leora; 07.10.2008
comment
Я думаю, это будет во многом зависеть от того, что вы помечаете. Однако я предпочитаю тяжелую нормализацию - вы действительно хотите, чтобы количество тегов было небольшим. - person Neall; 07.10.2008

Мне приходит в голову что-то вроде этого: добавьте эти две таблицы

Теги

  • TagID
  • Название тэга
  • Тег Описание

PhotoTags

  • Регистрационный номер фото
  • TagID

Вы также можете распространить это на альбомы, имея таблицу пересечений между фотоальбомами и тегами.

person Gabriele D'Antona    schedule 05.10.2008
comment
как избежать того, чтобы люди не использовали одно и то же имя для тега (например, чувствительность к регистру и т. д.) - person leora; 06.10.2008
comment
@akantro: дайте им список тегов, чтобы побудить их выбрать тег вместо того, чтобы вводить новый. Или современный эквивалент, текстовое поле с автозавершением тегов на основе AJAX. - person Bill Karwin; 06.10.2008
comment
есть ли готовый элемент управления для завершения тегов, управляемого AJAX? - person leora; 06.10.2008

Я предлагаю посмотреть, как это работает устоявшееся программное обеспечение с открытым исходным кодом. Например, Галерея хранит свои метаданные в базе данных, как и вы, и она довольно богата.

Однако я не думаю, что вы найдете «стандартную» схему. Самое близкое, что я могу придумать, - это формат метаданных EXIF, который встроен в сами файлы изображений (с помощью камер и т. Д.).

person skaffman    schedule 05.10.2008

если вам нужна реальная производительность с миллионами записей, вы можете хранить теги в одном поле, разделяя их запятыми, и извлекать записи с помощью демона полнотекстового индекса / поиска, такого как sphinxsearch. Все, что вам нужно добавить, это таблица, в которой перечислены все теги со значением счетчика, чтобы узнать, как часто они прикрепляются к элементу.

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

Вы также можете использовать функциональность полнотекстового поиска в своей СУБД, но когда записей много, большинство систем работают медленно.

Если это для небольшого проекта, вы можете пойти своим путем, швы, хороший и правильный способ сделать. Но я просто поделюсь с вами другим решением. Что ты думаешь о ?

person Community    schedule 05.10.2008

Небольшая заметка о том, как работать с тегами:

Системы тегов могут варьироваться от очень жестко определенных тегов, где создание новых требует явной дополнительной работы (подумайте о метках Gmail), до очень свободных систем, в которых рекомендуется добавлять как можно больше тегов (подумайте о flickr или тегах аудиоконтента, где может применяться транскрипция. прямо как теги).

В общем, легко индексируемый носитель (текст!) Должен иметь более жесткую систему, поскольку контент уже доступен для поиска. Дополнительные теги существуют больше только для категоризации, а категоризация полезна только тогда, когда разные пользователи широко распределяют вещи по одним и тем же категориям. Если у вас есть необработанный текст, для создания нового потребуется почти стихийное бедствие. тег.

С другой стороны, носители, которые труднее индексировать (изображения, видео, аудио), должны иметь гибкую систему, которая поддерживает множество тегов, поскольку они и другие метаданные - ваша единственная надежда при поиске.

Это важно, потому что схема базы данных, которую вы хотите, может несколько измениться в зависимости от того, на каком конце этого спектра вы окажетесь.

person Joel Coehoorn    schedule 06.10.2008

В моем приложении BugTracker.NET я предполагаю, что ошибок не будет слишком много. Может, десятки тысяч, но не десятки миллионов. Это предположение позволяет мне кэшировать теги и идентификаторы элементов, на которые они ссылаются.

В базе данных теги сохраняются по мере их ввода вместе с ошибками в текстовое поле с разделителями-запятыми.

Когда поле тега добавляется или изменяется, запускается фоновый поток, который выбирает все идентификаторы ошибок и их теги, анализирует текст и строит карту, где ключ является тегом, а значение представляет собой список всех идентификаторов, имеющих этот тег. . Затем я кэширую эту карту в объекте приложения Asp.Net.

Ниже приведен код, который я только что описал.

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

Когда кто-то выполняет поиск с использованием тега, я ищу значение на карте, получаю список идентификаторов, а затем извлекаю эти ошибки с помощью SQL с предложением «where id in (1, 2, 3 ...)».

    public static void threadproc_tags(object obj)
    {
        System.Web.HttpApplicationState app = (System.Web.HttpApplicationState)obj;

        SortedDictionary<string,List<int>> tags = new SortedDictionary<string,List<int>>();

        // update the cache
        DbUtil dbutil = new DbUtil();
        DataSet ds = dbutil.get_dataset("select bg_id, bg_tags from bugs where isnull(bg_tags,'') <> ''");

        foreach (DataRow dr in ds.Tables[0].Rows)
        {
            string[] labels = btnet.Util.split_string_using_commas((string) dr[1]);

            // for each tag label, build a list of bugids that have that label
            for (int i = 0; i < labels.Length; i++)
            {

                string label = normalize_tag(labels[i]);

                if (label != "")
                {
                    if (!tags.ContainsKey(label))
                    {
                        tags[label] = new List<int>();
                    }

                    tags[label].Add((int)dr[0]);
                }
            }
        }

        app["tags"] = tags;

    }
person Corey Trager    schedule 05.10.2008
comment
Нормализация будет медленнее для чтения, вставки и обновления. и удаляет. Почему БЫ я нормализовал? Что еще более важно, независимо от того, как данные тега хранятся физически, когда я фактически использую их для поиска, я использую то, что кэшировано в памяти. Сама по себе схема db не имеет значения во время поиска. - person Corey Trager; 10.09.2009