4

我目前正在编写我真正的第一个 PHP 应用程序,我想知道如何正确地项目/设计/实施 MySQL 视图;

在我的特殊情况下,用户数据分布在多个表中(由于数据库规范化),我正在考虑使用视图将数据分组到一个大表中:

CREATE VIEW `Users_Merged` (
name,
surname,
email,
phone,
role
) AS (
SELECT name, surname, email, phone, 'Customer'
FROM `Customer`
)
UNION (

SELECT name, surname, email, tel, 'Admin'
FROM `Administrator`
)
UNION (

SELECT name, surname, email, tel, 'Manager'
FROM `manager`
);

这样我可以轻松地使用来自 PHP 应用程序的视图数据,但我真的不知道这会对性能产生多大影响。

例如:

SELECT * from `Users_Merged` WHERE role = 'Admin';

是过滤视图数据的正确方法还是应该在创建视图本身之前过滤?(我需要这个有一个用户列表和按角色过滤它们的功能)。

编辑

具体来说,我想要获得的是将三个表非规范化为一个。我的解决方案正确吗? 参见维基百科上的非规范化

4

3 回答 3

3

一般来说,数据库引擎会为您执行优化。这意味着引擎将确定用户表在连接到其他表之前需要进行过滤。

所以,继续使用你的视图,让数据库担心它。

如果您稍后检测到性能不佳,请使用 MySQL EXPLAIN 让 MySQL 告诉您它在做什么。

PS:你的数据设计只允许每个用户一个角色,这是你想要的吗?如果是这样,并且您提供的示例查询是您打算经常运行的查询,请确保为 users 中的角色列建立索引。

于 2010-03-15T15:48:45.840 回答
1

如果您的用户少于 1000 个(这似乎很可能),那么您如何操作并不重要。如果用户列表不太可能在很长一段时间内发生变化,那么就性能而言,您可能做的最好的事情就是将用户列表加载到内存中,而根本不去数据库。即使同时用户数据发生变化,您也可以更新内存结构以及数据库,并且再次不必从数据库中读取用户信息。

于 2010-03-15T16:07:56.817 回答
0

将管理员、用户、经理和你拥有的东西标准化到一个统一的表中可能会更好地方。然后,您可以将特定于角色的详细信息添加到与连接中的用户表一起使用的不同表中。

然后,您的查询可能看起来很简单:

SELECT
   `Name`, `Surname`, `Email`, `Phone`, `Role`
FROM `User`
WHERE 
    `User`.`Role` IN('Administrator','Manager','Customer', ...)

union这对于数据库来说也比一组s更容易处理

如果您更进一步,您可以添加一个UserRoleCoupling表(而不是 中的RoleUser),其中包含用户每个用户拥有的所有角色:

CREATE TABLE `UserRoleCoupling` (
    UserID INT NOT NULL,  -- assuming your User table has and ID column of INT
    RoleID INT NOT NULL,
    PRIMARY KEY(UserID, RoleID)
);

并将实际的角色信息也放入一个单独的表中:

CREATE TABLE `Role` (
    ID INT NOT NULL UNIQUE AUTO_INCREMENT,
    Name VARCHAR(64) NOT NULL
    PRIMARY KEY (Name)
)

现在您可以为每个用户拥有多个角色并使用查询,例如

SELECT
    `U`.`Name`
   ,`U`.`Surname`
   ,`U`.`Email`
   ,`U`.`Phone`
   ,GROUP_CONCAT(`R`.`Name`) `Roles`
FROM `User`
INNER JOIN `UserGroupCoupling` `UGC` ON `UGC`.`UserID` = `User`.`ID`
INNER JOIN `Role` `R` ON `R`.`ID` = `UGC`.`RoleID`
GROUP BY
    `U`.`Name`, `U`.`Surname`, `U`.`Email`, `U`.`Phone`

这将为您提供基本详细信息和所有分配名称User的逗号分隔列表。Role

一般来说,规范化数据库结构的最佳方法是使表尽可能通用而不会冗余,因此不要将管理员或客户特定的详细信息添加到用户表中,而是使用 和 之间的关系UserAdministrator查找特定管理员细节。你现在这样做的方式并没有真正标准化。

我会看看我是否能找到我最喜欢的关于数据库规范化的书,并在以后有时间的时候发布 ISBN。

于 2010-03-15T18:53:52.307 回答