2010-03-29 71 views
57

在MySQL中存儲和檢索IP地址的最有效方式是什麼?現在我在做:在MySQL中存儲IP地址的最有效方式

SELECT * FROM logins WHERE ip = '1.2.3.4' 

其中ip是一個VARCHAR(15)字段。

有沒有更好的方法來做到這一點?

+11

好的,所以你的程序壞掉了,或者根本不能用IPv6 ......嘆氣。 – Juliano 2010-03-29 23:55:22

回答

95

IPv4 addresses,你可能需要將它們存儲爲一個int unsigned,並使用INET_ATON()INET_NTOA()功能,從它的數值返回的IP地址,反之亦然。

例子:

SELECT INET_ATON('127.0.0.1'); 

+------------------------+ 
| INET_ATON('127.0.0.1') | 
+------------------------+ 
|    2130706433 | 
+------------------------+ 
1 row in set (0.00 sec) 


SELECT INET_NTOA('2130706433'); 

+-------------------------+ 
| INET_NTOA('2130706433') | 
+-------------------------+ 
| 127.0.0.1    | 
+-------------------------+ 
1 row in set (0.02 sec) 
+4

您不會將其存儲爲「INT」,而是存儲爲「INT UNSIGNED」。儘管我喜歡使用故意內置的功能。 +1 – pstanton 2010-03-30 00:11:14

+0

謝謝。你知道這是否有一個Python函數? – ensnare 2010-03-30 00:48:01

+0

@ensnare:是的,請查看:http://snipplr.com/view/14807/convert-ip-to-int-and-int-to-ip/。 – 2010-03-30 00:53:34

4

最重要的是確保列被索引。這可能會對基於IP地址的查詢產生巨大影響。

+0

我的理解是varchar上的索引是有限的幫助。 – flickerfly 2016-02-29 17:30:02

1

也許將整數值直接存儲在整數字段中?一個IP地址基本上是4「短褲」。

檢查出來:http://en.kioskea.net/faq/945-converting-a-32-bit-integer-into-ip

+0

所以他會把它存儲在四個領域?他們會是字節,不是?每次2^8 或者,他可以將它們轉換爲十進制數並存儲小數,儘管這將是一個更大的字段,它將是一個字段。 – jcolebrand 2010-03-29 23:55:04

+1

更合適的方言將是IP地址是4個字節。 – 2010-03-29 23:58:30

+0

我明白了。布賴恩的說法是,概念上的一個整數由四個短褲組成。短是一個字節。一個int是4個字節。如本頁其他地方所說,它需要是一個unsigned int。 – joe 2016-02-29 23:59:43

52

如果你只是想存儲IPv4地址,那麼你可以將它們存儲在一個32位整型字段。

如果你也想支持IPv6,那麼一個字符串可能是最易於閱讀/使用的方式(儘管你可以在技術上將它們存儲在一個16字節的VARBINARY()字段中,但如果試圖生成SQL語句可通過IP地址「手動」進行選擇)

+18

+1:預測IPv6使用的唯一答案 – Juliano 2010-03-30 00:02:42

+3

正當使用IPV6的功能不同(INET6_ATON(ip))。 IPV4需要VARBINARY(4)和IPV6需要VARBINARY(16)(當然也適用於V4地址)。 您可以將V4 IP(INT)轉換爲兼容格式,如下所示:INET6_ATON(INET_NTOA(ip)) – John 2014-09-24 14:35:18

1

無論您使用什麼最簡單的方法。除非您知道這是分析問題,否則大小或速度問題不是問題。在某些情況下,如果需要進行部分匹配,字符串可能更容易處理。但作爲空間或性能問題,除非您真的有理由擔心它,否則不要擔心。