如何使用 PHP&MySQL 正确处理 n:m 关系?

Posted

技术标签:

【中文标题】如何使用 PHP&MySQL 正确处理 n:m 关系?【英文标题】:How to handle a n:m relation correctly with PHP&MySQL? 【发布时间】:2011-01-25 21:57:33 【问题描述】:

我有 3 张桌子:

+-----------------+ |验证 | +----+-------+----+ |编号 |参数 | ... +----+-------+ +------------------+ |替换| +----+--------------+ |编号 |更换| +----+--------------+ +--------------------------------+ |验证替换 | +---------------+----------------+ |验证ID |替换ID | +---------------+----------------+

现在我在这些表上运行我的 SQL 查询(当然还有连接)。而我在 php 中收到的是 sth。像这样:

... [6] => 标准类对象 ( [id] => 11 [search_param] => Dänische Belletristik [替换] => 丹麦 ) [7] => 标准类对象 ( [id] => 11 [search_param] => Dänische Belletristik [替换] => 小说 ) ...

现在,在我的 PHP 数组中,我多次获得了相同的“search_param”和“id”。把它打印到屏幕上很糟糕。我可以按“id”对数据进行分组以避免这种情况,但是我只有 1 个“替换”值可用。

我正在寻找的结果是这样的:

... [7] => 标准类对象 ( [id] => 11 [search_param] => Dänische Belletristik [替换] => 数组(丹麦,小说) ) ...

我想知道的是:我的表结构是否可以通过修复查询来实现?或者我是否必须在我的 PHP 代码中关心这一点 - 如果是这样:任何提示如何做到最好?有很多资料... 我的表结构是否正确?说到数据库,我还是有点不确定……

最好的问候。

【问题讨论】:

【参考方案1】:

您似乎想显示某个搜索参数的所有替换项?假设您的查询类似于:

SELECT * 
FROM validations_replacements vr 
INNER JOIN validations v ON v.id = vr.validation_id 
INNER JOIN replacements r ON r.id = vr.replacement_id
WHERE v.param = '$search_param'

假设您的结果对象是$results,您可以通过使用结果数组在 PHP 中对它们进行分组:

$replacements = array() ;
foreach ($results as $result) 
    $currSearchParam = $result['search_param'];
    $currReplacement = $result['replacement'] ;
    if (!isset($replacements[$currSearchParam])) 
        $replacements[$currSearchParam] = array() ;
    
    $replacements[$currSearchParam][] = $currReplacement;


//I'll let you fill in the blanks like object id or naming the array keys as you wish

或者你可以在 mysql 中完成,然后在 PHP 中迭代结果:

SELECT v.id, v.param, GROUP_CONCAT(r.replacement)
FROM validations_replacements vr 
INNER JOIN validations v ON v.id = vr.validation_id 
INNER JOIN replacements r ON r.id = vr.replacement_id
WHERE v.param = '$search_param'
GROUP BY v.id

使用GROUP_CONCAT,您将获得每个搜索参数的所有单个结果行,并在逗号分隔的字符串中获得所有替换,然后您可以通过在 PHP 中迭代结果轻松处理:

$replacements = array() ;
foreach ($results as $result) 
    $currSearchParam = $result['search_param'];
    $currReplacements = $result['replacements'] ;
    $replacements[$currSearchParam] = explode(',', $currReplacements) ;

【讨论】:

非常感谢。事实上 GROUP_CONCAT 对我来说是新的,但它似乎正是我想要的。 @d.hill 不客气 :) GROUP_CONCAT 这样非常有用,可以为您节省额外的迭代次数。【参考方案2】:

看起来你可以使用GROUP_CONCAT

【讨论】:

以上是关于如何使用 PHP&MySQL 正确处理 n:m 关系?的主要内容,如果未能解决你的问题,请参考以下文章

如何正确处理 PHP / MySQL / Apache 中的国际字符

PHP 脚本未正确从 MySQL 数据生成 KML 文件 - 如何正确处理此问题?

如何正确获取 PHP 和 MySQL 中的欧元符号

PHP & MySQL 搜索列的价值

当我将 PHP 与 Mysql 一起使用时,来自数据库的 URL 不正确

带有分层邻接模型MySql和PHP的缩进HTML下拉列表