そんなわけで、まずは DB のデータ環境を作成することにした。
手持ちの参考資料に構成が掲載されているため DB 設計は省略。
も少し余裕出てきてから、そこには着手しましょう。
ちなみに参考にしている資料はこちら (・ω・ つ 「新標準 PostgreSQL」
購入時にいろいろ見回った結果、いろんな言語からのアプローチが書いてあったためこれにしてみました。
余談はこれくらいにして、早速作業開始
01)ユーザー作成(P53)
まずやることはユーザー作成。いつまでも管理権限でやるわけにはいきません。
一般ユーザーを作成します。
ちなみに今後、特に断り無ければ SQL Shell の psql を使用していきます(スタートメニューの PostgreSQl 内にショートカットあり)
postgres=# create role normal1 createdb;
CREATE ROLE
postgres=# \password normal1
新しいパスワード:n1
もう一度入力してください:n1
postgres=#
こんな感じでユーザー作成完了です。
ちなみにパスワード部分は本来可視されませんが、備忘録兼ねているため表示しています。
さて気持ちよくテーブル作成に移ろうかと思ったのだが、ここで早速トラブル。
テーブルを作成するに辺り作成したユーザーでログインしようとしたら、できないと言われたのだ。
PostgreSQLに詳しい方なら、上のコマンドを見ればすぐに理由が判明するでしょう。
postgres-# \c postgres normal1
ユーザ normal1 のパスワード:
FATAL: ロール"normal1"はログインすることが許されていません
以前の接続は保持されています。
さて詳しくない僕は何とか理由を突き止めなければなりません。
作成をミスった・・・訳ではないらしい。
「許されていません」と言うことは権限判定はされているのでユーザーは作れているはず。
そんなわけでユーザー一覧を確認するコマンドを調べて実行してみた。
postgres-# \dg
ロール一覧
ロール名 | 属性 | メンバー
----------+----------------------------------------------------------------------+----------
normal1 | DBを作成できる, ログインできない | {}
postgres | スーパーユーザ, ロールを作成できる, DBを作成できる, レプリケーション | {}
ログインできない・・・って、おぃ(^^;
どー考えても権限問題ですね。
っとなると作成時のコマンドミスって事になります。
とりあえず
\h
コマンドを実行して、どんなコマンドがあるのか確認。すると
CREATE ROLE
以外に CREATE USER
なんていうのもあります。今回の問題に対する回答は
CREATE USER
のリファレンス内にありました。PostgreSQL 9.1.4文書 CREATE USER
要するに
CREATE ROLE
だとログイン権限が付与されないって訳です。はい、ロールの権限について勉強になりましたね。
さっさと権限を付与しましょう。
postgres-# \dg normal1
ロール一覧
ロール名 | 属性 | メンバー
----------+----------------------------------+----------
normal1 | DBを作成できる, ログインできない | {}
postgres=# alter role normal1 LOGIN;
ALTER ROLE
postgres=# \dg normal1
ロール一覧
ロール名 | 属性 | メンバー
----------+----------------+----------
normal1 | DBを作成できる | {}
postgres=# \c postgres normal1
ユーザ normal1 のパスワード:
データベース "postgres" にユーザ"normal1"として接続しました。
postgres=>
・・・やっとユーザー作成完了です
ある程度のトラブルとか知識不足は覚悟していましたが、これはまったく先が思いやられますね。
とにかく先に進みましょう。
02)データベースの作成(P56)
所有者にしたいロールでのログインは終わっているので、いきなり CREATE DATABASE
です。postgres=> create database study1;
CREATE DATABASE
postgres=> \l
データベース一覧
名前 | 所有者 | エンコーディング | 照合順序 | Ctype(変換演算子) | アクセス権
-----------+----------+------------------+-----------------+-------------------+-----------------------
postgres | postgres | UTF8 | Japanese, Japan | Japanese, Japan |
study1 | normal1 | UTF8 | Japanese, Japan | Japanese, Japan |
template0 | postgres | UTF8 | Japanese, Japan | Japanese, Japan | =c/postgres +
| | | | | postgres=CTc/postgres
template1 | postgres | UTF8 | Japanese, Japan | Japanese, Japan | =c/postgres +
| | | | | postgres=CTc/postgres
(4 行)
ざっくりオプションを省略しましたが、ちゃんとできているようです。
さて、倉庫はできたので、次に倉庫の中に入れる箱を用意しましょう。
03)テーブルの作成(P61)
やっと本題とも言えるテーブル作成です。postgres=> create table Company_Detail(
postgres(> Code int PRIMARY KEY,
postgres(> Name varchar NOT NULL,
postgres(> Address varchar);
NOTICE: CREATE TABLE / PRIMARY KEYはテーブル"company_detail"に暗黙的なインデックス"company_detail_pkey"を作成します
CREATE TABLE
postgres=>
postgres=> create table Post_Name(
postgres(> Code int PRIMARY KEY,
postgres(> Name varchar NOT NULL);
NOTICE: CREATE TABLE / PRIMARY KEYはテーブル"post_name"に暗黙的なインデックス"post_name_pkey"を作成します
CREATE TABLE
postgres=>
postgres=> create table userinfo(
postgres(> No serial PRIMARY KEY,
postgres(> First_Name varchar NOT NULL,
postgres(> Last_Name varchar,
postgres(> Company_Code int REFERENCES Company_Detail(Code),
postgres(> Post_Code int REFERENCES Post_Name(Code),
postgres(> User_ID varchar NOT NULL,
postgres(> Password varchar NOT NULL);
NOTICE: CREATE TABLEはシリアル列"userinfo.no"用に暗黙的なシーケンス"userinfo_no_seq"を作成します。
NOTICE: CREATE TABLE / PRIMARY KEYはテーブル"userinfo"に暗黙的なインデックス"userinfo_pkey"を作成します
CREATE TABLE
postgres=> \d
リレーションの一覧
スキーマ | 名前 | 型 | 所有者
----------+-----------------+------------+---------
public | company_detail | テーブル | normal1
public | post_name | テーブル | normal1
public | userinfo | テーブル | normal1
public | userinfo_no_seq | シーケンス | normal1
(4 行)
とりあえずできたようです。
いきなり3テーブルも作ったのに、うまくいったものです。
今のところエラーは無いようですし、この調子でデータの登録もやってしまいましょう。
04)データの登録(P62)
データの登録です。テーブル作成時に
REFERENCES
を指定しているので順番を注意しないといけません。postgres=> insert into Company_detail values( 1, '株式会社 風娘工房', 'ディオン教会脇' );
INSERT 0 1
postgres=> insert into Company_detail values( 2, 'カナリス コーポレーション', 'グルーディオ城の村1ー2' );
INSERT 0 1
postgres=> insert into Company_detail values( 3, '有限会社 雷娘電気' );
INSERT 0 1
postgres=>
postgres=> insert into Post_Name values
postgres-> ( 1, '会長' ),
postgres-> ( 5, '社長' ),
postgres-> ( 10, '部長' ),
postgres-> ( 99, '一般' );
INSERT 0 4
postgres=>
postgres=> insert into userinfo (First_Name, Last_Name, Company_Code, Post_Code, User_ID, Password) values
postgres-> ('カナリス', '', 2, 1, 'Canaris','Cana'),
postgres-> ('風娘', '', 1, 1, 'Fuunyan', 'Fuu'),
postgres-> ('雷娘', '', 3, 5, 'Rainyan', 'Rai'),
postgres-> ('マーニャ', '', 1, 99, 'Marnya', 'Mar'),
postgres-> ('フィルビス', 'ホーリーウッド', 1, 10, 'Filvis', 'Fil');
INSERT 0 5
postgres=> select * from Company_Detail;
code | name | address
------+----------------------------+--------------------------
1 | 株式会社 風娘工房 | ディオン教会脇
2 | カナリス コーポレーション | グルーディオ城の村1ー2
3 | 有限会社 雷娘電気 |
(3 行)
またエラー無しで登録できました。
内容を確認してみましょう。
postgres=> select * from Company_Detail;
code | name | address
------+----------------------------+--------------------------
1 | 株式会社 風娘工房 | ディオン教会脇
2 | カナリス コーポレーション | グルーディオ城の村1ー2
3 | 有限会社 雷娘電気 |
(3 行)
postgres=> select * from Post_Name;
code | name
------+------
1 | 会長
5 | 社長
10 | 部長
99 | 一般
(4 行)
postgres=> select * from userinfo;
no | first_name | last_name | company_code | post_code | user_id | password
----+------------+----------------+--------------+-----------+---------+----------
1 | カナリス | | 2 | 1 | Canaris | Cana
2 | 風娘 | | 1 | 1 | Fuunyan | Fuu
3 | 雷娘 | | 3 | 5 | Rainyan | Rai
4 | マーニャ | | 1 | 99 | Marnya | Mar
5 | フィルビス | ホーリーウッド | 1 | 10 | Filvis | Fil
(5 行)
company_code
と post_code
は REFERENCES
オプションを指定しているため、まずは Company_Detail
と Post_Name
にデータを登録しています。こうしないと参照したいデータがないと言われてエラーが発生します(まぁ回避策あるようなのですが、それはまた別途)
postgres=> insert into userinfo (First_Name, Last_Name, Company_Code, Post_Code, User_ID, Password) values ('ほげ', 'ほげほげ', 10, 1, 'hoge','hoge');
ERROR: テーブル"userinfo"への挿入、更新は外部キー制約"userinfo_company_code_fkey"に違反しています
DETAIL: テーブル"company_detail"にキー(company_code)=(10)がありません
postgres=>
エラーに出ているとおり会社コードに 10 なんて登録していませんから、エラーになります。
これでデータ側の事前準備完了・・・ですかね。
さーて、やっとアプリ作って、アクセスできるようになりましたよ。
そのあたりは次回。