د PK پرته د میز څخه د کلون ریکارډونه پاکول

داسې شرایط شتون لري کله چې له ابتدايي کیلي پرته میز ته یا ځینې نور ځانګړي شاخصونه، د نظارت له امله، د دمخه موجود ریکارډونو بشپړ کلون شامل دي.

د PK پرته د میز څخه د کلون ریکارډونه پاکول

د مثال په توګه، د کرونولوژیکي میټریک ارزښتونه د COPY جریان په کارولو سره په PostgreSQL کې لیکل شوي، او بیا ناڅاپه ناکامي شتون لري، او د بشپړ ورته معلوماتو یوه برخه بیا راځي.

د غیر ضروري کلونونو ډیټابیس څنګه پاک کړئ؟

کله چې PK یو مرستندوی نه وي

تر ټولو آسانه لاره دا ده چې په لومړي ځای کې د داسې یو حالت څخه مخنیوی وشي. د مثال په توګه، لومړنې کیلي رول کړئ. مګر دا تل د ذخیره شوي معلوماتو حجم زیاتولو پرته امکان نلري.

د مثال په توګه، که چیرې د سرچینې سیسټم دقت په ډیټابیس کې د ساحې دقت څخه لوړ وي:

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}

ایا تاسو پام کړی؟ د 00:00:02 پرځای شمیرنه په ډیټابیس کې د ts سره یوه ثانیه دمخه ثبت شوې وه ، مګر د غوښتنلیک له نظره خورا معتبره پاتې شوه (په هرصورت ، د معلوماتو ارزښتونه توپیر لري!).

البته تاسو دا کولی شئ PK(میټریک، ts) - مګر بیا به موږ د باوري معلوماتو لپاره د ننوتلو شخړې ترلاسه کړو.

کولای شي PK (میټریک، ts، ډاټا) - مګر دا به د هغې حجم خورا ډیر کړي، کوم چې موږ به یې ونه کاروو.

له همدې امله، ترټولو سمه لاره دا ده چې منظم غیر غیر معمولي شاخص جوړ کړئ (میټریک، ts) او د حقیقت څخه وروسته د ستونزو سره معامله وکړئ که دوی راپورته شي.

"کلونیکي جګړه پیل شوې"

یو ډول حادثه وشوه، او اوس موږ باید د میز څخه د کلون ریکارډونه له منځه یوسو.

د PK پرته د میز څخه د کلون ریکارډونه پاکول

راځئ چې اصلي ډاټا موډل کړو:

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)
;

دلته زموږ لاس درې ځله لړزېده، Ctrl+V ودرېده، او اوس...

لومړی، راځئ چې پوه شو چې زموږ میز خورا لوی کیدی شي، نو وروسته له دې چې موږ ټول کلونونه ومومو، دا زموږ لپاره مشوره کیږي چې په لفظي توګه "زموږ ګوتې" د حذف کولو لپاره "پټ کړئ". ځانګړي ریکارډونه پرته له دې چې دوی بیا لټون وکړي.

او داسې لاره شتون لري - دا د ctid لخوا خطاب کول، د یو ځانګړي ریکارډ فزیکي پیژندونکی.

دا، تر ټولو لومړی، موږ اړتیا لرو چې د جدول قطار د بشپړ منځپانګې په شرایطو کې د ریکارډونو ctid راټول کړو. ترټولو ساده اختیار دا دی چې ټوله کرښه په متن کې واچوي:

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)"}

ایا دا ممکنه ده چې ونه اچول شي؟په اصولو کې، دا په ډیرو مواردو کې ممکنه ده. تر هغه چې تاسو په دې جدول کې د ساحو کارول پیل کړئ ډولونه پرته د مساوات چلونکي:

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

هو ، موږ سمدلاسه وګورو چې که په صف کې له یو څخه ډیر ننوتل شتون ولري ، دا ټول کلونونه دي. راځئ چې یوازې دوی پریږدو:

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)

د هغو کسانو لپاره چې لنډ لیکل خوښويتاسو کولی شئ دا په لاندې ډول ولیکئ:

SELECT
  unnest((array_agg(ctid))[2:])
FROM
  tbl T
GROUP BY
  T::text;

له هغه ځایه چې د سیریل شوي تار ارزښت پخپله زموږ لپاره په زړه پوري نه دی ، نو موږ دا په ساده ډول د فرعي پوښتنو له راستانه شوي کالمونو څخه لرې کړل.

د کولو لپاره لږ څه پاتې دي - DELETE هغه سیټ وکاروئ چې موږ ترلاسه کړي:

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[]);

راځئ چې خپل ځان وګورو:

د PK پرته د میز څخه د کلون ریکارډونه پاکول
[ تشریح.tensor.ru ته وګورئ]

هو، هرڅه سم دي: زموږ 3 ریکارډونه د ټول جدول یوازې د سیق سکین لپاره غوره شوي، او د حذف کولو نوډ د معلوماتو لټون کولو لپاره کارول شوی و. د ټیډ سکین سره واحد پاس:

->  Tid Scan on tbl (actual time=0.050..0.051 rows=3 loops=1)
      TID Cond: (ctid = ANY ($0))

که تاسو ډیری ریکارډونه پاک کړئ، د ویکیوم تحلیل چلول مه هیروئ.

راځئ چې د لوی میز او د لوی شمیر نقلونو سره وګورو:

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;

د PK پرته د میز څخه د کلون ریکارډونه پاکول
[ تشریح.tensor.ru ته وګورئ]

نو، دا طریقه په بریالیتوب سره کار کوي، مګر دا باید د یو څه احتیاط سره وکارول شي. ځکه چې د هر ریکارډ لپاره چې حذف شوي وي، د معلوماتو یوه پاڼه په ټیډ سکین کې لوستل کیږي، او یو یې په حذف کې.

سرچینه: www.habr.com

Add a comment