> I have an existing website that uses a MySQL database with 60 tables.
>
> I'm working on a new website that will also use a MySQL database,
with about 40 tables. However, one of these tables (`users`) will
need to be identical for both sites, and inserts/updates come from
the public so it will change often.
How often do you use the user table in joins with other tables? Is
the user table ever *modified* based on joins with other tables?
You may have a situation (hopefully) where application #1 (User
Maintenance / Creation / Deletion) is the only one to *WRITE* the
users table, and application #2 (Your existing site) and application
#3 (Your new site) only read it. Does the User Maintenance application
need to read the other tables?
If User Maintenance is too tightly tied to the other applications,
this could get messy (this does not prohibit the other applications
having links to the "Change Your Password" or "Create An Account"
pages which are part of the User Maintenance application).
It might be possible (but I'm not sure how well-supported it is)
to put the users table in its own database and use replication to
replicate just that database. You can definitely put the users
table in a database on a different host and replicate that. Here
I presume that User Maintenance needs *only* the users table.
Replication of a single database and cross-database queries in
general don't mix well, but if all of the cross-database queries
involving the users table are read-only on the users table, I think
it will work.
> I edit quite a bit through phpMyAdmin, so I don't really want to
have 40 new tables in the same database. Plus, if the new site works
out then I'll probably create more sites like it, and definitely
don't want to add 40 tables to the same database for each new site!
That would make editing content unnecessarily complicated.
> Instead, I would much rather have a new database for each site,
but have the one table shared across all accounts.
I don't think that's practical. You might have that one table
in a different (possibly replicated) database. Replication avoids
the problem of all your sites going down (can't validate users)
if the user database goes down, but you still have the issue that
user *updates* go down if the user database master goes down.
> Can you guys suggest the best way to accomplish this? I know of
2 ways to do it, I just don't know if either are a good design
decision, or if there's a better option that I haven't considered.
> 1. I can create a second database, create a user that has access
to both databases, then access `users` like:
> "SELECT * FROM database2.users"
Are most accesses like that, or are they more like:
SELECT * FROM database2.users
WHERE username = '$user_name_input' AND
encrypted_password = pw_encrypt_function('$user_pw_input');
(and if you don't get a record back, the login failed)
where $user_name_input and $user_pw_input are properly escaped first
(or better, use prepared statements) and the password is encrypted
(if not in SQL, then in PHP or Perl). 'username' presumably has a
unique index on it.
Scanning the whole user list may be way slower than selecting
the single relevant user record, depending on how many users
you have.
> This seems like the smarter decision to me, am I correct that I
wouldn't be using "mysql_select_db", and would have to specify the
database in every query? That's a lot of room for error.
If you make sure NOT to have a users table in any other database,
it's an error that will be caught quickly when no one can log in.
Use of mysqli_select_db() can be a lot harder to debug when one
section of code *USUALLY* (but not always, perhaps only in an error
situation) puts the database back to the way it was, and occasionally
you execute a query elsewhere in the code (unrelated to where the
problem is) in the wrong database and have trouble figuring out why.
Using mysqli_select_db() before every query can be slow.
> 2. I can connect to both databases at once, like:
>
> $dbh1 = mysql_connect($hostname, $username, $password);
> $dbh2 = mysql_connect($hostname, $username, $password, true);
>
> mysql_select_db('database1', $dbh1);
> mysql_select_db('database2', $dbh2);
Use $dbh1 = mysqli_connect($hostname, $username, $password, $database1);
and $dbh2 = mysqli_connect($hostname, $username, $password, $database2);
where the main reason for using a common username and password is to ensure
that both databases are compromised at the same time :-( There is no necessary
reason to put the databases on the same host, either.
If you set up two connections, you will need to use the correct connection for
every query.
The User Maintenance app connects $dbh1 to the database with the users table
*READ/WRITE* and doesn't use $dbh2.
The other apps connect $dbh1 to the database with the users table *READ ONLY*
and uses $dbh2 for the other tables (probably READ/WRITE).
> mysql_query("SELECT * FROM users", $dbh1);
Use mysqli_query().
>
> I'm not sure how efficient this is, though. Does it slow everything
down if I connect to multiple databases at once?
Maybe a little. Probably not as much as a "SELECT * FROM users"
query. It depends on how much other work each page hit does.