Pomoc - Szukaj - Użytkownicy - Kalendarz
Pełna wersja: [MySQL]wydajność tabeli ulubionych
Forum PHP.pl > Forum > Przedszkole
tutmizos
Witam,
czy sposób a będzie wystarczająco wydajny przy dużej ilości rekordów?

a.
id id_user id_favorite
1 345 67
1 345 10

b.
czy
id id user id_favorite
1 345 67,10


pozdrawiam
session
Jeśli masz tablice z userami to lepiej dodać w niej kolumne id_fav i do niej obce ID z tablicy "ulubionych" oddzielając je separatorem (czyli lepiej b. moim zdaniem).
r4xz
Cytat(session @ 11.05.2013, 17:45:39 ) *
czyli lepiej b. moim zdaniem

cooo?! toć to najgorsze co można zrobić - tylko i wyłącznie A

dlaczego?
1. pobierz wszystkie ulubione wpisy dla np. użytkownika o id=4
2. spróbuj pobrać wszystkich użytkowników którzy lubią coś o id=3
3. zobacz jak różni się wydajność przeszukiwania przy polach typu TEXT, a jak przy Int
session
1. pobierasz selectem z kolumny id_fav where id=4 wartości dla określonego użykownika i explode(',' );
2. używanie like %,3,% w zapytaniu ( w zależności od konstrukcji bazy może się to różnić )
3. mowa o dużych bazach, więc tutaj różnica jest dyskusyjna, chociaż sprawa jest oczywista, jednak lepiej dla użytkownika który "lubi" 10 rzeczy wprowadzać 10 nowych rekordów ? Dosyć szybko dojdzie do przeładowania bazy przy częstych dodaniach. Czas skanowania wielu wpisów przy ogromnej ilości danych może być dłuższy, niż pobranie jednego pola TEXT.

Generalnie operacje na "rozdzielonych" indexach są łatwiejsze i przyjemniejsze, ale to nie znaczy że na połączonych separatorami są niemożliwe.
r4xz
Cytat(session @ 11.05.2013, 20:04:07 ) *
1. pobierasz selectem z kolumny id_fav where id=4 wartości dla określonego użykownika i explode(',' );
2. używanie like %,3,% w zapytaniu ( w zależności od konstrukcji bazy może się to różnić )
3. mowa o dużych bazach, więc tutaj różnica jest dyskusyjna, chociaż sprawa jest oczywista, jednak lepiej dla użytkownika który "lubi" 10 rzeczy wprowadzać 10 nowych rekordów ? Dosyć szybko dojdzie do przeładowania bazy przy częstych dodaniach. Czas skanowania wielu wpisów przy ogromnej ilości danych może być dłuższy, niż pobranie jednego pola TEXT.

Generalnie operacje na "rozdzielonych" indexach są łatwiejsze i przyjemniejsze, ale to nie znaczy że na połączonych separatorami są niemożliwe.

nie, nie, nie... to są totalne herezje (szczególnie punkt 2. i 3.)

#1 http://stackoverflow.com/questions/2578117...ndexes-in-mysql
#2 patrz jak mają to rozwiązane wszystkie frameworki

Czemu tak dużo osób boi się milionów wpisów w tabeli gdzie są 3 kolumny typu int? Toć wyszukiwanie po Int jest takie wydajne...
session
Cytat
to są totalne herezje

Z tym się nie zgodze. O ile wydajność int jest naturalnie lepsza nawet wynikająca z podstaw operowania komputerów na liczbach, jednak sposoby wyciągania danych z pkt. 2 mojego poprzedniego posta raczej powinny przynieść zamierzony efekt, ale samo like nie jest optymalne. Uświadomiłem sobie również, że przecież wcale nie musi to być TEXT jak sugerowałeś, tylko dobrze przemyślany VARCHAR lub CHAR.

Cytat

Wydaje mi się, że odnosi się to bardziej do autoincermentowania i używania tekstowych indexów, a przecież tutaj nadal pozostają INTowe indexy, przecież nie mówiłem nic o używaniu pełnych tekstowych nazw wink.gif

W jaki sposób są przechowywane w bazach hasła ? Są hashowane na kilkuset bitowe stringi, a następnie zapisywane przy każdym użytkowniku. W nieraz ogromnej ilości wpisów skrypty porównują (tekstowe) nazwy użytkowników i hashe i jest to optymalne rozwiązanie, z tym, że jeden użytkownik to jedno hasło.

Moim zdaniem wszystko zależy od późniejszego wykorzystywania danych z bazy i odpowiednie rozwiązania należy dobierać do założonych oczekiwań.
Thorang Hoog
Tylko i wyłącznie sposób pierwszy.
Jest prosty, łatwy w obsłudze po prostu optymalny.
Wyobraź sobie, że 3000 osób polubiło element o identyfikatorze 12365863. Już nie tak prosto wykonać 3000 porównań aby usunąć niepotrzebny identyfikator. I nagle tracisz na tabeli 24000 bajtów danych. To jest równowartość 16000 wpisów zawierających trzy kolumny domyślnego int(11) ze sposobu pierwszego. A jak łatwo usunąć niepotrzebne 3 tysie niepotrzebnych śmieci ;P MySQL z InnoDB z kluczami obcymi sam za ciebie to zrobi wink.gif

Edit//-> Zapomniałem dodać. Wyszukanie wszystkich osób które polubiły dany element (przy zbudowaniu indeksów id_favorite) jest o wiele szybsze i nie ma o czym dyskutować.
Można też dodać datę polubienia i na ich podstawie budować różne statystyki jak np. na fb. Wykres polubień w czasie i wiadomo jakie wydarzenie, czy sposób reklamy wpłynął na popularność. ph34r.gif
r4xz
Cytat(session @ 12.05.2013, 00:33:26 ) *
Z tym się nie zgodze. O ile wydajność int jest naturalnie lepsza nawet wynikająca z podstaw operowania komputerów na liczbach, jednak sposoby wyciągania danych z pkt. 2 mojego poprzedniego posta raczej powinny przynieść zamierzony efekt, ale samo like nie jest optymalne. Uświadomiłem sobie również, że przecież wcale nie musi to być TEXT jak sugerowałeś, tylko dobrze przemyślany VARCHAR lub CHAR.

Popatrz:
Kod
id | id_user | ids_fav
---+---------+-----------------------
1 | 1       | 1,23,62,24,74,436,242
2 | 3       | 1,2,3,4,5,6,7,...,1500

Taki prosty przykład - jaki CHAR/VARCHAR byś tutaj dał? smile.gif

Cytat(session @ 12.05.2013, 00:33:26 ) *
W jaki sposób są przechowywane w bazach hasła ? Są hashowane na kilkuset bitowe stringi, a następnie zapisywane przy każdym użytkowniku. W nieraz ogromnej ilości wpisów skrypty porównują (tekstowe) nazwy użytkowników i hashe i jest to optymalne rozwiązanie, z tym, że jeden użytkownik to jedno hasło.

To jest przykład z zupełnie innej bajki, tam porównujesz pełne pole, a nie korzystasz z totalnie niewydajnego przeszukiwania ciągu znaków.

Cytat(session @ 12.05.2013, 00:33:26 ) *
sposoby wyciągania danych z pkt. 2 mojego poprzedniego posta raczej powinny przynieść zamierzony efekt

...jeszcze by go trzeba było udoskonalić: mamy LIKE %,1,% tak? To nam fav o id=1 nie znajdzie smile.gif
session
Tak jak napisałem:
Cytat
Moim zdaniem wszystko zależy od późniejszego wykorzystywania danych z bazy i odpowiednie rozwiązania należy dobierać do założonych oczekiwań.

Zakładałem, że "ulubione" będzie to raczej grupa kilkudziesięciu kategorii czyli indexy maksymalnie dwu, ewentualnie trzy znakowe, wtedy łatwo przeliczyć i można ustawić varchar na maksymalną ilość kategorii*(liczba znaków+1). Co innego jeśli miałby to być serwis z "likeami" gdzie co chwile przybywa nowy wpis z nowym id do ewentualnego "polubienia", jednak autor tematu jednoznacznie się nie określił. Gdyby okazało się, że użytkownik może np. wybierać ulubione kategorie w stylu: "programowanie","narty","samochody" itp. to sposób b. wydaje się być bardziej optymalny.

Co do ostatniej kwestii:
Cytat
To nam fav o id=1 nie znajdzie

Jeśli wprowadzalibyśmy do bazy w postaci: ','.$id to by znalazło tongue.gif Oczywiście wtedy i tak pozostaje problem z ostatnią wartością, ale wtedy z pomocą przychodzi:
  1. rlike '.?,1(,|$)'


Jeśli nie ma zdefiniowanej konkretnej listy kategorii do polubienia, jak najbardziej się z Wami zgadzam że sposób A jest najbardziej sensowny wink.gif Jak mówiłem wszystko zależy od zastosowania.
r4xz
Cytat(session @ 12.05.2013, 10:28:34 ) *
Jeśli nie ma zdefiniowanej konkretnej listy kategorii do polubienia, jak najbardziej się z Wami zgadzam że sposób A jest najbardziej sensowny wink.gif Jak mówiłem wszystko zależy od zastosowania.

W każdym przypadku a jest lepsza, wersja b jest po prostu mniej wydajna/bardziej obciąża dysk/ciężka do rozbudowy o nowe statystyki etc. i nigdy nie powinna być stosowana.

To tyle z mojej strony w tym temacie, bo chyba dalsza dyskusja nie ma sensu...
Thorang Hoog
Cytat(session @ 12.05.2013, 10:28:34 ) *
Zakładałem, że "ulubione" będzie to raczej grupa kilkudziesięciu kategorii czyli indexy maksymalnie dwu, ewentualnie trzy znakowe, wtedy łatwo przeliczyć i można ustawić varchar na maksymalną ilość kategorii*(liczba znaków+1).


To jak podcinanie sobie gałęzi na której siedzisz. Za każdym razem gdy będziesz chciał dodać nową kategorię będziesz musiał na nowo przeliczać i przebudowywać tabele.

Cytat(session @ 12.05.2013, 10:28:34 ) *
Jeśli wprowadzalibyśmy do bazy w postaci: ','.$id to by znalazło tongue.gif Oczywiście wtedy i tak pozostaje problem z ostatnią wartością, ale wtedy z pomocą przychodzi:
  1. rlike '.?,1(,|$)'

thumbsdownsmileyanim.gif
Utrudnienia, utrudnienia, utrudnienia. Znajdź choćby jeden pozytyw.

//-> Edit

A InnoDB sam zmieni za ciebie wszystkie numery id w tabeli z lajkami kiedy przyjdzie taka potrzeba. I zapobiegnie omyłkowym podstawieniom kluczy nie istniejących.
session
Dla sprostowania:
Cytat
Za każdym razem gdy będziesz chciał dodać nową kategorię będziesz musiał na nowo przeliczać i przebudowywać tabele.

Jeśli tworzę serwis to potrafię przewidzieć ile kategorii +/- będzie potrzebne, można przewidzieć, że np nie więcej niż 99, więc 99*(2+1)=297 i taki varchar można ustawić. Jeśli są to serwisy w stylu: czym się interesujesz to myślę, że niemalże 100 wariantów spokojnie wystarczy, nawet int się kiedyś kończy na liczbie: 2147483647 tongue.gif.
Cytat
Utrudnienia, utrudnienia, utrudnienia.

Wydaje mi się, że nie bez powodu zostały stworzone takie rozwiązania. Jakie jest utrudnienie w krótkim wyrażeniu regularnym...
Cytat
dalsza dyskusja nie ma sensu...

Też tak uważam, więc generalizując można powiedzieć (jednogłośnie wink.gif ), że A jest lepsza, ale B też znajdzie swoje zastosowania
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.