Я не самый опытный разработчик, однако мы с друзьями собрались для проекта и создали автоматизированную систему полива растений. Я отвечаю за то, чтобы сайт работал и отображал статистику, создаваемую системой.
Как мой код очистить таблицу перед добавлением новых данных из файла 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.";
}
}
}
?>
TRUNCATE name
очень быстро и эффективно, но сбросит все AUTO_INCREMENT
ценности. Если у вас есть другие таблицы, которые ссылаются на эту таблицу через идентификаторы такого рода, это может быть проблематично, это может связать данные со случайными местами.
DELETE FROM name
удалит все, но не сбросит AUTO_INCREMENT
счетчики. Это имеет тенденцию быть медленнее, особенно в больших таблицах с большим количеством конфликтов, но имеет преимущество в том, что не использует идентификаторы повторно.
Вам нужно будет определить, какой из двух подходит для вашего конкретного случая использования. Для таблицы, которая не является перекрестно связанной, TRUNCATE
обычно работает лучше всего.
Я предпочитаю этот способ:
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
,
ПЕРЕИМЕНОВАНИЕ атомное.
Стол real
всегда доступен (без простоя).
Это скорее дополнение к уже правильному ответу @ tadman, но слишком длинное для комментария.
Разница в производительности заключается в том, что TRUNCATE
более или менее просто удаляет файл данных таблицы и создает новый пустой файл, который представляет собой одну большую, довольно непрерывную операцию ввода-вывода, с которой ваша ОС может справиться довольно эффективно.
С другой стороны, серия DELETE
Statement — это множество крошечных операций ввода-вывода, которые будут перегружать ваш диск, а также не восстанавливать пространство в файлах резервных копий данных.
если ты иметь идти DELETE
маршрут Я настоятельно рекомендую заключить все удаления внутри транзакции, что поможет в некоторой степени оптимизировать ввод-вывод. Затем, как только вы получите все импортированные данные (которые также должны быть в транзакции, предпочтительно даже ту же), вы можете запустить OPTIMIZE TABLE
операция по восстановлению любого неиспользуемого дискового пространства из файлов резервных копий, при условии, что существует достаточно значительная разница в размере данных, чтобы это оправдать.
Третий вариант:
last_updated
,START TRANSACTION;
SET @start = NOW();
INSERT INTO table ... ON DUPLICATE KEY UPDATE ...;
DELETE FROM table WHERE last_updated < @start;
COMMIT;
В качестве бонуса, если вы используете такие транзакции, нет момента, когда ваше приложение будет иметь «плохой» или отсутствующий набор данных.
Refs: