{"id":74953,"date":"2020-03-22T08:42:22","date_gmt":"2020-03-22T05:42:22","guid":{"rendered":"https:\/\/prohoster.info\/blog\/administrirovanie\/dba-gramotno-organizovyvaem-sinhronizaczii-i-importy"},"modified":"2020-03-22T08:42:22","modified_gmt":"2020-03-22T05:42:22","slug":"dba-gramotno-organizovyvaem-sinhronizaczii-i-importy","status":"publish","type":"post","link":"https:\/\/prohoster.info\/sk\/blog\/administrirovanie\/dba-gramotno-organizovyvaem-sinhronizaczii-i-importy","title":{"rendered":"DBA: spr\u00e1vne organizujeme synchroniz\u00e1cie a importy","gt_translate_keys":[{"key":"rendered","format":"text"}]},"content":{"rendered":"<p>Pri zlo\u017eitom spracov\u00e1van\u00ed ve\u013ek\u00fdch s\u00faborov d\u00e1t (r\u00f4znych <noindex><a rel=\"nofollow\" href=\"https:\/\/ru.wikipedia.org\/wiki\/ETL\">ETL procesov<\/a><\/noindex>: importy, konverzie a synchroniz\u00e1cie s extern\u00fdm zdrojom) \u010dasto vznik\u00e1 potreba <b>do\u010dasne \u201ezapam\u00e4ta\u0165\u201c a r\u00fdchlo spracova\u0165<\/b> nie\u010do objemn\u00e9.<\/p>\n<p>Typick\u00e1 \u00faloha tohto druhu znie zvy\u010dajne takto: <i>\u201eTu <noindex><a rel=\"nofollow\" href=\"https:\/\/sbis.ru\/accounting\">\u00fa\u010dtovn\u00edctvo exportovalo z klientsk\u00e9ho bankov\u00e9ho syst\u00e9mu<\/a><\/noindex> posledn\u00e9 prijat\u00e9 platby, mus\u00edme ich r\u00fdchlo nahra\u0165 na str\u00e1nku a priradi\u0165 k \u00fa\u010dtom\u201c<\/i><\/p>\n<p>Ke\u010f objem toho \u201enie\u010doho\u201c za\u010dne by\u0165 meran\u00fd na stovk\u00e1ch megabajtov a slu\u017eba mus\u00ed nepretr\u017eite pracova\u0165 s datab\u00e1zou a fungova\u0165 24\/7, objav\u00ed sa mno\u017estvo ved\u013eaj\u0161\u00edch \u00fa\u010dinkov, ktor\u00e9 v\u00e1m znepr\u00edjemnia \u017eivot.<br \/>\n<img decoding=\"async\" alt=\"DBA: spr\u00e1vne organizujeme synchroniz\u00e1cie a importy\" src=\"\/wp-content\/uploads\/2020\/03\/f74afb2cd6f5f8de26a0932166933c95.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\nAby sme sa s nimi vysporiadali v PostgreSQL (a nielen v \u0148om), m\u00f4\u017eeme vyu\u017ei\u0165 niektor\u00e9 mo\u017enosti optimaliz\u00e1cie, ktor\u00e9 umo\u017enia spracova\u0165 v\u0161etko r\u00fdchlej\u0161ie a s men\u0161ou spotrebou zdrojov.<br \/>\n<noindex><a rel=\"nofollow\" name=\"habracut\"><\/a><\/noindex><\/p>\n<h2>1. Kam nahr\u00e1va\u0165?<\/h2>\n<p>\nNajsk\u00f4r si ujasnime, kam m\u00f4\u017eeme nahra\u0165 d\u00e1ta, ktor\u00e9 chceme \u201espracova\u0165\u201c.<\/p>\n<h3>1.1. Do\u010dasn\u00e9 tabu\u013eky (TEMPORARY TABLE)<\/h3>\n<p>\nV podstate, pre PostgreSQL s\u00fa do\u010dasn\u00e9 tabu\u013eky rovnak\u00e9 ako ak\u00e9ko\u013evek in\u00e9. Preto s\u00fa falo\u0161n\u00e9 poverenia ako <i><b>\u201etam sa v\u0161etko uchov\u00e1va len v pam\u00e4ti a t\u00e1 m\u00f4\u017ee d\u00f4js\u0165\u201c<\/b><\/i>. Ale existuj\u00fa aj niektor\u00e9 podstatn\u00e9 rozdiely.<\/p>\n<h4>Svoj \u201emenov\u00fd priestor\u201c pre ka\u017ed\u00e9 pripojenie k DB<\/h4>\n<p>\nAk sa dve pripojenia pok\u00fasia s\u00fa\u010dasne vykona\u0165 <code>CREATE TABLE x<\/code>, niekto ur\u010dite z\u00edska <b>chybu nejedine\u010dnosti<\/b> objektov DB.<\/p>\n<p>Ale ak obaja uskuto\u010dnia <code>VYTVORI\u0164 <b>DO\u010cASN\u00c1<\/b> TABU\u013dKA x<\/code>, obaja to urobia bez probl\u00e9mov a ka\u017ed\u00fd dostane <b>svoj exempl\u00e1r<\/b> tabu\u013eky. A medzi nimi nebude ni\u010d spolo\u010dn\u00e9.<\/p>\n<h4>\u201eSamousmr\u0165\u201c pri odpojen\u00ed<\/h4>\n<p>\nPri uzavret\u00ed pripojenia s\u00fa v\u0161etky do\u010dasn\u00e9 tabu\u013eky automaticky odstr\u00e1nen\u00e9, preto \u201eru\u010dne\u201c vykon\u00e1va\u0165 <code>DROP TABLE x<\/code> nem\u00e1 zmysel, okrem\u2026<\/p>\n<p>Ak pracujete cez <b>pgbouncer v re\u017eime transakcie<\/b>, tak datab\u00e1za st\u00e1le pova\u017euje, \u017ee toto pripojenie je st\u00e1le akt\u00edvne, a v \u0148om t\u00e1to do\u010dasn\u00e1 tabu\u013eka na\u010falej existuje.<\/p>\n<p>Preto pokus o jej op\u00e4tovn\u00e9 vytvorenie z in\u00e9ho pripojenia k pgbouncer vedie k chybe. Ale toto sa d\u00e1 ob\u00eds\u0165 pomocou <code>VYTVO\u0158IT DO\u010cASNOU TABULKU <b>POKUD NEEXISTUJE<\/b> x<\/code>.<\/p>\n<p>Pravda, je lep\u0161ie to takto nerobi\u0165, preto\u017ee potom m\u00f4\u017eete \u201ene\u010dakane\u201c objavi\u0165 d\u00e1ta, ktor\u00e9 zostali po \u201epredch\u00e1dzaj\u00facom majite\u013eovi\u201c. Namiesto toho je ove\u013ea lep\u0161ie si pre\u010d\u00edta\u0165 manu\u00e1l a zisti\u0165, \u017ee pri vytv\u00e1ran\u00ed tabu\u013eky m\u00e1te mo\u017enos\u0165 doplni\u0165 <code>PRI PRIHL\u00c1SEN\u00cd <b>DROP<\/b><\/code> \u2014 to znamen\u00e1, \u017ee po dokon\u010den\u00ed transakcie sa tabu\u013eka automaticky odstr\u00e1ni.<\/p>\n<h4>Nereplikovan\u00e9<\/h4>\n<p>\nPreto\u017ee patr\u00ed iba k ur\u010dit\u00e9mu spojeniu, do\u010dasn\u00e9 tabu\u013eky sa nereplikuj\u00fa. Av\u0161ak <b>to zbavuje potreby dvojit\u00e9ho z\u00e1pisu \u00fadajov<\/b> do heap + WAL, preto s\u00fa INSERT\/UPDATE\/DELETE do nej podstatne r\u00fdchlej\u0161ie.<\/p>\n<p>Ale preto\u017ee do\u010dasn\u00e1 tabu\u013eka je predsa len 'takmer norm\u00e1lna' tabu\u013eka, nie je mo\u017en\u00e9 ju vytvori\u0165 ani na replike. Aspo\u0148 zatia\u013e, hoci pr\u00edslu\u0161n\u00fd patch sa u\u017e d\u00e1vno pohybuje.<\/p>\n<h3>1.2. Nereportovate\u013en\u00e9 tabu\u013eky (UNLOGGED TABLE)<\/h3>\n<p>\nAle \u010do robi\u0165, ak m\u00e1te nejak\u00fd zlo\u017eit\u00fd ETL proces, ktor\u00fd sa ned\u00e1 zrealizova\u0165 v r\u00e1mci jednej transakcie, a m\u00e1te <b>pgbouncer v re\u017eime transakcie<\/b>?..<\/p>\n<p>Alebo je tok \u00fadajov tak\u00fd ve\u013ek\u00fd, \u017ee <b>kapacita jedn\u00e9ho spojenia<\/b> s DB (\u010d\u00edtaj, jedn\u00e9ho procesu na CPU) nesta\u010d\u00ed?.<\/p>\n<p>Alebo \u010das\u0165 oper\u00e1ci\u00ed ide <b>asynchr\u00f3nne<\/b> v r\u00f4znych pripojeniach?.<\/p>\n<p>Tu je len jedna mo\u017enos\u0165 \u2014 <b>do\u010dasne vytvori\u0165 ne-do\u010dasn\u00fa tabu\u013eku<\/b>. Hra so slovami, \u00e1no. To znamen\u00e1:<\/p>\n<ul>\n<li>vytvoril 'svoje' tabu\u013eky s maxim\u00e1lne n\u00e1hodn\u00fdmi n\u00e1zvami, aby som sa s nik\u00fdm nezrazil<\/li>\n<li><b>Extract<\/b>: na\u010d\u00edtal som do nich \u00fadaje z extern\u00e9ho zdroja<\/li>\n<li><b>Transform<\/b>: pretransformoval, vyplnil k\u013e\u00fa\u010dov\u00e9 prepojen\u00e9 polia<\/li>\n<li><b>Load<\/b>: prelieval pripraven\u00e9 \u00fadaje do cie\u013eov\u00fdch tabuliek<\/li>\n<li>vymazal 'svoje' tabu\u013eky<\/li>\n<\/ul>\n<p>\nA teraz \u2014 ly\u017ei\u010dka dechtu. V podstate, <b>cel\u00fd z\u00e1pis v PostgreSQL prebieha dvakr\u00e1t<\/b> \u2014 <noindex><a rel=\"nofollow\" href=\"https:\/\/habr.com\/ru\/company\/postgrespro\/blog\/461523\/\">najprv do WAL<\/a><\/noindex>, potom u\u017e do tel\u00e1 tabuliek\/indexov. Toto v\u0161etko je uroben\u00e9 na podporu ACID a spr\u00e1vnej vidite\u013enosti \u00fadajov medzi <code>COMMIT<\/code>zalo\u017een\u00e9 a <code>ROLLBACK<\/code>zalo\u017een\u00e9 transakcie.<\/p>\n<p>Ale to my nepotrebujeme! N\u00e1\u0161 cel\u00fd proces <b>bu\u010f prebehol \u00faspe\u0161ne, alebo nie<\/b>. Nez\u00e1le\u017e\u00ed na tom, ko\u013eko v \u0148om bude medzi\u010dl\u00e1nkov \u2014 nezauj\u00edma n\u00e1s 'pokra\u010dova\u0165 v procese od polovice', najm\u00e4 ke\u010f nie je jasn\u00e9, kde bola.<\/p>\n<p>Na to v\u00fdvoj\u00e1ri PostgreSQL e\u0161te vo verzii 9.1 zaviedli tak\u00fa vec, ako s\u00fa <noindex><a rel=\"nofollow\" href=\"https:\/\/postgrespro.ru\/docs\/postgresql\/12\/sql-createtable#SQL-CREATETABLE-UNLOGGED\">nereportovate\u013en\u00e9 (UNLOGGED) tabu\u013eky.<\/a><\/noindex>:<\/p>\n<blockquote><p>S t\u00fdmto ustanoven\u00edm sa tabu\u013eka vytv\u00e1ra ako nereportovate\u013en\u00e1. \u00dadaje zapisovan\u00e9 do nereportovate\u013en\u00fdch tabuliek neprech\u00e1dzaj\u00fa cez \u017eurn\u00e1l predz\u00e1pisu (pozri Kapitolu 29), a v d\u00f4sledku toho tak\u00e9 tabu\u013eky <b>funguj\u00fa ove\u013ea r\u00fdchlej\u0161ie ako norm\u00e1lne<\/b>. Av\u0161ak, nie s\u00fa chr\u00e1nen\u00e9 pred zlyhan\u00edm; pri zlyhan\u00ed alebo havarijnom vypnut\u00ed servera sa nereportovate\u013en\u00e1 tabu\u013eka <b>automaticky zru\u0161\u00ed.<\/b>Okrem toho obsah nereportovate\u013enej tabu\u013eky <b>sa nereplikovan\u00fd.<\/b> na riaden\u00e9 servery. Ak\u00e9ko\u013evek indexy vytvoren\u00e9 pre nezaznamen\u00e1van\u00fa tabu\u013eku automaticky zost\u00e1vaj\u00fa nezaznamen\u00e1van\u00e9.<\/p><\/blockquote>\n<p>Kr\u00e1tko, <b>bude to v\u00fdrazne r\u00fdchlej\u0161ie<\/b>, ale ak server DB \u201espadne\u201c \u2014 bude to nepr\u00edjemn\u00e9. Ale st\u00e1va sa to \u010dasto, a vie v\u00e1\u0161 ETL proces to spr\u00e1vne spracova\u0165 \u201ez polovice\u201c po \u201eo\u017eiven\u00ed\u201c DB?..<\/p>\n<p>Ak sa tak nestane, a vy\u0161\u0161ie uveden\u00fd pr\u00edpad sa podob\u00e1 na v\u00e1\u0161 \u2014 pou\u017eite <code>UNLOGGED<\/code>, ale nikdy <b>nepou\u017e\u00edvajte tento atrib\u00fat na skuto\u010dn\u00fdch tabu\u013ek\u00e1ch<\/b>, ktor\u00fdch d\u00e1ta s\u00fa pre v\u00e1s cenn\u00e9.<\/p>\n<h3>1.3. ON COMMIT { DELETE ROWS | DROP }<\/h3>\n<p>\nTento pr\u00edkaz umo\u017e\u0148uje pri vytv\u00e1ran\u00ed tabu\u013eky nastavi\u0165 automatick\u00e9 spr\u00e1vanie po ukon\u010den\u00ed transakcie.<\/p>\n<p>O <code>PRI PRIHL\u00c1SEN\u00cd <b>DROP<\/b><\/code> u\u017e som nap\u00edsal vy\u0161\u0161ie, generuje <code>DROP TABLE<\/code>, a tu je <code>PRI PRIHL\u00c1SEN\u00cd <b>ZMAZA\u0164 RIADKY<\/b><\/code> situ\u00e1cia zauj\u00edmavej\u0161ia \u2014 tu sa generuje <code>TRUNCATE TABLE<\/code>.<\/p>\n<p>Ke\u010f\u017ee cel\u00e1 infra\u0161trukt\u00fara ukladania meta popisov do\u010dasnej tabu\u013eky je presne tak\u00e1 ist\u00e1, ako u be\u017enej, <b>neust\u00e1le vytv\u00e1ranie a mazanie do\u010dasn\u00fdch tabuliek vedie k v\u00fdrazn\u00e9mu \u201enafukovaniu\u201c syst\u00e9mov\u00fdch tabuliek<\/b> pg_class, pg_attribute, pg_attrdef, pg_depend,\u2026<\/p>\n<p>Teraz si predstavte, \u017ee m\u00e1te pracovn\u00edka na priamej spojen\u00ed s DB, ktor\u00fd ka\u017ed\u00fa sekundu otv\u00e1ra nov\u00fa transakciu, vytv\u00e1ra, nap\u013a\u0148a, spracov\u00e1va a ma\u017ee do\u010dasn\u00fa tabu\u013eku\u2026 Odpadu v syst\u00e9mov\u00fdch tabulk\u00e1ch sa nahromad\u00ed nadmern\u00e9 mno\u017estvo, \u010do sp\u00f4sobuje zbyto\u010dn\u00e9 spomalenia pri ka\u017edej oper\u00e1cii.<\/p>\n<p>V\u0161eobecne, nerobte to! V takomto pr\u00edpade je ove\u013ea efekt\u00edvnej\u0161ie <code>CREATE TEMPORARY TABLE x ... ON COMMIT DELETE ROWS<\/code> vynies\u0165 mimo cyklu transakci\u00ed \u2014 vtedy na za\u010diatku ka\u017edej novej transakcie tabu\u013eky u\u017e <b>existuj\u00fa<\/b> (\u0161etr\u00edme volanie <code>VYTVORI\u0164<\/code>), ale <b>bude pr\u00e1zdna<\/b>, v\u010faka <code>TRUNCATE<\/code> (jeho volanie sme tie\u017e u\u0161etrili) po ukon\u010den\u00ed predch\u00e1dzaj\u00facej transakcie.<\/p>\n<h3>1.4. AKO\u2026 ZAHRNUT\u00c9 \u2026<\/h3>\n<p>\nSpomenul som na za\u010diatku, \u017ee jedn\u00fdm z typick\u00fdch use case pre do\u010dasn\u00e9 tabu\u013eky je r\u00f4zne druhy importov \u2014 a v\u00fdvoj\u00e1r unavene kop\u00edruje zoznam pol\u00ed cie\u013eovej tabu\u013eky do vyhl\u00e1senia svojej do\u010dasnej\u2026<\/p>\n<p>Ale lenivos\u0165 je motor pokroku! Preto <b>vytvori\u0165 nov\u00fa tabu\u013eku \u201epod\u013ea vzoru\u201c<\/b> je ove\u013ea jednoduch\u0161ie:<\/p>\n<pre><code class=\"sql\">CREATE TEMPORARY TABLE import_table(\n  LIKE target_table\n);<\/code><\/pre>\n<p>\nKe\u010f\u017ee do tejto tabu\u013eky mo\u017eno generova\u0165 naozaj ve\u013ea \u00fadajov, vyh\u013ead\u00e1vanie v nej nebude r\u00fdchle. Ale proti tomu existuje tradi\u010dn\u00e9 rie\u0161enie \u2014 indexy! A \u00e1no, <b>do\u010dasn\u00e1 tabu\u013eka m\u00f4\u017ee ma\u0165 tie\u017e indexy<\/b>.<\/p>\n<p>Ke\u010f\u017ee \u010dasto, potrebn\u00e9 indexy sa zhoduj\u00fa s indexami cie\u013eovej tabu\u013eky, mo\u017eno jednoducho nap\u00edsa\u0165 <code>PODOBN\u00c9 ako target_table <b>ZAH\u0154\u0147AJ\u00daC INDEXY<\/b><\/code>.<\/p>\n<p>Ak potrebujete e\u0161te aj <code>DEFAULT<\/code>-hodnoty (napr\u00edklad na naplnenie hodn\u00f4t prim\u00e1rneho k\u013e\u00fa\u010da) m\u00f4\u017eete vyu\u017ei\u0165 <code>PODOBN\u00c9 ako target_table <b>VR\u00c1TANE VYHODNOCOV<\/b><\/code>. Alebo jednoducho \u2014 <code>PODOBN\u00c9 ako target_table <b>VR\u00c1TANE V\u0160ETK\u00c9HO<\/b><\/code> \u2014 skop\u00edruje predvolen\u00e9 hodnoty, indexy, obmedzenia,\u2026<\/p>\n<p>Ale tu u\u017e treba ch\u00e1pa\u0165, \u017ee ak ste vytvorili <b>importovaciu tabu\u013eku hne\u010f s indexmi, tak sa d\u00e1ta bud\u00fa importova\u0165 dlh\u0161ie<\/b>, ako keby ste najprv v\u0161etko importovali a a\u017e potom nasadili indexy \u2014 pozrite sa napr\u00edklad, ako to rob\u00ed <noindex><a rel=\"nofollow\" href=\"https:\/\/postgrespro.ru\/docs\/postgresql\/12\/app-pgdump\">pg_dump<\/a><\/noindex>.<\/p>\n<p>V\u0161eobecne, <noindex><a rel=\"nofollow\" href=\"https:\/\/postgrespro.ru\/docs\/postgresql\/12\/sql-createtable\">RTFM<\/a><\/noindex>!<\/p>\n<h2>2. Ako p\u00edsa\u0165?<\/h2>\n<p>\nPoviem to jednoducho \u2014 pou\u017e\u00edvajte <code><noindex><a rel=\"nofollow\" href=\"https:\/\/postgrespro.ru\/docs\/postgresql\/12\/sql-copy\">KOP\u00cdROVA\u0164<\/a><\/noindex><\/code>-pr\u00fad namiesto \u00abbal\u00edka\u00bb <code>INSERT<\/code>, <noindex><a rel=\"nofollow\" href=\"https:\/\/www.citusdata.com\/blog\/2017\/11\/08\/faster-bulk-loading-in-postgresql-with-copy\/\">ur\u00fdchlen\u00ed nieko\u013ekokr\u00e1t<\/a><\/noindex>. M\u00f4\u017eete dokonca priamo z predt\u00fdm vytvoren\u00e9ho s\u00faboru.<\/p>\n<h2>3. Ako spracov\u00e1va\u0165?<\/h2>\n<p>\nDajme tomu, \u017ee n\u00e1\u0161 vstup vyzer\u00e1 pribli\u017ene takto:<\/p>\n<ul>\n<li>uklad\u00e1te v datab\u00e1ze tabu\u013eku s klientsk\u00fdmi d\u00e1tami na <b>1M z\u00e1znamov<\/b><\/li>\n<li>ka\u017ed\u00fd de\u0148 v\u00e1m klient posiela nov\u00fd <b>\u00fapln\u00fd \u00abobraz\u00bb<\/b><\/li>\n<li>pod\u013ea sk\u00fasenosti viete, \u017ee sa zvy\u010dajne men\u00ed maxim\u00e1lne 10K z\u00e1znamov <b>Klasick\u00fdm pr\u00edkladom takejto situ\u00e1cie je<\/b><\/li>\n<\/ul>\n<p>\ndatab\u00e1za K\u013dADR <noindex><a rel=\"nofollow\" href=\"https:\/\/www.gnivc.ru\/technical_support\/classifiers_reference\/kladr\/\">\u2014 existuje ve\u013ea adries, ale v ka\u017edom t\u00fd\u017edennom v\u00fdkupe zmien (prezmenovanie obc\u00ed, zl\u00fa\u010denie ul\u00edc, vznik nov\u00fdch domov) ich nie je a\u017e tak ve\u013ea ani v celon\u00e1rodnom meradle.<\/a><\/noindex> 3.1. Algoritmus \u00faplnej synchroniz\u00e1cie<\/p>\n<h3>Pre jednoduchos\u0165 predpokladajme, \u017ee nemus\u00edte ani re\u0161tukturalizova\u0165 d\u00e1ta \u2014 sta\u010d\u00ed uvies\u0165 tabu\u013eku do po\u017eadovan\u00e9ho stavu, teda:<\/h3>\n<p>\nodstr\u00e1ni\u0165<\/p>\n<ul>\n<li><b>v\u0161etko, \u010do u\u017e neexistuje<\/b> aktualizova\u0165<\/li>\n<li><b>v\u0161etko, \u010do u\u017e bolo a treba aktualizova\u0165<\/b> vlo\u017ei\u0165<\/li>\n<li><b>v\u0161etko, \u010do e\u0161te nebolo<\/b> Pre\u010do by ste mali vykon\u00e1va\u0165 oper\u00e1cie presne v tomto porad\u00ed? Preto\u017ee len tak sa ve\u013ekos\u0165 tabu\u013eky zv\u00fd\u0161i minim\u00e1lne (<\/li>\n<\/ul>\n<p>\nnezabudnite na MVCC!<noindex><a rel=\"nofollow\" href=\"https:\/\/habr.com\/ru\/company\/tensor\/blog\/491366\/\">DELETE FROM dst<\/a><\/noindex>).<\/p>\n<h4>Nie, samozrejme, m\u00f4\u017eete sa ob\u00eds\u0165 s iba dvoma oper\u00e1ciami:<\/h4>\n<p>\n) cel\u00fa tabu\u013eku<\/p>\n<ul>\n<li><b>v\u0161etko, \u010do u\u017e neexistuje<\/b> (<code>DELETE<\/code>v\u0161etko z nov\u00e9ho obrazu<\/li>\n<li><b>v\u0161etko, \u010do e\u0161te nebolo<\/b> Ale pritom, v\u010faka MVCC,<\/li>\n<\/ul>\n<p>\nsa ve\u013ekos\u0165 tabu\u013eky zv\u00fd\u0161i presne na dvojn\u00e1sobok <b>! Z\u00edska\u0165 +1M obrazov z\u00e1znamov v tabu\u013eke z d\u00f4vodu aktualiz\u00e1cie 10K \u2014 to je dos\u0165 nadbyto\u010dn\u00e9\u2026<\/b>TRUNCATE dst<\/p>\n<h4>Sk\u00fasenej\u0161\u00ed v\u00fdvoj\u00e1ri vedia, \u017ee cel\u00fa tabu\u013eku je mo\u017en\u00e9 dos\u0165 lacno vy\u010disti\u0165:<\/h4>\n<p>\n) cel\u00fa tabu\u013eku<\/p>\n<ul>\n<li><b>vy\u010disti\u0165<\/b> (<code>TRUNCATE<\/code>Met\u00f3da je \u00fa\u010dinn\u00e1,<\/li>\n<li><b>v\u0161etko, \u010do e\u0161te nebolo<\/b> Ale pritom, v\u010faka MVCC,<\/li>\n<\/ul>\n<p>\nniekedy celkom aplikovate\u013en\u00e1 <noindex><a rel=\"nofollow\" href=\"https:\/\/habr.com\/ru\/company\/tensor\/blog\/481866\/\">, ale je tu probl\u00e9m\u2026 Vlo\u017ei\u0165 1M z\u00e1znamov n\u00e1m bude trva\u0165 dlho, tak\u017ee nem\u00f4\u017eeme dovoli\u0165, aby tabu\u013eka zostala pr\u00e1zdna po cel\u00fd ten \u010das (ako sa to stane bez obalenia do jednej transakcie).<\/a><\/noindex>A to znamen\u00e1:<\/p>\n<p>za\u010d\u00edna n\u00e1m<\/p>\n<ul>\n<li>dlh\u00e1 transakcia <b>kladie<\/b><\/li>\n<li><code>TRUNCATE<\/code> AccessExclusive <b>-z\u00e1mok<\/b>dlho rob\u00edme vkladanie, a v\u0161etci ostatn\u00ed v tom \u010dase<\/li>\n<li>nem\u00f4\u017eu ani <b>Ni\u010d dobr\u00e9 sa nezd\u00e1\u2026 <code>SELECT<\/code><\/b><\/li>\n<\/ul>\n<p>\nNie\u010do nie je v poriadku...<\/p>\n<h4>ALTER TABLE\u2026 PREMENOVA\u0164\u2026 \/ ZMAZA\u0164 TABU\u013dKU \u2026<\/h4>\n<p>\nAko mo\u017enos\u0165 \u2013 nahra\u0165 v\u0161etko do novej tabu\u013eky a potom jednoducho premenova\u0165 na miesto starej. Nieko\u013eko nepr\u00edjemn\u00fdch drobnost\u00ed:<\/p>\n<ul>\n<li>tie\u017e <b>-z\u00e1mok<\/b>, aj ke\u010f podstatne menej z \u010dasov\u00e9ho h\u013eadiska<\/li>\n<li>v\u0161etky pl\u00e1ny dotazov\/\u0161tatistiky tejto tabu\u013eky sa resetuj\u00fa, <noindex><a rel=\"nofollow\" href=\"https:\/\/habr.com\/ru\/company\/tensor\/blog\/479656\/\">je potrebn\u00e9 spusti\u0165 ANALYZE<\/a><\/noindex><\/li>\n<li><b>v\u0161etky vonkaj\u0161ie k\u013e\u00fa\u010de sa po\u0161kodia<\/b> (FK) na tabu\u013eku<\/li>\n<\/ul>\n<p>\nBol WIP-patch od Simona Riggsa, ktor\u00fd navrhoval vykona\u0165 <code>ALTER<\/code>-oper\u00e1ciu na v\u00fdmenu tela tabu\u013eky na \u00farovni s\u00faborov, bez dotknutia sa \u0161tatistiky a FK, ale nez\u00edskal kv\u00f3rum.<\/p>\n<h4>DELETE, UPDATE, INSERT<\/h4>\n<p>\nTak\u017ee sa zastavujeme na neblokuj\u00facej mo\u017enosti z troch oper\u00e1ci\u00ed. T\u00e9m\u011b\u0159 t\u0159i... Ako to spravi\u0165 najefekt\u00edvnej\u0161ie?<\/p>\n<pre><code class=\"sql\">-- v\u0161etko rob\u00edme v r\u00e1mci transakcie, aby nikto nevidel \"medzistavy\".\nBEGIN;\n\n-- vytv\u00e1rame do\u010dasn\u00fa tabu\u013eku s importovan\u00fdmi \u00fadajmi\nCREATE TEMPORARY TABLE tmp(\n  LIKE dst INCLUDING INDEXES -- pod\u013ea vzoru, spolo\u010dne s indexmi\n) ON COMMIT DROP; -- mimo transakcie ju nepotrebujeme\n\n-- r\u00fdchlo vklad\u00e1me nov\u00fd obraz cez COPY\nCOPY tmp FROM STDIN;\n-- ...\n-- .\n\n-- odstra\u0148ujeme ch\u00fdbaj\u00face\nDELETE FROM\n  dst D\nUSING\n  dst X\nLEFT JOIN\n  tmp Y\n    USING(pk1, pk2) -- polia prim\u00e1rneho k\u013e\u00fa\u010da\nWHERE\n  (D.pk1, D.pk2) = (X.pk1, X.pk2) AND\n  Y IS NOT DISTINCT FROM NULL; -- \"antijoin\"\n\n-- aktualizujeme zost\u00e1vaj\u00face\nUPDATE\n  dst D\nSET\n  (f1, f2, f3) = (T.f1, T.f2, T.f3)\nFROM\n  tmp T\nWHERE\n  (D.pk1, D.pk2) = (T.pk1, T.pk2) AND\n  (D.f1, D.f2, D.f3) IS DISTINCT FROM (T.f1, T.f2, T.f3); -- nie je potrebn\u00e9 aktualizova\u0165 zhodn\u00e9\n\n-- vklad\u00e1me ch\u00fdbaj\u00face\nINSERT INTO\n  dst\nSELECT\n  T.*\nFROM\n  tmp T\nLEFT JOIN\n  dst D\n    USING(pk1, pk2)\nWHERE\n  D IS NOT DISTINCT FROM NULL;\n\nCOMMIT;\n<\/code><\/pre>\n<p><\/p>\n<h3>3.2. Postprocessing importu<\/h3>\n<p>\nV rovnakom K\u013dADRi je potrebn\u00e9 v\u0161etky zmenen\u00e9 z\u00e1znamy dodato\u010dne spracova\u0165 \u2013 normalizova\u0165, vy\u010dleni\u0165 k\u013e\u00fa\u010dov\u00e9 slov\u00e1, uvies\u0165 do po\u017eadovan\u00fdch \u0161trukt\u00far. Ale ako zisti\u0165 \u2013 <b>\u010do presne sa menilo<\/b>, bez toho, aby sa t\u00fdmto skomplikoval k\u00f3d synchroniz\u00e1cie, ide\u00e1lne, v\u00f4bec ho netr\u00e1piac?<\/p>\n<p>Ak je v momente synchroniz\u00e1cie pr\u00edstup na z\u00e1pis len vo va\u0161om procese, m\u00f4\u017eete vyu\u017ei\u0165 trigger, ktor\u00fd zhroma\u017ed\u00ed v\u0161etky zmeny:<\/p>\n<pre><code class=\"sql\">-- cie\u013eov\u00e9 tabu\u013eky\nCREATE TABLE kladr(...);\nCREATE TABLE kladr_house(...);\n\n-- tabu\u013eky s hist\u00f3riou zmien\nCREATE TABLE kladr$log(\n  ro kladr, -- tu s\u00fa cel\u00e9 obrazy z\u00e1znamov star\u00fdch\/nov\u00fdch\n  rn kladr\n);\n\nCREATE TABLE kladr_house$log(\n  ro kladr_house,\n  rn kladr_house\n);\n\n-- v\u0161eobecn\u00e1 funkcia logovania zmien\nCREATE OR REPLACE FUNCTION diff$log() RETURNS trigger AS $$\nDECLARE\n  dst varchar = TG_TABLE_NAME || '$log';\n  stmt text = '';\nBEGIN\n  -- kontrolujeme potrebu logovania pri aktualiz\u00e1cii z\u00e1znamu\n  IF TG_OP = 'UPDATE' THEN\n    IF NEW IS NOT DISTINCT FROM OLD THEN\n      RETURN NEW;\n    END IF;\n  END IF;\n  -- vytv\u00e1rame z\u00e1znam logu\n  stmt = 'INSERT INTO ' || dst::text || '(ro,rn)VALUES(';\n  CASE TG_OP\n    WHEN 'INSERT' THEN\n      EXECUTE stmt || 'NULL,$1)' USING NEW;\n    WHEN 'UPDATE' THEN\n      EXECUTE stmt || '$1,$2)' USING OLD, NEW;\n    WHEN 'DELETE' THEN\n      EXECUTE stmt || '$1,NULL)' USING OLD;\n  END CASE;\n  RETURN NEW;\nEND;\n$$ LANGUAGE plpgsql;\n<\/code><\/pre>\n<p>\nTeraz m\u00f4\u017eeme sk\u00f4r ako za\u010dneme so synchroniz\u00e1ciou aplikova\u0165 (alebo zapn\u00fa\u0165 prostredn\u00edctvom <code>ALTER TABLE ... ENABLE TRIGGER ...<\/code>):<\/p>\n<pre><code class=\"sql\">CREATE TRIGGER log\n  AFTER INSERT OR UPDATE OR DELETE\n  ON kladr\n    FOR EACH ROW\n      EXECUTE PROCEDURE diff$log();\n\nCREATE TRIGGER log\n  AFTER INSERT OR UPDATE OR DELETE\n  ON kladr_house\n    FOR EACH ROW\n      EXECUTE PROCEDURE diff$log();\n<\/code><\/pre>\n<p>\nA potom si pokojne z log-tab\u00fa\u013e vyberieme v\u0161etky potrebn\u00e9 zmeny a prehneme ich cez dodato\u010dn\u00e9 spracovatele.<\/p>\n<h3>3.3. Import s\u00favisiacich s\u00faborov<\/h3>\n<p>\nU\u017e sme sa zaoberali pr\u00edpadmi, ke\u010f \u0161trukt\u00fary \u00fadajov zdroja a prij\u00edma\u010da sa zhoduj\u00fa. Ale \u010do robi\u0165, ak export z extern\u00e9ho syst\u00e9mu m\u00e1 form\u00e1t odli\u0161n\u00fd od \u0161trukt\u00fary, ktor\u00fa m\u00e1me v na\u0161ej datab\u00e1ze?<\/p>\n<p>Vezmeme si ako pr\u00edklad uchov\u00e1vanie klientov a ich fakt\u00far, klasick\u00fd variant \u201emnoho-k-jedn\u00e9mu\u201c:<\/p>\n<pre><code class=\"sql\">CREATE TABLE client(\n  client_id\n    serial\n      PRIMARY KEY\n, inn\n    varchar\n      UNIQUE\n, name\n    varchar\n);\n\nCREATE TABLE invoice(\n  invoice_id\n    serial\n      PRIMARY KEY\n, client_id\n    integer\n      REFERENCES client(client_id)\n, number\n    varchar\n, dt\n    date\n, sum\n    numeric(32,2)\n);<\/code><\/pre>\n<p>\nA export z extern\u00e9ho zdroja k n\u00e1m prich\u00e1dza vo forme \u201ev\u0161etko v jednom\u201c:<\/p>\n<pre><code class=\"sql\">CREATE TEMPORARY TABLE invoice_import(\n  client_inn\n    varchar\n, client_name\n    varchar\n, invoice_number\n    varchar\n, invoice_dt\n    date\n, invoice_sum\n    numeric(32,2)\n);<\/code><\/pre>\n<p>\nJe zrejm\u00e9, \u017ee \u00fadaje o klientoch sa v takomto pr\u00edpade m\u00f4\u017eu duplikova\u0165 a hlavn\u00fdm z\u00e1znamom je \u201efakt\u00fara\u201c:<\/p>\n<pre><code class=\"plaintext\">0123456789;V\u00e1clav;A-01;2020-03-16;1000.00\n9876543210;Peter;A-02;2020-03-16;666.00\n0123456789;V\u00e1clav;B-03;2020-03-16;9999.00\n<\/code><\/pre>\n<p>\nPre model jednoducho vlo\u017e\u00edme na\u0161e testovacie \u00fadaje, ale pam\u00e4t\u00e1me si \u2014 <code>KOP\u00cdROVA\u0164<\/code> efekt\u00edvnej\u0161ie!<\/p>\n<pre><code class=\"sql\">INSERT INTO invoice_import\nVALUES\n  ('0123456789', 'V\u00e1clav', 'A-01', '2020-03-16', 1000.00)\n, ('9876543210', 'Peter', 'A-02', '2020-03-16', 666.00)\n, ('0123456789', 'V\u00e1clav', 'B-03', '2020-03-16', 9999.00);<\/code><\/pre>\n<p>\nNajprv vyberieme tie \u201eprerezania\u201c, na ktor\u00e9 sa na\u0161e \u201efakty\u201c odkazuj\u00fa. V na\u0161om pr\u00edpade sa fakt\u00fary odkazuj\u00fa na klientov:<\/p>\n<pre><code class=\"sql\">CREATE TEMPORARY TABLE client_import AS\nSELECT DISTINCT ON(client_inn)\n-- mo\u017eno pou\u017ei\u0165 jednoducho SELECT DISTINCT, ak s\u00fa \u00fadaje predpokladane bezrozporu\n  client_inn inn\n, client_name \"name\"\nFROM\n  invoice_import;<\/code><\/pre>\n<p>\nAby sme spr\u00e1vne prepojili fakt\u00fary s ID klientov, mus\u00edme najprv tieto identifik\u00e1tory zisti\u0165 alebo vygenerova\u0165. Prid\u00e1me pre ne polia:<\/p>\n<pre><code class=\"sql\">ALTER TABLE invoice_import ADD COLUMN client_id integer;\nALTER TABLE client_import ADD COLUMN client_id integer;<\/code><\/pre>\n<p>\nVyu\u017eijeme vy\u0161\u0161ie op\u00edsan\u00fd sp\u00f4sob synchroniz\u00e1cie tabuliek s malou \u00fapravou \u2014 nebudeme ni\u010d aktualizova\u0165 ani maza\u0165 v cie\u013eovej tabu\u013eke, preto\u017ee import klientov je u n\u00e1s \"append-only\":<\/p>\n<pre><code class=\"sql\">-- prirad\u00edme v tabu\u013eke importu ID u\u017e existuj\u00facich z\u00e1znamov\nUPDATE\n  client_import T\nSET\n  client_id = D.client_id\nFROM\n  client D\nWHERE\n  T.inn = D.inn; -- unik\u00e1tny k\u013e\u00fa\u010d\n\n-- vlo\u017e\u00edme ch\u00fdbaj\u00face z\u00e1znamy a prirad\u00edme ich ID\nWITH ins AS (\n  INSERT INTO client(\n    inn\n  , name\n  )\n  SELECT\n    inn\n  , name\n  FROM\n    client_import\n  WHERE\n    client_id IS NULL -- ak ID nebolo priraden\u00e9\n  RETURNING *\n)\nUPDATE\n  client_import T\nSET\n  client_id = D.client_id\nFROM\n  ins D\nWHERE\n  T.inn = D.inn; -- unik\u00e1tny k\u013e\u00fa\u010d\n\n-- prira\u010fujeme ID klientov k z\u00e1znamom fakt\u00far\nUPDATE\n  invoice_import T\nSET\n  client_id = D.client_id\nFROM\n  client_import D\nWHERE\n  T.client_inn = D.inn; -- aplikovan\u00fd k\u013e\u00fa\u010d\n<\/code><\/pre>\n<p>\nVlastne, to je v\u0161etko \u2014 v <code>invoice_import<\/code> teraz m\u00e1me vyplnen\u00e9 pole pre prepojenie <code>client_id<\/code>, pomocou ktor\u00e9ho vlo\u017e\u00edme fakt\u00faru.<br \/>\n<br \/>Zdroj: <a content=\"nofollow\" rel=\"nofollow\" href=\"https:\/\/habr.com\/ru\/company\/tensor\/blog\/492464\/\">habr.com<\/a> <\/p>","protected":false,"gt_translate_keys":[{"key":"rendered","format":"html"}]},"excerpt":{"rendered":"<p>\u041f\u0440\u0438 \u0441\u043b\u043e\u0436\u043d\u043e\u0439 \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0435 \u0431\u043e\u043b\u044c\u0448\u0438\u0445 \u043d\u0430\u0431\u043e\u0440\u043e\u0432 \u0434\u0430\u043d\u043d\u044b\u0445 (\u0440\u0430\u0437\u043d\u044b\u0435 ETL-\u043f\u0440\u043e\u0446\u0435\u0441\u0441\u044b: \u0438\u043c\u043f\u043e\u0440\u0442\u044b, \u043a\u043e\u043d\u0432\u0435\u0440\u0442\u0430\u0446\u0438\u0438 \u0438 \u0441\u0438\u043d\u0445\u0440\u043e\u043d\u0438\u0437\u0430\u0446\u0438\u0438 \u0441 \u0432\u043d\u0435\u0448\u043d\u0438\u043c \u0438\u0441\u0442\u043e\u0447\u043d\u0438\u043a\u043e\u043c) \u0447\u0430\u0441\u0442\u043e \u0432\u043e\u0437\u043d\u0438\u043a\u0430\u0435\u0442 \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e\u0441\u0442\u044c \u0432\u0440\u0435\u043c\u0435\u043d\u043d\u043e \u00ab\u0437\u0430\u043f\u043e\u043c\u043d\u0438\u0442\u044c\u00bb, \u0438 \u0441\u0440\u0430\u0437\u0443 \u0431\u044b\u0441\u0442\u0440\u043e \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u0430\u0442\u044c \u0447\u0442\u043e-\u0442\u043e \u043e\u0431\u044a\u0435\u043c\u043d\u043e\u0435. \u0422\u0438\u043f\u043e\u0432\u0430\u044f \u0437\u0430\u0434\u0430\u0447\u0430 \u043f\u043e\u0434\u043e\u0431\u043d\u043e\u0433\u043e \u0440\u043e\u0434\u0430 \u0437\u0432\u0443\u0447\u0438\u0442 \u043e\u0431\u044b\u0447\u043d\u043e \u043f\u0440\u0438\u043c\u0435\u0440\u043d\u043e \u0442\u0430\u043a: \u00ab\u0412\u043e\u0442 \u0442\u0443\u0442 \u0431\u0443\u0445\u0433\u0430\u043b\u0442\u0435\u0440\u0438\u044f \u0432\u044b\u0433\u0440\u0443\u0437\u0438\u043b\u0430 \u0438\u0437 \u043a\u043b\u0438\u0435\u043d\u0442-\u0431\u0430\u043d\u043a\u0430 \u043f\u043e\u0441\u043b\u0435\u0434\u043d\u0438\u0435 \u043f\u043e\u0441\u0442\u0443\u043f\u0438\u0432\u0448\u0438\u0435 \u043e\u043f\u043b\u0430\u0442\u044b, \u043d\u0430\u0434\u043e \u0438\u0445 \u0431\u044b\u0441\u0442\u0440\u0435\u043d\u044c\u043a\u043e \u0432\u043a\u0430\u0447\u0430\u0442\u044c \u043d\u0430 \u0441\u0430\u0439\u0442 \u0438 \u043f\u0440\u0438\u0432\u044f\u0437\u0430\u0442\u044c \u043a \u0441\u0447\u0435\u0442\u0430\u043c\u00bb \u041d\u043e \u043a\u043e\u0433\u0434\u0430 [&hellip;]<\/p>\n","protected":false,"gt_translate_keys":[{"key":"rendered","format":"html"}]},"author":1,"featured_media":74954,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[688],"tags":[],"class_list":["post-74953","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-administrirovanie"],"aioseo_notices":[],"aioseo_head":"\n\t\t<!-- All in One SEO 5.0.4 - aioseo.com -->\n\t<meta name=\"description\" content=\"\u041f\u0440\u0438 \u0441\u043b\u043e\u0436\u043d\u043e\u0439 \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0435 \u0431\u043e\u043b\u044c\u0448\u0438\u0445 \u043d\u0430\u0431\u043e\u0440\u043e\u0432 \u0434\u0430\u043d\u043d\u044b\u0445 (\u0440\u0430\u0437\u043d\u044b\u0435 ETL-\u043f\u0440\u043e\u0446\u0435\u0441\u0441\u044b: \u0438\u043c\u043f\u043e\u0440\u0442\u044b, \u043a\u043e\u043d\u0432\u0435\u0440\u0442\u0430\u0446\u0438\u0438 \u0438 \u0441\u0438\u043d\u0445\u0440\u043e\u043d\u0438\u0437\u0430\u0446\u0438\u0438 \u0441 \u0432\u043d\u0435\u0448\u043d\u0438\u043c \u0438\u0441\u0442\u043e\u0447\u043d\u0438\u043a\u043e\u043c) \u0447\u0430\u0441\u0442\u043e.\" \/>\n\t<meta name=\"robots\" content=\"max-image-preview:large\" \/>\n\t<meta name=\"author\" content=\"Yuri Gagarin\"\/>\n\t<link rel=\"canonical\" href=\"https:\/\/prohoster.info\/sk\/blog\/administrirovanie\/dba-gramotno-organizovyvaem-sinhronizaczii-i-importy\" \/>\n\t\t<meta name=\"generator\" content=\"All in One SEO (AIOSEO) 5.0.4\" \/>\n\t\t<meta property=\"og:locale\" content=\"sk_SK\" \/>\n\t\t<meta property=\"og:site_name\" content=\"ProHoster | \u041a\u0443\u043f\u0438\u0442\u044c \u043d\u0430\u0434\u0435\u0436\u043d\u044b\u0439 \u0445\u043e\u0441\u0442\u0438\u043d\u0433 \u0434\u043b\u044f \u0441\u0430\u0439\u0442\u043e\u0432 \u0441 \u0437\u0430\u0449\u0438\u0442\u043e\u0439 \u043e\u0442 DDoS, VPS VDS \u0441\u0435\u0440\u0432\u0435\u0440\u044b\" \/>\n\t\t<meta property=\"og:type\" content=\"article\" \/>\n\t\t<meta property=\"og:title\" content=\"\ud83e\udd47DBA: \u0433\u0440\u0430\u043c\u043e\u0442\u043d\u043e \u043e\u0440\u0433\u0430\u043d\u0438\u0437\u043e\u0432\u044b\u0432\u0430\u0435\u043c \u0441\u0438\u043d\u0445\u0440\u043e\u043d\u0438\u0437\u0430\u0446\u0438\u0438 \u0438 \u0438\u043c\u043f\u043e\u0440\u0442\u044b | ProHoster\" \/>\n\t\t<meta property=\"og:description\" content=\"\u041f\u0440\u0438 \u0441\u043b\u043e\u0436\u043d\u043e\u0439 \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0435 \u0431\u043e\u043b\u044c\u0448\u0438\u0445 \u043d\u0430\u0431\u043e\u0440\u043e\u0432 \u0434\u0430\u043d\u043d\u044b\u0445 (\u0440\u0430\u0437\u043d\u044b\u0435 ETL-\u043f\u0440\u043e\u0446\u0435\u0441\u0441\u044b: \u0438\u043c\u043f\u043e\u0440\u0442\u044b, \u043a\u043e\u043d\u0432\u0435\u0440\u0442\u0430\u0446\u0438\u0438 \u0438 \u0441\u0438\u043d\u0445\u0440\u043e\u043d\u0438\u0437\u0430\u0446\u0438\u0438 \u0441 \u0432\u043d\u0435\u0448\u043d\u0438\u043c \u0438\u0441\u0442\u043e\u0447\u043d\u0438\u043a\u043e\u043c) \u0447\u0430\u0441\u0442\u043e.\" \/>\n\t\t<meta property=\"og:url\" content=\"https:\/\/prohoster.info\/sk\/blog\/administrirovanie\/dba-gramotno-organizovyvaem-sinhronizaczii-i-importy\" \/>\n\t\t<meta property=\"og:image\" content=\"https:\/\/prohoster.info\/wp-content\/uploads\/2021\/11\/logo-350.jpg\" \/>\n\t\t<meta property=\"og:image:secure_url\" content=\"https:\/\/prohoster.info\/wp-content\/uploads\/2021\/11\/logo-350.jpg\" \/>\n\t\t<meta property=\"og:image:width\" content=\"350\" \/>\n\t\t<meta property=\"og:image:height\" content=\"350\" \/>\n\t\t<meta property=\"article:published_time\" content=\"2020-03-22T05:42:22+00:00\" \/>\n\t\t<meta property=\"article:modified_time\" content=\"2020-03-22T05:42:22+00:00\" \/>\n\t\t<meta property=\"article:publisher\" content=\"https:\/\/www.facebook.com\/prohoster\" \/>\n\t\t<meta property=\"article:author\" content=\"https:\/\/www.facebook.com\/prohoster\" \/>\n\t\t<!-- All in One SEO -->\n\n","aioseo_head_json":{"title":"\ud83e\udd47DBA: spr\u00e1vne organizujeme synchroniz\u00e1cie a importy | ProHoster","description":"Pri zlo\u017eit\u00fdch procesoch spracovania ve\u013ek\u00fdch s\u00faborov \u00fadajov (r\u00f4zne ETL procesy: importy, konverzie a synchroniz\u00e1cie s vonkaj\u0161\u00edm zdrojom) sa to \u010dasto.","canonical_url":"https:\/\/prohoster.info\/sk\/blog\/administrirovanie\/dba-gramotno-organizovyvaem-sinhronizaczii-i-importy","robots":"max-image-preview:large","keywords":"","webmasterTools":{"miscellaneous":""},"schema":null,"og:locale":"sk_SK","og:site_name":"ProHoster | \u041a\u0443\u043f\u0438\u0442\u044c \u043d\u0430\u0434\u0435\u0436\u043d\u044b\u0439 \u0445\u043e\u0441\u0442\u0438\u043d\u0433 \u0434\u043b\u044f \u0441\u0430\u0439\u0442\u043e\u0432 \u0441 \u0437\u0430\u0449\u0438\u0442\u043e\u0439 \u043e\u0442 DDoS, VPS VDS \u0441\u0435\u0440\u0432\u0435\u0440\u044b","og:type":"article","og:title":"\ud83e\udd47DBA: \u0433\u0440\u0430\u043c\u043e\u0442\u043d\u043e \u043e\u0440\u0433\u0430\u043d\u0438\u0437\u043e\u0432\u044b\u0432\u0430\u0435\u043c \u0441\u0438\u043d\u0445\u0440\u043e\u043d\u0438\u0437\u0430\u0446\u0438\u0438 \u0438 \u0438\u043c\u043f\u043e\u0440\u0442\u044b | ProHoster","og:description":"\u041f\u0440\u0438 \u0441\u043b\u043e\u0436\u043d\u043e\u0439 \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0435 \u0431\u043e\u043b\u044c\u0448\u0438\u0445 \u043d\u0430\u0431\u043e\u0440\u043e\u0432 \u0434\u0430\u043d\u043d\u044b\u0445 (\u0440\u0430\u0437\u043d\u044b\u0435 ETL-\u043f\u0440\u043e\u0446\u0435\u0441\u0441\u044b: \u0438\u043c\u043f\u043e\u0440\u0442\u044b, \u043a\u043e\u043d\u0432\u0435\u0440\u0442\u0430\u0446\u0438\u0438 \u0438 \u0441\u0438\u043d\u0445\u0440\u043e\u043d\u0438\u0437\u0430\u0446\u0438\u0438 \u0441 \u0432\u043d\u0435\u0448\u043d\u0438\u043c \u0438\u0441\u0442\u043e\u0447\u043d\u0438\u043a\u043e\u043c) \u0447\u0430\u0441\u0442\u043e.","og:url":"https:\/\/prohoster.info\/sk\/blog\/administrirovanie\/dba-gramotno-organizovyvaem-sinhronizaczii-i-importy","og:image":"https:\/\/prohoster.info\/wp-content\/uploads\/2021\/11\/logo-350.jpg","og:image:secure_url":"https:\/\/prohoster.info\/wp-content\/uploads\/2021\/11\/logo-350.jpg","og:image:width":350,"og:image:height":350,"article:published_time":"2020-03-22T05:42:22+00:00","article:modified_time":"2020-03-22T05:42:22+00:00","article:publisher":"https:\/\/www.facebook.com\/prohoster","article:author":"https:\/\/www.facebook.com\/prohoster"},"aioseo_meta_data":{"post_id":"74953","title":null,"description":null,"keywords":null,"keyphrases":null,"primary_term":null,"canonical_url":null,"og_title":null,"og_description":null,"og_object_type":"default","og_image_type":"default","og_image_url":null,"og_image_width":null,"og_image_height":null,"og_image_custom_url":null,"og_image_custom_fields":null,"og_video":null,"og_custom_url":null,"og_article_section":null,"og_article_tags":null,"twitter_use_og":false,"twitter_card":"default","twitter_image_type":"default","twitter_image_url":null,"twitter_image_custom_url":null,"twitter_image_custom_fields":null,"twitter_title":null,"twitter_description":null,"schema":{"blockGraphs":[],"customGraphs":[],"default":{"data":{"Article":[],"Course":[],"Dataset":[],"FAQPage":[],"Movie":[],"Person":[],"Product":[],"ProductReview":[],"Car":[],"Recipe":[],"Service":[],"SoftwareApplication":[],"WebPage":[]},"graphName":"","isEnabled":true},"graphs":[]},"schema_type":null,"schema_type_options":null,"pillar_content":false,"robots_default":true,"robots_noindex":false,"robots_noarchive":false,"robots_nosnippet":false,"robots_nofollow":false,"robots_noimageindex":false,"robots_noodp":false,"robots_notranslate":false,"robots_max_snippet":null,"robots_max_videopreview":null,"robots_max_imagepreview":"large","priority":null,"frequency":null,"local_seo":null,"seo_analyzer_scan_date":null,"breadcrumb_settings":null,"limit_modified_date":false,"reviewed_by":null,"ai":null,"created":"2021-02-28 18:04:26","updated":"2022-09-30 13:25:20","focus_keyword":null,"additional_keywords":null,"truseo_locale":null},"gt_translate_keys":[{"key":"link","format":"url"}],"_links":{"self":[{"href":"https:\/\/prohoster.info\/sk\/wp-json\/wp\/v2\/posts\/74953","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/prohoster.info\/sk\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/prohoster.info\/sk\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/prohoster.info\/sk\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/prohoster.info\/sk\/wp-json\/wp\/v2\/comments?post=74953"}],"version-history":[{"count":0,"href":"https:\/\/prohoster.info\/sk\/wp-json\/wp\/v2\/posts\/74953\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/prohoster.info\/sk\/wp-json\/wp\/v2\/media\/74954"}],"wp:attachment":[{"href":"https:\/\/prohoster.info\/sk\/wp-json\/wp\/v2\/media?parent=74953"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/prohoster.info\/sk\/wp-json\/wp\/v2\/categories?post=74953"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/prohoster.info\/sk\/wp-json\/wp\/v2\/tags?post=74953"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}