<Issue> Hive 中的浮点数据类型
<Issue> Float data type in Hive
初始化数据:
CREATE TABLE `test.test_data`(
user VARCHAR(10),
amount FLOAT)
TBLPROPERTIES ('transactional'='true');
INSERT INTO `test.test_data`
SELECT 'sonnh', 300000000000
UNION ALL
SELECT 'sonnh1', 1000000000000
UNION ALL
SELECT 'sonnh2', 900000000000;
获取数据:
SELECT * FROM `test.test_data`
结果:
test.test_data.user test.test_data.amount
sonnh 299999986000
sonnh1 1000000000000
sonnh2 899999990000
我在使用上面的 float 数据类型时遇到问题。谁给我解释一下。
我认为这可以追溯到 Hive 如何存储浮点数、双精度数和小数点的基础知识。
- 十进制 - 根据文档 - 配置单元存储准确的数值。但实际上蜂巢存储几乎接近实际值,如果实际值超过比例、精度,则为 null。
- Double(8 字节,双精度)和 Float(4 字节,单精度)- 两者都是浮点数并存储非常接近的数值近似值。所以,如果它必须存储更高范围的东西,近似就不能正常工作。它可以存储大约从 -10^308 到 10^308.
因此,如果您需要财务应用程序,建议使用小数;如果您不关心舍入问题,请使用浮点数或双精度。
下面是对以上三种数据类型的实验。
CREATE TABLE tmp( a string, f FLOAT, db double, dc decimal(5,4) ) ;
insert into tmp SELECT 'id', 900000000000000000,900000000000000000,123.123 ;
insert into tmp SELECT 'id', 90000000,99900000000000000000,99.999 ;
insert into tmp SELECT 'id', 99123.456,9000000123.456,9.9999999 ;
insert into tmp SELECT 'id', 9999999123.456,500000,123.123 ;
insert into tmp SELECT 'id', 9999999000.456,99900000000000000000999999999999999.12349,9990.099999 ;
insert into tmp SELECT 'id', 9999999000.456,9990000000000000000099999999999.12349,90.999 ;
select * from tmp;
tmp.a tmp.f tmp.db tmp.dc
id 900000020000000000 900000000000000000 123.12300 -- notice that float column cant handle the data and showing different data.
id 90000000 99900000000000000000 99.99900 -- everything is fine because they are within range.
id 99123.45 9000000123.456 10.00000 -- decimal approximated the data to 10 which is very close to actual value.
id 9999999000 500000 123.12300 --all good
id 9999999000 9.99e+34 NULL --Decimal put null because it cant handle the data. Double approximated the data to E34.
id 9999999000 9.99e+30 90.99900 --Decimal is good because data is within range. Double approximated the data to E34.
初始化数据:
CREATE TABLE `test.test_data`(
user VARCHAR(10),
amount FLOAT)
TBLPROPERTIES ('transactional'='true');
INSERT INTO `test.test_data`
SELECT 'sonnh', 300000000000
UNION ALL
SELECT 'sonnh1', 1000000000000
UNION ALL
SELECT 'sonnh2', 900000000000;
获取数据:
SELECT * FROM `test.test_data`
结果:
test.test_data.user test.test_data.amount
sonnh 299999986000
sonnh1 1000000000000
sonnh2 899999990000
我在使用上面的 float 数据类型时遇到问题。谁给我解释一下。
我认为这可以追溯到 Hive 如何存储浮点数、双精度数和小数点的基础知识。
- 十进制 - 根据文档 - 配置单元存储准确的数值。但实际上蜂巢存储几乎接近实际值,如果实际值超过比例、精度,则为 null。
- Double(8 字节,双精度)和 Float(4 字节,单精度)- 两者都是浮点数并存储非常接近的数值近似值。所以,如果它必须存储更高范围的东西,近似就不能正常工作。它可以存储大约从 -10^308 到 10^308.
因此,如果您需要财务应用程序,建议使用小数;如果您不关心舍入问题,请使用浮点数或双精度。
下面是对以上三种数据类型的实验。
CREATE TABLE tmp( a string, f FLOAT, db double, dc decimal(5,4) ) ;
insert into tmp SELECT 'id', 900000000000000000,900000000000000000,123.123 ;
insert into tmp SELECT 'id', 90000000,99900000000000000000,99.999 ;
insert into tmp SELECT 'id', 99123.456,9000000123.456,9.9999999 ;
insert into tmp SELECT 'id', 9999999123.456,500000,123.123 ;
insert into tmp SELECT 'id', 9999999000.456,99900000000000000000999999999999999.12349,9990.099999 ;
insert into tmp SELECT 'id', 9999999000.456,9990000000000000000099999999999.12349,90.999 ;
select * from tmp;
tmp.a tmp.f tmp.db tmp.dc
id 900000020000000000 900000000000000000 123.12300 -- notice that float column cant handle the data and showing different data.
id 90000000 99900000000000000000 99.99900 -- everything is fine because they are within range.
id 99123.45 9000000123.456 10.00000 -- decimal approximated the data to 10 which is very close to actual value.
id 9999999000 500000 123.12300 --all good
id 9999999000 9.99e+34 NULL --Decimal put null because it cant handle the data. Double approximated the data to E34.
id 9999999000 9.99e+30 90.99900 --Decimal is good because data is within range. Double approximated the data to E34.