暂无图片
暂无图片
2
暂无图片
暂无图片
暂无图片

Halo DB 14 小白零基础系列(5)--SQL语句以及基本概念熟知

冷狼 2024-11-21
88

前言:

        即上篇的基础系统视图以后,有朋友私下反馈给我说,建议简单的介绍下SQL语句的基础用法,那OK,来了来了他来了–HaloDB之SQL语句以及相关基础概念,作为一名DBA,扎实的基本功是我们在日常工作中的基本素养。所以本篇为大家介绍SQL语句的用法的同时,也为大家奉上我本人整理的相关技术概念供各位新入门的朋友学习。

        说到我们的HaloDB,日常打广环节到了**(希望老板看见记得给我加鸡腿)**

        杭州易景数通科技有限公司,核心团队自2013年起投身数据库领域的研发,截至到2018年,从众多的金融系统数据库迁移项目中积累了丰富的数据库实施、迁移经验,团队积累了大量的数据库前沿以及核心技术;2019-2020年,结合自主研发的数据库产品(Halo数据库前身),成功完成了保险行业首个核心业务系统Oracle数据库的替换工作,获得了行业内外及监管机构的一致好评;2021年,现创始团队正式更名为且成立杭州易景数通科技有限公司,并正式发布Halo数据库系列产品,投身于数据库事业的星辰大海中。专注于数据库产品的研发,致力于数据库领域的技术研究和突破,立志成为中国,乃至世界领先的数据库技术公司(老板加油,谢谢!)

        如果有对我们的产品感兴趣的朋友可以通过主页的联系方式与我取得联系,获取license来安装体验,当然您如果有好的建议也可以提给我们,下面正式开始今天的内容。

参考文档:https://blog.csdn.net/weixin_41565755/article/details/96630044 (在此对作者表示衷心的感谢,省下我很多整理的时间)

        另外,本篇文档所使用的示例均出自CUUG讲师冉乃刚老师在授课时所采用的例子,在此对冉老师表示衷心的感谢。至于为什么要把这件事说出来,首先是对恩师的感谢,没有冉老师或许我也不会跟数据库解下如此深厚的缘分,另外我也想呼吁大家对知识产权的重视,最近圈子里出现了很多令人不愉快的事,把别人的文档直接拿过来改名申请原创甚至下载墨值,转载别人辛苦写的文章打上自己的原创这种行为表示强烈的鄙视。始作俑者甚至对此不屑一顾,甚至说,一个工具而已,有这个必要么?那既然如此,明天我也不写文章了,我直接抄你的然后我也打上原创好了~ 

鉴于你上述的令人疑惑言论和恬不知耻的行为,在这里值此新春即将到来之际,我衷心祝愿你全家身体健康,长命百岁~

            题外话就说这么多,我们还是开始今天的内容。兄弟们坐稳了,发车了~ 

一、什么是SQL语句:

          结构化查询语言(Structured Query Language)简称SQL,是一种特殊目的的编程语言,是一种数据库查询和程序设计语言,用于存取数据以及查询、更新和管理关系数据库系统。 结构化查询语言是高级的非过程化编程语言,允许用户在高层数据结构上工作。它不要求用户指定对数据的存放方法,也不需要用户了解具体的数据存放方式,所以具有完全不同底层结构的不同数据库系统, 可以使用相同的结构化查询语言作为数据输入与管理的接口。结构化查询语言语句可以嵌套,这使它具有极大的灵活性和强大的功能。

二、相关基础知识:

            在上一篇已经为大家介绍过SQL语句的常规用法,如果有不熟悉的小伙伴请参考之前的内容,但是概念性的东西还是应该熟悉和了解。下面是我整理的SQL语句语句相关基础概念,还是建议各位小伙伴有必要参考和熟悉:

1、SQL语句的主要类目:

  • 数据定义语言(Data Definition Language,DDL):这类语句用于定义数据库对象,如数据库、表、列、索引等。常见的关键词有createdropalter等。
  • 数据操作语言(Data Manipulation Language,DML):这类语句用于处理数据库中的数据,包括插入(insert)、删除(delete)、更新(update)以及查询(select)。查询语句虽然不是严格意义上的数据操作,但由于其用途广泛且频繁,有时也被归入此类。

  • 数据查询语言(Data Query Language,DQL):这类语句主要用于从数据库中获取数据信息。尽管在某些数据库系统中,查询语句可能被视为与数据操作类似的命令,但通常来说,查询语句是为了检索而非修改数据而设计的。

  • 数据控制语言(Data Control Language,DCL):这类语句用于管理数据库的用户账户及其权限,如授予(GRANT)和撤销(REVOKE)权限。虽然在某些情况下,数据控制也可以涉及数据的定义和管理,但它主要的功能还是集中在权限管理和安全性上。

2、事务的四大属性(ACID):

        说到ACID ,各位小白朋友可能有点懵,没关系,我在初入门的时候被别人问起ACID的时候我也是一脸懵关闭的,我从小到大只知道PICC(广告看多了)。但是作为一名比较合格的DBA,事务的ACID属性还是有必要熟悉掌握和了解的。首先要了解什么是事务,在关系型数据库中,一个事务可以是一条SQL语句,一组SQL语句或整个程序。

事务应该具有4个属性:原子性、一致性、隔离性、持久性。这四个属性通常称为ACID特性。

原子性(atomicity):一个事务是一个不可分割的工作单位,事务中包括的操作要么都做,要么都不做。

一致性(consistency):事务必须是使数据库从一个一致性状态变到另一个一致性状态。一致性与原子性是密切相关的。

隔离性(isolation):一个事务的执行不能被其他事务干扰。即一个事务内部的操作及使用的数据对并发的其他事务是隔离的,并发执行的各个事务之间不能互相干扰。

持久性(durability):持久性也称永久性(permanence),指一个事务一旦提交,它对数据库中数据的改变就应该是永久性的。接下来的其他操作或故障不应该对其有任何影响。

3、事务的隔离级别:

          事务的隔离级别按从低到高依次为:读未提交、读已提交、可重复读、可串行化。
    a、读未提交(Read Uncommitted):  

              一个事务,能够读到,其他事务,未提交的修改。一个事务读到了另一个事务未提交的操作,而之后另一个事务回滚,则会引起赃读。
    b、读已提交(Read Committed): 

              一个事务,所做的修改,只有在提交之后,才能被其他事务访问。可以避免赃读。一个事物两次读取同一份数据时,如果中间有其他事务的提交对该数据进行了修改,则会造成不可重复读。
    c、可重复读(Repeated Read): 

             在同一个事务的处理过程中,多次读取,同一份数据,的结果总是相同的,不管其他事务是否提交。可以避免赃读,不可重复读。相当于在事务开始时对所操作的数据进行了加锁,那么其他事务是不能改变这部分数据,但是可以插入新的数据。 如果一个事务对一个表中的所有数据进行了修改,同时其他事务插入了新的数据,那么在本事务看来,新插入的数据并没有被修改,因此产生幻读。
    d、串行读/顺序读(Serialization): 

             多个事务只能以串行方式执行,不能并发执行。是最高的隔离级别,可以解决并发引起的所有问题,但是牺牲了并发性。

说到这,那肯定有同学好奇问,脏读,幻读,这都什么鬼,来,我们继续:

4、脏读,幻读,不可重复读:

        在我们对数据库进行并发操作的时候(可以简单的理解为,多个人同时对同一张表进行操作,比如银行的转账账单这种)可能破坏事务的隔离性,带来的数据不一致性包括三类:赃读、不可重复读、幻读。那他们都分别是什么,我们接着往下看:

(1)赃读(Dirty Read):可能发生的隔离级别:读未提交的事务。脏读一般情况下意味着一个事务读取了另一个事务未提交的数据,而这个数据是有可能回滚。

(2)不可重复读 (Unrepeatable Read):可能发生的隔离级别:读提交的事务、读未提交的事务,不可重复读意味着,在数据库访问中,一个事务范围内两个相同的查询返回了不同数据。这是由于查询时系统中其他事务修改的提交而引起的。例如:事务B中对某个查询执行两次,当第一次执行完时,事务A对其数据进行了修改。事务B中再次查询时,数据发生了改变。

(3)丢失修改/幻读(phantom read):可能发生的隔离级别:不可重复读、读已提交的事务、读未提交的事务。幻读,是指当事务不是独立执行时发生的一种现象。例如第一个事务对一个表中的数据进行了修改,这种修改涉及到表中的全部数据行。同时,第二个事务也修改这个表中的数据,这种修改是向表中插入一行新数据。那么,以后就会发生操作第一个事务的用户发现表中还有没有修改的数据行,就好象发生了幻觉一样。对新插入的数据没有进行修改。

我们的HaloDB 目前默认采用的依旧是,读已提交,至于为何采用此种方式,我这里卖个关子,我会在后面的部分为大家解惑。

HaloDB中默认的隔离级别:

dtestzz=# SHOW transaction_isolation;
 transaction_isolation 
-----------------------
 read committed
(1 row)

三、SQL语句的简单查询:

        SQL语句的简单查询常用字句一般由下面的几种组成,在前面我们也铺垫过,这里就不做过多说明。常见的select字句如下,请参考:

  1)select子句   2)from子句  3)where子句  4)group by 子句  5)having 子句   6)order by 子句  7)limit子句  8) offset 子句

这几种语句在数据库中的执行顺序一般为:

①from, ②where, ③group by, ④having, ⑤select, ⑥order by ⑨offset ⑩ limit

1、SQL语句中运算符以及优先级:

常见的运算符可以简单的分为算数运算符、逻辑运算符、比较运算符三个大类

算数运算符:*,/,+,-

逻辑运算符:not, and ,or 这三种可以通过使用()改变运算优先级

比较运算符:=,>, >=,<,<=, <>,between ... and

示例1:找出emp表中工资大于2000且组名为10的员工
testzz=# select * from emp where sal>2000 and deptno=10;
 empno | ename |    job    | mgr  |  hiredate  | sal  | comm | deptno 
-------+-------+-----------+------+------------+------+------+--------
  7782 | CLARK | MANAGER   | 7839 | 1981-06-09 | 2450 |      |     10
  7839 | KING  | PRESIDENT |      | 1981-11-17 | 5000 |      |     10
(2 rows)
示例2:显示工资扣除30% 仍然大于2000的员工
testzz=# select * from emp where (sal-sal*30/100)>2000;
 empno | ename |    job    | mgr  |  hiredate  | sal  | comm | deptno 
-------+-------+-----------+------+------------+------+------+--------
  7566 | JONES | MANAGER   | 7839 | 1981-04-02 | 2975 |      |     20
  7839 | KING  | PRESIDENT |      | 1981-11-17 | 5000 |      |     10
  7902 | FORD  | ANALYST   | 7566 | 1981-12-03 | 3000 |      |     20
(3 rows)
示例3:用BETWEEN AND操作符来查询出在某一范围内的行
testzz=# SELECT ename, sal FROM emp WHERE sal BETWEEN 1000 AND 1500;
 ename  | sal  
--------+------
 WARD   | 1250
 MARTIN | 1250
 TURNER | 1500
 MILLER | 1300
(4 rows)

2、SQL语句中多值比较运算in、not in(>any,>all,<any,<all用于子查询比较):

示例4:字句in的使用方法
testzz=# select * from emp where deptno in (10,20);
 empno | ename  |    job    | mgr  |  hiredate  | sal  | comm | deptno 
-------+--------+-----------+------+------------+------+------+--------
  7566 | JONES  | MANAGER   | 7839 | 1981-04-02 | 2975 |      |     20
  7782 | CLARK  | MANAGER   | 7839 | 1981-06-09 | 2450 |      |     10
  7839 | KING   | PRESIDENT |      | 1981-11-17 | 5000 |      |     10
  7902 | FORD   | ANALYST   | 7566 | 1981-12-03 | 3000 |      |     20
  7934 | MILLER | CLERK     | 7782 | 1982-01-23 | 1300 |      |     10
  7369 | HALOZZ | CLERK     | 7902 | 1980-12-17 |  800 |      |     20
(6 rows)

我们也可以换一种写法:

testzz=# select * from emp where deptno=10 or deptno=20;
 empno | ename  |    job    | mgr  |  hiredate  | sal  | comm | deptno 
-------+--------+-----------+------+------------+------+------+--------
  7566 | JONES  | MANAGER   | 7839 | 1981-04-02 | 2975 |      |     20
  7782 | CLARK  | MANAGER   | 7839 | 1981-06-09 | 2450 |      |     10
  7839 | KING   | PRESIDENT |      | 1981-11-17 | 5000 |      |     10
  7902 | FORD   | ANALYST   | 7566 | 1981-12-03 | 3000 |      |     20
  7934 | MILLER | CLERK     | 7782 | 1982-01-23 | 1300 |      |     10
  7369 | HALOZZ | CLERK     | 7902 | 1980-12-17 |  800 |      |     20
(6 rows)

一个不够?那我们再看几个

testzz=# select * from emp where mgr in (7698,7369,7788,null);
 empno | ename  |   job    | mgr  |  hiredate  | sal  | comm | deptno 
-------+--------+----------+------+------------+------+------+--------
  7499 | ALLEN  | SALESMAN | 7698 | 1981-02-20 | 1600 |  300 |     30
  7521 | WARD   | SALESMAN | 7698 | 1981-02-22 | 1250 |  500 |     30
  7654 | MARTIN | SALESMAN | 7698 | 1981-09-28 | 1250 | 1400 |     30
  7844 | TURNER | SALESMAN | 7698 | 1981-09-08 | 1500 |    0 |     30
  7900 | JAMES  | CLERK    | 7698 | 1981-12-03 |  950 |      |     30
(5 rows)

这里需要注意,not in 里有null值,不返回结果集

testzz=# select * from emp where mgr not in (7698,7369,7788,null);
 empno | ename | job | mgr | hiredate | sal | comm | deptno 
-------+-------+-----+-----+----------+-----+------+--------
(0 rows)

3、SQL语句中模糊比较like的使用方法:

            在SQL语句中,可以使用like这种方式进行模糊查询,我们直接看例子:
示例5:like字句的使用方法
testzz=#  select * from emp where ename like 'A%';
 empno | ename |   job    | mgr  |  hiredate  | sal  | comm | deptno 
-------+-------+----------+------+------------+------+------+--------
  7499 | ALLEN | SALESMAN | 7698 | 1981-02-20 | 1600 |  300 |     30
(1 row)testzz=# create table test (name char(10));
CREATE TABLE
testzz=# insert into test values ('sFdL');
INSERT 0 1
testzz=# insert into test values ('AEdLHH');
INSERT 0 1
testzz=# insert into test values ('A%dMH');
INSERT 0 1
testzz=# select * from test where name like 'A\%%' escape '\';
    name    
------------
 A%dMH     
(1 row)

4、SQL语句中特殊比较之:is null 

示例6:is null字句的使用方法
testzz=# select * from emp where mgr is null;
 empno | ename |    job    | mgr |  hiredate  | sal  | comm | deptno 
-------+-------+-----------+-----+------------+------+------+--------
  7839 | KING  | PRESIDENT |     | 1981-11-17 | 5000 |      |     10
(1 row)

5、空值(null)的处理

    在我们的HaloDB中沿用了原生的PG中的coalesce这个函数是处理空值,可以有两个参数(相当于Oracle的nvl函数),coalesce(comm,0),当第一个参数不为空时取第一个值,当第一个值为NULL时,取第二个参数的值。用例子展示更加清晰些。

示例7:在HaloDB中关于空值的处理
testzz=# select empno,ename,sal,comm,sal+coalesce(comm,0) salary from emp;
 empno | ename  | sal  | comm | salary 
-------+--------+------+------+--------
  7499 | ALLEN  | 1600 |  300 |   1900
  7521 | WARD   | 1250 |  500 |   1750
  7566 | JONES  | 2975 |      |   2975
  7654 | MARTIN | 1250 | 1400 |   2650
  7698 | BLAKE  | 2850 |      |   2850
  7782 | CLARK  | 2450 |      |   2450
  7839 | KING   | 5000 |      |   5000
  7844 | TURNER | 1500 |    0 |   1500
  7900 | JAMES  |  950 |      |    950
  7902 | FORD   | 3000 |      |   3000
  7934 | MILLER | 1300 |      |   1300
  7369 | HALOZZ |  800 |      |    800
(12 rows)

结尾:

                今天就先整理这些,给大家分享,剩下的内容我会尽快整理成体系分享给大家,还有部分内容需要补充测试用例,最后,如果有对我们产品感兴趣的小伙伴和大佬,非常欢迎体验试用我们的产品,给我们提出好的意见和建议。

                 虽然是慢工,但是不是什么细活。

「喜欢这篇文章,您的关注和赞赏是给作者最好的鼓励」
关注作者
【版权声明】本文为墨天轮用户原创内容,转载时必须标注文章的来源(墨天轮),文章链接,文章作者等基本信息,否则作者和墨天轮有权追究责任。如果您发现墨天轮中有涉嫌抄袭或者侵权的内容,欢迎发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

评论