【问题标题】:PHP nested loops with foreign key table带有外键表的 PHP 嵌套循环
【发布时间】:2012-10-10 03:49:48
【问题描述】:

这是一个多部分的问题。我的数据库如下所示:

USERS
-id
-fname
-lname

COMPANIES
-id
-name
-type

PRODUCTS
-id
-product
-restaurant (foreign key to companies id)
-vendor (foreign key to companies id)
-user (foreign key to users id)
-transaction_date
  1. 这是设置数据库的好方法吗?我正在考虑为餐馆和供应商设置单独的表,但希望它们使用相同的登录页面,而不必担心 UNION 查询,我只需按类型选择它们。他们在登录时会看到不同的信息,所以我有一个 if 语句说 if type = r, show this else show that。最好的方法?

当我想在登录时显示信息时,第二个问题出现了。假设供应商登录,他们将看到与其供应商 ID 匹配的所有记录的列表。但是,由于我的嵌套循环,我看到了太多记录。例如,表格如下所示:

Date--Product--Restaurant--User

我正在使用这个查询:

$sql = mysql_query("SELECT products.*, companies.name, CONCAT_WS(' ', users.fname, users.lname) AS fullname FROM products INNER JOIN companies ON products.vendor = companies.id INNER JOIN users ON products.user = users.id WHERE company='$id' AND companies.type='$type'") or die(mysql_error());

$num=mysql_num_rows($sql);

$sql1 = mysql_query("SELECT products.restaurant, companies.name AS cname FROM products INNER JOIN companies ON products.restaurant = companies.id") or die(mysql_error());

$num1=mysql_num_rows($sql1);

$i = 0;
while ($i < $num) {
  $j = 0;
  while ($j < $num) {
$d = mysql_result($sql,$i,"transaction_date");
$p = mysql_result($sql,$i,"product");
$r = mysql_result($sql1,$j,"cname");
$u = mysql_result($sql,$i,"fullname");

<td><?php echo $d; ?></td>
<td><?php echo $p; ?></td>
<td><?php echo $r; ?></td>
<td><?php echo $u; ?></td>

$j++; }
$i++; }

$id$type 是登录时创建的会话值。表中当前有 4 条示例记录。它不是只显示 4,而是显示 16,因为 $num$num1 的值都是 4 并且 $num 循环 $num1 四次。

  1. 如何解决此问题并仅显示 4 条记录?

感谢您的帮助。如果您需要任何说明,请告诉我。

【问题讨论】:

  • 每个产品是否只有一个用户?如果是这样,您的架构看起来不错。如果没有,您需要创建一个包含 product_id、user_id 和交易日期的 product_users 表。
  • 是的,每个产品只有一个用户。实际上,我应该将 Products 表重命名为 Transactions,因为本质上只有一种产品。

标签: php database-design foreign-keys nested-loops


【解决方案1】:

您的数据库设置可能需要重新考虑。

我认为这是因为您需要知道每个用户所在的公司,而您不能像以前那样在产品表中拥有它。

我会考虑像这样将外键添加到 users 表中(假设一个用户有一个公司,一个公司有很多用户)。我还提出了一些其他建议,如下所示:

用户 - ID - company_id - 名 - 姓氏

公司 - ID - 姓名 - company_type_id

公司类型 - ID - 类型

产品 - ID - 产品名称 - company_id

交易 - ID - 用户身份 - product_id - 交易日期

they will see a list of all the records that match their vendor

现在您会注意到我从上表中删除了供应商 ID - 这是因为供应商 ID 与公司 ID 相同。对同一件事有两个单独的关系 ID 是没有意义的(如果我弄错了,请纠正我)

因此,通过上述更改,我们可以轻松列出这些记录,如下所示:

<?php

  $db   = new PDO(/**Connection info here**/);
  $stmt = $db->prepare("
    SELECT
      a.id AS product_id,
      a.product_name
    FROM 
      products AS a
    INNER JOIN
      companies AS b ON b.id = a.company_id
    INNER JOIN
      company_types AS c ON c.id = b.type_id
    WHERE
      b.id = :company AND c.id = :companyType
  ");
  $stmt->bindParam(":company", $usersCompanyIdHere, PDO::PARAM_INT);
  $stmt->bindParam(":companyType", $usersCompanyTypeHere, PDO::PARAM_INT);

  $data = $stmt->execute();

  while ($row = $data->fetch()) {
    /** List of all the products for given company id**/
  }

?>

我已将您的代码更改为使用 PDO,我不想在这里给您过多的信息,但我不能强调使用 PDO 优于原生的好处mysql_* 函数 - 使用 Google 搜索,我可以在前 10 个结果中看到很多有用且相关的信息。

【讨论】:

  • 感谢您的回复。您提供了非常详细的答案,但我可能没有正确解释设计。有顾客、供应商和餐馆。基本上只有一种产品,所以我应该将Products 表重命名为TransactionsTransactions 表中的每条记录都将包括日期、用户、餐厅和供应商。当供应商登录时,他们只会看到包含他们的记录,显示日期、用户、餐厅。当餐厅登录时,他们会看到包含他们的记录,显示日期、用户、供应商。
  • 我将供应商和餐馆放在Companies 的同一张表下,因为我不想对两个表进行联合查询。我可以查询一个表以显示我请求的数据的设置方式吗?如果有怎么办?谢谢。
  • 我查看了 PDO 并将实现它。你知道我的数据库设计是否有效吗?或者我应该改变它以便循环可以工作?
  • 您能解释一下供应商到底是什么吗?他们是餐馆的​​老板吗?您应该在这里考虑的是,“登录”的任何人都是用户,碰巧每个用户与产品/餐厅/供应商等都有不同的关系
  • 有客户(当前是 users 表)、餐馆、产品(可能应该将其更改为交易,因为只有一种产品)并且有供应商。将会发生的是,当交易发生时,将在 Products 表中生成一行,列出日期、产品 A、生成它的客户 ID、发生交易的餐厅 ID 以及与该餐厅相关的供应商 ID。某些供应商与某些餐厅有关。希望对您有所帮助。
猜你喜欢
  • 1970-01-01
  • 2012-12-15
  • 1970-01-01
  • 1970-01-01
  • 2021-06-19
  • 1970-01-01
  • 2013-04-13
  • 1970-01-01
  • 2016-07-27
相关资源
最近更新 更多