我有一个简单的CMS系统,它有一个简单的树层次结构:
我们的页面A到E具有以下层次结构: A - > B - > C - > D - > ë
所有页面都是同一个类,并且具有父子关系。
现在,假设我有一个我希望在页面中继承的属性。我们说A是红色的: A(红色) - > B - > C - > D - > ë
在这种情况下,B到E将继承“红色”。
或更复杂的情况: A(红色) - > B - > C(蓝色) - > D - > ë
B会继承红色,而D / E都是蓝色。
解决这类问题的最佳方法是什么?我有一个树形结构,有超过6,000片叶子,其中约有100片叶子具有遗传特性。那些100左右的叶子的属性保存在数据库中。对于没有显式属性的叶子,我查找祖先并使用memcached来保存属性。然后有非常复杂的算法来处理那些缓存到期。这非常令人费解,我想重构一个更清洁的解决方案/数据结构。
有人有什么想法吗?
谢谢!
答案 0 :(得分:2)
我假设你想要保存所有这些可继承属性的内存(或者你可能有 lot ),否则这可以通过虚拟属性轻松解决。
如果您需要稀疏的可继承属性,比如说您正在建模HTML DOM属性或CSS属性的传播方式,则需要:
当然,您可以在此基础上添加更多功能。这与Windows Presentation Foundation通过DependencyProperty解决此问题的方式类似。
如果您的问题是避免读取数据库以使树向上(即加载父项以查找继承的属性),则需要对父值执行某种缓存。或者,当您从数据库加载叶子时,您可以加载其所有父项并在内存中创建主合并属性字典。
如果要避免多个数据库查找以查找每个父节点,一个技巧是将每个节点的路径编码为文本字段,例如: “1.2.1.3.4”对于第6级的叶子。然后,仅加载具有开始子串的路径的节点。然后,您可以在一个SQL查询中获取整个父路径。
答案 1 :(得分:2)
有一种数据模型可以让您完美地表达这种信息,即RDF / RDFS。 RDF是W3C标准,用于根据三元组(主题,谓词,对象)和URI对数据建模;除其他外,RDFS允许您描述类层次结构和属性层次结构。好消息是,有许多库可以帮助您创建和查询此类数据。
例如,如果我想说某个特定文档Lion
属于班级Animal
且programmer
属于班级Geek
,我可以说:
doc:lion rdf:type class:mamal .
doc:programmer rdf:type class:Geek .
现在我可以宣布一个类的层次结构,并说每个mamal都是动物,每个动物都是生物。
class:mamal rdfs:subClassOf class:animal .
class:animal rdfs:subClassOf class:LivingThing .
而且,每个极客都是人,每个人都是生物:
class:geek rdfs:subClassOf class:human .
class:human rdfs:subClassOf class:LivingThing .
有一种类似于SQL
的语言,称为SPARQL来查询此类数据,例如,如果我发出查询:
SELECT * WHERE {
?doc rdf:type class:LivingThing .
}
其中?doc
是一个将class:LivingThing
的事物类型绑定的变量。我会得到这个查询doc:lion
和doc:programmer
的结果,因为数据库技术将遵循RDFS的语义,因此通过计算类的闭包,它将知道doc:lion
和{{ 1}}是doc:programmer
。
以同样的方式查询:
class:LivingThing
请告诉我SELECT * WHERE {
doc:lion rdf:type ?class .
}
doc:lion
rdf:type
class:mamal
和class:animal
。{/ p>
就像我刚才解释的那样,使用RDFS,您可以创建属性的层次结构,并说:
class:LivingThing
我们可以说,doc:programmer doc:studies doc:computerscience .
doc:lion doc:instint doc:hunting .
和doc:skill
属性都是doc:instint
的子属性:
doc:knows
使用查询:
doc:studies rdfs:subPropertyOf doc:knows .
doc:instint rdfs:subPropertyOf doc:knows .
我们会让狮子知道如何打猎,程序员也知道计算机科学。
大多数RDF / RDFS数据库可以轻松处理您在问题中提到的元素数量,并且有很多选择可以开始。如果您是Java人员,可以查看Jena,还有.Net lije this one或Python RDFLIB的框架
但最重要的是,请查看CMS的文档,因为可能有插件将元数据导出为RDF。例如,Drupal在这种情况下非常先进(见http://drupal.org/project/rdf
)