Article View: pl.comp.lang.php
Article #232402Re: Symfony 4 - jak projektować bazę danych pod Doctrine?
From: Kviat
Date: Wed, 24 Apr 2019 22:08
Date: Wed, 24 Apr 2019 22:08
275 lines
14585 bytes
14585 bytes
W dniu 24.04.2019 o 20:18, Wojciech Bancer pisze: > On 2019-04-24, Kviat <Kviat> wrote: > > [...] > >>> Podałem swoje argumenty dlaczego tak uważam i dlaczego uważam triggery >>> za mniej wydajne. Nie mam ochoty się powtarzać. Bazy danych są najbardziej >>> obciążonym kawałkiem w typowych aplikacjach i nie należy ich dociążać. >> >> Triggery i procedury wbudowane nie służą tylko i wyłącznie do celów >> optymalizacyjnych. > > No na pewno nie służą do zapisywania w nich logiki biznesowej. > Zbyt kiepski to język. W prawdziwym życiu oprócz logiki biznesowej (w zasadzie to do tego określenia możesz wrzucić wszystko co chcesz, dopóki nie uściślisz co masz na myśli), istnieją też inne logiki. Jeden klient może chcieć moduł sprzedażowy+magazyn w jednym, a inny osobno fakturowanie, a osobno magazyn. I te dwa różne modele biznesowe łączy tylko to, że łączą się z tym samym serwerem bazy danych. Jest jeszcze np. logika ustawodawcy, który wydaje takie, a nie inne przepisy, że np. nie możesz usunąć jakiegoś dokumentu jak już go wystawiłeś, albo dokumentu powiązanego logicznie (np. księgowo) z innym. Masz możliwość implementowania tego w kilku aplikacjach klienckich i przy każdej drobnej popierdółce zmieniasz i rekompilujesz wszystkie aplikacje/moduły (nie wspominając o narzędziach firm zewnętrznych) i wysyłasz klientowi żeby zrobił upgrade na 30 stanowiskach. Albo robisz jedną zmianę w strukturze bazy, trigger before delete i wysyłasz jeden upgrade dla serwera bazy. Wszystkie aplikacje, jakkolwiek by nie były wypasione i choćby się łączyły z serwerem z drugiego końca kraju, dostają komunikat z serwera, że nie da się usunąć rekordu i już. (nie czepiaj się proszę przykładu - to tylko przykład) Pisałem w poprzednim poście, co chyba przeoczyłeś, że jeżeli nie zapewnisz integralności na poziomie bazy, to wystarczy głupi błąd w jednej aplikacji klienckiej np.Magazyn w wersji 100.2345.45 SP3 i reszta aplikacji klienckich leży z błędnymi danymi. >> Nie widzę przeszkód w wersjonowaniu kodu procedury składowanej.. > > Aha. I rollback do tego też? Rollback do czego? Do przepisów księgowych które zmieniły się dwa lata temu? > Albo taka magiczna sztuczka jak przeskok o 2 wersje, połączone > ze zmianami na danych. I w czym problem? Jeżeli wyszła wersja 10.2, a klient pracuje na wersji 10.0 to aktualizacja struktury bazy polega na: 10.0 -> 10.1 -> 10.2 a nie 10.0 -> 10.2 Musi być zachowana ciągłość, bo niektóre zmiany w wersji 10.2 dotyczą wcześniejszych z wersji 10.1 Nie da się przeskoczyć z wersji 10.0 do 10.2, bo przepisy które są aktualne dla wersji 10.2 nie istniały w czasie wersji 10.0, a były to przepisy zmieniające przepisy z wersji 10.1, która wprowadzała zmianę do przepisów w wersji 10.0. Logika biznesowa to nie są sztuczki magiczne. >> Co do pracy w zespole, to przecież osoba pisząca aplikację łączącą się z >> bazą (korzystająca z danych składowanych w bazie) niekoniecznie musi >> wiedzieć, co dana procedura/trigger robi "w środku". Interesują go >> wyniki jakie otrzymuje z bazy. > > A potem osoba od DBA odejdzie i jest "aaayyyyeeeeecosiędzieje". > Widziałem takie podejście wiele razy. Przecież to nie jest wada triggerów i procedur składowanych. To wada firmy krzak, w której jedyna "osoba od DBA" robi notatki o zmianach ołówkiem na karteczkach post-it, a na odchodne ze złości klika "encrypt stored procedure". >>> A że trigger jakoś istotnie szybciej przeiteruje po tablicy >>> w pamięci niż aplikacja, to wybacz nie wierzę. Język interpretowany >>> nie ma dostępu do pamięci "gorszego sortu" tylko tej samej, >>> chyba że serwer DB stoi na innej infrastrukturze. >> >> I wtedy aby przeiterować trzeba z bazy wypchnąć do klienta wszystkie >> rekordy, które mają być przeiterowane, łącznie z rekordami zależnymi, >> żeby otrzymać wynik. > > I mam uwierzyć, że jak ktoś nie potrafi optymalnie sobie pobrać > danych do procesowania w aplikacji, to zrobi to optymalnie w triggerze. > Tak, jasne. Zdefiniuj co to znaczy "optymalnie pobrać"? Tylko połowę WZ, RW i PZ żeby poznać aktualny stan magazynowy towaru, czy wszystkie 15 tysięcy dokumentów zawierających jeszcze po 20 innych pozycji towarowych z ostatnich czterech miesięcy, albo tworzyć w kliencie dynamiczne zapytania do bazy, potworki SQLowe wybierające z ostatnich 15 tysięcy dokumentów tylko te zawierające dany towar i niech sobie klient zlicza jaki jest stan? A w czasie pobierania i zliczania trzy inne stanowiska właśnie wygenerowały kolejne 3 dokumenty i stan się zmienił. A nie lepiej zliczyć na bieżąco w bazie AFTER INSERT/DELETE/UPDATE po każdym dokumencie i zaktualizować pole ze stanem i wysłać tylko do klienta aktualny stan? >> Tutaj to kwestia kompromisu, czy do stu klientów wypchnąć po >> kablach/radiu po np. 5GB żeby sobie przeiterowali lokalnie, czy >> przeiterować 100 razy w bazie i w sieć puścić tylko wynik. > > I jak masz 100 takich klientów, to ten ostatni sobie poczeka na wyniki > tydzień, bo maszyna nie ogarnie. Albo nie poczeka, bo serwer już dawno to zrobił i ma gotowy wynik w buforze i jak trzeci klient zapyta o to samo, to mu wyśle gotowca. Setnemu też. Ten setny sto razy dłużej poczeka, gdy serwer będzie musiał wysłać do 100 klientów po 50 tys rekordów żeby sobie sami przeliczyli. >> A nawet przeiterować w bazie raz, zapisać wynik w tabeli tymczasowej i >> pchać sto razy wynik po jednej iteracji. > > Ciągle widzę brak ogarniania koncepcji skalowalności "wszerz". > Macie wszyscy nawyki pisania aplikacji z 10 userami dziennie, > czy może aplikacji desktopowych? Czasem model biznesowy klienta skalowalności wszerz polega na dołożeniu 30 biurka ze sprzedawcą w mieście dalej niż dołożenie dziesiątego serwera z bazą danych, bo jeden serwer nie wyrabia z pchaniem 15 tys dokumentów na sekundę do 30 sprzedawców przez vpn po neostradzie albo przez sieć komórkową, bo akurat handlowiec laptopa odpalił w samochodzie stojąc na MOPie i chciał sprawdzić stan magazynowy gwoździa 3". Zamiast powiedzieć klientowi ile ma gwoździ na stanie to wisi na telefonie i czeka aż mu się tabelka z dokumentami magazynowymi z ostatnich 4 miesięcy ściągnie do pamięci laptopa i laptop aktualny stan przeliczy. Świetny pomysł. >> Jeżeli z bazą łączą się różne aplikacje (np. Księgowość, Magazyn, >> Sprzedaż itp.), to łatwiej (i bezpieczniej) jest ogarnąć zależności np. >> między dokumentami w bazie, > > Nie. W API. Które jest jedno i tylko ono ma dostęp do bazy. Oczywiście zgoda. W świecie idealnym każda aplikacja ma api. Ba! A nawet api stoi na osobnej maszynie, a serwer bazy w bunkrze. Co nie zmienia faktu, że przy Twoim podejściu nadal do api musisz przesłać 100 razy po 15 tys. dokumentów, gdy 100 klientów poprosi o aktualny stan magazynowy i to api te 100 razy po 15 tys dokumentów musi przesłać do klientów. Hmmm... to może niech api raz przeliczy stan i sobie go zapisze... w bazie danych? I tak api przy każdym jednym INSERT/UPDATE/DELETE jednego dokumentu będzie pobierał wszystkie dokumenty z bazy i przeliczał i zapisywał w bazie? W świecie rzeczywistym zdarza się, że api jest instalowane wraz z aplikacją kliencką, żeby klient który kupił program miał ułatwienie w pisaniu (czy używaniu) "autorskich" rozszerzeń, a komp z serwerem bazodanowym stoi w pokoju obok. Skoro w/g Ciebie serwer bazodanowy nie jest od logiki biznesowej, to api tym bardziej. W świecie rzeczywistym zdarza się, że pomimo istnienia api, zlecenie napisania rozszerzenia/wtyczki przyjmuje ktoś, kto i tak "wie lepiej" i łączy się do bazy bezpośrednio, bo szef dał mu hasło. Dlatego wymyślono opcję "encrypt stored procedure", żeby w razie takiego zachowania maksymalnie zmniejszyć niepożądane skutki. Jak będzie chciał coś grzebnąć w bazie bezpośrednio z SQL Management Studio, to nawet nie usunie rekordu powiązanego logicznie (biznesowo) z innym rekordem. A nawet jak mu się uda jakimś cudem usunąć np. WZ, to procedura zadba o to, żeby uaktualnić stan magazynowy. >> niż w poszczególnych aplikacjach. Im więcej różnych aplikacji/modułów >> tym większa szansa, że w którejś z nich będzie błąd i spowoduje >> rozsypanie zależności. > > Od logiki biznesowej to jest JEDNA aplikacja, względnie zestaw niezależnych > aplikacji (mikroserwisów) realizujących swoje indywidualne (niezależne) funkcjonalności. Przecież napisałem, że może być wiele... W jaki sposób ma to zagwarantować integralność danych w bazie? > Wystawia się kontrakt, interfejs, dokumentację, walidację i odpowiada za > realizację. A nie pół dupy zza krzaka, część w triggerach, część w aplikacji > (tej której się triggerami nie da), a część bóg wie gdzie. W świecie idealnym pewnie tak jest. W prawdziwym świecie niektóre aplikacje żyją, rozwijają się i ewoluują latami wraz ze zmianami, które były nie do przewidzenia na etapie projektowania ileś lat wcześniej, nie wspominając o możliwościach ówczesnych serwerów bazodanowych czy infrastruktury. Są też takie aplikacje, gdzie zdecydowanie lepiej i bezpieczniej jest zapewnić integralność danych na poziomie bazy danych niż w aplikacji, bo z serwerem bazy danych ktoś może połączyć się nie tylko dedykowaną aplikacją czy przez api. > Aplikacje o których mówiłeś, łączą się do konkretnych usług które potrzebują > (jeśli mówimy o architekturze mikroserwisów), albo do jednej aplikacji (jak > o architekturze monolitycznej) i to one pilnują swojego subsetu reguł. > A nie jakiś kryptyczny kod w bazie. Aplikacje o których mówiłem łączą się z serwerem bazy danych. Zapewne masz na myśli jakieś inne aplikacje. > Dzięki temu masz i większe bezpieczeństwo i większą możliwość fragmentacji, > skalowania, wydzielania, zabezpieczania (dawanie wielu aplikacjom dostępu > do bazy to jakaś masakra, jak chces zprojektować np. aplikacje mobilne w > takim trybie) i większą skalowalność. Wyobrażasz sobie takie API facebooka > realizowane z dostępem "na bazie"? Nie, nie wyobrażam sobie takiego API facebooka. Nie samym facebukiem świat żyje. > Takie grzebanie po bazie to mi się wydaje charakterystyczne dla aplikacji > księgowych na Windowsa, Świat się nie kończy na wtyczce do internetu. > które instalowały na desktopie bazę, nie udostępniały > API, a wszelkie inne programy "wdrażane" wymagały specjalistów od modyfikacji > tejże bazy. Koszmarek. Zaskoczę Cię, są też takie, gdzie serwer bazy danych stoi na osobnym sprzęcie i mają api. Co nie zmienia faktu, że zapewnianie integralności logicznej dokumentów/wpisów w bazie z poziomu aplikacji klienckich to pomysł co najmniej średni. >> Dodatkowo, jeżeli potrzebna jest jakaś zmiana, to zmianę wykonujesz w >> jednym miejscu, w bazie, a nie we wszystkich aplikacjach klienckich. > > No chyba że zmiana jest niekompatybilna No chyba, że zmiana jest kompatybilna i nie musisz zmieniać wszystkich aplikacji klienckich. >i wtedy trzeba wszysktie aplikacje > klienckie aktualizować, bo baza nie umożliwia porządnego wersjonowania. A co przeszkadza w wersjonowaniu skryptów migracyjnych? Są też pomocne narzędzia: https://docs.microsoft.com/en-us/sql/ssdt/how-to-use-schema-compare-to-compare-different-database-definitions?view=sql-server-2017 "The results of the comparison appear as a set of actions that must be taken with the target to make it the same as the source. Once the comparison is complete you can update the target directly (if the target is a project or a database) or generate an update script that has the same effect. The differences between source and target appear in a grid for easy review. You can drill into and review each difference in the results grid or in script form. You can then selectively exclude specific differences. You can save comparisons either as part of a SQL Server Database project or as a standalone file. You can also set options that control the scope of the comparison and aspects of the update. Then you can save the comparison so that you can easily repeat the same comparison later or use it as the starting point for new comparison." > [...] > >> To tak w skrócie i na szybko, że jednak triggery i procedury składowane >> czasem się przydają. > > Błędne założenia (że dostęp do bazy mają jakieś dziwne aplikacje końcowe, > to i błędne wnioski. Błędne założenie, że nie istnieją aplikacje końcowe z dostępem do bazy, prowadzą do błędnych wniosków, że triggery i procedury składowane nie są w bazie danych potrzebne. A już stwierdzenie, że są złe bo się ich gdzieśtam nie używa jest co najmniej dziwne. Pozdrawiam Piotr
Technical Details
Message-ID:
<5cc0de68$0$539$65785112@news.neostrada.pl>Path:
mbox-mo1.pugleaf.net!news-archive.icm.edu.pl!news.icm.edu.pl!newsfeed.pionier.net.pl!goblin2!goblin1!goblin.stu.neva.ru!newsfeed.neostrada.pl!unt-exc-02.news.neostrada.pl!unt-spo-a-02.news.neostrada.pl!news.neostrada.pl.POSTED!not-for-mailReferences:
<q9foak$p72$1@node2.news.atman.pl> <slrnqboo9s.e87.wojciech.bancer@pl-test.org> <5cbf10a8$0$482$65785112@news.neostrada.pl> <slrnqbuasg.28r5.wojciech.bancer@pl-test.org> <5cc00030$0$476$65785112@news.neostrada.pl> <slrnqc0o86.drp.wojciech.bancer@pl-test.org> <5cc08eba$0$523$65785112@news.neostrada.pl> <slrnqc1a43.2amm.wojciech.bancer@pl-test.org>Show Full Headers
Complete Article Headers
Path: mbox-mo1.pugleaf.net!news-archive.icm.edu.pl!news.icm.edu.pl!newsfeed.pionier.net.pl!goblin2!goblin1!goblin.stu.neva.ru!newsfeed.neostrada.pl!unt-exc-02.news.neostrada.pl!unt-spo-a-02.news.neostrada.pl!news.neostrada.pl.POSTED!not-for-mail Subject: Re: Symfony 4 - jak projektować bazę danych pod Doctrine? Newsgroups: pl.comp.lang.php References: <q9foak$p72$1@node2.news.atman.pl> <slrnqboo9s.e87.wojciech.bancer@pl-test.org> <5cbf10a8$0$482$65785112@news.neostrada.pl> <slrnqbuasg.28r5.wojciech.bancer@pl-test.org> <5cc00030$0$476$65785112@news.neostrada.pl> <slrnqc0o86.drp.wojciech.bancer@pl-test.org> <5cc08eba$0$523$65785112@news.neostrada.pl> <slrnqc1a43.2amm.wojciech.bancer@pl-test.org> From: Kviat Date: Thu, 25 Apr 2019 00:08:39 +0200 User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:60.0) Gecko/20100101 Thunderbird/60.6.1 MIME-Version: 1.0 In-Reply-To: <slrnqc1a43.2amm.wojciech.bancer@pl-test.org> Lines: 275 Message-ID: <5cc0de68$0$539$65785112@news.neostrada.pl> Organization: Telekomunikacja Polska NNTP-Posting-Host: 5.173.137.1 X-Trace: 1556143720 unt-rea-a-02.news.neostrada.pl 539 5.173.137.1:65184 X-Complaints-To: abuse@news.neostrada.pl Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit