2011-02-13 149 views
45

在MySQL數據庫中存儲IP地址的最佳字段類型和長度是多少?在數據庫中存儲IP的最佳方法是什麼?

那麼IPv6呢?

+0

請參閱這裏的討論:http://stackoverflow.com/questions/444966/working-with-ipv6-addresses-in-php – 2011-02-13 07:54:49

+0

謝謝,這很好 – Mike 2011-02-13 09:19:02

回答

54

將ip存儲爲INT(11) UNSIGNED,然後使用INET_ATONINET_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*/ 
+6

在PHP方面,你可以嘗試`ip2long`和`long2ip`功能。 – Thai 2011-02-13 06:00:23

+0

我正在使用$ _SERVER ['REMOTE_ADDR']。所以我會做「INSERT表(IP)VALUES(INET_ATON($ _ SERVER ['REMOTE_ADDR']));」 ? – Mike 2011-02-13 06:02:15

15

這取決於你想用它做什麼,但可能是最簡單的方法是將其表示爲一個字符串。並且this question涵蓋了需要多少個字符來處理它。 (這是45)。

0

我完全Scrum的梅斯特同意最好方法是在INET功能使用INT(11) UNSIGNED具有存儲/檢索,但有時如果你不打算通過子網中查詢您可以選擇VARCHAR(45)

3

如果您計劃通過IP地址搜索數據庫,那麼INT將更快地進行查詢。如果你只是存儲顯示(例如在日誌輸出中),那麼字符串會更好,因爲你不需要來回轉換它。

5

IPv6地址是128位(16字節),所以你需要一個足夠大的字段來存儲它。此外,您可能需要一個字段來指示IP是IPv4還是IPv6(在IPv6中:: 192.168.4.10與IPv4中的192.168.4.10在數字上相同,但取決於您的應用程序,您可能需要區分這兩者) 。

如果您需要存儲子網,您可能需要存儲第一個地址,CIDR掩碼和計算出的子網的高位地址(廣播地址)。這將有助於搜索,以便您能如果您使用的子網,你還應該計算出下限自己,而不是僅僅依靠用戶做正確(僞代碼)做這樣的

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

查詢:

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

這適用於IPv4和IPv6。

6

如果您希望支持IPv6和IPv4,請將其存儲爲BINARY(16),然後在將IP地址插入數據庫之前轉換IP地址。例如,在PHP(通常用於MySQL的語言)中,您可以使用inet_pton()函數執行此操作。