VillageSQL is a drop-in replacement for MySQL with extensions.
All examples in this guide work on VillageSQL. Install Now →
VARCHAR(45). It works, but it wastes space, does nothing to validate the format, and sorts lexicographically instead of numerically — so 192.168.1.10 sorts before 192.168.1.9. VillageSQL’s INET type fixes all of this and handles IPv4 and IPv6 in the same column.
The MySQL Default: VARCHAR
The straightforward approach:VARCHAR(45) stores whatever string you give it. There’s no validation — 'not-an-ip' inserts without error. Sorting doesn’t follow numerical order, and comparing against a subnet requires string manipulation or conversion functions.
The Standard Workaround: INT UNSIGNED + INET_ATON
For IPv4, MySQL’sINET_ATON() converts a dotted-decimal string to a 4-byte integer. This is compact and sorts correctly:
INT UNSIGNED can’t hold a 128-bit address. You’d need VARBINARY(16) and INET6_ATON() / INET6_NTOA() for IPv6, meaning a schema change when IPv6 support is needed.
With VillageSQL: The INET Type
VillageSQL’svsql_network_address extension adds a native INET type that stores both IPv4 and IPv6 addresses in a compact binary format — 7 bytes for IPv4, 19 bytes for IPv6 — with validation on insert.
Working with stored addresses
Indexing
Choosing a Storage Approach
For new schemas that need both IPv4 and IPv6 with built-in validation,
INET is the cleanest option. For IPv4-only schemas with no VillageSQL dependency, INT UNSIGNED with INET_ATON / INET_NTOA is the established approach.
For subnet queries against stored addresses, see Querying by Subnet in MySQL.
Frequently Asked Questions
Can INET store addresses with a netmask, like 192.168.1.5/24?
Yes.INET allows host bits — 192.168.1.5/24 is valid. If you want to enforce that host bits are zero (pure network addresses), use the CIDR type instead.
Does INET validate the address on insert?
Yes.inet_from_string('not-an-ip') returns NULL rather than storing garbage. If you pass NULL to an INET column with a NOT NULL constraint, the insert fails.
How does ORDER BY ip_address sort mixed IPv4/IPv6?
IPv4 addresses sort before IPv6 addresses. Within each family, addresses sort numerically. This matches PostgreSQL’s INET sort order.Is INET the same as PostgreSQL’s inet type?
Functionally yes — same types (INET, CIDR, MACADDR, MACADDR8), same function naming conventions, same validation rules. The main difference is that VillageSQL provides functions rather than operators for comparisons and subnet checks.Troubleshooting
See also
- IPv6 Storage in MySQL — unified IPv4 and IPv6 storage with the INET type
- Querying by Subnet in MySQL — filtering rows by network range using INET
- Geolocation Lookups by IP in MySQL — enriching IP addresses with geographic data

