PostgreSQL Antipatterns: рд╕реЗрдЯрд╣рд░реВ рдкрд╛рд╕ рдЧрд░реНрджреИ рд░ SQL рдорд╛ рдЪрдпрди рдЧрд░реНрджрдЫ

рд╕рдордп рд╕рдордпрдорд╛ рдПрдХ рд╡рд┐рдХрд╛рд╕рдХрд░реНрддрд╛ рдЖрд╡рд╢реНрдпрдХ рдЫ рдЕрдиреБрд░реЛрдзрдорд╛ рдкреНрдпрд╛рд░рд╛рдорд┐рдЯрд░рд╣рд░реВрдХреЛ рд╕реЗрдЯ рд╡рд╛ рд╕рдореНрдкреВрд░реНрдг рдЪрдпрди рдкрд╛рд╕ рдЧрд░реНрдиреБрд╣реЛрд╕реН "рдкреНрд░рд╡реЗрд╢рджреНрд╡рд╛рд░рдорд╛"ред рдХрд╣рд┐рд▓реЗрдХрд╛рд╣реАрдБ рддрдкрд╛рдИрд▓реЗ рдпреЛ рд╕рдорд╕реНрдпрд╛рдХреЛ рд▓рд╛рдЧрд┐ рдзреЗрд░реИ рдЕрдиреМрдареЛ рд╕рдорд╛рдзрд╛рдирд╣рд░реВ рднреЗрдЯреНрдЯрд╛рдЙрдиреБрд╣реБрдиреНрдЫред
PostgreSQL Antipatterns: рд╕реЗрдЯрд╣рд░реВ рдкрд╛рд╕ рдЧрд░реНрджреИ рд░ SQL рдорд╛ рдЪрдпрди рдЧрд░реНрджрдЫ
рд╣рд╛рдореА рдкрдЫрд╛рдбрд┐ рдЬрд╛рдФрдВ рд░ рдХреЗ рдирдЧрд░реНрдиреЗ, рдХрд┐рди, рд░ рдХрд╕рд░реА рд╣рд╛рдореА рдпрд╕рд▓рд╛рдИ рдЕрдЭ рд░рд╛рдореНрд░реЛ рдЧрд░реНрди рд╕рдХреНрдЫреМрдВ рд╣реЗрд░реМрдВред

рдЕрдиреБрд░реЛрдзрдХреЛ рдореБрдЦреНрдп рднрд╛рдЧрдорд╛ рдорд╛рдирд╣рд░реВрдХреЛ рдкреНрд░рддреНрдпрдХреНрд╖ рд╕рдореНрдорд┐рд▓рди

рдпреЛ рд╕рд╛рдорд╛рдиреНрдпрддрдпрд╛ рдХреЗрд╣рд┐ рдпрд╕реНрддреЛ рджреЗрдЦрд┐рдиреНрдЫ:

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

...рд╡рд╛ рдпреЛ рдЬрд╕реНрддреИ:

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

рдпреЛ рд╡рд┐рдзрд┐ рднрдирд┐рдиреНрдЫ, рд▓рд┐рдЦрд┐рдд рд░ рдкрдирд┐ рдХреЛрд░рд┐рдПрдХреЛ рдкреНрд░рд╢рд╕реНрдд:

PostgreSQL Antipatterns: рд╕реЗрдЯрд╣рд░реВ рдкрд╛рд╕ рдЧрд░реНрджреИ рд░ SQL рдорд╛ рдЪрдпрди рдЧрд░реНрджрдЫ

рд▓рдЧрднрдЧ рд╕рдзреИрдВ рдпреЛ рдЫ SQL рдЗрдВрдЬреЗрдХреНрд╢рдирд╣рд░реВрдХреЛ рд▓рд╛рдЧрд┐ рд╕реАрдзрд╛ рдорд╛рд░реНрдЧ рд░ рд╡реНрдпрд╛рдкрд╛рд░ рддрд░реНрдХрдорд╛ рдЕрдирд╛рд╡рд╢реНрдпрдХ рд▓реЛрдб, рдЬреБрди рддрдкрд╛рдЗрдБрдХреЛ рдХреНрд╡реЗрд░реА рд▓рд╛рдЗрди "рдЧреЛрдВрдж" рдЧрд░реНрди рдмрд╛рдзреНрдп рдЫред

рдЖрд╡рд╢реНрдпрдХ рднрдПрдорд╛ рдорд╛рддреНрд░ рдпреЛ рджреГрд╖реНрдЯрд┐рдХреЛрдг рдЖрдВрд╢рд┐рдХ рд░реВрдкрдорд╛ рдиреНрдпрд╛рдпреЛрдЪрд┐рдд рд╣реБрди рд╕рдХреНрдЫ рд╡рд┐рднрд╛рдЬрди рдкреНрд░рдпреЛрдЧ рдЧрд░реНрджреИ PostgreSQL рд╕рдВрд╕реНрдХрд░рдг 10 рд░ рддрд▓ рдердк рдХреБрд╢рд▓ рдпреЛрдЬрдирд╛ рдкреНрд░рд╛рдкреНрдд рдЧрд░реНрдиред рдпреА рд╕рдВрд╕реНрдХрд░рдгрд╣рд░реВрдорд╛, рд╕реНрдХреНрдпрд╛рди рдЧрд░рд┐рдПрдХрд╛ рдЦрдгреНрдбрд╣рд░реВрдХреЛ рд╕реВрдЪреА рдорд╛рддреНрд░ рдЕрдиреБрд░реЛрдз рдирд┐рдХрд╛рдпрдХреЛ рдЖрдзрд╛рд░рдорд╛ рдкреНрд░рд╕рд╛рд░рд┐рдд рдкреНрдпрд╛рд░рд╛рдорд┐рдЯрд░рд╣рд░реВрд▓рд╛рдИ рдзреНрдпрд╛рдирдорд╛ рдирд▓рд┐рдИ рдирд┐рд░реНрдзрд╛рд░рдг рдЧрд░рд┐рдиреНрдЫред

$n-рддрд░реНрдХрд╣рд░реВ

рдкреНрд░рдпреЛрдЧ рдЧрд░реНрдиреБрд╣реЛрд╕реН рдкреНрд▓реЗрд╕рд╣реЛрд▓реНрдбрд░рд╣рд░реВ рдкреНрдпрд╛рд░рд╛рдорд┐рдЯрд░рд╣рд░реВ рд░рд╛рдореНрд░реЛ рдЫ, рдпрд╕рд▓реЗ рддрдкрд╛рдИрдВрд▓рд╛рдИ рдкреНрд░рдпреЛрдЧ рдЧрд░реНрди рдЕрдиреБрдорддрд┐ рджрд┐рдиреНрдЫ рддрдпрд╛рд░ рдХрдердирд╣рд░реВ, рд╡реНрдпрд╛рдкрд╛рд░ рддрд░реНрдХ (рдХреНрд╡реЗрд░реА рд╕реНрдЯреНрд░рд┐рдЩ рдПрдХ рдкрдЯрдХ рдорд╛рддреНрд░ рдЙрддреНрдкрдиреНрди рд░ рдкреНрд░рд╕рд╛рд░рд┐рдд рдЧрд░рд┐рдПрдХреЛ рдЫ) рд░ рдбрд╛рдЯрд╛рдмреЗрд╕ рд╕рд░реНрднрд░рдорд╛ рд▓реЛрдб рдШрдЯрд╛рдЙрдБрджреИ (рдкреНрд░рддреНрдпреЗрдХ рдХреНрд╡реЗрд░реА рдЙрджрд╛рд╣рд░рдгрдХреЛ рд▓рд╛рдЧрд┐ рдкреБрди: рдкрд╛рд░реНрд╕рд┐рдЩ рд░ рд╕рдордп рддрд╛рд▓рд┐рдХрд╛ рдЖрд╡рд╢реНрдпрдХ рдЫреИрди)ред

рддрд░реНрдХрд╣рд░реВрдХреЛ рдЪрд░ рд╕рдВрдЦреНрдпрд╛

рд╕рдорд╕реНрдпрд╛рд╣рд░реВ рд╣рд╛рдореАрд▓рд╛рдИ рдкрд░реНрдЦрдиреЗрдЫрдиреН рдЬрдм рд╣рд╛рдореА рддрд░реНрдХрд╣рд░реВрдХреЛ рдЕрдЬреНрдЮрд╛рдд рд╕рдВрдЦреНрдпрд╛ рдкрд╛рд╕ рдЧрд░реНрди рдЪрд╛рд╣рдиреНрдЫреМрдВ:

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

рдпрджрд┐ рд╣рд╛рдореАрд▓реЗ рдпреЛ рдлрд╛рд░рдордорд╛ рдЕрдиреБрд░реЛрдз рдЫреЛрдбреНрдЫреМрдВ, рдпрджреНрдпрдкрд┐ рдпрд╕рд▓реЗ рд╣рд╛рдореАрд▓рд╛рдИ рд╕рдореНрднрд╛рд╡рд┐рдд рдЗрдВрдЬреЗрдХреНрд╢рдирд╣рд░реВрдмрд╛рдЯ рдЬреЛрдЧрд╛рдЙрдиреЗрдЫ, рдпрд╕рд▓реЗ рдЕрдЭреИ рдкрдирд┐ рдЕрдиреБрд░реЛрдзрд▓рд╛рдИ рдорд░реНрдЬ/рдкрд╛рд░реНрд╕ рдЧрд░реНрди рдЖрд╡рд╢реНрдпрдХ рдкрд░реНрдиреЗрдЫред рддрд░реНрдХрд╣рд░реВрдХреЛ рд╕рдВрдЦреНрдпрд╛рдорд╛ рдирд┐рд░реНрднрд░ рдЧрд░реНрджреИ рдкреНрд░рддреНрдпреЗрдХ рд╡рд┐рдХрд▓реНрдкрдХреЛ рд▓рд╛рдЧрд┐ред рдпреЛ рд╣рд░реЗрдХ рдкрдЯрдХ рдЧрд░реНрдиреБ рднрдиреНрджрд╛ рд░рд╛рдореНрд░реЛ рдЫ, рддрд░ рддрдкрд╛рдИрдВ рдпрд╕рд▓рд╛рдИ рдмрд┐рдирд╛ рдЧрд░реНрди рд╕рдХреНрдиреБрд╣реБрдиреНрдЫред

рдпреЛ рд╕рдорд╛рд╡реЗрд╢ рдорд╛рддреНрд░ рдПрдХ рдкреНрдпрд╛рд░рд╛рдорд┐рдЯрд░ рдкрд╛рд╕ рдЧрд░реНрди рдкрд░реНрдпрд╛рдкреНрдд рдЫ рдХреНрд░рдордмрджреНрдз рд╕рд░рдгреА рдкреНрд░рддрд┐рдирд┐рдзрд┐рддреНрд╡:

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

рдХреЗрд╡рд▓ рднрд┐рдиреНрдирддрд╛ рд╕реНрдкрд╖реНрдЯ рд░реВрдкрдорд╛ рддрд░реНрдХрд▓рд╛рдИ рдЗрдЪреНрдЫрд┐рдд рдПрд░реЗ рдкреНрд░рдХрд╛рд░рдорд╛ рд░реВрдкрд╛рдиреНрддрд░рдг рдЧрд░реНрди рдЖрд╡рд╢реНрдпрдХ рдЫред рддрд░ рдпрд╕рд▓реЗ рд╕рдорд╕реНрдпрд╛ рдирд┐рдореНрддреНрдпрд╛рдЙрдБрджреИрди, рдХрд┐рдирдХрд┐ рд╣рд╛рдореА рдХрд╣рд╛рдБ рдЬрд╛рдБрджреИрдЫреМрдВ рднрдиреЗрд░ рд╣рд╛рдореАрд▓рд╛рдИ рдкрд╣рд┐рд▓реНрдпреИ рдерд╛рд╣рд╛ рдЫред

рдирдореВрдирд╛ рд╕реНрдерд╛рдирд╛рдиреНрддрд░рдг (рдореНрдпрд╛рдЯреНрд░рд┐рдХреНрд╕)

рд╕рд╛рдорд╛рдиреНрдпрддрдпрд╛ рдпреА рдбрд╛рдЯрд╛рдмреЗрд╕рдорд╛ рд╕рдореНрдорд┐рд▓рд┐рдд рдЧрд░реНрдирдХрд╛ рд▓рд╛рдЧрд┐ рдбреЗрдЯрд╛ рд╕реЗрдЯрд╣рд░реВ рд╕реНрдерд╛рдирд╛рдиреНрддрд░рдг рдЧрд░реНрдирдХрд╛ рд▓рд╛рдЧрд┐ рд╕рдмреИ рдкреНрд░рдХрд╛рд░рдХрд╛ рд╡рд┐рдХрд▓реНрдкрд╣рд░реВ рд╣реБрдиреН "рдПрдЙрдЯрд╛ рдЕрдиреБрд░реЛрдзрдорд╛":

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

рдЕрдиреБрд░реЛрдз "рдкреБрдирдГ gluing" рд╕рдВрдЧ рдорд╛рдерд┐ рд╡рд░реНрдгрд┐рдд рд╕рдорд╕реНрдпрд╛рд╣рд░реБ рдХреЛ рдЕрддрд┐рд░рд┐рдХреНрдд, рдпрд╕рд▓реЗ рд╣рд╛рдореАрд▓рд╛рдИ рдкрдирд┐ рдиреЗрддреГрддреНрд╡ рдЧрд░реНрди рд╕рдХреНрдЫ рдореЗрдореЛрд░реА рдмрд╛рд╣рд┐рд░ рд░ рд╕рд░реНрднрд░ рдХреНрд░реНрдпрд╛рд╕ред рдХрд╛рд░рдг рд╕рд░рд▓ рдЫ - PG рд▓реЗ рддрд░реНрдХрд╣рд░реВрдХреЛ рд▓рд╛рдЧрд┐ рдЕрддрд┐рд░рд┐рдХреНрдд рдореЗрдореЛрд░реА рдЖрд░рдХреНрд╖рд┐рдд рдЧрд░реНрджрдЫ, рд░ рд╕реЗрдЯрдорд╛ рд░реЗрдХрд░реНрдбрд╣рд░реВрдХреЛ рд╕рдВрдЦреНрдпрд╛ рдХреЗрд╡рд▓ рд╡реНрдпрд╛рдкрд╛рд░ рддрд░реНрдХрдХреЛ рдЖрд╡реЗрджрди рдЖрд╡рд╢реНрдпрдХрддрд╛рд╣рд░реВрджреНрд╡рд╛рд░рд╛ рд╕реАрдорд┐рдд рдЫред рд╡рд┐рд╢реЗрд╖ рдЧрд░реА рдХреНрд▓рд┐рдирд┐рдХрд▓ рдХреЗрд╕рд╣рд░реВрдорд╛ рдореИрд▓реЗ рд╣реЗрд░реНрдиреБрдкрд░реНтАНрдпреЛ "рдирдореНрдмрд░" рддрд░реНрдХрд╣рд░реВ $ 9000 рднрдиреНрджрд╛ рдмрдвреА рдЫрдиреН - рдпрд╕рд░реА рдирдЧрд░реНрдиреБрд╣реЛрд╕реНред

рдкрд╣рд┐рд▓реЗ рдиреИ рдкреНрд░рдпреЛрдЧ рдЧрд░реЗрд░ рдЕрдиреБрд░реЛрдз рдкреБрди: рд▓реЗрдЦреМрдВ "рджреБрдИ-рд╕реНрддрд░" рдХреНрд░рдорд┐рдХрд░рдг:

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;

рд╣реЛ, рдПрд░реЗ рднрд┐рддреНрд░ "рдЬрдЯрд┐рд▓" рдорд╛рдирд╣рд░реВрдХреЛ рдЕрд╡рд╕реНрдерд╛рдорд╛, рддрд┐рдиреАрд╣рд░реВ рдЙрджреНрдзрд░рдгрд╣рд░реВрджреНрд╡рд╛рд░рд╛ рдШреЗрд░рд┐рдПрдХреЛ рд╣реБрдиреБрдкрд░реНрдЫред
рдпреЛ рд╕реНрдкрд╖реНрдЯ рдЫ рдХрд┐ рдпрд╕ рддрд░рд┐рдХрд╛рд▓реЗ рддрдкрд╛рдИрд▓реЗ рдХреНрд╖реЗрддреНрд░рд╣рд░реВрдХреЛ рдордирдорд╛рдиреА рд╕рдВрдЦреНрдпрд╛рдХреЛ рд╕рд╛рде рдЪрдпрди "рд╡рд┐рд╕реНрддрд╛рд░" рдЧрд░реНрди рд╕рдХреНрдиреБрд╣реБрдиреНрдЫред

рдирд╕реНрдЯ, рдирд╕реНрдЯ,тАж

рд╕рдордп-рд╕рдордпрдорд╛ рддреНрдпрд╣рд╛рдБ "рдПрд░реЗрдХреЛ рдПрд░реЗ" рдзреЗрд░реИ "рд╕реНрддрдореНрднрд╣рд░реВрдХреЛ рдПрд░реЗ" рдХреЛ рд╕рдЯреНрдЯрд╛ рдкрд╛рд╕ рдЧрд░реНрдиреЗ рд╡рд┐рдХрд▓реНрдкрд╣рд░реВ рдЫрдиреН рдЬреБрди рдореИрд▓реЗ рдЙрд▓реНрд▓реЗрдЦ рдЧрд░реЗрдХреЛ рдЫреБред рдкрдЫрд┐рд▓реНрд▓реЛ рд▓реЗрдЦрдорд╛:

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 рдкреНрд░рдХрд╛рд░ рд╕рдВрдЧ рдХрд╛рдо рдЧрд░реНрди рдХреЛ рд▓рд╛рдЧреА рдкреВрд░реНрдг рдкреНрд░рдХрд╛рд░реНрдп рдЫред рддрд╕рд░реНрде, рдпрджрд┐ рддрдкрд╛рдИрдВрдХреЛ рдмреНрд░рд╛рдЙрдЬрд░рдорд╛ рдЗрдирдкреБрдЯ рдкреНрдпрд╛рд░рд╛рдорд┐рдЯрд░рд╣рд░реВрдХреЛ рдкрд░рд┐рднрд╛рд╖рд╛ рд╣реБрдиреНрдЫ рднрдиреЗ, рддрдкрд╛рдИрдВрд▓реЗ рдпрд╕рд▓рд╛рдИ рддреНрдпрд╣рд╛рдБ рдмрдирд╛рдЙрди рд╕рдХреНрдиреБрд╣реБрдиреНрдЫ SQL рдХреНрд╡реЗрд░реАрдХреЛ рд▓рд╛рдЧрд┐ json рд╡рд╕реНрддреБ:

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

рдЕрдШрд┐рд▓реНрд▓реЛ рд╕рдВрд╕реНрдХрд░рдгрд╣рд░реВрдХреЛ рд▓рд╛рдЧрд┐, рдПрдЙрдЯреИ рд╡рд┐рдзрд┐ рдкреНрд░рдпреЛрдЧ рдЧрд░реНрди рд╕рдХрд┐рдиреНрдЫ рдкреНрд░рддреНрдпреЗрдХ (hstore), рддрд░ hstore рдорд╛ рдЬрдЯрд┐рд▓ рд╡рд╕реНрддреБрд╣рд░реВ рдЫреЛрдбреЗрд░ рд╕рд╣реА "convolution" рд▓реЗ рд╕рдорд╕реНрдпрд╛ рдирд┐рдореНрддреНрдпрд╛рдЙрди рд╕рдХреНрдЫред

json_populate_recordset

рдпрджрд┐ рддрдкрд╛рдИрдВрд▓рд╛рдИ рдкрд╣рд┐рд▓реЗ рдиреИ рдерд╛рд╣рд╛ рдЫ рдХрд┐ "рдЗрдирдкреБрдЯ" json array рдмрд╛рдЯ рдбрд╛рдЯрд╛ рдХреЗрд╣рд┐ рддрд╛рд▓рд┐рдХрд╛ рднрд░реНрди рдкреНрд░рдпреЛрдЧ рдЧрд░рд┐рдиреЗрдЫ, рддрдкрд╛рдЗрдБ "dereferencing" рдХреНрд╖реЗрддреНрд░рд╣рд░реВрдорд╛ рдзреЗрд░реИ рдмрдЪрдд рдЧрд░реНрди рд╕рдХреНрдиреБрд╣реБрдиреНрдЫ рд░ 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

рдЕрд╕реНрдерд╛рдпреА рддрд╛рд▓рд┐рдХрд╛

рддрд░ рдпрджрд┐ рд╕реНрдерд╛рдирд╛рдиреНрддрд░рдг рдЧрд░рд┐рдПрдХреЛ рдирдореВрдирд╛рдорд╛ рдбрд╛рдЯрд╛рдХреЛ рдорд╛рддреНрд░рд╛ рдзреЗрд░реИ рдареВрд▓реЛ рдЫ рднрдиреЗ, рддреНрдпрд╕рд▓рд╛рдИ рдПрдХ рдХреНрд░рдордмрджреНрдз рдкреНрдпрд╛рд░рд╛рдорд┐рдЯрд░рдорд╛ рдлрд╛рд▓реНрдиреБ рдЧрд╛рд╣реНрд░реЛ рд░ рдХрд╣рд┐рд▓реЗрдХрд╛рд╣реАрдВ рдЕрд╕рдореНрднрд╡ рдЫ, рдХрд┐рдирдХрд┐ рдпрд╕рд▓рд╛рдИ рдПрдХ рдкрдЯрдХ рдЪрд╛рд╣рд┐рдиреНрдЫред рдореЗрдореЛрд░реА рдХреЛ рдПрдХ рдареВрд▓реЛ рдорд╛рддреНрд░рд╛ рдЖрд╡рдВрдЯрд┐рддред рдЙрджрд╛рд╣рд░рдгрдХрд╛ рд▓рд╛рдЧрд┐, рддрдкрд╛рдИрдВрд▓реЗ рд▓рд╛рдореЛ, рд▓рд╛рдореЛ рд╕рдордпрдХреЛ рд▓рд╛рдЧрд┐ рдмрд╛рд╣реНрдп рдкреНрд░рдгрд╛рд▓реАрдмрд╛рдЯ рдШрдЯрдирд╛рд╣рд░реВрдорд╛ рдбреЗрдЯрд╛рдХреЛ рдареВрд▓реЛ рдкреНрдпрд╛рдХреЗрдЬ рд╕рдЩреНрдХрд▓рди рдЧрд░реНрди рдЖрд╡рд╢реНрдпрдХ рдЫ, рд░ рддреНрдпрд╕рдкрдЫрд┐ рддрдкрд╛рдЗрдБ рдпрд╕рд▓рд╛рдИ рдбрд╛рдЯрд╛рдмреЗрд╕ рд╕рд╛рдЗрдбрдорд╛ рдПрдХ рдкрдЯрдХ рдкреНрд░рдХреНрд░рд┐рдпрд╛ рдЧрд░реНрди рдЪрд╛рд╣рдиреБрд╣реБрдиреНрдЫред

рдпрд╕ рдЕрд╡рд╕реНрдерд╛рдорд╛, рд╕рдмреИ рднрдиреНрджрд╛ рд░рд╛рдореНрд░реЛ рд╕рдорд╛рдзрд╛рди рдкреНрд░рдпреЛрдЧ рдЧрд░реНрди рд╣реБрдиреЗрдЫ рдЕрд╕реНрдерд╛рдпреА рддрд╛рд▓рд┐рдХрд╛рд╣рд░реВ:

CREATE TEMPORARY TABLE tbl(k text, v integer);
...
INSERT INTO tbl(k, v) VALUES($1, $2); -- ╨┐╨╛╨▓╤В╨╛╤А╨╕╤В╤М ╨╝╨╜╨╛╨│╨╛-╨╝╨╜╨╛╨│╨╛ ╤А╨░╨╖
...
-- ╤В╤Г╤В ╨┤╨╡╨╗╨░╨╡╨╝ ╤З╤В╨╛-╤В╨╛ ╨┐╨╛╨╗╨╡╨╖╨╜╨╛╨╡ ╤Б╨╛ ╨▓╤Б╨╡╨╣ ╤Н╤В╨╛╨╣ ╤В╨░╨▒╨╗╨╕╤Ж╨╡╨╣ ╤Ж╨╡╨╗╨╕╨║╨╛╨╝

рд╡рд┐рдзрд┐ рд░рд╛рдореНрд░реЛ рдЫ рдареВрд▓реЛ рдорд╛рддреНрд░рд╛рдХреЛ рд╕рд╛рдордпрд┐рдХ рд╕реНрдерд╛рдирд╛рдиреНрддрд░рдгрдХреЛ рд▓рд╛рдЧрд┐ рдбрд╛рдЯрд╛ред
рдпрд╕рдХреЛ рдбреЗрдЯрд╛рдХреЛ рд╕рдВрд░рдЪрдирд╛ рд╡рд░реНрдгрди рдЧрд░реНрдиреЗ рджреГрд╖реНрдЯрд┐рдХреЛрдгрдмрд╛рдЯ, рдПрдХ рдЕрд╕реНрдерд╛рдпреА рддрд╛рд▓рд┐рдХрд╛ "рдирд┐рдпрдорд┐рдд" рдПрдХ рдорд╛рддреНрд░ рдПрдХ рддрд░рд┐рдХрд╛рдорд╛ рдлрд░рдХ рдЫред pg_class рдкреНрд░рдгрд╛рд▓реА рддрд╛рд▓рд┐рдХрд╛рдорд╛, рд░ in pg_type, pg_depend, pg_attribute, pg_attrdef, ... - рдХреЗрд╣рд┐ рдкрдирд┐ рд╣реЛрдИрдиред

рддрд╕рд░реНрде, рд╡реЗрдм рдкреНрд░рдгрд╛рд▓реАрд╣рд░реВрдорд╛ рддрд┐рдиреАрд╣рд░реВрдордзреНрдпреЗ рдкреНрд░рддреНрдпреЗрдХрдХреЛ рд▓рд╛рдЧрд┐ рдзреЗрд░реИ рд╕рдВрдЦреНрдпрд╛рдорд╛ рдЫреЛрдЯреЛ-рдЕрд╡рд╕реНрдерд╛ рдЬрдбрд╛рдирд╣рд░реВ рдЫрдиреН, рдпрд╕реНрддреЛ рддрд╛рд▓рд┐рдХрд╛рд▓реЗ рдкреНрд░рддреНрдпреЗрдХ рдкрдЯрдХ рдирдпрд╛рдБ рдкреНрд░рдгрд╛рд▓реА рд░реЗрдХрд░реНрдбрд╣рд░реВ рдЙрддреНрдкрдиреНрди рдЧрд░реНрдиреЗрдЫ, рдЬреБрди рдбрд╛рдЯрд╛рдмреЗрд╕рдорд╛ рдЬрдбрд╛рди рдмрдиреНрдж рд╣реБрдБрджрд╛ рдореЗрдЯрд╛рдЗрдиреНрдЫред рдЕрдиреНрддрддрдГ, TEMP TABLE рдХреЛ рдЕрдирд┐рдпрдиреНрддреНрд░рд┐рдд рдкреНрд░рдпреЛрдЧрд▓реЗ pg_catalog рдорд╛ рдЯреЗрдмрд▓рдХреЛ "рд╕реБрдЬрди" рдирд┐рдореНрддреНрдпрд╛рдЙрдБрдЫ рд░ рддрд┐рдиреАрд╣рд░реВрд▓рд╛рдИ рдкреНрд░рдпреЛрдЧ рдЧрд░реНрдиреЗ рдзреЗрд░реИ рдЕрдкрд░реЗрд╢рдирд╣рд░реВ рд╕реБрд╕реНрдд рдкрд╛рд░реНрджреИред
рдирд┐рд╕реНрд╕рдиреНрджреЗрд╣, рдпреЛ рдкреНрд░рдпреЛрдЧ рдЧрд░реЗрд░ рд╡реНрдпрд╡рд╣рд╛рд░ рдЧрд░реНрди рд╕рдХрд┐рдиреНрдЫ рдЖрд╡рдзрд┐рдХ рдорд╛рд░реНрдЧ VACUUM FULL рдкреНрд░рдгрд╛рд▓реА рд╕реВрдЪреА рддрд╛рд▓рд┐рдХрд╛ рдЕрдиреБрд╕рд╛рд░ред

рд╕рддреНрд░ рдЪрд░

рдорд╛рдиреМрдВ рдХрд┐ рдЕрдШрд┐рд▓реНрд▓реЛ рдХреЗрд╕рдмрд╛рдЯ рдбрд╛рдЯрд╛ рдкреНрд░рд╢реЛрдзрди рдЧрд░реНрдиреБ рдПрдХ SQL рдХреНрд╡реЗрд░реАрдХреЛ рд▓рд╛рдЧрд┐ рдПрдХрджрдо рдЬрдЯрд┐рд▓ рдЫ, рддрд░ рддрдкрд╛рдЗрдБ рдпрд╕рд▓рд╛рдИ рдкреНрд░рд╛рдп: рдЧрд░реНрди рдЪрд╛рд╣рдиреБрд╣реБрдиреНрдЫред рддреНрдпреЛ рд╣реЛ, рд╣рд╛рдореА рдкреНрд░рдХреНрд░рд┐рдпрд╛рдЧрдд рдкреНрд░рд╢реЛрдзрди рдкреНрд░рдпреЛрдЧ рдЧрд░реНрди рдЪрд╛рд╣рдиреНрдЫреМрдВ рдмреНрд▓рдХ рдЧрд░реНрдиреБрд╣реЛрд╕реН, рддрд░ рдЕрд╕реНрдерд╛рдпреА рддрд╛рд▓рд┐рдХрд╛рд╣рд░реБ рдорд╛рд░реНрдлрдд рдбрд╛рдЯрд╛ рд╕реНрдерд╛рдирд╛рдиреНрддрд░рдг рдкреНрд░рдпреЛрдЧ рдзреЗрд░реИ рдорд╣рдБрдЧреЛ рд╣реБрдиреЗрдЫред

рд╣рд╛рдореА рдкрдирд┐ рдЕрдЬреНрдЮрд╛рдд рдмреНрд▓рдХрдорд╛ рдкрд╛рд╕ рдЧрд░реНрдирдХреЛ рд▓рд╛рдЧрд┐ $n-рдкреНрдпрд╛рд░рд╛рдорд┐рдЯрд░рд╣рд░реВ рдкреНрд░рдпреЛрдЧ рдЧрд░реНрди рд╕рдХреНрд╖рдо рд╣реБрдиреЗ рдЫреИрдиреМрдВред рд╕рддреНрд░ рдЪрд░ рд░ рдкреНрд░рдХрд╛рд░реНрдпрд▓реЗ рд╣рд╛рдореАрд▓рд╛рдИ рдпрд╕ рдЕрд╡рд╕реНрдерд╛рдмрд╛рдЯ рдмрд╛рд╣рд┐рд░ рдирд┐рд╕реНрдХрди рдорджреНрджрдд рдЧрд░реНрдиреЗрдЫ рд╣рд╛рд▓рдХреЛ_рд╕реЗрдЯрд┐рдЩ.

рд╕рдВрд╕реНрдХрд░рдг 9.2 рдЕрдШрд┐ рдпреЛ рдкреВрд░реНрд╡ рдХрдиреНрдлрд┐рдЧрд░ рдЧрд░реНрди рдЖрд╡рд╢реНрдпрдХ рдерд┐рдпреЛ рд╡рд┐рд╢реЗрд╖ рдирд╛рдо рд╕реНрдерд╛рди custom_variable_classes "рддрдкрд╛рдИрдВрдХреЛ" рд╕рддреНрд░ рдЪрд░рдХрд╛ рд▓рд╛рдЧрд┐ред рд╣рд╛рд▓рдХреЛ рд╕рдВрд╕реНрдХрд░рдгрд╣рд░реВрдорд╛ рддрдкрд╛рдИрдВрд▓реЗ рдпрд╕рд░реА рд▓реЗрдЦреНрди рд╕рдХреНрдиреБрд╣реБрдиреНрдЫ:

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

рдЕрдиреНрдп рд╕рдорд╛рдзрд╛рдирд╣рд░реВ рдЕрдиреНрдп рд╕рдорд░реНрдерд┐рдд рдкреНрд░рдХреНрд░рд┐рдпрд╛рддреНрдордХ рднрд╛рд╖рд╛рд╣рд░реВрдорд╛ рдлреЗрд▓рд╛ рдкрд╛рд░реНрди рд╕рдХрд┐рдиреНрдЫред

рдХреЗ рддрдкрд╛рдИрд▓рд╛рдИ рдЕрд░реВ рдХреБрдиреИ рддрд░рд┐рдХрд╛ рдерд╛рд╣рд╛ рдЫ? рдЯрд┐рдкреНрдкрдгреАрд╣рд░реВрдорд╛ рд╕рд╛рдЭрд╛ рдЧрд░реНрдиреБрд╣реЛрд╕реН!

рд╕реНрд░реЛрдд: www.habr.com

рдПрдХ рдЯрд┐рдкреНрдкрдгреА рдердкреНрди