PostgreSQL Antipatterns: "рдореГрдд" рдХреА рднреАрдбрд╝ рд╕реЗ рд▓рдбрд╝рдирд╛

PostgreSQL рдХреЗ рдЖрдВрддрд░рд┐рдХ рддрдВрддреНрд░ рдХреА рдЦрд╝рд╛рд╕рд┐рдпрддреЗрдВ рдЗрд╕реЗ рдХреБрдЫ рд╕реНрдерд┐рддрд┐рдпреЛрдВ рдореЗрдВ рдмрд╣реБрдд рддреЗрдЬрд╝ рдФрд░ рджреВрд╕рд░реЛрдВ рдореЗрдВ "рдмрд╣реБрдд рддреЗрдЬрд╝ рдирд╣реАрдВ" рд╣реЛрдиреЗ рдХреА рдЕрдиреБрдорддрд┐ рджреЗрддреА рд╣реИрдВред рдЖрдЬ рд╣рдо рдбреАрдмреАрдПрдордПрд╕ рдХреИрд╕реЗ рдХрд╛рдо рдХрд░рддрд╛ рд╣реИ рдФрд░ рдбреЗрд╡рд▓рдкрд░ рдЗрд╕рдХреЗ рд╕рд╛рде рдХреНрдпрд╛ рдХрд░рддрд╛ рд╣реИ, рдХреЗ рдмреАрдЪ рд╕рдВрдШрд░реНрд╖ рдХреЗ рдПрдХ рдЙрддреНрдХреГрд╖реНрдЯ рдЙрджрд╛рд╣рд░рдг рдкрд░ рдзреНрдпрд╛рди рдХреЗрдВрджреНрд░рд┐рдд рдХрд░реЗрдВрдЧреЗ - рдЕрджреНрдпрддрди рдмрдирд╛рдо рдПрдорд╡реАрд╕реАрд╕реА рд╕рд┐рджреНрдзрд╛рдВрдд.

рд╕реЗ рд╕рдВрдХреНрд╖рд┐рдкреНрдд рдХрд╣рд╛рдиреА рдмрдврд╝рд┐рдпрд╛ рд▓реЗрдЦ:

рдЬрдм рдХрд┐рд╕реА рдкрдВрдХреНрддрд┐ рдХреЛ рдЕрдкрдбреЗрдЯ рдХрдорд╛рдВрдб рджреНрд╡рд╛рд░рд╛ рд╕рдВрд╢реЛрдзрд┐рдд рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ, рддреЛ рд╡рд╛рд╕реНрддрд╡ рдореЗрдВ рджреЛ рдСрдкрд░реЗрд╢рди рдХрд┐рдП рдЬрд╛рддреЗ рд╣реИрдВ: рд╣рдЯрд╛рдПрдВ рдФрд░ рдбрд╛рд▓реЗрдВред рдореЗрдВ рд╕реНрдЯреНрд░рд┐рдВрдЧ рдХрд╛ рд╡рд░реНрддрдорд╛рди рд╕рдВрд╕реНрдХрд░рдг xmax рдХреЛ рдЕрджреНрдпрддрди рдХрд░рдиреЗ рд╡рд╛рд▓реЗ рд▓реЗрдирджреЗрди рдХреА рд╕рдВрдЦреНрдпрд╛ рдХреЗ рдмрд░рд╛рдмрд░ рд╕реЗрдЯ рдХрд┐рдпрд╛ рдЧрдпрд╛ рд╣реИред рдлрд┐рд░ рдЗрд╕реЗ рдмрдирд╛рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ рдПрдХ рдирдпрд╛ рд╕рдВрд╕реНрдХрд░рдг рд╡рд╣реА рдкрдВрдХреНрддрд┐; рдЗрд╕рдХрд╛ xmin рдорд╛рди рдкрд┐рдЫрд▓реЗ рд╕рдВрд╕реНрдХрд░рдг рдХреЗ xmax рдорд╛рди рд╕реЗ рдореЗрд▓ рдЦрд╛рддрд╛ рд╣реИред

рдЗрд╕ рд▓реЗрди-рджреЗрди рдХреЗ рдкреВрд░рд╛ рд╣реЛрдиреЗ рдХреЗ рдХреБрдЫ рд╕рдордп рдмрд╛рдж, рдкреБрд░рд╛рдирд╛ рдпрд╛ рдирдпрд╛ рд╕рдВрд╕реНрдХрд░рдг, рдЗрд╕ рдкрд░ рдирд┐рд░реНрднрд░ рдХрд░рддрд╛ рд╣реИ COMMIT/ROOLBACK, рдкрд╣рдЪрд╛рдирд╛ рдЬрд╛рдПрдЧрд╛ "рдореГрдд" (рдореГрдд рдЯреБрдкрд▓реНрд╕) рдЧреБрдЬрд░рддреЗ рд╕рдордп VACUUM рддрд╛рд▓рд┐рдХрд╛ рдХреЗ рдЕрдиреБрд╕рд╛рд░ рдФрд░ рд╕рд╛рдлрд╝ рдХрд┐рдпрд╛ рдЧрдпрд╛ред

PostgreSQL Antipatterns: "рдореГрдд" рдХреА рднреАрдбрд╝ рд╕реЗ рд▓рдбрд╝рдирд╛

рд▓реЗрдХрд┐рди рдпрд╣ рддреБрд░рдВрдд рдирд╣реАрдВ рд╣реЛрдЧрд╛, рд▓реЗрдХрд┐рди "рдореГрдд" рдХреЗ рд╕рд╛рде рд╕рдорд╕реНрдпрд╛рдПрдВ рдмрд╣реБрдд рдЬрд▓реНрджреА рд╣рд╛рд╕рд┐рд▓ рдХреА рдЬрд╛ рд╕рдХрддреА рд╣реИрдВ - рдмрд╛рд░-рдмрд╛рд░ рдпрд╛ рдХреЗ рд╕рд╛рде рдЕрднрд┐рд▓реЗрдЦреЛрдВ рдХрд╛ рдмрдбрд╝реЗ рдкреИрдорд╛рдиреЗ рдкрд░ рдЕрджреНрдпрддрдиреАрдХрд░рдг рдПрдХ рдмрдбрд╝реА рдореЗрдЬ рдкрд░, рдФрд░ рдереЛрдбрд╝реА рджреЗрд░ рдмрд╛рдж рдЖрдк рдЙрд╕реА рд╕реНрдерд┐рддрд┐ рдХрд╛ рд╕рд╛рдордирд╛ рдХрд░реЗрдВрдЧреЗ рд╡реИрдХреНрдпреВрдо рдорджрдж рдирд╣реАрдВ рдХрд░ рдкрд╛рдПрдЧрд╛.

#1: рдореБрдЭреЗ рдЗрд╕реЗ рд╕реНрдерд╛рдирд╛рдВрддрд░рд┐рдд рдХрд░рдирд╛ рдкрд╕рдВрдж рд╣реИ

рдорд╛рди рд▓реАрдЬрд┐рдП рдХрд┐ рдЖрдкрдХреА рд╡рд┐рдзрд┐ рд╡реНрдпрд╛рд╡рд╕рд╛рдпрд┐рдХ рддрд░реНрдХ рдкрд░ рдХрд╛рдо рдХрд░ рд░рд╣реА рд╣реИ, рдФрд░ рдЕрдЪрд╛рдирдХ рдЙрд╕реЗ рдПрд╣рд╕рд╛рд╕ рд╣реЛрддрд╛ рд╣реИ рдХрд┐ рдХреБрдЫ рд░рд┐рдХреЙрд░реНрдб рдореЗрдВ рдПрдХреНрд╕ рдлрд╝реАрд▓реНрдб рдХреЛ рдЕрдкрдбреЗрдЯ рдХрд░рдирд╛ рдЖрд╡рд╢реНрдпрдХ рд╣реЛрдЧрд╛:

UPDATE tbl SET X = <newX> WHERE pk = $1;

рдлрд┐рд░, рдЬреИрд╕реЗ-рдЬреИрд╕реЗ рдирд┐рд╖реНрдкрд╛рджрди рдЖрдЧреЗ рдмрдврд╝рддрд╛ рд╣реИ, рдпрд╣ рдкрддрд╛ рдЪрд▓рддрд╛ рд╣реИ рдХрд┐ Y рдлрд╝реАрд▓реНрдб рдХреЛ рднреА рдЕрджреНрдпрддрди рдХрд┐рдпрд╛ рдЬрд╛рдирд╛ рдЪрд╛рд╣рд┐рдП:

UPDATE tbl SET Y = <newY> WHERE pk = $1;

... рдФрд░ рдлрд┐рд░ Z рднреА - рдЫреЛрдЯреА-рдЫреЛрдЯреА рдмрд╛рддреЛрдВ рдкрд░ рд╕рдордп рдХреНрдпреЛрдВ рдмрд░реНрдмрд╛рдж рдХрд░реЗрдВ?

UPDATE tbl SET Z = <newZ> WHERE pk = $1;

рдЕрдм рд╣рдорд╛рд░реЗ рдкрд╛рд╕ рдбреЗрдЯрд╛рдмреЗрд╕ рдореЗрдВ рдЗрд╕ рд░рд┐рдХреЙрд░реНрдб рдХреЗ рдХрд┐рддрдиреЗ рд╕рдВрд╕реНрдХрд░рдг рд╣реИрдВ? рд╣рд╛рдБ, 4 рдЯреБрдХрдбрд╝реЗ! рдЗрдирдореЗрдВ рд╕реЗ, рдПрдХ рдкреНрд░рд╛рд╕рдВрдЧрд┐рдХ рд╣реИ, рдФрд░ 3 рдХреЛ рдЖрдкрдХреЗ рдмрд╛рдж [рдСрдЯреЛ]VACUUM рджреНрд╡рд╛рд░рд╛ рд╕рд╛рдлрд╝ рдХрд░рдирд╛ рд╣реЛрдЧрд╛ред

рдЗрд╕реЗ рдЗрд╕ рддрд░рд╣ рдордд рдХрд░реЛ! рдЙрдкрдпреЛрдЧ рдПрдХ рдЕрдиреБрд░реЛрдз рдореЗрдВ рд╕рднреА рдлрд╝реАрд▓реНрдб рдЕрдкрдбреЗрдЯ рдХрд░рдирд╛ - рд▓рдЧрднрдЧ рд╣рдореЗрд╢рд╛ рд╡рд┐рдзрд┐ рдХрд╛ рддрд░реНрдХ рдЗрд╕ рдкреНрд░рдХрд╛рд░ рдмрджрд▓рд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИ:

UPDATE tbl SET X = <newX>, Y = <newY>, Z = <newZ> WHERE pk = $1;

#2: рдЙрдкрдпреЛрдЧ рд▓реНрдпреВрдХ рд╕реЗ рдЕрд▓рдЧ рд╣реИ!

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

UPDATE tbl SET X = <newX> WHERE pk BETWEEN $1 AND $2;

рд▓рдЧрднрдЧ рдЗрд╕ рдлреЙрд░реНрдо рдореЗрдВ рдПрдХ рдЕрдиреБрд░реЛрдз рдЕрдХреНрд╕рд░ рд╣реЛрддрд╛ рд╣реИ рдФрд░ рд▓рдЧрднрдЧ рд╣рдореЗрд╢рд╛ рдПрдХ рдЦрд╛рд▓реА рдирдП рдлрд╝реАрд▓реНрдб рдХреЛ рднрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдирд╣реАрдВ, рдмрд▓реНрдХрд┐ рдбреЗрдЯрд╛ рдореЗрдВ рдХреБрдЫ рддреНрд░реБрдЯрд┐рдпреЛрдВ рдХреЛ рдареАрдХ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рд╣реЛрддрд╛ рд╣реИред рд╕рд╛рде рд╣реА рд╡рд╣ рд╕реНрд╡ рдореМрдЬреВрджрд╛ рдбреЗрдЯрд╛ рдХреА рд╢реБрджреНрдзрддрд╛ рдкрд░ рдмрд┐рд▓реНрдХреБрд▓ рднреА рдзреНрдпрд╛рди рдирд╣реАрдВ рджрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ - рдкрд░рдиреНрддреБ рд╕рдлрд▓рддрд╛ рдирд╣реАрдВ рдорд┐рд▓реА! рдпрд╛рдиреА, рд░рд┐рдХреЙрд░реНрдб рджреЛрдмрд╛рд░рд╛ рд▓рд┐рдЦрд╛ рдЬрд╛рддрд╛ рд╣реИ, рднрд▓реЗ рд╣реА рдЙрд╕рдореЗрдВ рд╡рд╣реА рд╣реЛ рдЬреЛ рд╡рд╛рдВрдЫрд┐рдд рдерд╛ - рд▓реЗрдХрд┐рди рдХреНрдпреЛрдВ? рдЖрдЗрдП рдЗрд╕реЗ рдареАрдХ рдХрд░реЗрдВ:

UPDATE tbl SET X = <newX> WHERE pk BETWEEN $1 AND $2 AND X IS DISTINCT FROM <newX>;

рдмрд╣реБрдд рд╕реЗ рд▓реЛрдЧреЛрдВ рдХреЛ рдРрд╕реЗ рдЕрджреНрднреБрдд рдСрдкрд░реЗрдЯрд░ рдХреЗ рдЕрд╕реНрддрд┐рддреНрд╡ рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдЬрд╛рдирдХрд╛рд░реА рдирд╣реАрдВ рд╣реИ, рдЗрд╕рд▓рд┐рдП рдпрд╣рд╛рдВ рдПрдХ рдЪреАрдЯ рд╢реАрдЯ рджреА рдЧрдИ рд╣реИ IS DISTINCT FROM рдФрд░ рдЕрдиреНрдп рддрд╛рд░реНрдХрд┐рдХ рдСрдкрд░реЗрдЯрд░ рдорджрдж рдХреЗ рд▓рд┐рдП:
PostgreSQL Antipatterns: "рдореГрдд" рдХреА рднреАрдбрд╝ рд╕реЗ рд▓рдбрд╝рдирд╛
... рдФрд░ рдХреЙрдореНрдкреНрд▓реЗрдХреНрд╕ рдкрд░ рд╕рдВрдЪрд╛рд▓рди рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдереЛрдбрд╝рд╛ ROW()-рднрд╛рд╡:
PostgreSQL Antipatterns: "рдореГрдд" рдХреА рднреАрдбрд╝ рд╕реЗ рд▓рдбрд╝рдирд╛

#3: рдореИрдВ рдЕрдкрдиреА рдкреНрд░рд┐рдпрддрдорд╛ рдХреЛ... рдмреНрд▓реЙрдХ рдХрд░рдХреЗ рдкрд╣рдЪрд╛рдирддрд╛ рд╣реВрдВ

рд▓реЙрдиреНрдЪ рдХрд┐рдП рдЬрд╛ рд░рд╣реЗ рд╣реИрдВ рджреЛ рд╕рдорд╛рди рд╕рдорд╛рдирд╛рдВрддрд░ рдкреНрд░рдХреНрд░рд┐рдпрд╛рдПрдВ, рдЬрд┐рдирдореЗрдВ рд╕реЗ рдкреНрд░рддреНрдпреЗрдХ рдкреНрд░рд╡рд┐рд╖реНрдЯрд┐ рдХреЛ рдЪрд┐рд╣реНрдирд┐рдд рдХрд░рдиреЗ рдХрд╛ рдкреНрд░рдпрд╛рд╕ рдХрд░рддрд╛ рд╣реИ рдХрд┐ рдпрд╣ "рдкреНрд░рдЧрддрд┐ рдкрд░" рд╣реИ:

UPDATE tbl SET processing = TRUE WHERE pk = $1;

рднрд▓реЗ рд╣реА рдпреЗ рдкреНрд░рдХреНрд░рд┐рдпрд╛рдПрдВ рд╡рд╛рд╕реНрддрд╡ рдореЗрдВ рдПрдХ-рджреВрд╕рд░реЗ рд╕реЗ рд╕реНрд╡рддрдВрддреНрд░ рдХрд╛рд░реНрдп рдХрд░рддреА рд╣реЛрдВ, рд▓реЗрдХрд┐рди рдПрдХ рд╣реА рдЖрдИрдбреА рдХреЗ рднреАрддрд░, рдкрд╣рд▓рд╛ рд▓реЗрдирджреЗрди рдкреВрд░рд╛ рд╣реЛрдиреЗ рддрдХ рдЗрд╕ рдЕрдиреБрд░реЛрдз рдкрд░ рджреВрд╕рд░рд╛ рдЧреНрд░рд╛рд╣рдХ "рд▓реЙрдХ" рд░рд╣реЗрдЧрд╛ред

рдирд┐рд░реНрдгрдп рд╕рдВрдЦреНрдпрд╛ 1: рдХрд╛рд░реНрдп рдкрд┐рдЫрд▓реЗ рд╡рд╛рд▓реЗ рддрдХ рдХрдо рд╣реЛ рдЧрдпрд╛ рд╣реИ

рдЪрд▓рд┐рдП рдЗрд╕реЗ рдлрд┐рд░ рд╕реЗ рдЬреЛрдбрд╝рддреЗ рд╣реИрдВ IS DISTINCT FROM:

UPDATE tbl SET processing = TRUE WHERE pk = $1 AND processing IS DISTINCT FROM TRUE;

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

рдирд┐рд░реНрдгрдп рд╕рдВрдЦреНрдпрд╛ 2: рд╕рд▓рд╛рд╣рдХрд╛рд░ рддрд╛рд▓реЗ

рдПрдХ рдЕрд▓рдЧ рд▓реЗрдЦ рдХреЗ рд▓рд┐рдП рдПрдХ рдмрдбрд╝рд╛ рд╡рд┐рд╖рдп, рдЬрд┐рд╕рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдЖрдк рдкрдврд╝ рд╕рдХрддреЗ рд╣реИрдВ рдЖрд╡реЗрджрди рдХреЗ рддрд░реАрдХреЗ рдФрд░ рдЕрдиреБрд╢рдВрд╕рд╛рддреНрдордХ рдЕрд╡рд░реЛрдзрди рдХреА "рд░реЗрдХ"ред.

рдирд┐рд░реНрдгрдп рд╕рдВрдЦреНрдпрд╛ 3: рдмреЗрд╡рдХреВрдлреА рднрд░реА рдХреЙрд▓

рд▓реЗрдХрд┐рди рдЖрдкрдХреЗ рд╕рд╛рде рдмрд┐рд▓реНрдХреБрд▓ рдпрд╣реА рд╣реЛрдирд╛ рдЪрд╛рд╣рд┐рдП рдПрдХ рд╣реА рд░рд┐рдХреЙрд░реНрдб рдХреЗ рд╕рд╛рде рдПрдХ рд╕рд╛рде рдХрд╛рдо рдХрд░рдирд╛? рдпрд╛ рдХреНрдпрд╛ рдЖрдкрдиреЗ рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП, рдХреНрд▓рд╛рдЗрдВрдЯ рд╕рд╛рдЗрдб рдкрд░ рдмрд┐рдЬрдиреЗрд╕ рд▓реЙрдЬрд┐рдХ рдХреЛ рдХреЙрд▓ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдПрд▓реНрдЧреЛрд░рд┐рджрдо рдХреЗ рд╕рд╛рде рдЧрдбрд╝рдмрдбрд╝реА рдХреА рд╣реИ? рдФрд░ рдЕрдЧрд░ рдЖрдк рдЗрд╕рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рд╕реЛрдЪрддреЗ рд╣реИрдВ?

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

рдПрдХ рдЯрд┐рдкреНрдкрдгреА рдЬреЛрдбрд╝реЗрдВ