Upload
proidea
View
177
Download
2
Embed Size (px)
Citation preview
Baza danych w aplikacji typu SaaS -błędy w projektowaniu
Agenda
• SaaS?
• Jak to sie zaczeło? Java + Postgres
• Wprowadzamy Oracle
• Klienci w wielu językach
• Wyszukiwarka K2
• Raporty
SaaS co to jest?
• Czy to jest tylko aplikacja w Internecie?
• Jakie są główne cechy SaaS?
• Czy portal to już SaaS?
• Systemy pocztowe?
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
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
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
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
ORACLE
• Jest komercyjny
• Wszyscy wiedzą że jest najlepszy
• Support 24/7
• Najbardziej wydajna baza danych
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
Dlaczego to będzie sukces?
• Zatrudnimy konsultantów
• Kupujemy duuuży serwer
• Dużo ramu
• Reforma infrastruktury
• Zrobimy podmiane POSTGRES ORACLE
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
Błędy w kolejnych fazach rozwoju
• Dodając nowe klasy w Javie – dodajemy nowe tabele i kolumny
• Baza staje się śmietnikiem zduplikowanychdanych
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
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
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),
);
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
);
Dylemat gdzie ja trzymać?
• GLOBALSCHEMA – dodawanie nazw specyficznych dla użytkownika skomplikuje zapytania
• SCHEMAT klienta – będzie dużo duplikatów
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
SQL
SELECT...NVL(t.name, l.label) UI_NAME...
FROM...LEFT JOIN LABELS LON L.NLVID = T.NLVID
...WHERE
L.LANG = UK
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
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
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
Obieg dokumentów
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
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
Zasilanie K2
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
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
If ........ {
k2call
} else if (.... ) {
sql = Select name,
FROM trainings
WHERE
contains(describe, ......) > 0
}
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
Raporty
• Dane muszą być ONLINE
• Raporty definiowane przez użytkowników
• Dowolne agregaty
• Raporty wyklikiwane – NIE SQL!!!!
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
Tłumaczenia w raportachSELECT
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
.....
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
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;
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.ndocumentidAND 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 gfanON gfan.nassignedquestionid = gfaq.nassignedquestionidAND gfan.ndocumentid = gfd.ndocumentid;
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
Kwerenda
View
Function
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ą