如何在MySQL的单个列中存储128位数字?

Ton*_*yer 36 mysql types ipv6

我正在更改一些表以将IP地址存储为数字而不是字符串.这对于IPv4来说很简单,其中32位地址可以适合整数列.但是,IPv6地址是128位.

MySQL文档仅示出了数字类型多达64个比特("BIGINT").

我应该坚持使用char/varchar进行IPv6吗?(理想情况下,我想对IPv4和IPv6使用相同的列,所以我不想这样做).

有没有比使用两个bigint列更好的东西?每当使用地址时,我宁愿不必将值分解为上限和下限/ 64.

我正在使用MariaDB 5.1 - 如果在更高版本的MySQL中有更好的解决方案,那么很高兴知道,虽然没有立即帮助.

[编辑]请注意,我建议采用最佳方式执行此操作 - 很明显,有多种方法可以做到这一点(包括现有的字符串表示),但是(在性能方面)最好?(即如果某人已经完成了分析,这将使我无法做到这一点,或者如果我遗漏了一些明显的东西,那么知道也很好).

Jak*_*ake 44

我发现自己在问这个问题,从我读过的所有帖子中都没有找到任何性能比较.所以这是我的尝试.

我创建了以下表格,填充了来自100个随机网络的2,000,000随机IP地址.

CREATE TABLE ipv6_address_binary (
    id SERIAL NOT NULL AUTO_INCREMENT PRIMARY KEY,
    addr BINARY(16) NOT NULL UNIQUE
);

CREATE TABLE ipv6_address_twobigints (
    id SERIAL NOT NULL AUTO_INCREMENT PRIMARY KEY,
    haddr BIGINT UNSIGNED NOT NULL,
    laddr BIGINT UNSIGNED NOT NULL,
    UNIQUE uidx (haddr, laddr)
);

CREATE TABLE ipv6_address_decimal (
    id SERIAL NOT NULL AUTO_INCREMENT PRIMARY KEY,
    addr DECIMAL(39,0) NOT NULL UNIQUE
);
Run Code Online (Sandbox Code Playgroud)

然后我选择每个网络的所有IP地址并记录响应时间.twobigints表上的平均响应时间约为1秒,而二进制表上的平均响应时间约为百分之一秒.

这是查询.

注意:

X_ [HIGH/LOW]是X的最高/最低有效64位

当NETMASK_LOW为0时,省略AND条件,因为它总是产生true.不会对性能产生太大影响.

SELECT COUNT(*) FROM ipv6_address_twobigints
WHERE haddr & NETMASK_HIGH = NETWORK_HIGH
AND laddr & NETMASK_LOW = NETWORK_LOW

SELECT COUNT(*) FROM ipv6_address_binary
WHERE addr >= NETWORK
AND addr <= BROADCAST

SELECT COUNT(*) FROM ipv6_address_decimal
WHERE addr >= NETWORK
AND addr <= BROADCAST
Run Code Online (Sandbox Code Playgroud)

平均响应时间:

图形:

http://i.stack.imgur.com/5NJvQ.jpg

BINARY_InnoDB  0.0119529819489
BINARY_MyISAM  0.0139244818687
DECIMAL_InnoDB 0.017379629612
DECIMAL_MyISAM 0.0179929423332
BIGINT_InnoDB  0.782350552082
BIGINT_MyISAM  1.07809265852
Run Code Online (Sandbox Code Playgroud)


Bnj*_*jmn 3

引用:“你考虑过二进制(64)吗”

在 MySQL 中存储非常大的整数

  • 请注意 - 128 位是“二进制 (16)” - 您以字节表示大小。 (16认同)