数据库 (一)--MySQL

数据库概述

所谓的数据库就是指存储和管理数据的仓库。如今市面上的数据库分为两大阵营:
关系型数据库和非关系型数据库。mysql

关系型数据库

关系型数据库最典型的数据结构是表,由二维表及其之间的联系所组成的一个数据组织。
优势:
一、易于维护:都是使用表结构,格式一致;
二、使用方便:SQL语言通用,可用于复杂查询;
三、复杂操做:支持SQL,可用于一个表以及多个表之间很是复杂的查询。
缺点:
一、读写性能比较差,尤为是海量数据的高效率读写;
二、固定的表结构,灵活度稍欠;
三、高并发读写需求,传统关系型数据库来讲,硬盘I/O是一个很大的瓶颈。
经常使用的几个:mysql /oracle/sql server/sqliteredis

非关系型数据库

非关系型数据库严格上不是一加粗样式种数据库,应该是一种数据结构化存储方法的集合,能够是文档或者键值对等
优势:
一、格式灵活:存储数据的格式能够是key,value形式、文档形式、图片形式等等,文档形式、图片形式等等,使用灵活,应用场景普遍,而关系型数据库则只支持基础类型。
二、速度快:nosql可使用硬盘或者随机存储器做为载体,而关系型数据库只能使用硬盘;
三、高扩展性;
四、成本低:nosql数据库部署简单,基本都是开源软件。
缺点:
一、不提供sql支持,学习和使用成本较高;
二、无事务处理;
三、数据结构相对复杂,复杂查询方面稍欠。
经常使用的几个:redis/hbase/mongoDB/CouchDB/Neo4Jsql

MySQL

瑞典MySQLAB公司提供,免费开源,适用于一些小型或者中型的项目中,在Java中的使用占比较高(小巧轻量)数据库

数据库服务器

数据库服务器就是一个软件(好比mysql软件)将数据库软件安装在电脑上,当前电脑就是一个数据库服务器。就能够对外提供存取数据的服务,在一个数据库服务器中能够建立多个数据库(dataBases),每个数据库都是一个单独的仓库。express

数据库

数据库就是存储和管理数据的仓库,一般状况下,一个网站的中的全部数据会存放在一个数据库中。编程

表(table)

一个数据库中能够建立多张表,每张表用于存储一类信息(数据库)安全

字段(column)

一张表中能够包含多行表记录,每一行表记录用于存储某一个具体的数据服务器

字段类型(type)

日期和时间数据类型
image
数值数据类型
整型
image
浮点型
image
字符串数据类型
image数据结构

语法

  • 启动mysql服务端,在cmd窗口运行mysql
  • 数据库初始化命令:mysql-initialize-insecure
  • 启动mysql客户端,并链接服务端mysql -uroot -p
  • 链接其余ip数据库,mysql -u帐号 -hIP地址 -P端口号 -p密码
  • 查看当前登录用户:select user( )
  • 刷新权限,执行命令:flush privileges;
  • 查看进程:tasklist | findstr mysql
  • 杀死进程:tasklist /F /PID 进程号

约束:做用是保证数据的完整性和一致性

  • not null 表示该字段数据不能为空
  • default 表示该字段的默认值
  • unique 惟一(列惟一,组合惟一)
  • primary key 主键 一张列表中只容许出现一个主键(not null + unique)
  • auto-increment 自增加
  • foregin key 外键 创建两个表之间的联系
  • 语法 constraint fk_dep foreign key(关联列名) references 被关联表(被关联列)
  • on delete cascade 同步删除
  • on update cascade 同步更新

SQL语言

SQL是一门用于操做关系型数据库的通用的语言(使用SQL能够操做全部的关系型数据库)
使用SQL能够操做数据库、表、表记录
(1)建立数据库、删除数据库、修改数据库、查询数据库
(2)建立表、删除表、修改表、查询表
(3)新增表记录、删除表记录、修改表记录、查询表记录
提示:SQL是一个标准通用的操做关系型数据库的语言(普通话),每一个数据库厂商为了加强本身数据库的功能,都提供了支持本身数据库的语言,称之为数据库的方言。方言不通用!并发

索引

索引就是一个数据结构,咱们把表中的记录用一个适合高效查找的数据结构来表示,目的就是让查询变得更高效。
mysql中使用最普遍的数据引擎实际上是B+树索引,原理详解推荐博客:mysql提高查询效率的神器索引

查看一个表中是否已经建立索引
show index from 表名;
建立索引
create index 索引名 on 数据表(字段名称长度)
删除索引
drop index 索引名称 on 数据表

表关系

常见的表关系分为如下三种:
一对多(多对一)、一对1、多对多
image
image
image

三大范式

目前关系数据库有六种范式:第一范式(1NF)、第二范式(2NF)、第三范式(3NF)、巴斯-科德范式(BCNF)、第四范式(4NF)和第五范式(5NF,又称完美范式)。
而一般咱们用的最多的就是第一范式(1NF)、第二范式(2NF)、第三范式(3NF),也就是通俗的数据库“三大范式”。

第一范式(1NF):要求数据库表的每一列都是不可分割的原子数据项。

举例说明:

在上面的表中,“家庭信息”和“学校信息”列均不知足原子性的要求,故不知足第一范式,调整以下:

可见,调整后的每一列都是不可再分的,所以知足第一范式(1NF);

第二范式(2NF):在1NF的基础上,非码属性必须彻底依赖于候选码(在1NF基础上消除非主属性对主码的部分函数依赖)

第二范式须要确保数据库表中的每一列都和主键相关,而不能只与主键的某一部分相关(主要针对联合主键而言)。
举例说明:

在上图所示的状况中,同一个订单中可能包含不一样的产品,所以主键必须是“订单号”和“产品号”联合组成,
但能够发现,产品数量、产品折扣、产品价格与“订单号”和“产品号”都相关,可是订单金额和订单时间仅与“订单号”相关,与“产品号”无关,
这样就不知足第二范式的要求,调整以下,需分红两个表:
   

第三范式(3NF):在2NF基础上,任何非主属性不依赖于其它非主属性(在2NF基础上消除传递依赖)

第三范式须要确保数据表中的每一列数据都和主键直接相关,而不能间接相关。
举例说明:

上表中,全部属性都彻底依赖于学号,因此知足第二范式,可是“班主任性别”和“班主任年龄”直接依赖的是“班主任姓名”,
而不是主键“学号”,因此需作以下调整:
  
这样以来,就知足了第三范式的要求。

ps:若是把上表中的班主任姓名改为班主任教工号可能更确切,更符合实际状况,不过只要能理解就行。

数据库操做

建立、删除、查看数据库

SHOW DATABASES; -- 查看当前数据库服务器中的全部库
CREATE DATABASE mydb1; -- 建立mydb1库
show databases; -- 查询服务器全部的数据库
show tables; -- 查询当前库全部表
use mysql; -- 进入到‘mysql’数据库
show tables; -- 查询当前库中的全部表
select database();-- 查看已进入的库

-- 先进入某一个库,再查看当前库中的全部表
use test;
show tables;

drop database mydb1; -- 删除mydb1库,但若是删除的库不存在,则会报错
drop database if exists mydb1;-- 若是mydb1库存在则删除,若是不存在,也就不执行删除操做!
create database mydb1 charset utf8;--从新建立mydb1库,指定编码为utf8
create database if not exists mydb1 charset utf8;-- 若是不存在则建立mydb1;
show create database mydb1;--查看建库时的语句

建立、删除、查看表

use mydb1; -- 进入mydb1库
drop table if exists stu;-- 若是存在stu表,则删除
desc stu;--查看stu学生表结构


-- 若是存在,则删除stu表
drop table if exists stu;
-- 建立stu学生表
create table stu(
id int primary key auto_increment, -- 给id添加主键约束,并设置自增
name varchar(50),
gender varchar(10) not null, -- 给gender添加非空约束
birthday date,
score double
);

新增、更新、删除表记录

-- 若是是在cmd中执行插入记录的语句,先 set names gbk; 再插入记录!
-- 因为id已经设置了主键自增,因此在插入数据,id能够不用给值
insert into stu(id,name,gender,birthday,score) value
(null,'tom','male','2000-3-4',89);
insert into stu value(null,'john','male','2002-5-6',78);
insert into stu value(null,'andy','female','2004-7-6',91);

select * from stu;-- 查询学生表中的全部记录
update stu set score=score+10;--修改stu表中全部学生的成绩,加10分特长分
update stu set score=83 where id=1;-- 修改stu表中编号为1的学生成绩,将成绩改成83分。
update stu set score=99,gender='male' where id=3;-- 修改3号学生的性别为 'male',成绩改成99;
delete from stu; -- 删除stu表中的全部记录
delete from stu where id>2; -- 删除stu表中id大于2的记录

查询表记录

select name,sal,bonus from emp;-- 查询emp表中的全部员工,显示姓名,薪资,奖金
select dept,job from emp;-- 查询emp表中的全部部门和职位
select distinct dept,job from e;--在select以后、列名以前,使用DISTINCT 剔除重复的记录

WHERE子句查询

WHERE子句查询语法:SELECT 列名称 | * FROM 表名称 WHERE 列 运算符 值
WHERE子句后面跟的是条件,条件能够有多个,多个条件之间用链接词(or | and)进行链接
下面的运算符可在 WHERE 子句中使用:
image

--查询emp表中【薪资大于3000】的全部员工,显示员工姓名、薪资
select name,sal from emp where sal>3000;
--查询emp表中【总薪资(薪资+奖金)大于3500】的全部员工,显示员工姓名、总薪资
select name,sal+bonus from emp
where sal+bonus > 3500;
--查询emp表中【薪资在3000和4500之间】的员工,显示员工姓名和薪资
select name, sal from emp
where sal>=3000 and sal<=4500;
--查询emp表中【薪资为 1400、1600、1800】的员工,显示员工姓名和薪资
select name,sal from emp
where sal=1400 or sal=1600 or sal=1800;

模糊查询

LIKE 操做符用于在 WHERE 子句中搜索列中的指定模式。
能够和通配符(%、_)配合使用,其中 "%"表示0或多个任意的字符 , "_"表示一个任意的字符 。
语法:SELECT 列 | * FROM 表名 WHERE 列名 LIKE 值

-- 查询emp表中姓名中以"刘"字开头的员工,显示员工姓名。
select name from emp where name like '刘%';
-- 查询emp表中姓名中包含"涛"字的员工,显示员工姓名。
select name from emp where name like '%涛%';
--查询emp表中姓名以"刘"开头,而且姓名为两个字的员工,显示员工姓名。
select name from emp where name like '刘_';
select name from emp where name like '刘__';

多行函数查询

多行函数也叫作聚合(汇集)函数,根据某一列或全部列进行统计
image
提示:
(1)多行函数不能用在where子句中
(2)多行函数和是否分组有关,分组与否会直接影响多行函数的执行结果。
(3)多行函数在统计时会对null值进行过滤,直接将null值丢弃,不参与统计。

--统计emp表中薪资大于3000的员工个数
select count(*) from emp where sal>3000; -- 7
select count(id) from emp where sal>3000; -- 7
--求emp表中的最高薪资
select max(sal) from emp; -- 返回最高薪资,5000
--统计emp表中全部员工的薪资总和(不包含奖金)
select sum(sal) from emp; -- 薪资总和:39650
select sum(bonus) from emp; -- 奖金总和:5900,多行函数对null会处理,直接丢弃,不参与统计
--统计emp表员工的平均薪资(不包含奖金)
select avg(sal) from emp; -- 39650/12
--统计emp表中的人数
select count(*) from emp; -- 12

分组查询

GROUP BY 语句根据一个或多个列对结果集进行分组。
在分组的列上咱们可使用 COUNT,SUM,AVG,MAX,MIN等函数。
语法:SELECT 列 | * FROM 表名 [WHERE子句] GROUP BY 列;

-- 根据部门对员工进行分组
select name,dept from emp group by dept;
-- 统计分组后,每组的人数
select count(*) from emp group by dept; -- 3个组,因此会统计出三个结果
-- 根据job进行分组,统计每一个组的人数(每一个职位的人数)
select job,count(*) from emp group by job;
-- 若是不分组,直接使用max(sal),这是统计整个emp表中的最高薪资
select max(sal) from emp; -- 5000;
-- 若是根据部门分组,能够分为三个组,再使用max(sal),就是统计每一个组的最高薪资
select dept, max(sal) from emp group by dept;

提示:
分组查询中若是有条件判断须要把关键字WHERE换成HAVING

排序查询

使用 ORDER BY 子句将结果集中记录根据指定的列排序后再返回
语法:SELECT 列名 FROM 表名 ORDER BY 列名 [ASC|DESC]

--对emp表中全部员工的薪资进行升序(从低到高)排序,显示员工姓名、薪资。
select name,sal from emp order by sal asc;
-- 默认是升序,asc能够省略
select name,sal from emp order by sal;
--对emp表中全部员工的奖金进行降序(从高到低)排序,显示员工姓名、奖金。
select name,bonus from emp order by bonus desc;

分页查询

在mysql中,经过limit进行分页查询,查询公式为:
limit (页码-1)*每页显示记录数, 每页显示记录数

-- 每页显示3条,查询第1页数据
select * from emp limit 0,3;
-- 每页显示3条,查询第2页数据
select * from emp limit 3,3;
-- 每页显示3条,查询第3页数据
select * from emp limit 6,3;
-- 每页显示3条,查询第4页数据
select * from emp limit 9,3;
-- 先根据薪资降序(从高到低)排序
select name,sal from emp order by sal desc;
-- 在排序的基础上,分页查询,每页显示3条,只查询第1页
select name,sal from emp order by sal desc limit 0,3;

其余函数

image

多表查询

链接查询

笛卡尔积查询:所谓笛卡尔积查询就是指,查询两张表,其中一张表有m条记录,另外一张表有n条记录,查询的结果是m*n条。
虽然笛卡尔积查询中包含大量错误数据,但咱们能够经过where子句将错误数据剔除,保留下来的就是正确数据。

-- 查询部门和部门对应的员工信息,员工所属的部门编号,等于部门的编号
select * from dept,emp
where emp.dept_id=dept.id;

左外链接查询

能够将左边表中的全部记录都查询出来,右边表只显示和左边相对应的数据,若是左边表中某些记录在右边没有对应的数据,右边显示为null便可。

--查询【全部部门】及部门对应的员工,若是某个部门下没有员工,员工显示为null
select * from dept left join emp
on emp.dept_id=dept.id;

右外链接查询

能够将右边表中的全部记录都查询出来,左边表只显示和右边相对应的数据,若是右边表中某些记录在左边没有对应的数据,能够显示为null。

--查询【全部员工】及员工所属的部门,若是某个员工没有所属部门,部门显示为null便可
select * from dept right join emp
on emp.dept_id=dept.id;

全外链接查询

若是想将两张表中的全部数据都查询出来(左外+右外并去除重复记录),可使用全外链接查询,可是mysql又不支持全外链接查询。可使用union将左外链接查询的结果和右外链接查询的结果合并在一块儿,并去除重复的记录。

select * from dept left join emp on emp.dept_id=dept.id
union
select * from dept right join emp on emp.dept_id=dept.id;

扩展

内链接:inner join
自链接:self (本质仍是内链接)

视图

视图是一个虚拟表,其内容由查询定义。同真实的表同样,视图包含一系列带有名称的列和行数据。可是,数据库中只存放了视图的定义,而并无存放视图中的数据,这些数据存放在原来的表中。使用视图查询数据时,数据库系统会从原来的表中取出对应的数据。所以,视图中的数据是依赖于原来的表中的数据的。一旦表中的数据发生改变,显示在视图中的数据也会发生改变。一样对视图的更新,会影响到原来表的数据。

视图是存储在数据库中的查询的SQL语句,它主要出于两种缘由:安全缘由,视图能够隐藏一些数据,例如,员工信息表,能够用视图只显示姓名、工龄、地址,而不显示社会保险号和工资数等;另外一个缘由是可以使复杂的查询易于理解和使用。这个视图就像一个“窗口”,从中只能看到你想看的数据列。这意味着你能够在这个视图上使用SELECT *,而你看到的将是你在视图定义里给出的那些数据列。

做用

视图是在原有表或者视图的基础上从新定义的虚拟表,这能够从原有的表上选取对用户有用的信息,忽略次要信息,其做用相似于筛选。视图的做用概括为以下几点:
1. 使操做简单化
视图须要达到的目的就是所见即所需。视图不只能够简化用户对数据的理解,也能够简化他们的操做。那些被常用的查询能够被定义为视图,从而使得用户没必要为之后的操做每次指定所有的条件。
2.增长数据的安全性
经过视图,用户只能查询和修改指定的数据。指定数据以外的信息,用户根本接触不到。这样能够防止敏感信息被未受权的用户查看,加强机密信息的安全性。
3.提升表的逻辑独立性
视图能够屏蔽原有表结构变化带来的影响。例如原有表增长列和删除未被引用的列,对视图不会形成影响。一样,若是修改表中的某些列,可使用修改视图来解决这些列带来的影响。

事务(ACID)

原子性(Atomicity):事务中的全部操做做为一个总体像原子同样不可分割,要么所有成功,要么所有失败。
一致性(Consistency):事务的执行结果必须使数据库从一个一致性状态到另外一个一致性状态。一致性状态是指:1.系统的状态知足数据的完整性约束(主码,参照完整性,check约束等) 2.系统的状态反应数据库本应描述的现实世界的真实状态,好比转帐先后两个帐户的金额总和应该保持不变。
隔离性(Isolation):并发执行的事务不会相互影响,其对数据库的影响和它们串行执行时同样。好比多个用户同时往一个帐户转帐,最后帐户的结果应该和他们按前后次序转帐的结果同样。
持久性(Durability):事务一旦提交,其对数据库的更新就是持久的。任何事务或系统故障都不会致使数据丢失。

数据库对象的概念

表格

数据库中的表与咱们平常生活中使用的表格相似,它也是由行(Row) 和列(Column)组成的。列由同类的信息组成,每列又称为一个字段,每列的标题称为字段名。行包括了若干列信息项。一行数据称为一个或一条记录,它表达有必定意义的信息组合。一个数据库表由一条或多条记录组成,没有记录的表称为空表。每一个表中一般都有一个主关键字,用于惟一地肯定一条记录。

索引

索引是根据指定的数据库表列创建起来的顺序。它提供了快速访问数据的途径,而且可监督表的数据,使其索引所指向的列中的数据不重复。如聚簇索引。

视图

视图看上去同表彷佛如出一辙,具备一组命名的字段和数据项,但它实际上是一个虚拟的表,在数据库中并不实际存在。视图是由查询数据库表产生的,它限制了用户能看到和修改的数据。因而可知,视图能够用来控制用户对数据的访问,并能简化数据的显示,即经过视图只显示那些须要的数据信息。

图表

图表其实就是数据库表之间的关系示意图。利用它能够编辑表与表之间的关系。

缺省值

缺省值是当在表中建立列或插入数据时,对没有指定其具体值的列或列数据项赋予事先设定好的值。

规则

规则是对数据库表中数据信息的限制。它限定的是表的列。

触发器

触发器由事件来触发,能够查询其余表,并且能够包含复杂的SQL语句。它们主要用于强制服从复杂的业务规则或要求。也可用于强制引用完整性,以便在多个表中添加、更新或删除行时,保留在这些表之间所定义的关系。

用户

所谓用户就是有权限访问数据库的人。
同时须要本身登录帐号和密码。用户分为:管理员用户和普通用户。前者可对数据库进行修改删除,后者只能进行阅读查看等操做。

序列

序列定义存储在数据字典中,序列经过提供惟一数值的顺序表用于简化程序设计工做。

函数

函数与过程很相似,通常用于计算数据,声明为FUNCTION,须要描述返回类型,且PL/SQL块中至少有一个有效的RETURN语句;函数不能独立运行,必须做为表达式的一部分;在DML和DQL中可调用函数。
函数的目标是返回一个值。大多数函数都返回一个标量值(scalar value),标量值表明一个数据单元或一个简单值。实际上,函数能够返回任何数据类型,包括表、游标等可返回完整的多行结果集的类型。

SQL代码执行过程

(9) SELECT (10)DISTINCT column,...           选择,去重
(6) AGG_FUNC(column or expression),...       聚合
(1) FROM [left_table]                        from后面表
(3) <join_type> JOIN <right_table>           join后面表
(2) ON <join_condition>                      经过关联条件
(4) WHERE <where_condition>                  过滤数据
(5) GROUP BY <group_by_list>                 分组
(7) WITH <CUBE | RollUP>            
(8) HAVING <having_condition>                分组后的过滤,相似where
(11)ORDER BY <order_by_list>                 排序
(12)LIMIT count OFFSET count;                分页

存储过程

一,什么是数据库存储过程?
存储过程(Stored Procedure)是一种在数据库中存储复杂程序,以便外部程序调用的一种数据库对象。
存储过程是为了完成特定功能的SQL语句集,经编译建立并保存在数据库中,用户可经过指定存储过程的名字并给定参数(须要时)来调用执行。
存储过程思想上很简单,就是数据库 SQL 语言层面的代码封装与重用。
二,为何要使用存储过程?

优势
  • 存储过程可封装,并隐藏复杂的商业逻辑。
  • 存储过程能够回传值,并能够接受参数。
  • 存储过程没法使用 SELECT 指令来运行,由于它是子程序,与查看表,数据表或用户定义函数不一样。
  • 存储过程能够用在数据检验,强制实行商业逻辑等。
缺点
  • 存储过程,每每定制化于特定的数据库上,由于支持的编程语言不一样。当切换到其余厂商的数据库系统时,须要重写原有的存储过程。
  • 存储过程的性能调校与撰写,受限于各类数据库系统。

三,存储过程的分类
(1)数据库系统存储过程:数据库自带
(2)用户自定义数据库存储过程:由用户根据须要自定义
四,MySql数据库存储过程
建立存储过程:

create procedure 存储过程名字() begin SQL语句/逻辑 end;

调用存储过程:

call 存储过程名字();
call 存储过程名字(@参数1,@参数2,@参数3,...);

删除存储过程:

drop procedure if exists 存储过程名字; - -这里存储过程名字后面没有()

五,举个例子

1.建立数据库:

create database test;

2.使用数据库:

use test;

3.建立数据表student:

create table student( id int not null comment '学生id', name varchar(30) comment '学生姓名', chinese int(3) comment '语文成绩', math int(3) comment '数学成绩', enginsh int(3) comment '英语成绩', count int(3) comment '总成绩', primary key(id) )Engine=InnoDB default charset=utf8 comment '学生成绩表';

4 数据表的数据为:
图片描述

5.建立带参数的存储过程:

create procedure mm( out min int, out max int, out avg decimal(8,2) ) begin select MIN(chinese) into min from student; select MAX(math) into max from student; select AVG(count) into avg from student; end;

图片描述
6.调用存储过程:

call mm(@min,@max,@avg);

该调用并无任何输出, 只是把调用的结果赋给了调用时传入的变量(@min, @avg, @max)。而后便可调用显示该变量的值。
图片描述

7.调用显示存储过程的值:

select @min,@max,@avg;

8.使用in参数, 输入一个学生id, 返回该学生的总成绩
存储过程代码:

create procedure getTotal( in id int, out total decimal(8,2) ) begin select SUM(s.count) from student s where s.id = id into total; end;

9.调用存储过程:

call getTotal(2, @total); select @total;

图片描述

至此就是一个简单的MySql数据库存储过程。

相关文章
相关标签/搜索