PostgreSQL Antipatterns- အစပျိုးကိုကျော်သွားသည့် ဒေတာကို ပြောင်းလဲပါ။

များမကြာမီ သို့မဟုတ် နောက်ပိုင်းတွင် ဇယားမှတ်တမ်းများတွင် တစ်စုံတစ်ခုကို အကြီးအကျယ်ပြင်ဆင်ရန် လိုအပ်ခြင်းနှင့် ရင်ဆိုင်နေရသည်။ ငါရှိပြီးသား ပိုကောင်းအောင် ဘယ်လိုလုပ်ရမလဲ ပြောပြပေးပါ။, ဘယ်လို - အဲဒါကို မလုပ်တာက ပိုကောင်းပါတယ်။ ဒီနေ့တော့ အစုလိုက်အပြုံလိုက် မွမ်းမံမှုရဲ့ ဒုတိယ ကဏ္ဍကို ပြောပြမယ် - အစပျိုးမှုများအကြောင်း.

ဥပမာအားဖြင့်၊ သင်တစ်ခုခုကိုပြင်ရန်လိုအပ်သည့်စားပွဲပေါ်တွင်မကောင်းသောအစပျိုးတစ်ခုဆွဲထားသည်။ ON UPDATEအပြောင်းအလဲအားလုံးကို စုစည်းမှုအချို့သို့ လွှဲပြောင်းခြင်း။ ပြီးတော့ အရာအားလုံးကို အပ်ဒိတ်လုပ်ရန် လိုအပ်သည် (ဥပမာ အကွက်အသစ်တစ်ခုကို အစပြုပါ)၊ ဤအစုအဝေးများကို မထိခိုက်စေရန် ဂရုတစိုက်လုပ်ဆောင်ပါ။

အစပျိုးမှုများကို ပိတ်ထားလိုက်ရအောင်။

BEGIN;
  ALTER TABLE ... DISABLE TRIGGER ...;
  UPDATE ...; -- тут долго-долго
  ALTER TABLE ... ENABLE TRIGGER ...;
COMMIT;

တကယ်တော့ ဒါပါပဲ- အရာအားလုံးက တွဲလောင်း.

ဘာဖြစ်လို့လဲဆိုတော့ ALTER TABLE ချမှတ်သည်။ သီးသန့်အသုံးပြုခွင့်- ရိုးရှင်းသောတစ်ခုပင်၊ မည်သူမျှအပြိုင်မပြေးနိုင်သောသော့ SELECTစားပွဲပေါ်မှ ဘာကိုမှ ဖတ်နိုင်မှာ မဟုတ်ဘူး။ ဆိုလိုသည်မှာ၊ ဤငွေပေးငွေယူမပြီးမချင်း၊ "ရုံ" ကိုပင်ဖတ်လိုသူတိုင်းစောင့်လိမ့်မည်။ ပြီးတော့ ငါတို့ အဲဒါကို သတိရတယ်။ UPDATE ငါတို့မှာ အကြာကြီးရှိတယ်...

အမြန်ပိတ်လိုက်ရအောင်၊ မြန်မြန်ဖွင့်လိုက်ပါ။

BEGIN;
  ALTER TABLE ... DISABLE TRIGGER ...;
COMMIT;

UPDATE ...;

BEGIN;
  ALTER TABLE ... ENABLE TRIGGER ...;
COMMIT;

ဒီမှာ အခြေအနေက ပိုကောင်းနေပြီ၊ စောင့်ရတဲ့ အချိန်က အရမ်းနည်းတယ်။ ဒါပေမယ့် ပြဿနာနှစ်ခုကပဲ အလှကို ပျက်စီးစေတယ်။

  • ALTER TABLE စားပွဲပေါ်ရှိ အခြားလုပ်ဆောင်မှုများအားလုံးကို အကြာကြီးစောင့်ဆိုင်းနေရသည်။ SELECT
  • ခလုတ်ပိတ်နေစဉ် "fly by" အပြောင်းအလဲရှိလား။ စားပွဲပေါ်မှာ၊ ငါတို့တောင်မဟုတ်ဘူး။ ၎င်းသည် ဖြစ်သင့်သော်လည်း အစုအဝေးများထဲသို့ ဝင်မည်မဟုတ်ပါ။ ဒုက္ခ။

session variable များကို စီမံခန့်ခွဲခြင်း။

ထို့ကြောင့်၊ ယခင်ဗားရှင်းတွင်၊ ကျွန်ုပ်တို့သည် အခြေခံကျသောအချက်ကို ထိမိသွားမိသည် - ကျွန်ုပ်တို့သည် ဇယားရှိ “ကျွန်ုပ်တို့၏” အပြောင်းအလဲများကို “ကျွန်ုပ်တို့၏မဟုတ်” နှင့် ခွဲခြားသိမြင်နိုင်စေရန် အစပျိုးကို တစ်နည်းနည်းဖြင့် သင်ကြားပေးရန် လိုအပ်ပါသည်။ “ကျွန်ုပ်တို့၏” ကို ယခင်အတိုင်း ကျော်သွားသော်လည်း “ကျွန်ုပ်တို့၏မဟုတ်” တွင် ၎င်းတို့ကို အစပျိုးထားသည်။ ဒီအတွက် သင်သုံးနိုင်တယ်။ session variable များ.

session_replication_role

ဖတ် လက်စွဲ:

configuration variable ကြောင့် trigger ယန္တရားကိုလည်း ထိခိုက်ပါသည်။ session_replication_role. ထပ်လောင်းညွှန်ကြားချက်များ (မူလ) မပါဘဲ ဖွင့်ထားသည်)၊ ကူးယူမှုအခန်းကဏ္ဍသည် "မူလ" (မူလ) သို့မဟုတ် "ဒေသခံ" ဖြစ်သောအခါ အစပျိုးမှုများ စတင်ပါမည်။ သတ်မှတ်ခြင်းဖြင့် အစပျိုးမှုများကို ဖွင့်ထားသည်။ ENABLE REPLICA, သာအလုပ်လုပ်ပါလိမ့်မယ်။ လက်ရှိ session မုဒ် - "ပုံတူ" နှင့် အစပျိုးမှုများကို သတ်မှတ်ခြင်းဖြင့် ဖွင့်ထားသည်။ ENABLE ALWAYSလက်ရှိပုံတူကူးမုဒ်ကို မည်သို့ပင်ဖြစ်စေ အလုပ်မလုပ်ပါ။

ဆက်တင်သည် အားလုံးကို တစ်ပြိုင်နက်တည်းနှင့် မသက်ဆိုင်ကြောင်း အထူးအလေးပေးဖော်ပြပါမည်။ ALTER TABLEကျွန်ုပ်တို့၏ သီးခြား အထူးချိတ်ဆက်မှုဆီသို့သာ။ စုစုပေါင်း၊ ထို့ကြောင့် မည်သည့်အပလီကေးရှင်းမှ အစပျိုး၍မရပါ။

SET session_replication_role = replica; -- выключили триггеры
UPDATE ...;
SET session_replication_role = DEFAULT; -- вернули в исходное состояние

အစပျိုးအတွင်းပိုင်းအခြေအနေ

သို့သော် အထက်ဖော်ပြပါ ရွေးချယ်မှုသည် အစပျိုးမှုအားလုံးအတွက် တစ်ပြိုင်နက် လုပ်ဆောင်နိုင်သည် (သို့မဟုတ် သင် disable မလုပ်လိုသော "အခြား" အစပျိုးမှုများကို ကြိုတင်လုပ်ဆောင်ရန် လိုအပ်ပါသည်။ လိုအပ်လျှင်လည်း "ပိတ်" တိကျသောအစပျိုးတစ်ခု?

ဒါက ငါတို့ကို ကူညီလိမ့်မယ်။ "အသုံးပြုသူ" session variable:

တိုးချဲ့မှု ကန့်သတ်ဘောင်အမည်များကို အောက်ပါအတိုင်း ရေးသားထားသည်- SQL ရှိ အရာဝတ္တုအမည်အပြည့်အစုံနှင့် ဆင်တူသော အစက်တစ်ခုနောက်တွင် ပါရာမီတာအမည်နှင့် ပါရာမီတာအမည်ကိုယ်တိုင်ဖြစ်သည်။ ဥပမာ- plpgsql.variable_conflict။
သင့်လျော်သော extension module ကို မတင်နိုင်သော လုပ်ငန်းစဉ်များတွင် စနစ်အပြင်မှ ရွေးချယ်စရာများကို သတ်မှတ်နိုင်သောကြောင့် PostgreSQL က လက်ခံသည်။ အစိတ်အပိုင်းနှစ်ခုပါသော မည်သည့်အမည်များအတွက် တန်ဖိုးများ.

ဦးစွာ၊ ကျွန်ုပ်တို့သည် ဤကဲ့သို့သောအရာတစ်ခုခုကို trigger ကို အပြီးသတ်လုပ်ဆောင်သည်-

BEGIN
    -- процессу конвертации можно делать все
    IF current_setting('mycfg.my_table_convert_process') = 'TRUE' THEN
        IF TG_OP IN ('INSERT', 'UPDATE') THEN
            RETURN NEW;
        ELSE
            RETURN OLD;
        END IF;
    END IF;
...

စကားမစပ်၊ ၎င်းကိုပိတ်ဆို့ခြင်းမရှိဘဲ "အမြတ်အစွန်းအတွက်" လုပ်ဆောင်နိုင်သည်။ CREATE OR REPLACE trigger function အတွက်။ ထို့နောက် အထူးချိတ်ဆက်မှုတွင် ကျွန်ုပ်တို့သည် "ကျွန်ုပ်တို့၏" variable ကို စွဲဆောင်သည်-


SET mycfg.my_table_convert_process = 'TRUE';
UPDATE ...;
SET mycfg.my_table_convert_process = ''; -- вернули в исходное состояние

အခြားနည်းလမ်းများ သိပါသလား။ မှတ်ချက်များတွင်မျှဝေပါ။

source: www.habr.com

မှတ်ချက် Add