• 基础SQL教程


    转载自廖雪峰老师的教程: 

    SQL教程 - 廖雪峰的官方网站

    一 概述

    简单地说,SQL就是访问和处理关系数据库的计算机标准语言。

    数据据库作为一种专门管理数据的软件。应用程序不需要自己管理数据,而是通过数据库软件提供的接口来读写数据。

    常见类型

    名称

    类型

    说明

    INT

    整型

    4字节整数类型,范围约+/-21亿

    BIGINT

    长整型

    8字节整数类型,范围约+/-922亿亿

    REAL

    浮点型

    4字节浮点数,范围约+/-10

    38

    DOUBLE

    浮点型

    8字节浮点数,范围约+/-10

    308

    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

    通常来说,BIGINT能满足整数存储的需求,VARCHAR(N)能满足字符串存储的需求,这两种类型是使用最广泛的。

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

    二 安装

    mysql两种引擎

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

    分支:

    • MariaDB:由MySQL的创始人创建的一个开源分支版本
    • Aurora:由Amazon改进的一个MySQL版本
    • PolarDB:由Alibaba改进的一个MySQL版本

    登录: mysql -u root -p,然后输入口令

    三 关系模型

    • 表的每一行称为记录(Record),记录是一个逻辑意义上的数据。
    • 表的每一列称为字段(Column),同一个表的每一行记录都拥有相同的若干字段。字段定义了数据类型(整型、浮点型、字符串、日期等),以及是否允许为NULL。注意null不是0,也不是空串""。

    在关系数据库中,关系是通过主键和外键来维护的。对于关系表,有个很重要的约束,就是任意两条记录不能重复。能够通过某个字段唯一区分出不同的记录,这个字段被称为主键

    对主键的要求,最关键的一点是:记录一旦插入到表中,主键最好不要再修改。选取主键的一个基本原则是:不使用任何业务相关的字段作为主键

    一般把这个字段命名为id。常见的可作为id字段的类型有:

    • 自增整数类型:数据库会在插入数据时自动为每一条记录分配一个自增整数,这样我们就完全不用担心主键重复,也不用自己预先生成主键;
    • 全局唯一GUID类型:使用一种全局唯一的字符串作为主键,类似8f55d96b-8acc-4636-8cb8-76bf8abc2f57。

    可以使用多个列作为联合主键,但联合主键并不常用。 

    在students表中,通过class_id的字段,可以把数据与另一张表关联起来,这种列称为外键。

    由于外键约束会降低数据库的性能,大部分互联网应用程序为了追求速度,并不设置外键约束,而是仅靠应用程序自身来保证逻辑的正确性

    通过中间表,我们就定义了一个“多对多”关系。还有一些应用会把一个大表拆成两个一对一的表,目的是把经常读取和不经常读取的字段分开,以获得更高的性能。

    索引的效率取决于索引列的值是否散列。使用主键索引的效率是最高的,因为主键会保证绝对唯一。通过创建唯一索引,可以保证某一列的值具有唯一性。

    四 查询数据

    使用SELECT * FROM students时,SELECT是关键字,表示将要执行一个查询,*表示“所有列”,FROM表示将要从哪个表查询。SELECT查询的结果是一个二维表。

    SELECT语句其实并不要求一定要有FROM子句。许多检测工具会执行一条SELECT 1;来测试数据库连接。

    通过WHERE条件查询,可以筛选出符合指定条件的记录,而不是整个表的所有记录。

    使用<>判断不相等

    score <> 80

    name <> 'abc'

    使用LIKE判断相似

    name LIKE 'ab%'

    name LIKE '%bc%'

    %表示任意字符,例如'ab%'将匹配'ab','abc','abcd'

    使用SELECT *表示查询表的所有列,使用SELECT 列1, 列2, 列3则可以仅返回指定列,这种操作称为投影。可以对结果集的列进行重命名 SELECT 列1 别名1, 列2 别名2 FROM XXX

    使用ORDER BY可以对结果集进行排序;可以对多列进行升序、倒序排序。ASC DESC

    使用LIMIT OFFSET 可以对结果集进行分页,每次查询返回结果集的一部分;

    OFFSET是可选的,如果只写LIMIT 15,那么相当于LIMIT 15 OFFSET 0。OFFSET超过了查询的最大数量并不会报错,而是得到一个空的结果集。

    SQL提供了专门的聚合函数,使用聚合函数进行查询,就是聚合查询。除了COUNT()函数外,SQL还提供了如下聚合函数:

    函数

    说明

    COUNT

    计算某一列数量

    SUM

    计算某一列的合计值,该列必须为数值类型

    AVG

    计算某一列的平均值,该列必须为数值类型

    MAX

    计算某一列的最大值

    MIN

    计算某一列的最小值

    要特别注意:如果聚合查询的WHERE条件没有匹配到任何行,COUNT()会返回0,而SUM()、AVG()、MAX()和MIN()会返回NULL

    GROUP BY可以进行分组

    多表查询又称笛卡尔查询,使用笛卡尔查询时要非常小心,结果集是目标表的行数乘积。使用多表查询可以获取M x N行记录;

    SQL还允许给表设置一个别名,让我们在投影查询中引用起来稍微简洁一点。

    最常用的一种内连接——INNER JOIN。

    • 先确定主表,仍然使用FROM 的语法;
    • 再确定需要连接的表,使用INNER JOIN 的语法;
    • 然后确定连接条件,使用ON ,这里的条件是s.class_id = c.id,表示students表的class_id列与classes表的id列相同的行需要连接;
    • 可选:加上WHERE子句、ORDER BY等子句

    假设查询语句是:

    SELECT ... FROM tableA  JOIN tableB ON tableA.column1 = tableB.column2;

    我们把tableA看作左表,把tableB看成右表。

    INNER JOIN是选出两张表都存在的记录:

    LEFT OUTER JOIN是选出左表存在的记录:

    RIGHT OUTER JOIN是选出右表存在的记录:

    FULL OUTER JOIN则是选出左右表都存在的记录:

    五 增删改

    增: INSERT

    如:

    INSERT INTO students (class_id, name, gender, score) VALUES (2, '大牛', 'M', 80);

    也可以插入多条,如

    INSERT INTO students (class_id, name, gender, score) VALUES (1, '大宝', 'M', 87), (2, '二宝', 'M', 81);

    改: UPDATE

    UPDATE students SET name='大牛', score=66 WHERE id=1;

    在UPDATE语句中,更新字段时可以使用表达式。

    UPDATE students SET score=score+10 WHERE score<80;

    最后,要特别小心的是,UPDATE语句可以没有WHERE条件,例如:

    UPDATE students SET score=60;

    这时,整个表的所有记录都会被更新。

    删: DELETE

    DELETE FROM students WHERE id=1;

    要特别小心的是,和UPDATE类似,不带WHERE条件的DELETE语句会删除整个表的数据:

    DELETE FROM students;

    这时,整个表的所有记录都会被删除。所以,在执行DELETE语句时也要非常小心,最好先用SELECT语句来测试WHERE条件是否筛选出了期望的记录集,然后再用DELETE删除。

    六 MYSQL

    客户端

    MySQL Client和MySQL Server的关系如下:

    在MySQL Client中输入的SQL语句通过TCP连接发送到MySQL Server。

    登录语句:

    mysql -h 10.0.1.99 -u root -p

    命令行程序

    mysql实际上是MySQL客户端,真正的MySQL服务器程序是mysqld,在后台运行

    管理MYSQL

    要列出所有数据库,使用命令SHOW:

    mysql> SHOW DATABASES;

    要创建一个新数据库,使用命令CREATE:

    mysql> CREATE DATABASE test;

    要删除一个数据库,使用命令DROP:

    mysql> DROP DATABASE test;

    对一个数据库进行操作时,要首先将其切换为当前数据库USE:

    mysql> USE test;

    列出当前数据库的所有表,使用命令SHOW:

    mysql> SHOW TABLES;

    要查看一个表的结构,使用命令DESC:

    mysql> DESC students;

    还可以使用以下命令查看创建表的SQL语句SHOW CREATE TABLE:

    mysql> SHOW CREATE TABLE students;

    创建表使用CREATE TABLE语句,而删除表使用DROP TABLE语句:

    mysql> DROP TABLE students;

    修改表就比较复杂,使用ALTER TABLE。如果要给students表新增一列birth:

    ALTER TABLE students ADD COLUMN birth VARCHAR(10) NOT NULL;

    要修改birth列,例如把列名改为birthday,类型改为VARCHAR(20):

    ALTER TABLE students CHANGE COLUMN birth birthday VARCHAR(20) NOT NULL;

    要删除列,使用:

    ALTER TABLE students DROP COLUMN birthday;

    退出MySQL

    使用EXIT命令退出MySQL:

    mysql> EXIT

    实用语句

    使用REPLACE语句,这样就不必先查询,再决定是否先删除再插入:

    REPLACE INTO students (id, class_id, name, gender, score) VALUES (1, 1, '小明', 'F', 99);

    希望插入一条新记录(INSERT),但如果记录已经存在,就更新该记录,此时,可以使用INSERT INTO ... ON DUPLICATE KEY UPDATE ...语句:

    INSERT INTO students (id, class_id, name, gender, score) VALUES (1, 1, '小明', 'F', 99) ON DUPLICATE KEY UPDATE name='小明', gender='F', score=99;

    希望插入一条新记录(INSERT),但如果记录已经存在,就啥事也不干直接忽略,此时,可以使用INSERT IGNORE INTO ...语句:

    INSERT IGNORE INTO students (id, class_id, name, gender, score) VALUES (1, 1, '小明', 'F', 99);

    如果想要对一个表进行快照,即复制一份当前表的数据到一个新表,可以结合CREATE TABLE和SELECT:

    -- 对class_id=1的记录进行快照,并存储为新表students_of_class1:

    CREATE TABLE students_of_class1 SELECT * FROM students WHERE class_id=1;

    用一条语句写入各班的平均成绩:

    INSERT INTO statistics (class_id, average) SELECT class_id, AVG(score) FROM students GROUP BY class_id;

    使用FORCE INDEX强制查询使用指定的索引。例如:

    > SELECT * FROM students FORCE INDEX (idx_class_id) WHERE class_id = 1 ORDER BY id DESC;

    前提是索引idx_class_id必须存在。

    七 事务

    1 概念

    这种把多条语句作为一个整体进行操作的功能,被称为数据库事务。

    数据库事务具有ACID这4个特性:

    • A:Atomic,原子性,将所有SQL作为原子工作单元执行,要么全部执行,要么全部不执行;
    • C:Consistent,一致性,事务完成后,所有数据的状态都是一致的,即A账户只要减去了100,B账户则必定加上了100;
    • I:Isolation,隔离性,如果有多个事务并发执行,每个事务作出的修改必须与其他事务隔离;
    • D:Duration,持久性,即事务完成后,对数据库数据的修改被持久化存储。

    单条SQL语句,数据库系统自动将其作为一个事务执行,这种事务被称为隐式事务。

    要手动把多条SQL语句作为一个事务执行,使用BEGIN开启一个事务,使用COMMIT提交一个事务,这种事务被称为显式事务

    BEGIN; UPDATE accounts SET balance = balance - 100 WHERE id = 1; UPDATE accounts SET balance = balance + 100 WHERE id = 2; COMMIT;

    使用ROLLBACK进行回滚

    BEGIN; UPDATE accounts SET balance = balance - 100 WHERE id = 1; UPDATE accounts SET balance = balance + 100 WHERE id = 2; ROLLBACK;

    SQL标准定义了4种隔离级别,分别对应可能出现的数据不一致的情况:

    Isolation Level

    脏读(Dirty Read)

    不可重复读(Non Repeatable Read)

    幻读(Phantom Read)

    Read Uncommitted

    Yes

    Yes

    Yes

    Read Committed

    -

    Yes

    Yes

    Repeatable Read

    -

    -

    Yes

    Serializable

    -

    -

    -

    2 四种隔离

    • 在Read Uncommitted隔离级别下,一个事务可能读取到另一个事务更新但未提交的数据,这个数据有可能是脏数据。
    • 在Read Committed隔离级别下,一个事务可能会遇到不可重复读(Non Repeatable Read)的问题。不可重复读是指,在一个事务内,多次读同一数据,在这个事务还没有结束时,如果另一个事务恰好修改了这个数据,那么,在第一个事务中,两次读取的数据就可能不一致。
    • 在Repeatable Read隔离级别下,一个事务可能会遇到幻读(Phantom Read)的问题。幻读是指,在一个事务中,第一次查询某条记录,发现没有,但是,当试图更新这条不存在的记录时,竟然能成功,并且,再次读取同一条记录,它就神奇地出现了。
    • Serializable是最严格的隔离级别。在Serializable隔离级别下,所有事务按照次序依次执行,因此,脏读、不可重复读、幻读都不会出现。虽然Serializable隔离级别下的事务具有最高的安全性,但是,由于事务是串行执行,所以效率会大大下降,应用程序的性能会急剧降低。如果没有特别重要的情景,一般都不会使用Serializable隔离级别。

    默认隔离级别

    如果没有指定隔离级别,数据库就会使用默认的隔离级别。在MySQL中,如果使用InnoDB,默认的隔离级别是Repeatable Read。

  • 相关阅读:
    C++ Reference: Standard C++ Library reference: C Library: cmath: remquo
    HarmonyOS鸿蒙学习笔记(6) @Consume和@Provide作用说明和简单案例
    Junit 超时测试
    一文带你了解 Spring 的@Enablexxx 注解
    【软件测试】性能测试
    2019-10《信息资源管理 02378》真卷(独家文字版),圈定章节考点+统计真题分布
    阿里巴巴中国站获得1688商品详情 API 返回值说明
    Invest模型问题答疑--产水模块、土壤保持模块、供需平衡分析、生态系统服务、生物多样性生境质量
    BIM设计 | 学会CAD这5个隐藏操作,让你受益无穷
    来自领导的指点--1 : 小程序和H5 代理问题
  • 原文地址:https://blog.csdn.net/wulitaotao96/article/details/125503265