在关系数据建模和文档数据建模之间挣扎
Struggling between relational data modeling and document data modeling
我目前正在为数据建模而苦苦挣扎。在一些table中有超过100万条记录,通过GROUP BY
和COUNT
查询输出需要相当长的时间。所以我转向了 Couchbase,因为它支持视图和索引,我发现它们在查询数据时速度更快。
MySQL 中有一个很大的优势,我发现它非常有用。比如我在用户 table 中有一个用户和一些与这个用户相关的文章,还有许多其他用户对这篇文章的一些喜欢和评论。我通常会执行 JOIN,因此输出会给我包含用户名和个人资料图像的文章。输出还附有其他用户的详细信息,包括点赞和评论。因此,如果用户上传了新的个人资料图片或更改了他的电子邮件地址,我只需要更新用户 table.
中的列
在 Couchbase 中,我尝试创建文档,因为我将数据存储在 MySQL 中,此类文章文档的作者为 user_id
,评论文档的作者为 commenter_id
和 article_id
.现在我发现在启用限制和排序的情况下将它们加入视图或索引非常困难。所以我将用户的 profile_img
和 first_name
以及 last_name
复制到所有相关文档中。因此,当我加载文章文档时,它具有以下结构:
{
"article_id": 1234,
"text": "A good article",
"author_id": 1,
"first_name": "John",
"last_name": "Smith",
"profile_img": "0bf34ee0a.jpg",
"likes": [
{
"user_id": 1,
"first_name": "John",
"last_name": "Smith",
"profile_img": "0bf34ee0a.jpg"
},
{
"user_id": 2,
"first_name": "Paul",
"last_name": "Einstein",
"profile_img": "1789ab00ef.jpg"
}
]
"comments": [
{
"user_id": 1,
"first_name": "John",
"last_name": "Smith",
"text": "This is my article",
"profile_img": "0bf34ee0a.jpg"
},
{
"user_id": 2,
"first_name": "Paul",
"last_name": "Einstein",
"text": "i like it",
"profile_img": "1789ab00ef.jpg"
}
]
}
这确实节省了我的查询时间。 (否则我必须先查询文章,从文章和喜欢和评论中提取用户 ID,然后根据用户 ID 查询用户,将用户详细信息附加到文章和喜欢和评论中)。但这给我带来了另一个问题,如果用户更新他的个人资料图片,我必须抓取所有文章以找到他的 user_id
并更新 profile_img
字段。
有人知道我应该走哪条路吗?
阅读 this blog post 看看这是否回答了您的一些问题,如果没有,让我们继续讨论。
对于上面的对象模型,将“赞”和“评论”嵌入到用户文档中可能不是一个很长的主意 运行。是的,您可以使用子文档 API 到 read/write JSON 的一部分,您可以通过复制等方式在后端支付费用,但也可以在随着时间的流逝,文档大小。很可能您最好将每个用户的喜欢和评论放入他们自己的文档中。即使那样,您也必须满足于该文档为活跃用户增长的方式。
还有一件事。评论和点赞应该与被评论的内容相关,还是与用户的评论和点赞相关?可能值得将每个评论放在自己的对象中,并使用标准化的键模式来识别它,然后再创建另一个对象,该对象是对原始想法进行评论的所有对象 ID 的数组。喜欢的人也一样。你做什么取决于你将如何访问数据,特别是你对应用程序的性能和扩展需求。我的意思是,您为每秒仅执行 500 次操作的系统做出的架构设计决策可能与每秒执行 200,000 次的系统大不相同。与 RDBMS 相比,在 NoSQL 数据库中访问数据的主要区别在于,使用 NoSQL 可以更容易地准确建模应用程序和用户将如何使用数据,而在 RDBMS 中,您必须多次建模最适合数据库引擎以及它将如何存储和使用数据。
此外,请阅读 this post and this one。请记住,关于高写入率的后者 post 是在 Couchbase 中的 N1QL 之前编写的,但无论如何它应该给你一些思考的想法。
这是数组索引的分类案例。
参见:
http://blog.couchbase.com/2016/march/making-the-most-of-your-arrays...-with-array-indexing
http://blog.couchbase.com/2016/may/1.making-most-of-your-arrays..-with-covering-array-indexes-and-more
我目前正在为数据建模而苦苦挣扎。在一些table中有超过100万条记录,通过GROUP BY
和COUNT
查询输出需要相当长的时间。所以我转向了 Couchbase,因为它支持视图和索引,我发现它们在查询数据时速度更快。
MySQL 中有一个很大的优势,我发现它非常有用。比如我在用户 table 中有一个用户和一些与这个用户相关的文章,还有许多其他用户对这篇文章的一些喜欢和评论。我通常会执行 JOIN,因此输出会给我包含用户名和个人资料图像的文章。输出还附有其他用户的详细信息,包括点赞和评论。因此,如果用户上传了新的个人资料图片或更改了他的电子邮件地址,我只需要更新用户 table.
中的列在 Couchbase 中,我尝试创建文档,因为我将数据存储在 MySQL 中,此类文章文档的作者为 user_id
,评论文档的作者为 commenter_id
和 article_id
.现在我发现在启用限制和排序的情况下将它们加入视图或索引非常困难。所以我将用户的 profile_img
和 first_name
以及 last_name
复制到所有相关文档中。因此,当我加载文章文档时,它具有以下结构:
{
"article_id": 1234,
"text": "A good article",
"author_id": 1,
"first_name": "John",
"last_name": "Smith",
"profile_img": "0bf34ee0a.jpg",
"likes": [
{
"user_id": 1,
"first_name": "John",
"last_name": "Smith",
"profile_img": "0bf34ee0a.jpg"
},
{
"user_id": 2,
"first_name": "Paul",
"last_name": "Einstein",
"profile_img": "1789ab00ef.jpg"
}
]
"comments": [
{
"user_id": 1,
"first_name": "John",
"last_name": "Smith",
"text": "This is my article",
"profile_img": "0bf34ee0a.jpg"
},
{
"user_id": 2,
"first_name": "Paul",
"last_name": "Einstein",
"text": "i like it",
"profile_img": "1789ab00ef.jpg"
}
]
}
这确实节省了我的查询时间。 (否则我必须先查询文章,从文章和喜欢和评论中提取用户 ID,然后根据用户 ID 查询用户,将用户详细信息附加到文章和喜欢和评论中)。但这给我带来了另一个问题,如果用户更新他的个人资料图片,我必须抓取所有文章以找到他的 user_id
并更新 profile_img
字段。
有人知道我应该走哪条路吗?
阅读 this blog post 看看这是否回答了您的一些问题,如果没有,让我们继续讨论。
对于上面的对象模型,将“赞”和“评论”嵌入到用户文档中可能不是一个很长的主意 运行。是的,您可以使用子文档 API 到 read/write JSON 的一部分,您可以通过复制等方式在后端支付费用,但也可以在随着时间的流逝,文档大小。很可能您最好将每个用户的喜欢和评论放入他们自己的文档中。即使那样,您也必须满足于该文档为活跃用户增长的方式。
还有一件事。评论和点赞应该与被评论的内容相关,还是与用户的评论和点赞相关?可能值得将每个评论放在自己的对象中,并使用标准化的键模式来识别它,然后再创建另一个对象,该对象是对原始想法进行评论的所有对象 ID 的数组。喜欢的人也一样。你做什么取决于你将如何访问数据,特别是你对应用程序的性能和扩展需求。我的意思是,您为每秒仅执行 500 次操作的系统做出的架构设计决策可能与每秒执行 200,000 次的系统大不相同。与 RDBMS 相比,在 NoSQL 数据库中访问数据的主要区别在于,使用 NoSQL 可以更容易地准确建模应用程序和用户将如何使用数据,而在 RDBMS 中,您必须多次建模最适合数据库引擎以及它将如何存储和使用数据。
此外,请阅读 this post and this one。请记住,关于高写入率的后者 post 是在 Couchbase 中的 N1QL 之前编写的,但无论如何它应该给你一些思考的想法。
这是数组索引的分类案例。
参见:
http://blog.couchbase.com/2016/march/making-the-most-of-your-arrays...-with-array-indexing http://blog.couchbase.com/2016/may/1.making-most-of-your-arrays..-with-covering-array-indexes-and-more