Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/mysql/60.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Mysql 使用多个左联接从不同的表获取产品详细信息是否是一种良好的做法?_Mysql_Left Join - Fatal编程技术网

Mysql 使用多个左联接从不同的表获取产品详细信息是否是一种良好的做法?

Mysql 使用多个左联接从不同的表获取产品详细信息是否是一种良好的做法?,mysql,left-join,Mysql,Left Join,我有一个select查询 SELECT tbl_product.prod_id,tbl_product.manuf_id, tbl_product.cat_type_id, tbl_product.cat_id, tbl_product.prod_mpn, tbl_product.prod_name, tbl_product.prod_model, tbl_product.prod_retail_price, tbl_product.prod_purchase_price, tbl_p

我有一个select查询

    SELECT tbl_product.prod_id,tbl_product.manuf_id, tbl_product.cat_type_id, tbl_product.cat_id, tbl_product.prod_mpn, 
tbl_product.prod_name, tbl_product.prod_model, tbl_product.prod_retail_price, tbl_product.prod_purchase_price, tbl_product.prod_sp_offer_price, tbl_product.prod_stock_qty, tbl_product.prod_ships_in, 
tbl_product.prod_rating, tbl_product.prod_preorder, tbl_category_types.cat_type_name, tbl_category_types.cat_type_seo_name, tbl_category.cat_name, tbl_category.cat_seo_name, tbl_product_images.prod_image, tbl_product_details.prod_short_desc, tbl_product_details.prod_long_desc, tbl_product_seo.prod_seo_title, tbl_product_seo.prod_seo_keywords,tbl_product_details.prod_rel_keywords,tbl_product_seo.prod_seo_desc, tbl_product.network_id, tbl_network.network, tbl_network.network_seo_name, tbl_manufacturer.manuf_id, tbl_manufacturer.manuf_name, tbl_manufacturer.manuf_seo_name, tbl_product.prod_preorder_text
FROM tbl_product    
        LEFT JOIN 
        tbl_category_types ON tbl_category_types.cat_type_id = tbl_product.cat_type_id
        LEFT JOIN 
        tbl_category ON tbl_category.cat_id = tbl_product.cat_id
        LEFT JOIN 
        tbl_product_images ON tbl_product_images.prod_id = tbl_product.prod_id
        LEFT JOIN 
        tbl_product_details ON tbl_product_details.prod_id=tbl_product.prod_id                  
        LEFT JOIN 
        tbl_product_seo ON tbl_product_seo.prod_id = tbl_product.prod_id                    
        LEFT JOIN 
        tbl_network ON tbl_network.network_id = tbl_product.network_id
        LEFT JOIN
        tbl_manufacturer ON tbl_manufacturer.manuf_id = tbl_product.manuf_id                        
        WHERE 
        tbl_product.lang_id = '".$_SESSION["lang_id"]."' AND
        tbl_product.is_comp_phone = 0 AND 
        tbl_product.prod_id = '".$product_id."' AND
        tbl_product_seo.lang_id = '".$_SESSION["lang_id"]."' AND 
        tbl_product_seo.dom_id = '".$_SESSION["domain_id"]."' AND 
        tbl_product_details.lang_id = '".$_SESSION["lang_id"]."' AND 
        tbl_product_details.dom_id = '".$_SESSION["domain_id"]."'  
        LIMIT 1";
我需要使用此查询获取产品详细信息,这种方式是否适合继续?
或者有更好的选择吗?

对我来说似乎是一个很好的问题。

你的问题的答案是肯定的,很好

唯一不好的是,它可能容易受到SQL注入的攻击(如果任何人可以在会话中修改
lang\u id
domain\u id
,他们就会!)

强烈建议您使用参数化查询,例如:

$dbh = new PDO('mysql:dbname=test;host=127.0.0.1','user', 'password'); //assuming mysql
$sql = "SELECT
    tbl_product.prod_id,
    tbl_product.manuf_id,
    tbl_product.cat_type_id,
    tbl_product.cat_id,
    tbl_product.prod_mpn,
    tbl_product.prod_name,
    tbl_product.prod_model,
    tbl_product.prod_retail_price,
    tbl_product.prod_purchase_price,
    tbl_product.prod_sp_offer_price,
    tbl_product.prod_stock_qty,
    tbl_product.prod_ships_in,
    tbl_product.prod_rating,
    tbl_product.prod_preorder,
    tbl_category_types.cat_type_name,
    tbl_category_types.cat_type_seo_name,
    tbl_category.cat_name,
    tbl_category.cat_seo_name,
    tbl_product_images.prod_image,
    tbl_product_details.prod_short_desc,
    tbl_product_details.prod_long_desc,
    tbl_product_seo.prod_seo_title,
    tbl_product_seo.prod_seo_keywords,
    tbl_product_details.prod_rel_keywords,
    tbl_product_seo.prod_seo_desc,
    tbl_product.network_id,
    tbl_network.network,
    tbl_network.network_seo_name,
    tbl_manufacturer.manuf_id,
    tbl_manufacturer.manuf_name,
    tbl_manufacturer.manuf_seo_name,
    tbl_product.prod_preorder_text
FROM tbl_product
LEFT JOIN 
    tbl_category_types ON tbl_category_types.cat_type_id = tbl_product.cat_type_id
LEFT JOIN 
    tbl_category ON tbl_category.cat_id = tbl_product.cat_id
LEFT JOIN 
    tbl_product_images ON tbl_product_images.prod_id = tbl_product.prod_id
LEFT JOIN 
    tbl_product_details ON tbl_product_details.prod_id=tbl_product.prod_id
LEFT JOIN 
    tbl_product_seo ON tbl_product_seo.prod_id = tbl_product.prod_id
LEFT JOIN 
    tbl_network ON tbl_network.network_id = tbl_product.network_id
LEFT JOIN
    tbl_manufacturer ON tbl_manufacturer.manuf_id = tbl_product.manuf_id
WHERE 
    tbl_product.lang_id = :langid AND
    tbl_product.is_comp_phone = 0 AND 
    tbl_product.prod_id = :productid AND
    tbl_product_seo.lang_id = :langid AND 
    tbl_product_seo.dom_id = :domainid AND 
    tbl_product_details.lang_id = :langid AND 
    tbl_product_details.dom_id = :domainid
LIMIT 1";
$stmt = $dbh->prepare($sql)
$stmt->prepare(':langid', $_SESSION["lang_id"]);
$stmt->prepare(':productid', $productid);
$stmt->prepare(':domainid', $_SESSION["domain_id");
if ($stmt->execute()) {
    $row = $stmt->fetch();
    if ($row === false) {
        // no rows
    } else {
        //do something with row data
    }
}

我也清理了一下。我碰巧喜欢查询中每列一行,但这是我个人的偏好。

是的,没关系。但是请记住,对于MySQL,左连接更难优化,因此为了性能起见,尽可能使用内部连接。

糟糕的查询,您在where子句中使用了一些左连接,将它们转换为内部连接。您需要将tbl_product_seo和tbl_product_details的过滤条件移动到左联接的ON子句中。

正如HLGEM所说,左联接在某些表上是毫无意义的,只要您在where子句中使用它们,优化器就会将它们转换为内部联接

原因是,您通常使用左连接来获取一个表中的记录以及第二个表中存在的任何记录,这将在第二个表中不存在任何记录时返回null


使用WHERE子句限制第二个表中的项时,它永远不会返回null,因此左连接完全没有意义

您知道DBMS中的所有内容都是表或视图吗?因此“tbl_”前缀非常没有意义?它不会传递任何有用的信息,并且会将名称弄乱。同样,使用精心选择的表别名(简称)而不是全名,SQL的可读性会更高。