简体   繁体   English

在不提供精度和比例的情况下,Oracle PL\\SQL 中 Number 数据类型的大小是多少?

[英]What is the size of Number data type in Oracle PL\SQL with out precision and scale suplied?

One of the guidelines in my new project is to specify precision & scale along with the NUMBER in Oracle PL\\SQL.我的新项目中的准则之一是在 Oracle PL\\SQL 中指定精度和比例以及 NUMBER。 The developer handbook says if this is not specified a default size of 22 bytes is allocated for every variable.开发人员手册说,如果未指定,则为每个变量分配 22 字节的默认大小。

While I understand it is important to specify precision & scale where ever possible.虽然我明白在可能的情况下指定精度和比例很重要。 I don't seem to agree that 22 bytes are allocated if the precision is not supplied.如果不提供精度,我似乎不同意分配 22 个字节。

http://docs.oracle.com/cd/B28359_01/server.111/b28318/datatype.htm#CNCPT1834 http://docs.oracle.com/cd/B28359_01/server.111/b28318/datatype.htm#CNCPT1834

From the Oracle documentations:从 Oracle 文档中:

" Internal Numeric Format "内部数字格式

Oracle Database stores numeric data in variable-length format. Oracle 数据库以可变长度格式存储数字数据。 Each value is stored in scientific notation, with 1 byte used to store the exponent and up to 20 bytes to store the mantissa.每个值都以科学记数法存储,其中 1 个字节用于存储指数,最多 20 个字节用于存储尾数。 The resulting value is limited to 38 digits of precision.结果值限制为 38 位精度。 Oracle Database does not store leading and trailing zeros. Oracle 数据库不存储前导零和尾随零。
For example, the number 412 is stored in a format similar to 4.12 x 10 2 , with 1 byte used to store the exponent(2) and 2 bytes used to store the three significant digits of the mantissa(4,1,2).例如,数字 412 以类似于 4.12 x 10 2的格式存储,其中 1 个字节用于存储指数 (2),2 个字节用于存储尾数的三个有效数字 (4,1,2)。 Negative numbers include the sign in their length."负数包括其长度中的符号。”

I sent the above documentation to the database architect, but he doesn't seem to agree with me.我把上面的文档发给了数据库架构师,但他似乎不同意我的看法。

If we don't specify precision & scale for a NUMBER datatype in oracle pl\\sql will it take 22 bytes or just enough bytes to store the value assigned to it?如果我们不在 oracle pl\\sql 中为 NUMBER 数据类型指定精度和小数位数,它是否需要 22 个字节或仅足够的字节来存储分配给它的值?

NUMBER is equivalent of NUMBER(*) . NUMBER相当于NUMBER(*) Precision and scale are only restrictions for accepted values and have no impact of the memory allocation.精度和比例只是对可接受值的限制,对内存分配没有影响。

HUSQVIK@HQ_PDB_TCP> DECLARE
  2      item_count CONSTANT NUMBER := 10000000;
  3      TYPE t_collection IS TABLE OF NUMBER(38);
  4      data t_collection := t_collection();
  5
  6      PROCEDURE print_allocated_memory IS
  7          allocated_memory NUMBER;
  8      BEGIN
  9          SELECT
 10              value INTO allocated_memory
 11          FROM
 12              v$statname
 13              JOIN v$mystat ON v$statname.statistic# = v$mystat.statistic#
 14          WHERE
 15              name = 'session pga memory';
 16
 17          dbms_output.put_line('Allocated memory: ' || round(allocated_memory / 1048576, 1) || ' MB');
 18      END;
 19  BEGIN
 20      print_allocated_memory;
 21
 22      data.extend(item_count);
 23
 24      print_allocated_memory;
 25
 26      FOR i IN 1..item_count  LOOP
 27          data(i) := 1.00000000000000000000000000000000000011;
 28      END LOOP;
 29
 30      print_allocated_memory;
 31  END;
 32  /
Allocated memory: 3.5 MB
Allocated memory: 483.8 MB
Allocated memory: 483.8 MB

PL/SQL procedure successfully completed.

Elapsed: 00:00:01.04
HUSQVIK@HQ_PDB_TCP>

You can experiment with NUMBER constraints and see that it makes no difference on memory allocation The memory is allocated before any value is actually set and it doesn't change after that.您可以尝试使用 NUMBER 约束,看看它对内存分配没有影响 内存在实际设置任何值之前分配,之后不会更改。 In the example one entry in the collection is approximately 48 bytes but I expect some significant overhead of collection entry itself.在示例中,集合中的一个条目大约为 48 字节,但我预计集合条目本身会产生一些显着的开销。

Associative arrays and nested tables allocate the same space (so I expect the nested table internally to be implemented same as associative array which is B-tree), with VARRAY I got to 410 MB so it's slightly more efficient (and faster too).关联数组和嵌套表分配相同的空间(所以我希望嵌套表在内部实现与 B 树关联数组相同),使用 VARRAY 我得到了 410 MB,所以它的效率更高(也更快)。

but he doesn't seem to agree with me.但他似乎不同意我的看法。

Show him a documentation of vsize function: http://docs.oracle.com/cd/B19306_01/server.102/b14200/functions213.htm#i80071向他展示vsize函数的文档: http : vsize

VSIZE returns the number of bytes in the internal representation of expr. VSIZE返回 expr 内部表示中的字节数。 If expr is null, then this function returns null.如果 expr 为 null,则此函数返回 null。

And simply prove him that 412 occupies 3 bytes, while -412 takes 4 bytes:并且简单地证明他 412 占用 3 个字节,而 -412 占用 4 个字节:

select vsize( 412), vsize( -412) from dual;
VSIZE(412)                             VSIZE(-412)
---------- ---------------------------------------
         3                                       4

Another test proves that @Husquick's answer is true:另一个测试证明@Husquick 的回答是正确的:

select vsize( 0.00000000000000000000000000000000000011 ), 
       vsize( 1.00000000000000000000000000000000000011)
from dual;
VSIZE(0.0000000000000000000000000000000 VSIZE(1.0000000000000000000000000000000
--------------------------------------- ---------------------------------------
                                      2                                      21

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM