この内容は古いバージョンです。最新バージョンを表示するには、戻るボタンを押してください。
バージョン:3
ページ更新者:atom
更新日時:2026-06-11 07:07:02

タイトル: 論理構造
SEOタイトル: Oracle データベース論理構造完全ガイド (Tablespace/Segment/Extent/Block)

この記事の要点
  • Oracle 論理構造は Tablespace → Segment → Extent → Block の 4 階層
  • Data Block はディスク I/O の最小単位(デフォルト 8KBDB_BLOCK_SIZE で決定)
  • Extent は連続した複数 Block、Segment は 1 オブジェクト(Table/Index 等)が使う全 Extent の集合
  • Tablespace 管理方式は Local Managed (LMT) が標準、Dictionary Managed (DMT) は非推奨
  • PCTFREE / PCTUSED / Row Migration / Row Chaining は Block レベルのチューニング論点

Oracle 論理構造の全体像

Oracle データベースは「物理構造(データファイル・REDO ログ・制御ファイル等の OS ファイル)」と「論理構造(Oracle が内部的に管理する論理単位)」に分かれます。論理構造は次の 4 階層で構成されます。

階層役割対応する物理
Tablespace論理的なストレージ領域。1 つ以上のデータファイルから構成1 つ以上のデータファイル (.dbf)
Segment1 つのオブジェクト (Table / Index / Cluster 等) が使う領域1 つの Tablespace 内に存在
Extent連続した複数の Block。Segment 拡張の単位1 つのデータファイル内で連続
Data BlockI/O の最小単位。OS ブロックの倍数(通常 8KB)OS ブロック数個分

Data Block (データブロック)

Oracle が読み書きする最小単位です。デフォルトは 8KB、初期化パラメータ DB_BLOCK_SIZE で決まり、データベース作成後の変更は不可(個別 Tablespace は DB_nK_CACHE_SIZE で別サイズ可)。

-- ブロックサイズ確認
SHOW PARAMETER db_block_size;

SELECT value FROM v$parameter WHERE name = 'db_block_size';
-- 8192 (= 8KB)

-- Tablespace 別のブロックサイズ
SELECT tablespace_name, block_size FROM dba_tablespaces;

Block の内部構造

領域内容
Block Headerブロックアドレス、Segment 種類、トランザクション情報 (ITL)
Table Directoryこのブロックに含まれる Table 情報(Cluster 使用時)
Row Directoryこのブロック内の各行のオフセット情報
Free Space未使用領域(UPDATE による行サイズ増加に備える)
Row Data実際の行データ

Extent (エクステント)

Segment を拡張する単位で、連続した複数の Blockの集まりです。テーブルにデータが追加されて現在の Extent が満杯になると、新しい Extent を割り当てて Segment を拡張します。

-- Segment ごとの Extent 数とサイズ
SELECT segment_name, segment_type, extents, bytes/1024/1024 AS mb
FROM   dba_segments
WHERE  owner = 'SCOTT'
ORDER  BY bytes DESC;

-- Extent の詳細(どのデータファイルのどこに配置されているか)
SELECT segment_name, extent_id, file_id, block_id, blocks, bytes
FROM   dba_extents
WHERE  segment_name = 'EMP'
ORDER  BY extent_id;

Extent サイズの管理方式

方式特徴推奨
Locally Managed Tablespace (LMT)Tablespace 内のビットマップで Extent を管理。高速・断片化耐性◎★ 標準(10g 以降デフォルト)
Dictionary Managed Tablespace (DMT)データディクショナリ (SYSTEM 表領域) で管理。古い方式非推奨(互換性以外で使わない)
LMT - AUTOALLOCATEOracle が自動でサイズを決定(64KB → 1MB → 8MB → 64MB …)★ 推奨デフォルト
LMT - UNIFORM全 Extent を固定サイズ(例: 1M)にするパーティション表で有効

Segment (セグメント)

Segment は「1 つのオブジェクトが消費する全 Extent の集合」です。Segment の種類は次のとおり。

Segment 種類内容
Table Segment通常のヒープテーブル
Index SegmentB-Tree / Bitmap などの索引
Cluster SegmentIndex Cluster / Hash Cluster
LOB SegmentBLOB / CLOB 等の大型データ本体
LOB IndexLOB のためのインデックス
Temporary SegmentORDER BY / GROUP BY / Hash Join 等で一時的に使用
Rollback / UNDO SegmentUNDO 表領域内の取り消し情報
Partition Segmentパーティション化されたテーブル / 索引の各パーティション

Tablespace (表領域)

論理構造の最上位。1 つ以上のデータファイルから構成され、ユーザはオブジェクト作成時にどの Tablespace に置くかを指定します。

-- 表領域一覧と種類
SELECT tablespace_name, contents, status, extent_management, allocation_type
FROM   dba_tablespaces;

-- 表領域作成 (Locally Managed + AUTOALLOCATE)
CREATE TABLESPACE app_data
DATAFILE '/u01/app/oracle/oradata/ORCL/app_data01.dbf' SIZE 100M
AUTOEXTEND ON NEXT 10M MAXSIZE 10G
EXTENT MANAGEMENT LOCAL AUTOALLOCATE
SEGMENT SPACE MANAGEMENT AUTO;   -- ASSM

-- テーブルを指定 Tablespace に作成
CREATE TABLE emp (
    emp_id NUMBER PRIMARY KEY,
    name   VARCHAR2(100)
) TABLESPACE app_data
  PCTFREE 10 PCTUSED 40;

PCTFREE / PCTUSED と Row Migration

Block 内の領域管理を制御するパラメータです。UPDATE で行サイズが増えたとき、空き領域がないと「Row Migration」「Row Chaining」が発生し、性能が低下します。

パラメータ意味デフォルト
PCTFREEINSERT 用に確保しておく空き領域の % (UPDATE で行が伸びる余地)10
PCTUSED削除でこの % を下回ると INSERT 候補に戻すしきい値40 (ASSM では無視)
Row MigrationUPDATE で増えた行が現在 Block に入りきらず、別 Block に移動。ROWID は元 Block に残り 2 回 I/O避けたい
Row Chaining1 行が 1 Block に収まらず、複数 Block にまたがる(大型 VARCHAR2 / LOB)BLOCK SIZE 拡大で対処

ASSM (Automatic Segment Space Management)

Oracle 9i 以降のビットマップ方式の Segment 空間管理。Free List 方式 (MSSM) よりも RAC 環境で競合が少なく、PCTUSED 不要。9i 以降は ASSM が標準

-- ASSM か MSSM か確認
SELECT tablespace_name, segment_space_management
FROM   dba_tablespaces;
-- AUTO  → ASSM (推奨)
-- MANUAL → MSSM (FREELIST 方式)

確認に使う代表的なディクショナリビュー

ビュー用途
DBA_TABLESPACES表領域一覧、管理方式
DBA_DATA_FILESデータファイルと表領域の対応
DBA_SEGMENTSSegment 一覧、サイズ、Extent 数
DBA_EXTENTSExtent 単位の配置情報
DBA_FREE_SPACE表領域の空き Extent
USER_TS_QUOTASユーザに割り当てられた表領域クォータ
V$DATAFILEデータファイル状態(動的)

サイズ確認の実用 SQL

-- 表領域使用率
SELECT df.tablespace_name,
       ROUND(df.bytes/1024/1024, 1) AS total_mb,
       ROUND((df.bytes - NVL(fs.bytes,0))/1024/1024, 1) AS used_mb,
       ROUND((1 - NVL(fs.bytes,0)/df.bytes)*100, 1) AS pct_used
FROM   (SELECT tablespace_name, SUM(bytes) bytes FROM dba_data_files GROUP BY tablespace_name) df
LEFT JOIN (SELECT tablespace_name, SUM(bytes) bytes FROM dba_free_space GROUP BY tablespace_name) fs
  ON df.tablespace_name = fs.tablespace_name
ORDER BY pct_used DESC;

-- Segment トップ 10
SELECT owner, segment_name, segment_type, bytes/1024/1024 AS mb
FROM   dba_segments
ORDER  BY bytes DESC
FETCH  FIRST 10 ROWS ONLY;

-- Row Migration / Chaining 検出
ANALYZE TABLE scott.emp COMPUTE STATISTICS;
SELECT table_name, num_rows, chain_cnt FROM user_tables WHERE chain_cnt > 0;

FAQ

Q: Block サイズを後から変更できる?
A: データベース全体の DB_BLOCK_SIZE は作成後変更不可。ただし個別の Tablespace なら DB_nK_CACHE_SIZE パラメータと組合せて別サイズを使えます。

Q: Extent が増えすぎると遅い?
A: 数百〜数千程度なら問題ありません。極端に多い場合(数万〜)はフルスキャン時のオーバーヘッドが見えてきます。LMT AUTOALLOCATE なら Oracle が自動で増分を拡大するので通常問題化しません。

Q: Row Migration が見つかったらどうする?
A: 該当テーブルを ALTER TABLE ... MOVE で再構築し、必要なら PCTFREE を増やします。索引は無効化されるので ALTER INDEX ... REBUILD も忘れずに。