Come faccio a (velocemente) raccolgono gli ID da diverse tabelle?
-
22-08-2019 - |
Domanda
Ho tre tabelle denormalizzati che devo prendere per oro colato (dati provengono da qualche risorsa esterna). Le tre tabelle hanno definizioni diverse, ma ognuno di loro descrivono lo stesso oggetto da diversi punti di vista.
object1 A B
object2 A
object3 B C
object4 C
L'unica comunanza tra queste tabelle è la loro chiave primaria. Posso corral gli ID insieme utilizzando SELEZIONA UNION SELECT, ma la query sembra relativamente lento, anche se ogni tavolo ha indicizzato il suo campo PK. Potrei creare una vista di astrarre questa query, vw_object_ids, ma esegue alla stessa velocità. Pensavo di poter aggiungere un indice di materializzare la vista, ma in SQL Server 2005, è possibile non vista index con i sindacati.
Quello che voglio è quello di avere un indice principale di ID essere in sintonia con con i dati sottostanti, che possono rimanere aggiornati o cancellati ogni volta. Credo che avrei potuto fare questo a tempo indeterminato con una serie pazzesca di trigger o semplicemente accontentarsi per la velocità della vista indicizzata. Ma volevo solo assicurarmi che non mi manca qualsiasi opzione o se questo scenario ha un nome o è indicativo di un modello.
Pensieri?
Soluzione
Creare una tabella principale che contiene solo l'ID:
CREATE TABLE master (ID INT NOT NULL PRIMARY KEY)
e fare tutti e tre i tavoli per fare riferimento a quel tavolo principale con ON DELETE CASCADE
.
Per popolare la tabella per la prima volta, il rilascio
INSERT
INTO master
SELECT id
FROM a
UNION
SELECT id
FROM b
UNION
SELECT id
FROM c
Per popolare la tabella su base regolare, creare un trigger su ciascuno dei tre tavoli.
Questo trigger dovrebbe cercare di inserire il nuovo ID
per master
e fallire in modo silenzioso sulla violazione PRIMARY KEY
.
Per interrogare, uso:
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
In questo modo utilizzare gli indici efficienty.
Per eliminare, l'uso:
DELETE
FROM master
WHERE id = @id
Questa sparerà ON DELETE CASCADE
ed eliminare record da tutte e tre le tabelle se del caso.
Altri suggerimenti
Perché non basta fare un outer join e poi confluire le colonne dalle tabelle dei componenti?