Witaj Gościu! ( Zaloguj | Rejestruj )

Forum PHP.pl

 
Reply to this topicStart new topic
> [MySQL]wydajność tabeli ulubionych
-tutmizos-
post
Post #1





Goście







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
Go to the top of the page
+Quote Post
session
post
Post #2





Grupa: Zarejestrowani
Postów: 112
Pomógł: 22
Dołączył: 11.04.2010
Skąd: Tarnów

Ostrzeżenie: (0%)
-----


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).
Go to the top of the page
+Quote Post
r4xz
post
Post #3





Grupa: Zarejestrowani
Postów: 673
Pomógł: 106
Dołączył: 31.12.2008

Ostrzeżenie: (0%)
-----


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
Go to the top of the page
+Quote Post
session
post
Post #4





Grupa: Zarejestrowani
Postów: 112
Pomógł: 22
Dołączył: 11.04.2010
Skąd: Tarnów

Ostrzeżenie: (0%)
-----


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.

Ten post edytował session 11.05.2013, 19:06:55
Go to the top of the page
+Quote Post
r4xz
post
Post #5





Grupa: Zarejestrowani
Postów: 673
Pomógł: 106
Dołączył: 31.12.2008

Ostrzeżenie: (0%)
-----


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...
Go to the top of the page
+Quote Post
session
post
Post #6





Grupa: Zarejestrowani
Postów: 112
Pomógł: 22
Dołączył: 11.04.2010
Skąd: Tarnów

Ostrzeżenie: (0%)
-----


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 (IMG:style_emoticons/default/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ń.

Ten post edytował session 11.05.2013, 23:34:06
Go to the top of the page
+Quote Post
Thorang Hoog
post
Post #7





Grupa: Zarejestrowani
Postów: 41
Pomógł: 9
Dołączył: 8.02.2009

Ostrzeżenie: (0%)
-----


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 (IMG:style_emoticons/default/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ść. (IMG:style_emoticons/default/ph34r.gif)

Ten post edytował Thorang Hoog 12.05.2013, 00:45:52
Go to the top of the page
+Quote Post
r4xz
post
Post #8





Grupa: Zarejestrowani
Postów: 673
Pomógł: 106
Dołączył: 31.12.2008

Ostrzeżenie: (0%)
-----


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ł? (IMG:style_emoticons/default/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 (IMG:style_emoticons/default/smile.gif)
Go to the top of the page
+Quote Post
session
post
Post #9





Grupa: Zarejestrowani
Postów: 112
Pomógł: 22
Dołączył: 11.04.2010
Skąd: Tarnów

Ostrzeżenie: (0%)
-----


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 (IMG:style_emoticons/default/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 (IMG:style_emoticons/default/wink.gif) Jak mówiłem wszystko zależy od zastosowania.

Ten post edytował session 12.05.2013, 09:32:01
Go to the top of the page
+Quote Post
r4xz
post
Post #10





Grupa: Zarejestrowani
Postów: 673
Pomógł: 106
Dołączył: 31.12.2008

Ostrzeżenie: (0%)
-----


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 (IMG:style_emoticons/default/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...
Go to the top of the page
+Quote Post
Thorang Hoog
post
Post #11





Grupa: Zarejestrowani
Postów: 41
Pomógł: 9
Dołączył: 8.02.2009

Ostrzeżenie: (0%)
-----


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 (IMG:style_emoticons/default/tongue.gif) Oczywiście wtedy i tak pozostaje problem z ostatnią wartością, ale wtedy z pomocą przychodzi:
  1. rlike '.?,1(,|$)'

(IMG:style_emoticons/default/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.

Ten post edytował Thorang Hoog 12.05.2013, 17:23:24
Go to the top of the page
+Quote Post
session
post
Post #12





Grupa: Zarejestrowani
Postów: 112
Pomógł: 22
Dołączył: 11.04.2010
Skąd: Tarnów

Ostrzeżenie: (0%)
-----


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 (IMG:style_emoticons/default/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 (IMG:style_emoticons/default/wink.gif) ), że A jest lepsza, ale B też znajdzie swoje zastosowania

Ten post edytował session 12.05.2013, 20:39:48
Go to the top of the page
+Quote Post

Reply to this topicStart new topic
2 Użytkowników czyta ten temat (2 Gości i 0 Anonimowych użytkowników)
0 Zarejestrowanych:

 



RSS Aktualny czas: 15.09.2025 - 16:08