假设我正在编写一个日志分析应用程序。主域对象将是一个 LogEntry。此外。应用程序的用户定义了一个 LogTopic,它描述了他们感兴趣的日志条目。当应用程序接收到日志条目时,它会将它们添加到 couchDB,并根据系统中的所有 LogTopics 检查它们是否符合主题中的条件. 如果是,则系统应记录该条目与主题匹配。因此,LogEntries 和 LogTopics 之间存在多对多的关系。
如果我将其存储在 RDBMS 中,我会执行以下操作:
CREATE TABLE Entry (
id int,
...
)
CREATE TABLE Topic (
id int,
...
)
CREATE TABLE TopicEntryMap (
entry_id int,
topic_id int
)
使用 CouchDB,我首先尝试只有两种文档类型。我有一个 LogEntry 类型,看起来像这样:
{
'type': 'LogEntry',
'severity': 'DEBUG',
...
}
我会有一个 LogTopic 类型,看起来像这样:
{
'type': 'LogTopic',
'matching_entries': ['log_entry_1','log_entry_12','log_entry_34',....],
...
}
您可以看到我通过matching_entries
在每个 LogTopic 文档中使用一个字段来存储 LogEntry 文档 ID 列表来表示关系。这在一定程度上可以正常工作,但是当多个客户端都尝试将匹配条目添加到主题时,我遇到了问题。两者都尝试乐观更新,一个失败了。我现在使用的解决方案是从本质上重现 RDBMS 方法,并添加第三种文档类型,例如:
{
'type':'LogTopicToLogEntryMap',
'topic_id':'topic_12',
'entry_id':'entry_15'
}
这有效,并且克服了并发更新问题,但我有两个保留意见:
- 我担心我只是在使用这种方法,因为这是我在关系数据库中所做的。我想知道是否有更类似于 couchDB(放松?)的解决方案。
- 我的视图无法再一次调用中检索特定主题的所有条目。我以前的解决方案允许这样做(如果我使用了 include_docs 参数)。
有人对我有更好的解决方案吗?如果我也发布我正在使用的视图会有帮助吗?