什么是使用PHP递归更新mysql的最佳方法

时间:2018-04-15 15:15:15

标签: php mysql recursion hierarchical-data

我不擅长php和mysql,但我知道一些, 我的问题是我想要更新200万行(将来,但是现在我只有少量数据)。

1

我有这张桌子:

    Array
(
    [0] => 87
    [1] => 88.90000000000001
    [2] => 97.40000000000001
    [3] => 27.4
    [4] => 94.7
    [5] => 91.7
    [6] => 93.90000000000001
    [7] => 100
    [8] => 0
    [9] => 100
    [10] => 94.40000000000001
    [11] => 90
    [12] => 100
    [13] => 78.59999999999999
    [14] => 63.3
    [15] => 97.40000000000001
    [16] => 96.90000000000001
    [17] => 97
)
Array
(
    [0] => 95.2
    [1] => 94.7
    [2] => 95
    [3] => 33.6
    [4] => 94.8
    [5] => 100
    [6] => 92.3
    [7] => 78.59999999999999
    [8] => 92.3
    [9] => 96.40000000000001
    [10] => 92.5
    [11] => 100
    [12] => 96.3
    [13] => 84.09999999999999
    [14] => 63
    [15] => 97.7
    [16] => 94.3
    [17] => 97.09999999999999
)
Array
(
    [0] => 100
    [1] => 95
    [2] => 91.90000000000001
    [3] => 33.6
    [4] => 98.2
    [5] => 96.3
    [6] => 97.90000000000001
    [7] => 86.7
    [8] => 91.7
    [9] => 96.59999999999999
    [10] => 92.5
    [11] => 100
    [12] => 92.3
    [13] => 83.3
    [14] => 63.6
    [15] => 92.90000000000001
    [16] => 94.40000000000001
    [17] => 98.59999999999999
)

我将插入第7行

ID   BAnumber  DateEntry    Parent   Side  LastA  LastB
1   10001    01-01-2018                                             03-02-2018
2   10002    01-13-2018        9055       B
3   10003    01-15-2018       10001      A  03-02-2018
4   10004    01-20-2018       10002      B
5   10005    02-05-2018       10003      A  03-02-2018
6   10006    03-02-2018       10005      A

第7行连接到其B侧的Parent 10005,而第6行连接到A侧,

插入第7行后,我想将其父(10005)最后一天(B面)更新为新创建的DateEntry, 并更新10005的父级(父级10003 sideA)具有相同日期的LastA。 这种情况一直持续到第一个数据没有父

7   10008    03-20-2018       10005      B

我可以通过php完成:

ID   BAnumber  DateEntry    Parent   Side  LastA  LastB
1   10001    01-01-2018                                             03-23-2018
2   10002    01-13-2018        9055       A
3   10003    01-15-2018       10001      B    03-23-2018
4   10004    01-20-2018       10002      B
5   10005    02-05-2018       10003      A    03-02-2018  03-23-2018
6   10006    03-02-2018       10005      A
7   10008    03-23-2018       10005      B

这将在循环中有太多的sql查询,这在少量数据中可以很好,但如何在大数据中优化它?

我的代码正在运行但我想仅针对更大的数据进行优化。

抱歉,我不知道如何使用手机发布表格和代码..

2

另一个问题, 我没有真正使用ID列,它是PK ,, 我应该删除它并使BANumber成为主键吗? 但BAnumber不应该是自动增量。

这样更好吗?

1 个答案:

答案 0 :(得分:0)

你的方法是正确的。

为什么呢? MySQL的生产版本缺乏执行分层查询的能力(例如,SELECT数据WHERE行 nnnnn的祖先)。 MySQL没有内置的WHERE P is-ancestor-of C操作,只有WHERE P is-parent-of C实现的WHERE P.BANumber = C.parent操作。

因此,您需要在循环中使用查询来执行操作。您需要为每个级别的祖先运行一次查询。如果您的某些数据行包含百万级别的祖先,那么您将循环运行一百万次。这是循环运行的很多次。 (大多数等级表示,例如物料清单 - 小部件:案例:螺丝 - 几乎没有多少级别的祖先。现实世界数据中有十个等级。)

您可能希望使用事务或表锁,因此同时尝试更新特定的祖先链不会引起混淆。

SQL Server,MariaDB的最新版本和PostgreSQL(以及其他版本)使用递归公用表表达式(您可以查找)实现分层查询。 Oracle为此使用了专门的START WITH ... CONNECT BY查询语法。

但是,如果您的数据具有很多级别的祖先,我强烈建议您尝试使用另一种方式来表示它。

关于使用您的唯一真实世界BANumber标识符作为主键而不是自动重写整数的问题:是。