文章目录
- 1 概述
- 2 相同点
- 2.1 整数类型,四舍五入
- 2.2 数据精度一致
- 3 不同点
- 3.1 执行效率
- 3.2 运算时,精度溢出,存疑
1 概述
1. 结论:三者都是 '整数类型',但使用场景不用
2. 使用优先级: simple_integer > pls_integer > binary_integer
(1) 如果没有 '数据溢出',也不支持 null,优先使用 simple_integer
(2) 如果没有 '数据溢出',支持 null,推荐使用 pls_integer
(3) 若上述均不满足,则使用 binary_integer
整数类型 | 解释 | 相同点 | 不同点 |
binary_integer | oracle 9.2 之前,Oracle 底层运算,效率一般 | 1. 整数类型,四舍五入 2. 数据精度: [-2^31, 2^31), 半闭半开区间 | 1. 默认值:binary_integer 和 pls_integer 都是 null,simple_integer 是 not null 2.执行速度:Simple_integer > Pls_Integer > Binary_Integer 3.运算溢出:Binary_Integer、Pls_Integer 会,Simple_integer 不会 |
pls_integer | oracle 9.2 之后,11g 之前常用,CPU 运算,效率较快 | ||
simple_integer | oracle 11g 之后出现,效率最快,但不能为 null | ||
number | 既有整数类型,又有小数类型 | number(p, s) p:1 -- 38 s:-84 -- 127 | 隐式数据类型转换 上述三种类型中,只有 simple_integer + number = number |
2 相同点
2.1 整数类型,四舍五入
declare
b1 binary_integer; -- binary_integer 和 pls_integer 默认 null
b2 binary_integer;
p1 pls_integer;
p2 pls_integer;
s1 simple_integer := 1.2; -- simple_integer not null,故变量必须初始化
s2 simple_integer := 1.5;
begin
b1 := 1.2;
b2 := 1.5;
p1 := 1.2;
p2 := 1.5;
-- 验证: 小数运算时, "四舍五入"
dbms_output.put_line('b1: ' || b1 || ', b2: ' || b2);
dbms_output.put_line('p1: ' || b1 || ', p2: ' || b2);
dbms_output.put_line('s1: ' || b1 || ', s2: ' || b2);
end;
输出结果:小数部分 被 四舍五入
b1: 1, b2: 2
p1: 1, p2: 2
s1: 1, s2: 2
2.2 数据精度一致
declare
init_min number := power(-2, 31);
init_max number := power(2, 31);
b_min binary_integer;
b_max binary_integer;
p_min pls_integer;
p_max pls_integer;
s_min simple_integer := 0; -- 必须初始化
s_max simple_integer := 0;
begin
-- 验证: 数据精度
dbms_output.put_line('power(-2, 31): ' || init_min ||
', power(2, 31): ' || init_max);
-- p_min、s_min 同理
-- b_min := init_min - 1; -- 超出数据精度,报错
-- b_max := init_max; -- 超出数据精度,报错
b_min := init_min;
b_max := init_max - 1;
dbms_output.put_line('b_min: ' || b_min || ', b_max: ' || b_max);
end;
输出结果:
power(-2, 31): -2147483648, power(2, 31): 2147483648
b_min: -2147483648, b_max: 2147483647
3 不同点
3.1 执行效率
-- 基础数据准备
create table stu_info (
id number(10),
name varchar2(30)
);
-- 数据表
create table stu_info_simple as select * from stu_info where 1 = 2;
create table stu_info_pls as select * from stu_info where 1 = 2;
create table stu_info_binary as select * from stu_info where 1 = 2;
结论:执行效率 Simple_integer > Pls_Integer > Binary_Integer
declare
v_binary_integer binary_integer := 10000; -- 测试 1w 条记录
v_pls_integer pls_integer := 10000;
v_simple_integer simple_integer := 10000;
v_start_date simple_integer := 0; -- 100 = 1s
v_end_date simple_integer := 0;
-- 100 = 1s 的验证思路如下:
--
begin
-- binary_integer 验证
v_start_date := dbms_utility.get_time;
for i in 1 .. v_binary_integer loop
insert into stu_info_binary (id, name) values (1, 'a' || i);
end loop;
commit;
v_end_date := dbms_utility.get_time;
dbms_output.put_line('binary_integer 用时: ' ||
(v_end_date - v_start_date) / 100 || ' 秒');
-- pls_integer 验证
v_start_date := dbms_utility.get_time;
for i in 1 .. v_pls_integer loop
insert into stu_info_pls (id, name) values (1, 'a' || i);
end loop;
commit;
v_end_date := dbms_utility.get_time;
dbms_output.put_line('pls_integer 用时: ' ||
(v_end_date - v_start_date) / 100 || ' 秒');
-- simple_integer 验证
v_start_date := dbms_utility.get_time;
for i in 1 .. v_simple_integer loop
insert into stu_info_simple (id, name) values (1, 'a' || i);
end loop;
commit;
v_end_date := dbms_utility.get_time;
dbms_output.put_line('simple_integer 用时: ' ||
(v_end_date - v_start_date) / 100 || ' 秒');
end;
输出结果:(数据量越大、差距越明显)
binary_integer 用时: .62 秒
pls_integer 用时: .59 秒
simple_integer 用时: .6 秒
3.2 运算时,精度溢出,存疑
网上说,
Simple_integer 、Pls_Integer
运算会溢出 而Binary_Integer
不会
因为:binary_integer 运算溢出时,会自动指派给一个 number 类型,从而避免报错
这点暂不知道如何证明,后续若知晓如何用实例证明,咱再修改
- binary_integer、pls_integer 会报超出精度的错误,simple_integer 不会
- 故与网上 运算溢出 的描述有误,暂存疑,验证思路如下:
declare
init_min number := power(-2, 31);
init_max number := power(2, 31);
-- b_min binary_integer;
b_max binary_integer;
-- p_min pls_integer;
p_max pls_integer;
-- s_min simple_integer := 0; -- 必须初始化
s_max simple_integer := 0; -- 必须初始化
n number;
begin
-- 验证: 数据精度
dbms_output.put_line('power(-2, 31): ' || init_min ||
', power(2, 31): ' || init_max);
-- 不会报错,但数据精度异常,存在 数据隐式转换 s_max + number = number
-- b_max、p_max 则直接报错:ORA-01426: 数字溢出
s_max := init_max - 1;
n := s_max + 1;
dbms_output.put_line('最大值:' || n);
end;
输出结果:
power(-2, 31): -2147483648, power(2, 31): 2147483648
最大值:-2147483648