今回は、Silverの「開発/SQL - SQLコマンド(スキーマ)」からの出題です。
CREATE TABLE bar(...); は public.bar というテーブルが既に存在するのでエラーになる。
ここで、CREATE TABLE foo.bar(...); を実行し、foo.bar と public.bar の2つのテーブルが存在する状態にした。
※この例題は実際のOSS-DB技術者認定試験とは異なります。
例題公開日:2020年2月26日
データベースのスキーマとは階層のないディレクトリ構造のようなものです。ユーザ毎あるいはアプリケーション毎に別のスキーマを作成し、テーブル、ビュー、インデックスなどのオブジェクトをそれぞれのスキーマに格納するようにすれば、管理が容易になる、名前の競合が避けられる(同じ名前のオブジェクトを複数作成できる)などの利点があります。
デフォルトインストールではpublicスキーマだけが存在し、これは全ユーザがアクセス可能ですが、CREATE SCHEMA を実行することでスキーマを追加することができます。
SELECTなどのSQLでテーブル名などのオブジェクトを指定するとき、foo.bar などのようにスキーマ名とオブジェクト名をドットでつないで指定するのが正式ですが、スキーマ名は省略することが許されています。その場合にどのオブジェクトを指定したとみなされるかが問題になりますが、PostgreSQLではそれがスキーマ検索パスによって決められます。デフォルトでは $user つまりユーザ名と同じスキーマが最優先、2番目が public となっています。SELECTで指定したテーブルなど、既存のオブジェクトを特定するときは、最優先のスキーマにその名前のオブジェクトがあればそれを使用し、なければ2番目のスキーマにあるかどうかを調べる、という手順になります。CREATE TABLEなどオブジェクトを作成するSQLの場合は、最優先のスキーマが存在すればそのスキーマに作成、なければ2番目のスキーマに作成、という手順です。スキーマ検索パスで3つ以上のスキーマを指定することも可能で、この場合は、2番目のスキーマにも指定した名前のオブジェクトがない(あるいは2番目のスキーマが存在しない)ときには3番目のスキーマを使用します。
さて、例題の選択肢ですが、AのSELECT * FROM bar は、まず foo.bar というテーブルがあればそこからSELECT、なければ public.bar から SELECT という動作をします。この場合は、foo.bar がありませんので、public.bar からSELECTします。BのCREATE TABLE bar では、foo というスキーマが存在するので、foo.bar というテーブルを作成します。もし、foo というスキーマにオブジェクトを作成する権限がなかったら、これはエラーになりますが、public.bar というテーブルが存在するかどうかは関係がありません。
CのSELECT * FROM bar を実行するときは、foo.bar と public.bar の両方が存在しますが、最優先の foo.bar だけが対象になります。DとEのDROP table bar も最優先の foo.bar だけが対象になり、public.bar は削除されません。
従って、正解はDです。
今回の解説について、理解できないポイントがあればどんどん質問をお寄せ下さい。
採用になった方にはLPI-Japanオリジナルの記念品を贈呈します。
※試験問題に関わるお問い合わせにつきましては、LPI-Japan事務局ではお応えできませんのでご了解ください。
© EDUCO All Rights Reserved.