データモデリング - David Nuescheler のモデル data-modeling-david-nuescheler-s-model

ソース source

以下は、David Nuescheler 氏が発表したアイデアとコメントである。

David は、2010 年にAdobeが買収した、グローバルなコンテンツ管理およびコンテンツインフラストラクチャソフトウェアの大手プロバイダ、Day Software AG の共同創設者および CTO でした。 David は現在、Adobeのエンタープライズテクノロジー部門の同僚であり、JSR-170 の開発をリードしています。JSR-170 は、コンテンツ管理の技術標準である Java™ Content Repository(JCR) アプリケーションプログラミングインターフェイス (API) を提供します。

その他の更新については、 https://cwiki.apache.org/confluence/display/jackrabbit/DavidsModel.

David の紹介 introduction-from-david

様々な議論の中で、開発者はコンテンツモデリング時に JCR が提示する機能や特徴にやや不安を感じていることがわかりました。 リポジトリ内のコンテンツをモデル化する方法と、あるコンテンツモデルが他のコンテンツモデルよりも優れている理由に関するガイドはまだありません。また、経験もほとんどありません。

リレーショナルな世界では、ソフトウェア業界はデータのモデル化に関する経験を持っていますが、コンテンツリポジトリ領域の初期段階に入っています。

コンテンツをモデル化する方法について、私の意見を述べ、この空白を埋めたいと思います。 私の願いは、これがいつか、開発者のコミュニティにとってより意味のある何かを学び、「私の意見」だけでなく、より一般的に適用できる何かを学ぶことができることです。 私の早く進化する最初の突き刺しを考えてみてください

NOTE
免責事項:これらのガイドラインは、私の個人的な見解や、賛否が分かれる場合もあります。 私は、これらのガイドラインを議論し、それらを磨くことを楽しみにしています。

簡単な 7 つのルール seven-simple-rules

ルール 1:データが第一、構造は二の次(おそらくですが)。 rule-data-first-structure-later-maybe

説明 explanation-1

ERD の意味で宣言されたデータ構造について心配しないことをお勧めします。 最初は

開発時に nt:unstructured (& friends) を愛する方法を学びます。

私の結論は、構造は高価で、多くの場合、基盤となるストレージに対して構造を明示的に宣言する必要はありません。

アプリケーションが本質的に使用する構造に関する暗黙の契約があります。 例えば、ブログ投稿の変更日を lastModified プロパティに保存するとします。 アプリは、同じプロパティから変更日を再度読み取ることを自動的に認識しています。明示的にそれを宣言する必要はありません。

必須やタイプ、値の制約などのその他のデータ制約は、データの整合性のために必要な場合にのみ適用する必要があります。

example-1

上記の lastModified 例えば「blog post」ノードの日付プロパティは、特別なノードタイプが必要であるとは意味しません。 私は、少なくとも最初は必ず nt:unstructured をブログ投稿ノード用に使います。私のブログアプリケーションでは、私が行うことは、とにかく lastModified 日を表示することだけです(おそらく"order by")私は、それが Date であるかどうかをほとんど気にしません。 私のブログの書き込みアプリケーションを暗黙的に信頼して「日付」を付けるので、実際には、 lastModified ノードタイプの形式の日付。

ルール#2:コンテンツ階層を駆動します。実行しないでください。 rule-drive-the-content-hierarchy-don-t-let-it-happen

説明 explanation-2

コンテンツ階層は貴重なアセットです。 実現させないで、設計してください。 人間が読み取れる「良い」ノード名を持っていない場合、それはおそらく考え直すべきものです。 任意の数字は、「良い名前」とはほとんど言えません。

既存のリレーショナルモデルを階層モデルにすばやく配置するのは簡単ですが、そのプロセスでは何らかの考えを持つ必要があります。

私の経験では、アクセス制御とコンテインメントをコンテンツ階層の優れたドライバーと考える場合。 ファイルシステムのように考えてみてください。 ローカルディスク上のモデルを作成する際に、ファイルやフォルダを使用する場合もあります。

個人的には、最初はノードタイピングシステムより階層規則を好み、後でタイピングを導入します。

CAUTION
コンテンツリポジトリの構造化の方法はパフォーマンスにも影響を及ぼす可能性があります。最高のパフォーマンスを得るには、コンテンツリポジトリ内の個々のノードにアタッチされている子ノードの数を 1,000 個以下にする必要があります。
詳しくは、 CRX で処理できるデータの量

example-2

単純なブログシステムを次のようにモデル化しました 最初は、この時点で使用する各ノードタイプについても気にしません。

/content/myblog
/content/myblog/posts
/content/myblog/posts/what_i_learned_today
/content/myblog/posts/iphone_shipping

/content/myblog/comments/iphone_shipping/i_like_it_too
/content/myblog/comments/iphone_shipping/i_like_it_too/i_hate_it

その内容の構造は、これ以上の説明なしに、例に基づいて理解されていることが、明らかになると思います。

最初は予期しないことがありますが、なぜ「コメント」を「投稿」と共に保存しないのですか。これは、アクセス制御を合理的に階層的に適用したいからです。

上記のコンテンツモデルを使用すると、「匿名」ユーザーに対して「コメントの作成」を簡単に許可できますが、残りのワークスペースでは読み取り専用の状態に保ちます。

ルール#3:ワークスペースは、clone()、merge() および update() 用です。 rule-workspaces-are-for-clone-merge-and-update

説明 explanation-3

を使用しない場合、 clone(), merge() または update() アプリケーション内のメソッドの場合、単一のワークスペースを使用する方法が考えられます。

「対応するノード」は、JCR 仕様で定義された概念です。 つまり、異なるいわゆるワークスペースで、同じコンテンツを表すノードに結び付きます。

JCR では、多くの開発者がワークスペースをどう扱うかわからないように、ワークスペースの抽象概念を導入しています。 今後、以下のようなテストを行うためのワークスペースの活用を提案します。

複数のワークスペースで「対応する」ノード(基本的には同じ UUID を持つノード)の重複が大きい場合は、ワークスペースを適切に使用できるように配置する必要があります。

同じ UUID を持つノードの重複がない場合は、ワークスペースを使用しない可能性があります。

アクセス制御にワークスペースを使用しないでください。 特定のユーザーグループのコンテンツを表示することは、物を異なるワークスペースに分ける良い議論ではありません。 JCR は、コンテンツリポジトリで「アクセス制御」を使用してこれを提供します。

ワークスペースは、参照とクエリの境界です。

example-3

ワークスペースは次のような用途に使用します。

  • プロジェクトの v1.2 とプロジェクトの v1.3
  • コンテンツの「開発」、「QA」および「公開済み」状態

以下のような用途にワークスペースを使用しないでください。

  • ユーザーのホームディレクトリ
  • 公開、非公開、ローカルなど、様々なターゲットオーディエンス向けの個別コンテンツ。
  • 様々なユーザー向けのメール受信ボックス

ルール#4:同じ名前の兄弟には注意が必要です。 rule-beware-of-same-name-siblings

説明 explanation-4

Same Name Siblings(SNS) が仕様に導入され、XML で設計および表現されるデータ構造との互換性が確保されました。したがって、JCR にとって有用です。 ただし、SNS にはリポジトリのオーバーヘッドと複雑さが伴います。

いずれかのパスセグメントに SNS が含まれているコンテンツリポジトリへのパスの安定性が大幅に低下します。 SNS が削除または並べ替えられると、他のすべての SNS とその子のパスに影響を与えます。

XML のインポートや既存の XML とのインタラクションに関しては、SNS が必要で役に立つかもしれませんが、私の「緑のフィールド」データモデルでは SNS を使用したことがありません(そして、そうするつもりもありません)。

example-4

使用方法

/content/myblog/posts/what_i_learned_today
/content/myblog/posts/iphone_shipping

の代わりに

/content/blog[1]/post[1]
/content/blog[1]/post[2]

規則#5:参照は有害と見なされます。 rule-references-considered-harmful

説明 explanation-5

参照は参照整合性を意味します。 参照を使用すると、参照整合性を管理するリポジトリに追加のコストがかかるだけでなく、コンテンツの柔軟性の観点からもコストがかかることを理解することが重要です。

個人的には、未設定の参照を扱えない場合にのみ参照を使用し、それ以外の場合はパス、名前、または文字列 UUID を使用して別のノードを参照します。

example-5

ドキュメント (a) から別のドキュメント (b) への「参照」を許可するとします。 参照プロパティを使用してこの関係をモデル化する場合、2 つのドキュメントはリポジトリレベルでリンクされます。 参照プロパティのターゲットが存在しない可能性があるので、ドキュメント (a) を個別に書き出し/読み込むことはできません。 結合、更新、リストア、クローンなどのその他の操作も影響を受けます。

そのため、これらの参照を「弱い参照」(JCR v1.0 では、基本的にはターゲットノードの uuid を含む文字列プロパティにボールダウンします)としてモデル化するか、単にパスを使用します。 最初にパスが意味を持つ場合もあります。

参照がダングリングしている場合、システムが実際には機能しないと思うのですが、直接的な経験から、良い「実際の」しかし単純な例を思い付くことはできません。

ルール 6:ファイルはファイルである。 rule-files-are-files

説明 explanation-6

リモートでもファイルやフォルダーのような匂いがするコンテンツモデルが公開される場合は、を使用(または拡張)しようとします nt:file, nt:folder、および nt:resource.

私の経験では、多くの汎用アプリケーションは nt:folder および nt:files とのやり取りを暗黙的に許可しており、追加のメタ情報でエンリッチメントされた場合に、これらのイベントを処理して表示する方法を知っています。 例えば、CIFや WebDAV など、JCR の上に配置されるファイルサーバー実装との直接のやり取りは、暗黙的になります。

私は経験則として、次のように使えると思います:ファイル名と MIME タイプを保存しなければならない場合、 nt:file/ nt:resource 良いマッチです。 複数の「ファイル」がある場合は、nt:folder は格納場所に適しています。

リソースのメタ情報を追加する必要がある場合(例えば、「author」や「description」プロパティなど)、 nt:resource not nt:file. nt:file を拡張することはほとんどなく、nt:resource を頻繁に拡張します。

example-6

次の場所にあるブログエントリに画像をアップロードするとします。

/content/myblog/posts/iphone_shipping

そして、最初の腸反応は、画像を含むバイナリプロパティを追加することでしょう。

バイナリプロパティのみを使用する良い使用例もありますが(例えば、名前は無関係で、mime タイプは暗黙的なものです)、この場合は、自分のブログの例で次の構造をお勧めします。

/content/myblog/posts/iphone_shipping/attachments [nt:folder]
/content/myblog/posts/iphone_shipping/attachments/front.jpg [nt:file]
/content/myblog/posts/iphone_shipping/attachments/front.jpg/jcr:content [nt:resource]

ルール#7:ID が悪い。 rule-ids-are-evil

説明 explanation-7

リレーショナルデータベースでは、ID は関係を表すのに必要な手段なので、コンテンツモデルでも ID を使用する傾向があります。 主に誤った理由から。

コンテンツモデルが「ID」で終わるプロパティでいっぱいの場合は、階層が正しく使用されていない可能性があります。

実際、一部のノードは、ライブサイクル全体で安定した識別を必要としますが、思ったよりも少なくなります。 しかし、 mix:referenceable にはリポジトリに組み込まれているこのようなメカニズムがあるので、ノードを安定した方法で識別する追加の手段を考え出す必要はありません。

項目はパスで識別できることにも注意してください。 また、UNIX®ファイルシステムのハードリンクよりも「symlinks」の方が多くのユーザーにとって意味を持ちますが、パスは、ほとんどのアプリケーションがターゲットノードを参照する意味を持ちます。

さらに重要な点は、 混ぜる:referenceable(参照可能)とは、実際に参照する必要がある時点でノードに適用できることを意味します。

したがって、「Document」タイプのノードを参照できるようにしたい場合とは異なり、「Document」ノードタイプを次の場所から拡張する必要があるわけではありません。 mix:referenceable 静的な方法で これは、「ドキュメント」の任意のインスタンスに動的に追加できるためです。

example-7

使用方法:

/content/myblog/posts/iphone_shipping/attachments/front.jpg

次の代わりに使用します。

[Blog]
-- blogId
-- author
[Post]
-- postId
-- blogId
-- title
-- text
-- date
[Attachment]
-- attachmentId
-- postId
-- filename
+ resource (nt:resource)
recommendation-more-help
19ffd973-7af2-44d0-84b5-d547b0dffee2