Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.

4Developers 2015: Baza danych w aplikacji typu SaaS - błędy w projektowaniu - Jacek Jagieła

291 views

Published on

Jacek Jagieła

Language: Polish

Każda aplikacja potrzebuje przechowywać dane, potrzebuje łatwego i szybkiego do nich dostępu. Rozwój aplikacji stawia nowe wyzwania przed baza danych, coraz więcej rzeczy potrzebujemy zapisać i odczytać. Klienci oczekuja szybkiego wyszukiwania, które będzie dawać "dobre" odpowiedzi. Dalsza ekspansja działu marketingu powoduje wprowadzenie obsługi wielu języków. Każdy klient potrzebuje raportów i agregat do właściwych wniosków w obsługiwanej przez nasz SaaS firmie. Architekt wybrał silnik bazy, który uchodzi za niezniszczalny - udźwignie wszystko zawsze i wszędzie. Czy jedna baza danych wystarczy? W którym momencie nastapi katastrofa - jak jej uniknać i jak się z niej podnieść. Zapoznamy się z wykorzystaniem baz danych w projekcie SaaS - od niewielkiej funkcjonalności - do aplikacji działajacej na wszystkich kontynentach w kilkunastu językach. Zobaczymy o czym nie wolno zapomnieć projektujac bazę danych. Czy SaaS dotyczy tylko klienta i jego oczekiwań? A może pojęcie SaaS powinno nam towrzyszyć na każdym etapie projektowania aplikacji?

Published in: Software
  • Be the first to comment

4Developers 2015: Baza danych w aplikacji typu SaaS - błędy w projektowaniu - Jacek Jagieła

  1. 1. Baza danych w aplikacji typu SaaS - błędy w projektowaniu jacek.jagiela@gmail.com
  2. 2. Agenda • SaaS? • Jak to sie zaczeło? Java + Postgres • Wprowadzamy Oracle • Klienci w wielu językach • Wyszukiwarka K2 • Raporty
  3. 3. SaaS co to jest? • Czy to jest tylko aplikacja w Internecie? • Jakie są główne cechy SaaS? • Czy portal to już SaaS? • Systemy pocztowe?
  4. 4. SaaS • Architektura zorientowana na usługi • Realizuje określoną funkcjonalność • Wysoka dostępność • Prosta konfiguracja • Bezpieczeństwo danych • Izolacja użytkowników • Personalizacja • Infrastruktura servera jest nieistotna dla użytkownika • Łatwa automatyczna aktualizacja • Wszyscy korzystają z tej samej wersji
  5. 5. Początek • Mamy aplikację napisaną w Javie • Oferujemy szkolenia w sieci • Platforma dla nauczycieli • Platforma dla uczniów • Udostępniamy szkolenia • Można się dzielić rozwiązaniami • Strony wyświetlana przez jsp
  6. 6. Baza danych • Schemat per klient • Dodatkowy schemat globalny określający uprawnienia, konfiguracje schematów klientów, sposób logowania się do aplikacji, konfiguracja usług zewnętrznych typu FTP, EMAIL => GLOBALSCHEMA
  7. 7. Wzrost aktywności • Pierwsze problemy z wydajnością • Klienci przestają być zadowoleni • Nie znamy zachowań klientów • Brak predykcji dotyczącej wykorzystania naszej aplikacji • Decyzja Kupujemy Oracle
  8. 8. ORACLE • Jest komercyjny • Wszyscy wiedzą że jest najlepszy • Support 24/7 • Najbardziej wydajna baza danych
  9. 9. ORACLE – błędny wybór? • Nie wiemy co jest nie tak z Postgresem • Nie znamy statystyk z działania naszego systemu • Co jest źródlem problemów? • Gdzie jest wąskie gardło? • Ilu klientów możemy maksymalnie obsłużyć na tym co mamy? • Jaki jest Design/Model naszej bazy danych? • Decyzja o zmianie silnika nie może być podyktowana tylko narzekaniem klientow
  10. 10. Dlaczego to będzie sukces? • Zatrudnimy konsultantów • Kupujemy duuuży serwer • Dużo ramu • Reforma infrastruktury • Zrobimy podmiane POSTGRES  ORACLE
  11. 11. Wdrożenie nowej bazy • Tworzymy nowe tabele zgodnie ze schematem w Postgresie • Zmieniamy procedury • Wielu developerów Javy - mało czasu • Architekci od Javy • Procedury PL/SQL pisane jak w Javie • Java jest OK wydajna – to baza spowalnia wszystko • Wdrożenie Oracle uratuje naszą pozycję na rynku • Dobry marketing – mamy Oracle
  12. 12. Błędy w kolejnych fazach rozwoju • Dodając nowe klasy w Javie – dodajemy nowe tabele i kolumny • Baza staje się śmietnikiem zduplikowanych danych
  13. 13. Języki • Nasza aplikacja wychodzi na świat • Chcemy aby każdy czytał w swoim języku • Wdrażając obsługę języków mamy 20 klientów • Strategia – klient to jeden schemat – jak wdrożyć języki • Mamy moduł rozszerzający formatki i formularze • Chcemy aby klient mógł definiować swoje określenia
  14. 14. Architektura Języków • Wprowadzamy Listę Wartości LV • Zdefiniowaliśmy na początek 120 000 określeń wymagających tłumaczeń • Mamy ORACLE – wrzucimy to w tabele • Tworzymy tabele LV, LABELS
  15. 15. CREATE TABLE LV ( "NLVID" NUMBER(10,0) NOT NULL ENABLE, "NKEYNAMEID" NUMBER(10,0), "LVNAME" VARCHAR2(120 BYTE) NOT NULL ENABLE, "DISABLED" NUMBER(1,0) DEFAULT 0, "DUPDATEDATE" DATE, "UPDATEUSERID" NUMBER(10,0), "CREATIONUSERID" NUMBER(10,0), );
  16. 16. CREATE TABLE LABELS ( "NKEYNAMEID" NUMBER(10,0) NOT NULL, "NLVID" NUMBER(10,0) NOT NULL, "SLANGUAGE" VARCHAR2(4 BYTE) DEFAULT 'EN', "SLABEL" VARCHAR2(510 BYTE) NOT NULL, "SUPPERLABEL" VARCHAR2(510 BYTE) NOT NULL );
  17. 17. Dylemat gdzie ja trzymać? • GLOBALSCHEMA – dodawanie nazw specyficznych dla użytkownika skomplikuje zapytania • SCHEMAT klienta – będzie dużo duplikatów
  18. 18. PERFORMANCE ponad wszystko • Dodajemy do schematu użytkownika • Przy 20 klientach: – 120 000 x 20 = 2 400 000 rekordów – 10 – 15% nazwy zdefiniowane przez użytkownika – Zamiast 100 000 identycznych nazw mamy 2 000 000 z duplikatami
  19. 19. SQL SELECT ... NVL(t.name, l.label) UI_NAME ... FROM ... LEFT JOIN LABELS L ON L.NLVID = T.NLVID ... WHERE L.LANG = UK
  20. 20. Po roku lub dwóch • Wzrost klientów do 400 • LABELS/klient 140 000 • 140 000 x 400 = 56 000 000 • 40 000 000 duplikatów • Za dużo danych w różnych tabelach i schematach – nie mieści się w CACHE
  21. 21. Jak przetrwać • Baza danych zawsze powinna zwracać w języku domyślnym • Tłumaczenia powinny być „Usługą”. • To część UI – jedna z jego warstw • LABELS mogą być przechowywane w tabeli w bazie operacyjnej • Obsługa powinna być w pamięci
  22. 22. Wyszukiwarka • Nasz SaaS – portal szkoleniowy • Integruje nauczycieli różnych dziedzin • Pozwala wymieniać informacje między uczniami • Abonament dla uczniów • Nie udostępniamy wszystkich danych na zewnątrz • Chcemy mieć wszystkie dane ONLINE • GOOGLE nie ma wstępu
  23. 23. Obieg dokumentów
  24. 24. Wybieramy K2 • Server K2 – indekser + prezenter danych • Broker K2 – zarządza serwerami K2 • Zasilanie K2 – XML files • Użycie K2 – komunikacja z Brokerem na porcie TCP
  25. 25. Co potrzebne do użycia K2 • Serwer (farma serverów) z K2 • Globalna wyszukiwarka dla wszystkich • Jedna kolejka zasilania K2 • Zasilamy danymi z bazy • Kolejka – tabela w bazie danych
  26. 26. Zasilanie K2
  27. 27. Problemy • Kolejne obciążenie bazy danych nie zdefiniowane jako usługa • Jedna tabela tworzy kolejkę – to rośnie w nieskończoność • Złamanie założenia dostępności Online • K2 źle wyszukuje kontekstowo • Szybkie wyszukiwanie zwraca złe wyniki
  28. 28. Rozszerzamy wyszukiwanie • Nasz przyjaciel Oracle ma wyszukiwanie kontekstowe – Domain Index • Wprowadzimy dwie formatki: – Quick search – oracle – Advance search – K2 • W aplikacji zdecydujemy z czego będziemy korzystać w zależności od kontekstu użytkownika
  29. 29. If ........ { k2call } else if (.... ) { sql = Select name, FROM trainings WHERE contains(describe, ......) > 0 }
  30. 30. Błędy • Wszystko ONLINE!! • Jeśli coś jest w bazie operacyjnej to powinno być dostępne • Brak Design wyszukiwarki • Rozproszenie wyszukiwania w wielu miejscach • Brak MOM
  31. 31. Raporty • Dane muszą być ONLINE • Raporty definiowane przez użytkowników • Dowolne agregaty • Raporty wyklikiwane – NIE SQL!!!!
  32. 32. Wprowadzamy Typy Raportów • Sztywna lista pól • Określamy zbiór tabel dla każdego typu • Sztywne powiązania (JOIN) • Agregaty zdefiniowane przez programistów • Warunki wynikajace z uprawnień w systemie • Warunki wprowadzane przez użytkowników
  33. 33. Tłumaczenia w raportach SELECT FIRST_NAME, (SELECT NVL(H_LB.SLABEL,H_L.SLOVVALUE) FROM LOV H_L, LABELS H_LB WHERE H_L.NKEYNAMEID=H_LB.NKEYNAMEID(+) AND H_LB.SLANGUAGE(+)='UK' AND H_L.NLOVID=JLO1.NLOVID) AS JLO1_NLOVID_6971, (SELECT NVL(H_LB.SLABEL,H_K.SKEYNAME) FROM KEYNAMES H_K, LABELS H_LB WHERE H_K.NKEYNAMEID=H_LB.NKEYNAMEID(+) AND H_LB.SLANGUAGE(+)='UK' AND H_K.NKEYNAMEID=ST1.NKEYNAMEID) AS ST1_NKEYNAMEID, (SELECT NVL(H_LB.SLABEL,H_K.SKEYNAME) FROM KEYNAMES H_K, LABELS H_LB WHERE H_K.NKEYNAMEID=H_LB.NKEYNAMEID(+) AND H_LB.SLANGUAGE(+)='UK' AND H_K.NKEYNAMEID=ST2.NKEYNAMEID) AS ST2_NKEYNAMEID, (SELECT NVL(H_LB.SLABEL,H_K.SKEYNAME) FROM KEYNAMES H_K, LABELS H_LB WHERE H_K.NKEYNAMEID=H_LB.NKEYNAMEID(+) AND H_LB.SLANGUAGE(+)='UK' AND H_K.NKEYNAMEID=ST3.NKEYNAMEID) AS ST3_NKEYNAMEID, (SELECT NVL(H_LB.SLABEL,H_K.SKEYNAME) FROM KEYNAMES H_K, LABELS H_LB WHERE H_K.NKEYNAMEID=H_LB.NKEYNAMEID(+) AND H_LB.SLANGUAGE(+)='UK' AND H_K.NKEYNAMEID=ST4.NKEYNAMEID) AS ST4_NKEYNAMEID .... FROM .....
  34. 34. Agregaty • Nie używamy funkcji analitycznych Oracle – ciężko je wyklikać • Piszemy własne funkcje analityczne • Duże ilości danych zbieramy w View • Klient może wiele razy odpowiadać na test w raportach interesuje nas tylko ostatnia odpowiedź • Kwerendy w raportach optymalizujemy pod raporty
  35. 35. create or replace FUNCTION AgregateF (nCustomerID in number, nquestionid in number) return varchar2 as v_STEXT VARCHAR2(4000); BEGIN SELECT SFREETEXT INTO v_STEXT FROM VIEW_F_MC TQF0 WHERE answerid = (SELECT MAX (answerid) FROM VIEW_F_MC WHERE questionid = nquestionid AND applicationid = nApplicationID) AND questionid = nquestionid AND applicationid = nApplicationID; return (v_SFREETEXT); END;
  36. 36. CREATE OR REPLACE VIEW "VIEW_F_MC" AS SELECT /*+ FIRST_ROWS */ doc.applicationid, gfd.ndocumentid, gfan.nanswerid, gfan.nquestionid, gfan.sfreetext, gfan.dDateAnswer FROM document doc INNER JOIN gf_document gfd ON doc.nobjectid = gfd.ndocumentid AND doc.vobjecttype = 'STRUCTURED' INNER JOIN gf_form gff ON gff.nformid = gfd.nformid INNER JOIN gf_assignedquestion gfaq ON gfaq.nformid = gff.nformid INNER JOIN gf_answer gfan ON gfan.nassignedquestionid = gfaq.nassignedquestionid AND gfan.ndocumentid = gfd.ndocumentid;
  37. 37. SELECT C1.LASTNAME AS C1_LASTNAME, C1.FIRSTNAME AS C1_FIRSTNAME, A1.CREATIONDATE AS A1_CREATIONDATE, F_AGGR_MC(A1.nApplicationId, 5, 459) AS A1_16683_26489_EXP, F_AGGR_MC(A1.nApplicationId, 5, 460) AS A1_16683_26490_EXP, F_AGGR_MC(A1.nApplicationId, 5, 461) AS A1_16683_26491_EXP, F_AGGR_MC(A1.nApplicationId, 5, 462) AS A1_16683_26492_EXP, F_AGGR_FT(A1.nApplicationId, 5) AS A1_5_414_16683_OTHER, ' ' AS A1_16683_TOTAL FROM APPLICATION A1, CANDIDATE C1, TRAININGSLIST DJJ1 WHERE A1.NCANDIDATEID=C1.NCANDIDATEID AND A1.NOPENINGID=DJJ1.NOPENINGID AND rownum < 64001 ORDER BY C1_SLASTNAME,A1_DCREATIONDATE
  38. 38. Kwerenda View Function
  39. 39. Wnioski • Baza danych w SaaS to usługa, która powinna być modelowana • Monitoring bazy od kwerend przez CPU, pamiec, Load • Predykcja wykorzystania przez klientów • Nie można mieć dobrej Bazy Operacyjnej i Bazy Raportowej w jednym silniku • Wyszukiwarka to też baza danych tylko wspierająca Bazę Operacyjną

×