Database design 多级项目
我们正在尝试构建一个应用程序来描述我们的价目表。价目表本身是多层次的,因此一个项目的价格取决于许多“选项”。我想在这里举个例子是我最好的选择 目前我有以下表格: 项目: 项目ID(主键)Database design 多级项目,database-design,database-schema,Database Design,Database Schema,我们正在尝试构建一个应用程序来描述我们的价目表。价目表本身是多层次的,因此一个项目的价格取决于许多“选项”。我想在这里举个例子是我最好的选择 目前我有以下表格: 项目: 项目ID(主键) 名称 主要选项: 主选项ID(主键) 名称 子选项: 子选项ID(主键) 主选项ID(FK) 名称 项目至子项目选项 项目ID 子选项ID 这是我们目前拥有的结构–以下是一个示例,以演示其工作原理: 物品:沙发 主选项:长度 子选项:40“-50” 项目至子项目选项:沙发的项目标识,40“-50”子项目标识 你
- 项目ID
- 子选项ID
设计数据库以实现此解决方案的最佳方法是什么?我可以考虑两种方法来设计类似的内容。但首先要认识到的是,您的数据在结构上具有固有的层次性,不一定非常规则。这意味着使用传统的关系数据库并不特别适合这种类型的数据。然而,这是可以做到的 我可能会自己使用的第一种方法是选择一个非关系型数据库,比如MongoDB,它是用来存储“文档”集合的。文档本质上有点像一个对象,并且可以在其中嵌入其他文档。这对于您的数据类型尤其有利。您可以创建如下数据模型:
Item {
main_options: [{
name: "Shape",
sub_options: [{
name: "1/2 Circle",
// Other fields here
}]
},
{
// Other main option
}]
}
这种基于文档的数据模型的优点在于,您不必遵循固定的模式。如果一个项目需要几个嵌套的选项集,您只需直接用这种方式定义该项目的文档即可。尽管每个“item”文档可能有很大的不同,但它们都存储在同一个“集合”中,您可以执行查询以查找不同的项。例如,您可以要求数据库查找带有“1/2圆”子选项“形状”的所有项目
如果您习惯于使用关系数据库,那么转向MongoDB之类的东西会有点让人心神不定,但我认为在这种情况下,它实际上非常适合您的数据性质
另一方面,如果您绝对必须使用关系数据库,那么您需要将事物建模为层次结构,这可能会有点棘手。基本上,您需要的表有点像您已经描述过的,尽管我在这里对它们进行了修改:
item (id (pk), name: text, ...)
option (id (pk), owner: option_id (fk), name: text, ...)
item_options (item_id, option_id)
因此,这里我们定义了我们的item表和另一个表,该表将一个item映射到它的一组主要选项,这些选项在“option”表中定义
选项表包含一个额外字段“owner”,对于主选项,您可以将该字段设置为“null”,但是对于子选项,您可以将该字段设置为主选项的选项ID,或者可能是“拥有”它的子选项。使用这种结构,您可以将选项嵌套到任意深度。以下是一些示例数据:
item (1, "Sofa", ...)
option (1, null, "Shape", ...)
option (2, null, "Length", ...)
option (3, 1, "1/2 Circle", ...)
option (4, 1, "3/4 Circle", ...)
option (5, 2, "Short", ...)
option (6, 2, "Long", ...)
option (7, 5, "Specific Short Measurement", ...)
option (8, 5, "Other Short Measurement", ...)
item_options (1, 1)
item_options (1, 2)
对这种类型的数据使用关系数据库的缺点是,查找内容的查询不是很容易。例如,要使用“1/2圆”选项搜索所有沙发,您可能需要以下内容:
select * from item i inner join item_options io on i.id = io.item_id inner join option o on io.option_id = o.id left join option o2 on o.id = o2.owner where o.name = 'Shape' and o2.name = '1/2 Circle';
正如您所看到的,项目结构越深,您必须进行越多的联接来查询层次结构中的深层内容。这个查询只针对只有main和sub选项的对象
无论如何,我希望这能为您提供一些如何建模的选项。您之所以难以做到这一点,是因为您对问题的思考有点错误。您不需要考虑包含子选项和其他子选项的主选项,而是要考虑由其他主选项组成的主选项 如果您将主选项视为“特性”或“质量”,而将子选项视为“值”,那么这一点就更清楚了。在您的示例中,沙发具有“形状”属性。出于您的目的,形状可以是线性或圆形。线性形状具有长度特性,而圆形具有角度特性。这些品质都没有任何值:形状、线性、圆形。但是,这些质量:长度、角度确实有值。长度的值可能是40“-50”,角度的值可能是1/2圆 因此,您的数据模型不需要太多更改: 只需将另一个FK from MAIN_选项添加到自身。你会注意到这也是David提出的,除了David认为这是一个糟糕的第二选择,而实际上这是一个不错的第一选择
您的规则是层次化的,RDBMS对于层次化数据来说可能很难使用,除非您深入研究层次结构。当您深入研究时,每个步骤都很简单。让我们假设我必须使用关系数据库——这不是更好的结构吗?还有其他人有不同的想法吗?没有更好的结构了。这是一个典型的关系数据库建模问题。Google提供了建模零件和子零件关系的示例