2010-12-07 4 views
2

So arbeite ich an einer Webanwendung, die unsere Kunden ihre Benutzerdaten getrennt von anderen Benutzerdaten des Clients wünschen. Da unsere Kunden zusammenarbeiten können, können wir nicht einfach eine neue Instanz der Anwendung für jeden Client erstellen, da wir sicherstellen müssen, dass die Benutzer-IDs übereinstimmen und zwischen den Clients eindeutig sind.Mysql Cross-Schema-Abfragen basierend auf Row-Daten

Grundsätzlich gibt es unsere "MasterApplication" -Datenbank, die eine "User" -Tabelle enthält, die eine UserId und den Namen der Datenbank enthält, wo die restlichen Benutzerdaten zu finden sind. Jeder Client hat seinen eigenen Datenbankbenutzer, der nur Zugriff auf die "MasterApplication" und seine eigene Client-Tabelle hat.

Hier ist ein Beispiel dafür, wie es aussieht.

CREATE DATABASE MasterDatabase 
CREATE DATABASE Client1 
CREATE DATABASE Client2 

CREATE TABLE `MasterDatabase`.`Person` (
    `PersonId` INT NOT NULL AUTO_INCREMENT, 
    `DatabaseName` Varchar(20) NOT NULL, 
    PRIMARY KEY (`PersonId`) 
) 

CREATE TABLE `Client1`.`Person` (
     `PersonId` INT NOT NULL, 
     `FirstName` Varchar(20) NOT NULL, 
     PRIMARY KEY (`PersonId`) 
    ) 

CREATE TABLE `Client2`.`Person` (
    `PersonId` INT NOT NULL, 
    `FirstName` Varchar(20) NOT NULL, 
     PRIMARY KEY (`PersonId`) 
) 

INSERT INTO MasterDatabase.Person VALUES (1, 'Client1'); 
INSERT INTO MasterDatabase.Person VALUES (2, 'Client2'); 

INSERT INTO Client1.Person VALUES (1, 'Matt'); 
INSERT INTO Client2.Person VALUES (2, 'Scott'); 

So hätte Client1 einen Datenbankbenutzer, der Zugriff auf die Tabellen MasterDatabase und Client1 hat. Client2 hätte einen Benutzer mit Zugriff auf MasterDatabase und Client2.

Ich hoffe, es gibt eine Möglichkeit, dass ich eine Cross-Schema-Abfrage problemlos mithilfe der Daten aus dem Feld "DatabaseName" in MasterDatabase tun kann, aber ich kann es nicht herausfinden. Ich weiß größtenteils, dass ich den Datenbanknamen des Klienten in der Anwendungslogik speichern und ihn einfach in die Abfrage einfügen kann, aber es wird ein paar Stellen geben, die ich brauche, um alle Klienten in eine Frage zu verbinden.

Mein Versuch war

SELECT *, `DatabaseName` INTO @DB FROM MasterDatabase.Person 
LEFT JOIN @DB.Person ON MasterDatabase.Person.PersonId = @DB.Person.PersonId 

zu tun, aber das hat nicht funktioniert, wie ich gehofft wurde. Kann ich es irgendwie mit einer Prozedur machen? Ich bin auch offen für andere Ideen, die Benutzerdaten pro Client zu trennen, wenn Sie welche haben.

Antwort

1

Ich denke, Sie können es in gespeicherten Verfahren tun. Es wird so etwas wie

DELIMITER // 
CREATE DEFINER='root'@'localhost' PROCEDURE GetData(IN user_id INT) 
BEGIN 
    DECLARE db_name varchar(100); 
    SELECT DatabaseName INTO db_name FROM MasterDatabase.Person WHERE PersonId = user_id; 
    SET @t1 =CONCAT('SELECT * FROM ',db_name,'.Person'); 
    PREPARE stmt1 FROM @t1; 
    EXECUTE stmt1; 
END// 

UPDATE schauen Sorry, ich DEALLOCATE PREPARE stmt1; vergessen; es sollte nach EXECUTE stmt1; sein

+0

Danke für die Antwort, während das für das Erhalten von 1 Benutzer funktioniert, ich hoffte auf eine Lösung, die jedem Schema mit einer Funktion/Abfrage beitreten würde. Ich nehme an, ich könnte jeden Benutzer durchlaufen und im Wesentlichen tun, was Sie haben, aber ich denke nicht, dass das sehr effizient wäre. – crontab

Verwandte Themen