PHP: 如何索引关联数组中的多个键?
PHP: how to index multiple keys in associative array?
我将使用 PHP 构建一个 "simple" RESTful 网络服务。我将提供 APIs 来访问我在网络服务器上收集的一些数据(通过 JSON)。主要数据 table 对于 public API 方法是只读的,并且将由单例私有方法定期写入。用户将能够将一些数据写入私有 tables。
我想避免 - 如果可能的话 - 增加处理数据库(甚至不是 SQLite)的复杂性;因此,我计划在磁盘上的文件中序列化我的数据,并在调用 PHP 脚本时在内存中反序列化它们。
为每个 PHP 实例将整个数据加载到内存中不会对 Web 服务器造成太大负担(我希望)... (数字是这些:主要数据 table size计划最大100k条记录,每条最大记录大小1k字节,所以数据大小将有最大可能大小100MB,通常大小10MB;最大并发数用户永远不会超过 100;这些数字是设计使然,不可能变大)。
问题是:我可以使用PHP关联数组对多个键进行查询吗?
一个例子:这是我简化的主要数据结构:
<?php
$data = [
"1" => [
"name" => "Alice",
"zip" => "12345",
"many" => "A",
"other" => "B",
"fields" => "C",
],
"2" => [
"name" => "Bob",
"zip" => "67890",
"many" => "X",
"other" => "Y",
"fields" => "Z",
],
// ...
];
?>
要通过主键访问记录,我当然应该这样做:
$key = "12345";
$record = $data[$key];
但是,如果我想(高效地,即避免顺序扫描...)通过不同的键访问一个或多个记录,比如 "zip" 怎么办?当然,这些键可能包含重复值。我想出的唯一解决方案是为 "index" 的每个辅助键构建一个新数组,并将其与主数据一起序列化 table...
例如:
$zip_idx = [
"12345" => [ "1", "355", "99999", ],
"67890" => [ "2", "732", ],
// ...
];
然后:
$zip = "67890";
$records = $zip_idx[$zip];
所以:
您是否发现此设计有任何问题、不一致或缺乏灵活性?
您能提出更智能或更紧凑的解决方案吗?
您有什么考虑或异议吗?
我不会再为其他 "indexes" 创建任何阵列。
只是做一个很好的 class 来处理查询。 zip 查询可能如下所示
class Data{
protected $data;
public function getByZip($zip){
return array_filter($this->getData(),function($item)use($zip){
if($item['zip'] == $zip) return true;
return false;
});
}
public function setData($data){
$this->data = $data;
}
public function getData($data){
return $this->data;
}
}
$dataArray = [
"1" => [
"name" => "Alice",
"zip" => "12345",
"many" => "A",
"other" => "B",
"fields" => "C",
],
"2" => [
"name" => "Bob",
"zip" => "67890",
"many" => "X",
"other" => "Y",
"fields" => "Z",
],
// ...
];
$data = new Data();
$data->setData($dataArray);
$result = $data->getByZip(12345);
你也可以使用数组中的userid,这样查询。
问候
编辑:针对您的性能问题 ->
正常情况下,您将数据库用于可达到 100MB 的数据。
原因是 - 如果您使用数组文件数据库 - 必须将 100MB 的整个文件读入内存。这不是什么大问题,但大多数提供商对您的应用程序使用 128MB 的最大内存限制,这可能会导致问题。
我将使用 PHP 构建一个 "simple" RESTful 网络服务。我将提供 APIs 来访问我在网络服务器上收集的一些数据(通过 JSON)。主要数据 table 对于 public API 方法是只读的,并且将由单例私有方法定期写入。用户将能够将一些数据写入私有 tables。
我想避免 - 如果可能的话 - 增加处理数据库(甚至不是 SQLite)的复杂性;因此,我计划在磁盘上的文件中序列化我的数据,并在调用 PHP 脚本时在内存中反序列化它们。
为每个 PHP 实例将整个数据加载到内存中不会对 Web 服务器造成太大负担(我希望)... (数字是这些:主要数据 table size计划最大100k条记录,每条最大记录大小1k字节,所以数据大小将有最大可能大小100MB,通常大小10MB;最大并发数用户永远不会超过 100;这些数字是设计使然,不可能变大)。
问题是:我可以使用PHP关联数组对多个键进行查询吗?
一个例子:这是我简化的主要数据结构:
<?php
$data = [
"1" => [
"name" => "Alice",
"zip" => "12345",
"many" => "A",
"other" => "B",
"fields" => "C",
],
"2" => [
"name" => "Bob",
"zip" => "67890",
"many" => "X",
"other" => "Y",
"fields" => "Z",
],
// ...
];
?>
要通过主键访问记录,我当然应该这样做:
$key = "12345";
$record = $data[$key];
但是,如果我想(高效地,即避免顺序扫描...)通过不同的键访问一个或多个记录,比如 "zip" 怎么办?当然,这些键可能包含重复值。我想出的唯一解决方案是为 "index" 的每个辅助键构建一个新数组,并将其与主数据一起序列化 table...
例如:
$zip_idx = [
"12345" => [ "1", "355", "99999", ],
"67890" => [ "2", "732", ],
// ...
];
然后:
$zip = "67890";
$records = $zip_idx[$zip];
所以:
您是否发现此设计有任何问题、不一致或缺乏灵活性?
您能提出更智能或更紧凑的解决方案吗?
您有什么考虑或异议吗?
我不会再为其他 "indexes" 创建任何阵列。
只是做一个很好的 class 来处理查询。 zip 查询可能如下所示
class Data{
protected $data;
public function getByZip($zip){
return array_filter($this->getData(),function($item)use($zip){
if($item['zip'] == $zip) return true;
return false;
});
}
public function setData($data){
$this->data = $data;
}
public function getData($data){
return $this->data;
}
}
$dataArray = [
"1" => [
"name" => "Alice",
"zip" => "12345",
"many" => "A",
"other" => "B",
"fields" => "C",
],
"2" => [
"name" => "Bob",
"zip" => "67890",
"many" => "X",
"other" => "Y",
"fields" => "Z",
],
// ...
];
$data = new Data();
$data->setData($dataArray);
$result = $data->getByZip(12345);
你也可以使用数组中的userid,这样查询。
问候
编辑:针对您的性能问题 -> 正常情况下,您将数据库用于可达到 100MB 的数据。 原因是 - 如果您使用数组文件数据库 - 必须将 100MB 的整个文件读入内存。这不是什么大问题,但大多数提供商对您的应用程序使用 128MB 的最大内存限制,这可能会导致问题。