社交网络应用程序数据库设计:如何改进此架构?
Posted
技术标签:
【中文标题】社交网络应用程序数据库设计:如何改进此架构?【英文标题】:Social web application database design: how can I improve this schema? 【发布时间】:2011-04-20 03:47:21 【问题描述】:背景
我正在为诗人和作家开发一个社交网络应用程序,让他们可以分享自己的诗歌、收集反馈并与其他诗人交流。我在数据库设计方面几乎没有接受过正规培训,但我一直在阅读书籍、SO 和在线数据库设计资源,以尝试确保性能和可伸缩性而不会过度设计。
数据库是 mysql,应用程序是用 php 编写的。我还不确定我们是使用 ORM 库还是在应用程序中从头开始编写 SQL 查询。除了 Web 应用程序,Solr 搜索服务器和一些消息传递客户端可能会与数据库进行交互。
当前需求
我在下面汇总的架构代表了网站第一个版本的主要组件。最初,用户可以注册该站点并执行以下任何操作:
创建和修改个人资料详细信息和帐户设置 发布、标记和分类他们的文章 阅读、评论和“收藏”其他用户的帖子 “关注”其他用户以获取他们的活动通知 搜索和浏览内容并获取建议的帖子/用户(尽管我们将使用 Solr 搜索服务器来索引数据库数据并运行这些类型的查询)架构
这是我在 MySQL Workbench 上为初始站点设计的内容。我对一些关系数据库的东西还是有点模糊,所以放轻松。
问题
-
总的来说,有什么我做错了或可以改进的地方吗?
有什么理由不应该将 ExternalAccounts 表合并到 UserProfiles 表中?
我有什么理由不应该将 PostStats 表合并到 Posts 表中?
我是否应该扩展设计以包含我们在第二个版本中所做的功能,以确保初始架构能够支持它?
我能做些什么来优化 Solr 索引/性能/其他方面的数据库设计吗?
我是否应该在 Locations 表中使用更自然的主键,例如用户名而不是 UserID,或者邮政编码/区号而不是代理 LocationID?
感谢您的帮助!
【问题讨论】:
请不要将 SQL 查询放在应用程序的嵌入字符串中。请考虑改用存储过程等。请。 哦,抱歉,我会使用存储过程/在查询和应用程序的其余部分之间构建一些基本抽象。 可能会为首选类别等添加“UserPreferences”——无论是新表还是在 UserProfiles 中。 【参考方案1】:总的来说,有什么我做错或可以改进的地方吗?
总的来说,我认为您当前的设置或架构没有任何重大缺陷。
我想知道的是您将其拆分为 3 个 User* 表。我得到了你想要的东西(有不同的用户相关的东西分开),但我不知道我是否会选择完全相同的东西。如果您计划仅显示站点上 User
表中的数据,这很好,因为在同一页面上不需要多次其他信息,但如果用户需要使用他们的真实姓名并显示他们的真实姓名(如John Doe 而不是 doe55),当数据变大时,这会减慢速度,因为您可能需要连接。将Preferences
分开似乎是个人选择。我不赞成也不反对。
您的多对多表不需要额外的 PK(例如 PostFavoriteID
)。 PostID
和 UserID
的组合主要就足够了,因为 PostFavoriteID
从未在其他任何地方使用过。这适用于所有连接表
我有什么理由不应该合并 ExternalAccounts 表到 UserProfiles 表中?
与上一个一样。回答,我没有看到优势或劣势。我可能将两者放在同一个表中,因为NULL
(或者更好的-1
)值不会打扰我。
我有什么理由不应该合并 PostStats 表 进入 Posts 表?
我会使用触发器将它们放入同一个表中以处理ViewCount
表的增量
我是否应该扩展设计以包括 我们正在做的功能 第二个版本只是为了确保 初始架构可以支持吗?
您使用的是 normalsied 架构,因此可以随时进行任何添加。
我可以做些什么来优化 Solr 的数据库设计 索引/性能/其他?
不能告诉你,还没做过,但我知道 Solr 非常强大和灵活,所以我认为你应该做得很好。
我应该使用更自然的主键,比如用户名而不是 用户 ID,或邮政编码/区号,而不是 Locations 中的代理 LocationID 桌子?
这里有 很多 个线程在讨论这个问题。就个人而言,我更喜欢代理键(或另一个唯一的数字键,如果可用),因为它使查询更容易和更快,因为查找 int 更容易。如果您允许更改用户名/电子邮件/无论您的 PK 是什么,则需要大量更新。使用代理键,您无需费心。
我还要做的是在(最好通过触发器或程序 IMO 完成)添加诸如 created_at
、last_accessed
之类的内容,以使一些统计信息可用。这确实可以为您提供有价值的统计数据
进一步提高性能的策略是内存缓存、计数器缓存、分区表等……当你真的被用户超越时,可以讨论这些事情,因为可能有东西/技术/技术/……非常针对您的问题。
【讨论】:
【参考方案2】:我不清楚您的 User* 表发生了什么 - 它们的设置好像是 1:1 但图表反映了一对多(鱼尾纹符号)。
ExternalAccounts
和 UserSettings
可以进一步规范化(在这种情况下,它们将是一对多!),这将为您提供更易于维护的设计 - 您无需添加更多列其他外部帐户或通知类型的架构(尽管这在性能方面可能不太可扩展)。
例如:
ExternalAccounts
UserId int,
AccountType varchar(45),
AccountIdentifier varchar(45)
将允许您以相同的结构存储 LinkedIn、Google 等帐户。 同样,可以使用以下结构轻松添加更多通知类型:
UserSettings
UserId int,
NotificationType varchar(45),
NotificationFlag ENUM('on','off')
第
【讨论】:
以上是关于社交网络应用程序数据库设计:如何改进此架构?的主要内容,如果未能解决你的问题,请参考以下文章