Først kan du oprette en VIEW
for at give denne funktionalitet:
CREATE VIEW orders AS
SELECT '1'::int AS source -- or any other tag to identify source
,"OrderNumber"::text AS order_nr
,"InvoiceNumber" AS tansaction_id -- no cast .. is int already
,"OrderDate" AT TIME ZONE 'UTC' AS purchase_date -- !! see explanation
FROM tbl_newegg
UNION ALL -- not UNION!
SELECT 2
"amazonOrderId"
,"merchant-order-id"
,"purchase-date"
FROM tbl_amazon;
Du kan forespørge på denne visning som enhver anden tabel:
SELECT * FROM orders WHERE order_nr = 123 AND source = 2;
-
source
er nødvendig, hvisorder_nr
er ikke enestående. Hvordan ville du ellers garantere unikke ordrenumre over forskellige kilder? -
Et
timestamp without time zone
er en tvetydig i en global sammenhæng. Det er kun godt i forbindelse med sin tidszone. Hvis du blandertimestamp
ogtimestamptz
, skal du placeretimestamp
i en bestemt tidszone medAT TIME ZONE
konstruere for at få dette til at fungere. For mere forklaring læs dette relaterede svar .Jeg bruger UTC som tidszone, du vil måske angive en anden. En simpel cast
"OrderDate"::timestamptz
ville antage din nuværende tidszone.AT TIME ZONE
anvendt på ettimestamp
resulterer itimestamptz
. Det er derfor, jeg ikke tilføjede endnu en rollebesætning. -
Mens du kan , Jeg anbefaler ikke at bruge kamel-case-id'er i PostgreSQL nogensinde . Undgår mange former for mulig forvirring. Bemærk de små bogstaver (uden de nu unødvendige dobbelte anførselstegn), jeg har leveret.
-
Brug ikke
varchar(25)
som type fororder_nr
. Brug baretext
uden vilkårlig længdemodifikator, hvis det skal være en streng. Hvis alle ordrenumre udelukkende består af cifre,integer
ellerbigint
ville være hurtigere.
Ydeevne
En måde at gøre dette hurtigt på ville være at materialisere udsigten. Dvs. skriv resultatet ind i en (midlertidig) tabel:
CREATE TEMP TABLE tmp_orders AS
SELECT * FROM orders;
ANALYZE tmp_orders; -- temp tables are not auto-analyzed!
ALTER TABLE tmp_orders
ADD constraint orders_pk PRIMARY KEY (order_nr, source);
Du bruger et indeks. I mit eksempel giver den primære nøglebegrænsning indekset automatisk.
Hvis dine borde er store, skal du sørge for at have nok midlertidige buffere at håndtere dette i RAM før du opretter temp-tabellen. Ellers vil det faktisk bremse dig.
SET temp_buffers = 1000MB;
Skal være det første opkald til midlertidige objekter i din session. Sæt det ikke højt globalt, kun for din session. En midlertidig tabel droppes alligevel automatisk i slutningen af din session.
For at få et skøn over, hvor meget RAM du har brug for, skal du oprette tabellen én gang og måle:
SELECT pg_size_pretty(pg_total_relation_size('tmp_orders'));
Mere om objektstørrelser under dette relaterede spørgsmål på dba.SE .
Al overhead betaler sig kun, hvis du skal behandle et antal forespørgsler inden for en session. Til andre brugssager er der andre løsninger. Hvis du kender kildetabellen på tidspunktet for forespørgslen, ville det være meget hurtigere at dirigere din forespørgsel til kildetabellen i stedet for. Hvis du ikke gør det, vil jeg stille spørgsmålstegn ved det unikke ved din order_nr
en gang til. Hvis det faktisk er garanteret at være unikt, kan du droppe kolonnen source
Jeg introducerede.
For kun én eller nogle få forespørgsler kan det være hurtigere at bruge visningen i stedet for den materialiserede visning.
Jeg ville også overveje en plpgsql-funktion der forespørger den ene tabel efter den anden, indtil posten er fundet. Kan være billigere for et par forespørgsler i betragtning af overhead. Indekser for alle nødvendige bord selvfølgelig.
Også, hvis du holder dig til text
eller varchar
for din order_nr
, overvej COLLATE "C"
for det.