2011-12-02 52 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和地区。我给你3个例子我有什么ahieve:

  • 当我offer_1存储在region_111然后我想显示当用户在浏览subregion_1,subregion_11和region_111
  • 此优惠。如果offer_1存储在区域subregion_11和region_121中,则当用户浏览子区域_1,子区域_11和子区域_11,子区域_12和区域_121的所有分支时显示报价,当我的offer_1被存储在子区域_1中时,则报价被显示在子区域_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  | 
------------------------ 

我创建ID为地区从1级串联,2级以及3级。在Offers_to_regions表中,我存储了优惠和地区。在这里,我有3级地区(020103)和2级地区(0202)的优惠1. 有了这个设计,我有问题如何查询每个地区的不同优惠的数量,以及如何查询level1地区的优惠, level2和level3地区。

+0

显示目前为止的内容总是一个好主意,然后询问有关您目前所处位置的具体问题。 – Bert

+0

你在使用什么样的数据库? – omarello

+0

@omarello MySQL。 –

回答

1

那么有它使用一个ID指向一个父类的明显的方式这

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) 
); 

但在你的情况,这可能被认为是一个反模式,因为它是不那么容易通过查询层次结构(特别是如果水平的变化数)

另一种方法可以使用类似路径枚举,您存储类似于例如UNIX路径层级路径。例如。

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

这将允许您存储层次结构这样

--------------------------------------------- 
| 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  | 
--------------------------------------------- 

这样,查询时您的报价表(其中每个报价将有一个参考文献的REGION_ID),并同时浏览,可说为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)你可能会有兴趣看看为好。每个人都有选择中/插入的条件不同而各有利弊/删除性能

编辑:

我只注意到你编辑你的问题,也即报价可能属于一个以上的区域。上述可能需要进行调整以支持分配多个区域,但基本思想仍然可以应用。

+0

但是,如果优惠将被添加到数据库与subregion_1(id = 1)。此优惠应在所有分行的'1 /%'中显示,但在这种情况下,只有在subregion_1页面中才能看到? –

+0

如果某个商品处于subergion_1中,当您浏览例如region_111和subregion_11和subregion_1时应该显示该商品吗?另外,如果商品在region_111中,它应该在region_111,subregion_11和subregion_1中可见?如果是这样的话,我认为不再需要层次结构来成为老手了!只需使用多对多关系来定义报价的可见性 – omarello

+0

是可以的。这是为司机和乘客服务的。如果passenges在area_1中寻找驱动程序,那么他会看到来自该区域1的所有驱动程序的所有优惠_1,这意味着他看到了area_1内较小区域的优惠,但他并未看到area_2的优惠,因为这是不同的地理区域。当驱动程序为area_1添加报价时,他的报价将在area_1下的所有子树中可见。但是,当他在区域__1内的区域__1添加优惠时,那么当乘客访问区域_1的网站时应该看到该优惠,因为区域_1包含区域_1_1。 –