在主键上指定精度有什么好处吗?假设可能永远不会有超过几千条记录,7.0就足够了吗?
不指定精度有什么危险吗?
发布于 2009-08-05 17:31:55
NUMBER(7, 0)只是对值域进行了约束。
它们的内部表示没有不同:
CREATE TABLE t_pk (col1 NUMBER(7, 0) NOT NULL, col2 NUMBER(38) NOT NULL)
INSERT
INTO t_pk
VALUES (9999999, 9999999)
SELECT DUMP(col1), DUMP(col2)
FROM t_pk
DUMP(col1) DUMP(col2)
--- ---
Typ=2 Len=5: 196,10,100,100,100 Typ=2 Len=5: 196,10,100,100,100在Oracle中,NUMBER被存储为归一化为0.01 <= N < 1的数字值的百分位数,并以指数为前缀。
在上面的示例中:
196是十进制指数(4).10 is decimal 9100's 99's 192-based
整数以十进制表示为00.09 99 99 99 * (100 ^ 4) = 9,999,999
为了满足所要求的精度,需要的数字越多,存储的数字当然就越多。
当您将精确值插入到精度较低的列中时,它只会四舍五入到列的精度,并被四舍五入地存储。
因此,将列声明为NUMBER(38)在性能上是安全的,因为它不会产生超过NUMBER(7, 0)的开销(对于同时适合两种类型的数字)。
但是,如果精度本质上是整型的,那么最好将PRIMARY KEY指定为0,以确保没有小数值进入您的表。
更新:
@Mac还指出,客户端可能依赖于列数据类型来确定值域。
如果您的应用程序需要一个INT32,那么您应该将您的数字设置为NUMBER(9)或更低(或者您的客户认为可以转换为Int32的任何类型)。
发布于 2009-08-07 09:44:11
在数据库方面,我没有什么可以添加到Quassnoi's answer中的。
但值得注意的是,它也可能对访问数据库的应用程序(或者更准确地说,对这些应用程序的开发人员)产生影响。例如,在.NET中,如果您得到一个包含主键的IDataRecord (使用ODP ),那么当您的列被定义为.NET(38)时,对GetInt32的调用将非常失败,而当被定义为NUMBER(7)时,对GetInt32的调用将会成功(即使当值在正确的范围内)。
发布于 2009-08-06 10:08:33
如果您期望的记录不超过,例如表中的100K记录,如果您使用N(7,0)指定PK,那么如果某个失控进程最终溢出PK,您将得到早期警告。如果您将其指定为N(38),则警告可能不会出现得这么早。
我总是错误地将尺寸限制为“产品生命周期”所期望的最小尺寸,并有合理的误差余量。
https://stackoverflow.com/questions/1234634
复制相似问题