Оптимизация размера базы данных




Принцип обмена данными из 1С с сайтом (на MySQL) и выдачи (публикации) этих данных по запросу.
PHP-Скрипт автоматической загрузки данных из файла данных в формате CSV в базу данных сайта работающего на WordPress.

В продолжение моей темы: 1С:Альфа-Авто Автосалон Автосервис: обмен с сайтом.
С помощью данного скрипта можно загружать в автоматическом режиме, по расписанию, данные сервисных книжек (ремонтов авто) из 1С:Альфа-Авто Автосалон Автосервис.
Также можно загружать данные в ручном режиме: для этого делается скрытая страница, где размещается специальная кнопка.
Комментарии размещенные внутри скрипта разъяснят логику и порядок действия.
Комментарии с "/////    echo" использовались для отладки.
Дополнительно создана таблица для журналирования результатов загрузки данных.
Скрипт включает в себя защиту от SQL инъекций (думаю безопасность соблюдена в полной мере).
В кратце:
1. Пишется скрипт, который запускает этот.
2. Создается регламентное задание в WordPress, по которому запускается скрипт из п.1. 
3. Этот скрипт осуществляет проверку на существование файла обмена в папке.
4. Если данные не новые, загрузка не производится.
5. Если данные новые, очищается таблица сервисных книжек.
6. Загружаются новые данные.

Собственно сам скрипт:

<?php // Полная загрузка сервисных книжек, создан 2024-01-05 12:44:55

global $wpdb2;
global $failure;
global $file_hist;

/////  echo '<H2><b>Старт загрузки</b></H2><br>';

$failure=FALSE;
//подключаемся к базе
$wpdb2 = include_once 'connection.php'; ; // подключаемся к MySQL
// если не удалось подключиться, и нужно оборвать PHP с сообщением об этой ошибке
if (!empty($wpdb2->error))
{
/////   echo '<H2><b>Ошибка подключения к БД, завершение.</b></H2><br>';
$failure=TRUE;
wp_die( $wpdb2->error );
}

$m_size_file=0;
$m_mtime_file=0;
$m_comment='';
/////проверка существования файлов выгрузки из 1С
////файл выгрузки сервисных книжек
$file_hist = ABSPATH.'/_1c_alfa_exchange/AA_hist.csv';
if (!file_exists($file_hist))
{
/////   echo '<H2><b>Файл обмена с сервисными книжками не существует.</b></H2><br>';
$m_comment='Файл обмена с сервисными книжками не существует';
$failure=TRUE;
}

/////инициируем таблицу лога
/////если не существует файла то возврат и ничего не делаем
if ($failure){
///включает защиту от SQL инъекций и данные можно передавать как есть, например: $_GET['foo']
/////   echo '<H2><b>Попытка вставить запись в лог таблицу</b></H2><br>';
$insert_fail_zapros=$wpdb2->insert('vin_logs', array('time_stamp'=>time(),'last_mtime_upload'=>$m_mtime_file,'last_size_upload'=>$m_size_file,'comment'=>$m_comment));
wp_die();
/////    echo '<H2><b>Возврат в начало.</b></H2><br>';
return $failure;
}
/////проверка лога загрузки, что бы не загружать тоже самое
$masiv_data_file=stat($file_hist);   ////передаем в массив свойство файла
$m_size_file=$masiv_data_file[7];    ////получаем размер файла
$m_mtime_file=$masiv_data_file[9];   ////получаем дату модификации файла
////создаем запрос на получение последней удачной загрузки
////выбираем по штампу времени создания (редактирования) файла загрузки AA_hist.csv, $m_mtime_file

/////   echo '<H2><b>Размер файла: '.$m_size_file.'</b></H2><br>';
/////   echo '<H2><b>Штамп времени файла: '.$m_mtime_file.'</b></H2><br>';
/////   echo '<H2><b>Формирование запроса на выборку из лога</b></H2><br>';
////препарируем запрос
$text_zaprosa=$wpdb2->prepare("SELECT * FROM `vin_logs` WHERE `last_mtime_upload` = %s", $m_mtime_file);
$results=$wpdb2->get_results($text_zaprosa);

if ($results)
{   foreach ( $results as $r)
{
////если штамп времени и размер файла совпадают, возврат
if (($r->last_mtime_upload==$m_mtime_file) && ($r->last_size_upload==$m_size_file))
{////echo '<H2><b>Возврат в начало, т.к. найдена запись в логе.</b></H2><br>';
$insert_fail_zapros=$wpdb2->insert('vin_logs', array('time_stamp'=>time(),'last_mtime_upload'=>$m_mtime_file,'last_size_upload'=>$m_size_file,'comment'=>'Загрузка отменена, новых данных нет, т.к. найдена запись в логе.'));
wp_die();
return $failure;
}
}
}
////если данные новые, пишем в лог запись о начале загрузки
/////echo '<H2><b>Попытка вставить запись о начале загрузки в лог таблицу</b></H2><br>';
$insert_fail_zapros=$wpdb2->insert('vin_logs', array('time_stamp'=>time(),'last_mtime_upload'=>0, 'last_size_upload'=>$m_size_file, 'comment'=>'Начало загрузки'));

////очищаем таблицу
$clear_tbl_zap=$wpdb2->prepare("TRUNCATE TABLE %s", 'vin_history');
$clear_tbl_zap_repl=str_replace("'","`",$clear_tbl_zap);
$results=$wpdb2->query($clear_tbl_zap_repl);
/////   echo '<H2><b>Очистка таблицы сервисных книжек</b></H2><br>';
if (empty($results))
{
/////   echo '<H2><b>Ошибка очистки таблицы книжек, завершение.</b></H2><br>';
//// если очистка не удалась, возврат
$failure=TRUE;
wp_die();
return $failure;
}

////загружаем данные
$table='vin_history';         // Имя таблицы для импорта
//$file_hist Имя CSV файла, откуда берется информация     // (путь от корня web-сервера)
$delim=';';          // Разделитель полей в CSV файле
$enclosed='"';      // Кавычки для содержимого полей
$escaped='\

16 Comments

  1. SergDi

    2,5 млн o_O ?

    хорошая идея

    Reply
  2. recon

    Эммм… Пометили на удаление документы и плакали наши цены ?

    Reply
  3. tormozit

    2 500 000 * 365 = 912 500 000,

    Миллиард записей к концу года. Может быть автор преувеличивает?

    Reply
  4. Поручик

    Уменьшить размер базы помогает очистка регистра сведений СписанныеТовары от записей закрытого периода.

    (2) Неактуальные цены почему бы не удалять?

    Reply
  5. Nykyanen

    (2) recon, Не внимательно читаем батенька.

    «Еще не забываем очистить потом табличные части документов, тех которые уже были созданы.»

    Зачем же в итоге повторять текст статьи который выше написан.

    Reply
  6. Nykyanen

    (3) tormozit, примерно так и было.

    Правда там выпадали выходные и праздничные дни.

    Проблема возникла после 3 месяцев использования, новой системы хранения цен.

    Но быстро была решена. См.текст публикации.

    Reply
  7. Nykyanen

    (4) Поручик, у каждого своя специфика.

    Анализ размеров таблиц показал, что проблемное место у нас «цены номенклатуры».

    Возможно, со временем придется бороться и с другими таблицами.

    Reply
  8. hogik

    (1)(3)

    Интереснее посчитать в другую сторону. 😉

    2 500 000 / 24 / 60 / 60 = 29 в секунду.

    Цена используется в «Управление торговлей».

    Если с такой скоростью меняется цена, то на это не сможет «реагировать» ни покупатель, ни продавец. Думаю, на самом деле цена не меняется, а записывается в базу многократно одинаковые значения. Что есть ошибка в алгоритме обработки цен и/или схеме базы данных.

    Reply
  9. Nykyanen

    (8) hogik, Надо учить мат часть.

    Запись в регистре сведений цены номенклатуры записываються с переодичностью — день.

    Значит сама платформа будет ругаться, если записывать вторую цену в течении одного дня!!!

    Просто большой справочник номеклатуры. А думаю не меньший справочник в комусе или озоне.

    А дальше все зависит много от чего. Например, варианты:

    1) мы по какомому алгоритму каждый день пересчитываем цены, например от курса ЦБ.

    2) мы перепродаем товар других фирм, они нам шлют каждый день свой новый прайс.

    и тд и тп.

    Может у вас быть сразу все варианты? Все возможно.

    Зачем нам хранить столько цен?

    Вроде все логично, что бы потом можно было разобрать, почему была цена именно такая в момент покупки/продажи.

    Reply
  10. hogik

    (9)

    «Надо учить мат часть.»(с)

    МатЧасть — это 1С и её регистры? 🙂

    Я обратил Ваше внимание на задачу — как она есть.

    А не как она сделана в некой системе (конфигурации).

    «что бы потом можно было разобрать, почему была цена именно такая в момент покупки/продажи»(с)

    Если проводить анализ цен в «мировом» масштабе, то в базе можно сохранять еще больше, чем 2.5 миллиона записей в день. 😉 А в момент «покупки/продажи» используется конкретная цена продажи «соотнесенная» с ценой конкретной закупки. Реальная цена продажи и закупки не может меняться с такой скоростью. Сумма конкретной продажи может меняться, например, из-за скидки, формы оплаты, объема закупки и т.д. Но, эта информация не о цене, а о конкретной сделке. И хранится она, надеюсь, в другом месте.

    А если требуется провести анализ (сравнение) цен конкретной сделки Вашей конторы с ценами на рынке вообще, то совершенно не требуется их хранить, например, с ежедневным пересчетом по курсу ЦБ. Т.е. это другая задача, алгоритм, схема базы данных…

    Reply
  11. Nykyanen

    (10) hogik, если тебе хочется пофлудить, найди другую тему.

    Не нравиться, так и напиши. Только сначала прочитай о том, что комментируешь.

    «А не как она сделана в некой системе (конфигурации).» — в публикации написано «В базе Управление Торговлей 10».

    Цена покупки/продажи, скидка сохраняется, в документе.

    Если тебе хочется, можешь <<проводить анализ цен в «мировом» масштабе»>>.

    У нас, есть такая потребность сохранять все цены. Задача решена. Всё ОК.

    У многих хуже и без таких сложных задач.

    Например, не закрываются регистры, когда должны и таблицы итогов пухнут, но не кому до этого дела нет, пока место не кончиться.

    Reply
  12. hogik

    (11)

    «Не нравиться, так и напиши.»(с)

    Очень нравится. 😉 Отличное решение. Я его, даже, и не обсуждаю.

    Вам задан простой вопрос в развернутой форме. Флудом. 🙂

    Вы уверены, что требуется «сохранять все цены» таким «лобовым» способом?

    Лично у меня вызвало недоумение не Ваше решение, а сама задача.

    Reply
  13. Psylocibine

    Интересное решение, не хочется даже вникать, зачем такое количество записей в базе, просто на заметочку возьму)

    А как выявляли проблемные места? Что использовали для анализа таблиц?

    Reply
  14. Nykyanen

    (13) Psylocibine, можно поискать тут или в инете.

    Я когда то давно позаимствовал идею подпилил для себя.

    Думаю вам подойдут и то что предлогаю тут:

    Для файловой — http://infostart.ru/public/82178/

    Для SQL — http://infostart.ru/public/95193/

    Reply
  15. Nykyanen

    (12) hogik, спасибо за вопросы.

    «Цены хранить в некоторой у.е. без пересчета» — не получается.

    Я знаю что некоторые из поставщиков считают свой прайс от у.е. по курсу ЦБ или своего банка «+» какой то процент. Некоторые еще применяют метод устанения дребезга цен (это если новая цена отличается от старой всего на 1%, то оставить старую. Порог у каждого свой).

    Идея конечно была привязаться и к этому, но после месяца анализа цен выяснилось, что они могут менять свои формулы расчета, в итоге из-за этого у нас тоже переставало работать коррекно. Понятно и так, что секретов нам не кто раскрывать не будет кто как считает.

    Reply
  16. zfilin

    (8) hogik, Та, не. Вы количество записей на количество позиций номенклатуры (а может еще и на количество категорий цен) поделите, а потом уже на время. А-то со здоровой номенклатурой, если так «в лоб» делить, то не то что 29 раз в секунду, и больше может быть. =)

    Reply

Leave a Comment

Ваш адрес email не будет опубликован. Обязательные поля помечены *