我一直在对 Nosql(尤其是 RavenDB)进行一些研究,但我仍然不确定处理以下问题的最佳方法:
我有两个简单的对象,“用户”和“事件”。一个用户可以输入多个事件,一个事件可以由多个用户输入——标准的多对多关系。我正在尝试摆脱关系数据库的思维模式!
以下是我想对数据库运行的查询/操作:
- 获取用户未输入的所有事件
- 获取用户输入的所有事件
- 非常频繁地更新所有事件(剩余空间等属性)(从各种外部数据源轮询的数据)。
- 删除过期的事件
所以根据我所读到的内容,我有几种选择:
<醇>This seems the most logical to me, but it feels rather 'relational database' approach?
Seems sensible, but wouldn't this make querying from both directions difficult?
非常感谢,
丹C
最佳答案
实际上,RavenDB 非常适合。为了正确地做到这一点,问问自己模型中的主要实体是什么?这些中的每一个都将是 RavenDB 中的一种文档类型。
因此在您的场景中,您将拥有 Event
和 User
。然后,Event
可以有一个 User
ID 列表,然后您可以轻松地对其进行索引和查询。有更多方法可以做到这一点,我实际上 discussed this in my blog some time in the past可能会出现一些进一步的考虑。
唯一重要的部分可能是用于回答诸如“用户未输入的所有事件”之类的查询的索引,但这也很容易完成:
public class Events_Registrations : AbstractIndexCreationTask<Event>
{
public Events_Registrations()
{
Map = events => from e in events
select new { EventId = e.Id, UserId = e.Registrations.SelectMany(x => x.UserId) });
}
}
一旦有了这样的索引,您就可以执行如下查询以获取指定用户未注册的所有事件:
var events = RavenSession.Advanced.LuceneQuery<Event, Events_Registrations>()
.Where("EventId:*")
.AndAlso()
.Not
.WhereEquals("UserId", userId).ToList();
然后处理过期事件等事情就很容易完成了。绝对不要对 User 对象中的事件数据进行反规范化,这会让你的生活变得一团糟。
虽然缺少一些数据 - 例如每个事件允许多少注册。如果太多,您可能希望将其从实际的 Event
对象中分离出来,或者恢复为您提到的 Booking 对象。我在我的书 RavenDB in Action 中对此进行了详细讨论(我知道这是无耻的插件,但在这里实际讨论它实在是太长了)。
关于nosql - NoSql (RavenDB) 的多对多设计,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20265056/