文章目录

  • 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