{"id":273304,"date":"2016-02-01T10:18:02","date_gmt":"2016-02-01T07:18:02","guid":{"rendered":"http:\/\/savepearlharbor.com\/?p=273304"},"modified":"-0001-11-30T00:00:00","modified_gmt":"-0001-11-29T21:00:00","slug":"","status":"publish","type":"post","link":"https:\/\/savepearlharbor.com\/?p=273304","title":{"rendered":"C\u0442\u0430\u0442\u0438\u0441\u0442\u0438\u0447\u0435\u0441\u043a\u0438\u0439 \u0430\u043d\u0430\u043b\u0438\u0437 \u0432 PostgreSQL \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e PL\/R"},"content":{"rendered":"<p>       <i>\u0414\u0440\u0443\u0437\u044c\u044f, \u043d\u0430 \u043f\u0440\u043e\u0448\u0435\u0434\u0448\u0435\u0439 \u0432 \u043f\u0440\u043e\u0448\u043b\u043e\u043c \u0433\u043e\u0434\u0443 \u043a\u043e\u043d\u0444\u0435\u0440\u0435\u043d\u0446\u0438\u0438 <a href=\"http:\/\/pgday.ru\/ru\/2015\">PG Day&#8217;15 Russia<\/a> \u043e\u0434\u0438\u043d \u0438\u0437 \u043d\u0430\u0448\u0438\u0445 \u0434\u043e\u043a\u043b\u0430\u0434\u0447\u0438\u043a\u043e\u0432, Joseph Conway, \u043f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u0438\u043b \u0438\u043d\u0442\u0435\u0440\u0435\u0441\u043d\u044b\u0439 \u043c\u0430\u0442\u0435\u0440\u0438\u0430\u043b \u043e\u0431 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u0438 \u0441\u043e\u0437\u0434\u0430\u043d\u043d\u043e\u0433\u043e \u0438 \u043f\u043e\u0434\u0434\u0435\u0440\u0436\u0438\u0432\u0430\u0435\u043c\u043e\u0433\u043e \u0438\u043c \u0443\u0436\u0435 \u0431\u043e\u043b\u044c\u0448\u0435 \u0434\u0435\u0441\u044f\u0442\u0438 \u043b\u0435\u0442 \u0440\u0430\u0441\u0448\u0438\u0440\u0435\u043d\u0438\u044f PL\/R, \u043a\u043e\u0442\u043e\u0440\u043e\u0435 \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u0435\u0442 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u044f\u0437\u044b\u043a \u0434\u043b\u044f \u0441\u0442\u0430\u0442\u0438\u0441\u0442\u0438\u0447\u0435\u0441\u043a\u043e\u0433\u043e \u0430\u043d\u0430\u043b\u0438\u0437\u0430 R \u0432\u043d\u0443\u0442\u0440\u0438 \u0432\u0441\u0435\u043c\u0438 \u043b\u044e\u0431\u0438\u043c\u043e\u0439 \u0431\u0430\u0437\u044b \u0434\u0430\u043d\u043d\u044b\u0445. \u0425\u043e\u0447\u0443 \u043f\u0440\u0435\u0434\u043b\u043e\u0436\u0438\u0442\u044c \u0432\u0430\u0448\u0435\u043c\u0443 \u0432\u043d\u0438\u043c\u0430\u043d\u0438\u044e follow-up \u0441\u0442\u0430\u0442\u044c\u044e, \u0441\u043e\u0437\u0434\u0430\u043d\u043d\u0443\u044e \u043d\u0430 \u043e\u0441\u043d\u043e\u0432\u0435 \u043c\u0430\u0442\u0435\u0440\u0438\u0430\u043b\u043e\u0432, \u043f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u043b\u0435\u043d\u043d\u044b\u0445 <a href=\"http:\/\/pgday.ru\/ru\/2015\/papers\/25\">\u0432 \u0434\u043e\u043a\u043b\u0430\u0434\u0435 Joe<\/a>. \u0417\u0430\u0434\u0430\u0447\u0430 \u0434\u0430\u043d\u043d\u043e\u0439 \u043f\u0443\u0431\u043b\u0438\u043a\u0430\u0446\u0438\u0438 \u2014 \u043e\u0431\u0437\u043e\u0440\u043d\u043e \u043f\u043e\u0437\u043d\u0430\u043a\u043e\u043c\u0438\u0442\u044c \u0432\u0430\u0441 \u0441 \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u044f\u043c\u0438 \u044f\u0437\u044b\u043a\u0430 PL\/R. \u041d\u0430\u0434\u0435\u044e\u0441\u044c, \u0447\u0442\u043e \u0432\u044b \u043d\u0430\u0439\u0434\u0435\u0442\u0435 \u043f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u043b\u0435\u043d\u043d\u0443\u044e \u0437\u0434\u0435\u0441\u044c \u0438\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0438\u044e \u043f\u043e\u043b\u0435\u0437\u043d\u043e\u0439 \u0434\u043b\u044f \u0441\u0435\u0431\u044f.<\/i><\/p>\n<p>  <img decoding=\"async\" src=\"https:\/\/habrastorage.org\/files\/d7f\/c27\/2b9\/d7fc272b9c95473abe52ffef4143dc2f.png\" alt=\"image\"\/><\/p>\n<p>  \u041f\u043e\u0441\u043b\u0435\u0434\u043d\u0438\u0435 \u0442\u0435\u043d\u0434\u0435\u043d\u0446\u0438\u0438 \u0432 \u043e\u0431\u043b\u0430\u0441\u0442\u0438 Big Data \u043f\u043e\u043e\u0449\u0440\u044f\u044e\u0442 \u0441\u0431\u043b\u0438\u0436\u0435\u043d\u0438\u0435 \u0430\u043d\u0430\u043b\u0438\u0442\u0438\u043a\u0438 \u0438 \u0434\u0430\u043d\u043d\u044b\u0445, \u0432 \u0442\u043e \u0432\u0440\u0435\u043c\u044f \u043a\u0430\u043a PL\/R \u043d\u0435\u043d\u0430\u0432\u044f\u0437\u0447\u0438\u0432\u043e \u043f\u0440\u0435\u0434\u043e\u0441\u0442\u0430\u0432\u043b\u044f\u0435\u0442 \u0442\u0430\u043a\u043e\u0439 \u0441\u0435\u0440\u0432\u0438\u0441 \u0432\u043e\u0442 \u0443\u0436\u0435 12 \u043b\u0435\u0442! \u0415\u0441\u043b\u0438 \u0432\u0434\u0440\u0443\u0433 \u0432\u044b \u043d\u0435 \u0432 \u043a\u0443\u0440\u0441\u0435, PL\/R \u2013 \u044d\u0442\u043e \u0440\u0430\u0441\u0448\u0438\u0440\u0435\u043d\u0438\u0435 \u0434\u043b\u044f PostgreSQL, \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u044e\u0449\u0435\u0435 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c R, \u044f\u0437\u044b\u043a \u0434\u043b\u044f \u043c\u0430\u0442\u0435\u043c\u0430\u0442\u0438\u0447\u0435\u0441\u043a\u0438\u0445 \u0440\u0430\u0441\u0447\u0435\u0442\u043e\u0432, \u043f\u0440\u044f\u043c\u043e \u0438\u0437 PostgreSQL \u0434\u043b\u044f \u0442\u043e\u0433\u043e, \u0447\u0442\u043e\u0431\u044b \u043b\u0435\u0433\u043a\u043e \u0438 \u043f\u0440\u043e\u0441\u0442\u043e \u043f\u043e\u043b\u0443\u0447\u0430\u0442\u044c \u0440\u0430\u0437\u0432\u0435\u0440\u043d\u0443\u0442\u0443\u044e \u0430\u043d\u0430\u043b\u0438\u0442\u0438\u043a\u0443. \u0420\u0430\u0441\u0448\u0438\u0440\u0435\u043d\u0438\u0435 \u0434\u043e\u0441\u0442\u0443\u043f\u043d\u043e \u0438 \u0430\u043a\u0442\u0438\u0432\u043d\u043e \u0441\u043e\u0432\u0435\u0440\u0448\u0435\u043d\u0441\u0442\u0432\u0443\u0435\u0442\u0441\u044f \u0441 2003 \u0433\u043e\u0434\u0430. \u041e\u043d\u043e \u0440\u0430\u0431\u043e\u0442\u0430\u0435\u0442 \u0441\u043e \u0432\u0441\u0435\u043c\u0438 \u043f\u043e\u0434\u0434\u0435\u0440\u0436\u0438\u0432\u0430\u0435\u043c\u044b\u043c\u0438 \u0432\u0435\u0440\u0441\u0438\u044f\u043c\u0438 PostgreSQL \u0438 \u0441\u043e \u0432\u0441\u0435\u043c\u0438 \u0441\u0432\u0435\u0436\u0438\u043c\u0438 \u0432\u0435\u0440\u0441\u0438\u044f\u043c\u0438 R. \u0422\u044b\u0441\u044f\u0447\u0438 \u043b\u044e\u0434\u0435\u0439 \u0432\u043e \u0432\u0441\u0435\u043c \u043c\u0438\u0440\u0435 \u0443\u0436\u0435 \u043e\u0446\u0435\u043d\u0438\u043b\u0438 \u0435\u0433\u043e \u0443\u0434\u043e\u0431\u0441\u0442\u0432\u043e \u0438 \u044d\u0444\u0444\u0435\u043a\u0442\u0438\u0432\u043d\u043e\u0441\u0442\u044c. \u0414\u0430\u0432\u0430\u0439\u0442\u0435 \u0436\u0435 \u0440\u0430\u0437\u0431\u0435\u0440\u0435\u043c\u0441\u044f, \u0447\u0442\u043e \u0442\u0430\u043a\u043e\u0435 PL\/R, \u043e\u0431\u0441\u0443\u0434\u0438\u043c \u0434\u043e\u0441\u0442\u043e\u0438\u043d\u0441\u0442\u0432\u0430 \u0438 \u043d\u0435\u0434\u043e\u0441\u0442\u0430\u0442\u043a\u0438 \u0442\u0430\u043a\u043e\u0433\u043e \u043f\u043e\u0434\u0445\u043e\u0434\u0430 \u043a \u0430\u043d\u0430\u043b\u0438\u0437\u0443 \u0434\u0430\u043d\u043d\u044b\u0445 \u0438 \u0440\u0430\u0441\u0441\u043c\u043e\u0442\u0440\u0438\u043c \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u043e \u043f\u0440\u0438\u043c\u0435\u0440\u043e\u0432 \u0434\u043b\u044f \u043d\u0430\u0433\u043b\u044f\u0434\u043d\u043e\u0441\u0442\u0438.<br \/>  <a name=\"habracut\"><\/a><br \/>  \u0414\u043b\u044f \u043d\u0430\u0447\u0430\u043b\u0430 \u0434\u0430\u0434\u0438\u043c \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0435\u043d\u0438\u044f \u0431\u0430\u0437\u043e\u0432\u044b\u043c \u043f\u043e\u043d\u044f\u0442\u0438\u044f\u043c. R \u2013 \u044d\u0442\u043e \u044f\u0437\u044b\u043a \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f \u0434\u043b\u044f \u0441\u0442\u0430\u0442\u0438\u0441\u0442\u0438\u0447\u0435\u0441\u043a\u043e\u0439 \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0438 \u0434\u0430\u043d\u043d\u044b\u0445 \u0438 \u0440\u0430\u0431\u043e\u0442\u044b \u0441 \u0433\u0440\u0430\u0444\u0438\u043a\u043e\u0439, \u0430 \u0442\u0430\u043a\u0436\u0435 \u0441\u0432\u043e\u0431\u043e\u0434\u043d\u0430\u044f \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u043d\u0430\u044f \u0441\u0440\u0435\u0434\u0430 \u0432\u044b\u0447\u0438\u0441\u043b\u0435\u043d\u0438\u0439 \u0441 \u043e\u0442\u043a\u0440\u044b\u0442\u044b\u043c \u0438\u0441\u0445\u043e\u0434\u043d\u044b\u043c \u043a\u043e\u0434\u043e\u043c. \u0410 PostgreSQL \u2013 \u044d\u0442\u043e \u043c\u043e\u0449\u043d\u0430\u044f \u0441\u0432\u043e\u0431\u043e\u0434\u043d\u0430\u044f \u043e\u0431\u044a\u0435\u043a\u0442\u043d\u043e-\u0440\u0435\u043b\u044f\u0446\u0438\u043e\u043d\u043d\u0430\u044f \u0441\u0438\u0441\u0442\u0435\u043c\u0430 \u0443\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u0438\u044f \u0431\u0430\u0437\u0430\u043c\u0438 \u0434\u0430\u043d\u043d\u044b\u0445, \u043a\u043e\u0442\u043e\u0440\u0430\u044f \u0430\u043a\u0442\u0438\u0432\u043d\u043e \u0440\u0430\u0437\u0440\u0430\u0431\u0430\u0442\u044b\u0432\u0430\u0435\u0442\u0441\u044f \u0432\u043e\u0442 \u0443\u0436\u0435 \u0431\u043e\u043b\u0435\u0435 25 \u043b\u0435\u0442 \u0438 \u0437\u0430\u0440\u0430\u0431\u043e\u0442\u0430\u043b\u0430 \u043e\u0442\u043b\u0438\u0447\u043d\u0443\u044e \u0440\u0435\u043f\u0443\u0442\u0430\u0446\u0438\u044e \u0431\u043b\u0430\u0433\u043e\u0434\u0430\u0440\u044f \u0441\u0432\u043e\u0435\u0439 \u043d\u0430\u0434\u0435\u0436\u043d\u043e\u0441\u0442\u0438, \u0430 \u0442\u0430\u043a\u0436\u0435 \u043a\u043e\u0440\u0440\u0435\u043a\u0442\u043d\u043e\u0441\u0442\u0438 \u0438 \u0446\u0435\u043b\u043e\u0441\u0442\u043d\u043e\u0441\u0442\u0438 \u0434\u0430\u043d\u043d\u044b\u0445. \u0418, \u043d\u0430\u043a\u043e\u043d\u0435\u0446, PL\/R. \u041a\u0430\u043a \u0443\u0436\u0435 \u0431\u044b\u043b\u043e \u0441\u043a\u0430\u0437\u0430\u043d\u043e \u0432\u044b\u0448\u0435, \u044d\u0442\u043e \u043f\u0440\u043e\u0446\u0435\u0434\u0443\u0440\u043d\u044b\u0439 \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u0447\u0438\u043a \u044f\u0437\u044b\u043a\u0430 R \u0434\u043b\u044f PostgreSQL, \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u044e\u0449\u0438\u0439 \u043f\u0438\u0441\u0430\u0442\u044c SQL-\u0444\u0443\u043d\u043a\u0446\u0438\u0438 \u043d\u0430 R.<\/p>\n<p>  \u0418\u0442\u0430\u043a, \u0432 \u0447\u0435\u043c \u0436\u0435 \u043f\u0440\u0435\u0438\u043c\u0443\u0449\u0435\u0441\u0442\u0432\u0430 PL\/R? \u0412\u043e-\u043f\u0435\u0440\u0432\u044b\u0445, PL\/R \u0441\u043f\u043e\u0441\u043e\u0431\u0441\u0442\u0432\u0443\u0435\u0442 \u0440\u0430\u0437\u0432\u0438\u0442\u0438\u044e \u0447\u0435\u043b\u043e\u0432\u0435\u0447\u0435\u0441\u043a\u0438\u0445 \u0437\u043d\u0430\u043d\u0438\u0439 \u0438 \u043d\u0430\u0432\u044b\u043a\u043e\u0432, \u0442\u0430\u043a \u043a\u0430\u043a \u043c\u0430\u0442\u0435\u043c\u0430\u0442\u0438\u043a\u0430, \u0441\u0442\u0430\u0442\u0438\u0441\u0442\u0438\u043a\u0430, \u0431\u0430\u0437\u044b \u0434\u0430\u043d\u043d\u044b\u0445 \u0438 \u0432\u0435\u0431 \u2013 \u044d\u0442\u043e \u0440\u0430\u0437\u043d\u044b\u0435 \u0441\u043f\u0435\u0446\u0438\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0438, \u043d\u043e \u0432\u0441\u0435 \u0438\u0445 \u043f\u0440\u0438\u0434\u0451\u0442\u0441\u044f \u0432 \u0442\u043e\u0439 \u0438\u043b\u0438 \u0438\u043d\u043e\u0439 \u043c\u0435\u0440\u0435 \u043e\u0441\u0432\u043e\u0438\u0442\u044c \u0434\u043b\u044f \u0440\u0430\u0431\u043e\u0442\u044b \u0441 PL\/R. \u0412\u043e-\u0432\u0442\u043e\u0440\u044b\u0445, \u044d\u0442\u043e \u0440\u0430\u0441\u0448\u0438\u0440\u0435\u043d\u0438\u0435 \u0441\u0442\u0438\u043c\u0443\u043b\u0438\u0440\u0443\u0435\u0442 \u0443\u043b\u0443\u0447\u0448\u0435\u043d\u0438\u0435 \u201c\u0436\u0435\u043b\u0435\u0437\u0430\u201d, \u043f\u043e\u0441\u043a\u043e\u043b\u044c\u043a\u0443 \u0432\u0430\u043c \u043f\u043e\u0442\u0440\u0435\u0431\u0443\u0435\u0442\u0441\u044f \u0441\u0435\u0440\u0432\u0435\u0440, \u0441\u043f\u043e\u0441\u043e\u0431\u043d\u044b\u0439 \u0432\u044b\u0434\u0435\u0440\u0436\u0430\u0442\u044c \u0430\u043d\u0430\u043b\u0438\u0437 \u0431\u043e\u043b\u044c\u0448\u0438\u0445 \u043d\u0430\u0431\u043e\u0440\u043e\u0432 \u0434\u0430\u043d\u043d\u044b\u0445. \u0412-\u0442\u0440\u0435\u0442\u044c\u0438\u0445, \u0432\u044b\u0440\u0430\u0441\u0442\u0435\u0442 \u044d\u0444\u0444\u0435\u043a\u0442\u0438\u0432\u043d\u043e\u0441\u0442\u044c \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0438, \u0442\u0430\u043a \u043a\u0430\u043a \u0432\u0430\u043c \u0431\u043e\u043b\u044c\u0448\u0435 \u043d\u0435 \u043f\u0440\u0438\u0434\u0435\u0442\u0441\u044f \u043f\u0435\u0440\u0435\u0434\u0430\u0432\u0430\u0442\u044c \u0431\u043e\u043b\u044c\u0448\u0438\u0435 \u043d\u0430\u0431\u043e\u0440\u044b \u0434\u0430\u043d\u043d\u044b\u0445 \u0447\u0435\u0440\u0435\u0437 \u0432\u0441\u044e \u0441\u0435\u0442\u044c, \u0438 \u043f\u0440\u043e\u043f\u0443\u0441\u043a\u043d\u0430\u044f \u0441\u043f\u043e\u0441\u043e\u0431\u043d\u043e\u0441\u0442\u044c \u0443\u0432\u0435\u043b\u0438\u0447\u0438\u0442\u0441\u044f. \u0412-\u0447\u0435\u0442\u0432\u0435\u0440\u0442\u044b\u0445, \u0432\u044b \u043c\u043e\u0436\u0435\u0442\u0435 \u0431\u044b\u0442\u044c \u0443\u0432\u0435\u0440\u0435\u043d\u044b, \u0447\u0442\u043e \u0430\u043d\u0430\u043b\u0438\u0437 \u0431\u0443\u0434\u0435\u0442 \u043f\u0440\u043e\u0432\u043e\u0434\u0438\u0442\u044c\u0441\u044f \u043f\u043e\u0441\u043b\u0435\u0434\u043e\u0432\u0430\u0442\u0435\u043b\u044c\u043d\u043e. \u0412-\u043f\u044f\u0442\u044b\u0445, PL\/R \u0434\u0435\u043b\u0430\u0435\u0442 \u0441\u0438\u0441\u0442\u0435\u043c\u0443 \u043b\u044e\u0431\u043e\u0439 \u0441\u043b\u043e\u0436\u043d\u043e\u0441\u0442\u0438 \u043f\u043e\u043d\u044f\u0442\u043d\u043e\u0439 \u0438 \u043f\u043e\u0434\u0434\u0435\u0440\u0436\u0438\u0432\u0430\u0435\u043c\u043e\u0439. \u0418, \u043d\u0430\u043a\u043e\u043d\u0435\u0446, \u0431\u043b\u0430\u0433\u043e\u0434\u0430\u0440\u044f \u0431\u043e\u0433\u0430\u0442\u043e\u0439 \u0444\u0443\u043d\u043a\u0446\u0438\u043e\u043d\u0430\u043b\u044c\u043d\u043e\u0441\u0442\u0438 \u0438 \u043e\u0433\u0440\u043e\u043c\u043d\u043e\u0439 \u044d\u043a\u043e\u0441\u0438\u0441\u0442\u0435\u043c\u0435 PL\/R \u0440\u0430\u0441\u0448\u0438\u0440\u044f\u0435\u0442 \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u0438 R.<\/p>\n<p>  \u041d\u043e, \u043a\u043e\u043d\u0435\u0447\u043d\u043e \u0436\u0435, \u0435\u0441\u0442\u044c \u0438 \u043c\u0438\u043d\u0443\u0441\u044b. \u041f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044e PostgreSQL \u0441\u043a\u043e\u0440\u0435\u0435 \u0432\u0441\u0435\u0433\u043e \u043f\u043e\u043a\u0430\u0436\u0435\u0442\u0441\u044f, \u0447\u0442\u043e PL\/R \u0440\u0430\u0431\u043e\u0442\u0430\u0435\u0442 \u043c\u0435\u0434\u043b\u0435\u043d\u043d\u0435\u0435, \u043e\u0441\u043e\u0431\u0435\u043d\u043d\u043e \u043d\u0430 \u043f\u0440\u043e\u0441\u0442\u044b\u0445 \u0437\u0430\u0434\u0430\u0447\u0430\u0445. \u0410 \u0434\u043b\u044f \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u0438\u0441\u0442\u0430 \u043d\u0430 R \u0443\u0441\u043b\u043e\u0436\u043d\u0438\u0442\u0441\u044f \u043f\u0440\u043e\u0446\u0435\u0441\u0441 \u043e\u0442\u043b\u0430\u0434\u043a\u0438 \u0438 \u0430\u043d\u0430\u043b\u0438\u0437 \u0441\u0442\u0430\u043d\u0435\u0442 \u043c\u0435\u043d\u0435\u0435 \u0433\u0438\u0431\u043a\u0438\u043c. \u041a\u0440\u043e\u043c\u0435 \u0442\u043e\u0433\u043e, \u043e\u0431\u043e\u0438\u043c \u043f\u0440\u0438\u0434\u0451\u0442\u0441\u044f \u0443\u0447\u0438\u0442\u044c \u043d\u043e\u0432\u044b\u0439 \u044f\u0437\u044b\u043a.<\/p>\n<p>  \u041f\u0440\u0438\u043c\u0435\u0440\u043d\u043e \u0432\u043e\u0442 \u0442\u0430\u043a \u0432\u044b\u0433\u043b\u044f\u0434\u0438\u0442 \u0441\u0442\u0430\u043d\u0434\u0430\u0440\u0442\u043d\u0430\u044f \u0444\u0443\u043d\u043a\u0446\u0438\u044f \u0432 R:<\/p>\n<pre><code>func_name &lt;- function(myarg1 [,myarg2...]) {     function body referencing myarg1 [, myarg2 ...] } <\/code><\/pre>\n<p>  \u0421\u043e\u0437\u0434\u0430\u043d\u0438\u0435 \u0444\u0443\u043d\u043a\u0446\u0438\u0439 \u0432 PL\/R \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u043e \u043e\u0442\u043b\u0438\u0447\u0430\u0435\u0442\u0441\u044f, \u043d\u043e \u0441\u0445\u043e\u0436\u0435 \u0441 \u0434\u0440\u0443\u0433\u0438\u043c\u0438 PL \u0432 PostgreSQL:<\/p>\n<pre><code class=\"sql\">CREATE OR REPLACE FUNCTION func_name(arg-type1 [, arg-type2 ...])     RETURNS return-type AS $$     function body referencing arg1 [, arg2 ...] $$ LANGUAGE 'plr';  CREATE OR REPLACE FUNCTION func_name(myarg1 arg-type1 [, myarg2 arg-type2 ...])     RETURNS return-type AS $$     function body referencing myarg1 [, myarg2 ...] $$ LANGUAGE 'plr'; <\/code><\/pre>\n<p>  \u041f\u0440\u0438\u0432\u0435\u0434\u0435\u043c \u043f\u0440\u0438\u043c\u0435\u0440:<\/p>\n<pre><code class=\"sql\">CREATE EXTENSION plr;  CREATE OR REPLACE FUNCTION test_dtup(OUT f1 text, OUT f2 int) RETURNS SETOF record AS $$     data.frame(letters[1:3],1:3) $$ LANGUAGE 'plr';  SELECT * FROM test_dtup();  f1 | f2 ----+---- a | 1 b | 2 c | 3 (3 rows) <\/code><\/pre>\n<p>  \u0421\u043b\u043e\u0436\u043d\u043e \u043f\u0435\u0440\u0435\u0447\u0438\u0441\u043b\u0438\u0442\u044c \u0432\u0441\u0451, \u0447\u0442\u043e \u043c\u043e\u0436\u043d\u043e \u0434\u0435\u043b\u0430\u0442\u044c \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e PL\/R, \u043d\u043e \u0434\u0430\u0432\u0430\u0439\u0442\u0435 \u043f\u043e\u0434\u0440\u043e\u0431\u043d\u043e \u043e\u0441\u0442\u0430\u043d\u043e\u0432\u0438\u043c\u0441\u044f \u043d\u0430 \u043d\u0435\u043a\u043e\u0442\u043e\u0440\u044b\u0445 \u0432\u0430\u0436\u043d\u044b\u0445 \u0441\u0432\u043e\u0439\u0441\u0442\u0432\u0430\u0445, \u0442\u0430\u043a\u0438\u0445 \u043a\u0430\u043a:<\/p>\n<ul>\n<li>\u0441\u043e\u0432\u043c\u0435\u0441\u0442\u0438\u043c\u043e\u0441\u0442\u044c \u0441 PostgreSQL;<\/li>\n<li>\u043a\u0430\u0441\u0442\u043e\u043c\u043d\u044b\u0435 \u0430\u0433\u0440\u0435\u0433\u0430\u0442\u044b SQL;<\/li>\n<li>\u043e\u043a\u043e\u043d\u043d\u044b\u0435 \u0444\u0443\u043d\u043a\u0446\u0438\u0438;<\/li>\n<li>\u043f\u0435\u0440\u0435\u0432\u043e\u0434 \u043e\u0431\u044a\u0435\u043a\u0442\u0430 R \u0432 bytea (\u0434\u0432\u043e\u0438\u0447\u043d\u044b\u0435 \u0441\u0442\u0440\u043e\u043a\u0438).<\/li>\n<\/ul>\n<p>  \u0411\u043b\u0430\u0433\u043e\u0434\u0430\u0440\u044f \u0441\u043e\u0432\u043c\u0435\u0441\u0442\u0438\u043c\u043e\u0441\u0442\u0438 \u0441 PostgreSQL, \u043c\u044b \u043c\u043e\u0436\u0435\u043c \u0441\u043e\u0437\u0434\u0430\u0432\u0430\u0442\u044c \u043f\u0440\u043e\u0442\u043e\u0442\u0438\u043f\u044b \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e R, \u0430 \u0437\u0430\u0442\u0435\u043c \u043f\u0435\u0440\u0435\u043c\u0435\u0449\u0430\u0442\u044c\u0441\u044f \u0432 PL\/R \u0434\u043b\u044f \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u044f \u0432 \u201c\u043f\u0440\u043e\u0434\u0430\u043a\u0448\u0435\u043d\u0435\u201d. \u0422\u0430\u043a\u0436\u0435 \u043d\u0435\u0441\u043e\u043c\u043d\u0435\u043d\u043d\u044b\u043c \u043f\u043b\u044e\u0441\u043e\u043c \u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u0442\u043e, \u0447\u0442\u043e \u0432\u0441\u0435 \u0437\u0430\u043f\u0440\u043e\u0441\u044b \u0432\u044b\u043f\u043e\u043b\u043d\u044f\u044e\u0442\u0441\u044f \u0432 \u0442\u0435\u043a\u0443\u0449\u0435\u0439 \u0431\u0430\u0437\u0435 \u0434\u0430\u043d\u043d\u044b\u0445. \u041f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u044b \u043d\u0430\u0441\u0442\u0440\u043e\u0435\u043a \u0434\u0440\u0430\u0439\u0432\u0435\u0440\u0430 \u0438 \u043f\u043e\u0434\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u044f \u0438\u0433\u043d\u043e\u0440\u0438\u0440\u0443\u044e\u0442\u0441\u044f, \u043f\u043e\u044d\u0442\u043e\u043c\u0443 dbDriver, dbConnect, dbDisconnect \u0438 dbUnloadDriver \u043d\u0435 \u0442\u0440\u0435\u0431\u0443\u044e\u0442 \u0437\u0430\u0442\u0440\u0430\u0442\u044b \u0434\u043e\u043f\u043e\u043b\u043d\u0438\u0442\u0435\u043b\u044c\u043d\u044b\u0445 \u0443\u0441\u0438\u043b\u0438\u0439:<\/p>\n<pre><code>dbDriver(character dvr_name) dbConnect(DBIDriver drv, character user, character password, character host, character dbname, character port, character tty, character options) dbSendQuery(DBIConnection conn, character sql) fetch(DBIResult rs, integer num_rows) dbClearResult (DBIResult rs) dbGetQuery(DBIConnection conn, character sql) dbReadTable(DBIConnection conn, character name) dbDisconnect(DBIConnection conn) dbUnloadDriver(DBIDriver drv) <\/code><\/pre>\n<p>  \u0414\u0430\u0432\u0430\u0439\u0442\u0435 \u043f\u0440\u0438\u0432\u0435\u0434\u0435\u043c \u043f\u0430\u0440\u0443 \u043f\u0440\u0438\u043c\u0435\u0440\u043e\u0432 \u0434\u043b\u044f \u043d\u0430\u0433\u043b\u044f\u0434\u043d\u043e\u0441\u0442\u0438. \u0414\u043e\u043f\u0443\u0441\u0442\u0438\u043c, \u043d\u0430\u043c \u043d\u0443\u0436\u043d\u043e \u043e\u0431\u0440\u0430\u0442\u0438\u0442\u044c\u0441\u044f \u043a PostgreSQL \u0438\u0437 R \u0434\u043b\u044f \u0440\u0435\u0448\u0435\u043d\u0438\u044f \u0437\u043d\u0430\u043c\u0435\u043d\u0438\u0442\u043e\u0439 \u0437\u0430\u0434\u0430\u0447\u0438 \u043a\u043e\u043c\u043c\u0438\u0432\u043e\u044f\u0436\u0451\u0440\u0430, \u043a\u043e\u0442\u043e\u0440\u0443\u044e \u043f\u043e\u0437\u0436\u0435 \u043c\u044b \u0440\u0430\u0441\u0441\u043c\u043e\u0442\u0440\u0438\u043c \u043f\u043e\u0434\u0440\u043e\u0431\u043d\u043e:<\/p>\n<pre><code>tsp_tour_length&lt;-function() {     require(TSP)     require(fields)     require(RPostgreSQL)      drv &lt;- dbDriver(&quot;PostgreSQL&quot;)     conn &lt;- dbConnect(drv, user=&quot;postgres&quot;, dbname=&quot;plr&quot;, host=&quot;localhost&quot;)      sql.str &lt;- &quot;select id, st_x(location) as x, st_y(location) as y, location from stands&quot;     waypts &lt;- dbGetQuery(conn, sql.str)     dist.matrix &lt;- rdist.earth(waypts[,2:3], R=3949.0)     rtsp &lt;- TSP(dist.matrix)     soln &lt;- solve_TSP(rtsp)      dbDisconnect(conn)     dbUnloadDriver(drv)      return(attributes(soln)$tour_length) } <\/code><\/pre>\n<p>  \u0410 \u0432\u043e\u0442 \u0442\u0430\u043a \u0432\u044b\u0433\u043b\u044f\u0434\u0438\u0442 \u0442\u0430 \u0436\u0435 \u0444\u0443\u043d\u043a\u0446\u0438\u044f \u0432 PL\/R:<\/p>\n<pre><code class=\"sql\">CREATE OR REPLACE FUNCTION tsp_tour_length()  RETURNS float8 AS $$     require(TSP)     require(fields)     require(RPostgreSQL)          drv &lt;- dbDriver(&quot;PostgreSQL&quot;)     conn &lt;- dbConnect(drv, user=&quot;postgres&quot;, dbname=&quot;plr&quot;, host=&quot;localhost&quot;)          sql.str &lt;- &quot;select id, st_x(location) as x, st_y(location) as y, location from stands&quot;     waypts &lt;- dbGetQuery(conn, sql.str)     dist.matrix &lt;- rdist.earth(waypts[,2:3], R=3949.0)     rtsp &lt;- TSP(dist.matrix)     soln &lt;- solve_TSP(rtsp)          dbDisconnect(conn)     dbUnloadDriver(drv)          return(attributes(soln)$tour_length) $$ LANGUAGE 'plr' STRICT; <\/code><\/pre>\n<p>  \u0412\u043e\u0442 \u0447\u0442\u043e \u043d\u0430\u043c \u0432 \u0438\u0442\u043e\u0433\u0435 \u0432\u044b\u0432\u043e\u0434\u0438\u0442 R:<\/p>\n<pre><code>tsp_tour_length() [1] 2804.581 <\/code><\/pre>\n<p>  \u0418 \u0442\u0430 \u0436\u0435 \u0444\u0443\u043d\u043a\u0446\u0438\u044f \u0432 PL\/R:<\/p>\n<pre><code class=\"sql\">SELECT tsp_tour_length(); tsp_tour_length ------------------ 2804.58129355858 (1 row) <\/code><\/pre>\n<p>  \u041a\u0430\u043a \u0432\u044b \u0432\u0438\u0434\u0438\u0442\u0435, \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442 \u043e\u0434\u0438\u043d\u0430\u043a\u043e\u0432\u044b\u0439.<\/p>\n<p>  \u0422\u0435\u043f\u0435\u0440\u044c \u043f\u043e\u0433\u043e\u0432\u043e\u0440\u0438\u043c \u043e\u0431 <a href=\"http:\/\/www.postgresql.org\/docs\/9.5\/static\/sql-createaggregate.html\">\u0430\u0433\u0440\u0435\u0433\u0430\u0442\u0430\u0445<\/a> (aggregates). \u041e\u0434\u043d\u0438\u043c \u0438\u0437 \u0441\u0430\u043c\u044b\u0445 \u043f\u043e\u043b\u0435\u0437\u043d\u044b\u0445 \u0441\u0432\u043e\u0439\u0441\u0442\u0432 PostgreSQL \u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u044c \u043f\u0438\u0441\u0430\u0442\u044c \u0441\u0432\u043e\u0438 \u0441\u043e\u0431\u0441\u0442\u0432\u0435\u043d\u043d\u044b\u0435 \u0430\u0433\u0440\u0435\u0433\u0430\u0442\u043d\u044b\u0435 \u0444\u0443\u043d\u043a\u0446\u0438\u0438. \u0410\u0433\u0440\u0435\u0433\u0430\u0442\u044b \u0432 PostgreSQL \u043c\u043e\u0436\u043d\u043e \u0440\u0430\u0441\u0448\u0438\u0440\u044f\u0442\u044c \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e \u043a\u043e\u043c\u0430\u043d\u0434 SQL. \u041f\u0440\u0438 \u044d\u0442\u043e\u043c \u0443\u043a\u0430\u0437\u044b\u0432\u0430\u0435\u0442\u0441\u044f \u0444\u0443\u043d\u043a\u0446\u0438\u044f \u043f\u0435\u0440\u0435\u0445\u043e\u0434\u0430 \u043c\u0435\u0436\u0434\u0443 \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u044f\u043c\u0438 (state transition function) \u0438, \u0438\u043d\u043e\u0433\u0434\u0430, \u0444\u0438\u043d\u0430\u043b\u044c\u043d\u0430\u044f \u0444\u0443\u043d\u043a\u0446\u0438\u044f (final function). \u041d\u0430\u0447\u0430\u043b\u044c\u043d\u043e\u0435 \u0443\u0441\u043b\u043e\u0432\u0438\u0435 \u0444\u0443\u043d\u043a\u0446\u0438\u0438 \u043f\u0435\u0440\u0435\u0445\u043e\u0434\u0430 \u0442\u0430\u043a\u0436\u0435 \u043c\u043e\u0436\u0435\u0442 \u0431\u044b\u0442\u044c \u0437\u0430\u0434\u0430\u043d\u043e. \u0418 \u044d\u0442\u0438\u043c\u0438 \u043f\u0440\u0435\u0438\u043c\u0443\u0449\u0435\u0441\u0442\u0432\u0430\u043c\u0438 \u0432\u044b \u043c\u043e\u0436\u0435\u0442\u0435 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c\u0441\u044f, \u0440\u0430\u0431\u043e\u0442\u0430\u044f \u0441 PL\/R.<\/p>\n<p>  \u041f\u0440\u0438\u0432\u0435\u0434\u0435\u043c \u043f\u0440\u0438\u043c\u0435\u0440 \u0444\u0443\u043d\u043a\u0446\u0438\u0438 PL\/R, \u0440\u0435\u0430\u043b\u0438\u0437\u0443\u044e\u0449\u0435\u0439 \u043d\u043e\u0432\u044b\u0439 \u0430\u0433\u0440\u0435\u0433\u0430\u0442. \u0414\u043e \u043d\u0435\u0434\u0430\u0432\u043d\u0435\u0433\u043e \u0432\u0440\u0435\u043c\u0435\u043d\u0438 \u044d\u0442\u043e \u0431\u044b\u043b\u043e \u043d\u0435\u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e \u0441\u0434\u0435\u043b\u0430\u0442\u044c \u0438\u0437 PostgreSQL, \u0444\u0443\u043d\u043a\u0446\u0438\u043e\u043d\u0430\u043b\u044c\u043d\u043e\u0441\u0442\u044c GROUPING SETS \u043f\u043e\u044f\u0432\u0438\u043b\u0430\u0441\u044c \u0442\u043e\u043b\u044c\u043a\u043e \u0432 \u0432\u0435\u0440\u0441\u0438\u0438 9.5, \u0432 \u0442\u043e \u0432\u0440\u0435\u043c\u044f \u043a\u0430\u043a PL\/R \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u0435\u0442 \u0434\u0435\u043b\u0430\u0442\u044c \u044d\u0442\u043e \u0432 \u043b\u044e\u0431\u044b\u0445 \u0432\u0435\u0440\u0441\u0438\u044f\u0445 PG. \u042f \u0441\u043e\u0437\u0434\u0430\u043c \u0430\u0433\u0440\u0435\u0433\u0430\u0442\u043d\u0443\u044e \u0444\u0443\u043d\u043a\u0446\u0438\u044e \u043d\u0430 \u043e\u0441\u043d\u043e\u0432\u0435 \u0440\u0435\u0430\u043b\u044c\u043d\u044b\u0445 \u0434\u0430\u043d\u043d\u044b\u0445 \u043e\u0434\u043d\u043e\u0439 \u043f\u0440\u043e\u0438\u0437\u0432\u043e\u0434\u0441\u0442\u0432\u0435\u043d\u043d\u043e\u0439 \u043a\u043e\u043c\u043f\u0430\u043d\u0438\u0438 \u0438 \u043d\u0430\u0437\u043e\u0432\u0443 \u0435\u0451 quartile:<\/p>\n<pre><code class=\"sql\">CREATE OR REPLACE FUNCTION r_quartile(ANYARRAY)  RETURNS ANYARRAY AS $$     quantile(arg1, probs = seq(0, 1, 0.25), names = FALSE) $$ LANGUAGE 'plr';  CREATE AGGREGATE quartile (ANYELEMENT) (     sfunc = array_append,     stype = ANYARRAY,     finalfunc = r_quantile,     initcond = '{}' );      SELECT workstation, quartile(id_val)      FROM sample_numeric_data     WHERE ia_id = 'G121XB8A' GROUP BY workstation;      workstation | quantile -------------+--------------------------------- 1055 | {4.19,5.02,5.21,5.5,6.89} 1051 | {3.89,4.66,4.825,5.2675,5.47} 1068 | {4.33,5.2625,5.455,5.5275,6.01} 1070 | {4.51,5.1975,5.485,5.7575,6.41} (4 rows) <\/code><\/pre>\n<p>  R \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u0435\u0442 \u0432\u044b\u0432\u043e\u0434\u0438\u0442\u044c \u0434\u0430\u043d\u043d\u044b\u0435 \u0432 \u0432\u0438\u0434\u0435 \u0441\u0438\u043c\u043f\u0430\u0442\u0438\u0447\u043d\u044b\u0445 \u0433\u0440\u0430\u0444\u0438\u043a\u043e\u0432. \u0412 \u0434\u0430\u043d\u043d\u043e\u043c \u0441\u043b\u0443\u0447\u0430\u0435 \u0431\u044b\u043b\u0430 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0430 \u043a\u043e\u0440\u043e\u0431\u0447\u0430\u0442\u0430\u044f \u0434\u0438\u0430\u0433\u0440\u0430\u043c\u043c\u0430:<br \/>  <img decoding=\"async\" src=\"https:\/\/habrastorage.org\/files\/7f5\/5e2\/c93\/7f55e2c93811481fb9841bdfc8442e63.png\"\/><br \/>  \u041f\u043e \u0433\u0440\u0430\u0444\u0438\u043a\u0443 \u0432\u0438\u0434\u043d\u043e, \u0447\u0442\u043e \u043e\u0434\u043d\u0430 \u0438\u0437 \u043f\u0440\u043e\u0438\u0437\u0432\u043e\u0434\u0441\u0442\u0432\u0435\u043d\u043d\u044b\u0445 \u0441\u0442\u0430\u043d\u0446\u0438\u0439 \u043c\u0435\u043d\u0435\u0435 \u043f\u0440\u043e\u0434\u0443\u043a\u0442\u0438\u0432\u043d\u0430 \u043f\u043e \u0441\u0440\u0430\u0432\u043d\u0435\u043d\u0438\u044e \u0441 \u043e\u0441\u0442\u0430\u043b\u044c\u043d\u044b\u043c\u0438, \u0438 \u043d\u0443\u0436\u043d\u043e \u043f\u0440\u0438\u043d\u044f\u0442\u044c \u043c\u0435\u0440\u044b, \u0447\u0442\u043e\u0431\u044b \u044d\u0442\u043e \u0438\u0441\u043f\u0440\u0430\u0432\u0438\u0442\u044c.<\/p>\n<p>  \u041e\u0442\u0434\u0435\u043b\u044c\u043d\u043e \u0441\u0442\u043e\u0438\u0442 \u043e\u0441\u0442\u0430\u043d\u043e\u0432\u0438\u0442\u044c\u0441\u044f \u043d\u0430 <a href=\"http:\/\/www.postgresql.org\/docs\/9.5\/static\/tutorial-window.html\">\u043e\u043a\u043e\u043d\u043d\u044b\u0445 \u0444\u0443\u043d\u043a\u0446\u0438\u044f\u0445<\/a> (window functions). \u041e\u043d\u0438 \u0434\u043e\u0441\u0442\u0443\u043f\u043d\u044b \u0432 PostgreSQL, \u043d\u0430\u0447\u0438\u043d\u0430\u044f \u0441 \u0432\u0435\u0440\u0441\u0438\u0438 8.4, \u0438 \u043e\u0442\u043b\u0438\u0447\u043d\u043e \u043f\u043e\u0434\u0445\u043e\u0434\u044f\u0442 \u0434\u043b\u044f \u0441\u0442\u0430\u0442\u0438\u0441\u0442\u0438\u0447\u0435\u0441\u043a\u043e\u0433\u043e \u0430\u043d\u0430\u043b\u0438\u0437\u0430. \u041e\u043a\u043e\u043d\u043d\u044b\u0435 \u0444\u0443\u043d\u043a\u0446\u0438\u0438 \u0441\u0445\u043e\u0436\u0438 \u0441 \u0430\u0433\u0440\u0435\u0433\u0430\u0442\u043d\u044b\u043c\u0438, \u043d\u043e, \u0432 \u043e\u0442\u043b\u0438\u0447\u0438\u0435 \u043e\u0442 \u043d\u0438\u0445, \u043d\u0435 \u0433\u0440\u0443\u043f\u043f\u0438\u0440\u0443\u044e\u0442 \u0441\u0442\u0440\u043e\u043a\u0438, \u0430 \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u044e\u0442 \u043f\u0440\u043e\u0438\u0437\u0432\u043e\u0434\u0438\u0442\u044c \u0440\u0430\u0441\u0447\u0435\u0442\u044b \u0432 \u043d\u0430\u0431\u043e\u0440\u0430\u0445 \u0441\u0442\u0440\u043e\u043a, \u0441\u0432\u044f\u0437\u0430\u043d\u043d\u044b\u0445 \u0441 \u0442\u0435\u043a\u0443\u0449\u0435\u0439 \u0441\u0442\u0440\u043e\u043a\u043e\u0439, \u0438\u043c\u0435\u044f \u0434\u043e\u0441\u0442\u0443\u043f \u043d\u0435 \u0442\u043e\u043b\u044c\u043a\u043e \u043a \u0442\u0435\u043a\u0443\u0449\u0435\u0439 \u0441\u0442\u0440\u043e\u043a\u0435 \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442\u0430 \u0437\u0430\u043f\u0440\u043e\u0441\u0430. \u0418\u043d\u044b\u043c\u0438 \u0441\u043b\u043e\u0432\u0430\u043c\u0438, \u0432\u0430\u0448\u0438 \u0434\u0430\u043d\u043d\u044b\u0435 \u0440\u0430\u0437\u0431\u0438\u0442\u044b \u043d\u0430 \u0441\u0435\u043a\u0446\u0438\u0438, \u0438 \u0435\u0441\u0442\u044c \u043e\u043a\u043d\u043e, \u043a\u043e\u0442\u043e\u0440\u043e\u0435 \u0441\u043a\u043e\u043b\u044c\u0437\u0438\u0442 \u043f\u043e \u044d\u0442\u0438\u043c \u0441\u0435\u043a\u0446\u0438\u044f\u043c \u0438 \u0432\u044b\u0434\u0430\u0451\u0442 \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442 \u0434\u043b\u044f \u043a\u0430\u0436\u0434\u043e\u0439 \u0433\u0440\u0443\u043f\u043f\u044b \u0434\u0430\u043d\u043d\u044b\u0445:<\/p>\n<p>  <img decoding=\"async\" src=\"https:\/\/habrastorage.org\/files\/667\/7e9\/17a\/6677e917a7ee48bdbcb181ca70a3e247.png\"\/><br \/>  \u041d\u0435\u043c\u043d\u043e\u0433\u0438\u0435 \u043f\u0440\u043e\u0446\u0435\u0434\u0443\u0440\u043d\u044b\u0435 \u044f\u0437\u044b\u043a\u0438 PostgreSQL \u043f\u043e\u0434\u0434\u0435\u0440\u0436\u0438\u0432\u0430\u044e\u0442 \u043e\u043a\u043e\u043d\u043d\u044b\u0435 \u0444\u0443\u043d\u043a\u0446\u0438\u0438, \u043d\u043e \u0432 PL\/R \u043e\u043d\u0438 \u0432\u0435\u0441\u044c\u043c\u0430 \u043f\u043e\u043b\u0435\u0437\u043d\u044b. \u041f\u0440\u0438\u0432\u0435\u0434\u0435\u043c \u043f\u0440\u0438\u043c\u0435\u0440: \u0441\u043e\u0437\u0434\u0430\u0434\u0438\u043c \u0442\u0430\u0431\u043b\u0438\u0446\u0443 \u0441\u043b\u0443\u0447\u0430\u0439\u043d\u044b\u0445 \u0434\u0430\u043d\u043d\u044b\u0445, \u0441\u0438\u043c\u0443\u043b\u0438\u0440\u0443\u044e\u0449\u0443\u044e \u0434\u043e\u0445\u043e\u0434\u044b \u0438 \u0446\u0435\u043d\u044b \u043d\u0430 \u0430\u043a\u0446\u0438\u0438.<\/p>\n<pre><code class=\"sql\">CREATE TABLE test_data (     fyear integer,     firm float8,     eps float8 );  INSERT INTO test_data  SELECT (b.f + 1) % 10 + 2000 AS fyear,        floor((b.f+1)\/10) + 50 AS firm,        f::float8\/100 + random()\/10 AS eps             FROM generate_series(-500,499,1) b(f);      CREATE OR REPLACE FUNCTION r_regr_slope(float8, float8) RETURNS float8 AS  $BODY$     slope &lt;- NA     y &lt;- farg1     x &lt;- farg2     if (fnumrows==9) try (slope &lt;- lm(y ~ x)$coefficients[2])     return(slope) $BODY$ LANGUAGE plr WINDOW; <\/code><\/pre>\n<p>  \u0418 \u043d\u0430\u043f\u0438\u0448\u0435\u043c \u0444\u0443\u043d\u043a\u0446\u0438\u044e \u0434\u043b\u044f \u0442\u043e\u0433\u043e \u0447\u0442\u043e\u0431\u044b \u0432\u044b\u044f\u0441\u043d\u0438\u0442\u044c, \u043c\u043e\u0436\u043d\u043e \u043b\u0438 \u043f\u0440\u0435\u0434\u0441\u043a\u0430\u0437\u0430\u0442\u044c \u0434\u043e\u0445\u043e\u0434\u044b \u0432 \u044d\u0442\u043e\u043c \u0433\u043e\u0434\u0443, \u043e\u0441\u043d\u043e\u0432\u044b\u0432\u0430\u044f\u0441\u044c \u043d\u0430 \u043f\u043e\u043a\u0430\u0437\u0430\u0442\u0435\u043b\u044f\u0445 \u043f\u0440\u043e\u0448\u043b\u043e\u0433\u043e \u0433\u043e\u0434\u0430, \u043c\u0435\u0442\u043e\u0434\u043e\u043c \u043f\u0440\u043e\u0441\u0442\u043e\u0439 \u0440\u0435\u0433\u0440\u0435\u0441\u0441\u0438\u0438.<\/p>\n<pre><code class=\"sql\">SELECT *, r_regr_slope(eps, lag_eps) OVER w AS slope_R      FROM (         SELECT firm AS f,                 fyear AS fyr,                 eps,                lag(eps) OVER (PARTITION BY firm ORDER BY firm, fyear) AS lag_eps             FROM test_data     ) AS a           WHERE eps IS NOT NULL          WINDOW w AS (PARTITION BY firm ORDER BY firm, fyear ROWS 8 PRECEDING);  f | fyr | eps | lag_eps | slope_r ---+------+-------------------+-------------------+------------------- 1 | 1991 | -4.99563754182309 | | 1 | 1992 | -4.96425441872329 | -4.99563754182309 | 1 | 1993 | -4.96906093481928 | -4.96425441872329 | 1 | 1994 | -4.92376988714561 | -4.96906093481928 | 1 | 1995 | -4.95884547665715 | -4.92376988714561 | 1 | 1996 | -4.93236254784279 | -4.95884547665715 | 1 | 1997 | -4.90775520844385 | -4.93236254784279 | 1 | 1998 | -4.92082695348188 | -4.90775520844385 | 1 | 1999 | -4.84991340579465 | -4.92082695348188 | 0.691850614092383 1 | 2000 | -4.86000917562284 | -4.84991340579465 | 0.700526929134053 <\/code><\/pre>\n<p>  \u041a\u0430\u043a \u0432\u044b \u0432\u0438\u0434\u0438\u0442\u0435, \u0444\u0443\u043d\u043a\u0446\u0438\u044f \u043f\u043e\u0441\u0447\u0438\u0442\u0430\u043b\u0430 \u043d\u0430\u043c \u0437\u0430\u0432\u0438\u0441\u0438\u043c\u043e\u0441\u0442\u044c \u0434\u043e\u0445\u043e\u0434\u043e\u0432 \u043e\u0442 \u043f\u043e\u043a\u0430\u0437\u0430\u0442\u0435\u043b\u0435\u0439 \u043f\u0440\u043e\u0448\u043b\u044b\u0445 \u043b\u0435\u0442. <\/p>\n<p>  \u041f\u043e\u0441\u043b\u0435\u0434\u043d\u0435\u0435, \u043e \u0447\u0435\u043c \u0441\u0442\u043e\u0438\u0442 \u043f\u043e\u0433\u043e\u0432\u043e\u0440\u0438\u0442\u044c \u043f\u043e\u0434\u0440\u043e\u0431\u043d\u043e, \u044d\u0442\u043e \u043c\u0435\u0445\u0430\u043d\u0438\u0437\u043c\u044b \u0432\u043e\u0437\u0432\u0440\u0430\u0442\u0430 \u043e\u0431\u044a\u0435\u043a\u0442\u043e\u0432 R \u0438 \u0441\u043f\u043e\u0441\u043e\u0431\u044b \u0438\u0445 \u0445\u0440\u0430\u043d\u0435\u043d\u0438\u044f. <\/p>\n<p>  \u041f\u0440\u0438\u0432\u0435\u0434\u0435\u043c \u043f\u0440\u0438\u043c\u0435\u0440 \u0441 \u0431\u0438\u0440\u0436\u0435\u0432\u044b\u043c\u0438 \u0434\u0430\u043d\u043d\u044b\u043c\u0438. \u0414\u043b\u044f \u044d\u0442\u043e\u0433\u043e \u0432\u043e\u0437\u044c\u043c\u0435\u043c Hi-Low-Close \u0434\u0430\u043d\u043d\u044b\u0435 \u0438\u0437 Yahoo \u0434\u043b\u044f \u043b\u044e\u0431\u043e\u0433\u043e \u201c\u0442\u0438\u043a\u0435\u0440\u0430\u201d (stock ticker). \u041f\u043e\u0441\u0442\u0440\u043e\u0438\u043c \u0433\u0440\u0430\u0444\u0438\u043a \u0441 \u043b\u0438\u043d\u0438\u044f\u043c\u0438 \u0411\u043e\u043b\u043b\u0438\u043d\u0434\u0436\u0435\u0440\u0430 \u0438 \u043e\u0431\u044a\u0451\u043c\u043e\u043c. \u041d\u0430\u043c \u043f\u043e\u0442\u0440\u0435\u0431\u0443\u044e\u0442\u0441\u044f \u0434\u043e\u043f\u043e\u043b\u043d\u0438\u0442\u0435\u043b\u044c\u043d\u044b\u0435 R \u043f\u0430\u043a\u0435\u0442\u044b, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u043c\u043e\u0436\u043d\u043e \u043f\u043e\u043b\u0443\u0447\u0438\u0442\u044c \u0438\u0437 R \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0435\u0439 \u043a\u043e\u043c\u0430\u043d\u0434\u043e\u0439:<\/p>\n<pre><code>install.packages(c('xts','Defaults','quantmod','cairoDevice','RGtk2')) <\/code><\/pre>\n<p>  \u0422\u0435\u043f\u0435\u0440\u044c \u0441\u043e\u0441\u0442\u0430\u0432\u0438\u043c \u0437\u0430\u043f\u0440\u043e\u0441:<\/p>\n<pre><code class=\"sql\">CREATE OR REPLACE FUNCTION plot_stock_data(sym text)    RETURNS bytea AS  $$     library(quantmod)     library(cairoDevice)     library(RGtk2)          pixmap &lt;- gdkPixmapNew(w=500, h=500, depth=24)          asCairoDevice(pixmap)     getSymbols(c(sym))     chartSeries(get(sym), name=sym, theme=&quot;white&quot;, TA=&quot;addVo();addBBands();addCCI()&quot;)          plot_pixbuf &lt;- gdkPixbufGetFromDrawable(NULL, pixmap,     pixmap$getColormap(),0, 0, 0, 0, 500, 500)     buffer &lt;- gdkPixbufSaveToBufferv(plot_pixbuf, &quot;jpeg&quot;, character(0), character(0))$buffer          return(buffer) $$ LANGUAGE plr; <\/code><\/pre>\n<p>  \u0414\u043b\u044f \u0442\u0438\u043f\u043e\u0432\u043e\u0433\u043e \u0441\u0435\u0440\u0432\u0435\u0440\u0430 \u043f\u043e\u0442\u0440\u0435\u0431\u0443\u0435\u0442\u0441\u044f \u044d\u043a\u0440\u0430\u043d\u043d\u044b\u0439 \u0431\u0443\u0444\u0435\u0440, \u0447\u0442\u043e\u0431\u044b \u0441\u043e\u0437\u0434\u0430\u0442\u044c \u0433\u0440\u0430\u0444\u0438\u043a:<\/p>\n<pre><code>Xvfb :1 -screen 0 1024x768x24 export DISPLAY=:1.0 <\/code><\/pre>\n<p>  \u0422\u0435\u043f\u0435\u0440\u044c \u0432\u044b\u0437\u043e\u0432\u0435\u043c \u0444\u0443\u043d\u043a\u0446\u0438\u044e \u0438\u0437 PHP \u0434\u043b\u044f \u0442\u0438\u043a\u0435\u0440\u0430 CYMI:<\/p>\n<pre><code class=\"php\">&lt;?php  $dbconn = pg_connect(&quot;...&quot;); $rs = pg_query($dbconn, &quot;select plr_get_raw(plot_stock_data('CYMI'))&quot;); $hexpic = pg_fetch_array($rs); $cleandata = pg_unescape_bytea($hexpic[0]);  header(&quot;Content-Type: image\/png&quot;); header(&quot;Last-Modified: &quot; . date(&quot;r&quot;, filectime($_SERVER['SCRIPT_FILENAME']))); header(&quot;Content-Length: &quot; . strlen($cleandata));  echo $cleandata;  ?&gt; <\/code><\/pre>\n<p>  \u0418 \u0432\u043e\u0442 \u0442\u0430\u043a\u043e\u0439 \u0433\u0440\u0430\u0444\u0438\u043a \u043c\u044b \u043f\u043e\u043b\u0443\u0447\u0430\u0435\u043c \u043d\u0430 \u0432\u044b\u0445\u043e\u0434\u0435:<\/p>\n<p>  <img decoding=\"async\" src=\"https:\/\/habrastorage.org\/files\/395\/6f2\/fbb\/3956f2fbb34146be9512e3d488a74a8a.png\"\/><br \/>  \u0421\u043e\u0433\u043b\u0430\u0441\u0438\u0442\u0435\u0441\u044c, \u0443\u0434\u0438\u0432\u0438\u0442\u0435\u043b\u044c\u043d\u043e, \u0447\u0442\u043e \u043c\u044b \u043c\u043e\u0436\u0435\u043c \u043d\u0430\u043f\u0438\u0441\u0430\u0442\u044c \u0434\u0435\u0441\u044f\u0442\u043e\u043a \u0441\u0442\u0440\u043e\u043a \u043d\u0430 PL\/R \u0438 \u043c\u0435\u043d\u044c\u0448\u0435 \u0434\u044e\u0436\u0438\u043d\u044b \u0441\u0442\u0440\u043e\u043a \u0432 PHP, \u0430 \u0432 \u0438\u0442\u043e\u0433\u0435 \u043f\u043e\u043b\u0443\u0447\u0438\u0442\u044c \u0442\u0430\u043a\u043e\u0435 \u043f\u043e\u0434\u0440\u043e\u0431\u043d\u043e\u0435 \u0432\u0438\u0437\u0443\u0430\u043b\u044c\u043d\u043e\u0435 \u043e\u0442\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u0438\u0435 \u0438 \u0430\u043d\u0430\u043b\u0438\u0437 \u043d\u0430\u0448\u0438\u0445 \u0434\u0430\u043d\u043d\u044b\u0445.<\/p>\n<p>  \u0427\u0442\u043e\u0431\u044b \u0437\u0430\u043a\u0440\u0435\u043f\u0438\u0442\u044c \u0438\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0438\u044e, \u0440\u0430\u0441\u0441\u043c\u043e\u0442\u0440\u0438\u043c \u0431\u043e\u043b\u0435\u0435 \u0441\u043b\u043e\u0436\u043d\u044b\u0435 \u043f\u0440\u0438\u043c\u0435\u0440\u044b. \u0414\u0443\u043c\u0430\u044e, \u043c\u043d\u043e\u0433\u0438\u0435 \u0437\u043d\u0430\u043a\u043e\u043c\u044b \u0441 \u0437\u0430\u043a\u043e\u043d\u043e\u043c \u0411\u0435\u043d\u0444\u043e\u0440\u0434\u0430, \u0438\u043b\u0438 \u0437\u0430\u043a\u043e\u043d\u043e\u043c \u043f\u0435\u0440\u0432\u043e\u0439 \u0446\u0438\u0444\u0440\u044b, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043e\u043f\u0438\u0441\u044b\u0432\u0430\u0435\u0442 \u0432\u0435\u0440\u043e\u044f\u0442\u043d\u043e\u0441\u0442\u044c \u043f\u043e\u044f\u0432\u043b\u0435\u043d\u0438\u044f \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0451\u043d\u043d\u043e\u0439 \u043f\u0435\u0440\u0432\u043e\u0439 \u0437\u043d\u0430\u0447\u0430\u0449\u0435\u0439 \u0446\u0438\u0444\u0440\u044b \u0432 \u0440\u0430\u0441\u043f\u0440\u0435\u0434\u0435\u043b\u0435\u043d\u0438\u044f\u0445 \u0432\u0435\u043b\u0438\u0447\u0438\u043d, \u0432\u0437\u044f\u0442\u044b\u0445 \u0438\u0437 \u0440\u0435\u0430\u043b\u044c\u043d\u043e\u0439 \u0436\u0438\u0437\u043d\u0438. \u041d\u043e \u043d\u0435\u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u043d\u0435 \u0437\u043d\u0430\u044e\u0442 \u043e \u0435\u0433\u043e \u0441\u0443\u0449\u0435\u0441\u0442\u0432\u043e\u0432\u0430\u043d\u0438\u0438 \u0438 \u0441\u0430\u043c\u0438 \u0440\u0430\u0441\u043f\u0440\u0435\u0434\u0435\u043b\u044f\u044e\u0442 \u0434\u0430\u043d\u043d\u044b\u0435 \u0442\u0430\u043a, \u043a\u0430\u043a \u0438\u043c \u043d\u0443\u0436\u043d\u043e, \u0432\u043c\u0435\u0441\u0442\u043e \u0442\u043e\u0433\u043e, \u0447\u0442\u043e\u0431\u044b \u043f\u0440\u0438\u043c\u0435\u043d\u0438\u0442\u044c \u0437\u0430\u043a\u043e\u043d. <\/p>\n<p>  \u0417\u0430\u043a\u043e\u043d \u0411\u0435\u043d\u0444\u043e\u0440\u0434\u0430 \u043c\u043e\u0436\u043d\u043e \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u0434\u043b\u044f \u0432\u044b\u044f\u0432\u043b\u0435\u043d\u0438\u044f \u043f\u043e\u0442\u0435\u043d\u0446\u0438\u0430\u043b\u044c\u043d\u043e\u0433\u043e \u043c\u043e\u0448\u0435\u043d\u043d\u0438\u0447\u0435\u0441\u0442\u0432\u0430: \u0441 \u0435\u0433\u043e \u043f\u043e\u043c\u043e\u0449\u044c\u044e \u043c\u043e\u0436\u043d\u043e \u043f\u043e\u0441\u0442\u0440\u043e\u0438\u0442\u044c \u043f\u0440\u0438\u043c\u0435\u0440\u043d\u0443\u044e \u0433\u0435\u043e\u043c\u0435\u0442\u0440\u0438\u0447\u0435\u0441\u043a\u0443\u044e \u043f\u043e\u0441\u043b\u0435\u0434\u043e\u0432\u0430\u0442\u0435\u043b\u044c\u043d\u043e\u0441\u0442\u044c \u043d\u0430 \u043e\u0441\u043d\u043e\u0432\u0430\u043d\u0438\u0438 \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u0438\u0445 \u043d\u0430\u0447\u0430\u043b\u044c\u043d\u044b\u0445 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0439, \u0430 \u043f\u043e\u0442\u043e\u043c \u0441\u0440\u0430\u0432\u043d\u0438\u0442\u044c \u0441 \u0440\u0435\u0430\u043b\u044c\u043d\u044b\u043c\u0438 \u0434\u0430\u043d\u043d\u044b\u043c\u0438 \u0438 \u043d\u0430\u0439\u0442\u0438 \u043d\u0435\u0441\u043e\u043e\u0442\u0432\u0435\u0442\u0441\u0442\u0432\u0438\u044f. \u0422\u0430\u043a\u043e\u0439 \u043c\u0435\u0442\u043e\u0434 \u043c\u043e\u0436\u043d\u043e \u043f\u0440\u0438\u043c\u0435\u043d\u044f\u0442\u044c \u043a \u0433\u0440\u0430\u0444\u0438\u043a\u0430\u043c \u043f\u0440\u043e\u0434\u0430\u0436, \u0434\u0430\u043d\u043d\u044b\u043c \u043f\u0435\u0440\u0435\u043f\u0438\u0441\u0438, \u043e\u0442\u0447\u0435\u0442\u0430\u043c \u043e \u0437\u0430\u0442\u0440\u0430\u0442\u0430\u0445 \u0438 \u0442.\u0434.<\/p>\n<p>  \u0420\u0430\u0441\u0441\u043c\u043e\u0442\u0440\u0438\u043c \u043f\u0440\u0438\u043c\u0435\u0440 \u0441 \u0434\u0430\u043d\u043d\u044b\u043c\u0438 \u041a\u0430\u043b\u0438\u0444\u043e\u0440\u043d\u0438\u0439\u0441\u043a\u043e\u0439 \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u044b \u043f\u043e \u043e\u043f\u0442\u0438\u043c\u0438\u0437\u0430\u0446\u0438\u0438 \u044d\u043d\u0435\u0440\u0433\u043e\u0437\u0430\u0442\u0440\u0430\u0442. \u0414\u043b\u044f \u043d\u0430\u0447\u0430\u043b\u0430 \u0441\u043e\u0437\u0434\u0430\u0434\u0438\u043c \u0438 \u0437\u0430\u043f\u043e\u043b\u043d\u0438\u043c \u0442\u0430\u0431\u043b\u0438\u0446\u0443 \u0441 \u0434\u0430\u043d\u043d\u044b\u043c\u0438 \u043e\u0431 \u0438\u043d\u0432\u0435\u0441\u0442\u0438\u0446\u0438\u044f\u0445 \u0432 \u043f\u0440\u043e\u0435\u043a\u0442 (\u0434\u0430\u043d\u043d\u044b\u0435 \u0434\u043e\u0441\u0442\u0443\u043f\u043d\u044b \u043f\u043e \u0441\u0441\u044b\u043b\u043a\u0435 <a href=\"http:\/\/open-emv.com\/data\">http:\/\/open-emv.com\/data<\/a>):<\/p>\n<pre><code class=\"sql\">CREATE TABLE open_emv_cost(value float8, district int);  COPY open_emv_cost FROM 'open-emv.cost.csv' WITH delimiter ','; <\/code><\/pre>\n<p>  \u0422\u0435\u043f\u0435\u0440\u044c \u043d\u0430\u043f\u0438\u0448\u0435\u043c \u0444\u0443\u043d\u043a\u0446\u0438\u044e \u0437\u0430\u043a\u043e\u043d\u0430 \u0411\u0435\u043d\u0444\u043e\u0440\u0434\u0430:<\/p>\n<pre><code class=\"sql\">CREATE TYPE benford_t AS (     actual_mean float8,     n int,     expected_mean float8,     distorion float8,     z float8 );  CREATE OR REPLACE FUNCTION benford(numarr float8[]) RETURNS benford_t AS  $$     xcoll &lt;- function(x) {         return ((10 * x) \/ (10 ^ (trunc(log10(x)))))     }          numarr &lt;- numarr[numarr &gt;= 10]     numarr &lt;- xcoll(numarr)     actual_mean &lt;- mean(numarr)     n &lt;- length(numarr)     expected_mean &lt;- (90 \/ (n * (10 ^ (1\/n) - 1)))     distorion &lt;- ((actual_mean - expected_mean) \/ expected_mean)     z &lt;- (distorion \/ sd(numarr))     retval &lt;- data.frame(actual_mean,n,expected_mean,distorion,z)          return(retval) $$ LANGUAGE plr; <\/code><\/pre>\n<p>  \u0418 \u0437\u0430\u043f\u0443\u0441\u0442\u0438\u043c \u0441\u0440\u0430\u0432\u043d\u0435\u043d\u0438\u0435:<\/p>\n<pre><code class=\"sql\">SELECT * FROM benford(array(SELECT value FROM open_emv_cost)); -[ RECORD 1 ]-+---------------------- actual_mean | 38.1936561918275 n | 240 expected_mean | 38.8993031865999 distorion | -0.0181403505195804 z | -0.000984036908080443 <\/code><\/pre>\n<p>  \u041f\u043e\u0445\u043e\u0436\u0435, \u0447\u0442\u043e \u0440\u0435\u0430\u043b\u044c\u043d\u044b\u0435 \u0434\u0430\u043d\u043d\u044b\u0435 \u0441\u043e\u043e\u0442\u0432\u0435\u0442\u0441\u0442\u0432\u0443\u044e\u0442 \u043f\u0440\u043e\u0433\u043d\u043e\u0437\u0438\u0440\u0443\u0435\u043c\u044b\u043c, \u0442\u0430\u043a \u0447\u0442\u043e \u043f\u0440\u0438\u0437\u043d\u0430\u043a\u0438 \u043c\u043e\u0448\u0435\u043d\u043d\u0438\u0447\u0435\u0441\u0442\u0432\u0430 \u0432 \u0434\u0430\u043d\u043d\u043e\u043c \u0441\u043b\u0443\u0447\u0430\u0435 \u043e\u0442\u0441\u0443\u0442\u0441\u0442\u0432\u0443\u044e\u0442.<\/p>\n<p>  \u0412\u0435\u0440\u043d\u0435\u043c\u0441\u044f \u043a \u0437\u0430\u0434\u0430\u0447\u0435 \u043a\u043e\u043c\u043c\u0438\u0432\u043e\u044f\u0436\u0451\u0440\u0430. \u042d\u0442\u043e \u043e\u0434\u043d\u0430 \u0438\u0437 \u0441\u0430\u043c\u044b\u0445 \u0438\u0437\u0432\u0435\u0441\u0442\u043d\u044b\u0445 \u0437\u0430\u0434\u0430\u0447 \u043a\u043e\u043c\u0431\u0438\u043d\u0430\u0442\u043e\u0440\u043d\u043e\u0439 \u043e\u043f\u0442\u0438\u043c\u0438\u0437\u0430\u0446\u0438\u0438, \u0437\u0430\u043a\u043b\u044e\u0447\u0430\u044e\u0449\u0430\u044f\u0441\u044f \u0432 \u043f\u043e\u0438\u0441\u043a\u0435 \u0441\u0430\u043c\u043e\u0433\u043e \u0432\u044b\u0433\u043e\u0434\u043d\u043e\u0433\u043e \u043c\u0430\u0440\u0448\u0440\u0443\u0442\u0430, \u043f\u0440\u043e\u0445\u043e\u0434\u044f\u0449\u0435\u0433\u043e \u0445\u043e\u0442\u044f \u0431\u044b \u0440\u0430\u0437 \u0447\u0435\u0440\u0435\u0437 \u0443\u043a\u0430\u0437\u0430\u043d\u043d\u044b\u0435 \u0433\u043e\u0440\u043e\u0434\u0430, \u0441 \u043f\u043e\u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u043c \u0432\u043e\u0437\u0432\u0440\u0430\u0442\u043e\u043c \u0432 \u0438\u0441\u0445\u043e\u0434\u043d\u044b\u0439 \u0433\u043e\u0440\u043e\u0434. \u0412 \u0443\u0441\u043b\u043e\u0432\u0438\u044f\u0445 \u0437\u0430\u0434\u0430\u0447\u0438 \u0443\u043a\u0430\u0437\u044b\u0432\u0430\u044e\u0442\u0441\u044f \u043a\u0440\u0438\u0442\u0435\u0440\u0438\u0438 \u0432\u044b\u0433\u043e\u0434\u043d\u043e\u0441\u0442\u0438 \u043c\u0430\u0440\u0448\u0440\u0443\u0442\u0430 (\u043a\u0440\u0430\u0442\u0447\u0430\u0439\u0448\u0438\u0439, \u043d\u0430\u0438\u0431\u043e\u043b\u0435\u0435 \u0434\u0435\u0448\u0451\u0432\u044b\u0439, \u0441\u043e\u0432\u043e\u043a\u0443\u043f\u043d\u044b\u0439 \u043a\u0440\u0438\u0442\u0435\u0440\u0438\u0439 \u0438 \u0442\u0430\u043a \u0434\u0430\u043b\u0435\u0435) \u0438 \u0441\u043e\u043e\u0442\u0432\u0435\u0442\u0441\u0442\u0432\u0443\u044e\u0449\u0438\u0435 \u043c\u0430\u0442\u0440\u0438\u0446\u044b \u0440\u0430\u0441\u0441\u0442\u043e\u044f\u043d\u0438\u0439, \u0441\u0442\u043e\u0438\u043c\u043e\u0441\u0442\u0438 \u0438 \u0442\u043e\u043c\u0443 \u043f\u043e\u0434\u043e\u0431\u043d\u043e\u0433\u043e. \u041a\u0430\u043a \u043f\u0440\u0430\u0432\u0438\u043b\u043e, \u0443\u043a\u0430\u0437\u044b\u0432\u0430\u0435\u0442\u0441\u044f, \u0447\u0442\u043e \u043c\u0430\u0440\u0448\u0440\u0443\u0442 \u0434\u043e\u043b\u0436\u0435\u043d \u043f\u0440\u043e\u0445\u043e\u0434\u0438\u0442\u044c \u0447\u0435\u0440\u0435\u0437 \u043a\u0430\u0436\u0434\u044b\u0439 \u0433\u043e\u0440\u043e\u0434 \u0442\u043e\u043b\u044c\u043a\u043e \u043e\u0434\u0438\u043d \u0440\u0430\u0437. \u0414\u0430\u0432\u0430\u0439\u0442\u0435 \u0440\u0430\u0441\u0441\u043c\u043e\u0442\u0440\u0438\u043c \u0438\u043c\u0435\u043d\u043d\u043e \u044d\u0442\u043e\u0442 \u0432\u0430\u0440\u0438\u0430\u043d\u0442. <\/p>\n<p>  \u0414\u043b\u044f \u043d\u0430\u0447\u0430\u043b\u0430 \u0441\u043e\u0437\u0434\u0430\u0434\u0438\u043c \u0438 \u043d\u0430\u043f\u043e\u043b\u043d\u0438\u043c \u0442\u0430\u0431\u043b\u0438\u0446\u0443 \u0441\u043e \u0432\u0441\u0435\u043c\u0438 \u0433\u043e\u0440\u043e\u0434\u0430\u043c\u0438, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u043d\u0443\u0436\u043d\u043e \u043f\u043e\u0441\u0435\u0442\u0438\u0442\u044c:<\/p>\n<pre><code class=\"sql\">CREATE TABLE stands (     id serial primary key,     strata integer not null,     initage integer );  SELECT AddGeometryColumn('','stands','boundary','4326','MULTIPOLYGON',2);  CREATE INDEX &quot;stands_boundary_gist&quot; ON &quot;stands&quot; USING gist (&quot;boundary&quot; gist_geometry_ops);  SELECT AddGeometryColumn('','stands','location','4326','POINT',2);  CREATE INDEX &quot;stands_location_gist&quot; ON &quot;stands&quot; USING gist (&quot;location&quot; gist_geometry_ops);  INSERT INTO stands (id,strata,initage,boundary,location)           VALUES     (         1,1,1,         GeometryFromText(             'MULTIPOLYGON(((59.250000 65.000000,55.000000 65.000000,55.000000 51.750000,             60.735294 53.470588, 62.875000 57.750000, 59.250000 65.000000 )))', 4326         ),         GeometryFromText('POINT( 61.000000 59.000000 )', 4326)     ), (         2,2,1,         GeometryFromText(             'MULTIPOLYGON(((67.000000 65.000000,59.250000 65.000000,62.875000 57.750000,             67.000000 60.500000, 67.000000 65.000000 )))', 4326         ),         GeometryFromText('POINT( 63.000000 60.000000 )', 4326 )     ), (         3,3,1,         GeometryFromText(             'MULTIPOLYGON(((67.045455 52.681818,60.735294 53.470588,55.000000 51.750000,             55.000000 45.000000, 65.125000 45.000000, 67.045455 52.681818 )))', 4326         ),         GeometryFromText('POINT( 64.000000 49.000000 )', 4326 )     ) ; <\/code><\/pre>\n<p>  \u0427\u0442\u043e\u0431\u044b \u043f\u043e\u043b\u0443\u0447\u0438\u0442\u044c \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442, \u043c\u043d\u0435 \u043f\u0440\u0438\u0434\u0435\u0442\u0441\u044f \u043d\u0430\u043f\u0438\u0441\u0430\u0442\u044c \u043f\u0430\u0440\u0443 \u0432\u0441\u043f\u043e\u043c\u043e\u0433\u0430\u0442\u0435\u043b\u044c\u043d\u044b\u0445 \u0437\u0430\u043f\u0440\u043e\u0441\u043e\u0432. \u041f\u0435\u0440\u0432\u044b\u0439 \u0441\u043e\u0437\u0434\u0430\u0441\u0442 \u043c\u0430\u0440\u0448\u0440\u0443\u0442, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u044f \u0445\u043e\u0447\u0443 \u043f\u043e\u043b\u0443\u0447\u0438\u0442\u044c \u043d\u0430 \u0432\u044b\u0445\u043e\u0434\u0435:<\/p>\n<pre><code class=\"sql\">INSERT INTO stands (id,strata,initage,boundary,location)       VALUES     (         4,4,1,         GeometryFromText(             'MULTIPOLYGON(((71.500000 53.500000,70.357143 53.785714,67.045455 52.681818,             65.125000 45.000000, 71.500000 45.000000, 71.500000 53.500000 )))', 4326         ),         GeometryFromText('POINT( 68.000000 48.000000 )', 4326)     ), (         5,5,1,         GeometryFromText(             'MULTIPOLYGON(((69.750000 65.000000,67.000000 65.000000,67.000000 60.500000,             70.357143 53.785714, 71.500000 53.500000, 74.928571 54.642857, 69.750000 65.000000 )))', 4326         ),         GeometryFromText('POINT( 71.000000 60.000000 )', 4326)     ), (         6,6,1,         GeometryFromText(             'MULTIPOLYGON(((80.000000 65.000000,69.750000 65.000000,74.928571 54.642857,             80.000000 55.423077, 80.000000 65.000000 )))', 4326         ),         GeometryFromText('POINT( 73.000000 61.000000 )', 4326)     ), (         7,7,1,         GeometryFromText(             'MULTIPOLYGON(((80.000000 55.423077,74.928571 54.642857,71.500000 53.500000,             71.500000 45.000000, 80.000000 45.000000, 80.000000 55.423077 )))', 4326         ),         GeometryFromText('POINT( 75.000000 48.000000 )', 4326)     ), (         8,8,1,         GeometryFromText(             'MULTIPOLYGON(((67.000000 60.500000,62.875000 57.750000,60.735294 53.470588,             67.045455 52.681818, 70.357143 53.785714, 67.000000 60.500000 )))', 4326         ),         GeometryFromText('POINT( 65.000000 57.000000 )', 4326)     ) ; <\/code><\/pre>\n<p>  \u0410 \u0432\u0442\u043e\u0440\u043e\u0439 \u2013 \u0434\u0430\u043d\u043d\u044b\u0435, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u044f \u0432\u0432\u043e\u0436\u0443 \u0432 plr_modules, \u0438 \u0442\u0438\u043f \u0438\u0442\u043e\u0433\u043e\u0432\u044b\u0445 \u0434\u0430\u043d\u043d\u044b\u0445:<\/p>\n<pre><code class=\"sql\">DROP TABLE IF EXISTS events CASCADE;  CREATE TABLE events (     seqid int not null primary key, -- visit sequence #     plotid int, -- original plot id     bearing real, -- bearing to next waypoint     distance real, -- distance to next waypoint     velocity real, -- velocity of travel, in nm\/hr     traveltime real, -- travel time to next event     loitertime real, -- how long to hang out     totaltraveldist real, -- cummulative distance     totaltraveltime real -- cummulaative time );  SELECT AddGeometryColumn('','events','location','4326','POINT',2); CREATE INDEX &quot;events_location_gist&quot; ON &quot;events&quot; USING gist (&quot;location&quot; gist_geometry_ops);  CREATE TABLE plr_modules (     modseq int4 primary key,     modsrc text ); <\/code><\/pre>\n<p>  \u0421\u043e\u0437\u0434\u0430\u0434\u0438\u043c \u043e\u0441\u043d\u043e\u0432\u043d\u0443\u044e \u0444\u0443\u043d\u043a\u0446\u0438\u044e PL\/R:<\/p>\n<pre><code class=\"sql\">CREATE OR REPLACE FUNCTION solve_tsp(makemap bool, mapname text)    RETURNS SETOF events AS $$     require(TSP)     require(fields)          sql.str &lt;- &quot;select id, st_x(location) as x, st_y(location) as y, location from stands;&quot;     waypts &lt;- pg.spi.exec(sql.str)     dist.matrix &lt;- rdist.earth(waypts[,2:3], R=3949.0)     rtsp &lt;- TSP(dist.matrix)     soln &lt;- solve_TSP(rtsp)     tour &lt;- as.vector(soln)          pg.thrownotice( paste(&quot;tour.dist=&quot;, attributes(soln)$tour_length))          route &lt;- make.route(tour, waypts, dist.matrix)          if (makemap) {         make.map(tour, waypts, mapname)     }          return(route) $$ LANGUAGE 'plr' STRICT; <\/code><\/pre>\n<p>  \u0422\u0435\u043f\u0435\u0440\u044c \u043d\u0430\u043c \u043d\u0443\u0436\u043d\u043e \u0443\u0441\u0442\u0430\u043d\u043e\u0432\u0438\u0442\u044c \u0444\u0443\u043d\u043a\u0446\u0438\u044e make.route():<\/p>\n<pre><code class=\"sql\">INSERT INTO plr_modules VALUES (     0,     $$ make.route &lt;-function(tour, waypts, dist.matrix) {         velocity &lt;- 500.0         starts &lt;- tour[1:(length(tour))-1]         stops &lt;- tour[2:(length(tour))]         dist.vect &lt;- diag( as.matrix( dist.matrix )[starts,stops] )         last.leg &lt;- as.matrix( dist.matrix )[tour[length(tour)],tour[1]]         dist.vect &lt;- c(dist.vect, last.leg )         delta.x &lt;- diff( waypts[tour,]$x )         delta.y &lt;- diff( waypts[tour,]$y )         bearings &lt;- atan( delta.x\/delta.y ) * 180 \/ pi         bearings &lt;- c(bearings,0)         for( i in 1:(length(tour)-1) ) {         if( delta.x[i] &gt; 0.0 && delta.y[i] &gt; 0.0 ) bearings[i] &lt;- bearings[i]         if( delta.x[i] &gt; 0.0 && delta.y[i] &lt; 0.0 ) bearings[i] &lt;- 180.0 + bearings[i]         if( delta.x[i] &lt; 0.0 && delta.y[i] &gt; 0.0 ) bearings[i] &lt;- 360.0 + bearings[i]         if( delta.x[i] &lt; 0.0 && delta.y[i] &lt; 0.0 ) bearings[i] &lt;- 180 + bearings[i]     }          route &lt;- data.frame(seq=1:length(tour), ptid=tour, bearing=bearings, dist.vect=dist.vect,     velocity=velocity, travel.time=dist.vect\/velocity, loiter.time=0.5)     route$total.travel.dist &lt;- cumsum(route$dist.vect)     route$total.travel.time &lt;- cumsum(route$travel.time+route$loiter.time)     route$location &lt;- waypts[tour,]$location          return(route)}$$ ); <\/code><\/pre>\n<p>  \u0418 \u0444\u0443\u043d\u043a\u0446\u0438\u044e make.map():<\/p>\n<pre><code class=\"sql\">INSERT INTO plr_modules VALUES (     1,      $$make.map &lt;-function(tour, waypts, mapname) {         require(maps)                  jpeg(file=mapname, width = 480, height = 480, pointsize = 10, quality = 75)         map('world2', xlim = c(20, 120), ylim=c(20,80) )         map.axes()         grid()         arrows(             waypts[tour[1:(length(tour)-1)],]$x,              waypts[tour[1:(length(tour)-1)],]$y,             waypts[tour[2:(length(tour))],]$x,              waypts[tour[2:(length(tour))],]$y,             angle=10, lwd=1, length=.15, col=&quot;red&quot;         )         points( waypts$x, waypts$y, pch=3, cex=2 )         points( waypts$x, waypts$y, pch=20, cex=0.8 )         text( waypts$x+2, waypts$y+2, as.character( waypts$id ), cex=0.8 )         title( &quot;TSP soln using PL\/R&quot; )         dev.off()     }$$ ); <\/code><\/pre>\n<p>  \u0417\u0430\u043f\u0443\u0441\u043a\u0430\u0435\u043c \u0444\u0443\u043d\u043a\u0446\u0438\u044e \u043f\u043e\u043b\u0443\u0447\u0435\u043d\u0438\u044f TSP \u043c\u0435\u0442\u043a\u0438:<\/p>\n<pre><code class=\"sql\">-- only needed if INSERT INTO plr_modules was in same session SELECT reload_plr_modules(); SELECT seqid, plotid, bearing, distance, velocity, traveltime, loitertime, totaltraveldist FROM solve_tsp(true, 'tsp.jpg'); NOTICE: tour.dist= 2804.58129355858 seqid | plotid | bearing | distance | velocity | traveltime | loitertime | totaltraveldist -------+--------+---------+----------+----------+------------+------------+----------------- 1 | 8 | 131.987 | 747.219 | 500 | 1.49444 | 0.5 | 747.219 2 | 7 | -90 | 322.719 | 500 | 0.645437 | 0.5 | 1069.94 3 | 4 | 284.036 | 195.219 | 500 | 0.390438 | 0.5 | 1265.16 4 | 3 | 343.301 | 699.683 | 500 | 1.39937 | 0.5 | 1964.84 5 | 1 | 63.4349 | 98.2015 | 500 | 0.196403 | 0.5 | 2063.04 6 | 2 | 84.2894 | 345.957 | 500 | 0.691915 | 0.5 | 2409 7 | 6 | 243.435 | 96.7281 | 500 | 0.193456 | 0.5 | 2505.73 8 | 5 | 0 | 298.855 | 500 | 0.59771 | 0.5 | 2804.58 (8 rows) <\/code><\/pre>\n<p>  \u0420\u0430\u0441\u0448\u0438\u0440\u0435\u043d\u043d\u044b\u0439 \u0440\u0435\u0436\u0438\u043c \u043f\u0440\u043e\u0441\u043c\u043e\u0442\u0440\u0430:<\/p>\n<pre><code class=\"sql\">\\x SELECT * FROM solve_tsp(true, 'tsp.jpg'); NOTICE: tour.dist= 2804.58129355858 -[ RECORD 1 ]---+--------------------------------------------------- seqid | 1 plotid | 3 bearing | 104.036 distance | 195.219 velocity | 500 traveltime | 0.390438 loitertime | 0.5 totaltraveldist | 195.219 totaltraveltime | 0.890438 location | 0101000020E610000000000000000050400000000000804840 -[ RECORD 2 ]---+--------------------------------------------------- [...] <\/code><\/pre>\n<p>  \u0422\u0430\u043a\u0438\u043c \u043e\u0431\u0440\u0430\u0437\u043e\u043c, \u043c\u044b \u043f\u043e\u043b\u0443\u0447\u0438\u043b\u0438 \u043f\u043e\u0440\u044f\u0434\u043e\u043a, \u0432 \u043a\u043e\u0442\u043e\u0440\u043e\u043c \u0441\u0442\u043e\u0438\u0442 \u043f\u043e\u0441\u0435\u0449\u0430\u0442\u044c \u044d\u0442\u0438 \u0433\u043e\u0440\u043e\u0434\u0430, \u0440\u0430\u0441\u0441\u0442\u043e\u044f\u043d\u0438\u0435 \u043c\u0435\u0436\u0434\u0443 \u043d\u0438\u043c\u0438 \u0438 \u0442.\u0434. \u041a\u0440\u043e\u043c\u0435 \u0442\u043e\u0433\u043e, \u0443 \u043d\u0430\u0441 \u0435\u0441\u0442\u044c \u0438 \u043d\u0430\u0433\u043b\u044f\u0434\u043d\u043e\u0435 \u0440\u0435\u0448\u0435\u043d\u0438\u0435 \u0437\u0430\u0434\u0430\u0447\u0438 \u043a\u043e\u043c\u043c\u0438\u0432\u043e\u044f\u0436\u0451\u0440\u0430:<\/p>\n<p>  <img decoding=\"async\" src=\"https:\/\/habrastorage.org\/files\/148\/056\/434\/148056434d144c3ca2d26155cfe8a2b7.png\"\/><br \/>  \u0420\u0430\u0441\u0441\u043c\u043e\u0442\u0440\u0438\u043c \u0435\u0449\u0435 \u043e\u0434\u0438\u043d \u043f\u0440\u0438\u043c\u0435\u0440, \u043d\u0430 \u044d\u0442\u043e\u0442 \u0440\u0430\u0437 \u0441 \u0441\u0435\u0439\u0441\u043c\u0438\u0447\u0435\u0441\u043a\u0438\u043c\u0438 \u0434\u0430\u043d\u043d\u044b\u043c\u0438. <\/p>\n<p>  \u041a\u043e\u0433\u0434\u0430 \u043f\u0440\u043e\u0438\u0441\u0445\u043e\u0434\u0438\u0442 \u0437\u0435\u043c\u043b\u0435\u0442\u0440\u044f\u0441\u0435\u043d\u0438\u0435, \u043e\u043d\u043e \u043e\u0431\u044b\u0447\u043d\u043e \u0434\u043b\u0438\u0442\u0441\u044f 15-20 \u0441\u0435\u043a\u0443\u043d\u0434, \u0438 \u0441\u0435\u0439\u0441\u043c\u043e\u043b\u043e\u0433\u0438 \u0441\u043e\u0431\u0438\u0440\u0430\u044e\u0442 \u0434\u0430\u043d\u043d\u044b\u0435 \u043e\u0431 \u0438\u043d\u0442\u0435\u043d\u0441\u0438\u0432\u043d\u043e\u0441\u0442\u0438 \u0435\u0433\u043e \u043a\u043e\u043b\u0435\u0431\u0430\u043d\u0438\u0439. \u0422\u043e \u0435\u0441\u0442\u044c \u0443 \u043d\u0430\u0441 \u0435\u0441\u0442\u044c \u0432\u0440\u0435\u043c\u0435\u043d\u043d\u044b\u0435 \u0440\u044f\u0434\u044b (timeseries) \u0434\u0430\u043d\u043d\u044b\u0445 \u0432 \u0444\u043e\u0440\u043c\u0430\u0442\u0435 \u043e\u0441\u0446\u0438\u043b\u043e\u0433\u0440\u0430\u043c\u043c\u044b (waveform data). \u0414\u0430\u043d\u043d\u044b\u0435 \u0445\u0440\u0430\u043d\u044f\u0442\u0441\u044f \u0432 \u0432\u0438\u0434\u0435 \u043c\u0430\u0441\u0441\u0438\u0432\u0430 \u0447\u0438\u0441\u0435\u043b \u0441 \u043f\u043b\u0430\u0432\u0430\u044e\u0449\u0435\u0439 \u0437\u0430\u043f\u044f\u0442\u043e\u0439 (floats), \u0437\u0430\u0440\u0435\u0433\u0438\u0441\u0442\u0440\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u044b\u0445 \u0432\u043e \u0432\u0440\u0435\u043c\u044f \u0441\u0435\u0439\u0441\u043c\u0438\u0447\u0435\u0441\u043a\u043e\u0433\u043e \u0441\u043e\u0431\u044b\u0442\u0438\u044f \u0441 \u043f\u043e\u0441\u0442\u043e\u044f\u043d\u043d\u043e\u0439 \u0447\u0430\u0441\u0442\u043e\u0442\u043e\u0439 \u0432\u044b\u0431\u043e\u0440\u043a\u0438. \u041e\u043d\u0438 \u0434\u043e\u0441\u0442\u0443\u043f\u043d\u044b \u0438\u0437 \u043e\u043d\u043b\u0430\u0439\u043d-\u0438\u0441\u0442\u043e\u0447\u043d\u0438\u043a\u043e\u0432 \u0432 \u043e\u0442\u0434\u0435\u043b\u044c\u043d\u044b\u0445 \u0444\u0430\u0439\u043b\u0430\u0445 \u0434\u043b\u044f \u043a\u0430\u0436\u0434\u043e\u0439 \u0430\u043a\u0442\u0438\u0432\u043d\u043e\u0441\u0442\u0438. \u0412 \u043a\u0430\u0436\u0434\u043e\u043c \u0444\u0430\u0439\u043b\u0435 \u043d\u0430\u0445\u043e\u0434\u0438\u0442\u0441\u044f \u043e\u043a\u043e\u043b\u043e 16000 \u044d\u043b\u0435\u043c\u0435\u043d\u0442\u043e\u0432.<\/p>\n<p>  \u0417\u0430\u0433\u0440\u0443\u0437\u0438\u043c 1000 \u0441\u0435\u0439\u0441\u043c\u0438\u0447\u0435\u0441\u043a\u0438\u0445 \u0430\u043a\u0442\u0438\u0432\u043d\u043e\u0441\u0442\u0435\u0439 \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e PL\/pgSQL:<\/p>\n<pre><code class=\"sql\">DROP TABLE IF EXISTS test_ts;  CREATE TABLE test_ts (     dataid bigint NOT NULL PRIMARY KEY,     data double precision[] );  CREATE OR REPLACE FUNCTION load_test(int)    RETURNS text AS  $$ DECLARE     i int;     arr text;     sql text; BEGIN     arr := pg_read_file('array-data.csv', 0, 500000);          FOR i IN 1..$1 LOOP         sql := $i$INSERT INTO test_ts(dataid,data) VALUES ($i$ || i || $i$,'{$i$ || arr || $i$}')$i$;         EXECUTE sql;     END LOOP;          RETURN 'OK'; END; $$ LANGUAGE plpgsql;  SELECT load_test(1000); load_test ----------- OK (1 row) Time: 37336.539 ms <\/code><\/pre>\n<p>  \u042d\u0442\u043e \u043c\u043e\u0436\u043d\u043e \u0441\u0434\u0435\u043b\u0430\u0442\u044c \u0438 \u043f\u043e-\u0434\u0440\u0443\u0433\u043e\u043c\u0443, \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e R, \u0438 \u044d\u0442\u043e \u0437\u0430\u0439\u043c\u0435\u0442 \u0432 \u0434\u0432\u0430 \u0440\u0430\u0437\u0430 \u043c\u0435\u043d\u044c\u0448\u0435 \u0432\u0440\u0435\u043c\u0435\u043d\u0438 \u2013 \u0442\u043e\u0442 \u0440\u0435\u0434\u043a\u0438\u0439 \u0441\u043b\u0443\u0447\u0430\u0439, \u043a\u043e\u0433\u0434\u0430 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u0435 PL\/R \u0443\u0441\u043a\u043e\u0440\u044f\u0435\u0442, \u0430 \u043d\u0435 \u0437\u0430\u043c\u0435\u0434\u043b\u044f\u0435\u0442 \u043f\u0440\u043e\u0446\u0435\u0441\u0441:<\/p>\n<pre><code class=\"sql\">DROP TABLE IF EXISTS test_ts_obj;  CREATE TABLE test_ts_obj (     dataid serial PRIMARY KEY,     data bytea );  CREATE OR REPLACE FUNCTION make_r_object(fname text)    RETURNS bytea AS  $$     myvar&lt;-scan(fname,sep=&quot;,&quot;)     return(myvar); $$ LANGUAGE 'plr' IMMUTABLE;  INSERT INTO test_ts_obj (data)          SELECT make_r_object('array-data.csv')          FROM generate_series(1,1000);      INSERT 0 1000 Time: 12166.137 ms <\/code><\/pre>\n<p>  \u0421\u043e\u0437\u0434\u0430\u0434\u0438\u043c \u043e\u0441\u0446\u0438\u043b\u043e\u0433\u0440\u0430\u043c\u043c\u0443:<\/p>\n<pre><code class=\"sql\">CREATE OR REPLACE FUNCTION plot_ts(ts double precision[])    RETURNS bytea AS  $$     library(quantmod)     library(cairoDevice)     library(RGtk2)      pixmap &lt;- gdkPixmapNew(w=500, h=500, depth=24)     asCairoDevice(pixmap)     plot(ts,type=&quot;l&quot;)          plot_pixbuf &lt;- gdkPixbufGetFromDrawable(         NULL, pixmap, pixmap$getColormap(), 0, 0, 0, 0, 500, 500     )     buffer &lt;- gdkPixbufSaveToBufferv(         plot_pixbuf,         &quot;jpeg&quot;,         character(0),         character(0)     )$buffer          return(buffer) $$ LANGUAGE 'plr' IMMUTABLE;  SELECT plr_get_raw(plot_ts(data)) FROM test_ts WHERE dataid = 42; <\/code><\/pre>\n<p>  \u041f\u043e\u043b\u0443\u0447\u0430\u0435\u043c \u0432\u043e\u0442 \u0442\u0430\u043a\u0443\u044e \u043a\u0430\u0440\u0442\u0438\u043d\u043a\u0443 \u0434\u043b\u044f \u043a\u043e\u043d\u043a\u0440\u0435\u0442\u043d\u043e\u0433\u043e \u0437\u0435\u043c\u043b\u0435\u0442\u0440\u044f\u0441\u0435\u043d\u0438\u044f:<\/p>\n<p>  <img decoding=\"async\" src=\"https:\/\/habrastorage.org\/files\/836\/d3b\/a76\/836d3ba769cd44d0b3501405c3e2f640.png\"\/><br \/>  \u0422\u0435\u043f\u0435\u0440\u044c \u0435\u0451 \u043d\u0443\u0436\u043d\u043e \u043f\u0440\u043e\u0430\u043d\u0430\u043b\u0438\u0437\u0438\u0440\u043e\u0432\u0430\u0442\u044c, \u0447\u0442\u043e\u0431\u044b, \u043d\u0430\u043f\u0440\u0438\u043c\u0435\u0440, \u0443\u0437\u043d\u0430\u0442\u044c, \u043a\u0430\u043a \u043b\u0443\u0447\u0448\u0435 \u043f\u0440\u043e\u0435\u043a\u0442\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0437\u0434\u0430\u043d\u0438\u044f \u0432 \u0437\u043e\u043d\u0435 \u0441 \u043f\u043e\u0434\u043e\u0431\u043d\u043e\u0439 \u0441\u0435\u0439\u0441\u043c\u0438\u0447\u0435\u0441\u043a\u043e\u0439 \u0430\u043a\u0442\u0438\u0432\u043d\u043e\u0441\u0442\u044c\u044e. \u0412\u044b \u043d\u0430\u0432\u0435\u0440\u043d\u044f\u043a\u0430 \u043f\u043e\u043c\u043d\u0438\u0442\u0435 \u0438\u0437 \u0448\u043a\u043e\u043b\u044c\u043d\u043e\u0433\u043e \u043a\u0443\u0440\u0441\u0430 \u0444\u0438\u0437\u0438\u043a\u0438 \u0442\u0430\u043a\u043e\u0435 \u043f\u043e\u043d\u044f\u0442\u0438\u0435 \u043a\u0430\u043a \u00ab\u0440\u0435\u0437\u043e\u043d\u0430\u043d\u0441\u043d\u0430\u044f \u0447\u0430\u0441\u0442\u043e\u0442\u0430\u00bb. \u041d\u0430 \u0432\u0441\u044f\u043a\u0438\u0439 \u0441\u043b\u0443\u0447\u0430\u0439 \u043d\u0430\u043f\u043e\u043c\u043d\u044e, \u0447\u0442\u043e \u044d\u0442\u043e \u0442\u0430\u043a\u0430\u044f \u0447\u0430\u0441\u0442\u043e\u0442\u0430 \u043a\u043e\u043b\u0435\u0431\u0430\u043d\u0438\u0439, \u043f\u0440\u0438 \u043a\u043e\u0442\u043e\u0440\u043e\u0439 \u0430\u043c\u043f\u043b\u0438\u0442\u0443\u0434\u0430 \u043a\u043e\u043b\u0435\u0431\u0430\u043d\u0438\u0439 \u0440\u0435\u0437\u043a\u043e \u0432\u043e\u0437\u0440\u0430\u0441\u0442\u0430\u0435\u0442. \u042d\u0442\u0430 \u0447\u0430\u0441\u0442\u043e\u0442\u0430 \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u044f\u0435\u0442\u0441\u044f \u0441\u0432\u043e\u0439\u0441\u0442\u0432\u0430\u043c\u0438 \u0441\u0438\u0441\u0442\u0435\u043c\u044b. \u0422\u043e \u0435\u0441\u0442\u044c \u0432 \u0437\u043e\u043d\u0435 \u0441 \u0441\u0435\u0439\u0441\u043c\u0438\u0447\u0435\u0441\u043a\u043e\u0439 \u0430\u043a\u0442\u0438\u0432\u043d\u043e\u0441\u0442\u044c\u044e \u043d\u0443\u0436\u043d\u043e \u043f\u0440\u043e\u0435\u043a\u0442\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0441\u0442\u0440\u043e\u0435\u043d\u0438\u044f \u0442\u0430\u043a\u0438\u043c \u043e\u0431\u0440\u0430\u0437\u043e\u043c, \u0447\u0442\u043e\u0431\u044b \u0438\u0445 \u0440\u0435\u0437\u043e\u043d\u0430\u043d\u0441\u043d\u0430\u044f \u0447\u0430\u0441\u0442\u043e\u0442\u0430 \u043d\u0435 \u0441\u043e\u0432\u043f\u0430\u0434\u0430\u043b\u0430 \u0441 \u0447\u0430\u0441\u0442\u043e\u0442\u043e\u0439 \u0437\u0435\u043c\u043b\u0435\u0442\u0440\u044f\u0441\u0435\u043d\u0438\u0439. \u042d\u0442\u043e \u043c\u043e\u0436\u043d\u043e \u0441\u0434\u0435\u043b\u0430\u0442\u044c \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e R:<\/p>\n<pre><code class=\"sql\">CREATE OR REPLACE FUNCTION plot_fftps(ts bytea)    RETURNS bytea AS  $$     library(quantmod)     library(cairoDevice)     library(RGtk2)          fourier&lt;-fft(ts)     magnitude&lt;-Mod(fourier)          y2 &lt;- magnitude[1:(length(magnitude)\/10)]     x2 &lt;- 1:length(y2)\/length(magnitude)     mydf &lt;- data.frame(x2,y2)     pixmap &lt;- gdkPixmapNew(w=500, h=500, depth=24)          asCairoDevice(pixmap)     plot(mydf,type=&quot;l&quot;)     plot_pixbuf &lt;- gdkPixbufGetFromDrawable(         NULL, pixmap, pixmap$getColormap(), 0, 0, 0, 0, 500, 500     )     buffer &lt;- gdkPixbufSaveToBufferv(         plot_pixbuf, &quot;jpeg&quot;, character(0), character(0)     )$buffer          return(buffer) $$ LANGUAGE 'plr' IMMUTABLE;  SELECT plr_get_raw(plot_fftps(data)) FROM test_ts_obj WHERE dataid = 42; <\/code><\/pre>\n<p>  \u0418 \u0432\u043e\u0442 \u0442\u0430\u043a \u0432\u044b\u0433\u043b\u044f\u0434\u0438\u0442 \u043e\u043a\u043e\u043d\u0447\u0430\u0442\u0435\u043b\u044c\u043d\u044b\u0439 \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442, \u043f\u043e\u043a\u0430\u0437\u044b\u0432\u0430\u044e\u0449\u0438\u0439 \u0447\u0430\u0441\u0442\u043e\u0442\u0443 \u0432\u0438\u0431\u0440\u0430\u0446\u0438\u0439 \u0438 \u0438\u0445 \u0430\u043c\u043f\u043b\u0438\u0442\u0443\u0434\u0443:<\/p>\n<p>  <img decoding=\"async\" src=\"https:\/\/habrastorage.org\/files\/690\/c50\/fcf\/690c50fcf3dc42598d3ca0efbc0b643d.png\"\/><br \/>  \u0418\u043c\u0435\u044f \u0442\u0430\u043a\u043e\u0439 \u0433\u0440\u0430\u0444\u0438\u043a \u043f\u0435\u0440\u0435\u0434 \u0433\u043b\u0430\u0437\u0430\u043c\u0438, \u0430\u0440\u0445\u0438\u0442\u0435\u043a\u0442\u043e\u0440 \u043c\u043e\u0436\u0435\u0442 \u0441\u0434\u0435\u043b\u0430\u0442\u044c \u0440\u0430\u0441\u0447\u0435\u0442\u044b \u0438 \u0441\u043f\u0440\u043e\u0435\u043a\u0442\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0441\u0442\u0440\u043e\u0435\u043d\u0438\u0435, \u043a\u043e\u0442\u043e\u0440\u043e\u0435 \u043d\u0435 \u0440\u0443\u0445\u043d\u0435\u0442 \u043f\u0440\u0438 \u043f\u0435\u0440\u0432\u043e\u043c \u0436\u0435 \u043f\u043e\u0434\u0437\u0435\u043c\u043d\u043e\u043c \u0442\u043e\u043b\u0447\u043a\u0435.<\/p>\n<p>  \u041a\u0430\u043a \u0432\u044b \u0432\u0438\u0434\u0438\u0442\u0435, \u0443 PL\/R \u0435\u0441\u0442\u044c \u043c\u043d\u043e\u0436\u0435\u0441\u0442\u0432\u043e \u0441\u0444\u0435\u0440 \u043f\u0440\u0438\u043c\u0435\u043d\u0435\u043d\u0438\u044f, \u0442\u0430\u043a \u043a\u0430\u043a \u043e\u043d \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u0435\u0442 \u0441\u0432\u044f\u0437\u0430\u0442\u044c \u043f\u0440\u043e\u0434\u0432\u0438\u043d\u0443\u0442\u0443\u044e \u0430\u043d\u0430\u043b\u0438\u0442\u0438\u043a\u0443 \u0441 \u0431\u0430\u0437\u0430\u043c\u0438 \u0434\u0430\u043d\u043d\u044b\u0445 \u0438 \u043e\u0434\u043d\u043e\u0432\u0440\u0435\u043c\u0435\u043d\u043d\u043e \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u0444\u0443\u043d\u043a\u0446\u0438\u043e\u043d\u0430\u043b\u044c\u043d\u043e\u0441\u0442\u044c R \u0438 PostgreSQL \u0441\u043e \u0432\u0441\u0435\u043c\u0438 \u0438\u0445 \u043f\u0440\u0435\u0438\u043c\u0443\u0449\u0435\u0441\u0442\u0432\u0430\u043c\u0438. \u041d\u0430\u0434\u0435\u044e\u0441\u044c, \u044d\u0442\u0430 \u0441\u0442\u0430\u0442\u044c\u044f \u043e\u043a\u0430\u0436\u0435\u0442\u0441\u044f \u0432\u0430\u043c \u043f\u043e\u043b\u0435\u0437\u043d\u0430, \u0438 \u0432\u044b \u043d\u0430\u0439\u0434\u0435\u0442\u0435 \u043f\u0440\u0438\u043c\u0435\u043d\u0435\u043d\u0438\u0435 \u0441\u0442\u043e\u043b\u044c \u044d\u0444\u0444\u0435\u043a\u0442\u0438\u0432\u043d\u043e\u043c\u0443 \u0438 \u043c\u043d\u043e\u0433\u043e\u0444\u0443\u043d\u043a\u0446\u0438\u043e\u043d\u0430\u043b\u044c\u043d\u043e\u043c\u0443 \u0438\u043d\u0441\u0442\u0440\u0443\u043c\u0435\u043d\u0442\u0443.<\/p>\n<p>  <i>\u041f\u0440\u0438\u0433\u043b\u0430\u0448\u0430\u0435\u043c \u0432\u0430\u0441 \u0442\u0430\u043a\u0436\u0435 \u043e\u0437\u043d\u0430\u043a\u043e\u043c\u0438\u0442\u044c\u0441\u044f \u0441 \u0438\u0441\u0445\u043e\u0434\u043d\u044b\u043c\u0438 \u043c\u0430\u0442\u0435\u0440\u0438\u0430\u043b\u0430\u043c\u0438, \u043d\u0430 \u043e\u0441\u043d\u043e\u0432\u0435 \u043a\u043e\u0442\u043e\u0440\u044b\u0445 \u0431\u044b\u043b\u0430 \u043f\u043e\u0434\u0433\u043e\u0442\u043e\u0432\u043b\u0435\u043d\u0430 \u0434\u0430\u043d\u043d\u0430\u044f \u0441\u0442\u0430\u0442\u044c\u044f: <a href=\"http:\/\/pgday.ru\/files\/papers\/25\/pgday2015.joe.conway.plr.pdf\">\u043f\u0440\u0435\u0437\u0435\u043d\u0442\u0430\u0446\u0438\u044f<\/a> \u0438 <a href=\"https:\/\/youtu.be\/83MC6dBDpkM?list=PL83V-7VhzqkpQbw7hn6b32OmxK8SRKoHU\">\u0432\u0438\u0434\u0435\u043e<\/a> \u0441 \u0432\u044b\u0441\u0442\u0443\u043f\u043b\u0435\u043d\u0438\u044f Joe Conway \u043d\u0430 PG Day&#8217;15 Russia. \u0415\u0441\u043b\u0438 \u0442\u0435\u043c\u0430 \u043f\u0440\u0438\u043c\u0435\u043d\u0435\u043d\u0438\u044f PL\/R \u043a\u0430\u0436\u0435\u0442\u0441\u044f \u0432\u0430\u043c \u0438\u043d\u0442\u0435\u0440\u0435\u0441\u043d\u043e\u0439, \u043e\u0431\u044f\u0437\u0430\u0442\u0435\u043b\u044c\u043d\u043e \u043f\u043e\u0434\u0435\u043b\u0438\u0442\u0435\u0441\u044c \u0441\u0432\u043e\u0438\u043c\u0438 \u0441\u043e\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u0438\u044f\u043c\u0438 \u0438 \u0438\u0434\u0435\u044f\u043c\u0438. \u041a\u0442\u043e \u0437\u043d\u0430\u0435\u0442, \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e, \u043c\u044b \u043e\u0440\u0433\u0430\u043d\u0438\u0437\u0443\u0435\u043c \u0434\u043e\u043a\u043b\u0430\u0434 \u043d\u0430 \u044d\u0442\u0443 \u0442\u0435\u043c\u0443 \u043d\u0430 \u043f\u0440\u0435\u0434\u0441\u0442\u043e\u044f\u0449\u0435\u043c PG Day&#8217;16 \u0432 \u0438\u044e\u043b\u0435. \u041a\u0430\u043a \u043e\u0431\u044b\u0447\u043d\u043e, \u0436\u0434\u0435\u043c \u0432\u0430\u0448\u0438\u0445 \u043a\u043e\u043c\u043c\u0435\u043d\u0442\u0430\u0440\u0438\u0435\u0432.<\/i>               <\/p>\n<div class=\"clear\"><\/div>\n<p> \u0441\u0441\u044b\u043b\u043a\u0430 \u043d\u0430 \u043e\u0440\u0438\u0433\u0438\u043d\u0430\u043b \u0441\u0442\u0430\u0442\u044c\u0438 <a href=\"https:\/\/habrahabr.ru\/post\/275487\/\"> https:\/\/habrahabr.ru\/post\/275487\/<\/a><\/p>\n","protected":false},"excerpt":{"rendered":"<p>       <i>\u0414\u0440\u0443\u0437\u044c\u044f, \u043d\u0430 \u043f\u0440\u043e\u0448\u0435\u0434\u0448\u0435\u0439 \u0432 \u043f\u0440\u043e\u0448\u043b\u043e\u043c \u0433\u043e\u0434\u0443 \u043a\u043e\u043d\u0444\u0435\u0440\u0435\u043d\u0446\u0438\u0438 <a href=\"http:\/\/pgday.ru\/ru\/2015\">PG Day&#8217;15 Russia<\/a> \u043e\u0434\u0438\u043d \u0438\u0437 \u043d\u0430\u0448\u0438\u0445 \u0434\u043e\u043a\u043b\u0430\u0434\u0447\u0438\u043a\u043e\u0432, Joseph Conway, \u043f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u0438\u043b \u0438\u043d\u0442\u0435\u0440\u0435\u0441\u043d\u044b\u0439 \u043c\u0430\u0442\u0435\u0440\u0438\u0430\u043b \u043e\u0431 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u0438 \u0441\u043e\u0437\u0434\u0430\u043d\u043d\u043e\u0433\u043e \u0438 \u043f\u043e\u0434\u0434\u0435\u0440\u0436\u0438\u0432\u0430\u0435\u043c\u043e\u0433\u043e \u0438\u043c \u0443\u0436\u0435 \u0431\u043e\u043b\u044c\u0448\u0435 \u0434\u0435\u0441\u044f\u0442\u0438 \u043b\u0435\u0442 \u0440\u0430\u0441\u0448\u0438\u0440\u0435\u043d\u0438\u044f PL\/R, \u043a\u043e\u0442\u043e\u0440\u043e\u0435 \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u0435\u0442 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u044f\u0437\u044b\u043a \u0434\u043b\u044f \u0441\u0442\u0430\u0442\u0438\u0441\u0442\u0438\u0447\u0435\u0441\u043a\u043e\u0433\u043e \u0430\u043d\u0430\u043b\u0438\u0437\u0430 R \u0432\u043d\u0443\u0442\u0440\u0438 \u0432\u0441\u0435\u043c\u0438 \u043b\u044e\u0431\u0438\u043c\u043e\u0439 \u0431\u0430\u0437\u044b \u0434\u0430\u043d\u043d\u044b\u0445. \u0425\u043e\u0447\u0443 \u043f\u0440\u0435\u0434\u043b\u043e\u0436\u0438\u0442\u044c \u0432\u0430\u0448\u0435\u043c\u0443 \u0432\u043d\u0438\u043c\u0430\u043d\u0438\u044e follow-up \u0441\u0442\u0430\u0442\u044c\u044e, \u0441\u043e\u0437\u0434\u0430\u043d\u043d\u0443\u044e \u043d\u0430 \u043e\u0441\u043d\u043e\u0432\u0435 \u043c\u0430\u0442\u0435\u0440\u0438\u0430\u043b\u043e\u0432, \u043f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u043b\u0435\u043d\u043d\u044b\u0445 <a href=\"http:\/\/pgday.ru\/ru\/2015\/papers\/25\">\u0432 \u0434\u043e\u043a\u043b\u0430\u0434\u0435 Joe<\/a>. \u0417\u0430\u0434\u0430\u0447\u0430 \u0434\u0430\u043d\u043d\u043e\u0439 \u043f\u0443\u0431\u043b\u0438\u043a\u0430\u0446\u0438\u0438 \u2014 \u043e\u0431\u0437\u043e\u0440\u043d\u043e \u043f\u043e\u0437\u043d\u0430\u043a\u043e\u043c\u0438\u0442\u044c \u0432\u0430\u0441 \u0441 \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u044f\u043c\u0438 \u044f\u0437\u044b\u043a\u0430 PL\/R. \u041d\u0430\u0434\u0435\u044e\u0441\u044c, \u0447\u0442\u043e \u0432\u044b \u043d\u0430\u0439\u0434\u0435\u0442\u0435 \u043f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u043b\u0435\u043d\u043d\u0443\u044e \u0437\u0434\u0435\u0441\u044c \u0438\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0438\u044e \u043f\u043e\u043b\u0435\u0437\u043d\u043e\u0439 \u0434\u043b\u044f \u0441\u0435\u0431\u044f.<\/i><\/p>\n<p>  <img decoding=\"async\" src=\"https:\/\/habrastorage.org\/files\/d7f\/c27\/2b9\/d7fc272b9c95473abe52ffef4143dc2f.png\" alt=\"image\"\/><\/p>\n<p>  \u041f\u043e\u0441\u043b\u0435\u0434\u043d\u0438\u0435 \u0442\u0435\u043d\u0434\u0435\u043d\u0446\u0438\u0438 \u0432 \u043e\u0431\u043b\u0430\u0441\u0442\u0438 Big Data \u043f\u043e\u043e\u0449\u0440\u044f\u044e\u0442 \u0441\u0431\u043b\u0438\u0436\u0435\u043d\u0438\u0435 \u0430\u043d\u0430\u043b\u0438\u0442\u0438\u043a\u0438 \u0438 \u0434\u0430\u043d\u043d\u044b\u0445, \u0432 \u0442\u043e \u0432\u0440\u0435\u043c\u044f \u043a\u0430\u043a PL\/R \u043d\u0435\u043d\u0430\u0432\u044f\u0437\u0447\u0438\u0432\u043e \u043f\u0440\u0435\u0434\u043e\u0441\u0442\u0430\u0432\u043b\u044f\u0435\u0442 \u0442\u0430\u043a\u043e\u0439 \u0441\u0435\u0440\u0432\u0438\u0441 \u0432\u043e\u0442 \u0443\u0436\u0435 12 \u043b\u0435\u0442! \u0415\u0441\u043b\u0438 \u0432\u0434\u0440\u0443\u0433 \u0432\u044b \u043d\u0435 \u0432 \u043a\u0443\u0440\u0441\u0435, PL\/R \u2013 \u044d\u0442\u043e \u0440\u0430\u0441\u0448\u0438\u0440\u0435\u043d\u0438\u0435 \u0434\u043b\u044f PostgreSQL, \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u044e\u0449\u0435\u0435 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c R, \u044f\u0437\u044b\u043a \u0434\u043b\u044f \u043c\u0430\u0442\u0435\u043c\u0430\u0442\u0438\u0447\u0435\u0441\u043a\u0438\u0445 \u0440\u0430\u0441\u0447\u0435\u0442\u043e\u0432, \u043f\u0440\u044f\u043c\u043e \u0438\u0437 PostgreSQL \u0434\u043b\u044f \u0442\u043e\u0433\u043e, \u0447\u0442\u043e\u0431\u044b \u043b\u0435\u0433\u043a\u043e \u0438 \u043f\u0440\u043e\u0441\u0442\u043e \u043f\u043e\u043b\u0443\u0447\u0430\u0442\u044c \u0440\u0430\u0437\u0432\u0435\u0440\u043d\u0443\u0442\u0443\u044e \u0430\u043d\u0430\u043b\u0438\u0442\u0438\u043a\u0443. \u0420\u0430\u0441\u0448\u0438\u0440\u0435\u043d\u0438\u0435 \u0434\u043e\u0441\u0442\u0443\u043f\u043d\u043e \u0438 \u0430\u043a\u0442\u0438\u0432\u043d\u043e \u0441\u043e\u0432\u0435\u0440\u0448\u0435\u043d\u0441\u0442\u0432\u0443\u0435\u0442\u0441\u044f \u0441 2003 \u0433\u043e\u0434\u0430. \u041e\u043d\u043e \u0440\u0430\u0431\u043e\u0442\u0430\u0435\u0442 \u0441\u043e \u0432\u0441\u0435\u043c\u0438 \u043f\u043e\u0434\u0434\u0435\u0440\u0436\u0438\u0432\u0430\u0435\u043c\u044b\u043c\u0438 \u0432\u0435\u0440\u0441\u0438\u044f\u043c\u0438 PostgreSQL \u0438 \u0441\u043e \u0432\u0441\u0435\u043c\u0438 \u0441\u0432\u0435\u0436\u0438\u043c\u0438 \u0432\u0435\u0440\u0441\u0438\u044f\u043c\u0438 R. \u0422\u044b\u0441\u044f\u0447\u0438 \u043b\u044e\u0434\u0435\u0439 \u0432\u043e \u0432\u0441\u0435\u043c \u043c\u0438\u0440\u0435 \u0443\u0436\u0435 \u043e\u0446\u0435\u043d\u0438\u043b\u0438 \u0435\u0433\u043e \u0443\u0434\u043e\u0431\u0441\u0442\u0432\u043e \u0438 \u044d\u0444\u0444\u0435\u043a\u0442\u0438\u0432\u043d\u043e\u0441\u0442\u044c. \u0414\u0430\u0432\u0430\u0439\u0442\u0435 \u0436\u0435 \u0440\u0430\u0437\u0431\u0435\u0440\u0435\u043c\u0441\u044f, \u0447\u0442\u043e \u0442\u0430\u043a\u043e\u0435 PL\/R, \u043e\u0431\u0441\u0443\u0434\u0438\u043c \u0434\u043e\u0441\u0442\u043e\u0438\u043d\u0441\u0442\u0432\u0430 \u0438 \u043d\u0435\u0434\u043e\u0441\u0442\u0430\u0442\u043a\u0438 \u0442\u0430\u043a\u043e\u0433\u043e \u043f\u043e\u0434\u0445\u043e\u0434\u0430 \u043a \u0430\u043d\u0430\u043b\u0438\u0437\u0443 \u0434\u0430\u043d\u043d\u044b\u0445 \u0438 \u0440\u0430\u0441\u0441\u043c\u043e\u0442\u0440\u0438\u043c \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u043e \u043f\u0440\u0438\u043c\u0435\u0440\u043e\u0432 \u0434\u043b\u044f \u043d\u0430\u0433\u043b\u044f\u0434\u043d\u043e\u0441\u0442\u0438.  <\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[],"tags":[],"class_list":["post-273304","post","type-post","status-publish","format-standard","hentry"],"_links":{"self":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts\/273304","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=273304"}],"version-history":[{"count":0,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts\/273304\/revisions"}],"wp:attachment":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=273304"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=273304"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=273304"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}