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

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

Что относительно IPv6?

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

Сохраните 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*/ 

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

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

Адреса 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.

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

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