2

私の今後のプロジェクトでは、(私が呼んでいるもの)「抽象エンティティ参照」を含む設計を検討しています。これは、より一般的なデータ モデルの設計とは大きく異なりますが、必要な柔軟性を実現するために必要な場合があります。他のアーキテクトがこのようなシステムの経験を持っているかどうか、また注意点はどこにあるのか疑問に思っています。

このプロジェクトには、さまざまな人物によるさまざまなエンティティ (論理的にはビジネス オブジェクト、物理的にはデータベース行) へのアクセスを制御するという要件があります。たとえば、次のようなルールを作成したい場合があります。

  • ユーザー Alice は Z 社のメンバーです
  • ユーザー Bob は、ユーザー Charlie、Dave、および Eve を持つグループ Y のマネージャーです。
  • ユーザー Frank は、[重要なビジネス オブジェクト] X のデータと、[重要なビジネス オブジェクト グループ] U の [重要なビジネス オブジェクト] のデータを入力できます。
  • ユーザー George は T 社のメンバーではありませんが、T 社のレポートを表示できます。

さまざまなセキュリティ保護可能なオブジェクト、ロール、グループ、およびアクセス許可があり、システムでこれを処理する必要があるという考えです。理想的には、このシステムは、起動後に新しい状況に対応するためのコーディングをほとんど、またはまったく必要としません。それは非常に柔軟でなければなりません。

「従来の」データ設計では、次のようなエンティティ/テーブルがある場合があります。

  • ユーザー
  • 会社
  • ユーザー/会社相互参照
  • ユーザー・グループ
  • ユーザー/ユーザーグループの相互参照
  • CBO (「重要なビジネスオブジェクト」)
  • ユーザー/CBO 相互参照
  • CBOグループ
  • ユーザー/CBOGroup 相互参照
  • CBO/CBOGroup 相互参照
  • レポートへのアクセス専用のユーザーと会社間の相互参照であるReportAccess

相互参照テーブルの数が多いことに注意してください。このシステムは非常に柔軟ではありません。新しいアクセス手段を追加したいときはいつでも、新しい相互参照テーブルを導入する必要があるからです。つまり、追加のコーディングを意味します。

提案されたシステムでは、すべての主要なエンティティ (ユーザー、会社、CBO) がエンティティと呼ばれる新しいテーブルの値を参照します。(コードでは、これらすべてのエンティティーを Entity スーパークラスのサブクラスにする可能性があります)。次に、エンティティの「サブクラス」でもある Entity * Group を参照する 2 つの追加テーブルがあります。* EntityRelation は、任意のタイプ (グループを含む) の 2 つのエンティティ間の関係です。これにはおそらく、関係を説明/修飾するためのある種の「関係タイプ」フィールドもあります。

このシステムは、少なくとも一見しただけでは、私たちの多くの要件を満たしているように見えます。今後、新しいエンティティを導入する可能性がありますが、これらのエンティティ間のグループ化と関係を処理するために追加のテーブルを作成する必要はありません。これは、Group と EntityRelation が既に処理できるためです。

しかし、これが実際にはうまく機能しないのではないかと心配しています。エンティティ間の関係は非常に複雑になり、人々 (ユーザーと開発者の両方) がそれらを理解するのが非常に難しくなる可能性があります。また、それらは非常に再帰的です。これにより、SQL に依存するレポート作成スタッフにとって事態はさらに困難になります。

似たようなシステムを経験した人はいますか?

4

4 に答える 4

3

これには奇妙な経験があります。これは次のとおりです。

アーキテクト/プログラマーは、非常にきれいに見え、非常にツリー的で再帰的である、非常に対称的な汎用モデルを設計します。

ユーザー インターフェイスの設計に関して、顧客またはユーザーは、実際の使用ははるかに簡単であり、これら 2 つの単純な画面で満足できると主張します (ユーザー/顧客は、聞きながら黒板にこれらを描画します)。

この段階では、根本的なモデルが誰も本当に望んでいない、または必要としない非常に一般的なユースケースをサポートしている場合、ソリューションが非常に肥大化する傾向があることに一貫して気付きます。そのため、私の基本的なアドバイスは、常にお客様の話を注意深く聞き、実際の要件が何であるかに非常に忠実であることです。きちんとした構造に対する個人的な欲求がここでの原動力ではないことを確認してください。

はい、私はこれを何度も経験してきました。最近の経験では、すべての開発者は、階層ツリー構造について話していることを完全に確信していました。しかし、顧客はこれをすべての点でフラットなリストのような構造にすることを決定的に望んでいました。陥る前に、完全に一周する必要がありました (最初にツリーを実装し、次にリストを実装する)。

あなたが提案する一般的なモデルについては完全にはわかりませんが、過度に一般的なモデルについて話すのをやめさせるすべての匂いがあります. 少なくとも、選択する前に両方の選択肢を完全に詳細にモデル化することを常に確実にします.

于 2009-01-08T19:07:11.700 に答える
3

それ自体が複雑な実世界の一連のビジネス ルールをモデル化しています。したがって、どのように作成してもモデルが複雑になることは驚くべきことではありません。

賢くしようとするのではなく、関係をより正確に記述するデータベース設計を選択することをお勧めします。巧妙な設計により、テーブルが少なくなる可能性がありますが (実際には桁違いではありません)、それを管理するためのアプリケーション コードが多くなるというトレードオフがあります。

たとえば、ユーザーやレポート デザイナーが混乱することは既にわかっています。もう 1 つの弱点は、「関係の種類」列に、関係に関係するエンティティの意味のある文字列のみが含まれるようにすることです。たとえば、 と言うのは理にかなっていますBob IsMemberOf UserGroup4が、 の場合はどういう意味CBO CanViewReportsOf Bobですか? また、 と などの相互に排他的な条件をどのように防止しますBob IsMemberOf Company1Bob IsMemberOf Company2?

データを挿入する前とフェッチした後にデータを検証するアプリケーション コードを作成する必要があります (コードの別の部分がデータ整合性のバグを導入していないことをコードが確認できないため)。また、データベース全体で品質管理チェックを実行し、異常が発生したときにクリーンアップするためのアプリケーション コードを作成する必要がある場合もあります。

無効なリレーションシップを入力できないデータベース設計と比較してください。これは、データベース メタデータにそれを防止する制約が含まれているためです。これにより、アプリケーション コードが大幅に簡素化されます。

のように、階層的なアクセス権限も識別します。その場合Bob CanViewReportsOf Company1、その会社のメンバーであるユーザー グループまたは CBO のレポートを表示できる必要がありますか? または、Bob が読み取ることができるすべてのエンティティのレポートに対して個別の行を入力する必要がありますか? これらはポリシーの問題であり、使用する設計に関係なく存在します。


コメントに返信するには:

ビザンチンな例外ケースや、単純なソリューションの設計を難しくしている進化する要件に、私は確かに共感できます。

私は、非常に複雑になった現実世界のポリシーをモデル化しようとするシステムに取り組んだため、ソフトウェアで成文化しようとするのはばかげているように思えました。最終的に、私を雇ったクライアントは、紙と鉛筆を使ってプロジェクトを追跡するフルタイムの管理アシスタントを 1 人か 2 人雇った方が、お金をより効果的に使っていたでしょう。ソフトウェアに実装するのに数週間かかった新しい例外ケースは、AA に説明するのに数分かかったでしょう。

自動化は、手動で行うよりも困難です。自動化が正当化される唯一の方法は、人間が行うよりも速く、または大量に情報を追跡する必要がある場合です。

于 2009-01-08T19:13:22.687 に答える
2

あなたのエンティティ/リレーションの提案は非常に「メタ」であるため、すべてのクレイジーな順列を処理するのに十分な柔軟性があります-ロジックを実装するクラスへのパスを含む単一の列を持つ単一のテーブルから一歩離れています。それが行われました-しかし、あなたが指摘するように、それを直接管理すると、狂った混乱が生じるでしょう. すべての抽象化を非表示にするには、ビジネス オブジェクト レイヤー (re: 単一テーブルの継承?) から素敵なかなりのラッパーを配置する必要があります。しかし、そのすべての問題を解決する前に、すでに確立されている他のシステムをチェックしてください。ほとんどの場合、このうさぎの穴に落ちてしまい、最終的にUnix ファイル システムのアクセス許可を実装することになります。

于 2009-01-08T23:15:12.463 に答える
2

以前の仕事では、同様の道をたどり、データ エンティティに対してアクティブ ディレクトリ タイプのアクセス許可を効果的に実装することになりました。

アクセス許可が必要な各テーブルには、SecurityObject テーブルへの外部キーがあります。UserPermission テーブルと GroupPermission テーブルの行は、さまざまなユーザーがその SecurityObject 行に対して持っていた権限の種類を示していました。SecurityObject テーブルのデータは階層化されていました。デフォルトでは、各行は親から権限を継承していました。

対応するデータ エンティティ クラスは共通のインターフェイスを実装しているため、セキュリティ API は、それが何であるかを正確に知らなくても、「保護可能な」データを操作できます。

グループおよびユーザーのアクセス許可を制御するための UI コンポーネントは、エンティティのアクセス許可を管理するための共通のインターフェイスを提供しました。

これは、社内データベース駆動型 CMS のアクセス許可を設定するために使用され、パートナー企業が社内外で使用する多数のサイトを構築するために使用され、クライアント レコードへのアクセスなどの他の種類のデータも作成されました。

それを構築するときに私たちが抱えていた主な問題の 1 つは、データベースのヒット数を最小限に抑えることでした。これは、SecurityObject および Group テーブル内の階層データによって効率的なクエリが困難になるため、問題がありました。これは、多くのデータ エンティティに対してアクセス許可のチェックを行う場合に大きな問題となります。

これにより、多数のマシンにアプリケーションを分散させている場合、データのキャッシュがかなり重くなり、それ自体の問題が発生します。

これらすべての結果として、これがビジネスに必要なものであることを十分に確認する必要があるという他のポスターのいくつかに同意する傾向がありますそうしないと、苦痛な方法で時間を無駄にしていることに気付くかもしれません.

これをもう一度行う場合、セキュリティ オブジェクトとアクセス許可のチェックと管理に必ずストアド プロシージャを使用することになります。ORM エンティティの使用に固執することで、私の仕事がより困難になった可能性があります :]

于 2009-01-08T23:50:33.030 に答える