快速回顾 MySQL:字符集、校对顺序和安全管理

前提要述:参考书籍《MySQL必知必会》

17.1 字符集和校对顺序

我们有时候会乱码,主要原因就是字符集的编码设置,这是很多语言都遇到过的问题,数据库也是如此;而校对顺序就是:假如A和a的比较,取决于我们是否区分大小写,这就是需要设置校对顺序。

像我们创建表或数据库时,通常得指定字符集,不然就会给出一个默认的字符集。该默认的字符集在mysql安装目录中名为my.ini的文件中可以看到,也可以修改。下面是我在my.ini的配置:

[mysqld]
# port 3306   端口号
port=3306
# install path   安装路径
basedir=G:\\frame\\MYSQL\\mysql-5.7.24-winx64
# data path  存放数据的路径
datadir=G:\\frame\\MYSQL\\mysql-5.7.24-winx64\\mysqldata
# max_connections   最大连接数
max_connections=200
# max_connect_errors   连接错误5次就拒绝连接(防止黑客侵入数据丢失)
max_connect_errors=5
# charset   默认编码方式
character-set-server=utf8
# default-storage-engine   默认存储引擎
default-storage-engine=INNODB
# plugs  默认密码插件
default_authentication_plugin=mysql_native_password
[mysql]
default-character-set=utf8
[client]
port=3306
default-character-set=utf8

我都把字符集改成默认为utf8。

一些术语:

  • 字符集(Character Set)为字母和符号的集合;
  • 编码(Encoding)为某个字符集成员的内部表示;
  • 校对(也叫字符序)(Collation)为规定字符如何比较的指令。

17.1.1 使用字符集和校对顺序

MySQL支持众多的字符集。为查看所支持的字符集完整列表,使用以下语句:

SHOW CHARACTER SET;

可以看到所有可用的字符集以及每个字符集的描述和默认校对。

查看所支持的校对的完整列表:

SHOW COLLATION;

可以看到所有可用的校对,以及它们适用的字符集。有的字符集不止一种校对。


查看目前我们使用的字符集:

# 查看字符集
SHOW VARIABLES LIKE 'character%'';

下面解释显示的Variable_name:

  • character_set_client:客户端来源数据使用的字符集
  • character_set_connection:连接层字符集
  • character_set_database:当前选中数据库的默认字符集
  • character_set_results:查询结果字符集
  • character_set_server:默认的内部操作字符集
  • character_set_system:系统元数据(字段名等)字符集

为什么会有这么多种字符集?这涉及到转换:(参考别人,最下面有贴转载地址)

MySQL中的字符集转换过程

  1. MySQL Server收到请求时将请求数据从character_set_client转换为character_set_connection;

  2. 进行内部操作前将请求数据从character_set_connection转换为内部操作字符集,其确定方法如下:

    • 使用每个数据字段的CHARACTER SET设定值(character_set_system);
    • 若上述值不存在,则使用对应数据表的DEFAULT CHARACTER SET设定值(MySQL扩展,非SQL标准);
    • 若上述值不存在,则使用对应数据库的DEFAULTCHARACTER SET设定值(character_set_database);
    • 若上述值不存在,则使用character_set_server设定值。
  3. 将操作结果从内部操作字符集转换为character_set_results。

可以回忆一下,在创建数据库时我们需要指定字符集和校对顺序;在表中也有指定,不然就默认。这也可看出MySQL对于字符集提供了不同级别的设置,包括server级、database级、table级、column级。其中,中间两个级别就是刚才说的那两种。

而column级可用在表定义列时指定,我们也可以在SELECT语句中指定列的字符集和校对顺序:

SELECT _utf8 '我是小白' COLLATE utf8_general_ci;

而server级则就是我们上面的character_set_server,可用在mysql安装目录的my.ini指定。


查看校对顺序:

# 查看校对顺序
SHOW VARIABLES LIKE 'collation%';

对于校对顺序,一般常使用有两种就是是否区分大小写的校对顺序,像utf8_general_ci是不区分大小写;utf8_bin就区分大小写。名字带有general_ci的时不区分大小写的校对,而不带的就是区分大小写的校对。

下面来个创建表时指定的字符集和校对顺序:

CREATE TABLE mytable
(
    c1 INT PRIMARY KEY,
    t2 VARCHAR(10),
    t3 VARCHAR(10) CHARACTER SET 'utf8' COLLATE 'utf8_bin'
) DEFAULT CHARACTER SET 'utf8'
    COLLATE 'utf8_general_ci';

可插入大写A,然后使用WHERE子句试试。

mysql> SELECT * FROM mytable WHERE t2='A';
+----+----+----+
| c1 | t2 | t3 |
+----+----+----+
|  1 | A  | A  |
+----+----+----+
1 row in set (0.07 sec)

mysql> SELECT * FROM mytable WHERE t2='a';
+----+----+----+
| c1 | t2 | t3 |
+----+----+----+
|  1 | A  | A  |
+----+----+----+
1 row in set (0.06 sec)

mysql> SELECT * FROM mytable WHERE t3='a';
Empty set

mysql> SELECT * FROM mytable WHERE t3='A';
+----+----+----+
| c1 | t2 | t3 |
+----+----+----+
|  1 | A  | A  |
+----+----+----+
1 row in set (0.06 sec)

一般,MySQL如下确定使用什么样的字符集和校对:

  • 如果指定CHARACTER SET和COLLATE两者,则使用这些值。
  • 如果只指定CHARACTER SET, 则使用此字符集以及其默认的校对。
  • 如果即不指定CHARACTER SET,也不指定COLLATE,则使用数据库默认的。

COLLATE子句还可以用在GROUP BY、HAVING、聚集函数、别名等。

参考:
Mysql字符集设置

17.2 安全管理

17.2.1 访问控制

MySQL服务器的安全基础是:用户应该对他们需要的数据具有适当的访问权,既不能多也不能少。

回忆前面登录数据库时,用户名使用的是root,它对整个MySQL服务器具有完全的控制。但是在日常工作中,绝不能使用root,应该创建一系列账号,有的用于管理,有的供用户使用,有的供开发人员使用。

17.2.2 管理用户

MySQL用户账号和信息存储在名为mysql的MySQL数据库中。一般不需要直接访问mysql数据库和表(稍后就会知道原因),但有时需要直接访问。需要直接访问它的时机之一是在需要获得所有用户账号列表时。可使用以下代码:

USE mysql;
SELECT user FROM user;

可用多个客户机(mysql命令行多开),其中一个作为管理登录,其他作为被测试的用户登录。

17.2.3 创建用户账号

使用CREATE USER语句:

CREATE USER 'ben' IDENTIFIED BY '123456';

(我测试了好像不一定要在mysql数据库里创建)

解释:可使用这样:'ben’指定用户名,IDENTIFIED BY指定密码。

用户可定义为user@host,比如’ben’@‘localhost’。MySQL的权限用用户名和主机名结合定义。如果不指定主机名,则使用默认的主机名%(授予用户访问权限而不管主机名)

IDENTIFIED BY 指定的口令(密码)为纯文本,保存到user表之前对其进行加密。

重命名用户名:

RENAME USER ben TO benb;

17.2.4 删除用户账号

使用DROP USER语句:

DROP USER benb;

17.2.5 设置访问权限

在创建用户后,必须接着分配访问权限。新创建的用户账号没用访问权限,只能登录而已,所以看不到数据,也不能操作数据库。

可使用以下语句查看用户账号的权限:

SHOW GRANTS FOR ben;

输出:

+---------------------------------+
| Grants for ben@%                |
+---------------------------------+
| GRANT USAGE ON *.* TO 'ben'@'%' |
+---------------------------------+
1 row in set (0.04 sec)

解释:显示用户ben有一个权限USAGE ON .。USAGE表示根本没有权限(这MySQL设置的,不直观),所以此结果就表示在任意数据库和任意表上对任何东西没有权限。

可使用GRANT语句设置权限,但必须给出以下信息:

  • 要授予的权限;
  • 被授予访问权限的数据库或表;
  • 用户名。

比如:

GRANT SELECT ON crashcourse.* TO ben;

解释:授予用户在crashcourse.*(crashcourse数据库所有表,不管数据库存不存在)上使用SELECT。即,用户ben对crashcourse数据库所有表具有只读访问权限。

来查看:

# 查看ben的权限
SHOW GRANTS FOR ben;
# 输出:
+-------------------------------------------------+
| Grants for ben@%                                |
+-------------------------------------------------+
| GRANT USAGE ON *.* TO 'ben'@'%'                 |
| GRANT SELECT ON `crashcourse`.* TO 'ben'@'%'    |
+-------------------------------------------------+
3 rows in set (0.04 sec)

撤销权限使用REVOKE语句:

REVOKE SELECT ON crashcourse.* FROM ben;

注意:被撤销的访问权限必须存在,否则出错。


GRANT和REVOKE可在几个层次上控制访问权限:

  • 整个服务器,使用GRANT ALL和REVOKE ALL;
  • 整个数据库,使用ON database.*;
  • 特定的表,使用ON database.table;
  • 特定的列;
  • 特定的存储过程。

参考官网:MySQL

权限 说明
ALL [PRIVILEGES] 除了GRANT OPTION外的所有权限
ALTER 使用ALTER TABLE
ALTER ROUTINE 使用ALTER PROCEDURE和DROP PROCEDURE
CREATE 使用CREATE TABLE
CREATE ROUTINE 使用CREATE PROCEDURE
CREATE TABLESPACE 使用CREATE TABLESPACE
CREATE TEMPORARY TABLES 使用CREATE TEMPORARY TABLE
CREATE USER 使用GREATE USER、DROP USER、RENAME USER和REVOKE ALL PRIVILEGES
CREATE VIEW 使用CREATE VIEW
DELETE 使用DELETE
DROP 使用DROP TABLE
EVENT 允许使用为事件计划程序创建、更改、删除或显示事件的语句。
EXECUTE 使用CALL和存储过程
FILE 使用SELECT INTO OUTFILE和LOAD DATA INFILE
GRANT OPTION 使用GRANT和REVOKE
INDEX 使用CREATE INDEX和DROP INDEX
INSERT 使用INSERT
LOCK TABLES 使用LOCK TABLES
PROCESS 使用SHOW FULL PROCESSLIST(查看进程权限)
PROXY 允许一个用户模拟或成为另一个用户
REFERENCES 创建外键约束需要父表的REFERENCES权限
RELOAD 使用FLUSH
REPLICATION CLIENT 服务器位置的访问
REPLICATION SLAVE 由复制从属使用
SELECT 使用SELECT
SHOW DATABASES 使用SHOW DATABASES
SHOW VIEW 使用SHOW VIEW
SHUTDOWN 使用mysqladmin shutdown(用来关闭MySQL)
SUPER 使用CHANGE MASTER、KILL、LOGS、PURGE、MASTER和SET GLOBAL。还允许mysqladmin调试登录
TRIGGER 使用
UPDATE 使用UPDATE
USAGE 无访问权限

可通过列出各权限并用逗号分隔,将多条GRANT语句串在一起,如下:

GRANT SELECT, INSERT ON crashcourse.* TO ben;

在使用GRANT和REVOKE时,用户账号必须存在,但对所涉及的对象没有这个要求。这允许管理员在创建数据库和表之前设计和实现安全措施。这样的副作用就是:当某个数据库或表被删除时,相关的访问权限还在。而且如果将来重新创建该数据库或表,这些权限仍然起作用。

17.2.6 更改口令

使用SET PASSWORD语句,新口令必须如下加密:

SET PASSWORD FOR ben = PASSWORD('n3w');

新口令必须传递到PAWWRORD()函数进行加密。

还可以对当前登录用户的口令更改,即不指定用户名:

SET PASSWORD = PASSWORD('n3w');

17.3 数据库维护

17.3.1 备份数据

MySQL数据必须经常备份。由于MySQL数据库是基于磁盘的文件,普通的备份系统和例程就能备份MySQL的数据。但是由于这些文件总是处于打开和使用状态,普通的文件副本备份不一定总是有效。下面提出解决:

  • 使用命令行实用程序mysqldump转存所有数据库内容到某个外部文件。在进行常规备份前这个实用程序应该正常允许,以便能够整个地备份转存文件。
  • 可用,命令行实用程序mysqlhotcopy从一个数据库复制所有数据(并非所有数据库引擎都支持这个实用程序)
  • 可用使用MySQL的BACKUP TABLE或SELECT INTO OUTFILE转存所有数据到某个外部文件。这两条语句都接受将要创建的系统文件名,此系统文件必须不存在,否则会出错。数据可用RESTORE TABLE来复原。

为保证所有数据被写道磁盘(包括索引数据),可能需要在进行备份前使用FLUSH TABLES语句,即刷新未写数据。

17.3.2 进行数据库维护

下面说一些该知道的语句:

  1. ANALYZE TABLE:用来检查表键是否正确:
ANALYZE TABLE orders;

输出:

+-----------+---------+----------+----------+
| Table     | Op      | Msg_type | Msg_text |
+-----------+---------+----------+----------+
| tt.orders | analyze | status   | OK       |
+-----------+---------+----------+----------+
1 row in set (0.08 sec)
  1. CHECK TABLE用来针对许多问题对表进行检查。在MyISAM表上还对索引进行检索(5.0以后也应该对InnoDB的索引一样检索)。CHECK TABLE支持一系列的用于MyISAM表的方式:CHANGED检查自最后一次检查以来改动过的表;EXTENDED执行最彻底的检查,FAST只检查未正常关闭的表;MEDIUM检查所有被删除的链接并进行键检验;QUICK只进行快速扫描。
CHECK TABLE orders, orderitems;

输出:

+---------------+-------+----------+----------+
| Table         | Op    | Msg_type | Msg_text |
+---------------+-------+----------+----------+
| tt.orders     | check | status   | OK       |
| tt.orderitems | check | status   | OK       |
+---------------+-------+----------+----------+
2 rows in set (0.08 sec)

其他使用方式:

CHECK TABLE orders,orderitems QUICK;
  • 如果MyISAM表访问产生不正确和不一致的结果,可能需要用REPAIR TABLE来修复相应的表。这条语句不应该经常使用,如果需要经常使用,那么可能会有更大的问题要解决。
  • 如果从一个表中删除大量数据,应该使用OPTIMIZE TABLE来回收所用的空间,从而优化表的性能。

17.3.3 其他指令

  • --helo:显示帮助,一个选择列表;
  • --safe-mode:装载减去某些最佳配置的服务器;
  • --verbose:显示全文本消息
  • --version:显示版本信息

17.3.4 查看日志文件

  • 错误日志:它包含启动和关闭问题以及任意关键错误的细节。此日志名通常为host
    name.err,位于data目录中。此日志名可用:--log-error 命令行选项更改。
  • 查询日志:它记录所有的MySQL活动,在诊断问题时非常有用。此日志文件可能会很快地变得很大,因此不应该长期使用它。此日志名通常为hostname.log,位于data目录中。此名字可用--log 命令行选项更改。
  • 二进制日志:它记录更新过数据(或可能更新过数据)的所有语句。此日志名通常为hostname-bin,位于data目录中。此名字可用:--log-bin 命令行选项更改。注意,这个日志文件是MySQL5中添加的,以前的MySQL版本中使用的是更新日志。
  • 缓慢查询日志:此日志记录执行缓慢的任何查询。这个日志在确定数据库何处需要优化很有用。 此日志名通常为hostname-slow.log,位于data目录中。此名字可用: --log-slow-queries 命令行选项更改。

在使用日志时,可用FLUSH LOGS语句来刷新和重新开始所有的日志文件。

更多的缓慢查询日志请看这篇:MySQL慢查询日志总结

发布了61 篇原创文章 · 获赞 30 · 访问量 2万+

猜你喜欢

转载自blog.csdn.net/weixin_41800884/article/details/104066837