PREPARATION
受験対策

オススメ!OSS-DB情報

第15回 スキーマ

データベースを知らない人、あるいは学習を始めたばかりの人にとって、スキーマ(SCHEMA)はあまり耳慣れない言葉かもしれませんが、データベース管理において重要な概念です。

データベースをOSに例えてみると、データベース内に作成したテーブル(表)は、OSが管理するディスク上に作成されたファイルに相当します。OSで多数のファイルを作るとき、ファイルの種類、目的、所有者などに応じて複数のディレクトリ(フォルダ)に分けて保存する、というのが普通です。データベースでも、多数のテーブルを作るときに、テーブルの目的や所有者に応じて格納場所を別にすることで、分類できます。そのための仕組みがスキーマです。

データベースのスキーマは、OSのディレクトリとよく似た性質を持っています。

テーブルなど、すべてのオブジェクトは、何らかのスキーマに所属します。これは、OSのファイルが、何らかのディレクトリに所属するのと同じですね。

CREATE TABLE 文でテーブルを作成する際、スキーマが別であれば同じ名前のテーブルを複数、作成することができます。しかし、同じスキーマの中に同じ名前のテーブルを複数作ることはできません。これも、OSのファイル名とディレクトリの関係と同じです。

スキーマには所有者、書き込み権限などの概念があり、適切な権限を持ったユーザでなければそのスキーマ内に新規にテーブルなどのオブジェクトを作成することはできません。OSのディレクトリにもユーザやグループによる書き込み権限などの制約があり、そのディレクトリについて適切な権限を持つユーザでなければ、ファイルを作れません。

SQL 文でテーブルを指定するとき、スキーマ名とテーブル名を"."(ピリオド)でつないで記述します。ただし、スキーマ名は省略可能なので、テーブル名だけを指定しても良いです。このとき、どのスキーマにあるテーブルであると想定するか、の規則が決まっています。
例えばLinuxでは、ディレクトリ名とファイル名を"/"(スラッシュ)でつないで記述しますが、ディレクトリ名を省略してファイル名だけ指定することも可能ですよね。

スキーマとディレクトリの大きな違いの1つは、スキーマが階層化できないことです。ディレクトリは、その下にサブディレクトリを作って階層化できますが、スキーマは、その下にサブスキーマのようなものを作ることはできません。

スキーマは標準SQLにある概念ですが、その実装はRDBMSの種類によって異なる部分があります。以下ではPostgreSQLにおけるスキーマの使い方について簡単に説明します。

PostgreSQLのスキーマ機能の特徴として、public スキーマおよびスキーマ検索パスがあります。

デフォルトの状態では、新しいデータベースには public というスキーマだけが存在しています。public スキーマにはどのユーザでもテーブルなどを作成することができます。少数のユーザでデータベースを利用する場合は、この public スキーマだけを使って、スキーマ機能の存在を意識しない使い方をすることもできます。

public 以外のスキーマを使う時は、CREATE SCHEMA 文により新規のスキーマを作成します。新しいスキーマを作ったとき、デフォルトでは、その所有者(つまり作成者)だけがそのスキーマ内にテーブルなどのオブジェクトを作成することができます。スキーマにオブジェクトを作成する権限は GRANT 文で付与できます。ALTER SCHEMA 文でスキーマの名前や所有者を変更することもできますし、 DROP SCHEMA 文で作成済みのスキーマを削除することもできます。

テーブルの参照時にスキーマ名を省略した場合は、スキーマ検索パスを使ってテーブルを検索します。スキーマ検索パスはユーザが自由に変更することができますが、デフォルトでは、ユーザ名と同じスキーマ→publicスキーマ、という優先順位になっています。

例えば、obama というユーザが、SELECT * FROM test1; というSQLを実行したときは、
(1) obama.test1 というテーブルがあれば、そこから SELECT する
(2) public.test1 というテーブルがあれば、そこから SELECT する
(3) どちらもなければ、テーブルが見つからない、というエラー
という処理手順になります。obama.test1 があれば、public.test1 があっても無視される、ということに注意してください。

一方で、同じユーザが CREATE TABLE test2 ...; を実行した時は、
(1) obama というスキーマがあれば、CREATE TABLE obama.test2 ...; として実行
(2) それ以外の場合、CREATE TABLE public.test2 ...; として実行
という処理手順になります。
obama.test2 が既存のテーブルなら、もちろんエラーになりますが、
public.test2 が既存の場合でも、それを無視して obama.test2 を作ることには注意して下さい。

解説:松田神一

LPI-Japan
Platinum Sponsors

関連資格