{"id":55011,"date":"2020-01-10T00:00:00","date_gmt":"2020-01-09T21:00:00","guid":{"rendered":"https:\/\/prohoster.info\/blog\/blog_prohoster\/bd-messendzhera-ch-1-proektiruem-karkas-bazy"},"modified":"2020-02-18T14:03:05","modified_gmt":"2020-02-18T11:03:05","slug":"bd-messendzhera-ch-1-proektiruem-karkas-bazy","status":"publish","type":"post","link":"https:\/\/prohoster.info\/pl\/blog\/administrirovanie\/bd-messendzhera-ch-1-proektiruem-karkas-bazy","title":{"rendered":"Baza danych komunikatora (cz. 1): projektowanie szkieletu bazy","gt_translate_keys":[{"key":"rendered","format":"text"}]},"content":{"rendered":"<p>Jak mo\u017cna przet\u0142umaczy\u0107 wymagania biznesowe na konkretne struktury danych na przyk\u0142adzie projektowania bazy dla komunikatora od podstaw.<\/p>\n<ul>\n<li>Cz\u0119\u015b\u0107 1: projektowanie struktury bazy<\/li>\n<li><noindex><a rel=\"nofollow\" href=\"https:\/\/habr.com\/ru\/post\/483170\/\">Cz\u0119\u015b\u0107 2: sekcjonowanie \"na \u017cywo\"<\/a><\/noindex><\/li>\n<\/ul>\n<p>\n<img decoding=\"async\" alt=\"Baza danych komunikatora (cz. 1): projektowanie szkieletu bazy\" src=\"\/wp-content\/uploads\/2020\/01\/d4e85052405da3f6580e4e931c292079.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\nNasza baza nie b\u0119dzie tak masywna i rozproszona, <noindex><a rel=\"nofollow\" href=\"https:\/\/habr.com\/ru\/company\/vk\/blog\/342570\/\">jak u \u0412\u041a\u043e\u043d\u0442\u0430\u043a\u0442\u0435,<\/a><\/noindex> lub <noindex><a rel=\"nofollow\" href=\"https:\/\/habr.com\/ru\/company\/oleg-bunin\/blog\/340976\/\">Badoo<\/a><\/noindex>, a \u201e\u017ceby by\u0142o\u201d, ale \u017ceby by\u0142o dobrze \u2014 funkcjonalnie, szybko i <b>mie\u015bci\u0142o si\u0119 na jednym serwerze.<\/b> PostgreSQL \u2014 \u017ceby mo\u017cna by\u0142o uruchomi\u0107 oddzielny egzemplarz us\u0142ugi gdzie\u015b po stronie, na przyk\u0142ad.<\/p>\n<p>Dlatego nie b\u0119dziemy porusza\u0107 kwestii shardingu, replikacji i system\u00f3w geograficznie rozproszonych, ale skoncentrujemy si\u0119 na rozwi\u0105zaniach schematycznych w obr\u0119bie DB.<br \/>\n<noindex><a rel=\"nofollow\" name=\"habracut\"><\/a><\/noindex><\/p>\n<h2>Krok 1: Troch\u0119 specyfiki biznesowej<\/h2>\n<p>\nNasz system wymiany wiadomo\u015bci b\u0119dziemy projektowa\u0107 nie abstrakcyjnie, ale wkomponuj\u0105c go w otoczenie <noindex><a rel=\"nofollow\" href=\"https:\/\/sbis.ru\/help\/work_in\/sms\/\">korporacyjnej sieci spo\u0142eczno\u015bciowej.<\/a><\/noindex>Oznacza to, \u017ce ludzie nie \u201epo prostu wymieniaj\u0105 wiadomo\u015bci\u201d, ale komunikuj\u0105 si\u0119 w kontek\u015bcie rozwi\u0105zania okre\u015blonych problem\u00f3w biznesowych.<\/p>\n<p>Jakie problemy mog\u0105 mie\u0107 firmy? Przyjrzyjmy si\u0119 na przyk\u0142adzie Wasilija \u2014 kierownika dzia\u0142u rozwoju.<\/p>\n<ul>\n<li><i>\u201eNiko\u0142aj, ten patch musi by\u0107 gotowy ju\u017c dzi\u015b!\u201d<\/i><br \/>\nOznacza to, \u017ce rozmowa mo\u017ce toczy\u0107 si\u0119 w kontek\u015bcie jakiego\u015b <b>dokumentu<\/b>.<\/li>\n<li><i>\u201eKolia, grajmy wieczorem w Dota?\u201d<\/i><br \/>\nOznacza to, \u017ce nawet w przypadku jednej pary rozm\u00f3wc\u00f3w, komunikacja mo\u017ce si\u0119 jednocze\u015bnie toczy\u0107 <b>na r\u00f3\u017cne tematy.<\/b>.<\/li>\n<li><i>\u201ePiotr, Niko\u0142aj, zerknijcie do za\u0142\u0105cznika, jest cennik na nowy serwer.\u201d<\/i><br \/>\nZatem jedno wiadomo\u015b\u0107 mo\u017ce mie\u0107 <b>kilku adresat\u00f3w.<\/b>Przy tym wiadomo\u015b\u0107 mo\u017ce zawiera\u0107 <b>za\u0142\u0105czniki,<\/b>.<\/li>\n<li><i>\u201eSemen, zerknij tak\u017ce ty.\u201d<\/i><br \/>\nI powinna by\u0107 mo\u017cliwo\u015b\u0107 zaproszenia nowego uczestnika do ju\u017c istniej\u0105cej rozmowy. <b>Na razie zatrzymamy si\u0119 na tym wykazie \u201eoczywistych\u201d potrzeb.<\/b>.<\/li>\n<\/ul>\n<p>\nBez zrozumienia aplikacyjnej specyfiki zadania oraz narzuconych mu ogranicze\u0144, zaprojektowanie<\/p>\n<blockquote><p>efektywnego <b>schematu DB dla jego rozwi\u0105zania jest praktycznie niemo\u017cliwe.<\/b> Krok 2: Minimalny logiczny schemat<\/p><\/blockquote>\n<p><\/p>\n<h2>Schemat wygl\u0105da na bardzo przypominaj\u0105cy korespondencj\u0119 e-mailow\u0105 \u2014 tradycyjne narz\u0119dzie prowadzenia biznesu. Tak, \u201ealgorytmicznie\u201d wiele zada\u0144 biznesowych jest do siebie podobnych, dlatego narz\u0119dzia do ich rozwi\u0105zywania b\u0119d\u0105 strukturalnie podobne.<\/h2>\n<p>\nUtrwalmy ju\u017c otrzymany logiczny schemat relacji encji. Dla uproszczenia zrozumienia naszej modelu skorzystamy z najprostszej wersji graficznej<\/p>\n<p>modelu ER <noindex><a rel=\"nofollow\" href=\"https:\/\/ru.wikipedia.org\/wiki\/ER-%D0%BC%D0%BE%D0%B4%D0%B5%D0%BB%D1%8C\">bez komplikacji UML lub notacji IDEF:<\/a><\/noindex> \u0431\u0435\u0437 \u0443\u0441\u043b\u043e\u0436\u043d\u0435\u043d\u0438\u0439 UML \u0438\u043b\u0438 IDEF-\u043d\u043e\u0442\u0430\u0446\u0438\u0439:<\/p>\n<p><img decoding=\"async\" alt=\"Baza danych komunikatora (cz. 1): projektowanie szkieletu bazy\" src=\"\/wp-content\/uploads\/2020\/01\/75d0b3cf9e5a44ae3e243449fa406fbc.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nW naszym przyk\u0142adzie posta\u0107, dokument i binarne \u201ecia\u0142o\u201d pliku to \u201ezewn\u0119trzne\u201d byty, kt\u00f3re istniej\u0105 niezale\u017cnie od naszej us\u0142ugi. Dlatego w dalszej cz\u0119\u015bci b\u0119dziemy je postrzega\u0107 jako pewne odno\u015bniki \u201egdzie\u015b\u201d wed\u0142ug UUID.<\/p>\n<blockquote><p>Rysujcie <b>schematy w jak najprostszy spos\u00f3b<\/b> \u2014 wi\u0119kszo\u015b\u0107 os\u00f3b, kt\u00f3rym je poka\u017cecie, nie jest ekspertem w czytaniu UML\/IDEF. Ale \u2014 rysujcie koniecznie.<\/p><\/blockquote>\n<p><\/p>\n<h2>Krok 3: Szkicujemy struktur\u0119 tabel<\/h2>\n<p>\n<b class=\"spoiler_title\">O nazwach tabel i p\u00f3l<\/b>Do \"rosyjskich\" nazw p\u00f3l i tabel mo\u017cna podchodzi\u0107 r\u00f3\u017cnie, ale to kwestia gustu. Poniewa\u017c <noindex><a rel=\"nofollow\" href=\"https:\/\/tensor.ru\/about\/career\/vacancies\">w naszym \"Tenzorze\"<\/a><\/noindex> nie mamy zagranicznych deweloper\u00f3w, a PostgreSQL pozwala nam nadawa\u0107 nazwy nawet w hieroglifach, je\u017celi s\u0105 <u>zamkni\u0119te w cudzys\u0142owach<\/u>, wi\u0119c wolimy nazywa\u0107 obiekty jednoznacznie, aby unikn\u0105\u0107 nieporozumie\u0144.<br \/>\nPoniewa\u017c wiadomo\u015bci pisze nam wiele os\u00f3b jednocze\u015bnie, cz\u0119\u015b\u0107 z nich mo\u017ce to robi\u0107 <u>w trybie offline<\/u>, to najprostszym rozwi\u0105zaniem jest <b>u\u017cywanie UUID jako identyfikator\u00f3w<\/b> nie tylko dla zewn\u0119trznych byt\u00f3w, ale tak\u017ce dla wszystkich obiekt\u00f3w w naszej us\u0142udze. Co wi\u0119cej, mo\u017cna je generowa\u0107 nawet po stronie klienta \u2014 to pomo\u017ce nam wspiera\u0107 wysy\u0142anie wiadomo\u015bci podczas kr\u00f3tkotrwa\u0142ej niedost\u0119pno\u015bci Bazy Danych, a prawdopodobie\u0144stwo kolizji jest ekstremalnie ma\u0142e.<\/p>\n<p>Robocza struktura tabel w naszej bazie przyjmie taki kszta\u0142t:<br \/>\n<b class=\"spoiler_title\">Tabele: RU<\/b><\/p>\n<pre><code class=\"sql\">CREATE TABLE \"Temat\"(\n  \"Temat\"\n    uuid\n      PRIMARY KEY\n, \"Dokument\"\n    uuid\n, \"Nazwa\"\n    text\n);\n\nCREATE TABLE \"Wiadomo\u015b\u0107\"(\n  \"Wiadomo\u015b\u0107\"\n    uuid\n      PRIMARY KEY\n, \"Temat\"\n    uuid\n, \"Autor\"\n    uuid\n, \"DataCzas\"\n    timestamp\n, \"Tekst\"\n    text\n);\n\nCREATE TABLE \"Adresat\"(\n  \"Wiadomo\u015b\u0107\"\n    uuid\n, \"Osoba\"\n    uuid\n, PRIMARY KEY(\"Wiadomo\u015b\u0107\", \"Osoba\")\n);\n\nCREATE TABLE \"Plik\"(\n  \"Plik\"\n    uuid\n      PRIMARY KEY\n, \"Wiadomo\u015b\u0107\"\n    uuid\n, \"BLOB\"\n    uuid\n, \"Nazwa\"\n    text\n);<\/code><\/pre>\n<p>\n<b class=\"spoiler_title\">Tabele: EN<\/b><\/p>\n<pre><code class=\"sql\">CREATE TABLE theme(\n  theme\n    uuid\n      PRIMARY KEY\n, document\n    uuid\n, title\n    text\n);\n\nCREATE TABLE message(\n  message\n    uuid\n      PRIMARY KEY\n, theme\n    uuid\n, author\n    uuid\n, dt\n    timestamp\n, body\n    text\n);\n\nCREATE TABLE message_addressee(\n  message\n    uuid\n, person\n    uuid\n, PRIMARY KEY(message, person)\n);\n\nCREATE TABLE message_file(\n  file\n    uuid\n      PRIMARY KEY\n, message\n    uuid\n, content\n    uuid\n, filename\n    text\n);<\/code><\/pre>\n<p><\/p>\n<blockquote><p>Najprostszym sposobem na opisanie formatu jest zaczynanie od \u201erozkr\u0119cania\u201d grafu powi\u0105za\u0144 <b>od tabel, kt\u00f3re nie maj\u0105 odno\u015bnik\u00f3w<\/b> nigdzie.<\/p><\/blockquote>\n<p><\/p>\n<h2>Krok 4: Ustalamy nieoczywiste potrzeby<\/h2>\n<p>\nWszystko, zaprojektowali\u015bmy baz\u0119, w kt\u00f3rej mo\u017cna doskonale pisa\u0107 i <i><b>jako\u015b<\/b><\/i> czyta\u0107.<\/p>\n<p>Wyobra\u017amy sobie, \u017ce jeste\u015bmy u\u017cytkownikiem naszej us\u0142ugi \u2014 co chcieliby\u015bmy robi\u0107 za jej pomoc\u0105?<\/p>\n<ul>\n<li><i>Ostatnie wiadomo\u015bci<\/i><br \/>\nTo <b>chronologicznie uporz\u0105dkowany<\/b> \u043f\u043e \u0440\u0430\u0437\u043b\u0438\u0447\u043d\u044b\u043c \u043f\u0440\u0438\u0437\u043d\u0430\u043a\u0430\u043c \u0440\u0435\u0435\u0441\u0442\u0440 \u00ab\u043c\u043e\u0438\u0445\u00bb \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0439. \u0413\u0434\u0435 \u044f \u043e\u0434\u0438\u043d \u0438\u0437 \u0430\u0434\u0440\u0435\u0441\u0430\u0442\u043e\u0432, \u0433\u0434\u0435 \u044f \u0430\u0432\u0442\u043e\u0440, \u0433\u0434\u0435 \u043c\u043d\u0435 \u043d\u0430\u043f\u0438\u0441\u0430\u043b\u0438, \u0430 \u044f \u043d\u0435 \u043e\u0442\u0432\u0435\u0442\u0438\u043b, \u0433\u0434\u0435 \u043d\u0435 \u043e\u0442\u0432\u0435\u0442\u0438\u043b\u0438 \u043c\u043d\u0435, &#8230;<\/li>\n<li><i>Uczestnicy korespondencji<\/i><br \/>\nKto w og\u00f3le bierze udzia\u0142 w tej d\u0142ugiej-d\u0142ugiej rozmowie?<\/li>\n<\/ul>\n<p>\nNasza struktura pozwala na rozwi\u0105zanie obu tych zada\u0144 \u201ew og\u00f3le\u201d, ale nie szybko. Problem polega na tym, \u017ce do sortowania w ramach pierwszego zadania <b>nie mo\u017cna utworzy\u0107 indeksu<\/b>, odpowiedniego dla ka\u017cdego z uczestnik\u00f3w (i b\u0119dzie trzeba wydoby\u0107 wszystkie zapisy), a do rozwi\u0105zania drugiego potrzeba <b>wydoby\u0107 wszystkie wiadomo\u015bci<\/b> na dany temat.<\/p>\n<blockquote><p>Nieprzewidziane u\u017cytkowe zadania mog\u0105 na\u0142o\u017cy\u0107 powa\u017cny <b>krzy\u017cyk na wydajno\u015b\u0107<\/b>.<\/p><\/blockquote>\n<p><\/p>\n<h2>Krok 5: Rozs\u0105dna denormalizacja<\/h2>\n<p>\nOba nasze problemy mog\u0105 zosta\u0107 rozwi\u0105zane przez dodatkowe tabele, w kt\u00f3re b\u0119dziemy <b>duplikowa\u0107 cz\u0119\u015b\u0107 danych<\/b>, potrzebnych do utworzenia na nich odpowiednich do naszych zada\u0144 indeks\u00f3w.<br \/>\n<img decoding=\"async\" alt=\"Baza danych komunikatora (cz. 1): projektowanie szkieletu bazy\" src=\"\/wp-content\/uploads\/2020\/01\/f136a9904518b05bca74cc2b9c2f01b2.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\n<b class=\"spoiler_title\">Tabele: RU<\/b><\/p>\n<pre><code class=\"sql\">CREATE TABLE \"RejestrWiadomo\u015bci\"(\n  \"W\u0142a\u015bciciel\"\n    uuid\n, \"TypRejestru\"\n    smallint\n, \"DataCzas\"\n    timestamp\n, \"Wiadomo\u015b\u0107\"\n    uuid\n, PRIMARY KEY(\"W\u0142a\u015bciciel\", \"TypRejestru\", \"Wiadomo\u015b\u0107\")\n);\nCREATE INDEX ON \"RejestrWiadomo\u015bci\"(\"W\u0142a\u015bciciel\", \"TypRejestru\", \"DataCzas\" DESC);\n\nCREATE TABLE \"UczestnikTematu\"(\n  \"Temat\"\n    uuid\n, \"Osoba\"\n    uuid\n, PRIMARY KEY(\"Temat\", \"Osoba\")\n);<\/code><\/pre>\n<p>\n<b class=\"spoiler_title\">Tabele: EN<\/b><\/p>\n<pre><code class=\"sql\">CREATE TABLE message_registry(\n  owner\n    uuid\n, registry\n    smallint\n, dt\n    timestamp\n, message\n    uuid\n, PRIMARY KEY(owner, registry, message)\n);\nCREATE INDEX ON message_registry(owner, registry, dt DESC);\n\nCREATE TABLE theme_participant(\n  theme\n    uuid\n, person\n    uuid\n, PRIMARY KEY(theme, person)\n);<\/code><\/pre>\n<p>\nTutaj zastosowali\u015bmy dwa typowe podej\u015bcia, stosowane podczas tworzenia tabel pomocniczych:<\/p>\n<ul>\n<li><b>Mno\u017cenie zapis\u00f3w<\/b><br \/>\nTworzymy kilka zapis\u00f3w po jednej podstawowej wiadomo\u015bci w r\u00f3\u017cne rodzaje rejestr\u00f3w dla r\u00f3\u017cnych w\u0142a\u015bcicieli \u2014 zar\u00f3wno dla nadawcy, jak i dla odbiorcy. Dzi\u0119ki temu ka\u017cdy z rejestr\u00f3w teraz uk\u0142ada si\u0119 na indeks \u2014 bo w typowym przypadku chcieliby\u015bmy widzie\u0107 tylko pierwsz\u0105 stron\u0119.<\/li>\n<li><b>Unikalizacja zapis\u00f3w<\/b><br \/>\nPrzy ka\u017cdej wysy\u0142ce wiadomo\u015bci w konkretnej tematyce wystarczy sprawdzi\u0107, czy taki zapis ju\u017c istnieje. Je\u015bli nie \u2014 dodajemy go do naszego \u201es\u0142ownika\u201d.<\/li>\n<\/ul>\n<p>\nW nast\u0119pnej cz\u0119\u015bci artyku\u0142u mowa b\u0119dzie o <noindex><a rel=\"nofollow\" href=\"https:\/\/habr.com\/ru\/post\/483170\/\">wdro\u017ceniu partycjonowania<\/a><\/noindex> w struktur\u0119 naszej bazy.<br \/>\n<br \/>\u0179r\u00f3d\u0142o: <a content=\"nofollow\" rel=\"nofollow\" href=\"https:\/\/habr.com\/ru\/post\/483176\/\">habr.com<\/a><\/p>","protected":false,"gt_translate_keys":[{"key":"rendered","format":"html"}]},"excerpt":{"rendered":"<p>\u041a\u0430\u043a \u043c\u043e\u0436\u043d\u043e \u043f\u0435\u0440\u0435\u0432\u0435\u0441\u0442\u0438 \u0431\u0438\u0437\u043d\u0435\u0441-\u0442\u0440\u0435\u0431\u043e\u0432\u0430\u043d\u0438\u044f \u0432 \u043a\u043e\u043d\u043a\u0440\u0435\u0442\u043d\u044b\u0435 \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u044b \u0434\u0430\u043d\u043d\u044b\u0445 \u043d\u0430 \u043f\u0440\u0438\u043c\u0435\u0440\u0435 \u043f\u0440\u043e\u0435\u043a\u0442\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f \u00ab\u0441 \u043d\u0443\u043b\u044f\u00bb \u0431\u0430\u0437\u044b \u0434\u043b\u044f \u043c\u0435\u0441\u0441\u0435\u043d\u0434\u0436\u0435\u0440\u0430. \u0427\u0430\u0441\u0442\u044c 1: \u043f\u0440\u043e\u0435\u043a\u0442\u0438\u0440\u0443\u0435\u043c \u043a\u0430\u0440\u043a\u0430\u0441 \u0431\u0430\u0437\u044b \u0427\u0430\u0441\u0442\u044c 2: \u0441\u0435\u043a\u0446\u0438\u043e\u043d\u0438\u0440\u0443\u0435\u043c \u00ab\u043d\u0430\u0436\u0438\u0432\u0443\u044e\u00bb \u041d\u0430\u0448\u0430 \u0431\u0430\u0437\u0430 \u0431\u0443\u0434\u0435\u0442 \u043d\u0435 \u0442\u0430\u043a\u043e\u0439 \u043c\u0430\u0441\u0448\u0442\u0430\u0431\u043d\u043e\u0439 \u0438 \u0440\u0430\u0441\u043f\u0440\u0435\u0434\u0435\u043b\u0435\u043d\u043d\u043e\u0439, \u043a\u0430\u043a \u0443 \u0412\u041a\u043e\u043d\u0442\u0430\u043a\u0442\u0435 \u0438\u043b\u0438 Badoo, \u0430 \u00ab\u0447\u0442\u043e\u0431\u044b \u0431\u044b\u043b\u043e\u00bb, \u043d\u043e \u0431\u044b\u043b\u043e \u0445\u043e\u0440\u043e\u0448\u043e \u2014 \u0444\u0443\u043d\u043a\u0446\u0438\u043e\u043d\u0430\u043b\u044c\u043d\u043e, \u0431\u044b\u0441\u0442\u0440\u043e \u0438 \u0443\u043c\u0435\u0449\u0430\u043b\u043e\u0441\u044c \u043d\u0430 \u043e\u0434\u043d\u043e\u043c \u0441\u0435\u0440\u0432\u0435\u0440\u0435 PostgreSQL \u2014 \u0447\u0442\u043e\u0431\u044b [&hellip;]<\/p>\n","protected":false,"gt_translate_keys":[{"key":"rendered","format":"html"}]},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[688],"tags":[],"class_list":["post-55011","post","type-post","status-publish","format-standard","hentry","category-administrirovanie"],"aioseo_notices":[],"aioseo_head":"\n\t\t<!-- All in One SEO 5.0.1.1 - aioseo.com -->\n\t<meta name=\"description\" content=\"\u041a\u0430\u043a \u043c\u043e\u0436\u043d\u043e \u043f\u0435\u0440\u0435\u0432\u0435\u0441\u0442\u0438 \u0431\u0438\u0437\u043d\u0435\u0441-\u0442\u0440\u0435\u0431\u043e\u0432\u0430\u043d\u0438\u044f \u0432 \u043a\u043e\u043d\u043a\u0440\u0435\u0442\u043d\u044b\u0435 \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u044b \u0434\u0430\u043d\u043d\u044b\u0445 \u043d\u0430 \u043f\u0440\u0438\u043c\u0435\u0440\u0435 \u043f\u0440\u043e\u0435\u043a\u0442\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f \u00ab\u0441 \u043d\u0443\u043b\u044f\u00bb \u0431\u0430\u0437\u044b \u0434\u043b\u044f \u043c\u0435\u0441\u0441\u0435\u043d\u0434\u0436\u0435\u0440\u0430. \u0427\u0430\u0441\u0442\u044c 1: \u043f\u0440\u043e\u0435\u043a\u0442\u0438\u0440\u0443\u0435\u043c \u043a\u0430\u0440\u043a\u0430\u0441 \u0431\u0430\u0437\u044b\" \/>\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\/pl\/blog\/administrirovanie\/bd-messendzhera-ch-1-proektiruem-karkas-bazy\" \/>\n\t<meta name=\"generator\" content=\"All in One SEO (AIOSEO) 5.0.1.1\" \/>\n\t\t<meta property=\"og:locale\" content=\"pl_PL\" \/>\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\u0411\u0414 \u043c\u0435\u0441\u0441\u0435\u043d\u0434\u0436\u0435\u0440\u0430 (\u0447.1): \u043f\u0440\u043e\u0435\u043a\u0442\u0438\u0440\u0443\u0435\u043c \u043a\u0430\u0440\u043a\u0430\u0441 \u0431\u0430\u0437\u044b | ProHoster\" \/>\n\t\t<meta property=\"og:description\" content=\"\u041a\u0430\u043a \u043c\u043e\u0436\u043d\u043e \u043f\u0435\u0440\u0435\u0432\u0435\u0441\u0442\u0438 \u0431\u0438\u0437\u043d\u0435\u0441-\u0442\u0440\u0435\u0431\u043e\u0432\u0430\u043d\u0438\u044f \u0432 \u043a\u043e\u043d\u043a\u0440\u0435\u0442\u043d\u044b\u0435 \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u044b \u0434\u0430\u043d\u043d\u044b\u0445 \u043d\u0430 \u043f\u0440\u0438\u043c\u0435\u0440\u0435 \u043f\u0440\u043e\u0435\u043a\u0442\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f \u00ab\u0441 \u043d\u0443\u043b\u044f\u00bb \u0431\u0430\u0437\u044b \u0434\u043b\u044f \u043c\u0435\u0441\u0441\u0435\u043d\u0434\u0436\u0435\u0440\u0430. \u0427\u0430\u0441\u0442\u044c 1: \u043f\u0440\u043e\u0435\u043a\u0442\u0438\u0440\u0443\u0435\u043c \u043a\u0430\u0440\u043a\u0430\u0441 \u0431\u0430\u0437\u044b\" \/>\n\t\t<meta property=\"og:url\" content=\"https:\/\/prohoster.info\/pl\/blog\/administrirovanie\/bd-messendzhera-ch-1-proektiruem-karkas-bazy\" \/>\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-01-09T21:00:00+00:00\" \/>\n\t\t<meta property=\"article:modified_time\" content=\"2020-02-18T11:03:05+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\udd47Baza danych komunikatora (cz\u0119\u015b\u0107 1): projektujemy szkielet bazy | ProHoster","description":"Jak mo\u017cna przet\u0142umaczy\u0107 wymagania biznesowe na konkretne struktury danych na przyk\u0142adzie projektowania \u201eod zera\u201d bazy dla komunikatora. Cz\u0119\u015b\u0107 1: projektujemy szkielet bazy","canonical_url":"https:\/\/prohoster.info\/pl\/blog\/administrirovanie\/bd-messendzhera-ch-1-proektiruem-karkas-bazy","robots":"max-image-preview:large","keywords":"","webmasterTools":{"miscellaneous":""},"schema":null,"og:locale":"pl_PL","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\u0411\u0414 \u043c\u0435\u0441\u0441\u0435\u043d\u0434\u0436\u0435\u0440\u0430 (\u0447.1): \u043f\u0440\u043e\u0435\u043a\u0442\u0438\u0440\u0443\u0435\u043c \u043a\u0430\u0440\u043a\u0430\u0441 \u0431\u0430\u0437\u044b | ProHoster","og:description":"\u041a\u0430\u043a \u043c\u043e\u0436\u043d\u043e \u043f\u0435\u0440\u0435\u0432\u0435\u0441\u0442\u0438 \u0431\u0438\u0437\u043d\u0435\u0441-\u0442\u0440\u0435\u0431\u043e\u0432\u0430\u043d\u0438\u044f \u0432 \u043a\u043e\u043d\u043a\u0440\u0435\u0442\u043d\u044b\u0435 \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u044b \u0434\u0430\u043d\u043d\u044b\u0445 \u043d\u0430 \u043f\u0440\u0438\u043c\u0435\u0440\u0435 \u043f\u0440\u043e\u0435\u043a\u0442\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f \u00ab\u0441 \u043d\u0443\u043b\u044f\u00bb \u0431\u0430\u0437\u044b \u0434\u043b\u044f \u043c\u0435\u0441\u0441\u0435\u043d\u0434\u0436\u0435\u0440\u0430. \u0427\u0430\u0441\u0442\u044c 1: \u043f\u0440\u043e\u0435\u043a\u0442\u0438\u0440\u0443\u0435\u043c \u043a\u0430\u0440\u043a\u0430\u0441 \u0431\u0430\u0437\u044b","og:url":"https:\/\/prohoster.info\/pl\/blog\/administrirovanie\/bd-messendzhera-ch-1-proektiruem-karkas-bazy","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-01-09T21:00:00+00:00","article:modified_time":"2020-02-18T11:03:05+00:00","article:publisher":"https:\/\/www.facebook.com\/prohoster","article:author":"https:\/\/www.facebook.com\/prohoster"},"aioseo_meta_data":{"post_id":"55011","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":"2026-01-24 13:30:15","breadcrumb_settings":null,"limit_modified_date":false,"reviewed_by":null,"ai":null,"created":"2021-02-28 17:27:13","updated":"2026-01-24 13:30:15","focus_keyword":null,"additional_keywords":null,"truseo_locale":null},"gt_translate_keys":[{"key":"link","format":"url"}],"_links":{"self":[{"href":"https:\/\/prohoster.info\/pl\/wp-json\/wp\/v2\/posts\/55011","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/prohoster.info\/pl\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/prohoster.info\/pl\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/prohoster.info\/pl\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/prohoster.info\/pl\/wp-json\/wp\/v2\/comments?post=55011"}],"version-history":[{"count":0,"href":"https:\/\/prohoster.info\/pl\/wp-json\/wp\/v2\/posts\/55011\/revisions"}],"wp:attachment":[{"href":"https:\/\/prohoster.info\/pl\/wp-json\/wp\/v2\/media?parent=55011"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/prohoster.info\/pl\/wp-json\/wp\/v2\/categories?post=55011"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/prohoster.info\/pl\/wp-json\/wp\/v2\/tags?post=55011"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}