Friction River Software

  • お問い合わせ

CakePHP5入門【WebAPI編②】要件定義&DB設計

B美

それでは「ナンバーズ情報をWebAPIとして提供するWebアプリケーション」を構築していくわけだけど…

まずは要件定義からね

A子

JSONフォーマットについては前回考えたけどさ
(あくまでも基本形であって、あとで変更するかもしれないけど…)

まずはExcelデータを取り込んだりするための管理画面が必要だね

C菜

管理者認証は、簡単なBASIC認証にしましょう~
(usersテーブルや認証機構を作るのは面倒です~)

A子

だね(苦笑)

トップページには各種WebAPIの説明文を表示して、右下くらいの位置に管理画面へのリンクを張ろう

C菜

当選番号データを追加・更新するためのCRUDクラッド画面は必要でしょうか~?

A子

CRUDって、Create・Read・Update・Deleteだよね

当然、要るんじゃない?

B美

毎日(月曜日から金曜日まで)、データを追加していくのは割と面倒だけどね

なので、できれば自動でデータを取得していく仕組みを作りたいところなんだけど、それってかなり難しいのよ(苦笑)

A子

不可能じゃないのなら、それもおいおい挑戦してみたいね

B美だったら、やり方を知ってるんでしょ?

B美

もちろん

でも私もあまりやりたくはないかな
(だって難しいんだもん)

C菜

B美部長が「やりたくない」とまでおっしゃるとは、かなり大変そうですね~
あ、とりあえずはExcelファイルのほうを更新(データ追加)して、それを随時読み込ませるようにしたらどうでしょう~?

インポート時に「すでにデータベースに存在するデータについては無視する」ようにすれば良いと思うんですよね~
(要するに、追加した分だけを読み込んでいくってことです~)

B美

データ収集が面倒なのは同じだけど、CRUD画面を作るよりはマシか…

それでいきましょう

A子

んじゃ、トップ画面と管理画面があって、管理画面だけはBASIC認証必須にして、Excelファイルのインポートのみ行うと…

WebAPIの仕様書って、どうすんの?

B美

当然、必要よ

URL戻り値であるJSON形式の二つが分かれば良いわ
ただし、それについては「基本設計」の段階でやるべきことかな

A子

だったら、要件定義ではこの記述だけで良いかな

「適切なURLを指定すれば、それに応じて適切なJSONデータを返す」

C菜

それでは、ここまでの分をまとめますね~

【要件定義】
・トップ画面にはWebAPIの説明文と管理画面(BASIC認証を行う)へのリンクを設ける
・管理画面ではExcelファイルのインポート処理のみを行う
・管理画面にはCRUD機能を実装しない
・適切なURLを指定すれば、それに応じて適切なJSONデータを返す
・WebAPIは基本的にナンバーズ3及び4の当選番号等の基礎情報を返すが、各種統計情報については別途追加していく

こんな感じでいかがでしょうか~?

B美

うん、良いと思うわよ

では、次にデータベース設計ね
今回、そこまでやっておきましょう

A子

簡単、簡単

create table numbers (
    id int auto_increment primary key,
    lottery_time int not null,
    lottery_date datetime not null,
    num3 varchar(3) not null,
    num4 varchar(4) not null,
    created datetime,
    modified datetime
) charset=utf8mb4;

lottery_time」が実施回、「lottery_date」が抽選日で、「num3」がナンバーズ3の当選番号、「num4」がナンバーズ4の当選番号ね

C菜

抽選日である「lottery_date」のデータ型ですけど、文字列型(varchar)のほうが良いのではないですか~?

B美

いえ、datetime型のほうが検索の自由度は広がるでしょうね
(○○年○月○日から××年×月×日の間…って感じの検索は、datetime型のほうがやりやすいからね)

まぁ、両方を持っておくというのも一つの方法だけど…
あと、曜日についてもあらかじめ算出しておいて、データベースに格納しておくってのが良いと思うわよ

A子

うーん、だったらこうしよう

create table numbers (
    id int auto_increment primary key, #主キー
    lottery_time int not null, #実施回
    lottery_date_dt datetime not null, #抽選日(日付型)→2026-02-27
    lottery_date_str varchar(20) not null, #抽選日(文字列型)→2026年2月27日
    lottery_week_int int not null, #抽選日の曜日(整数型)→0…日曜日,1…月曜日,2…火曜日,3…水曜日,4…木曜日,5…金曜日,6…土曜日
    lottery_week_str1 varchar(10) not null, #抽選日の曜日1(文字列型)→日曜日,月曜日,火曜日,水曜日,木曜日,金曜日,土曜日
    lottery_week_str2 varchar(5) not null, #抽選日の曜日2(文字列型)→日,月,火,水,木,金,土
    num3 varchar(3) not null, #ナンバーズ3の当選番号
    num4 varchar(4) not null, #ナンバーズ4の当選番号
    created datetime,
    modified datetime
) charset=utf8mb4;

それぞれの項目の意味はコメントに書いている通りね

B美

お、ちょっと驚いたわね

SQL文におけるコメントの書き方なんて教えてないのに…

C菜

シャープ(#)から改行までがコメントなんですか~?

B美

そうよ
ほかにも「#」の代わりに「--」を使う方法もあるけどね

あ、ただしMySQLでは「--コメント」はエラーになる
(「-- コメント」という書き方ならOK)

A子

ググったときにその情報は見たよ

「--」の後ろに半角スペースを入れないとダメだってさ

C菜

あ、抽選日の年月日をそれぞれ別の整数型項目として持っておくというのはどうでしょう~?
(「年」と「月」と「日」の項目です~)

そのほうが検索しやすいんじゃないでしょうか~?

A子

お、それ良いかも

ついでに当選番号についても整数型項目を追加して、さらに各桁ごとの数値を整数型で持っておこうか

create table numbers (
    id int auto_increment primary key, #主キー
    lottery_time int not null, #実施回
    lottery_date_dt datetime not null, #抽選日(日付型)→2026-02-27
    lottery_date_str varchar(20) not null, #抽選日(文字列型)→2026年2月27日
    lottery_date_year int not null, #抽選日の年
    lottery_date_month int not null, #抽選日の月
    lottery_date_day int not null, #抽選日の日
    lottery_week_int int not null, #抽選日の曜日(整数型)→0…日曜日,1…月曜日,2…火曜日,3…水曜日,4…木曜日,5…金曜日,6…土曜日
    lottery_week_str1 varchar(10) not null, #抽選日の曜日1(文字列型)→日曜日,月曜日,火曜日,水曜日,木曜日,金曜日,土曜日
    lottery_week_str2 varchar(5) not null, #抽選日の曜日2(文字列型)→日,月,火,水,木,金,土
    num3_str varchar(3) not null, #ナンバーズ3の当選番号(文字列型)
    num3_int int not null, #ナンバーズ3の当選番号(整数型)
    num3_place1 int not null, #ナンバーズ3の当選番号の一の位
    num3_place10 int not null, #ナンバーズ3の当選番号の十の位
    num3_place100 int not null, #ナンバーズ3の当選番号の百の位
    num4_str varchar(4) not null, #ナンバーズ4の当選番号(文字列型)
    num4_int int not null, #ナンバーズ4の当選番号(整数型)
    num4_place1 int not null, #ナンバーズ4の当選番号の一の位
    num4_place10 int not null, #ナンバーズ4の当選番号の十の位
    num4_place100 int not null, #ナンバーズ4の当選番号の百の位
    num4_place1000 int not null, #ナンバーズ4の当選番号の千の位
    created datetime,
    modified datetime
) charset=utf8mb4;

これでどうよ(ドヤ顔)

C菜

あ~、あと「大安」とか「仏滅」なんかの情報を持っておきたいですね~

簡単に調べられるのかどうかは分かりませんけど~

B美

いわゆる「六曜ろくよう」ってやつね

PHPには便利なライブラリがあるから、簡単に求められるわよ
(ただし、そのライブラリって、今回は利用できないんだけどね(苦笑))

A子

ふむ、だったらその六曜ってのも入れよう
(整数型と文字列型の両方で)

create table numbers (
    id int auto_increment primary key, #主キー
    lottery_time int not null, #実施回
    lottery_date_dt datetime not null, #抽選日(日付型)→2026-02-27
    lottery_date_str varchar(20) not null, #抽選日(文字列型)→2026年2月27日
    lottery_date_year int not null, #抽選日の年
    lottery_date_month int not null, #抽選日の月
    lottery_date_day int not null, #抽選日の日
    lottery_week_int int not null, #抽選日の曜日(整数型)→0…日曜日,1…月曜日,2…火曜日,3…水曜日,4…木曜日,5…金曜日,6…土曜日
    lottery_week_str1 varchar(10) not null, #抽選日の曜日1(文字列型)→日曜日,月曜日,火曜日,水曜日,木曜日,金曜日,土曜日
    lottery_week_str2 varchar(5) not null, #抽選日の曜日2(文字列型)→日,月,火,水,木,金,土
    lottery_rokuyo_int int not null, #抽選日の六曜(整数型)→0…大安,1…赤口,2…先勝,3…友引,4…先負,5…仏滅
    lottery_rokuyo_str varchar(10) not null, #抽選日の六曜(文字列型)→大安,赤口,先勝,友引,先負,仏滅
    num3_str varchar(3) not null, #ナンバーズ3の当選番号(文字列型)
    num3_int int not null, #ナンバーズ3の当選番号(整数型)
    num3_place1 int not null, #ナンバーズ3の当選番号の一の位
    num3_place10 int not null, #ナンバーズ3の当選番号の十の位
    num3_place100 int not null, #ナンバーズ3の当選番号の百の位
    num4_str varchar(4) not null, #ナンバーズ4の当選番号(文字列型)
    num4_int int not null, #ナンバーズ4の当選番号(整数型)
    num4_place1 int not null, #ナンバーズ4の当選番号の一の位
    num4_place10 int not null, #ナンバーズ4の当選番号の十の位
    num4_place100 int not null, #ナンバーズ4の当選番号の百の位
    num4_place1000 int not null, #ナンバーズ4の当選番号の千の位
    created datetime,
    modified datetime
) charset=utf8mb4;

もう無いかな?

C菜

「rokuyo」がローマ字です~(笑)

A子

仕方ないじゃない

Google翻訳でも「六曜 → rokuyo」って、出たんだから(苦笑)

B美

それにしても、なかなかの規模のテーブルになったわね

まぁ、「最低限のデータから得た結果をそのつど加工する方法」と、「あらかじめ加工済みのデータを持っておく方法」のどっちが良いかって話なんだけどね

C菜

今回のケースではどちらがベストなんでしょうか~?

B美

当然、後者よ

統計情報を集計するときって、最新のデータを含めて計算しないとダメなんだけど、毎回「曜日計算」や「六曜計算」をやってられないってわけ
一回だけ計算して、その結果を保存しておくほうが合理的だからね)

A子

よしっ!
それじゃ、以下のSQL文を読み込ませるよ
(ファイル名は「numbersdb.sql」にしたからね)

create database numbersdb;

use numbersdb;

create table numbers (
    id int auto_increment primary key, #主キー
    lottery_time int not null, #実施回
    lottery_date_dt datetime not null, #抽選日(日付型)→2026-02-27
    lottery_date_str varchar(20) not null, #抽選日(文字列型)→2026年2月27日
    lottery_date_year int not null, #抽選日の年
    lottery_date_month int not null, #抽選日の月
    lottery_date_day int not null, #抽選日の日
    lottery_week_int int not null, #抽選日の曜日(整数型)→0…日曜日,1…月曜日,2…火曜日,3…水曜日,4…木曜日,5…金曜日,6…土曜日
    lottery_week_str1 varchar(10) not null, #抽選日の曜日1(文字列型)→日曜日,月曜日,火曜日,水曜日,木曜日,金曜日,土曜日
    lottery_week_str2 varchar(5) not null, #抽選日の曜日2(文字列型)→日,月,火,水,木,金,土
    lottery_rokuyo_int int not null, #抽選日の六曜(整数型)→0…大安,1…赤口,2…先勝,3…友引,4…先負,5…仏滅
    lottery_rokuyo_str varchar(10) not null, #抽選日の六曜(文字列型)→大安,赤口,先勝,友引,先負,仏滅
    num3_str varchar(3) not null, #ナンバーズ3の当選番号(文字列型)
    num3_int int not null, #ナンバーズ3の当選番号(整数型)
    num3_place1 int not null, #ナンバーズ3の当選番号の一の位
    num3_place10 int not null, #ナンバーズ3の当選番号の十の位
    num3_place100 int not null, #ナンバーズ3の当選番号の百の位
    num4_str varchar(4) not null, #ナンバーズ4の当選番号(文字列型)
    num4_int int not null, #ナンバーズ4の当選番号(整数型)
    num4_place1 int not null, #ナンバーズ4の当選番号の一の位
    num4_place10 int not null, #ナンバーズ4の当選番号の十の位
    num4_place100 int not null, #ナンバーズ4の当選番号の百の位
    num4_place1000 int not null, #ナンバーズ4の当選番号の千の位
    created datetime,
    modified datetime
) charset=utf8mb4;

C菜

良いと思います~

mysql -u root -p < numbersdb.sql[Enter]

上記のコマンドを「MATE端末」上で実行しますね~

A子

念のため、確認しておこう

mysql -u root -p numbersdb[Enter]
show fields from numbers;[Enter]


B美

うん、良いみたいね

それじゃ、今回はここまでにしておきましょう
次回はWebアプリケーションを作っていくわよ

C菜

了解です~