《SQL&MySQL必知必会》读书笔记

原创内容,转载请注明出处!

DBMS 基于 MySQL 5.7

第1章 了解SQL

1.1 数据库基础

1.1.1 数据库

数据库(DATABASE):一种容器,用于保存有组织的数据(通常是一个文件或一组文件)。

数据库 ≠ 数据库管理系统。

数据库管理系统(DBMS):一种系统软件,用于创建和操纵数据库(DBMS 具体究竟是什么,形式如何,各种数据库都不一样)。

人们通常用数据库这个术语来代表他们所使用的数据库软件,这是不正确的。

我们不直接访问数据库,我们使用 DBMS,它替我们访问数据库。

1.1.2 表

表(TABLE):某种特定类型数据的结构化清单(数据库中的文件)。

特定数据类型:一个表中所保存的数据必须是同一个类别。

重点提醒:决不应该将多个类别的数据合并存到同一个表中,这样做将使后期的检索和访问很困难。应该创建多个表,每个数据类别放在一个表中。

结构化清单:通俗的理解,结构化就是一张二维表(Excle)。

表名:表的名字,用于在同一数据库中唯一标识自己。

唯一性:在同一数据库中,每个表只有唯一一个名字标识自己。

表名的唯一性取决于多个因素,一般来说为:数据库名 + 表名,这也是为什么不同的数据库内允许相同表名的表存在且不冲突的原因。

很多人也习惯将表名取为:数据库名前缀_表名。

1.1.3 模式

模式(SCHEMA):关于数据库和表的布局及特性的信息。

简单的理解模式:描述表的一组信息(模式可以用来描述数据库中特定的表以及整个数据库其中表之间的关系)。

模式的举例:数据在表中如何存储、表中可以存储什么样的数据、数据如何分解、各部分信息如何命名、表之间如何关联,等等。

模式和数据库的区别:大多数情况下,模式与数据库是同义词。在大多数 DBMS 中,创建数据库与创建模式是相同的效果。

1.1.4 列

列(COLUMN):表由列组成,所有表都是由一个或多个列组成。

字段:列也称为字段。

分解数据:合理地将数据分解为多个列极为重要!

合理地把数据按类型分解为若干个列,才可能利用特定的列对数据进行排序和过滤。否则在后期会很麻烦,并且性能也会低下。

1.1.5 数据类型

数据类型(DATATYPE):所容许的数据类型。每个表列都有相应的数据类型,它限制(或容许)该列中存储的数据。

数据类型的限制除了优化表的结构外,还帮助正确地排序数据(如果所有数据作为串处理,则1位于10之前,而10又位于2之前,即:串以字典顺序排序,从左边开始比较,一次一个字符),并在优化磁盘使用方面起重要的作用(可以用一种比文本串更简洁的格式存储数值和日期时间值)。

因此,在创建表时必须对数据类型给予特别的关注。

1.1.6 MySQL数据类型

注意:此处所列出的 MySQL 数据类型并不完整与全面,相关详细知识请查阅完整文档。

(1)串数据类型

两种基本的串类型:定长串、变长串。

既然变长数据类型这样灵活,为什么还要使用定长数据类型?

回答是因为性能。MySQL 处理定长列远比处理变长列快得多。此外,MySQL 不允许对变长列(或一个列的可变部分)进行索引。这也会极大地影响性能。

数据类型说明
CHAR1~255 个字符的定长串。它的长度必须在创建时指定,否则 MySQL 假定为 CHAR(1)
ENUM接受最多 64K 个串组成的一个预定义集合的某个串
LONGTEXT与 TEXT 相同,但最大长度为 4GB
MEDIUMTEXT与 TEXT 相同,但最大长度为 16K
SET接受最多 64 个串组成的一个预定义集合的零个或多个串
TEXT最大长度为 64K 的变长文本
TINYTEXT与 TEXT 相同,但最大长度为 255 字节
VARCHAR长度可变,最多不超过 255 字节。如果在创建时指定为 VARCHAR(n),则可存储 0 到 n 个字符的变长串(其中 n <= 255)

使用引号:不管使用何种形式的串数据类型,串值都必须括在引号内(通常单引号更好)。

当数值不是数值时:我们应该将电话号码、邮政编码之类的数据存储到串中,而不是数据类型中。

原因有:

一、如果在数值字段中存储邮政编码 01234,则保存的将是 1234,实际上丢失了一位数字。

二、电话号码、邮政编码是固定的,不需要进行加减乘除等计算,保存为串类型更为安全合理。

(2)数值数据类型

两种基本的数值数据类型:有符号、无符号。

所有数值类型(除 BIT 和 BOOLEAN 外)都可以有符号或无符号。

默认情况为有符号,但如果你知道自己不需要存储负值,可以使用 UNSIGNED 关键字,这样做将允许你存储两倍大小的值。

数据类型说明
BIT位字段,1~64 位(在 MySQL 5 之前,BIT 在功能上等价于 TINYINT)。
BIGINT整数值,支持 -9223372036854775808~9223372036854775807(如果是 UNSIGNED,为 0~18446744073709551615)的数。
BOOLEAN(或BOOL)布尔标志,或者为 0,或者为 1,主要用于开/关(on/off)标志。
DECIMAL(或DEC)精度可变的浮点值。
DOUBLE双精度浮点值
FLOAT单精度浮点值
INT(或INTEGER)整数值,支持 -2147483648~2147483647(如果是 UNSIGNED,为 0~4294967295)的数
MEDIUMINT整数值,支持 -8388608~8388607(如果是 UNSIGNED,为 0~16777215)的数
REAL4 字节的浮点值
SMALLINT整数值,支持 -32768~32767(如果是 UNSIGNED,为 0~65535)的数
TINYINT整数值,支持 -128~127(如果为 UNSIGNED,为 0~255)的数

不使用引号:与串不一样,数值不应该括在引号内。

存储货币数据类型:MySQL 中没有专门存储货币的数据类型,一般情况下使用 DECIMAL(8, 2)。

(3)日期和时间数据类型

MySQL 使用专门的数据类型来存储日期和时间值。

数据类型说明
DATE表示 1000-01-01~9999-12-31 的日期,格式为 YYYY-MM-DD
DATETIMEDATE 和 TIME 的组合
TIMESTAMP功能和 DATETIME 相同(但范围较小)
TIME格式为 HH:MM:SS
YEAR用 2 位数字表示,范围是 70(1970年)~ 69(2069年),用 4 位数字表示,范围是 1901 年~2155年

(4)二进制数据类型

二进制数据类型可存储任何数据(甚至包括二进制信息),如图像、多媒体、字处理文档等。

数据类型说明
BLOBBlob 最大长度为 64KB
MEDIUMBLOBBlob 最大长度为 16MB
LONGBLOBBlob 最大长度为 4GB
TINYBLOBBlob 最大长度为 255 字节

1.1.7 行

行(ROW):表中的一个记录。

是记录(RECORD)还是行(ROW)?

在很大程度上,这两个术语是可以互相替代的,但从技术上说,行才是正确的术语。

1.1.8 主键

主键(PRIMARY KEY):一列(或一组列),其值能够唯一区分表中每个行。

主码:主码就是主键。

没有主键,更新或删除表中特定行会很困难,因为没有安全的方法保证只涉及相关的行。

应该总是定义主键:虽然并不总是都需要主键,但大多数数据库设计人员都应该保证他们创建的每个表具有一个主键,以便于以后的数据操纵和管理。

表中的任何列都可以作为主键,只要它满足以下条件:

主键值规则:这里列出的规则是 MySQL 本身强制实施的。

主键通常定义在表的一列上,但这并不是必需的,也可以一起使用多个列作为主键。在使用多列作为主键时,上述条件必须应用到构成主键的所有列,所有列值组合必须是唯一的(但单个列的值可以不唯一)。

主键的最好习惯:除 MySQL 强制实施的规则外,应该坚持的几个普遍认可的最好的习惯为:

  • 不更新主键列中的值
  • 不重用主键列的值
  • 不在主键列中使用可能会更改的值(例如:如果使用一个名字作为主键,那么名字在后期有需要更改的可能性)

1.1.9 外键

外键(FOREIGN KEY):某个表中的一列,它包含另一个表的主键值,定义了两个表之间的关系。

外码:外码就是外键。

外键要么为 NULL,要么为关联表的主键值。

定义外键的优点:

  • 信息不重复,从而不浪费时间和空间
  • 如果相应的数据变动,只需要更新所关联表中的单个记录,本表中的数据不用改动
  • 由于数据无重复,显然数据是一致的,这使得处理数据更简单
  • 数据更安全,存储到外键字段中的数据必需依据于所关联表列的具体数据,可以有效避免非法数据的录入
  • 表更安全,相互关联的表之间,假如要删除一个表,需要先解除其中的相关性,这使得非法的表删除会被有效阻止,一定程度上保证了表的安全性

通过在表中指定主键和外键来维护引用完整性,可极大地提高数据库的可伸缩性!

引用完整性:参照完整性(Referential Integrity)引用完整性指被引用表中的主关键字和引用表中的外部主关键字之间的关系。

可伸缩性(SCALE):能够适应不断增加的工作量而不失败。

1.1.10 数据完整性

以下内容来源于 CSDN 博主:moxiaomo0804

(1)域完整性

是指一个列的输入有效性,是否允许为空值。强制域完整性的方法有:限制类型(通过设定列的数据类型)、格式(通过 CHECK 约束和规则)或可能值的范围(通过 FOREIGN KEY 约束、CHECK 约束、DEFAULT 定义、NOT NULL 定义和规则)。如:学生的考试成绩必须在 0~100 之间,性别只能是 “男” 或 “女”。

(2)实体完整性

是指保证表中所有的行唯一。实体完整性要求表中的所有行都有一个唯一标识符。这个唯一标识符可能是一列,也可能是几列的组合,称为主键。也就是说,表中的主键在所有行上必须取唯一值。强制实体完整性的方法有:索引、UNIQUE 约束、PRIMARY KEY 约束或 IDENTITY 属性。如:student 表中 sno(学号)的取值必须唯一,它唯一标识了相应记录所代表的学生,学号重复是非法的。学生的姓名不能作为主键,因为完全可能存在两个学生同名同姓的情况。

(3)参照完整性

是指保证主关键字(被引用表)和外部关键字(引用表)之间的参照关系。它涉及两个或两个以上表数据的一致性维护。外键值将引用表中包含此外键的记录和被引用表中主键与外键相匹配的记录关联起来。在输入、更改或删除记录时,参照完整性保持表之间已定义的关系,确保键值在所有表中一致。这样的一致性要求确保不会引用不存在的值,如果键值更改了,那么在整个数据库中,对该键值的所有引用要进行一致的更改。参照完整性是基于外键与主键之间的关系。例如学生学习课程的课程号必须是有效的课程号,score 表(成绩表)的外键 cno(课程号)将参考 course 表(课程表)中主键 cno(课程号)以实现数据完整性。

域完整性、实体完整性及参照完整性分别在列、行、表上实施。数据完整性任何时候都可以实施,但对已有数据的表实施数据完整性时,系统要先检查表中的数据是否满足所实施的完整性,只有表中的数据满足了所实施的完整性,数据完整性才能实施成功。

1.2 什么是SQL

SQL:结构化查询语言(Structured Query Language)。

SQL 是一种专门用来与数据库通信的语言。

SQL 的优点:

  • 几乎所有的 DBMS 都支持 SQL
  • SQL 简单易学
  • SQL 非常灵活,可以进行非常复杂和高级的数据库操作

DBMS 专用的 SQL:

SQL 不是一种专利语言,而是存在一个标准委员会(ANSI),他们试图定义可供所有 DBMS 使用的 SQL 语法,也称为:ANSI SQL。

所有主要的 DBMS,即使有自己的扩展,也都支持 ANSI SQL。

本文档是专门针对 MySQL 的,虽然大多数语法也适用于其他 DBMS,但不要认为这些 SQL 语法是完全可移植的。

第2章 MySQL简介

2.1 什么是MySQL

MySQL 是一种 DBMS,即它是一种数据库软件。

MySQL 目前得到广泛运用的原因:

2.1.1 客户机——服务器软件

DBMS 可分为两类:

(一)基于共享文件系统的 DBMS

用于桌面用途,通常不用于高端或更关键的应用。

例如:Microsoft Access 和 FileMaker。

(二)基于客户机——服务器的 DBMS

客户机——服务器应用分为两个不同的部分:

客户机部分是负责与用户打交道的软件。(这个部分运行在具体的用户计算机应用程序上)。

服务器部分是负责所有数据访问和处理的一个软件(这个软件运行在称为数据库服务器的计算机上)。

客户机和服务器软件可能安装在两台计算机或一台计算机上。不管它们在不在相同的计算机上,为进行所有数据库交互,客户机软件都要与服务器软件进行通信。

所有的活动对用户都是透明的(用户不必要在乎内部实现的细节)。

事实上,多数网络的建立使用户不具有对数据的访问权,甚至不具有对存储数据的驱动器的访问权。

因为使用了 MySQL,我们需要访问运行 MySQL 服务器软件的计算机和发布命令到 MySQL 的客户机软件的计算机。

  • 服务器软件为 MySQL DBMS。可以在本地安装的副本上运行,也可以连接到运行在具有访问权的远程服务器上的一个副本。
  • 客户机可以是 MySQL 提供的工具、脚本语言(如:Python)、Web 应用开发语言(如:PHP、Node.js)、程序设计语言(如:Java、Go、C++)等。

2.1.2 MySQL版本

本文档在 MySQL 5.7 版本下通过测试,同时该版本也是到目前为止实际开发中最为常见的版本。

2.2 MySQL工具

如前所述,MySQL 是一个客户机——服务器 DBMS,因此,为了使用 MySQL,需要有一个客户机,即你需要用来与 MySQL 打交道(给 MySQL 提供要执行命令)的一个应用。

2.2.1 MySQL命令行实用程序

每个 MySQL 安装都有一个名为 mysql 的简单命令行实用程序。这个实用程序没有下拉菜单、流行的用户界面、鼠标支持或任何类似的东西。

在操作系统命令提示符下输入 mysql 便会打开此实用程序。

mysql 选项和参数:如果仅输入 mysql,可能会出现一个错误消息。因为可能需要安全证书,或者是因为 mysql 没有运行在本地或默认端口上(没有配置 path 环境变量)。mysql 接受你可以(和可能需要)使用的一组命令行参数。例如:为了指定用户登录名 ben,应该使用 mysql -u ben。为了给出用户名、主机名、端口号、用户名和口令,应该使用:mysql [-h localhost -P 3306] -u ben -p(对于本机可以省略 [] 中的内容)。

完整的命令行选项和参数列表可使用 mysql --help 获得。

当然,具体版本和连接信息可能不同,但都可以使用这个实用程序。请注意:

mysql 命令行实用程序是使用最多的实用程序之一,它对于快速测试和执行脚本非常有价值。

即使我们选择后面即将介绍的某款图形工具,也应该保证熟悉 mysql 命令行实用程序,因为它是可以安全地依靠的一个总是会被给出的客户机(因为它是核心 MySQL 安装的一部分)。

 

2.2.2 MySQL图形化交互程序

以下软件均为收费软件,请科学使用:)

第3章 使用MySQL

3.1 连接

MySQL 在能执行命令之前必需要登录到 DBMS。

MySQL 在内部保存自己的用户列表,并且把每个用户与各种权限关联起来。

首先我们需要启动 MySQL 的服务:net start mysql

在首次安装 MySQL 时,要求输入一个管理登录(通常为 root)和一个口令(通常默认为 空)。

假如密码不为空,那么可以打开 MySQL 安装目录:

  • 在安装包根目录下新建 my.ini MySQL 配置文件
  • 编辑 my.ini 文件,注意根据安装包位置替换路径

mysql -u root -p、回车、密码为空、回车。

(以上命令全写:mysql -h localhost -P 3306 -u root -p

首次进入之后可以通过以下方法重设密码:

最后输入 flush privileges; 刷新权限。

此处以 root 用户和 123456 密码为例。

有必要的情况下:

  • 删除 my.ini 文件最后一句 skip-grant-tables
  • 重启 MySQL 即可正常使用 net stop mysqlnet start mysql

在实际团队开发中,管理登录受到密切保护(因为对它的访问授予了创建表、删除整个数据库、更改登录和口令等完全的权限)。

总结,为了连接到 MySQL,需要以下信息:

  • 主机名(计算机名)—— 如果连接到本地 MySQL 服务器,为 localhost;
  • 端口(如果使用的是默认端口 3306 之外的其他端口)
  • 一个合法的用户名
  • 用户口令(如果需要)

3.2 选择数据库

USE 数据库名:选择某个数据库。

例如:USE course;

3.3 了解数据库和表

SELECT VERSION();:查看 MySQL 版本。

SHOW DATABASES;:列出并显示所有的数据库。

SHOW TABLES;:列出并显示一个数据库中所有的表。

SHOW TABLES FROM 数据库名:在不切换当前数据库的前提下,查看另一个数据库的表。

SHOW COLUMNS FROM 表名:显示一个表的详细信息(如:字段名、数据类型、是否允许 NULL、键信息、默认值以及其他信息)。例如:SHOW COLUMNS FROM customers;

DESCRIBE 表名:在 MySQL 中提供的一种 “SHOW COLUMNS FROM 表名” 的快捷方式。

DESC 表名:"DESCRIBE 表名" 的缩写。

SELECT DATABASE();:查看当前所在的数据库。

所支持的其他 SHOW 语句还有:

进一步了解 SHOW:请执行命令 HELP SHOW;

附:SQL练习