1

我对项目中的所有实体使用 Phalcon\Mvc\Model(以保持标准化)。今天我不得不在我的 mysql 数据库中导入 maxmind geoip 数据库来实现一些实体和 maxmind 位置(和块)之间的本地关系。

Maxmind数据库默认以csv形式交付,那么如何在mysql中进行组织——是每个开发者都需要根据自己的需求来解决的问题。Maxmind 数据库包含 2 个文件:

  1. GeoLiteCity-Blocks.csv(存储 ip 范围)
  2. GeoLiteCity-Location.csv(存储有关位置的信息)

大多数教程建议使用以下表定义来存储具有 ip 范围的表:

CREATE TABLE IF NOT EXISTS `GeoLiteCity_Blocks` (
  `startIpNum` int(10) unsigned NOT NULL,
  `endIpNum` int(10) unsigned NOT NULL,
  `locId` int(10) unsigned NOT NULL,
  PRIMARY KEY (`startIpNum`,`endIpNum`)
) ENGINE=InnoDB;

如您所见,有复合主键。在 Phalcon\Mvc\Model 中使用这样的键可以吗?我想有一些限制(从逻辑上讲,它们应该存在,例如,我无法预测 Phalcon\Mvc\Model::findFirst($key) 方法的行为)

真的,我不在乎磁盘大小,这个表将使用,对我来说只有一件事很重要 - 性能。此外,我想保持所有模型标准化,而不是记住每个实体/表的大量小方面。

所以,我的问题是:是否可以使用 Phalcon\Mvc\Model 和复合键,或者最好多制作一个id列,这将是主键并添加索引startIpNum并使endIpNum选择更快?

4

1 回答 1

3

Phalcon\Mvc\Model 可用于具有复合主键的表。但是,findFirst 快捷方式不可用,您可以执行以下操作:

GeoLiteBlocks::findFirst(array(
   'startipnum = ?0 AND endipnum = ?1',
   'bind' => array($start, $end)
));

此外,可以在模型中添加一种方法来减少编码:

class GeoLiteBlocks extends Phalcon\Mvc\Model
{
    public function static findBlock($start, $end)
    {
        return self::findFirst(array(
           'startipnum = ?0 AND endipnum = ?1',
           'bind' => array($start, $end)
        ));
    }
}
于 2013-02-04T18:26:28.927 回答