我目前正在从RDBMS过渡到NoSQL解决方案,更具体地说是MongoDB。考虑我的数据库中的以下表格(原始解决方案要复杂得多,但我包含了这个,所以你有一个想法):
此表中的键是GUID,但它们是自定义生成的。例如:
现在,假设我想将此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
}
我选择此建模策略的原因如下:当前项目包括使用ORM和RDBMS的整个Web服务,以及或多或少将数据库对象映射到客户端视图对象的客户端。因此,尽可能保留Ids / PK的名称是非常必要的。我决定让MongoDB在内部使用ObjectId(用于CRUD操作)是最好的,因为它们不会导致性能开销,并且使用自定义GUID,因此它们与我的其余代码兼容。这样,必须进行最小的更改,MongoDB很高兴,我很高兴,因为在外部,我可以根据我的GUID PK查询结果,这些结果将始终是唯一的。 在MongoDB中,我的PK GUID存储为唯一字符串,我想我不必担心服务器端的GUID开销:GUID是由我的C#应用程序创建的。
但是,我对性能有疑问,现在每个文档/集合至少有2个索引,并且不知道它在性能方面有多昂贵。
对我的问题有更好的方法,还是我应该坚持现有的解决方案?
亲切的问候。
答案 0 :(得分:0)
我现在每个文档/集合至少有2个索引,并且不知道它在性能方面有多昂贵。
索引会降低插入和更新的性能,并且您没有发布有关写入操作或设置频率的信息。没有测量就无法给出明确的答案。
然后,如果您正在使用网络应用程序,我会说,对您的客户来说,纯粹的网络延迟将比数据之间的差异高几个数量级 ,2或3个索引,因为所有这些操作主要都会打到RAM。
写入磁盘的代价是多少,而不是内存中BTree的重组。当然,拥有越来越多的索引会增加插入的可能性,从而导致必须在磁盘上进行代价高昂的索引树重构,但这也取决于密钥本身的结构。
如果有的话,我担心错误的缓存一致性和GUID的时间局部性:如果你的数据非常时间本地(如日志),那么GUID可能会受到伤害(字符串开头的高抖动) ),因为更新将更有可能重新排列整个子树,典型的时间范围查询将抓住整个树中杂乱的项目。但由于这似乎是关于用户和用户配置文件,这样的查询可能没有多大意义。