Niektóre myśli, jeśli niekoniecznie odpowiedź:
Wyraźnie dziennik zmian jest must-have dla ciebie, więc oryginalna konstrukcja z pojedynczym rzędzie dla każdego użytkownika nie jest rozwiązaniem dla Ciebie. Więc mówimy o wyborze pomiędzy:
- Pojedynczy wiersz dla każdej wersji zestawu danych każdego użytkownika; lub
- Pojedynczy wiersz za wersją item każdego użytkownika informacji
Rozwiązanie 1 odpowiada Twoim
userLog (id INT, date TIMESTAMP, email VARCHAR, phone VARCHAR, address VARCHAR)
Rozwiązanie 2 odpowiada Wordpress jednym:
umeta_id INT, user_id INT, meta_key VARCHAR, meta_value VARCHAR
Twoje pytanie 1: Nie widzę żadnej korzyści dla rozwiązania 2, z wyjątkiem tego, jeśli później zdecydujesz, że chcesz o przechwyć użytkowników (na przykład) URL witryny lub (na przykład) ulubiony kolor, możesz to zrobić, dodając meta_key. Ale równie łatwo można to zrobić w ramach rozwiązania 1, wykonując po prostu czynność To nie jest trudne. Chyba że DBA w twoim sklepie są wyjątkowo dobermannowe (;)). Ponieważ przechowujesz dziennik zmian, wszyscy istniejący użytkownicy (w momencie zmiany) będą teraz mieli pustą kolumnę WebsiteURL; ale to jest dokładnie to, czego potrzebujesz: nie znasz ich adresu URL, ponieważ system nie przechwycił go wcześniej. Oczywiście, nowa kolumna będzie musiała być NIESTABILNA - ale i tak może być nieunikniona, nawet z "początkowymi" danymi, chyba że metoda, której używasz do przechwytywania informacji o użytkownikach, nalega na e-mail, telefon i adres jako wymagane kolumny.
Dla mnie wady rozwiązania meta_key przewyższają zalety. Wadami są:
Trzeba rozwijać kawałek kodu przegubu do obracania informacji o użytkowniku dla jednego użytkownika na jednym
rzędu. Musisz wywoływać ten kod w każdym miejscu, w którym chcesz uzyskać informacje o użytkowniku w jednym wierszu. W Natomiast Porada1 wymaga jedynie
SELECT USERID [wszystkie Informacja o użytkowniku] Z userLog INNER JOIN (SELECT MAX (USERID datechanged) AS LatestDAteChanged OD userlog GROUP BY identyfikator użytkownika) A na userlog.userid = a.userID I userlog .DateChanged = a.LatestDAteChanged
, która jest znacznie wydajniejsza niż oś obrotu. Z indeksem na UserID, DateChanged, to będzie działać jak wiatr.
Jeśli naprawdę nie chcesz przechowywać wartości meta_key wiele razy w tabeli informacji o użytkowniku (e-mail, e-mail, e-mail, e-mail, e-mail), potrzebna jest dodatkowa tabela Meta_Key_Lookup.
Drugie pytanie: Dla ostatecznego czasoprzestrzeni wydajności, tak, meta_key Solution2 jest najlepszy. Zwłaszcza, jeśli nie używasz metakeys VARCHAR, ale wartości metakey ID i masz osobną tablicę meta_key lookup (np. 1 = Email, 2 = Telefon itd.). Ale nie sądzę, że jest to rozstrzygający argument dla meta_key Solution2, biorąc pod uwagę praktycznie zerową cenę pamięci i trudności związane z tym rozwiązaniem.
(Uwaga/zamysł: IMHO Twój pomysł na zachowanie wartości NULL w twoim rozwiązaniu1, gdzie wartość się nie zmieniła, to zła droga. Kodowanie, aby spróbować uzyskać najnowszą wiadomość e-mail, następnie telefon, a następnie adres (osobno) dla każdego użytkownika, będzie koszmarem: prawie tak trudnym do zakodowania/przetestowania - i do uruchomienia serwera - jako osią obrotową wymaganą przez inne rozwiązanie, a zmniejszenie pamięci marginalnej. Wystarczy przytrzymać cały rząd za każdym razem, gdy Jeśli nie podasz przykładów, a prawdziwy zestaw informacji o użytkowniku ma 50 kolumn szerokości ...)
IMHO problem z pamięcią masową nie jest decydujący. Przejdźmy zatem do wydajności SELECT/INSERT:
W tej kwestii myślę, że rozwiązanie 1 nadal wygrywa. Na wkładkach wygrywa 1 wygrana: wstawiany jest tylko jeden wiersz, nawet jeśli użytkownik zmienia każde pole w swoich informacjach. W SELECTS, SOlution 1 wygrywa ponownie: potrzebujesz tylko widoku najnowszych informacji na użytkownika (powyższy kod), z czym jest zoptymalizowany SQL. Natomiast rozwiązanie 2 wymagałoby przestawienia: coś, co SQL nie jest dobre.
Jakiego systemu baz danych używasz? – sufleR
@sufleR MySQL i PostgreSQL. – Mario