So i've assume you have only 1 MySQL database (minimum package on your webhost) and need to store a copy of a system for each of your clients.
What I was suggesting, is that you create a separate set of tables as you already are (for each client), but the name wont matter because you have a look-up of the table names in your clients table.
Heres my example for you: The clients table should store the table names of their own tables
(e.g. users_tbl = clientone_users for client id:1) So that later on you can just query the clients table and get his/her table names, then use that result to query on his/her user, news, pages, and files tables.
# SQL: new table structure -- store the names of the clients tables here CREATE TABLE clients( id INT NOT NULL AUTO_INCREMENT, PRIMARY KEY(id), name VARCHAR(50), address VARCHAR(250), email VARCHAR(50), pass BLOB, /* table names*/ users_tbl VARCHAR(70), news_tbl VARCHAR(70), pages_tbl VARCHAR(70), files_tbl VARCHAR(70) ) ENGINE = InnoDB; # PHP: Some definitions for the table structure $tbl_names = array("_users","_news","_pages","_files"); $tbl_fields = array(); $tbl_fields[0] = array("id INT","users_col1 VARCHAR(10)","users_col2 VARCHAR(20)"); $tbl_fields[1] = array("id INT","news_col1 DATE",...); $tbl_fields[2] = array(...); $tbl_fields[3] = array(...); // refers to YOUR clients table field names (see above) $clients_fields = array("users_tbl", "news_tbl", "pages_tbl", "files_tbl"); # PHP: Create a user and create the users database function createUser($name, $address, $email, $pass, $salt) { global $db, $tbl_names, $tbl_fields; $success = false; if ($db->beginTransaction()) { $sql = "INSERT INTO clients(name, address, email, pass) VALUES (?, ?, ?, AES_ENCRYPT(?, ?));" $query = $db->prepare($sql); $query->execute(array($name, $address, $email, $pass, $salt)); if ($query->rowCount() == 1) { # if rowCount() doesn't work # get the client ID # there are alternative ways $client_id = $db->lastInsertId(); for ($i=0; $i<sizeof($tbl_names); $i++) { $client_tbl_name = $name . $tbl_names[$i]; $sql = "CREATE TABLE " . $client_tbl_name . "(" . implode(',', $tbl_fields[$i]) . ");"; if (!$db->query($sql)) { $db->rollBack(); return false; } else { $sql = "UPDATE clients SET ".clients_fields[$i]."=? " ."WHERE id=?;"; $query = $db->prepare($sql); if (!$query->execute( array($client_tbl_name, (int)$client_id) )) { $db->rollBack(); return false; } } } $db->commit(); $success = true; } if (!$success) $db->rollBack(); } return $success; } # PHP: Get the Client's table names function getClientsTableNames($client_id) { $sql = "SELECT (users_tbl, news_tbl, pages_tbl, files_tbl) FROM clients WHERE id=?;"; $query = $db->prepare($sql); if ($query->execute(array((int)$client_id))) return $query->fetchAll(); else return null; } # PHP: Use the table name to query it function getClientsTable($client_id, $table_no) { $table_names = getClientsTableNames($client_id); if ($table_names != null && isset($table_names[$table_no])) { $sql = "SELECT * FROM ".$table_names[$table_no].";"; $query = $db->prepare($sql); if ($query->execute(array((int)$client_id))) return $query->fetchAll(); } return null; }
clientstable so you know which table is for which client?SELECT name FROM clients WHERE id=?) then append that to the table name. Besides whats ugly about it when no one is supposed to be able to see it (private info about your clients?). It should only be accessed through your program so the name is sort of hidden anyway.users,news,pages,files. I want to haveone of each (and others) table for each client. Because is one mysql with multiple client projects. So, this is not the best way.