Perl/Database 페이지의 소스 보기
마지막으로 [b]
-- Loading page list... --
내용출력
로그인[l]
Diary
[f]
최근변경내역
[r]
페이지목록[i]
횡설수설[2]
게시판[3]
링크
수정할 수 없습니다: Perl/Database 는 읽기 전용 페이지입니다.
[[Perl]]에서 데이타베이스 사용하기
* 간단하게는 DBM(Database Manager) 모듈을 이용하여, tied hash를 통해 DB를 사용할 수 있음 * DBI(Database Interface)와 DBD(Database Driver) 모듈을 이용하여 MySQL등의 DB에 접근할 수 있음 == # DBM == DBM 데이타베이스는 간단한 키-밸류 형태의 DB를 구현
* index, binary tree, multiple table, transaction 등은 지원하지 않음 DBM 구현들. 각각의 DBM이 설치된 후에 Perl을 설치해야 해당 DBM을 쓸 수 있는 모듈이 생성된다.
* gdbm - GNU DBM. 빠르고 호환성 좋음. ndbm DB를 읽고 쓰는 것도 지원. * ndbm - new DBM. UNIX시스템에 많이 쓰임 * odbm - old DBM. UNIX시스템에서 처음 사용되었던 구현. 웬만하면 쓰는 걸 피하자. * sdbm - 펄 표준. gdbm 등보다 성능도 나쁘고 규모가 큰 DB에 적합하지 않으나 Perl이 설치되어 있다면 사용가능. 호환성 좋음 * bsd-db - Berkeley DB. 간단한 해시 포맷 뿐 아니라 바이너리 트리 포맷도 지원. DBM을 사용한 간단한 데이타베이스 {{{#!vim perl #!/usr/bin/perl #simpledb.plx use warnings; use strict; use POSIX; use SDBM_File; # or GDBM_File / NDBM_File / AnyDBM_File... my %dbm; # DB와 결합할 해쉬 변수 my $db_file = "simpledb.dbm"; # 디스크에 저장될 DB파일 # 해쉬 변수와 DB를 바인드 tie %dbm, 'SDBM_File', $db_file, O_CREAT|O_RDWR, 0644; # 이미 존재하는 DB를 읽기 전용으로 여는 예: # tie %dbm, 'SDBM_File', $db_file, O_RDONLY, 0; # 제대로 바인드되었는지 검사 if (tied %dbm) { print "File $db_file now open.\n"; } else { die "Sorry - unable to open $db_file\n"; } $_ = ""; until (/^q/i) { print "What would you like to do? ('o' for options): "; chomp($_ =
); if ($_ eq "o") { dboptions() } elsif ($_ eq "r") { readdb() } elsif ($_ eq "l") { listdb() } elsif ($_ eq "w") { writedb() } elsif ($_ eq "d") { deletedb() } elsif ($_ eq "x") { cleardb() } else { print "Sorry, not a recognized option.\n"; } } # 해쉬 변수와 DB의 결합 해제 - DBM DB를 닫음 untie %dbm; #*** Option Subs ***# sub dboptions { print<
DB엔트리 읽음 if (exists $dbm{"$keyname"}) { print "Element '$keyname' has value $dbm{$keyname}"; } else { print "Sorry, this element does not exist.\n" } } sub listdb { # DB엔트리 덤프 foreach (sort keys(%dbm)) { print "$_ => $dbm{$_}\n"; } } sub writedb { my $keyname = getkey(); my $keyval = getval(); if (exists $dbm{$keyname}) { print "Sorry, this element already exists.\n" } else { # 해쉬 요소를 추가 -> DB 엔트리 추가 $dbm{$keyname}=$keyval; } } sub deletedb { my $keyname = getkey(); if (exists $dbm{$keyname}) { print "This will delete the entry $keyname.\n"; delete $dbm{$keyname} if besure(); } } sub cleardb { print "This will delete the entire contents of the current database.\n"; # undef %dbm - DB의 내용을 전부 지움 undef %dbm if besure(); } #*** Input Subs ***# sub getkey { print "Enter key name of element: "; chomp($_ =
); $_; } sub getval { print "Enter value of element: "; chomp($_ =
); $_; } sub besure { print "Are you sure you want to do this?"; $_ =
; /^y/i; } }}} == # AnyDBM_File == AnyDBM_File 모듈을 사용하면, 특정 DBM을 명시하지 않고, 시스템에 설치된 DBM을 사용할 수 있다.
{{{#!vim perl use AnyDBM_File; use POSIX; my %dbm; my $db_file="anydbmdemo.dbm"; tie (%dbm, 'AnyDBM_File', $db_file, O_CREAT|O_RDWR, 0644); }}} AnyDBM은 다음 순서로 DBM을 찾는다.
* NDBM_File, DB_File (버클리DB), GDBM_File, SDBM_File, ODBM_File 이 순서는 @ISA에 들어 있으므로, 만일 바꾸고 싶다면 다음과 같이 한다. {{{#!vim perl BEGIN { @AnyDBM_File::ISA = qw(GDBM_File NDBM_File SDBM_File); } use AnyDBM_File; }}} * 이렇게 @ISA의 내용을 미리 바꾸는 것은 AnyDBM의 경우 @ISA가 미리 정의되었는지 확인하기 때문에 가능한 것이고, 아무 모듈에서나 되는 것은 아님에 유의 == # 서로 다른 DBM 포맷들 간의 복사 == 그냥 해쉬 변수들 간의 할당문으로 간편하게 된다. NDBM DB를 GDBM DB로 옮기는 경우의 예:
{{{#!vim perl use POSIX; use NDBM_File; use GDBM_File; my (%ndbm_db,%gdbm_db); my $ndbm_file='/tmp/my_old_ndbm_database'; my $gdbm_file='/tmp/my_new_gdbm_database'; tie %ndbm_db, 'NDBM_File',$ndbm_file, O_RDONLY, 0; tie %gdbm_db, 'GDBM_File',$gdbm_file, O_CREAT|O_WRONLY, 0644; %gdbm_db=%ndbm_db; # 복사 untie %ndbm_db; untie %gdbm_db; }}} == # 복잡한 데이타 == 리스트나 해쉬를 DBM DB에 저장하려면?
1) 직접 스칼라 형태로 변환하는 경우 - join, split 등을 사용 {{{#!vim perl $dbm{'key'} = join ("_XYZ_", @list); # 이 때 구분자는 데이타에 들어있지 않은 걸 써야 된다. my @list = split "_XYZ_", $dbm{'key'}; }}} 2) 직렬화해주는 모듈 사용 - Data::Dumper, Storable, FreezeThaw 등 Storable 사용 예: {{{#!vim perl use POSIX; use SDBM_File; use Storable; my %dbm; my $db_file="demo.dbm"; tie %dbm, 'SDBM_File', $db_file, O_CREAT|O_RDWR, 0644; # store a hash in DBM (note that we must supply a reference): $dbm{'key'}=Storable::freeze({Name=>"John", Value=>"Smith", Age=>"42"}); # retrieve a hash from DBM (as a reference or as a hash): my $href=Storable::thaw($dbm{'key'}); my %hash=%{ Storable::thaw($dbm{'key'}) }; }}} == # Multi-Level DBM (MLDBM) == 일일이 프로그래머가 데이타를 직렬화하여 저장하고 읽어오는 것도 불편하다. [http://search.cpan.org/~chamas/MLDBM-2.01/lib/MLDBM.pm MLDBM]모듈을 사용하면 Perl에서 생성할 수 있는 어떤 데이타 구조도 저장가능하다.
사용법은 다른 DBM과 동일
{{{#!vim perl use MLDBM; use POSIX; #for O_CREAT and O_RDWR symbols use strict; my %mlhash; my $mldb_file="mlanydbmdemo.dbm"; tie %mlhash, 'MLDBM', $mldb_file, O_CREAT|O_RDWR, 0644; }}} 이 경우 MLDBM은 기본으로 * DBM은 SDBM을, * 직렬화 모듈은 Data::Dumper를 사용한다. 이것은 성능이 좋지 못하다. MLDBM은 필요한 함수가 제공된다면 어떤 모듈을 써도 상관없다. SDBM과 Storable을 사용하는 예
{{{#!vim perl use SDBM_File; use Storable; use MLDBM qw(SDBM_File Storable); # DB와 serializer 지정 }}} AnyDBM_File을 사용할 수도 있다
{{{#!vim perl BEGIN { @AnyDBM_File::ISA = qw(GDBM_File DB_File NDBM_File SDBM_File); } use AnyDBM_File; use Storable; use MLDBM qw(AnyDBM_File Storable); }}} 복잡한 데이타를 저장하는 예
{{{#!vim perl #!/usr/bin/perl #mldbm4.plx use MLDBM qw(SDBM_File Storable); use POSIX; use warnings; use strict; my %mldbm; my $mldb_file="mldbmdemo.dbm"; tie (%mldbm, 'MLDBM', $mldb_file, O_CREAT|O_RDWR, 0644); unless (tied %mldbm) { print "Error opening $mldb_file: $!\n"; } else { # wipe out the old contents, if any undef %mldbm; $mldbm{'Created'}=localtime; # assign a list anonymously, directly and as a copy $mldbm{'AnonymousList'}=[1,2,3,4,"Five",6,7.8]; my @list=(9,"Ten",11,12.13,14); $mldbm{'OriginalList'}=\@list; $mldbm{'CopyOfList'}=[ @list ]; $mldbm{'NumberOfListElems'}=@list; $list[0]="Nine"; #does NOT modify 'OriginalList' # assign a hash anonymously, directly and as a copy $mldbm{'AnonymousHash'}={One=>'1',Two=>'2',Three=>'3'}; my %hash=(Four=>'4',Five=>'5',Six=>'6'); $mldbm{'OriginalHash'}=\%hash; $mldbm{'CopyOfHash'}={ %hash }; $mldbm{'NumberOfHashKeys'}=keys %hash; $hash{Four}="IV"; #does NOT modify 'OriginalHash' # assign a random key and value $mldbm{rand()}=rand; # a more complex assignment $mldbm{'HashOfMixedValues'}={ List1=>[1,2,3], List2=>[4,5,6], String=>"A String", Hash1=>{ A=>"a", B=>"b", Hash2=>{ C=>"c", }, }, Number=>14.767, List3=>[7,8,9], }; # now dump out the contents again foreach (sort keys %mldbm) { print "$_ => $mldbm{$_}\n"; if (my $ref=ref $mldbm{$_}) { if ($ref eq 'HASH') { foreach my $key (sort keys %{ $mldbm{$_} }) { print "\t$key => $mldbm{$_}{$key}\n"; } } else { print "\t",(join ",",@{ $mldbm{$_} }),"\n"; } } } untie %mldbm; } }}} * 해쉬나 리스트를 저장할 때는 ** 원본 데이타에 대해 백슬래쉬 레퍼런스를 사용하거나 ** 익명 해쉬, 익명 리스트 생성자 ({}, [])를 사용할 수 있다 ** 이 때 MLDBM은 그 변수의 사본을 저장하므로, 원본 변수를 변경해도 DB에는 영향을 미치지 않는다 * MLDBM DB내의 데이타에 대한 레퍼런스를 만들어서 접근하더라도 그 레퍼런스는 tie된게 아니므로 DB의 값을 바꿀 수 없다. 오직 tie된 해쉬를 통해 최상위 레벨의 접근만이 올바르게 동작 * 리스트나 해쉬는 레퍼런스로 저장해야지, 그냥 쓰면 원소의 갯수가 저장된다. == # 기타 == * [http://ko.perlmaven.com/simple-database-access-using-perl-dbi-and-sql Perl DBI와 SQL을 사용한 간단한 데이타베이스] - Perl Maven 기사 번역. SQLite를 사용하는 간단한 예제. == # comments ==
----
---- [[컴퓨터분류]]
Perl/Database
페이지로 돌아가기 |
다른 수정본 보기