DECIMAL 和 NUMERIC 之间的区别
SQL 数据类型 NUMERIC
和 DECIMAL
之间有什么区别? 如果数据库以不同的方式对待这些类型,我想知道至少如何:
- SQL Server
- Oracle
- Db/2
- MySQL
- PostgreSQL
此外,数据库驱动程序解释这些类型的方式是否有任何差异?
What's the difference between the SQL datatype NUMERIC
and DECIMAL
?
If databases treat these differently, I'd like to know how for at least:
- SQL Server
- Oracle
- Db/2
- MySQL
- PostgreSQL
Furthermore, are there any differences in how database drivers interpret these types?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
它们几乎在所有用途上都是相同的。
曾经,不同的供应商对几乎相同的事物使用不同的名称(
NUMERIC
/DECIMAL
)。 SQL-92 使它们相同,但有一个细微差别,该差别可能是特定于供应商的:NUMERIC
必须与定义的一样精确 - 因此,如果将其定义为总共 8 位数字,小数点后 4 位为在小数点右侧,DB 必须始终存储 (8, 4) 位小数,不能多也不能少。如果更容易实现,
DECIMAL
可以自由地允许更高的数字。这意味着数据库实际上可以存储比指定更多的数字(因为后台存储有空间容纳额外的数字)。这意味着数据库可能允许在上面的 (8, 4) 位小数示例中存储12345.0000
,但如果这样做可能影响任何未来的计算,则仍然不允许存储1.00005
。当前大多数数据库系统将
DECIMAL
和NUMERIC
视为完美同义词,或者视为具有完全相同行为的两种不同类型。如果类型被认为完全不同,您可能无法在引用NUMERIC
列的DECIMAL
列上定义外键约束,反之亦然。They are the same for almost all purposes.
At one time different vendors used different names (
NUMERIC
/DECIMAL
) for almost the same thing. SQL-92 made them the same with one minor difference which can be vendor specific:NUMERIC
must be exactly as precise as it is defined — so if you define it as 8 total digits with 4 decimal places to the right of the decimal point, the DB must always store (8, 4) decimal places, no more, no less.DECIMAL
is free to allow higher numbers if that's easier to implement. This means that the database can actually store more digits than specified (due to the behind-the-scenes storage having space for extra digits). This means the database might allow storing12345.0000
in the above example of (8, 4) decimal places, but storing1.00005
is still not allowed if doing so could affect any future calculations.Most current database systems treat
DECIMAL
andNUMERIC
either as perfect synonyms, or as two distinct types with exactly the same behavior. If the types are considered distinct at all, you might not be able to define a foreign key constrain on aDECIMAL
column referencing aNUMERIC
column or vice versa.它们是同义词,没有任何区别。
至少
在 SQL Server 上符合 ANSI SQL 标准。这个所以答案显示 ANSI 中有些差异,但我怀疑在实现上它们是相同的
They are synonyms, no difference at all.
At least
on SQL Serverin the ANSI SQL standards.This SO answer shows some difference in ANSI but I suspect in implementation they are the same
Postgres: 没有区别
表8.1中的文档描述看起来相同,但没有解释为什么单独提到它,所以
根据汤姆·莱恩帖子
下一页 docs 清楚地表明,
以及 别名表
十进制 [ (p, s) ]
被提及为数字 [ (p, s) ]
的别名Postgres: No difference
in documentation description in table 8.1 looks same, yet it is not explained why it is mentioned separately, so
according to Tom Lane post
also a page lower docs state clearly, that
and also at aliases table
decimal [ (p, s) ]
is mentioned as alias fornumeric [ (p, s) ]
它们实际上是等价的,但它们是独立的类型,并且在技术上不是同义词,例如 ROWVERSION 和 TIMESTAMP - 尽管它们可能曾经在文档中被称为同义词。这是同义词的一种稍微不同的含义(例如,除了名称之外,它们是无法区分的,没有一个是另一个的别名)。讽刺吧?
我从MSDN的措辞中解读出来的其实是:
这些类型是相同的,只是名称不同。
除了 type_id 值之外,这里的所有内容都是相同的:
我完全不知道两者之间有任何行为差异,回到 SQL Server 6.5,一直将它们视为 100% 可互换的。
仅当您明确这样做时。您可以通过创建一个表,然后检查执行显式转换或(您可能期望的)隐式转换的查询的查询计划来轻松证明这一点。这是一个简单的表:
现在运行这些查询并捕获计划:
我们在要求的地方进行了显式转换,但在我们可能期望的地方没有显式转换。优化器似乎也将它们视为可互换的。
就我个人而言,我更喜欢使用术语“DECIMAL”,因为它更准确且更具描述性。 BIT 也是“数字”。
They are actually equivalent, but they are independent types, and not technically synonyms, like ROWVERSION and TIMESTAMP - though they may have been referred to as synonyms in the documentation at one time. That is a slightly different meaning of synonym (e.g. they are indistinguishable except in name, not one is an alias for the other). Ironic, right?
What I interpret from the wording in MSDN is actually:
These types are identical, they just have different names.
Other than the type_id values, everything here is identical:
I have absolutely no knowledge of any behavioral differences between the two, and going back to SQL Server 6.5, have always treated them as 100% interchangeable.
Only if you do so explicitly. You can prove this easily by creating a table and then inspecting the query plan for queries that perform explicit or - you might expect - implicit conversions. Here's a simple table:
Now run these queries and capture the plan:
we have explicit conversions where we asked for them, but no explicit conversions where we might have expected them. Seems the optimizer is treating them as interchangeable, too.
Personally, I prefer to use the term DECIMAL just because it's much more accurate and descriptive. BIT is "numeric" too.