RailsでPostgreSQLに接続するまでに必要な知識

## 概要
RailsのデータベースとしてPostgreSQLを使用しようと思ったのですがかなり沼にハマったので、自分が必要だと感じたものを残します。
主にコマンドの解説になっております。
Railsとの接続手順については詳しい記事があるので、そちらを参考にしてください。（参考の節にリンクがあります）
まともに学習したわけではないので、理解できていない部分もあります。
間違いがあればご指摘よろしくお願いします。

## 環境
macOS Catalina
Ruby : 2.7.1
Rails : 6.0.2.2
PostgreSQL : 12.2
Homebrew 2.2.14

## PostgreSQLのインストール
PostgreSQLを起動した状態でRailsと接続する必要があるのでインストールをします。
ここではHomebrew経由の方法です。

```zsh
$ brew install postgresql

$ postgres --version
postgres (PostgreSQL) 12.2
```

## PATHの設定

```zsh
# PostgreSQLのパス
export PATH=/usr/local/pgsql/bin:$PATH

# PostgreSQL設定（DBの置き場所）
export PGDATA='/usr/local/var/postgres'
``` 

注:パスは開発グループの文書を参考にしているが、正直な話、ちゃんと通っているのか必要なのかもわからない...

```zsh
$  which postgres
/usr/local/bin/postgres

$  echo $PATH
/usr/local/pgsql/bin:
```

## PostgreSQLの起動
起動方法を3つみつけたが、何か違うのかなどよく分かっていない...
①はrails serverなどと同じように起動したターミナルに入力ができなくなるが、②、③についてはそのまま入力ができる。

自分は起動状態が分かりやすいので①で起動している。

①

```zsh
$ postgres #起動

$  pg_ctl status #確認（別タブ）
pg_ctl: server is running
```
Ctrl+C で終了

②

```zsh
$  pg_ctl start #起動
server started

$  pg_ctl status #確認
pg_ctl: server is running

$  pg_ctl stop #終了
server stopped
```

③

```zsh
$  brew services start postgresql #起動
==> Successfully started `postgresql` (label: homebrew.mxcl.postgresql)

$  pg_ctl status #確認
pg_ctl: server is running

$  brew services stop postgresql #終了
Stopping `postgresql`... (might take a while)
==> Successfully stopped `postgresql` (label: homebrew.mxcl.postgresql)
```

## データベースの確認
**PostgreSQLを起動**した状態で次のコマンドから確認できる。
データベース名は省略可。

```zsh
psql --list [データベース名]
psql -l [データベース名]
```

```zsh
$ postgres #dbの起動

$ psql -l
                              List of databases
      Name      |   Owner   | Encoding | Collate | Ctype | Access privileges
----------------+-----------+----------+---------+-------+-------------------
 postgres       | wm        | UTF8     | C       | C     |
 template0      | wm        | UTF8     | C       | C     | =c/user          +
                |           |          |         |       | user=CTc/user
 template1      | wm        | UTF8     | C       | C     | =c/user          +
                |           |          |         |       | user=CTc/user
```
インストール後の状態ですでに3つのデータベースがあるが、必要なものなので**削除しない**ように注意。

templateはデータベースを作成する際にプログラムが使用しているらしい。

postgresは削除すると次のように、データベース名省略でのコマンドが使えなくなったので、詳しくはわからないがこれも削除しない方がよさそう。（コマンドの初期値になっているのかな？）

```zsh
$  psql --list
psql: error: could not connect to server: FATAL:  database "postgres" does not exist
```

## データベースの作成と削除
**PostgreSQLを起動**した状態で次のコマンドからデータベースの作成と削除が可能。

```zsh
$ createdb [データベース名] #dbの作成

$ dropdb [データベース名] #dbの削除
```

## データベースへの接続
**PostgreSQLを起動**した状態で、次のコマンドで接続される。

```zsh
$ psql [データベース名] #dbに接続

postgres=>\q #終了
```

```zsh
psql (12.2)
Type "help" for help.

postgres=> 
```
「postgres=>」部分に続けてコマンド入力することで操作する。
スーパーユーザーだと「postgres=#」、それ以外だと「postgres=>」になる。

## ロール（ユーザー）の確認
PostgreSQLではユーザーのことをロールというらしい。
**PostgreSQLを起動**した状態で**データベースに接続後**、次のコマンドからロールの作成と削除が可能。

```zsh
$ postgres=> \du
```
```zsh
$ postgres #dbの起動

$  psql postgres #データベースに接続
psql (12.2)
Type "help" for help.

postgres=>\du
                                     
   Role name   |                List of roles Attributes                    | Member of
---------------+------------------------------------------------------------+-----------
 user          | Superuser, Create role, Create DB, Replication, Bypass RLS | {}
```

## ロール（ユーザー）の作成、削除
**PostgreSQLを起動**した状態で**データベースに接続後**、次のコマンドからロールの作成と削除が可能。
コマンドの最後に「 **;** 」が必要なので忘れないように注意。

```zsh
postgres=> create role [ロール名]; #ロールの作成

postgres=> drop role [ロール名]; #ロールの削除
```

```zsh
postgres=> create role new_user; #ロールの作成

postgres=> \du #ロールの確認
                                     
   Role name   |                List of roles Attributes                    | Member of
---------------+------------------------------------------------------------+-----------
 new_user      | Cannot login                                               | {}
 user          | Superuser, Create role, Create DB, Replication, Bypass RLS | {}
```
これでロールは作成されるのだが、Attributesに「Cannot login」とあるように、これではユーザーとして登録されていない。

```zsh
postgres=> select usename from pg_user; #ユーザーの確認
  usename
-----------
 wm
(1 rows)
```

そこで次のようにオプションを指定する。(指定できるオプションについては[こちら](https://www.postgresql.jp/document/9.2/html/sql-createrole.html))

```zsh
postgres=> create role new_user WITH LOGIN; #ログインできるロールの作成

postgres=> \du #ロールの確認

   Role name   |                List of roles Attributes                    | Member of
---------------+------------------------------------------------------------+-----------
 new_user      |                                                            | {}
 user          | Superuser, Create role, Create DB, Replication, Bypass RLS | {}


postgres=> select usename from pg_user; #ユーザーの確認
  usename
-----------
 wm
 divemates
(2 rows)
```

## データベースのオーナーを変更
データベースとロールが作成されている状態で次のコマンドで変更可能。
オプションについて詳しくは[こちら](https://www.postgresql.jp/document/11/html/sql-alterdatabase.html)

```zsh
postgres=> ALTER DATABASE [データベース名] OWNER TO [新しいオーナー名];
```

## オーナーを指定してデータベースを作成
ロールが作成されている状態で次のコマンドで作成。

```zsh
$  createdb [データベース名] -O [ロール名]
```

## テーブルの確認
Railsなどでテーブルを作成後、次のコマンドで確認できる。

```zsh
postgres=> SELECT * FROM [テーブル名];
```

```zsh
$ postgres #dbの起動

$ psql mydb #テーブルを作成したデータベースに接続
psql (12.2)
Type "help" for help.

mydb=> SELECT * FROM users;
 id | name | email 
----+------+------
(0 rows)
```

## 参考
[PostgreSQL 11.5文書](https://www.postgresql.jp/document/11/html/index.html)
[PostgreSQLのインストールからRailsでのDB変更まで](https://qiita.com/krtsato/items/4565051608a63f11b316)