{"id":83649,"date":"2020-06-02T07:42:21","date_gmt":"2020-06-02T05:42:21","guid":{"rendered":"https:\/\/prohoster.info\/blog\/administrirovanie\/database-as-sode-experience"},"modified":"2020-06-02T07:42:21","modified_gmt":"2020-06-02T05:42:21","slug":"database-as-sode-experience","status":"publish","type":"post","link":"https:\/\/prohoster.info\/sk\/blog\/administrirovanie\/database-as-sode-experience","title":{"rendered":"Z\u00e1\u017eitok \u00abDatabase as Code\u00bb","gt_translate_keys":[{"key":"rendered","format":"text"}]},"content":{"rendered":"<p><img decoding=\"async\" alt=\"Z\u00e1\u017eitok \u00abDatabase as Code\u00bb\" src=\"\/wp-content\/uploads\/2020\/06\/a1ac23deeded97559fbe787ed09184a5.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>SQL, \u010do m\u00f4\u017ee by\u0165 jednoduch\u0161ie? Ka\u017ed\u00fd z n\u00e1s m\u00f4\u017ee nap\u00edsa\u0165 jednoduch\u00fd dotaz \u2014 zad\u00e1me <strong><em>select<\/em><\/strong>, vymen\u00favame potrebn\u00e9 st\u013apce, potom <strong><em>z<\/em><\/strong>, n\u00e1zov tabu\u013eky, trochu podmienok v <strong><em>kde<\/em><\/strong> a v\u0161etko \u2014 u\u017e m\u00e1me u\u017eito\u010dn\u00e9 d\u00e1ta v na\u0161ich ruk\u00e1ch, pri\u010dom (takmer) nez\u00e1le\u017e\u00ed na tom, ak\u00fd DBMS sa nach\u00e1dza pod kapotom (alebo to mo\u017eno ani nie je <noindex><a rel=\"nofollow\" href=\"https:\/\/osquery.io\/\">DBMS). V\u00fdsledkom je, \u017ee s ak\u00fdmko\u013evek zdrojom \u00fadajov (rela\u010dn\u00fdm alebo nie) sa d\u00e1 pracova\u0165 z poh\u013eadu be\u017en\u00e9ho k\u00f3du (s v\u0161etk\u00fdm, \u010do z toho vypl\u00fdva \u2014 verzionovanie, rev\u00edzia k\u00f3du, statick\u00e1 anal\u00fdza, automatizovan\u00e9 testy a v\u0161etko toto). A to sa net\u00fdka len samotn\u00fdch d\u00e1t, sch\u00e9m a migr\u00e1ci\u00ed, ale v\u00f4bec celej \u010dinnosti \u00falo\u017eiska. V tomto \u010dl\u00e1nku sa budeme zaobera\u0165 ka\u017edodenn\u00fdmi \u00falohami a probl\u00e9mami pri pr\u00e1ci s r\u00f4znymi DB so zameran\u00edm na \"datab\u00e1zu ako k\u00f3d\".<\/a><\/noindex>). V d\u00f4sledku toho mo\u017eno pracova\u0165 prakticky s ak\u00fdmiko\u013evek zdrojmi \u00fadajov (rela\u010dn\u00fdmi aj nie) z poh\u013eadu be\u017en\u00e9ho k\u00f3du (so v\u0161etk\u00fdm, \u010do k tomu patr\u00ed \u2014 verzionovanie, rev\u00edzia k\u00f3du, statick\u00e1 anal\u00fdza, automatizovan\u00e9 testy a podobne). A to sa t\u00fdka nielen samotn\u00fdch \u00fadajov, sch\u00e9m a migr\u00e1ci\u00ed, ale vlastne celej \u017eivotnosti \u00falo\u017eiska. V tomto \u010dl\u00e1nku sa budeme venova\u0165 ka\u017edodenn\u00fdm \u00faloh\u00e1m a probl\u00e9mom pri pr\u00e1ci s r\u00f4znymi datab\u00e1zami z h\u013eadiska &quot;database as code&quot;.<\/p>\n<p><\/p>\n<p>ORM. <noindex><a rel=\"nofollow\" href=\"https:\/\/www.yegor256.com\/2014\/12\/01\/orm-offensive-anti-pattern.html\">Prv\u00e9 bitky typu \"SQL vs ORM\" boli zaznamenan\u00e9 u\u017e v<\/a><\/noindex>. Prv\u00e9 bitky typu &quot;SQL vs ORM&quot; boli zaznamenan\u00e9 u\u017e v <noindex><a rel=\"nofollow\" href=\"https:\/\/www.sql.ru\/forum\/904343\/orm-vs-sql\">Objektovo-rela\u010dn\u00e9 mapovanie<\/a><\/noindex>.<\/p>\n<p><noindex><a rel=\"nofollow\" name=\"habracut\"><\/a><\/noindex><\/p>\n<h5 id=\"obektno-relyacionnyy-maping\">Z\u00e1stancovia ORM tradi\u010dne oce\u0148uj\u00fa r\u00fdchlos\u0165 a jednoduchos\u0165 v\u00fdvoja, nez\u00e1vislos\u0165 od DBMS a \u010distotu k\u00f3du. Pre mnoh\u00fdch z n\u00e1s k\u00f3d pr\u00e1ce s DB (a \u010dasto aj samotn\u00e1 DB)<\/h5>\n<p><\/p>\n<p>vyzer\u00e1 zvy\u010dajne pribli\u017ene takto\u2026<\/p>\n<p><\/p>\n<p>                        <b class=\"spoiler_title\">zvy\u010dajne vyzer\u00e1 pribli\u017ene takto\u2026<\/b><\/p>\n<pre><code class=\"java\">@Entity\n@Table(name = &quot;stock&quot;, catalog = &quot;maindb&quot;, uniqueConstraints = {\n        @UniqueConstraint(columnNames = &quot;STOCK_NAME&quot;),\n        @UniqueConstraint(columnNames = &quot;STOCK_CODE&quot;) })\npublic class Stock implements java.io.Serializable {\n\n    @Id\n    @GeneratedValue(strategy = IDENTITY)\n    @Column(name = &quot;STOCK_ID&quot;, unique = true, nullable = false)\n    public Integer getStockId() {\n        return this.stockId;\n    }\n  ...<\/code><\/pre>\n<p><\/p>\n<p>\"SQL nen\u00e1vis\u0165.\" <noindex><a rel=\"nofollow\" href=\"https:\/\/www.sql.ru\/forum\/1303231\/prichiny-nenavisti-k-yazyku-sql\">&quot;SQL nen\u00e1visti&quot;<\/a><\/noindex>.<\/p>\n<p><\/p>\n<p>Na druhej strane barik\u00e1dy pr\u00edvr\u017eenci \u010distej &quot;handmade&quot;-SQL poukazuj\u00fa na mo\u017enos\u0165 vy\u017em\u00fdka\u0165 maximum zo svojej DB bez dodato\u010dn\u00fdch vrstiev a abstrakci\u00ed. V d\u00f4sledku toho vznikaj\u00fa &quot;data-centric&quot; projekty, kde sa datab\u00e1zami zaoberaj\u00fa \u0161peci\u00e1lne vy\u0161kolen\u00ed \u013eudia (tie\u017e naz\u00fdvan\u00ed &quot;datab\u00e1zisti&quot;, &quot;datab\u00e1zov\u00ed \u0161pecialisti&quot; a pod.), a v\u00fdvoj\u00e1rom ost\u00e1va len &quot;\u0165aha\u0165&quot; hotov\u00e9 poh\u013eady a ulo\u017een\u00e9 proced\u00fary, ani\u017e by sa zaoberali podrobnos\u0165ami.<\/p>\n<p><\/p>\n<p>Yesql. <noindex><a rel=\"nofollow\" href=\"https:\/\/github.com\/krisajenkins\/yesql\">Uvediem p\u00e1r vet z celkovej koncepcie vo svojom vo\u013enom preklade, a podrobnej\u0161ie sa s \u0148ou m\u00f4\u017eete obozn\u00e1mi\u0165.<\/a><\/noindex>. Uvediem p\u00e1r viet z v\u0161eobecnej koncepcie vo svojom vo\u013enom preklade, a podrobnej\u0161ie sa s \u0148ou m\u00f4\u017eete obozn\u00e1mi\u0165 <noindex><a rel=\"nofollow\" href=\"https:\/\/github.com\/krisajenkins\/yesql#rationale\">tu<\/a><\/noindex>.<\/p>\n<p><\/p>\n<blockquote><p>Clojure je skvel\u00fd jazyk na vytv\u00e1ranie DSL, ale SQL je u\u017e s\u00e1m osebe skvel\u00fd DSL, a nepotrebujeme \u010fal\u0161\u00ed. S-v\u00fdrazy s\u00fa \u00fa\u017easn\u00e9, ale tu neprin\u00e1\u0161aj\u00fa ni\u010d nov\u00e9. Nakoniec dostaneme z\u00e1tvorky len pre z\u00e1tvorky. Nes\u00fahlas\u00edte? Potom si po\u010dkajte, kedy abstrakcia nad datab\u00e1zou za\u010dne unika\u0165 a vy za\u010dnete bojova\u0165 s funkciou. <em>(raw-sql)<\/em><\/p>\n<p>A \u010do robi\u0165? Po\u010fme necha\u0165 SQL oby\u010dajn\u00fdm SQL \u2014 jeden s\u00fabor na jeden dotaz:<\/p><\/blockquote>\n<p><\/p>\n<pre><code class=\"sql\">-- name: users-by-country\nselect *\n  from users\n where country_code = :country_code<\/code><\/pre>\n<p><\/p>\n<blockquote><p>\u2026 a potom si pre\u010d\u00edtajte tento s\u00fabor a preme\u0148te ho na oby\u010dajn\u00fa Clojure funkciu:<\/p><\/blockquote>\n<p><\/p>\n<pre><code class=\"lisp\">(defqueries &quot;some\/where\/users_by_country.sql&quot;\n   {:connection db-spec})\n\n;;; Bola vytvoren\u00e1 funkcia s n\u00e1zvom `users-by-country`.\n;;; Po\u010fme ju pou\u017ei\u0165:\n(users-by-country {:country_code &quot;GB&quot;})\n;=&gt; ({:name &quot;Kris&quot; :country_code &quot;GB&quot; ...} ...)<\/code><\/pre>\n<p><\/p>\n<blockquote><p>Dodr\u017eiavan\u00edm princ\u00edpu &quot;SQL oddelene, Clojure oddelene&quot; z\u00edskate:<\/p>\n<ul>\n<li>\u017diadne syntaktick\u00e9 prekvapenia. Va\u0161a datab\u00e1za (ako ka\u017ed\u00e1 in\u00e1) nie je na 100 % v s\u00falade so SQL \u0161tandardom \u2014 ale pre Yesql to nie je d\u00f4le\u017eit\u00e9. Nikdy nebudete tr\u00e1vi\u0165 \u010das loven\u00edm funkci\u00ed so syntaxou ekvivalentnou SQL. Nikdy sa nebudete musie\u0165 vraca\u0165 k funkcii <em>(raw-sql &quot;some (&#8216;funky&#8217; :: SYNTAX)&quot;))<\/em>.<\/li>\n<li>Najlep\u0161ia podpora editora. V\u00e1\u0161 editor u\u017e m\u00e1 skvel\u00fa podporu pre SQL. Zachovan\u00edm SQL ako SQL ho m\u00f4\u017eete jednoducho pou\u017e\u00edva\u0165.<\/li>\n<li>Kompatibilita pre t\u00edm. Va\u0161i DBA m\u00f4\u017eu \u010d\u00edta\u0165 a p\u00edsa\u0165 SQL, ktor\u00e9 pou\u017e\u00edvate vo svojom Clojure projekte.<\/li>\n<li>Jednoduch\u0161ia konfigur\u00e1cia v\u00fdkonu. Potrebujete vytvori\u0165 pl\u00e1n pre problematick\u00fd dotaz? Nie je to probl\u00e9m, ke\u010f je v\u00e1\u0161 dotaz oby\u010dajn\u00fdm SQL.<\/li>\n<li>Op\u00e4tovn\u00e9 pou\u017eitie dotazov. Presu\u0148te tieto ist\u00e9 SQL s\u00fabory do in\u00fdch projektov, preto\u017ee to je len star\u00fd dobr\u00fd SQL \u2014 jednoducho ho zdie\u013eajte.<\/li>\n<\/ul>\n<p>\n<\/p><\/blockquote>\n<p>Pod\u013ea m\u0148a je my\u0161lienka ve\u013emi skvel\u00e1 a z\u00e1rove\u0148 ve\u013emi jednoduch\u00e1, v\u010faka \u010domu projekt z\u00edskal mno\u017estvo <noindex><a rel=\"nofollow\" href=\"https:\/\/github.com\/krisajenkins\/yesql#other-languages\">n\u00e1sledn\u00edkov.<\/a><\/noindex> v r\u00f4znych jazykoch. A my sa \u010falej pok\u00fasime aplikova\u0165 podobn\u00fa filozofiu oddelenia SQL k\u00f3du od v\u0161etk\u00e9ho ostatn\u00e9ho \u010faleko za hranice ORM.<\/p>\n<p><\/p>\n<h5 id=\"ide--db-menedzhery\">IDE &amp; DB-\u0159\u00eddic\u00ed n\u00e1stroje<\/h5>\n<p><\/p>\n<p>Za\u010dneme jednoduchou ka\u017edodennou \u00falohou. \u010casto mus\u00edme vyh\u013ead\u00e1va\u0165 objekty v datab\u00e1ze, napr\u00edklad n\u00e1js\u0165 tabu\u013eku v sch\u00e9me a presk\u00fama\u0165 jej \u0161trukt\u00faru (ak\u00e9 s\u00fa pou\u017eit\u00e9 st\u013apce, k\u013e\u00fa\u010de, indexy, obmedzenia a podobne). Od akejko\u013evek grafickej IDE alebo aspo\u0148 z\u00e1kladn\u00e9ho DB-managera o\u010dak\u00e1vame predov\u0161etk\u00fdm tieto schopnosti. Aby sme to mali r\u00fdchlo a nemuseli \u010daka\u0165 pol hodiny, k\u00fdm sa objav\u00ed okno s potrebn\u00fdmi inform\u00e1ciami (najm\u00e4 pri pomal\u00fdch pripojeniach k vzdialen\u00fdm datab\u00e1zam), a navy\u0161e, aby z\u00edskan\u00e9 inform\u00e1cie boli \u010derstv\u00e9 a aktu\u00e1lne, a nie star\u00e9 vyrovnan\u00e9 d\u00e1ta. \u010c\u00edm zlo\u017eitej\u0161ia a v\u00e4\u010d\u0161ia datab\u00e1za je, t\u00fdm \u0165a\u017e\u0161ie je to dosiahnu\u0165.<\/p>\n<p><\/p>\n<p>Ale zvy\u010dajne hod\u00edm my\u0161 niekde bokom a jednoducho p\u00ed\u0161em k\u00f3d. Povedzme, \u017ee potrebujem zisti\u0165, ak\u00e9 tabu\u013eky (a s ak\u00fdmi vlastnos\u0165ami) sa nach\u00e1dzaj\u00fa v sch\u00e9me \"HR\". V mnoh\u00fdch S\u00daDB je potrebn\u00e9ho v\u00fdsledku mo\u017en\u00e9 dosiahnu\u0165 tak\u00fdmto jednoduch\u00fdm dopytom z information_schema:<\/p>\n<p><\/p>\n<pre><code class=\"sql\">select table_name\n     , ...\n  from information_schema.tables\n where schema = 'HR'<\/code><\/pre>\n<p><\/p>\n<p>Obsah tak\u00fdchto tabuliek referen\u010dn\u00fdch \u00fadajov sa pri prechode medzi datab\u00e1zami l\u00ed\u0161i v z\u00e1vislosti od schopnost\u00ed ka\u017ed\u00e9ho DBMS. Napr\u00edklad pre MySQL m\u00f4\u017eeme z tej istej tabu\u013eky z\u00edska\u0165 \u0161pecifick\u00e9 parametre pre tento DBMS:<\/p>\n<p><\/p>\n<pre><code class=\"sql\">select table_name\n     , storage_engine -- Pou\u017e\u00edvan\u00fd \"motor\" (\"MyISAM\", \"InnoDB\" at\u010f.)\n     , row_format     -- Form\u00e1t riadku (\"Fixed\", \"Dynamic\" at\u010f.)\n     , ...\n  from information_schema.tables\n where schema = 'HR'<\/code><\/pre>\n<p><\/p>\n<p>Oracle nem\u00e1 information_schema, ale m\u00e1 <noindex><a rel=\"nofollow\" href=\"https:\/\/en.wikipedia.org\/wiki\/Oracle_metadata\">Oracle metadata<\/a><\/noindex>, a nevznikaj\u00fa s t\u00fdm ve\u013ek\u00e9 probl\u00e9my:<\/p>\n<p><\/p>\n<pre><code class=\"sql\">select table_name\n     , pct_free       -- Minim\u00e1lne vo\u013en\u00e9 miesto v bloku \u00fadajov (%)\n     , pct_used       -- Minim\u00e1lne pou\u017eit\u00e9 miesto v bloku \u00fadajov (%)\n     , last_analyzed  -- D\u00e1tum posledn\u00e9ho zhroma\u017edenia \u0161tatistiky\n     , ...\n  from all_tables\n where owner = 'HR'<\/code><\/pre>\n<p><\/p>\n<p>Nie je v\u00fdnimkou ani ClickHouse:<\/p>\n<p><\/p>\n<pre><code class=\"sql\">select name\n     , engine -- Pou\u017e\u00edvan\u00fd \"motor\" (\"MergeTree\", \"Dictionary\" at\u010f.)\n     , ...\n  from system.tables\n where database = 'HR'<\/code><\/pre>\n<p><\/p>\n<p>Nie\u010do podobn\u00e9 je mo\u017en\u00e9 vykona\u0165 aj v Cassandre (kde s\u00fa columnfamilies namiesto tabuliek a keyspacey namiesto sch\u00e9m):<\/p>\n<p><\/p>\n<pre><code class=\"sql\">select columnfamily_name\n     , compaction_strategy_class  -- Strat\u00e9gia zberu odpadu\n     , gc_grace_seconds           -- Doba \u017eivota odpadu\n     , ...\n  from system.schema_columnfamilies\n where keyspace_name = 'HR'<\/code><\/pre>\n<p><\/p>\n<p>Pre v\u00e4\u010d\u0161inu ostatn\u00fdch datab\u00e1z je tie\u017e mo\u017en\u00e9 vymyslie\u0165 podobn\u00e9 dopyty (aj v Mongo je <noindex><a rel=\"nofollow\" href=\"https:\/\/docs.mongodb.com\/manual\/reference\/system-collections\/#%3Cdatabase%3E.system.namespaces\">\u0161peci\u00e1lna syst\u00e9mov\u00e1 kolekcia<\/a><\/noindex>, ktor\u00e1 obsahuje inform\u00e1cie o v\u0161etk\u00fdch kolekci\u00e1ch v syst\u00e9me).<\/p>\n<p><\/p>\n<p>Samozrejme, t\u00fdmto sp\u00f4sobom je mo\u017en\u00e9 z\u00edska\u0165 inform\u00e1cie nielen o tabu\u013ek\u00e1ch, ale o akomko\u013evek objekte. Pravidelne sa n\u00e1jdu \u013eudia, ktor\u00ed zdie\u013eaj\u00fa tak\u00fdto k\u00f3d pre r\u00f4zne datab\u00e1zy, ako napr\u00edklad v s\u00e9rii \u010dl\u00e1nkov na habr \"Funkcie na dokument\u00e1ciu datab\u00e1z PostgreSQL\" (<noindex><a rel=\"nofollow\" href=\"https:\/\/habr.com\/post\/415575\">ajb<\/a><\/noindex>, <noindex><a rel=\"nofollow\" href=\"https:\/\/habr.com\/post\/415897\">ben<\/a><\/noindex>, <noindex><a rel=\"nofollow\" href=\"https:\/\/habr.com\/post\/418597\">gim<\/a><\/noindex>). Samozrejme, udr\u017ea\u0165 si v\u0161etky tieto dopyty v hlave a neust\u00e1le ich zad\u00e1va\u0165 je \"tak\u00e9 si\" pote\u0161enie, preto vo svojej ob\u013e\u00fabenej IDE\/redaktore m\u00e1m vopred pripraven\u00fa sadu snippetu pre \u010dasto pou\u017e\u00edvan\u00e9 dopyty a zost\u00e1va len zada\u0165 men\u00e1 objektov do \u0161abl\u00f3ny.<\/p>\n<p><\/p>\n<p>Nakoniec je tak\u00fd sp\u00f4sob navig\u00e1cie a vyh\u013ead\u00e1vania objektov ove\u013ea flexibilnej\u0161\u00ed, \u0161etr\u00ed ve\u013ea \u010dasu a umo\u017e\u0148uje z\u00edska\u0165 presne tie inform\u00e1cie a v tej forme, v akej s\u00fa v s\u00fa\u010dasnosti potrebn\u00e9 (ako je pop\u00edsan\u00e9 v pr\u00edspevku <noindex><a rel=\"nofollow\" href=\"https:\/\/habr.com\/company\/JetBrains\/blog\/342094\">\"Export \u00fadajov z datab\u00e1zy v \u013eubovo\u013enom form\u00e1te: \u010do dok\u00e1\u017eu IDE na platforme IntelliJ\"<\/a><\/noindex>).<\/p>\n<p><\/p>\n<h5 id=\"operacii-s-obektami\">Oper\u00e1cie s objektmi<\/h5>\n<p><\/p>\n<p>Po tom, \u010do sme na\u0161li a presk\u00famali potrebn\u00e9 objekty, je \u010das s nimi urobi\u0165 nie\u010do u\u017eito\u010dn\u00e9. Samozrejme, bez toho, aby sme zdvihli prsty od kl\u00e1vesnice.<\/p>\n<p><\/p>\n<p>Nie je tajomstvom, \u017ee jednoduch\u00e9 odstr\u00e1nenie tabu\u013eky bude vyzera\u0165 rovnako takmer vo v\u0161etk\u00fdch DB:<\/p>\n<p><\/p>\n<pre><code class=\"sql\">drop table hr.persons<\/code><\/pre>\n<p><\/p>\n<p>S vytv\u00e1ran\u00edm tabuliek je to u\u017e zauj\u00edmavej\u0161ie. Takmer ka\u017ed\u00e1 DBMS (vr\u00e1tane mnoh\u00fdch NoSQL) v nejakom form\u00e1te zvl\u00e1da &quot;create table&quot;, a jej hlavn\u00fa \u010das\u0165 mo\u017eno len \u0165a\u017eko odl\u00ed\u0161i\u0165 (n\u00e1zov, zoznam st\u013apcov, d\u00e1tov\u00e9 typy), no ostatn\u00e9 detaily sa m\u00f4\u017eu drasticky l\u00ed\u0161i\u0165 a z\u00e1visia od vn\u00fatornej \u0161trukt\u00fary a mo\u017enost\u00ed konkr\u00e9tnej DBMS. M\u00f4j ob\u013e\u00faben\u00fd pr\u00edklad \u2014 v dokument\u00e1cii Oracle s\u00fa len &quot;hol\u00e9&quot; BNF&#8217;y pre syntax &quot;create table&quot; <noindex><a rel=\"nofollow\" href=\"https:\/\/docs.oracle.com\/en\/database\/oracle\/oracle-database\/19\/sqlrf\/sql-language-reference.pdf\">31 str\u00e1n<\/a><\/noindex>. In\u00e9 SODB maj\u00fa skromnej\u0161ie mo\u017enosti, ale ka\u017ed\u00e1 z nich m\u00e1 aj mno\u017estvo zauj\u00edmav\u00fdch a unik\u00e1tnych funkci\u00ed na vytv\u00e1ranie tabuliek (<noindex><a rel=\"nofollow\" href=\"https:\/\/www.postgresql.org\/docs\/current\/static\/sql-createtable.html\">postgres<\/a><\/noindex>, <noindex><a rel=\"nofollow\" href=\"https:\/\/dev.mysql.com\/doc\/refman\/8.0\/en\/create-table.html\">mysql<\/a><\/noindex>, <noindex><a rel=\"nofollow\" href=\"https:\/\/www.cockroachlabs.com\/docs\/stable\/create-table.html#expanded\">cockroach<\/a><\/noindex>, <noindex><a rel=\"nofollow\" href=\"https:\/\/docs.datastax.com\/en\/cql\/3.3\/cql\/cql_reference\/cqlCreateTable.html\">cassandra<\/a><\/noindex>).  \u0164a\u017eko si predstavi\u0165, \u017ee by nejak\u00fd grafick\u00fd &quot;wizard&quot; z \u010fal\u0161ej IDE (najm\u00e4 univerz\u00e1lnej) mohol celkom pokry\u0165 v\u0161etky tieto schopnosti, a ak aj dok\u00e1\u017ee, bude to poh\u013ead pre slab\u0161ie povahy. Z\u00e1rove\u0148 spr\u00e1vne a na\u010das nap\u00edsan\u00fd pr\u00edkaz <strong><em>create table<\/em><\/strong> umo\u017en\u00ed bez probl\u00e9mov vyu\u017ei\u0165 v\u0161etky z nich, zabezpe\u010di\u0165 ukladanie a pr\u00edstup k va\u0161im \u00fadajom spo\u013eahliv\u00fd, optim\u00e1lny a maxim\u00e1lne pohodln\u00fd.<\/p>\n<p><\/p>\n<p>Rovnako v mnoh\u00fdch DBMS existuj\u00fa \u0161pecifick\u00e9 typy objektov, ktor\u00e9 v in\u00fdch DBMS ch\u00fdbaj\u00fa. Dokonca m\u00f4\u017eeme vykon\u00e1va\u0165 oper\u00e1cie nielen nad datab\u00e1zov\u00fdmi objektmi, ale aj nad samotnou DBMS, ako napr\u00edklad &quot;ukon\u010di\u0165&quot; proces, uvo\u013eni\u0165 nejak\u00fa oblas\u0165 pam\u00e4te, zapn\u00fa\u0165 trasovanie, prejs\u0165 do re\u017eimu &quot;read only&quot; a mnoho \u010fal\u0161\u00edch.<\/p>\n<p><\/p>\n<h5 id=\"a-teper-nemnogo-porisuem\">A teraz si trochu nakresl\u00edme.<\/h5>\n<p><\/p>\n<p>Jednou z najbe\u017enej\u0161\u00edch \u00faloh je vytvori\u0165 diagram s datab\u00e1zov\u00fdmi objektmi, na peknom obr\u00e1zku vidie\u0165 objekty a vz\u0165ahy medzi nimi. Toto zvl\u00e1dne takmer ka\u017ed\u00e1 grafick\u00e1 IDE, jednotliv\u00e9 pr\u00edkazov\u00e9 n\u00e1stroje, \u0161pecializovan\u00e9 grafick\u00e9 n\u00e1stroje a modelovacie programy. Ktor\u00e9 v\u00e1m nie\u010do nakreslia &quot;ako vedia&quot;, a trochu ovplyvni\u0165 tento proces m\u00f4\u017eete len s nieko\u013ek\u00fdmi parametrami v konfigura\u010dnom s\u00fabore alebo za\u010diarkavac\u00edmi pol\u00ed\u010dkami v rozhran\u00ed.<\/p>\n<p><\/p>\n<p>Av\u0161ak tento probl\u00e9m mo\u017eno vyrie\u0161i\u0165 ove\u013ea jednoducho, flexibilnej\u0161ie a elegantnej\u0161ie, a samozrejme pomocou k\u00f3du. Na vytv\u00e1ranie diagramov akejko\u013evek zlo\u017eitosti m\u00e1me hne\u010f nieko\u013eko \u0161pecializovan\u00fdch zna\u010dkovac\u00edch jazykov (DOT, GraphML a pod.), pri\u010dom k nim existuje mno\u017estvo aplik\u00e1ci\u00ed (GraphViz, PlantUML, Mermaid), ktor\u00e9 dok\u00e1\u017eu \u010d\u00edta\u0165 tak\u00e9to pokyny a vizualizova\u0165 ich v r\u00f4znych form\u00e1toch. A inform\u00e1cie o objektoch a vz\u0165ahoch medzi nimi u\u017e vieme, ako z\u00edska\u0165.<\/p>\n<p><\/p>\n<p>Uvedieme mal\u00fd pr\u00edklad toho, ako by to mohlo vyzera\u0165 s pou\u017eit\u00edm PlantUML a <noindex><a rel=\"nofollow\" href=\"https:\/\/habr.com\/ru\/company\/postgrespro\/blog\/316428\/\">demon\u0161tra\u010dnej datab\u00e1zy pre PostgreSQL.<\/a><\/noindex> (v\u013eavo SQL dotaz, ktor\u00fd vygeneruje potrebn\u00fd pr\u00edkaz pre PlantUML, a vpravo v\u00fdsledok):<\/p>\n<p>\n<img decoding=\"async\" alt=\"Z\u00e1\u017eitok \u00abDatabase as Code\u00bb\" src=\"\/wp-content\/uploads\/2020\/06\/c5cb2a138df1527abe47cbf8d695cb36.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<pre><code class=\"sql\">select '@startuml'||chr(10)||'hide methods'||chr(10)||'hide stereotypes' union all\nselect distinct ccu.table_name || ' --|&gt; ' ||\n       tc.table_name as val\n  from table_constraints as tc\n  join key_column_usage as kcu\n    on tc.constraint_name = kcu.constraint_name\n  join constraint_column_usage as ccu\n    on ccu.constraint_name = tc.constraint_name\n where tc.constraint_type = 'FOREIGN KEY'\n   and tc.table_name ~ '.*' union all\nselect '@enduml'<\/code><\/pre>\n<p><\/p>\n<p>Ak sa trochu sna\u017e\u00edme, m\u00f4\u017eeme na z\u00e1klade <noindex><a rel=\"nofollow\" href=\"https:\/\/gist.github.com\/QuantumGhost\/0955a45383a0b6c0bc24f9654b3cb561\">ER \u0161abl\u00f3ny pre PlantUML<\/a><\/noindex> z\u00edska\u0165 nie\u010do silne podobn\u00e9 skuto\u010dnej ER diagrame:<\/p>\n<p><\/p>\n<p>                        <b class=\"spoiler_title\">SQL dotaz je o \u010dosi zlo\u017eitej\u0161\u00ed.<\/b><\/p>\n<pre><code class=\"sql\">-- Hlavi\u010dka\nselect &#039;@startuml\n        !define Table(name,desc) class name as &quot;desc&quot; &lt;&lt; (T,#FFAAAA) &gt;&amp;gt;\n        !define primary_key(x) &lt;b&gt;x&lt;\/b&gt;\n        !define unique(x) &lt;color:green&gt;x&lt;\/color&gt;\n        !define not_null(x) &lt;u&gt;x&lt;\/u&gt;\n        hide methods\n        hide stereotypes&#039;\n union all\n-- Tabu\u013eky\nselect format(&#039;Table(%s, &quot;%s n inform&aacute;cie o %s&quot;) {&#039;||chr(10), table_name, table_name, table_name) ||\n       (select string_agg(column_name || &#039; &#039; || upper(udt_name), chr(10))\n          from information_schema.columns\n         where table_schema = &#039;public&#039;\n           and table_name = t.table_name) || chr(10) || &#039;}&#039;\n  from information_schema.tables t\n where table_schema = &#039;public&#039;\n union all\n-- Vz\u0165ahy medzi tabu\u013ekami\nselect distinct ccu.table_name || &#039; &quot;1&quot; --&amp;gt; &quot;0..N&quot; &#039; || tc.table_name || format(&#039; : &quot;A %s m&ocirc;\u017ee ma\u0165 mnoho %s&quot;&#039;, ccu.table_name, tc.table_name)\n  from information_schema.table_constraints as tc\n  join information_schema.key_column_usage as kcu on tc.constraint_name = kcu.constraint_name\n  join information_schema.constraint_column_usage as ccu on ccu.constraint_name = tc.constraint_name\n where tc.constraint_type = &#039;FOREIGN KEY&#039;\n   and ccu.constraint_schema = &#039;public&#039;\n   and tc.table_name ~ &#039;.*&#039;\n union all\n-- P&auml;tka\nselect &#039;@enduml&#039;<\/code><\/pre>\n<p>\n<img decoding=\"async\" alt=\"Z\u00e1\u017eitok \u00abDatabase as Code\u00bb\" src=\"\/wp-content\/uploads\/2020\/06\/bd45420a4fd1bdfcf20cbe74a0638c7b.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p>Ak si pozorne v\u0161imneme, mnoho vizualiza\u010dn\u00fdch n\u00e1strojov tie\u017e pod kapotou pou\u017e\u00edva podobn\u00e9 dotazy. Pravda v\u0161ak je, \u017ee tieto dotazy s\u00fa zvy\u010dajne hlboko <noindex><a rel=\"nofollow\" href=\"https:\/\/github.com\/pgmodeler\/pgmodeler\/blob\/9c615c0b0871df3cd649983ce61e802b0ff0137b\/schemas\/catalog\/table.sch\">&quot;zak\u00f3dovan\u00e9&quot; v samotnom k\u00f3de aplik\u00e1cie a \u0165a\u017eko sa porozumie<\/a><\/noindex>, nieto e\u0161te o ich modifik\u00e1cii.<\/p>\n<p><\/p>\n<h5 id=\"metriki-i-monitoring\">Met\u00f3dy a monitorovanie<\/h5>\n<p><\/p>\n<p>Prejdime k tradi\u010dne zlo\u017eitej t\u00e9me \u2014 monitorovanie v\u00fdkonu DB. Spom\u00ednam si na mal\u00fd pravdiv\u00fd pr\u00edbeh, ktor\u00fd mi rozpr\u00e1val \"jeden m\u00f4j priate\u013e\". Na jednom projekte \u017eil mocn\u00fd DBA, a m\u00e1lokto z v\u00fdvoj\u00e1rov ho poznal osobne, ba dokonca v\u00f4bec ho kedyko\u013evek videl (napriek tomu, \u017ee \u00fadajne pracoval niekde v susednej budove). V hodine \"X\", ke\u010f produk\u010dn\u00e1 syst\u00e9m ve\u013ek\u00e9ho retaileru zrazu za\u010dal \"zl\u00e9ho zn\u00e1\u0161a\u0165\", ticho posielal screenshoty grafov z Oracle Enterprise Managera, na ktor\u00fdch opatrne zv\u00fdraz\u0148oval kritick\u00e9 miesta \u010derven\u00fdm zv\u00fdraz\u0148ova\u010dom pre \"jasnos\u0165\" (to, mierne povedan\u00e9, m\u00e1lo pom\u00e1halo). A tak sa na z\u00e1klade tejto \"fotografie\" muselo lie\u010di\u0165. Z\u00e1rove\u0148 nikto nemal pr\u00edstup k cenn\u00e9mu (v oboch zmysloch slova) Enterprise Manager, preto\u017ee syst\u00e9m je komplikovan\u00fd a drah\u00fd, aby sa \"v\u00fdvoj\u00e1ri n\u00e1hodou nepokazili a v\u0161etko nezni\u010dili\". Preto v\u00fdvoj\u00e1ri \"empiricky\" nach\u00e1dzali miesto a pr\u00ed\u010dinu spomalenia a vydali opravy. Ak sa stra\u0161n\u00fd list od DBA znova neobjavil v najbli\u017e\u0161om \u010dase, tak v\u0161etci si s \u00fa\u013eavou vyd\u00fdchli a vr\u00e1tili sa k svojim aktu\u00e1lnym \u00faloh\u00e1m (do nov\u00e9ho Listu).<\/p>\n<p><\/p>\n<p>Ale proces monitorovania m\u00f4\u017ee vyzera\u0165 vesel\u0161ie a priate\u013eskej\u0161ie, a najm\u00e4 \u2014 pr\u00edstupne a transparentne pre v\u0161etk\u00fdch. Aspo\u0148 jeho z\u00e1kladn\u00e1 \u010das\u0165, ako doplnok k hlavn\u00fdm monitorovac\u00edm syst\u00e9mom (ktor\u00e9 s\u00fa bezpochyby u\u017eito\u010dn\u00e9 a v mnoh\u00fdch pr\u00edpadoch nenahradite\u013en\u00e9). Ka\u017ed\u00e1 DBMS je ochotn\u00e1 a \u00faplne bezplatne zdie\u013ea\u0165 inform\u00e1cie o svojom aktu\u00e1lnom stave a v\u00fdkonnosti. V tej istej \"krvavej\" Oracle DB je prakticky mo\u017en\u00e9 z\u00edska\u0165 ak\u00e9ko\u013evek inform\u00e1cie o v\u00fdkonnosti zo syst\u00e9mov\u00fdch poh\u013eadov, za\u010d\u00ednaj\u00fac procesmi a rel\u00e1ciami a kon\u010diac stavom vyrovn\u00e1vacej pam\u00e4te (napr\u00edklad, <noindex><a rel=\"nofollow\" href=\"https:\/\/oracle-base.com\/dba\/scripts\">Skripty DBA<\/a><\/noindex>, sekcia \"Monitoring\"). V PostgreSQL je taktie\u017e cel\u00e1 rada syst\u00e9mov\u00fdch poh\u013eadov pre <noindex><a rel=\"nofollow\" href=\"https:\/\/www.postgresql.org\/docs\/current\/static\/monitoring-stats.html\">monitorovanie \u010dinnosti datab\u00e1z<\/a><\/noindex>, najm\u00e4 tak\u00e9 nezamenite\u013en\u00e9 v ka\u017edodennom \u017eivote ka\u017ed\u00e9ho DBA, ako s\u00fa <noindex><a rel=\"nofollow\" href=\"https:\/\/www.postgresql.org\/docs\/current\/static\/monitoring-stats.html#PG-STAT-ACTIVITY-VIEW\">pg_stat_activity<\/a><\/noindex>, <noindex><a rel=\"nofollow\" href=\"https:\/\/www.postgresql.org\/docs\/current\/static\/monitoring-stats.html#PG-STAT-DATABASE-VIEW\">pg_stat_database<\/a><\/noindex>, <noindex><a rel=\"nofollow\" href=\"https:\/\/www.postgresql.org\/docs\/current\/static\/monitoring-stats.html#PG-STAT-BGWRITER-VIEW\">pg_stat_bgwriter<\/a><\/noindex>. V MySQL je na tento \u00fa\u010del vyhraden\u00e1 dokonca samostatn\u00e1 sch\u00e9ma <noindex><a rel=\"nofollow\" href=\"https:\/\/dev.mysql.com\/doc\/refman\/8.0\/en\/performance-schema-table-descriptions.html\">performance_schema<\/a><\/noindex>. A v Mongo je zabudovan\u00fd <noindex><a rel=\"nofollow\" href=\"https:\/\/docs.mongodb.com\/manual\/tutorial\/manage-the-database-profiler\/\">profil\u00e9r<\/a><\/noindex> zhroma\u017e\u010fuje \u00fadaje o v\u00fdkone do syst\u00e9movej kolekcie <noindex><a rel=\"nofollow\" href=\"https:\/\/docs.mongodb.com\/manual\/tutorial\/manage-the-database-profiler\/#view-profiler-data\">system.profile<\/a><\/noindex>.<\/p>\n<p><\/p>\n<p>T. o., ozbrojen\u00fd nejak\u00fdm zbera\u010dom metr\u00edk (Telegraf, Metricbeat, Collectd), ktor\u00fd dok\u00e1\u017ee vykon\u00e1va\u0165 vlastn\u00e9 sql dotazy, skladom t\u00fdchto metr\u00edk (InfluxDB, Elasticsearch, Timescaledb) a vizualiz\u00e1torom (Grafana, Kibana), sa d\u00e1 z\u00edska\u0165 pomerne \u013eahk\u00fd a flexibiln\u00fd syst\u00e9m monitorovania, ktor\u00fd bude \u00fazko integrovan\u00fd s in\u00fdmi v\u0161eobecn\u00fdmi metrikami (z\u00edskan\u00fdmi napr\u00edklad zo servera aplik\u00e1ci\u00ed, od OS a pod.). Ako je napr\u00edklad to, \u010do rob\u00ed pgwatch2, kde sa pou\u017e\u00edva kombin\u00e1cia InfluxDB + Grafana a s\u00fabor dotazov na syst\u00e9mov\u00e9 zobrazenia, ku ktor\u00fdm sa daj\u00fa <noindex><a rel=\"nofollow\" href=\"https:\/\/github.com\/cybertec-postgresql\/pgwatch2#adding-metrics\">prida\u0165 vlastn\u00e9 dotazy<\/a><\/noindex>.<\/p>\n<p><\/p>\n<h2 id=\"itogo\">Spolu<\/h2>\n<p><\/p>\n<p>A to je len pribli\u017en\u00fd zoznam toho, \u010do m\u00f4\u017eeme urobi\u0165 s na\u0161ou DB pomocou oby\u010dajn\u00e9ho SQL k\u00f3du. Som si ist\u00fd, \u017ee m\u00f4\u017eeme n\u00e1js\u0165 e\u0161te mno\u017estvo \u010fal\u0161\u00edch aplik\u00e1ci\u00ed, nap\u00ed\u0161te v koment\u00e1roch. A o tom, ako (a predov\u0161etk\u00fdm pre\u010do) to v\u0161etko automatizova\u0165 a zakomponova\u0165 do svojho CI\/CD pipeline, si povieme nabud\u00face.<\/p>\n<p>Zdroj: <a content=\"nofollow\" rel=\"nofollow\" href=\"https:\/\/habr.com\/ru\/post\/426833\/\">habr.com<\/a> <\/p>","protected":false,"gt_translate_keys":[{"key":"rendered","format":"html"}]},"excerpt":{"rendered":"<p>SQL, \u0447\u0442\u043e \u043c\u043e\u0436\u0435\u0442 \u0431\u044b\u0442\u044c \u043f\u0440\u043e\u0449\u0435? \u041a\u0430\u0436\u0434\u044b\u0439 \u0438\u0437 \u043d\u0430\u0441 \u043c\u043e\u0436\u0435\u0442 \u043d\u0430\u043f\u0438\u0441\u0430\u0442\u044c \u043f\u0440\u043e\u0441\u0442\u0435\u043d\u044c\u043a\u0438\u0439 \u0437\u0430\u043f\u0440\u043e\u0441 \u2014 \u043d\u0430\u0431\u0438\u0440\u0430\u0435\u043c select, \u043f\u0435\u0440\u0435\u0447\u0438\u0441\u043b\u044f\u0435\u043c \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u044b\u0435 \u043a\u043e\u043b\u043e\u043d\u043a\u0438, \u0437\u0430\u0442\u0435\u043c from, \u0438\u043c\u044f \u0442\u0430\u0431\u043b\u0438\u0446\u044b, \u043d\u0435\u043c\u043d\u043e\u0433\u043e \u0443\u0441\u043b\u043e\u0432\u0438\u0439 \u0432 where \u0438 \u0432\u0441\u0435 \u2014 \u043f\u043e\u043b\u0435\u0437\u043d\u044b\u0435 \u0434\u0430\u043d\u043d\u044b\u0435 \u0443 \u043d\u0430\u0441 \u0432 \u043a\u0430\u0440\u043c\u0430\u043d\u0435, \u043f\u0440\u0438\u0447\u0435\u043c (\u043f\u043e\u0447\u0442\u0438) \u043d\u0435\u0437\u0430\u0432\u0438\u0441\u0438\u043c\u043e \u043e\u0442 \u0442\u043e\u0433\u043e \u043a\u0430\u043a\u0430\u044f \u0421\u0423\u0411\u0414 \u0432 \u044d\u0442\u043e \u0432\u0440\u0435\u043c\u044f \u043d\u0430\u0445\u043e\u0434\u0438\u0442\u0441\u044f \u043f\u043e\u0434 \u043a\u0430\u043f\u043e\u0442\u043e\u043c (\u0430 \u043c\u043e\u0436\u0435\u0442 \u0438 \u043d\u0435 \u0421\u0423\u0411\u0414 \u0432\u043e\u0432\u0441\u0435). \u0412 [&hellip;]<\/p>\n","protected":false,"gt_translate_keys":[{"key":"rendered","format":"html"}]},"author":1,"featured_media":83650,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[688],"tags":[],"class_list":["post-83649","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=\"SQL, \u0447\u0442\u043e \u043c\u043e\u0436\u0435\u0442 \u0431\u044b\u0442\u044c \u043f\u0440\u043e\u0449\u0435?\" \/>\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\/database-as-sode-experience\" \/>\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\udd47\u00abDatabase as \u0421ode\u00bb Experience | ProHoster\" \/>\n\t\t<meta property=\"og:description\" content=\"SQL, \u0447\u0442\u043e \u043c\u043e\u0436\u0435\u0442 \u0431\u044b\u0442\u044c \u043f\u0440\u043e\u0449\u0435?\" \/>\n\t\t<meta property=\"og:url\" content=\"https:\/\/prohoster.info\/sk\/blog\/administrirovanie\/database-as-sode-experience\" \/>\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-06-02T05:42:21+00:00\" \/>\n\t\t<meta property=\"article:modified_time\" content=\"2020-06-02T05:42:21+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\udd47\u201eDatabase as Code\u201c Experience | ProHoster","description":"SQL, \u010do m\u00f4\u017ee by\u0165 jednoduch\u0161ie?","canonical_url":"https:\/\/prohoster.info\/sk\/blog\/administrirovanie\/database-as-sode-experience","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\udd47\u00abDatabase as \u0421ode\u00bb Experience | ProHoster","og:description":"SQL, \u0447\u0442\u043e \u043c\u043e\u0436\u0435\u0442 \u0431\u044b\u0442\u044c \u043f\u0440\u043e\u0449\u0435?","og:url":"https:\/\/prohoster.info\/sk\/blog\/administrirovanie\/database-as-sode-experience","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-06-02T05:42:21+00:00","article:modified_time":"2020-06-02T05:42:21+00:00","article:publisher":"https:\/\/www.facebook.com\/prohoster","article:author":"https:\/\/www.facebook.com\/prohoster"},"aioseo_meta_data":{"post_id":"83649","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 15:13:28","updated":"2022-10-02 10:23:46","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\/83649","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=83649"}],"version-history":[{"count":0,"href":"https:\/\/prohoster.info\/sk\/wp-json\/wp\/v2\/posts\/83649\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/prohoster.info\/sk\/wp-json\/wp\/v2\/media\/83650"}],"wp:attachment":[{"href":"https:\/\/prohoster.info\/sk\/wp-json\/wp\/v2\/media?parent=83649"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/prohoster.info\/sk\/wp-json\/wp\/v2\/categories?post=83649"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/prohoster.info\/sk\/wp-json\/wp\/v2\/tags?post=83649"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}