前言

很久之前学的数据库,已经有些模糊了,最近由于需要又复习了一遍,决定写篇博客梳理总结一下。

一、安装

网上已经有很多的教程了,我就不说了,这里要提醒的是如果想安装新的数据库,记得把之前的删干净,不然会出现一些莫名其妙的错误(不要问我怎么知道的)。

二、简介

数据库分为1.关系型数据库,如MySQL、SQL等;2.非关系型数据库,如redis等。这里主要讲的是关系型数据库或者说是MySQL
想了解关系型和非关系型数据库的区别,可以看这位大佬写的文章

三、数据类型

数据库的基础类型与开发语言的类型有相似的地方,但又有所不同。
MySQL支持多种类型的SQL数据类型,包括:数值、字符串(字符与字节)、时间与日期、空间、Json等类型。常用的有数值型、字符串以及时间与日期型

  1. 数值型

包括整型、浮点型、定点型

整型(精确值):

  • TINYINT
    tinyint:范围非常小的整数,有符号的范围是 -128到127,无符号的范围是0到 255.。
  • SMALLINT
    smallint: 范围较小的整数,有符号的范围是 -32768到32767,无符号的范围是0到 65535。
  • MEDIUMINT
    mediumint: 中等大小的整数,有符号的范围是 -8388608到8388607,无符号的范围是0到 16777215。
  • INT
    int:正常大小的整数,有符号的范围是 -2147483648到 2147483647。无符号的范围是 0到4294967295。该数据类型最常用。
  • BIGINT
    bigint: 大整数,有符号的范围是 -9223372036854775808到 9223372036854775807,无符号的范围是0到 18446744073709551615。
    字节数分别为1、2、3、4、8。

浮点型:

  • FLOAT
    float(M,D):单精度浮点数。允许值是-3.402823466E+38 到-1.175494351E-38, 0以及1.175494351E-38 到3.402823466E+38,M是总位数,D是小数点后面的位数。
  • DOUBLE
    double(M,D)双精度浮点数。允许值是 -1.7976931348623157E+308到-2.2250738585072014E-308,0以及 2.2250738585072014E-308到 1.7976931348623157E+308。M是总位数,D是小数点后面的位数。
    定点型:
  • DECINAL
    decinal(M,D):常用于存储精确的小数,M是总位数,D是小数点后的位数。小数点和(负数) -符号不计入 M。如果 D为0,则值没有小数点或小数部分。如果D省略,则默认值为0.如果M省略,则默认值为10。M的范围是1到65。D范围为0到30,且不得大于M。
  1. 字符串

常用的字符串类型有如下:

  • CHAR
    char(M):一个固定长度的字符串,在存储时始终用空格填充指定长度。 M表示以字符为单位的列长度。M的范围为0到255.如果M省略,则长度为1,存储时占用M个字节
  • VARCHAR
    varchar(M):可变长度的字符串,M 表示字符的最大列长度,M的范围是0到65,535,存储时占用L+1(L<=M,L为实际字符的长度)个字节
  • TINYTEXT
    tinytext(M): 不能有默认值,占用L+1个字节,L<2^8
  • TEXT
    text(M):不能有默认值,占用L+2个字节,L<2^16
  • MEDIUMTEXT
    mediumtext(M):不能有默认值,占用L+3个字节,L<2^24
  • LONGTEXT
    longtext(M):不能有默认值,占用L+4个字节,L<2^32
  • ENUM
    enum(‘value1’,‘value2’,…):枚举类型,是一个字符串对象,其值从允许值列表中选择,它只能有一个值,从值列表中选择,最多可包含65,535个不同的元素
  • SET
    set(‘value1’,‘value2’,…):字符串对象,从允许值列表中选择,可以有零个或多个值,最多可包含64个不同的成员
  1. 时间与日期
  • TIME
    time:范围是’-838:59:59.000000’ 到’838:59:59.000000’
  • DATA
    data: 支持的范围是 ‘1000-01-01’到 ‘9999-12-31’
  • DATATIME
    datatime: 日期和时间组合。支持的范围是 ‘1000-01-01 00:00:00.000000’到 ‘9999-12-31 23:59:59.999999’。
  • TIMESTAMP
    timestamp:时间戳。范围是’1970-01-01 00:00:01.000000’UTC到’2038-01-19 03:14:07.999999’UTC。
  • YEAR
    year:范围是 1901到2155
    TIME的完整的显示为 D HH:MM:SS
    D:表示天数,当指定该值时,存储时小时会先乘以该值
    HH:表示小时
    MM:表示分钟
    SS:表示秒
  1. 约束条件

约束条件就是在给字段加一些约束,使该字段存储的值更加符合我们的预期。

常用约束条件有以下这些:
UNSIGNED :无符号,值从0开始,无负数
ZEROFILL:零填充,当数据的显示长度不够的时候可以使用前补0的效果填充至指定长度,字段会自动添加UNSIGNED
NOT NULL:非空约束,表示该字段的值不能为空
DEFAULT:默认值,表示如果插入数据时没有给该字段赋值,那么就使用默认值
PRIMARY KEY:主键约束,表示唯一标识,不能为空,且一个表只能有一个主键。一般都是用来约束id
AUTO_INCREMENT:自增长,只能用于数值列,而且配合索引使用,默认起始值从1开始,每次增长1
UNIQUE KEY:唯一值,表示该字段下的值不能重复,null除外。比如身份证号是一人一号的,一般都会用这个进行约束
FOREIGN KEY:外键约束,目的是为了保证数据的完成性和唯一性,以及实现一对一或一对多关系
如果想要更详细的介绍,可以看看这位大佬的文章,超详细的数据类型介绍,里面还附带操作实列。

四、基础操作

数据库操作语句包括:
数据操作语句(DML):即常见的对数据的增删查改;
数据定义语句(DDL):由于控制表结构;
数据控制语句(DCL):包括用户权限设置、事务处理等;
一般岗位人员主要掌握DML语句即可。

1.增删查改

DDL:

#数据库
#创建数据库
create database dbname;
#删除数据库
drop database dbname;
#使用数据库
use dbname;
#查看所有数据库
show databases;
#表
#查找所有的表
show tables;

#创建表,注意:名称尽量不要含有数字,以下仅为方便理解
create table tablename01(id int,t_name varchar(10));
# 直接将查询结果导入或复制到新创建的表
create table tablename02 select * from tablenaem01;
# 新创建的表与一个存在的表的数据结构类似
create table tablename02 like tablename01;
# 创建一个临时表
# 临时表将在你连接MySQL期间存在。当断开连接时,MySQL将自动删除表并释放所用的空间。也可手动删除。
create temporary table tablename00(id int, name varchar(10));
# 直接将查询结果导入或复制到新创建的临时表
create temporary table tablename00 select * from tablename01;

# 增加字段
# alter是个神奇的关键字
alter table tablename02 add age varchar(2) ;

# 删除一个存在表
drop table if exists tablename01;
# 删除字段
alter table tablename02 drop age;

# 更改存在表的名称
alter table tablename00 rename tablename01;
rename table tablename00 to tablename01;
# 更改字段名和属性
alter table tablename02 change age a int(10);
# 只更改字段属性
alter table tablename02 modify age varchar(7) ;

# 查看表的结构(以下五条语句效果相同)
desc tablename01;   # 因为简单,所以建议使用
describe tablename01;
show columns in tablename01;
show columns from tablename01;
explain tablename01;
# 查看表的创建语句
show create table tablename01;

DML

# 增加数据
insert into tablename01 values (1, 'tom', '23'), (2, 'john', '22');
insert into tablename01 select * from tablename01;  # 把数据复制一遍重新插入

# 删除数据
delete from tablename01 where id = 2;

# 更改数据
update tablename01 SET name = 'tom' where id = 2;

# 数据查找
select * from tablename where name like '%h%';

# 数据排序(反序/降序),order by 默认为升序
select * from tablename01 order by name, id desc;

2.多表联接

内联接:内连接inner join后面可跟where查询条件和on查询条件,此处也可以说成笛卡尔带有查询条件后是内连接。

# 内联接
select * from t01 inner join t02 on t01.id = t02.id;

外联接:
全外连接 :select * from tablename01 full join tablename02 on tablename01.id=tablenamet02.id;
全外连接在mysql中不能用,在oracle中可以使用;查询结果为左右的数据都显示,如果左边对应的右边没有与之相匹配的数据,则为null,同理左边的为nul。

# 类似全连接full join的联接用法
select id,name from t01
union
select id,name from t02;

左外连接:
查询结果为:左边的全部显示,右边的如果全部满足左边话,就和左边的显示数据条数相同;如果右边的不完全满足左边的话,则左边的表数据对应的右边为null;

# 左(外)联接
select * from t01 left join t02 ON t01.id = t02.id;

右外连接:
查询结果为:右边的全部显示,左边的如果全部满足右边话,就和右边的显示数据条数相同;如果左边的不完全满足右边的话,则右边的表数据对应的左边为null。

# 右(外)联接
select * from t01 right join t02 on t01.id = t02.id;

交叉联接(笛卡尔积):
返回左表中的所有行,左表中的每一行与右表中的所有行组合。交叉联接也称作笛卡尔积,不带条件的内连接也是笛卡尔积。

# 交叉联接
select * from t01 cross join t02;   # 标准写法
select * from t01,t02;

自然联接:
自然联接是一种特殊的等值连接,要求两个关系表中进行比较的属性组必须是名称相同的属性组,并且在结果中把重复的属性列去掉(即:留下名称相同的属性组中的其中一组)。两张表中的名称和类型完全一致的列进行内连接

#自然联接
select *  from t01 natrual  join t02;

三个及以上表的联接

#三个及以上表连接
select id,name
from t01 t1
inner join t02 t2 on t1.id = t2.id
inner join t03 t3 on t1.id = t3.id
where id = 10001;

3.键

主键(PRIMARY KEY)的完整称呼是“主键约束”,是 MySQL 中使用最为频繁的约束。一般情况下,为了便于 数据库管理系统更快的查找到表中的记录,都会在表中设置一个主键。
注意:
1.每个表只能定义一个主键。
2.唯一性原则。即主键值必须唯一标识表中的每一行,且不能为 NULL,即表中不可能存在有相同主键值的两行数据。
3.一个字段名只能在联合主键字段表中出现一次。

# 添加主键
#添加主键有两种方式,创建表时添加或创建后添加
#创建表时添加
create table tablename01(
primary key(id);
)
#创建表后添加
alter table tablename01 add primary key (id);
alter table tablename01 add constraint pk_id primary key (id);   # 主键只有一个,所以定义键名其实没有什么用,但是有其他约束时,尤其是有两个以上约束时,定义键名是非常有必要的
# 删除主键
alter table tablename01 drop primary key;

联合主键:
联合主键是由一张表中多个字段组成的,不能包含不必要的多余字段。当把联合主键的某一字段删除后,如果剩下的字段构成的主键仍然满足唯一性原则,那么这个联合主键是不正确的。这是最小化原则。
除了联合主键外,其实还有一种主键叫复合主键,但是目前我没有觉得两者有什么不同,网上有人说这两者是相同的,也有人认为不同,如果有位大佬明白,请告诉我一声,非常感谢

#联合主键
primary key(字段1,字段2,…,字段n)

外键
简单的说下,外键的出现是为了在减少表数据的冗余的同时保持数据的一致性、完整性。
《外键的作用》,这篇博客中博主提出的问题是新手常见的对外键的迷惑,博客下面有大佬的解答,看完之后你就会豁然开朗。

# 添加外键
alter table tablename01 add foreign key(id) references tablename02(id);    # 自动生成键名m_ibfk_1
alter table tablename01 add constraint fk_id foreign key(id) references tablename02(id);   # 使用定义的键名fk_id
# 删除外键
alter table tablename01 drop foreign key 'fk_id';
# 修改外键
alter table tablename01 drop foreign key 'fk_id',add constraint fk_id2 f0reign key(id) references tablename02(id);   # 删除之后从新建
# 添加唯一键
alter table tablename01 add unique(name);
alter table tablename01 add unique u_name(name);
alter table tablename01 add constraint u_name unique(name);
#添加唯一索引
alter table tablename01 add unique index u_name(name);
create unique index u_name on tableame01(name);

五、索引

以下情况适合创建索引:
1.进常被查询的字段,即在where的字段;
2.分组的字段,即在group by的字段;
3.存在依赖关系的子父表联合查询,即主键或外键;
4.设置有唯一完整性约束的字段;

查询中很少被使用的拥有许多重复值的字段不适合创建索引;

# 添加索引
alter table tablename01 add index(age);
alter table tablenmae01 add index i_age(age);
# 删除索引
drop index i_age on tablename01;

六、视图

提高复杂语句的复用性和安全性,是一种虚拟表
除了对视图内容的更新会印象到基本表外,其他的任何操作不影响基本表;
对视图的增删改查可以参考表

create view viewname as 查询语句;
select * from viewname;

结尾

剩下的还有事务,函数,存储过程和触发器,留在下一篇总结了
最后推荐一篇数据库的基础操作练习题,个人感觉很棒。