将MySQL值存储为整数

时间:2014-05-05 12:14:02

标签: php mysql sql join jointable

我有两个数据库表,我用它来创建一个Twitter风格的跟随系统。

sh_subscriptions
    => id
    => user_id
    => feed_id

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

feed_id中存储shop_name而不是sh_subscriptions的问题在于它需要大量表格加入:

$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会更快}?

1 个答案:

答案 0 :(得分:2)

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

您的基本概念是:您拥有一组用户和一组供稿。每个用户可以订阅零个或多个订阅源,每个订阅源可以包含零个或多个订阅者。

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

你说有很多桌子加入。相对而言,这并不是很多表加入。 MySQL是为这种加入而制作的,它会很好用。

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

  1. 摆脱id列。而是将user_id和feed_id列转换为复合主键。这样您就可以自动防止重复订阅。
  2. 在表格中添加active列...短整数....当它设置为值1时,您的Suscription处于活动状态。这样,您可以通过将active设置为0来取消订阅。
  3. 如果您愿意,也可以添加subscribed_date列。
  4. 在表格中创建两个复合非唯一索引(active,user_id,feed_id)(active,feed_id,userId)。这些将极大地加速连接这样的表的查询。
  5. 查询片段:

       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值。它可以通过从随机访问索引的位置扫描索引来实现,而无需返回表格。这确实非常快。它被称为覆盖索引

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

    要理解的诀窍是这些索引既可以随机访问,也可以顺序扫描。

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