馬鹿なことをやっていた 今気づいたけど

さて、kamakuralive.netは鎌倉ライブの Home Pageですが、先日までサーバーの切り替えですったもんだしたのです しかし、このクラウド・ベースのサーバーになり速度は明らかに早くなり安定しています

ここのプログラムは何回も言いますが、全てゼロから僕自身が html, css, jQuery, javascript, php, sql (mysql)を用いてプログラムを書いてきたものです

基本的にデータ構造は、たった3つのテーブルを使用するのみです それは、それぞれ dr_tbl, session_tbl, role_tblと名付けていますが、論理的にはお互いにリンク付けられ、関係データベースを形成しています

そのように作ったつもりだったのですが、今日突然気づきました それは database sqlのデバグをしている段階だったのです 何と role_tblsが session_tblを指すべき indexを作っていなかったのです!!!

もちろん今からこれを作るのは簡単ですが、そうなるとそこに関係したプログラムのみならず、既に入力されているデータそのものも変更が必要となります 参りました

そんなことをすれば膨大な時間がかかりますので、とりあえずはこのままにすることに決めました ほとんど不都合は発生しませんが、役割の時間帯重複を sqlで検出することが困難なのです

三つのテーブルをつなぐ肝腎の SQL文

忘れない内に残しておきましょう というのも、インターネット上には誤った SQL文が堂々と upload公開されていたりするのですから・・・

まずはテーブルの定義です

CREATE TABLE `man_tbls` (
	`id` INT( 11 ) NOT NULL AUTO_INCREMENT,
	`sirname` VARCHAR( 100 ) NOT NULL DEFAULT '',
	`firstname` VARCHAR( 100 ) NOT NULL DEFAULT '',
	`is_male` BOOLEAN NOT NULL DEFAULT '1',
	`birthdate` DATE NOT NULL DEFAULT '0000-00-00',
	PRIMARY KEY (`id`),
) ENGINE = InnoDB CHARACTER SET utf8 COLLATE utf8_general_ci AUTO_INCREMENT=0;

CREATE TABLE `disease_tbls` (
	`id` INT( 11 ) NOT NULL AUTO_INCREMENT,
	`diagnosis` VARCHAR( 100 ) NOT NULL DEFAULT '',
	PRIMARY KEY (`id`),
) ENGINE = InnoDB CHARACTER SET utf8 COLLATE utf8_general_ci AUTO_INCREMENT=0;

CREATE TABLE `relation_tbls` (
	`id` INT( 11 ) NOT NULL AUTO_INCREMENT,
	`man_tbl_id` INT( 11 ) NOT NULL DEFAULT '0',
        `disease_tbl_id` INT( 11 ) NOT NULL DEFAULT '0',
	PRIMARY KEY (`id`),
) ENGINE = InnoDB CHARACTER SET utf8 COLLATE utf8_general_ci AUTO_INCREMENT=0;

この SQL文により、MySQLデータベース・エンジンにより三つのテーブルが作成されます 本当はこのデータベースに対して、さっき記述したデータを入力しておいて下さると助かりますが・・・

さて、このようなデータベース、これは実は 二つの固有テーブルを「関係テーブル」で結びつける「多」対「多」関係のデータなのですが、この中から、ある人が、ある病気にかかっている、ということを記述する SQL文は次のようになります

SELECT `M`.`id`,  `M`.`sirname`, `M`.`firstname`, `M`.`is_male`, `M`.`birthdate`,`D`.`disease
FROM `man_tbls` AS `M` INNER JOIN(`relation_tbls` AS `R` INNER JOIN  `disease_tbls` AS `D` ON `D`.`id` = 
`R`.`disease_tbl_id`  ) ON `M`.`id` = `R`.`man_tbl_id`;

結構複雑でしょ?

少し複雑な SQL文

一泊二日で台湾・高雄でお仕事して月曜日は外来診療、そして色々なお仕事しました

火曜日の9:27は朝から Houstonに向けて飛び立ち、そのまま Colombiaに入るのです 今は、Houston空港で 6時間余りの transitをしています

そんな中懸案の SQLがようやく書けました これは、三つのテーブルを結びつけるものですが、要するに「多」対「多」という二つのテーブルを結びつけるために、間に「関連」テーブルを使うものです

この関係は実社会で良く見られるものです 例えば 人物テーブルを考えて下さい、このテーブルで重要なデータは

  1. 固有のID 今日の日本であれば、「個人番号」でしょうね
  2. 名前の姓
  3. 名前の名
  4. 性別
  5. 生年月日

などでしょう もちろん他にも色々付け足せますが、ここで重要なのは個々のフィールド (ここでは番号の1~5ですが)については、一度値が入れば、変化しない、ということです そして、1については、「個人番号」がそうであるように、重複することが決して無い ということなのですよっ

例えば、6.として「職業」を持ってきたとします ある時点では、その値は、学生であり、次には会社員となり、その次にはアルバイトになるかも知れません 要するに、「職業」というものは変化していきますので、この人物テーブルの構成要素としては相応しくありません

もちろん、「職業1」「職業2」「職業3」・・・・「職業10」ぐらい予備に造っておけばそれでも良いでしょうが

名前については、実は微妙な問題があります 日本では結婚することにより女性の姓が変化するのが普通ですので、最初から「姓1」「姓2」・・「姓5」ぐらい造っておいた方が良いかも知れませんね

さて、次に 病気テーブル について考えましょう これは簡単に次のようにしましょう

  1. 病気のID ここは例えば色々な国際的コードがあります
  2. 病名 例えば、胃炎、心筋梗塞などなどですね

さて、この二つのテーブルを用いて、ある人がある病気にかかっている という状態をどのように表せば良いでしょうか?

実はここで必要なのが、二つのテーブルを結びつける「関係テーブル」なのです

まずは「人物テーブル」です

ID 性別 生年月日
1 ABE SHI M 19500215
2 TABE SHISHI F 19511115
3 TABEKI MOMO M 19520415

さて次に「病気テーブル」です

ID 病名
1 急性胃炎
2 慢性胃炎
3 狭心症

さて、ある人の状態を表すにはどのようにすれば良いでしょうか? 例えば TABEさんが狭心症にかかっている、というのは「人物テーブル」のID=1と 「病気テーブル」のID3を結びつければ良いですよね 従って以下の 関連テーブルが必要となります

ID 人物テーブルID 病気テーブルID
1 1 3

このテーブルをどんどん増やしていけば良いのですよね これが Relational Database (関係データベース)の基礎の基礎なのですが、結構難しいのですよ これをSQL文で書くのは

何と そうだったのか

ここに二つのテーブルがあります そう、片方は doctor_tblsであり、今一つは role_tblsです 簡単にすれば

doctor_tblsは

doctor_tbl_id name is_male
1 saito 1
2 shigeru 1
3 hanako 0

このようにしましょう is_maleは性別であり、男性であれば、1 女性であれば 0としましょう

もう一つのテーブルは役割配置表 role_tblsで その構造は

role_tbl_id doctor_tbl_id role_kind
1 2 chair
2 2 speaker
3 1 moderator

のように例えばなります つまり、saitoさんは doctor_tbl_id = 1ですが、 role表の中の role_tbl_id = 3に配置されていますね そして役割は moderatorということになります これをSQL文で記述すれば

SELECT * FROM `doctor_tbls` INNER JOIN `role_tbls` 
ON `doctor_tbls`.`doctor_tbl_id` = `role_tbls`.`doctor_tbl_id`;

ということになります ここで良くあるように

role_tbl_id doctor_tbl_id role_kind
1 2 chair
2 2 speaker
3 1 moderator
4 1 speaker
5 1 chair

のようにsaitoさんの役割分担が三つに増えたとしましょう この時に、役割が2つの人を探す SQL文について考えみました なかなか正解には至らなかったのですが、色々調べてようやく分かりました それは

SELECT `dr_tbl_id`, count(`dr_tbl_id`) as `Frequency` FROM `role_tbls` group by `dr_tbl_id` HAVING `Frequency` = '2'

というものです ここで HAVING句を用いるのと、仮想列名 Frequencyというのを用いるのがミソなのです 素晴らしいですね

とにかく SQLというのはプログラミング言語の中でも異色のものであり、集合演算をするのです これを理解しないと無駄足を踏むことになりますね

目標としていた9月1日に何とか間に合いました

鎌倉ライブデモンストレーションのHome Pageの全面改訂を8月の10日頃から行ってきました ある程度公開するのを9月1日と目標設定していたのですが、何とか間に合いました

http://kamakuralive.net/

大きなバグはとれていると思います このページの特徴は、SQL databaseに色々なデータを別の保護されたページにより登録すれば、それが自動的にこのページで更新されていく、ということです

鎌倉ライブデモンストレーションの詳細については未だ確定できない部分も多く、かといって全く分からないままで放置しておくことも良くないので、このような構造にしたのです

僕にとってこれは長年のライブデモンストレーション生活の中での最適解の一つなのですが、それをどのように実現していけば良いのか、それを解決できるだけのスキルも知力も以前の僕にはありませんでした しかし、今は違います これをやり遂げるだけの能力を習得したのです 嬉しいな

これもTAVIがすんなりと治療できるから可能なのです ありがとう SAPIEN3

洗練化するデータ構造

鎌倉ライブデモンストレーションの公式Web Site構築中です こっそりと現在の姿お見せすると

http://kamakuralive.net/23rd/db_read/come_session_all_read.php

となるのですが、もちろん公式には未だ公開していません

このページの特徴は、参加して頂く方のデータを別のページでdatabaseに登録し、そこから読みだしているのです 従ってそのページにアクセスする方々は、常時データを更新することができ、それが瞬時に反映される、ということなのです さらに、データ構造を工夫してあり、たとえば ◯◯さんがどの時間帯に dutyがあり、それがぶつかっていないかどうかもすぐに判明できる、というものにしてあるのです このデータ構造を創造するのには随分と頭を回転させました 知力の勝負ですね

ぎりぎりセーフでお礼メールの発送完了 そして新年に

大晦日の紅白歌合戦が始まってから、「これはいかん」と思いま、集中的にとりかかりました

それは、鎌倉ライブデモンストレーションにFacultyとしていらして頂いた先生方にお礼のメールを出すことです もちろんそんなことは手作業でもできるのですが、折角ですのでプログラムを書いて Databaseより宛先を拾い、そしてその宛先にメールを発信する、そうしようと思いました

時間は迫るし、何しろプログラミングも少し離れると忘れてしまうので回復に時間が必要でした それでもぎりぎり 11:59PMには全員に自動発信することができました

良かった良かった そして新年となり、「皆様方 新年も宜しくお願いします。」

夢は広がる

さて、先ほどの SQLを使用すればたとえば以下のような出力が得られます もちろんデータは dummyですし、<table></table>を用いてhtmlで整形しています

登録数 病院名 年月
3 ShonanKamakura General Hospital 202410
15 ShonanKamakura General Hospital 202411
22 ShonanKamakura General Hospital 202412

これを用いれば、データをデータベースより出力し、現在勉強中の d3.jsを用いてグラフ化することも近いですね これは夢が拡がります

本日また新たな手技に一歩を踏み出すのです

今朝は早朝起床し、何時もより長く小雨降りしきる中自転車で出勤しました わざと通り道してペダルを漕ぎ、何だか何時もうまくいかない世の中を嘆きながら心を清く、そして強くしていくのでした

とはいいつつ頭の中は高速回転で一つのことを考えていたのです それは、登録日、病院毎に登録症例数を一覧として出力する SQL文の作成でした これは実用上重要であり、もちろん PHPや JavaScriptなどのスクリプトを介すれば誰でも出来ますが、それを SQL文で一発で行う、というものです

そして書きましたね 以下の文を

SELECT 
COUNT(*), `hp_tbls`.`hp_name`,       DATE_FORMAT(`pt_tbls`.`registration_date`, '%Y%m') 
FROM `pt_tbls` 
INNER JOIN `hp_tbls` 
ON `pt_tbls`.`hp_tbl_id` = `hp_tbls`.`id` 
GROUP BY `hp_tbls`.`id`, DATE_FORMAT(`pt_tbls`.`registration_date`, '%Y%m')

これで病院別かつ月別に登録症例数が一覧として出力されます あっ、SQLは MySQLのものですよ ここでのキモは、GROUP BYと DATE_FORMATでしょうか

何れにしても早朝より頭の回転は優れていました これで本日の新しい手技に全力で臨めますね

だめだだめだ 睡眠不足

昨日は早朝から霞ヶ関に出かけました まあ公用と言って良いでしょう まずは霞ヶ関ビル地下の喫茶店で1時間余り打ち合わせ 英語での打ち合わせなので疲れますよね

それからいよいよ本番でした とても良い方々ばかりで色々と救われます

それが済んでから鎌倉にとんぼ返りして、 13:45には病院到着 そして、そのまま外来診療に入りました

そもそも午前中外来診療する筈でしたが、その公用の予定時刻がなかなか確定しませんでしたので、外来診療予定はクローズせずにおいたのですが、結局午前に確定した段階で、診療時刻を移動しました もちろん患者さんにその都度連絡せねばならず、クラークの人たちに負担をかけることになりました

外来診療終了してから、経皮的冠動脈インターベンションです

疲れきってしまいましたので、早々に帰宅し、早めに寝ました

しかししかしなのです 韓国の先生からの電子メール受領

「日韓友好TRIセミナー・Slender Club Japanの受付サイトに入ったが、最終登録リンクが切れている」そのような内容でした

そうだこのサイトは、ぶっつけで作成したので、バグとりもなにもしていなかった それからバグとりしたのですが、何しろもう忘れているので、自分自身が catch upするのに時間がかかり、結局、2:30AMにまたまた起きてバグとり なかなかバグが潰せず苦労しましたが、何とか 5:00AM過ぎに潰れました そして ServerにUploardすると共に、SQL dumpをとり、それをメールに貼り付け、メールを送られてきた Lee先生に「大丈夫 バグはとれました」とメールしました

さて、これから寝るか と思うも、そんな時間は無い 無い 無い 無い

あーん結局今日も寝不足のまま出勤ですね

明日は朝出発で岐阜県の可児市に出かけ、可児のスレンダーライブデモンストレーションに参加します 1例治療することになり、また会の終了後、講演です

そうだそうだ水曜日は朝札幌東徳洲会病院心臓センターに出かけ、外来診療してからとんぼ返り、そして夜は横浜で講演会だったのです 何だか一日二日前の出来事もどんどん記憶の彼方に押しやっていっています そうしないともうむちゃくちゃになってしまいそうですよ

でも今日のバグとりは楽しかったですね 頭脳を相当に使います HTML, CSS, JavaScript, jQuery, SQL, PHPという6種類の言語を駆使して作り上げている総勢 5,000行ぐらいのサイトです 大きくはないけども securty checkなど結構頭を使います