Misy toe-javatra rehefa amin'ny latabatra tsy misy fanalahidy fototra na fanondro hafa tsy manam-paharoa, noho ny fanaraha-maso, dia ampidirina ireo clones feno amin'ireo rakitra efa misy.
Ohatra, ny soatoavin'ny metric chronological dia voasoratra ao amin'ny PostgreSQL mampiasa stream COPY, ary avy eo dia misy ny tsy fahombiazana tampoka, ary tonga indray ny ampahany amin'ny angona mitovy tanteraka.
Ahoana ny fanesorana ny angon-drakitra amin'ny klones tsy ilaina?
Rehefa tsy mpanampy i PK
Ny fomba tsotra indrindra dia ny fisorohana ny toe-javatra toy izany amin'ny voalohany. Ohatra, manorata KEY PRIMARY. Saingy tsy azo atao foana izany raha tsy mampitombo ny habetsaky ny angona voatahiry.
Ohatra, raha ambony noho ny fahamarinan'ny saha ao amin'ny tahiry ny fahamarinan'ny rafitra loharano:
metric | ts | data
--------------------------------------------------
cpu.busy | 2019-12-20 00:00:00 | {"value" : 12.34}
cpu.busy | 2019-12-20 00:00:01 | {"value" : 10}
cpu.busy | 2019-12-20 00:00:01 | {"value" : 11.2}
cpu.busy | 2019-12-20 00:00:03 | {"value" : 15.7}
Voamarikao ve? Ny countdown fa tsy 00:00:02 dia voarakitra ao amin'ny angon-drakitra miaraka amin'ny ts iray segondra teo aloha, saingy nijanona ho manan-kery avy amin'ny fomba fijery fampiharana (na izany aza, ny soatoavin'ny data dia samy hafa!).
Mazava ho azy fa vitanao izany PK(metrika, ts) - fa avy eo dia hahazo fifandirana fampidirana ho an'ny angona manan-kery.
Afaka manao PK(metric, ts, data) - fa izany dia hampitombo be ny habeny, izay tsy hampiasaintsika.
Noho izany, ny safidy marina indrindra dia ny fanaovana tondro tsy mahazatra mahazatra (metrika, ts) ary miatrika olana aorian'ny zava-misy raha toa ka mitranga izany.
"Efa nanomboka ny ady klonika"
Nisy karazana loza nitranga, ary ankehitriny dia tsy maintsy handrava ny clone firaketana avy amin'ny latabatra.
Andao hatao modely ny angona tany am-boalohany:
CREATE TABLE tbl(k text, v integer);
INSERT INTO tbl
VALUES
('a', 1)
, ('a', 3)
, ('b', 2)
, ('b', 2) -- oops!
, ('c', 3)
, ('c', 3) -- oops!!
, ('c', 3) -- oops!!
, ('d', 4)
, ('e', 5)
;
In-telo nangovitra ny tananay, Ctrl+V niraikitra, ary izao...
Voalohany, andeha hojerentsika fa ny latabatra misy antsika dia mety ho lehibe be, ka rehefa avy mahita ny clones rehetra isika, dia tsara ho antsika ny "manindrona ny rantsan-tΓ nantsika" ara-bakiteny mba hamafa. firaketana manokana nefa tsy mikaroka azy ireo indray.
Ary misy fomba toy izany - izany
Izany hoe, voalohany indrindra, dia mila manangona ny ctid ny firaketana an-tsoratra ao amin'ny toe-javatra ny votoaty feno ny latabatra andalana. Ny safidy tsotra indrindra dia ny fandefasana ny andalana manontolo ho lahatsoratra:
SELECT
T::text
, array_agg(ctid) ctids
FROM
tbl T
GROUP BY
1;
t | ctids
---------------------------------
(e,5) | {"(0,9)"}
(d,4) | {"(0,8)"}
(c,3) | {"(0,5)","(0,6)","(0,7)"}
(b,2) | {"(0,3)","(0,4)"}
(a,3) | {"(0,2)"}
(a,1) | {"(0,1)"}
Azo atao ve ny tsy manary?Amin'ny ankapobeny dia azo atao izany amin'ny ankamaroan'ny tranga. Mandra-panombohanao mampiasa saha amin'ity tabilao ity karazana tsy misy mpandraharaha mitovy:
CREATE TABLE tbl(k text, v integer, x point);
SELECT
array_agg(ctid) ctids
FROM
tbl T
GROUP BY
T;
-- ERROR: could not identify an equality operator for type tbl
Eny, hitantsika avy hatrany fa raha misy fidirana mihoatra ny iray ao amin'ny array dia klones daholo ireo. Avelao fotsiny izy ireo:
SELECT
unnest(ctids[2:])
FROM
(
SELECT
array_agg(ctid) ctids
FROM
tbl T
GROUP BY
T::text
) T;
unnest
------
(0,6)
(0,7)
(0,4)
Ho an'ireo tia manoratra fohy kokoaAzonao atao koa ny manoratra azy toy izao:
SELECT
unnest((array_agg(ctid))[2:])
FROM
tbl T
GROUP BY
T::text;
Koa satria tsy mahaliana antsika ny sandan'ny tady serialised, dia nariantsika fotsiny avy ao amin'ny tsanganana miverina amin'ny subquery.
Kely sisa no tokony hatao - ampiasao ny DELETE amin'ny seta azonay:
DELETE FROM
tbl
WHERE
ctid = ANY(ARRAY(
SELECT
unnest(ctids[2:])
FROM
(
SELECT
array_agg(ctid) ctids
FROM
tbl T
GROUP BY
T::text
) T
)::tid[]);
Andeha hojerentsika ny tenantsika:
Eny, marina ny zava-drehetra: ny firaketanay 3 dia nofantenana ho an'ny Seq Scan tokana amin'ny latabatra manontolo, ary ny node Delete dia nampiasaina hikaroka data pass tokana miaraka amin'ny Tid Scan:
-> Tid Scan on tbl (actual time=0.050..0.051 rows=3 loops=1)
TID Cond: (ctid = ANY ($0))
Raha nodiovinao ny rakitra maro,
Andeha hojerentsika raha misy latabatra lehibe kokoa sy misy duplicate betsaka kokoa:
TRUNCATE TABLE tbl;
INSERT INTO tbl
SELECT
chr(ascii('a'::text) + (random() * 26)::integer) k -- a..z
, (random() * 100)::integer v -- 0..99
FROM
generate_series(1, 10000) i;
Noho izany, ny fomba fiasa dia mahomby, saingy tsy maintsy ampiasaina amim-pitandremana. Satria isaky ny rakitra voafafa dia misy pejy iray ny angona vakiana ao amin'ny Tid Scan, ary iray ao amin'ny Delete.
Source: www.habr.com