SQLデータ型NUMERIC
とDECIMAL
の違いは何ですか?データベースがこれらを異なる方法で処理する場合、少なくとも次の方法について知りたいです。
さらに、データベースドライバーがこれらのタイプを解釈する方法に違いはありますか?
ほとんどすべての目的で同じです。
かつて、異なるベンダーがほぼ同じものに対して異なる名前(数値/十進数)を使用していました。 SQL-92はそれらを同じにしましたが、ベンダー固有のわずかな違いが1つあります。
NUMERICは、定義されているとおりに正確でなければなりません。したがって、小数点以下4桁を定義する場合、DBは常に小数点以下4桁を格納する必要があります。
DECIMALは少なくともである必要があります。これは、データベースが実際に指定されたよりも多くの桁を格納できることを意味します(裏側のストレージに余分な桁用のスペースがあるため)。つまり、データベースには1.00005
の代わりに 1.0000
、将来の計算に影響します。
SQL Serverでは、Numericはすべての点でDecimalと同一であると定義されています。両方とも常に指定された小数点以下の桁数のみを格納します。
それらは同義語であり、まったく違いはありません。
少なくとも sQL Server ANSI SQL標準。これは SO回答が示しています ANSIに多少の違いがありますが、実装では同じだと思います
Postgres:差異なし
in documentation 表8.1の説明は同じに見えますが、なぜ個別に言及されているのかは説明されていないため、Tom Laneによると post
Postgresでは違いはありません。 SQL標準では両方の名前を受け入れる必要があるため、2つの型名があります。標準をざっと見てみると、唯一の違いはこれです:
_17)NUMERIC specifies the data type exact numeric, with the decimal precision and scale specified by the <precision> and <scale>. 18)DECIMAL specifies the data type exact numeric, with the decimal scale specified by the <scale> and the implementation-defined decimal precision equal to or greater than the value of the specified <precision>.
_つまり、DECIMALの場合、実装は小数点の左側で要求されたよりも多くの桁を許可できます。 Postgresはその自由を行使しないので、これらのタイプに違いはありません。
_regards, tom lane
_
また、1ページ下 docs 状態を明確にし、
10進数と数値のタイプは同等です。どちらのタイプもSQL標準の一部です。
また、 aliases tabledecimal [ (p, s) ]
は、numeric [ (p, s) ]
のエイリアスとして言及されています
これらは実際には同等ですが、ROWVERSIONやTIMESTAMPのような技術的には同義語ではなく、独立したタイプです。ただし、ドキュメントでは一度に同義語と呼ばれていた可能性があります。これは、同義語のわずかに異なる意味です(たとえば、名前を除いて区別できません。一方が他方のエイリアスではありません)。皮肉だよね?
MSDNの表現から私が実際に解釈しているのは、次のとおりです。これらの型は同じで、名前が異なるだけです。
Type_id値を除いて、ここにあるものはすべて同じです。
SELECT * FROM sys.types WHERE name IN (N'numeric', N'decimal');
私は2つの間の動作の違いについてまったく知りません。SQLServer 6.5に戻ると、それらは常に100%交換可能として扱われてきました。
for DECIMAL(18,2) and NUMERIC(18,2)? Assigning one to the other is technically a "conversion"?
明示的に行う場合のみ。これを簡単に証明するには、テーブルを作成し、明示的に、または暗黙の変換を実行するクエリのクエリプランを検査します。簡単な表は次のとおりです。
CREATE TABLE [dbo].[NumDec]
(
[num] [numeric](18, 0) NULL,
[dec] [decimal](18, 0) NULL
);
次に、これらのクエリを実行して計画をキャプチャします。
DECLARE @num NUMERIC(18,0);
DECLARE @dec DECIMAL(18,0);
SELECT
CONVERT(DECIMAL(18,0), [num]), -- conversion
CONVERT(NUMERIC(18,0), [dec]) -- conversion
FROM dbo.NumDec
UNION ALL SELECT [num],[dec]
FROM dbo.NumDec WHERE [num] = @dec -- no conversion
UNION ALL SELECT [num],[dec]
FROM dbo.NumDec WHERE [dec] = @num; -- no conversion
要求した場所には明示的な変換がありますが、期待した場所には明示的な変換はありません。オプティマイザもそれらを交換可能として処理しているようです。
個人的には、DECIMALという用語を使用する方がはるかに正確でわかりやすいためです。 BITも「数値」です。