2015-01-21 3 views
0

나는 PHP로 "간단한"RESTful 웹 서비스를 만들 예정이다. 웹 서버에서 수집 한 일부 데이터 (JSON을 통해)에 액세스하기위한 API를 제공 할 것입니다. 주 데이터 테이블은 공용 API 메소드에 대해 읽기 전용이며 일정한 시간 간격으로 싱글 톤 개인 메소드에 의해 작성됩니다. 사용자는 일부 데이터를 개인 테이블에 쓸 수 있습니다.PHP : 연관 배열에서 여러 개의 키를 인덱싱하는 방법은 무엇입니까?

가능한 경우 데이터베이스 (SQLite조차도 포함하지 않음) 처리의 복잡성을 추가하지 않으려합니다. 그래서, 디스크상의 파일에 대한 데이터를 직렬화하고, PHP 스크립트가 호출 될 때마다 메모리에서 비 직렬화 할 계획입니다.

각 PHP 인스턴스마다 메모리에 전체 데이터를로드해도 웹 서버에 너무 많은 부담을주지는 않습니다. (희망 사항) (숫자는 다음과 같습니다. 주 데이터 테이블 크기는 최대 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"과 같은 다른 키로 하나 이상의 레코드에 액세스하고 싶습니까? 물론 이러한 키에는 중복 된 값이 포함될 수 있습니다.

$zip_idx = [ 
    "12345" => [ "1", "355", "99999", ], 
    "67890" => [ "2", "732", ], 
    // ... 
]; 

후 : 내가 생각 해낸 유일한 해결책은 예를 들어

... "인덱스"각 보조 키에 대한 새로운 배열을 구축하고, 주요 데이터 테이블과 함께 직렬화하는 것입니다 :

$zip = "67890"; 
$records = $zip_idx[$zip]; 

그래서 :
는이 디자인 문제, inconsistecies 또는 부족 유연성을 볼 수 있나요?
똑똑하고 컴팩트 한 솔루션을 제안 할 수 있습니까?
의견이 있으십니까?

답변

1

다른 "색인"을 위해 더 이상 배열을 만들지 않습니다.

그냥 쿼리 처리를위한 멋진 클래스를 만드십시오. 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); 

이 배열의 사용자 ID를 사용하여이 방법으로 쿼리 할 수도 있습니다.

인사

편집 : 당신의 성능 질문은 -> 정상 당신은 100메가바이트 얻을 수있는 데이터에 대한 데이터베이스를 사용합니다. 이유는 배열 파일 데이터베이스를 사용하는 경우 100MB의 전체 파일을 메모리로 읽어 들여야하기 때문입니다.그다지 문제는 아니지만 대부분의 프로 바이더는 애플리케이션에 128MB의 최대 메모리 제한을 사용하므로 문제가 발생할 수 있습니다.

+0

감사합니다 ...하지만 PHP array_filter의 워드 프로세서 (http://php.net/manual/en/function.array-filter.php)에서 : "** 각 ** 값을 배열로 반복합니다." .--(나는 매우 효율적이지 않을까 두렵습니다 :-) – MarcoS

+0

그것은 매우 효율적입니다 - php array iterations는 모든 데이터베이스 쿼리보다 훨씬 빠릅니다. - 성능을 테스트하고 싶다면 iteration을 시작/끝내는 데에 microtime() echo를 사용하여 걸리는 시간을 확인하십시오. 병목 현상이 될 파일을 읽을 시간이 필요합니다. – mkempf

+0

흠 ... 나는 줄 것입니다. 해결책은 가능한 한 빨리 시도하십시오 :-) – MarcoS

관련 문제