2012-03-22 71 views
1

我是数据库设计的新手,只是想了解一下我是否以逻辑的方式来解决这个问题。我正在构建一个简单的MySQL数据库,通过它,用户可以将项目上载到先前存在的(不变的)分层树中。关于层次化MySQL数据库设计的建议

对于一个简单的例子:

第一节

     司1.1
           分区1.1.1
           分区1.1.2

     司1.2
           分区1.2.1
           分区1.2.2

第2节

     司2.1
           分区2.1.1
           分区2.1.2

     司2.2
           分区2.2.1
           分区2.2.2

树是不会改变的结构,用户将只需上传产品,将属于细分下(行业特定的方式组织大量的产品)。我已经完成了关于邻接列表和嵌套集合的研究,但是我倾向于分别引用其父母主键的3个独立表格(因为树的顶层几乎不会改变)。当新产品上传时,它会引用它的所有三个父母(如果它是根据细分1.1.2提交的,它必然是第1部分第1部分的一部分)。最终的树会有4个部分,每个部分有10个部门,每个部门有10个部门。这是否有意义作为一个启动策略?

与数据库的交互作用或多或少地局限于输入信息并对其进行准确分类,然后能够显示已在部门,部门或细分部门中提交的产品数量。该库将显示在一系列下拉列表中,并且单击列表项将弹出存储的信息。

任何建议或参考文献/教程将不胜感激!

+1

如果你永远不会超过3个关卡,那么你可以'便宜'并且只需要'(section_id,div_id,subdiv_id)'并且把它全部保存在一张表中。但它会很容易受到像sec#1,div 2.1,subsec 1.1.1这样的等级错误的影响。 – 2012-03-22 19:57:13

+0

我同意Marc B的结构是技术层次结构,但它的结构不够动态以保证高级数据结构。您可以通过简单的限制避免类别错误 – 2012-03-22 20:11:58

+0

非常感谢Marc和David!大卫,你可以通过简单的约束扩展你的意思吗?马克B,如果所有的产品都被要求分配到一个小部分(比如“Bill's Macintosh苹果园”在美国水果>苹果>麦金塔下归档),那么我刚才说我会有一张描述不变树的桌子,然后是第二个表,其中包含“Bill's Macintosh Apple Orchard”的特定信息和ID以及对其父级subdiv_id的引用?我希望这是明确的:) – TheNally 2012-03-23 01:21:49

回答

2

因为 “树的结构不会改变”,你需要sectiondivisionsubdivision桌子(也是产品)。

create table section (
    id int primary key, 
    name varchar(100) 
); 

create table division (
    id int primary key, 
    name varchar(100) , 
    section_id int references section 
); 

create table subdivision (
    id int primary key, 
    name varchar(100) , 
    division_id int references division 
); 

create table product (
    id int primary key, 
    name varchar(100) , 
    subdivision_id int references subdivision 
); 

对于其他requerimets,例如:

  • 不明深度的树。
  • 将产品分配到多个树级别。

你将寻找一个亲子soluction,例如:

create table tree (
    id int primary key, 
    parent_id int null references tree, 
    name varchar(100) 
); 

create table product (
    id int primary key, 
    name varchar(100) , 
    subdivision_id int references tree 
); 
+0

非常感谢!这正是我想表达的。我开始这个过程,但不确定它是否被认为是可以接受的解决方案。 – TheNally 2012-03-23 02:34:15

2

由于类别(节)都或多或少是静态的,你可以做的是分配给每个类别中的“高”和“低”号,如

catid name  low  high 
1  Section1  1  20 
2  Div1.1  2  10 
3  Div1.2  11  19 
4  Section2  21  40 
5  Div2.1  22  29 
6  Div2.2  30  39 

然后有一个单独的表内容:

id catid content 
1 2  fileA 
2 2  fileB 
3 5  fileC 

为了然后查询所有项目第1节,只需查询的类别有1到20之间的高和低,以获得Div2.1所有项目的所有项目(下),你查询所有具有高和低的类别的项目都在22和29之间。这使得它成为可能很容易跟踪子类别下的项目数量。

我忘记了这种实际方法的名称(如果有确切的方法),但我已经使用了很多次。对于变化不大的结构,与传统的parent_id-child_id类型结构相比,它更容易使用。

+0

我认为它被称为嵌套:http://mikehillyer.com/articles/managing-hierarchical-data-in-mysql/ – Nathan 2012-03-22 20:12:58

+0

GrandmasterB和其他人,感谢您的意见。实际上,我之前已经在嵌套集合图中绘制了模式(花了一段时间,约有400个最终细分)。我的问题从你描述的第二张桌子开始。项目必须按照细分类别进行分类,因此所有输入的信息将始终处于同一级别。代码段看起来像将fileC输入到Section 2,Division 2,Subdivision 1(从您的示例中)?还有(在黑暗中拍摄)有没有简单的方法将低/高数字分配给大量的树节点? – TheNally 2012-03-23 01:04:47

+0

您可以将递归表转换为嵌套集。检查这篇文章:http://sqlblog.com/blogs/adam_machanic/archive/2006/07/12/swinging-from-tree-to-tree-using-ctes-part-1-adjacency-to-nested-sets。 aspx此外:http://jsimonbi.wordpress.com/2011/02/14/nested-set-hierarchy/ – Nathan 2012-03-24 14:23:31

2

一个很好的解决方案将有一个递归表。

检查这个职位上的StackOverflow:Hierarchical Data in MySQL

这样,你的设计将支持具有多层次树倒。关于这个话题

其他有趣的文章:

Managing Hierarchical Data in MySQL

Hierarchical data in MySQL: parents and children in one query

Hierarchical data in MySQL: easy and fast

Recursion-less storage of hierarchical data in a relational database

+0

感谢您提供的参考资料,其中有一些我已经过检查,但我一定会进一步研究递归表格。再次感谢! – TheNally 2012-03-23 02:32:22