2010-12-07 9 views
2

私は、クライアントが他のクライアントのユーザーデータから分離したユーザーデータを必要とするWebアプリケーションに取り組んでいます。私たちのクライアントは互いに協力することができるので、ユーザーIDがクライアント間で一意であることを確認する必要があるため、クライアントごとに新しいアプリケーションインスタンスを作成することはできません。行データに基づくMysqlのクロススキーマクエリ

基本的に、UserIdと残りのユーザーデータを検索するデータベースの名前を含む「User」テーブルを持つ「MasterApplication」データベースがあります。各クライアントには、「MasterApplication」および独自のクライアント・テーブルにのみアクセスできる独自のデータベース・ユーザーがあります。

これはどのように見えるかの例です。

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'); 

したがって、Client1には、MasterDatabaseおよびClient1テーブルにアクセスできるデータベースユーザーが存在します。 Client2には、MasterDatabaseとClient2にアクセスできるユーザーが必要です。

私はMasterDatabaseの "DatabaseName"フィールドのデータを使用して簡単にクロススキーマクエリを実行できる方法があると思っていますが、わかりません。私はほとんどの場合、クライアントのデータベース名をアプリケーションロジックに格納してそれをクエリに挿入することができますが、すべてのクライアントを1つのクエリに結合するために必要なスポットがいくつかあります。

私の試みは

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

を行うことでした。しかし、私は期待していたとして、それは動作しませんでした。私はプロシージャでそれをやり遂げることができますか?また、クライアントごとにユーザーデータを分けるというアイディアもあります。

答えて

1

私はあなたがストアドプロシージャでそれを行うことができると思います。それは申し訳ありませんが、私はDEALLOCATE PREPARE stmt1;を忘れてしまった

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のようになります。それは後にする必要がありますEXECUTE stmt1;

+0

私は1人のユーザーを取得するために動作しますが、私は1つの機能/クエリですべてのスキーマを結合するソリューションを期待していた。私はすべてのユーザーをループして本質的にあなたが持っていることをやり遂げることができると思うが、それは非常に効率的だとは思わない。 – crontab

関連する問題