« 2007年05月30日 | メイン | 2007年06月07日 »

2007年06月06日 アーカイブ

2007年06月06日

MySQL 主キー(PRIMARY KEY)、外部キー(FOREIGN KEY)について

●主キー(PRIMARY KEY)
プライマリキー
プライマリキーとはレコードを1行ずつ識別するためのフィールドで、プライマリキーは必ずユニークな値となる。プライマリキーの指定により、膨大なデータから必要なレコードだけを確実に取り出すことが可能。

>primary key 主キー制約(unique & not null)
>主キーはテーブル毎にひとつだけ設定できます。ここで主キーを設定する列にはNOT NULL制約が必要です。
>text型とBLOB型の列は、そのままでは主キーに含めることが出来ません。その列の先頭から何バイトを主キーとするか、明示的に指定してください。
「MySQL 全機能 リファレンス」P269

なるほど!!

●外部キー(FOREIGN KEY)
外部キー(Foreign Key)
テーブルのプライマリキーと同じ値を持った別のテーブルのフィールド値。

>バージョン3.23.43から外部キー(FOREIGN KEY)制約がサポートされました。このとき、外部キー制約を設定するテーブルと被参照テーブルは、InnoDBテーブル型でなければなりません。また、被参照テーブルと被参照列には、一意性(UNIQUE)制約、インデックス(INDEX)、主キー(PRIMARY KEY)のいずれかが設定されていなければなりません。

なるほどーー!

>外部キー制約を持つ参照元テーブルにデータを挿入しようとすると、その値が被参照テーブルの被参照列に存在するか否かを検査し、存在するときのみデータを挿入します。
「MySQL 全機能 リファレンス」P272

なるほど!!外部キーにはこんな役目があるんだ!!

>では、データ挿入後に(被参照テーブルの)被参照列の値を更新したり削除したい場合はどうなるのでしょうか。デフォルト動作では、更新や削除をしようとするとエラーとなり、参照元テーブルと被参照テーブル間のデータ整合性を保ちます。
>しかし、他のテーブルから参照されたばかりに、被参照テーブルの更新や削除ができなくなるのは不便です。この状況への対処法は、(外部キー制約を設定した)参照元のテーブルにON DELETE句とON UPDATE句を設定し、被参照テーブルでの更新や削除が行われた場合の動作(action)を指定することです。

>例えば、動作として”CASCADE”を指定すると、(被参照テーブルの)被参照列の値が更新された場合は、参照もとの列にも更新が反映され、削除された場合は、参照元のテーブルも削除されます。
>動作として"SET NULL"を指定すると、(被参照テーブルの)被参照列の値が更新や削除された場合に、参照もとの列に"NULL"が設定されます。同様に、"SET DEFAULT"の場合は、デフォルト値が設定されます。

なーるほどー!

MySQL JOIN構文

リレーショナルデータベース実験!

http://homepage2.nifty.com/sak/w_sak3/doc/sysbrd/mysql_09.htm
http://dev.mysql.com/doc/refman/4.1/ja/join.html
http://wota.jp/ac/?date=20051107
↑こちらを参考にした。

http://wota.jp/ac/?date=20060514
↑Railsと絡めるならここも役に立ちます。

●●●●準備●●●●

create database r_test;

use r_test

create table units (
  id      int(8),
  unit_name  char(8),
  primary key (id)
) type=InnoDB;

create table company (
  id      int(8),
  name    char(8),
  age     int8,
  unit_id int8,
  primary key (id)
)type=InnoDB
;

create table reports (
  id      int(8),
  company_id  int(8),
  content char(8),
  primary key (id)
) type=InnoDB
;

insert into company values (1,'abc', 21, 1);
insert into company values (2,'def', 30, 2);
insert into company values (3,'ghi', 40, 1);

insert into reports values (1,1, 'test');
insert into reports values (2,2, 'test2');
insert into reports values (3,3, 'test3');

insert into units values (1,'aries');
insert into units values (2,'gemini');
insert into units values (3,'capu');

●●●●確認●●●●

mysql> show tables;
+------------------+
| Tables_in_r_test |
+------------------+
| company          |
| reports          |
| units            |
+------------------+
3 rows in set (0.00 sec)

mysql> select * from units;
+----+-----------+
| id | unit_name |
+----+-----------+
|  1 | aries     |
|  2 | gemini    |
|  3 | capu      |
+----+-----------+
3 rows in set (0.00 sec)

mysql> select * from company;
+----+------+------+---------+
| id | name | age  | unit_id |
+----+------+------+---------+
|  1 | abc  |   21 |       1 |
|  2 | def  |   30 |       2 |
|  3 | ghi  |   40 |       1 |
+----+------+------+---------+
3 rows in set (0.00 sec)

mysql> select * from reports;
+----+------------+---------+
| id | company_id | content |
+----+------------+---------+
|  1 |          1 | test    |
|  2 |          2 | test2   |
|  3 |          3 | test3   |
+----+------------+---------+
3 rows in set (0.00 sec)

●●●●実験●●●●

mysql> select * from company inner join units where company.unit_id=units.id and units.id=1;
+----+------+------+---------+----+-----------+
| id | name | age  | unit_id | id | unit_name |
+----+------+------+---------+----+-----------+
|  1 | abc  |   21 |       1 |  1 | aries     |
|  3 | ghi  |   40 |       1 |  1 | aries     |
+----+------+------+---------+----+-----------+

mysql> select * from reports left join company on reports.company_id=company.id;
+----+------------+---------+------+------+------+---------+
| id | company_id | content | id   | name | age  | unit_id |
+----+------------+---------+------+------+------+---------+
|  1 |          1 | test    |    1 | abc  |   21 |       1 |
|  2 |          2 | test2   |    2 | def  |   30 |       2 |
|  3 |          3 | test3   |    3 | ghi  |   40 |       1 |
+----+------------+---------+------+------+------+---------+

おおおぉ。分かってきた・・・。


mysql> select * from ( reports left join company on reports.company_id=company.id ) 
  left join units on company.unit_id = units.id ;
+----+------------+---------+------+------+------+---------+------+-----------+
| id | company_id | content | id   | name | age  | unit_id | id   | unit_name |
+----+------------+---------+------+------+------+---------+------+-----------+
|  1 |          1 | test    |    1 | abc  |   21 |       1 |    1 | aries     |
|  2 |          2 | test2   |    2 | def  |   30 |       2 |    2 | gemini    |
|  3 |          3 | test3   |    3 | ghi  |   40 |       1 |    1 | aries     |
+----+------------+---------+------+------+------+---------+------+-----------+

おおおおぉ!完璧!
なんだ。できた。

さらに、where文も追加!

mysql> select * from ( reports left join company on reports.company_id=company.id ) 
  left join units on company.unit_id = units.id where units.id = 1;
+----+------------+---------+------+------+------+---------+------+-----------+
| id | company_id | content | id   | name | age  | unit_id | id   | unit_name |
+----+------------+---------+------+------+------+---------+------+-----------+
|  1 |          1 | test    |    1 | abc  |   21 |       1 |    1 | aries     |
|  3 |          3 | test3   |    3 | ghi  |   40 |       1 |    1 | aries     |
+----+------------+---------+------+------+------+---------+------+-----------+

完璧!

2007年06月

Sun Mon Tue Wed Thu Fri Sat
1 2
3 4 5 6 7 8 9
10 11 12 13 14 15 16
17 18 19 20 21 22 23
24 25 26 27 28 29 30

Map

About 2007年06月

2007年06月にブログ「プログラマ 福重 伸太朗 ~基本へ帰ろう~」に投稿されたすべてのエントリーです。過去のものから新しいものへ順番に並んでいます。

前のアーカイブは2007年05月30日です。

次のアーカイブは2007年06月07日です。

他にも多くのエントリーがあります。メインページアーカイブページも見てください。