sql >> Database teknologi >  >> RDS >> PostgreSQL

Hvordan kan jeg indsætte almindelige data i en midlertidig tabel fra forskellige skemaer?

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, hvis order_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 blander timestamp og timestamptz , skal du placere timestamp i en bestemt tidszone med AT 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å et timestamp resulterer i timestamptz . 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 for order_nr . Brug bare text uden vilkårlig længdemodifikator, hvis det skal være en streng. Hvis alle ordrenumre udelukkende består af cifre, integer eller bigint 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.



  1. Hvorfor er de slettede (uforpligtede) rækker i Oracle SQL ikke synlige i den aktuelle session, men synlige i andre sessioner?

  2. Direkte adgang til serverdatabase via Ajax (uden PHP eller en anden mellemliggende)

  3. Oracle fremmed nøgle

  4. Får fejl Ulovlig blanding af kollationer (utf8mb4_unicode_ci,IMPLICIT) og (utf8mb4_general_ci,IMPLICIT) for operation '='