Innanzitutto, puoi creare un VIEW
per fornire questa funzionalità:
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;
Puoi interrogare questa vista come qualsiasi altra tabella:
SELECT * FROM orders WHERE order_nr = 123 AND source = 2;
-
Il
source
è necessario se ilorder_nr
non è unico. In quale altro modo garantiresti numeri d'ordine univoci su diverse fonti? -
Un
timestamp without time zone
è un ambiguo in un contesto globale. Va bene solo in connessione con il suo fuso orario. Se mescolitimestamp
etimestamptz
, devi inserire iltimestamp
in un determinato fuso orario con ilAT TIME ZONE
costruire per farlo funzionare. Per ulteriori spiegazioni leggi questa risposta correlata .Uso UTC come fuso orario, potresti voler fornirne uno diverso. Un semplice cast
"OrderDate"::timestamptz
assumerebbe il tuo fuso orario attuale.AT TIME ZONE
applicato a untimestamp
risulta intimestamptz
. Ecco perché non ho aggiunto un altro cast. -
Mentre tu puoi , ti consiglio di non usare gli identificatori camel-case in PostgreSQL mai . Evita molti tipi di possibile confusione. Nota gli identificatori minuscoli (senza le virgolette ora non necessarie) che ho fornito.
-
Non utilizzare
varchar(25)
come tipo per ilorder_nr
. Usa semplicementetext
senza un modificatore di lunghezza arbitrario se deve essere una stringa. Se tutti i numeri d'ordine sono costituiti esclusivamente da cifre,integer
obigint
sarebbe più veloce.
Prestazioni
Un modo per rendere questo veloce sarebbe quello di materializzare la vista. Ad esempio, scrivi il risultato in una tabella (temporanea):
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);
Hai necessità un indice. Nel mio esempio, il vincolo della chiave primaria fornisce l'indice automaticamente.
Se i tuoi tavoli sono grandi, assicurati di avere abbastanza buffer temporanei per gestirlo nella RAM prima crei la tabella temporanea. Altrimenti ti rallenterà effettivamente.
SET temp_buffers = 1000MB;
Deve essere la prima chiamata agli oggetti temporanei nella tua sessione. Non impostarlo in alto a livello globale, solo per la tua sessione. Una tabella temporanea viene comunque eliminata automaticamente alla fine della sessione.
Per ottenere una stima della quantità di RAM necessaria, crea la tabella una volta e misura:
SELECT pg_size_pretty(pg_total_relation_size('tmp_orders'));
Ulteriori informazioni sulle dimensioni degli oggetti in questa domanda correlata su dba.SE .
Tutto il sovraccarico paga solo se devi elaborare un numero di query all'interno di una sessione. Per altri casi d'uso ci sono altre soluzioni. Se si conosce la tabella di origine al momento della query, sarebbe invece molto più veloce indirizzare la query alla tabella di origine. In caso contrario, metterei in dubbio l'unicità del tuo order_nr
ancora una volta. Se, infatti, è garantito che sia univoco, puoi eliminare la colonna source
Ho presentato.
Per solo una o poche query, potrebbe essere più veloce utilizzare la vista invece della vista materializzata.
Considererei anche una funzione plpgsql che interroga una tabella dopo l'altra finché non viene trovato il record. Potrebbe essere più economico per un paio di domande, considerando il sovraccarico. Ovviamente indici per ogni tabella necessaria.
Inoltre, se rimani su text
o varchar
per il tuo order_nr
, considera COLLATE "C"
per questo.