我需要将 128 位无符号整数存储到 MySQL 中,我想知道存储如此大数字的最佳数据类型是什么。
现在,我正在使用,binary(16)
但这涉及很多转换功能pack(/huge number in hex .../)
。
是否有最好的数据类型来存储 128 位无符号整数?
Joe*_*Joe 11
我不知道存储它的最佳方法是什么——但至少有一个比使用 a varchar(39)
(或者varchar(40)
如果你需要它签名)更好的选择;而是使用decimal(39,0)
. 从 mysql 文档:
定点(精确值)类型
DECIMAL 和 NUMERIC 类型存储精确的数字数据值。这些类型用于保持精确精度很重要的情况,例如货币数据。在 MySQL 中,NUMERIC 实现为 DECIMAL,因此以下关于 DECIMAL 的说明同样适用于 NUMERIC。
MySQL 5.1 以二进制格式存储 DECIMAL 值。在 MySQL 5.0.3 之前,它们被存储为字符串。请参见第 11.18 节,“精确数学”。
在 DECIMAL 列声明中,可以(并且通常是)指定精度和小数位数;例如:
Run Code Online (Sandbox Code Playgroud)salary DECIMAL(5,2)
在本例中,5 是精度,2 是比例。精度表示为值存储的有效位数,小数位数表示可以存储在小数点后的位数。
标准 SQL 要求 DECIMAL(5,2) 能够存储任何五位数和两位小数的值,因此可以存储在薪水列中的值范围从 -999.99 到 999.99。
在标准 SQL 中,语法 DECIMAL(M) 等效于 DECIMAL(M,0)。类似地,语法 DECIMAL 等效于 DECIMAL(M,0),其中允许实现决定 M 的值。 MySQL 支持这两种 DECIMAL 语法的变体形式。M 的默认值为 10。
如果小数位数为 0,则 DECIMAL 值不包含小数点或小数部分。
DECIMAL 的最大位数为 65,但给定 DECIMAL 列的实际范围可能受给定列的精度或小数位数限制。如果为此类列分配的值的小数点后位数超过指定比例所允许的位数,则该值将转换为该比例。(确切的行为是特定于操作系统的,但通常效果是截断到允许的位数。)
它是打包存储的,所以它占用的空间比 varchar 少(18 字节,如果我的数学正确的话),我希望你能直接对它进行数学运算,但我已经从来没有尝试过用这么大的数字来看看会发生什么。
小智 8
我发现自己在问这个问题,并且从我阅读的所有帖子中都没有找到任何性能比较。所以这是我的尝试。
我创建了以下表格,其中填充了来自 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 条件被省略,因为它总是产生真。对性能影响不大。
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)
平均响应时间:
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)
归档时间: |
|
查看次数: |
11540 次 |
最近记录: |