Perl dbi를 사용하여 "id에 대한 모든 태그"와 같이 목록 해시를 구축합니다.

Perl dbi를 사용하여 "id에 대한 모든 태그"와 같이 목록 해시를 구축합니다.

문서를 검색 dbi하고 검색했지만 목록 해시를 구축하는 (dbi) 기본 방법이 있는지 찾을 수 없었습니다. 내가 생각할 수 있는 가장 가까운 것은 fetchall_hashref결과를 덮어쓰고 마지막 쌍이 무엇이든 나에게만 제공한다는 것입니다. 명확히 하기 위해 내 테이블은 "id, tag"와 같은 쌍의 목록입니다. 모든 행을 ID별로 그룹화하고 키가 ID이고 "값"이 모든 태그 목록인 해시를 반환하고 싶습니다. 따라서 다음과 같은 경우:

id1, tag1
id1, tag2
id2, tag3
id2, tag1

난 갖길 원해:

{'id1' => ['tag1', 'tag2'],
 'id2' => ['tag3', 'tag1'] }

이것이 가능한가? 그렇지 않은 경우 기본적으로 이 작업을 수행하는 가장 좋은(가장 효율적인) 방법은 무엇입니까? 확실한 접근 방식은 fetchall_* + push() 콤보를 수행하는 것이지만 더 좋은 방법이 있습니까?

답변1

내 현재 접근 방식은 다음과 같습니다.

my $ret = {};
foreach (@{ $sth->fetchall_arrayref(  ) }) { # returns ref to array
    push  @{ $ret->{ $_->[0] } }, $_->[1] ;
    }
return $ret;

누군가에게 유용할 경우를 대비해 더 나은 방법이 있는지 기다리겠습니다.


편집하다:

GROUP_CONCAT나는 "태그"에 대해 MySQL에서 사용하는 또 다른 접근 방식을 발견했으며 , 고유한 문자와 결합하여 split()Perl에서 사용했습니다. 쿼리는 다음과 같습니다.

SELECT id, GROUP_CONCAT(tag, '|')
FROM mytable
GROUP BY tag

그런 다음 펄에서:

my $ret = {};
foreach (@{ $sth->fetchall_arrayref(  ) }) { # returns ref to array
    push  @{ $ret->{ $_->[0] } }, split("|", $_->[1]) ;
    }
return $ret;

테스트되지 않은 코드이므로 표준 경고가 적용됩니다.

내가 볼 수 있는 유일한 장점은 이것이 db에서 더 적은 행을 반환하므로 foreach의 반복 횟수가 줄어든다는 것입니다. 어쩌면 누군가가 이 코드를 프로파일링하여 접근 방식에 상당한 속도 차이가 있는지 알려줄 수 있을 것입니다.

관련 정보