Ten eerste kunt u een VIEW
maken
om deze functionaliteit te bieden:
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;
U kunt deze weergave opvragen zoals elke andere tabel:
SELECT * FROM orders WHERE order_nr = 123 AND source = 2;
-
De
source
is nodig als hetorder_nr
is niet uniek. Hoe zou je anders unieke bestelnummers over verschillende bronnen garanderen? -
Een
timestamp without time zone
is een ambigue in een mondiale context. Het is alleen goed in verband met zijn tijdzone. Als jetimestamp
door elkaar haalt entimestamptz
, moet u detimestamp
. plaatsen in een bepaalde tijdzone met deAT TIME ZONE
bouwen om dit te laten werken. Lees voor meer uitleg dit gerelateerde antwoord .Ik gebruik UTC als tijdzone, misschien wilt u een andere opgeven. Een eenvoudige cast
"OrderDate"::timestamptz
zou uitgaan van uw huidige tijdzone.AT TIME ZONE
toegepast op eentimestamp
resulteert intimestamptz
. Daarom heb ik geen andere cast toegevoegd. -
Terwijl je kunt , raad ik aan om geen camel-case-ID's te gebruiken in PostgreSQL ooit . Vermijdt vele soorten mogelijke verwarring. Let op de kleine letters (zonder de nu overbodige dubbele aanhalingstekens) die ik heb opgegeven.
-
Gebruik
varchar(25)
niet als type voor hetorder_nr
. Gebruik gewoontext
zonder willekeurige lengtemodifier als het een string moet zijn. Als alle bestelnummers uitsluitend uit cijfers bestaan,integer
ofbigint
zou sneller zijn.
Prestaties
Een manier om dit snel te maken zou zijn om het uitzicht te materialiseren. Dat wil zeggen, schrijf het resultaat in een (tijdelijke) 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);
Je nodig een index. In mijn voorbeeld levert de primaire sleutelbeperking automatisch de index.
Als je tabellen groot zijn, zorg er dan voor dat je voldoende tijdelijke buffers hebt om dit voor in het RAM af te handelen je maakt de temp tabel. Anders zal het je juist vertragen.
SET temp_buffers = 1000MB;
Moet de eerste oproep zijn om tijdelijke objecten in uw sessie te plaatsen. Zet het niet wereldwijd hoog, alleen voor uw sessie. Een tijdelijke tafel wordt sowieso automatisch verwijderd aan het einde van je sessie.
Om een schatting te krijgen hoeveel RAM u nodig heeft, maakt u de tabel één keer aan en meet u:
SELECT pg_size_pretty(pg_total_relation_size('tmp_orders'));
Meer over objectgroottes onder deze gerelateerde vraag over dba.SE .
Alle overhead loont alleen als je meerdere vragen binnen één sessie moet verwerken. Voor andere use-cases zijn er andere oplossingen. Als u de brontabel kent op het moment van de query, zou het veel sneller zijn om uw query in plaats daarvan naar de brontabel te leiden. Als je dat niet doet, zou ik de uniciteit van je order_nr
in twijfel trekken nog een keer. Als het in feite gegarandeerd uniek is, kun je de kolom source
. weglaten Ik heb geïntroduceerd.
Voor slechts één of enkele zoekopdrachten kan het sneller zijn om de weergave te gebruiken in plaats van de gerealiseerde weergave.
Ik zou ook een plpgsql-functie . overwegen die de ene tabel na de andere doorzoekt totdat het record is gevonden. Misschien goedkoper voor een paar vragen, gezien de overhead. Indexen voor elke benodigde tafel natuurlijk.
Ook als u zich houdt aan text
of varchar
voor uw order_nr
, overweeg COLLATE "C"
ervoor.