![]() |
![]() ![]() |
![]() |
![]()
Post
#1
|
|
Grupa: Zarejestrowani Postów: 12 Pomógł: 0 Dołączył: 13.03.2015 Ostrzeżenie: (0%) ![]() ![]() |
Witam.
Mam pewien problem z wyświetlaniem danych z bazy. Mam utworzoną tabelę w której przechowywane są dane użytkownika. Tabela składa się z następujących pól: id - identyfikator wiadomości id_user - identyfikator osoby która dostała wiadomość id_sender - identyfikator osoby wysyłającej wiadomość content - treść wiadomości stauts - 0 lub 1 w zależności czy wiadomość została przeczytana Chciałbym wyśwetlić wszystkie w tabeli osoby w którymi były prowadzone rozmowy. Czyli wyświetlić mam osoby do których pisałem albo które do mnie pisały, ale bez powtórzeń. Pierwsze co zrobiłem to:
A efekt tego był taki: -michał -adam -adam -michał -michał Czyli nie poprawnie. Późnie spróbowałem Group By
Jednak to również daje niepoprawne wyniki bo czasami ja jestem nadwacą (czyli id_sender) a czasami odbiorcą (id_user) więc grupowanie musiało by być przez: id_user, id_sender. Ktoś ma jakieś pomysły? |
|
|
![]()
Post
#2
|
|
Grupa: Zarejestrowani Postów: 95 Pomógł: 7 Dołączył: 27.10.2015 Ostrzeżenie: (0%) ![]() ![]() |
dzisiejszy odcinek sponsoruje liczba 1 oraz słowo: 'distinct'
|
|
|
![]()
Post
#3
|
|
Grupa: Zarejestrowani Postów: 12 Pomógł: 0 Dołączył: 13.03.2015 Ostrzeżenie: (0%) ![]() ![]() |
Zatem jak to ma wyglądać?
Zapomniałem dodać, że w tabeli messages są tylko identyfikatory użytkowników, z kolei w tabeli members są ich dane takie jak np imie. Poniżej przedstawiam graficznie jaki jest problem. Po lewej są moje tabele z bazy danych, po prawej cały rezultat jaki chciałbym osiągnąć. Bardzo proszę o pomoc ![]() |
|
|
![]()
Post
#4
|
|
![]() Grupa: Moderatorzy Postów: 36 557 Pomógł: 6315 Dołączył: 27.12.2004 ![]() |
Cytat dzisiejszy odcinek sponsoruje liczba 1 oraz słowo: 'distinct' oraz fraza 'nie tedy droga' ![]() @krynol wracajac do tematu: Twoje pierwsze zapytanie jest jak najbardziej ok (pomijajac fakt ze pomiedzy SELECT a FROM ewidentnie czegos brakuje ![]() Teraz w php musisz pogrupowac swoje rekordy po id nie nalezacym do osoby aktualnie zalogowanej i jestes w domu. Jak to sie mniej wiecej robi pokazalem tu http://nospor.pl/grupowanie-wynikow.html majac tak przygotowana tablice wyswietlasz ja sobie jak ci pasuje -------------------- "Myśl, myśl, myśl..." - Kubuś Puchatek || "Manual, manual, manual..." - Kubuś Programista "Szukaj, szukaj, szukaj..." - Kubuś Odkrywca || "Debuguj, debuguj, debuguj..." - Kubuś Developer |
|
|
![]()
Post
#5
|
|
Grupa: Zarejestrowani Postów: 95 Pomógł: 7 Dołączył: 27.10.2015 Ostrzeżenie: (0%) ![]() ![]() |
Patrząc na Twoją bazę kilka uwag:
- tabela z użytkownikami nie potrzebuje pola ID_user wystary ID które będzie użyte w tabelce messages. - tabelka z messages pola ID_user ID_sender proponuję zamienić na ID_sender, ID_receiver. Co do samego działania to potrzebujesz wyświetlić użytkowników z którymi dany user prowadził rozmowę, możesz to zrobić jednym zapytaniem:
i dostaniesz osoby z którymi gadał user o ID = 1. Nie słuchaj rad zeby coś tam robić w PHP jakieś pętle, filtrowania cuda na kiju, później kończy się to tak że jak będziesz miał wiele milionów rekodrów, bazę danych na innym serwerze to wszystko trzeba będzie przepchnąć przez sieć do serwera PHP i sieć się zamuli, aplikacja się zamuli i będzie kupa. Oczywiście wiemy że ta aplikacja to jakaś tam mała zabawa, ale uczyć trzeba się od samego początku dobrze ![]() |
|
|
![]()
Post
#6
|
|
![]() Grupa: Moderatorzy Postów: 36 557 Pomógł: 6315 Dołączył: 27.12.2004 ![]() |
Cytat Nie słuchaj rad zeby coś tam robić w PHP jakieś pętle, filtrowania cuda na kiju, później kończy się to tak że jak będziesz miał wiele milionów rekodrów, bazę danych na innym serwerze to wszystko trzeba będzie przepchnąć przez sieć do serwera PHP i sieć się zamuli, aplikacja się zamuli i będzie kupa. @javafxdev przeczytaj jeszcze raz problem autora, przejrzyj obrazki, a moze cos ci zaswita ![]() -------------------- "Myśl, myśl, myśl..." - Kubuś Puchatek || "Manual, manual, manual..." - Kubuś Programista "Szukaj, szukaj, szukaj..." - Kubuś Odkrywca || "Debuguj, debuguj, debuguj..." - Kubuś Developer |
|
|
![]()
Post
#7
|
|
Grupa: Zarejestrowani Postów: 95 Pomógł: 7 Dołączył: 27.10.2015 Ostrzeżenie: (0%) ![]() ![]() |
Problem autora jest taki:
"Czyli wyświetlić mam osoby do których pisałem albo które do mnie pisały, ale bez powtórzeń" @nospor Załóżmy że user o ID = 1 przeprowadził milion rozmów z uzytkownikiem 'Ania' w Twoim rozwiązaniu zostanie 'Ania' zwrócona milion razy i pogrupowana w PHP i finalnie dostaniemy jeden rekord. W moim rozwiązaniu 'Ania' zostanie zwrócona jeden raz. Nie będzie pętli w php robiącej milion razy sprawdzenie, nie będzie przepychania niepotrzebnych danych przez sieć. Piszesz również że: " Przeciez twoje zapytanie tak samo pobierze te milion rekordow jak ich tyle bedzie..." otóż nie, pobierze tylko jeden raz. Spróbuj sobie odpalić to zapytanie i sprawdź sam. Jeżeli nie widzisz różnicy to po co się kłucić. |
|
|
![]()
Post
#8
|
|
![]() Grupa: Moderatorzy Postów: 36 557 Pomógł: 6315 Dołączył: 27.12.2004 ![]() |
@javafxdev autor chce rowniez wyswietlic wiadomosci z danym userem.
A po drugie twoje zapytanie nie ma zadnego limitu ani nic, wiec jak user mial milion wiadomosci z userem nospor to dostanie milion rekordow a nie jeden. I teraz pozwol ze zacytuje ciebie "Jeżeli nie widzisz różnicy to po co się kłucić." edit: ok, UNION usunie duplikaty, nie zwrocilem uwagi na to. Nie jestem jednak przekonany co do optymalnosci tego rozwiazania bo i tak zapytanie wpierw musi przeleciec przez te wszystkie milion wiadomosci a dopiero potem usunie na łaczeniu UNION duplikaty Nie zmienia to faktu ze autor chce wyswietlic tez wiadomosci przy userze wiec tak czy siak trzeba je pobrac. Mozna to oczywiscie zrobic dynamicznie chocby ajaxem.
Powód edycji: [nospor]:
-------------------- "Myśl, myśl, myśl..." - Kubuś Puchatek || "Manual, manual, manual..." - Kubuś Programista "Szukaj, szukaj, szukaj..." - Kubuś Odkrywca || "Debuguj, debuguj, debuguj..." - Kubuś Developer |
|
|
![]()
Post
#9
|
|
Grupa: Zarejestrowani Postów: 95 Pomógł: 7 Dołączył: 27.10.2015 Ostrzeżenie: (0%) ![]() ![]() |
@nospor wyobraź sobie sytułację gdzie masz telefon na którym chcesz zrobić taką aplikację - wyświetlasz listę kontaktów i po kliknięciu na dany kontakt wyświetlasz historię rozmowy. Wyobraź sobie teraz że telefon wyciąga wszystkie dane z historią rozmowy do pamięci - wyciąga z karty pamięci SD (wolne czasy dostępów) milion rekordów trwa to koszmarnie długo, przenosi to do pamięci i zaczyna obrabiać, pamięci w telefonie zaczyna brakować (odpalony facebook i inne chaty), zużycie baterii na przejście po całej liście diametralnie rośnie, procesor się poci i to wszystko tylko po to zeby pokazać listę 80 kontaktów gdzie na koniec musisz jeszcze zrobić jednego if-a zeby usunąć samego siebie z listy. Do historii rozmów z 74 osobami nie wejdziesz nigdy w przeciągu miesiąca/dwóch albo i dłużej, ale musisz je mieć na liście. Zasoby potrzebne do wyświetlenia tej listy w Twoim rozwiązaniu są lekko mówiąc zbyt duże.
A teraz wyobraź sobie że zamiast telefonu masz PHP z 1000 userów. szybki dysk SSD zaczyna być jak karta w telefonie, szybki procesor intel i7 staje się jak Pentium II, 32 GB ramu robią się jak 128 MB, firma hostingowa liczy cykle procesora tylko po to zeby wykonać milion niepotrzebnych obrotów pętli, procek cały czas chodzi na 100% zeby zrobić prostą rzecz jaką jest pokazanie 80 osób na liście kontaktów, userzy mówią że im apka muli i nie będa z niej korzystać i tak kończy 80% projektów w IT ![]() |
|
|
![]()
Post
#10
|
|
![]() Grupa: Moderatorzy Postów: 36 557 Pomógł: 6315 Dołączył: 27.12.2004 ![]() |
wyobraz sobie, ze autor poprosil o rozwiazanie jak na obrazku...
Ja sobie wole wyobrazac piekniejsze obrazki. Przedstawilem rozwiazanie o ktore prosil autor. Oczywiscie ze mozna to zrobic optymalniej, pobrac tylko wpierw nazwy userow bez duplikacji a potem klikajc na usera doczytywac wiadomosci (chocby ajaxem). Ja to wiem. ps: jest tez cos takiego jak stronicowanie itp, bo nawet jak wyswietlisz wiadomosci tylko dla jednego usera a ich bedzie milion to tez szlag trafi appke. Tak samo jak szlag trafi appke jak user rozmawial z milionem uzytkownikow i nawet wowczas twoje hiper zapytanie tez spowoduje rozwalenie appki - wyobraz to sobie ![]() -------------------- "Myśl, myśl, myśl..." - Kubuś Puchatek || "Manual, manual, manual..." - Kubuś Programista "Szukaj, szukaj, szukaj..." - Kubuś Odkrywca || "Debuguj, debuguj, debuguj..." - Kubuś Developer |
|
|
![]()
Post
#11
|
|
Grupa: Zarejestrowani Postów: 6 806 Pomógł: 1828 Dołączył: 11.03.2014 Ostrzeżenie: (0%) ![]() ![]() |
-------------------- |
|
|
![]()
Post
#12
|
|
![]() Grupa: Moderatorzy Postów: 36 557 Pomógł: 6315 Dołączył: 27.12.2004 ![]() |
@trueblue zapomniales o warunku ze szukamy wiadomosci z userem o id 15
![]() -------------------- "Myśl, myśl, myśl..." - Kubuś Puchatek || "Manual, manual, manual..." - Kubuś Programista "Szukaj, szukaj, szukaj..." - Kubuś Odkrywca || "Debuguj, debuguj, debuguj..." - Kubuś Developer |
|
|
![]()
Post
#13
|
|
Grupa: Zarejestrowani Postów: 6 806 Pomógł: 1828 Dołączył: 11.03.2014 Ostrzeżenie: (0%) ![]() ![]() |
-------------------- |
|
|
![]()
Post
#14
|
|
Grupa: Zarejestrowani Postów: 95 Pomógł: 7 Dołączył: 27.10.2015 Ostrzeżenie: (0%) ![]() ![]() |
@trueblue jak napisał @nospor 'nie tedy droga' trzeba robić w PHP, do tego Twoje zapytanie zwróci też samego usera o ID = 15, a tego nie chcemy mieć w wynikach
@nospor mówisz o stronicowaniu więc wytłumaczę Ci jak to będzie działać w moim przykładzie: do tego union dodasz LIMIT i OFFSET i nadal masz listę 10,20,50 userów ktorzy są potrzebni do wyświetlenia na liście, dostaniesz z bazy tyle ile potrzebujesz i apki 'szlag nie trafi', natomiast w Twoim rozwiązaniu przy milionie kontaktów i tak wszystko przepchniesz do PHP i tam dopiero zrobisz limit i offset? nie mając unikalnych rezultatów z bazy i tak będziesz musiał wszystko przepchnąć do serwera zeby chociażby zrobić stronicowanie (skąd będziesz wiedział ile elementów będzie zawierać lista jak nie przejdziesz całej w PHP) i tutaj apka się rzeczywiście wywali, dlatego nie rozumiem dlaczego tak bronisz tego swojego rozwiązania opartego na PHP. |
|
|
![]()
Post
#15
|
|
![]() Grupa: Moderatorzy Postów: 36 557 Pomógł: 6315 Dołączył: 27.12.2004 ![]() |
Ciezko mi sie z toba rozmawia
![]() Cytat dlatego nie rozumiem dlaczego tak bronisz tego swojego rozwiązania opartego na PHP. Sprobuje jeszcze raz ci to wyjasnic: autor prosil o liste userow bez duplikatow oraz liste wiadomosci przy kazdym userze. Moj kod to robi. Tak, moj kod sie wywali przy duzej liczbie danych. Teraz twoje rozwiazanie, ktore jest rozwiazaniem problemu wg ciebie a nie jest, bo nie robi to o co prosil autor. Robi tylko w polowie. I twoje rozwiazanie przy duzej liczbie danych tez sie wylozy. Teraz nagle dodajesz do niego limit offsety itp. No ok, ale rownie dobrze mozna to pododawac do mojego. poza tym napisalem wczesniej jak to powinno wygladac Cytat Oczywiscie ze mozna to zrobic optymalniej, pobrac tylko wpierw nazwy userow bez duplikacji a potem klikajc na usera doczytywac wiadomosci (chocby ajaxem). Ja to wiem. Wiec nie, nie upieram sie przy moim pierwszym rozwiazaniu. Mowie jedynie ze ono robi to o co prosil autor, a Twoje nie. Twoje trzeba jeszcze uzupelnic o druga polowe i tak czy siak zabezpieczyc przed duza iloscia danych a z Twojej pierwszej wypowidzi wynikalo ze Twoje zapytanie jest och i ach a nie bylo.
-------------------- "Myśl, myśl, myśl..." - Kubuś Puchatek || "Manual, manual, manual..." - Kubuś Programista "Szukaj, szukaj, szukaj..." - Kubuś Odkrywca || "Debuguj, debuguj, debuguj..." - Kubuś Developer |
|
|
![]()
Post
#16
|
|
Grupa: Zarejestrowani Postów: 95 Pomógł: 7 Dołączył: 27.10.2015 Ostrzeżenie: (0%) ![]() ![]() |
Ciężko się rozmawia bo przedstawiam logiczne argumenty
![]() To ja Ci też spróbuje wyjaśnić dlaczego napisałem o offsetach i limitach - bo Ty zacząłeś: cytat: "ps: jest tez cos takiego jak stronicowanie itp" więc jak zacząłeś o tym mówić to chciałem Ci wyjaśnić dlaczego moje zapytanie będzie działać przy stronicowaniu a Twoje nie, natomiast Ty piszesz dalej: "Teraz nagle dodajesz do niego limit offsety itp. No ok, ale rownie dobrze mozna to pododawac do mojego." Otóż wyjaśniam że do Twojego nie można dodać limitu i offsetu - dlaczego, ano dlatego: Jeżeli wyciągnę pierwszych 10 rekordów z tabelki messages zapytaniem
to jeżeli pierwsze 10 rozmów było prowadzone z np. 'Arkiem' to nie dostanę listy userów grupując to w PHP, bo dostanę tylko 'Arka', więc nie dość że Twoje rozwiązanie się nie skaluje, to jeszcze NIE MOŻNA do niego dodać limitu i offsetu. Natomiast w moim zapytaniu:
dostaniesz nadal właściwą listę userów i dopiero potem wyciągasz ajaxem dla konkretnego klikniętego usera wiadomości z LIMITEM. Więc Twoje rozwiązanie ma dwa problemy: wywali się przy dużej liczbie danych, a następnie będzie potrzebny refaktoring PHP i samych zapytań aby to naprawić jak aplikacja zacznie się rozrastać- droższy maintanace. Ale obaj przecież wiemy, że to tylko jakaś praca domowa, ew. 'nowy facebook', więc nie ma się o co kłucić ![]() Ja z chęcią zobaczę lepsze rozwiązanie od tego co ja podałem takie żeby było skalowalne i szybkie bo nie twierdzę że moje rozwiązanie jest najlepsze. |
|
|
![]()
Post
#17
|
|
![]() Grupa: Moderatorzy Postów: 36 557 Pomógł: 6315 Dołączył: 27.12.2004 ![]() |
Cytat Ciężko się rozmawia bo przedstawiam logiczne argumenty Nie dosc ze inteligentny to jeszcze skromny ![]() Bede mial kiedys chwilke to zrobie testy na duzych danych dla Twojego zapytania i zapytania trueblue bo mnie ciekawi co tutaj bedzie lepsze *nie, to nie byl sarkazm ani nic zlego nie mialem na mysli ![]() -------------------- "Myśl, myśl, myśl..." - Kubuś Puchatek || "Manual, manual, manual..." - Kubuś Programista "Szukaj, szukaj, szukaj..." - Kubuś Odkrywca || "Debuguj, debuguj, debuguj..." - Kubuś Developer |
|
|
![]() ![]() |
![]() |
Aktualny czas: 19.08.2025 - 22:50 |