Witaj Gościu! ( Zaloguj | Rejestruj )

Forum PHP.pl

> Lokalizacja obiektu po wspolrzednych
prowseed
post 21.09.2012, 13:13:45
Post #1





Grupa: Zarejestrowani
Postów: 433
Pomógł: 64
Dołączył: 29.01.2011
Skąd: Warszawa

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


Witam,
mam dosc nietypowy problem i nie wiem jak sobie z nim poradzic. Dodam, ze uzycie bazy z zalozenia bedzie duze i boje sie, ze zrobie to nieoptymalnie...
Ale do rzeczy: Mam tabelę z listą obiektów, która wygląda tak:

[ id | name ]

oraz tabelę właściwości, która prezentuje się tak:

[ id | object_id | attribute | value ]

Atrybutów dla jednego object_id jest bardzo dużo, między innymi znajduje się tam latitude i longitude, czyli przykładowe wiersze:

[ 45 | 11 | lat | 55.423423 ]
[ 46 | 11 | lng | 21.102234 ]


Baza w taki sposób była budowana dość długo, a teraz ma dojść, że tak powiem feature lokalizacji obiektów za pomocą funkcji haversina, która wykonuje się mniej więcej tak:
haversine_distance(lat_0, lng_0, lat, lng) < 40
Zwraca ona true lub false w zależności od tego, czy dany punkt lat,lng znajduje się w promienu 40 kilometrów od lat_0,lng_0

Zdaję sobie sprawę, że jest to nieoptymalne i najłatwiejszą rzeczą byłoby posiadanie tabeli obiektów w postaci [ id | name | lat | lng ] ( co w ostateczności uczynię )
ale jest jak jest, do tego są już wszystkie mechanizmy i bardziej mi się na chwilę obecną czasowo opłaca zrobić nieludzkie zapytanie niż zmieniać konstrukcję aplikacji.
Tylko... Nie wiem jak owe zapytanie zbudować :/
Do tej pory zapytania wyglądały mniej więcej jakoś tak:

  1. SELECT id
  2. FROM objects
  3. INNER JOIN objects_attr m1
  4. ON ( objects.id = m1.object_id )
  5. WHERE
  6. objects.id > 2233
  7. AND ( m1.attribute = 'lat' AND m1.value < 60 )
  8. AND ( m1.attribute = 'lon' AND m1.value < 30 )


Czy jest jakaś możliwość połączenia tego zapytania z funkcją haversina która de facto musi sprawdzić obie wartości value występujące powyżej?

Jeżeli się nie jasno wyraziłem, to mówić- doprecyzuję, sam nie jestem w stanie sprawdzić, bo już mnie głowa boli od myślenia :s
Dzięki za pomoc.


--------------------
Go to the top of the page
+Quote Post
 
Start new topic
Odpowiedzi (1 - 3)
kayman
post 21.09.2012, 14:24:07
Post #2





Grupa: Zarejestrowani
Postów: 556
Pomógł: 40
Dołączył: 20.07.2012
Skąd: Warszawa

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


nie wiem czy to dobrze zrozumiałem

  1. SELECT id
  2. FROM objects
  3. INNER JOIN objects_attr m1
  4. ON ( objects.id = m1.object_id AND ( m1.attribute = 'lat' AND m1.value < 60 ) AND ( m1.attribute = 'lon' AND m1.value < 30 ))
  5. WHERE
  6. objects.id > 2233
Go to the top of the page
+Quote Post
prowseed
post 21.09.2012, 14:44:46
Post #3





Grupa: Zarejestrowani
Postów: 433
Pomógł: 64
Dołączył: 29.01.2011
Skąd: Warszawa

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


Ok, tylko nie zapomnij jeszcze o tej nieszczęsnej funkcji ; )

haversine_distance(lat_0, lng_0, lat, lng) < 40

gdzie lat to value dla attribute = lat, a lng to value dla attribute = lng


--------------------
Go to the top of the page
+Quote Post
Crozin
post 21.09.2012, 14:52:42
Post #4





Grupa: Zarejestrowani
Postów: 6 476
Pomógł: 1306
Dołączył: 6.08.2006
Skąd: Kraków

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


Jak sam zauważyłeś, struktura tabeli jest beznadziejna i raczej powinieneś dążyć do jak najszybszego poprawienia jej. Jednak, jeżeli to nie jest możliwe możesz zrobić następującą "protezę":
1. Do tabeli z obiektami dodaj kolumny longitude, latitude z założonym odpowiednim indeksem. Kolumny te będą służyć wyłącznie za kopię danych z tabeli z atrybutami. Dzięki temu cała reszta aplikacji będzie mogła działać tak jak do tej pory, a wyszukiwanie na podstawie odległości będzie mogło korzystać z "normalnej" struktury.
2. Utwórz triggery AFTER INSERT|UPDATE|DELETE dla tabeli z atrybutami, które będą aktualizowały dane w tabeli z obiektami.

O ile aplikacja nie jest napisana w jakiś tragiczny sposób, taka zmiana nie powinna mieć żadnego wpływu na działanie aplikacji.
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 - 11:19