PHP更新MYSQL的多对多关系

EsT*_*eGe 7 php mysql many-to-many

我有一个多对多关系,用MySQL中的关联表实现.我有一张儿童餐桌和一张父母餐桌.子项可以有多个父项,保存在parent_child_link关联表中,并带有其ID.

可以通过HTML表单更新子项,父项是HTML多选.现在我需要更新数据库中的记录,但我的解决方案效率不高.这是伪代码我做的:

  1. 更新child_id = x的子信息
  2. 删除parent_child_link中child_id = x的所有当前关联
  3. 插入新关联

这个解决方案效果很好,但是当父母没有被改变时,例如只改变了孩子的名字,那么执行了2个不必要的查询.如何避免那些不必要的查询?有没有办法检查多选中的父母是否没有改变?

当然,我可以忽略所有这些麻烦,因为它已经有效,但我真的希望尽可能保持高效.

Tho*_*hom 8

我有同样的问题,并在我阅读时想出了我的解决方案.

当我准备处理提交的条目时,我首先进行查询以获取当前关联并调用该数组$ original_list.提交的列表我将调用$ submitted_list.

$original_list = array(3,5,7);
$submitted_list = array(1,2,3);
Run Code Online (Sandbox Code Playgroud)

然后我只需要弄清楚1)要删除的项目(不再存在)和2)要添加的项目(新关联).两个列表中的项目都不会被触及.

$delete_list = array_diff($original_list, $submitted_list);
$insert_list = array_diff($submitted_list, $original_list);

foreach($delete_list as $item) {
    // delete $item from DB
}

foreach($insert_list as $item) {
    // insert item in db
}
Run Code Online (Sandbox Code Playgroud)

很想知道其他人是否认为这是一个有效的解决方案.


Joh*_*n P 0

尝试在数据库中解决它,而不是在应用程序层中通过在子表的定义中使用ON UPDATE CASCADEand来解决。ON DELETE CASCADE

MySQL 站点的一个稍微修改过的示例:

CREATE TABLE parent (id INT NOT NULL,
                     PRIMARY KEY (id)
) ENGINE=INNODB;

CREATE TABLE child (id INT, parent_id INT,
                    INDEX par_ind (parent_id),
                    FOREIGN KEY (parent_id) REFERENCES parent(id)
                      ON DELETE CASCADE ON UPDATE CASCADE
) ENGINE=INNODB;
Run Code Online (Sandbox Code Playgroud)

查看此处的文档:http://dev.mysql.com/doc/refman/5.5/en/innodb-foreign-key-constraints.html

编辑:对于多对多关系,您可以使用以下内容:

CREATE TABLE parent_child_link (
                    parent_id INT NOT NULL,
                    child_id INT NOT NULL,
                    PRIMARY KEY(parent_id, child_id),
                    FOREIGN KEY (parent_id) REFERENCES parent(id)
                      ON DELETE CASCADE ON UPDATE CASCADE,
                    FOREIGN KEY (child_id) REFERENCES child(id)
                      ON DELETE CASCADE ON UPDATE CASCADE
);
Run Code Online (Sandbox Code Playgroud)

希望这可以帮助。

  • 我很想将其移到应用程序层之外,但我不知道您的引用解决方案如何解决我的问题。据我设法分析它,在删除子项或父项(以删除链接)时它会很有用。 (2认同)