Witaj Gościu! ( Zaloguj | Rejestruj )

Forum PHP.pl

> Jak trzymać miasta w osobnej tabeli i umozliwiść sortowanie według miast w innej tabeli, Tabela 'users' którą chce sortować po mieście trzymane w tab.
Sajrox
post 13.05.2010, 20:57:33
Post #1





Grupa: Zarejestrowani
Postów: 254
Pomógł: 7
Dołączył: 9.10.2007
Skąd: Poznań

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


Witam,

Jak trzymać miasta w bazie. Otóż mam tabele 'users', każdy użytkownik ma swoje miasto. Pytanie czy poniższe rozwiązanie jest optymalne.

Chce zrobić tak:
Utworzyć tabelę 'cities' z polami:
id | city

id - zawiera nazwe miasta bez polskich znaków i będzie kluczem dla każdego miasta
city - zawiera poprawną nazwę miasta z polskimi znakami


Tabela 'users' w polu 'cities_id' będzie zawierać włąśnie klucz obcy miasta (czyli wartość z pola 'id' z tabeli 'cities')
Dlaczego jako klucza nie chce używać liczby INT, ponieważ dzięki klucza w formie jak wyżej można będzie sortować użytkowników po mieście.
W przypadku klucza typu INT sortowanie odpada. Gdyż w polu 'cities_id' w tabeli 'users' nie ma możliwości sortowania w ten sposób po mieście.
Go to the top of the page
+Quote Post
 
Start new topic
Odpowiedzi (1 - 6)
Wicepsik
post 13.05.2010, 21:03:16
Post #2





Grupa: Zarejestrowani
Postów: 1 575
Pomógł: 299
Dołączył: 26.03.2009

Ostrzeżenie: (20%)
X----


tabela users
id_user, name, id_city

tabela cities
id, city


  1. SELECT u.name, c.city FROM users u, cities c WHERE c.id = u.id_city ORDER BY c.city ASC


Zrób to na kluczach INT.

Ten post edytował Wicepsik 13.05.2010, 21:04:19


--------------------
Go to the top of the page
+Quote Post
Sajrox
post 13.05.2010, 21:08:23
Post #3





Grupa: Zarejestrowani
Postów: 254
Pomógł: 7
Dołączył: 9.10.2007
Skąd: Poznań

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


Tak tylko że jak w bazie users będę miał np milion użytkowników, to baza zdechnie delikatnie mówiąc.

Rozważam takie zapytanie na kluczu jako INT

  1. SELECT u.name, c.city FROM cities c LEFT JOIN users u ON c.id = u.id_city, WHERE c.id = u.id_city ORDER BY c.city ASC

I index na pole city w tabeli 'cities'

Chociaż jeśli dobrze myślę że index nie zadziała tak jak powinień, zadziała dla tabeli cities ale użytkownicy i tak będą sortowane beż użycia jakiegoś indexu tzn wolno (mówiąc o milion uzytkownikach)
Go to the top of the page
+Quote Post
phpion
post 14.05.2010, 08:56:41
Post #4





Grupa: Moderatorzy
Postów: 6 072
Pomógł: 861
Dołączył: 10.12.2003
Skąd: Dąbrowa Górnicza




W Twoim zapytaniu powinieneś mieć utworzone 2 indeksy:
1. na kluczu obcym w tabeli użytkowników łączących rekord z tabelą miast.
2. na nazwie miasta w tabeli miast.

Jeśli dodatkowo chciałbyś sortować użytkowników również po nazwie użytkownika to załóż indeks na to pole (najlepiej unikalny).

PS: Ten dodatkowy WHERE jest kompletnie zbędny, a dodatkowo połączenie LEFT JOIN + ten WHERE da tak naprawdę samo JOIN (czyli jeśli użytkownik nie ma przypisanego miasta to nie zostanie wyświetlony).
Go to the top of the page
+Quote Post
Sajrox
post 14.05.2010, 21:51:20
Post #5





Grupa: Zarejestrowani
Postów: 254
Pomógł: 7
Dołączył: 9.10.2007
Skąd: Poznań

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


Racja ten WHERE nie jest tam potrzebny, Mały błąd smile.gif

Właśnie przeprowadziłem testy;
Do bazy users dodałem około 3 mln użytkowników, każdy ma jakieś miasto
Miast jest ponad 100.

Teraz zapytanie SQL:
  1. SELECT `u`.`name`, `u`.`surname`, `c`.`city` FROM `users` AS `u` INNER JOIN `cities` AS `c` ON u.id_city=c.id_city ORDER BY `c`.`city` DESC LIMIT 20


Dodałem idexy na pola:
id_city w tabeli users
city w tabeli cities

Zapytanie wykonuje się powyżej 30 sekund, czyli powyżej normy :/

Może jakieś pomysły ?

Go to the top of the page
+Quote Post
matix
post 20.05.2010, 20:37:13
Post #6





Grupa: Zarejestrowani
Postów: 278
Pomógł: 10
Dołączył: 13.02.2007
Skąd: Rybnik

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


Możesz spróbować stworzyć widok, który będzie połączeniem tych dwóch tabel. Spróbuj - powinno być szybciej ze względu na wbudowany system cachowania.

Pzdr.


--------------------
Nawet, jeżeli nie jesteś zainteresowany usługami IT ani outsourcingiem, a Twoją pasją jest programowanie - zobacz naszą stronę. Piszemy dużo fajnych use-caseów, jak podchodzimy do tematu programowania dla naszych klientów. A tak na co dzień tworzymy budujemy mvp oraz tworzymy platformę b2b.
Go to the top of the page
+Quote Post
Sajrox
post 23.05.2010, 15:44:56
Post #7





Grupa: Zarejestrowani
Postów: 254
Pomógł: 7
Dołączył: 9.10.2007
Skąd: Poznań

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


Zauważyłem że zmiana z INNER JOIN na RIGHT JOIN spowodowało że czas spadłz okolo 35 s. do 0.04 s

  1. SELECT `u`.`name`, `u`.`surname`, `c`.`city` FROM `users` AS `u` RIGHT JOIN `cities` AS `c` ON u.id_city=c.id_city ORDER BY `c`.`city` DESC LIMIT 20


Z tego wynika że pole po którym następuje sortowanie musi pochodzić z 1 tabeli wiec w tym wypadku jest nią tabela 'cities'.
Wydaje mi się że o to chodziło smile.gif
Go to the top of the page
+Quote Post

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

 



RSS Wersja Lo-Fi Aktualny czas: 14.08.2025 - 15:19