Mysql 社交应用程序的数据库设计和优化考虑

Mysql 社交应用程序的数据库设计和优化考虑,mysql,database,database-design,query-optimization,scalability,Mysql,Database,Database Design,Query Optimization,Scalability,通常的情况。我有一个简单的应用程序,可以让人们上传照片和跟踪其他人。因此,每个用户都会有类似“墙”或“活动提要”的东西,在那里他或她可以看到朋友(他或她关注的人)上传的最新照片 大多数功能都很容易实现。然而,当涉及到这个历史活动提要时,由于纯粹的性能原因,事情很容易变得一团糟 我在这里遇到了以下困境: 我可以很容易地将活动提要设计为数据库的规范化部分,这将节省我的编写周期,但在为每个用户选择这些结果时会大大增加复杂性(对于在特定时间段内上传的每张照片,请选择一个特定的数字,我正在跟踪其上传者/对

通常的情况。我有一个简单的应用程序,可以让人们上传照片和跟踪其他人。因此,每个用户都会有类似“墙”或“活动提要”的东西,在那里他或她可以看到朋友(他或她关注的人)上传的最新照片

大多数功能都很容易实现。然而,当涉及到这个历史活动提要时,由于纯粹的性能原因,事情很容易变得一团糟

我在这里遇到了以下困境: 我可以很容易地将活动提要设计为数据库的规范化部分,这将节省我的编写周期,但在为每个用户选择这些结果时会大大增加复杂性(对于在特定时间段内上传的每张照片,请选择一个特定的数字,我正在跟踪其上传者/对于我跟踪的每个人,请选择他的照片)

一个优化选项可以是引入一系列阈值约束,例如,允许我根据上次上传的日期对我跟踪的人进行排序,甚至排除一些,以节省周期,并且对于每个用户,仅选择5张(例如)上次上传的照片

第二种方法是为活动提要引入一个完全非规范化的模式,其中每一行代表我的一个追随者的通知。这意味着每次我上传一张照片,DB都会在这个“drop bucket”中放入n行,n表示我跟随的人数,即大量的书写周期。但是,如果我有这样一个表,我可以很容易地应用一些优化技术,例如巧妙的索引,以及修剪超过一定时间段(队列)的条目

然而,我想到的第三种方法是一种非规范化程度更低的模式,其中服务器端应用程序将从数据库中减少部分复杂性。我看到一些社交应用程序(如friendfeed)严重依赖于数据库中序列化对象(如JSON对象)的存储


我肯定仍在掌握可伸缩数据库设计的技能,因此我确信我错过了很多东西,或者还有很多东西需要学习。如果有人能给我指出正确的方向,我将不胜感激。

您可以选择很多方法

  • 添加更多硬件、内存、CPU--
  • 大多数重要的数据库信息都可以存储在内存中
  • 选择带有可扩展SSD的主机。
  • 在应用程序中使用基于事件的系统来编写“历史记录”所有用户的。所以它将是这样的:
    id,user\u id,event\u name,date,event\u parameters'
    ——一个例子是:
    1,8,CHANGED\u PROFILE\u PICTURE,26-03-2011 12:34,
    最重要的是,这个表将在内存中。不再需要担心写性能。在记录过了3天之后如果用户选择返回到另一个表(在非内存中),它们可以被清除到另一个表中,并包含到查询结果中。通过将所有这些都放在一个表中,您可以删除必须执行多个查询并选择建立这些信息
  • 用于历史记录/提要表

好的阅读资源


如果你的应用程序成功,那么你的读操作肯定会比写操作多——我只上传一张照片一次(写),但我的每个朋友在刷新提要时都会读。因此,你应该优化快速读操作,而不是快速写操作,这指向非规范化模式的方向

这里的问题是,如果有大量用户,您创建的数据量可能会很快失控。非常大的表在数据库上很难查询,因此同样存在一个潜在的性能问题。(还有一个问题是有足够的存储空间,但这更容易解决)

如果如您所建议的那样,您可以在一定时间后删除行,那么这可能是一个很好的解决方案。随着您的增长和遇到性能问题,您可以减少该时间(在一定程度上)

关于存储序列化对象,如果这些对象是不可变的(您在编写之后不会更改它们),并且您不需要对它们进行索引或查询,那么这是一个不错的选择。请注意,如果您对数据进行非规范化,这可能意味着您的活动提要只有一个表。在这种情况下,我认为存储blob没有什么好处。 如果您要使用序列化对象的方式,请考虑使用一些NoSQL解决方案,如CouCHDB——它们更好地优化了处理此类数据,因此原则上,您应该为相同的硬件设置获得更好的性能。 请注意,我并不是建议您将所有数据移动到NoSQL—只针对更好的解决方案


最后,从经验中可以看出,构建一个可扩展的应用程序非常困难,而且需要花更多的时间在其他地方。在你担心如何为数以百万计的用户提供服务之前,你应该先考虑如何让数以百万计的用户使用你的应用程序——首先是更困难的问题。当你开始他指出,你非常成功,你可以重新设计和重建你的应用程序。

这些问题就是为什么现在使用NOSql解决方案的原因。我在previos项目中所做的非常简单。我不在内存存储中保留用户->墙用户->历史记录,它只包含提要ID(我最喜欢的是redis)。因此,在每次插入中,我对数据库执行1次插入操作,并在内存存储中执行(n*读取优化)插入操作。我设计内存存储以优化读取。如果我要筛选用户历史记录(或墙)中的视频,我会将推送ID放入一个列表,如用户::{userid}::墙::视频

当然,你也可以在memstores中构建这个系统,但这对h来说很好