ایسے حالات ہیں جب بنیادی کلید کے بغیر میز پر یا کوئی اور منفرد انڈیکس، ایک نگرانی کی وجہ سے، پہلے سے موجود ریکارڈز کے مکمل کلون شامل ہیں۔
مثال کے طور پر، ایک تاریخی میٹرک کی اقدار کو پوسٹگری ایس کیو ایل میں کاپی سٹریم کا استعمال کرتے ہوئے لکھا جاتا ہے، اور پھر اچانک ناکامی ہوتی ہے، اور مکمل طور پر ایک جیسے ڈیٹا کا کچھ حصہ دوبارہ آتا ہے۔
غیر ضروری کلون کے ڈیٹا بیس سے کیسے چھٹکارا حاصل کیا جائے؟
جب پی کے مددگار نہیں ہے۔
سب سے آسان طریقہ یہ ہے کہ ایسی صورت حال کو پہلے جگہ پر ہونے سے روکا جائے۔ مثال کے طور پر، بنیادی کلید کو رول کریں۔ لیکن ذخیرہ شدہ ڈیٹا کا حجم بڑھائے بغیر یہ ہمیشہ ممکن نہیں ہوتا۔
مثال کے طور پر، اگر سورس سسٹم کی درستگی ڈیٹا بیس میں فیلڈ کی درستگی سے زیادہ ہے:
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(میٹرک، ٹی ایس، ڈیٹا) - لیکن اس سے اس کا حجم بہت بڑھ جائے گا، جسے ہم استعمال نہیں کریں گے۔
اس لیے سب سے درست آپشن یہ ہے کہ باقاعدہ غیر منفرد انڈیکس بنایا جائے۔ (میٹرک، ٹی ایس) اور حقیقت کے بعد مسائل سے نمٹیں اگر وہ پیدا ہوتے ہیں۔
"کلونی جنگ شروع ہو چکی ہے"
کسی قسم کا حادثہ ہوا، اور اب ہمیں ٹیبل سے کلون ریکارڈز کو تباہ کرنا ہے۔
آئیے اصل ڈیٹا کا نمونہ بنائیں:
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 جمع کرنے کی ضرورت ہے۔ سب سے آسان آپشن پوری لائن کو متن میں ڈالنا ہے:
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[]);
آئیے خود کو چیک کریں:
ہاں، سب کچھ درست ہے: ہمارے 3 ریکارڈ پورے ٹیبل کے واحد Seq اسکین کے لیے منتخب کیے گئے تھے، اور ڈیلیٹ نوڈ کو ڈیٹا کی تلاش کے لیے استعمال کیا گیا تھا۔ ٹڈ اسکین کے ساتھ سنگل پاس:
-> 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;
لہذا، طریقہ کامیابی سے کام کرتا ہے، لیکن اسے کچھ احتیاط کے ساتھ استعمال کیا جانا چاہئے. کیونکہ حذف ہونے والے ہر ریکارڈ کے لیے، ٹڈ اسکین میں ایک ڈیٹا صفحہ پڑھا جاتا ہے، اور ایک ڈیلیٹ میں۔
ماخذ: www.habr.com