如何在使用php导入csv之前清除表?

l2osamch  于 2021-06-25  发布在  Mysql
关注(0)|答案(3)|浏览(310)

我不是最熟练的开发人员,但是我和我的朋友们为一个项目组织起来,创建了一个植物自动浇水系统。我的职责是让网站工作并显示系统创建的统计数据。
在从csv文件添加新数据之前,如何让代码清除表?
以下是索引页上显示的代码:

<!-- Importing the CSV -->

        <div id="wrap">
        <h2 class='sub-header'>Upload .csv to refresh data</h2>
          <?php
            include("csv.php");
            $csv = new csv();
            if ( isset($_POST['sub'])) {
              $csv->import($_FILES['file']['tmp_name']);
            }
          ?>

          <form method="post" enctype="multipart/form-data">
            <input type="file" name="file" class="btn btn-info"><br>
            <input type="submit" name="sub" value="Import" class="btn btn-success"> 
          </form>
        </div>
      </div>
    </div>

以下是php文件:

<?php
class csv extends mysqli
{
    private $state_csv = false;
    public function __construct()
    {
        parent::__construct("localhost","root","raspberry","statistics");
        if ($this->connect_error) {
            echo "Failed to connect to the database: ". $this->connect_error;
        }
    }
    public function import($file)
    {
        $file = fopen($file, 'r');
        while ($row = fgetcsv($file)) {
            $value = "'". implode("','", $row) ."'";
            $q = "INSERT INTO data(moisture_of_soil,temperature,humidity,light_levels,last_updated) VALUES(". $value .")";
            if ( $this->query($q) ) {
                $this->state_csv = true;
            }else {
                $this->state_csv = false;
            }
        }
        if ($this->state_csv) {
            echo "<meta http-equiv='refresh' content='0'>";
        } else {
            echo "Something went wrong.";
        }
    }
}
?>
yjghlzjz

yjghlzjz1#

我更喜欢这样:

CREATE TABLE new LIKE real;   (or spell out the schema)
LOAD DATA .. INTO new ...;
RENAME TABLE real TO old, new TO real;
DROP TABLE old;

唯一慢的部分是 LOAD .
重命名是原子的。
table real 始终可用(无停机)。

x7yiwoj4

x7yiwoj42#

TRUNCATE name 是非常迅速和有效的,但会重置所有 AUTO_INCREMENT 价值观。如果有其他表通过这些标识符引用此表,这可能会有问题,它可能会将数据链接到随机位置。 DELETE FROM name 将删除所有内容,但不会重置 AUTO_INCREMENT 计数器。它往往比较慢,特别是在有大量争用的大型表上,但它的优点是不回收标识符。
您需要确定这两个选项中哪一个适合您的特定用例。对于一个没有交叉引用的表, TRUNCATE 通常效果最好。

ldxq2e6h

ldxq2e6h3#

这更像是对@tadman已经正确答案的补充,但形式太长,无法发表评论。
性能差异在于 TRUNCATE 或多或少只是删除表中的数据文件,并生成一个新的空文件,这是一个很大的、相当连续的io操作,您的操作系统可以非常有效地处理它。
另一方面,一系列 DELETE 语句是许多微小的io操作,它们会使磁盘陷入困境,也不会恢复备份数据文件中的任何空间。
如果你必须去 DELETE route我强烈建议将所有删除都包含在事务中,这将在一定程度上有助于优化io。然后,一旦导入了所有数据(也应该在事务中,最好是同一个事务中),就可以运行 OPTIMIZE TABLE 从备份数据文件中恢复任何未使用的磁盘空间的操作,假设数据大小有足够大的差异来保证。
第三种选择:
添加一个基本上 last_updated .
START TRANSACTION; SET @start = NOW(); 回路: INSERT INTO table ... ON DUPLICATE KEY UPDATE ...; DELETE FROM table WHERE last_updated < @start; COMMIT; 另外,如果您使用的是这样的事务,那么您的应用程序不会出现“坏”或丢失数据集的时间点。
参考文献:
https://dev.mysql.com/doc/refman/5.7/en/sql-syntax-transactions.html
https://dev.mysql.com/doc/refman/5.7/en/insert-on-duplicate.html

相关问题