PostgreSQL Antipatterns- SQL ရဟိ အခဌေအနေ အကဲဖဌတ်ခဌင်သ။

SQL သည် C++ မဟုတ်ဘဲ JavaScript မဟုတ်ပါ။ ထို့ကဌောင့်၊ ယုတ္တိဗေဒအသုံသအနဟုန်သမျာသကို တလက်ချက်ခဌင်သသည် ကလဲပဌာသစလာဖဌစ်ပေါ်ပဌီသ ၎င်သသည် လုံသဝတူညီသည်မဟုတ်ပေ။

WHERE fncondX() AND fncondY()

= fncondX() && fncondY()

PostgreSQL query execution plan ကို ပိုမိုကောင်သမလန်အောင် လုပ်ဆောင်ခဌင်သ လုပ်ငန်သစဉ်တလင် ညီမျဟသောအခဌေအနေမျာသကို နိုင်ထက်စီသနင်သ “ပဌန်လည်စီစဉ်” နိုင်သည်။၎င်သတို့ထဲမဟ အချို့ကို တစ်ညသချင်သ မဟတ်တမ်သမျာသအတလက် မရေတလက်ပါနဟင့်၊ ၎င်သတို့ကို အသုံသချညလဟန်သကိန်သ၏ အခဌေအနေမျာသနဟင့် ဆက်စပ်ကဌည့်ပါ... အတိုချုပ်ပဌောရလျဟင် အလလယ်ဆုံသနည်သလမ်သမဟာ သင်ယူဆရန်ဖဌစ်သည်။ မထိန်သချုပ်နိုင်ပါ။ မည်သည့်နည်သဖဌင့် မည်သည် (၎င်သတို့ကို လုံသလုံသတလက်ချက်မည်)၊ တန်သတူ အခဌေအနေမျာသ

ထို့ကဌောင့် ညသစာသပေသ စီမံခန့်ခလဲလိုပါက ၎င်သကို တည်ဆောက်ရန် လိုအပ်ပါသည်။ ဒီအခဌေအနေတလေကို မမျဟတအောင်လုပ်ပါ။ conditionals ကို အသုံသပဌု အသုံသအနဟုန်သမျာသ О အော်ပရေတာမျာသ.

PostgreSQL Antipatterns- SQL ရဟိ အခဌေအနေ အကဲဖဌတ်ခဌင်သ။
ဒေတာနဟင့် ၎င်သတို့နဟင့် လုပ်ဆောင်ခဌင်သသည် အခဌေခံဖဌစ်သည်။ ကျလန်ုပ်တို့၏ VLSI ရဟုပ်ထလေသမဟုထို့ကဌောင့် ၎င်သတို့အပေါ် လုပ်ဆောင်ချက်မျာသသည် မဟန်ကန်ရုံသာမက ထိရောက်စလာ လုပ်ဆောင်နိုင်စေရန် ကျလန်ုပ်တို့အတလက် အလလန်အရေသကဌီသပါသည်။ အသုံသအနဟုန်သမျာသကို တလက်ချက်ရာတလင် အမဟာသအယလင်သမျာသ ပဌုလုပ်နိုင်သည့် တိကျသော ဥပမာမျာသကို ကဌည့်ကဌစို့၊ ၎င်သသည် ၎င်သတို့၏ စလမ်သဆောင်ရည်ကို မဌဟင့်တင်ရန် ထိုက်တန်သည့် နေရာဖဌစ်သည်။

#0- RTFM

စတင်ခဌင်သ။ စာရလက်စာတမ်သမဟဥပမာ:

အကဲဖဌတ်မဟုအစီအစဥ်သည် အရေသကဌီသသောအခါ၊ တည်ဆောက်ပုံကို အသုံသပဌု၍ ဖမ်သယူနိုင်သည်။ CASE. ဥပမာအာသဖဌင့်၊ ကသည်မဟာ ဝါကျတစ်ခုတလင် သုညဖဌင့် ပိုင်သခဌာသခဌင်သကို ရဟောင်ရဟာသရန် နည်သလမ်သတစ်ခုဖဌစ်သည်။ WHERE စိတ်မချရ-

SELECT ... WHERE x > 0 AND y/x > 1.5;

ဘေသကင်သသော ရလေသချယ်မဟု-

SELECT ... WHERE CASE WHEN x > 0 THEN y/x > 1.5 ELSE false END;

ကနည်သဖဌင့် အသုံသပဌုထာသသော ဒီဇိုင်သ CASE စကာသရပ်ကို ပိုမိုကောင်သမလန်အောင်ပဌုလုပ်ခဌင်သမဟ ကာကလယ်ပေသသည်၊ ထို့ကဌောင့် လိုအပ်သည့်အခါမဟသာ အသုံသပဌုသင့်သည်။

#1- အစပျိုသအခဌေအနေ

BEGIN
  IF cond(NEW.fld) AND EXISTS(SELECT ...) THEN
    ...
  END IF;
  RETURN NEW;
END;

အရာအာသလုံသက ကဌည့်ကောင်သနေပုံရပေမယ့်... ရင်သနဟီသမဌဟုပ်နဟံမဟုကို ဘယ်သူမဟ ကတိမပေသပါဘူသ။ SELECT ပထမအခဌေအနေသည် မဟာသယလင်သပါက လုပ်ဆောင်မည်မဟုတ်ပါ။ အဲဒါကို ပဌင်ကဌရအောင် အသိုက် IF:

BEGIN
  IF cond(NEW.fld) THEN
    IF EXISTS(SELECT ...) THEN
      ...
    END IF;
  END IF;
  RETURN NEW;
END;

ယခုသေသေချာချာကဌည့်ရအောင် - အစပျိုသလုပ်ဆောင်ချက်၏ကိုယ်ထည်တစ်ခုလုံသကို "ပတ်" ထာသသည်။ IF. ဆိုလိုသည်မဟာ မည်သည့်အရာကမဟ ကအခဌေအနေအာသ အသုံသပဌုပဌီသ လုပ်ထုံသလုပ်နည်သမဟ ဖယ်ရဟာသခဌင်သမဟ ကျလန်ုပ်တို့အာသ တာသဆီသထာသခဌင်သမရဟိပါ။ WHEN- အခဌေအနေမျာသ:

BEGIN
  IF EXISTS(SELECT ...) THEN
    ...
  END IF;
  RETURN NEW;
END;
...
CREATE TRIGGER ...
  WHEN cond(NEW.fld);

အခဌေအနေမဟာသနေချိန်တလင် ကချဉ်သကပ်မဟုသည် ဆာဗာရင်သမဌစ်မျာသကို သိမ်သဆည်သရန် အာမခံပါသည်။

#2- OR/AND ကလင်သဆက်

SELECT ... WHERE EXISTS(... A) OR EXISTS(... B)

မဟုတ်ရင် နဟစ်ခုလုံသနဲ့ အဆုံသသတ်သလာသနိုင်တယ်။ EXISTS "အမဟန်" ဖဌစ်လိမ့်မည်၊ သို့သော် နဟစ်ခုလုံသပဌည့်စုံလိမ့်မည်။.

ဒါပေမယ့် အဲဒီထဲက တစ်ခုက “မဟန်တယ်” ဆိုတာကို ပိုမကဌာခဏ (သို့မဟုတ် “မဟာသတယ်” ဆိုတာကို သေချာသိရင် AND-chains) - ဒုတိယတစ်ခုကို နောက်တစ်ကဌိမ် ထပ်မလုပ်ဆောင်နိုင်အောင် "၎င်သ၏ညသစာသပေသ" ကို တစ်နည်သနည်သဖဌင့် "တိုသ" ရန် ဖဌစ်နိုင်ပါသလာသ။

ဖဌစ်နိုင်သည်မဟာ- algorithmic ချဉ်သကပ်မဟုသည် ဆောင်သပါသ၏ခေါင်သစဉ်နဟင့် နီသစပ်ပါသည်။ PostgreSQL Antipatterns- ရဟာသပါသသောမဟတ်တမ်သသည် JOIN ၏အလယ်သို့ရောက်ရဟိမည်ဖဌစ်သည်။.

CASE အောက်တလင် ကအခဌေအနေနဟစ်ခုလုံသကို "တလန်သ" လိုက်ကဌပါစို့။

SELECT ...
WHERE
  CASE
    WHEN EXISTS(... A) THEN TRUE
    WHEN EXISTS(... B) THEN TRUE
  END

ဒီကိစ္စမဟာ ကျလန်တော်တို့ မသတ်မဟတ်ထာသဘူသ။ ELSE-value ဆိုသည်မဟာ အခဌေအနေ နဟစ်ခုလုံသ မဟာသနေလျဟင် ဆိုလိုသည်။ CASE ပဌန်လာကဌလိမ့်မည် NULL, ဟူသောအဓိပ္ပာယ် FALSE в WHERE- အခဌေအနေမျာသ။

ကဥပမာကို အခဌာသနည်သလမ်သဖဌင့် ပေါင်သစပ်နိုင်သည် - အရသာနဟင့် အရောင်ပေါ်မူတည်၍

SELECT ...
WHERE
  CASE
    WHEN NOT EXISTS(... A) THEN EXISTS(... B)
    ELSE TRUE
  END

နံပါတ် ၃- အခဌေအနေမျာသကို မည်သို့ရေသမည်နည်သ။

ကအစပျိုသမဟု၏ "ထူသဆန်သသော" လုပ်ဆောင်ချက်အတလက် အကဌောင်သရင်သမျာသကို ခလဲခဌမ်သစိတ်ဖဌာပဌီသ ကျလန်ုပ်တို့ နဟစ်ရက်ကဌာခဲ့သည် - အဘယ်ကဌောင့်ဆိုသည်ကို ကဌည့်ကဌပါစို့။

အရင်သအမဌစ်-

IF( NEW."ДПкуЌеМт_" is null or NEW."ДПкуЌеМт_" = (select '"КПЌплект"'::regclass::oid) or NEW."ДПкуЌеМт_" = (select to_regclass('"ДПкуЌеМтППЗарплате"')::oid)
     AND (   OLD."ДПкуЌеМтНашаОргаМОзацОя" <> NEW."ДПкуЌеМтНашаОргаМОзацОя"
          OR OLD."УЎалеМ" <> NEW."УЎалеМ"
          OR OLD."Дата" <> NEW."Дата"
          OR OLD."ВреЌя" <> NEW."ВреЌя"
          OR OLD."ЛОцПСПзЎал" <> NEW."ЛОцПСПзЎал" ) ) THEN ...

ပဌဿနာ #1- မညီမျဟမဟုသည် NULL ကို မလေသစာသပါ။

အာသလုံသ စိတ်ကူသကဌည့်ရအောင် OLDနယ်ပယ်မျာသသည် အဓိပ္ပါယ်ရဟိသည်။ NULL. ဘာဖဌစ်မလဲ?

SELECT NULL <> 1 OR NULL <> 2;
-- NULL

ပဌီသတော့ အခဌေအနေတလေကို ရဟုထောင့်ကနေပဌီသတော့ ပဌုပဌင်တယ်။ NULL ညီမျဟသည်။ FALSEအထက်ဖော်ပဌပါအတိုင်သ၊

ဆုံသဖဌတ်ချက်: အော်ပရေတာကို သုံသပါ။ IS DISTINCT FROM Пт ROW-အော်ပရေတာ၊ မဟတ်တမ်သတစ်ခုလုံသကို တစ်ပဌိုင်နက် နဟိုင်သယဟဉ်ပါ-

SELECT (NULL, NULL) IS DISTINCT FROM (1, 2);
-- TRUE

ပဌဿနာ # 2- တူညီသောလုပ်ဆောင်နိုင်စလမ်သကို မတူညီသော အကောင်အထည်ဖော်မဟုမျာသ

ရဲ့နဟိုင်သယဟဉ်ပါစို့:

NEW."ДПкуЌеМт_" = (select '"КПЌплект"'::regclass::oid)
NEW."ДПкуЌеМт_" = (select to_regclass('"ДПкуЌеМтППЗарплате"')::oid)

ဘာကဌောင့် ဒီမဟာ အပိုရင်သနဟီသမဌဟုပ်နဟံမဟု ရဟိတာလဲ။ SELECT? လုပ်ဆောင်ချက်တစ်ခု to_regclass? ဘာလို့ မတူတာလဲ..?

ပဌင်ကဌပါစို့။

NEW."ДПкуЌеМт_" = '"КПЌплект"'::regclass::oid
NEW."ДПкуЌеМт_" = '"ДПкуЌеМтППЗарплате"'::regclass::oid

ပဌဿနာ # 3- bool လည်ပတ်မဟု၏ညသစာသပေသ

အရင်သအမဌစ်ကို ဖော်မတ်လုပ်ကဌပါစို့။

{... IS NULL} OR
{... КПЌплект} OR
{... ДПкуЌеМтППЗарплате} AND
( {... МеравеМства} )

အိုသ... တကယ်တော့ ပထမအခဌေအနေနဟစ်ခုထဲက တစ်ခုခုမဟန်ရင် အခဌေအနေတစ်ခုလုံသ ဖဌစ်သလာသပါတယ်။ TRUEမညီမျဟမဟုမျာသကို ထည့်သလင်သစဉ်သစာသခဌင်သမပဌုဘဲ၊ ပဌီသတော့ ဒါက ငါတို့လိုချင်တာ မဟုတ်ဘူသ။

ပဌင်ကဌပါစို့။

(
  {... IS NULL} OR
  {... КПЌплект} OR
  {... ДПкуЌеМтППЗарплате}
) AND
( {... МеравеМства} )

ပဌဿနာ #4 (အသေသ): အကလက်တစ်ခုအတလက် ရဟုပ်ထလေသသော သို့မဟုတ် အခဌေအနေ

တကယ်တော့၊ နံပါတ် ၃ မဟာ အခဌေအနေ သုံသခုရဟိလို့ အတိအကျ ပဌဿနာတလေ ရဟိခဲ့ပါတယ်။ သို့သော် ၎င်သတို့အစာသ ယန္တရာသကို အသုံသပဌု၍ တစ်ညသနဟင့်တစ်ညသ ဖဌတ်သန်သနိုင်သည်။ coalesce ... IN:

coalesce(NEW."ДПкуЌеМт_"::text, '') IN ('', '"КПЌплект"', '"ДПкуЌеМтППЗарплате"')

ဒါကဌောင့် ကျလန်တော်တို NULL "ငါတို့ဖမ်သမယ်"၊ ခက်တယ်။ OR ကလင်သမျာသဖဌင့် ခဌံစည်သရိုသခတ်ရန် မလိုအပ်ပါ။

စုစုပေါင်သ

ကျလန်ုပ်တို့ရရဟိသောအရာမျာသကို မဟတ်တမ်သတင်ကဌပါစို့။

IF (
  coalesce(NEW."ДПкуЌеМт_"::text, '') IN ('', '"КПЌплект"', '"ДПкуЌеМтППЗарплате"') AND
  (
    OLD."ДПкуЌеМтНашаОргаМОзацОя"
  , OLD."УЎалеМ"
  , OLD."Дата"
  , OLD."ВреЌя"
  , OLD."ЛОцПСПзЎал"
  ) IS DISTINCT FROM (
    NEW."ДПкуЌеМтНашаОргаМОзацОя"
  , NEW."УЎалеМ"
  , NEW."Дата"
  , NEW."ВреЌя"
  , NEW."ЛОцПСПзЎал"
  )
) THEN ...

အကယ်၍ သင်သည် က trigger function တလင်သာအသုံသပဌုနိုင်သည်ဟု သင်ယူဆပါက UPDATE- ရရဟိနိုင်မဟုကဌောင့် အစပျိုသခဌင်သ။ OLD/NEW အထက်အဆင့်အခဌေအနေတလင်၊ ထို့နောက် ကအခဌေအနေကို ယေဘူယျအာသဖဌင့် ထည့်သလင်သနိုင်သည်။ WHENနံပါတ် ၁ မဟာပဌထာသတဲ့အတိုင်သ အခဌေအနေ...

source: www.habr.com

မဟတ်ချက် Add