[첫화면으로]Perl/Database

마지막으로 [b]

1. DBM
2. AnyDBM File
3. 서로 다른 DBM 포맷들 간의 복사
4. 복잡한 데이타
5. Multi-Level DBM (MLDBM)
6. 기타
7. comments

Perl에서 데이타베이스 사용하기1

1. DBM

DBM 데이타베이스는 간단한 키-밸류 형태의 DB를 구현2

DBM 구현들. 각각의 DBM이 설치된 후에 Perl을 설치해야 해당 DBM을 쓸 수 있는 모듈이 생성된다.3

DBM을 사용한 간단한 데이타베이스
#!/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($_ = <STDIN>);

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<<EOF;
        Options available:
        o - view options
        r - read entry
        l - list all entries
        w - write entry
        d - delete entry
        x - delete all entries
EOF
}

sub readdb {
    my $keyname = getkey();

# 해쉬를 읽음 -> 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($_ = <STDIN>);
    $_;
}

sub getval {
    print "Enter value of element: ";
    chomp($_ = <STDIN>);
    $_;
}

sub besure {
    print "Are you sure you want to do this?";
    $_ = <STDIN>;
    /^y/i;
}

2. AnyDBM File

AnyDBM File 모듈을 사용하면, 특정 DBM을 명시하지 않고, 시스템에 설치된 DBM을 사용할 수 있다.4
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을 찾는다.5 이 순서는 @ISA에 들어 있으므로, 만일 바꾸고 싶다면 다음과 같이 한다.
BEGIN {
   @AnyDBM_File::ISA = qw(GDBM_File NDBM_File SDBM_File);
}
use AnyDBM_File;

3. 서로 다른 DBM 포맷들 간의 복사

그냥 해쉬 변수들 간의 할당문으로 간편하게 된다. NDBM DB를 GDBM DB로 옮기는 경우의 예:6
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;

4. 복잡한 데이타

리스트나 해쉬를 DBM DB에 저장하려면?7

1) 직접 스칼라 형태로 변환하는 경우 - join, split 등을 사용
$dbm{'key'} = join ("_XYZ_", @list);   # 이 때 구분자는 데이타에 들어있지 않은 걸 써야 된다.
my @list = split "_XYZ_", $dbm{'key'};

2) 직렬화해주는 모듈 사용 - Data::Dumper, Storable, FreezeThaw 등

Storable 사용 예:
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'}) };

5. Multi-Level DBM (MLDBM)

일일이 프로그래머가 데이타를 직렬화하여 저장하고 읽어오는 것도 불편하다. [MLDBM]모듈을 사용하면 Perl에서 생성할 수 있는 어떤 데이타 구조도 저장가능하다.8

사용법은 다른 DBM과 동일9
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은 기본으로 사용한다. 이것은 성능이 좋지 못하다. MLDBM은 필요한 함수가 제공된다면 어떤 모듈을 써도 상관없다.

SDBM과 Storable을 사용하는 예10
use SDBM_File;
use Storable;
use MLDBM qw(SDBM_File Storable);   # DB와 serializer 지정

AnyDBM File을 사용할 수도 있다11
BEGIN {
    @AnyDBM_File::ISA = qw(GDBM_File DB_File NDBM_File SDBM_File);
}
use AnyDBM_File;
use Storable;
use MLDBM qw(AnyDBM_File Storable);

복잡한 데이타를 저장하는 예12
#!/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;
}

6. 기타

7. comments

이름:  
Homepage:
내용:
 


컴퓨터분류
각주:
1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. Beginning Perl, Chapter 13

마지막 편집일: 2013-5-22 6:08 pm (변경사항 [d])
2770 hits | Permalink | 변경내역 보기 [h] | 페이지 소스 보기