2015-01-09 4 views
2

mysql에서 json으로 다음과 같은 구조의 데이터를 생성하는 모듈을 개발 중입니다.PHP에서 json으로 mysql 관계형 데이터를 내보내는 방법

{"employee": 
    [ 
     {"id":1, 
     "name":"jhon doe", 
     "register_date":"2011-05-11", 
     "education": 
      [ 
       {"degree":"B.A","description":"History"}, 
       {"degree":"M.A","description":"History"} 
      ] 
     }, 
     {"id":2, 
     "name":"Smith", 
     "register_date":"2011-06-11", 
     "education": 
      [ 
       {"degree":"B.E","description":"Mechnical"}, 
       {"degree":"M.E","description":"Mechnical"} 
      ] 
     } 
    ] 
} 

이렇게하려면 첫째로 직원 데이터를 다음과 같이 register_date 범위로 검색합니다. 그런 다음

$result=mysql_query("SELECT * FROM employee WHERE register_date>'2011-04-31' AND register_date<'2011-07-01'"); 

나는 결과에서 각 행을 반복하고 다음과 같은 교육 테이블에서 교육 정보 검색 :

while($row = mysql_fetch_assoc($result)){ 
    $id=$row["id"]; 
    $education=mysql_query("SELECT degree,description from education where emp_id=$id"); 
    // assigning education array as educaiton field in $row 
    // write json_encode($row) to output buffer 
} 

이 프로젝트의 데이터 구조 내 디자인 아니고, 나는 그것이 '직원을 설정하는 것은 좋은 생각이 아니다 알고를 ID를 교육용 테이블에서 외래 키로 사용하는 대신 교육 ID를 외래 키로 설정해야합니다. 내 문제는 (이 데이터 구조를 사용하여) 직원의 각 행에 대한 교육 목록을 검색하는 것은 한 달 동안 직원의 약 500000 기록이있을 수 있고 그 금액에 대해 MySQL의 선택 쿼리는 500000 번 처리해야하기 때문에 큰 성능 문제입니다 각 직원에 대한 교육 데이터 검색. 어떻게 최적화해야합니까?

1. 데이터 구조를 변경해야합니까?
2. 데이터베이스에서 직접 json 문자열을 생성하는 mysql 저장 프로 시저를 작성해야합니까?
3. 직원 데이터 테이블에서 교육 데이터를 비정규 화해야합니까?
가장 효율적인 방법 또는 제안 사항은 무엇입니까?

도와주세요.

+1

http : //en.wikipedia.org/wiki/Join_ (SQL) : P * 하나의 * 쿼리를 사용하여 테이블을 올바르게 결합하면 모든 데이터를 한 번에 가져올 수 있습니다. (오, 나는 2015 년에'mysql_query'를 여전히 사용하여 당신을 조롱 할 의무가 있습니다.) – cHao

+0

이것이 퍼포먼스 문제의 병목 현상이 아니라고 생각합니다. 기본 키로 단일 행을 쿼리하는 것은 충분히 빠릅니다 (mysql 서버 캐싱 매개 변수를 올바르게 구성한 경우). PHP-ORM 라이브러리와 같은 것을 사용하여 php 코드와 mysql 사이에 다른 캐싱 계층을 추가하는 것이 가장 좋습니다. –

+0

@Olim : 분명히 * 병목 현상입니다. 기본 키에 의한 한 행에 대한 하나의 쿼리, 꽤 빠릅니다. 그래도 50 만 건이 필요합니까? 별로. 네트워크/구문 분석/실행 시간이 합산되면 캐싱이 실제로 방해가 될 수 있습니다 (쿼리가 모두 다른 데이터를 요구하고 모든 쿼리가 캐시 누락을 초래할 수 있기 때문에) ORM은 불필요한 개체 구성과 N + 1 쿼리를 추가합니다. 더미에 대한 위험성, 각 쿼리의 엄격한 직렬 처리로 인해 많은 대기가 발생합니다. 여기에 10-100 배의 속도 향상을 쉽게 그릴 수 있습니다. – cHao

답변

0

의견에서 지적한 것처럼 어떤 종류의 JOIN을 사용할 수 있습니다.

다음은 내가 & 더러운 해결책을 소개합니다. 이것은 램을 많이 사용합니다. 특정 질문에 대한

$arr_education = array(); 
$res_education = mysql_query("SELECT emp_id, degree, description FROM education"); 

while($row_education = mysql_fetch_assoc($res_education)) { 
    $arr_education[$row_education["emp_id"]] = array("degree"=>$row_education["degree"], "description" => $row_education["description"]); 
} 

$result=mysql_query("SELECT * FROM employee WHERE register_date>'2011-04-31' AND register_date<'2011-07-01'"); 

while($row=mysql_fetch_assoc($result)) { 
    //$arr_education[$row["id"]] is an array containing the education-entries for the employee 
    $tmp = $row; 
    $tmp["education"] = $arr_education[$row["id"]]; 
    echo json_encode($tmp); 
} 

:

  1. 는 EMP 경우 -> 교육은 데이터 구조를 변경해야 1 1의 관계입니다.

가 PDO로 전환을 고려하는 것이 그러지 마,하지 마! http://php.net/manual/en/book.pdo.php 이 특별한 경우에는 도움이되지 않지만 결코을 사용하십시오 mysql_* 기능을 사용해야합니다.

1

직원을 가져 와서 PHP 루프에서 할당 한 후에 교육 데이터를 쿼리 할 수 ​​있습니다.

$result = mysql_query("select * from employee where register_date > '2011-04-31' and register_date < '2011-07-01'"); 

$employees = []; 

while ($row = mysql_fetch_assoc($result)) { 
    $id = $row['id']; 
    $employees[$id] = $row; 
} 

$ids = join(', ', array_keys($employees)); 

$result = mysql_query(sprintf('select degree, description, employee.id as employee_id from education left join employee on emp_id = employee.id where employee.id in (%s)', $ids)); 

while ($row = mysql_fetch_assoc($result)) { 
    $id = $row['employee_id']; 
    unset($row['employee_id']); 

    if (!isset($employees[$id]['education'])) { 
     $employees[$id]['education'] = []; 
    } 

    $employees[$id]['education'][] = $row; 
} 
0

더 나은 당신은 데이터를 처리하고 JSON 문자열을 반환하기 위해 SP를 사용할 수 있습니다. DB 시스템이 처리하고 반복하도록합니다. 나는 이것이 현재의 구현에 비해 많이 개선 될 것이라고 생각한다.

관련 문제