
アイテムの親子関係を管理しよう #Notionコラム
#Notionコラム は、Notionの応用的な使い方を検討・提案するマガジンです。
今回は、以下のようなアイテムに親子関係があるデータベースの設計例を提案していきます。

#Notion #アイテム #データベース #プロパティ #タイトルプロパティ #アイコン #StackedDiscs #Document #自己参照 #リレーションプロパティ #BabyMobile #リレーション #セクション #ロールアッププロパティ #StackedSquares #関数プロパティ #データベースページ #ビュー #if関数 #empty関数 #add演算子 #セレクトプロパティ #数値プロパティ #length関数 #フィルター #テーブルビュー #MagnifyingGlass #検索ビュー #並び替え #グループ #エラー検知ビュー #ExclamationTriangle #ツリービュー #サブアイテム
プロパティ
はじめに、プロパティを紹介していきます。
タイトルプロパティ
まずは、データベース名に合わせて「データベースA」と名づけられた、タイトルプロパティがあります。

アイコンもデータベースと合わせて、「stacked discs」を使用しています。
実用の際にはプロパティ名もアイコンも異なるものを使用すると思いますが、タイトルプロパティの設定はそのデータベースの設定に合わせるのがオススメです。
アイテムのアイコンには「document」を使用していますが、こちらもどんなデータベースかによって変えると良いでしょう。
色に関しては、今回はツリーの深さでパープル・レッド・イエロー……と色分けしていますが、「アイテム1-*」や「アイテム2-*」ごとに変える等、ツリーの幅で色分けしてもいいと思います。
リレーションプロパティ
それから、親子関係を表す自己参照のリレーションプロパティも1ペアあります。

アイコンはどちらも「baby mobile」を使用しています。
ツリー構造(親子関係)を表す際に転用できるアイコンです。
親子関係の親側を表すリレーションプロパティは「親」と名づけます。

一般的なツリー構造において、それぞれのノードの親は1つなので、リレーションできる数を1ページに制限します。
親子関係の子側を表すリレーションプロパティは「子」と名づけます。

子アイテムは複数リレーションされる可能性があるため、制限は設けず、代わりにセクションとして表示します。
ロールアッププロパティ
そして、親の階層を表す「階層 親」という名前のロールアッププロパティもあります。

アイコンは「stacked squares」を使用しています。
今回は、リレーションプロパティ「親」でリレーションされたアイテムが持つ、関数プロパティ「階層」の「平均」を計算しています。
リレーションプロパティ「親」のリレーション数を1ページに制限しているため、この例では「平均」ではなくても構いませんが、制限しない場合は「平均」にしておくことが無難だと思うので、それに合わせています。
なお、「階層 親」は計算に使うためのプロパティなので、データベースページでも、各種ビューでも、基本的に非表示にしています。
関数プロパティ
最後に、親子関係の階層の深さを表す、「階層」という関数プロパティもあります。

if(empty(prop("親")), 1, prop("階層 親") + 1)
こちらも、アイコンは「stacked squares」を使用しています。
if関数とempty関数を使って、リレーションプロパティ「親」に何もリレーションされていない場合は、1としています。
それから、ロールアッププロパティ「階層 親」の値に対して、add演算子で1を加算しています。
「階層 親」で「階層」を参照し、「階層」の数式で「階層 親」を参照しているため、プログラミングで言う「再帰関数」のように循環参照しています。
別の方法
ロールアッププロパティと関数プロパティで循環参照する方法以外にも、階層の深さの管理は、セレクトプロパティで手入力する方法でも可能です。
なお、数値プロパティでも構いませんが、階層の深さは多くても10択程度でしょうから、入力を自動化しない限りは、ヒューマンエラーの起こりづらいセレクトプロパティを使う方がオススメです。
あるいは、今回の例のように、タイトルプロパティの値を規則的に名付ける場合は、length関数などを活用した関数プロパティでも代用できます。

(length(prop("データベースA")) - 3) / 2
ビュー
ここからは、ビューを紹介していきます。
検索ビュー
まず、テーブルビュー「検索」を用意してあります。

アイコンは「magnifying glass」を使用しています。
どのデータベースにおいても、フィルターの使わない検索ビューを用意しておくと便利です。
「階層」昇順、「親」昇順、「データベースA」昇順の順に並び替えを設定してあります。

※ 「子」昇順は誤りで、「データベースA」昇順が正しいです
アイテムが増えてきたら、「階層」でグループを設定してもいいと思います。

(グループ化単位を1にした時にも「1~2」みたいに表示される不具合(?)、早く直るといいですね……。)
エラー検知ビュー
それから、テーブルビュー「エラー」も用意してあります。

アイコンは「exclamation triangle」を使用しています。
タイトルプロパティ「データベースA」や関数プロパティ「階層」は未入力を許容したくないので、それらをフィルターで検知しています。
また、リレーションプロパティ「親」とリレーションプロパティ「子」が双方とも未入力であることも許容したくないため、これも確認しています。
フィルター以外は、検索ビューと同様です。
エラー検知ビューも、どのデータベースにも用意しておくと便利です。
ツリービュー
最後に、本命であるリストビュー「ツリー」を紹介していきます。

アイコンはリレーションプロパティと同様に「baby mobile」を使用しています。
リストビューでは、自己参照のリレーションプロパティをサブアイテムに設定することで、以下のような階層的な表示に変更することができます。

今回は、リレーションプロパティ「子」をサブアイテムに設定しています。
サブアイテムはテーブルビューでも使用可能ですが、主に罫線のせいで表示がごちゃごちゃする点が嫌いなため、私はリストビューでしか使いません。

(テーブルビューの縦線は非表示にできますが、横線は多分非表示にできません……なぜ…………。一応CSSをいじってborder-topやborder-bottomをnoneにすれば消せなくもないですが、タイパ悪いと思います……。)

ツリービューでは、アイテムが増えてきたら、フィルターで「階層」が2以下のもののみ表示する等の工夫をするとスッキリします。
