指定PK的精度有什么好处吗?鉴于可能永远不会有超过几千条记录,7,0是否足够?
没有指定精度的危险吗?
答案 0 :(得分:10)
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
是基于192
的指数(4
)。10
是十进制9
100
是十进制99
的整数以小数形式显示为00.09 99 99 99 * (100 ^ 4) = 9,999,999
满足所要求的精度所需的位数越多,当然会存储的数字越多。
当您将精确值插入精度较低的列时,它只会舍入到列的精度并存储为圆形。
因此,声明列NUMBER(38)
在性能上是安全的,因为它意味着没有超过NUMBER(7, 0)
的开销(对于适合这两种类型的数字)。
但是,如果您的PRIMARY KEY
本质上是整数,则最好将精度指定为0
,以确保没有小数值到达您的表格。
<强>更新强>
@Mac还指出客户端可能依赖列数据类型来确定值域。
如果您的申请需要INT32
,则应将您的号码设为NUMBER(9)
或更低(或您的客户认为可转换为Int32
的任何类型)。
答案 1 :(得分:4)
在问题的数据库方面,我无法添加到Quassnoi's answer。
但值得注意的是,它可能会对访问数据库的应用程序产生影响(或者更准确地说,对这些应用程序的开发人员产生影响)。例如,在.NET中,如果您获得包含主键的IDataRecord(使用ODP .NET),当您的列定义为NUMBER(38)并且成功时,对GetInt32的调用将很可能失败定义为NUMBER(7)(即使该值在正确范围内时)。
答案 2 :(得分:2)
如果你不期望超过,比如表中的100K记录,如果你用N(7,0)指定PK,如果一些失控过程最终溢出PK,你将得到一个早期警告。如果你用N(38)指定它,警告可能不会那么早出现。
我总是错误地将尺寸限制在“产品寿命”的最小尺寸,并有合理的误差幅度。