Datenbanken und DBI

Werbung
10. Datenbanken
und DBI
Ties
BerkeleyDB
Datenbanken und DBI
Oracle, Mysql und Proxy Server
10-1
Ties
tie bildet komplexe Operationen auf Daten ab auf
Manipulation einfacher Perlvariablen (Skalare,
Arrays, Hashes, Filehandles)
Manipulation der Variablen löst entsprechende
Aktionen aus
realisiert durch Subroutinen zum Lesen, Schreiben,
Einfügen und Löschen von Daten
Standardverhalten der Variables ist verändert
Ties binden Methoden aus Packages an Variablen
10-2
Ties und Objekte
Gebundene (tied) Variablen arbeiten wie Objekte
das Interface ist definiert
Methoden eines Packages werden gerufen
Unterschied: festgelegte Namen von Methoden
Ties suchen nach den gleichen Prinzipien wie bei
Objekten die Methoden
versteckter Polymorphismus
10-3
Realisierung von Ties
ein Tie ist an eine Klasse gebunden (Package)
Methoden mit festen Namen sind bereitzustellen
für Skalar: TIESCALAR, FETCH, STORE, DESTROY
für Hash: 9 Methoden, u.a. FIRSTKEY, NEXTKEY...
Methoden werden an Variable gebunden:
tie $var, $class, @args; ruft den Konstruktor
$class->TIESCALAR @args; # constructor
Aufruf weiterer Methoden bei Benutzung von $var
Verbindung zu Methoden lösen: untie $var;
10-4
Tie Anwendungen
Viele Module benutzen Tie Mechanismus
derzeit über 200 Module auf CPAN, die Tie nutzen
oder bei der Erstellung von Ties helfen
(Tie::Scalar, Tie::Hash, ...) (im core perl)
Abbildung auf Hashes am weitesten verbreitet
Aber auch Bindung an Filehandles möglich
Viele Module stellen Datenbankinterface bereit
zu SQL Datenbanken (Tie::DBI)
zu Berkeley DB (DB_File, BerkeleyDB)
siehe auch perldoc perltie
10-5
Pflege von
Datenbanken mit tie
In UNIX gibt es viele Varianten von DBM
Berkeley DB ist erste Wahl (simultane Updates,
Transaktionen)
diese DB's implementieren Disk basierten Hash
alle mit mehr oder weniger Nachteilen
(siehe perldoc AnyDBM)
Modul BerkeleyDB besser als DB_File (für DB 1.x)
SDBM_File (simple Database) im perl Core, auch
auf Windows
10-6
tie und untie für
Datenbanken
Verbinden mit der Datenbank ist Aufruf von tie
use Fcntl;
#Constants O_RDWR and O_CREAT
use DB_File;
#Berkeley DB
tie %h,’DB_File’,$file,O_RDWR|O_CREAT,0666,$DB_BTREE;
Lesen/Schreiben/Ändern durch Benutzen von %h
$val=$h{key1}; $h{key2}=’new text’;
Löschen von Einträgen ist Löschen von key/value
delete $h{key2};
Rückspeichern in Datenbank auf Disk durch untie
untie %h;
10-7
tie Demo
### Bitte spielen Sie dieses Beispiel durch ###
use Fcntl;
# for the constants O_RDWR and O_CREAT
use SDBM_File; # Simple DB, in Perl always available
tie %hash,'SDBM_File','C:\Temp\mydb',O_RDWR|O_CREAT,0666;
$hash{key1} = 11.2;
$hash{key2} = 'text';
$date = localtime(time); #use the date stamp as key
$hash{$date} = '';
print "In memory: ", join ("\n\t", keys %hash), "\n";
untie %hash;
print "After untie:", keys %hash, "\n";
tie %hash,'SDBM_File','C:\Temp\mydb',O_RDWR|O_CREAT,0666;
print "Read from file: ", join ("\n\t", keys %hash), "\n";
untie %hash;
10-8
DBM Anwendungen
NIS (Yellow Pages) Maps sind DBM Files
Konversionen zwischen DBM Formaten
durch zwei tie Aufrufe, danach einfach %new=%old
Bearbeitung von Textfiles als BerkeleyDB(RECNO)
einfacher Zugriff über Perl's tie Mechanismus
damit einfacher Zugriff per Zeilennummer möglich
Mehrere Anwendungen nutzen BerkeleyDB
spamassassin, gridengine, sendmail, firefox, ...
10-9
Editieren von Text mit
DB_File
use DB_File;
tie @lines, 'DB_File', 'textfile', O_RDWR|
O_CREAT, 0666, $DB_RECNO;
$lines[0] = 'New first line';
push @lines, 'yet another new line';
$lines[5] = 'replacement for line 6';
$lines[8] = 'last line';
$lines[-1] = 'remove this line later';
$last = pop @lines; #last line gets removed
untie @lines;
10-10
Relationale
Datenbanken
DBI (Data Base Interface) ist Schnittstelle
zwischen perl und relationalen SQL Datenbanken
Standardisiertes API für viele RDBMS
besteht aus Modul DBI (generisch für alle DB's)
und spezifischen Modulen (DBD, Datenbanktreiber)
Code damit weitgehend unabhängig von RDBMS
Ähnliches Konzept für Windows (ODBC)
Zugriff auf DB's, die ODBC Interface haben mit
DBI+DBD::ODBC (es gibt auch Win32::ODBC)
10-11
Weiterführende
Literatur
perldoc DBI; perldoc DBD::Oracle ...
Programming the Perl DBI, Alligator Descartes & Tim
Bunce, O'Reilly (2000)
DBI Homepage: http://dbi.perl.org
Vorträge von Tim Bunce auf:
http://backpan.cpan.org/authors/id/T/TI/TIMB/
DBI_AdvancedTalk_200708.pdf
DBI_WhatsNewTalk_200607.pdf
OraclePerlTalk_200201.ppt
10-12
SQL (Structured Query
Language)
wird zur Arbeit mit RDBMS benötigt
Perl reicht SQL an RDBMS ohne Prüfung durch
Einfache SQL Statements
INSERT INTO table (colx, coly, ...) VALUES (val1, val2, ...)
UPDATE table SET colx = val1 WHERE coly LIKE val2
DELETE FROM table WHERE colz=num1
SELECT colx, coly, ... FROM table WHERE ... ORDER BY colz, ...
schon bei WHERE Unterschiede zwischen DB's
z.B. bei Stringvergleich:
UPPER(val) LIKE .. (Oracle) val CLIKE .. (mysql)
10-13
Unterstützte RDBMS
Viele RDBMS unterstützt (CPAN), bei DESY u.a.:
DBD::Oracle, DBD::mysql
DBD::ODBC und ADO Datenbanken (Windows)
DBD::CSV Text files (Comma Separated Values)
alle obige RDBMS auf allen Systemen bei Nutzung
des DBD::Proxy Treibers (kommt mit DBI Modul)
Nutzung der DBI Schnittstelle einfach mit
use DBI; #use DBD::xxx usually not required
Einige RDBMS brauchen Zusatzinformationen (s.u.)
10-14
Das DBI/DBD Interface
DBI definiert einheitliche Methoden, die großteils in
den DBD Treibern realisiert sind
DBD Module können zusätzliche Methoden
definieren, die nur für konkretes RDBMS gelten
Methoden auf Datenbank- bzw. Tabellenebene
brauchen database handle, erhält man mit connect
Operationen innerhalb einer Tabelle brauchen ein
statement handle, erhält man z.B. mit prepare
10-15
Prinzipskizze DBI/DBD
(aus Talk T. Bunce)
Perl Application
DBI Module
DBD::Oracle
Oracle Server
DBD::Informix
Informix Server
DBD::Other
Other Server
10-16
Oracle mit DBI
Windows: SQLPlus installieren (Netinstall)
UNIX: ORACLE_HOME muss gesetzt werden:
$ENV{ORACLE_HOME}='/opt/products/oracle-client/10.2g'
gilt nur ab SL3 und neuer
und /opt/products/perl/5.8.8/bin/perl
für ältere Versionen 5.8.8 -> 5.8.2, 10.2g
-> 9.2.0
Windows User dürfen diese Variable nicht setzen
als DB Name 'dbi:Oracle:desy_db' verwenden!
10-17
Datenbankabfrage
(Oracle)
use DBI;
replace for other RDBMS, DB, table
$dbname = 'dbi:Oracle:desy_db';
$ENV{ORACLE_HOME}='/opt/products/oracle-client/10.2g'
if $dbname =~ /dbi:Oracle:/i and $^O ne 'MSWin32';
$dbuser = $ENV{ORACLE_USERID} || 'read/read';
$dbh = DBI->connect($dbname, $dbuser, '');
$sth = $dbh->prepare(qq{select * from bolewski.teilnehmer
where NAME like ?});
$sth->execute('Fri%'); # insert parameters for ?
$fieldnames = $sth->{'NAME'}; # field names
while ($row = $sth->fetchrow_arrayref) {
print "$row->[1]: $fieldnames->[2]=$row->[2]\n"; }
$sth->finish; $dbh->disconnect;
10-18
Optimierungen
Benutzen von connect_cached statt connect
neue Verbindungen zu DB öffnen dauert lange
Verwenden von prepare und execute statt do
ein prepare call für viele execute calls nutzbar
Verwenden von Platzhaltern ? in prepare und
Ersetzung durch aktuelle Argumente in execute
Nutzung von fetchrow_arrayref statt fetchrow_array
weniger Datenbewegungen, da Pointer verwendet
Bei großen Projekten kann Ima::DBI hilfreich sein
10-19
Fehlerbehandlung
Die meisten DBI Methoden liefern undef bei Fehler
Dann steht in $DBI::errstr die Fehlermeldung
Einschalten automatischer Fehlerprüfungen:
$handle->{RaiseError}=1; #die on error
$handle->{PrintError}=1; #warn on error
$DBI::errstr wird in beiden Fällen ausgegeben
Programmabbruch kann vermieden werden:
$handle->{RaiseError} = 1;
eval{ ...; $handle->method; ...};
if ($@) {... better error handling ...} 10-20
Fehlersuche
Tracing in DBI eingebaut (global oder per Handle)
Tracing kann man einschalten
Output kann in File umgeleitet werden
DBI->trace($level);
# global tracing
$handle->trace($level); # at handle level
$handle->trace($level, $file);
Auch mit ENV variable DBI_TRACE steuerbar
DBI_TRACE=level DBI_TRACE=file DBI_TRACE=level=file
normalerweise Level 1 und 2 am sinnvollsten
10-21
Proxy Server
Benutzt zur Arbeit mit RDBMS wenn
Datenbank nicht netzfähig ist (z.B. Access)
es keinen Treiber für benutztes System gibt
Firewall Direktzugriff verhindert
Zahl der Klienten mit Direktzugriff klein sein muss
DBI::ProxyServer benötigt Zugriff auf DB
DBD::Proxy verbindet sich zu Proxyserver per TCP
Proxy package kann konfiguriert werden
Datenkompression, Zugriffskontrolle, Verschlüsselung
10-22
Die Proxy Architektur
Application
DBD::mysql
DBI
DBI
DBD::Proxy
DBI::ProxyServer
RPC::pClient
RPC::pServer
Client
Server
10-23
Proxy Server Benutzung
Proxy Server wird von Kommandozeile gestartet
dbiproxy --localport portnumber
(für UNIX in /opt/products/perl/5.8.8, für Win im PATH)
ENV Vars auf Proxy Host setzen ! (ORACLE_HOME)
Standalone Skript wird zum Proxy Client durch
Ändern des DB Namens im connect Aufruf oder
Setzen des DB Namens in der ENV Variable
DBI_AUTOPROXY, dann keine Änderung des Skripts!
Benutzen Sie die Oracle Demo per Proxy
10-24
mysql per Proxy
Starten Sie einen Proxy Server auf Port 1206, dann:
use DBI;
$dsn = 'DBI:mysql:test_perlkurs;host=mysql.ifh.de';
# dsn has to begin with dbi:xxx: and be last part of $dbname !!!
# $dbname = "DBI:Proxy:hostname=????.desy.de;port=1206;dsn=$dsn";
$ENV{DBI_AUTOPROXY} = 'hostname=????.desy.de;port=1206'; # flexible
$dbh=DBI->connect($dsn, ''); # or $dbh=DBI->connect($dbname,..);
$sth = $dbh->prepare("SELECT * FROM user WHERE name like ?");
$sth->execute('guest');
while (@row = $sth->fetchrow_array) {
print join(", ", @row[1,2]), "\n"; }
$sth->finish;
$dbh->disconnect;
10-25
Persistente Objekte
Objekte werden am Ende eines Programms zerstört
Lösung: Dauerhafte Speicherung in Datenbank
durch Abbildung von Objekten auf Datenbank
durch Konvertierung von Objekten in Strings
Data::Dumper, Dumpvalue
durch Konvertierung in binäre Daten
Class::DBI, Tangram, ...
Storable, FreezeThaw
und anschließende Speicherung in File oder DB
Komplettlösung mit Pixie
10-26
DBI Code Portabilität
DBI Code weitgehend portabel, da DBI auf vielen
Systemen lauffähig (Linux, Windows, Mac, ...)
ProxyServer erhöht Flexibilität
DBI Code reflektiert SQL Implementation der
RDBMS
z.B. Zugriff auf Access DB von UNIX aus!
SQL Dialekte und SQL Erweiterungen
DBD Treiber Einschränkungen beachten
RDBMS Abhängigkeit eliminieren:
einfache SQL Statements benutzen
den Rest in perl kodieren, DBI hat RDBMS Infos
10-27
Weitere Themen
Multithreading für DBI
DBD::Multiplex Treiber
Tie::DBI um SQL Syntax zu vermeiden:
um mehrere DB's synchron zu halten
Lastverteilung für Queries
Erhöhung der Ausfallsicherheit
Konsistenzprüfung mehrerer DB's
$hash{table}->{field} = 42;#is SQL UPDATE
DBD::Gofer als Ersatz für DBD::Proxy
10-28
Herunterladen