OSS DB Silverの学習メモ

# 一般知識

■有償で配布しても構いません。

■PostgreSQLのマニュアルは、ボランティアの手によって英語から日本語に翻訳され、無償で公開されています。

# インストール

■1台のマシンに複数のバージョンのPostgreSQL(例えばバージョン9.1.4とバージョン9.2.3)をインストールして、両方を同時に稼働させることが可能です。

# 権限
■権限付与について、デフォルトではテーブルの作成者（所有者）のみがすべての権限を所持しており、他のユーザは一切の権限を所持していません。

■テーブルの所有者からアクセス権限をREVOKEすることができます（データベースの種類によっては、所有者の権限はREVOKEできませんが、PostgreSQLでは可能です）。
SELECT権限をREVOKEされたら、所有者でもそのテーブルのデータをSELECTすることはできません。
ただし、所有者はGRANTコマンドを実行することができるので、自分に対してGRANT SELECT を実行すれば、再び SELECTできるようになります。

■スーパーユーザは特殊なユーザで、アクセス権限がなくても、テーブルにアクセスすることができます。スーパーユーザから SELECT 権限を REVOKE するコマンド自体は成功しますが、スーパーユーザはそれでもそのテーブルから SELECT を実行することができます。

■GRANT/REVOKEで付与する、あるいは取り消す権限はテーブル、あるいはテーブルの列が対象で、行単位の権限はありません。

■テーブル自体を削除(DROP)するのは、テーブルの所有者に限られ、その権限をGRANTで付与することはできません。

■ビューからSELECTするときは、ビューに対するSELECT権限だけがあれば良く、ビューを構成するテーブルに対するSELECT権限は必要ありません。

■UPDATE権限だけで実行できるUPDATE文は、条件指定をしない非常に単純なものだけです。WHERE句で条件を指定したUPDATE文は、行を特定するためのSELECT権限も必要になります。

# データ型

■NUMERIC型は整数、小数のどちらにも利用できます。
金額計算など正確さのためにNUMERICを使うべき場面はありますが、INTEGER型に比べると演算速度が非常に遅くなります。

■SHORT、LONGというデータ型はありません。

# postgresql.conf

■サーバの動作を制御する様々なパラメータを設定することができます。
このファイルで設定されるパラメータは、実行時パラメータと呼ばれ、GUCともいいます。

■GUCを操作するためのコマンドも用意されています。例えば、psql上からSET パラメータ名 = 値、またはSET パラメータ名 TO 値と実行することで値を変更できます。

■多くのパラメータは、pg_ctl reloadによってファイルを再読み込みさせることで変更が反映されますが、一部のパラメータの変更はpg_ctl restartなどサーバの再起動が必要です。
変更を反映させるためにサーバの再起動が必要となるもの
⇒port
⇒max_connections

■PostgreSQLではログ出力に関する様々なパラメータがあり、それをpostgresql.confに設定することで、何をどのような条件のときに出力するかについて細かい制御をすることができます。

# pg_hba.conf

■pg_hba.confのHBAはHost-Based Authentication（ホストベース認証）の略で、クライアントがデータベースに接続するときの認証方法を設定するファイルです。

■IPアドレスは、IPv4の他に、IPv6のアドレスも指定できます。

■pg_hba.confでは1行に1つの認証条件を記述します。データベース、ユーザ、アクセス元の組み合わせがマッチするレコードを先頭行から順に探し、最初に見つかった行の認証方式を利用します。それより下にマッチする組み合わせのレコードがあってもそれは採用されません。

# トランザクション

■トランザクションにはACID属性というものがあります。原子性、一貫性、分離性、持続性です。

■標準SQLではトランザクションはSTART TRANSACTIONで始まり、COMMITで書き込まれて終了、あるいはROLLBACKで取り消されて終了、となります。
PostgreSQLの拡張として、START TRANSACTIONの代わりにBEGINを使用することができ、またCOMMITの代わりにENDまたはEND TRANSACTIONを使うことができます。
STOP TRANSACTIONとかCANCELいう制御文はありません。

■トランザクション分離レベルを設定するコマンドの構文は下記です。 
SET TRANSACTION ISOLATION LEVEL { }

■トランザクション分離レベルは、トランザクション開始のBEGIN(あるいはSTART TRANSACTION)コマンドのオプションで指定するか、あるいはBEGINの直後にSET TRANSACTIONコマンドで指定します。トランザクション内でSELECTやUPDATEなどのSQL文を実行した後では、トランザクション分離レベルは指定できません。

■トランザクションブロックの外部でトランザクション分離レベルを指定しても何の効果もありませんが、これ自体は警告を発するだけでエラーにはなりません。

■トランザクション中にシーケンスのnextvalを書いて、rollbackしても、nextvalの実行は取り消されません。

■ロックは先着順なので、ロックの種類に関わらず、後からロックしようとした方がロック解放待ちの状態になります。ロックの内容やユーザの種類によって、ロックが優先されることはありません。

# 運用管理

■XIDとは、トランザクションごとに自動的に割り振られるトランザクション識別子です。テーブルの行には、どのトランザクションで操作されたかを示すXIDが内部的に割り振られています。

■XIDの周回問題は、XIDが32bit、つまり最大で約42億個の値しか保持できないことに起因します。XIDが周回してしまうと、存在するはずのデータが消失するなどの問題が発生します。XIDが周回しそうになるとPostgreSQLは停止する仕様になっています。

■CLUSTERは、テーブルのデータをインデックス順に並び替えるコマンドです。このため、CLUSTERコマンドを使うためにはインデックスが必要です。

# SQL

■算術演算子で最も優先順位が高いのは、^（べき乗）です。

■UNION演算子を使って複数の SELECT 文をつなぐことにより、SELECT の結果の和集合を求めることができます。
SELECT ... UNION SELECT ... UNION SELECT ... とすることで3つ以上の SELECT の結果の和集合を求めることもできます。
UNION を使うとき、それぞれの SELECT 文で選択する列について、個数と型が一致しなければならない、という条件があります。ただし、型については、変換可能であれば十分で、例えば、一方が INTEGER、他方が VARCHAR 型であればエラーになりますが、一方がVARCHAR(10)、他方がVARCHAR(15)やCHAR(15)というケースは問題ありません。
列の名前は同じである必要はありませんが、SELECT の結果が表示されるときのヘッダには、先頭の SELECT 文のテーブルの列名が表示されます。

和集合なので、両方の SELECT 文に全く同じ結果が含まれていた場合は、1件しか出力されません。ただし、UNION の代わりに UNION ALL とすると、同じ結果も複数回出力されます。

# テーブル、ビュー

■ALTER TABLEではテーブル定義を変更するため、その実行中は、全てのアクセスは待機させられます。SELECTもできません。

■テーブルの列のデフォルト値は、あくまでも新規に追加(INSERT)されるデータについての値を定めるものであるため、ALTER TABLEで設定が変更されても、既存のデータには影響がありません。

■ビューにインデックスを作ることはできません。ビューからのSELECTは、内部的には常にそれを構成するテーブルからのSELECTに書き換えられるため、高速化のためにはテーブルに適切なインデックスを作る必要があります。