2015-09-16 4 views
0

Я установил Maxmind GeoIP database, и теперь я тестирую результаты. Я живу в Амстердаме, поэтому я проверил проверку IP-адресов с помощью своего собственного IP-адреса, но получил 2 результата. Я что-то делаю неправильно или данные не ясны? ПримерБаза данных GeoIP SQL-запрос возвращает несколько результатов

База данных:

enter image description here

SQL-запрос:

SELECT * FROM wp_geoip WHERE '{my-ip-address}' BETWEEN begin_ip_num AND end_ip_num; 

Результаты:

enter image description here

ответ

1

вы не можете просто хранить IP-адреса в качестве VARCHAR. Ну ... вы можете, но это неправильно на чем-то фундаментальном уровне.

Правильное решение заключается в том, чтобы хранить IP-адреса в том виде, в каком они фактически представляют: 32-разрядные целые числа без знака (INT UNSIGNED).

Преобразование данных при импорте, используя INET_ATON() built-in function, который преобразует адрес IPv4 с точками в целое число без знака.

запроса данных с использованием обратной функции:

WHERE INET_NTOA('you.r.ip.add') BETWEEN begin_ip_num AND end_ip_num; 

вы получите более performanace если вы индексировать начала и конца колонны в обоих направлениях, например:

PRIMARY KEY(begin_ip_num,end_ip_num), 
KEY(end_ip_num,begin_ip_num) 

Однако ... B -Это не подходит для такого поиска.

Вы также сможете запросить его еще быстрее, если вы используете spatial index, как Jeremy Cole explains in a blog post on the topic. Обратите внимание, что он также подробно рассказывает об использовании INET_ATON() и INET_NTOA().

Концепция пространственного индекса взрывает умы некоторых людей, так как они предполагают, что «пространственными» означает лишь «гео пространственного», но IP-адрес пространство, в конце концов, все еще «пространство» и R-Tree индексов при условии пространственных расширений MySQL, гораздо более оптимальны, чем B-деревья для поиска границ «пространства», которые занимает вещь (например, IP-адрес).

+0

Спасибо за ответ! низкое знание MySQL. Поэтому, прежде чем я создал таблицу в phpmyadmin и загрузил CSV-файл с помощью инструмента импорта. Но когда вам нужно использовать встроенные функции, вы должны правильно создать сценарий импорта? С чего начать? – Robbert

+0

You может начать с уже имеющейся таблицы. Создайте новую таблицу с нужной структурой и столбцами в той же позиции, а затем используйте 'INSERT ... SELECT' t o копировать из таблицы в таблицу с преобразованием: 'INSERT INTO table2 SELECT INET_ATON (begin_ip_num), INET_ATON (end_ip_num), долгота, ... FROM table1;'. https://dev.mysql.com/doc/refman/5.6/en/insert-select.html –

+0

Да, это сработало. Большое спасибо! – Robbert

0

Возможно, он использует begin_ip_num и end_ip_num как поле varchar.

Таким образом, IP-адрес, начинающийся с 92,11 [...], также будет находиться между диапазоном в первой записи. Для первых записей он проверяет любую строку между и 92.3

Так что при текстовом поиске вы получите неправильные результаты в этом случае. Вы можете попытаться преобразовать все IP-адреса в хорошую строку с возможностью поиска. Это означает, что ip, например 92.31.255.255, должен быть преобразован в 092.031.255.255

Если вы сделаете это для всех своих IP-адресов, вы можете сделать правильный поиск по ним.

CREATE FUNCTION dbo.formatIP (@ip varchar(20)) 
RETURNS varchar(20) 
AS 
BEGIN 
    SELECT RIGHT('000' + PARSENAME(@ip,4), 3) + '.' + 
      RIGHT('000' + PARSENAME(@ip,3), 3) + '.' + 
      RIGHT('000' + PARSENAME(@ip,2), 3) + '.' + 
      RIGHT('000' + PARSENAME(@ip,1), 3) 
END 

Wrap, что в функции и использовать его как это:

SELECT * FROM wp_geoip 
WHERE dbo.formatIP('{my-ip-address}') 
    BETWEEN dbo.formatIP(begin_ip_num) AND dbo.formatIP(end_ip_num); 
+0

Спасибо за ваш ответ. Я попробую! Можно также изменить тип с varchar на unsigned int? – Robbert

+0

Я получил эту синтаксическую ошибку: # 1064 - У вас есть ошибка в синтаксисе SQL; проверьте руководство, соответствующее версии вашего сервера MySQL, для правильного синтаксиса для использования рядом с «@ip varchar (20)) RETURNS varchar (20) AS BEGIN SELECT RIGHT ('000' + PAR 'в строке 1 – Robbert

+0

I не видел, что речь идет о сервере MySQL. В вашем сообщении есть тег SQL-сервера. Я не уверен, как его переписать для MySQL. – SouthL

 Смежные вопросы

  • Нет связанных вопросов^_^