Computer >> บทช่วยสอนคอมพิวเตอร์ >  >> การเขียนโปรแกรม >> MySQL

เรียงลำดับ IP Address ใน MySQL ด้วย INET_ATON()

จัดเรียง 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;
}