Нормализация общего типа идентификатора, общего для таблиц - PullRequest
1 голос
/ 21 октября 2008

Это упрощенная версия проблемы.

У нас есть клиенты, которые отправляют нам много данных и затем запрашивают их. Они обязаны иметь несколько «открытых» идентификаторов, по которым они могут запрашивать наши данные. (Большинство хотят запросить нашу систему через идентификатор, который они отправляют вместе с данными, но не всегда). Для простоты мы будем называть их «pid», «crid» и «musicbrainzid». У нас есть таблица «сущностей», в которой хранится эта информация. Это выглядит примерно так («авторитет» - это тот, кто отправил данные):

entity 
-- 
entity_id   
authority  // who sent the data
type       // 'pid', 'crid', 'musicbrainz', etc.
value      // the actual id value

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

Каким образом внешние клиенты могут осуществлять поиск, используя pid или crid, и получать соответствующий эпизод или серию вместе с надлежащей идентификацией того, что это такое? Учитывая pid, мы можем получить идентификатор объекта, но затем нам нужно найти таблицы значений эпизода, серии и широковещания для этого значения. Кроме того, не все идентификаторы обязательно будут связаны со всеми другими таблицами, но любой объект (например, «эпизод») может иметь несколько идентификаторов (pid, crid и т. Д.)

Стратегии:

  1. Найдите идентификатор сущности для pid и найдите в каждой другой таблице pid.
  2. Поместить столбец «entity_type» на сущность, но что, если это pid в таблице эпизодов, но мы случайно установили episode.type в серию? Мы не хотим дублировать данные, и я не хочу помещать метаданные базы данных в значения столбцов.

Опция №1 медленная и кажется неправильной (кроме того, различные таблицы имеют разные структуры, что делает проблематичным).

Вариант 2 означает дублирование данных, и эти данные могут быть не синхронизированы. Мы можем использовать триггеры для форсирования этого, но это кажется действительно неприятным, и, в любом случае, ошибки в реализации триггеров mysql поразили нас несколько раз. Мы используем эту стратегию прямо сейчас, но без триггеров.

Какой вариант 3?

Примечание: мы знаем, что нужно разбить «полномочия» на отдельные таблицы, потому что не все комбинации прав / типов действительны.

1 Ответ

3 голосов
/ 21 октября 2008

Если я правильно понял ваш вопрос, я бы выбрал вариант 1.

Запрос на идентификацию строки на основе entity_id не должен быть таким медленным, поскольку все эти данные должны быть в индексе.
Если ваши индексы настроены правильно, это не должно даже получить доступ к фактическим данным. (По крайней мере, в SQL Server это не так.)

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

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

...