За последние 24 часа нас посетили 58417 программистов и 1780 роботов. Сейчас ищут 811 программистов ...

выборка ближайших объектов

Тема в разделе "PHP для новичков", создана пользователем vikrorpert, 11 сен 2016.

  1. vikrorpert

    vikrorpert Активный пользователь

    С нами с:
    13 окт 2010
    Сообщения:
    984
    Симпатии:
    10
    в базе есть объекты с полями широта\долгота
    нужно получить текущее положение юзера и отсортировать объекты от ближайших к дальним
    как лучше такое сделать?
     
  2. Fell-x27

    Fell-x27 Суперстар
    Команда форума Модератор

    С нами с:
    25 июл 2013
    Сообщения:
    12.156
    Симпатии:
    1.771
    Адрес:
    :сердА
    Это зависит от того, с чем имеете дело. Если просто сайтом, то мб GEOIP вам поможет. Но там точность, кхм, в городах измеряется.
    Выбрать из базы по условию "широта < $широта_пользователя + N_градусов" AND "широта > $широта_пользователя - N_градусов" AND то же самое с долготой. Получите выборку объектов в квадрате N*N от указанной точки. Ну а там уж либо на стороне сервера сортируйте, вычисляя расстояния по формуле, либо через SQL и хитрым ORDER BY..
     
    vikrorpert нравится это.
  3. vikrorpert

    vikrorpert Активный пользователь

    С нами с:
    13 окт 2010
    Сообщения:
    984
    Симпатии:
    10
    а как проще? GEOIP или на клиенте запросить местоположение?
     
  4. Ganzal

    Ganzal Суперстар
    Команда форума Модератор

    С нами с:
    15 мар 2007
    Сообщения:
    9.893
    Симпатии:
    965
    Клиент может и сам не знать своего местоположения. Проще конечно же по IP, но недостоверно для мобильных клиентов.
     
  5. vikrorpert

    vikrorpert Активный пользователь

    С нами с:
    13 окт 2010
    Сообщения:
    984
    Симпатии:
    10
    вроде есть функционал где браузер спрашивает отправить свое местоположение
     
  6. igordata

    igordata Суперстар
    Команда форума Модератор

    С нами с:
    18 мар 2010
    Сообщения:
    32.408
    Симпатии:
    1.768
    если браузер его знает
     
  7. Ganzal

    Ganzal Суперстар
    Команда форума Модератор

    С нами с:
    15 мар 2007
    Сообщения:
    9.893
    Симпатии:
    965
    @vikrorpert и дальше что?

    1) юзер может банально сказать "да пошел ты" - ответа не придет.
    2) у юзера может отключена служба чуть более точного геопозиционирования (гпс) чем через триангуляцию гсм - ответ будет содержать неверные данные с разбросом в несколько километров.
    3) у юзера включена счбтг (гпс) ччт гсм, но облачность висит плотная и девайс не видит спутников. Ответа может вообще не придти, если нет альтернативы в виде гсм, или придти неточным силами пары спутников или гсм.
     
  8. vikrorpert

    vikrorpert Активный пользователь

    С нами с:
    13 окт 2010
    Сообщения:
    984
    Симпатии:
    10
    теперь не пойму как быть с выборкой
    "широта < $широта_пользователя + N_градусов" AND "широта > $широта_пользователя - N_градусов"
    что за N_градусов? и как потом отсортировать выбранные объекты от ближайшего к дальним?
     
  9. Ganzal

    Ganzal Суперстар
    Команда форума Модератор

    С нами с:
    15 мар 2007
    Сообщения:
    9.893
    Симпатии:
    965
    Н-градусов это максимальная дистанция относительно координаты пользователя. У тебя есть одна точка, она имеет координаты. Другая точка тоже имеет координаты. С учетом прямоугольности координатной системы - расстояние между точками условно равно гипотенузе треугольника, катеты которого просто параллельны осям координатной системы. "Условно равно" потому что Земля не плоская и не идеальный шар. У каждого градуса-минуты-секунды своя метрическая длина в зависимости от широты. Ну это детали. Через абсолютные значения дельт соответствующих координат получаешь длину гипотенузы (не в "градусах"), потом сортируешь по этим длинам - вот тебе и от ближнего к дальним.
     
    Fell-x27 и vikrorpert нравится это.
  10. vikrorpert

    vikrorpert Активный пользователь

    С нами с:
    13 окт 2010
    Сообщения:
    984
    Симпатии:
    10
    с градусом понятно.по сути чем больше градус тем больше объектов выберется?
    а что насчет сортировки?что почитать?
     
  11. Fell-x27

    Fell-x27 Суперстар
    Команда форума Модератор

    С нами с:
    25 июл 2013
    Сообщения:
    12.156
    Симпатии:
    1.771
    Адрес:
    :сердА
    @vikrorpert , вот теперь ты меня начал пугать. Следующий вопрос будет, случайно, не "что такое переменная"? Что с тобой случилось, ты за 6 лет начал учиться программировать в обратную сторону? О_о у тебя же не было таки проблем.

    Сортировка - это сортировка. В пыхе даже нативные средства для оной есть. На край - можно написать свою. Если объектов не тысячи, то сойдет даже "пузырек", который любой программист должен уметь написать самостоятельно с закрытыми глазами с нуля за 15 минут.
     
  12. igordata

    igordata Суперстар
    Команда форума Модератор

    С нами с:
    18 мар 2010
    Сообщения:
    32.408
    Симпатии:
    1.768
    тебе не всё равно? выбери тех, кто попадает в квадрат. Потом уже в пхп посчитай расстояние по прямой, это ж быстрая операция, шестой класс школы (или какой там). Отсортируешь по удалённости и готово.
     
  13. MiksIr

    MiksIr Активный пользователь

    С нами с:
    29 ноя 2006
    Сообщения:
    2.339
    Симпатии:
    44
  14. igordata

    igordata Суперстар
    Команда форума Модератор

    С нами с:
    18 мар 2010
    Сообщения:
    32.408
    Симпатии:
    1.768
    мне кажется двух циферок хватит за глаза. объектов наверное не миллион.
     
  15. MiksIr

    MiksIr Активный пользователь

    С нами с:
    29 ноя 2006
    Сообщения:
    2.339
    Симпатии:
    44
    "SELECT * FROM users" для проверки пароля тоже для кого-то нормально
     
  16. vikrorpert

    vikrorpert Активный пользователь

    С нами с:
    13 окт 2010
    Сообщения:
    984
    Симпатии:
    10
  17. igordata

    igordata Суперстар
    Команда форума Модератор

    С нами с:
    18 мар 2010
    Сообщения:
    32.408
    Симпатии:
    1.768
    максимализм и категоричность это не лучшие друзья
     
  18. vikrorpert

    vikrorpert Активный пользователь

    С нами с:
    13 окт 2010
    Сообщения:
    984
    Симпатии:
    10
    вот сам запрос
    Код (Text):
    1. SELECT id, ( 3959 * acos( cos( radians(37) ) * cos( radians( lat ) ) * cos( radians( lng ) - radians(-122) ) + sin( radians(37) ) * sin( radians( lat ) ) ) ) AS distance FROM markers HAVING distance < 25 ORDER BY distance LIMIT 0 , 20;
     
  19. Fell-x27

    Fell-x27 Суперстар
    Команда форума Модератор

    С нами с:
    25 июл 2013
    Сообщения:
    12.156
    Симпатии:
    1.771
    Адрес:
    :сердА
    Охохо...я могу ошибаться, но лучше бы ты это бомбанул в хранимую процедуру.
     
  20. vikrorpert

    vikrorpert Активный пользователь

    С нами с:
    13 окт 2010
    Сообщения:
    984
    Симпатии:
    10
    может тормозить если много записей?
     
  21. mkramer

    mkramer Суперстар
    Команда форума Модератор

    С нами с:
    20 июн 2012
    Сообщения:
    8.600
    Симпатии:
    1.764
    На скорость это не повлияет ведь? Только на читаемость?

    У самого сейчас такой запрос в проекте, не знаю, как будет под большой нагрузкой, но на локалке выбирает с нормальной скоростью. В базу специально нагнал 5000 тестовых записей - думаю, в реале не скоро столько организций наберёт проект. Хотя может позже нафигачу ещё тысяч 10000, пока хватает и так
     
  22. Fell-x27

    Fell-x27 Суперстар
    Команда форума Модератор

    С нами с:
    25 июл 2013
    Сообщения:
    12.156
    Симпатии:
    1.771
    Адрес:
    :сердА
    Тут ничего сказать не могу за скорость. Не приходилось на практике с такими выражениями работать. Просто программерская логика подсказывает, что функция должна быть функцией, а запрос должен быть запросом. И что в запросе спрашивать надо function(lng,lat), а не кучу раз lng и lat, но каждый раз по-своему. Запрос должен получить условия и вернуть результат. Логикой обработки и выражениями должен заниматься либо вопрощающий сервер, либо код, обернутый в хранимую процедуру.

    Опять же, из вопроса скорости - если на БД будет предполагаться большая нагрузка, то я бы, все же, вынес вычисления на сторону PHP. Если в будущем будет иметь место масштабирование, с последующим выносом БД на отдельный физический сервер, то лучше тратить процессорное время этого сервера на чисто выборки данных, без обработки.

    Более того, если в связку PHP<->MySQL будет добавлено третье звено, какой-нибудь мемкеш, то схема с вычислениями на стороне БД накроет эту затею тазом. Потому что кэшировать в оперативке координаты статичных объектов - вообще как нехрен делать. А вот кэшировать в оперативке расчетные значения, полученные на основании динамических данных, уникальных для каждого пользователя...это, я бы сказал, и глупо, и бессмысленно.

    Есть такой термин "холодный кэш". Это когда кэширование настроено, но кэш еще пустой, и, покуда он пустой, то каждый запрос к себе проксирует в БД и, в итоге, портит производительность и мешается, потому что не генерирует ничего, кроме оверхедов. Но, в ходе работы кэш постепенно прогревается, наполняясь актуальными данными и процент пробросов к БД снижается. В итоге мы получаем "прогретый" или "горячий" кэш. Кэш, у которого экономия на запросах к БД превышает внутренний оверхед, и в общем ускоряет работу системы в разы. Это именно то, чего пытаются добиться, устанавливая его.

    Так вот, в случае с расчетами на стороне БД у нас будет "вечнохолодный кэш". Его будет невозможно прогреть.
     
    #22 Fell-x27, 12 сен 2016
    Последнее редактирование: 12 сен 2016
  23. vikrorpert

    vikrorpert Активный пользователь

    С нами с:
    13 окт 2010
    Сообщения:
    984
    Симпатии:
    10
    разве не все равно кто будет считать- пхп или база?
     
  24. mkramer

    mkramer Суперстар
    Команда форума Модератор

    С нами с:
    20 июн 2012
    Сообщения:
    8.600
    Симпатии:
    1.764
    В прошлом проекте я так и сделал, но в новом мне нужно находить ближайшие объекты к координатам, введённым пользователем, а это выборка, и выборка с формулой. И вроде база не сильно страдает от этой формулы.
     
  25. Fell-x27

    Fell-x27 Суперстар
    Команда форума Модератор

    С нами с:
    25 июл 2013
    Сообщения:
    12.156
    Симпатии:
    1.771
    Адрес:
    :сердА
    А я простыню выше для чего написал? Ёлки-палки..
    Хочешь сказать, у тебя сложная формула в WHERE?
    --- Добавлено ---
    Просто у @vikrorpert формулы в WHERE нет, так что для него моя простыня актуальна. Для тебя, наверное нет.