こんにちは、かつコーチです。
Oracle Database編の5本目です。
今回は上級者向けの内容として、Oracle独自の表領域設計と、ユーザー・権限管理を扱います。
PL/SQLの基本、シーケンス・ROWNUM・ROWIDの違いを理解している前提で、実務での設計・運用に踏み込んだ内容にしていきます。
表領域の基本設計
SYSTEM・SYSAUX・USERS表領域の役割
Oracle Databaseでは、テーブルやインデックスなどのオブジェクトを物理的にどこに格納するかを、表領域(テーブルスペース)という論理的な単位で管理します。
デフォルトで用意される主要な表領域は次の通りです。
| 表領域 | 役割 |
|---|---|
| SYSTEM | データディクショナリなど、データベース自体の管理情報を格納 |
| SYSAUX | AWR(自動ワークロードリポジトリ)など補助的な管理情報を格納 |
| UNDOTBS1 | ロールバックやREAD COMMITTEDの一貫性読み取りに使うUNDOデータを格納 |
| TEMP | ソートや一時的な作業領域として使用 |
| USERS | アプリケーションのユーザーデータをデフォルトで格納 |
MySQLやPostgreSQLでは、データファイルの物理配置をあまり意識せずに運用できることが多いですが、Oracleでは業務データをSYSTEM表領域に混在させないことが設計上の鉄則です。
SYSTEM表領域が肥大化・断片化すると、データベース全体の管理性能に影響するため、業務用のテーブルは必ず専用の表領域に分離して作成します。
表領域作成・データファイル管理
業務用の表領域は、次のように作成します。
-- 業務用の表領域を新規作成する
CREATE TABLESPACE app_data
DATAFILE '/opt/oracle/oradata/FREE/app_data01.dbf'
SIZE 500M
AUTOEXTEND ON NEXT 100M MAXSIZE 5G;
AUTOEXTEND ONを指定すると、データファイルの容量が不足した際に自動拡張されますが、MAXSIZEの上限設定を忘れると、ディスク容量を使い切ってデータベース全体が停止するインシデントにつながります。
以前、検証環境でMAXSIZE UNLIMITEDのまま長期運用していたところ、大量データ投入バッチの実行中にディスクフルでOracleインスタンスが応答しなくなったことがありました。
本番運用では、MAXSIZEを明示的に設定したうえで、ディスク使用率の監視アラートと組み合わせておくのが鉄則です。
ユーザーとスキーマ
CREATE USER、デフォルト表領域・一時表領域
Oracleでは、ユーザーがスキーマ(そのユーザーが所有するオブジェクトの集合)と1対1で対応するという設計思想があり、MySQL・PostgreSQLの「データベース」と「ユーザー」の関係とは考え方が異なります。
-- 業務用ユーザーの作成
CREATE USER app_user IDENTIFIED BY "StrongPassword#2026"
DEFAULT TABLESPACE app_data
TEMPORARY TABLESPACE temp
QUOTA UNLIMITED ON app_data;
DEFAULT TABLESPACEを指定しないと、作成したオブジェクトが意図せずUSERS表領域に格納され続け、後から表領域を分離するのが手間になります。
QUOTAは、そのユーザーが表領域内でどれだけ容量を使えるかの割り当てで、QUOTA 0のまま気づかずに運用し、ORA-01536(表領域割り当て容量を超えました)エラーで初めて設定漏れに気づく、というのはOracle運用でありがちな失敗です。
プロファイルによるリソース制御
プロファイルを使うと、パスワードポリシーやリソース制限をユーザーごとに定義できます。
-- パスワードの有効期限・ロック条件を定義するプロファイル
CREATE PROFILE app_user_profile LIMIT
PASSWORD_LIFE_TIME 90
FAILED_LOGIN_ATTEMPTS 5
PASSWORD_LOCK_TIME 1;
ALTER USER app_user PROFILE app_user_profile;
金融・官公庁系のシステムでは、監査要件としてパスワードの定期変更やロックアウトポリシーが求められることが多く、こうしたプロファイルによる統制がOracle採用の理由の1つになっています。
権限管理
システム権限とオブジェクト権限
Oracleの権限は、大きくシステム権限(データベース全体に対する操作の権限)とオブジェクト権限(特定のテーブルなどに対する操作の権限)に分かれます。
-- システム権限:セッションを確立できる権限
GRANT CREATE SESSION TO app_user;
-- オブジェクト権限:特定テーブルへのSELECT・INSERT権限
GRANT SELECT, INSERT ON hr.employees TO app_user;
MySQLのGRANT SELECT ON db.table TO userと似た書き方ですが、Oracleでは「セッションを確立できる権限」自体が明示的な付与対象になっている点に注意が必要です。
CREATE SESSION権限がないユーザーは、パスワードが正しくてもログインすらできません。
ロールによる権限のグルーピング
権限をユーザーに個別付与し続けると管理が煩雑になるため、ロール(権限のまとまり)を使ってグルーピングするのが実務でのセオリーです。
❌ Before:権限を個々のユーザーに直接付与している
GRANT SELECT ON hr.employees TO user1;
GRANT SELECT ON hr.employees TO user2;
GRANT SELECT ON hr.departments TO user1;
GRANT SELECT ON hr.departments TO user2;
このやり方だと、新しいテーブルを追加するたびに全ユーザーへの付与漏れが起きやすく、監査時に「誰にどの権限があるか」を追いきれなくなります。
✅ After:ロールに権限をまとめ、ユーザーにはロールを付与する
CREATE ROLE hr_reader;
GRANT SELECT ON hr.employees TO hr_reader;
GRANT SELECT ON hr.departments TO hr_reader;
GRANT hr_reader TO user1;
GRANT hr_reader TO user2;
新しいテーブルの権限を追加したいときは、ロールに対して1回GRANTするだけで、そのロールを持つ全ユーザーに反映されます。
権限の棚卸しをする際も、DBA_ROLE_PRIVSやROLE_TAB_PRIVSといったデータディクショナリビューをロール単位で確認すればよく、監査対応の工数を大きく削減できます。
よくあるつまずきポイント・エラー対処
ORA-01950:表領域への書き込み権限不足
QUOTA未設定のまま業務ユーザーでテーブル作成・データ投入を行うと、次のエラーで止まることがあります。
❌ Before:QUOTAを設定せずにテーブル作成・INSERTを実行
ORA-01950: 表領域'APP_DATA'に対する権限がありません
GRANT CREATE TABLEのようなシステム権限だけでは、表領域への書き込みは許可されません。
✅ After:対象の表領域にQUOTAを明示的に付与する
ALTER USER app_user QUOTA UNLIMITED ON app_data;
MySQL・PostgreSQLにはない、Oracle特有の「オブジェクト作成権限」と「表領域への書き込み容量」が分離しているという設計を理解していないと、原因の切り分けに時間がかかるエラーです。
まとめ
この記事のポイント
- 業務データはSYSTEM表領域と分離し、専用の表領域とMAXSIZEの上限設定を必ず行う
- Oracleではユーザーとスキーマが1対1で対応し、DEFAULT TABLESPACEとQUOTAの設定が必須
- プロファイルでパスワードポリシー・ログイン失敗時のロック条件を統制できる
- 権限はユーザーに個別付与せず、ロールにまとめて付与すると監査・運用の負荷が下がる
- ORA-01950はQUOTA未設定が原因であることが多く、表領域への書き込み権限とオブジェクト作成権限は別物として扱う
次に読むべき記事
- シーケンスとROWNUM・ROWID、MySQL/PostgreSQLとの違い
- Oracleと他RDBMS、企業システムでどちらを選ぶべきか比較検証
タグ: Oracle, 上級者向け, セキュリティ