2011-01-13 62 views
0

我正在努力与数据模型(我使用MySQL的数据库)。我对自己的想法感到不安。如果有人可以提出更好的方法,或者指出一些参考问题,我将不胜感激。挣扎与数据建模问题

该数据将有许多类型的组织。我正在尝试做一个3级分类(类,类别,类型)。说,如果我有“意大利餐厅”,这将有如下分类

食品服务>餐馆>意大利

然而,一个组织可以属于多个组。一家餐馆也可以服务中国和意大利。因此,将适用于2个分类

食品服务>餐馆>意大利
食品服务>餐馆>中国

分级参考表将是这样的:

ORG_CLASS(RowId的,ClassCode,类名)

1, FOOD, Food Services 

ORG_CATEGORY(RowId的,ClassCode,CategoryCode ,类别名称)

1, FOOD, REST, Restaurants 

ORG_TYPE(RowId的,ClassCode,CategoryCode,类型码,类型名)

100, FOOD, REST, ITAL, Italian 
101, FOOD, REST, CHIN, Chinese 
102, FOOD, REST, SPAN, Spanish 
103, FOOD, REST, MEXI, Mexican 
104, FOOD, REST, FREN, French 
105, FOOD, REST, MIDL, Middle Eastern 

实际的数据表将是这样的:

我将允许最多组织3个分类。我将有3个GroupId,每个指向ORG_TYPE中的一行。所以,我有我的ORGANIZATION_TABLE

ORGANIZATION_TABLE(OrgGroupId1,OrgGroupId2,OrgGroupId3,ORGNAME,OrgAddres)

100,103,NULL,MyRestaurant1, MyAddr1 
100,102,NULL,MyRestaurant2, MyAddr2 
100,104,105, MyRestaurant3, MyAddr3 

在添加数据,一个对话框,可以让用户选择clssa,类别,类型和相应的可以使用ORG_TYPE表中的rowid填充GroupId。

搜索过程中,如果选择了所有三种分类,它将更具体。例如,如果

食品服务>餐馆>意大利人的标准,where子句是'where OrgGroupId1 = 100'

如果只有2个水平选择

餐饮服务>餐厅

我必须做的'where OrgGroupId1 in (100,101,102,103,104,105, .....)' - 该列表中可能有一百个

我将不允许进行课程级别搜索。那就是我会强制选择一个班级和类别

这些ID是整数。我正在尝试查看性能问题和其他问题。

总的来说,这项工作?或者我需要抛出并从头开始。

+0

这可能是矫枉过正你的目的,但有关管理的层次化数据的好文章:http://dev.mysql.com/tech-resources/articles/hierarchical-data.html – trickwallett 2011-01-13 12:14:08

+0

感谢链接。这确实是一个很好的参考。它确实让我有另一种分类选择。文章中的这种方法更加灵活,并且不会限制分类的数量级别。 – rpat 2011-01-14 17:01:19

+0

@trickwallet:该文章不在此地址。它现在在这里:http://mikehillyer.com/articles/managing-hierarchical-data-in-mysql/ – 2011-08-05 18:44:44

回答

1

我不喜欢有三列“最多三个”分类。在我看来,最好有一个交叉引用表,允许在组织和类型之间进行多对多映射,即将ORGANISATION_GROUPS与列OrganisationId,OrgGroupId关联起来。

要解决查询指定的不同级别的问题,您可以设置此交叉引用表来保存实际的分类,即ORGANISATION_GROUPS取而代之具有列:OrganisationId,ClassCode,CategoryCode,TypeCode。

这将使查询在不同级别的分类非常容易。

为了参照完整性来处理这个方案,我建议不要为ORG_ *表使用代理整型键,而应将主键设置为真正的唯一键,即ClassCode,CategoryCode和TypeCode for ORG_TYPE。

0

我在你的设计中看到的问题是它有点僵硬。您可能需要考虑的更灵活的方法如下:

首先,您需要一个表格,类别,类型和任何其他分类类型。该表将被自动引用。所有寄存器将有一个字段指的是其直接父,如以下:

分类(ID,描述,PARENT_ID)

ITAL, Italian, REST 
CHIN, Chinese, REST 
MEXI, Mexican, REST 
REST, Restaurant, FOOD 

接下来你将有,作为@约翰拾取建议的,一个中间横 - 餐馆(或任何你需要的)表和分类表之间的参考表,它只包含一个复合主键,它的组成部分是两个表的主键。

FOODSERVICE_CLASSIFICATION(Rest_Id,类标识码)

100, ITAL 
100, CHIN 
101, MEXI 
102, CHIN 

这将是可取的,以限制它使得只有分类表的叶寄存器可以在交叉引用表被引用。

您寻找所有餐馆的例子就像查找REST的所有子类别并在交叉引用表中搜索它们一样简单。这可以写入Oracle中的单个选择(不确定其他RDBMS)。

这种方式,您可以:

  • 有你的餐馆多种分类,而不限于3个类别。
  • 使用交叉引用表进行快速搜索。

请注意,如果您的分类类似于以基本类别作为根的树,则此模式可行。如果您需要更宽松的分类,您可能需要使用标签方法。

顺便说一下,我也同意@John Pickup在这种情况下最好使用真正的主键。

HTH