安全第一
所以,这部分真的只是过一下而已!走马观花的过一下而已!!
数据库的安全性
官方文档:https://dev.mysql.com/doc/refman/5.7/en/security.html
MySQL也有非常详尽的安全性控制文档,我这个笔记的内容偏向于SQL应用,所以只记录一些与SQL有关的内容。
上一篇中也提到了“视图”也有一定的安全性作用,这篇也就不记了。
创建用户(CREATE USER)
本来以为内容不多,结果看了一个多小时ヽ(ˋДˊ)ノ。而且,MySQL 5.7.6前后版本还有些区别,我用的是5.7.17版本的,所以前面版本的并不清楚。
官方文档:https://dev.mysql.com/doc/refman/5.7/en/create-user.html
To use CREATE USER, you must have the global CREATE USER privilege, or the INSERT privilege for the mysql database. When the read_only system variable is enabled, CREATE USER additionally requires the SUPER privilege.
使用CREATE USER需要全局的“CREATE USER”权限,或者拥有数据库的INSERT权限。当系统变量read_only = enabled时,只有SUPER权限的用户才可以使用“CREATE USER”。
创建的用户都记录在 mysql.user 中。另外,MySQL中新创建的用户没有任何权限。
An account when first created has no privileges.
例1、创建一个用户credo,密码credo。
CREATE USER 'credo'@'localhost'
IDENTIFIED BY 'credo';
然后登陆credo用户,执行以下SELECT,会发现被拒绝了,因为没有相应的权限。
另外,有创建就会有删除(https://dev.mysql.com/doc/refman/5.7/en/drop-user.html)。
删除credo用户:
DROP USER 'credo'@'localhost';
也会有修改用户(ALTER USER)的情况,格式和CREATE USER差不多:
https://dev.mysql.com/doc/refman/5.7/en/alter-user.html
更少不了重命名用户(RENAME USER)的情况:
https://dev.mysql.com/doc/refman/5.7/en/rename-user.html
授权(GRANT)
官方文档:https://dev.mysql.com/doc/refman/5.7/en/grant.html
想要授权,首先需要能够将权限授予给其他用户的权限,然后本身也需要具有欲授予权限的权限。(太绕了不是吗?°(°ˊДˋ°) °,我只是想试试到底能说的有多绕)
To use GRANT, you must have the GRANT OPTION privilege, and you must have the privileges that you are granting. When the read_only system variable is enabled, GRANT additionally requires the SUPER privilege.
使用GRANT,首先需要GRANT的权限,然后只能将已经具备的权限授权给其他用户。另外,同CREATE USER一样,当系统变量read_only = enabled时,只有具有SUPER权限的用户才能授权。
SQL语句格式:
GRANT <权限>
ON <对象类型>
TO <用户> ;
例2、将查询数据库credo中所有表的权限授予给用户’credo’@’localhost’。
GRANT SELECT
ON credo.*
TO 'credo'@'localhost';
然后分别对mysql.user和credo.student进行SELECT操作,会发现对前者的操作依然被拒绝,而对后者的SELECT操作则顺利执行。
那么,MySQL具体有哪些可授权(回收)的动作咧?参见下表。
Permissible Privileges for GRANT and REVOKE
Privilege Meaning and Grantable Levels ALL [PRIVILEGES] Grant all privileges at specified access level except GRANT OPTION and PROXY. ALTER Enable use of ALTER TABLE. Levels: Global, database, table. ALTER ROUTINE Enable stored routines to be altered or dropped. Levels: Global, database, procedure. CREATE Enable database and table creation. Levels: Global, database, table. CREATE ROUTINE Enable stored routine creation. Levels: Global, database. CREATE TABLESPACE Enable tablespaces and log file groups to be created, altered, or dropped. Level: Global. CREATE TEMPORARY TABLES Enable use of CREATE TEMPORARY TABLE. Levels: Global, database. CREATE USER Enable use of CREATE USER, DROP USER, RENAME USER, and REVOKE ALL PRIVILEGES. Level: Global. CREATE VIEW Enable views to be created or altered. Levels: Global, database, table. DELETE Enable use of DELETE. Level: Global, database, table. DROP Enable databases, tables, and views to be dropped. Levels: Global, database, table. EVENT Enable use of events for the Event Scheduler. Levels: Global, database. EXECUTE Enable the user to execute stored routines. Levels: Global, database, table. FILE Enable the user to cause the server to read or write files. Level: Global. GRANT OPTION Enable privileges to be granted to or removed from other accounts. Levels: Global, database, table, procedure, proxy. INDEX Enable indexes to be created or dropped. Levels: Global, database, table. INSERT Enable use of INSERT. Levels: Global, database, table, column. LOCK TABLES Enable use of LOCK TABLES on tables for which you have the SELECT privilege. Levels: Global, database. PROCESS Enable the user to see all processes with SHOW PROCESSLIST. Level: Global. PROXY Enable user proxying. Level: From user to user. REFERENCES Enable foreign key creation. Levels: Global, database, table, column. RELOAD Enable use of FLUSH operations. Level: Global. REPLICATION CLIENT Enable the user to ask where master or slave servers are. Level: Global. REPLICATION SLAVE Enable replication slaves to read binary log events from the master. Level: Global. SELECT Enable use of SELECT. Levels: Global, database, table, column. SHOW DATABASES Enable SHOW DATABASES to show all databases. Level: Global. SHOW VIEW Enable use of SHOW CREATE VIEW. Levels: Global, database, table. SHUTDOWN Enable use of mysqladmin shutdown. Level: Global. SUPER Enable use of other administrative operations such as CHANGE MASTER TO, KILL, PURGE BINARY LOGS, SET GLOBAL, and mysqladmin debug command. Level: Global. TRIGGER Enable trigger operations. Levels: Global, database, table. UPDATE Enable use of UPDATE. Levels: Global, database, table, column. USAGE Synonym for “no privileges”
回收(REVOKE)
可回收的权限列表参见上表。
官方文档:https://dev.mysql.com/doc/refman/5.7/en/revoke.html
SQL语句格式:
REVOKE<权限>
ON <对象类型>
FROM <用户> ;
仅仅是把关键字换一下,其他的和GRANT几乎一样。
例3、收回用户’credo’@’localhost’对数据库credo中所有表的查询权限。
REVOKE SELECT
ON credo.*
FROM 'credo'@'localhost';
结果如图:
用户定义完整性
数据完整性主要包括主体完整性、参照完整性、用户定义的完整性。前面几章已经提到过主体完整性、参照完整性的定义和实现。这里就记一下用户如何自定义完整性约束条件。
用户定义完整性主要包括:NOT NULL、UNIQUE、CHECK 短语。
前两个早就用嗨了,说说CHECK 短语。下面给出了两个例子,分别是三种写法。
例4、创建Student表时,限制属性Ssex只能是‘男’或者 ‘女’。
CREATE TABLE Student
(
Sno CHAR(9) PRIMARY KEY, /* 定义‘主键’的一种方法 */
Sname CHAR(20) UNIQUE, /* Sname 取唯一值 */
Ssex CHAR(2),
Sage SMALLINT,
Sdept CHAR(20),
CHECK ( Ssex IN ('男','女') ) /* 限制属性Ssex只能是‘男’或者 ‘女’ */
);
例5、当学生性别是‘男’时,其名字不能以‘Ms.’开头。
CREATE TABLE Student
(
Sno CHAR(9) PRIMARY KEY, /* 定义‘主键’的一种方法 */
Sname CHAR(20) UNIQUE, /* Sname 取唯一值 */
Ssex CHAR(2) CHECK ( Ssex IN ('男','女') ), /* 限制属性Ssex只能是‘男’或者 ‘女’ */
Sage SMALLINT,
Sdept CHAR(20),
CONSTRAINT C1 CHECK ( Ssex = '女' OR Sname NOT LIKE 'Ms.%' ) /* 当学生性别是‘男’时,其名字不能以‘Ms.’开头,并将此限制命名为C1 */
);
触发器(Trigger)
官方文档:https://dev.mysql.com/doc/refman/5.7/en/trigger-syntax.html
嗯,这个Trigger很灵活,比FOREIGN KEY、CHECK什么的加起来还要灵活。
SQL语句格式:
CREATE TRIGGER <触发器名>
{ BEFORE | AFTER } <触发事件> ON <表名>
FOR EACH { ROW | STATEMENT }
<触发动作体>
相关要求&说明:
①、同一模式下,触发器名必须唯一,并且触发器名必须和表名在同一个模式下。
②、不能在临时表或试图上创建触发器。
③、同一张表上有多个触发器时,若没有定义执行顺序,则按照建立的先后顺序触发。
④、触发动作体既可以是一个PL/SQL过程块,也可以是存储过程的调用。
⑤、只有行级触发器(FOR EACH ROW),才能用NEW和OLD表示更新前后的值。
⑥、触发事件(INSERT | DELETE | UPDATE)并不是仅只执行这三种操作时才会触发,以“INSERT”为例,当执行“LOAD DATA”时,同样是向表中插入新数据,也会触发。
例6、建立一张账目表account(acct_num INT, amount DECIMAL(10,2)),并设置一个记录总量的用户变量@sum。建立一个触发器:每插入一行记录,则计算@sum。
CREATE TABLE account (
acct_num INT,
amount DECIMAL(10,2)
);
SET @sum = 0;
CREATE TRIGGER ins_sum
BEFORE INSERT ON account
FOR EACH ROW
SET @sum = @sum + NEW.amount;
INSERT INTO account VALUES(137,14.98),(141,1937.50),(97,-100.00);
SELECT @sum AS 'Total amount inserted';
例7、建立一张成绩日志表SC_LOG(Optime,Sno,Cno,Old_Grade,New_Grade)。在SC表上定义三个行级触发器insTrigger、updTrigger、delTrigger,将SC表上的Insert、Update、Delete操作记录在SC_LOG表上。
CREATE TABLE SC_LOG
(
Optime DATETIME,
Sno CHAR(9),
Cno CHAR(4),
Old_Grade SMALLINT,
New_Grade SMALLINT,
CONSTRAINT pk PRIMARY KEY (Optime,Sno,Cno)
);
/* insTrigger */
CREATE TRIGGER insTrigger
AFTER INSERT ON SC
FOR EACH ROW
INSERT
INTO SC_LOG
VALUES(CURRENT_TIMESTAMP,NEW.Sno,NEW.Cno,NULL,NEW.Grade);
/* updTrigger */
delimiter //
CREATE TRIGGER updTrigger
AFTER UPDATE ON SC
FOR EACH ROW
BEGIN
IF NEW.Grade <> OLD.Grade THEN
INSERT INTO SC_LOG VALUES( CURRENT_TIMESTAMP, NEW.Sno, NEW.Cno, OLD.Grade, NEW.Grade);
END IF;
END;//
delimiter ;
/* delTrigger */
CREATE TRIGGER delTrigger
AFTER DELETE ON SC
FOR EACH ROW
INSERT
INTO SC_LOG
VALUES(CURRENT_TIMESTAMP,OLD.Sno,OLD.Cno,OLD.Grade,NULL);
/* Test Action */
INSERT
INTO SC(Sno,Cno,Grade)
VALUES ('200215121','1',92);
UPDATE SC
SET Grade = 97
WHERE Sno = '200215121';
UPDATE SC
SET Grade = 97
WHERE Sno = '200215121';
DELETE
FROM SC
WHERE Sno = '200215121';
可以看到表SC_LOG只有3条记录,因为第二个UPDATE其实并没有更新Grade,所以不满足updTrigger里PL/SQL过程块中的IF条件,故虽然触发了updTrigger但没有更新。
删除触发器:
例8、删除前文建立的所有触发器。
DROP TRIGGER IF EXISTS ins_sum;
DROP TRIGGER IF EXISTS insTrigger;
DROP TRIGGER IF EXISTS updTrigger;
DROP TRIGGER IF EXISTS delTrigger;