web-dev-qa-db-ja.com

データベースの1つのスーパークラスから継承されたオブジェクトを保存する方法

私の個人的なプロジェクトでは、2D形状をPostgresデータベースに保存する必要があります。たとえば、Circle、Pentagon、Rectangleなどです。最初はそのようにしました:すべての形状はShapesと呼ばれる抽象クラスから継承されます。これには、たとえば、各オブジェクトがそれ自体で実行するために必要ないくつかのメソッドがあります(SpringデータでJavaを使用しています) ):

for(Shape shape : shapes){
    shape.getArea();
}

これはコードとしては優れていますが、データベースに格納するための適切な方法がわかりません。すべての形状には他のものとは異なるいくつかのパラメーター(円の半径、長方形の高さおよび長さなど)があるため、ジオメトリタイプごとに多くのテーブルが必要なようです。しかし、別のテーブルから各形状を参照する方法は?

現在、私はこれをGeometryという単一のクラスで解決しようとしています。たとえば、typeフィールドとそれにリンクされているパラメータのセットがあり、CircleにはテーブルGeometryに1つのレコードがあり、テーブルParametersに1つのレコードがあります。このクラスには、次のように、使用可能な各シェイプに必要なすべてのメソッドもあります。

getArea(){
    switch(type){
        case circle: ....
        case pentagon: ...
    }
}

しかし、私はこれを解決するよりエレガントな方法があるかどうか疑問に思っていますか?

2
Zmur

それは、形状を保存するだけなのか、それらのプロパティに対してクエリを実行するだけなのかによって異なります。

それらを保存するだけの場合、最も簡単な方法は、シリアル化してシリアル化したデータをshapeidフィールドと共に保存し、取得した形状の種類を通知することです。各サブクラスは独自のシリアル化を処理できます。データベースに画像を保存するのとよく似ています。

特定の形状のプロパティに対してクエリを実行する場合は、それらのプロパティをテーブルの列として公開するか、PostgreSQLのジオメトリックタイプを使用する必要があります(Patrick Mevzekが言及)。ただし、特定のデータベースエンジンの型を使用することは、移植性があまり高くありません。

1

すべての種類の形状を持つ複雑な幾何学プログラムを維持するには、ポリモーフィズムと、Shapeから継承するクラスを使用することをお勧めします。これにより、コードが理解しやすくなり、保守しやすくなります(つまり、長いスイッチを使用するよりも、ポリモーフィズムを使用して新しい形状を追加する方が簡単です)。

リレーショナルデータベースでの永続化のために、Martin Fowlerの本「Pattern of Enterprise Application Architecture」で非常によく説明されているいくつかの選択肢があります。

  • 形状にはそれほど多くのパラメーターがないため、次のようになります 単一のテーブル継承 :ジオメトリクラスと少し似ているように、すべてのデータを保持する単一のテーブルがあります。
  • 形状が非常に複雑で、さまざまなデータがたくさんある場合は、 クラステーブルの継承 を使用できます。クラスごとに独自のテーブルがあります(ある種類の場合はShapeを含む)共通データの)。
  • 両方の間に 具体的なテーブル継承 があり、ほとんどの派生クラスはすべてのデータを含む独自のテーブルを持っています(つまり、SquaresCirclesShape自体ではありません。

したがって、コツは、メモリに存在するオブジェクトと、それらがデータベースに格納される方法をいくらか分離することです。

1
Christophe