2016-07-01 5 views
1

モデルの型の格納に関するモデル設計に関する質問があります。Djangoモデルの型を格納する最適な方法とSQLデータベースからの効率的な読み取り

class Building(models.Model) 
    id = models.AutoField(primary_key=True) 
    address = models.CharField() 

class Bar(models.Model) 
    id = models.AutoField(primary_key=True) 
    building = models.ForeignKey(Building) 
    seats = models.Integer() 
    waiters = models.Integer() 

class Bakery(models.Model) 
    id = models.AutoField(primary_key=True) 
    building = models.ForeignKey(Building) 
    sells_beverages = models.Boolean(default=False) 

class Toilet(models.Model) 
    id = models.AutoField(primary_key=True) 
    building = models.ForeignKey(Building) 
    has_air_dryer = models.Boolean(default=False) 

は、例えば、建物のバー&トイレを持つことができますが、パンを持っていない:ここでは一例です。建物の内容によっては、建物の種類を表す建物のタイプを保存したいと考えています。また、データベース内のルックアップの数を制限するというアイデアもあるので、建物にトイレがある場合(そのタイプから見ることができます)、BarまたはBakeryが存在するかどうかを確認するためにデータベースに別のものを置く必要はありません建物の中に。

これは型を明示的に定義しますが、後で列を追加することで問題が発生する可能性があります。

class Building(models.Model) 
    id = models.AutoField(primary_key=True) 
    address = models.CharField() 
    bar = models.Boolean(default=False) 
    bakery = models.Boolean(default=False) 
    toilet = models.Boolean(default=False) 

これは、設立が建物の中に存在するかどうかを明示的に定義します

class Bar(models.Model) 
    ... 
    bar = models.Boolean(default=False) 

class Bakery(models.Model) 
    ... 
    bakery = models.Boolean(default=False) 

class Toilet(models.Model) 
    ... 
    bakery = models.Boolean(default=False) 

これは、コードまたは別のテーブルのどこかに定義されなければならないタイプのコードを、追加します。たとえば、タイプコード3は、建物にはバーとベーカリーがありますがトイレはありません。

class Building(models.Model) 
    id = models.AutoField(primary_key=True) 
    address = models.CharField() 
    type = models.Integer() 

これは私が考えたアプローチですが、どちらが最適かはわかりません。また、1つの建物につき4つのクエリを作成しなければならないことは避けなければなりません。建物の大きなリストを取得するときには物事が遅くなるからです。

私はselect_related & prefetch_relatedを調べましたが、select_relatedは逆の外部キー関係を行わず、フォローアップのみを行います。そして、私が収集したものからprefetch_relatedは、それぞれの可能な施設ごとに別々のクエリを作成します。

問題について正しい方向に私を指摘できることを願っています。

ありがとうございます。

+0

Can Buildingオブジェクトには、たとえば、2つのバーがありますか? –

+0

最初の選択肢によると、建物には多くのバー/ベーカリー/トイレがあるようです。 –

答えて

1

オプション1は、3つの異なるSQL結合検索が必要です(つまり、各施設とのビルディングテーブルの結合)ので、最も高価です。また、1つの建物が各タイプから複数の施設を持つことができることを意味します。

オプション2は最も安価です。ビルドオブジェクトを取得した後、クエリは必要ありません。このオプションは、施設の存在のみを検索する場合に最適です。

最後のオプションは、それぞれの設定置換の異なるタイプを必要とするため、少し厄介です(この例では9つのオプション)。考慮すべき

別のオプションは、それが何であるかを知らせるタイプフィールドで設立モデルを持つことです。

class Establishment(models.Model) 
    id = models.AutoField(primary_key=True) 
    building = models.ForeignKey(Building) 
    type = models.CharField(max_length=64) 

これは、単一のクエリがそれの施設と一緒に建物を取得できるようになります(操作に参加)、しかし、追加の施設ごとのプロパティを持つことはできません。

関連する問題