为什么Oracle varchar2具有强制大小作为定义参数?

use*_*427 15 oracle varchar2

我想知道为什么Oracle需要在定义中使用size参数VARCHAR2.

我认为这是为了制约.oracle将此参数作为像NUMBERdataType 这样的可选项更好吗?

我经常在将旧表调整为更大的大小时遇到​​问题,因为有时值大于VARCHAR2列的大小定义.

定义一种类型的VARCHAR2(10或者是相同的VARCHAR2(1000).

我想,这是一个不必要的约束.如果没有,你知道这个约束导致一些有用的真实案例吗?为什么没有这种NUMBER类型的声明?

APC*_*APC 24

定义varchar2(10)或varchar2(1000)的类型是一样的.

不,这根本不是一回事.

  1. 列的长度是开发人员构建屏幕的有用元数据.
  2. 类似地,TOAD和SQL Developer等自动查询工具在呈现结果时使用列的长度.
  3. 在为PL/SQL集合分配内存时,数据库使用变量的长度.由于内存来自PGA超大变量声明可能导致程序失败,因为服务器内存不足.
  4. PL/SQL程序中单个变量的声明存在类似问题,只是集合倾向于使问题成倍增加.
  5. 超大列为复合索引带来问题.以下是具有8K块的数据库

....

SQL> create table t23 (col1 varchar2(4000), col2 varchar2(4000))
  2  /

Table created.

SQL> create index t23_i on t23(col1,col2)
  2  /
create index t23_i on t23(col1,col2)
                      *
ERROR at line 1:
ORA-01450: maximum key length (6398) exceeded


SQL>
Run Code Online (Sandbox Code Playgroud)

但最重要的是,列大小是错误检查的一种形式.如果该列应该是十个字符长,并且一些自主进程正在尝试加载一千个字符,则出现问题.这个过程应该失败,所以我们可以调查我们为什么要加载duff数据.替代方案是一个充满垃圾的数据库,如果这是我们想要的东西,我们应该给每个人Excel,并完成它.

事实证明,当我们低估时改变列大小可能会令人厌烦.但它并不经常发生,我们可以通过在PL/SQL中使用%TYPE和SUBTYPE声明而不是硬编码变量长度来缓解很多痛苦.


"为什么在NUMBER类型中没有这样的声明"

数字是不同的.首先,数字的最大大小远小于文本等效项(保证精度的38位数).

但关键的区别在于Oracle 以科学计数法存储数值,因此数字的算术大小与其消耗的存储空间之间没有直接的关系.

SQL> select vsize(123456789012345678901) n1
  2         , vsize(999999999999999999999999999999) n2
  3         , vsize(0.000000000000000000001) n3
  4         , vsize(1000000000000000000000000) n4
  5  from dual
  6  /

        N1         N2         N3         N4
---------- ---------- ---------- ----------
        12         16          2          2

SQL> 
Run Code Online (Sandbox Code Playgroud)

尽管如此,在可能的情况下指定比例和精度仍然是一种好的做法,特别是当我们处理整数,比如说或金钱时.


Bob*_*ica 7

我认为记住关系数据库的历史背景是很重要的.在它们被开发的时候(70年代末期 - 80年代初期),通常可用的计算机比现在的计算机要小得多(在内存和磁盘空间方面)并且功能不强(在CPU方面),并且管理这些资源必然是令人信服的关注.COBOL是商业计算的通用语言(并且仍然被广泛使用),并且面向对象的语言,例如Smalltalk和C++,对于所有实际目的而言都是未知的.那时,程序会准确地确定每个数据元素需要多少存储空间,例如字符串为10个字节,短整数为2个字节,浮点数为4个字节等,因此这种声明方式当时新开发的关系数据库使用了它.更重要的是,假设每个数据元素将(隐式地或显式地)声明它所需的存储量,并且这被编码到非常基础的关系引擎中.

现在,随着时间的推移,这个要求已经有所放松,至少就磁盘上的数据存储而言.我相信在Oracle中,NUMBER数据类型将灵活地分配空间,以便实际只使用存储其值所需的最小空间量,并且VARCHAR2列将仅使用足够的磁盘空间来存储实际数据而不存储尾随空白,虽然您仍需要声明VARCHAR2所需的最大存储量.

您可以查看SYS.STANDARD包以了解如何声明VARCHAR2子类型.例如,如果您想要自己的'字符串'类型,您可以使用它而无需修改长度规范,您可以尝试:

SUBTYPE MY_STRING IS VARCHAR2(4000);
Run Code Online (Sandbox Code Playgroud)

但是,如果您要对相关列进行索引(如前面的@APC所指出的),请注意这一点.

我同意我只是能够声明一个STRING(也就是BTW,在SYS.STANDARD中定义为VARCHAR2的子类型)而不必声明长度,但这不是Oracle的工作方式,而且我也是我不打算开始编写我自己的关系数据库(我有自己的风车可以倾斜,谢谢:-)我将继续现状.

我希望这有帮助.


Jef*_*emp 5

为什么不将每个数据库表中的每一列都设为CLOB?这样你就不用担心最大长度......

不过实话说:

数据类型长度约束的原因与任何约束相同:它们通过确保表中成功存储的任何数据符合您定义的约束,减少了需要在所有应用程序代码中进行的错误检查.