今天说一下这个MySQL 系列教程之(一)初识 MySQL

数据库

Database,是按照数据结构来组织、存储和管理数据的仓库

功能

  • 持久存储和管理(增加 删除 更新)大量数据
  • 高效率查询并提取满足条件的数据,数据访问速度快
  • 约束存储的数据类型
  • 支持远程数据共享和权限管理

数据库管理系统(DBMS)

  • 是操纵和管理、建立和使用数据库的大型软件,保证数据库数据的安全性和完整性
  • 可以通过DBMS访问数据库中的数据,进行数据库的维护工作
  • 提供数据定义语言DDL和数据操作语言DML,通过DNMS提供的接口来读写数据,实现对数据库里面的数据的追加、删除等操作
  • 允许多个用户在不同时不同地去建立,修改和访问数据库
    文件中的数据, 可以通过Excel和wps打开查看,增加和删除数据

DBMS分类

  • 关系型
MySQL(是最流行的开源数据库管理系统)、Microsoft SQL Server、Oracle(收费)、pgSQL

  • 非关系型
MongoDb、redis、Cloudant、HBase


关系型数据库

特点

1· 数据以表格的形式出现,每个表有自己的名字(同一数据库内唯一),表内被组织为行和列的一一对应关系

2. 行为各种数据记录名称
3. 每列为记录名称所对应的数据域
4· 许多的行和列组成一张表格
5.若干的表格组成关系型数据库(database), 每个数据库有自己的名字(唯一)

术语

  • 数据: data
  • 行:表中的数据是按行存储的,所保存的每个记录存储在自己的行内(数据记录)
  • 列:一列(数据),同一列具有相同类型的数据元素
  • 数据表: 表是数据的矩阵,在一个数据库中的表看起来像一个简单的电子表
  • 数据库:表的集合db
  • 主键:唯一标识表中每行的这个列(或这组列)称为主键,用来表示一个特定的行,主键列不允许NULL值
没有主键,更新或删除表中特定行很困难,因为没有安全的方法保证只涉及相关的行。虽然并不总是都需要主键,但大多数数据库设计人员都应保证他们创建的每个表具有一个主键,以便于以后的数据操纵和管理。

  • 索引:使用索引可快速访问数据表中的数据

MySQL数据库

  • MySQL是开源免费的,不需要支付额外的费用
  • MySQL支持大型的数据库,支持5000万条记录的数据仓库,32位系统表文件最大可支持4GB,64位系统支持最大的表文件为8TB。
  • MySQL使用标准的SQL数据语言形式
  • MySQL可以运行于多个系统上,并且支持多种语言。这些编程语言包括C、C++、Python, Java,Perl. PHP, Eiffel. Ruby和Tcl等

优点

  1. 简单易用
MySQL 是一个高性能且相对简单的数据库系统,与一些更大系统的设置和管理相比,其复杂程度较低

  1. 价格
对多数个人用户来说是免费的,任何人都可以在官网下载安装使用

  1. 小巧
的数据库发行版仅仅只有21M,安装完成也仅仅51M

  1. 支持查询语言
可以利用SQL (结构化查询语言),SQL是一种所有现代数据库系统都选用的语言

  1. 性能
没有用户数的限制,多个客户机可同时使用同一个数据库。MySQL运行速度很快。开发者声称MySQL可能是目前能得到的最快的数据库

  1. 连接性和安全性
MySQL是完全网络化的,可在任何地方访问,可以和任何地方的任何人共享数据库,可以控制哪些人不能看到您的数据

缺点

  • 为了维护一致性所付出的巨大代价就是其读写性能比较差
  • 固定的表结构
  • 高并发读写需求
  • 海量数据的高效率读写

服务器处理客户端请求

其实不论客户端进程和服务器进程是采用哪种方式进行通信,最后实现的效果都是:客户端进程向服务器进程发送一段文本(MySQL语句),服务器进程处理后再向客户端进程发送一段文本(处理结果)。那服务器进程对客户端进程发送的请求做了什么处理,才能产生最后的处理结果呢?客户端可以向服务器发送增删改查各类请求,我们这里以比较复杂的查询请求为例来画个图展示一下大致的过程:

image_1c8d26fmg1af0ms81cpc7gm8lv39.png-97.9kB

虽然查询缓存有时可以提升系统性能,但也不得不因维护这块缓存而造成一些开销,比如每次都要去查询缓存中检索,查询请求处理完需要更新查询缓存,维护该查询缓存对应的内存区域。从MySQL 5.7.20开始,不推荐使用查询缓存,并在MySQL 8.0中删除。

存储引擎

MySQL服务器把数据的存储和提取操作都封装到了一个叫存储引擎的模块里。我们知道是由一行一行的记录组成的,但这只是一个逻辑上的概念,物理上如何表示记录,怎么从表中读取数据,怎么把数据写入具体的物理存储器上,这都是存储引擎负责的事情。为了实现不同的功能,MySQL提供了各式各样的存储引擎,不同存储引擎管理的表具体的存储结构可能不同,采用的存取算法也可能不同。

存储引擎以前叫做表处理器,它的功能就是接收上层传下来的指令,然后对表中的数据进行提取或写入操作。

为了管理方便,人们把连接管理查询缓存语法解析查询优化这些并不涉及真实数据存储的功能划分为MySQL server的功能,把真实存取数据的功能划分为存储引擎的功能。各种不同的存储引擎向上边的MySQL server层提供统一的调用接口(也就是存储引擎API),包含了几十个底层函数,像”读取索引第一条内容”、”读取索引下一条内容”、”插入记录”等等。

所以在MySQL server完成了查询优化后,只需按照生成的执行计划调用底层存储引擎提供的API,获取到数据后返回给客户端就好了。

MySQL支持非常多种存储引擎:

存储引擎

描述

ARCHIVE

用于数据存档(行被插入后不能再修改)

BLACKHOLE

丢弃写操作,读操作会返回空内容

CSV

在存储数据时,以逗号分隔各个数据项

FEDERATED

用来访问远程表

InnoDB

具备外键支持功能的事务存储引擎

MEMORY

置于内存的表

MERGE

用来管理多个MyISAM表构成的表集合

MyISAM

主要的非事务处理存储引擎

NDB

MySQL集群专用存储引擎

关于存储引擎的一些操作

查看当前服务器程序支持的存储引擎

我们可以用下边这个命令来查看当前服务器程序支持的存储引擎:

SHOW ENGINES;

设置表的存储引擎

我们前边说过,存储引擎是负责对表中的数据进行提取和写入工作的,我们可以为不同的表设置不同的存储引擎,也就是说不同的表可以有不同的物理存储结构,不同的提取和写入方式。

创建表时指定存储引擎

我们之前创建表的语句都没有指定表的存储引擎,那就会使用默认的存储引擎InnoDB(当然这个默认的存储引擎也是可以修改的,我们在后边的章节中再说怎么改)。如果我们想显式的指定一下表的存储引擎,那可以这么写:

CREATE TABLE 表名(
    建表语句;
) ENGINE = 存储引擎名称;

比如我们想创建一个存储引擎为MyISAM的表可以这么写:

mysql> CREATE TABLE engine_demo_table(
    ->     i int
    -> ) ENGINE = MyISAM;
Query OK, 0 rows affected (0.02 sec)

mysql>

修改表的存储引擎

如果表已经建好了,我们也可以使用下边这个语句来修改表的存储引擎:

ALTER TABLE 表名 ENGINE = 存储引擎名称;

比如我们修改一下engine_demo_table表的存储引擎:

mysql> ALTER TABLE engine_demo_table ENGINE = InnoDB;
Query OK, 0 rows affected (0.05 sec)
Records: 0  Duplicates: 0  Warnings: 0

mysql>

这时我们再查看一下engine_demo_table的表结构:

mysql> SHOW CREATE TABLE engine_demo_table\G
*************************** 1. row ***************************
       Table: engine_demo_table
Create Table: CREATE TABLE `engine_demo_table` (
  `i` int(11) DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8
1 row in set (0.01 sec)

mysql>

可以看到该表的存储引擎已经改为InnoDB了。

了解一下字符集和乱码

字符集简介

我们知道在计算机中只能存储二进制数据,那该怎么存储字符串呢?当然是建立字符与二进制数据的映射关系了,建立这个关系最起码要搞清楚两件事儿:

  1. 你要把哪些字符映射成二进制数据?

也就是界定清楚字符范围。

  1. 怎么映射?

将一个字符映射成一个二进制数据的过程也叫做编码,将一个二进制数据映射到一个字符的过程叫做解码

人们抽象出一个字符集的概念来描述某个字符范围的编码规则

我们看一下一些常用字符集的情况:

  • ASCII字符集

共收录128个字符,包括空格、标点符号、数字、大小写字母和一些不可见字符。由于总共才128个字符,所以可以使用1个字节来进行编码,我们看一些字符的编码方式:

‘L’ -> 01001100(十六进制:0x4C,十进制:76)

‘M’ -> 01001101(十六进制:0x4D,十进制:77)

  • ISO 8859-1字符集

共收录256个字符,是在ASCII字符集的基础上又扩充了128个西欧常用字符(包括德法两国的字母),也可以使用1个字节来进行编码。这个字符集也有一个别名latin1

  • GB2312字符集

收录了汉字以及拉丁字母、希腊字母、日文平假名及片假名字母、俄语西里尔字母。其中收录汉字6763个,其他文字符号682个。同时这种字符集又兼容ASCII字符集,所以在编码方式上显得有些奇怪:

  • 如果该字符在ASCII字符集中,则采用1字节编码。
  • 否则采用2字节编码。

这种表示一个字符需要的字节数可能不同的编码方式称为变长编码方式。比方说字符串'爱u',其中'爱'需要用2个字节进行编码,编码后的十六进制表示为0xCED2'u'需要用1个字节进行编码,编码后的十六进制表示为0x75,所以拼合起来就是0xCED275

小贴士: 我们怎么区分某个字节代表一个单独的字符还是代表某个字符的一部分呢?别忘了ASCII字符集只收录128个字符,使用0~127就可以表示全部字符,所以如果某个字节是在0~127之内的,就意味着一个字节代表一个单独的字符,否则就是两个字节代表一个单独的字符。

  • GBK字符集

GBK字符集只是在收录字符范围上对GB2312字符集作了扩充,编码方式上兼容GB2312

  • utf8字符集

收录地球上能想到的所有字符,而且还在不断扩充。这种字符集兼容ASCII字符集,采用变长编码方式,编码一个字符需要使用1~4个字节,比方说这样:

‘L’ -> 01001100(十六进制:0x4C)

‘啊’ -> 111001011001010110001010(十六进制:0xE5958A)

小贴士: 其实准确的说,utf8只是Unicode字符集的一种编码方案,Unicode字符集可以采用utf8、utf16、utf32这几种编码方案,utf8使用1~4个字节编码一个字符,utf16使用2个或4个字节编码一个字符,utf32使用4个字节编码一个字符。更详细的Unicode和其编码方案的知识不是本书的重点,大家上网查查哈~ MySQL中并不区分字符集和编码方案的概念,所以后边唠叨的时候把utf8、utf16、utf32都当作一种字符集对待。

对于同一个字符,不同字符集也可能有不同的编码方式。比如对于汉字'我'来说,ASCII字符集中根本没有收录这个字符,utf8gb2312字符集对汉字的编码方式如下:

utf8编码:111001101000100010010001 (3个字节,十六进制表示是:0xE68891)
gb2312编码:1100111011010010 (2个字节,十六进制表示是:0xCED2)

MySQL中的utf8和utf8mb4

我们上边说utf8字符集表示一个字符需要使用1~4个字节,但是我们常用的一些字符使用1~3个字节就可以表示了。而在MySQL中字符集表示一个字符所用最大字节长度在某些方面会影响系统的存储和性能,所以设计MySQL的大叔偷偷的定义了两个概念:

  • utf8mb3:阉割过的utf8字符集,只使用1~3个字节表示字符。
  • utf8mb4:正宗的utf8字符集,使用1~4个字节表示字符。

有一点需要大家十分的注意,在MySQLutf8utf8mb3的别名,所以之后在MySQL中提到utf8就意味着使用1~3个字节来表示一个字符,如果大家有使用4字节编码一个字符的情况,比如存储一些emoji表情啥的,那请使用utf8mb4

字符集的查看

MySQL支持好多好多种字符集,查看当前MySQL中支持的字符集可以用下边这个语句:

正文完