アプリケーションを構築する際には、データの構造や、エディターでどのように表現するかを考える必要があります。そこで、型とフィールドの定義が非常に重要になります。
Contents
Types
データの種類(「データ型」)は、データ駆動型アプリケーションを構築する際に定義する最も上位の概念である。データベースでデータを持ちたいものの種類のように考えることができます。例えば、Instagramを構築するのであれば、「User」タイプと「Post」タイプを用意することになります。これらのタイプを定義することは、これらの項目をどのように記述するかを定義する前に、データベースに何が含まれるかを記述する最初のステップとなります。
Fields
フィールドとは、あるデータ型のエントリーがどのように記述されるべきかを定義する方法です。つまり、あるエントリーのデータを保存する場所です。例えば、’Post’ には ‘photo’ や ‘title’ 、’description’ などのフィールドがあります。これらのフィールドを定義することで、適切なデータを適切な場所に保存し、 アプリケーションに表示させることができます。
データ型にフィールドを作成する際には、そのフィールドの型を選択する必要があります。たとえば、Post の場合は ‘photo’ フィールドのタイプが ‘image’ で ‘title’ のタイプが ‘text’ となります。ほとんどのフィールドは、Bubble-built-in のフィールドタイプのいずれかを使用することになります。
・text: テキストを表現するために使用される(文字の連なり)。
・number: 小数点以下の数字を表すために使用されます。
・yes/no: イエスかノーの値を表すのに使う(従来のプログラミング言語ではブーリアン)。
・date: 特定の日付、すなわち日付と時刻を表すために使用される。
・geographic address:住所を表すのに使われる。
・image, file:イメージ、ファイル
・number interval:数列間隔
・date interval:日付間隔
フィールドタイプは、アプリを構築する際にデータをどのように利用するか、あるいはデータに対してどのような操作を行うかに重要な影響を及ぼします。テキスト型のフィールドは連結や切り捨てができ、数値は掛け算ができ、住所は地図上に表示できる、などです。
組み込みのフィールド型に加え、フィールドには別のデータ型を持たせることができます。これらの型は複合型と呼ばれ、データベース内の2つのエントリーを関連付ける方法です。たとえば、’Post’ には ‘User’ 型の ‘Creator’ が含まれることになります。これは、’Post’ がデータベース内の特定の ‘User’ を「指している」、あるいは「つながっている」状態だと考えることができます。
最後に、ある型に新しいフィールドを作成するとき、フィールドに入れる値が1つなのか、それとも値のリストなのかを指定しなければならないことに注意することが重要です。リストは最大10,000件まで保持でき、リスト内の項目は自動的にダンプ解除されることに注意してください。
Things(モノ)
Bubbleでいうところの「モノ」とは、データベース内のエントリーのことです。例えば、この例ではユーザーが作成した特定の「投稿」です。モノ」という言葉は、データベースのエントリーに名前を付けるために便宜上使われています。Bubbleエディタでは、多くの場所で「モノ」に言及されていますが、コンテキストに適用できるコンテンツのタイプを定義するとすぐに、「モノ」は、例えば「ポスト」のようなタイプ名に置き換えられます。
Built-in fields(内蔵フィールド)
Bubbleは設計上、各タイプにいくつかのフィールドを追加しています。これらのフィールドは、日付型の ‘Created Date’ と ‘Modified Date’ です。ユーザーでないものについては、3つ目のフィールドとして ‘Creator’ があり、これはフィールドタイプ ‘User’ です。User’でないものについては、このフィールドは、そのものが作成されたときにログインしていたユーザーにリンクされます。また、すべての thing には ‘slug’ があります。これは、thing を参照するための省略記法であり、一意な方法です。スラッグ値は、一般的にURLで使用されます。
Bubbleの各物件は、作成時に一意のIDが割り当てられます。このユニークIDは、一見ランダムな数字の長い文字列で、真ん中に「x」がある形式になっています。このフィールドを使うことは一般的ではありませんが、あるモノを一意に識別する方法が必要な場合、「ユニークID」フィールドを使うことができます。
これらのフィールドを自分で追加して管理する代わりに、Bubbleのデータエンジンに頼ってフィールドを作成し、モノの作成時に正しいデータを割り当て、必要な場所でそのデータを使用することができます。
タイプ&フィールドの追加
Bubbleでデータ型やフィールドを作成するには、主に2つの方法があります。データタブで行う方法と、インターフェースを設計したりワークフローを構築したりする際にその場で行う方法です。
なお、Bubbleでは、型やフィールドの削除は実際の削除ではありません。なぜなら、データはまだデータベースに保存されており、アプリケーションはタイプに関する何らかの情報を持っている必要があるからです。タイプやフィールドを削除すると、選択可能なタイプやフィールドのリストから非表示になります。言い換えれば、削除は元に戻すことができます。データタブの「削除されたタイプを表示」または「削除されたフィールドを表示」をクリックすると、削除された項目が表示され、各項目の横に「復元」ボタンが表示されます。
デフォルト値の設定
また、「データ」タブでは、各フィールドのデフォルト値を定義することができます。この値は、指定されたタイプのものが新しく作成されるときに使用されます。例えば、初期値を10に設定したい場合は、テキストボックスに10と入力します。なお、これはデフォルト値を設定した後に作成されたものにのみ適用され、一度デフォルト値を削除すると、そのものはデフォルト値を使用しなくなります。
ユーザータイプ
Bubbleは、アプリケーションがユーザー管理システムに依存し、ユーザーがサインアップ、ログイン、ログアウト、およびアプリケーションでのアクションを実行することを想定しています。そのため、新しい Bubble アプリケーションにはそれぞれ組み込みの ‘User’ データ型があり、いくつかの主要なプロパティを追加して作成する他の型と同様に動作します。アプリケーションでユーザーを使用しない場合は、アプリケーションに影響を与えることはありません。
User’ 型は、アプリケーションで定義する他のデータ型と非常によく似た動作をします。例えば、ユーザーを変更したり、削除したり、リピーターグループにリストアップしたり、などです。しかし、いくつかの重要な違いがあります。ユーザーは、アプリケーションでセッションや認証を扱うために使用することができます。言い換えると、’User’ 型は、現在誰がアプリケーションを使用しているかを知るために使用することができます。
User’ データ型には、アプリケーションで使用するためのいくつかの組み込みフィールドがあります。最も重要かつ一般的なのは ‘email’ フィールドで、 ユーザがサインアップした際に使用したメール、 あるいは外部サービスを使用してユーザを認証している場合に 外部サービスから取得した最初のメールを格納します。2 番目のフィールドは ‘email confirmed’ で、これはユーザーがリンクをクリックしてメールアカウントの所有権を確認したかどうかを知るためのものです (このアクションがアプリケーションの設計で使用されている場合)。このフィールドは yes/no 値を返します。
APIデータの場合
アプリ内で外部APIに接続するプラグインを使用している場合、これらのAPIがアプリケーションにいくつかのデータ型を追加する可能性が非常に高いです。例えば、Twitterに接続する場合、Twitterが返すデータ型は’Tweet’です。これらのデータ型は、先に定義したカスタムデータ型とよく似ており、物事を記述することができ、いくつかのフィールドを持つことができます。Bubble Editorの多くの場所で、上記と同様に使用することができます。例えば、繰り返しグループを使用してリストを表示する場合、コンテンツのタイプとして「ツイート」を選択することができます。ただし、このタイプのものは作れない(タイプ「Tweet」のものは作れない)し、変更もできないのが大きな違いです。
接続タイプ(Connecting types)
「データベースをどのように構成するか」はよくあることで、しかも重要なことです。- 重要な質問です。幸いなことに、Bubbleのデータベースは非常に柔軟で、多くの正しい答えがあります。また、間違った方向に進んでしまったことに後で気づいても、簡単に「修正」することができます。このセクションでは、あるデータ型と別のデータ型を接続するためのいくつかの一般的なパターンを説明します。特に、1 つの Thing が別のデータ型の多くの Things と関連する可能性がある場合です。
このコンテンツの一部は、Bubbleにおける「外部キー」や「多対多の関係」の仕組みを説明したものであると、技術者の方は認識されるかもしれません。Bubbleはこれらの用語を使用しませんし、これらの概念はBubbleデータベースには全く同じようには存在しませんが、それでも同じ最終結果を簡単に達成することができます。
使用例
アプリの「データ」タブでデータ型の新しいフィールドを定義するとき、それがテキスト、数値、YES/NO、あるいは別のデータ型であるかを指定することができます。また、そのフィールドがその型の値を1つだけ持つか、その型の値のリストを持つかを指定することもできます。
フィールドが他のデータ型の(単一の)値である場合の例:
・BlogPostデータ型には、Creatorフィールドがあり、これはUser
・Eventデータ型はVenueフィールドを持ち、これはBuildingである
・JobCandidate データ型には、Degree From フィールドがあり、これは School(学校)
・Community データ型は、State フィールドを持ち、これは State
フィールドが他のデータ型の値のリストである場合の例:
・BlogPostデータタイプは、タグのリストであるタグのフィールドを持っています。
・プロジェクトデータ型は、フォロワーのリストであるFollowerのフィールドを持つ。
・マーケットプレイスアプリのユーザーは、自分がスターを付けたプロパティのリストであるFavoritesのフィールドを持っています。
・ディスパッチアプリのコントラクターには、ジョブというフィールドがあり、過去と現在のジョブがリストアップされます。
データベースの技術的なバックグラウンドをお持ちの方のために説明すると、Bubbleでは、ある関係が「一対多」か「多対多」かを宣言する必要はありません。データ型Aにモノa、データ型Bにモノbがあり、AにB型のフィールドがある場合、Bubbleは与えられたbにいくつのaがつながっているかを気にしません。
シナリオの例
Bubbleアプリのブログの例で、PostとTagというデータ型を使って実行してみましょう。個々のPostは多くのTagを持つことができ、もちろん1つのTagは多くのPostで使用することができます。これはどのように設定するのでしょうか。
答えは「場合による」です。バブルの他の分野と同様、さまざまな方法でこれを構築する柔軟性がありますが、ここで取り上げるようなトレードオフが存在します。
ここでは、この関係を作るために使用できる主要なオプションを紹介します。
オプション1:各PostにTagフィールドがあり、Tagのリストになっている。
つまり、「ブログ記事#123」には、「料理」、「旅行」、「遊び」というタグがあり、これらはすべて「記事」のタグフィールドに格納される。
この方法の利点は、ある投稿があり、それがどのタグを持っているかを調べたいとき、それが簡単にできることです。例えば、データ型がPostに割り当てられているページがあるとします(各Postはそれぞれのページにあります)。これは簡単なクエリです。
この方法の欠点は、あるタグを持っていて、そのタグを持つ投稿を調べたい場合、クエリーがもう少し回りくどくなることです。例えば、各タグには、そのタグを持つすべての投稿をリストアップするページがあるとします。このような投稿のリストを見つけるには、「タグが現在のページのタグを含む」というフィルタをかけて、投稿を検索する必要があります。これは、より遅いクエリです(ほとんどの通常サイズのブログでは、これはおそらくパフォーマンスの観点から顕著に悪いものではありませんが、より大きなスケールの並列状況を想像することができます)。
オプション2:各タグには、そのタグを持つ投稿のリストが表示されます。
つまり、タグ「料理」には、「ブログ記事#123」、「ブログ記事#153」、「ブログ記事#89」などのフィールドが存在することになります。
この場合の長所と短所は、上記のオプション1の逆です。特定のタグのすべてのPostを取得するクエリは簡単ですが、単一のPost上のすべてのタグを見つけるには、少し長いクエリになります。
オプション1+2:上記の両方が可能です
各投稿はどのタグを持っているかを記録し、各タグはそのタグを持つ投稿を記録する。
上記のオプションの両方を実行することを妨げるものは何もありません。この方法では、ある投稿につけられたすべてのタグをすばやく取得でき、またあるタグにつけられたすべての投稿をすばやく取得することができます。
この欠点は、二重の作業をする必要があることです。投稿に新しいタグが割り当てられるたびに、そのタグを投稿のタグリストに追加し、さらにタグの投稿リストにも追加する必要があるのです。余分な作業ではありませんが、これを忘れるとデータの整合性に問題が生じる可能性があります。
オプション3:PostとTagの2つのフィールドを持つ新しいPostTagデータ型
つまり、Post + Tagのペアを処理するために新しいPostTagを作成するのです。つまり、「ブログ記事123」+「料理」用のPostTag、「ブログ記事123」+「旅行」用のPostTag、そして「ブログ記事123」+「遊び」用のPostTagというように。
(技術者の方は、これを「結合テーブル」と認識されるかもしれません)。
これは、オプション1と2の間の「妥協」ソリューションのようなものです。ある投稿のすべてのタグを見つけるには、Post = 現在のページの投稿であるすべてのPostTagsを検索するか、逆にあるタグのすべての投稿を見つける必要があります。このため、両方向の検索は、オプション1やオプション2による高速な検索よりも少し遅くなります。また、もう一つの小さな欠点は、PostTagのエントリーが重複してしまう可能性があることだ。Option 1や2でリストを使っていた場合、Bubbleはリスト内のエントリーの重複を自動的に解除してくれる。
では、なぜこの選択肢を選ぶのでしょうか?答えは、よりスケーラブルだからです。あるデータ型があるフィールドのリストを持つ場合、そのリストの最大値は10,000エントリです。しかし、例えば、一人のユーザーが生涯でどれだけのPinterestの投稿を心に刻むか想像してみてください!これは非常に大きなことです。オプション1や2はこの規模になると壊れてしまいますが、オプション3はうまく処理できます。
実際には、この種のリレーションシップを作成する際に、あるものが別のものの100を超える値のリストを持つことが予想される場合、オプション3を選択することをお勧めします。
要約すると、選択するオプションは、まず Bubble アプリに必要な規模(オプション 1 または 2 がオプションであるかどうかを決定するかもしれません)、次にクエリを超高速化したい方向(複数可)に依存します。オプション1または2から始めて、後でオプション3に移行することも可能です。)
特別な例:友人関係が複雑な場合
多くのアプリは、あるユーザーが他のユーザーと友達になれるような「相互」関係を構築したいと思うかもしれません。一般的には同じオプションが適用されますが、すべてが同じデータ型で行われるため、少し混乱します! この場合、オプション1か2を使うことができますが、アリスとボブが友達である場合、ボブがアリスの友達リストにあり、逆はない場合、混乱します。オプション1+2の方がよいでしょう。オプション3では、少し設定を変更する必要があるかもしれません。一方のユーザーともう一方のユーザーのフィールドの代わりに、ユーザーのリストである「Friendship Members」のフィールドを1つ用意します。これは、アリスとボブをいわば「同じ立場」に置き、誰が「友達1」か「友達2」かを気にする必要がありません。(ソーシャルネットワークはこのような関係を多く持つ傾向があるので、この場合はオプション3を試すことをお勧めします)。
型の不整合と問題点
前述したように、Issue Checkerは、アプリケーションの不整合を特定するのに役立ちます。アプリケーションを設計する際に修正しなければならない不整合の多くは、型の不整合でしょう。ある要素やアクションが特定の型を期待しているのに、別の型につながるデータを定義するために式を使用している場合、Issue Checker はこれを修正すべき問題としてフラグ付けします。これらの問題を修正することは、実行モードでアプリケーションに期待される動作を得るために非常に重要です。
例えば、コンテンツの種類が「車」であるグループを使うとします。これは、グループ(と中の要素)が特定の「車」を参照して、その写真、名前、価格などをRun-modeで表示することを意味します。さて、そのグループ内のデータを表示するアクション(言い換えれば、グループ内にどのようなものを表示するかを定義するアクション)があるとします。このアクションは、タイプ’Car’のモノを表示する必要があります。Run-modeで、グループに表示しようとするものが「User」と評価されるようにアクションを設計すると、型の不一致が発生します。イシューチェッカーは、これをエディターでキャッチします。
このような型の不整合は、フィールドの型でも起こり得ます。例えば、’Charge the current user’ アクションを使用してユーザーのクレジットカードに課金する場合、このアクションのフィールドの一つは ‘amount’ になります。このフィールドは当然ながら数値であるべきです。この金額を定義するために動的式を使用し、それが例えばテキストやアドレスと評価された場合、課題チェッカーはこれを解決すべき課題としてフラグ付けします。動的な式の上にカーソルを置くと、それが何として評価されるかを確認できます。
参考英語サイト
https://manual.bubble.io/help-guides/structuring-an-application/data-structure