2009-01-09 14 views
7

Jestem w trakcie prac nad systemem profilu użytkownika dla strony internetowej i zastanawiam się, jakie byłoby lepsze (skalowalne) podejście do podjęcia. Wymyśliłem dwa rozwiązania i szukam albo danych wejściowych, albo wskazówek do czegoś, co mogłem przegapić.Wybór metody przechowywania profili użytkowników?

Poniższe instrukcje tabel nie mają być wykonywane, ale służą jedynie do przedstawienia układu tabel.

Moją pierwszą myślą było coś takiego:

CREATE TABLE user(
    id INT UNSIGNED NOT NULL AUTO_INCREMENT, 

    user_email VARCHAR(320), 

    user_joined DATATIME, 
    user_last_seen DATATIME, 

    user_name_first VARCHAR, 
    user_name_last VARCHAR, 

    user_name_alias VARCHAR, 

    user_location_country VARCHAR, 
    user_location_region VARCHAR, 
    user_location_city VARCHAR 

    # ... 
); 

Oczywiście nie jest to w ogóle bardzo skalowalne i dodanie dodatkowych właściwości i denerwujące. Jedyną zaletą jest to, że mogę szybko wyszukać użytkowników pasujących do określonego zestawu właściwości. Zrobiłem trochę rozglądania się i to dość powszechne podejście (np. Wordpress).

Moje drugie podejście (jeden Jestem obecnie zabawy z) jest znacznie bardziej skalowalne, ale jestem trochę zaniepokojony wydajność:

CREATE TABLE user(
    id INT UNSIGNED NOT NULL AUTO_INCREMENT, 

    user_email VARCHAR(320) 
); 

CREATE TABLE user_profile(
    user_id INT UNSIGNED NOT NULL, 

    visibility ENUM('PRIVATE', 'PUBLIC'), 

    name VARCHAR, 
    value VARCHAR 
); 

Stosując to podejście ma zastosowanie każdego zestawu wartości klucza powiązane z nim pary, co sprawia, że ​​dodawanie dodatkowych właściwości jest banalne, a także ładowanie profilu użytkowników podczas logowania. Jednak tracę wszystkie informacje o typie, które miałem w pierwszym podejściu (np. DATETIME jest teraz zapisany jako sformatowany ciąg), więc niektóre wyszukiwania stają się denerwujące. To daje mi większą kontrolę nad wyborem właściwości, które użytkownik chce publicznie wyświetlić.

Czy podejście hybrydyczne byłoby lepsze, pozwalając zrównoważyć zalety i wady obu metod? Jaką metodę stosuje SO? Czy istnieje inne podejście do tego, o czym nie pomyślałem ani co przegapiłem?

Rozszerzenie: Z hybrydowego podejścia byłoby korzystne także wstawić właściwości z tabeli użytkownika do tabeli user_profile kontrolować ich widoczność dla innych użytkowników czy to może ewentualnie być postrzegane jako dodatkowe obciążenie?

Odpowiedz

3

Rozwiązanie hybrydowe nie jest dobre. Zasadniczo przechowujesz dodatkowe właściwości w tabeli worka własności. To sprawi, że raportowanie i zapytania będą skomplikowane w dłuższej perspektywie. Również przechowywanie dat, int, dziesiętnych, ntext itp. Jako varchar nie będzie akceptowalną wymianą wydajności dla skalowalności. Jak utworzyć relacje z tego stołu, jeśli zajdzie taka potrzeba?

Lepszym rozwiązaniem jest posiadanie tabeli użytkowników dla informacji o użytkowniku.Następnie, gdy Twoje potrzeby zostaną rozwinięte, utwórz nowe klasy reprezentujące nowe funkcje. Te nowe klasy będą prawdopodobnie miały odpowiednie tabele. W ten sposób twoja klasa "użytkownika" nie eksponuje się wykładniczo, gdy właściwości powiązane z użytkownikiem należą do ich własnej przestrzeni. Tak, w przyszłości naprawdę możesz mieć nową właściwość, która należy do tabeli użytkowników. W tym momencie będziesz musiał wrócić i dostosować swój schemat i DBAL, ale to jest cena kodu, który jest łatwy do zrozumienia.

W twoim przykładzie masz informacje adresowe dla użytkownika w pierwszej tabeli użytkowników. Jedną z rzeczy, którą robię, jest to, że muszę przechowywać adresy nie tylko dla użytkowników. Tak więc będę miał oddzielną tabelę adresów, a następnie włączam zerowy identyfikator adresu w tabeli użytkownika. W ten sposób, gdy mam tabelę Sklepy, tabelę zdarzeń, mogę tam również wstawiać relacje AddressId. Efektem ubocznym tego podejścia jest to, że po powrocie i dodaniu lat/long do obiektu Adres, wszyscy w moim modelu danych otrzymują te nowe właściwości.

+0

Wydaje mi się, że (i popraw mnie, jeśli się mylę), że to podejście będzie z czasem podlegało "rozrostowi stołu" z wieloma tabelami dodawanymi do bazy danych w celu dodania innej funkcjonalności? –

+0

Nie jestem pewien, czy nadmiar tabeli jest naprawdę problemem. Jeśli masz aplikację zawierającą 1000 punktów charakterystycznych, ale tylko 5 tabel, będę bardzo sceptycznie nastawiony do normalizacji tabel. Martin Fowler omawia tutaj schemat projektowania modułu tabeli: http://martinfowler.com/eaaCatalog/tableModule.html – DavGarcia

4

Użyłbym podejścia hybrydowego. Niektóre podstawowe właściwości, takie jak nazwa użytkownika, adres e-mail, data ostatniego logowania itp., Powinny zostać dodane do tabeli użytkowników. Elementy o drugorzędnym znaczeniu można dodać jako pary klucz/wartość.

W ten sposób można nadal łatwo wyszukiwać najważniejsze informacje i dodawać elementy profilu bez zmian schematu.

0

Poszedłbym też z rozwiązaniem hybrydowym, ze względu na wydajność i skalowalność projektu.

Mam wrażenie, że tabele takie jak (lubię również w liczbie mnogiej w nazwach tabel) muszą zostać podzielone na podstawowy zestaw danych, na które zwykle działają inne obiekty, i te rozszerzone bity danych zasadniczo tylko do zapisu w Specs jak "region", "middleinitial", "shoeize" może zostać przeniesiony do rozszerzalnego i rzadziej aktualizowanego obszaru.

0

Dlaczego nie ma pola XML do przechowywania dodatkowych informacji, które nie są niezbędne.

Można to skonfigurować w pliku konfiguracyjnym, a nawet posunąć o krok dalej i wygenerować elementy sterujące interfejsu użytkownika z konfiguracji.

+0

XML jest niewłaściwym narzędziem do tego, prowadziłoby to do niewiarygodnie absurdalnych zapytań, gdybym potrzebował zrobić coś z tymi nieistotnymi informacjami. Musiałbym przeanalizować XML dla każdego wyniku, zanim mógłbym zrobić wszystko, co zabiłoby wydajność. –

+0

Firma Microsoft stosuje takie samo podejście do swojego dostawcy członkostwa. Spójrz na to. Istnieją również podobne rozwiązania dostawcy, jak wyjaśniono powyżej. Prawdopodobnie masz rację co do wydajności, więc zaleca się przechowywanie wyłącznie informacji w pliku XML, którego nie chcesz przesyłać. –

Powiązane problemy