php 如何使SQL数据库值与API值保持最新?

ffdz8vbo  于 2023-06-20  发布在  PHP
关注(0)|答案(1)|浏览(119)

我有一个SQL数据库,我正在使用它来存储一个非常大的API的内容(大约300万个结果),因为我必须对它进行几次查询以进行数据分析,所以调用API来执行此操作的成本太高。我目前有大约一个月前存储的API数据,但我需要一种方法来保持最新的API数据。
我尝试使用的API是Texas Mixed Beverage报告:https://data.texas.gov/dataset/Mixed-Beverage-Gross-Receipts/naix-2893
新的结果不断地被添加进来,并且一些列的值也会发生变化。我更新数据的计划是在用户加载我们的网页时运行一个脚本,检查最近一个月的数据是否在数据库中,如果没有,它会获取整个月的数据并更新/插入它,然后在接下来的几个月里做同样的事情,直到找到匹配。
这并没有很好地工作,我最终与重复在我的数据库,不知道为什么。任何帮助或提示是赞赏!以下是脚本:

function update_mixed_bev($conn)
{
    $last_date = date('Y-m-d');

    $count = 0;
    // if not in db
    while ($count == 0) {
        // get most recent entry to mixed bev report
        $url = 'https://data.texas.gov/resource/naix-2893.json?$limit=1&$where=obligation_end_date_yyyymmdd%20<=%20%27' . $last_date . '%27&$order=obligation_end_date_yyyymmdd%20DESC';
        $json = file_get_contents($url);
        $data = json_decode($json, true);

        $row = $data[0];

        // query to see if data exists in db
        $location_address = mysqli_real_escape_string($conn, $row['location_address']);
        $location_name = mysqli_real_escape_string($conn, $row['location_name']);
        $record_end_date = date('Y-m-d', strtotime($row['obligation_end_date_yyyymmdd']));
        $sql = "SELECT COUNT(*) FROM mixed_bev_data WHERE location_address='" . $location_address . "' AND record_end_date='" . $record_end_date . "' AND location_name='" . $location_name . "' AND beer_receipts=" . $row['beer_receipts'] . " AND total_receipts=" . $row['total_receipts'];

        $result = mysqli_query($conn, $sql);
        $count = mysqli_fetch_array($result)[0];

        if ($count == 0) {
            $url = 'https://data.texas.gov/resource/naix-2893.json?$where=obligation_end_date_yyyymmdd%20=%20%27' . $record_end_date . '%27&$order=obligation_end_date_yyyymmdd%20DESC';
            $json = file_get_contents($url);
            $data = json_decode($json, true);

            // for each of month data
            foreach ($data as $row) {
                $taxpayer_name = mysqli_real_escape_string($conn, $row['taxpayer_name']);
                $location_name = mysqli_real_escape_string($conn, $row['location_name']);
                $location_address = mysqli_real_escape_string($conn, $row['location_address']);
                $location_city = mysqli_real_escape_string($conn, $row['location_city']);
                $location_state = mysqli_real_escape_string($conn, $row['location_state']);
                $location_zip = mysqli_real_escape_string($conn, $row['location_zip']);
                $record_end_date = date('Y-m-d', strtotime($row['obligation_end_date_yyyymmdd']));
                $beer_receipts = intval($row['beer_receipts']);
                $total_receipts = intval($row['total_receipts']);

                $sql = "INSERT INTO mixed_bev_data (taxpayer_name, location_name, location_address, location_city, location_state, location_zip, record_end_date, beer_receipts, total_receipts)
VALUES ('$taxpayer_name', '$location_name', '$location_address', '$location_city', '$location_state', '$location_zip', '$record_end_date', $beer_receipts, $total_receipts)
ON DUPLICATE KEY UPDATE beer_receipts = $beer_receipts, total_receipts = $total_receipts, time = CURRENT_TIMESTAMP();";

                if (!mysqli_query($conn, $sql)) {
                    echo "Error: " . $sql . "<br>" . mysqli_error($conn);
                }
            }

        }

        $last_date = date('Y-m-d', strtotime($record_end_date . ' - 1 day'));

    }
}
dsekswqp

dsekswqp1#

两件事
1.从您的问题和UPDATE代码中可以明显看出,beer_receiptstotal_receipts列是您的数据,可以更改的数据。其他列标识packy(新英格兰酒类商店)和日期。
然而,当您检查是否已经有记录时,您会检查这两个 data 字段以及 identifying 字段中的匹配项。如果你从你的API得到不同的 * 数据 *,你的COUNT()查询将为零。也许不该这样这可能会导致一个dup。 1.看起来您使用了ON DUPLICATE KEY UPDATE来防止表中出现重复记录。如果不知道表的主键和任何UNIQUE键中有哪些列,则可能没有正确的键来防止重复。 这是两件需要检查的事情。 另外:如果这个政府数据是按月更新的,为什么不在更新发布后不久用一个cronjob在一夜之间更新它的副本呢?让你的用户等待你按需更新它,在我看来,这就像是他们抱怨你的应用程序速度慢的未来--因为你必须在他们等待的时候花时间更新它。除非你在API上有利率限制,否则一夜之间两三个超级跑车听起来并不是一个巨大的负担。特别是如果您的应用程序正在从govt API中删除一些白天流量,因为您有一个副本。 然后,**编辑**。 实现这一点的一个好方法是使用两个表。让我们调用一个表packy`--salesestablishment。其中:

  • packy_id一个自动递增的id,主键。你最好使用BIGINT,毕竟你在德克萨斯州。
  • taxpayer_namelocation_name。识别器。
  • location_address和其他属性

第二张table:

  • record_end_date主键首列
  • packy_id引用第一个表。PK中的第二列。
  • beer_receiptstotal_receipts数据。

这将为您提供packy_id,即每个机构的标识符。它可以让您高效地更新您的数据。

相关问题