Спасиб за статью. На самом деле SxGeo именно так и работает, потому у него и база очень компактная. Но кроме того там были еще некоторые оптимизации, чтобы хранить начало диапазона не в 4, а в 3 байтах, плюс дополнительный индекс. Ну это думаю уже в отдельной статье распишу детали.
Нет, я не видел особого смысла делать лишнее преобразование в базе, поэтому конвертилка работает с таблицей в которой обычные диапазоны. Планирую еще сделать чтобы можно было конвертить сразу из CSV, без предварительного загона данных в MySQL.
Товарищ phpdude, этот подход как раз и был опробован и создан под необходимостью работы с городами — см. ipgeobase российскую.
Если найдете серьезный баг или невозможность им пользоваться — скину 50 рублей на Ваш сотовый.
2 karellen: Это то очевидно. Ускорение идёт в процессе поиска, а не в дальнейших оптимизациях. А если у нас сайт, где юзеров много и они заходят на 1-2-3 страницы, то быстрый поиск крайне выгоден. Конечно лучше всего нативный.
При скольких тысячах хитов в секунду стоит вообще об этом беспокоиться, страшно подумать. Всегда ведь можно 1 раз посчитать для пользователя город по любому алгоритму, а потом записать его и хэш от IP в куку. Потом читать из куки, и, если хэш изменился, пересчитывать город. Это на 99.999% снизит объем обращений к геобазе. Разве нет?
Вот я как раз нечто подобное реализовал в open-source проекте IpLoc. Там берётся база GeoLiteCity c maxmind.com, приводится к оптимальному виду, и потом при помощи двух простых запросов по IP адресу получаются Страна + Город + координаты провайдера. На дешёвеньком хостинге такая штука находит нужный адрес за 1-3мс.
Ой, я что-то не до конца вчитался, у вас тут как-то совсем всё навёрнуто… Я исходил из того, что если отсортировать все диапазоны по ip_start, и далее забить на ip_end, а просто искать нужный диапозон запросом вида: SELECT locationId as id FROM '. $this->ipMasksTable. ' WHERE startIp < "'. sprintf('%u', ip2long($ip)). '" ORDER BY startIp DESC LIMIT 1, то с 99% процентной вероятностью результат будет правильным.
Плоский GeoIP или диапазон в одной колонке