我目前正在尝试为使命召唤 4 创建一个日志解析器。解析器本身位于 php 中,并读取特定服务器的日志文件的每一行,并使用 mysqli 将所有统计信息写入数据库。数据库已经到位,我相当肯定(以我有限的经验)它们组织良好。但是,我不确定应该以何种方式将更新/插入查询发送到数据库,或者更确切地说,哪种方式是最佳的。
我的数据库结构如下
-- --------------------------------------------------------
--
-- Table structure for table `servers`
--
CREATE TABLE IF NOT EXISTS `servers` (
`server_id` tinyint(3) unsigned NOT NULL auto_increment,
`servernr` smallint(1) unsigned NOT NULL default '0',
`name` varchar(30) NOT NULL default '',
`gametype` varchar(8) NOT NULL default '',
PRIMARY KEY (`server_id`),
UNIQUE KEY (`servernr`)
) ENGINE=MyISAM DEFAULT CHARSET=latin1;
-- --------------------------------------------------------
--
-- Table structure for table `players`
--
CREATE TABLE IF NOT EXISTS `players` (
`player_id` tinyint(3) unsigned NOT NULL auto_increment,
`guid` varchar(8) NOT NULL default '0',
`fixed_name` varchar(30) NOT NULL default '',
`hide` smallint(1) NOT NULL default '0',
PRIMARY KEY (`player_id`),
UNIQUE KEY (`guid`)
) ENGINE=MyISAM DEFAULT CHARSET=latin1;
-- --------------------------------------------------------
--
-- Table structure for table `playerstats`
--
CREATE TABLE IF NOT EXISTS `playerstats` (
`pid` mediumint(9) unsigned NOT NULL auto_increment,
`guid` varchar(8) NOT NULL default '0',
`servernr` smallint(1) unsigned NOT NULL default '0',
`kills` mediumint(8) unsigned NOT NULL default '0',
`deaths` mediumint(8) unsigned NOT NULL default '0',
# And more stats...
PRIMARY KEY (`pid`)
) ENGINE=MyISAM DEFAULT CHARSET=latin1;
简而言之,服务器和玩家包含独特的实体,它们组合在玩家统计中(即特定服务器中玩家的统计数据)。除了统计数据之外,他们还被赋予了一个玩家 id (pid) 以供以后的数据库中使用。同样,该数据库包含表武器(唯一武器)和武器统计(服务器中武器的统计数据)、附件和附件统计以及地图和地图统计。一旦我完成了所有这些工作,我想在这些统计数据之间实现更多关系(即,使用 pid 和 wid 在特定服务器中特定武器的玩家统计数据)。
PHP 解析器通过 http 复制每个服务器的日志(有 6 个 atm),然后每 5 分钟读取一次(我对此还不太确定)。可以假设在这个解析过程中,每个表都必须被查询(使用 UPDATE 或 INSERT)至少一次(并且可能更多)。现在,我有很多关于如何发送查询的选项(我知道):
1:使用常规查询,即
$statdb = new mysqli($sqlserver,$user,$pw, $db);
foreach( $playerlist as $guid => $data ){
$query = 'INSERT INTO `playerstats`
VALUES (NULL, '$guid', $servernr, $data[0], $data[1])';
$statdb->query($query);
}
2:使用多查询
$statdb = new mysqli($sqlserver,$user,$pw, $db);
foreach( $playerlist as $guid => $data ){
$query = "INSERT INTO `playerstats`
VALUES (NULL, '$guid', $servernr, $data[0], $data[1]);";
$totalquery .= $query;
}
$statdb->multi_query($totalquery);
3:使用准备好的语句;我还没有真正尝试过这个。这似乎是一个好主意,但我必须为每张桌子准备一个声明(我认为)。这甚至可能吗?如果可以,它会有效吗?
4:正如您从上述代码中可能看到的那样,我最初将每个玩家、武器、地图等的所有统计数据都统计到一个数组中。一旦解析器读取了整个文件,它就会向 mysql 服务器发送一个带有这些累积统计信息的查询。但是,我在其他日志解析器中也看到(更多时候不是),只要解析了日志文件的新行,就会发送查询,例如:
UPDATE playerstats
SET kills = kills+1
WHERE guid = $guid
这对我来说似乎效率不高,但是我又一次开始使用 php 和 sql,所以我知道什么:>
所以,简而言之;考虑到 logparser 逐行读取每一行,查询数据库的最有效方法是什么?当然,任何其他意见或建议总是受欢迎的。