Pomoc - Szukaj - Użytkownicy - Kalendarz
Pełna wersja: Optymalizacja bazy
Forum PHP.pl > Forum > Bazy danych > MySQL
TakiJakis
Założmy, że mamy bazę danych, w niej tabelę posty. W tej tabeli komórki autor_id, data, treść itp... Założmy, że treść jest zwykle długa. Czy opłaca robić się osobną tabelę dla treści? Jeśli tak, to w jakich sytuacjach to się opłaci?

Np. na czym polega szukanie, np. "SELECT COUNT(*) FROM posty". Czy to pobiera wszystkie wartości (czyli im więcej tekstu w komórce treść, tym dłużej zapytanie będzie trwało)?
MaKARON
Oplaci sier robic osobna tabele dla tresci jesli - wpisow bedzie duzo, bedziesz je przeszukiwal, bedziesz robil joiny, bedzie duzo zapytan do bazy danych. jesli to "twoja strona domowa" i bedziesz mial 20 artykulow miesiecznie (z czasem pewnie 5) to nie ma koniecznosci. dla wyrobienia sobie dobrych nawykow mozesz zrobic osobno.

select count(*) bez where wykorzysta dane zapisane w tabeli bez przegladania tresci, jesli beda dodatkowe where - to juz bedzie zalezalo od struktury (w niektorych przypadkach bedzie mozna wykorzystac indeksy, w innych trzeba bedzie przejsc po calej tabeli).
Sh4dow
Po pierwsze jesli 1 pole z trescia jest przypisywane do jednego rekordu z postem to nie rozdzielamy tablicy. Jeżeli natomiast jedno pole z tresciu nalezy do wielu rekordow z postami lub wiele tresci nalezy do jednego rekordu to wtedy sie rozdziela tablice.

NIE ROBIMY
  1. SELECT COUNT(*) FROM tablica

duzo lepiej jest zrobic
  1. SELECT COUNT(id) FROM tablica

gdzie pole id jest indexem tablicy.

Do indeksowania pol textowych dla szybkiego wyszukiwania sluzy index FULLTEXT ktory zakłada sie na tablice naprzyklad z trescia tytulem.
TakiJakis
Cytat(Sh4dow @ 25.10.2006, 06:48:29 ) *
Po pierwsze jesli 1 pole z trescia jest przypisywane do jednego rekordu z postem to nie rozdzielamy tablicy. Jeżeli natomiast jedno pole z tresciu nalezy do wielu rekordow z postami lub wiele tresci nalezy do jednego rekordu to wtedy sie rozdziela tablice.

W tabeli z postami, np. na forum, praktycznie każdy post ma swoją własną, unikalną treść i na odwrót. Zatem rozumiem, że nie zgadzasz się z MaKARONem?
thornag
Jesli relacja jest jeden do jeden do wielu to robimy dwie tabele, jesli relacja wiele do wielu to trzy, gdzie przy relacji 1->* mamy np

post_id user_id jakies tam dane

i to user_id jest tutaj 'klulczem obcym', post moze nalezec tylko do jednego usera, dlatego zazwyczaj organizuje sie to na dwoch tabelach.

W przypadku *->* robimy trzy tabele, np

grupa_id grupa_nazwa
user_id user_nazwa
user_id grupa_id

Tutaj kazdy uzytkownik moze nalezec do dowolnie wielu grup, kazda grupa moze zawierac w sobie dowolnie wielu uzytkownikow dlatego tworzymy trzy tabela gdzie ta trzecia to tabela relacji user grupy.
TakiJakis
thornag dzieki za probe pomocy, ale nie chodzilo mi o suche regulki, a odp. na moje konkretne pytanie. Jezeli w tabeli posty z komorkami post_id, autor_id i tresc wywalimy tresc (do tabeli posty_tresci z komorkami id i tresc) i zastapimy ja komorka tresc_id, ktora bedzie odnosic sie do tabeli posty_tresci, to bedzie to odstapienie od zasad normalizacji. Moje pytanie brzmi, czy warto takie cos zastosowac, by zyskac na szybkosc. Wydaje mi sie, ze odp. MaKARONa jest ok, ale Sh4dow sie z nim nie zgodzil (of kors zakladajac, ze gdy raz na 1000 postow powtorzy sie jakis post w stylu "zgadzam sie", to nie bedziemy liczyc, ze jedna tresc odpowiada kilku postom, no ale to chyba jasne)...
thornag
To zastosuj swoj problem do tego co napisalem.


Dla mnie oczywistym jest ze jeden post moze 'nalezec' tylko do jednego uzytkownika, i jednego tematu. Ja zastosowalbym schemat

Tabela 1 - Uzytkownicy
Tabela 2 - Tematy

a w tabeli 3 tj Posty

post_id, temat_id, user_id, i reszta.
TakiJakis
Cytat(thornag @ 25.10.2006, 13:38:00 ) *
Dla mnie oczywistym jest ze jeden post moze 'nalezec' tylko do jednego uzytkownika, i jednego tematu. Ja zastosowalbym schemat

Tabela 1 - Uzytkownicy
Tabela 2 - Tematy

a w tabeli 3 tj Posty

post_id, temat_id, user_id, i reszta.

No to chyba sie nie rozumiemy, bo dla mnie to tez jest oczywiste. Pytam o cos zupelnie innego.
thornag
Chyba rzeczywiscie sie nie rozumiemy, no ale jak Tobie trzeba odpwieadac wprost, to bedzie wprost.

1. Wedlug mnie nie nie oplaca sie trzymac tresci w osobnych tabelach jesli jedna tresc nie nalezy do wielu postow i na odwrot wiele postow nie ma identycznej tresci.

2. Szczerze nie mam pojecia, najbezpieczniej liczyc po kolumnie zawierajacej indeks, chodz bardzo prawdopodobne ze jak dasz * to MySQL bedzie mielil wszystkie rekordy.
TakiJakis
Nie majac pojecia na temat odpowiedzi do pytania 2. raczej ciezko odpowiedziec na pytanie 1. winksmiley.jpg. Dziekuje Ci za pomoc, czekam jeszcze na opinie innych forumowiczow. Dodam, ze PHPBB team nie zgadza sie z thornagiem - oni dla tresci postow tworza osobna tabele.
Sh4dow
Cytat(TakiJakis @ 25.10.2006, 10:14:43 ) *
W tabeli z postami, np. na forum, praktycznie każdy post ma swoją własną, unikalną treść i na odwrót. Zatem rozumiem, że nie zgadzasz się z MaKARONem?

Tak zarczej sie nie zgadzam z MaKARoNem poniewaz rozdzielanie takiej tablicy spowoduje jedynie obnizenie optymalizacji. Tak jak mowiłem dodaj index FULLTEXT (jesli twoja wersja mysqla pozwala na to), poszukaj sobie metod przeszukiwania w SQL (poszukaj w manuala MATCH AGAINST, jesli dobrze to pamietam). Wszystkie kolumny łączące relacje między tabelami, np. user_id, topic_id i inne dodawaj jako INDEX w tablicy. Bedziesz czesto łączył tablice po tych kolumnach wiec bedzie działa dużo szybciej. W sumie tak wygląda koniec optymalizacji tej tablicy. Przy innych moze być podobnie, chyba ze masz inne relacje miedzy tablicami to może być troche inaczej. Życze powodzenia. Po optymalizacji rzetestuj sobie tak napisane forum przy ilości postow na poziomie 10-500 tys rekordow dla znalezienia ewentualnych "wąskich gardeł"
guitar.gif
To jest wersja lo-fi głównej zawartości. Aby zobaczyć pełną wersję z większą zawartością, obrazkami i formatowaniem proszę kliknij tutaj.
Invision Power Board © 2001-2025 Invision Power Services, Inc.