基于行数据的Mysql交叉模式查询

时间:2010-12-07 18:50:22

标签: sql mysql

所以我正在开发一个Web应用程序,我们的客户希望将其用户数据与其他客户端的用户数据分开。由于我们的客户可以相互协作,因此我们不能只为每个客户创建一个新的应用程序实例,因为我们必须确保用户ID匹配并且在客户端之间是唯一的。

基本上我们的“MasterApplication”数据库有一个“User”表,其中包含UserId和数据库的名称,用于查找剩余的用户数据。每个客户端都有自己的数据库用户,只能访问“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”字段中的数据轻松地进行交叉模式查询,但我无法弄清楚。我知道大部分时间我都可以将客户端的数据库名称存储在应用程序逻辑中,然后将其插入到查询中,但是我需要将一些地点连接到一个查询中。

我的尝试是

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

但这并不像我希望的那样有用。有可能我可以用程序做到吗?如果您有任何想法,我也会对每个客户分离用户数据的其他想法持开放态度。

1 个答案:

答案 0 :(得分:1)

我认为你可以在存储过程中完成它。它看起来像

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//

更新抱歉,我忘了DEALLOCATE PREPARE stmt1;;它应该在EXECUTE stmt1;之后