当没有业务约束时,我应该为Oracle字符类型设置什么限制



我习惯于为PostgreSQL设计,PostgreSQL的字符类型没有性能差异,社区的建议是,只存在明确的限制来强制执行业务规则。

https://www.postgresql.org/docs/current/datatype-character.html

现在我在甲骨文(19c(工作。我对字符类型的选择似乎要么是带有强制限制的VARCHAR2,要么是CLOB。

社区的建议似乎是尽可能避免CLOB。我不清楚这是出于性能原因还是传统原因,还是因为CLOB在没有一些操作的情况下不会显示在查询编辑器中。

如果业务或领域没有规定文本字段的最大长度,那么在选择限制时,我应该考虑哪些技术、性能或用户体验因素?

">这是否是出于性能原因"-那。CLOB在Oracle中非常慢(尤其是如果您对它们进行了大量更改(

如果没有业务规则,并且4000字节(!(似乎暂时足够,请使用varchar2(4000)

不要试图使用允许varchar2(32767)的扩展varchars——它们作为CLOB存储在后台,并且会遇到同样的性能问题。

TL;DR:避免CLOB,使用长度合理的VARCHAR2

关于CLOB和varchar2(32767),我完全同意@a_hors_with_no_name的观点。

然而,我不建议使用VARCHAR2(4000)的最大大小,而是使用一个合理的上限,这实际上很难估计。如果字段太短,用户和其他开发人员会讨厌你。如果字段太长,数据库会做一些奇怪的事情。

因为VARCHAR2只存储实际使用的字符,所以在存储端不会发现任何差异,它在插入、更新或删除过程中的性能很可能是相同的。

然而,有时Oracle假设实际使用了最大长度:

CREATE TABLE t (
a VARCHAR2(   1 CHAR),
b VARCHAR2(   1 CHAR),
c VARCHAR2(4000 CHAR),
d VARCHAR2(4000 CHAR)
);
CREATE INDEX i1 ON t(a,b);
Index I1 created.
CREATE INDEX i1000 ON t(c, d);
ORA-01450: maximum key length (6398) exceeded

此外,当数据库服务器(或客户端应用程序(按最大长度分配内存时,有时会对性能产生影响,例如:

INSERT INTO t SELECT 'a','a','a','a' FROM all_objects;
INSERT INTO t SELECT 'b','b','b','b' FROM all_objects;
INSERT INTO t SELECT 'c','c','c','c' FROM all_objects;
INSERT INTO t SELECT 'd','d','d','d' FROM all_objects;
EXECUTE dbms_stats.gather_table_stats(null, 't');
SET AUTOTRACE TRACEONLY STAT

现在在内存中按VARCHAR2(1)列进行排序(这很快(:

SELECT a,b FROM t ORDER BY a,b;
Statistics
----------------------------------------------------------
1  sorts (memory)
0  sorts (disk)
268520  rows processed

而按VARCHAR2(4000)列排序不适合内存,因此必须在磁盘上排序,这很慢:

SELECT c,d FROM t ORDER BY c,d;
Statistics
----------------------------------------------------------
0  sorts (memory)
1  sorts (disk)
268520  rows processed

我不得不承认,我把可用内存设置得很小,只是为了证明这一点,但我想你已经明白了。

最新更新