在Microsoft SQL Server中存储IP地址

8

我知道关于这个话题已经有很多问题了,但我可能有一些额外的问题。

我想把IP地址存储在数据库中(如果可能的话,只用单列)。我想能够存储IPv4或IPv6地址。我希望在检索时能够区分IPv4和IPv6地址。

我考虑过的方法:

  • 使用VARCHAR(45)以文本格式存储IP地址。 IPv4地址的文本表示的最大长度为15个字符。 IPv6地址的文本表示的最大长度为39个字符,尽管我读到它们实际上可以高达45个字符,当它们代理IPv4地址时(我不熟悉这个,所以我可能会错),某些软件的头文件似乎反映了这一点,指定IPv6地址的最大长度为46(45 + \0)。两种格式之间的区别微不足道。

  • 将IP地址存储在两个bigint列中。这比文本格式使用更少的空间。区分格式-如果第一列为0或NULL(虽然性能不佳),则是IPv4地址,否则是IPv6地址?

  • 将IP地址存储在uniqueidentifier列中。 128位,可以以最紧凑的方式存储两种地址格式(我们在IPv4地址上浪费了96位,但无论我们做什么都无法避免这种情况)。这种方式似乎是最可取的,但是,对于任何128位整数,是否可能知道该128位整数表示IPv4还是IPv6地址?

如果可以区分表示为单个128位整数的IPv4和IPv6地址,则我更喜欢使用第三种方法,除非该解决方案存在任何主要问题。我想我的主要问题是是否可能,但听到有关不同方法(包括我没有在此列出的方法)的优缺点的任何想法也会很有帮助。

另外...如果必要,在第三种方法中添加一个位列来区分IPv4和IPv6是否是一个好主意?位列实际上是1位还是8位?


请参见https://dev59.com/CFnUa4cB1Zd3GeqPXBbr。 - Owen Blacker
这个回答解决了你的问题吗?在SQL Server中存储IP地址的数据类型 - apaderno
1个回答

6
我可以将其存储为二进制。IPv6地址长度为128位,即16字节。如果要存储IPv4地址,则应将其存储在最后4个字节中。当您在应用程序中使用此字段时,有许多内置选项可用于从IPv6转换为文本,以及从文本转换回IPv6二进制。
对于IPv4情况:该地址类型的前80位(10字节)设置为零,接下来的16位(2字节)设置为1(0xFF),而其最后32位(4字节)则填充了IPv4地址。堆栈实现通常有所不同,因此您应该在客户端进行转换(从IPv6到IPv4)。此地址空间是安全的,因此保留了IPv4寻址。 更多信息更多信息

1
那么,如果一个128位整数的前96位是0,那么它一定是最初的IPv4地址吗?还是也可能是IPv6地址? - Jake Petroules
这是答案:这里。这种地址类型的前80位设为0,接下来的16位设置为1,而最后32位则填充IPv4地址。堆栈实现通常有所不同,因此您应该在客户端进行转换(从IPv6到IPv4)。这很容易,因为您应该使用前4个字节进行寻址。 - Naszta
@Jake Petroules: “或者也可能是IPv6地址吗?” 不,这个地址空间是保留给IPv4地址的。 - Naszta

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接