Как (быстро) сопоставить идентификаторы из разных таблиц? - PullRequest
2 голосов
/ 01 апреля 2009

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

   object1  A  B
   object2  A
   object3     B  C
   object4        C

Единственное сходство между этими таблицами - это их первичный ключ. Я могу собрать идентификаторы вместе, используя SELECT UNION SELECT, но запрос кажется относительно медленным, даже если в каждой таблице есть индексированное поле PK. Я мог бы создать представление для абстрагирования этого запроса, vw_object_ids, но он работает с той же скоростью. Я думал, что мог бы добавить индекс для материализации представления, но в SQL Server 2005 нельзя индексировать представления с помощью UNION.

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

Мысли

Ответы [ 2 ]

2 голосов
/ 01 апреля 2009

Создайте основную таблицу, которая содержит только идентификатор:

CREATE TABLE master (ID INT NOT NULL PRIMARY KEY)

и создайте все три таблицы для ссылки на эту основную таблицу с помощью ON DELETE CASCADE.

Чтобы заполнить таблицу в первый раз, наберите

INSERT
INTO    master
SELECT  id
FROM    a
UNION
SELECT  id
FROM    b
UNION
SELECT  id
FROM    c

Чтобы регулярно заполнять таблицу, создайте триггер для каждой из трех таблиц.

Этот триггер должен попытаться вставить новый ID в master и молча завершиться ошибкой при PRIMARY KEY нарушении.

Для запроса используйте:

SELECT  *
FROM    master m
LEFT OUTER JOIN
        a
ON      a.id = m.id
LEFT OUTER JOIN
        b
ON      b.id = m.id
LEFT OUTER JOIN
        c
ON      c.id = m.id

Это будет эффективно использовать индексы.

Чтобы удалить, используйте:

DELETE
FROM    master
WHERE   id = @id

Это вызовет ON DELETE CASCADE и удалит записи из всех трех таблиц, если таковые имеются.

0 голосов
/ 01 апреля 2009

Почему бы просто не выполнить внешнее соединение, а затем объединить столбцы из таблиц компонентов?

...