Как мне (быстро) сопоставить идентификаторы из разных таблиц?
-
22-08-2019 - |
Вопрос
У меня есть три денормализованные таблицы, которые мне приходится принимать за чистую монету (данные поступают из какого-то внешнего ресурса).Три таблицы имеют разные определения, но каждая из них описывает один и тот же объект с разных точек зрения.
object1 A B
object2 A
object3 B C
object4 C
Единственное общее между этими таблицами — это их первичный ключ.Я могу объединить идентификаторы с помощью SELECT UNION SELECT, но запрос кажется относительно медленным, даже если в каждой таблице индексировано поле PK.Я мог бы создать представление, чтобы абстрагировать этот запрос, vw_object_ids, но оно выполняется с той же скоростью.Я думал, что смогу добавить индекс для материализации представления, но в SQL Server 2005 нельзя индексировать представления с помощью UNION.
Я хочу, чтобы главный индекс идентификаторов был синхронизирован с базовыми данными, которые могут обновляться или удаляться в любое время.Думаю, я мог бы делать это бесконечно с помощью сумасшедшего набора триггеров или просто довольствоваться скоростью неиндексированного представления.Но я просто хотел убедиться, что не упускаю ни одного варианта, имеет ли этот сценарий название или указывает на закономерность.
Мысли?
Решение
Создайте главную таблицу, содержащую только идентификатор:
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
и удалите записи из всех трех таблиц, если таковые имеются.
Другие советы
Почему бы просто не выполнить внешнее соединение, а затем объединить столбцы из таблиц компонентов?