简短的回答:不要让您的用户直接访问数据库。他们应该永远无法连接。只有负责维护和操作的人员才能访问生产数据库。这是出于安全原因。几乎在所有信息存储在数据库中的情况下,都有一个应用程序控制所有访问,它处理实际更新,并强制执行您选择的业务逻辑。
不要将数据与业务逻辑混为一谈。
有一些数据库系统,比如 Oracle,它们擅长让你的存储和应用你的大部分业务逻辑到数据库本身。但是,这是针对不同类型的应用程序和构建系统的不同方法。
MySQL 没有所有这些工具来让这件事变得如此简单。相信我,当我告诉您,如果您尝试在触发器、存储过程和视图中编写应用程序逻辑,然后让您的用户直接访问数据库,那么您正在为维护噩梦做准备。
当您注册某项服务时,您最后一次获得直接数据库访问权限是什么时候?Twitter、Netflix、Groupon、Facebook——您正在与基于 Web 的应用程序交互,该应用程序应用业务规则并代表您将数据读取和写入数据库。
有很多工具可以让您更轻松地编写应用程序软件:调试、分析、代码和协作开发的源代码控制、单元测试、持续集成和部署工具。如果您尝试将所有内容写入数据库,您将失去所有这些。
这是一个如何工作的简单示例:
将您的权限系统构建为三个表:user、group、user_group。用户拥有您系统中的用户帐户,组拥有各种访问级别,例如“管理员”、“客户端”、“匿名”等。组是您为用户分配访问级别的方式。
`CREATE TABLE `user` (
`user_id` int(10) unsigned NOT NULL AUTO_INCREMENT,
`email` varchar(64) NOT NULL,
PRIMARY KEY (`user_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
CREATE TABLE `group` (
`group_id` int(10) unsigned NOT NULL AUTO_INCREMENT,
`name` varchar(32) NOT NULL,
PRIMARY KEY (`group_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
CREATE TABLE `user_group` (
`user_id` int(10) unsigned NOT NULL,
`group_id` int(10) unsigned NOT NULL,
PRIMARY KEY (`user_id`,`group_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;`
现在定义一些组
`insert into `group` (name) values ('admin'), ('user'), ('anonymous');`
和一个用户,然后将他们添加到管理员组:
`insert into user (email) values ('admin@yoursite.com');`
`insert into user_group (user_id,group_id) values (1,1);`
现在这个权限模型表明一个用户可以属于一个或多个安全组。您的应用程序将检查这些组并根据结果执行不同的操作。让我们看一些伪代码:
加载用户组:
class User {
private $user_id;
private $groups;
private $db;
function load_groups() {
// query the database
$result = $db->query("SELECT name FROM `group` g JOIN user_group ug USING (group_id) WHERE user_id={$this->user_id}");
// save an array of group names
while ($row = $result->fetchrow()) {
$this->groups[] = $row['name'];
}
}
function is_member($group) {
if (in_array($group, $this->groups) {
return true; // user group includes this value
}
return false; // user is not in the group
}
现在在您的应用程序中,您可能有一个查看数据的功能,但它会根据用户的组产生不同的结果:
function display_data($user_object) {
display_basic_data(); // everyone sees the basic data
if ($user_object->is_member('admin')) {
// if the user is an admin, then display bank data too
display_bank_data();
}
}
同样,您修改数据的功能应验证用户是否有权更改内容。