个人技术分享

一、数据库介绍

0x00 什么是数据库

数据库是一个广义的概念:

  1. 表示 “数据库” 这一门学科。研究如何设计实现一个数据库(造轮子)

  2. 表示一类软件,用来有效管理数据

    ......

我们这里介绍的是mysql数据库管理软件。学科啥的太抽象了~

0x01 数据库软件

数据库的软件大致可以分为下面几种:

  1. Oracle : 数据库软件中的大哥。但是因为软件要收费,而且Oracle数据库在使用的时候,必须搭配IBM的小型机(不是一般我们用的电脑),才能发挥出十成功力, 但是小型机很贵,所以使用Oracle数据库的成本太高了,一般都是银行这种不差钱,且要保存非常重要的数据的公司才会使用

  2. MySQL:开源&免费的数据库(白嫖能不香嘛)!不过已经被Oracle公司收购了~ 钞能力的强大 ~

  3. SQLSever:微软做的数据库,但是最初的时候,由于只支持Windows系统,而且还收费,而使用数据库的场景一般是服务器开发,用到的系统大多是Linux,所以到现在用的公司不是很多~

  4. SQLite:主打一个轻便。运行速度快,占用内存小,经常在嵌入式设备(智能冰箱、洗衣机、空调......)中使用~

  5. redis:与上面的数据库不同的是,redis是“非关系型数据库”,并且Redis中的数据存储在内存上

补充

关系型数据库(比较传统的数据库),是使用“表”这样的结构来组织数据的,对数据的格式要求较高,也就是说每一行的每一列都得与设置的含义匹配上。举个例子:我们创建一个int的二维数组, 里面就只能存放int型的数据,而非关系型,就类似创建一个object的二维数组,里面可以存放不止一种类型的数据。

非关系型数据库,更加灵活,通常使用“文档”、“键值对”这样的结构来组织数据,也就是说一行/条数据差异可以很大~

0x02 MySQL结构

MySQL使用的是cs的结构,就是“客户端-服务器”结构。

客户端主动发起请求的一方

服务器被动响应客户端请求的一方。由于服务器不知道客户端什么时候请求,因此服务器需要一直等待~

补充

当客户端的数量越来越多的时候,那么他们对服务器的请求也越来越多,这就要求服务器要增加性能来应对这些请求,但是往后增加性能的成本会越来越高,因此,就出现了“分布式系统”,也就是说一台机器,既可以是服务器,也可以是客户端。当机器A想要请求资源的时候,可以对机器B发起,然后B可以看看自己有没有资源,没有的话就向其他机器请求,在这里面每一个就是一个对等体,所以也可以叫做peer to peer的模式。

虽然MySQL是客户端-服务器的结构,但是我们真实的数据是存储在硬盘上的,而服务器才是MySQL的本体,负责存储和管理数据~

二、数据库操作

0x00 创建数据库

create database [if not exists] 数据库名 charset 字符集名字;
​
#说明
#[]里面的内容是可加可不加的~
#if not exists 可以用来避免报错,使用场景是当我们要执行一系列的SQL语句时,如果存在了同名数据库,此时依旧会执行后面的SQL语句
#charset 也可以写成 character set 可以指定当前数据库使用什么编码方式
#在写完SQL语句后要加;号,表示此行语句写完了,因为mysql客户端允许你输入的时候换行

补充

不同的字符集,会产生不同的编码方式,也就是说在不同的字符集下,一个汉字占用几个字节是不同的。例如:gbk编码,一个汉字占用2个字节utf8编码,一个汉字占3个字节

0x01 查看所有数据库

show databases;
​
#列出当前mysql服务器上一共有哪些数据库

0x02 选中数据库

use 数据库名;
​
#当我们想要对数据进行操作的时候,我们首先要选中数据库,可以理解为指向性技能~

0x03 删除数据库

drop database 数据库名;
​
#删除一个数据库,会删除里面的所有内容,非常危险(从删库到跑路~)
#当年炉石服务器就发生了严重的数据问题,服务器选择了回档,但还好补偿够给力,玩家选择了集体失忆~

三、表操作

0x 00 字段类型

一些常用的类型。一般够用了,如果有特殊场景可以去网上再查查~

数据类型 大小 说明 对应java类型
int 4字节 Integer
bigint 8字节 Long
double 8字节 Double
decimal(M,D) M/D最大值+2 M指定数的长度,D表示小数点显示到D位数 BigDecimal
varchar(N) 0-65535字节 可变长度字符串,N表示字符串长度 String
datetime 8字节 插入格式:“YY-MM-DD 00:00:00” java.util.Date

有了这些类型,那么就可以开始创建一张表,开始存储数据了~

0x 01 创建表

create table 表名(列名 类型, 列名 类型......);
​
#创建一张表,指定列的属性

0x 02 查看所有表

show tables;
​
#查看当前数据库中所有的表

0x 03 查看表结构

desc 表名;
​
#查看指定表的结构
#desc 的全称是 describe 描述

0x 04 删除表

drop table 表名;
​
#删除指定表,比较危险需要慎重

四、SQL的增删改查

增删改查也称crud,全称create、read、update、delete,是数据库非常基础的部分,也是后端开发工作中主要的一部分。

0x 00 插入数据

insert into 表名 values (值, 值......);
​
#此处的值需要和表的列进行一一对应, 也就是值的个数和类型要匹配
​
insert into 表名 (列名, 列名......) values (值, 值......);
​
#此处的值需要和前面的列名匹配,如果有的列没有赋值,会进行赋默认值
​
insert into 表名 values (值, 值......), (值, 值......);
​
#一次插入多个数据,相比于分多次插入会有性能的提升。因为每次一次操作客户端都要向服务器请求,服务器要响应,这一定会影响性能。

0x 01 删除数据

delete from 表名 where 条件;
​
#删除表中某一行数据
#如果不加where的话,将会删除表中所有数据!

0x 02 修改数据

update 表名 set 列名 = 值 where 条件;
​
#将表中某一列的值修改
#如果不加where的话,将会修改表中所有数据!

0x 03 查询数据

3.1 全列查询

select * from 表名;
​
#把表中所有行所有列的数据查询出来
# * 表示通配符,代指所有列

补充

select * 是一个危险操作。如果当前这个表的数据特别多,可能会把硬盘的IO跑满, 此时其他程序想要访问硬盘,会非常慢。而且由于是客户端-服务器的结构,我们是通过客户端发起请求,然后服务器通过网络将查询的结构返回给客户端,此时数据太多的话, 可能会把网卡的带宽跑满,其他客户端通过网络访问服务器将非常慢~

3.2 指定列查询

select 列名, 列名...... from 表名 ;
​
#指定查询表中指定列的数据

3.3 查询字段为表达式

select 列名 + 10 from 表名;
​
#一边查询,一边进行计算
#这里的操作不会对真正的数据库中的数据进行修改,相当于临时的

3.4 别名

select 列名 as 别名 from 表名;
​
#将某一列查询后面改个名字,一般配套表达式使用
#这里的as可以省略也可以不省略(通常建议不省略,防止看花眼)~

3.5 去重

select distinct 列名, 列名...... from 表名;
​
# distinct 修饰某个列/多个列, 此时查询的结果中相同的数据只会保留一个

3.6 排序

select 列名, 列名...... from 表名 order by 列名 desc/asc;
​
#以某一列的数值为准,进行排序操作
#如果写了desc 那就是降序,如果不写或者写了asc 那就是升序

补充

如果order by 列1, 列2, 列3 写了多个字段,那么会先按照字段的顺序进行排序,比如,现在回先按照列1进行排序,如果列1的值相同,那么再比较列2 ,以此往复~

3.7 条件查询

select 列名 from 表名 where 条件;

条件中存在着一些运算符,我们来认识一下~

运算符 说明
>, >=, <, <= 大于,大于等于,小于,小于等于
= 等于,NULL 不安全,例如 NULL = NULL 的结果是 NULL
<=> 等于,NULL 安全,例如 NULL <=> NULL 的结果是 TRUE(1)
!=, <> 不等于,推荐写成 !=
between a0 and a1 范围匹配,[a0, a1] 都是闭区间,如果 a0 <= value <= a1,返回 TRUE(1)
in (n1, n2, .....) 离散化,如果是 (n1, n2, ......) 中的任意一个,返回 TRUE(1)
is null 是 null
is not null 不是null
like 模糊匹配。后面可以接通配符类似于癞子,或者%表示大于等于0个字符,_表示一个字符

还有一些逻辑运算符~

运算符 说明
AND 多个条件必须都为 TRUE(1),结果才是 TRUE(
OR 任意一个条件为 TRUE(1), 结果为 TRUE(1)
NOT 条件为 TRUE(1),结果为 FALSE(0)

注意

where 条件可以使用表达式,但不能使用别名。

因为select 条件查询的执行顺序

  1. 遍历表中每个记录

  2. 根据记录的值带入条件,根据条件进行筛选

  3. 如果这个记录条件成立,则保留当前记录,然后进行列上的表达式计算(或者重命名啥的)

  4. 如果有order by, 再进行排序

所以,在条件筛选的优先级高于列上的表达式计算,因此使用别名的话,sql服务器就不认识了~

3.8 分页查询

select 列名 from 表名 limit n offset x;
​
#offset是偏移量的意思,也可以理解为下标
#从下标为x的记录(第一条记录的下标为0)开始, 查询出 n 条记录

以上都是基础的SQL查询语句,不过很实用~