我正在与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条记录,每个表一个插入语句):
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。这是一个非常简单的任务,我想保持代码简单。
我的问题:
如果我不使用正确的cron术语,请道歉,这对我来说是新的。
答案 0 :(得分:1)
保持简单。 ORM会因此而膨胀。
数目:
mysql -u username --password=password < import_file.sql
将数据加载到服务器中。所以我将我的文件存储在磁盘上的某处,所以我总是看看它。甚至可以编辑一次性校正负载。但你仍然可以通过将sql语句写入文件来实现。0 7 * * 0 /path/to/php -c /path/to/php.ini /path/to/script.php 2> /tmp/errors_file
因此你可以在第一个脚本运行后创建SECOND脚本runnin通过电子邮件通知script.php中的错误或....通知你的任何方式喜欢。我更愿意register_shutdown_functions检查error_file
,如果它不为空,请通知您并在之后将其删除。我的意见,但我希望我的回答有所帮助。