【问题标题】:Modelling NoSQL database (when converting from SQL database)建模 NoSQL 数据库(从 SQL 数据库转换时)
【发布时间】:2013-04-30 08:04:24
【问题描述】:

我有一个想要转换为 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 中使用引用?

【问题讨论】:

  • "NoSQL" 不是数据库 - 它是不使用 SQL 的数据库的通用术语。这包括键值存储、文档数据库、图形数据库等。如何建模数据取决于您的用例和您使用的数据库中可用的功能。
  • 我写过我正在使用 RavenDB,它是一个文档数据库

标签: sql nosql ravendb


【解决方案1】:

Raven 等文档数据库不是关系数据库。您不能先构建数据库模型,然后再决定各种有趣的查询方式。相反,您应该首先确定要支持的访问模式,然后相应地设计文档架构。

因此,为了回答您的问题,我们真正需要知道的是您打算如何使用这些数据。例如,显示按时间排序的所有跟踪与显示与特定部署或应用程序相关联的跟踪明显不同。这些要求中的每一个都将决定不同的设计,同时支持它们。

这本身对您来说可能是有用的信息 (?),但我怀疑您想要更具体的答案 :) 所以请添加一些有关您的预期用途的其他详细信息。

在决定策略时有一些“做”和“不做”:

DO:针对常见用例进行优化。通常有 20/80 的细分,其中 20% 的 UX 驱动 80% 的负载——Web 应用程序的主页/登录页面就是一个典型的例子。首要任务是确保这些尽可能高效。确保您的数据模型允许 A)在单个 IO 请求中加载它们或 B)缓存友好

不要:不要落入可怕的“N+1”陷阱。当您的数据模型强制您进行 N 次调用以加载 N 个实体时,就会出现这种模式,通常在此之前还有一个额外的调用以获取 N 个 ID 的列表。这是一个杀手,尤其是和#3一起......

DO:始终限制(通过 UX)您愿意获取的数据量。如果用户有 3729 个 cmets,您显然不会一次全部获取它们。即使从数据库的角度来看它是可行的,用户体验也会很糟糕。这就是搜索引擎使用“下一个 20 个结果”范式的原因。因此,您可以(例如)将数据库结构与 UX 对齐,并将 cmets 保存为 20 个块。然后每次页面刷新都涉及一个 DB get。

DO:平衡读取和写入要求。某些类型的系统是读取繁重的,您可以假设每次写入都会有很多读取(StackOverflow 就是一个很好的例子)。因此,为了提高读取性能,提高写入成本是有意义的。例如,数据非规范化和复制。其他系统均衡甚至写入繁重,需要其他方法

DO:利用时间维度来发挥你的优势。 Twitter 是一个典型的例子:99.99% 的推文在第一个小时/天/周/任何时间之后将永远不会被访问。这会在您的数据架构中开启各种有趣的优化可能性。

这只是冰山一角。我建议阅读一些基于列的 NoSQL 系统(例如 Cassandra)

【讨论】:

  • 感谢您的友好回答 :) 首先,写作比阅读要多。其次,我必须主要通过日期时间快速获取大量数据(我知道我没有将它写在我的文档中)。第三,通过我拥有的几个键值id(例如:MessageId =“aaa22kk”,我想获取该消息的数据)。我知道我应该为这类读取操作设置索引,但我仍然不知道我应该如何设计我的数据库模型。
  • 这是一种日志文档,其中有大量的写入内容和一些读取内容..
【解决方案2】:

如何为文档建模主要取决于您的应用程序及其域。从那里,可以通过了解您的数据访问模式来完善文档模型。

盲目地尝试将关系数据模型映射到非关系数据模型可能不是一个好主意。

更新:我认为马特在这里得到了我的主要观点。我想说的是,没有规定的方法(无论如何我都知道)可以在不理解和考虑应用程序的领域。让我在这里详细说明一下...

查看您的 SQL 架构后,我不知道除了似乎连接应用程序和部署的表之外还有什么跟踪。我也不知道您的应用程序通常如何查询数据。了解这一点会在您为文档建模时有所作为,就像它会对您为应用程序对象(或域对象)建模的方式产生影响一样。

因此,您的问题中建议的文档模型可能适用于您的应用程序,也可能不适用于您的应用程序。

【讨论】:

  • 所以你的意思是我应该使用我上面建议的 NoSQL 模型?
  • 我认为他的意思是你应该采取以领域为中心的方法,而不是以数据为中心的方法。
猜你喜欢
  • 1970-01-01
  • 2021-12-28
  • 2021-05-17
  • 1970-01-01
  • 2022-11-14
  • 1970-01-01
  • 1970-01-01
  • 2013-05-14
  • 1970-01-01
相关资源
最近更新 更多