จัดเรียง IP Address ให้ถูกต้องตามค่าตัวเลขด้วย INET_ATON()
IP Address เป็น String การ ORDER BY ip ASC แบบ String จะได้ลำดับผิด (เช่น 192.168.1.100 < 192.168.1.2 เพราะ '1' < '2') ใช้ INET_ATON() แปลง IPv4 เป็น Unsigned Integer แล้ว ORDER BY
สร้างตารางและข้อมูล
mysql> CREATE TABLE DemoTable (IpAddress VARCHAR(50));
Query OK, 0 rows affected (1.36 sec)
mysql> INSERT INTO DemoTable VALUES
-> ('192.168.110.78'), ('192.168.110.87'), ('192.168.110.75');
Query OK, 3 rows affected
ข้อมูลก่อนเรียง (String Order)
+----------------+ | IpAddress | +----------------+ | 192.168.110.78 | | 192.168.110.87 | | 192.168.110.75 | +----------------+
คำสั่ง: ORDER BY INET_ATON(IpAddress)
mysql> SELECT * FROM DemoTable ORDER BY INET_ATON(IpAddress);
ผลลัพธ์: เรียงถูกต้องตามค่าตัวเลข
+----------------+ | IpAddress | +----------------+ | 192.168.110.75 | | 192.168.110.78 | | 192.168.110.87 | +----------------+
คำอธิบาย INET_ATON()
- แปลง IPv4 Address (Dotted Quad) เป็น Unsigned 32-bit Integer
INET_ATON('192.168.110.75')= 192×256³ + 168×256² + 110×256 + 75 = 3232236107- ฟังก์นันคืนค่า NULL หาก IP ไม่ถูกต้อง
ฟังก์ชันคู่: INET_NTOA() (Integer → IP String)
mysql> SELECT INET_NTOA(3232236107); +-----------------------+ | INET_NTOA(3232236107) | +-----------------------+ | 192.168.110.75 | +-----------------------+
⚠️ ข้อจำกัด
- รองรับเฉพาะ IPv4 ไม่รองรับ IPv6
- IPv6 ใช้
INET6_ATON()/INET6_NTOA()(คืนค่า VARBINARY/HEX) - Performance: INET_ATON() เรียกทุกแถว → หาก Query บ่อย ควรเพิ่ม Generated Column + Index
Optimization: Generated Column + Index (MySQL 5.7+)
ALTER TABLE DemoTable ADD COLUMN ip_int INT UNSIGNED AS (INET_ATON(IpAddress)) STORED, ADD INDEX idx_ip_int (ip_int); -- Query เร็วขึ้น SELECT * FROM DemoTable ORDER BY ip_int;
การใช้งานใน Application (Java Example)
// แปลง IP String → Long สำหรับ Query
long ipLong = ipToLong("192.168.110.75");
public static long ipToLong(String ip) {
String[] octets = ip.split("\\.");
long result = 0;
for (String octet : octets) {
result = (result << 8) + Integer.parseInt(octet);
}
return result;
}