为什么将Oracle表/列/索引名称限制为30个字符?


149

我可以理解,很多年前会有这种限制,但如今肯定可以轻松地增加此限制。我们有对象的命名约定,但是总有一种情况会达到这个极限,尤其是在命名外键时。

有人真的知道为什么它不是更大吗?还是11g更大?


显然,答案是它将破坏当前没有防御性编码的脚本。我说这是一个非常令人担忧的事情,甲骨文正在试图成为数据库,想必这是什么样的,你必须不断提高的东西,否则你的产品会死一千削减死亡。

每当我在公司内部看到这种异议时,我认为是时候该硬着头皮整理一下。如果人们运行的脚本在升级Oracle版本时没有检查或维护,那么他们将遭受这种选择的后果。给他们提供一个兼容性标志,大小最大为4000,然后为我节省创建对象的浪费时间,这些对象必须不断地计数到30来检查名称是否为“ OK”。


3
既然需要限制?将其设置为64个字符,您可能会发现有人问为什么不是128等。一个字符串多长时间?
主席

45
是的,但是30是很短的字符串。为什么不能将它变成4000(Varchar2的大小),Oracle真的在乎解析查询后需要多长时间?
克里斯·吉尔

22
@TheChairman PostgreSQL将我限制为63个字符,并且这个长度限制我从来没有遇到过问题。这个名字足够大,适合我的名字,如果我考虑使用一个更长的名字,是时候开始考虑对可读性的负面影响了。另一方面,在Oracle中,我经常遇到名称长度限制,由于30个字符的限制,不得不降低名称的可读性。少数人可能会抱怨64 个字符的限制,但是由于30个字符的限制,很多人已经遇到了问题。这将满足99%的用例,而Oracle在此失败。
jpmc26 2015年

1
来吧,甲骨文,您已成为恐龙!Microsoft在使SQL Server更友好方面做得很好。现在放宽名称长度限制。
user3454439 '18

1
快进到Oracle 12cR2,它现在是128个字节,而不是30 :-) docs.oracle.com/en/database/oracle/oracle-database/12.2/newft/...
斯特凡大号

Answers:


71

我相信这是ANSI标准。

编辑:

实际上,我认为这是SQL-92标准。

该标准的更高版本似乎可以选择允许128个字符的名称,但是Oracle尚不支持此名称(或仅部分支持它,因为它允许30个字符。嗯。)

在此页面上搜索“ F391,长标识符” ... http://stanford.edu/dept/itss/docs/oracle/10g/server.101/b10759/ap_standard_sql001.htm

(寻找参考)


1
嗯,那不是我阅读该文件的方式。它对我说F391是SQL / Foundation规范中的一项(无论如何),并且Oracle对它具有部分支持,最多30个字符。
skaffman

21
部分合规。真是笑话。“我们的螺钉部分符合公制标准,但不是公制。”
延斯·肖德

5
我尚未详细阅读F391规范,但我假设(可能不正确)“长标识符”表示标识符长度从30增加到128。因此,说“部分”支持30个字符,这是对的:有点厚脸皮。您不支持新标准,您仍然支持旧标准(尽管达到新标准的25%),这有意义吗?!?
cagcowboy

7
SQL-92标准在此处contrib.andrew.cmu.edu/~shadow/sql/sql1992.txt,但是,如果您阅读“ 17.1 SQL项描述符区域的描述”部分,则表示诸如名称和模式之类的标识符必须至少允许128个字符。
里克

46
Oracle迷们看不到30个以上的char标识符的实用性这一事实令人不安。“使您的名字有意义/具有描述性,使用下划线代替驼峰式大小写,并保持30个字符以内”。那永远不会超过30个字符。亚铁矿?更像是缩写,当没有一个名字有意义时,请花一整天时间阅读/更新文档。
亚当·琼斯

45

除了cagcowboy的观点是从SQL标准衍生而来的(从历史上看,我怀疑Oracle的决定导致了SQL标准,因为Oracle早于SQL的标准化),我还要打赌,大部分不愿意允许更长的标识符的原因是认识到有数百万个DBA具有数百万个自定义脚本,所有这些脚本都假定标识符的长度为30个字符。允许每一行类似的代码

  l_table_name VARCHAR2(30);
BEGIN
  SELECT table_name
    INTO l_table_name
    FROM dba_tables
   WHERE ...

之所以突然中断,是因为15年前的DBA使用VARCHAR2(30)而不是DBA_TABLES.TABLE_NAME%TYPE脚本中的VARCHAR2(30)会引起大规模反抗。我敢打赌,多年来,仅Oracle就拥有成千上万种使用各种程序包和组件来完成此类工作的地方。改造所有现有的代码,以支持更长的标识符将是一个巨大的工程,几乎肯定会产生办法的开发时间更多的成本,质量保证时间,和新引进的错误比这将产生效益。


13
+1这几乎可以肯定是Oracle众多遗留设计缺陷之一。
skaffman

43
当然是时候增加一对并增加它了-添加一个标志,以便DBA可以将其精简到30个。这样的遗留问题应始终面对并解决,否则最终会破坏整个代码库,而人们只会移动到别的东西上
克里斯·吉尔

6
不仅是数百万行的DBA书面代码,而且毫无疑问,大量的oracle内部代码也是如此。这个话题是在与史蒂芬·费尔斯坦的一次会议上提出的,他说他认为他们永远都不会改变它。
马修·沃森

10
他们也不能完全将其吹嘘为新功能,或者……他们将花费大量时间来扩展该限制,然后宣布“您现在可以使用长度超过30个字符的名称!”。他们会是笑柄。
skaffman

9
如果您仍在使用15年的脚本,那绝对是错误的。而且,修复它们将是一次性的成本(可能还会增加一些成本,以进行持续维护),而开发人员将继续浪费时间,不必要地无限期地制作可怕的缩写名称。@skaffman他们已经为笑柄没有修复它(以及其他设计决策是在当今时代可怜,好像没有布尔或自动递增类型的主机),就我而言。
jpmc26 2015年

11

我一直在查找并通过Google找到了这个问题,但是还发现从Oracle 12c第2版(12.2)开始,这种情况不再严格。(https://oracle-base.com/articles/12c/long-identifiers-12cr2

在某些时候,每个DBA或开发人员都会遇到这样的问题,即对象名称的30个字符限制会引起问题。当执行从SQL Server或MySQL到Oracle的迁移项目时,此限制可能会非常痛苦。在Oracle Database 12cR2中,大多数标识符的最大长度现在为128个字符。

根据(http://blog.dbi-services.com/oracle-12cr2-long-identifiers/),这是12.2中的新功能。根据该帖子,12.1仍限于30个字符。


编辑:这是解释更改的Oracle官方文档的链接。(https://docs.oracle.com/cloud/latest/exadataexpress-cloud/CSDBF/longer-identifier-names.htm#CSDBF-GUID-F4CA155F-5A37-4705-8443-0A8C9E3F875C

从Oracle Database 12c第2版(12.2)开始,大多数类型的数据库对象的标识符名称的最大长度已增加到128个字节。


128字节/ 4字节(Unicode)= 32个字符。至少我的理解是非Unicode字符的4字节不是很常见吗?我想知道这是否仅表示他们现在支持Unicode?就像VARCHAR2(2)不代表2个字符而是2个字节一样。
赛斯

1
我明白您的意思,但是字符vs字节确实取决于您的数据库字符集。该设置确定char数据类型的编码(例如varchar2)以及db标识符的编码。这与用于nchar数据类型的国家字符集形成对比。因此,是的,如果您使用一种编码方式,使得标识符每个字符使用4个字节(假设可以将其用作DB字符集),那么现在您将拥有32个字节而不是7个字符。但是我认为在大多数情况下,标识符将是单字节字符。
Kanmuri

6

考虑到标识符长度限制的实际必要性,良好的设计会限制实际名称的长度,以免在名称相互组合且带有前缀和后缀的情况下达到上限。

例如,命名外键约束的约定

FK_<table1>_<table2> 

表格名称不得超过13个字符;大多数数据库将需要更多的前缀和后缀,从而进一步限制了表名的长度。


5

在SQLERRM中报告了违反约束的情况,限制为255个字符,大多数客户端使用该错误来使错误可见。我怀疑增加约束名称的允许大小会严重影响报告违规行为的能力(尤其是在通过PL / SQL代码几层冒出约束违规的情况下)。


那么,那张桌子要宽些吗?
skaffman

2
它不是表,而是客户端软件实际上如何从数据库中获取错误。
加里·迈尔斯

@skaffman SQLERRM的长度是API / ABI规范。更改此设置意味着必须修补地球上的每个OCI驱动程序(否则缓冲区溢出)。他们可以先将更改分配给客户端,以首先增加OCI 13中的buflen,然后将服务器添加至Oracle 15之类的服务器中,我想不再支持OCI 10客户端。(也许他们甚至现在都在考虑使用它,但是oracle主版本仅每隔几年发布一次;然后,当应用程序迁移到其他服务器/客户端时,我们可能仍会遇到脚本/应用程序升级的麻烦)。
Cowbert

4

我相信30个字符的标识符长度来自于1950年代后期标准化的COBOL。由于COBOL程序是SQL的主要用户(在此之前是SEQUEL(在此之前是QUEL),因此在标识符长度上似乎是一个合理的数字。


5
我相信Oracle的第一个版本是用Fortran编写的,我认为其标识符长度限制为31。也许这是相关的。
David Aldridge

4

所有这些“约束”都是对70年代处理器架构所施加的限制的回应。从那时起,处理器已发展到不再需要这些限制的程度。他们只剩下。但是,对于RDBMS的编写者来说,更改它们是一项大交易。由于这些长度限制会影响下游的所有变化,因此,为了适应这个问题,我们会说,更长的过程名称可能并且很可能会破坏很多其他内容,例如感知报告,数据字典等,等等。我需要对Oracle RDBMS进行重大重写。


2

这个问题的直接答案是,Oracle风格是从较早的想法继承而来的,在旧的想法中,似乎30年代很多,而更多的想法将增加从典型数据库的实际内存中取消字典高速缓存的风险。

相比之下,ODBC名称空间来自一个非常不同的地方,在该地方,通过解析Excel工作表中的表可以快速提取数据集,并使用工作表表标题中的列名自动构建数据库表。这样思考会使您允许甚至包含嵌入式回车符,当然还有特殊字符和大小写混合的标识符。这是一个明智的抽象,因为它模拟了当今数据分析师的思维方式。

不用担心SQL92,对于当今的通用数据库而言,真正重要的是ODBC遵从性,其他供应商比Oracle更好地解决了这一问题。例如,即使不是很多人都喜欢的Teradata,也可以满足两个命名空间的需要,带引号和不带引号,前者有30个字符的限制,后者是一个完整的ODBC实现,可满足奇怪的长标识符的需要。 。

即使在传统的大型数据库领域中,名称通常也要保持有意义,一致和令人难忘的30个字符。一旦开始设计具有角色命名继承的专业化结构,就开始缩写缩写,并且一致性很快消失,因为例如,在一种情况下,呈现为表名或列名的同一根标识符将需要进一步缩写,而在另一种情况下,则不需要缩写。如果邀请了大量的实际用户使用这些层,后果将是非常差的可用性,幸运的是,对于任何老化的数据库,现在的主要动力是通过对象层和BI工具将用户与数据库分离。

这将数据库层留给了DBA和数据架构师团队,他们也许并不那么在意。看来,制定缩写方案仍然是终生的工作。

Oracle尚未解决这一旧局限性,这可能主要反映了这样一个事实,即当它不能直接移植使用较长标识符构建的数据库设计时,它并没有因此而失去很多业务。


不是Oracle。ODBC是Microsoft的基础,而不是Java。它仍然是与OCI链接的单独的帮助程序库(请查看InstantClient的部署方式-为了使ODBC与InstantClient一起使用,您需要OCI驱动程序和ODBC InstantClient zips)。Oracle的主要客户端平台(除旧版Pro * C / C / C ++之外)是JDBC,它直接链接到OCI,而不是ODBC。
Cowbert

1

以上所有注释都是正确的,但是您需要记住长名称的性能成本。在1990年代初期,Informix设立了巨大的广告牌“ Informix比Oracle快!”。在Oracle总部旁边的101号路由上,Informix允许表名仅短于18个字符!原因很明显-表名以其原义形式(即实际名称而不是“ t138577321”或类似名称)存储在数据字典中。较长的名称等于较大的数据字典,并且由于每次查询需要进行硬解析时都会读取数据字典,因此较大的数据字典等于较差的性能...


7
除非您进行数十亿次操作,否则绝对没有理由将短字符串的精确匹配作为任何现代软件的瓶颈,而在查询解析中则并非如此。最初设计Oracle的这一部分时,大小性能方面的考虑因素可能很重要,但如今它们实际上并不相关。
莎拉·G

-7

好,限制存在。

但是您真的需要超过30个字符来命名表/索引/列吗?

在编写查询时,由于这个限制,我仍然会发现一些烦人的列/表名。如果限制更高,我可能会遇到需要查询的表,例如:

select unique_identifier_column, 
time_when_the_user_remembered_to_change_the_row_in_the_receipt_table, 
foreign_key_to_the_ap_invoice_distributions_history_table_related_to_the_all_rows_table 
from ap_invoices_really_really_all_all_rows_present_in_this_ebs_table.

我很抱歉的大话:P


29
能够使用它们所连接的表和列的名称来命名外键是很好的-因此,当引发外键异常时,您不必查找导致失败的列。然后,Oracle可以再次告诉您该信息...
Chris Gill

10
我们需要30个以上字符的原因有很多,尽管通常30个字符就足够了。有时,表名必须足够详细才能有意义。例如,我有此表调用sch_PatternRunTimeException,它正好是30个字符长。现在,我需要添加一个镜像表调用sch_DevPatternRunTimeException。这个额外的3个字符的命名标准不适用于Oracle,MSSQL没有问题。这迫使我想出一个新名字。重命名表是可行的,但会影响我们的客户操作,因此我们尝试避免这种情况。
dsum 2011年

6
如果在99.9%的可能情况下,+ 30个字符令人讨厌,并不意味着其他0.1%会派上用场。
勒内Nyffenegger

14
h草率的论点。限制只有4个字母数字字符可以使我们获得超过100万个表组合,因此没有人真正“需要”超过4个。它实际上不是30个字符,少于30个字符,因为我的pascal大小写约定必须在缺乏区分大小写的情况下放弃,并用下划线分隔的名称代替。结合各种前缀/后缀,您很幸运甚至拥有20个字符。谁会不愿意一个健壮的索引名在缩写和下划线的大杂烩中回荡违反错误?
b_levitt

同意这不能解决问题。通常,人类不需要更长的列名,但是在很多情况下会自动生成对象名。
fool4jesus
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.