Tha suidheachaidhean ann nuair a gu bòrd gun phrìomh iuchair no clàr-amais sònraichte eile, mar thoradh air sealladh farsaing, tha clones iomlan de chlàran a tha ann mar-thà air an toirt a-steach.
Mar eisimpleir, tha luachan meatrach eachdraidheach air an sgrìobhadh a-steach do PostgreSQL a’ cleachdadh sruth COPY, agus an uairsin bidh fàilligeadh gu h-obann, agus thig pàirt den dàta gu tur co-ionann a-rithist.
Ciamar a gheibh thu cuidhteas clones neo-riatanach bhon stòr-dàta?
Nuair nach eil PK na neach-cuideachaidh
Is e an dòigh as fhasa casg a chuir air suidheachadh mar sin sa chiad àite. Mar eisimpleir, rolla PRÌOMH PRÌOMH. Ach chan eil seo an-còmhnaidh comasach gun a bhith a 'meudachadh na tha de dhàta air a stòradh.
Mar eisimpleir, ma tha cruinneas an t-siostam stòr nas àirde na cruinneas an raoin san stòr-dàta:
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}
An do mhothaich thu? The countdown instead of 00:00:02 chaidh a chlàradh anns an stòr-dàta le ts an dàrna fear na bu thràithe, ach dh'fhuirich e gu math dligheach bho shealladh tagraidh (às deidh a h-uile càil, tha luachan an dàta eadar-dhealaichte!).
Gu dearbh faodaidh tu a dhèanamh PK (meatrach, ts) - ach an uairsin gheibh sinn còmhstri cuir a-steach airson dàta dligheach.
Is urrainn a dhèanamh PK (meatrach, ts, dàta) — ach meudaichidh so gu mòr an tomhas-lìonaidh, nach cleachd sinn.
Mar sin, is e an roghainn as ceart clàr-amais cunbhalach neo-shònraichte a dhèanamh (meatrach, ts) agus dèiligeadh ri duilgheadasan às deidh an fhìrinn ma dh’ èiricheas iad.
"Tha an cogadh clonic air tòiseachadh"
Thachair tubaist de sheòrsa air choreigin, agus a-nis feumaidh sinn na clàran clone a sgrios bhon bhòrd.
Leig leinn an dàta tùsail a mhodail:
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)
;
An seo chrith ar làmh trì tursan, chaidh Ctrl+V an sàs, agus a-nis ...
An toiseach, tuigidh sinn gum faod am bòrd againn a bhith gu math mòr, agus mar sin às deidh dhuinn na clones gu lèir a lorg, tha e ciallach dhuinn gu litireil “ar meur a phutadh” airson cuir às. clàran sònraichte gun a bhith gan ath-sgrùdadh.
Agus tha leithid de dhòigh ann - seo
Is e sin, an toiseach, feumaidh sinn ctid chlàran a chruinneachadh ann an co-theacsa susbaint iomlan an t-sreath bùird. Is e an roghainn as sìmplidh an loidhne gu lèir a thilgeil ann an teacsa:
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)"}
A bheil e comasach gun a bhith a 'tilgeil?Ann am prionnsabal, tha e comasach sa mhòr-chuid de chùisean. Gus an tòisich thu a’ cleachdadh raointean sa chlàr seo seòrsaichean às aonais gnìomhaiche co-ionannachd:
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
Yeah, chì sinn sa bhad ma tha barrachd air aon inntrigeadh san raon, is e clones a tha sin uile. Fàgaidh sinn iad dìreach:
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)
Dhaibhsan a tha dèidheil air sgrìobhadh nas giorraFaodaidh tu cuideachd a sgrìobhadh mar seo:
SELECT
unnest((array_agg(ctid))[2:])
FROM
tbl T
GROUP BY
T::text;
Leis nach eil luach an t-sreang sreathach fhèin inntinneach dhuinn, tha sinn dìreach ga thilgeil a-mach às na colbhan a chaidh a thilleadh den fho-cheist.
Chan eil ach beagan air fhàgail ri dhèanamh - thoir air DELETE an seata a fhuair sinn a chleachdadh:
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[]);
Feuch an dèan sinn sgrùdadh oirnn fhìn:
Tha, tha a h-uile dad ceart: chaidh na clàran 3 againn a thaghadh airson an aon Seq Scan den chlàr gu lèir, agus chaidh an nód Sguab às a chleachdadh gus dàta a lorg pas singilte le Tid Scan:
-> Tid Scan on tbl (actual time=0.050..0.051 rows=3 loops=1)
TID Cond: (ctid = ANY ($0))
Ma ghlanas tu mòran chlàran,
Feuch an dèan sinn sgrùdadh airson clàr nas motha agus le àireamh nas motha de dhùblaidhean:
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;
Mar sin, tha an dòigh ag obair gu soirbheachail, ach feumaidh e bhith air a chleachdadh le beagan faiceallach. Oir airson a h-uile clàr a thèid a dhubhadh às, tha aon duilleag dàta air a leughadh ann an Tid Scan, agus aon ann an Sguab às.
Source: www.habr.com