【SQL数据库】

SQL

关系型数据库:指这种数据库不光光可以用来存储数据,还可以存储数据与数据之间的关系。一般是放在磁盘中的

非关系型数据库:非关系型数据库仅仅用来存储数据。非关系型数据库又有一个名字,叫NoSQL。存放在内存上,读写速度快

字符集:其实就是一套符号和编码。utf8,gbk,Latin1(不支持中文),utf8mb4(对UTF8的一个拓展),在创建的时候如果不指定字符集,默认是使用Latin1

校对规则:其实就是一套用来比较字符集内字符大小的规则。utf8_bin(区分大小写),utf8_general_ci(不区分大小写)

create database dbName character set utf8 collate utf8_bin;

drop database [if exists] dbName;

-- 修改库的名字(不支持)
-- 修改库的字符集
alter database 36th character set gbk collate gbk_bin;

-- 查询库
-- 查询所有的库
show databases;

-- 查询库的建库语句  可以帮助我们查看库的字符集和校对规则
show create database 36th;

常用的类型

整型:常用int,数据过大使用bigint

浮点型:float(4,2),double(6,2),decimal(8,2),前面的参数表示总共的位数,后面的表示小数位数,如果小数位数大于该参数,会自动四舍五入

date类型:year, date,time,datetime, timestamp

-- datetime 和timestamp的区别
-- 1. datetime 占用8个字节 timestamp占用4个字节
-- 2. timestamp默认时间是当前时间,datetime默认是null
-- 3. timestamp 跟着mysql的时间走,而datetime跟着系统的时间走

使用now()可以获得当前时间,前面加上year等参数可以获取当前的年月日

year(now())

字符串类型:常用char、varchar(可变)、text(长文本)

枚举类型:只能选择其中的一个

enum('first','second','third')

集合类型:可以选择多个

set("bob","tom","jerry")

use database;
create table user(
name varchar(20),
age int,
gender enum('male','female')
)character set utf8 collate utf8_bin;

drop table [if exists] user;

--改表名
rename table user to user1;
--改表的字符集
alter table user character set utf8 collate utf8_bin;
--修改列
--增加列
alter table user add height int;
--删除列
alter table user drop height;
--修改列的名字
alter table user change height width double(4,2);
--修改列的类型
alter table user modify width int;

--查建表语句
show create table user;
--查所有的表
show tables;
--查表的结构
describe tableName;
desc tableName;

数据

使用values关键字即可,如果没有指定插入列的话,插入的值需要与表的顺序一一对应

insert into user1 values
(3,"云天明2号","男",'2000-10-19','2015-10-11','讲师',10000.00,'王道最可爱的天明妈妈'),
(2,"长风","男",'2000-10-19','2015-10-11','讲师',20000.00,'王道最会单手打方向盘的男人');

插入的多个值使用逗号隔开

-- 插入指定列的值
insert into user1 (uid,name) values (1002,'楚云飞');

-- 删除
delete from user1;

-- 删除指定的数据 where
-- where是对表中的记录去过滤,筛选出符合条件的行(记录)
delete from user1 where uid = 1;
delete from user1 where name = '楚云飞';

-- 修改
-- 修改单列
update user1 set name = '短风'; 

-- 修改单列
update user1 set name = '长风' where uid = 1;

-- 修改多列
update user1 set job = '总经理',resume='最大方的总经理'  where uid = 1;

select关键字的额外功能:

now()获取当前时间

trim 消除空格

concat 拼接字符串

-- 查询
-- 查询表 t_students 中学生的姓名
select name from t_students;

-- 查询多列
select id,name,class from t_students;

--查询所有信息
select * from students;

关键字

where

用于过滤表中的数据,后面需跟一个布尔表达式

多个条件中间使用and或者or来连接

is null | is not null

is null :判断是否为空

is not null:判断是否不为空

但要注意,null和空字符串是有区别的

between and | not between and

between and 表示查询一个范围区间(闭区间)的成员

select * from students where math between 80 and 90;
in | not in

查询在一个指定范围内的成员

select * from students where class in ('36期','35期');
like | not like

模糊查询

-- like
-- 模糊查询 
-- % 表示通配
-- _表示占位
select * from students where name like '黄%';
select * from students where name like '黄_';
select * from students where name like '%黄%';

distinct

用于去重的关键字

-- 查询 students 表中的不同班级名
select distinct(class) from students;

需要注意的是,只有两行数据完全一致的时候才会去重,假如不一致,就不会去重

select distinct(class),name from students;

limit

限制结果集,可以控制语句输出的条数

-- 查询 students 表中第3到第5条记录;
select * from students limit 2,3; --从下标为2的位置开始打印3个数据

--查询前3条记录
select * from students limit 3;

分页公式:

limit (page_no - 1) * page_size,page_size

order

排序

  • 升序:默认值,ASC
  • 降序:DESC
select * from students order by chinese desc,math asc,limit 3;
-- 查询总成绩前三名同学的信息。
select * from students order by (chinese+math+english) desc limit 3;

计算字段

对一行中的数据进行计算

-- 查询总成绩信息
select name,chinese+english+math from students;

AS

对表或者列起别名

select * from (select name as '名字',chinese+math+english as"总分" from students) as user;

group by

对查询的结果进行分组

group_concat:对同一组的列的数组进行合并

select class,group_concat(id),group_concat(name) from students group by class;

having:对分组之后的结果进行过滤。分组后只能用having不能用where

-- 对于分组之后的结果过滤,我们要使用having关键字
-- 对于分组之前的原始表中的数据进行过滤,我们要使用where关键字
select class,count(*) as count from students group by class having count > 2;

count:统计分组的列数

聚合函数

  • max

    求最大值

    select class,max(score) from student group by class;
    
  • min

    求最小值

    select class,min(score) from student group by class;
    
  • sum

    求和

    select class,sum(score) from student GROUP BY class;
    
  • count

    计数

    select count(*) from student group by class;
    
  • avg

    select class,avg(score) from students group by class;
    

SQL语句的执行顺序

(5) SELECT column_name, ... 
(1) FROM table_name, ...
(2) [WHERE ...] 
(3) [GROUP BY ...] 
(4) [HAVING ...] 
(6) [ORDER BY ...]
(7) [limit...];

SQL的语句的原则:首先要输入你想要查询的数据,然后写明从哪个表查询,然后过滤原表数据,分组,分组之后的数据过滤,排序,limit永远在最后

数据完整性

数据完整性是为了保证插入到数据库中的数据是正确的,它防止了用户可能的输入错误。

实体完整性

主键:保证表中的每一条数据都是唯一的

  • 主键是不重复的,唯一的
  • 每一个表中必须得有一个主键
  • 主键通常使用id来作为这个主键字段
  • 主键不能为空

在MySQL中,我们的每一个表都有一个主键,如果用户没有设置的话,会自动生成一个隐藏的列作为主键

使用 auto_increment 关键字可以让主键自增,默认有一个记录,从1开始自增,会记录行数,如果前面的数据全部删除,会从原来自增到的地方往下自增

-- primary key  表示这个字段是主键
-- auto_increment 表示主键自增
create table t_user (
	id int PRIMARY KEY auto_increment,
	name varchar(20)
)character set utf8;

域完整性

表中的每一列都有一个特定的数据类型约束

  • not null (不为空)

  • unique (唯一)

create table t_user(
	id int PRIMARY KEY auto_increment,
    name varchar(20) not null,
    age int unique
)character set utf8;

unique与主键的区别

  • 主键不能为空,unique可以为空
  • 存储方式有区别

参照完整性

外键:与其他表的数据相关联

create table province(
	id int PRIMARY KEY,
    name varchar(20) not null
)character set utf8;

create table city(
	id int PRIMARY KEY,
    name varchar(20) not null,
    province_id int,
    constraint fk_province_id foreign key(province_id) references province(id)
)character set uft8;

建立外键后存在两个约束:

  • 当我们添加或者修改城市表中的数据时,需要检测省份id是否存在于省份表中
  • 当我们删除或者修改省份表时,要注意城市表中是否存在对应的省份id
  • 注意主键不能作为外键,并且外键的字段长度要一致

多表设计

一对一

记录一一对应

  • 人和身份证号
  • 学生和学号

一对多

如果A(一)和B(多)两个表的关系是一对多的, 那么表中的数据应该有如下关系:

A表中的一条记录对应B表中的多条记录,B表中的一条记录对应A表的一条记录

关系数据应该记录在B表

常见的一对多模型:

  • 省份和城市
  • 班级和学生
  • 院和系
  • 分类和商品

多对多

多对多其实就是互为一对多,A表中的一条记录对应B表中的多条记录,B表中的一条记录对应A表中的多条记录

常见的多对多模型:

  • 学生和课程
  • 商品和订单
  • 导师和学生

维护多对多的模型需要建立一个中间表

三大范式

第一范式

原子性:每一列存储的数据都是不可分割的,例如收货地址需要分割成省市区来存储

第二范式

**唯一性:**记录要有唯一的标识,不能有部分依赖

第三范式

字段不要冗余

在有些时候字段冗余可以降低维护的成本,所以在设计的时候如果一个表的查询需求远大于增删改的需求,那么可以适当的冗余,这种叫反范式化设计;在设计表的时候会遵循第一和第二范式,但第三范式看情况

多表查询

交叉连接

求两个表的笛卡尔积

select * from province cross join city;

内连接

在交叉连接的基础上进行筛选

  • 显式内连接
select * from province inner join city on province.id = city.province_id;
  • 隐式内连接
select * from province,city where province.id = city.province_id;

外链接

在交叉连接的基础上进行筛选,然后再做并集

  • 左外连接
select * from province left outer join city on province.id = city.province_id;
  • 右外连接
select * from province right outer join city on province.id = city.province_id;
  • 三张表的连接查询
-- 内连接
select 
	s.id as '学生id',
	s.name as '学生姓名',
	c.teacher_name as '老师名字',
	c.name as '课程名字'
from
	student as s,
	sc,
	course as c
where
	s.id = sc.sid
	and sc.cid = c.id;
-- 外连接
select
	s.id as '学生id',
	s.name as '学生姓名',
	c.teacher_name as '老师名字',
	c.name as '课程名字'
from 
	student as s 
	left join sc on s.id = sc.sid
	left join course as c on sc.cid = c.id;

子查询

可以嵌套的查询

-- 查询江苏省和湖北省的所有城市
select * from city where province_id in (select id from province where name = '江苏省' or name = '湖北省');

联合查询

联合查询可以合并查询的结果,并且去掉重复行

-- 联合查询
-- 双方的字段必须一致
select * from province where name = '湖北省'
union
select * from province where name = '安徽省';

数据的备份与恢复

  • 备份
-- 1.打开cmd执行窗口
-- 2.执行命令
mysqldump -uroot -p dbname>文件全路径名

备份完成之后会生成一个sql文件,这个sql文件是这个数据库里面所有的表的建表语句以及数据信息。但备份的时候没有建库语句

  • 恢复
-- 1.连接MySQL服务
mysql -uroot -p

-- 2.建库
create database dbName;
use dbname;

-- 3.恢复
source src

枚举类型

public enum  OrderStatus {
    
	// 枚举类型不可以创建实例对象
    // 定义好枚举类型的实例对象
    
    NOT_PAYED(1,"未支付"),
    PAYED(2,"已支付"),
    CANCEL(3,"取消")
    ;

    int id;
    String desc;

    OrderStatus(int id, String desc) {
        this.id = id;
        this.desc = desc;
    }

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public String getDesc() {
        return desc;
    }

    public void setDesc(String desc) {
        this.desc = desc;
    }
}

你可能感兴趣的:(#,Java核心技术精选,数据库,sql)