苦苦于数据建模问题

时间:2011-01-13 12:07:20

标签: datamodel database-design

我正在努力使用数据模型(我使用MySQL作为数据库)。我对我的想法感到不安。如果有人可以提出更好的方法,或者指出一些参考问题,我会很感激。

数据将包含多种类型的组织。我正在尝试进行3级分类(类,类别,类型)。如果我有'意大利餐厅',它将具有以下分类

食品服务>餐馆>意大利

但是,组织可能属于多个组。餐厅也可以供应中餐和意大利餐。所以它将适合2个分类

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

分类参考表如下:

ORG_CLASS(RowId,ClassCode,ClassName)

1, FOOD, Food Services

ORG_CATEGORY(RowId,ClassCode,CategoryCode,CategoryName)

1, FOOD, REST, Restaurants

ORG_TYPE(RowId,ClassCode,CategoryCode,TypeCode,TypeName)

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,category,type,并且可以使用ORG_TYPE表中的rowid填充相应的GroupId。

在搜索过程中,如果选择了所有三个分类,则会更具体。例如,如果

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

如果只选择了2个级别

食品服务>餐馆

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

我将禁止上课级搜索。那就是我将强制选择一个类和类别

Ids将是整数。我试图看到性能问题和其他问题。

总的来说,这会有用吗?或者我需要抛弃它并从头开始。

2 个答案:

答案 0 :(得分:1)

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

要找出能够查询指定的不同分类级别的问题,您可以设置此交叉引用表来保存实际分类,即ORGANISATION_GROUPS改为具有列:OrganisationId,ClassCode,CategoryCode,TypeCode。

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

为了使用这种方案的参照完整性,我建议不要为你的ORG_ *表使用代理整数键,而是将主键设置为真正的唯一键,即ClassCode,CategoryCode,ORG_TYPE的TypeCode。

答案 1 :(得分:0)

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

首先,您将拥有类,类别,类型和任何其他分类类型的表。该表将自动引用。所有寄存器都有一个引用其直接父级的字段,如下所示:

分类(ID,描述,Parent_Id)

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

接下来你会像@John皮卡建议的那样,在你的餐厅(或任何你需要的)表和分类表之间建立一个中间交叉引用表,该表只包含一个复合主键,其组成部分是主键。两张桌子。

FOODSERVICE_CLASSIFICATION (Rest_Id,Class_Id)

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

建议对其进行限制,以便只能在交叉引用表中引用CLASSIFICATION表的叶子寄存器。

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

这样你就可以:

  • 对您的餐厅进行多次分类,但不限于3个类别。
  • 使用交叉引用表进行快速搜索。

请注意,这个模式可以使用,假设您的分类就像一个以基类作为根的树。如果您需要更松散的分类,则可能需要使用标签方法。

不过,我同意@John Pickup的观点,在这种情况下最好使用真正的主键。

HTH