简体   繁体   中英

Database Design: Hierarchical Data

I am having trouble arriving at a normalized relational database design to describe a small hierarchy which deviates enough from the typical hierarchy examples such that I am unsure how to proceed my first time tackling such a problem.

My problem is as follows:

Each branch in the hierarchy is guaranteed to be either 2, 4, or 6 levels deep. If it is 2 levels deep, the hierarchy looks like this:

Category / Group / Component

If it is 4 levels deep, it looks like this:

Category / Group / Component / Group / Component

If it is 6 levels deep, it looks like this:

Category / Group / Component / Group / Component / Group / Component

Categories, Groups, and Components each have their own set of attributes. To further complicate matters, a relationship exists between a Component and entity A, a Component and entity B, and a Component and entity C.

My original thought was to strive to keep the Components in one table, however, I have been unable to come up with a normalized solution that satisfies this goal.

Instead, I came up with a normalized solution where there is a separate table for Components at each of the three possible component levels. However, I am not really comfortable with this because it triples the number of tables capturing links between components and entitites A, B, and C (9 total link tables rather than 3 if all components were in one table).

Here is what the design I came up with looks like:

TABLE: Group_1_Components

ATTRIBUTES: Row_ID, Category, Component

RELATES-TO: Group_1_Components_A_Links, Group_1_Components_B_Links, Group_1_Components_C_Links, Group_2_Components

TABLE: Group_2_Components

ATTRIBUTES: Row_ID, Group, Component, Group_1_Component_Row_ID

RELATES-TO: Group_2_Components_A_Links, Group_2_Components_B_Links, Group_2_Components_C_Links, Group_1_Components, Group_3_Components

TABLE: Group_3_Components

ATTRIBUTES: Row_ID, Group, Component, Group_2_Component_Row_ID

RELATES-TO: Group_3_Components_A_Links, Group_3_Components_B_Links, Group_3_Components_C_Links, Group_2_Components

Each of the 9 links tables contain two Row IDs to address a many-to-many relationship with either table A, B, or C.

Is this a reasonable design or am I overlooking a simpler, more typical solution? I looked at a few design techniques specific to capturing hierarchies in a relational database, notably the adjacency list, but I am not sure they fit here, nor do they appear to be normalized solutions.

It should be noted that the hierarchy will be seldomly modified; it will frequently be read where reads retrieve either all of the components or components at a specific level for a selected group. The link tables to entities A, B, and C will be written to regularly.

Any and all suggestions are welcome. Thanks in advance for your help. Brian

I suggest that you de-normalize your data so that your hierarchy is based on component/group entities, so that you match "regular" hierarchies. In this case you can have the following tables:

a) Components

b) Groups

c) Component_Groups - with a unique key on component_id and group_id to ensure that you only have one combination for each component and group

In this case then your hierarchy will be: Category -> Component_Group -> Component_Group -> Component_Group

Another option for this kind of problem is using a self-referencing table. Just one table.

Single table with ID, PARENT_ID and a TYPE so you can distinguish CATEGORY, GROUP and COMPONENT.

All categories would have no PARENT_ID and then you could search for all child objects where the parent id is equal to the id of the category you want to dive deeper into.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM