рдХреИрд╕реЗ рд╣рдо рдПрдХ рдмрд╛рдЗрдЯ рдЬреЛрдбрд╝ рдХреЗ рдмрд┐рдирд╛ PostgreSQL рдореЗрдВ рд╕реНрдореГрддрд┐ рд╕рдорд╕реНрдпрд╛ рдХреЛ рд╣рд▓ рдХрд┐рдпрд╛


рд╕рдорд╕реНрдпрд╛ рдХреЗ "рднрд╛рд░реА" рдЕрдиреБрд░реЛрдз рдФрд░ рд╕реБрд░реБрдЪрд┐рдкреВрд░реНрдг рд╕рдорд╛рдзрд╛рди рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдПрдХ рдЫреЛрдЯреА рдХрд╣рд╛рдиреА


рд╣рд╛рд▓ рд╣реА рдореЗрдВ, рд░рд╛рдд рдореЗрдВ, рдЕрд▓рд░реНрдЯ рдиреЗ рд╣рдореЗрдВ рдЬрдЧрд╛рдирд╛ рд╢реБрд░реВ рдХрд┐рдпрд╛: рдкрд░реНрдпрд╛рдкреНрдд рдбрд┐рд╕реНрдХ рд╕реНрдерд╛рди рдирд╣реАрдВ рдерд╛ред рд╣рдордиреЗ рдЬрд▓реНрджреА рд╕реЗ рдкрддрд╛ рд▓рдЧрд╛рдпрд╛ рдХрд┐ рд╕рдорд╕реНрдпрд╛ рдИрдЯреАрдПрд▓ рдХрд╛рд░реНрдпреЛрдВ рдореЗрдВ рд╣реИред


ETL рдХрд╛рд░реНрдп рдПрдХ рддрд╛рд▓рд┐рдХрд╛ рдореЗрдВ рдХрд┐рдпрд╛ рдЧрдпрд╛ рдерд╛ рдЬрд╣рд╛рдВ рдмрд╛рдЗрдирд░реА рд░рд┐рдХреЙрд░реНрдб рдФрд░ рдбрдВрдк рд╕рдВрдЧреНрд░рд╣реАрдд рдХрд┐рдП рдЬрд╛рддреЗ рд╣реИрдВред рд╣рд░ рд░рд╛рдд, рдпрд╣ рдХрд╛рд░реНрдп рдбреБрдкреНрд▓рд┐рдХреЗрдЯ рдбрдВрдк рдХреЛ рд╣рдЯрд╛рдиреЗ рдФрд░ рд╕реНрдерд╛рди рдЦрд╛рд▓реА рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдерд╛ред


рдбрдВрдк рдбрдВрдк рдХреА рдЦреЛрдЬ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП, рд╣рдордиреЗ рдЗрд╕ рдХреНрд╡реЗрд░реА рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд┐рдпрд╛:


id, MIN(id) OVER (PARTITION BY blob ORDER BY id) FROM dumps 

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


рдЕрдиреБрд░реЛрдз рдХреЛ рдХреБрдЫ рд╕рдордп рдХреЗ рд▓рд┐рдП рдирд┐рд╖реНрдкрд╛рджрд┐рдд рдХрд┐рдпрд╛ рдЧрдпрд╛ рдерд╛, рдФрд░, рдЬреИрд╕рд╛ рдХрд┐ рд▓реЙрдЧ рд╕реЗ рджреЗрдЦрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИ, рдмрд╣реБрдд рд╕рд╛рд░реА рдореЗрдореЛрд░реА рдЦрд╛ рд▓реАред рдЧреНрд░рд╛рдлрд╝ рджрд┐рдЦрд╛рддрд╛ рд╣реИ рдХрд┐ рдЙрд╕рдиреЗ рд╣рд░ рд░рд╛рдд рдореБрдлреНрдд рдбрд┐рд╕реНрдХ рд╕реНрдерд╛рди рдХреИрд╕реЗ рдмрдирд╛рдпрд╛:



рд╕рдордп рдХреЗ рд╕рд╛рде, рдЕрдиреБрд░реЛрдз рдХреЛ рдЕрдзрд┐рдХ рд╕реНрдореГрддрд┐ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рдереА, рд╡рд┐рдлрд▓рддрд╛рдПрдВ рдЧрд╣рд░реА рд╣реЛ рдЧрдИрдВред рдФрд░, рдирд┐рд╖реНрдкрд╛рджрди рдпреЛрдЬрдирд╛ рдХреЛ рджреЗрдЦрддреЗ рд╣реБрдП, рд╣рдордиреЗ рддреБрд░рдВрдд рджреЗрдЦрд╛ рдХрд┐ рд╕рдм рдХреБрдЫ рдХрд╣рд╛рдВ рдЬрд╛рддрд╛ рд╣реИ:


  Buffers: shared hit=3916, temp read=3807 written=3816 -> Sort (cost=69547.50..70790.83 rows=497332 width=36) (actual time=107.607..127.485 rows=39160) Sort Key: blob, id Sort Method: external merge Disk: 30456kB Buffers: shared hit=3916, temp read=3807 written=3816 -> Seq Scan on dumps (cost=0..8889.32 rows=497332 width=36) (actual time=0.022..8.747 rows=39160) Buffers: shared hit=3916 Execution time: 159.960 ms 

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


рдРрд╕рд╛ рдХреНрдпреЛрдВ?


PostgreSQL рд╣реИрд╢рд┐рдВрдЧ рдФрд░ рд╕реЙрд░реНрдЯрд┐рдВрдЧ рдХреЗ рд▓рд┐рдП рдореЗрдореЛрд░реА рдЖрд╡рдВрдЯрд┐рдд рдХрд░рддрд╛ рд╣реИред рдореЗрдореЛрд░реА рдХреА рдорд╛рддреНрд░рд╛ рдХреЛ work_mem рдкреИрд░рд╛рдореАрдЯрд░ рджреНрд╡рд╛рд░рд╛ рдирд┐рдпрдВрддреНрд░рд┐рдд рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИред Work_mem рдХрд╛ рдбрд┐рдлрд╝реЙрд▓реНрдЯ рдЖрдХрд╛рд░ 4 MB рд╣реИред рдпрджрд┐ рд╣реИрд╢рд┐рдВрдЧ рдпрд╛ рд╕реЙрд░реНрдЯрд┐рдВрдЧ рдХреЗ рд▓рд┐рдП 4 рдПрдордмреА рд╕реЗ рдЕрдзрд┐рдХ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реЛрддреА рд╣реИ, рддреЛ PostgreSQL рдЕрд╕реНрдерд╛рдпреА рд░реВрдк рд╕реЗ рдбрд┐рд╕реНрдХ рд╕реНрдерд╛рди рдХреА рдЦрдкрдд рдХрд░рддрд╛ рд╣реИред


рд╣рдорд╛рд░реА рдХреНрд╡реЗрд░реА 4 рдПрдордмреА рд╕реЗ рдЕрдзрд┐рдХ рд╕реНрдкрд╖реНрдЯ рд░реВрдк рд╕реЗ рдЦрдкрдд рдХрд░рддреА рд╣реИ, рдЗрд╕рд▓рд┐рдП рдбреЗрдЯрд╛рдмреЗрд╕ рдЗрддрдиреА рдореЗрдореЛрд░реА рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рддрд╛ рд╣реИред рд╣рдордиреЗ рддрдп рдХрд┐рдпрд╛: рд╣рдо рдЬрд▓реНрджреА рдирд╣реАрдВ рдЧрдП, рдФрд░ рдкреИрд░рд╛рдореАрдЯрд░ рдореЗрдВ рд╡реГрджреНрдзрд┐ рдирд╣реАрдВ рдХреА рдФрд░ рднрдВрдбрд╛рд░рдг рдХрд╛ рд╡рд┐рд╕реНрддрд╛рд░ рдХрд┐рдпрд╛ред рдЫрдВрдЯрд╛рдИ рдХреЗ рд▓рд┐рдП рдореЗрдореЛрд░реА рдХреЛ рдЯреНрд░рд┐рдо рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рджреВрд╕рд░реЗ рддрд░реАрдХреЗ рдХреА рддрд▓рд╛рд╢ рдХрд░рдирд╛ рдмреЗрд╣рддрд░ рд╣реИред


рдЖрд░реНрдерд┐рдХ рдЫрдБрдЯрд╛рдИ


"рдХрд┐рддрдиреА рдЫрдБрдЯрд╛рдИ рдЦрд╛рдПрдЧрд╛ рдбреЗрдЯрд╛ рд╕реЗрдЯ рдХреЗ рдЖрдХрд╛рд░ рдФрд░ рд╕реЙрд░реНрдЯ рдХреБрдВрдЬреА рдкрд░ рдирд┐рд░реНрднрд░ рдХрд░рддрд╛ рд╣реИред рдЖрдк рдбреЗрдЯрд╛ рд╕реЗрдЯ рдХреЛ рдХрдо рдирд╣реАрдВ рдХрд░ рд╕рдХрддреЗ, рд▓реЗрдХрд┐рди рдХреБрдВрдЬреА рдХрд╛ рдЖрдХрд╛рд░ рд╕рдВрднрд╡ рд╣реИ ред


рд╕рдВрджрд░реНрдн рдмрд┐рдВрджреБ рдХреЗ рд▓рд┐рдП, рд╣рдо рд╕реЙрд░реНрдЯ рдХреБрдВрдЬреА рдХрд╛ рдФрд╕рдд рдЖрдХрд╛рд░ рд▓реЗрддреЗ рд╣реИрдВ:


  avg ---------- 780 

рдкреНрд░рддреНрдпреЗрдХ рдХреБрдВрдЬреА рдХрд╛ рд╡рдЬрди 780 рд╣реИред рджреНрд╡рд┐рдЖрдзрд╛рд░реА рдХреБрдВрдЬреА рдХреЛ рдХрдо рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП, рдЗрд╕реЗ рд╣реИрд╢ рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИред PostgreSQL рдореЗрдВ рдЗрд╕рдХреЗ рд▓рд┐рдП md5 рд╣реИ (рд╣рд╛рдБ, рд╕реБрд░рдХреНрд╖рд╛ рдирд╣реАрдВ, рд▓реЗрдХрд┐рди рд╣рдорд╛рд░реЗ рдЙрджреНрджреЗрд╢реНрдп рдХреЗ рд▓рд┐рдП рдпрд╣ рдХрд░реЗрдЧрд╛)ред рдЖрдЗрдП рджреЗрдЦреЗрдВ рдХрд┐ md5 рдХреЗ рд╡рдЬрди рдХреЗ рд╕рд╛рде BLOB рд╣реИрд╢реЗрдб рдХрд┐рддрдирд╛ рд╣реИ:


  avg ----------- 36 

Md5 рдХреЗ рдорд╛рдзреНрдпрдо рд╕реЗ рдХреБрдВрдЬреА рд╣реИрд╢реЗрдб рдХрд╛ рдЖрдХрд╛рд░ 36 рдмрд╛рдЗрдЯреНрд╕ рд╣реИред рдПрдХ рд╣реИрд╢реЗрдб рдХреБрдВрдЬреА рдХрд╛ рдореВрд▓ рд╡рд┐рдХрд▓реНрдк рдХреЗрд╡рд▓ 4% рд╣реЛрддрд╛ рд╣реИ ред


рдЕрдЧрд▓рд╛, рд╣рдордиреЗ рд╣реИрд╢ рдХреА рдХреЗ рд╕рд╛рде рдореВрд▓ рдЕрдиреБрд░реЛрдз рд▓реЙрдиреНрдЪ рдХрд┐рдпрд╛:


  id, MIN(id) OVER ( PARTITION BY md5(array_to_string(blob, '') ) ORDER BY id) FROM dumps; 

рдФрд░ рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди рдпреЛрдЬрдирд╛:


  Buffers: shared hit=3916 -> Sort (cost=7490.74..7588.64 rows=39160 width=36) (actual time=349.383..353.045 rows=39160) Sort Key: (md5(array_to_string(blob, ''::text))), id Sort Method: quicksort Memory: 4005kB Buffers: shared hit=3916 -> Seq Scan on dumps (cost=0..4503.40 rows=39160 width=36) (actual time=0.055..292.070 rows=39160) Buffers: shared hit=3916 Execution time: 374.125 ms 

рд╣реИрд╢реЗрдб рдХреБрдВрдЬреА рдХреЗ рд╕рд╛рде, рдЕрдиреБрд░реЛрдз рдХреЗрд╡рд▓ 4 рдЕрддрд┐рд░рд┐рдХреНрдд рдореЗрдЧрд╛рдмрд╛рдЗрдЯ рдХрд╛ рдЙрдкрднреЛрдЧ рдХрд░рддрд╛ рд╣реИ, рдЕрд░реНрдерд╛рдд рдкрд┐рдЫрд▓реЗ 30 рдПрдордмреА рдХреЗ 10% рд╕реЗ рдереЛрдбрд╝рд╛ рдЕрдзрд┐рдХ рд╣реИред рддреЛ рд╕реЙрд░реНрдЯ рдХреБрдВрдЬреА рдХрд╛ рдЖрдХрд╛рд░ рдмрд╣реБрдд рд╕реНрдореГрддрд┐ рдХреЛ рдкреНрд░рднрд╛рд╡рд┐рдд рдХрд░рддрд╛ рд╣реИ рдХрд┐ рд╕реЙрд░реНрдЯ рдХрд┐рддрдирд╛ рдЦрд╛рддреА рд╣реИ ред


рдЖрдЧреЗ рдФрд░ рднреА


рдЗрд╕ рдЙрджрд╛рд╣рд░рдг рдореЗрдВ, рд╣рдордиреЗ md5 рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рддреЗ рд╣реБрдП BLOB рдХреЛ md5 ред MD5 рдХреЗ рд╕рд╛рде рдмрдирд╛рдИ рдЧрдИ рд╣реИрд╢ рдХрд╛ рд╡рдЬрди 16 рдмрд╛рдЗрдЯ рд╣реЛрдирд╛ рдЪрд╛рд╣рд┐рдПред рдФрд░ рд╣рдо рдФрд░ рдЕрдзрд┐рдХ:


 md5_size ------------- 32 

рд╣рдорд╛рд░рд╛ рд╣реИрд╢ рдмрд┐рд▓реНрдХреБрд▓ рджреБрдЧрдирд╛ рдерд╛, рдХреНрдпреЛрдВрдХрд┐ md5 рд╣реЗрдХреНрд╕рд╛рдбреЗрд╕рд┐рдорд▓ рдкрд╛рда рдХреЗ рд░реВрдк рдореЗрдВ рдПрдХ рд╣реИрд╢ рдХрд╛ рдЙрддреНрдкрд╛рджрди рдХрд░рддрд╛ рд╣реИред


PostgreSQL рдореЗрдВ, рдЖрдк pgcrypto рдПрдХреНрд╕рдЯреЗрдВрд╢рди рдХреЗ рд╕рд╛рде рд╣реИрд╢рд┐рдВрдЧ рдХреЗ рд▓рд┐рдП MD5 рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВред pgcrypto рдкреНрд░рдХрд╛рд░ рдХреЗ bytea MD5 (рдмрд╛рдЗрдирд░реА рдореЗрдВ) рдмрдирд╛рддрд╛ рд╣реИ:


 select pg_column_size( digest('foo', 'md5') ) as crypto_md5_size crypto_md5_size --------------- 20 

рд╣реИрд╢ рдЕрднреА рднреА 4 рдмрд╛рдЗрдЯреНрд╕ рдХреА рддреБрд▓рдирд╛ рдореЗрдВ рдЕрдзрд┐рдХ рд╣реЛрдирд╛ рдЪрд╛рд╣рд┐рдПред рдпрд╣ рд╕рд┐рд░реНрдл рдЗрддрдирд╛ рд╣реИ рдХрд┐ рдореВрд▓реНрдп рдХреА рд▓рдВрдмрд╛рдИ рдХреЛ рд╕рдВрдЧреНрд░рд╣реАрдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП bytea рдкреНрд░рдХрд╛рд░ рдЗрди 4 рдмрд╛рдЗрдЯреНрд╕ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рддрд╛ рд╣реИ, рд▓реЗрдХрд┐рди рд╣рдордиреЗ рдЗрд╕реЗ рдЗрд╕ рддрд░рд╣ рдирд╣реАрдВ рдЫреЛрдбрд╝рд╛ред


рдпрд╣ рдкрддрд╛ рдЪрд▓рд╛ рд╣реИ рдХрд┐ PostgreSQL рдореЗрдВ uuid рдкреНрд░рдХрд╛рд░ рдХрд╛ рд╡рдЬрди рд▓рдЧрднрдЧ 16 рдмрд╛рдЗрдЯреНрд╕ рд╣реЛрддрд╛ рд╣реИ рдФрд░ рдХрд┐рд╕реА рднреА рдордирдорд╛рдиреЗ рдореВрд▓реНрдп рдХрд╛ рд╕рдорд░реНрдерди рдХрд░рддрд╛ рд╣реИ, рдЗрд╕рд▓рд┐рдП рд╣рдо рд╢реЗрд╖ рдЪрд╛рд░ рдмрд╛рдЗрдЯреНрд╕ рд╕реЗ рдЫреБрдЯрдХрд╛рд░рд╛ рдкрд╛ рд▓реЗрддреЗ рд╣реИрдВ:


 uuid_size --------------- 16 

рд╡рд╣ рд╕рдм рд╣реИред Md5 рдХреЗ рд╕рд╛рде 32 рдмрд╛рдЗрдЯреНрд╕ uuid рд╕рд╛рде 16 рдореЗрдВ рдмрджрд▓ рдЬрд╛рддреЗ рд╣реИрдВред


рдореИрдВрдиреЗ рдПрдХ рдмрдбрд╝рд╛ рдбреЗрдЯрд╛рд╕реЗрдЯ рд▓реЗрдХрд░ рдкрд░рд┐рд╡рд░реНрддрди рдХреЗ рдкреНрд░рднрд╛рд╡реЛрдВ рдХреА рдЬрд╛рдБрдЪ рдХреАред рдбреЗрдЯрд╛ рд╕реНрд╡рдпрдВ рдирд╣реАрдВ рджрд┐рдЦрд╛рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИ, рд▓реЗрдХрд┐рди рдореИрдВ рдкрд░рд┐рдгрд╛рдо рд╕рд╛рдЭрд╛ рдХрд░реВрдВрдЧрд╛:



рдЬреИрд╕рд╛ рдХрд┐ рдЖрдк рддрд╛рд▓рд┐рдХрд╛ рд╕реЗ рджреЗрдЦ рд╕рдХрддреЗ рд╣реИрдВ, рдореВрд▓ рд╕рдорд╕реНрдпрд╛рдЧреНрд░рд╕реНрдд рдЕрдиреБрд░реЛрдз рдХрд╛ рд╡рдЬрди 300 рдПрдордмреА (рдФрд░ рд░рд╛рдд рдХреЗ рдордзреНрдп рдореЗрдВ рд╣рдореЗрдВ рдЙрдард╛рддрд╛ рд╣реИ)ред uuid рдХреБрдВрдЬреА рдХреЗ рд╕рд╛рде, рдЫрдБрдЯрд╛рдИ рдХреЗрд╡рд▓ 7 рдПрдордмреА рдХреА рд╣реБрдИред


рдЕрдиреБрд╡рд░реНрддреА рд╡рд┐рдЪрд╛рд░


рдПрдХ рд╣реИрд╢реЗрдб рдореЗрдореЛрд░реА рдЫрдБрдЯрд╛рдИ рдХреБрдВрдЬреА рдХреЗ рд╕рд╛рде рдПрдХ рдЕрдиреБрд░реЛрдз рдХрдо рдЦрдкрдд рдХрд░рддрд╛ рд╣реИ, рд▓реЗрдХрд┐рди рдпрд╣ рдмрд╣реБрдд рдзреАрдореА рдЧрддрд┐ рд╕реЗ рдХрд╛рдо рдХрд░рддрд╛ рд╣реИ:



рд╣реИрд╢рд┐рдВрдЧ рдЕрдзрд┐рдХ рд╕реАрдкреАрдпреВ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рддрд╛ рд╣реИ, рдЗрд╕рд▓рд┐рдП рд╣реИрд╢ рдХреЗ рд╕рд╛рде рдПрдХ рдЕрдиреБрд░реЛрдз рдзреАрдорд╛ рд╣реИред рд▓реЗрдХрд┐рди рд╣рдордиреЗ рдбрд┐рд╕реНрдХ рд╕реНрдерд╛рди рдХреЗ рд╕рд╛рде рд╕рдорд╕реНрдпрд╛ рдХреЛ рд╣рд▓ рдХрд░рдиреЗ рдХреА рдХреЛрд╢рд┐рд╢ рдХреА, рдЗрд╕рдХреЗ рдЕрд▓рд╛рд╡рд╛, рд░рд╛рдд рдореЗрдВ рдХрд╛рд░реНрдп рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ, рдЗрд╕рд▓рд┐рдП рд╕рдордп рдХреЛрдИ рд╕рдорд╕реНрдпрд╛ рдирд╣реАрдВ рд╣реИред рд╣рдордиреЗ рд╕реНрдореГрддрд┐ рдХреЛ рдмрдЪрд╛рдиреЗ рдХреЗ рд▓рд┐рдП рд╕рдордЭреМрддрд╛ рдХрд┐рдпрд╛ред


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

Source: https://habr.com/ru/post/hi437730/


All Articles