Подтвердить что ты не робот

Лучший способ сохранить IP-адрес в базе данных?

Каков наилучший тип поля и длина для хранения IP-адресов в базе данных MySQL?

Как насчет IPv6?

4b9b3361

Ответ 1

Сохраните ip как INT(11) UNSIGNED, затем используйте INET_ATON и INET_NTOA для сохранения/получения IP-адреса.

Пример кода:

INSERT table(ip) VALUES (INET_ATON('192.168.0.1')); /*ip = 3232235521*/
SELECT INET_NTOA(ip) As IPAddress FROM table; /*IPAddress = 192.168.0.1*/

Ответ 2

Это зависит от того, что вы хотите с ним сделать, но, вероятно, самым простым способом было бы представлять его как строку. И этот вопрос охватывает количество символов, необходимых для его обработки. (Это 45).

Ответ 3

Если вы хотите, чтобы поддержка как IPv6, так и IPv4 сохраняла его как BINARY(16) и конвертировала IP-адрес, прежде чем вставлять его в базу данных. Например, в PHP (langugage, обычно используемом с MySQL) вы можете сделать это с помощью inet_pton().

Ответ 4

Адреса IPv6 составляют 128 бит (16 байт), поэтому вам нужно поле, достаточно большое для хранения этого. Кроме того, вам может понадобиться поле, указывающее, является ли IP-адрес IPv4 или IPv6 (:: 192.168.4.10 в IPv6, в числовом формате, таким же, как 192.168.4.10 в IPv4, но в зависимости от вашего приложения вам может потребоваться провести различие между ними).

Если вам нужно сохранить подсети, вы можете захотеть сохранить первый адрес, маску CIDR и вычисленный верхний адрес (широковещательный адрес) подсети. Это поможет в поиске, чтобы вы могли делать такие запросы

SELECT * FROM networks WHERE lowerBound<=MYIP AND upperBound>=MYIP

Если вы используете подсети, вы также должны вычислить, что нижняя граница сама, а не просто полагаться на правильное выполнение пользователем (псевдокод):

lowerBound = AND(networkAddress, subnetMask)
upperBound = OR(lowerBound, complement(subnetMask))

Это относится как к IPv4, так и к IPv6.

Ответ 5

Если вы планируете искать базу данных по IP-адресу, тогда INT будет намного быстрее запрашивать. Если вы просто сохраняете для отображения (например, в выходном логе), тогда строка будет лучше, так как вам не нужно ее конвертировать назад и вперед.

Ответ 6

Я полностью согласен с Scrum Meister в том, что лучший способ использовать INT(11) UNSIGNED с сохранением/извлечением в функциях INET, но иногда, если вы не собираетесь запрашивать подсеть, вы можете выберите VARCHAR(45)