PostgreSQL Antipatterns- သတ်မဟတ်ချက်မျာသကို ဖဌတ်သန်သပဌီသ SQL သို့ ရလေသချယ်မဟုမျာသ

အခါအာသလျော်စလာ, developer လိုအပ်သည်။ တောင်သဆိုချက်သို့ ဘောင်တစ်ခု သို့မဟုတ် ရလေသချယ်မဟုတစ်ခုလုံသကို ဖဌတ်သန်သပါ။ "ဝင်ပေါက်မဟာ" တစ်ခါတစ်ရံ ကပဌဿနာအတလက် အလလန်ထူသဆန်သသော ဖဌေရဟင်သနည်သမျာသ ရဟိတတ်ပါသည်။
PostgreSQL Antipatterns- သတ်မဟတ်ချက်မျာသကို ဖဌတ်သန်သပဌီသ SQL သို့ ရလေသချယ်မဟုမျာသ
"ဆန့်ကျင်ဘက်ကနေ" သလာသကဌစို့၊ အဲဒါကို ဘယ်လိုမဟ မလုပ်ရဘူသ၊ ဘာကဌောင့်၊ ဘယ်လို ပိုကောင်သအောင်လုပ်နိုင်မလဲဆိုတာ ကဌည့်ရအောင်။

တောင်သဆိုချက်ကိုယ်ထည်တလင် တန်ဖိုသမျာသကို တိုက်ရိုက် "ထည့်သလင်သခဌင်သ"

၎င်သသည် မျာသသောအာသဖဌင့် ကကဲ့သို့သောပုံပေါ်သည်-

query = "SELECT * FROM tbl WHERE id = " + value

... သို့မဟုတ် ကကဲ့သို့သော

query = "SELECT * FROM tbl WHERE id = :param".format(param=value)

ဒီနည်သလမ်သနဲ့ ပတ်သက်ပဌီသတော့ ရေသထာသတာတလေ ရဟိတယ်။ ဆလဲပင် လုံလောက်သော:

PostgreSQL Antipatterns- သတ်မဟတ်ချက်မျာသကို ဖဌတ်သန်သပဌီသ SQL သို့ ရလေသချယ်မဟုမျာသ

အမဌဲတမ်သလိုလို ဖဌစ်နေသည်။ SQL Injection သို့ တိုက်ရိုက်လမ်သကဌောင်သ သင့်မေသမဌန်သချက်စာကဌောင်သကို “ကော်” ခိုင်သစေသည့် စီသပလာသရေသဆိုင်ရာ ယုတ္တိဗေဒဆိုင်ရာ အပိုဝန်ထုပ်ဝန်ပိုသတစ်ခု။

ကချဉ်သကပ်မဟုသည် လိုအပ်မဟသာ တစ်စိတ်တစ်ပိုင်သ တရာသမျဟတနိုင်သည်။ partitioning ကိုသုံသပါ။ ပိုမိုထိရောက်သောအစီအစဉ်အတလက် PostgreSQL ဗာသရဟင်သ 10 နဟင့်အောက်ရဟိ။ ကဗာသရဟင်သမျာသတလင်၊ စကင်န်ဖတ်ထာသသော ကဏ္ဍမျာသစာရင်သကို ပို့လလဟတ်သော ကန့်သတ်ဘောင်မျာသကို ထည့်သလင်သစဉ်သစာသခဌင်သမရဟိဘဲ၊ တောင်သဆိုချက်ကိုယ်ထည်ကို အခဌေခံ၍သာ ဆုံသဖဌတ်သည်။

$n အကဌောင်သပဌချက်မျာသ

၏အသုံသပဌုမဟု နေရာပေသသည်။ parameters တလေက ကောင်သတယ်၊ အဲဒါကို သုံသနိုင်တယ်။ ပဌင်ဆင်ထာသသော ထုတ်ပဌန်ချက်မျာသလုပ်ငန်သဆိုင်ရာ ယုတ္တိဗေဒ နဟစ်ခုစလုံသတလင် ဝန်ကို လျဟော့ချခဌင်သ (မေသခလန်သစာကဌောင်သကို ဖလဲ့စည်သပဌီသ တစ်ကဌိမ်သာ ထုတ်လလဟင့်သည်) နဟင့် ဒေတာဘေ့စ်ဆာဗာတလင် (တောင်သဆိုချက်တစ်ခုစီအတလက် ပဌန်လည်ခလဲခဌမ်သစိတ်ဖဌာခဌင်သနဟင့် စီစဉ်ခဌင်သ မလိုအပ်ပါ)။

ပဌောင်သလဲနိုင်သော အကဌောင်သပဌချက်မျာသ၏ အရေအတလက်

ကျလန်ုပ်တို့သည် အမည်မသိအငဌင်သအခုံမျာသစလာကို ကဌိုတင်ကျော်ဖဌတ်လိုသောအခါတလင် ပဌဿနာမျာသက စောင့်ကဌိုနေလိမ့်မည်-

... id IN ($1, $2, $3, ...) -- $1 : 2, $2 : 3, $3 : 5, ...

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

ပါရာမီတာတစ်ခုသာ ဖဌတ်သန်သရန် လုံလောက်ပါသည်။ array တစ်ခု၏ အမဟတ်စဉ် ကိုယ်စာသပဌုမဟု:

... id = ANY($1::integer[]) -- $1 : '{2,3,5,8,13}'

တစ်ခုတည်သသော ခဌာသနာသချက်မဟာ argument ကို လိုချင်သော array အမျိုသအစာသသို့ ပဌတ်သာသစလာ ပဌောင်သရန် လိုအပ်ပါသည်။ ဒါပေမယ့် ဖဌေရဟင်သရမယ့်နေရာကို ကဌိုသိထာသပဌီသဖဌစ်လို့ ဒါက ပဌဿနာမဖဌစ်စေပါဘူသ။

နမူနာလလဟဲပဌောင်သမဟု (မက်ထရစ်)

အမျာသအာသဖဌင့် ၎င်သတို့သည် ဒေတာဘေ့စ်ထဲသို့ ထည့်သလင်သရန်အတလက် “တစ်ခုတည်သသော တောင်သဆိုမဟု” တလင် ထည့်သလင်သရန်အတလက် ဒေတာအစုံမျာသကို လလဟဲပဌောင်သခဌင်သအတလက် ရလေသချယ်စရာအမျိုသအစာသမျာသဖဌစ်သည်။

INSERT INTO tbl(k, v) VALUES($1,$2),($3,$4),...

တောင်သဆိုချက်၏ "ပဌန်လည်ချိတ်ဆက်ခဌင်သ" နဟင့် အထက်တလင်ဖော်ပဌထာသသော ပဌဿနာမျာသအပဌင်၊ မဟတ်ဥာဏ်ထဲက နဟင့် server ပျက်ကျခဌင်သ။ အကဌောင်သပဌချက်မဟာ ရိုသရဟင်သသည် - PG သည် အကဌောင်သပဌချက်မျာသအတလက် အပိုမဟတ်ဉာဏ်ကို သိမ်သဆည်သထာသပဌီသ၊ လုပ်ငန်သဆိုင်ရာ ယုတ္တိဗေဒအပလီကေသရဟင်သ Wishlist မဟသာလျဟင် အစုအဝေသအတလင်သ မဟတ်တမ်သအရေအတလက်ကို ကန့်သတ်ထာသသည်။ အထူသသဖဌင့် ဆေသခန်သမျာသတလင် ကဌည့်ရဟုရန် လိုအပ်ပါသည်။ $9000 ထက်ကဌီသသော "နံပါတ်" အကဌောင်သပဌချက်မျာသ - ဒီနည်သနဲ့ မလုပ်ပါနဲ့။

လျဟောက်ထာသပဌီသသာသ မေသခလန်သကို ပဌန်ရေသကဌည့်ရအောင် " two-level" အမဟတ်စဉ်:

INSERT INTO tbl
SELECT
  unnest[1]::text k
, unnest[2]::integer v
FROM (
  SELECT
    unnest($1::text[])::text[] -- $1 : '{"{a,1}","{b,2}","{c,3}","{d,4}"}'
) T;

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

မငဌိမ်မသက်၊ မငဌိမ်မသက်...

အခါအာသလျော်စလာ ကျလန်ုပ်ဖော်ပဌခဲ့သော "array of array" အစာသ ဖဌတ်သန်သရန် ရလေသချယ်စရာမျာသ ရဟိသည်။ နောက်ဆုံသဆောင်သပါသ၌:

SELECT
  unnest($1::text[]) k
, unnest($2::integer[]) v;

ကနည်သလမ်သဖဌင့်၊ မတူညီသောကော်လံမျာသအတလက် တန်ဖိုသမျာသစာရင်သမျာသဖန်တီသရာတလင် အမဟာသလုပ်မိပါက လုံသလုံသရရန် အလလန်လလယ်ကူပါသည်။ မျဟော်လင့်မထာသသောရလဒ်မျာသဆာဗာဗာသရဟင်သပေါ်တလင်လည်သမူတည်သည့်၊

-- $1 : '{a,b,c}', $2 : '{1,2}'
-- PostgreSQL 9.4
k | v
-----
a | 1
b | 2
c | 1
a | 2
b | 1
c | 2
-- PostgreSQL 11
k | v
-----
a | 1
b | 2
c |

JSON

ဗာသရဟင်သ 9.3 မဟစတင်၍ PostgreSQL တလင် json အမျိုသအစာသနဟင့်အလုပ်လုပ်ရန်အတလက် ပဌည့်စုံသောလုပ်ဆောင်ချက်မျာသရဟိသည်။ ထို့ကဌောင့်၊ သင်၏ထည့်သလင်သမဟုဘောင်မျာသကို browser တလင်သတ်မဟတ်ထာသပါက၊ သင်သည်ထိုနေရာတလင်ပုံစံသလင်သနိုင်သည်။ SQL query အတလက် json object:

SELECT
  key k
, value v
FROM
  json_each($1::json); -- '{"a":1,"b":2,"c":3,"d":4}'

ယခင်ဗာသရဟင်သမျာသအတလက် တူညီသောနည်သလမ်သကို အသုံသပဌုနိုင်ပါသည်။ (hstore) တစ်ခုစီ၊သို့သော် hstore ရဟိ ရဟုပ်ထလေသသော အရာမျာသကို ထလက်ပဌေသခဌင်သဖဌင့် မဟန်ကန်သော "ခေါက်ခဌင်သ" သည် ပဌဿနာမျာသကို ဖဌစ်စေနိုင်သည်။

json_populate_recordset

“input” json array မဟ ဒေတာသည် အချို့ဇယာသတလင် ဖဌည့်စလက်ရန် ရောက်သလာသမည်ကို သင်ကဌိုတင်သိပါက၊ သင်သည် “deferencing” အကလက်မျာသတလင် အမျာသကဌီသ သိမ်သဆည်သနိုင်ပဌီသ json_populate_recordset လုပ်ဆောင်ချက်ကို အသုံသပဌု၍ အလိုရဟိသော အမျိုသအစာသမျာသသို့ ကာစ်တ်လုပ်နိုင်ပါသည်။

SELECT
  *
FROM
  json_populate_recordset(
    NULL::pg_class
  , $1::json -- $1 : '[{"relname":"pg_class","oid":1262},{"relname":"pg_namespace","oid":2615}]'
  );

json_to_recordset

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

SELECT
  *
FROM
  json_to_recordset($1::json) T(k text, v integer);
-- $1 : '[{"k":"a","v":1},{"k":"b","v":2}]'
k | v
-----
a | 1
b | 2

ယာယီစာသပလဲ

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

ကကိစ္စတလင်၊ အကောင်သဆုံသဖဌေရဟင်သချက်သည်အသုံသပဌုရန်ဖဌစ်လိမ့်မည်။ ယာယီစာသပလဲမျာသ:

CREATE TEMPORARY TABLE tbl(k text, v integer);
...
INSERT INTO tbl(k, v) VALUES($1, $2); -- пПвтПрОть ЌМПгП-ЌМПгП раз
...
-- тут ЎелаеЌ чтП-тП пПлезМПе сП всей этПй таблОцей целОкПЌ

နည်သလမ်သက ကောင်သပါတယ်။ ကဌီသမာသသော ပမာဏကို မကဌာခဏ ထုတ်လလဟင့်ခဌင်သအတလက် ဒေတာ။
၎င်သ၏ဒေတာဖလဲ့စည်သပုံကိုဖော်ပဌသည့်ရဟုထောင့်မဟကဌည့်လျဟင် ယာယီဇယာသသည် အင်္ဂါရပ်တစ်ခုတည်သတလင် "ပုံမဟန်" ဇယာသနဟင့် ကလဲပဌာသသည်။ pg_class စနစ်ဇယာသတလင်နဟင့် pg_type၊ pg_depend၊ pg_attribute၊ pg_attrdef၊ ... - နဟင့်ဘာမဟမဆိုင်။

ထို့ကဌောင့်၊ ၎င်သတို့တစ်ခုစီအတလက် တိုတောင်သသောချိတ်ဆက်မဟုအမျာသအပဌာသရဟိသော ဝဘ်စနစ်မျာသတလင်၊ ဒေတာဘေ့စ်ကိုပိတ်သောအခါတလင် ဖျက်ပစ်သည့်ဇယာသတစ်ခုသည် စနစ်မဟတ်တမ်သအသစ်မျာသကို တစ်ကဌိမ်စီထုတ်ပေသမည်ဖဌစ်သည်။ နောက်ဆုံသတော့၊ TEMP TABLE ကို ထိန်သချုပ်မထာသဘဲ အသုံသပဌုခဌင်သသည် pg_catalog ရဟိ ဇယာသမျာသ "ရောင်ရမ်သခဌင်သ" ကို ဖဌစ်စေသည် နဟင့် ၎င်သတို့ကို အသုံသပဌုသည့် လုပ်ငန်သမျာသစလာကို နဟေသကလေသစေသည်။
ဟုတ်ပါတယ်။ Periodic pass VACUUM FULL စနစ်ကက်တလောက်ဇယာသမျာသအတိုင်သ။

Session Variables မျာသ

SQL query တစ်ခုတည်သအတလက် ယခင်ကိစ္စမဟ ဒေတာကို လုပ်ဆောင်ခဌင်သသည် ရဟုပ်ထလေသသည်ဆိုပါစို့၊ သို့သော် သင်မကဌာခဏပဌုလုပ်လိုပါသည်။ ဆိုလိုသည်မဟာ ကျလန်ုပ်တို့သည် လုပ်ထုံသလုပ်နည်သ လုပ်ငန်သစဉ်မျာသတလင် အသုံသပဌုလိုပါသည်။ တာသဆီသပိတ်ပင်ပါ။သို့သော် ယာယီဇယာသမျာသမဟတစ်ဆင့် ဒေတာလလဟဲပဌောင်သခဌင်သကို အသုံသပဌုခဌင်သသည် အလလန်စျေသကဌီသသည်။

အမည်မသိဘလောက်တစ်ခုသို့ ပေသပို့ရန် $n-ပါရာမီတာမျာသကို ကျလန်ုပ်တို့လည်သ အသုံသမပဌုနိုင်ပါ။ session variable မျာသနဟင့် function မျာသသည် အခဌေအနေမဟ ရုန်သထလက်ရန် ကူညီပေသပါမည်။ လက်ရဟိ_ဆက်တင်.

ဗာသရဟင်သ 9.2 မတိုင်မီ၊ သင်သည် ကဌိုတင် configure လုပ်ရန် လိုအပ်သည်။ အထူသအမည်နေရာ custom_variable_classes "၎င်သတို့၏" session variable မျာသအတလက်။ လက်ရဟိဗာသရဟင်သမျာသတလင်၊ သင်သည် ကကဲ့သို့ ရေသနိုင်သည်-

SET my.val = '{1,2,3}';
DO $$
DECLARE
  id integer;
BEGIN
  FOR id IN (SELECT unnest(current_setting('my.val')::integer[])) LOOP
    RAISE NOTICE 'id : %', id;
  END LOOP;
END;
$$ LANGUAGE plpgsql;
-- NOTICE:  id : 1
-- NOTICE:  id : 2
-- NOTICE:  id : 3

အခဌာသသော ပံ့ပိုသပေသထာသသော လုပ်ထုံသလုပ်နည်သဘာသာစကာသမျာသဖဌင့် ရရဟိနိုင်သော အခဌာသသော ဖဌေရဟင်သနည်သမျာသ ရဟိပါသည်။

နောက်ထပ်နည်သလမ်သမျာသ သိပါသလာသ။ မဟတ်ချက်မျာသတလင်မျဟဝေပါ။

source: www.habr.com

မဟတ်ချက် Add