Hello Lawrence:

If I were doing this with Sybase or MS SQL Server,
using SQL syntax like:

insert targetdb.tablename select * from
sourcedb.tablename

would have the performance advantage of avoiding
network traffic and avoiding passing your data through
the client libraries. Everything would be done within
the database server. 

David
--- Lawrence Waterhouse
<[EMAIL PROTECTED]> wrote:

> Hello everyone,
> 
> First I would like to apologise for this long mail
> but I really need
> some advices on a web application I am currently
> working on. This
> application makes extensive use of DBI and interacts
> with many
> databases at the same time.
> 
> I will try to resume my setup the best way I can,
> English is not my
> native language so I hope everyone will understand
> me well even if my
> English is not perfect :P
> 
> Server:
> Apache 1.3.29 + mod_perl 1.29 + Mason 1.26
> Perl 5.85 / DBI 1.45 + DBD::mysql-2.9004 +
> Apache::DBI 0.94
> 
> This is a multi-client web application, each client
> can have more than
> one user, there is a 'master' database which is
> global to everyone and
> contain among other things a 'users' table used to
> store credentials
> of the users.
> 
> Here is the complex part: each client has 2
> databases
> ('client-clientname' and 'archives-clientname')
> which are specific to
> the client. So basically, each client has access to
> three databases,
> the master and the 2 client specific database.
> 
> At the moment, I use a global hash to aggregate all
> my dbh, and I am
> not sure if this is the right way to do it. The
> master dbh is
> initiated in my handler.pl, while the two client
> specific database
> connections are initiated after the user log-in to
> the web
> application.
> 
> Here are the relevant portion of my handler.pl
> 
> use Apache::DBI;
> use DBI;
> 
> …
> 
> # DSN declaration
> my $dsn =
> "DBI:$db_type:host=127.0.0.1;dbname=master";
> 
> # Debug mode
> $Apache::DBI::DEBUG = 2;
> 
> # Connect to master database
> Apache::DBI->connect_on_init( $dsn, 'db_user',
> 'db_pass' ) or die
> "Cant connect to master database: $DBI::errstr!\n";
> #Apache::DBI->setPingTimeOut( $dsn, 0 );
> 
> sub handler
> {
>       # Get the Apache request object
>       my $r = shift;
> 
>       # Only handle text
>       return -1 if $r->content_type and $r->content_type
> !~ m|^text/|i;
>       
>       # (re)-Connect to the master database
>       $HTML::Mason::Commands::dbh{'master'} =
> DBI->connect($dsn, 'db_user',
> 'db_pass') or die "Cannot connect to master
> database:
> $DBI::errstr!\n";
> 
>       # Return to the browser
>       return $ah->handle_request($r);
> }
> 
> 
> The application is used by the users to move data
> between is two
> client specific databases.
> 
> Here an example:
> 
> 1. A user log-in, the credentials are taken from the
> 'master' database
> and the user is authenticated, I use
> Apache::Session::MySQL and
> cookies to store session information (user_id,
> client_id and others…).
> 2. If the user is authenticated, I initiate a
> connection to the
> client-specific databases based on the value of
> client_id. User now
> have access to the three databases, all dbh are
> stored in a global
> %dbh hash.
> 3. User move data between is two table, (clientdb =>
> archivesdb).
> 
> This setup is working but it is giving me some
> problems:
> 
> Since the Apache::DBI module don't share dbh between
> the apache child
> processes, each user might end up using a total of
> 11 connections! One
> for the master and five for each client specific
> databases (my setup
> use 5 apache child processes, the apache default).
> 
> The Apache::DBI recycle the 'master' dbh without
> problem but a new
> connection is initiated to each client specific
> database at every user
> request, thus not recycling it. I have seen a patch
> (http://mathforum.org/epigone/modperl/stroblangnerm)
> for Apache::DBI
> but I am not sure if I should use it.
> 
> Here is a sanitized sample of my error_log with
> $Apache::DBI::DEBUG =
> 2 in my handler.pl :
> 
> 16629 Apache::DBI             new connect to
>
'host=127.0.0.1;dbname=masterdb_userdb_passAutoCommit=1PrintError=1Username=db_user'
> 20332 Apache::DBI             new connect to
>
'host=127.0.0.1;dbname=masterdb_userdb_passAutoCommit=1PrintError=1Username=db_user'
> 29081 Apache::DBI             new connect to
>
'host=127.0.0.1;dbname=masterdb_userdb_passAutoCommit=1PrintError=1Username=db_user'
> 12403 Apache::DBI             new connect to
>
'host=127.0.0.1;dbname=masterdb_userdb_passAutoCommit=1PrintError=1Username=db_user'
> 7125 Apache::DBI             new connect to
>
'host=127.0.0.1;dbname=masterdb_userdb_passAutoCommit=1PrintError=1Username=db_user'
> 24346 Apache::DBI             new connect to
>
'host=127.0.0.1;dbname=masterdb_userdb_passAutoCommit=1PrintError=1Username=db_user'
> 20332 Apache::DBI             already connected to
>
'host=127.0.0.1;dbname=masterdb_userdb_passAutoCommit=1PrintError=1Username=db_user'
> 20332 Apache::DBI             already connected to
>
'host=127.0.0.1;dbname=masterdb_userdb_passAutoCommit=1PrintError=1Username=db_user'
> 20332 Apache::DBI             already connected to
>
'host=127.0.0.1;dbname=masterdb_userdb_passAutoCommit=1PrintError=1Username=db_user'
> 20332 Apache::DBI             new connect to
>
'host=127.0.0.1;dbname=client-client1db_userdb_passAutoCommit=1PrintError=1Username=db_user'
> 20332 Apache::DBI             new connect to
>
'host=127.0.0.1;dbname=archives-client1db_userdb_passAutoCommit=1PrintError=1Username=db_user'
> 20332 Apache::DBI             already connected to
>
'host=127.0.0.1;dbname=masterdb_userdb_passAutoCommit=1PrintError=1Username=db_user'
> 26657 Apache::DBI             new connect to
>
'host=127.0.0.1;dbname=masterdb_userdb_passAutoCommit=1PrintError=1Username=db_user'
> 20332 Apache::DBI             already connected to
>
'host=127.0.0.1;dbname=masterdb_userdb_passAutoCommit=1PrintError=1Username=db_user'
> 20332 Apache::DBI             already connected to
>
'host=127.0.0.1;dbname=client-client1db_userdb_passAutoCommit=1PrintError=1Username=db_user'
> 20332 Apache::DBI             already connected to
>
'host=127.0.0.1;dbname=archives-client1db_userdb_passAutoCommit=1PrintError=1Username=db_user'
> 29081 Apache::DBI             already connected to
>
'host=127.0.0.1;dbname=masterdb_userdb_passAutoCommit=1PrintError=1Username=db_user'
> 29081 Apache::DBI             already connected to
>
'host=127.0.0.1;dbname=masterdb_userdb_passAutoCommit=1PrintError=1Username=db_user'
> 29081 Apache::DBI             new connect to
>
'host=127.0.0.1;dbname=client-client1db_userdb_passAutoCommit=1PrintError=1Username=db_user'
> 29081 Apache::DBI             new connect to
>
'host=127.0.0.1;dbname=archives-client1db_userdb_passAutoCommit=1PrintError=1Username=db_user'
> 20332 Apache::DBI             already connected to
>
'host=127.0.0.1;dbname=masterdb_userdb_passAutoCommit=1PrintError=1Username=db_user'
> 29081 Apache::DBI             already connected to
>
'host=127.0.0.1;dbname=masterdb_userdb_passAutoCommit=1PrintError=1Username=db_user'
> 29081 Apache::DBI             already connected to
>
'host=127.0.0.1;dbname=client-client1db_userdb_passAutoCommit=1PrintError=1Username=db_user'
> 29081 Apache::DBI             already connected to
>
'host=127.0.0.1;dbname=archives-client1db_userdb_passAutoCommit=1PrintError=1Username=db_user'
> 20332 Apache::DBI             already connected to
>
'host=127.0.0.1;dbname=masterdb_userdb_passAutoCommit=1PrintError=1Username=db_user'
> 
> So basically I am wondering if I should modify my
> application behaviour.
> 
> I know that with DBI I can initiate a connection to
> the server instead
> of a database if I don't specify a tablename in my
> DSN and modify my
> code to use SQL query like the following:
> 
> SELECT * FROM database.table …
> 
> Instead of specifying a database in my DSN (like I
> do now) and using
> query like this:
> 
> SELECT * FROM table …
> 
> This approach could also allow me to move data
> between my databases in
> a more 'sexy' way using the new mysql 4.1 'INSERT
> … SELECT' syntax,
> like this:
> 
> INSERT INTO archives-clientname.table (*)  SELECT *
> FROM client-clientname.table
> 
> Since this would require a lot of change to my code,
> I am wondering if
> I am heading in the right direction or if there a
> better solution
> (modyfing my Apache::DBI setup or application
> behaviour). I am also
> wondering if modifying my code to connect directly
> to the server and
> use database.table syntax would cause security
> issues since it would
> require me to use a mysql user who has access to all
> databases.
> 
> Any idea, tips, pointers or recommendations will be
> much appreciated 
> It is the first multi-databases application I am
> writing and I am
> still learning!
> 
> And thanks in advance !
> 
> Ps: I apologise for my not-so-perfect English, if
> something is not
> clear or if I need to provide more information's
> about my setup, just
> tell me.
> 

Reply via email to