如果问题标题含糊不清,我深表歉意,但我无法更好地表述它。我想要的是 TSQL 的替代方法CREATE TYPE
,因此我可以在列定义中使用它。
例如,我需要 Oracle 中的“money”类型,这在技术上是NUMBER(18,4)
在我的系统中,并且每个表都会有“money”列而不是底层NUMBER
以保持一致性。还有一些其他“类型”我想有别名而不是直接使用它们。
不幸的是,我还没有找到可接受的解决方案,除了放弃并为每列使用具有约束(或大小规范)的标准类型。似乎唯一可行的方法是创建OBJECT
类型,但它会为我试图避免的系统增加不必要的复杂性。
一个非常好的 Oracle 特性,SUBTYPE
在这种情况下不起作用。据我所知,SUBTYPE
(和来自 的子类型STANDARD
)创建了不能在 SQL 中使用的 PL/SQL 数据类型。我知道这有多种原因。
我想知道解决此类问题的最佳做法是什么。
谢谢你。
更新
到目前为止,我似乎已经列出了所有可能的方法,我宁愿关闭这个问题。不确定它是否对任何人有用;如果是,我暂时不删除这个问题。
这是一个非常好的问题,不仅仅是因为它显示了您为回答问题所做的努力。感谢您的询问,请不要删除它。
正如您已经发现的那样,答案是——您不能那样做。
您已经正确识别了几个相似的概念,包括...
为什么 SQL 子类型可能有用?你提到了一致性。这里有一些想法:
将一个表中的字段插入到另一个表中时可以避免错误。
不必记住或查找字段的定义。
打字少了。
更改定义可以在一个地方完成。
数据类型名称提供文档。
以下是解决这些问题的一些想法:
表定义不会经常更改。是的,它们确实发生了变化,但变化量远小于 PL/SQL(您可以在其中使用子类型和 %types)或应用程序端代码。
数据库通常被规范化以消除数据重复并限制多个表具有具有相同定义的字段的要求。当然,像 Money 类型这样通用的东西会在很多地方使用,但有些类型会被移到查找表中,只有键在多个地方重复。
对不同的表使用不同的大小通常会有好处。一家折扣店可能有一个产品表,其中的一个字段定义为 Number(4,2),因为他们的售价从不超过 10 美元。该定义本身就是对数据的约束——提高准确性、记录系统、速度快、无法规避并且比任何应用程序端约束都更好的约束。如果企业决定通过增加字段大小来移除此约束,这并不一定意味着它需要更改其他字段的大小,例如 Salary、SalesAmount 等。
非规范化数据通常是聚合的,可能需要不同的字段大小。薪资列不必是 Number(18,4),甚至公司范围内所有薪资列的总和也不必是 Number(18,4)(接近 100 万亿)。即使由于公司的发展需要增加包含薪资信息的聚合字段,您仍然不一定需要同时增加薪资字段,但如果它们基于相同的 SQL 子类型,那么您将有没有选择。适当大小的字段具有使用更少存储和内存以及具有更快的索引和表查找的好处。
记住或查找自定义类型与记住或查找以前使用的字段定义的难度相似。
Oracle 在使用10.2 Transparent Gateway时将 SQL Server Money 类型转换为 Number(19,4) ,因此在使用网关时即使对 Number(18,4) 进行标准化也是错误的。
在 Oracle 中,经常创建表列,其中包含可能在其他系统的数据类型名称中的定义。例如,数据类型为 Money 的 Wholesale 在 Oracle 中可能是 WholesaleCost,因此很明显该字段与金钱相关。有时这种消歧是必要的,例如如果有 UnitCount、UnitVolume 和 UnitCosts 字段。其他时候,名称本身会泄露类型(例如 Salary)。最后,如有必要,可以在表格列上添加注释以提供进一步的说明。
我说这一切并不是说 SQL 子类型的概念不好,只是它不像看起来那么有用。
另一种方法(但在更高层次上)可能是使用支持域的 ER 建模工具。
然后,您可以在模型中定义一个域“money”(或任何您需要的),当您对模型进行正向工程时,该工具将在域外创建相应的“本地”类型。