本笔记为阿里云天池龙珠计划SQL训练营的学习内容,链接为:https://tianchi.aliyun.com/specials/promotion/aicampsql
有了数据库,自然也就要能够很好地使用、管理数据,所以用来管理数据库的计算机系统就称为数据库管理系统(DBMS,DataBase Management System)。通过 DBMS,就能够很方便地管理数据,而不必操心具体的细节。
DBMS 有很多种,目前主流的 DBMS都是关系型的,所以也叫 RDBMS(Relational DBMS)。当然也出现了很多非关系型的DBMS,它们被称之为 NoSQL。一般情况下,如果没有特别强调,DBMS 指的就是 RDBMS。
这种存储行列数据表的数据库就是关系型数据库(RDB),而管理关系型数据库的就是关系数据库管理系统(RDBMS),它是一种特殊的数据库管理系统(DBMS),也是目前主流的数据库管理系统。
现在应用最广泛的数据库,和 Excel 一样使用由行和列组成的二维表格来组织数据,同时还使用专门的结构化查询语言(Structured Query Language,SQL)对数据进行操作,目前最有代表性的 RDBMS 有下面几种
一种用来保存查询所使用的键值对的数据库,由于数据结构较为简单,所以它的速度特别快,适合作为缓存系统来使用,例如目前在 Web 应用中已经成为主流的 Redis 和 Memcached。
它其实是键值型数据库的一个子类,它的不同在于:它也有诸如行列一样的结构,但和关系型数据库不同的是:它的这种行列却不是结构化的,而是不同的记录之间可以有完全不同的行和列,目前文档型数据库的主要 DBMS 是 MongoDB。
提供数据定义语言(DDL),数据库的逻辑结构、完整性约束和物理储存结构保存在内部的数据字典中,各种数据操作(如增删改查)、集合运算和数据库的维护管理都是以数据库模式为依据的。
提供易使用的交互式查询语言,如 SQL。DBMS 负责执行查询命令,并将查询结果定向到终端输出。
提供事务运行管理及运行日志,事务运行的安全性监控和数据完整性检查,事务的并发控制及系统恢复等功能,事务的 ACID 性质就是由事务管理来保障的。
为数据库管理员提供软件支持,包括数据安全控制、完整性保障、数据库备份恢复、性能监控等工具。
事务是一组要么同时执行成功,要么同时执行失败的 SQL 语句,而没有一些执行成功而另一些执行失败的情况。之所以会有事务,是因为有的数据必须一起保存,例如订单和用户积分必须一起保存下来,否则单独增加或减少都没有意义。
隐式事务
:对于单条SQL语句,数据库系统自动将其作为一个事务执行,这种事务被称为隐式事务。
显式事务
:要手动把多条SQL语句作为一个事务执行,使用BEGIN
开启一个事务,使用COMMIT
提交一个事务,这种事务被称为显式事务,例如,把上述的转账操作作为一个显式事务:
原子性(Atomicity):原子在化学中是最小单位,不可以再分割了。事务必须是原子工作单位,对于数据变化,要么全都执行,要么全都不执行。比如如果在银行转帐时 ATM 崩溃了,那么要么转账成功,要么账户余额要原路退回,不可能存在中间状态。
一致性(Consistency):一致性是指事务必须使数据库从一个一致性状态变换到另一个一致性状态,也就是说一个事务执行之前和执行之后都必须处于一致性状态。拿转账来说,假设用户 A 和用户 B 两者的钱加起来一共是 5000,那么不管 A 和 B 之间如何转账,转几次账,事务结束后两个用户的钱相加起来应该还得是 5000,这就是事务的一致性。
隔离性(Isolation):当多个用户并发访问数据库时,比如操作同一张表时,数据库为每一个用户开启的事务,不能被其他事务的操作所干扰,多个并发事务之间要相互隔离。也就是要达到这么一种效果,对于任意两个并发的事务 T1 和 T2,在事务 T1 看来,T2 要么在 T1 开始之前就已经结束,要么在 T1 结束之后才开始,这样每个事务都感觉不到有其他事务在并发地执行。
持久性(Durability):持久性是指一个事务一旦被提交,它对数据库中数据的改变就是永久性的,接下来的其他操作和数据库故障不应该对其有任何影响,该修改即使出现系统故障也将一直保持。
事务的隔离级别有 4 个,由低到高依次为 Read uncommitted(读未提交)、Read committed(读已提交)、Repeatable read(可重复读)、Serializable(串行化),这四个级别可以逐个解决脏读、不可重复读、幻读这几类问题。
脏度 | 不可重复读 | 幻读 | |
---|---|---|---|
Read uncommitted(读未提交) | √ | √ | √ |
Read committed(读已提交) | × | √ | √ |
Repeatable read(可重复读) | × | × | √ |
Serializable(串行化) | × | × | × |
Structured Query Language:结构化查询语言。
其实就是定义了操作所有关系型数据库的规则。每一种数据库操作的方式存在不一样的地方,称为“方言”。
SQL 语句可以单行或多行书写,以分号结尾。
可使用空格和缩进来增强语句的可读性。
MySQL 数据库的 SQL 语句不区分大小写,关键字建议使用大写。
注释
单行注释: – 注释内容 或 # 注释内容(mysql 特有)
多行注释: /* 注释 */
用来定义数据库对象:数据库,表,列等。关键字:create, drop,alter 等
用来对数据库中表的数据进行增删改。关键字:insert, delete, update 等
用来查询数据库中表的记录(数据)。关键字:select, where 等
用来定义数据库的访问权限和安全级别,及创建用户。关键字:GRANT, REVOKE 。
数据库中存储的表结构类似于excel中的行和列,在数据库中,行称为记录,它相当于一条记录,列称为字段,它代表了表中存储的数据项目。
行和列交汇的地方称为单元格,一个单元格中只能输入一条记录。
SQL是为操作数据库而开发的语言。国际标准化组织(ISO)为 SQL 制定了相应的标准,以此为基准的SQL 称为标准 SQL(相关信息请参考专栏——标准 SQL 和特定的 SQL)。
完全基于标准 SQL 的 RDBMS 很少,通常需要根据不同的 RDBMS 来编写特定的 SQL 语句,原则上,本课程介绍的是标准 SQL 的书写方式。
根据对 RDBMS 赋予的指令种类的不同,SQL 语句可以分为三类: DDL 、DML 、DCL。
DDL(Data Definition Language,数据定义语言) 用来创建或者删除存储数据用的数据库以及数据库中的表等对象。DDL 包含以下几种指令。
DML(Data Manipulation Language,数据操纵语言) 用来查询或者变更表中的记录。DML 包含以下几种指令。实际运用中,有 90% 的语句属于 DML。
DCL(Data Control Language,数据控制语言) 用来确认或者取消对数据库中的数据进行的变更。除此之外,还可以对 RDBMS 的用户是否有权限操作数据库中的对象(数据库表等)进行设定。DCL 包含以下几种指令。
数据库创建的表,所有的列都必须指定数据类型,每一列都不能存储与该列数据类型不符的数据。
四种最基本的数据类型
用来指定存储整数的列的数据类型(数字型),不能存储小数。
用来存储定长字符串,当列中存储的字符串长度达不到最大长度的时候,使用半角空格进行补足,由于会浪费存储空间,所以一般不使用。
用来存储可变长度字符串,定长字符串在字符数未达到最大长度时会用半角空格补足,但可变长字符串不同,即使字符数未达到最大长度,也不会用半角空格补足。
用来指定存储日期(年月日)的列的数据类型(日期型)。
NOT NULL
是非空约束,即该列必须输入数据。
PRIMARY KEY
是主键约束,代表该列是唯一值,可以通过该列取出特定的行的数据。
CREATE DATABASE < 数据库名称 > ;
使用 CREATE TABLE
语句
语法:
CREATE TABLE < 表名 >
( < 列名 1> < 数据类型 > < 该列所需约束 > ,
< 列名 2> < 数据类型 > < 该列所需约束 > ,
< 列名 3> < 数据类型 > < 该列所需约束 > ,
< 列名 4> < 数据类型 > < 该列所需约束 > ,
.
.
.
< 该表的约束 1> , < 该表的约束 2> ,……);
DROP TABLE < 表名 > ;
需要特别注意的是,删除的表是无法恢复的,只能重新插入,因此删除数据表之前需要做好备份。
ALTER TABLE < 表名 > ADD COLUMN < 列的定义 >;
-- 添加一列可以存储100位的可变长字符串的 product_name_pinyin 列
ALTER TABLE product ADD COLUMN product_name_pinyin VARCHAR(100);
ALTER TABLE < 表名 > DROP COLUMN < 列名 >;
ALTER TABLE 语句和 DROP TABLE 语句一样,执行之后无法恢复。误添的列可以通过 ALTER TABLE 语句删除,或者将表全部删除之后重新再创建。
TRUNCATE TABLE TABLE_NAME;
优点:相比drop``/``delete
,truncate
用来清除数据时,速度最快。
修改字段属性
ALTER TABLE <表名> MODIFY <字段名> <字段类型> [完整性约束条件];
--如果要修改 address 字段的长度,就要在 mysql 的命令行中执行下面的 SQL
mysql > ALTER TABLE user MODIFY address VARCHAR(256);
基本语法:
INSERT INTO <表名> (列1, 列2, 列3, ……) VALUES (值1, 值2, 值3, ……);
对表进行全列 INSERT
时,可以省略表名后的列清单。这时 VALUES子句的值会默认按照从左到右的顺序赋给每一列。
从数据表中选取数据时需要通过 SELECT
语句来实现,SELECT
是 SQL 查询中最基本
的语句,它的语法如下:
SELECT <列名 1>, <列名 2>, ...... FROM <数据表名>;
或者
SELECT * FROM <数据表名>;
--如果要选择刚才创建的用户表的数据,那么 SQL 应该这么写:
SELECT id, name, gender, age, address, regdate FROM user;
--如果只需要用户名、性别和年龄这些数据,那么可以这样做:
SELECT name, gender, age FROM user;
「*」表示选择全部的列,这是一种简写。但在有大量数据的表中不建议这么写,而是需要什么列的数据,就选择什么列的数据,不要用「*」代替。
有时候我们并不需要全部的数据,而是只需要一些特定的数据。比如如果我们只想看到年龄超过 20 岁并且性别为男性的用户。此时可以通过 SELECT
语句的 WHERE
子句来实现,它的语法是:
SELECT <列名 1>, <列名 2>, ......
FROM <数据表名>
WHERE <条件表达式>;
--选择年龄超过 20 岁并且性别为男性的用户
SELECT id, name, gender, age, address, regdate FROM user WHERE age
> 20 AND gender = '男'
注意:在同一条语句内,SELECT
、FROM
和 WHERE
的语句顺序是固定的,如果改变它们的顺序会导致 SQL 语法报错;
编写一条 CREATE TABLE 语句,用来创建一个包含表 1-A 中所列各项的表 Addressbook (地址簿),并为 regist_no (注册编号)列设置主键约束表1-A 表 Addressbook (地址簿)中的列
答:
CREATE TABLE Addressbook(
regist_no INTEGER NOT NULL,
name VARCHAR(128) NOT NULL,
address VARCHAR(256) NOT NULL,
tel_no CHAR(10),
mail_address CHAR(20),
PRIMARY KEY(regist_no)
);
假设在创建上一个中的 Addressbook 表时忘记添加如下一列 postal_code (邮政编码)了,请把此列添加到 Addressbook 表中。
列名 : postal_code
数据类型 :定长字符串类型(长度为 8)
约束 :不能为 NULL
答:
ALTER TABLE Addressbook ADD COLUMN postal_code CHAR(8) NOT NULL;
编写 SQL 语句来删除 Addressbook 表。
答:
DROP TABLE Addressbook;
编写 SQL 语句来恢复删除掉的 Addressbook 表。
答:
无法恢复,只能再次用任务 3.1 中的代码重新创建