php - 将 MySQL 值存储为整数

标签 php mysql sql join jointable

我有两个数据库表,我正在使用它们来创建一个 Twitter 风格的关注系统。

sh_subscriptions
    => id
    => user_id
    => feed_id

sh_feeds
    => id
    => item
    => shop_name
    => feed_id

sh_subscriptions 中存储 feed_id 而不是 shop_name 的问题是它需要大量的表连接:

$id = $_POST['id'];
$user_id = $id['id'];
$shop_name = mysqli_escape_string($con, $_POST['shop_name']);

$query = "SELECT * FROM sh_subscriptions s INNER JOIN sh_feeds f ON s.feed_id = f.feed_id WHERE s.user_id = $user_id AND f.shop_name = '$shop_name'";
$result = mysqli_query($con, $query) or die(mysqli_error($con));

if (mysqli_num_rows($result) > 0)
{
    $query2 = "DELETE FROM sh_subscriptions s INNER JOIN sh_feeds f ON s.feed_id = f.feed_id WHERE s.user_id = $user_id AND f.shop_name = '$shop_name'";
    $result2 = mysqli_query($con, $query2) or die(mysqli_error($con));
}

else
{
    // insert the row instead
}

(我知道 if 语句中某处有错误,但稍后我会担心。)

如果我将 feed_id 替换为 shop_name,我可以将第 5 行替换为:

$query = "SELECT * FROM sh_subscriptions WHERE user_id = $user_id AND shop_name = '$shop_name'";

我的问题是:是否总是尽可能将 MySQL 值存储为整数,或者在这种情况下,让 sh_subscriptions 包含 shop_name 会更快吗而不是 feed_id

最佳答案

您的 sh_subscriptions 表实际上是一个将用户与提要相关联的多对多连接表。这被认为是设计数据库模式的好方法。

您的基本概念是:您有一组用户和一组提要。每个用户可以订阅零个或多个提要,每个提要可以有零个或多个订阅者。

要输入订阅,您需要在 sh_subscriptions 表中创建一行。要取消它,请删除该行。

你说有“很多表连接”。恕我直言,这不是很多表连接。 MySQL 就是为这种连接而生的,它会很好地工作。

我对您的 sh_subscriptions 表有一些建议。

  1. 去掉 id 列。而是将 user_id 和 feed_id 列变成复合主键。这样您将自动防止重复订阅。
  2. 添加一个 active 列 ... 一个短整数 ... 到表中。当它设置为 1 时,您的订阅处于事件状态。这样您就可以通过将 active 设置为 0 来取消订阅。
  3. 如果您关心的话,您还可以添加一个 subscribed_date 列。
  4. 在表上创建两个复合非唯一索引 (active,user_id,feed_id)(active,feed_id,userId)。这些将大大加快像这样连接表的查询。

查询片段:

   FROM sh_feed f
   JOIN sh_subscription s ON (f.feed_id = s.feed_id AND s.active = 1)
   JOIN sh_users u ON (s.user_id = u.user_id)
  WHERE f.shop_name = 'Joe the Plumber'

如果您达到了拥有数亿用户或提要的地步,您可能需要考虑对该表进行非规范化。也就是说,例如,重新定位商店名称文本,使其位于 sh_subscriptions 表中。但不是现在。

编辑 我建议使用多个复合覆盖索引。例如,如果您要加入用户提要,MySQL 会通过确定 sh_feeds 中与您的选择匹配的行来开始满足您的查询。

然后它确定 feed_id,并随机访问 feed_id 上的复合索引。然后,它需要查找该 feed_id 的所有 user_id 值。它可以通过从随机访问索引的点开始扫描索引来做到这一点,而无需返回到表中。这确实非常快。它称为覆盖索引

另一个覆盖索引处理从已知用户开始并继续查找提要的查询。索引中列的顺序很重要:随机访问只能从索引的第一列(最左边)开始。

要理解的技巧是这些索引既可以随机访问又可以顺序扫描。

另一个注意事项 如果连接表中只有两列,覆盖索引之一也是您的主键,另一个包含与主键相反顺序的列。您不需要任何重复索引。

关于php - 将 MySQL 值存储为整数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23472191/

相关文章:

php - 使用 PHP 将数据从 MySQL 转换为 JSON

php - 在更新表单 php 上显示图像路径

mysql - Rails 3.1 - Heroku 上 mySQL 和 PostgreSQL 之间巨大的查询时间差异

php - 输入框字段值不以json格式显示

php - OOP中的单一职责原则

MySQL通过乘法自增字段

mysql - 如何将列添加到表中,以组合其他列中的字符串?

c# - 最佳登录做法

php - wasRecentlyCreated 和 wasChanged 不起作用

javascript - 如何将 jquery 添加到 wordpress 插件