我目前正在从 RDBMS 过渡到 NoSQL 解决方案,更具体地说是 MongoDB。考虑我的数据库中的下表(原始解决方案要复杂得多,但我将其包括在内以便您有一个想法):
- 用户(PK_ID_User、名字、姓氏...);
- 用户配置文件:(PK_ID_UserProfile、ProfileName、FK_ID_User、...);
此表中的键是 GUID,但它们是自定义生成的。例如:
- UserGUID 将具有以下结构:US022d717e507f40a6b9551f11ebf2fcb4(因此,美国前缀和随机数), 而 UserProfile GUIDS 将采用以下格式:UP0025f5804a30483b9b769c5707b02af6(因此 UP 前缀和随机数)
现在,假设我想将此 RDBMS 数据模型转换为 NoSQL MongoDB。对于我的应用程序(使用 C# 驱动程序),MongoDB 中的所有文档属性都具有相同的名称非常重要。这对于 ID 字段也很重要:名称 PK_ID_User 和 PK_ID_UserProfile,包括 GUID,必须相同。
现在,MongoDB 使用标准的唯一索引属性 _id 来存储 ID。这个 _id 字段的名称当然不能更改,即使我确实需要我的应用程序保留列/属性名称。
因此,我为我的用户和用户配置文件提出了以下文档结构。请记住,对于这种情况,我选择使用引用数据建模而不是嵌入,原因多种多样,我不会在这里解释: 用户文档
{
_id: ObjectId, - indexed
PK_ID_User: custom GUID, - indexed, as it needs to be unique
FirstName: string,
...
}
UserProfile-document
{
_id: ObjectId - indexed
PK_ID_UserProfile: custom GUID, as explained above - indexed, as it needs to be unique,
...
}
这是 C# 类:
public class User
{
[BsonConstructor]
public User() { }
[BsonId] // the _id field
[BsonRepresentation(BsonType.ObjectId)]
public string Id { get; set; }
[BsonElement("PK_ID_User")]
public string PK_ID_User { get; set; }
//Other Mapper properties
}
我选择这种建模策略的原因如下:当前项目包含一个完整的 Web 服务,使用 ORM 和 RDBMS,以及一个或多或少将数据库对象映射到客户端 View 对象的客户端。因此,确实有必要尽可能多地保留 ID/PK 的名称。我决定最好让 MongoDB 在内部使用 ObjectId(用于 CRUD 操作),因为它们不会导致性能开销,并使用自定义 GUID,以便它们与我的其余代码兼容。这样,只需进行最少的更改,MongoDB 很高兴,我也很高兴,因为在外部,我可以根据始终唯一的 GUID PK 继续查询结果。 与在 MongoDB 中一样,我的 PK GUID 存储为唯一字符串,我想我不必担心服务器端的 GUID 开销:GUID 是由我的 C# 应用程序创建的。
但是,我对性能有疑问,我现在每个文档/集合至少有 2 个索引,并且不知道它在性能方面的成本有多大。
是否有更好的方法来解决我的问题,还是我应该坚持目前的解决方案?
亲切的问候。
最佳答案
I now always have a minimum of 2 indexes per document / collection, and have no idea how costly it is in terms of performance.
索引会降低插入和更新的性能,并且您没有发布有关写入操作频率或您的设置的信息。没有测量就不可能给出明确的答案。
然后,如果您使用的是 Web 应用程序,我想说您的客户端的纯粹网络延迟将比 1、2 或 3 之间的差异高几个数量级索引,因为所有这些操作大部分都会访问 RAM。
代价高昂的是写入磁盘,而不是在内存中重构 BTree。当然,拥有越来越多的索引会增加插入操作的可能性,从而导致必须对磁盘进行昂贵的索引树重组,但这也取决于键本身的结构。
如果有的话,我会担心 GUID 的缓存一致性和时间局部性不好:如果您的数据非常具有时间局部性(如日志),那么 GUID 可能会受到伤害(字符串开头的高抖动),因为更新更有可能重新排列整个子树,而典型的时间范围查询会抓取整个树中杂乱无章的项目。但由于这似乎与用户和用户个人资料有关,因此这样的查询可能没有多大意义。
关于c# - MongoDB数据建模——索引和PK,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28960272/