Utrzymywać użytkownika i profil użytkownika w różnych tabelach?

26

Widziałem w kilku projektach, że programiści wolą przechowywać niezbędne informacje o użytkowniku w jednej tabeli (adres e-mail / login, hash hasła, nazwa ekranowa), a resztę nieistotnego profilu użytkownika w innej (data utworzenia, kraj itp.). Przez niepotrzebne rozumiem, że dane te są potrzebne tylko od czasu do czasu. Oczywistą korzyścią jest to, że jeśli używasz zapytań ORM, mniej pól jest oczywiście dobre. Ale wtedy możesz mieć dwa podmioty zmapowane do tej samej tabeli, co pozwoli ci uniknąć zapytań o rzeczy, których nie potrzebujesz (a jednocześnie będziesz wygodniejszy). Czy ktoś zna inną zaletę trzymania tych rzeczy w dwóch tabelach?

Andrey
źródło
1
@MichaelT dzięki! Ciekawe, że nie ma zgody na wszystkie powiązane pytania.
Andrey
Właśnie dlatego wybrałem listę powiązanych pytań zamiast samemu na nie odpowiadać. To naprawdę sprowadza się do poszczególnych przypadków i tego, jak tworzona jest konkretna aplikacja. Pamiętaj, że zawsze możesz użyć widoku, aby wyciągnąć dwa bity razem, jeśli to konieczne. Zastanów się również nad możliwością odłączenia jednego (usunięcie konta), ale zachowania drugiego (pytania muszą być powiązane z kontem, ale konto nie zawsze ma profil ...). Ciekawym pytaniem może być wrzucenie do czatu inżynierii oprogramowania lub udanie się do DBA.SE i poproszenie na czacie.
1
@MichaelT Zastanawiam się nad stworzeniem uogólnionego frameworku, który zapewni model użytkownika.
Andrey
W niektórych wcześniejszych projektach celowo przenosiłem kolumny, które miały być zapisywane bardzo często, do ich oddzielnych tabel w celu ochrony tabeli podstawowej na wypadek uszkodzenia lub uszkodzenia pliku bazy danych.
GrandmasterB

Odpowiedzi:

11

To zależy od wielkości i wymagań twojego projektu.

Widzę jeden sposób, w jaki dane o użytkownikach można podzielić na dwa zestawy o różnych celach, a tym samym wymaganiach:

  • Dane tożsamości: nazwa użytkownika, skrót hasła, adres e-mail, czas ostatniego logowania itp.
  • Dane profilu użytkownika, w tym preferencje użytkowników, ostatnia aktywność, aktualizacje statusu itp.

Należy pamiętać, że istnieją pewne atrybuty dotyczące użytkownika, które mogą należeć do dowolnej kategorii (np. Data urodzenia użytkownika). Różnica między tymi dwoma zestawami polega jednak na tym, że pierwszy jest ściśle kontrolowany i można go modyfikować tylko poprzez określone przepływy pracy. Na przykład zmiana hasła może wymagać podania istniejącego hasła, zmiana adresu e-mail może wymagać weryfikacji adresu e-mail i będzie to miało miejsce w przypadku, gdy użytkownik zapomni hasło.

Preferencje nie wymagają takich list ACL i mogą być teoretycznie modyfikowane przez użytkownika lub inną aplikację, o ile użytkownik wyrazi na to zgodę. Stawka jest niska, jeśli aplikacja złośliwie lub z powodu błędu uszkadza dane lub próbuje je zmodyfikować (zakładając, że zostaną podjęte inne środki bezpieczeństwa). Zazwyczaj byłoby to katastrofalne, gdyby nazwa użytkownika, hasło lub adres e-mail mogły zostać zmodyfikowane ponieważ można ich użyć do potwierdzenia tożsamości użytkownika lub odmowy usługi lub spowodowania kosztów wsparcia itp. dla administratora.

Dlatego zwykle dane są przechowywane w dwóch typach systemów:

  • Dane identyfikacyjne zwykle trafiają do katalogu lub rozwiązania IAM.
  • Dane preferencji znajdą się w bazie danych.

Powiedziawszy to, w praktyce ludzie będą naruszać te reguły i będą używać jednego lub drugiego (np. Serwer SQL za dostawcą członkostwa ASP.NET).

W miarę powiększania się danych tożsamości lub powiększania się organizacji, która je wykorzystuje, wkradają się różnego rodzaju problemy. Na przykład w przypadku katalogu podejmie próbę natychmiastowej replikacji zmian hasła na wszystkich serwerach w środowisku wieloserwerowym. Jednak preferencje użytkownika wymagają tylko ostatecznej spójności. (FYI: Oba są różnymi optymalizacjami twierdzenia CAPS.)

Wreszcie, katalogi (zwłaszcza katalogi online / w chmurze) będą również wydawać tokeny dostępu do innych zasobów przy użyciu protokołów takich jak OAUTH (np. Rozważ Facebook, Google, konto Microsoft, ADFS), podczas gdy baza danych nie ma takiej potrzeby. Baza danych będzie obsługiwać dość złożone sprzężenia i strukturę zapytań, których katalog nie potrzebuje.

Aby uzyskać więcej informacji, pomogłoby kilka wyszukiwań katalogu tożsamości vs bazy danych.

Ostatecznie sprowadza się to do tego, jakie są twoje scenariusze i jakie będą w przyszłości, w tym do integracji ze stronami trzecimi (i tego, z czego korzystają). Jeśli jest to dobrze zamknięty projekt i masz pewność, że możesz zabezpieczyć dane tożsamości użytkownika i poprawnie się uwierzytelnić, możesz wybrać bazę danych. W przeciwnym razie warto sprawdzić katalog tożsamości.

Jeśli wybierzesz DB, IMO, użycie jednego DB kontra dwa ostatecznie sprowadzi się do kontroli dostępu, zarówno dla użytkowników, jak i aplikacji.

Omer Iqbal
źródło
3

Istnieją co najmniej trzy przypadki, gdy potrzebna jest tabela osób dla podstawowych atrybutów i pożądana jest druga tabela dla innych atrybutów z relacją jeden do jednego:

  • Dane BLOB jak obraz. Oddzielna tabela pozwala na osobne przechowywanie danych ze względu na wydajność, na przykład w osobnym obszarze tabel.
  • Dane, które nie dotyczą wszystkich lub dotyczą tylko osoby odgrywającej określoną rolę. Pomyśl o tym jak o kolumnach, które byłyby puste w wielu wierszach, gdyby były częścią głównej tabeli. W bazie danych kliniki możesz mieć tabelę osobową, tabelę pacjenta i tabelę medyczną, w pierwszej miałbyś podstawowe atrybuty, w drugiej tylko atrybuty istotne, gdy dana osoba jest jak ubezpieczenie, w trzecia tabela (gdy dana osoba jest medykiem), możesz mieć specjalizację medyczną i inne dane, które dotyczą tylko personelu medycznego. Oczywiście medyk może być pacjentem.
  • Tabela, która materializuje relację z bytem w zdalnym systemie. W takim przypadku tabela ustanawia równoważność unikalnych identyfikatorów w oddzielnej bazie danych ze względu na interoperacyjność.

Myślę, że sprawa, którą wystawiasz, pasuje do drugiej sprawy.

Tulains Córdova
źródło
1

Moim głównym powodem, aby je rozdzielić, jest unikanie tego, co znane jest w programowaniu obiektowym jako „klasa boga”. ORM wiąże tabele i pola z klasami i atrybutami, więc staje się to istotne również jako poziom SQL (nawet bez ORM istnieje ogólnie podobna zasada).

Klasa użytkownika (i przez skojarzenie tabeli użytkowników) jest często tabelą, która staje się klasą bogów z setkami atrybutów / pól, dziesiątkami lub setkami metod i definicją klasy (dla metod) ponad 1000 linii. Widziałem to wszystko. Więcej niż raz.

Tak więc separacja użytkowników próbuje rozwiązać ten problem. Może istnieć osoba, użytkownik, konto, a rozdzielenie obaw może wydawać się nieco sztuczne, ale ma to na celu uniknięcie złożoności i upewnienie się, że każdy obiekt dotyczy tylko jednego aspektu danych.

Michael Durrant
źródło
2
Nawet rozdęta klasa użytkownika wciąż niekoniecznie jest klasą boską. Może się rozdęć logiką związaną z użytkownikiem (co może skomplikować się w dużych projektach), ale jeśli nie zawiera logiki niepowiązanej, nie widzę dużego problemu. Nie jestem pewien, jak rozbicie 1 klasy na 2 rozwiąże wspomniany problem z klasą bożą.
Andrey