数据库系统概论学习笔记(七):安全性,数据完整性(触发器)

版权声明:本文为博主原创文章,转载请注明出处。 https://blog.csdn.net/credolhcw/article/details/59103957

安全第一

所以,这部分真的只是过一下而已!走马观花的过一下而已!!


数据库的安全性

官方文档: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';

Create User 1

然后登陆credo用户,执行以下SELECT,会发现被拒绝了,因为没有相应的权限。

Select denied
 
另外,有创建就会有删除(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';

Grant Select

然后分别对mysql.user和credo.student进行SELECT操作,会发现对前者的操作依然被拒绝,而对后者的SELECT操作则顺利执行。

Grant select result
 
那么,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';

结果如图:
Revoke Select

Revoke Select Result
 


用户定义完整性

数据完整性主要包括主体完整性、参照完整性、用户定义的完整性。前面几章已经提到过主体完整性、参照完整性的定义和实现。这里就记一下用户如何自定义完整性约束条件。

用户定义完整性主要包括: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';

Account Trigger
 
例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';

Three Triggers
 
可以看到表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;

猜你喜欢

转载自blog.csdn.net/credolhcw/article/details/59103957