5

私はテーブルを持っています。それぞれが特定のエンティティに関するアトミックデータを含む25列の大きなテーブル。エンティティは、具体的には、販売用の不動産プロパティ(部屋や家など)であるため、テーブルはプロパティと呼ばれます。

すべてのプロパティにはサブクラスがあり(実際には「タイプ」と呼ばれますが、データ型との混同を避けるために「サブクラス」と呼びます)、現時点では「構築済みで販売中」または「建設中ですが、に投資しました」。また、住所や価格などの多くの属性があり、そのほとんどはサブクラス間で共有されますが、そうでないものもあります。属性には、次のようなさまざまなデータ型があります。

  • 整数
  • 浮動小数点数
  • テキストの短い行
  • テキストの長いチャンク
  • 他のテーブルへの外部キー

これらの「その他のテーブル」は、モデレーターが編集可能なオプションのリスト(市区町村のリスト、建築会社のリストなど)から選択するためのものです。

モデレーターは、新しいプロパティを作成して編集できる必要があります。ユーザーは、特定のプロパティの詳細情報を表示し、特定の条件を満たすプロパティを検索して、それらをテーブルとして表示し、列の1つで並べ替えることができる必要があります。

プロパティのサブクラスに応じて、プロパティ属性のサブセットのみが、ユーザーが表示したり、モデレーターが編集したりできます。また、データタイプに応じて、これらの属性をユーザーに表示し、モデレーターに編集コントロールを提供するために異なるHTMLコードが必要です。また、編集後に異なるデータ検証チェックを実行する必要があります。

フィールドのリストは動的ではありません。列のリストとその表示方法が頻繁に変更される可能性は低く、モデレーターが変更できる必要はありません。

ただし、25はかなり大きい数なので、プロパティテーブルに関するすべてのメタデータ(列のサブクラスとデータの表示、編集、検証方法に関する情報)を1か所にまとめて保持したいと思います。コードからこのすべてのメタデータに簡単な方法(配列など)でアクセスできると便利です。これを行うには、次の3つのオプションがあります。


1.定数PHP配列

メタデータを使用して配列を構築するPHPファイルまたは関数を作成し、必要に応じてそれをインクルード/呼び出します。

長所:

  • 単純。
  • 速い。

短所:

  • 過度に冗長で醜いPHPコードのため、保守が困難です。

2.MySQLデータベース

データベースにテーブルproperty_metaを作成し、そこにメタデータを保存します。新しいテーブルには、プロパティテーブルの列名、この列のデータと各プロパティサブクラスとの関連性、予想されるデータ型などが含まれます。次に、必要なフィールドをクエリし、結果のデータを配列として返す関数を作成します。

長所:

  • メタデータの変更が簡単です。
  • 維持するコードが少なくなります。
  • 後で拡張して、ユーザーが列のリストを変更できるようにすることができます。プロパティテーブルに列を追加したり、プロパティテーブルから列を削除したりすることはそれほど問題にはなりません。私の意見では、ユーザーがデータベーススキーマをその場で変更できることは、深刻なコードの臭いです。私が間違っている場合は私を訂正してください。

短所:

  • メタデータが変更されるたびに、それに応じてサーバーデータベースを更新する必要があります。ただし、データベーススキーマが変更された場合にのみ発生するため、誰も気にしません。
  • 低速-アレイの作成コストに加えて、サーバーとの通信コストとデータベースからデータを選択するコストが追加されます。後者はMySQLクエリキャッシングメカニズムによって否定される可能性がありますが。

3.プロパティとその属性を異なるテーブルに分割します

上記のソリューションのようにメタデータテーブルを作成し、property_attributeという名前のみを付けます。また、 propertyおよびproperty_attributeへの外部キーと属性値用のもう1つの列を使用してproperty_dataテーブルを作成します。その場合、プロパティテーブルには主キーとサブクラスのみが含まれ、実際の属性値は2つの結合を持つクエリでのみ取得できます。

長所:

  • 最も柔軟なソリューション。属性のリストが変更されても、データベーススキーマは同じままです。

短所:

  • property_data行には、タイプが不明な単一のデータが含まれます。それらすべてをTEXTまたはBLOBとして格納するか、個別のデータ型に対して個別の列を作成します。どちらのソリューションも見苦しいです。
  • プロパティテーブルからの以前の外部キーの処理方法は不明です。すべての挿入で実行される自動データ整合性チェックはほぼ不可能になります(おそらくトリガーで可能ですか?わかりません)。
  • データの選択は非常に難しくなります。データは---三位一体としてフェッチされますが、これは直感的ではなく、適切に出力するにはより多くの労力が必要property_idですproperty_attribute_idvalue
  • それ以上に、1つ以上の属性によるフィルタリングと並べ替えは、私を傷ついた世界に送ります。
  • とても、とても遅い。
  • ヘリコプターを使って通りを渡るような気分です。

率直に言って、私はこれらの解決策のどちらも好きではありません。しかし、私の意見では、2番目のものは最も醜いものではありません。どう思いますか?

4

2 に答える 2

2

あなたへの私の最初の質問は次のようになります:あなたは適切なデータベーススキーマを考案する助けを求めていますか、それともコードでこれらのプロパティ/サブクラスを処理する方法を求めていますか?

データベーススキーマ

データベーススキーマは私の得意分野ではないので、私よりもよく知っている人に任せます。簡単で、各フィールドに適切にインデックスを付けることができるため、単一のプロパティ
テーブル に各フィールドを独自の列として含めることもできます。あなたが言ったように、新しいフィールドは頻繁に追加されることはありません。

PHPで処理する

私の意見では、これらのフィールドをメタデータとして考えることは間違っています。各サブクラスには独自のフィールドのセットがあります。つまり、技術的には、それらはすべて別個の種類のエンティティです。

わかりやすくするためにこれを単純にしていますが、これが私が行うことの線に沿ったものです。

  1. プロパティタイプごとにPOPO(plain ole'phpオブジェクト)を作成します。
    これらは、ORMで見られるものと同様に、単なる値オブジェクトです。Doctrine2エンティティのように、それらはいかなる種類の永続性も実行しません。

  2. ここで例を簡略化します。これは間違いなくSRPに準拠しておらず、設計が不適切ですが、簡潔にするためにこのように記述しています。

    データベースとの間でデータをフェッチおよび保存し、適切なPOPOを作成し、それに応じてデータを入力するファクトリクラスを作成します。

それが本当にすべてです。ミニORMです。必要に応じて、実際には#2を廃止し、適切なORMを使用できます...

それらの鍵は、プロパティサブクラスごとに個別のオブジェクトを持つことです。それは次の理由で有利です:

  • 各プロパティタイプには、独自の事前定義されたプロパティのセット(およびゲッター/セッター)を持つ独自のクラスがあるため、他のプロパティタイプに属するデータの入力や使用について心配する必要はありません。
  • これは、各プロパティタイプに固有のテンプレートをレンダリングするために使用できる明確な区別を提供します。(以前はこれができなかったわけではありません...この方法の方がクリーンだと感じています。)
  • 各プロパティタイプクラスは、プロパティタイプ間で共通のすべてのフィールドに対応するために、ベースから継承できます。
于 2012-08-29T18:16:23.463 に答える
1

I see another options, you can take into consideration using NoSQL, in addition to MySQL, but you need to think hard about your requirements to make the right product choice between

  • Column Store / Column Families
  • Document Store
  • Key Value
  • ...and more

One of the big benefit is the flexible data models, but NoSQL and Relational Database have everyone their advantages, disadvantages and strong point, so you have to known this product before decide for a nosql solution

于 2012-08-29T18:31:19.133 に答える