Каков наилучший тип и длина поля для хранения IP-адресов в базе данных MySQL?
Что относительно IPv6?
Сохраните 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)