DBA: konzekerani mwaluso zolumikizirana ndi zotumiza kunja
Kwa makonzedwe ovuta a ma data akuluakulu (osiyana Zotsatira za ETL: kuitanitsa, kutembenuka ndi kugwirizanitsa ndi gwero lakunja) nthawi zambiri pamakhala chosowa kwa kanthawi "kumbukirani" ndipo nthawi yomweyo ikonza chinthu voluminous.
M'malo mwake, matebulo osakhalitsa a PostgreSQL ndi ofanana ndi ena aliwonse. Choncho, zikhulupiriro ngati βChilichonse chomwe chilipo chimasungidwa mβchikumbukiro, ndipo chimathaβ. Koma palinso zosiyana zingapo.
"Namespace" yanu pa kulumikizana kulikonse ku database
Chifukwa chake, kuyesa kuyipanganso, kuchokera ku kulumikizana kosiyana kupita ku pgbouncer, kumabweretsa cholakwika. Koma izi zitha kupewedwa pogwiritsa ntchito CREATE TEMPORARY TABLE IF NOT EXISTS x.
Zoona, ndi bwino kuti musachite izi, chifukwa ndiye mukhoza "mwadzidzidzi" kupeza deta yomwe yatsala kuchokera kwa "mwiniwake wakale". M'malo mwake, ndi bwino kuwerenga bukuli ndikuwona kuti popanga tebulo ndizotheka kuwonjezera ON COMMIT DROP - ndiye kuti, ntchito ikatha, tebulo lidzachotsedwa.
Kusabwerezabwereza
Chifukwa amangolumikizana ndi gulu linalake, matebulo osakhalitsa samapangidwanso. Koma izi zimathetsa kufunika kawiri kujambula deta mu mulu + WAL, kotero INSERT/UPDATE/FUTA mmenemo ndiyofulumira kwambiri.
Koma popeza tebulo lakanthawi likadali tebulo "lapafupifupi", silingapangidwenso pachithunzichi. Osachepera pano, ngakhale chigamba chofananiracho chakhala chikuzungulira kwa nthawi yayitali.
1.2. TABELO OSALOGGWA
Koma muyenera kuchita chiyani, mwachitsanzo, ngati muli ndi mtundu wina wazovuta za ETL zomwe sizingachitike pakangochitika kamodzi, koma pgbouncer mu transaction mode? ..
Kapena kuyenda kwa data kumakhala kwakukulu kwambiri Palibe bandwidth yokwanira pa kulumikizana kumodzi kuchokera ku database (werengani, njira imodzi pa CPU)?..
Kapena maopareshoni ena akuchitika asynchronously m'malo osiyanasiyana?..
pa ON COMMIT DROP Ndalemba kale pamwambapa, imapanga DROP TABLE,koma ndi ON COMMIT DELETE ROWS mkhalidwewu ndi wosangalatsa kwambiri - wapangidwa apa TRUNCATE TABLE.
Popeza zida zonse zosungiramo mafotokozedwe a meta osakhalitsa ndizofanana ndendende ndi tebulo lanthawi zonse, ndiye Kulengedwa kosalekeza ndi kuchotsedwa kwa matebulo osakhalitsa kumabweretsa "kutupa" kwakukulu kwa matebulo a dongosolo pg_class, pg_attribute, pg_attrdef, pg_depend,β¦
Tsopano taganizirani kuti muli ndi wogwira ntchito pa kugwirizana kwachindunji ku database, yomwe imatsegula malonda atsopano sekondi iliyonse, imapanga, imadzaza, imayendetsa ndikuchotsa tebulo losakhalitsa ... izi zidzapangitsa mabuleki owonjezera pa ntchito iliyonse.
Kawirikawiri, musachite izi! Pankhaniyi ndizothandiza kwambiri CREATE TEMPORARY TABLE x ... ON COMMIT DELETE ROWS zichotseni pakusinthana - ndiye poyambira pazochitika zatsopano zilizonse matebulo ali kale adzakhalapo (sungani foni CREATE), koma adzakhala opanda kanthu, chifukwa cha TRUNCATE (tidasunganso kuyitana kwake) pomaliza ntchito yapitayi.
Koma ulesi ndiye injini ya chitukuko! Ndichifukwa chake pangani tebulo latsopano "kutengera zitsanzo" zitha kukhala zophweka:
CREATE TEMPORARY TABLE import_table(
LIKE target_table
);
Popeza mutha kupanga zambiri patebuloli, kusaka sikudzakhala mwachangu. Koma pali njira yachikhalidwe pa izi - ma index! Ndipo, inde, tebulo losakhalitsa likhozanso kukhala ndi ma index.
Popeza, nthawi zambiri, ma index omwe amafunikira amagwirizana ndi ma index a tebulo lomwe mukufuna, mutha kungolemba LIKE target_table INCLUDING INDEXES.
Ngati inunso muyenera DEFAULT-values ββ(mwachitsanzo, kudzaza makiyi oyambira), mutha kugwiritsa ntchito LIKE target_table INCLUDING DEFAULTS. Kapena mophweka - LIKE target_table INCLUDING ALL - makope osasintha, ma index, zopinga, ...
Koma apa muyenera kumvetsetsa kuti ngati mudapanga lowetsani tebulo nthawi yomweyo ndi ma index, ndiye kuti datayo idzatenga nthawi yayitali kuti muyikekuposa ngati mutadzaza zonse, ndiyeno pokhapo pindani ma index - onani momwe zimachitira izi monga chitsanzo pg_kuta.
Chitsanzo chodziwika bwino cha mkhalidwe wotero ndi Chithunzi cha KLADR - pali ma adilesi ambiri, koma pakukweza kwa mlungu uliwonse pali zosintha zochepa (kusinthidwa kwa malo okhala, kuphatikiza misewu, mawonekedwe a nyumba zatsopano) ngakhale pamlingo wadziko lonse.
Panali chigamba cha WIP chochokera kwa Simon Riggs chomwe chimalimbikitsa kupanga ALTER-Opaleshoni m'malo tebulo thupi pa wapamwamba mlingo, popanda kukhudza ziwerengero ndi FK, koma sanatolere quorum.
-- Π²ΡΠ΅ Π΄Π΅Π»Π°Π΅ΠΌ Π² ΡΠ°ΠΌΠΊΠ°Ρ ΡΡΠ°Π½Π·Π°ΠΊΡΠΈΠΈ, ΡΡΠΎΠ±Ρ Π½ΠΈΠΊΡΠΎ Π½Π΅ Π²ΠΈΠ΄Π΅Π» "ΠΏΡΠΎΠΌΠ΅ΠΆΡΡΠΎΡΠ½ΡΡ " ΡΠΎΡΡΠΎΡΠ½ΠΈΠΉ
BEGIN;
-- ΡΠΎΠ·Π΄Π°Π΅ΠΌ Π²ΡΠ΅ΠΌΠ΅Π½Π½ΡΡ ΡΠ°Π±Π»ΠΈΡΡ Ρ ΠΈΠΌΠΏΠΎΡΡΠΈΡΡΠ΅ΠΌΡΠΌΠΈ Π΄Π°Π½Π½ΡΠΌΠΈ
CREATE TEMPORARY TABLE tmp(
LIKE dst INCLUDING INDEXES -- ΠΏΠΎ ΠΎΠ±ΡΠ°Π·Ρ ΠΈ ΠΏΠΎΠ΄ΠΎΠ±ΠΈΡ, Π²ΠΌΠ΅ΡΡΠ΅ Ρ ΠΈΠ½Π΄Π΅ΠΊΡΠ°ΠΌΠΈ
) ON COMMIT DROP; -- Π·Π° ΡΠ°ΠΌΠΊΠ°ΠΌΠΈ ΡΡΠ°Π½Π·Π°ΠΊΡΠΈΠΈ ΠΎΠ½Π° Π½Π°ΠΌ Π½Π΅ Π½ΡΠΆΠ½Π°
-- Π±ΡΡΡΡΠΎ-Π±ΡΡΡΡΠΎ Π²Π»ΠΈΠ²Π°Π΅ΠΌ Π½ΠΎΠ²ΡΠΉ ΠΎΠ±ΡΠ°Π· ΡΠ΅ΡΠ΅Π· COPY
COPY tmp FROM STDIN;
-- ...
-- .
-- ΡΠ΄Π°Π»ΡΠ΅ΠΌ ΠΎΡΡΡΡΡΡΠ²ΡΡΡΠΈΠ΅
DELETE FROM
dst D
USING
dst X
LEFT JOIN
tmp Y
USING(pk1, pk2) -- ΠΏΠΎΠ»Ρ ΠΏΠ΅ΡΠ²ΠΈΡΠ½ΠΎΠ³ΠΎ ΠΊΠ»ΡΡΠ°
WHERE
(D.pk1, D.pk2) = (X.pk1, X.pk2) AND
Y IS NOT DISTINCT FROM NULL; -- "Π°Π½ΡΠΈΠ΄ΠΆΠΎΠΉΠ½"
-- ΠΎΠ±Π½ΠΎΠ²Π»ΡΠ΅ΠΌ ΠΎΡΡΠ°Π²ΡΠΈΠ΅ΡΡ
UPDATE
dst D
SET
(f1, f2, f3) = (T.f1, T.f2, T.f3)
FROM
tmp T
WHERE
(D.pk1, D.pk2) = (T.pk1, T.pk2) AND
(D.f1, D.f2, D.f3) IS DISTINCT FROM (T.f1, T.f2, T.f3); -- Π½Π΅Π·Π°ΡΠ΅ΠΌ ΠΎΠ±Π½ΠΎΠ²Π»ΡΡΡ ΡΠΎΠ²ΠΏΠ°Π΄Π°ΡΡΠΈΠ΅
-- Π²ΡΡΠ°Π²Π»ΡΠ΅ΠΌ ΠΎΡΡΡΡΡΡΠ²ΡΡΡΠΈΠ΅
INSERT INTO
dst
SELECT
T.*
FROM
tmp T
LEFT JOIN
dst D
USING(pk1, pk2)
WHERE
D IS NOT DISTINCT FROM NULL;
COMMIT;
Ngati njira yanu yokhayo ili ndi mwayi wolembera panthawi yolumikizana, ndiye kuti mutha kugwiritsa ntchito choyambitsa chomwe chingatitengere zosintha zonse:
-- ΡΠ΅Π»Π΅Π²ΡΠ΅ ΡΠ°Π±Π»ΠΈΡΡ
CREATE TABLE kladr(...);
CREATE TABLE kladr_house(...);
-- ΡΠ°Π±Π»ΠΈΡΡ Ρ ΠΈΡΡΠΎΡΠΈΠ΅ΠΉ ΠΈΠ·ΠΌΠ΅Π½Π΅Π½ΠΈΠΉ
CREATE TABLE kladr$log(
ro kladr, -- ΡΡΡ Π»Π΅ΠΆΠ°Ρ ΡΠ΅Π»ΡΠ΅ ΠΎΠ±ΡΠ°Π·Ρ Π·Π°ΠΏΠΈΡΠ΅ΠΉ ΡΡΠ°ΡΠΎΠΉ/Π½ΠΎΠ²ΠΎΠΉ
rn kladr
);
CREATE TABLE kladr_house$log(
ro kladr_house,
rn kladr_house
);
-- ΠΎΠ±ΡΠ°Ρ ΡΡΠ½ΠΊΡΠΈΡ Π»ΠΎΠ³ΠΈΡΠΎΠ²Π°Π½ΠΈΡ ΠΈΠ·ΠΌΠ΅Π½Π΅Π½ΠΈΠΉ
CREATE OR REPLACE FUNCTION diff$log() RETURNS trigger AS $$
DECLARE
dst varchar = TG_TABLE_NAME || '$log';
stmt text = '';
BEGIN
-- ΠΏΡΠΎΠ²Π΅ΡΡΠ΅ΠΌ Π½Π΅ΠΎΠ±Ρ ΠΎΠ΄ΠΈΠΌΠΎΡΡΡ Π»ΠΎΠ³Π³ΠΈΡΠΎΠ²Π°Π½ΠΈΡ ΠΏΡΠΈ ΠΎΠ±Π½ΠΎΠ²Π»Π΅Π½ΠΈΠΈ Π·Π°ΠΏΠΈΡΠΈ
IF TG_OP = 'UPDATE' THEN
IF NEW IS NOT DISTINCT FROM OLD THEN
RETURN NEW;
END IF;
END IF;
-- ΡΠΎΠ·Π΄Π°Π΅ΠΌ Π·Π°ΠΏΠΈΡΡ Π»ΠΎΠ³Π°
stmt = 'INSERT INTO ' || dst::text || '(ro,rn)VALUES(';
CASE TG_OP
WHEN 'INSERT' THEN
EXECUTE stmt || 'NULL,$1)' USING NEW;
WHEN 'UPDATE' THEN
EXECUTE stmt || '$1,$2)' USING OLD, NEW;
WHEN 'DELETE' THEN
EXECUTE stmt || '$1,NULL)' USING OLD;
END CASE;
RETURN NEW;
END;
$$ LANGUAGE plpgsql;
CREATE TRIGGER log
AFTER INSERT OR UPDATE OR DELETE
ON kladr
FOR EACH ROW
EXECUTE PROCEDURE diff$log();
CREATE TRIGGER log
AFTER INSERT OR UPDATE OR DELETE
ON kladr_house
FOR EACH ROW
EXECUTE PROCEDURE diff$log();
Kenako timachotsa mwakachetechete zosintha zonse zomwe timafunikira pamatebulo a logi ndikuziyendetsa kudzera mwa othandizira ena.
3.3. Kulowetsa Ma Seti Olumikizidwa
Pamwambapa tidaganizira nthawi zomwe magawo a data amachokera ndi kopita ali ofanana. Koma bwanji ngati kukweza kuchokera kudongosolo lakunja kuli ndi mawonekedwe osiyana ndi momwe amasungiramo mu database yathu?
Tiyeni titenge mwachitsanzo kusungirako makasitomala ndi maakaunti awo, njira yachidule ya "ambiri-to-one":
CREATE TABLE client(
client_id
serial
PRIMARY KEY
, inn
varchar
UNIQUE
, name
varchar
);
CREATE TABLE invoice(
invoice_id
serial
PRIMARY KEY
, client_id
integer
REFERENCES client(client_id)
, number
varchar
, dt
date
, sum
numeric(32,2)
);
Koma kutsitsa kuchokera kunja kumabwera kwa ife mu mawonekedwe a "onse mumodzi":
-- ΠΏΡΠΎΡΡΠ°Π²Π»ΡΠ΅ΠΌ Π² ΡΠ°Π±Π»ΠΈΡΠ΅ ΠΈΠΌΠΏΠΎΡΡΠ° ID ΡΠΆΠ΅ ΡΡΡΠ΅ΡΡΠ²ΡΡΡΠΈΡ Π·Π°ΠΏΠΈΡΠ΅ΠΉ
UPDATE
client_import T
SET
client_id = D.client_id
FROM
client D
WHERE
T.inn = D.inn; -- unique key
-- Π²ΡΡΠ°Π²Π»ΡΠ΅ΠΌ ΠΎΡΡΡΡΡΡΠ²ΠΎΠ²Π°Π²ΡΠΈΠ΅ Π·Π°ΠΏΠΈΡΠΈ ΠΈ ΠΏΡΠΎΡΡΠ°Π²Π»ΡΠ΅ΠΌ ΠΈΡ ID
WITH ins AS (
INSERT INTO client(
inn
, name
)
SELECT
inn
, name
FROM
client_import
WHERE
client_id IS NULL -- Π΅ΡΠ»ΠΈ ID Π½Π΅ ΠΏΡΠΎΡΡΠ°Π²ΠΈΠ»ΡΡ
RETURNING *
)
UPDATE
client_import T
SET
client_id = D.client_id
FROM
ins D
WHERE
T.inn = D.inn; -- unique key
-- ΠΏΡΠΎΡΡΠ°Π²Π»ΡΠ΅ΠΌ ID ΠΊΠ»ΠΈΠ΅Π½ΡΠΎΠ² Ρ Π·Π°ΠΏΠΈΡΠ΅ΠΉ ΡΡΠ΅ΡΠΎΠ²
UPDATE
invoice_import T
SET
client_id = D.client_id
FROM
client_import D
WHERE
T.client_inn = D.inn; -- ΠΏΡΠΈΠΊΠ»Π°Π΄Π½ΠΎΠΉ ΠΊΠ»ΡΡ