@rodion11
php dev

Как правильно обработать строки из бд?

Задача получить строки из большой таблицы, изменить каждую строку согласно определенным правилам и вставить в другую таблицу.
Например на входе строка:
id = 17
name = victor
role = admin
Мы ее меняем согласно правилам, например id = id + 1000; name переводим на русский, role нужно чтобы начиналось с большой буквы.
В другую таблицу мы должны добавить
1017, Виктор, Admin

Хочется решить задачу максимально правильно.

Есть класс Database, паттерн singleton.
В нем создается подключение к бд и имеются методы для вставки, обновления и получения строк. Например:
function getRecords() {
    $info= array();
    $res = $this->connection->query("SELECT * FROM `table`");
    while ($row = $res->fetch_assoc()) {
       $info[] = $row;
    }
    return $info; 
}

Данный подход для большого числа строк не подойдет, можно ли переписать так?
public function getRecords() {
    $info= array();
    return $this->connection->query("SELECT * FROM `table`"); 
}


А дальше не совсем понятно как быть, на ум приходит такое решение, но мне кажется оно плоховато.
$db = new Database();
foreach ($db->getRecords() as $arr) {
    //класс Row тут не знаю, нужен или нет. 
    //если делать в нем public переменные id, role, name, то это аналог массива получается. 
    //создаем класс на основе строки из бд
    $row = new Row($arr);

    //передаем его классу, который будет улучшать поля
    $improve = new Improve($row);

    $improve->translateName();
    $improve->fixId();
    $improve->fixRole();

    //передаем массив функции, которая добавит в бд обработанную строку
    $db->addRow($row->returnArray());
}


Если кратко:
1) Правильно ли переписан метод getRecords()? Если нет, то как такое решается
2) Как правильно спроектировать обработку строки? Мне кажется текущий вариант плох.

Спасибо!
  • Вопрос задан
  • 275 просмотров
Пригласить эксперта
Ответы на вопрос 2
romash
@romash
web-разработчик
Сделав
return $this->connection->query("SELECT * FROM `table`");

, вы вернули из метода getRecords() не массив, а... не уверен, как это называется, но цикл
foreach ($db->getRecords() as $arr)
точно работать не будет.
Можете вместо этого цикла делать как-то так:
$results = $db->getRecords();
while ($row = $results->fetch_assoc())
{
    // Здесь $row - массив с индексами id, name, role
    // Изменяете его и заносите в новую таблицу сразу
}
Ответ написан
DmitriyEntelis
@DmitriyEntelis
Думаю за деньги
Самое главное что нужно учесть в это задаче - если это живые обновляемые данные, то получение и обновление должны находиться в рамках одной транзакции.
Делая SELECT * FROM `table`, а потом обновляя записи в цикле - вы имеете огромные шансы что за это время другой поток как-то обновит таблицу, и ваш код вставит старое значение.

Ну и я лично не стал бы городить класс Improve ради разовой задачи, это проще все описать в функции.

Советовать что-то еще сложно, не зная реальных условий (сколько данных, как они обновляются, дополняются, какие требования к доступности на время обновления) - это всё тонкая тема, хаков много разных можно придумать.
Ответ написан
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы
YCLIENTS Москва
от 200 000 до 350 000 ₽
Ведисофт Екатеринбург
от 25 000 ₽
ИТЦ Аусферр Магнитогорск
от 100 000 до 160 000 ₽
24 апр. 2024, в 10:32
400000 руб./за проект
24 апр. 2024, в 10:12
10000 руб./за проект