Skip to content

基础

什么是SQL?简单地说,SQL就是访问和处理关系数据库的计算机标准语言。也就是说,无论用什么编程语言(Java、Python、C++……)编写程序,只要涉及到操作关系数据库,比如,一个电商网站需要把用户和商品信息存入数据库,或者一个手机游戏需要把用户的道具、通关信息存入数据库,都必须通过SQL来完成。

所以,现代程序离不开关系数据库,要使用关系数据库就必须掌握SQL。

在本教程中,你将学到关系数据库的基本概念,如何使用SQL操作数据库,以及一种最流行的开源数据库MySQL的基本安装和使用方法。

NoSQL

你可能还听说过NoSQL数据库,也就是非SQL的数据库,包括MongoDB、Cassandra、Dynamo等等,它们都不是关系数据库。有很多人鼓吹现代Web程序已经无需关系数据库了,只需要使用NoSQL就可以。但事实上,SQL数据库从始至终从未被取代过。回顾一下NoSQL的发展历程:

  • 1970: NoSQL = We have no SQL
  • 1980: NoSQL = Know SQL
  • 2000: NoSQL = No SQL!
  • 2005: NoSQL = Not only SQL
  • 2013: NoSQL = No, SQL!

今天,SQL数据库仍然承担了各种应用程序的核心数据存储,而NoSQL数据库作为SQL数据库的补充,两者不再是二选一的问题,而是主从关系。所以,无论使用哪种编程语言,无论是Web开发、游戏开发还是手机开发,掌握SQL,是所有软件开发人员所必须的。

不要再犹豫了!从现在开始,坚持一周,拿下SQL!

关系数据库概述

为什么需要数据库?

因为应用程序需要保存用户的数据,比如Word需要把用户文档保存起来,以便下次继续编辑或者拷贝到另一台电脑。

要保存用户的数据,一个最简单的方法是把用户数据写入文件。例如,要保存一个班级所有学生的信息,可以向文件中写入一个CSV文件:

csv
id,name,gender,score
1,小明,M,90
2,小红,F,95
3,小军,M,88
4,小丽,F,88

如果要保存学校所有班级的信息,可以写入另一个CSV文件。

但是,随着应用程序的功能越来越复杂,数据量越来越大,如何管理这些数据就成了大问题:

  • 读写文件并解析出数据需要大量重复代码;
  • 从成千上万的数据中快速查询出指定数据需要复杂的逻辑。

如果每个应用程序都各自写自己的读写数据的代码,一方面效率低,容易出错,另一方面,每个应用程序访问数据的接口都不相同,数据难以复用。

所以,数据库作为一种专门管理数据的软件就出现了。应用程序不需要自己管理数据,而是通过数据库软件提供的接口来读写数据。至于数据本身如何存储到文件,那是数据库软件的事情,应用程序自己并不关心:

┌───────────┐
│application│
└───────────┘
     ▲ │
     │ │
 read│ │write
     │ │
     │ ▼
┌───────────┐
│ database  │
└───────────┘

这样一来,编写应用程序的时候,数据读写的功能就被大大地简化了。

数据模型

数据库按照数据结构来组织、存储和管理数据,实际上,数据库一共有三种模型:

  • 层次模型
  • 网状模型
  • 关系模型

层次模型就是以“上下级”的层次关系来组织数据的一种方式,层次模型的数据结构看起来就像一颗树:

            ┌─────┐
            │     │
            └─────┘

       ┌───────┴───────┐
       │               │
    ┌─────┐         ┌─────┐
    │     │         │     │
    └─────┘         └─────┘
       │               │
   ┌───┴───┐       ┌───┴───┐
   │       │       │       │
┌─────┐ ┌─────┐ ┌─────┐ ┌─────┐
│     │ │     │ │     │ │     │
└─────┘ └─────┘ └─────┘ └─────┘

网状模型把每个数据节点和其他很多节点都连接起来,它的数据结构看起来就像很多城市之间的路网:

     ┌─────┐      ┌─────┐
   ┌─│     │──────│     │──┐
   │ └─────┘      └─────┘  │
   │    │            │     │
   │    └──────┬─────┘     │
   │           │           │
┌─────┐     ┌─────┐     ┌─────┐
│     │─────│     │─────│     │
└─────┘     └─────┘     └─────┘
   │           │           │
   │     ┌─────┴─────┐     │
   │     │           │     │
   │  ┌─────┐     ┌─────┐  │
   └──│     │─────│     │──┘
      └─────┘     └─────┘

关系模型把数据看作是一个二维表格,任何数据都可以通过行号+列号来唯一确定,它的数据模型看起来就是一个Excel表:

┌─────┬─────┬─────┬─────┬─────┐
│     │     │     │     │     │
├─────┼─────┼─────┼─────┼─────┤
│     │     │     │     │     │
├─────┼─────┼─────┼─────┼─────┤
│     │     │     │     │     │
├─────┼─────┼─────┼─────┼─────┤
│     │     │     │     │     │
└─────┴─────┴─────┴─────┴─────┘

随着时间的推移和市场竞争,最终,基于关系模型的关系数据库获得了绝对市场份额。

为什么关系数据库获得了最广泛的应用?

因为相比层次模型和网状模型,关系模型理解和使用起来最简单。

关系数据库的关系模型是基于数学理论建立的。我们把域(Domain)定义为一组具有相同数据类型的值的集合,给定一组域D1,D2,...,Dn,它们的笛卡尔集定义为D1×D2×……×Dn={(d1,d2,...,dn)|di∈Di,i=1,2,...,n}, 而D1×D2×……×Dn的子集叫作在域D1,D2,...,Dn上的关系,表示为R(D1,D2,...,Dn),这里的R表示#%&^@!&$#;!~%¥%……算了,根本讲不明白,大家也不用理解。

基于数学理论的关系模型虽然讲起来挺复杂,但是,基于日常生活的关系模型却十分容易理解。我们以学校班级为例,一个班级的学生就可以用一个表格存起来,并且定义如下:

ID姓名班级ID性别年龄
1小明201M9
2小红202F8
3小军202M8
4小白201F9

其中,班级ID对应着另一个班级表:

ID名称班主任
201二年级一班王老师
202二年级二班李老师

通过给定一个班级名称,可以查到一条班级记录,根据班级ID,又可以查到多条学生记录,这样,二维表之间就通过ID映射建立了“一对多”关系。

数据类型

对于一个关系表,除了定义每一列的名称外,还需要定义每一列的数据类型。关系数据库支持的标准数据类型包括数值、字符串、时间等:

名称类型说明
INT整型4字节整数类型,范围约+/-21亿
BIGINT长整型8字节整数类型,范围约+/-922亿亿
REAL浮点型4字节浮点数,范围约+/-1038
DOUBLE浮点型8字节浮点数,范围约+/-10308
DECIMAL(M,N)高精度小数由用户指定精度的小数,例如,DECIMAL(20,10)表示一共20位,其中小数10位,通常用于财务计算
CHAR(N)定长字符串存储指定长度的字符串,例如,CHAR(100)总是存储100个字符的字符串
VARCHAR(N)变长字符串存储可变长度的字符串,例如,VARCHAR(100)可以存储0~100个字符的字符串
BOOLEAN布尔类型存储True或者False
DATE日期类型存储日期,例如,2018-06-22
TIME时间类型存储时间,例如,12:20:59
DATETIME日期和时间类型存储日期+时间,例如,2018-06-22 12:20:59

上面的表中列举了最常用的数据类型。很多数据类型还有别名,例如,REAL又可以写成FLOAT(24)。还有一些不常用的数据类型,例如,TINYINT(范围在0~255)。各数据库厂商还会支持特定的数据类型,例如JSON

选择数据类型的时候,要根据业务规则选择合适的类型。通常来说,BIGINT能满足整数存储的需求,VARCHAR(N)能满足字符串存储的需求,这两种类型是使用最广泛的。

主流关系数据库

目前,主流的关系数据库主要分为以下几类:

  1. 商用数据库,例如:OracleSQL ServerDB2等;
  2. 开源数据库,例如:MySQLPostgreSQL等;
  3. 桌面数据库,以微软Access为代表,适合桌面应用程序使用;
  4. 嵌入式数据库,以Sqlite为代表,适合手机应用和桌面程序。

SQL

什么是SQL?SQL是结构化查询语言的缩写,用来访问和操作数据库系统。SQL语句既可以查询数据库中的数据,也可以添加、更新和删除数据库中的数据,还可以对数据库进行管理和维护操作。不同的数据库,都支持SQL,这样,我们通过学习SQL这一种语言,就可以操作各种不同的数据库。

虽然SQL已经被ANSI组织定义为标准,不幸地是,各个不同的数据库对标准的SQL支持不太一致。并且,大部分数据库都在标准的SQL上做了扩展。也就是说,如果只使用标准SQL,理论上所有数据库都可以支持,但如果使用某个特定数据库的扩展SQL,换一个数据库就不能执行了。例如,Oracle把自己扩展的SQL称为PL/SQL,Microsoft把自己扩展的SQL称为T-SQL

现实情况是,如果我们只使用标准SQL的核心功能,那么所有数据库通常都可以执行。不常用的SQL功能,不同的数据库支持的程度都不一样。而各个数据库支持的各自扩展的功能,通常我们把它们称之为“方言”。

总的来说,SQL语言定义了这么几种操作数据库的能力:

DDL:Data Definition Language

DDL允许用户定义数据,也就是创建表、删除表、修改表结构这些操作。通常,DDL由数据库管理员执行。

DML:Data Manipulation Language

DML为用户提供添加、删除、更新数据的能力,这些是应用程序对数据库的日常操作。

DQL:Data Query Language

DQL允许用户查询数据,这也是通常最频繁的数据库日常操作。

语法特点

SQL语言关键字不区分大小写!!!但是,针对不同的数据库,对于表名和列名,有的数据库区分大小写,有的数据库不区分大小写。同一个数据库,有的在Linux上区分大小写,有的在Windows上不区分大小写。

所以,本教程约定:SQL关键字总是大写,以示突出,表名和列名均使用小写。

安装MySQL

MySQL是目前应用最广泛的开源关系数据库。MySQL最早是由瑞典的MySQL AB公司开发,该公司在2008年被SUN公司收购,紧接着,SUN公司在2009年被Oracle公司收购,所以MySQL最终就变成了Oracle旗下的产品。

和其他关系数据库有所不同的是,MySQL本身实际上只是一个SQL接口,它的内部还包含了多种数据引擎,常用的包括:

  • InnoDB:由Innobase Oy公司开发的一款支持事务的数据库引擎,2006年被Oracle收购;
  • MyISAM:MySQL早期集成的默认数据库引擎,不支持事务。

MySQL接口和数据库引擎的关系就好比某某浏览器和浏览器引擎(IE引擎或Webkit引擎)的关系。对用户而言,切换浏览器引擎不影响浏览器界面,切换MySQL引擎不影响自己写的应用程序使用MySQL的接口。

使用MySQL时,不同的表还可以使用不同的数据库引擎。如果你不知道应该采用哪种引擎,记住总是选择InnoDB就好了。

因为MySQL一开始就是开源的,所以基于MySQL的开源版本,又衍生出了各种版本:

MariaDB

由MySQL的创始人创建的一个开源分支版本,使用XtraDB引擎。

Aurora

由Amazon改进的一个MySQL版本,专门提供给在AWS托管MySQL用户,号称5倍的性能提升。

PolarDB

由Alibaba改进的一个MySQL版本,专门提供给在阿里云托管的MySQL用户,号称6倍的性能提升。

而MySQL官方版本又分了好几个版本:

  • Community Edition:社区开源版本,免费;
  • Standard Edition:标准版;
  • Enterprise Edition:企业版;
  • Cluster Carrier Grade Edition:集群版。

以上版本的功能依次递增,价格也依次递增。不过,功能增加的主要是监控、集群等管理功能,对于基本的SQL功能是完全一样的。

所以使用MySQL就带来了一个巨大的好处:可以在自己的电脑上安装免费的Community Edition版本,进行学习、开发、测试,部署的时候,可以选择付费的高级版本,或者云服务商提供的兼容版本,而不需要对应用程序本身做改动。

安装MySQL

要安装MySQL,可以从MySQL官方网站下载最新的MySQL Community Server版本:

https://dev.mysql.com/downloads/mysql/

选择对应的操作系统版本,下载安装即可。在安装过程中,MySQL会自动创建一个root用户,并提示输入root口令。

要在Linux上安装MySQL,可以使用发行版的包管理器。例如,Debian和Ubuntu用户可以简单地通过命令apt install mysql-server安装最新的MySQL版本。

MySQL安装后会自动在后台运行。为了验证MySQL安装是否正确,我们需要通过mysql这个命令行程序来连接MySQL服务器。

在命令提示符下输入mysql -u root -p,然后输入口令,如果一切正确,就会连接到MySQL服务器,同时提示符变为mysql>

输入exit退出MySQL命令行。注意,MySQL服务器仍在后台运行。

使用Docker运行MySQL

另一种运行MySQL的方式不需要下载安装包,而是直接通过Docker安装最新的MySQL:

首先安装Docker Desktop,然后在命令行输入以下命令拉取MySQL最新版:

plain
$ docker pull mysql

拉取完成后,输入以下命令直接启动MySQL服务器:

plain
$ docker run -d --name mysql -p 3306:3306 -e MYSQL_ROOT_PASSWORD=password -v /Users/liaoxuefeng/mysql-data:/var/lib/mysql mysql

命令docker run表示启动一个容器,后面各参数含义如下:

  • -d:表示在后台执行;
  • --name mysql:表示容器的名字,不输入Docker会自动选择一个名字;
  • -p 3306:3306:表示把容器的端口3306映射到本机,这样可以在本机通过3306端口连接MySQL;
  • -e MYSQL_ROOT_PASSWORD=password:表示传入一个环境变量,作为root的口令,这里设置的口令是password,不输入此项则会自动生成一个口令,需要查看日志才能知道口令;
  • -v /Users/liaoxuefeng/mysql-data:/var/lib/mysql:表示将本地目录映射到容器目录/var/lib/mysql作为MySQL数据库存放的位置,需要将/Users/liaoxuefeng/mysql-data改为你的电脑上的实际目录;
  • mysql:最后一个参数是Docker镜像的名称。

可以在Docker Desktop的管理窗口中选择Containers,看到正在运行的MySQL。

点击MySQL查看日志。

点击Exec进入命令行,输入命令mysql -u root -p,输入口令,即可进入MySQL命令行界面。

使用Docker运行MySQL时,任何时候都可以删除MySQL容器并重新运行。如果删除了本地映射的目录,重新运行就相当于一个全新的MySQL,因此,建议仅作为学习和开发使用,不要存储重要的数据。

总结

掌握SQL是非常重要且实用的技能,除了开发者应当熟练使用SQL外,许多岗位,如数据分析师、数据库运维、财务人员等,都可以通过SQL进行复杂的数据分析,生成自动化报表,为各种决策提供数据洞察力。

对于云计算、数据仓库、大数据处理等领域,SQL是这些高级技术的基础。

总之,SQL是一种强大的工具,对任何需要处理和分析数据的人来说,SQL是必备技能。