tag:crieit.net,2005:https://crieit.net/tags/MinQ/feed 「MinQ」の記事 - Crieit Crieitでタグ「MinQ」に投稿された最近の記事 2019-12-12T21:21:54+09:00 https://crieit.net/tags/MinQ/feed tag:crieit.net,2005:PublicArticle/15600 2019-12-12T21:21:54+09:00 2019-12-12T21:21:54+09:00 https://crieit.net/posts/MinQ-5-MinQ MinQ開発日記 (5) MinQが目指すもの & テーブル設計 <h1 id="MinQとは何なのかを考える"><a href="#MinQ%E3%81%A8%E3%81%AF%E4%BD%95%E3%81%AA%E3%81%AE%E3%81%8B%E3%82%92%E8%80%83%E3%81%88%E3%82%8B">MinQとは何なのかを考える</a></h1> <h2 id="動機"><a href="#%E5%8B%95%E6%A9%9F">動機</a></h2> <p>勉強がてら適当に作っていたAPIサーバー. このデータベースのテーブル設計を考え始めたらどんなデータを収めるべきなのかを考える必要が出てきた. めんどくさいわけだが, これはMinQを具体的に掘り下げるのにいい機会にもなると思った.</p> <h2 id="MinQを作ろうと思った理由"><a href="#MinQ%E3%82%92%E4%BD%9C%E3%82%8D%E3%81%86%E3%81%A8%E6%80%9D%E3%81%A3%E3%81%9F%E7%90%86%E7%94%B1">MinQを作ろうと思った理由</a></h2> <p>基本的には勉強履歴を付けようと思ったからです. ただそのためのルールとかサービスで自分に合うものがなかった(見つけられなかった)のでポートフォリオがわりになるかと思って作り始めました.</p> <h2 id="より良い勉強法とは?"><a href="#%E3%82%88%E3%82%8A%E8%89%AF%E3%81%84%E5%8B%89%E5%BC%B7%E6%B3%95%E3%81%A8%E3%81%AF%3F">より良い勉強法とは?</a></h2> <p>勉強に王道はないとよく言われる. 特に楽な方法はないとされます(<a target="_blank" rel="nofollow noopener" href="https://wired.jp/2014/08/15/learn-languages-while-sleeping/">睡眠学習にも一定の効果があると言う話もある</a>という話もありますが・・・). 反復学習が必要でモノの本には脳に汗をかかせることが大事と言う趣旨のことが書いてあった記憶があります. とはいえ闇雲にやっても暗中模索で, 迷子になるのがオチだし, 忘却曲線のように効果がある勉強法もいくつか存在するのは確かです. アウトプットが良いなんて話もあって, 勉強したことをブログに書くと言うこともあるだろう. 備忘録にもなるので設定や環境構築なんかではやる人も多いわけですが, 実際はググった方が速かったりします.</p> <h2 id="勉強法"><a href="#%E5%8B%89%E5%BC%B7%E6%B3%95">勉強法</a></h2> <p>いち初学者として自分が勉強する上でどうやれば良いのかを考えた. また教育系の一般書に目を通して比較的効率的な学習法も調べた. その結果現状あまり良い勉強法と言うか環境が提供されていない気がした.</p> <div class="table-responsive"><table> <thead> <tr> <th align="center">勉強法</th> <th align="center">利点</th> <th align="center">弱点</th> </tr> </thead> <tbody> <tr> <td align="center">アウトプット</td> <td align="center">情報を共有できる</td> <td align="center">グーグル検索問題</td> </tr> <tr> <td align="center">動画</td> <td align="center">分かりやすい</td> <td align="center">効率がいまいち</td> </tr> <tr> <td align="center">文章チュートリアル</td> <td align="center">分かりやすい. 動画よりは効率的</td> <td align="center">探すのが辛い</td> </tr> <tr> <td align="center">スクール</td> <td align="center">ピア・プレッシャでモチベーションを維持できる</td> <td align="center">高額, 初心者向けしかない</td> </tr> <tr> <td align="center">検定(情報処理技術者試験, LPIC)</td> <td align="center">基準が明確</td> <td align="center">試験のインターバルが長い</td> </tr> <tr> <td align="center">本</td> <td align="center">情報の精度は高い(はず)</td> <td align="center">古い, カリキュラムが組みにくい</td> </tr> </tbody> </table></div> <p>誰でも一つまたは複数の勉強法を試したことがあるはずです. さてこのようにコンテンツは沢山あり勉強するには良い時代・・・となりそうですが(別に否定はしませんが), 個人的な不満があったりします.</p> <h3 id="本"><a href="#%E6%9C%AC">本</a></h3> <p>情報が古いとかは承知で買うしそれはそれで勉強になったりするのですが, 復習が困難です. 本によっては課題や復習問題が付いていますが, それを自分で管理するのは面倒です. 特に大量にインプットしたらもう一度同じ本を読むのは億劫です. また全体のカリキュラムも描き難いです. 内容ごとに言語にまたがることも多いので, 効率性も微妙な気はします.</p> <h3 id="検定"><a href="#%E6%A4%9C%E5%AE%9A">検定</a></h3> <p>テストは学習において効果が高いとされていますが, 難易度の調整が微妙な気がします. もっと柔軟な習熟度に合わせた学習法が実現できそうです. 他にもテストのインターバルが長すぎる, 学習履歴が残らないと点が不満です.</p> <h3 id="動画"><a href="#%E5%8B%95%E7%94%BB">動画</a></h3> <p>動画は見ていると楽しいものもありますが, プログラムの場合追いにくい場合があります. 結局GitHubなどに置かれている完成品を読んだり写経するという羽目になったりします. 復習もやりずらいです.</p> <h3 id="スクール"><a href="#%E3%82%B9%E3%82%AF%E3%83%BC%E3%83%AB">スクール</a></h3> <p>金がない(以上)</p> <h3 id="文書"><a href="#%E6%96%87%E6%9B%B8">文書</a></h3> <p>ブログのことと思えばいいです. 検索してヒットするとありがたいのですが勉強法としては, 疑問です. 結局ドキュメントのメモだったりするものもあり, ドキュメントを読むということも多々あります. ただエラーへの対処とかは便利だと思います.</p> <h3 id="アウトプット"><a href="#%E3%82%A2%E3%82%A6%E3%83%88%E3%83%97%E3%83%83%E3%83%88">アウトプット</a></h3> <p>勉強記録とかGitHubにひたすらコードをあげるという感じです. この開発日記もその一つでしょう. 人に教えるというのは高い学習効果があるとされていますのである程度の効果は見込めそうです. しかし見返す前に同じ内容をググってしまったり, 単なるメモや記事として価値がないようなもの(この記事みたいな?)があったりします. さらに時間がかかります. とはいえ自分の記事に助けられるという機会があった人もいるでしょう.</p> <h2 id="MinQはどうする?"><a href="#MinQ%E3%81%AF%E3%81%A9%E3%81%86%E3%81%99%E3%82%8B%3F">MinQはどうする?</a></h2> <p>これらを踏まえてMinQはどうするかです. MinQはクイズベースです. 形式としてはLPICが一番近い気がしますが, 別にプログラミングに限る必要はなく英語や数学なんかもやってみたいです. また学習履歴も細かく管理したいですが, 学習管理サービスは別に作るつもりなのでここでは考えません.</p> <h3 id="なぜクイズ?"><a href="#%E3%81%AA%E3%81%9C%E3%82%AF%E3%82%A4%E3%82%BA%3F">なぜクイズ?</a></h3> <p>テスト形式が比較的学習効果が高いそうです(確かそうだったはずです). 作りやすいし, 還元的な手法は物事を理解する基本だと思います. 解析とかもしたいのでデータを細かく取りたいというのもあります. 学習者(現状対象者は私だけですが)は理解していることよりもしていないことを知りたいわけです. また隙間時間で学習できるようにしたいというのもありこの形式を採用しました.</p> <ul> <li>学習のリズムを作る</li> <li>適切な問を適切な時に</li> </ul> <h3 id="従来のクイズ・アプリ/サービスとの違いは?"><a href="#%E5%BE%93%E6%9D%A5%E3%81%AE%E3%82%AF%E3%82%A4%E3%82%BA%E3%83%BB%E3%82%A2%E3%83%97%E3%83%AA%2F%E3%82%B5%E3%83%BC%E3%83%93%E3%82%B9%E3%81%A8%E3%81%AE%E9%81%95%E3%81%84%E3%81%AF%3F">従来のクイズ・アプリ/サービスとの違いは?</a></h3> <p>あくまで個人の実験用アプリなのであんまり詳しく考えてませんが, 以下のような感じでしょうか.</p> <ul> <li>隙間時間の有効活用</li> <li>復習のしやすさ</li> <li>忘却曲線</li> <li>知識/能力の可視化</li> </ul> <p>究極の目標は知識/能力の可視化です. クイズだと単位が小さすぎるのでどうなるか分かりませんが, 知識や技術をネット上で短く切り売りできたら面白いかなと思っています. PRaasS (PRogrammer As a Service)とでも呼んでおきましょうか.</p> <p>そういう意味ではクイズが目的というよりは能力を可視化するというのが大きな目標になりそうです.</p> <h2 id="テーブル設計"><a href="#%E3%83%86%E3%83%BC%E3%83%96%E3%83%AB%E8%A8%AD%E8%A8%88">テーブル設計</a></h2> <p>でようやく本題ですが, 関係データベースはテーブルから構成されるのですが, テーブルはスキーマと呼ばれる構造を持っています. まずはデータを編集するための管理画面(adminページ)用のテーブルが必要にあります.</p> <div class="table-responsive"><table> <thead> <tr> <th>カラム名</th> <th>用途</th> </tr> </thead> <tbody> <tr> <td>id</td> <td>主キー</td> </tr> <tr> <td>user_name</td> <td>ユーザーの名前</td> </tr> <tr> <td>email</td> <td>メール・アドレス</td> </tr> <tr> <td>password</td> <td>暗号化したパスワード</td> </tr> </tbody> </table></div> <p>こんなところでしょうか. 次はクイズ・テーブルが必要です.</p> <div class="table-responsive"><table> <thead> <tr> <th align="center">カラム名</th> <th align="center">用途</th> </tr> </thead> <tbody> <tr> <td align="center">id</td> <td align="center">主キー</td> </tr> <tr> <td align="center">question</td> <td align="center">問題文</td> </tr> <tr> <td align="center">answer</td> <td align="center">回答/解説</td> </tr> <tr> <td align="center">tag</td> <td align="center">グループ/カテゴリ名</td> </tr> </tbody> </table></div> <p>こんなカラムがあれば良いと思うのですが, 問題はanswerカラムとtagカラムです.</p> <h3 id="問答のフォーマット"><a href="#%E5%95%8F%E7%AD%94%E3%81%AE%E3%83%95%E3%82%A9%E3%83%BC%E3%83%9E%E3%83%83%E3%83%88">問答のフォーマット</a></h3> <p>いろんな形式がありますが, MinQでは<a target="_blank" rel="nofollow noopener" href="https://nbformat.readthedocs.io/en/latest/">The Jupyter Notebook Format</a>を参考しようと思います. この形式の利点は以下です.</p> <ul> <li>複数の形式を簡単に扱える</li> <li>ビューをシンプルに保てる</li> </ul> <p>リスト構造なのでビュー側での表示のロジックが簡単になります. またセルごとに形式を指定するのでパースして内容を解析するという工程が不要です. 例えばMarkdownに数式やコードを埋め込むと, 該当箇所を判別して違うレンダラを利用する必要があります. これをセル単位で管理すると文章か数式かコード片か, あるいは画像かなどは即座に判断できます. 表示もセルのリストなので比較的簡単です.</p> <h3 id="tagと関連実体"><a href="#tag%E3%81%A8%E9%96%A2%E9%80%A3%E5%AE%9F%E4%BD%93">tagと関連実体</a></h3> <p>クイズの分類のためにタグをつける場合, クイズが複数の分類に跨ることは普通にありえることです.そのためクイズには複数のタグを持たせられるようにするべきです. 一方でタグからクイズを絞り込むということもできた方が便利でしょう.</p> <p><a target="_blank" rel="nofollow noopener" href="https://charlesleifer.com/blog/a-tour-of-tagging-schemas-many-to-many-bitmaps-and-more/">A Tour of Tagging Schemas: Many-to-many, Bitmaps and More</a>にはいくつかの方法が解説されていて面白いです.</p> <p>もっとも素朴な解決策はタグをCSV(Character Seperated Value)形式で保存する方法です. 表示だけのことを考えるとこれで十分ですが, タグをつける理由は表示のためではないでしょう. またビットマップという手法もあります. ビット列をそれぞれのタグの有無と対応づける方法です. n番目のビットが1ならAタグが付いていることと見なすわけです. この方法は検索は効率的ですが, ビット列以上のタグを持てません.</p> <p><a target="_blank" rel="nofollow noopener" href="https://www.shoeisha.co.jp/book/detail/9784798124704">達人に学ぶDB設計 徹底指南書</a>では学生エンティティと講義エンティティの例が示されています. 両者を繋ぐのが関連実体/関連エンティティの受講です. この受講エンティティと呼ばれるエンティティは学生エンティティと講義エンティティの主キーを組み合わせたキーを主キーします. こうしたテーブル間の関係を多対多の関連 (Many-to-Many relationship)というらしいですが, GORMでは<a target="_blank" rel="nofollow noopener" href="http://gorm.io/docs/many_to_many.html">Joinテーブル</a>という中間テーブルで管理するようです. この機能を使うようにします.</p> <p>## MariaDB</p> <p>RDBMS(Relational DataBase Management System)としてはMariaDBを使おうと思います.</p> <p>### 導入</p> <p>CentOS 7にはMariaDBが入っていますが, 5.5とバージョンが古いです.</p> <p>```bash<br /> $ yum list installed | grep mariadb</p> <p>mariadb.x86_64 1:5.5.64-1.el7 @base<br /> mariadb-libs.x86_64 1:5.5.64-1.el7 @base<br /> mariadb-server.x86_64 1:5.5.64-1.el7 @base<br /> ```</p> <p>これをまずアンインストールします. <a target="_blank" rel="nofollow noopener" href="https://mariadb.com/resources/blog/installing-mariadb-10-on-centos-7-rhel-7/">How to install MariaDB 10 on CentOS 7 / RHEL 7</a>に従って, インストールします. 現状ではバージョン10.4が安定バージョンのようです.</p> <p><a href="https://crieit.now.sh/upload_images/f9bf88a0a074e399496de2154d0154d25df208e9769e9.png" target="_blank" rel="nofollow noopener"><img src="https://crieit.now.sh/upload_images/f9bf88a0a074e399496de2154d0154d25df208e9769e9.png?mw=700" alt="Screenshot 2019-12-12 at 18.30.01.png" /></a></p> <p><code>bash sudo systemctl enable mariadb sudo systemctl start mariadb</code></p> <p>これでMariaDBが起動しました.</p> <h3 id="セキュリティ"><a href="#%E3%82%BB%E3%82%AD%E3%83%A5%E3%83%AA%E3%83%86%E3%82%A3">セキュリティ</a></h3> <p>次はセキュリティの設定です.</p> <pre><code class="bash">sudo mysql_secure_installation </code></pre> <p>基本的には全てYesでいいらしいです. 途中rootパスワードの設定が必要なのでパスワードを用意しておきましょう.</p> <pre><code class="bash">mysql -u root -p </code></pre> <p>上で設定したパスワードを入力してMariaDBと表示されればオッケーのようです.</p> <h3 id="文字コードの変更と寿司ビール問題"><a href="#%E6%96%87%E5%AD%97%E3%82%B3%E3%83%BC%E3%83%89%E3%81%AE%E5%A4%89%E6%9B%B4%E3%81%A8%E5%AF%BF%E5%8F%B8%E3%83%93%E3%83%BC%E3%83%AB%E5%95%8F%E9%A1%8C">文字コードの変更と寿司ビール問題</a></h3> <p>デフォルトの文字コードはutf8とlatin1が混在しているのですが, これをutf8mb4という絵文字も扱える方式に統一するという話です. またutf8mb4にしても照合順序の関係で寿司とビールの絵文字が同値として扱われるという問題があるそうです. ただいずれも絵文字に対応する処理なので現状関係なさそうなのでほっときます.</p> <p><a target="_blank" rel="nofollow noopener" href="https://onoredekaiketsu.com/mariadb-secure-installation-and-chenge-to-utf8mb4/">MariaDB(MySQL)初期設定時のセキュリティとutf8mb4化の手順</a>を参照するなりググルなりしてください.</p> <h2 id="まとめ"><a href="#%E3%81%BE%E3%81%A8%E3%82%81">まとめ</a></h2> <p>次は管理画面とログイン機能を作っていきたいと思います.</p> <h2 id="Reference"><a href="#Reference">Reference</a></h2> <p><a target="_blank" rel="nofollow noopener" href="https://linuxize.com/post/install-mariadb-on-centos-7/">Install MariaDB on CentOS 7</a><br /> <a target="_blank" rel="nofollow noopener" href="https://www.digitalocean.com/community/tutorials/how-to-install-mariadb-on-centos-7">How To Install MariaDB on CentOS 7</a></p> ブレイン