2011-12-02 12 views
0

データベース構造の設計上問題があります。 目標は、クライアントがある地理的地域ごとに提供するオファーのデータベースを持つことです。 各オファーは多くの地域で提供することができます。データベースデザイン - アイテムと地域

領域がhierarhyである - 例:

subregion_1 
    subregion_11 
    region_111 
    region_112 
    subregion_12 
    region_121 
    region_122 
subregion_2 
    subregion_21 
    region_221 

は今、私は、データベースにその提供のためのoffer_1と地域を保存したいです。 offer_1格納されている場合は、私のoffer_1がregion_111に格納されて

  • が、私は、ユーザーがsubregion_1、subregion_11とregion_111
  • を閲覧しているこのオファーを表示したいと思います:私はahieveしなければならないものをあなたに3例を与えるだろう地域subregion_11とregion_121では、オファーは、ユーザーがsubregion_1、subregion_11、およびsubregion_11、subregion_12、およびregion_121のすべてのブランチをブラウズしているときに表示されます。
  • 私のoffer_1がsubregion_1に格納され、オファーがsubregion_1ページおよびすべてのブランチsubregion_1。

また、各地域のさまざまなオファーの数を動的に、非常に高速に計算する方法を提供する必要があります。 誰かがこのデザインをどのように提案するのかアドバイスしていますか?

ここは私がこれほど遠いです。

Regions 
------------------------------------------------------------ 
| id  | level1 | level2 | level3 | name   | level | 
------------------------------------------------------------ 
| 02  | 02  | null | null | subregion_1 | 1  | 
| 0201 | 02  | 01  | null | subregion_11 | 2  | 
| 020103 | 02  | 01  | 03  | region_111 | 3  | 
------------------------------------------------------------ 

Offers to regions 
------------------------ 
| offer_id | region_id | 
------------------------ 
| 1  | 020103 | 
| 1  | 0202  | 
------------------------ 

level1、level2、level3を連結して領域を作成しました。 Offers_to_regionsテーブルには、オファーと地域が保存されています。ここでは、オファー1のレベル3(020103)とレベル2(0202)のリージョンがあります。 このデザインでは、リージョンごとの異なるオファーの数を照会する方法と、レベル1のリージョンのオファーを照会する方法に問題があります。レベル2およびレベル3の領域。

+0

あなたがこれまでに持っているものを見せて、あなたが現在立っている場所について具体的な質問をすることは、常に良い考えです。 – Bert

+0

どのような種類のデータベースを使用していますか? – omarello

+0

@omarello MySQL。 –

答えて

1

さて、この

CREATE TABLE Regions (
    region_id INT AUTO_INCREMENT PRIMARY KEY, 
    parent_id INT, 
    region_name VARCHAR(100) NOT NULL, 
    FOREIGN KEY (parent_id) REFERENCES Regions(region_id) 
); 

のような親を指すようにIDを使用しています。しかし、を通じて照会するのは簡単ではありませんので、あなたの状況では、これは、アンチパターンと考えることができる明確な方法があります

パス列挙のような別の方法では、たとえばUNIXパスと同様の階層パスを保存することができます。例えば。

CREATE TABLE Regions (
    region_id INT AUTO_INCREMENT PRIMARY KEY, 
    path VARCHAR(100), 
    region_name VARCHAR(100) NOT NULL 
); 

ブラウジングができますしながら、(ここで、各オファーは参照を持っています。のregion_idに)あなたの申し出のテーブルを照会し、ときに、あなたがこの

--------------------------------------------- 
| region_id | path  | region_name  | 
--------------------------------------------- 
| 1   | 1/   | subregion_1  | 
| 2   | 1/2/  | subregion_11  | 
| 3   | 1/2/3/  | region_111  | 
| 4   | 1/2/4/  | region_112  | 
--------------------------------------------- 

のように、この方法を、あなたの階層を保存することができますsubregion_1(id 1の場合)のク​​エリは、次のように表示されます。

select Offers.SOME_COLUMN, ...... 
from Offers, Regions 
where Offers.region_id = Regions.region_id 
and Regions.path like '1/%' 

は、あなたの階層データをモデル化するために他のパターンがありますが、同様に見て興味があるかもしれないようなNested Setsクロージャ表maybe relevant)。各セレクト/インサートの面でさまざまな長所と短所を持っている/パフォーマンスを

削除

EDIT:

私はちょうどあなたが申し出が複数の領域に属することができることも、あなたの質問を編集した気づきました。上記は、複数の地域の割り当てをサポートするために調整が必要な場合がありますが、基本的な考え方はまだ適用できます。

+0

しかし、offerがsubregion_1(id = 1)のデータベースに追加されるとどうなりますか?このオファーはすべての支店 '1 /%'に表示されるはずですが、この状況ではサブリージョン1ページのみに表示されますか? –

+0

例:region_111、subregion_11、subregion_1を参照している間は、オファーがsubergion_1の場合は表示されますか?オファーがregion_111にある場合、それはregion_111、subregion_11、およびsubregion_1に表示されるはずですか?それが当てはまる場合、私は階層の必要性がなくなっているのを見ていませんか?オファーの可視性を定義するには、多対多の関係を使用してください。 – omarello

+0

ありがとうございます。これは運転手と乗客のためです。乗客がエリア1の運転手を探している場合、彼はこのエリア1の運転手からのすべてのオファーを見るので、エリア1内のより小さいエリアからのオファーを見ることになりますが、これは地理的に異なるため、エリア2からオファーを見ませんでした。ドライバがエリア1のオファーを追加すると、オファーはエリア1のすべてのサブツリーに表示されます。しかし、area_1の小領域であるoffer_1をarea_1に追加すると、乗客がarea_1のサイトにアクセスするときに、area_1にarea_1_1が含まれているため、オファーが表示されます。 –