day33 数据库初识
今日内容概要
- 数据库的概念
- 数据库的基本术语
- 数据库的分类
- MySQL的安装
- MySQL的基本命令
昨日内容回顾
- socketserver
- subprocess
- 粘包
今日内容详细
数据库的概念
我们从前都是把数据存放到文件当中。但是对于真正的生产环境而言,文件存储有其先天的不足。
比如,很多情况下,我们的客户端和服务器都不止一个。而如果把数据只以文件的形式存储到一个服务器上,另一台服务器可能不能及时接收到相应。对于用户信息之类的重要数据而言,这将是不可接受的。而且我们往往一台计算机只进行一种任务。这样的话,即便有一台计算机出了问题,其他计算机依然可以继续正常工作,整个系统的容灾性会很好。
于是,很多情况下,我们会把储存数据的任务交给独特的计算机,也就是数据库。
当然,一台数据库也可能不能满足我们对多任务处理和数据安全的要求,我们还会使用多台计算机协调备份数据。
数据库之间实时要进行通信,一旦某一个数据库中的数据发生了改变,另一个数据库也要及时备份。
我们其实可以按照从前学过的socket网络编程和文件操作的只是来实现数据库的操作。但是,如果要保证能够完美地支持高并发,支持多台计算机完美协调,将会是一个极其困难繁琐的工作。
好在有很多很厉害的程序员已经帮我们写好了这类处理存储数据的工具,我们可以直接拿来用。这就是我们要学期的数据库管理系统。
数据库是一个存储数据的工具。
数据库帮我们解决了很多问题:
- 安全认证
- 并发问题,多个程序都请求同一个数据库获取数据
- 优化:缓存cache,分析
- 容灾:数据库搭建集群
这里解释一下数据库对我们存储数据的优化。当数据量很大的时候,我们先想要从中获取想要的数据可能会比较麻烦。而有些数据,我们又需要经常地反复地获取。如果每次数据库都从硬盘中重新查找,将会耗费很多时间。于是,很多数据库都对这种情况做出了优化。当我们使用完一条数据之后,这条数据会储存到一个暂存区cache中。当我们下次还想获取同样的数据时,不会去硬盘中查找,而是先去缓存cache中查找。如果能够找到,那就直接使用。这样一来,对于一些经常使用的数据,会节省很多查找的时间,从而提高程序的运行效率。
数据库的基本术语
数据库经过这么多年的发展,已经相当程序。程序员间对数据库中的一些概念有了一套约定俗成的称谓,也就是数据库的基本术语。我们需要了解这些数据,以便日后能够跟人更好地交流学习。
数据库管理系统(DBMS,database management system):
- 管理着一个大的文件系统
- 包括文件夹(数据库)和文件(表)
数据库(DB,database):就是文件夹
表(table):文件
一条数据:文件中的每一行数据
数据:data
数据库管理员(DBA):database administrator
需要指明的是,我们口头上常说的数据库,并不单单指文件夹。我们说的数据库,可能指文件夹,也可能指数据库管理系统,还可能指整个数据库的软硬件体系。具体指代哪一个,要因地制宜,不可钻牛角尖。
数据库的分类
数据库根据其数据间的逻辑,可分为关系型数据库和非关系型数据库两类,其代表性的数据库分别有:
- 关系型数据库:MySQL,Oracle,SQL server,SQLite
- 非关系型数据库:Redis,MongoDB,HBase,MemCache
MySQL的安装
我们要学习的数据库是MySQL。选择这个数据库的原因是,它发展的时间较久,总体而言比较成熟。而且它开源免费,深受互联网公司欢迎。基本上,我们国家的互联网公司,使用的关系型数据库,90%以上都是MySQL。
最新的MySQL版本是8.0版本。但是一般而言,新版本的软件不确定性很多。比如兼容性和稳定性都不很确定。大多数时候,我们都会选择一个从前的稳定版本来使用。于是,我们安装的不是最新的MySQL 8.0版本,而是5.6版本。
之所以也不使用5.7版本,是因为5.7版本在初始化时会默认生成一个密码,如果没有记住又没来得及修改很麻烦,所以不推荐使用。
我们下载MySQL只能来自两个途径,MySQL官方网站和公司给我们提供的MySQL。其他途径下载的MySQL有可能会存在安全隐患,极度不推荐使用。数据是极其重要的,万不可以马虎。
首先,我们在浏览器中输入www.mysql.com
进入MySQL官方网站。点击主页上的DOWNLOADS
标签,进入MySQL的下载页,https://www.mysql.com/downloads/
。
在下载页中,找到MySQL社区版下载的入口,MySQL Community (GPL) Downloads »
,进入到社区版下载页,https://dev.mysql.com/downloads/
。
找到需要下载在哪种平台使用的MySQL。我用的是Windows系统,所以选择MySQL Installer for Windows
。进入到最新版本MySQL的下载页面,https://dev.mysql.com/downloads/installer/
。如果是Mac或Linux系统,也可以按自己的需要下载不同的版本。
这个页面是最新的8.0版本的下载页面。按我们刚刚所说,我们要下载的是5.6版本。点击右上角的Looking for previous GA versions?
,进入到版本选择界面。
在下拉框中选择我们要下载的5.6.45版本。
这个方法虽然也能找到5.6版本MySQL的安装包,但只能找到32位版本。如果想要下载64位版本的安装包,可以去5.6版本专门的下载界面,https://dev.mysql.com/downloads/mysql/5.6.html#downloads
。
下载好了之后,将压缩包解压到文件夹中。最好把它解压到根目录中。
需要注意的是,安装路径要尽量避免出现中文。而且不可以有\n \t
之类有特殊含义的字母。
使用PyCharm创建一个名为my.ini
的文件,并在文件中写入下面的内容:
[mysql] # 设置mysql客户端默认字符集 default-character-set=utf8 [mysqld] #设置3306端口 port = 3306 # 设置mysql的安装目录 basedir=C:\mysql-5.6.46-winx64 # 设置mysql数据库的数据的存放目录 datadir=C:\mysql-5.6.46-winx64\data # 允许最大连接数 max_connections=200 # 服务端使用的字符集默认为8比特编码的latin1字符集 character-set-server=utf8 # 创建新表时将使用的默认存储引擎 default-storage-engine=INNODB
如果你是复制粘贴过去的,首先要检查每一行后面是否有空格。如果有,一定要删除干净。每一行后面都不可以有任何空格,否则可能会出现莫名其妙的错误。
然后,将basedir
和datadir
两个修改成你刚刚解压的MySQL文件所处的路径。
修改完成后,保存并关闭。然后把这个my.ini
文件放到刚刚解压的MySQL根目录中。
数据会存放在data文件夹中,而命令的执行程序则被放在bin文件夹中。
我们需要把bin所在的目录放到环境变量中,这样才能顺利使用MySQL的各种命令。
以管理员身份运行终端cmd,在终端中输入下面两条命令:
mysqld install net start mysql
如果提示安装成功,则说明一切安装顺利。
如果输入第一条命令时,提示说mysqld不是系统命令,说明没有成功将bin目录添加到环境变量中,需要检查一下环境变量。
另外一个需要注意的是一定要以管理员身份运行cmd。具体方法是,在搜索框(比如小娜)中,搜索cmd,然后右键出现的cmd,选择以管理员身份运行即可。
还有一点,不可以双击打开my.ini文件。因为Windows使用的是gbk编码,而我们需要它使用utf-8编码。但是,如果我们双击打开文件,有可能会改变文件的编码方式,从而导致错误。如果需要编辑,可以使用PyCharm或者notepad++之类的能够指定编码的编辑器。
我们刚刚输入了两条命令,其含义为:
mysqld install
,在命令行中启动mysqld.exe文件,传入了一个参数installnet start mysql
,告诉操作系统启动已经安装好的MySQL服务
MySQL的服务默认开机自启,只要我们不关闭,就会一直在后台运行。如果我们想要关闭这个服务,可以使用与开启服务类似的命令:
net stop mysql
只有安装MySQL和开启关闭MySQL服务时需要使用管理员身份运行cmd,其他操作都可以在普通的cmd中运行。
另外,我们还需要区分MySQL的服务端和客户端:当我们执行mysql.exe文件时,实际上执行的是客户端。
MySQL客户端命令
进入客户端
我们可以直接在终端中输入mysql进入终端,但是几乎没有什么权限,因为我们还没有登陆。新出现的mysql>
意味着我们可以在后面输入MySQL指令。
我们还可以通过指定用户名和密码的方式登录指定的用户操作数据库:
mysql -uroot -p
这行代码中,-u后面接的是用户名,意思是要登陆root用户。-p后面可以解密码,但是此时密码会以明文的形式出现,有可能会不安全。建议输入完-p之后按回车,然后再按照提示,输入密码。此时的密码会以*代替,安全性大大提高。MySQL 5.6版本,root用户初始密码为空,可以直接登录。
如果服务器在局域网内的另一台计算机上,需要在用户名后,用-h指定另一台计算机的IP:
mysql -uguest -h192.168.34.112 -p
退出客户端
推出客户端的命令有两个:
exit quit
这两个命令的功能完全一样,随意使用哪一个都可以推出客户端。
和用户相关的命令
如果想要知道当前登录的用户名是什么,可以使用命令:
select user();
需要注意的是,MySQL中,每一条命令结束之后都要使用;
表示命令的终止。
输出的结果中,root
表示的是用户名;localhost
指代的是IP地址。
MySQL 5.6版本的root用户初始密码为空。root用户有着最高的管理权限,不能让人随意登录。于是,我们需要给它设置密码,保护我们的数据安全:
set password = password('123');
password()
用来给密码使用MD5的方式加密。密码需要使用引号引起来。
我这里的密码是123,练习时是没问题的。但是在真正的生产环境中,还是要使用复杂一点的密码,保障数据的安全。
我们可以授权数据库给某个用户,其命令为:
grant all on *.* to 'username'@'%' identified by '123';
使用下面的命令,让更改立即生效:
flush privileges;
在授权用户的命令中:
all
意味着授权所有权限。我们也可以限制用户的权限,例如将它改成select
等*.*
意味着将所有数据库的所有内容全部开放。但是更多时候,我们只会给一个用户开放一个数据库的权限,我们可以指定授权的数据库,例如test.*
。'username'
指代的当然是用户名。'%'
表示,对于所有IP的计算机,只要用户名和密码正确,都可以访问。我们也可以限制IP段位,例如'192.168.10.%'
。%在这里可以指带任意数字。有时候远程访问时的IP会显示为localhost
,需要进行其他设置。目前,我们还没能力解决类似的问题,暂时还是用一个%指代所有IP即可。'123'
是授权用户的密码。
有了上面的知识,我们就可以通过下面的步骤,让局域网中的其他人访问我们的数据库:
- 我是root用户,我可以给别人一个权限,让他能够访问我
- 使用
create database 数据库名
创建一个想要共享的数据库 - 使用命令
grant all on 数据库名.* to '用户名'@'%' identified by '密码';
,将数据库的所有权限开放给指定用户 - 将用户名和密码告诉我们的合作伙伴
- 伙伴通过用户名和密码连接我们的数据库:
mysql -u用户名 -hIP -p
数据库基本操作
数据库操作
数据库,database,db,其本质上就是一个文件夹。
要想查看我们都有哪些数据库,可以使用这个命令:
show databases;
输出的结果为:
+--------------------+ | Database | +--------------------+ | information_schema | | helloworld | | mysql | | performance_schema | | public | +--------------------+
如果想要创建一个数据库,可以使用命令:
create database 数据库名;
例如,我们创建一个名为test的数据库,其命令为:
create database test;
回车之后,提示创建成功:
Query OK, 1 row affected (0.00 sec)
我们在数据存放的目录中,也发现新创建了一个名为test的文件夹。
需要注意的是,我们无论如何也不可以改动MySQL安装目录中的文件。因为这些文件都是按照很复杂的规则编写的,文件直接的关联也很紧密。修改一个数据,有可能造成整个数据库无法正常运行,甚至会造成数据的错误和丢失。
另外,创建的数据库名字中不能出现中文和特殊字符。一定要按照变量命名规范,使用数字、字母和下划线命名。
如果我们需要使用一个数据库,只需要使用命令:
use 数据库命;
这里的分号可以不加。在MySQL中,几乎只有use和exit、quit这三个命令后面不需要加分号了。但是稳妥起见,还是建议后面加上一个分号。
例如,我们要使用刚刚创建的test数据库,就可以这样写:
use test;
返回结果如下,说明成功切换到test数据库:
Database changed
如果想知道当前使用的是哪一个数据库,可以输入命令:
select database();
当前运行的数据库名顺利返回:
+------------+ | database() | +------------+ | test | +------------+
我们日后几乎不会有删除数据库的需求。删除数据库是一个非常不好的行为,所以不在这里介绍删除数据库的方法。如果一定要学习,或者真的有删除数据库的需求,可以自行搜索,还是很简单的。
表操作
表,table,本质上就是数据库中的每一个文件。
创建表的方式和创建数据库极其相似,也是要用到create语句。不过创建表时,我们需要指定表头内容,以及其中的数据类型:
create table 表名( id int, name char(20), age int);
需要注意,最后一项的后面不可以加逗号。
在MySQL中,如果不在语句的后面加分号,就会认为命令没有完结,就还可以继续输入。多行输入可以让内容开起来更直观。
上面的例子中,id、name和age是表头,int的意思是,id和age必须是整数。char(20)的意思是,名字必须是不超过20位的字符串。
除了int和char外,MySQL中还有其他数据类型,我们以后会有讨论。
于是,我们可以建立这样两个表:
create table table1( id int, name char(20), age int); create table table2( id int, username char(20), password char(32));
每次创建完表格,都会有提示创建成功:
Query OK, 0 rows affected (0.04 sec)
要想查看当前数据库中都有哪些表,我们可以使用命令:
show tables;
我们就可以看到,我们创建的两个表就在其中:
+----------------+ | Tables_in_test | +----------------+ | table1 | | table2 | +----------------+
正如我们从前讨论的,表本质上是储存在数据库文件夹中的文件。
如果有一个表,我们不想要了,删除表格是很容易的:
drop table 表名;
例如,我们想删除刚刚创建的table2,可以使用这样的命令:
drop table table2;
敲下回车后,提示删除成功:
Query OK, 0 rows affected (0.01 sec)
使用show tables;
查询,以及看不见table2:
+----------------+ | Tables_in_test | +----------------+ | table1 | +----------------+
在数据库文件夹中,也不见table2的踪迹。
删除表虽然不像删除数据库那样严重,但依然不是好习惯。除非你十分确定需要删除那个表,而且名字没有错误,否则不可以轻易使用这个命令。
表格创建好之后,如果表头很长,我们或许无法记住标头的内容。可以通过这样的方法查看表结构:
desc 表名;
desc是describe的缩写,也就是描述的意思。
例如,要查看table1的表结构,可以用这个办法:
desc table1;
table1的表结构就会呈现出来:
+-------+----------+------+-----+---------+-------+ | Field | Type | Null | Key | Default | Extra | +-------+----------+------+-----+---------+-------+ | id | int(11) | YES | | NULL | | | name | char(20) | YES | | NULL | | | age | int(11) | YES | | NULL | | +-------+----------+------+-----+---------+-------+
除此之外,我们也可以通过查看创建表的语句来查看表头信息:
show create table 表名;
对于table1而言,具体的命令就是:
show create table table1;
table1的创建表语句为:
+--------+--------------------------------------------------------------------------------------------------------------------------------------------------------+ | Table | Create Table | +--------+--------------------------------------------------------------------------------------------------------------------------------------------------------+ | table1 | CREATE TABLE `table1` ( `id` int(11) DEFAULT NULL, `name` char(20) DEFAULT NULL, `age` int(11) DEFAULT NULL ) ENGINE=InnoDB DEFAULT CHARSET=utf8 | +--------+--------------------------------------------------------------------------------------------------------------------------------------------------------+
我们看到,查看表结构和创建表语句都可以达到查看表头信息的目的。不同的是,查看创建表语句还能看到诸如引擎、编码之类的更加详细的信息。
数据操作
表中的每一行内容,就是一条数据(data)。数据库从根本上来讲,就是用来管理这些数据的。数据存放在表中,而表存放在数据库中。
对数据的操作,无外乎增删改查四种,接下来,我们将逐一探讨。
增
向表中增加数据的基本结构为:
insert into 表名 values(数据1,数据2,数据3...);
例如,我们可以向table1中插入数据。注意数据要与表头一一对应:
insert into table1 values(1, 'alex', 83)
回车过后,提示操作成功:
Query OK, 1 row affected, 1 warning (0.00 sec)
我们可以通过命令select * from table1
查看表中的内容,此时的结果为:
+------+------+------+ | id | name | age | +------+------+------+ | 1 | alex | 83 | +------+------+------+
数据添加成功。
如果我们只想输入id和name两项内容,不想输入age。如果这样输入会报错:
insert into table1 (2, 'wusir');
报错信息为,输入的数据条数和表格的列数不匹配:
ERROR 1136 (21S01): Column count doesn't match value count at row 1
这时,我们可以在表名后面指定我们要插入的数据的标题。同样地,指定的标题数目和我们插入的数据条数要一一对应,比如这样:
insert into table1(id,name) values(2,'wusir');
成功插入,查看table1中的内容是这样的:
+------+-------+------+ | id | name | age | +------+-------+------+ | 1 | alex | 83 | | 2 | wusir | NULL | +------+-------+------+
第二行的age显示为NULL,意味着本行为空。
其实,我们可以一次性在values后面指定多条数据,批量插入,每条数据之间,需要使用逗号隔开。例如:
insert into table1 values(3,'baoyuan',18),(4,'沙河吴彦祖',16);
此时table1中的内容为:
+------+-----------------+------+ | id | name | age | +------+-----------------+------+ | 1 | alex | 83 | | 2 | wusir | NULL | | 3 | baoyuan | 18 | | 4 | 沙河吴彦祖 | 16 | +------+-----------------+------+
说明一点,虽然存放数据库的路径和数据库名字、表名字中不可以出现中文,数据中是可以存放中文的。
同样地,我们也可以通过指定标题的方式,只插入部分数据:
insert into table1(id,name) values(5,'baoyuan'),(6,'沙河吴彦祖');
成功插入后,table1的内容为:
+------+-----------------+------+ | id | name | age | +------+-----------------+------+ | 1 | alex | 83 | | 2 | wusir | NULL | | 3 | baoyuan | 18 | | 4 | 沙河吴彦祖 | 16 | | 5 | baoyuan | NULL | | 6 | 沙河吴彦祖 | NULL | +------+-----------------+------+
删
有的时候,我们需要删除表格中的某些数据。删除数据的标准格式为:
delete from 表名 where 条件
注意,这里面一定要指定条件,否则的话,这个命令就是清空整个表格。
对于上面的例子中,后两条命令与前面的重复,我们想要把它们都删掉。我们发现,它们的id都大于4,且只有它们的id大于4。于是,我们就可以用这个作为条件,把它们删除掉:
delete from table1 where id>4;
后面两条内容被成功删除:
+------+-----------------+------+ | id | name | age | +------+-----------------+------+ | 1 | alex | 83 | | 2 | wusir | NULL | | 3 | baoyuan | 18 | | 4 | 沙河吴彦祖 | 16 | +------+-----------------+------+
改
我们看到,第二行wusir的年龄我们没有指定。这就需要修改他的年龄。
MySQL标准的修改数据的方式为:
update 表名 set 字段名 = 值 where 条件;
同样地,这里的条件是必须的。否则,该字段下的所有数据都会被修改成为新的值。
如果我们想设置wusir的年纪,可以这样操作:
update table1 set age = 35 where id = 2;
设置成功:
+------+-----------------+------+ | id | name | age | +------+-----------------+------+ | 1 | alex | 83 | | 2 | wusir | 35 | | 3 | baoyuan | 18 | | 4 | 沙河吴彦祖 | 16 | +------+-----------------+------+
这里的条件不一定要指定id=2
,我们也可以使用name='wusir'
。需要注意的是,字符串的'wusir'
要用引号引起来。
查
表格中数据的查找我们一直都在用,其基本结构为:
selct * from 表名;
这条命令用来查看表格中所有的内容。
不过对于一些列数特别多的表格来说,这种查看方式会很乱,甚至可能会乱到无法阅读。
比如对于mysql数据库的user表来说,我们用这个方式查看,得到的结果会是这样:
+-----------+---------+-------------------------------------------+-------------+-------------+-------------+-------------+-------------+-----------+-------------+---------------+--------------+-----------+------------+-----------------+------------+------------+--------------+------------+-----------------------+------------------+--------------+-----------------+------------------+------------------+----------------+---------------------+--------------------+------------------+------------+--------------+------------------------+----------+------------+-------------+--------------+---------------+-------------+-----------------+----------------------+-----------------------+-----------------------+------------------+ | Host | User | Password | Select_priv | Insert_priv | Update_priv | Delete_priv | Create_priv | Drop_priv | Reload_priv | Shutdown_priv | Process_priv | File_priv | Grant_priv | References_priv | Index_priv | Alter_priv | Show_db_priv | Super_priv | Create_tmp_table_priv | Lock_tables_priv | Execute_priv | Repl_slave_priv | Repl_client_priv | Create_view_priv | Show_view_priv | Create_routine_priv | Alter_routine_priv | Create_user_priv | Event_priv | Trigger_priv | Create_tablespace_priv | ssl_type | ssl_cipher | x509_issuer | x509_subject | max_questions | max_updates | max_connections | max_user_connections | plugin | authentication_string | password_expired | +-----------+---------+-------------------------------------------+-------------+-------------+-------------+-------------+-------------+-----------+-------------+---------------+--------------+-----------+------------+-----------------+------------+------------+--------------+------------+-----------------------+------------------+--------------+-----------------+------------------+------------------+----------------+---------------------+--------------------+------------------+------------+--------------+------------------------+----------+------------+-------------+--------------+---------------+-------------+-----------------+----------------------+-----------------------+-----------------------+------------------+ | localhost | root | *23AE809DDACAF96AF0FD78ED04B6A265E05AA257 | Y | Y | Y | Y | Y | Y | Y | Y | Y | Y | Y | Y | Y | Y | Y | Y | Y | Y | Y | Y | Y | Y | Y | Y | Y | Y | Y | Y | Y | | | | | 0 | 0 | 0 | 0 | mysql_native_password | | N | | 127.0.0.1 | root | | Y | Y | Y | Y | Y | Y | Y | Y | Y | Y | Y | Y | Y | Y | Y | Y | Y | Y | Y | Y | Y | Y | Y | Y | Y | Y | Y | Y | Y | | | | | 0 | 0 | 0 | 0 | mysql_native_password | | N | | ::1 | root | | Y | Y | Y | Y | Y | Y | Y | Y | Y | Y | Y | Y | Y | Y | Y | Y | Y | Y | Y | Y | Y | Y | Y | Y | Y | Y | Y | Y | Y | | | | | 0 | 0 | 0 | 0 | mysql_native_password | | N | | localhost | | | N | N | N | N | N | N | N | N | N | N | N | N | N | N | N | N | N | N | N | N | N | N | N | N | N | N | N | N | N | | | | | 0 | 0 | 0 | 0 | mysql_native_password | NULL | N | | % | guest | *23AE809DDACAF96AF0FD78ED04B6A265E05AA257 | N | N | N | N | N | N | N | N | N | N | N | N | N | N | N | N | N | N | N | N | N | N | N | N | N | N | N | N | N | | | | | 0 | 0 | 0 | 0 | mysql_native_password | | N | | % | xianhui | *23AE809DDACAF96AF0FD78ED04B6A265E05AA257 | N | N | N | N | N | N | N | N | N | N | N | N | N | N | N | N | N | N | N | N | N | N | N | N | N | N | N | N | N | | | | | 0 | 0 | 0 | 0 | mysql_native_password | | N | +-----------+---------+-------------------------------------------+-------------+-------------+-------------+-------------+-------------+-----------+-------------+---------------+--------------+-----------+------------+-----------------+------------+------------+--------------+------------+-----------------------+------------------+--------------+-----------------+------------------+------------------+----------------+---------------------+--------------------+------------------+------------+--------------+------------------------+----------+------------+-------------+--------------+---------------+-------------+-----------------+----------------------+-----------------------+-----------------------+------------------+
除非使用一个很大的显示器,我们很难看懂这一大串数据究竟是什么东西。
不过如果我们只对表格中的某几列感兴趣,就可以将*
替换成列的名字,列明之间用逗号隔开,例如我们只想查看Host
、User
和Password
这三列,就可以这样查看:
select host,user,password from user;
结果就变成了:
+-----------+---------+-------------------------------------------+ | host | user | password | +-----------+---------+-------------------------------------------+ | localhost | root | *23AE809DDACAF96AF0FD78ED04B6A265E05AA257 | | 127.0.0.1 | root | | | ::1 | root | | | localhost | | | | % | guest | *23AE809DDACAF96AF0FD78ED04B6A265E05AA257 | | % | xianhui | *23AE809DDACAF96AF0FD78ED04B6A265E05AA257 | +-----------+---------+-------------------------------------------+
看起来就简单了许多。
你或许已经发现,在上面的现实中,Host、User和Password的首字母都大写,而我输入的标题全部用的小写。这是因为MySQL的标题中是不区分大小写的。