我有一个我想要转换为NoSQL的SQL数据库(目前我正在使用RavenDB)
以下是我的表格:
追踪:
ID (PK, bigint, not null)
DeploymentID (FK, int, not null)
AppCode (int, not null)
部署:
DeploymentID (PK, int, not null)
DeploymentVersion (varchar(10), not null)
DeploymentName (nvarchar(max), not null)
应用
AppID (PK, int, not null)
AppName (nvarchar(max), not null)
目前我的表中有这些行:
跟踪:
ID: 1 , DeploymentID: 1, AppCode: 1
ID: 2 , DeploymentID: 1, AppCode: 2
ID: 3 , DeploymentID: 1, AppCode: 3
ID: 3 , DeploymentID: 2, AppCode: 1
部署:
DeploymentID: 1 , DeploymentVersion: 1.0, DeploymentName: "Test1"
DeploymentID: 2 , DeploymentVersion: 1.0, DeploymentName: "Test2"
应用:
AppID: 1 , AppName: "Test1"
AppID: 2 , AppName: "Test2"
AppID: 3 , AppName: "Test3"
我的问题是:我该如何构建我的NoSQL文档模型?
看起来应该是这样的:
trace/1
{
"Deployment": [ { "DeploymentVersion": "1.0", "DeploymentName": "Test1" } ],
"Application": "Test1"
}
trace/2
{
"Deployment": [ { "DeploymentVersion": "1.0", "DeploymentName": "Test1" } ],
"Application": "Test2"
}
trace/3
{
"Deployment": [ { "DeploymentVersion": "1.0", "DeploymentName": "Test1" } ],
"Application": "Test3"
}
trace/4
{
"Deployment": [ { "DeploymentVersion": "1.0", "DeploymentName": "Test2" } ],
"Application": "Test1"
}
如果部署1发生变化怎么办?我应该查看每个文档并更改数据吗?
我什么时候应该在NoSQL中使用引用?
答案 0 :(得分:7)
Raven等文档数据库不是关系数据库。您不能先构建数据库模型,然后再决定查询它的各种有趣方法。相反,您应首先确定要支持的访问模式,然后相应地设计文档模式。
因此,为了回答您的问题,我们真正需要知道的是您打算如何使用这些数据。例如,显示按时间排序的所有跟踪与显示与特定部署或应用程序关联的跟踪明显不同。这些要求中的每一个都将规定不同的设计,并支持它们。
这本身对您来说可能是有用的信息(?),但我怀疑您需要更具体的答案:)所以请在预期用途上添加一些其他详细信息。
在决定策略时,有一些“做”和“不做”:
DO:针对常见用例进行优化。通常有20/80的细分,其中20%的UX驱动80%的负载 - 网络应用的主页/登陆页面是一个典型的例子。首要任务是确保这些尽可能高效。确保您的数据模型允许A)在单个IO请求中加载它们或B)是缓存友好的
不要:不要陷入可怕的“N + 1”陷阱。当您的数据模型强制您进行N次调用以加载N个实体时,通常会先执行额外调用以获取N个ID列表,从而出现此模式。这是一个杀手,特别是与#3 ... 一起DO:始终限制(通过UX)您愿意获取的数据量。如果用户有3729条评论,您显然不会立即获取所有评论。即使从数据库的角度看它是可行的,用户体验也会很糟糕。这就是搜索引擎使用“未来20个结果”范例的原因。因此,您可以(例如)将数据库结构与UX对齐,并将注释保存为20个块。然后每个页面刷新涉及单个数据库获取。
DO:平衡读写要求。某些类型的系统读取很重,您可以假设每次写入都会有很多读取(StackOverflow就是一个很好的例子)。因此,为了获得读取性能的好处,使写入更加昂贵是有意义的。例如,数据非规范化和复制。其他系统均衡均衡,甚至写得很重,需要其他方法
DO:使用TIME的维度。 Twitter是一个典型的例子:99.99%的推文在第一小时/每天/每周/之后永远不会被访问。这将在您的数据模式中打开各种有趣的优化可能性。
这只是冰山一角。我建议稍微阅读基于列的NoSQL系统(如Cassandra)
答案 1 :(得分:1)
您对文档建模的方式主要取决于您的应用程序及其域名。从那里,可以通过了解您的数据访问模式来改进文档模型。
盲目地尝试将关系数据模型映射到非关系数据模型可能不是一个好主意。
更新:我认为马特在这里得到了我的观点。我想说的是,没有规定的方法(我知道无论如何)将关系数据模型(如规范化的SQL模式)转换为非关系数据模型(如文档模型)而不理解和考虑应用程序的域。让我在这里详细说明......
在查看了您的SQL模式之后,除了看似加入应用程序和部署的表之外,我不知道跟踪是什么。我也不知道您的应用程序通常如何查询数据。在对文档建模时,了解一点这一点会有所不同,就像它对应用程序对象(或域对象)的建模方式有所不同。
因此,您的问题中建议的文档模型可能适用于您的申请,也可能不适用。