PostgreSQL14 Documentation reading (第I部, 1-3章)

## 第I部 チュートリアル
### 1章: はじめに
https://www.postgresql.org/docs/14/tutorial-createdb.html
>Database names must have an alphabetic first character and are limited to 63 bytes in length.

へー、これは知らなかった。

>$ createdb
If you do not want to use your database anymore you can remove it. For example, if you are the owner (creator) of the database mydb, you can destroy it using the following command:
$ dropdb mydb
(For this command, the database name does not default to the user account name. You always need to specify it.) This action physically removes all files associated with the database and cannot be undone, so this should only be done with a great deal of forethought.

確かに dropdb が引数無しで DB を削除してしまうと `dropdb $DBNAME` みたいなことをした時に悲劇が生まれそうなのでこれはそうなんだろうな

### 2章: SQL 言語
https://www.postgresql.org/docs/14/tutorial-sql-intro.html

>$ psql -s mydb
...
mydb=> \i basics.sql

>The \i command reads in commands from the specified file. psql's -s option puts you in single step mode which pauses before sending each statement to the server. The commands used in this section are in the file basics.sql.

-i でファイルからコマンド読み取り出来るのもなにげに知らなかった。。。 -s も使ったことないわ。

https://www.postgresql.org/docs/14/tutorial-concepts.html
>列は各行で固定された順序を持っているのに対し、SQLはテーブル内の行の順序をいかなる形でも保証しないことを覚えておくことが重要です（ただし、表示のために明示的にソートすることは可能です）。

順序が気になるときは大抵 order by をつけてるけど、order by なしで引いた時に順序が保証されるかを確認したことはないな。どうなんだろう

https://www.postgresql.org/docs/14/tutorial-populate.html
>また、フラットテキストファイルから大量のデータを読み込むためにCOPYを使用することもできました。COPYコマンドはこの用途に最適化されている一方で、INSERTよりも柔軟性に欠けるため、通常はこちらの方が高速です。例を挙げると、以下のようになります。
COPY weather FROM '/home/user/weather.txt';
ここで、ソースファイルのファイル名は、バックエンドプロセスが直接ファイルを読み込むため、クライアントではなく、バックエンドプロセスを実行しているマシンで利用可能である必要があります。COPYコマンドについては、COPYで詳しく説明されています。

COPY コマンド。よく聞くけど使ったことない。

https://www.postgresql.org/docs/14/tutorial-agg.html
>これは、都市ごとに 1 つの出力行を与えるものです。各集約結果は、その都市にマッチするテーブルの行に対して計算されます。これらのグループ化された行は、HAVINGを使用してフィルタリングすることができます。
SELECT city, max(temp_lo) FROM weather GROUP BY city HAVING max(temp_lo) < 40;

いつも忘れる HAVING。

>集約とSQLの WHERE句やHAVING句の相互作用を理解することは重要です。WHEREと HAVINGの基本的な違いは、次のとおりです。 WHEREはグループと集約が計算される前に入力行を選択します（したがって、どの行が集約の計算に入るかを制御します）。一方、HAVINGはグループと集約が計算された後にグループの行を選択します。したがって、WHERE句は集約関数を含んではいけません。どの行が集約の入力となるかを判断するために集約を使おうとしても、それは意味がありません。一方、HAVING句は常に集約関数を含んでいます。(厳密に言えば、集約を使用しないHAVING句を書くことは許されていますが、めったに役に立つことはありません）。同じ条件ならWHERE句の段階でもっと効率的に使えるはずです)。
前の例では、都市名の制限は集約を必要としないので、WHEREで適用することができます。これは、HAVINGに制限を加えるよりも効率的です。なぜなら、WHEREチェックに失敗したすべての行に対してグループ化および集約の計算を行う必要がなくなるからです。

WHERE と HAVING の違い、全然意識してなかった。。。これだけで読んだ甲斐あったわ。

### 3章: 高度な機能
https://www.postgresql.org/docs/14/tutorial-views.html
>CREATE VIEW myview AS
    SELECT name, temp_lo, temp_hi, prcp, date, location
        FROM weather, cities
        WHERE city = name;

普段あまり使わない VIEW 構文

>CREATE TABLE cities (
        name     varchar(80) primary key,
        location point
);

>CREATE TABLE weather (
        city      varchar(80) references cities(name),
        temp_lo   int,
        temp_hi   int,
        prcp      real,
        date      date
);

外部キーってあんまりこういう風にかいてた記憶ないけどこうもかけるんだな。

>BEGIN;
UPDATE accounts SET balance = balance - 100.00
    WHERE name = 'Alice';
SAVEPOINT my_savepoint;
UPDATE accounts SET balance = balance + 100.00
    WHERE name = 'Bob';
-- oops ... forget that and use Wally's account
ROLLBACK TO my_savepoint;
UPDATE accounts SET balance = balance + 100.00
    WHERE name = 'Wally';
COMMIT;

正直 SAVEPOINT 一度も使ったことがない

https://www.postgresql.org/docs/14/tutorial-window.html

ウィンドウ関数も一度も使ったことない。
ウィンドウ関数は[このあたり](https://qiita.com/HiromuMasuda0228/items/0b20d461f1a80bd30cfc)がわかりやすい

https://www.postgresql.org/docs/14/tutorial-inheritance.html

継承という概念があることも初めて知った、、がこれは使わないほうがいい気がするな。