First, the user interface:作为用户I hate在以strictly hierarchical方式组织的目录中搜索产品.我从来不记得"异国情调"的产品属于哪个子类……,这迫使我浪费时间go 探索"有前途的"类别,结果却发现它是以一种奇怪的方式(至少对我来说是这样)归类的.
Kevin Peno建议是一个好建议,被称为101.正如Marcia Bates在After the Dot-Bomb: Getting Web Information Retrieval Right This Time中所写,".. faceted classification is to hierarchical classification as relational databases are to hierarchical databases. ..".
本质上,faceted search允许用户从他们喜欢的任何"方面"开始搜索目录,并允许他们在搜索过程中 Select 其他方面来过滤信息.请注意,与标签系统通常的构思相反,没有什么可以阻止您按层次组织这些方面.
要快速理解分面搜索是怎么回事,在The Flamenco Search Interface Project - Search Interfaces that Flow有100种搜索方式可供探索.
Second, the application logic: Manitra提出的建议也是一个很好的建议(据我所知),即以不同的关系分隔树/图的nodes
和links
.他所说的"祖先表"(这是一个直观得多的名称)被称为transitive closure of a directed acyclic graph (DAG)(可达性关系).正如马尼特拉所说,除了性能,它还大大简化了查询.
But对于这样的"祖先表"(可传递闭包),我建议使用view,这样更新是实时的和增量的,而不是按批处理作业(job)定期更新.在我对query language for graph sets: data modeling question的回答中提到的论文中有SQL代码(但我认为它需要稍微修改一下以适应特定的DBMS).具体来说,请看Maintaining Transitive Closure of Graphs in SQL(.ps-postscript).
Products-Categories relationship
马尼特拉的第一点也值得强调.
他说的是,产品和类别之间存在多对多关系.即:每个产品可以在一个或多个类别中,每个类别中可以有零个或多个产品.
给定关系变量(relvars)产品和类别,例如,这种关系可以表示为至少具有属性P#和C#的relvar PC,即外键关系中的产品和类别号(标识符)与相应的产品和类别号.
这是对类别层次 struct 管理的补充.当然,这只是一个设计草图.
On faceted browsing in SQL个
实现"分面浏览"的一个有用的概念是relational division,甚至relational comparisons(见链接页面底部).也就是说,将PC(产品类别)除以从用户(方面导航)中 Select 的(不断增长的)类别列表,一个人只能获得此类类别中的产品(当然,类别被认为是相互排斥的,否则 Select 两个类别一个人将获得零产品).
基于SQL的DBMS通常缺少这种运算符(除法和比较),因此我在下面给出一些有趣的文章来实现/讨论它们:
以此类推.
我不会在这里详细介绍,但是类别、层次 struct 和方面浏览之间的交互需要特别注意.
A digression on "flatness"个
我简单地看了一下Pras,Managing Hierarchical Data in MySQL链接的那篇文章,但在导言中的这几行之后我停止了阅读:
Introduction个
大多数用户在某个时候都有
为了理解为什么这种对关系平坦性的坚持是just nonsense,想象一个three dimensional Cartesian coordinate system中的立方体:它将由8个坐标(三元组)标识,比如P1(x1,y1,z1),P2(x2,y2,z2)...,P8(x8,y8,z8)[这里我们不关心这些坐标的约束,所以它们实际上代表一个立方体].
现在,我们将把这组坐标(点)放入一个关系变量中,并将这个变量命名为Points
.我们将Points
的关系值作为下表:
Points| x | y | z |
=======+====+====+====+
| x1 | y1 | z1 |
+----+----+----+
| x2 | y2 | z2 |
+----+----+----+
| .. | .. | .. |
| .. | .. | .. |
+----+----+----+
| x8 | y8 | z8 |
+----+----+----+
这个立方体是不是仅仅因为用表格的方式来表示就被"压扁"了?关系(值)和它的表格表示法是一样的吗?
关系变量假定n维离散空间中的点集为值,其中n是关系属性("列")的数量.对于n维离散空间来说,"扁平"意味着什么?就像我在上面写的那样,简直是胡说八道.
不要误会我的意思,SQL确实是一种设计糟糕的语言,基于SQL的DBMS充满了特性和缺点(NULL、冗余等),特别是糟糕的DBMS as-umb-store类型(没有引用约束、没有完整性约束,等等).但这与关系数据模型幻想中的局限性无关,相反:他们越远离它,结果就越糟糕.
具体地说,一旦您理解了关系数据模型,它在表示任何 struct (甚至是层次 struct 和图形)方面都不会有任何问题,正如我在上面提到的已发表论文的引用中所详细描述的那样.即使是SQL,如果您掩饰它的不足之处,也会错过更好的东西.
On the "The Nested Set Model"个
我浏览了一下睡觉的that article值,我对这种逻辑设计并不是特别感兴趣:它建议将两个不同的实体nodes和links混为一谈,这可能会造成尴尬.但我不想更彻底地分析这个设计,抱歉.
EDIT:斯蒂芬·埃格蒙特(Stephan Eggermont)在下面的 comments 中反对"The flat list model is a problem. It is an abstraction of the implementation that makes performance difficult to achieve. ...".
现在,我的观点是,确切地说,
- 这个"扁平列表模型"是一个fantasy:仅仅因为一个人将关系布局(表示)为表格("扁平列表")并不意味着关系就是"扁平列表"(一个"对象",它的表示不是一回事);
- 逻辑表示(关系)和物理存储详细信息(水平或垂直分解、压缩、索引(散列、b+树、r-树等)、群集、分区等)关系数据模型(RDM)的要点之一是将逻辑模型与"物理"模型解耦(对DBMS的用户和实现者都有好处);
- 性能是物理存储细节(实现)和逻辑表示的直接结果(Eggermont的 comments 是logical-physical confusion的classic 示例).
RDM模型不以任何方式约束实现;您可以随意实现元组和关系.关系是not necessarily个文件,元组是一个文件的not necessarily条记录.这样的通信是哑巴direct-image implementation.
不幸的是,基于SQL的DBMS实现are经常是愚蠢的直接映像实现,并且它们在各种场景中的性能都很差-OLAP/ETL产品就是为了弥补这些缺点而存在的.
这种情况正在慢慢改变.有一些商业和自由软件/开源实现最终避免了这个基本trap :
当然,not的要点是必须存在一个"最佳"的物理存储设计,但是任何物理存储设计都可以由基于关系代数/演算(SQL就是bad个例子)的declarative language抽象出来,或者更直接地基于逻辑编程语言(例如,Prolog-请参见我对"prolog to SQL converter"问题的回答).一个好的数据库管理系统应该是基于数据访问统计数据(和/或用户提示)在飞翔上更改物理存储设计.
最后,在埃格蒙特的 comments 中,声明"The relational model is getting squeeezed between the cloud and prevayler."是另一种胡说八道,但我不能在这里给出反驳,这个 comments 已经太长了.