What Is the Most Appropriate Data Type for Storing an Ip Address in SQL Server

What is the most appropriate data type for storing an IP address in SQL server?

Storing an IPv4 address as a binary(4) is truest to what it represents, and allows for easy subnet mask-style querying. However, it requires conversion in and out if you are actually after a text representation. In that case, you may prefer a string format.

A little-used SQL Server function that might help if you are storing as a string is PARSENAME, by the way. Not designed for IP addresses but perfectly suited to them. The call below will return '14':

SELECT PARSENAME('123.234.23.14', 1)

(numbering is right to left).

Datatype for storing ip address in SQL Server

The technically correct way to store IPv4 is binary(4), since that is what it actually is (no, not even an INT32/INT(4), the numeric textual form that we all know and love (255.255.255.255) being just the display conversion of its binary content).

If you do it this way, you will want functions to convert to and from the textual-display format:

Here's how to convert the textual display form to binary:

CREATE FUNCTION dbo.fnBinaryIPv4(@ip AS VARCHAR(15)) RETURNS BINARY(4)
AS
BEGIN
DECLARE @bin AS BINARY(4)

SELECT @bin = CAST( CAST( PARSENAME( @ip, 4 ) AS INTEGER) AS BINARY(1))
+ CAST( CAST( PARSENAME( @ip, 3 ) AS INTEGER) AS BINARY(1))
+ CAST( CAST( PARSENAME( @ip, 2 ) AS INTEGER) AS BINARY(1))
+ CAST( CAST( PARSENAME( @ip, 1 ) AS INTEGER) AS BINARY(1))

RETURN @bin
END
go

And here's how to convert the binary back to the textual display form:

CREATE FUNCTION dbo.fnDisplayIPv4(@ip AS BINARY(4)) RETURNS VARCHAR(15)
AS
BEGIN
DECLARE @str AS VARCHAR(15)

SELECT @str = CAST( CAST( SUBSTRING( @ip, 1, 1) AS INTEGER) AS VARCHAR(3) ) + '.'
+ CAST( CAST( SUBSTRING( @ip, 2, 1) AS INTEGER) AS VARCHAR(3) ) + '.'
+ CAST( CAST( SUBSTRING( @ip, 3, 1) AS INTEGER) AS VARCHAR(3) ) + '.'
+ CAST( CAST( SUBSTRING( @ip, 4, 1) AS INTEGER) AS VARCHAR(3) );

RETURN @str
END;
go

Here's a demo of how to use them:

SELECT dbo.fnBinaryIPv4('192.65.68.201')
--should return 0xC04144C9
go

SELECT dbo.fnDisplayIPv4( 0xC04144C9 )
-- should return '192.65.68.201'
go

Finally, when doing lookups and compares, always use the binary form if you want to be able to leverage your indexes.


UPDATE:

I wanted to add that one way to address the inherent performance problems of scalar UDFs in SQL Server, but still retain the code-reuse of a function is to use an iTVF (inline table-valued function) instead. Here's how the first function above (string to binary) can be re-written as an iTVF:

CREATE FUNCTION dbo.itvfBinaryIPv4(@ip AS VARCHAR(15)) RETURNS TABLE
AS RETURN (
SELECT CAST(
CAST( CAST( PARSENAME( @ip, 4 ) AS INTEGER) AS BINARY(1))
+ CAST( CAST( PARSENAME( @ip, 3 ) AS INTEGER) AS BINARY(1))
+ CAST( CAST( PARSENAME( @ip, 2 ) AS INTEGER) AS BINARY(1))
+ CAST( CAST( PARSENAME( @ip, 1 ) AS INTEGER) AS BINARY(1))
AS BINARY(4)) As bin
)
go

Here's it in the example:

SELECT bin FROM dbo.fnBinaryIPv4('192.65.68.201')
--should return 0xC04144C9
go

And here's how you would use it in an INSERT

INSERT INTo myIpTable
SELECT {other_column_values,...},
(SELECT bin FROM dbo.itvfBinaryIPv4('192.65.68.201'))

IP Address datatype

varchar(15) if you just want to store the IP and you don't have much data.

An IPv4 address is actually a 32 bit integer that can be converted to/from it's numeric form to display form. (The same is true for IPv6: it's a 128-bit integer).

If you stored it as binary(4) it would take up less space (4 bytes instead of 15); you could do IP range checks in your queries; and it would be faster to use as a condition in a select statement since the DB wouldnt have to do string comparisons.

The downside is you would need to convert the IP to it's integer form to use it with the DB; and you would have to convert it to it's display form before showing it to users. If you search a bit, I'm sure you'll find prewritten functions for this in whatever language you're using, but it's an extra step.

I would say either is ideal depending on your circumstances.

What is the ideal datatype to store IP address in a mysql table?

IPv4 addresses use 32 bits (4 bytes), IPv6 addresses use 128 bits (16 bytes). Thus, you can store their binary representation in BINARY(16) or VARBINARY(16) fields.

Also see my answer to the question IP address storing in mysql database. It also provides comments why you would choose one over the other.

Most efficient way to store IP Address in MySQL

For IPv4 addresses, you may want to store them as an int unsigned and use the INET_ATON() and INET_NTOA() functions to return the IP address from its numeric value, and vice versa.

Example:

SELECT INET_ATON('127.0.0.1');

+------------------------+
| INET_ATON('127.0.0.1') |
+------------------------+
| 2130706433 |
+------------------------+
1 row in set (0.00 sec)

SELECT INET_NTOA('2130706433');

+-------------------------+
| INET_NTOA('2130706433') |
+-------------------------+
| 127.0.0.1 |
+-------------------------+
1 row in set (0.02 sec)

Which MySQL datatype to use for an IP address?

Since IPv4 addresses are 4 byte long, you could use an INT (UNSIGNED) that has exactly 4 bytes:

`ipv4` INT UNSIGNED

And INET_ATON and INET_NTOA to convert them:

INSERT INTO `table` (`ipv4`) VALUES (INET_ATON("127.0.0.1"));
SELECT INET_NTOA(`ipv4`) FROM `table`;

For IPv6 addresses you could use a BINARY instead:

`ipv6` BINARY(16)

And use PHP’s inet_pton and inet_ntop for conversion:

'INSERT INTO `table` (`ipv6`) VALUES ("'.mysqli_real_escape_string(inet_pton('2001:4860:a005::68')).'")'
'SELECT `ipv6` FROM `table`'
$ipv6 = inet_pton($row['ipv6']);

Storing IP addresses in Microsoft SQL Server

I may store it in binary. An IPv6 address is 128bit -> 16 bytes long. If you store IPv4 address, you should store it at the last 4 bytes. When you use this field in application there are many built in options to convert from IPv6 to text and text back to IPv6 binary.

In IPv4 case: this address type has its first 80 bits (10 bytes) set to zero and the next 16 bits (2 bytes) set to one (0xFF), while its last 32 bits (4 bytes) are filled with the IPv4 address. The stack implementation usually differs, so you should make the conversions at client side (from IPv6 to IPv4). This address space is safe, so it is reserved for IPv4 addressing.

More info and more info.

Store IP Address in Data Base best way

"Octects in four tinyint columns." http://web.archive.org/web/20150511204915/http://sqlserver2000.databases.aspfaq.com/how-should-i-store-an-ip-address-in-sql-server.html

Max length for client ip address

For IPv4, you could get away with storing the 4 raw bytes of the IP address (each of the numbers between the periods in an IP address are 0-255, i.e., one byte). But then you would have to translate going in and out of the DB and that's messy.

IPv6 addresses are 128 bits (as opposed to 32 bits of IPv4 addresses). They are usually written as 8 groups of 4 hex digits separated by colons: 2001:0db8:85a3:0000:0000:8a2e:0370:7334. 39 characters is appropriate to store IPv6 addresses in this format.

Edit: However, there is a caveat, see @Deepak's answer for details about IPv4-mapped IPv6 addresses. (The correct maximum IPv6 string length is 45 characters.)



Related Topics



Leave a reply



Submit