您有没有想过 Instagram、Twitter、Facebook 或任何社交媒体平台如何跟踪谁喜欢您的帖子?让我们在这篇文章中弄清楚!
目录
- 1.序言
- 2.让我们研究一下
- 3.研究数据类型
- 4.正确建模
- 5.最后的考虑
1.序言
最近,我受邀在一个名为“CityJS”的活动中发言。但事情是这样的:我是 PHP 专家。我根本不做JS,但我接受了挑战。为了成功,我需要找到一个很好的例子来展示高度可扩展和低延迟的数据库是如何工作的。
所以,我问了我的一位同事举个例子。他告诉我要在任何平台内寻找高数字,例如计数器或类似的东西。那时我意识到任何类型的指标都适合这个例子。点赞、观点、评论、关注等都可以作为计数器进行查询。在本文中,您将找到我关于如何使用ScyllaDB 为这些数据建模的研究。
(更多优质教程:java567.com,搜"mysql")
2. 让我们研究一下
要事第一,对吧?在决定了我的演讲要涵盖的内容之后,我需要了解如何构建此数据模型。
我们需要一个posts表格,还有一个post_likes表格来关联每个帖子的点赞者。到目前为止,似乎足以计算我们的喜好。
我第一次打赌计算所有喜欢的查询是这样的:
好吧,如果我只是用
SELECT count(*) FROM social.post_likes它做一个查询就可以了,对吧?
好吧,它确实有效,但是当我在一篇文章中对几千个赞进行测试时,它的性能不如预期。随着点赞数的增加,查询变得越来越慢......
“但是 ScyllaDB 可以轻松处理数千行……为什么它的性能不佳?” 这可能就是您现在(或可能不是)的想法。
ScyllaDB——即使作为一个具有很酷功能的很酷的数据库——也不会解决糟糕的数据建模问题。我们需要考虑如何让事情变得更快。
3.研究数据类型
好的,让我们直接思考:数据需要存储,我们需要谁喜欢我们的帖子之间的关系,但我们不能用它来计数。那么,如果我integer在posts表中创建一个新行并每次递增/递减它呢?
好吧,这似乎是个好主意,但有一个问题:我们需要跟踪 posts 表上的每个更改,如果我们开始在那里插入或更新数据,我们可能会在我们的数据库中创建一堆无意义的记录.
使用 ScyllaDB,每次您需要更新某些内容时,您实际上都会创建新数据。
scylla@cqlsh:socials> INSERT INTO socials.posts (id, user_id, description, image_url, created_at, likes) VALUES (4d18bb8c-9c57-44fe-827a-4a2d65f331e5, 3edd5f1d-67e9-4a3e-af1a-9adbb41e2129, 'Such a cool event P99 Conf!', 'https://i.imgur.com/Xp8gi7t.jpg', '2023-04-23 15:02:49', 1);
scylla@cqlsh:socials> INSERT INTO socials.posts (id, user_id, description, image_url, created_at, likes) VALUES (4d18bb8c-9c57-44fe-827a-4a2d65f331e5, 3edd5f1d-67e9-4a3e-af1a-9adbb41e2129, 'Such a cool event P99 Conf!', 'https://i.imgur.com/Xp8gi7t.jpg', '2023-04-23 15:02:50', 2);
scylla@cqlsh:socials> INSERT INTO socials.posts (id, user_id, description, image_url, created_at, likes) VALUES (4d18bb8c-9c57-44fe-827a-4a2d65f331e5, 3edd5f1d-67e9-4a3e-af1a-9adbb41e2129, 'Such a cool event P99 Conf!', 'https://i.imgur.com/Xp8gi7t.jpg', '2023-04-23 15:02:51', 3);
scylla@cqlsh:socials> SELECT * from posts;
id | user_id | created_at | description | image_url | likes
--------------------------------------+--------------------------------------+---------------------------------+-----------------------------+---------------------------------+-------
4d18bb8c-9c57-44fe-827a-4a2d65f331e5 | 3edd5f1d-67e9-4a3e-af1a-9adbb41e2129 | 2023-04-23 15:02:48.000000+0000 | Such a cool event P99 Conf! | https://i.imgur.com/Xp8gi7t.jpg | 1
4d18bb8c-9c57-44fe-827a-4a2d65f331e5 | 3edd5f1d-67e9-4a3e-af1a-9adbb41e2129 | 2023-04-23 15:02:50.000000+0000 | Such a cool event P99 Conf! | https://i.imgur.com/Xp8gi7t.jpg | 2
4d18bb8c-9c57-44fe-827a-4a2d65f331e5 | 3edd5f1d-67e9-4a3e-af1a-9adbb41e2129 | 2023-04-23 15:02:51.000000+0000 | Such a cool event P99 Conf! | https://i.imgur.com/Xp8gi7t.jpg | 3
您将必须跟踪数据中发生的所有变化。因此,每次增加,都会多一行,除非您不更改集群键或不关心时间戳(一个非常愚蠢的想法)。
在那之后,我进入了ScyllaDB 文档,发现有一种类型叫做counter满足我们的需要并且也是ATOMIC!
好的,它符合我们的需求但不符合我们的数据建模。要使用这种类型,我们必须遵循一些规则,但让我们关注那些现在给我们带来麻烦的规则:
- 具有计数器列的表中唯一的其他列可以是主键的列(无法更新)。
- 不能包含其他类型的列。
- 您需要使用 UPDATE 查询来处理拥有计数器数据类型的表。
- 您只能增加或减少值,不允许设置特定值。
此限制通过不允许它们在同一操作中来保障正确处理计数器和非计数器更新。
所以,我们可以使用这个计数器,但不能用在 posts 表上……好吧,看来我们正在寻找一种方法来完成它。
4.正确建模
counter有了类型不应与表中的其他数据类型“混合”的信息,留给我们的唯一选择是创建一个新表并存储这种类型的数据。
所以,我创建了一个名为的新表post_analytics,它只包含counter类型。目前,让我们只处理喜欢,因为我们已经创建了多对多关系 (post_likes)。
这些接下来的查询是您可能会为我们创建的这个示例运行的查询:
## Social when you like a post
UPDATE socials.post_analytics SET likes = likes + 1 WHERE post_id = 4d18bb8c-9c57-44fe-827a-4a2d65f331e5;
INSERT INTO socials.post_likes (post_id, user_id, liked_at) VALUES (4d18bb8c-9c57-44fe-827a-4a2d65f331e5, 3edd5f1d-67e9-4a3e-af1a-9adbb41e2129, '2023-04-23 15:02:50');
# Social when you dislike a post
DELETE FROM socials.post_likes WHERE post_id = 4d18bb8c-9c57-44fe-827a-4a2d65f331e5 AND user_id = 3edd5f1d-67e9-4a3e-af1a-9adbb41e2129;
UPDATE socials.post_analytics SET likes = likes - 1 WHERE post_id = 4d18bb8c-9c57-44fe-827a-4a2d65f331e5;
现在您可能会有新的悬而未决的问题,例如:“所以每次我需要一个与某些数据相关的新计数器时,我都需要一个新表?” 好吧,这取决于您的用例。在社交媒体案例中,如果你想存储谁看到了帖子,你可能需要一个post_viewers包含 session_id 和其他一些东西的表。
拥有这些可以在没有连接的情况下完成的简单查询比拥有count(*)查询要快得多 。
5. 最后的考虑
我在 CityJS 阶段说了一堆使用 TS 的废话数据建模
我不仅通过研究数据建模的新方法而且还必须学习 TypeScript 来创建 CityJS 演示文稿和构建此用例,从而学到了很多东西。
由于一切对我来说都是全新的,我会尽我所能继续分享我的学习成果。请随时在评论中纠正我!讨论是学习新事物的最好方法。
不要忘记喜欢这篇文章!
(更多优质教程:java567.com,搜"mysql")