皆さん、こんにちは!今回は、DB事例集の第3回として「学習サポートアプリ」を例に、DB設計についてのポイントをご紹介したいと思います。
Bubble でのデータベースについて学習中の方は、是非参考にしてみてくださいね。
学習サポートアプリ 概要
「学習サポートアプリ」は、昨年の11月末にノーコード ラボで作成したアプリです。ノーコード ラボでは、元号ジェネレータ clone や Twitter clone といった Bubble 入門者向けのコンテンツをいくつか公開していますが、この「学習サポートアプリ」では、第2回のDB事例集でも紹介した「4択クイズ」の機能などを含んで作成しています。しかし「学習サポートアプリ」内の「4択クイズ」では、データベースの構成が先の「4択クイズ」とは実は全く異なっています。
アプリのリリース時の記事は以下になります。詳しい機能などは、以下の記事もご参考いただければと思いますが、今回はデータベースの事例集としてご紹介させていただきますので、データベースの構成を考える上で必要な内容を改めて掲載させていただきます。
アプリ仕様
- 「学習サポートアプリ」は自分専用のオリジナル辞書のようなものを作成し、作成した辞書を基に学習用の問題を作成することができます。
- 英単語用や歴史年号用など、オリジナル辞書は複数作成することが可能です。
- 学習メニュー(種別)は「4択クイズ」「2択クイズ(制限時間のタイマー付き)」「フラッシュカード」の3種類があります。
アプリURL
「学習サポートアプリ」は、以下URLから利用できます。
https://learning-app.bubbleapps.io/
画面イメージ
アプリの画面は以下のような画面となっています。
データベースの構成について
ダイアグラム
設計で考慮したポイント
本アプリでは、まずは辞書作成して、その辞書を利用して問題を作成するという前提でデータベースも設計しています。
この事が、前項の概要でも触れた、ノーコードラボで入門者向けのコンテンツとしている「4択クイズ」とは考え方が大きく異なる点です。入門者向け「4択クイズ」の際は、「4択クイズ」という機能ありきでデータベースを作成しています。その為、問題管理するテーブルには、「質問、正解の答え、選択肢」にあたるフィールドが存在します。しかし、本アプリでは「4択クイズ」以外にも「2択クイズ」や「フラッシュカード」といった機能も追加していますので、先に述べた通り、辞書のデータを基に問題を作成することを前提として設計しました。
こうすることで「4択クイズ」用、「フラッシュカード」用といった具合に、学習メニュー毎に問題を作成する必要がなくなり、今後、新しく学習メニューを増やす場合でも、「問題をどのように表示させるか」ということだけを考えれば、新しい学習メニューを簡単に追加することができます。
また、ユーザーにとっても「間違って問題を削除してしまった!」という場合でも、辞書機能を利用したほうが問題の再作成も簡単なのではと考えました。
テーブル(Type)概要説明
本アプリの主要テーブルは以下7つです。
Type name | 詳細 |
---|---|
User | ユーザー情報を保持するテーブル |
Theme | アプリ画面のテーマカラーを保持するテーブル |
AppMaster | アプリの学習メニュー(種別)マスター※ |
Category | 辞書のカテゴリー(種類)情報を保持するテーブル。例:英単語辞書、歴史年号辞書 |
Library | いずれかの Category に所属し、辞書の中身を保持するテーブル |
AppListData | どの学習メニュー(種別)の問題集であるかを保持するテーブル |
Question | 問題集の中身を保持するテーブル |
※ アプリの学習メニュー(種別)情報を保持する AppMaster テーブルは、固定値を保存している為、現在の Bubble のバージョンでは テーブルで持つより、Option sets で管理する方が適しているかもしれません。
Option sets の登録方法は以下の記事で触れていますので、ご参考ください。
各テーブル(Type)の設計ポイント
以下に各テーブルの主要なフィールド列挙し、設計時のポイントをまとめています。
User Type
- AppName
- StartDialog
- Theme
- Timer_FlashCard
- Timer_Quiz_1
- Timer_Quiz_2 etc
User Type では、ユーザー毎に管理したい項目を保持します。本アプリではアプリの名前や、テーマカラー、タイマーの秒数といったものを管理しています。Theme field は 型を Theme とすることで Theme Type と紐づけています。
Theme Type
- AccentColor
- Default
- SubColor
- ThemeColor
- Title etc
Theme Type は、ユーザー毎にアプリのテーマカラーを設定できるように User Type で紐づけされています。ボタンの色やテキストの色などが、このテーブルから取得されます。具体的には「Current User's Theme's AccentColor」といった具合ですね。Default の型は真偽値で、ユーザーが新規作成された場合のテーマを Default field で判定することができます。
AppMaster Type
- AppId(学習メニューID)
- AppName_ja(学習メニュー日本語名称)etc
AppMaster Type は「4択クイズ」「2択クイズ」「フラッシュカード」というアプリの種別情報を保持しています。種別ごとに ID があるのは、パラメータでページ間の受け渡しに使用したかったのと unique id よりも視認性があるためです。なお、前項でも記載しましたが、本テーブルは固定値のため、現在の Bubble のバージョンでは Option sets で保持した方が分かりやすいと思います。
Category Type
- 1
- 2
- 3
- 4
- 5
- Explanation
- ID
- Name
- User etc
Category Type は「どのような辞書であるか」という情報を保持させます。1~5 field は辞書ごとに要素名が指定できるようにするためのフィールドです。例えば、英単語の辞書を作成したい場合は、「単語、意味、読み方、品詞、例文」などが要素となり、歴史年号の辞書では、「年、語呂合わせ、出来事、時代、人物」などが要素となります。要素自体を持つことで、複数の辞書が作成できるように設計しました。また、User型の User field を持つことで、今後データ作成したユーザーを更新することも可能です。User 情報を保持するフィールドは Built-in field の Creator にもありますが、Built-in field の Creator は更新することができませんので、ユーザーをどのように扱うかでどちらを使用するか検討すると良いですね。
なお、今回は Category の要素を単純に1~5の固定フィールドで作成していますが、これがそのまま次項の Library で管理する辞書の中身の意味になります。拡張を考える時など場合によっては、List of text (リスト形式のテキスト)型にしてしまうという手もあります。
Library Type
- 1
- 2
- 3
- 4
- 5
- Category etc
Library Type は、実際の辞書の中身なので、必ずいずれかの Category Type に属する必要があります。Category field の方を Category とすることで紐づけています。なお、ユーザーが辞書登録を行う際は、画面設計においても 1~5 field は Category Type で定義した要素と一致させるように設計します。
以下は Category Type と Library Type のサンプルデータです。Library Type の Category field で Category Type と紐づけ、Library Type の1~5 field の要素の意味と一致させています。
ここで Category と Library について、もう一つの考え方に触れておきたいと思います。今回は、Library Type からデータを取得すると同時に Category を条件に絞り込みをしたデータと marge したかったため、Library Type の中に Category field を持っていますが、もし Library Type のデータが膨大で、かつ Category に含まれる Library の件数などを取得する必要があるならば、Category Type にも Library field を作成し List 形式で持っておくと良いかもしれません。
AppListData Type
- AppId
- Category
- Title
- ID
- User
AppListData Type では、どの学習メニュー(種別)の問題で、どの辞書を使用しているかという情報を保持しています。また、ID field を持つことで、種別ごとに複数の問題集を作成することができます。例えば、英単語辞書を作成して、4択クイズでは「初級」「中級」「上級」といったレベル別の問題集を作成することができるように設計しました。
Question Type
- AppListData
- Library
- MistakeFlag etc
Question Type は問題集の中身を保持するテーブルなので、必ずいずれかの AppListData Type に属しており、問題とする Library Type と紐づけられています。例えば、4択クイズの場合を考えると、Library field のデータを正解と考え、残り3つの選択肢は、同じ Category に属する他の Library のデータを任意に取得し表示させるといった具合です。また、MistakeFlag field を持つことで、問題の正誤履歴をユーザーに表示することができるようになります。
もう一つの案について
では、ここでデータベース構成のもう一つの案について、ご紹介したいと思います。
こちらの案は画面の項目とデータの持ち方を一致させて、メンテナンス性を重視したデータベース構造の案です。
現在の構成では、Question Type に「4択クイズ」や「2択クイズ」といったすべての種別の問題を管理していますが、この場合だと、例えば「4択クイズ」の場合は前項で述べた通り
Library field のデータを正解と考え、残り3つの選択肢は、同じ Category に属する他の Library のデータを任意に取得し表示させる
という設定を RepeatingGroup の Data source にする必要があります。その結果、検索した2種類のデータをマージさせてランダムに並び替えるなど、設定が複雑になってしまうという課題もあるのです。
データベースを設計する上で、テーブルをより少なく、データもシンプルにすることを検討するのはもちろん大切なことですが、やり過ぎには注意です。テーブルが多少増えても素直に画面の項目と一致させている方が、データの取得方法がシンプルになる分、後々のメンテナンスを考える上ではラクかもしれません。
例えば、今回のアプリでいうと、Question Type にあたる 問題データは「4択クイズ用」と「2択クイズ用」などテーブルを種別毎に作成しまうのもアリだと思います。
データベース設計では、画面の項目とデータの持ち方を一致させるということも検討に加えてはいかがでしょうか?
まとめ
Bubble でのデータベースの魅力は、なんといってもリレーションの手軽さです。フィールドの型に、テーブルである Type 自身を定義することができるため、「どのユーザーのデータか」や「どのデータに属しているか」などどいった情報が非常に手軽に参照できます。 また、フィールドの型を定義する際に、合わせてそのデータが List であるかという情報も定義できるので、件数を取得したいといった場合も手軽であると思います。
Bubble で実際にデータベースを作成する手順については、入門者向けコンテンツである「4択クイズ」の記事にも記載していますので、ご参考くださいね。では、次回もどうぞお楽しみに!