PHP嵌套循环与外键表

时间:2012-10-19 13:55:01

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

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

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语句,如果type = r,则显示其他信息显示。最好的方式?
  2. 当我想在登录时显示信息时,会出现第二个问题。假设供应商登录,他们将看到与其供应商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条记录?
    2. 感谢您的帮助。如果您需要对任何部分进行任何澄清,请与我们联系。

1 个答案:

答案 0 :(得分:1)

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

我认为这是因为您需要知道每个用户所在的公司,并且您不能像产品一样在产品表中使用此公司。

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

用户  - ID   - company_id  - 名字   - last_name

公司  - ID  - 名称   - company_type_id

<强> company_types  - ID   - 输入

<强>产品  - ID  - 产品名称   - company_id

<强>交易  - ID  - 用户身份   - product_id   - transaction_date

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个结果中看到大量有用且相关的信息。