构建关注者/跟随MySQL数据库的最佳实践

时间:2016-09-26 11:27:19

标签: mysql database performance

我将为社交网络风格的网站构建一个MySQL数据库,用户可以关注其他用户,然后从他们关注的用户那里获取更新。

我的数据库由一个包含用户基本信息的表组成:

| ID | username | password | email | ... other few columns | 

“ID”是主要的,“用户名”和“电子邮件”是唯一的索引。

然后我有一个包含用户Feed的表,只有在其他用户关注它时才会显示,'ID'始终是主要的:

| ID | feed_to_show_in_home |

然后是一个包含关注者统计信息的表格,以加快用户个人资料页面:

| ID | followers_count | following_count |

至少真正的粉丝网表存放谁跟谁:

| ID | following |

在此表中,“ID”和“跟随”都是主要的,因为用户只能关注一次其他用户。

现在我想从性能的角度来看我的结构是否合适。我特别担心如何检查用户是否关注其他用户,停止关注用户,以及仅当我关注该特定用户时如何显示提要。

在任何一种情况下,我想到的解决方案是始终扫描整个表的长度,但我认为这不是一个好的选择,因为这个DB计划存储超过10,000个用户。

2 个答案:

答案 0 :(得分:1)

简短回答:10,000是如此之少,以至于任何设计都“足够好”。

答案很长:要进行更多缩放,请考虑以下内容......

这些设计通常不良做法:

  • 两个1:1关系的表格。
  • 存储可以计算的东西。

我说“通常是”,因为您正在接触需要例外的情况。但首先,让我提一下其他一些架构设计:

  <select class="form-control" ng-model="model.selectedValue" name="groupzname" ng-change="getselectval(model.selectedValue)" readonly disabled>
    <option ng-repeat="item in model.dropDownData track by $index" value="{{item}}">{{item}}</option>
  </select>
</div>
<div class="form-group">
  <select class="form-control" name="role"
      ng-model="model.rolename"
      ng-change="getassignRole(model.rolename)">
    <option selected>Select Roles</option>
    <option ng-repeat="role in model.assignroles track by $index"
        value="{{role.rolename}}">{{role.rolename}}</option>
    <table  ng-repeat="role in model.assignroles track by $index" >
      <thead>
        <tr>
          <th>{{maxCount}}</th>
        </tr>
      </thead>
      <tbody>

注意:

  • 没有代理CREATE TABLE Follow ( er ..., -- user id of the the follower ed ..., -- user id of the the followed PRIMARY KEY(er, ed), INDEX(ed, er) ) ENGINE=InnoDB; SELECT COUNT(*) FROM Follow WHERE ed = ?; -- number of followers for `ed`. SELECT er FROM Follow WHERE ed = ? -- list of such followers (Similarly for the flip direction) ,因为有一个非常好的PK。 查询将运行得更快,我们将在一分钟内看到。
  • 在您拥有100K关注者之前,AUTO_INCREMENT查询“足够快”,因此您无需预先计算计数。

如果您要计算“喜欢”的数量,那么为这个经常更新的值设置一个单独的表是明智的。这样的表与User表是1:1,从而违反了第一个不良做法。这里的理由是将Like中的非常高的 write 活动与 low 分开,但在“user”的其余部分中重要的读取活动资讯

答案 1 :(得分:0)

对于这样的事情,我更喜欢图形数据库,因为你想要解决的现实问题有一个图形作为它的自然结构。

从关系的角度来看,你的想法看起来不错。我不太确定你是否已经拥有了你需要的所有关系,但是基本概念你可能是正确的。

对于性能问题,您应该使用一些任意测试数据和EXPLAIN语句(see this)进行一些测试。现在,您可以尝试在要过滤的列上设置一些索引并再次测试它。最好设置哪些索引在很大程度上取决于您的查询以及哪些索引最好不要设置取决于更新/插入内容的频率或数量。还有很多其他文章比我更好地解释它,所以你应该看一下索引的一些最佳实践,并在它们实际发生时询问特定的性能问题。