我想知道为什么Oracle需要VARCHAR2
定义中的size参数。
我认为这是为了制约。 oracle将此参数作为可选的NUMBER
dataType?
我经常在将旧表格调整为较大尺寸时遇到问题,因为有时值会大于VARCHAR2
列的尺寸定义。
定义VARCHAR2(10
)或VARCHAR2(1000)
的类型是一样的。
我想,这是一个不必要的约束。如果没有,你知道这个约束导致一些有用的真实案例吗?为什么在NUMBER
类型中没有这样的声明?
答案 0 :(得分:24)
定义一种类型是一样的 varchar2(10)或varchar2(1000)。
不,这根本不是一回事。
...
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>
但最重要的是,列大小是一种错误检查形式。如果该列应该是十个字符长,并且一些自主进程试图加载一千个字符,则出现问题。这个过程应该失败,所以我们可以调查我们为什么要加载duff数据。另一种选择是一个充满垃圾的数据库,如果这是我们想要的东西,我们应该给每个人提供Excel并完成它。
确实,当我们低估时改变列大小可能会令人厌烦。但它并不经常发生,我们可以通过在PL / SQL中使用%TYPE和SUBTYPE声明而不是硬编码变量来减轻很多痛苦。
“为什么在NUMBER类型中没有这样的声明”
数字不同。首先,数字的最大大小远小于文本等效项(保证精度的38位数)。
但关键的区别在于Oracle存储数值in scientific notation,因此数字的算术大小与其消耗的存储空间之间没有直接的关系。
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>
尽管如此,在可能的情况下指定比例和精度仍然是一个好习惯,特别是当我们处理整数,比如说或金钱时。
答案 1 :(得分:7)
我认为记住关系数据库的历史背景是很重要的。在它们被开发的时候(70年代末期 - 80年代初期),通常可用的计算机比现在的计算机要小得多(在内存和磁盘空间方面)和功能不强(在CPU方面),并且管理这些资源必然是令人信服的关注。 COBOL是商业计算的通用语言(并且仍然被广泛使用),并且面向对象的语言(例如Smalltalk和C ++)在所有实际应用中都是未知的。那时,预计程序将准确地声明每个数据元素需要多少存储空间,例如:字符串为10个字节,短整数为2个字节,浮点数为4个字节,等等,因此当时新开发的关系数据库使用了这种声明方式。更重要的是,假设表明每个数据元素都会(隐式或显式地)声明它所需的存储量,并且这已经在非常基础的级别上编码到关系引擎中。
现在,随着时间的推移,这个要求已经有所放松,至少就磁盘上的数据存储而言。我相信在Oracle中,NUMBER数据类型将灵活地分配空间,以便实际只使用存储其值所需的最小空间量,并且VARCHAR2列将仅使用足够的磁盘空间来存储实际数据而不存储尾随空白,虽然您仍需要声明VARCHAR2所需的最大存储量。
您可以查看SYS.STANDARD包以了解如何声明VARCHAR2子类型。例如,如果你想要自己的'字符串'类型,你可以使用它而无需修改长度规范,你可以尝试:
SUBTYPE MY_STRING IS VARCHAR2(4000);
但是,如果您要对相关列进行索引(如前面的@APC所指出的那样),请注意这一点。
我同意我只是能够声明一个STRING(即BTW,在SYS.STANDARD中定义为VARCHAR2的子类型)而不必声明长度,但这不是Oracle的工作原理,并且因为我不打算开始编写我自己的关系数据库(我有自己的风车可以倾斜,谢谢:-)我会跟上现状。
我希望这会有所帮助。
答案 2 :(得分:5)
为什么不将每个数据库表中的每一列都设为CLOB?这样你就不用担心最大长度...
但是,严肃地说:
数据类型长度约束与任何约束的原因相同:它们通过确保表中成功存储的任何数据符合您的约束,减少了需要在所有应用程序代码中进行的错误检查。已定义。
答案 3 :(得分:3)
即使它没有像char字段那样在磁盘上分配一定数量的字节,但仍有合理的原因:
我确信其他人可以想到更多的理由,但那些是我在过去的项目中看到的,有人选择了varchar2(4000)
所有内容。
答案 4 :(得分:3)
从提取信息的角度来看,了解这个领域有多大是非常有用的。例如,如果您必须在信封上打印地址或在屏幕上显示地址,您想知道该字段的大小。
或购买非常大的信封。
答案 5 :(得分:0)
可能会对性能造成影响:在MySQL中,temporary tables
和MEMORY tables
将VARCHAR
列存储为固定长度的列,并填充到其最大长度。
如果您设计的VARCHAR
列比您需要的最大尺寸大,那么您将消耗更多内存。这会影响cache efficiency, sorting speed, etc
。
所以你给出字符串下面的最大长度。就像你最大字符10的长度所以不要给他的长度100或更多。