her*_*son 45 primary-key-design mongodb composite-primary-key
我正在尝试确定在mongo db中处理复合主键的最佳方法.与该系统中的数据交互的主要密钥由2个uuids组成.uuids的组合保证是独特的,但是没有个体uuids.
我看到了几种管理方法:
使用一个对象作为由2个值组成的主键(如此处所示)
使用标准的自动生成的mongo对象id作为主键,将我的密钥存储在两个单独的字段中,然后在这两个字段上创建一个复合索引
使主键成为2个uuids的哈希值
我目前还没有意识到的其他一些很棒的解决方案
这些方法的性能影响是什么?
对于选项1,由于具有非顺序键,我担心插入性能.我知道这可以扼杀传统的RDBMS系统,我已经看到迹象表明在MongoDB中也是如此.
对于选项2,拥有一个永远不会被系统使用的主键似乎有点奇怪.此外,似乎查询性能可能不如选项1中的好.在传统的RDBMS中,聚簇索引提供最佳查询结果.MongoDB中有多相关?
对于选项3,这将创建一个单个id字段,但同样在插入时它不会是顺序的.这种方法还有其他优点/缺点吗?
对于选项4,那么......选项4是什么?
此外,还有一些讨论可能在将来的某个时候使用CouchDB而不是MongoDB.使用CouchDB会提出不同的解决方案吗?
更多信息:关于这个问题的一些背景知识可以在这里找到
Asy*_*sky 39
你应该选择1.
主要原因是你说你担心性能 - 使用始终存在的_id索引并且已经唯一将允许你节省必须维护第二个唯一索引.
对于选项1,我担心插入性能会影响非顺序键.我知道这可以扼杀传统的RDBMS系统,我已经看到迹象表明在MongoDB中也是如此.
你的其他选择不能避免这个问题,他们只是将它从_id索引转移到辅助唯一索引 - 但现在你有两个索引,一旦是正确平衡的,另一个是随机访问.
只有一个原因可以对选项1提出质疑,即如果您计划只通过一个UUID或其他UUID值来访问文档.只要您始终提供这两个值并且(这部分非常重要)您总是在所有查询中以相同的方式对它们进行排序,那么_id索引将有效地满足其全部目的.
作为详细解释为什么你必须确保总是以相同的方式对两个UUID值进行排序,当比较子文档{ a:1, b:2 }
不等于{ b:2, a:1 }
- 你可以有一个集合,其中两个文档具有_id的那些值.因此,如果您首先将_id与字段存储在一起,那么您必须始终在所有文档和查询中保留该顺序.
另一个警告是索引_id:1
将可用于查询:
db.collection.find({_id:{a:1,b:2}})
Run Code Online (Sandbox Code Playgroud)
但它不能用于查询
db.collection.find({"_id.a":1, "_id.b":2})
Run Code Online (Sandbox Code Playgroud)
我会选择2,这就是为什么
我会选择选项 2。您仍然可以创建一个处理两个 UUID 字段的索引,并且性能应该与复合主键相同,只是它更容易使用。
另外,根据我的经验,我从来没有后悔给某些东西一个唯一的 ID,即使它不是严格要求的。但也许这是一个不受欢迎的观点。