Я работаю с MLS провайдером недвижимости (RETS).Каждые 48 часов мы будем извлекать данные с их сервера в задании cron в базу данных SQL.Мне поручено написать скрипт php, который будет запускаться после сброса данных с удаленного сервера в наши «сырые» таблицы.В этих необработанных таблицах все столбцы VARCHAR(255)
, и мы хотим переместить данные в оптимизированные таблицы.Прежде чем отправить свой сценарий парню, отвечающему за настройку работы cron, я подумал, есть ли более эффективный способ сделать это, чтобы я не выглядел глупо.
Вот что я делаю:
Всего 8 таблиц, 4 необработанных и 4 оптимизированных - все в одной базе данных.Имена необработанных столбцов таблицы не являются описательными, как, например, c1, c2, c2, c4 и т. Д. Это сделано намеренно, поскольку данные, поступающие в каждый столбец, могут измениться.Имена столбцов необработанной таблицы сопоставляются с правильными оптимизированными столбцами таблицы с помощью php, что-то вроде этого:
$tables['optimized_table_name1']['raw_table'] = 'raw_table_name1';
$tables['optimized_table_name1']['data_map'] = array(
'c1' => array( // <--- "c1" is the raw table column name
'column_name' => 'id',
// I use other values for table creation,
// but they don't matter to the question.
// Just explaining why the array looks like this
//'type' => 'VARCHAR',
//'max_length' => 45,
//'primary_key' => FALSE,
// etc.
),
'c9' => array('column_name' => 'address'),
'c25' => array('column_name' => 'baths'),
'c2' => array('column_name' => 'bedrooms') //etc.
);
Я делаю то же самое для каждой из 4 таблиц: SELECT * FROM
необработанная таблица,прочитайте массив конфигурации и создайте огромный оператор вставки SQL, TRUNCATE
оптимизированную таблицу, затем выполните запрос INSERT
.
foreach ($tables as $table_name => $config):
$raw_table = $config['raw_table'];
$data_map = $config['data_map'];
$fields = array();
$values = array();
$count = 0;
// Get the raw data and create an array mapped to the optimized table columns.
$query = mysql_query("SELECT * FROM dbname.{$raw_table}");
while ($row = mysql_fetch_assoc($query))
{
// Reading column names from my config file on first pass
// Setting up the array, will only run once per table
if (empty($fields))
{
foreach ($row as $key => $val)
{// Produces an array with the column names
$fields[] = $data_map[$key]['column_name'];
}
}
foreach ($row as $key => $val)
{// Assigns data to an array to be imploded later
$values[$count][] = $val;
}
$count++;
}
// Create the INSERT statement string
$insert = array();
$sql = "\nINSERT INTO `{$table_name}` (`".implode('`,`', $fields)."`) VALUES\n";
foreach ($values as $key => $vals)
{
foreach ($vals as &$val)
{
// Escape the data
$val = mysql_real_escape_string($val);
}
// Using implode for simplicity, could avoid the nested foreach if I wanted to
$insert[] = "('".implode("','", $vals)."')";
}
$sql .= implode(",\n", $insert).";\n";
// TRUNCATE optimized table and run INSERT query here
endforeach;
, который производит что-то вроде этого (только больше - максимум около 15 000 записей вtable, и одно оператор вставки на таблицу):
INSERT INTO `optimized_table_name1` (`id`,`beds`,`baths`,`town`) VALUES
('50300584','2','1','Fairfield'),
('87560584','3','2','New Haven'),
('76545584','2','1','Bristol');
Теперь я должен признать, что я был под крылом ORM в течение долгого времени и не в курсе моего ванильного mysql / php.Это довольно простая задача, и я хочу сделать код простым.
Мои вопросы:
- Является ли метод TRUNCATE / INSERT хорошим способом сделатьэто?
- Есть ли что-то в моем коде, что вы видите в качестве проблемы?Я знаю, что вы видите вложенные циклы foreach и просто содрогаетесь, но я хочу, чтобы код был как можно более чистым и избегал большого количества беспорядочной конкатенации строк (чтобы создать запрос на вставку).Как я уже сказал, я также давно не использовал нативные функции php для SQL.
- Мне кажется, что действительно не имеет значения, не оптимизирован ли код, если он запускается в 3 часа ночи каждые 2 дня, Имеет ли значение ?Будет ли этот код преформироваться? ОК?
- Есть ли лучшая общая стратегия для выполнения этой задачи?
- Нужно ли использовать транзакции?
- Как узнатьошибок, которые могут возникнуть в скриптах cron?
Извиняюсь, если я не использую правильный жаргон cron, для меня это ново.