Схема мультитенантных тегов для распределенных типов контента

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

Я заинтересован в использовании тегов в нескольких функциях многопользовательского бизнес-приложения; тот, где теги могут быть связаны с полями формы, документами, фотографиями, настройками конфигурации и многим другим.

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

tags {
  tagsID
  tagName
}
tagChildren {
  childID
  childValue
}
tagType {
  typeID
  typeName
}
entity {
  entityID
  entityName
  ... 
}
tagMap {
  mapID  
  tagsID (FK)
  childID (FK)
  typeID (FK)
  entityID (FK)
}

tagMap можно использовать для подключения любого количества этих элементов, но он будет соединять как минимум теги и tagType. Например, тег может быть связан с раскрывающимся типом поля. Это может быть раздел реестра с типом реестра, дочерним значением и быть связанным с сущностью. Дочерний тег может быть другим тегом, чтобы обеспечить многоуровневые отношения родитель-потомок.

При распределении существует риск, поскольку многие функции становятся зависимыми от небольшого набора таблиц.

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

Спасибо!


person user160383    schedule 20.08.2009    source источник
comment
Не могли бы вы дать реальное использование ваших тегов с реальными именами тегов и сущностями?   -  person Quassnoi    schedule 21.08.2009
comment
Вот несколько реальных примеров: Теги ключа реестра: CSSLocation tagChildren: /styles/myCSSFile.css tagType: RegistrySetting entity: 1, myCompanyName tagMap: ключи для соединения тегов, tagChildren, tagType, entity Теги поля формы: Address tagType: textInput entity: 2, someOtherCompany TagMap: ключи для объединения тегов, типов и объектов   -  person user160383    schedule 21.08.2009
comment
Также: Пользовательские теги иерархического элемента счета-фактуры: Blood Draw (для этой концепции в таблице тегов также будет присутствовать частный бит, чтобы позволить пользователю выбирать, делиться ли элементом или нет); tagChildren: Плата за хранение, Плата за доставку, Плата за пребывание; тип тега: элемент счета-фактуры; сущность: 3, какая-то больница; tagMap: объединить теги, tagChildren, tagType и Entity   -  person user160383    schedule 21.08.2009


Ответы (2)


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

**Create a single Tags Table:**
  Tags { TagsID, TenantID, Name, CreatorID }    

**Documents:**
  TagMap_Documents { TagMap_DocumentsID, DocID, TagID }
  Documents { DocID, Location/Blob, ... }

**Photos:**
  TagMap_Photos { TagMap_PhotosID, PhotoID, TagID }
  Photos { PhotoID, URL, PhotoBlob ... }      

Теперь мы представили новую проблему - таблица тегов денормализована. В сценарии Марка и в моем собственном здесь мы представили создание нескольких имен тегов для каждого арендатора и создателя или перегруженных полей арендатора и создателя (несколько идентификаторов в одной записи).

Чтобы исправить это, мы можем:

  • переместите объект и пользовательский контекст в таблицы TagMap и присоединитесь к более чем трем таблицам. Я думаю, что это было бы более эффективно, чем то, что я изложил в своем первоначальном посте, потому что мы распространили контент.

    Создайте единую таблицу тегов: теги { TagsID, имя }

    Использование таблиц арендаторов и пользователей Арендатор { TenantID, Name, ... } Пользователи { UserID, Name, ... }

    Документы: TagMap_Documents { TagMap_DocumentsID, DocID, TagID, TenantID, CreatorID } Документы { DocID, Location/Blob, private(bit), ... }

    Фотографии: TagMap_Photos { TagMap_PhotosID, PhotoID, TagID, TenantID, CreatorID } Фотографии { PhotoID, URL, PhotoBlob, private(bit), ... }

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

    Создайте единую таблицу тегов: теги { TagsID, имя }

    Документы: TagMap_Documents { TagMap_DocumentsID, DocID, TagID } Документы { DocID, Location/Blob, TenantID, CreatorID, private(bit), ... }

    Фотографии: TagMap_Photos { TagMap_PhotosID, PhotoID, TagID } Фотографии { PhotoID, URL, PhotoBlob, TenantID, CreatorID, private(bit), ... }

Поиск серебряной пули здесь может потребовать больше размышлений, чем вся охота ;) Если бы это было не так, то мы все равно не получили бы никакого удовольствия :)

person user160383    schedule 21.08.2009

Я не верю, что меньшее количество таблиц сделает работу более эффективной. Не лучше ли просто иметь отдельные таблицы для каждого типа контента. Это было бы более читабельно. Запросы для подсчета также были бы проще и эффективнее, если бы было меньше JOIN и т. д.?

eg:

Для документа:

DocumentTags { ID TenantID Name CreatorID }

DocumentMappedTags {ID DocumentID DocumentTagID }

Для фотографий:

PhotoTags { ID TenantID Name CreatorID }

PhotoMappedTags {ID PhotoID PhotoTagID }

person Mark Redman    schedule 20.08.2009
comment
Это основано на реализации некоторых новых функций, поэтому интересует вопрос. - person Mark Redman; 21.08.2009
comment
Да, я думаю, вы подтверждаете риск дистрибуции, о котором я упоминал. И это именно тот ответ, который я ищу. Спасибо! - person user160383; 21.08.2009