第5回:テーブルを作っていじる(3)


シリアル型

テーブルを作ったりデータを入れたり出したりするやり方はわかったんで、次はテーブルのフィールド構成をいじってみる。 リレーショナル・データベースをいじくるのに、レコードを識別させるために ID 番号を持つテーブルを作るのは一般的であろうかと。 ここでも ID 番号を持つテーブルを作っちゃう。
ID 番号はテーブル内で重複しない一意な数とか文字とかがなにかとうれしい。 ポスグレには serial 型があって、フィールド定義で serial 型で宣言すれば一意な数字を自動で割り振ってくれる。便利。Access で言うところのオートナンバー型がこれです。
第3回第4回で作った address テーブルに ID 番号を持つ serial 型を追加してみる。 以下の内容の create2.sql ってファイルを作る。
CREATE TABLE address (
        id serial,
        name varchar(50),
        tel varchar(50),
        email varchar(50)
);
で create2.sql を読み込んで adress テーブルを作った。
postgres$ psql mydb
mydb=# \i create2.sql
psql:create2.sql:6: NOTICE:  CREATE TABLE will create implicit sequence 'address_id_s
eq' for SERIAL column 'address.id'
psql:create2.sql:6: NOTICE:  CREATE TABLE / UNIQUE will create implicit index 'addres
s_id_key' for table 'address'
CREATE
最後に CREATE ってあるんで成功しとるけど、なんか NOTICE ってメッセージがゴチャゴチャと出た。 これは内部で SEQUENCE が作られてるためです。確認してみた。
mydb=# \d
          List of relations
      Name      |   Type   |  Owner
----------------+----------+----------
 address        | table    | postgres
 address_id_seq | sequence | postgres
(2 rows)
address テーブルと address_id_seq シーケンスが作られてるのがわかる。
これについてマニュアルとか文献をあたってみると、serial 型を宣言すれば自動的にシーケンスが作られるとのこと。つまり、
CREATE TABLE address (id serial);
って宣言してあると、
CREATE SEQUENCE "address_id_seq";

CREATE TABLE "address" (
        "id" integer DEFAULT nextval("address_id_seq")
);

CREATE UNIQUE INDEX address_id_key ON address;
とコマンドを自動で実行してシーケンスを作ってくれるらしい。詳細は不明やけど気にしないことにする。
シリアル型を作ったならば、注意として、テーブルを削除する時に DROP TABLE で削除してもシーケンスは残ったままになるとのこと。 ちゃんと DROP SEQURNCE コマンドも実行してシーケンスも削除しておきましょう。だってさ。

データを入れてみる

シリアル型で ID 番号を持つテーブルを作ったんで、実際にデータを入れてみる。
前回使った、以下の内容のファイル insert.sql を用意して
INSERT INTO address (name, tel, email)
        VALUES ('Watashi', '234-8900', 'aa@bb.net');
INSERT INTO address (name, tel, email)
        VALUES ('Omae', '321-0000', 'ff@bb.net');
INSERT INTO address (name, tel, email)
        VALUES ('Anta', '234-0000', 'dd@ff.net');
これらを address テーブルに挿入させてみた。
mydb=# \i insert.sql
INSERT 16643 1
INSERT 16644 1
INSERT 16645 1
いい感じ。うまくいったか一覧表示。
mydb=# SELECT * FROM address;
 id |  name   |   tel    |   email
----+---------+----------+-----------
  1 | Watashi | 234-8900 | aa@bb.net
  2 | Omae    | 321-0000 | ff@bb.net
  3 | Anta    | 234-0000 | dd@ff.net
(3 rows)
うけけけ。ちゃんと ID 番号が振られてるね。

シーケンス値を見てみる

シリアル型でシーケンス値がつくられたのは確認した。 直前に入力したシーケンス値を調べたいときは、SELECT でシーケンスの last_value 値を調べれば収得できる。 こうする。
mydb=# SELECT last_value FROM address_id_seq;
 last_value
------------
          3
(1 row)
last_value が 3 だよと教えてくれました。
ちなみに、シーケンス値の最小値を知りたいときは min_value を見る。
mydb=# SELECT min_value FROM address_id_seq;
 min_value
-----------
         1
(1 row)
min_value が 1 だよと教えてくれました。 最大値は max_value です。
mydb=# SELECT max_value FROM address_id_seq;
      max_value
---------------------
 9223372036854775807
(1 row)
うーん、最大値は兆を超えてる。

シーケンス値をいじる

一回シーケンス値を定義してしまっても後でシーケンス値を変えたい場合がある。 たとえば、バックアップしてあるデータを挿入したときなんか。 ID 番号をユニークな主キーとして定義して他のテーブルとリレーションを作ってるときなんか、 シーケンス値が重複したらまずいので、なおさら再定義したくなっちゃう。
シーケンス値を再定義するのは setval 関数を使う。
setval('シーケンス名',値);
こげな感じ。さっそく試してみる。 シーケンス値を 100 にしてみると、
mydb=# SELECT setval('address_id_seq', 100);
 setval
--------
    100
(1 row)
こうなりました。ほんまに 100 になったんか確認してみる。
上でデータを挿入した insert.sql ファイルをもう一度使って挿入してみました。
mydb=# \i insert.sql
mydb=# SELECT * FROM address;
 id  |  name   |   tel    |   email
-----+---------+----------+-----------
   1 | Watashi | 234-8900 | aa@bb.net
   2 | Omae    | 321-0000 | ff@bb.net
   3 | Anta    | 234-0000 | dd@ff.net
 101 | Watashi | 234-8900 | aa@bb.net
 102 | Omae    | 321-0000 | ff@bb.net
 103 | Anta    | 234-0000 | dd@ff.net
(6 rows)
うーん、ID 番号は 100 から振られると思ったら 101 からに設定されてるね。 ま細かいことは気にしません。そういう使用なんやろう。
('03.01.22)

Back