Как к устройству хранения данных данных проектирования для разделенной системы меток?

Как к устройству хранения данных данных проектирования для огромной системы меток (как digg или восхитительный)?

Уже существует дискуссия об этом, но это о централизованной базе данных. Так как данные, как предполагается, растут, мы должны будем разделить данные в несколько черепков скоро или позже. Так, вопрос поворачивается, чтобы быть: Как к устройству хранения данных данных проектирования для разделенной системы меток?

Система меток в основном имеет 3 таблицы:

Item (item_id, item_content)

Tag (tag_id, tag_title)

TagMapping(map_id, tag_id, item_id)

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

Для таблицы Item мы можем разделить ее содержание с ее ключом item_id. Для тега таблицы мы можем разделить его содержание с его ключом tag_id. Например, мы хотим к таблице разделов Тег в базы данных K. Мы можем просто выбрать число (tag_id % K) база данных для хранения данный тег.

Но, как к таблице разделов TagMapping?

Таблица TagMapping представляет many-many отношения. Я могу только отобразить, чтобы иметь дублирование. Таким образом, то же содержание TagMappping имеет две копии. Каждый делится с tag_id, и другой делится с item_id. В сценарии для нахождения тегов для данного объекта мы используем раздел с tag_id. Если сценарий для нахождения объектов для данного тега мы используем раздел с item_id.

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

Там какое-либо лучшее решение состоит в том, чтобы решить эту many-many проблему раздела?

8
задан Community 23 May 2017 в 12:19
поделиться

3 ответа

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

Поиск тегов для данного объекта

A1. Вы собираетесь отобразить все тегов для данного элемента сразу

A2. Вы должны убедиться, что все тегов элемента являются уникальными

Поиск элементов для данного тега

B1. Вам понадобится несколько элементов для данного тега за раз (чтобы заполнить страницу результатов поиска)

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

B3.Вы собираетесь отсортировать элементы для данного тега (или тегов) по некоторой степени популярности

Учитывая вышесказанное, я думаю, что хорошим подходом было бы разделить TagMapping по элементам. Таким образом, все теги для данного элемента находятся в одном разделе. Разделение может быть более детальным, поскольку элементов, вероятно, гораздо больше, чем тегов, и каждый элемент имеет лишь несколько тегов. Это упрощает поиск (A1), а уникальность может быть обеспечена в пределах одного раздела (A2). Кроме того, этот единственный раздел может сказать вам, соответствует ли элемент нескольким тегам (B2).

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

Порядок, в котором вы выбираете разделы, будет важен, так как он повлияет на группировку результатов поиска. Если порядок не важен (например, B3 не имеет значения), выберите разделы случайным образом, чтобы ни один из ваших разделов не стал слишком горячим. Если порядок важен, вы можете создать идентификатор элемента так, чтобы он кодировал информацию, относящуюся к порядку сортировки результатов. Тогда соответствующая схема разделения будет учитывать это кодирование.Например, если результаты представляют собой URL-адреса, отсортированные по популярности, вы можете объединить последовательный идентификатор элемента с рейтингом страницы Google для этого URL-адреса (или чего-либо подобного). Схема разделения должна гарантировать, что все элементы в данном разделе имеют одинаковую оценку. Запросы будут выбирать разделы в порядке оценки, чтобы в первую очередь возвращались наиболее популярные элементы (B3). Очевидно, это допускает только один вид сортировки, и задействованные свойства должны быть постоянными, поскольку теперь они являются частью ключа и определяют раздел записи. Это не совсем новое ограничение, поскольку нелегко поддерживать различные виды или сортировки по изменчивым свойствам, в любом случае с разделенными данными.

4
ответ дан 5 December 2019 в 22:17
поделиться

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

Вы говорите о раздаче БД, обычно это в основном проблема синхронизации . Чтение, которое обычно составляет около 90% работы, может выполняться в реплицированной базе данных. Проблема в том, как обновить одну БД и сохранить согласованность со всеми остальными без снижения производительности. Это зависит от деталей вашего сценария.

Другая возможность - разделить, как вы и просили, все данные без перекрытия.Вы, вероятно, будете разбивать на разделы по идентификатору пользователя или идентификатору темы. Если вы разбиваете по идентификатору темы, одна база данных может ссылаться на все темы и просто сообщать, в какой выделенной базе данных хранятся данные. Затем вы можете запросить правильный. Поскольку вы разделяете по идентификатору, вся информация, относящаяся к этой теме, может находиться в этой специализированной базе данных. Вы также можете разделить на язык или страну для международного веб-сайта.

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

PS: Не забывайте о кешировании, это сэкономит вам больше, чем распределенная БД.

1
ответ дан 5 December 2019 в 22:17
поделиться

Правило заключается в том, что разделение выполняется по полю, по которому вы собираетесь делать запрос. В противном случае вам придется просматривать все разделы. Вы уверены, что вам нужно запросить таблицу Tag только по tag_id? Я думаю, что нет, вам также понадобится запрос по названию тега. Это не так очевидно для таблицы Item, но, возможно, вы также захотите сделать запрос по чему-то вроде URL, чтобы найти item_id для него, когда другой пользователь будет присваивать ему теги.

Но обратите внимание, что таблицы Tag и Item имеют неизменяемые названия и URL. Это означает, что вы можете использовать следующую технику:

  1. Выберите раздел из заголовка (для тега) или URL (для элемента).
  2. Выберите последовательность для этого раздела, чтобы сгенерировать идентификатор.

Вы либо используете пару partition-localID в качестве глобального идентификатора, либо используете непересекающиеся наборы чисел. В любом случае, теперь вы можете вычислить раздел из полей id и title/URL. Не знаете количество разделов заранее или опасаетесь, что оно может измениться в будущем? Создайте больше разделов и объедините их в группы, чтобы в будущем их можно было перегруппировать.

Конечно, вы не можете сделать то же самое для таблицы TagMapping, поэтому вам придется ее дублировать. Вам нужно запросить ее по map_id, по tag_id, по item_id, верно? Так что даже без разделения вам придется дублировать данные, создавая 3 индекса. Разница в том, что вы используете разные разделы (по разным полям) для каждого индекса. Я не вижу причин для беспокойства.

1
ответ дан 5 December 2019 в 22:17
поделиться
Другие вопросы по тегам:

Похожие вопросы: