TwojePC.pl © 2001 - 2025
|
|
A R C H I W A L N A W I A D O M O Ś Ć |
|
|
|
[MySQL] FINAL BATTLE, podsumowanie i próba podjęcia ostatecznych decyzji , kubazzz 24/12/08 17:40 Opiszę dokładnie, punkt po punkcie i napiszę wyjaśnienie, dlaczego tak a nie inaczej.
1. Jest potrzebna tabela użytkowników, dla których jest sporo unikalnych informacji, takij jak login, hasło, imię, data urodzenia itd..
- lista początkowo będzie krótka, ale z czasem się rozrośnie, chociaż nie powinna przekroczyć 100 tysięcy wpisów [w wariancie przyszłościowym]
2. Nie było tego wcześniej napisanego, ale chciałem zrobić potwierdzenie poprzez email, na takiej zasadzie:
- użytkownik podaje wszystkie dane podczas rejestracji.
- dane te są wpisywane do bazy danych do tabeli USERS, ale w polu klasa_użytkownika jest wpisane 0 [zero], co oznacza że użytkownik jest niepotwierdzony. [klasa 1 to zwykły uzytkownik, klasa 2 to administrator itp].
- użytkownik podczas rejestracji dostaje maila, z linkiem
kubazzz.pl/confirm/23468972346059237469834bhgsdhgdlgh2375
przy czym ten ciąg znaków to hash('whirlpool', $email+time());
- ten hash jest wpisywany do tabeli UNCONFIRMED_USERS, o takiej strukturze
unc_user_id | user_id(taki jak w tabeli users) | email | hash | registration_date
- kiedy użytkownik przejdzie tym w link z tego maila do skryptu confirm.php, to ten skrypt porówna hash w bazie UNCONFIRMED_USERS i jeśli znajdzie taki to danemu użytkownikowi zmieni klasę na 1 i wykasuje wpis z z bazy UNCONFIRMED_USERS
Dlaczego tak?
Wg mnie lepiej jest od razu wpisać wszystkie dane do bazy USERS i dać klasę 0 (niepotwierdzony), bo
- wtedy łatwiej jest ręcznie zmienić klasę użytkownikowi, jakby się coś paprało
- nie trzeba przenosić kilkunastu kolumn (wiek, imie, login itd) z bazy niepotwierdzonych do potwierdzonych, w przypadku potwierdzania.
- mniej energii trzeba poświęcić na przeszukiwanie hashów, z racji tego, że tabela UNCONFIRMED będzie prawie na pewno krótsza, poza tym ma mniej kolumn, a z czasem, kiedy przyrośnie ogólna ilość użytkowników, różnice między USERS a UNCONF_USERS będą jeszcze większe
- prawdopodobnie będzie trzeba jakiegoś cron'a zrobić, co by wywalał przeterminowane rejestracje [skanując tablicę UNCONFIRMED_USERS, czyli też oszczędność zamiast skanować całą tabelę USERS]
W sumie ten koncept wymyśliłem sam, tak wymyśliłem że to działa w praktycznych zastosowaniach:)
3. Jak wcześniej wspomniano, userzy mają sporo opcji opisowych, indywidualnych dla każdego użytkownika, ale mają też możliwość wyboru od jednej do kilku cech [np że jest murzynem, polakiem, katolikiem, kierowcą, miłośnikiem kwiatów, ma córkę]
- takich cech będzie nie więcej niż 10 [na razie wyliczyłem 8], na pewno nie będą przyrastać w jakiś dużych ilościach, z czasem jakas może zostanie usunięta, albo dodana
- KAŻDA taka cecha wiąże ze sobą konieczność dołożenia paru dodatkowych pól opisowych. Pola te NIE SĄ powiązane między cechami.
- Ilość pól dla każdej z cech jest inna i może się zmieniać, ale też w zakresie kilku-kilkunastu
Po analizie tych opisów, tekstów na wikipedii, analizie bazy phpbb3, wymyśliłem, że optymalne będzie takie rozwiązanie:
tabela USERS
user_id | user_name | user_email .... | user_is_murzyn | user_is_polak | user_has_corka itd
tabela MURZYNI
murzyn_id | user_id | user_name | region_pochodzenia | ksztalt_twarzoczaszki | itd..
tabela FLOWERLOVERS
fl_id | user_id | user_name | ulubiony_kwiat | ulubiony_kolor | ilość_wogrodku
tabela POLAKI
polak_id | user_id | user_name | region | ród | tytul
CZYLI:
- dla każdego usera są w kolumnach wartości logiczne definiujące czy daną cechę ma, czy nie ma
- dla każdej cechy jest zrobiona osobna tabela, w której jest id danego usera i kopia jego imienia/loginu.łotewer
Dlaczego tak??
- w ten sposób wydaje mi się to najbardziej wydajne, ponieważ przeszukując TYLKO bazę użytkowników, można wyświetlić info, że kubazzz jest lubi kwiaty, nie ma córki i nie jest murzynem.
skomplikowane szukanie, typu, user ma 20 lat i lubi kwiaty, też można przeprowadzić na tej bazie łatwo.
- wcześniej miałem pomysł [post z godziny 00:40, http://twojepc.pl/boardPytanie138976.htm#22 ], żeby zamiast wartości 0/1 w tabeli USERS w odpowiednich kolumnach było id_murzyna, id_polaka ,itd
ALE!!
Przy INSERT trzebaby najpierw wpisać usera to tabel murzyni, lubi kwiaty, polacy itd, pozbierać odpowiednie ID z tych tabel, a dopiero potem wpisać do bazy USERS odpowiednie id_murzyna, id_polaka itd
Na moją kobiecą intuicję to generuje duże pole do błędów i problemy z wydajnością [bo wpis do USERS czeka na wyniki innych wpisów]
- łatwiej i szybciej będzie przeszukiwać, bo szukając w tabeli MURZYNI, murzyna z regionu NIGERIA, znajdujemy rekordy w których od razu mamy user_id i user_name. Można w ten sposób łatwo wyświetlić listę takich murzynów, bez robienia fullsearch na tabeli USERS, nawet nie trzeba jej dotykać.
A kiedy trzeba wziąć dane z tabeli USERS, to mamy user_id, na którym jest indeks.
Gdybyśmy, tak jak we wcześniejszym wariancie, mieli w tabeli MURZYNI tylko murzyn_id, to żeby wyświetlić jakiekolwiek info o tym murzynie, choćby jego login, to trzebaby robić search na tabeli USERS where murzyn_id[users] = murzyn_id[murzyni].
Nie sposób zrobić 8 czy 10 dodatkowych indeksów na każdym takim polu cechy w tabeli USERS.
4. Każdy user może zawrzeć przyjaźń/kontakt z innym użytkownikiem - przyjaźń jest dwustronna zawsze.
Nie ma przymusu, ani limitu, może nie mieć przyjaźni, a może mieć ze wszystkimi.
kubazzz : grocal === grocal : kubazzz
Każdy user może dodać kogoś do obserwowanych, to jest jednostronne, też nie ma przymusu i też nie ma limitów.
kubazzz : grocla <> grocal : kubazzz
W tym punkcie się trochę gubię wciąż, bo nie jestem pewien
4A) jak skontruować tabelę lub tabele [bo raczej potrzeba dwie stworzyć, osobną dla przyjaźni i osobną dla obserwacji]
4B) jak wydajnie i poprawnie przeszukiwać te tabele
Co do tabeli obserwujących to myślę że to powinno wyglądać tak:
tabela OBSERWACJE:
obserwuje_kto | obserwuje_kogo
i to wystarczy, zawsze relacja będzie jednostronna, jeśli chcę wziąć wszystkie osoby które obserwuje kubazzz, to lecę po kolumnie obserwuje_kto i szukam wszystkich pozycji kubazzz, a następnie odczytuję obserwuje_kogo. Banał.
ALE!!
taka tabela będzie co najmniej kilkukrotnie dłuższa niż tabela USERS, jako że każdy user może być wielokrotnie wpisany w pozycji obserwuje_kto.
Co do tabeli kontaktów/przyjaciół to potrzebuję jeszcze porad.
bo już wiem, że mniejsze ID ma być w pierwszej kolumnie
5. Szukałem wczoraj trochę po dokumentacji MySQL i phpmyadmin, ale się nie doszukałem.
5a) ile dawać indeksów i na co naprawdę warto dać indeks?
5b) co to jest za guzik "pełny tekst"
5c) co to jest za guzik "jednoznaczny"
5d) kiedy dawać wartość NULL a kiedy NOT NULL
5e) jak ustawić unikalność [unique; czy to jest ten 'jednoznaczny' ?] i co mi to daje tak naprawdę?
5f) skopiowałem styl nazw z php_bb3 czyli w tabeli USERS robię pola user_id, user_name itd
Podobnie robię w stylach i kiedy operuję na elementach javascriptem, dla mnie to jest czytelniejsze, ale dostałem opinię, że tak się nie robi w bazach.
____________
z góry dziękuję za pomoc, jednocześnie bardzo o nią proszę.
Starałem się opisać to wszystko dokładnie, opisać w jaki sposób rozumuję i czego nie jestem pewien.
Życzę wszystkim Wesołych Świąt, smacznego karpia, góry prezentów i znormalizowanych baz danych!!SM-S908 - pierwszy :) , DrLamok 24/12/08 22:14
heh sorki :) nie mogłem się powstrzymać :) ale przynajmniej przeczytałem całość.
Zrobiłeś w jednym miejscu czeski błąd w user_name użytkownika z którym się zaprzyjaźniłeś :) Grocal a nie Grocla :)
Ja niestety nie pomogę.. o php nie mam bladego pojęcia.. ale fajnie się czytało... - drugi :) , Grocal 24/12/08 22:57
Na poczatek powiem, ze teoria swoje a praktyka swoje. Teoretycznie zawsze powinnismy dazyc co najmniej do 3NF, ale w praktyce okazuje sie, ze wymagania systemu wymuszaja na nas niestandardowe rozwiazania. Tak wiec zawsze warto na projekt bazy danych patrzec przez pryzmat jej wykorzystania. Ty akurat to robisz, co oczywiscie sie bardzo chwali.
Ad2. Potwierdzenie aktywacji wystarczy chyba zrobic jako dwie kolumy w USERS i tyle - pola hash i active odpowiednio z hashem (kasowany po aktywacji) i active (0/1 - wiadomo). Przyda sie tez kolumna date_registered lub cos w ten desen. Proste i juz...
Ad3. A moze wykorzystac baze danych nie tylko do trzymania danych ale i do... ich opisu? Powiedzmy, ze stworzymy tabele USERS_DEFINITIONS_PROPERTIES (ID_PROPERTY, name) oraz USERS_PROPERTIES (ID_USER, ID_PROPERTY, value). W pierwszej dodajesz np. (1, 'ulubiony kwiat') a w drugiej dla usera o ID=1, ktory lubi gozdziki (1,1,'gozdzik'). Zamiast dodawac kolumny w bazie - dodajesz rekordy w tabeli definiujacej dane. Drawback? Pole value w drugiej tabeli musi byc w miare uniwersalnym "nosnikiem", czyli najlepiej text o odpowiedniej dlugosci.
Ad4. Trzymaj sie definicji tabeli (ID_USER1, ID_USER2) z unique key na oba pola i juz (plus ewentualne kolumny/pola np. na date dodania relacji, aktywnosci relacji, potwierdzenia, hashu itp.). Unique daje Ci gwarancje, ze nie powtorzy sie w bazie ta sama kombinacja ID_USER1-ID_USER2. Jeżeli ma to byc relacja jednokierunkowa (obserwowani) to jasne jest, ze para np. (3,7) to co innego niz (7,3) - definicja tabeli wystarczy. W przypadku relacji w obie strony (przyjaciele) - olewasz fakt, ze pary moga byc w obie strony j/w - albo dodajesz z warunkiem ID_USER1<ID_USER2 i pozbywasz sie np. przypadku (7,3) albo pozwalasz na takie przypadki ale po odczytaniu z bazy ktorakolwiek z tych par (jedna z nich lub obie na raz) potwierdzaja istnienie relacji 3<->7. Nie ma co filozofowac - tu zadziala raczej logika aplikacji. To aplikacja bedzie wstawiac dane, wiec mozna je przed tym na bank sprawdzic. W ogole, to olanie warunku ID_USER1<ID_USER2 pozwala np. na stwierdzienie, kto komu wyslal zaproszenie do "bycia przyjacielem", np. ID_USER1 wysyla zaproszenie do ID_USER2 (np. 3 wysyla do 7), to w bazie bedzie to jako (3,7).
Odczyt? Zakladajac, ze szukamy przyjaciol usera=3.
SELECT id_user1, id_user2 FROM users WHERE id_user1 = '3' OR id_user2 = '3'; i lecisz foreachem po wynikach odczytujac zarowno id_user1 jak i id_user2 olewajac ewentualne wartosci '3'.
Tyle na razie. Chyba za duzo pierogow :)Na pewno, na razie, w ogóle...
Naprawdę, naprzeciwko, stąd...
Ortografia nie gryzie! |
|
|
|
|
All rights reserved ® Copyright and Design 2001-2025, TwojePC.PL |
|
|
|
|