首先,用户界面:作为用户我讨厌以严格分级方式组织的目录中搜索产品。我从来不记得在什么子子子类别中有一个“异国情调”的产品,这迫使我浪费时间探索“有希望”的类别,只是为了发现它被归类为(对我来说,至少)奇怪的方式
实质上,分面搜索允许用户从他们喜欢的任何“facet”开始搜索您的目录,并让他们过滤选择搜索的其他方面的信息。请注意,与标签系统通常构想相反,没有什么可以阻止您分层组织这些方面的一些。
要快速了解哪一方面的搜索是关键,some demos有some demos要探索。
第二,应用逻辑:Manitra提出的也是一个很好的建议(据我所知),即分离不同关系中的树/图的节点和链接。他所谓的“祖先表”(这是一个更好的直观的名字)被称为transitive closure of a directed acyclic graph (DAG)(可达性关系)。除了性能,它简化了查询,正如马尼特拉所说。
但是我建议一个view这样的“祖先表”(传递关闭),以便更新是实时和增量的,而不是批处理作业的定期更新。在我在query language for graph sets: data modeling question的答案中提到的论文中有SQL代码(但是我认为需要对特定的DBMS进行一些调整)。特别是,看看Maintaining Transitive Closure of Graphs in SQL(.ps – postscript)。
产品分类关系
马尼特拉的第一点也值得强调。
他所说的是产品和类别之间存在着多对多的关系。即:每个产品可以在一个或多个类别中,并且在每个类别中可以有零个或更多个产品。
给定关系变量(relvars)产品和类别这种关系可以表示为例如具有至少属性P#和C#的相关PC,即与对应的产品和类别的外键关系中的产品和类别编号(标识符)数字。
这是对类别等级制度的管理的补充。当然这只是一个设计素描。
在SQL上进行多面浏览
实现“分面浏览”的一个有用的概念是relational division,甚至是relational comparisons(参见链接页面的底部)。即通过从用户(面导航)中选择的(不断增加的)类别列表分割PC(产品类别),只能获得这样的类别的产品(当然,类别被假定不是全部互斥,否则选择两个类别将获得零产品)。
基于SQL的DBMS通常缺少这个运算符(分割和比较),所以我给下面一些实现/讨论它们的有趣的文章:
等等…
我不会在这里详细介绍,类别层次和面浏览之间的互动需要特别注意。
对“平坦度”
Introduction
Most users at one time or another have
dealt with hierarchical data in a SQL
database and no doubt learned that the
management of hierarchical data is not
what a relational database is intended
for. The tables of a relational
database are not hierarchical (like
XML), but are simply a flat list.
Hierarchical data has a parent-child
relationship that is not naturally
represented in a relational database
table. …
为了理解为什么这种坚持关系的平坦性只是废话,想象一个three dimensional Cartesian coordinate system中的立方体:它将由8个坐标(三重点)识别,例如P1(x1,y1,z1),P2(x2,y2,z2), …,P8(x8,y8,z8)[这里我们不关心这些坐标的约束,因此它们代表真正的一个立方体]。
现在我们将把这些坐标坐标(point)放在一个关系变量中,我们将把这个变量命名为Points。我们将代表点的关系值如下表所示:
Points| x | y | z |
=======+====+====+====+
| x1 | y1 | z1 |
+----+----+----+
| x2 | y2 | z2 |
+----+----+----+
| .. | .. | .. |
| .. | .. | .. |
+----+----+----+
| x8 | y8 | z8 |
+----+----+----+
这个立方体是否被“扁平化”,只是以表格的方式代表它?关系(价值)与其表格表示相同吗?
关系变量假设为n维离散空间中的值集合,其中n是关系属性的数量(“列”)。对于一个n维的离散空间来说,这是什么意思?只是胡说八道,就像我上面写的那样。
不要误会,SQL是一种设计不善的语言,而且基于SQL的DBMSs充满了特殊的缺点(NULL,冗余,…),特别是坏的DBMS-as-哑店类型(无参照约束,无完整性约束,…)。但这与关系数据模型的幻想局限毫无关系,恰恰相反:更多的是他们转而离开,更糟糕的是结果。
特别地,关系数据模型,一旦你明白了,在表示任何结构,甚至层次结构和图形方面都不会有任何问题,正如我对上述发表的论文的详细描述。即使SQL可以,如果你掩饰它的缺陷,缺少一些更好的东西。
在“嵌套集模型”
我撇去了that article的其余部分,我并没有对这种逻辑设计留下深刻的印象:它建议将两个不同的实体,节点和链接混合成一个关系,这可能会导致尴尬。但是我并不倾向于更彻底地分析这个设计,对不起。
编辑:Stephan Eggermont反对,在下面的评论中,“平面列表模型是一个问题,这是实现的抽象,使得性能难以实现…”。
现在,我的观点就是这样:
>这个“平面榜模型”是一个幻想:只是因为一个表格(表示)关系是表(“平面列表”)并不意味着关系是“平面列表”(一个“对象”,它的表示不一样事情);
>逻辑表示(关系)和物理存储细节(水平或垂直分解,压缩,索引(散列,b树,r-tree,…),聚类,分割等)是不同的;关系数据模型(RDM)的一个要点是将逻辑与“物理”模型分离(对DBMS的用户和实现者都有优势);
>性能是物理存储细节(实现)的直接后果,而不是逻辑表示(Eggermont的评论是logical-physical confusion的典型例子)。
RDM模型不以任何方式约束实现;一个可以自由地实现元组和关系,因为一个人认为合适。关系不一定是文件,元组不一定是文件的记录。这种对应是一种愚蠢的直接图像实现。
不幸的是,基于SQL的DBMS实现通常是愚蠢的直接映像实现,并且它们在各种场景中遭受较差的性能 – OLAP/ETL产品存在以覆盖这些缺点。
这是慢慢变化的有商业和免费的软件/开源实现,最终避免了这个根本的陷阱:
当然,关键并不在于存在一个“最优”的物理存储设计,而是基于关系代数/结论(而SQL是一个不错的例子),不管物理存储设计可以被一个很好的声明性语言所抽象出来直接使用逻辑编程语言(例如Prolog,请参阅我的答案为“prolog to SQL converter”)。基于数据访问统计(和/或用户提示),良好的DBMS应该是即时更改物理存储设计。
最后,在Eggermont的评论中,“关系模型正在云和前辈之间”的声明是另一个废话,但我不能在这里作出反驳,这个评论已经太久了。