統計分析中常需按 IP 段聚合,MySQL 內建 INET_ATON()(IP→數字)與 INET_NTOA()(數字→IP)完美支援 IPv4 轉換。本文驗證轉換算法、短格式支援、儲存類型建議與實戰查寫模式。
| 函數 | 輸入 | 輸出 | 說明 |
|---|---|---|---|
INET_ATON(expr) | 字符串 'a.b.c.d' | 無符號長整數 | 網絡字節序:a×256³ + b×256² + c×256¹ + d×256⁰ |
INET_NTOA(expr) | 數字 | 字符串 'a.b.c.d' | INET_ATON 逆運算 |
mysql> SELECT INET_NTOA(3507806248);
+-----------------------+
| INET_NTOA(3507806248) |
+-----------------------+
| 209.20.224.40 |
+-----------------------+
-- 手動驗算
mysql> SELECT 209*POW(256,3) + 20*POW(256,2) + 224*POW(256,1) + 40*POW(256,0);
+------------------------------------------------------------+
| 209*POW(256,3)+20*POW(256,2)+224*POW(256,1)+40*POW(256,0) |
+------------------------------------------------------------+
| 3507806248 |
+------------------------------------------------------------+
⚠️ 原文驗算用 207 而非 20,導致結果 3520061480 不匹配。正確第二段為 20。
mysql> SELECT INET_ATON('127.0.0.1'), INET_ATON('127.1');
+------------------------+--------------------+
| INET_ATON('127.0.0.1') | INET_ATON('127.1') |
+------------------------+--------------------+
| 2130706433 | 2130706433 |
+------------------------+--------------------+
127.1 等價於 127.0.0.1,中間兩段自動補 0。
IPv4 最大值 255.255.255.255 → 4294967295,超過有符號 INT 最大值 2147483647。
| 類型 | 範圍 | 能否存儲全 IPv4 | 建議 |
|---|---|---|---|
| INT SIGNED | -2147483648 ~ 2147483647 | ❌ 截斷 | 不建議 |
| INT UNSIGNED | 0 ~ 4294967295 | ✅ 精確 | 推薦 |
| BIGINT | 更大 | ✅ 精確 | 兼容 IPv6 擴展 |
最佳實踐: ip_int INT UNSIGNED NOT NULL 或 BIGINT。
INSERT INTO access_log (ip_int, url) VALUES (INET_ATON('192.168.1.100'), '/index');
-- 或應用層轉換後傳參,減少 DB CPU
SELECT INET_NTOA(ip_int) AS ip, COUNT(*) AS pv
FROM access_log
WHERE log_date = CURDATE()
GROUP BY ip_int
ORDER BY pv DESC LIMIT 10;
-- 查詢 192.168.1.0/24 網段
SELECT * FROM access_log
WHERE ip_int BETWEEN INET_ATON('192.168.1.0') AND INET_ATON('192.168.1.255');
配合 ip_int 索引,範圍查詢極快,避免 LIKE '192.168.1.%' 全表掃描。
MySQL 5.6+ 支援 INET6_ATON() / INET6_NTOA() 返回 VARBINARY(16),儲存建議用 VARBINARY(16) 或 BINARY(16)。
掌握 IP 數字化存儲與查詢,是日誌分析、風控畫像、網絡審計場景的核心技能。