Gotcha z shardingiem polega na tym, że aplikacja musi wiedzieć, który fragment ma zostać wysłany. Zasadniczo odbywa się to poprzez dzielenie na coś takiego jak klient. Dostosuję jeden z moich starych postów na blogu, aby używał go jako mojej odpowiedzi.
Podczas budowania aplikacji dla wielu klientów istnieją dwa typowe sposoby projektowania baz danych:
- Opcja A: Umieść wszystkich klientów w tej samej bazie danych
- Opcja 2: zbuduj jedną bazę danych na klienta
Umieszczenie wszystkich klientów w tej samej bazie danych
To proste: wystarczy dodać tabelę klienta u góry schematu, dodać tabelę ClientUsers, aby upewnić się, że ludzie widzą tylko własne dane, i gotowe.
Korzyści z tego podejścia:
Łatwiejsze zarządzanie schematem. Gdy programiści wdrażają nową wersję aplikacji, muszą wprowadzać zmiany schematu tylko w jednej bazie danych. Nie ma obaw, że różni klienci nie będą zsynchronizowani lub będą mieli niewłaściwą wersję.
Łatwiejsze dostrajanie wydajności. Możemy sprawdzić wykorzystanie indeksu i statystyki w jednym miejscu, łatwo wdrożyć ulepszenia i natychmiast zobaczyć efekty u wszystkich naszych klientów. W przypadku setek lub tysięcy baz danych koordynacja nawet najmniejszej zmiany może być trudna. Możemy sprawdzać zawartość naszej pamięci podręcznej procedur i mieć pewność, które zapytania lub procedury przechowywane są najbardziej intensywne w całej naszej aplikacji, natomiast jeśli używamy oddzielnych baz danych dla klienta, możemy mieć trudniejsze agregowanie zapytań w różnych planach wykonania.
Łatwiej zbudować zewnętrzny interfejs API. Jeśli musimy przyznać dostęp do całej naszej bazy danych osobom postronnym w celu tworzenia produktów, możemy to zrobić łatwiej, jeśli wszystkie dane znajdują się w jednej bazie danych. Jeśli interfejs API ma do czynienia z grupowaniem danych z wielu baz danych na wielu serwerach, wydłuża czas programowania i testowania. (Z drugiej strony to, że „wiele serwerów” zaczyna wskazywać na ograniczenie scenariusza „jedna baza danych do rządzenia nimi wszystkimi”: jedna baza danych zwykle oznacza, że całe nasze obciążenie wpływa tylko na jeden serwer bazy danych.) W twoim przypadku , dzięki PowerBI, posiadanie wszystkich w jednej bazie danych znacznie ułatwi zarządzanie połączeniami.
Łatwiejsza wysoka dostępność i odzyskiwanie po awarii. Naprawdę bardzo proste jest zarządzanie kopią lustrzaną bazy danych, wysyłaniem dzienników, replikacją i klastrowaniem, jeśli wszystko, o co musimy się martwić, to tylko jedna baza danych. Możemy szybko zbudować infrastrukturę.
Umieszczenie każdego klienta we własnej bazie danych lub odłamku
Nadal potrzebujesz listy klientów, ale teraz staje się ona katalogiem - dla każdego klienta śledzisz również fragment, w którym on żyje. Po uruchomieniu aplikacja wysyła zapytanie do tej tabeli i buforuje ją w pamięci RAM. Gdy potrzebuje danych dla klienta, łączy się bezpośrednio z tym fragmentem (baza danych i serwer).
Korzyści z tego podejścia:
Łatwiejsze przywracanie pojedynczego klienta. Klientami są niewiarygodne worki mięsne. (Z wyjątkiem moich - są niezawodnymi workami z mięsem). Mają wszelkiego rodzaju „ups” momenty, w których chcą odzyskać wszystkie swoje dane z powrotem do punktu w czasie, a to jest ogromny ból z tyłu, jeśli ich dane są pomieszane inne dane klienta w tych samych tabelach. Przywracanie w scenariuszu z pojedynczą bazą danych klienta jest wyjątkowo proste: wystarczy przywrócić bazę danych klienta. Nie dotyczy to nikogo innego.
Łatwiejszy eksport danych. Klienci uwielbiają dostawać swoje dane. Chcą bezpieczeństwa, wiedząc, że mogą wydostać swoje dane w dowolnym momencie, unikając przerażającego scenariusza blokowania dostawcy i chcą tworzyć własne raporty. Po odizolowaniu danych każdego klienta w jego własnej bazie danych, możemy po prostu dać mu kopię własnej kopii zapasowej bazy danych. Nie musimy budować interfejsów API eksportu danych.
Łatwiejsza skalowalność wielu serwerów. Gdy nasza aplikacja potrzebuje więcej mocy, niż możemy uzyskać z jednego serwera, możemy podzielić bazy danych na wiele serwerów. Możemy również rozłożyć obciążenie geograficznie, dzięki czemu serwery w Azji lub Europie będą bliżej klientów.
Łatwiejsze dostrajanie wydajności dla poszczególnych klientów. Jeśli niektórzy klienci używają różnych funkcji lub raportów, możemy zbudować wyspecjalizowany zestaw indeksów lub indeksowanych widoków tylko dla tych klientów bez zwiększania wielkości danych wszystkich osób. To prawda, że istnieje tu pewne ryzyko - ze względu na różnice w schematach między klientami sprawiliśmy, że wdrażanie kodu jest nieco bardziej ryzykowne, a zarządzanie wydajnością trudniejsze.
Łatwiejsze zarządzanie bezpieczeństwem. Tak długo, jak prawidłowo zablokowaliśmy bezpieczeństwo dla jednego użytkownika na bazę danych, nie musimy się martwić, że Klient X uzyska dostęp do danych klienta Y. Jeśli jednak użyjemy tylko jednego loginu dla wszystkich, to tak naprawdę nie rozwiązaliśmy tego problemu.
Łatwiejsze utrzymanie okien. W globalnym środowisku, w którym klienci są rozproszeni po całym świecie, łatwiej jest przenieść klientów offline w celu konserwacji, jeśli możemy to zrobić w grupach lub strefach.
Który do ciebie pasuje?
Nie ma jednego właściwego wyboru: musisz poznać mocne i słabe strony swojej firmy. Weźmy za przykład dwóch moich klientów.
Firma A specjalizuje się w dostrajaniu wydajności sprzętu. Są naprawdę, bardzo dobrzy w wyciskaniu ostatniej wydajności sprzętu i nie mają nic przeciwko wymianie sprzętu SQL Server w cyklu 12-18 miesięcy. (Odświeżają serwery internetowe co 4-6 miesięcy!) Ich piętą achillesową są ekstremalne wymagania dotyczące zgodności i bezpieczeństwa. Mają niewiarygodne potrzeby kontrolne, a im łatwiej jest wdrożyć kuloodporne kontrole na jednym serwerze, jednej bazie danych, niż zarządzać tymi wymaganiami w tysiącach baz danych na dziesiątkach serwerów. Wybrali jedną bazę danych, jeden serwer, wielu klientów.
Firma 2 przoduje w praktykach programistycznych. Zarządzanie zmianami schematu i wdrażaniem kodu w tysiącach baz danych po prostu nie stanowi dla nich problemu. Mają klientów na całym świecie i przetwarzają transakcje kartą kredytową dla tych klientów przez całą dobę. Potrzebują zdolności do geograficznego rozkładania obciążenia i nie chcą wymieniać serwerów na całym świecie co 12-18 miesięcy. Wybrali jedną bazę danych dla każdego klienta, a to się opłaca, gdy zaczynają umieszczać serwery SQL w Azji i Europie dla swoich zagranicznych klientów.
Jeszcze jedna uwaga, której jeszcze nie widziałem w innych odpowiedziach.
Posiadanie projektu, który pozwala wielu najemcom w jednej bazie danych, zapewni elastyczność później. Jeśli ładowanie / skalowanie w górę / zabezpieczenia / lokalizacja geograficzna będą później sugerować, że najemca powinien mieć oddzielną bazę danych, można ją utworzyć, przywracając poprawną bazę danych w nowej instancji. Dane pozostałych najemców są nadal chronione przez istniejące mechanizmy. Teraz przestarzałe dane można usuwać fragmentarycznie ze starych i nowych baz danych w miarę upływu czasu.
Odwrotna sytuacja nie jest prawdą. Konsolidacja wielu baz danych dla jednego dzierżawcy będzie wymagać znacznie więcej pracy.
źródło
Jedną z praktyk, która sprawia, że modele z wieloma dzierżawcami są znacznie łatwiejsze, nawet jeśli psuje normalizację *, jest umieszczenie kolumny dla każdego najemcy. Możesz to nazwać TenantID. W ten sposób każde zapytanie uruchomione w bazie danych może filtrować według TenantID w każdej tabeli, a partycjonowanie bazy danych umożliwia izolowanie danych dla każdego dzierżawcy i przyspieszenie zapytań dzięki dopasowanym partycjom. Znacznie łatwiej jest mieć w ten sposób wszystkich najemców w jednej bazie danych.
* Nie zawsze łamie normalizację, ale może. Na przykład, jeśli masz
Person
i doPersonAddress
stołu.Person
Stół będzie miałTenantID, PersonID
jako klucz podstawowy.PersonAddress
Stół będzie miałTenantID, PersonID, AddressTypeID
jako klucz podstawowy z tym, co ja sugeruję.Normalnie
PersonID
wystarczyłoby, ponieważ możesz dołączyć to z powrotem doPerson
stołu, aby znaleźćTenant
. Sugeruję, abyś przeniósłTenantID
się do każdego kolejnego stołu, nawet jeśli cieńszy klucz będzie działał.Rozumiałem, że przekazanie jakichkolwiek informacji do tabeli, które można by uzyskać z innych danych, uznano za przełamanie normalizacji. Ale być może używanie cienkich klawiszy jest po prostu najlepszą praktyką.
źródło