【问题标题】:how to design the query for non-sql database如何设计非sql数据库的查询
【发布时间】:2010-05-04 03:11:03
【问题描述】:

谁能给一些非sql数据库查询接口设计模式的参考?

对于基于sql的数据库,可以通过组合查询token来实现查询。 但是对于非sql,如何设计查询,因为查询可能很复杂。

编辑:

我在使用db4o存储一些对象,可能需要根据某个Id,时间范围,或者它们的组合来查询。

如何设计查询方式?

public IEnumerable<Foo> GetFoos(int id);
public IEnumerable<Foo> GetFoos(int id, TimeRange range);

构建大量重载似乎很愚蠢,如果需要新查询怎么办?

【问题讨论】:

  • “查询”一词在您的问题中使用得非常松散。请更具体地说明您所指的查询类型和“非 sql 数据库”。
  • @Benny,嗨,Benny,我也是 Benny。 :)
  • 嗯,您是否考虑在这里使用存储库模式?这就是“查询”和“重载”的意思吗?

标签: nosql db4o


【解决方案1】:

在 C# 中,绝对最好使用 Linq。原生查询经常无法优化,这将导致 db4o 水合所有对象并实际上调用实例化对象上的 lambda 表达式。这只不过是对 linq-to-objects 的自动回退,相比之下它非常慢。仅仅为 6 万个典型物体补水就需要几秒钟。

提示:决不能调用 lambda 表达式上的断点。

即使使用Db4oTool.exe 优化原生查询作为构建后步骤,在域对象中使用属性或自动属性时,即使是简单的查询也会导致问题。

linq 提供者总是给我最好的结果。它具有最简洁的语法并且它的优化工作。此外,linq 提供程序非常完整,只是它可能会比您预期的更频繁地回退到 linq-to-objects。

此外,linq 提供程序在项目文件夹中具有某些 dll 也很重要。这些取决于版本。如果您是using builds >= 14204,请确保Mono.Reflection.dll 在您的应用文件夹中。

对于旧版本,必须具备以下所有条件:

Db4obects.Db4o.Instrumentation.dll
Db4objects.Db4o.NativeQueries.dll
Mono.Cecil.dll
Cecil.FlowAnalysis.dll

请注意,对于本机查询,即使在较新的版本中,这些仍然是必需的。

【讨论】:

  • 嗨。我是 db4o 核心团队的成员。我很好奇,在使用具有简单属性的本机查询时,您面临哪些问题?如果该属性确实是一个简单的“吸气剂”,那么您应该没有问题。无论如何,恕我直言,LINQ 是 .Net 3.5 中查询的最佳选择。关于 LINQ,从 build 14204 db4o LINQ 提供程序(用于桌面框架)开始,仅依赖于 Mono.Reflection.dll(和 Db4objects.Db4o.dll :))
  • 嘿 Adriano,感谢您的评论并同意 LINQ 是 .NET 3.5 的最佳选择 =) 我认为 German 将我与 DateTime 相关的一个问题转发给了您。至于查询优化:即使对于简单的情况(自动属性),查询优化也会失败。查询比使用 linq 慢几个数量级。 Linq 显然使用 BTree(大约 log n),而 NQ 充其量是线性的。尝试使用就地 NQ 和 Db4oTool IL 编织。
【解决方案2】:

看起来 db4o 使用自己的查询,Versant 称之为 Native Queries(注意:.Net 和 Java native queries 有单独的语法)。比如:

IObjectContainer container = Database();
container.Query(delegate(Foo foo) {
    return foo.id == id;
});

container.Query(delegate(Foo foo) {
        return foo.id == id;
    },
    delegate(Foo foo) {
        return range.IsIn(foo.time);
    });

【讨论】:

  • 所以,基本上,我应该像这样定义查询方法:GetFoos(Predict predicator),对吧?
  • GetFoos 可以采用bool delegate(Foo)Database.Query 也支持。
  • Query() 方法在哪个版本中接受第二个委托?第二个代表应该做什么?为什么要显式声明委托而不是使用 lambda 方法?为什么不使用 linq? range.IsIn() 绝对不能优化,所以在任何情况下都不应该在查询中使用它。
  • @mnemosyn:所有优点。 Query() 采用两个代表直接来自文档,使用显式代表也是如此。由于 OP 没有指定他所针对的 .Net 版本,所以我坚持使用 2.0。 .Net 2 下 db4o 是否支持 LINQ?文档 (db4o.com/s/linqdb.aspx) 仅提及 3.5。
  • @outis: 不。由于 .Net 3.5 的平台中引入了 LINQ 支持,而较新的 db4o 不能在旧版本中支持它(我知道它可能可以使用黑客,但恕我直言,这不值得麻烦)。
猜你喜欢
  • 2020-05-14
  • 2011-01-02
  • 2014-12-29
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-02-11
相关资源
最近更新 更多