【完全ガイド】Oracle NUMBER型 vs INTEGER の違い|精度・スケール・BINARY_DOUBLE・PLS_INTEGER 徹底解説

【完全ガイド】Oracle NUMBER型 vs INTEGER の違い|精度・スケール・BINARY_DOUBLE・PLS_INTEGER 徹底解説

Oracle 開発者なら必ず一度は考える問い:

-- どちらを使うべき?
CREATE TABLE t (
  id     NUMBER,     -- こっち?
  count  INTEGER     -- それとも?
);

驚くべき真実:

INTEGER = NUMBER(38, 0) の完全な別名(シノニム)

内部的に全く同じ。使い分けは慣習と可読性のみの問題です。

しかし、Oracle にはさらに多くの数値型があり、実際は使い分けが重要:

  • NUMBER: 汎用、精度・スケール指定可能
  • INTEGER: NUMBER(38) の別名
  • INT / SMALLINT: これも NUMBER(38) の別名
  • NUMERIC / DECIMAL: NUMBER と等価
  • FLOAT: NUMBER の別種
  • BINARY_FLOAT: 32bit IEEE 754
  • BINARY_DOUBLE: 64bit IEEE 754
  • PLS_INTEGER: PL/SQL 専用、高速
  • SIMPLE_INTEGER: PL/SQL 専用、超高速

さらに、多くの日本語記事が誤解している事実:

  • SMALLINT は「小さい INTEGER」ではない(NUMBER(38) の別名)
  • DECIMAL(10, 2) は本当に固定小数点ではない(内部は NUMBER)
  • FLOAT は BINARY_FLOAT とは別(内部は NUMBER)
  • BINARY_DOUBLE は金融計算には不適(精度損失)
  • PLS_INTEGER は SQL では使えない(PL/SQL 専用)
  • PostgreSQL / MySQL の INTEGER とは全く違う

実務では:

  • 性能重視: BINARY_DOUBLE を検討
  • 金融: NUMBER 一択
  • 主キー: NUMBER でも INTEGER でも
  • PL/SQL のループカウンタ: PLS_INTEGER
  • NULL 不可の高速化: SIMPLE_INTEGER
  • 他 DB からの移行: 型マッピング注意

本記事では、Oracle の数値型を完全に理解するための決定版ガイドを、リファレンスとして実用的に整理します。NUMBER と INTEGER の実態、11 種類の数値型の完全比較、選択ガイド、ストレージサイズ、パフォーマンス、他 DB との比較、Rails/Java/Python 対応、実践シナリオ、FAQまで完全網羅。この1本で Oracle 数値型を根本から理解できるようになります。


目次

結論:INTEGER は NUMBER(38) の別名

時間がない方向けに、最速の理解を示します。

衝撃の真実

Oracle における数値型の別名関係:

NUMERIC   → NUMBER
DECIMAL   → NUMBER
INTEGER   → NUMBER(38, 0)   ← ここ!
INT       → NUMBER(38, 0)
SMALLINT  → NUMBER(38, 0)   ← 実は SMALL じゃない
FLOAT(p)  → NUMBER (2進精度指定版)
REAL      → FLOAT(63)
DOUBLE PRECISION → FLOAT(126)

INTEGER と NUMBER(38) は完全に同じもの。CREATE TABLE で INTEGER を使っても、内部的には NUMBER(38, 0) として格納されます。

検証

CREATE TABLE test_types (
  a NUMBER(38, 0),
  b INTEGER,
  c INT,
  d SMALLINT
);

SELECT column_name, data_type, data_precision, data_scale
FROM user_tab_columns WHERE table_name = 'TEST_TYPES';

結果:

COLUMN_NAME  DATA_TYPE  DATA_PRECISION  DATA_SCALE
A            NUMBER     38              0
B            NUMBER                     0
C            NUMBER                     0
D            NUMBER                     0

全て NUMBER に変換されている。

実際に使うべき数値型

用途推奨型
汎用(不明)NUMBER
整数NUMBER(N) or NUMBER
通貨NUMBER(12, 2) 等
主キーNUMBER(IDENTITY)
科学計算・高速BINARY_DOUBLE
PL/SQL ループPLS_INTEGER
PL/SQL NULL 不可SIMPLE_INTEGER

覚えておくべき3つの数値型

NUMBER          -- 汎用(金融、DB全般)
BINARY_DOUBLE   -- 高速科学計算
PLS_INTEGER     -- PL/SQL 内の整数演算

この3つで99%のケースをカバー

詳細は以下で解説します。


まず理解する:NUMBER 型の詳細

NUMBER(p, s) の意味

NUMBER(precision, scale)
  • precision (p): 総桁数(1-38)
  • scale (s): 小数点以下桁数(-84 to 127)

NUMBER(5, 2)  -- 総5桁、小数2桁 → 123.45
NUMBER(10, 0) -- 総10桁、整数のみ
NUMBER(38, 0) -- 最大精度の整数(= INTEGER)
NUMBER        -- 制約なし(最大精度 40 桁)
NUMBER(4, -3) -- 千の位まで(1000, 2000, 3000, ...)

内部表現

可変長(1〜22 バイト):

0        → 1 バイト
100      → 2 バイト
100000   → 3 バイト
最大精度  → 22 バイト

格納効率が高い

NUMBER 型の範囲

-1 × 10^126 から 9.999...9 × 10^125
(最大 38桁の有効数字)

精度と丸め

NUMBER(5, 2)

-- OK
INSERT VALUES (123.45)  -- 123.45
INSERT VALUES (123.456) -- 123.46(丸め)

-- エラー
INSERT VALUES (1234.5)  -- ORA-01438: value larger than specified precision

Oracle 数値型完全一覧

数値型の別名マッピング

SQL 型実体説明
NUMBERNUMBER汎用
NUMBER(p)NUMBER(p, 0)p 桁整数
NUMBER(p, s)同左p 桁、s 小数
INTEGERNUMBER(38, 0)ANSI 標準名
INTNUMBER(38, 0)INTEGER 短縮
SMALLINTNUMBER(38, 0)実は SMALL でない
NUMERICNUMBERANSI 標準
NUMERIC(p, s)NUMBER(p, s)同左
DECIMALNUMBERANSI 標準
DECIMAL(p, s)NUMBER(p, s)同左
FLOATNUMBER (2進精度)ANSI 標準
FLOAT(p)2進 p 桁精度
REALFLOAT(63)ANSI 標準
DOUBLE PRECISIONFLOAT(126)ANSI 標準
BINARY_FLOAT独立型32bit IEEE 754
BINARY_DOUBLE独立型64bit IEEE 754

PL/SQL 専用型

説明
PLS_INTEGER32bit 整数、高速
BINARY_INTEGERPLS_INTEGER と同じ
SIMPLE_INTEGERPLS_INTEGER + NULL 不可、超高速
SIMPLE_FLOATBINARY_FLOAT + NULL 不可
SIMPLE_DOUBLEBINARY_DOUBLE + NULL 不可
NATURAL0 以上の整数
NATURALN1 以上の整数
POSITIVE1 以上の整数
POSITIVEN1 以上 + NOT NULL
SIGNTYPE-1, 0, 1 のみ

FLOAT の実態(罠あり)

FLOAT は NUMBER の一種

CREATE TABLE t (col FLOAT);
-- ↑ 内部は NUMBER

CREATE TABLE t (col FLOAT(10));
-- ↑ 2進10桁精度の NUMBER

FLOAT vs BINARY_FLOAT

別物です!

項目FLOATBINARY_FLOAT
内部NUMBERIEEE 754
精度正確(10進数)近似(2進数)
性能遅い高速
サイズ可変4 バイト
用途金融科学計算

落とし穴

CREATE TABLE t1 (col FLOAT);       -- NUMBER の別名
CREATE TABLE t2 (col BINARY_FLOAT); -- IEEE 754

INSERT INTO t1 VALUES (0.1);  -- 正確に 0.1
INSERT INTO t2 VALUES (0.1);  -- 近似値(0.100000001... 等)

SELECT SUM(col) FROM (SELECT 0.1 col FROM DUAL CONNECT BY LEVEL <= 10);
-- NUMBER: 1.0 完全一致
-- BINARY_FLOAT: 微妙にずれる可能性

BINARY_FLOAT / BINARY_DOUBLE

IEEE 754 準拠

BINARY_FLOAT:  32bit(単精度)
BINARY_DOUBLE: 64bit(倍精度)

特徴

  • ハードウェア計算(CPU 直接演算)
  • NUMBER より高速
  • 近似値(正確な10進数保存不可)
  • 特殊値: Inf, -Inf, NaN 対応

使用例

CREATE TABLE scientific_data (
  measurement_id NUMBER,
  temperature    BINARY_DOUBLE,   -- 高速演算
  pressure       BINARY_FLOAT
);

-- 特殊値
INSERT INTO t VALUES ('Inf');
INSERT INTO t VALUES ('-Inf');
INSERT INTO t VALUES ('NaN');

リテラル

SELECT 3.14f FROM DUAL;   -- BINARY_FLOAT
SELECT 3.14d FROM DUAL;   -- BINARY_DOUBLE

金融には不適

-- 0.1 + 0.2 = ?
SELECT BINARY_DOUBLE '0.1' + BINARY_DOUBLE '0.2' FROM DUAL;
-- 0.30000000000000004  ← 誤差

SELECT NUMBER '0.1' + NUMBER '0.2' FROM DUAL;
-- 0.3  ← 正確

通貨計算には必ず NUMBER


PLS_INTEGER / SIMPLE_INTEGER(PL/SQL 専用)

PLS_INTEGER

DECLARE
  counter PLS_INTEGER := 0;
BEGIN
  FOR i IN 1 .. 1000000 LOOP
    counter := counter + 1;
  END LOOP;
END;
/

特徴:

  • 32bit 整数(-2,147,483,648 〜 2,147,483,647)
  • ハードウェア演算(PL/SQL の NUMBER より高速)
  • PL/SQL 専用(SQL では使えない)
  • NULL 許可

SIMPLE_INTEGER

DECLARE
  counter SIMPLE_INTEGER := 0;  -- 初期値必須
BEGIN
  FOR i IN 1 .. 1000000 LOOP
    counter := counter + 1;
  END LOOP;
END;
/

特徴:

  • PLS_INTEGER と同じ範囲
  • NULL 不可
  • オーバーフロー時ラップアラウンド(例外なし)
  • PLS_INTEGER より高速(NULL チェック省略)
  • PLSQL_CODE_TYPE=’NATIVE’ で最速

パフォーマンス比較

-- 1000万回ループ
DECLARE
  v1 NUMBER := 0;
  v2 PLS_INTEGER := 0;
  v3 SIMPLE_INTEGER := 0;
BEGIN
  -- NUMBER: 遅い
  FOR i IN 1..10000000 LOOP v1 := v1 + 1; END LOOP;
  
  -- PLS_INTEGER: 高速
  FOR i IN 1..10000000 LOOP v2 := v2 + 1; END LOOP;
  
  -- SIMPLE_INTEGER: 最速
  FOR i IN 1..10000000 LOOP v3 := v3 + 1; END LOOP;
END;
/

目安: SIMPLE_INTEGER は NUMBER の 5-10 倍高速。

FOR ループ変数の型

FOR i IN 1..1000000 LOOP ... END LOOP;
-- i は PLS_INTEGER 型(デフォルト)

Oracle が自動最適化


選択ガイド

フローチャート

どこで使う?
├─ SQL / テーブル
│   ├─ 金融・通貨 → NUMBER(p, s)
│   ├─ 主キー → NUMBER
│   ├─ カウント → NUMBER(N)
│   ├─ 科学計算・大量計算 → BINARY_DOUBLE
│   └─ 汎用 → NUMBER
│
└─ PL/SQL 内変数
    ├─ ループカウンタ → PLS_INTEGER (自動)
    ├─ NULL 不可の整数 → SIMPLE_INTEGER
    ├─ 高速な計算 → BINARY_DOUBLE + SIMPLE_DOUBLE
    ├─ 金融計算 → NUMBER
    └─ 汎用 → PLS_INTEGER or NUMBER

ケース別推奨

金融アプリ:

amount NUMBER(15, 2)  -- 通貨額
rate   NUMBER(5, 4)   -- 利率

在庫管理:

quantity NUMBER(10)   -- 数量
weight   NUMBER(8, 3) -- 重量

科学データ:

temperature BINARY_DOUBLE
pressure    BINARY_DOUBLE

主キー:

id NUMBER GENERATED ALWAYS AS IDENTITY
-- または
id NUMBER(19) -- BIGINT 相当

ストレージサイズ

NUMBER の可変長

NUMBER 型は 1-22 バイトの可変長:

値              バイト数
0               1
1〜99           2
100〜9999       3
NULL            0(別途フラグ)

格納効率が高い、大量データで有利。

固定長型との比較

BINARY_FLOAT:  4 バイト(固定)
BINARY_DOUBLE: 8 バイト(固定)
NUMBER:        1-22 バイト(可変)

実測

SELECT column_name, avg_col_len
FROM user_tab_columns
WHERE table_name = 'MY_TABLE';
-- 実際の平均バイト数

パフォーマンス

NUMBER vs BINARY_DOUBLE

大量計算(例: LOG 集計):

-- 遅い: NUMBER
SELECT SUM(LN(amount)) FROM huge_table;

-- 高速: BINARY_DOUBLE
SELECT SUM(LN(CAST(amount AS BINARY_DOUBLE))) FROM huge_table;

BINARY_DOUBLE のほうが 2-10 倍高速なケース多い。

インデックスの効率

  • NUMBER: 可変長のためインデックスは若干サイズ大きい
  • BINARY_DOUBLE: 固定長、インデックス効率良い

集計処理

PGA の消費:

  • BINARY_DOUBLE: 固定 8 バイト
  • NUMBER: 平均 5-10 バイト

大量ソートで PGA 消費差が出る。PGA 関連は ORA-04030: process memory の記事も参照してください。

インデックス比較

-- NUMBER のインデックス
CREATE INDEX idx1 ON t(number_col);

-- BINARY_DOUBLE のインデックス
CREATE INDEX idx2 ON t(bin_double_col);

-- 検索速度差はある程度あるが、
-- 通常は精度優先で NUMBER

他 DB との比較

型マッピング表

OraclePostgreSQLMySQLSQL Server
NUMBERNUMERICDECIMALDECIMAL
INTEGERINTEGERINTINT
NUMBER(19, 0)BIGINTBIGINTBIGINT
NUMBER(10, 0)INTEGERINTINT
NUMBER(5, 0)SMALLINTSMALLINTSMALLINT
BINARY_FLOATREALFLOATREAL
BINARY_DOUBLEDOUBLE PRECISIONDOUBLEFLOAT

重要な違い

PostgreSQL/MySQL の INTEGER:

  • 32bit 整数 (-2^31 to 2^31-1)
  • 4 バイト固定
  • 高速

Oracle の INTEGER:

  • NUMBER(38, 0)(最大精度)
  • 可変長
  • PostgreSQL/MySQL の INTEGER より大きな数を扱える

移行時の注意:

PostgreSQL: id INTEGER (4 バイト)
        ↓ 移行
Oracle: id NUMBER(10) (可変長、より広い範囲)

Rails / Java / Python 対応

Rails ActiveRecord

Rails のマイグレーション:

class CreateUsers < ActiveRecord::Migration[8.0]
  def change
    create_table :users do |t|
      t.bigint :login_count      # NUMBER(19)
      t.integer :age              # NUMBER(10)
      t.decimal :balance, precision: 12, scale: 2  # NUMBER(12, 2)
      t.float :score              # BINARY_FLOAT
    end
  end
end

oracle_enhanced adapter の変換:

  • bigint → NUMBER(19)
  • integer → NUMBER(10)
  • decimal → NUMBER(p, s)
  • float → NUMBER(BINARY_FLOAT ではない)

Rails 8 系の詳細は Rails 8 アップグレードガイドの記事、rails db:migrate 使い方の記事、find/find_by/where の記事も参照してください。

Java

// JDBC 型マッピング
NUMBER          → java.math.BigDecimal
NUMBER(10, 0)   → int, long, BigDecimal
NUMBER(19, 0)   → long, BigDecimal
BINARY_FLOAT    → float
BINARY_DOUBLE   → double

// 明示的キャスト
BigDecimal balance = rs.getBigDecimal("balance");
double score = rs.getDouble("score");

Python (oracledb)

import oracledb

# 型マッピング
NUMBER          → int or float (適切に判定)
BINARY_FLOAT    → float
BINARY_DOUBLE   → float

# Decimal 使用
import decimal
oracledb.defaults.fetch_decimals = True
# 全ての数値を Decimal で取得

実践シナリオ

シナリオ1:新規テーブル設計

CREATE TABLE orders (
  order_id       NUMBER GENERATED ALWAYS AS IDENTITY PRIMARY KEY,
  customer_id    NUMBER(10) NOT NULL,
  order_date     DATE NOT NULL,
  amount         NUMBER(15, 2) NOT NULL,   -- 通貨は NUMBER
  quantity       NUMBER(10) NOT NULL,
  discount_rate  NUMBER(3, 2),              -- 0.00-9.99
  weight         BINARY_DOUBLE,             -- 科学測定値
  temperature    BINARY_DOUBLE
);

シナリオ2:金融計算(NUMBER 必須)

-- ❌ BINARY_DOUBLE は誤差
CREATE TABLE bad_finance (
  amount BINARY_DOUBLE  -- ← ダメ!
);

-- ✅ NUMBER で正確に
CREATE TABLE good_finance (
  amount NUMBER(15, 2)  -- 円: 15桁整数、小数2桁
);

-- 消費税計算
SELECT amount,
       ROUND(amount * 0.10, 0) AS tax,
       amount + ROUND(amount * 0.10, 0) AS total
FROM orders;

シナリオ3:高速集計(BINARY_DOUBLE)

-- 大量データの科学計算
SELECT SUM(LN(CAST(measurement AS BINARY_DOUBLE))) AS log_sum
FROM huge_scientific_data;

シナリオ4:PL/SQL バッチ処理

DECLARE
  counter    PLS_INTEGER := 0;
  batch_size PLS_INTEGER := 1000;
  processed  SIMPLE_INTEGER := 0;
BEGIN
  FOR rec IN (SELECT * FROM orders WHERE status = 'PENDING') LOOP
    counter := counter + 1;
    processed := processed + 1;
    
    -- 処理
    process_order(rec.order_id);
    
    IF counter = batch_size THEN
      COMMIT;
      counter := 0;
    END IF;
  END LOOP;
  COMMIT;
END;
/

分析関数は Oracle 分析関数(OVER/PARTITION BY)の記事、Solid Queue の詳細は Solid Queue 使い方の記事も参照してください。

シナリオ5:PIVOT との組み合わせ

-- 月次売上(NUMBER)でクロス集計
SELECT * FROM (
  SELECT customer_id, TO_CHAR(order_date, 'MM') month, amount
  FROM orders
)
PIVOT (
  SUM(amount)  -- NUMBER 集計
  FOR month IN ('01' AS jan, '02' AS feb, '03' AS mar)
);

PIVOT の詳細は Oracle PIVOT/UNPIVOT の記事を参照してください。

シナリオ6:他 DB からの移行

-- PostgreSQL からの移行
-- PostgreSQL: id BIGINT PRIMARY KEY
-- Oracle:     id NUMBER(19) PRIMARY KEY

-- PostgreSQL: price NUMERIC(10, 2)
-- Oracle:     price NUMBER(10, 2)

-- PostgreSQL: score REAL
-- Oracle:     score BINARY_FLOAT  -- または NUMBER

シナリオ7:Data Pump インポート

# インポート時の型マッピング確認
impdp system/pw dumpfile=data.dmp tables=orders
# 元 DB の型が Oracle にどうマップされたか

Data Pump の詳細は Oracle Data Pump 使い方の記事も参照してください。

シナリオ8:Docker Oracle での検証

docker exec -it oracle-xe sqlplus scott/tiger <<EOF
CREATE TABLE type_test (
  a NUMBER, b INTEGER, c INT, d SMALLINT,
  e NUMERIC, f DECIMAL, g BINARY_FLOAT, h BINARY_DOUBLE
);

SELECT column_name, data_type, data_precision, data_scale
FROM user_tab_columns WHERE table_name = 'TYPE_TEST';
EOF

Docker 関連は docker daemon 接続エラーの記事、Docker no space left on device の記事も参照してください。

シナリオ9:Rails アプリでの数値型

# app/models/order.rb
class Order < ApplicationRecord
  # amount: NUMBER(15, 2) → BigDecimal
  # quantity: NUMBER(10) → Integer
  # score: NUMBER(3, 2) → BigDecimal
  
  validates :amount, presence: true, numericality: { greater_than: 0 }
  
  # 精度重要な計算は BigDecimal
  def total_with_tax
    amount * BigDecimal("1.10")
  end
end

シナリオ10:レガシー DB のリファクタリング

-- 昔の設計(誤解)
CREATE TABLE legacy (
  small_num SMALLINT   -- 小さい整数のつもり
);

-- 実は NUMBER(38, 0)、無駄
-- リファクタリング:
ALTER TABLE legacy MODIFY small_num NUMBER(5);
-- 小さい範囲を明示、若干のストレージ削減

予防のベストプラクティス

1. 用途を明示的に

-- ❌ 曖昧
CREATE TABLE t (val NUMBER);

-- ✅ 意図明確
CREATE TABLE t (
  price   NUMBER(10, 2),   -- 通貨
  count   NUMBER(10),       -- カウント
  ratio   NUMBER(3, 2)      -- 0-9.99
);

2. 金融は必ず NUMBER

-- 通貨は BINARY_* を使わない
amount NUMBER(15, 2)

3. 大量計算では BINARY_DOUBLE

-- 科学計算・統計
SELECT SUM(x * y) FROM data
-- x, y が BINARY_DOUBLE ならより高速

4. PL/SQL では PLS_INTEGER

FOR i IN 1..N LOOP  -- 自動 PLS_INTEGER
counter PLS_INTEGER := 0;  -- 明示

5. NULL 不可なら SIMPLE_INTEGER

counter SIMPLE_INTEGER := 0;  -- 初期値必須

6. 型変換のオーバーヘッド

-- 頻繁な CAST は避ける
CAST(number_col AS BINARY_DOUBLE)  -- コストあり

7. インデックス設計

-- 主キーは NUMBER が標準
CREATE TABLE t (
  id NUMBER GENERATED ALWAYS AS IDENTITY PRIMARY KEY
);

8. 他 DB 連携の考慮

移行時の型マッピングを文書化

9. Rails でのマイグレーション

# 明示的な型指定
t.decimal :price, precision: 10, scale: 2

10. 一貫性

プロジェクト内で NUMBER/INTEGER 等の使い分けを統一

トラブルシューティング

ORA-01438: value larger than specified precision

-- NUMBER(5, 2) に 1000 を入れると発生
INSERT VALUES (1234.5);  -- ORA-01438

対処: 精度を増やす or 入力チェック

予期しない丸め

INSERT INTO t VALUES (0.005);
-- NUMBER(4, 2) だと 0.01 に丸め

丸め動作: 半分は偶数側(銀行家丸め)ではない。通常の四捨五入

BINARY_DOUBLE の精度損失

SELECT BINARY_DOUBLE '0.1' + BINARY_DOUBLE '0.2' FROM DUAL;
-- 0.30000000000000004

対処: 金融は NUMBER科学は BINARY_DOUBLE

CAST エラー

CAST('abc' AS NUMBER);
-- ORA-01722: invalid number

数値変換エラーは ORA-01858: non-numeric character の記事も参考にしてください。

他 DB からのインポート精度損失

MySQL INT(11) → Oracle NUMBER(38)
(Oracle は NUMBER(11) にすべき)

明示的な型マッピングを。

PL/SQL の PLS_INTEGER オーバーフロー

DECLARE v PLS_INTEGER;
BEGIN
  v := 2147483647 + 1;
  -- ORA-01426: numeric overflow
END;
/

対処: NUMBER に変更 or SIMPLE_INTEGER でラップ


よくある質問(FAQ)

Q1. INTEGER と NUMBER(38) の違いは?

ありません(完全な別名)。

Q2. SMALLINT は本当に小さい?

いいえ。NUMBER(38, 0) の別名。他 DB の SMALLINT とは違う。

Q3. どちらを使うべき?

慣習で選択:

  • ANSI 標準準拠: INTEGER
  • Oracle 標準: NUMBER
  • どちらでも同じ

Q4. FLOAT と BINARY_FLOAT は?

別物:

  • FLOAT: NUMBER の一種(正確)
  • BINARY_FLOAT: IEEE 754(近似)

Q5. BINARY_DOUBLE は金融で使える?

NO。0.1 + 0.2 = 0.30000…4 のような誤差。

Q6. PLS_INTEGER を SQL で使いたい

不可。PL/SQL 専用。SQL では NUMBER。

Q7. 主キーの型

NUMBER 一択(IDENTITY 列で)。

Q8. Rails の integer は?

NUMBER(10)、bigint は NUMBER(19)。

Q9. 他 DB との互換性

ANSI 標準名(INTEGER, DECIMAL) を使うと移植しやすい。

Q10. NUMBER のパフォーマンス

通常十分。大量計算のみ BINARY_DOUBLE 検討。

Q11. 桁数指定なし NUMBER

NUMBER = 最大精度(40 桁)。推奨されない、明示的指定推奨。

Q12. Oracle 23ai の新機能

JSON 型内の数値は BINARY_DOUBLE 相当。


参考リンク

Oracle 公式


まとめ

Oracle 数値型の要点を再整理します。

衝撃の真実

INTEGER = NUMBER(38, 0)  ← 完全な別名
INT     = NUMBER(38, 0)
SMALLINT = NUMBER(38, 0)  ← 実は SMALL でない
NUMERIC = NUMBER
DECIMAL = NUMBER

実際に使うべき型

覚えるべき3つ:

NUMBER          -- 汎用(金融、DB全般)
BINARY_DOUBLE   -- 高速科学計算
PLS_INTEGER     -- PL/SQL 内の整数演算

選択ガイド

用途推奨型
通貨・金融NUMBER(p, s)
主キーNUMBER (IDENTITY)
カウントNUMBER(N)
科学計算・高速BINARY_DOUBLE
PL/SQL ループPLS_INTEGER
PL/SQL NULL不可SIMPLE_INTEGER

全数値型リファレンス

SQL 型:
- NUMBER, NUMBER(p), NUMBER(p, s)
- INTEGER, INT, SMALLINT = NUMBER(38, 0)
- NUMERIC, DECIMAL = NUMBER
- FLOAT, REAL, DOUBLE PRECISION = NUMBER 系
- BINARY_FLOAT (32bit IEEE 754)
- BINARY_DOUBLE (64bit IEEE 754)

PL/SQL 型:
- PLS_INTEGER (32bit, 高速)
- SIMPLE_INTEGER (NULL 不可, 超高速)
- SIMPLE_FLOAT / SIMPLE_DOUBLE
- NATURAL, POSITIVE 等

パフォーマンス

金融: NUMBER 一択(BINARY_* は誤差)
科学: BINARY_DOUBLE で 2-10 倍高速
PL/SQL: PLS_INTEGER で 5-10 倍高速

他 DB との違い

Oracle INTEGER (NUMBER(38)) 
  ≠ PostgreSQL INTEGER (32bit)
  ≠ MySQL INT (32bit)

移行時に注意

予防のベストプラクティス

  • 用途を明示的に(NUMBER(15, 2) 等)
  • 金融は必ず NUMBER
  • 大量計算では BINARY_DOUBLE
  • PL/SQL では PLS_INTEGER
  • NULL 不可なら SIMPLE_INTEGER
  • 型変換のオーバーヘッド意識
  • 他 DB 連携の考慮
  • プロジェクト内で統一

事故防止

  • INTEGER と NUMBER(38) は同じ(別名を選ぶ理由がない)
  • SMALLINT は「小さい」ではない
  • BINARY_ は金融で使わない*
  • FLOAT ≠ BINARY_FLOAT
  • PL/SQL 変数は PLS_INTEGER 推奨

これらの知識は、Oracle でのデータベース設計・スキーマ設計・アプリ開発・他 DB からの移行・パフォーマンスチューニング・金融アプリ・科学計算アプリ・Rails / Java / Python 開発など、あらゆる場面で活用できます。本記事をブックマークしておけば、Oracle 数値型を確実に理解・選択できるようになります。


本記事は2026年6月時点の情報をもとに、Oracle Database 19c〜23ai での動作確認・公式ドキュメントに基づき作成しています。Oracle のバージョンにより挙動が異なる場合があるため、最新の情報は Oracle 公式ドキュメント(docs.oracle.com)もあわせてご確認ください。