社交Web应用程序数据库设计:如何改进此架构?

时间:2010-10-02 05:11:40

标签: mysql database database-design schema social-networking

背景

我正在为诗人和作家开发一个社交网络应用程序,允许他们分享他们的诗歌,收集反馈,并与其他诗人交流。我在数据库设计方面的培训很少,但我一直在阅读书籍,SO和在线数据库设计资源,以确保性能和可扩展性而不会过度设计。

数据库是MySQL,应用程序是用PHP编写的。我不确定我们是否会在应用程序中使用ORM库或从头开始编写SQL查询。除了Web应用程序之外,Solr搜索服务器和某些消息传递客户端将与数据库进行交互。

当前需求

我在下面一起抛出的架构代表了网站第一版的主要组件。最初,用户可以注册该站点并执行以下任何操作:

  • 创建和修改个人资料详细信息和帐户设置
  • 发布,标记和分类他们的写作
  • 阅读,评论和“最喜欢”其他用户的帖子
  • “关注”其他用户以获取有关其活动的通知
  • 搜索和浏览内容并获取建议的帖子/用户(尽管我们将使用Solr搜索服务器索引数据库数据并运行这些类型的查询)

模式

以下是我在MySQL Workbench上为初始网站提出的建议。我对某些关系数据库事物仍然有点模糊,所以请轻松一点。

Schema Image

问题

  1. 一般来说,有什么我做错了或可以改进吗?
  2. 我有什么理由不将ExternalAccounts表合并到UserProfiles表中吗?
  3. 我有什么理由不将PostStats表合并到Posts表中吗?
  4. 我是否应该扩展设计以包含我们在第二个版本中所做的功能,以确保初始架构可以支持它?
  5. 我可以做些什么来优化Solr索引/性能/其他的数据库设计?
  6. 我应该使用更自然的主键,例如Username而不是UserID,还是zip / area代码而不是Locations表中的代理LocationID?
  7. 感谢您的帮助!

2 个答案:

答案 0 :(得分:3)

  

一般来说,有什么我做错了或可以改进吗?

总的来说,我认为您当前的设置或架构没有任何重大缺陷。

我想知道你分成3个User *表。我得到了你想要的东西(不同的用户相关的东西分开),但我不知道我是否会采用完全相同的东西。如果您计划仅显示网站上User表中的数据,这很好,因为在同一页面上不需要多次其他信息,但如果用户需要使用他们的真实姓名并显示他们的真实姓名(比如John Doe而不是doe55)比这更慢,因为你可能需要连接时数据变大。 Preferences分开似乎是个人选择。我没有赞成也不反对它。

您的多对多表格不需要额外的PK(例如PostFavoriteID)。 PostIDUserID的主要组合就足够了,因为PostFavoriteID从未在其他任何地方使用过。这适用于所有连接表

  

我有什么理由不合并ExternalAccounts   表进入UserProfiles表?

与上一篇文章一样。回答,我没有看到一个优点或缺点。我可能将两者放在同一个表中,因为NULL(或者更好-1)值不会打扰我。

  

我有什么理由不合并PostStats表   进入帖子表?

我会使用触发器将它们放到同一个表中来处理ViewCount表的增量

  

我应该扩展设计以包含   我们正在做的功能   第二版只是为了确保   初始架构可以支持吗?

您正在使用标准化架构,因此可以随时进行任何添加。

  

我可以做些什么来优化Solr的数据库设计   索引/性能/不管?

不能告诉你,还没有完成,但我知道Solr是非常强大和灵活的所以我认为你应该做得很好。

  

我是否应该使用更自然的主键,例如Username而不是   UserID,或zip /区号而不是   代理位置中的位置ID   表

这里有许多线程在讨论这个问题。就个人而言,我更喜欢代理键(或其他唯一数字键,如果可用),因为它使查询更容易和更快,因为更容易查找int。如果您允许更改用户名/电子邮件/无论您的PK是什么,那么需要进行大量更新。使用代理键,您无需费心。

我还要做的是添加created_atlast_accessed之类的内容(最好通过触发器或程序IMO完成)以获得一些统计数据。这可以真正为您提供有价值的统计数据

进一步增加性能的策略将是memcache,计数器缓存,分区表等......当你真的被用户占用时,可以讨论这些事情,因为可能有东西/技术/技术/ ......对你的问题非常具体。

答案 1 :(得分:1)

我不清楚您的User *表格发生了什么 - 它们的设置好像它们是1:1,但图表反映了1对多(乌鸦的符号)。

ExternalAccountsUserSettings可以进一步标准化(在这种情况下,它们将是1对多!),这将为您提供更易于维护的设计 - 您不需要为您的架构添加更多列以获取其他外部帐户或通知类型(尽管在性能方面可能不太可扩展)。

例如:

ExternalAccounts
    UserId int,
    AccountType varchar(45),  
    AccountIdentifier varchar(45)

允许您以相同的结构存储LinkedIn,Google等帐户。 同样,可以使用如下结构轻松添加更多通知类型:

UserSettings
    UserId int,  
    NotificationType varchar(45),  
    NotificationFlag ENUM('on','off')

HTH