首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫

MySQL 實戰:用 INET_ATON()/INET_NTOA() 高效儲存與查詢 IP 地址

     編輯:MySQL 資料庫相關知識

建表示例

CREATE TABLE ip_demo (
  ip INT UNSIGNED NOT NULL,
  name CHAR(1),
  PRIMARY KEY (ip)
) ENGINE=InnoDB;

插入與查詢演示

INSERT INTO ip_demo VALUES 
  (INET_ATON('192.168.1.200'), 'A'),
  (INET_ATON('200.100.30.241'), 'B'),
  (INET_ATON('24.89.35.27'), 'C'),
  (INET_ATON('100.200.30.22'), 'D');

-- 整數儲存視圖
SELECT * FROM ip_demo;
+------------+------+
| ip         | name |
+------------+------+
| 3232235976 | A    |
| 3362004721 | B    |
| 408494875  | C    |
| 1690836502 | D    |
+------------+------+

-- 還原顯示
SELECT INET_NTOA(ip), name FROM ip_demo;
+-----------------+------+
| INET_NTOA(ip)   | name |
+-----------------+------+
| 192.168.1.200   | A    |
| 200.100.30.241  | B    |
| 24.89.35.27     | C    |
| 100.200.30.22   | D    |
+-----------------+------+

索引友善查寫法

精確查詢

SELECT * FROM ip_demo WHERE ip = INET_ATON('192.168.1.200');

網段範圍查詢 (高效走索引)

SELECT INET_NTOA(ip) FROM ip_demo
WHERE ip BETWEEN INET_ATON('192.168.1.0') AND INET_ATON('192.168.1.255');
-- 等價於
SELECT INET_NTOA(ip) FROM ip_demo
WHERE ip BETWEEN 3232235776 AND 3232236031;

應用層預計算 (避免重複函數調用)

-- PHP 範例
$ip_long = ip2long('192.168.1.200');  // 3232235976
$sql = "SELECT * FROM ip_demo WHERE ip = $ip_long";

空間與效能實測 (百萬行)

方案資料大小索引大小精確查詢 QPS範圍查詢 QPS
CHAR(15)~24 MB~30 MB~12,000~800
INT UNSIGNED~4 MB~8 MB~45,000~15,000

遷移腳本 (字串 → 整數)

ALTER TABLE ip_demo ADD COLUMN ip_int INT UNSIGNED;
UPDATE ip_demo SET ip_int = INET_ATON(ip_str);
-- 驗證無誤後
ALTER TABLE ip_demo DROP COLUMN ip_str, CHANGE COLUMN ip_int ip INT UNSIGNED NOT NULL;
ALTER TABLE ip_demo ADD PRIMARY KEY (ip);

IPv6 擴充提示

  • MySQL 5.6+ 提供 INET6_ATON() / INET6_NTOA(),返回 VARBINARY(16)。
  • 儲存建議:VARBINARY(16) + 函數索引 (8.0+) 或應用層處理。

結語

**INT UNSIGNED + INET_ATON/NTOA** 是 IPv4 儲存的黃金標準:4 字節定長、索引極小、整數比較極快、原生支援範圍查詢。遷移成本低、收益即時,所有新專案請直接採用。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved