{"id":79465,"date":"2020-04-27T07:42:20","date_gmt":"2020-04-27T05:42:20","guid":{"rendered":"https:\/\/prohoster.info\/blog\/administrirovanie\/istina-prezhde-vsego-ili-pochemu-sistemu-nuzhno-proektirovat-ishodya-iz-ustrojstva-bazy-dannyh"},"modified":"2020-04-27T07:42:20","modified_gmt":"2020-04-27T05:42:20","slug":"istina-prezhde-vsego-ili-pochemu-sistemu-nuzhno-proektirovat-ishodya-iz-ustrojstva-bazy-dannyh","status":"publish","type":"post","link":"https:\/\/prohoster.info\/sq\/blog\/administrirovanie\/istina-prezhde-vsego-ili-pochemu-sistemu-nuzhno-proektirovat-ishodya-iz-ustrojstva-bazy-dannyh","title":{"rendered":"E v\u00ebrteta mbi t\u00eb gjitha, ose p\u00ebrse sistemi duhet t\u00eb projektohet duke u bazuar n\u00eb struktur\u00ebn e baz\u00ebs s\u00eb t\u00eb dh\u00ebnave","gt_translate_keys":[{"key":"rendered","format":"text"}]},"content":{"rendered":"<p>P\u00ebrsh\u00ebndetje, Habr!<\/p>\n<p>Ne pohojme t\u00eb hetojm\u00eb tem\u00ebn <noindex><a rel=\"nofollow\" href=\"https:\/\/www.piter.com\/collection\/all\/product\/sovremennyy-yazyk-java-lyambda-vyrazheniya-potoki-i-funktsionalnoe-programmirovanie\">Java<\/a><\/noindex> dhe <noindex><a rel=\"nofollow\" href=\"https:\/\/storage.piter.com\/upload\/contents\/978544611587\/978544611587_X.pdf\">Spring<\/a><\/noindex>, p\u00ebrfshir\u00eb n\u00eb nivelin e bazave t\u00eb t\u00eb dh\u00ebnave. Sot ju ofrojm\u00eb nj\u00eb lexim mbi arsyen se pse kur projektoni aplikacione t\u00eb m\u00ebdha, struktura e baz\u00ebs s\u00eb t\u00eb dh\u00ebnave, dhe jo kodi Java, duhet t\u00eb ket\u00eb r\u00ebnd\u00ebsi vendimtare, si \u00ebsht\u00eb e realizueshme kjo dhe cilat jan\u00eb p\u00ebrjashtimet nga ky rregull.<br \/>\n<noindex><a rel=\"nofollow\" name=\"habracut\"><\/a><\/noindex> <br \/>\nN\u00eb k\u00ebt\u00eb artikull t\u00eb vonuar, do t\u00eb shpjegoj arsyen pse mendoj se n\u00eb praktikisht t\u00eb gjitha rastet, modeli i t\u00eb dh\u00ebnave n\u00eb aplikacion duhet t\u00eb projektohet \"duke u nisur nga baza e t\u00eb dh\u00ebnave\", dhe jo \"duke u nisur nga mund\u00ebsit\u00eb e Java\" (ose ndonj\u00eb gjuhe tjet\u00ebr klienti me t\u00eb cil\u00ebn po punoni). Duke zgjedhur qasjen e dyt\u00eb, ju filloni nj\u00eb rrug\u00eb t\u00eb gjat\u00eb vuajtjesh sapo projekti juaj fillon t\u00eb rritet.<\/p>\n<p>Artikulli \u00ebsht\u00eb shkruar mbi motivin e <noindex><a rel=\"nofollow\" href=\"https:\/\/stackoverflow.com\/questions\/50706556\/kotlin-with-jooq-and-write-table-models-manually-without-code-generation\">nj\u00eb pyetjeje<\/a><\/noindex>, q\u00eb u b\u00eb n\u00eb Stack Overflow.<\/p>\n<p>Diskutimet interesante n\u00eb reddit n\u00eb seksionet <noindex><a rel=\"nofollow\" href=\"https:\/\/www.reddit.com\/r\/java\/comments\/8p0uj3\/truth_first_or_why_you_should_mostly_implement\/\">\/r\/java<\/a><\/noindex> dhe <noindex><a rel=\"nofollow\" href=\"https:\/\/www.reddit.com\/r\/programming\/comments\/8p0qle\/truth_first_or_why_you_should_mostly_implement\/\">\/r\/programming<\/a><\/noindex>.<\/p>\n<h4>Gjenerimi i kodit<\/h4>\n<p>\nSa shum\u00eb u befasova kur zbulova se ekziston nj\u00eb grup aq i vog\u00ebl p\u00ebrdoruesish, t\u00eb cil\u00ebt, pasi u njoh\u00ebn me jOOQ, u shqet\u00ebsuan nga fakti se n\u00eb pun\u00ebn me jOOQ mb\u00ebshtetet seriozisht n\u00eb gjenerimin e kodit. Askush nuk ju pengon t\u00eb p\u00ebrdorni jOOQ ashtu si e shihni t\u00eb arsyeshme dhe nuk ju detyron t\u00eb p\u00ebrdorni gjenerimin e kodit. Por n\u00eb m\u00ebnyr\u00eb default (ashtu si\u00e7 p\u00ebrshkruhet n\u00eb manual), puna me jOOQ ndodh k\u00ebshtu: filloni me (trash\u00ebguar) schem\u00ebn e baz\u00ebs s\u00eb t\u00eb dh\u00ebnave, kryeni inxhinierin\u00eb e saj t\u00eb prapm\u00eb me ndihm\u00ebn e gjeneratorit t\u00eb kodit jOOQ, p\u00ebr t\u00eb marr\u00eb nj\u00eb grup klasash q\u00eb p\u00ebrfaq\u00ebsojn\u00eb tabelat tuaja, dhe m\u00eb pas shkruani pyetje t\u00eb sigurta p\u00ebr tipin p\u00ebr k\u00ebto tabela:<\/p>\n<pre><code class=\"java\">\tfor (Record2 record : DSL.using(configuration)\n\/\/   ^^^^^^^^^^^^^^^^^^^^^^^ Informacioni mbi tipet \u00ebsht\u00eb nxjerr\u00eb n\u00eb \n\/\/   baz\u00eb t\u00eb kodit t\u00eb gjeneruar, i cili referohet n\u00eb kushtin e dh\u00ebn\u00eb\n\/\/ m\u00eb posht\u00eb SELECT \n\n       .select(ACTOR.FIRST_NAME, ACTOR.LAST_NAME)\n\/\/           vvvvv ^^^^^^^^^^^^  ^^^^^^^^^^^^^^^ emrat e gjeneruar\n       .from(ACTOR)\n       .orderBy(1, 2)) {\n    \/\/ ...\n}<\/code><\/pre>\n<p>\nKodi gjenerohet ose manualisht jasht\u00eb nd\u00ebrtimit, ose manualisht \u00e7do her\u00eb kur ndodh nd\u00ebrtimi. P\u00ebr shembull, nj\u00eb rigjenerim i till\u00eb mund t\u00eb ndodh\u00eb menj\u00ebher\u00eb pas <noindex><a rel=\"nofollow\" href=\"https:\/\/blog.jooq.org\/2014\/06\/25\/flyway-and-jooq-for-unbeatable-sql-development-productivity\/\">migros t\u00eb baz\u00ebs s\u00eb t\u00eb dh\u00ebnave Flyway, e cila gjithashtu mund t\u00eb kryhet manualisht ose automatikisht<\/a><\/noindex>.<\/p>\n<h4>Gjenerimi i kodit burimor<\/h4>\n<p>\nMe k\u00ebto qasje ndaj gjenerimit t\u00eb kodit \u2013 manuale dhe automatike \u2013 lidhen filozofi t\u00eb ndryshme, avantazhe dhe disavantazhe, t\u00eb cilat nuk do t\u2019i diskutoj n\u00eb detaje n\u00eb k\u00ebt\u00eb artikull. Por, n\u00eb p\u00ebrgjith\u00ebsi, e gjith\u00eb thelbi i kodit t\u00eb gjeneruar \u00ebsht\u00eb se ai lejon t\u00eb riprodhohet n\u00eb Java ajo \"e v\u00ebrtet\u00eb\", q\u00eb e pranojm\u00eb si t\u00eb dh\u00ebn\u00eb, qoft\u00eb brenda sistemit ton\u00eb, qoft\u00eb jasht\u00eb tij. N\u00eb nj\u00ebfar\u00eb m\u00ebnyre, t\u00eb nj\u00ebjt\u00ebn gj\u00eb b\u00ebjn\u00eb kompilet, t\u00eb cil\u00ebt gjenerojn\u00eb kodin bajt, kodin makinerik ose ndonj\u00eb form\u00eb tjet\u00ebr t\u00eb kodit mbi baz\u00ebn e burimeve \u2013 ne marrim nj\u00eb p\u00ebrfaq\u00ebsim t\u00eb \"e v\u00ebrtet\u00ebs\" ton\u00eb n\u00eb nj\u00eb gjuh\u00eb tjet\u00ebr, pavar\u00ebsisht shkakut t\u00eb ve\u00e7ant\u00eb. <\/p>\n<p>Ekzistojn\u00eb shum\u00eb t\u00eb till\u00eb gjenerues kodesh. P\u00ebr shembull, <noindex><a rel=\"nofollow\" href=\"https:\/\/docs.oracle.com\/javase\/8\/docs\/technotes\/tools\/unix\/xjc.html\">XJC mund t\u00eb gjeneroj\u00eb kod Java mbi baza t\u00eb skedar\u00ebve XSD ose WSDL<\/a><\/noindex>. Parimi gjithmon\u00eb \u00ebsht\u00eb i nj\u00ebjt\u00eb:<\/p>\n<ul>\n<li>Ekziston nj\u00eb e v\u00ebrtet\u00eb (brendshme ose jashtme) \u2013 p\u00ebr shembull, specifikimi, modeli i t\u00eb dh\u00ebnave, etj.<\/li>\n<li>Na nevojitet nj\u00eb p\u00ebrfaq\u00ebsim lokal i k\u00ebsaj t\u00eb v\u00ebrtete n\u00eb gjuh\u00ebn ton\u00eb programore.<\/li>\n<\/ul>\n<p>\nDhe \u00ebsht\u00eb gjithmon\u00eb e arsyeshme t\u00eb gjenerohet nj\u00eb p\u00ebrfaq\u00ebsim i till\u00eb \u2013 p\u00ebr t\u00eb evituar q\u00ebllimin e tep\u00ebrt.<\/p>\n<h4>Ofertues t\u00eb llojeve dhe p\u00ebrpunimi i annotimeve<\/h4>\n<p>\nP\u00ebr t'u v\u00ebn\u00eb n\u00eb dukje: nj\u00eb tjet\u00ebr, m\u00eb modern dhe specifik qasje ndaj gjenerimit t\u00eb kodit p\u00ebr jOOQ lidhet me p\u00ebrdorimin e ofertuesve t\u00eb llojeve, <noindex><a rel=\"nofollow\" href=\"https:\/\/docs.microsoft.com\/en-us\/dotnet\/fsharp\/tutorials\/type-providers\/\">n\u00eb form\u00ebn si\u00e7 jan\u00eb implementuar n\u00eb F#<\/a><\/noindex>. N\u00eb k\u00ebt\u00eb rast, kodi gjenerohet nga kompajleri, pik\u00ebrisht n\u00eb faz\u00ebn e kompilimimit. N\u00eb form\u00ebn e burimeve nj\u00eb kod i till\u00eb n\u00eb parim nuk ekziston. N\u00eb Java ekzistojn\u00eb mjete t\u00eb ngjashme, megjith\u00ebse jo aq elegante \u2013 k\u00ebto jan\u00eb procesor\u00ebt e annotimeve, p\u00ebr shembull, <noindex><a rel=\"nofollow\" href=\"https:\/\/projectlombok.org\">Lombok<\/a><\/noindex>.<\/p>\n<p>N\u00eb nj\u00eb far\u00eb kuptimi, k\u00ebtu ndodhin t\u00eb nj\u00ebjtat gj\u00ebra si n\u00eb rastin e par\u00eb, p\u00ebrve\u00e7:<\/p>\n<ul>\n<li>Nuk e shihni kodin e gjeneruar (ndoshta kjo situat\u00eb disa njer\u00ebzve u duket jo aq e frikshme?)<\/li>\n<li>Duhet t\u00eb garantoni q\u00eb llojet mund t\u00eb ofrohen, dmth, \"e v\u00ebrteta\" gjithmon\u00eb duhet t\u00eb jet\u00eb e disponueshme. Kjo \u00ebsht\u00eb e leht\u00eb n\u00eb rastin e Lombok, i cili annoton \u201ce v\u00ebrtet\u00ebn\u201d. M\u00eb pak e thjesht\u00eb me modelet e bazave t\u00eb t\u00eb dh\u00ebnave, puna e t\u00eb cilave varet nga nj\u00eb lidhje e drejtp\u00ebrdrejt\u00eb e vazhdueshme.<\/li>\n<\/ul>\n<p><\/p>\n<h4>Cila \u00ebsht\u00eb problemi me gjenerimin e kodit?<\/h4>\n<p>\nP\u00ebrve\u00e7 nj\u00eb pyetje t\u00eb holl\u00eb rreth m\u00ebnyr\u00ebs m\u00eb t\u00eb mir\u00eb p\u00ebr t\u00eb filluar gjenerimin e kodit - n\u00eb m\u00ebnyr\u00eb manuale apo automatikisht, duhet t\u00eb p\u00ebrmendim gjithashtu se ka njer\u00ebz q\u00eb mendojn\u00eb se gjenerimi i kodit nuk \u00ebsht\u00eb i nevojsh\u00ebm fare. Justifikimi i nj\u00eb pik\u00ebpamjeje t\u00eb till\u00eb, t\u00eb cilin e kam hasur shpesh, \u00ebsht\u00eb se at\u00ebher\u00eb \u00ebsht\u00eb e v\u00ebshtir\u00eb t\u00eb konfigurosh cilindrin e nd\u00ebrtimit. Po, me t\u00eb v\u00ebrtet\u00eb \u00ebsht\u00eb e v\u00ebshtir\u00eb. Ka shpenzime shtes\u00eb infrastrukturore. N\u00ebse sapo po filloni t\u00eb punoni me nj\u00eb produkt t\u00eb caktuar (qoft\u00eb jOOQ, JAXB, Hibernate, etj.), koha e nevojshme p\u00ebr t\u00eb konfiguruar mjedisin e pun\u00ebs \u00ebsht\u00eb nj\u00eb koh\u00eb q\u00eb do t\u00eb donit ta kalonit duke studiuar vet\u00eb API-n, p\u00ebr t\u00eb nxjerr\u00eb m\u00eb von\u00eb vler\u00eb prej saj.<\/p>\n<p>N\u00ebse shpenzimet jan\u00eb shum\u00eb t\u00eb m\u00ebdha p\u00ebr t\u00eb kuptuar funksionimin e gjeneratorit \u2013 at\u00ebher\u00eb me t\u00eb v\u00ebrtet\u00eb API-ja nuk ka punuar mir\u00eb n\u00eb p\u00ebrdorshm\u00ebrin\u00eb e gjeneratorit (dhe m\u00eb von\u00eb del se edhe konfigurimi i p\u00ebrdoruesit n\u00eb t\u00eb \u00ebsht\u00eb i komplikuar). Leht\u00ebsia e p\u00ebrdorimit duhet t\u00eb jet\u00eb prioriteti m\u00eb i lart\u00eb p\u00ebr \u00e7do API t\u00eb till\u00eb. Por ky \u00ebsht\u00eb vet\u00ebm nj\u00eb argument kund\u00ebr gjenerimit t\u00eb kodit. N\u00eb t\u00eb tjerat, \u00ebsht\u00eb absolutisht e nevojshme t\u00eb shkruhet manualisht prezantimi lokal i s\u00eb v\u00ebrtet\u00ebs s\u00eb brendshme ose t\u00eb jashtme.<\/p>\n<p>Shum\u00eb do t\u00eb thon\u00eb se nuk kan\u00eb koh\u00eb p\u00ebr t\u00eb b\u00ebr\u00eb t\u00eb gjitha k\u00ebto. Ata kan\u00eb afate p\u00ebr produktin e tyre Super. Diku m\u00eb von\u00eb do ta rregullojm\u00eb cilindrin e nd\u00ebrtimit, do t\u00eb kemi koh\u00eb. Un\u00eb iu p\u00ebrgjigjem atyre:<\/p>\n<p><img decoding=\"async\" alt=\"E v\u00ebrteta mbi t\u00eb gjitha, ose p\u00ebrse sistemi duhet t\u00eb projektohet duke u bazuar n\u00eb struktur\u00ebn e baz\u00ebs s\u00eb t\u00eb dh\u00ebnave\" src=\"\/wp-content\/uploads\/2020\/04\/cd9aca1e0365fa5af28cfc72c201cb8c.png\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<noindex><a rel=\"nofollow\" href=\"https:\/\/www.flickr.com\/photos\/toddle_email_newsletters\/15596940251\/in\/photostream\/\">Originali<\/a><\/noindex>, <noindex><a rel=\"nofollow\" href=\"http:\/\/audiencestack.com\/static\/blog.html\">Alan O'Rourke, Audience Stack<\/a><\/noindex> <\/p>\n<p><b>Por n\u00eb Hibernate \/ JPA \u00ebsht\u00eb kaq e leht\u00eb t\u00eb shkruash kod \"n\u00ebn Java\". <\/b><\/p>\n<p>N\u00eb t\u00eb v\u00ebrtet\u00eb. P\u00ebr Hibernate dhe p\u00ebrdoruesit e tij, kjo \u00ebsht\u00eb nj\u00ebher\u00ebsh nj\u00eb bekim dhe nj\u00eb mallkim. N\u00eb Hibernate mund t\u00eb shkruash thjesht disa entitete, k\u00ebshtu:<\/p>\n<pre><code class=\"java\">\t@Entity\nclass Book {\n  @Id\n  int id;\n  String title;\n}<\/code><\/pre>\n<p>\nDhe pothuajse \u00e7do gj\u00eb \u00ebsht\u00eb gati. Tani detyra e Hibernate \u00ebsht\u00eb t\u00eb gjeneroj\u00eb \"detajet\" komplekse t\u00eb asaj se si do t\u00eb p\u00ebrcaktohet me t\u00eb v\u00ebrtet\u00eb kjo entitet n\u00eb DDL-n\u00eb e \"dialektit\" tuaj SQL:<\/p>\n<pre><code class=\"sql\">\tCREATE TABLE book (\n  id INTEGER PRIMARY KEY GENERATED ALWAYS AS IDENTITY,\n  title VARCHAR(50),\n \n  CONSTRAINT pk_book PRIMARY KEY (id)\n);\n \nCREATE INDEX i_book_title ON book (title);<\/code><\/pre>\n<p>\n... dhe fillojm\u00eb t\u00eb p\u00ebrshkojm\u00eb aplikacionin. V\u00ebrtet nj\u00eb mund\u00ebsi e shk\u00eblqyer, p\u00ebr t\u00eb filluar shpejt dhe p\u00ebr t\u00eb provuar gj\u00ebra t\u00eb ndryshme.<\/p>\n<p>Megjithat\u00eb, ndaluni nj\u00eb \u00e7ast. Kam g\u00ebnjyer.<\/p>\n<ul>\n<li>Por a do ta aplikoj\u00eb Hibernate definicionin e k\u00ebtij \u00e7el\u00ebsi primar t\u00eb em\u00ebruar?<\/li>\n<li>A do t\u00eb krijoj\u00eb Hibernate indeksin n\u00eb TITLE? \u2013 un\u00eb e di sakt\u00ebsisht se do na nevojitet. <\/li>\n<li>A do ta b\u00ebj\u00eb Hibernate k\u00ebt\u00eb \u00e7el\u00ebs identifikues n\u00eb Specifikimin e Identitetit?<\/li>\n<\/ul>\n<p>\nNdoshta jo. N\u00ebse po e zhvilloni projektin tuaj nga e para, gjithmon\u00eb \u00ebsht\u00eb e dobishme t\u00eb hiqni baz\u00ebn e t\u00eb dh\u00ebnave t\u00eb vjet\u00ebr dhe t\u00eb krijoni nj\u00eb t\u00eb re, sa her\u00eb q\u00eb t\u00eb shtoni anotacionet e nevojshme. K\u00ebshtu, entiteti Book n\u00eb fund do t\u00eb duket si: <\/p>\n<pre><code class=\"java\">\t@Entity\n@Table(name = \"book\", indexes = {\n  @Index(name = \"i_book_title\", columnList = \"title\")\n})\nclass Book {\n  @Id\n  @GeneratedValue(strategy = IDENTITY)\n  int id;\n  String title;\n}\n<\/code><\/pre>\n<p>\nSuper. Rinisni nga fillimi. Edhe k\u00ebsaj here, n\u00eb nj\u00eb rast t\u00eb till\u00eb, do t\u00eb jet\u00eb shum\u00eb e leht\u00eb n\u00eb fillim.<\/p>\n<h4>Por m\u00eb von\u00eb do t'ju duhet t\u00eb paguani p\u00ebr k\u00ebt\u00eb.<\/h4>\n<p>\nP\u00ebr ose m\u00eb von\u00eb do t\u00eb duhet t\u00eb kaloni n\u00eb prodhim. Pik\u00ebrisht at\u00ebher\u00eb ky model do t\u00eb ndaloj\u00eb s\u00eb funksionuari. Sepse: <\/p>\n<p>N\u00eb prodhim nuk do t\u00eb jet\u00eb e mundur, sipas nevoj\u00ebs, t\u00eb hiqni baz\u00ebn e t\u00eb dh\u00ebnave t\u00eb vjet\u00ebr dhe t\u00eb filloni gjith\u00e7ka nga e para. Baza juaj e t\u00eb dh\u00ebnave do t\u00eb b\u00ebhet hereditar.<\/p>\n<p>Q\u00eb nga tani e tutje do t'ju duhet t\u00eb shkruani <noindex><a rel=\"nofollow\" href=\"https:\/\/blog.jooq.org\/2014\/06\/25\/flyway-and-jooq-for-unbeatable-sql-development-productivity\/\">skriptet e migracionit DDL, p\u00ebr shembull, duke p\u00ebrdorur Flyway.<\/a><\/noindex>. Por \u00e7far\u00eb do t\u00eb ndodh\u00eb n\u00eb k\u00ebt\u00eb rast me entitetet tuaja? Ju mund t\u00eb adaptoni ato manualisht (dhe k\u00ebshtu do t\u00eb dyfishoni pun\u00ebn tuaj), ose mund t\u00eb k\u00ebrkoni nga Hibernate t'i gjeneroj\u00eb p\u00ebrs\u00ebri p\u00ebr ju (sa t\u00eb m\u00ebdha jan\u00eb shanset q\u00eb ato t\u00eb jen\u00eb si\u00e7 e prisni?) N\u00eb \u00e7do rast, ju humbni.<\/p>\n<p>Pra, sa her\u00eb q\u00eb kaloni n\u00eb prodhim, ju nevojiten patches t\u00eb nxehta. Dhe ato duhet t\u00eb dalin n\u00eb prodhim shum\u00eb shpejt. Sepse ju nuk u p\u00ebrgatit\u00ebt dhe nuk organizuat nj\u00eb konvej p\u00ebr migrimet tuaja, ju gjith\u00e7ka do ta pat\u00e7oni. Dhe pastaj nuk do t\u00eb keni koh\u00eb ta b\u00ebni gjith\u00e7ka si\u00e7 duhet. Dhe e akuzoni Hibernate, sepse gjithmon\u00eb \u00ebsht\u00eb faji i dikujt tjet\u00ebr, jo ju...<\/p>\n<p>N\u00eb vend t\u00eb k\u00ebsaj, q\u00eb nga fillimi mund t\u00eb b\u00ebni gjith\u00e7ka krejt ndryshe. P\u00ebr shembull, ndoshta t\u00eb vendosni rrota t\u00eb rrumbullak\u00ebta n\u00eb bi\u00e7iklet\u00eb.<\/p>\n<h4>S\u00eb pari baza e t\u00eb dh\u00ebnave.<\/h4>\n<p>\nE v\u00ebrteta e v\u00ebrtet\u00eb n\u00eb skem\u00ebn e baz\u00ebs tuaj t\u00eb t\u00eb dh\u00ebnave dhe \"sovraniteti\" mbi t\u00eb q\u00ebndron brenda baz\u00ebs s\u00eb t\u00eb dh\u00ebnave. Skema p\u00ebrcaktohet vet\u00ebm brenda vet\u00eb baz\u00ebs s\u00eb t\u00eb dh\u00ebnave dhe askund tjet\u00ebr, dhe \u00e7do klient ka nj\u00eb kopje t\u00eb k\u00ebsaj skeme, k\u00ebshtu q\u00eb \u00ebsht\u00eb krejt e arsyeshme t\u00eb impononi ruajtjen e skem\u00ebs dhe integritetit t\u00eb saj, duke b\u00ebr\u00eb k\u00ebt\u00eb direkt n\u00eb baz\u00ebn e t\u00eb dh\u00ebnave \u2013 aty ku ruhet informacioni. <br \/>\nKjo \u00ebsht\u00eb nj\u00eb urt\u00ebsi e vjet\u00ebr, madje e vjet\u00ebr. \u00c7el\u00ebsat e par\u00eb dhe unik\u00eb jan\u00eb t\u00eb mir\u00eb. \u00c7el\u00ebsat e jasht\u00ebm \u2013 jan\u00eb t\u00eb mir\u00eb. Verifikimi i kufizimeve \u2013 \u00ebsht\u00eb i mir\u00eb. <noindex><a rel=\"nofollow\" href=\"https:\/\/community.oracle.com\/ideas\/13028\">Shprehjet<\/a><\/noindex> \u2013 jan\u00eb t\u00eb mira. <\/p>\n<p>Dhe, kjo nuk \u00ebsht\u00eb gjith\u00e7ka. P\u00ebr shembull, duke p\u00ebrdorur Oracle, ndoshta do t\u00eb d\u00ebshironi t\u00eb specifikoni:<\/p>\n<ul>\n<li>N\u00eb cilin hap\u00ebsir\u00eb tabellash ndodhet tabela juaj <\/li>\n<li>Cili \u00ebsht\u00eb vler\u00eb PCTFREE <\/li>\n<li>Cili \u00ebsht\u00eb madh\u00ebsia e caches n\u00eb sekuenc\u00ebn tuaj (pas identifikuesit)<\/li>\n<\/ul>\n<p>\nNdoshta e gjitha kjo nuk ka r\u00ebnd\u00ebsi n\u00eb sistemet e vogla, por nuk \u00ebsht\u00eb e nevojshme t\u00eb prisni kalimin n\u00eb fush\u00ebn e 't\u00eb dh\u00ebnave t\u00eb m\u00ebdha' \u2014 mund t\u00eb filloni t\u00eb p\u00ebrfitoni nga optimizimet e ruajtjes s\u00eb t\u00eb dh\u00ebnave q\u00eb ofrohen nga ofruesi, si ato t\u00eb p\u00ebrmendura m\u00eb sip\u00ebr, edhe m\u00eb her\u00ebt. Asnj\u00eb prej ORM-ve q\u00eb kam par\u00eb (p\u00ebrfshir\u00eb jOOQ) nuk ofron qasje n\u00eb t\u00eb gjith\u00eb grupin e mund\u00ebsive DDL q\u00eb mund t\u00eb d\u00ebshironi t\u00eb p\u00ebrdorni n\u00eb baz\u00ebn tuaj t\u00eb t\u00eb dh\u00ebnave. ORM-t\u00eb ofrojn\u00eb disa mjete q\u00eb ndihmojn\u00eb n\u00eb shkrimin e DDL.<\/p>\n<p>Por, n\u00eb fund t\u00eb fundit, nj\u00eb skem\u00eb e mir\u00ebprojektuar shkruhet manualisht n\u00eb DDL. \u00c7do DDL e gjeneruar \u00ebsht\u00eb vet\u00ebm nj\u00eb aproximim i saj.<\/p>\n<h4>\u00c7far\u00eb ndodh me modelin e klientit?<\/h4>\n<p>\nSi\u00e7 u p\u00ebrmend m\u00eb par\u00eb, n\u00eb klient do t'ju duhet nj\u00eb kopje e skem\u00ebs s\u00eb baz\u00ebs suaj t\u00eb t\u00eb dh\u00ebnave, nj\u00eb pamje e klientit. E tep\u00ebrt p\u00ebr t\u00eb p\u00ebrmendur se kjo pamje e klientit duhet t\u00eb jet\u00eb e sinkronizuar me modelin e v\u00ebrtet\u00eb. Si t'ia arrini m\u00eb s\u00eb miri k\u00ebsaj? Me ndihm\u00ebn e nj\u00eb gjeneratori kodi.<\/p>\n<p>T\u00eb gjitha bazat e t\u00eb dh\u00ebnave ofrojn\u00eb metainformacionin e tyre p\u00ebrmes SQL. Ja si t\u00eb merrni t\u00eb gjitha tabelat nga baza juaj e t\u00eb dh\u00ebnave n\u00eb dialekte t\u00eb ndryshme SQL:<\/p>\n<pre><code class=\"sql\">\t-- H2, HSQLDB, MySQL, PostgreSQL, SQL Server\nSELECT table_schema, table_name\nFROM information_schema.tables\n \n-- DB2\nSELECT tabschema, tabname\nFROM syscat.tables\n \n-- Oracle\nSELECT owner, table_name\nFROM all_tables\n \n-- SQLite\nSELECT name\nFROM sqlite_master\n \n-- Teradata\nSELECT databasename, tablename\nFROM dbc.tables\n<\/code><\/pre>\n<p>\nK\u00ebto k\u00ebrkesa (apo t\u00eb ngjashme me to, n\u00eb var\u00ebsi t\u00eb faktit n\u00ebse duhet t\u00eb merrni parasysh gjithashtu pamjet, pamjet e materializuara, funksionet me vler\u00eb tabellash) ekzekutohen gjithashtu p\u00ebrmes thirrjes <noindex><a rel=\"nofollow\" href=\"https:\/\/docs.oracle.com\/javase\/10\/docs\/api\/java\/sql\/DatabaseMetaData.html#getTables(java.lang.String,java.lang.String,java.lang.String,java.lang.String%5B%5D)\"><code>DatabaseMetaData.getTables()<\/code><\/a><\/noindex> nga JDBC, ose p\u00ebrmes modulit meta jOOQ.<\/p>\n<p>Nga rezultatet e k\u00ebtyre k\u00ebrkesave \u00ebsht\u00eb relativisht e leht\u00eb t\u00eb gjenerosh \u00e7do pamje klienti t\u00eb modelit t\u00eb baz\u00ebs s\u00eb t\u00eb dh\u00ebnave, pa zakoni se \u00e7far\u00eb teknologjie p\u00ebrdorni n\u00eb klientin tuaj.<\/p>\n<ul>\n<li>N\u00ebse p\u00ebrdorni JDBC ose Spring, mund t\u00eb krijoni nj\u00eb grup konstantash string <\/li>\n<li>N\u00ebse p\u00ebrdorni JPA, mund t\u00eb gjeneroni vet\u00eb entitetet <\/li>\n<li>N\u00ebse p\u00ebrdorni jOOQ, mund t\u00eb gjeneroni modelin meta t\u00eb jOOQ<\/li>\n<\/ul>\n<p>\nN\u00eb var\u00ebsi t\u00eb asaj q\u00eb ofrohet nga API juaj p\u00ebr klient\u00ebt (p.sh. jOOQ ose JPA), meta-modeli i gjeneruar mund t\u00eb jet\u00eb me t\u00eb v\u00ebrtet\u00eb i pasur dhe i plot\u00eb. Le t\u00eb marrim, p\u00ebr shembull, mund\u00ebsin\u00eb e bashkimeve t\u00eb implicit, <noindex><a rel=\"nofollow\" href=\"https:\/\/blog.jooq.org\/2018\/02\/20\/type-safe-implicit-join-through-path-navigation-in-jooq-3-11\/\">q\u00eb u shfaq n\u00eb jOOQ 3.11<\/a><\/noindex>, e cila mb\u00ebshtetet n\u00eb metainformacionin e gjeneruar mbi marr\u00ebdh\u00ebniet e \u00e7el\u00ebsave t\u00eb jasht\u00ebm, q\u00eb veprojn\u00eb midis tabelave tuaja.<\/p>\n<p>Tani \u00e7do rritje e baz\u00ebs s\u00eb t\u00eb dh\u00ebnave do t\u00eb \u00e7oj\u00eb automatikisht n\u00eb p\u00ebrdit\u00ebsimin e kodit t\u00eb klientit. Imagjinoni, p\u00ebr shembull:<\/p>\n<pre><code class=\"sql\">ALTER TABLE book RENAME COLUMN title TO book_title;<\/code><\/pre>\n<p>\nA do t\u00eb donit t\u00eb b\u00ebnit k\u00ebt\u00eb pun\u00eb dy her\u00eb? Asnj\u00ebher\u00eb. Thjesht regjistroni DDL-n\u00eb, kaloni at\u00eb p\u00ebrmes konvejerit tuaj t\u00eb nd\u00ebrtimit dhe merrni entitetin e p\u00ebrdit\u00ebsuar:<\/p>\n<pre><code class=\"java\">@Entity\n@Table(name = \"book\", indexes = {\n \n  \/\/ A keni menduar p\u00ebr k\u00ebt\u00eb?\n  @Index(name = \"i_book_title\", columnList = \"book_title\")\n})\nclass Book {\n  @Id\n  @GeneratedValue(strategy = IDENTITY)\n  int id;\n \n  @Column(\"book_title\")\n  String bookTitle;\n}<\/code><\/pre>\n<p>\nOse klasa e p\u00ebrdit\u00ebsuar jOOQ. Shumica e ndryshimeve DDL reflektohen gjithashtu n\u00eb semantike, dhe jo vet\u00ebm n\u00eb sintaks\u00eb. Prandaj, ndonj\u00ebher\u00eb \u00ebsht\u00eb e dobishme t\u00eb shihni n\u00eb kodin e kompiluar se cili kod do t\u00eb preket (apo mund t\u00eb preket) nga rritja e baz\u00ebs suaj t\u00eb t\u00eb dh\u00ebnave.<\/p>\n<h4>E v\u00ebrteta e vetme<\/h4>\n<p>\nPavar\u00ebsisht se \u00e7far\u00eb teknologjie p\u00ebrdorni, gjithmon\u00eb ka nj\u00eb model q\u00eb \u00ebsht\u00eb burimi i vet\u00ebm i v\u00ebrtet\u00ebs p\u00ebr nj\u00eb n\u00ebnsisistem t\u00eb caktuar \u2013 ose, t\u00eb pakt\u00ebn, duhet t\u00eb strimcahemi p\u00ebr k\u00ebt\u00eb dhe t\u00eb shmangim nj\u00eb konfuzion t\u00eb till\u00eb enterprise ku \"e v\u00ebrteta\" \u00ebsht\u00eb menj\u00ebher\u00eb kudo dhe asnj\u00ebher\u00eb. Gjith\u00e7ka mund t\u00eb jet\u00eb shum\u00eb m\u00eb e thjesht\u00eb. N\u00ebse thjesht shk\u00ebmbeni skedar\u00eb XML me ndonj\u00eb sistem tjet\u00ebr, thjesht p\u00ebrdorni XSD. Shikoni n\u00eb meta-modelin INFORMATION_SCHEMA nga jOOQ n\u00eb formatin XML:<br \/>\n<noindex><a rel=\"nofollow\" href=\"https:\/\/www.jooq.org\/xsd\/jooq-meta-3.10.0.xsd\">https:\/\/www.jooq.org\/xsd\/jooq-meta-3.10.0.xsd<\/a><\/noindex><\/p>\n<ul>\n<li>XSD \u00ebsht\u00eb e kuptueshme mir\u00eb<\/li>\n<li>XSD markon mjaft mir\u00eb p\u00ebrmbajtjen e XML dhe lejon validimin n\u00eb t\u00eb gjitha gjuh\u00ebt e klient\u00ebve <\/li>\n<li>XSD ka nj\u00eb versionim t\u00eb mir\u00eb dhe ofron nj\u00eb p\u00ebrputhshm\u00ebri t\u00eb avancuar mbrapa <\/li>\n<li>XSD mund t\u00eb transformohet n\u00eb kod Java p\u00ebrmes XJC<\/li>\n<\/ul>\n<p>\nPika e fundit \u00ebsht\u00eb e r\u00ebnd\u00ebsishme. Kur komunikojm\u00eb me nj\u00eb sistem t\u00eb jasht\u00ebm p\u00ebrmes mesazhesh XML, duam t\u00eb jemi t\u00eb sigurt p\u00ebr vlefshm\u00ebrin\u00eb e mesazheve tona. Kjo \u00ebsht\u00eb shum\u00eb e leht\u00eb t\u00eb arrihet p\u00ebrmes JAXB, XJC dhe XSD. Do t\u00eb ishte \u00e7menduri t\u00eb mendojm\u00eb se, duke iu qasur projektimit \"Java e par\u00eb\", ku ne i b\u00ebjm\u00eb mesazhet tona si objekte Java, ato mund t\u00eb projektohen n\u00eb XML dhe t\u00eb d\u00ebrgohen p\u00ebr konsum n\u00eb nj\u00eb sistem tjet\u00ebr. XML i gjeneruar k\u00ebshtu do t\u00eb ishte me cil\u00ebsi shum\u00eb t\u00eb dob\u00ebt, pa dokumentim, dhe do t\u00eb ishte i v\u00ebshtir\u00eb p\u00ebr t'u zhvilluar. N\u00ebse p\u00ebr nj\u00eb nd\u00ebrfaqe t\u00eb till\u00eb ekzistonte nj\u00eb marr\u00ebveshje p\u00ebr nivelin e sh\u00ebrbimit (SLA), do ta kishim d\u00ebshtuar menj\u00ebher\u00eb.<\/p>\n<p>Sinqerisht, kjo \u00ebsht\u00eb pik\u00ebrisht ajo q\u00eb ndodh vazhdimisht me API-t\u00eb n\u00eb JSON, por kjo \u00ebsht\u00eb nj\u00eb histori tjet\u00ebr, her\u00ebn tjet\u00ebr do t\u00eb ankohem... <\/p>\n<h4>Baza t\u00eb dh\u00ebnash: \u00ebsht\u00eb e nj\u00ebjta gj\u00eb.<\/h4>\n<p>\nKur punoni me baza t\u00eb dh\u00ebnash, kuptoni se t\u00eb gjitha jan\u00eb, n\u00eb thelb, t\u00eb ngjashme. Nj\u00eb baz\u00eb zot\u00ebron t\u00eb dh\u00ebnat e saj dhe duhet t\u00eb udh\u00ebheq\u00eb skem\u00ebn. \u00c7do modifikim q\u00eb b\u00ebhet n\u00eb skem\u00eb duhet t\u00eb implementohet drejtp\u00ebrdrejt n\u00eb DDL, n\u00eb m\u00ebnyr\u00eb q\u00eb burimi i vet\u00ebm i s\u00eb v\u00ebrtet\u00ebs t\u00eb azhurnohet.<\/p>\n<p>Kur burimi i azhurnohet, t\u00eb gjith\u00eb klient\u00ebt gjithashtu duhet t\u00eb azhurnojn\u00eb kopjet e tyre t\u00eb modelit. Disa klient\u00eb mund t\u00eb jen\u00eb shkruar n\u00eb Java duke p\u00ebrdorur jOOQ dhe Hibernate ose JDBC (apo t\u00eb gjitha nj\u00ebher\u00ebsh). Klient\u00eb t\u00eb tjer\u00eb mund t\u00eb jen\u00eb shkruar n\u00eb Perl (u uroj fat), t\u00eb tjer\u00ebt - n\u00eb C#. Nuk ka r\u00ebnd\u00ebsi. Modeli kryesor \u00ebsht\u00eb n\u00eb baz\u00ebn e t\u00eb dh\u00ebnave. Modelet e gjeneruara p\u00ebrmes ORM zakonisht jan\u00eb t\u00eb dob\u00ebta, me dokumentim t\u00eb dob\u00ebt dhe t\u00eb v\u00ebshtira p\u00ebr t'u zhvilluar.<\/p>\n<p>Prandaj mos b\u00ebni gabime. Prej fillimit mos b\u00ebni gabime. Punoni nga baza e t\u00eb dh\u00ebnave. Nd\u00ebrtoni nj\u00eb pipeline shp\u00ebrndarjeje q\u00eb mund t\u00eb automatizohet. P\u00ebrfshini gjeneruesit e kodit p\u00ebr ta b\u00ebr\u00eb t\u00eb leht\u00eb kopjimin e modelit t\u00eb baz\u00ebs tuaj t\u00eb dh\u00ebnash dhe shp\u00ebrndarjen e tij te klient\u00ebt. Dhe ndaloni s\u00eb shqet\u00ebsuari p\u00ebr gjeneruesit e kodit. Ata jan\u00eb t\u00eb mir\u00eb. Me ta do t\u00eb b\u00ebheni m\u00eb produktiv\u00eb. Vet\u00ebm duhet t\u00eb shpenzoni pak koh\u00eb n\u00eb fillim p\u00ebr t'i p\u00ebrshtatur ato \u2013 dhe m\u00eb pas ju presin vite produktiviteti t\u00eb p\u00ebrmir\u00ebsuar, nga t\u00eb cilat do t\u00eb formohet historia e projektit tuaj.<\/p>\n<p>Mos e fal\u00ebndero tani, m\u00eb von\u00eb.<\/p>\n<h4>Shpjegimi<\/h4>\n<p>\nP\u00ebr qart\u00ebsi: Ky artikull n\u00eb asnj\u00eb m\u00ebnyr\u00eb nuk propagandon q\u00eb modeli i baz\u00ebs suaj t\u00eb t\u00eb dh\u00ebnave duhet t\u00eb p\u00ebrshtatet me gjith\u00eb sistemin (pra, fush\u00ebn e subjektit, logjik\u00ebn e biznesit, etj.). N\u00eb k\u00ebt\u00eb artikull, po flas p\u00ebr faktin se kodi i klientit q\u00eb interakton me baz\u00ebn e t\u00eb dh\u00ebnave duhet t\u00eb veproj\u00eb duke u bazuar n\u00eb modelin e baz\u00ebs s\u00eb t\u00eb dh\u00ebnave, n\u00eb m\u00ebnyr\u00eb q\u00eb n\u00eb vetvete t\u00eb mos riprodhohet modeli i baz\u00ebs s\u00eb t\u00eb dh\u00ebnave si nj\u00eb \u201cklas\u00eb e par\u00eb\u201d. Kjo logjik\u00eb zakonisht vendoset n\u00eb nivelin e qasjes s\u00eb t\u00eb dh\u00ebnave tek ju n\u00eb klient.<\/p>\n<p>N\u00eb arkitektur\u00ebn me dy nivele, e cila ende ekziston n\u00eb disa vende, nj\u00eb model i till\u00eb i sistemit mund t\u00eb jet\u00eb i vetmi i mundsh\u00ebm. Megjithat\u00eb, n\u00eb shumic\u00ebn e sistemeve, niveli i qasjes s\u00eb t\u00eb dh\u00ebnave m\u00eb duket si nj\u00eb \u201cn\u00ebn sistem\u201d, q\u00eb inkapsulon modelin e baz\u00ebs s\u00eb t\u00eb dh\u00ebnave.<\/p>\n<h4>P\u00ebrjashtimet<\/h4>\n<p>\nNga \u00e7do rregull ka p\u00ebrjashtime, dhe un\u00eb kam th\u00ebn\u00eb tashm\u00eb se qasja me r\u00ebnd\u00ebsin\u00eb e baz\u00ebs s\u00eb t\u00eb dh\u00ebnave dhe gjenerimin e kodit burimor ndonj\u00ebher\u00eb mund t\u00eb jet\u00eb e pap\u00ebrshtatshme. K\u00ebtu jan\u00eb dy p\u00ebrjashtime t\u00eb tilla (pranoni se do t\u00eb ket\u00eb edhe t\u00eb tjera):<\/p>\n<ul>\n<li>Kur skema \u00ebsht\u00eb e panjohur dhe duhet t\u00eb hapet. P\u00ebr shembull, ju jeni ofrues i nj\u00eb instrumenti q\u00eb ndihmon p\u00ebrdoruesit t\u00eb orientohen n\u00eb \u00e7do skem\u00eb. Uff. K\u00ebtu pa gjenerim kode. Por p\u00ebrs\u00ebri \u2013 baza e t\u00eb dh\u00ebnave \u00ebsht\u00eb mbi t\u00eb gjitha.<\/li>\n<li>Kur skema duhet t\u00eb gjenerohet n\u00eb fluks p\u00ebr t\u00eb zgjidhur nj\u00eb detyr\u00eb t\u00eb caktuar. Ky shembull duket si nj\u00eb version paksa i zbukuruar i modelit <noindex><a rel=\"nofollow\" href=\"https:\/\/en.wikipedia.org\/wiki\/Entity%E2%80%93attribute%E2%80%93value_model\">t\u00eb atributit t\u00eb entitetit<\/a><\/noindex>, dometh\u00ebn\u00eb, ju me t\u00eb v\u00ebrtet\u00eb nuk keni nj\u00eb skem\u00eb t\u00eb qart\u00eb t\u00eb p\u00ebrcaktuar. N\u00eb k\u00ebt\u00eb rast, shpesh nuk mund t\u00eb jeni t\u00eb sigurt se ju p\u00ebrshtatet nj\u00eb RDBMS.<\/li>\n<\/ul>\n<p>\nP\u00ebrjashtimet p\u00ebr natyr\u00ebn e tyre jan\u00eb t\u00eb ve\u00e7anta. N\u00eb shumic\u00ebn e rasteve, q\u00eb lidhen me p\u00ebrdorimin e RDBMS, skema \u00ebsht\u00eb e njohur paraprakisht, ajo ndodhet brenda RDBMS dhe \u00ebsht\u00eb burimi i vet\u00ebm i \"t\u00eb v\u00ebrtet\u00ebs\", dhe t\u00eb gjith\u00eb klient\u00ebt duhet t\u00eb krijojn\u00eb kopje t\u00eb saj, t\u00eb derivuara prej saj. N\u00eb ide, n\u00eb k\u00ebt\u00eb rast, duhet t\u00eb angazhohet nj\u00eb gjenerator kodi.<br \/>\n<br \/>Burimi: <a content=\"nofollow\" rel=\"nofollow\" href=\"https:\/\/habr.com\/ru\/company\/piter\/blog\/498816\/\">habr.com<\/a> <\/p>","protected":false,"gt_translate_keys":[{"key":"rendered","format":"html"}]},"excerpt":{"rendered":"<p>\u041f\u0440\u0438\u0432\u0435\u0442, \u0425\u0430\u0431\u0440! \u041c\u044b \u043f\u0440\u043e\u0434\u043e\u043b\u0436\u0430\u0435\u043c \u0438\u0441\u0441\u043b\u0435\u0434\u043e\u0432\u0430\u0442\u044c \u0442\u0435\u043c\u0443 Java \u0438 Spring, \u0432 \u0442\u043e\u043c \u0447\u0438\u0441\u043b\u0435, \u043d\u0430 \u0443\u0440\u043e\u0432\u043d\u0435 \u0431\u0430\u0437 \u0434\u0430\u043d\u043d\u044b\u0445. \u0421\u0435\u0433\u043e\u0434\u043d\u044f \u043f\u0440\u0435\u0434\u043b\u0430\u0433\u0430\u0435\u043c \u043f\u043e\u0447\u0438\u0442\u0430\u0442\u044c \u043e \u0442\u043e\u043c, \u043f\u043e\u0447\u0435\u043c\u0443 \u043f\u0440\u0438 \u043f\u0440\u043e\u0435\u043a\u0442\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0438 \u0431\u043e\u043b\u044c\u0448\u0438\u0445 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0439 \u0438\u043c\u0435\u043d\u043d\u043e \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u0430 \u0431\u0430\u0437\u044b \u0434\u0430\u043d\u043d\u044b\u0445, \u0430 \u043d\u0435 \u043a\u043e\u0434 Java, \u0434\u043e\u043b\u0436\u043d\u0430 \u0438\u043c\u0435\u0442\u044c \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u044f\u044e\u0449\u0435\u0435 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435, \u043a\u0430\u043a \u044d\u0442\u043e \u0434\u0435\u043b\u0430\u0435\u0442\u0441\u044f, \u0438 \u043a\u0430\u043a\u0438\u0435 \u0438\u0441\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u044f \u0435\u0441\u0442\u044c \u0438\u0437 \u044d\u0442\u043e\u0433\u043e \u043f\u0440\u0430\u0432\u0438\u043b\u0430. \u0412 \u044d\u0442\u043e\u0439 \u0434\u043e\u0432\u043e\u043b\u044c\u043d\u043e \u0437\u0430\u043f\u043e\u0437\u0434\u0430\u043b\u043e\u0439 \u0441\u0442\u0430\u0442\u044c\u0435 \u044f \u043e\u0431\u044a\u044f\u0441\u043d\u044e, [&hellip;]<\/p>\n","protected":false,"gt_translate_keys":[{"key":"rendered","format":"html"}]},"author":1,"featured_media":79466,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[688],"tags":[],"class_list":["post-79465","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.2 - aioseo.com -->\n\t<meta name=\"description\" content=\"\u041f\u0440\u0438\u0432\u0435\u0442, \u0425\u0430\u0431\u0440! \u041c\u044b \u043f\u0440\u043e\u0434\u043e\u043b\u0436\u0430\u0435\u043c \u0438\u0441\u0441\u043b\u0435\u0434\u043e\u0432\u0430\u0442\u044c \u0442\u0435\u043c\u0443\" \/>\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\/sq\/blog\/administrirovanie\/istina-prezhde-vsego-ili-pochemu-sistemu-nuzhno-proektirovat-ishodya-iz-ustrojstva-bazy-dannyh\" \/>\n\t<meta name=\"generator\" content=\"All in One SEO (AIOSEO) 5.0.2\" \/>\n\t\t<meta property=\"og:locale\" content=\"sq_AL\" \/>\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\u0418\u0441\u0442\u0438\u043d\u0430 \u043f\u0440\u0435\u0436\u0434\u0435 \u0432\u0441\u0435\u0433\u043e, \u0438\u043b\u0438 \u043f\u043e\u0447\u0435\u043c\u0443 \u0441\u0438\u0441\u0442\u0435\u043c\u0443 \u043d\u0443\u0436\u043d\u043e \u043f\u0440\u043e\u0435\u043a\u0442\u0438\u0440\u043e\u0432\u0430\u0442\u044c, \u0438\u0441\u0445\u043e\u0434\u044f \u0438\u0437 \u0443\u0441\u0442\u0440\u043e\u0439\u0441\u0442\u0432\u0430 \u0431\u0430\u0437\u044b \u0434\u0430\u043d\u043d\u044b\u0445 | ProHoster\" \/>\n\t\t<meta property=\"og:description\" content=\"\u041f\u0440\u0438\u0432\u0435\u0442, \u0425\u0430\u0431\u0440! \u041c\u044b \u043f\u0440\u043e\u0434\u043e\u043b\u0436\u0430\u0435\u043c \u0438\u0441\u0441\u043b\u0435\u0434\u043e\u0432\u0430\u0442\u044c \u0442\u0435\u043c\u0443\" \/>\n\t\t<meta property=\"og:url\" content=\"https:\/\/prohoster.info\/sq\/blog\/administrirovanie\/istina-prezhde-vsego-ili-pochemu-sistemu-nuzhno-proektirovat-ishodya-iz-ustrojstva-bazy-dannyh\" \/>\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-04-27T05:42:20+00:00\" \/>\n\t\t<meta property=\"article:modified_time\" content=\"2020-04-27T05:42:20+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\udd47E v\u00ebrteta mbi t\u00eb gjitha, ose pse sistemi duhet t\u00eb projektohet duke u bazuar n\u00eb nd\u00ebrtimin e baz\u00ebs s\u00eb t\u00eb dh\u00ebnave | ProHoster","description":"P\u00ebrsh\u00ebndetje, Habr! Ne vazhdojm\u00eb t\u00eb eksplorojm\u00eb tem\u00ebn","canonical_url":"https:\/\/prohoster.info\/sq\/blog\/administrirovanie\/istina-prezhde-vsego-ili-pochemu-sistemu-nuzhno-proektirovat-ishodya-iz-ustrojstva-bazy-dannyh","robots":"max-image-preview:large","keywords":"","webmasterTools":{"miscellaneous":""},"schema":null,"og:locale":"sq_AL","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\u0418\u0441\u0442\u0438\u043d\u0430 \u043f\u0440\u0435\u0436\u0434\u0435 \u0432\u0441\u0435\u0433\u043e, \u0438\u043b\u0438 \u043f\u043e\u0447\u0435\u043c\u0443 \u0441\u0438\u0441\u0442\u0435\u043c\u0443 \u043d\u0443\u0436\u043d\u043e \u043f\u0440\u043e\u0435\u043a\u0442\u0438\u0440\u043e\u0432\u0430\u0442\u044c, \u0438\u0441\u0445\u043e\u0434\u044f \u0438\u0437 \u0443\u0441\u0442\u0440\u043e\u0439\u0441\u0442\u0432\u0430 \u0431\u0430\u0437\u044b \u0434\u0430\u043d\u043d\u044b\u0445 | ProHoster","og:description":"\u041f\u0440\u0438\u0432\u0435\u0442, \u0425\u0430\u0431\u0440! \u041c\u044b \u043f\u0440\u043e\u0434\u043e\u043b\u0436\u0430\u0435\u043c \u0438\u0441\u0441\u043b\u0435\u0434\u043e\u0432\u0430\u0442\u044c \u0442\u0435\u043c\u0443","og:url":"https:\/\/prohoster.info\/sq\/blog\/administrirovanie\/istina-prezhde-vsego-ili-pochemu-sistemu-nuzhno-proektirovat-ishodya-iz-ustrojstva-bazy-dannyh","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-04-27T05:42:20+00:00","article:modified_time":"2020-04-27T05:42:20+00:00","article:publisher":"https:\/\/www.facebook.com\/prohoster","article:author":"https:\/\/www.facebook.com\/prohoster"},"aioseo_meta_data":{"post_id":"79465","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 16:37:24","updated":"2022-09-29 16:13:15","focus_keyword":null,"additional_keywords":null,"truseo_locale":null},"gt_translate_keys":[{"key":"link","format":"url"}],"_links":{"self":[{"href":"https:\/\/prohoster.info\/sq\/wp-json\/wp\/v2\/posts\/79465","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/prohoster.info\/sq\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/prohoster.info\/sq\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/prohoster.info\/sq\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/prohoster.info\/sq\/wp-json\/wp\/v2\/comments?post=79465"}],"version-history":[{"count":0,"href":"https:\/\/prohoster.info\/sq\/wp-json\/wp\/v2\/posts\/79465\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/prohoster.info\/sq\/wp-json\/wp\/v2\/media\/79466"}],"wp:attachment":[{"href":"https:\/\/prohoster.info\/sq\/wp-json\/wp\/v2\/media?parent=79465"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/prohoster.info\/sq\/wp-json\/wp\/v2\/categories?post=79465"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/prohoster.info\/sq\/wp-json\/wp\/v2\/tags?post=79465"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}