努力解决数据建模问题
我正在努力研究数据模型(我使用 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,每个 GroupId 都指向 ORG_TYPE 中的一行。所以我有我的 ORGANIZATION_TABLE
ORGANIZATION_TABLE (OrgGroupId1, OrgGroupId2, OrgGroupId3, OrgName, OrgAdres)
100,103,NULL,MyRestaurant1, MyAddr1
100,102,NULL,MyRestaurant2, MyAddr2
100,104,105, MyRestaurant3, MyAddr3
在数据添加期间,一个对话框可以让用户选择 clssa、类别、类型,并且可以使用以下内容填充相应的 GroupId来自 ORG_TYPE 表的 rowid。
搜索时,如果三个分类都选择,会更加具体。例如,如果
食品服务>餐厅>意大利语为标准,where 子句将为 'where OrgGroupId1 = 100'
如果仅选择 2 个级别
餐饮服务 > 餐厅
我必须做的
'where OrgGroupId1 in (100,101,102,103,104,105, .....)'
- 该列表中可能有一百个,我将禁止类级别搜索。也就是说,我将强制选择一个类和类别,
Id 将为整数。我正在尝试查看性能问题和其他问题。
总的来说,这可行吗?或者我需要把它扔掉并从头开始。
I am struggling with a data model (I use MySQL for the database). I am uneasy about what I have come up with. If someone could suggest a better approach, or point me to some reference matter I would appreciate it.
The data would have organizations of many types. I am trying to do a 3 level classification (Class, Category, Type). Say if I have 'Italian Restaurant', it will have the following classification
Food Services > Restaurants > Italian
However, an organization may belong to multiple groups. A restaurant may also serve Chinese and Italian. So it will fit into 2 classifications
Food Services > Restaurants > Italian
Food Services > Restaurants > Chinese
The classification reference tables would be like the following:
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
The actual data tables would be like the following:
I will allow an organization a max of 3 classifications. I will have 3 GroupIds each pointing to a row in ORG_TYPE. So I have my ORGANIZATION_TABLE
ORGANIZATION_TABLE (OrgGroupId1, OrgGroupId2, OrgGroupId3, OrgName, OrgAddres)
100,103,NULL,MyRestaurant1, MyAddr1
100,102,NULL,MyRestaurant2, MyAddr2
100,104,105, MyRestaurant3, MyAddr3
During data add, a dialog could let the user choose the clssa, category, type and the corresponding GroupId could be populated with the rowid from the ORG_TYPE table.
During Search, If all three classification are chosen, It will be more specific. For example, if
Food Services > Restaurants > Italian is the criteria, the where clause would be 'where OrgGroupId1 = 100'
If only 2 levels are chosen
Food Services > Restaurants
I have to do 'where OrgGroupId1 in (100,101,102,103,104,105, .....)'
- There could be a hundred in that list
I will disallow class level search. That is I will force selection of a class and category
The Ids would be integers. I am trying to see performance issues and other issues.
Overall, would this work? or I need to throw this out and start from scratch.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
我不喜欢“最多三个”分类的三列。在我看来,最好有一个交叉引用表,允许您在组织和类型之间进行多对多映射,即表 ORGANISATION_GROUPS 与列 OrganizationId、OrgGroupId。
为了解决能够查询指定的不同分类级别的问题,您可以设置此交叉引用表来保存实际分类,即 ORGANISATION_GROUPS 具有以下列:OrganizationId、ClassCode、CategoryCode、TypeCode。
这将使不同分类级别的查询变得非常容易。
为了实现此方案的引用完整性,我建议不要对 ORG_* 表使用代理整数键,而是将主键设置为真正的唯一键,即 ORG_TYPE 的 ClassCode、CategoryCode、TypeCode。
I don't like the having three columns for the "up to three" classifications. In my opinion it would be better to have a cross-reference table that allows your many-to-many mapping between organisation and type, i.e. table ORGANISATION_GROUPS with columns OrganisationId, OrgGroupId.
To sort out the problem of being able to query a different levels of classification specified you could setup this cross-ref table to hold the actual classifications, i.e. ORGANISATION_GROUPS instead has columnns: OrganisationId, ClassCode, CategoryCode, TypeCode.
This will make queries at different levels of classification very easy.
For referential integrity to work with this scheme I'd then suggest not using surrogate integer keys for your ORG_* tables but instead setting the primary key to be the real unique key, i.e. ClassCode, CategoryCode, TypeCode for ORG_TYPE.
我在你的设计中看到的问题是它有点僵化。您可能需要考虑的更灵活的方法如下:
首先,您将有一个用于类、类别、类型和任何其他分类类型的表。该表将被自动引用。所有寄存器都会有一个引用其直接父级的字段,如下所示:
CLASSIFICATION (Id, Description, Parent_Id)
接下来,正如 @John Pickup 建议的那样,您的餐厅之间会有一个中间交叉引用表(或任何您需要的)表和分类表仅包含一个复合主键,作为其组件,两个表的主键。
FOODSERVICE_CLASSIFICATION(Rest_Id,Class_Id)
建议对其进行限制,以便在交叉引用表中只能引用 CLASSIFICATION 表的叶寄存器。
查找所有餐馆的示例就像查找 REST 的所有子类别并在交叉引用表中搜索它们一样简单。这可以写在 Oracle 中的单个选择中(不确定其他 RDBMS 是否如此)。
这样您就可以:
请注意,假设您的分类就像一棵树,以基本类别作为根,则此模式将起作用。相反,如果您需要更宽松的分类,您可能需要标签方法。
顺便说一句,我也同意@John Pickup 的观点,在这种情况下最好使用真正的主键。
华泰
The problem i see in your design is that it is a bit rigid. A more flexible approach you might want to consider is following:
First you would have a table for classes, categories, types and any other classification type. This table would be auto-referenced. All registers would have a field referring to its immediate parent, like following:
CLASSIFICATION (Id, Description, Parent_Id)
Next you would have, as @John pickup suggested, an intermediate cross-reference table between your restaurant (or whatever you need) table and the classification table which would contain only a composite primary key, being its components the primary key of both tables.
FOODSERVICE_CLASSIFICATION (Rest_Id, Class_Id)
It would be advisable to limit it so that only leaf registers of the CLASSIFICATION table can be referenced in the cross-reference table.
Your example of looking for all restaurants would be as simple as looking for all child categories of REST and search for them in the cross-reference table. This can be written in a single select in Oracle (not sure about other RDBMS).
This way you can:
Mind you, this schema would work supposing your categorization is like a tree with a base category acting as the root. If instead you need a more loose categorization you would probably need a tags approach.
Btw, I also agree with @John Pickup that it is better to use real primary keys in this case.
HTH