PostgreSQL Antipatterns: Na-agafe Ntọala na họrọ na SQL

Site n'oge ruo n'oge onye nrụpụta chọrọ Nyefee a set nke parameters ma ọ bụ ọbụna a dum nhọrọ na arịrịọ "n'ọnụ ụzọ". Mgbe ụfọdụ, ị na-ahụ nnọọ iju ngwọta maka nsogbu a.
PostgreSQL Antipatterns: Na-agafe Ntọala na họrọ na SQL
Ka anyị laghachi azụ hụ ihe anyị agaghị eme, ihe kpatara ya, na otu anyị ga-esi mee ya nke ọma.

Ntinye aka nke ụkpụrụ n'ime ahụ arịrịọ

Ọ na-adịkarị ka nke a:

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

... ma ọ bụ dị ka nke a:

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

Usoro a ka ekwuru, dee na ọbụna dọtara ọtụtụ:

PostgreSQL Antipatterns: Na-agafe Ntọala na họrọ na SQL

Ọ fọrọ nke nta ka ọ bụrụ mgbe niile ụzọ ziri ezi na SQL injections na ibu na-enweghị isi na mgbagha azụmahịa, nke a na-amanye "kpado" ahịrị ajụjụ gị.

Enwere ike izipu ụzọ a naanị ma ọ bụrụ na ọ dị mkpa iji partitioning na ụdị PostgreSQL 10 na nke dị n'okpuru iji nweta atụmatụ dị mma karị. Na nsụgharị ndị a, a na-ekpebi ndepụta nke akụkụ ndị a na-enyocha n'ebughị n'uche ihe ndị a na-ebufe, naanị na ndabere nke arịrịọ ahụ.

$n-arụmụka

Jiri ndị na-edebe ebe parameters dị mma, ọ na-enye gị ohere iji Okwu akwadoro, Mbelata ibu ma na mgbagha azụmahịa (a na-emepụta eriri ajụjụ ma na-ebufe naanị otu ugboro) na na ihe nkesa nchekwa data (re-parsing and scheduling maka ajụjụ ajụjụ ọ bụla achọghị).

Ọnụọgụ arụmụka dị iche iche

Nsogbu ga-echere anyị mgbe anyị chọrọ ịfefe ọnụọgụ arụmụka amaghi ama:

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

Ọ bụrụ na anyị ahapụ arịrịọ ahụ n'ụdị a, ọ bụ ezie na ọ ga-echebe anyị pụọ na injections nwere ike ime, ọ ka ga-eduga na mkpa ijikọta / mebie arịrịọ ahụ. maka nhọrọ ọ bụla dabere na ọnụọgụ arụmụka. Ọ ka mma karịa ime ya mgbe ọ bụla, mana ị nwere ike ime na-enweghị ya.

O zuru ezu ịgafe naanị otu oke nwere ihe nnọchianya n'usoro:

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

Naanị ihe dị iche bụ mkpa ịmegharị arụmụka ahụ n'ụzọ doro anya na ụdị nhazi a chọrọ. Ma nke a adịghị akpata nsogbu, ebe ọ bụ na anyị amaraworị ụzọ ebe anyị na-aga.

Na-ebufe sample (matrix)

Ọtụtụ mgbe, ndị a bụ ụdị nhọrọ niile maka ịnyefe data maka ntinye n'ime nchekwa data "n'otu arịrịọ":

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

Na mgbakwunye na nsogbu ndị akọwara n'elu na "re-gluing" arịrịọ ahụ, nke a nwekwara ike iduga anyị pụọ na ebe nchekwa na ihe nkesa. Ihe kpatara ya dị mfe - PG na-edobe ebe nchekwa ọzọ maka arụmụka, na ọnụ ọgụgụ nke ndekọ dị na setịpụ naanị site na mkpa ngwa nke mgbagha azụmahịa. N'okwu gbasara ahụike m ga-ahụrịrị Arụmụka “nọmba” karịrị $9000 - emela ya otu a.

Ka anyị jiri ugbua degharịa arịrịọ ahụ "abụọ-larịị" serialization:

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;

Ee, n'ihe banyere ụkpụrụ "mgbagwoju anya" n'ime otu n'usoro, ha ga-agba ya gburugburu.
O doro anya na n'ụzọ dị otú a ị nwere ike "ịgbasa" nhọrọ na ọnụ ọgụgụ nke ubi aka ike.

ọgba aghara, ọgba aghara,…

Site n'oge ruo n'oge, a na-enwe nhọrọ maka ịgafe kama ịbụ "usoro nhazi" ọtụtụ "usoro nke kọlụm" nke m kwuru. n'isiokwu ikpeazụ:

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

Na usoro a, ọ bụrụ na imehie ihe mgbe ị na-emepụta ndepụta nke ụkpụrụ maka kọlụm dị iche iche, ọ dị mfe ịnweta. ihe a na-atụghị anya ya, nke dabere na ụdị nkesa:

-- $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

Kemgbe ụdị 9.3, PostgreSQL enweela ọrụ zuru oke maka iji ụdị json rụọ ọrụ. Ya mere, ọ bụrụ na nkọwa nke paramita ntinye pụtara na ihe nchọgharị gị, ị nwere ike ịmepụta ya ozugbo json ihe maka ajụjụ SQL:

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

Maka nsụgharị ndị gara aga, enwere ike iji otu usoro ahụ onye ọ bụla (hstore), mana "convolution" ziri ezi yana ịgbanarị ihe mgbagwoju anya na hstore nwere ike ịkpata nsogbu.

json_populate_recordset

Ọ bụrụ na ịmara na mbụ na data sitere na “ntinye” json array ga-eji mejuo ụfọdụ tebụl, ị nwere ike ịchekwa ọtụtụ ihe na mpaghara “dereferencing” wee tụba ha na ụdị achọrọ site na iji json_populate_recordset ọrụ:

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

json_to_recordset

Ọrụ a ga-eme ka ọ “gbasaa” ọtụtụ ihe ndị agafere na nhọrọ, na-adabereghị na usoro tebụl:

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

Tebụl nwa oge

Ma ọ bụrụ na ọnụọgụ data dị na nlele mbufe dị ukwuu, mgbe ahụ, ịtụba ya n'otu usoro nke usoro siri ike na mgbe ụfọdụ agaghị ekwe omume, ebe ọ na-achọ otu oge. ekenye nnukwu ego nchekwa. Dịka ọmụmaatụ, ịkwesịrị ịnakọta nnukwu ngwugwu data na ihe omume sitere na sistemụ mpụga ogologo oge, wee chọọ ịhazi ya otu oge n'akụkụ nchekwa data.

N'okwu a, ngwọta kachasị mma ga-abụ iji tebụl nwa oge:

CREATE TEMPORARY TABLE tbl(k text, v integer);
...
INSERT INTO tbl(k, v) VALUES($1, $2); -- повторить много-много раз
...
-- тут делаем что-то полезное со всей этой таблицей целиком

Usoro dị mma maka nnyefe nke nnukwu mpịakọta mgbe ụfọdụ data.
Site n'echiche nke ịkọwa nhazi nke data ya, tebụl nwa oge dị iche na "mgbe niile" n'otu ụzọ. na pg_class usoro tebụl, na n’ime pg_type, pg_depend, pg_attribute, pg_attrdef, ... - ọ dịghị ihe ọ bụla.

Ya mere, na usoro weebụ nke nwere ọnụ ọgụgụ dị ukwuu nke njikọ dị mkpirikpi maka nke ọ bụla n'ime ha, tebụl dị otú ahụ ga-emepụta ihe ndekọ usoro ọhụrụ oge ọ bụla, nke na-ehichapụ mgbe njikọ na nchekwa data mechiri. N'ikpeazụ, Iji TEMP TABLE eme ihe na-achịkwaghị achịkwa na-eduga na “ọzịza” nke tebụl na pg_catalog na ibelata ọtụtụ ọrụ na-eji ha.
N'ezie, nke a nwere ike ime iji nkeji oge VACUUM FULL dị ka tebụl katalọgụ usoro.

Ngbanwe Oge

Ka anyị were na nhazi data sitere na ikpe gara aga bụ ihe mgbagwoju anya maka otu ajụjụ SQL, mana ịchọrọ ịme ya ọtụtụ oge. Ya bụ, anyị chọrọ iji nhazi usoro n'ime Mgbochi, mana iji nnyefe data site na tebụl nwa oge ga-adị oke ọnụ.

Anyị agaghịkwa enwe ike iji $n-parameters maka ịgafe na ngọngọ na-amaghị aha. Ụdị mgbanwe oge na ọrụ ahụ ga-enyere anyị aka ịpụ n'ọnọdụ a nke ugbu a_setting.

Tupu mbipute 9.2 ọ dị mkpa iji hazie ya oghere aha pụrụ iche custom_variable_klas maka "gị" mgbanwe nnọkọ. Na nsụgharị dị ugbu a ị nwere ike dee ihe dị ka nke a:

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

Enwere ike ịchọta azịza ndị ọzọ n'asụsụ usoro akwadoro.

Ị maara ụzọ ọ bụla ọzọ? Kekọrịta na nkwupụta!

isi: www.habr.com

Zụta nnabata ntụkwasị obi maka saịtị nwere nchekwa DDoS, sava VPS VDS 🔥 Zụta ebe nrụọrụ weebụ a pụrụ ịtụkwasị obi na nchekwa DDoS, sava VPS VDS | ProHoster