データベース
Oracle Database
概要
Oracle Databaseは、企業向けに設計された世界最高峰のリレーショナルデータベース管理システムです。高い信頼性、スケーラビリティ、セキュリティ機能を提供し、ミッションクリティカルなアプリケーションでの使用に最適化されています。金融、政府、大企業で広く採用されている業界標準のデータベースです。
詳細
Oracle Databaseは1979年にラリー・エリソンらによって開発が開始され、40年以上にわたる継続的な進化により、現在では以下の特徴を持つ包括的なデータベース・プラットフォームとなっています。
主要特徴
- Autonomous Database: 自動化された管理、パッチ適用、チューニング
- In-Memory Computing: メモリ内処理による超高速クエリ実行
- Multitenant Architecture: コンテナ・データベース(CDB)とプラガブル・データベース(PDB)
- Advanced Security: 透明なデータ暗号化、データマスキング、監査機能
- Real Application Clusters (RAC): アクティブ-アクティブクラスタリング
- Advanced Analytics: 機械学習、グラフ分析、空間データ処理
- JSON and XML: NoSQLデータの完全サポート
- Blockchain Tables: 改ざん防止機能付きテーブル
アーキテクチャ
- System Global Area (SGA): 共有メモリ領域
- Process Global Area (PGA): プロセス専用メモリ領域
- Background Processes: PMON、SMON、DBWR、LGWR等
- Oracle Net Services: ネットワーク通信とセキュリティ
- Automatic Storage Management (ASM): ストレージ自動管理
エディション構成
- Oracle Database Free: 開発・学習用無料版
- Standard Edition: 中小企業向け
- Enterprise Edition: 企業向け高機能版
- Autonomous Database: クラウド最適化版
メリット・デメリット
メリット
- 最高レベルの信頼性: エンタープライズグレードの可用性とデータ整合性
- 優秀なパフォーマンス: In-Memoryテクノロジーによる高速処理
- 包括的な機能: 分析、AI/ML、ブロックチェーン等の先進機能
- 強力なセキュリティ: 多層防御とコンプライアンス機能
- 豊富なツール: Oracle SQL Developer、Enterprise Manager等
- 成熟したエコシステム: 豊富なサードパーティツールとベンダーサポート
- 専門サポート: Oracleによる24/7エンタープライズサポート
デメリット
- 高いコスト: ライセンス費用と保守費用が高額
- 複雑な管理: 設定・チューニングに専門知識が必要
- ベンダーロックイン: Oracle固有の機能に依存するリスク
- リソース消費: 大量のメモリとストレージを必要とする
- 学習コストの高さ: 習得に時間と投資が必要
- ライセンス複雑性: 複雑なライセンス体系と監査リスク
主要リンク
書き方の例
インストール・セットアップ
# Oracle Database Free (Linux)
dnf install oracle-database-free-23c
/etc/init.d/oracle-db-free-23c configure
# Docker環境
docker pull container-registry.oracle.com/database/free:latest
docker run --name oracle-free \
-p 1521:1521 -p 5500:5500 \
-e ORACLE_PWD=mypassword \
container-registry.oracle.com/database/free:latest
# 環境変数設定
export ORACLE_HOME=/opt/oracle/product/23c/dbhome_1
export ORACLE_SID=FREE
export PATH=$ORACLE_HOME/bin:$PATH
# SQLPlusでの接続
sqlplus sys/password@localhost:1521/FREE as sysdba
基本操作(CRUD)
-- 表領域とユーザー作成
CREATE TABLESPACE company_data
DATAFILE 'company_data.dbf' SIZE 100M AUTOEXTEND ON;
CREATE USER company_user IDENTIFIED BY strongpassword
DEFAULT TABLESPACE company_data;
GRANT CONNECT, RESOURCE TO company_user;
-- 接続とテーブル作成
CONNECT company_user/strongpassword@localhost:1521/FREE;
CREATE TABLE employees (
employee_id NUMBER(10) PRIMARY KEY,
first_name VARCHAR2(50) NOT NULL,
last_name VARCHAR2(50) NOT NULL,
email VARCHAR2(100) UNIQUE,
hire_date DATE DEFAULT SYSDATE,
salary NUMBER(10,2),
department_id NUMBER(10)
);
-- シーケンス作成
CREATE SEQUENCE emp_seq START WITH 1 INCREMENT BY 1;
-- データ挿入
INSERT INTO employees VALUES (
emp_seq.NEXTVAL, '太郎', '田中', '[email protected]',
SYSDATE, 75000, 100
);
-- データ選択
SELECT employee_id, first_name || ' ' || last_name AS full_name,
email, hire_date, salary
FROM employees
WHERE department_id = 100;
-- データ更新
UPDATE employees
SET salary = salary * 1.1
WHERE hire_date < ADD_MONTHS(SYSDATE, -12);
COMMIT;
データモデリング
-- 外部キー制約付きテーブル設計
CREATE TABLE departments (
department_id NUMBER(10) PRIMARY KEY,
department_name VARCHAR2(100) NOT NULL,
manager_id NUMBER(10),
location_id NUMBER(10)
);
CREATE TABLE employees (
employee_id NUMBER(10) PRIMARY KEY,
first_name VARCHAR2(50) NOT NULL,
last_name VARCHAR2(50) NOT NULL,
department_id NUMBER(10),
CONSTRAINT fk_emp_dept
FOREIGN KEY (department_id)
REFERENCES departments(department_id)
);
-- JSONサポート
CREATE TABLE customer_data (
customer_id NUMBER PRIMARY KEY,
customer_info JSON,
preferences JSON
);
INSERT INTO customer_data VALUES (
1,
JSON_OBJECT('name' VALUE '田中太郎', 'age' VALUE 35, 'city' VALUE '東京'),
JSON_OBJECT('newsletter' VALUE true, 'language' VALUE 'ja')
);
-- パーティショニング
CREATE TABLE sales_data (
sale_id NUMBER,
sale_date DATE,
customer_id NUMBER,
amount NUMBER(10,2)
) PARTITION BY RANGE (sale_date) (
PARTITION sales_2023 VALUES LESS THAN (DATE '2024-01-01'),
PARTITION sales_2024 VALUES LESS THAN (DATE '2025-01-01'),
PARTITION sales_future VALUES LESS THAN (MAXVALUE)
);
インデックス・最適化
-- インデックス作成
CREATE INDEX idx_emp_department ON employees(department_id);
CREATE INDEX idx_emp_name ON employees(last_name, first_name);
-- 関数ベースインデックス
CREATE INDEX idx_emp_email_upper ON employees(UPPER(email));
-- ビットマップインデックス
CREATE BITMAP INDEX idx_emp_status ON employees(status);
-- 実行計画の確認
EXPLAIN PLAN FOR
SELECT * FROM employees WHERE department_id = 100;
SELECT * FROM TABLE(DBMS_XPLAN.DISPLAY);
-- 統計情報の更新
EXEC DBMS_STATS.GATHER_TABLE_STATS('COMPANY_USER', 'EMPLOYEES');
-- パフォーマンス監視
SELECT sql_text, executions, elapsed_time, cpu_time
FROM v$sql
WHERE executions > 10
ORDER BY elapsed_time DESC;
実用例
-- PL/SQLストアドプロシージャ
CREATE OR REPLACE PROCEDURE calculate_bonus(
p_department_id IN NUMBER,
p_bonus_rate IN NUMBER DEFAULT 0.1
) AS
v_total_bonus NUMBER := 0;
BEGIN
FOR emp_rec IN (SELECT employee_id, salary FROM employees
WHERE department_id = p_department_id) LOOP
UPDATE employees
SET bonus = salary * p_bonus_rate
WHERE employee_id = emp_rec.employee_id;
v_total_bonus := v_total_bonus + (emp_rec.salary * p_bonus_rate);
END LOOP;
DBMS_OUTPUT.PUT_LINE('Total bonus allocated: ' || v_total_bonus);
COMMIT;
END;
/
-- PL/SQLファンクション
CREATE OR REPLACE FUNCTION get_employee_age(p_birth_date DATE)
RETURN NUMBER AS
BEGIN
RETURN MONTHS_BETWEEN(SYSDATE, p_birth_date) / 12;
END;
/
-- トリガー
CREATE OR REPLACE TRIGGER audit_employee_changes
AFTER UPDATE ON employees
FOR EACH ROW
BEGIN
INSERT INTO employee_audit (
employee_id, change_date, old_salary, new_salary, changed_by
) VALUES (
:NEW.employee_id, SYSDATE, :OLD.salary, :NEW.salary, USER
);
END;
/
-- Advanced Queuing (メッセージキュー)
BEGIN
DBMS_AQADM.CREATE_QUEUE_TABLE('order_queue_table', 'SYS.AQ$_JMS_TEXT_MESSAGE');
DBMS_AQADM.CREATE_QUEUE('order_queue', 'order_queue_table');
DBMS_AQADM.START_QUEUE('order_queue');
END;
/
ベストプラクティス
-- データベースリンク
CREATE DATABASE LINK remote_db
CONNECT TO remote_user IDENTIFIED BY password
USING 'remote_host:1521/remote_service';
-- マテリアライズドビュー
CREATE MATERIALIZED VIEW mv_sales_summary
REFRESH FAST ON COMMIT AS
SELECT department_id, SUM(salary) as total_salary, COUNT(*) as emp_count
FROM employees
GROUP BY department_id;
-- セキュリティ設定
-- Transparent Data Encryption
ALTER SYSTEM SET ENCRYPTION KEY IDENTIFIED BY "myencryptionkey";
ALTER TABLE sensitive_data MODIFY (ssn ENCRYPT);
-- 仮想プライベートデータベース (VPD)
CREATE OR REPLACE FUNCTION employee_security_policy(
schema_var IN VARCHAR2,
table_var IN VARCHAR2
) RETURN VARCHAR2 AS
BEGIN
IF USER = 'HR_MANAGER' THEN
RETURN '1=1'; -- フルアクセス
ELSE
RETURN 'department_id = SYS_CONTEXT(''USERENV'', ''CLIENT_IDENTIFIER'')';
END IF;
END;
/
-- RACでの接続
-- tnsnames.ora設定例
ORCL_RAC =
(DESCRIPTION =
(ADDRESS = (PROTOCOL = TCP)(HOST = node1)(PORT = 1521))
(ADDRESS = (PROTOCOL = TCP)(HOST = node2)(PORT = 1521))
(LOAD_BALANCE = yes)
(CONNECT_DATA =
(SERVER = DEDICATED)
(SERVICE_NAME = orcl)
)
)