Mysql入门

Mysql 入门

0. 前言

学习目标:

  1. 安装数据库,以 Windows OS 的Mysql 为例;
  2. 了解数据库的一些基本概念;
  3. SQL语句的学习与练习;
  4. 了解事务、索引、SQL优化。

1. 准备工作

正式学习之前,我们要了解数据库的一些相关概念、将学习过程中所需的Mysql 准备好。

1.1 相关概念

名称作用
数据库DataBase(DB)存储数据的仓库,数据是有组织的进行存储
数据库管理系统DataBase Management System(DBMS)操纵和管理数据库的大型软件
结构化查询语言Structured Query Language(SQL)操作关系型数据库的编程语言,定义了一套操作关系型数据库的同一标准

数据库的种类:
层次式数据库(已过时)、网络型数据库(已过时)、关系型数据库、非关系型数据库;

常见的数据库:
SQL Server、MySQL、Oracle、DB2、Sqlite、redis(非关系型数据库)、mongodb(非关系型数据库)

Mysql是关系型数据库,本文我们侧重学习Mysql。

推荐教材:《数据库系统概论》

1.2 Mysql 安装与启动

(1)下载与安装:

下载:下载地址

安装:安装教程,转载自博客园

(2)启动:

安装完毕后,我们可以在 windows 的 dos 窗口启动Mysql、连接客户端

	net start mysql

(3)连接客户端

	mysql [-h 127.0.0.1] [-P 3306] -uroot -p
参数:
	-h:mysql服务所在的主机IP
	-P:mysql服务端口号,默认是3306
	-u:mysql数据库用户名,一般为约定俗成的root
	-p:mysql数据库用户名对应的密码
注意:[]内的参数是可选的,如果需要连接远程的mysql,就需要提供主机IP和端口号,如果是连接本地的mysql,就不用提供这两个参数;注意大小写。

1.3 常用工具

我们常用一些可视化工具来辅助我们操作数据库。对于mysql,此处推荐: navicat,sqlyog等。

下载地址:
navicat:navicat官网
sqlyog: sqlyog官网

2. Mysql 入门

2.1 数据模型

在上一个小节我们提到过,Mysql是一种关系型数据库(Relational Database Management System,RDBMS),是建立在关系模型基础上,由多张相互连接的二维表组成的数据库。

二维表:类似于excel,由行和列组成的表。

2.2 SQL语言分类

我们使用SQL来操作数据库。SQL分为5类:

语言作用关键词举例
DDL(Data Definition Language)数据定义语言定义数据,如创建表、修改表字段等CREATE,ALTER,DROP
DQL(Data Query Language)数据查询语言查询数据SELECT
DML(Data Manipulation Language)数据操纵语言操作数据,增删改等INSERT,UPDATE,DELETE
DTL(Data Transaction Language) 事务控制语言事务提交与回滚COMMIT,ROLLBACK
DCL(Data Control Language)数据控制语言权限授予与回收GRANT,REVOKE

此阶段我们重点学习DDL、DQL与DML。

2.3 Mysql数据类型

Mysql支持的数据类型从大类可以分为以下几类:数值类型、字符串类型、日期、其他数据类型。

类别常见类型
数值类型int, tinyint, smallint, bigint, float, double, bool 等
字符串类型varchar, char, text 等
日期date, time, datetime, year 等
其他set, point 等

现阶段我们应学习常见的数值、字符串、日期类型,至于其他类型,可以在实际业务中用到时再去学习或研究。

2.4 DDL数据库操作

在了解了上面的SQL语言分类、数据类型之后,我们就可以学习并使用这些SQL语句了。

Mysql 既是一个DB,也是一个DBMS。所以当我们连接了Mysql客户端后,可以进行数据库操作。

  1. 查询所有数据库:
show databases;
  1. 创建数据库:
create database [ if not exists ] 数据库名 [ default charset 字符集 ] [ collate 排序规则 ];
  1. 删除数据库:
drop database [ if exists ] 数据库名;
  1. 切换数据库:
use 数据库名;

2.5 DDL表操作

当我们切换至某个数据库后,可以在这个数据库内进行表操作。

  1. 查询当前数据库所有表
show TABLES;
  1. 查看指定表结构
desc 表名;
  1. 查询指定表的建表语句
show create table 表名;
  1. 创建表结构
create table 表名(
	字段1 字段类型 [ COMMENT 注释1 ],
    字段2 字段类型 [ COMMENT 注释2 ],
    字段3 字段类型 [ COMMENT 注释3 ],
    .......
    字段N 字段类型 [ COMMENT 注释N ],
) [ COMMENT 表注释 ];
  1. 添加表字段
ALTER TABLE 表名 ADD 字段名 数据类型(长度) [COMMENT 注释] [ 约束 ];
  1. 修改字段数据类型
ALTER TABLE 表名 MODIFY 字段名 新数据类型(长度);
  1. 修改字段名和字段类型
ALTER TABLE 表名 CHANGE 旧字段名 新字段名 数据类型(长度) [COMMENT 注释] [ 约束 ];
  1. 删除字段
ALTER TABLE 表名 DROP 字段名;
  1. 修改表名
ALTER TABLE 表名 RENAME TO 新表名;
  1. 删除表
DROP TABLE [ IF EXISTS ] 表名;
  1. 删除并重新创建表
TRUNCATE TABLE 表名;

2.6 DML 数据操作

  1. 添加数据

    // 指定字段名
    INSERT INTO 表名(字段1,字段2,....) VALUES(1,2,....);
    // 不指定字段名,值列表的顺序必须与字段的顺序一致
    INSERT INTO 表名 VALUES(1,2,....);
    // 批量添加数据
    INSERT INTO 表名(字段1,字段2,....) VALUES(1,2,....),(1,2,....),(1,2,....);
    
  2. 修改数据

    UPDATE 表名 SET 字段1=1,字段2=2,..... [ WHERE 条件 ];
    
  3. 删除数据

    DELETE FROM 表名 [ WHERE 条件 ];
    

2.7 DQL 数据查询

基本语法:

SELECT
	字段列表
FROM
	表名列表
WHERE
	条件列表
GROUP BY
	分组字段列表
HAVING
	分组后条件列表
ORDER BY
	排序字段列表
LIMIT
	分页参数
  • 基础查询(不带任何条件)
  • 条件查询(WHERE)
  • 聚合函数(count、max、min、avg、sum)
  • 分组查询(GROUP BY)
  • 排序查询(ORDER BY):排序规则 DESC(降序) || ASC (升序,默认)
  • 分页查询(LIMIT):参数 (index,pageSize)index:记录的索引,从0开始,pageSize:每次查询多少条记录

2.8 综合练习

学习完上述语句后,我们来做一组综合练习来巩固一下:

  1. 准备数据库表:

    DROP DATABASE IF EXISTS test1;
    CREATE DATABASE test1;
    USE test1;
    ##部门表
    #DROP IF EXISTS TABLE DEPT;
    CREATE TABLE DEPT(
    DEPTNO int PRIMARY KEY,##部门编号
    DNAME VARCHAR(14) , ##部门名称
    LOC VARCHAR(13) ##部门地址
    ) ;
    INSERT INTO DEPT VALUES (10,'ACCOUNTING','NEW YORK');
    INSERT INTO DEPT VALUES (20,'RESEARCH','DALLAS');
    INSERT INTO DEPT VALUES (30,'SALES','CHICAGO');
    INSERT INTO DEPT VALUES (40,'OPERATIONS','BOSTON');
    ##员工表
    #DROP IF EXISTS TABLE EMP;
    CREATE TABLE EMP(
    EMPNO int PRIMARY KEY, #员工编号
    ENAME VARCHAR(10), #员工姓名
    JOB VARCHAR(9), #员工工作
    MGR int, #员工直属领导编号
    HIREDATE DATE, #入职时间
    SAL double, #工资
    COMM double, #奖金
    DEPTNO int #对应dept表的外键
    );
    ## 添加 部门 和 员工 之间的主外键关系
    
    INSERT INTO EMP VALUES(7369,'SMITH','CLERK',7902,"1980-12-17",800,NULL,20);
    INSERT INTO EMP VALUES(7499,'ALLEN','SALESMAN',7698,'1981-02-20',1600,300,30);
    INSERT INTO EMP VALUES(7521,'WARD','SALESMAN',7698,'1981-02-22',1250,500,30);
    INSERT INTO EMP VALUES(7566,'JONES','MANAGER',7839,'1981-04-02',2975,NULL,20);
    INSERT INTO EMP VALUES(7654,'MARTIN','SALESMAN',7698,'1981-09-28',1250,1400,30);
    INSERT INTO EMP VALUES(7698,'BLAKE','MANAGER',7839,'1981-05-01',2850,NULL,30);
    INSERT INTO EMP VALUES(7782,'CLARK','MANAGER',7839,'1981-06-09',2450,NULL,10);
    INSERT INTO EMP VALUES(7788,'SCOTT','ANALYST',7566,'1987-07-03',3000,NULL,20);
    INSERT INTO EMP VALUES(7839,'KING','PRESIDENT',NULL,'1981-11-17',5000,NULL,10);
    INSERT INTO EMP VALUES(7844,'TURNER','SALESMAN',7698,'1981-09-08',1500,0,30);
    INSERT INTO EMP VALUES(7876,'ADAMS','CLERK',7788,'1987-07-13',1100,NULL,20);
    INSERT INTO EMP VALUES(7900,'JAMES','CLERK',7698,'1981-12-03',950,NULL,30);
    INSERT INTO EMP VALUES(7902,'FORD','ANALYST',7566,'1981-12-03',3000,NULL,20);
    INSERT INTO EMP VALUES(7934,'MILLER','CLERK',7782,'1981-01-23',1300,NULL,10);
    #工资等级表
    #DROP IF EXISTS TABLE SALGRADE;
    CREATE TABLE SALGRADE(
    GRADE int, #等级
    LOSAL double, #最低工资
    HISAL double ); #最高工资
    INSERT INTO SALGRADE VALUES (1,700,1200);
    INSERT INTO SALGRADE VALUES (2,1201,1400);
    INSERT INTO SALGRADE VALUES (3,1401,2000);
    INSERT INTO SALGRADE VALUES (4,2001,3000);
    INSERT INTO SALGRADE VALUES (5,3001,9999);
    
  2. 题目:

    #1、查找部门30中员工的详细信息。
    
    #2、找出从事clerk工作的员工的编号、姓名、部门号。
    
    #3、检索出奖金多于基本工资的员工信息。
    
    #4、检索出奖金多于基本工资60%的员工信息。
    
    #5、找出10部门的经理、20部门的职员 的员工信息。
    
    #6、找出10部门的经理、20部门的职员 或者既不是经理也不是职员但是工资高于2000元的员工信息。
    
    #7、找出获得奖金的员工的工作。
    
    #8、找出奖金少于100或者没有获得奖金的员工的信息。
    
    #9、找出姓名以A、B、S开始的员工信息。
    
    #10、找到名字长度为6个字符的员工信息。
    
    #11、名字中不包含R字符的员工信息。
    
    #12、返回员工的详细信息并按姓名排序。
    
    #13、返回员工的信息并按工作降序工资升序排列。
    
    #14、计算员工的日薪(按30天)。
    
    #15、找出姓名中包含A的员工信息。
    
    多表查询
    
    #1、返回拥有员工的部门名、部门号。
    
    #2、工资水平多于smith的员工信息。
    
    #3、返回员工和所属经理的姓名。
    
    #4、返回雇员的雇佣日期早于其经理雇佣日期的员工及其经理姓名。
    
    #5、返回员工姓名及其所在的部门名称。
    
    #6、返回从事clerk工作的员工姓名和所在部门名称。
    
    #7、返回部门号及其本部门的最低工资。
    
    #8、返回销售部(sales)所有员工的姓名。
    
    #9、返回工资水平多于平均工资的员工。
    
    #10、返回与SCOTT从事相同工作的员工。
    
    #11、返回与30部门员工工资水平相同的员工姓名与工资。
    
    #12、返回工资高于30部门所有员工工资水平的员工信息。
    
    #13、返回部门号、部门名、部门所在位置及其每个部门的员工总数。
    
    #14、返回员工的姓名、所在部门名及其工资。
    
    #15、返回员工的详细信息。(包括部门名)
    
    #16、返回员工工作及其从事此工作的最低工资。
    
    #17、计算出员工的年薪,并且以年薪排序。
    
    #18、返回工资处于第四级别的员工的姓名。
    
    #19、返回工资为二等级的职员名字、部门所在地、和二等级的最低工资和最高工资
    
    #20.工资等级多于smith的员工信息。
    

3. 事务

3.1 事务的简介

事务:是一组操作的集合,它是一个不可分割的工作单元,事务会把所有的操作作为一个整体一起向系统提交或撤销操作请求,即这些操作要么同时成功,要么同时失败。

3.2 事务的特性:ACID

原子性(Atomicity):事务是不可分割的最小操作单元,要么全部成功,要么全部失败。

一致性(Consistency):事务完成时,必须使所有的数据都保持一致状态。

隔离性(Isolation):数据库系统提供的隔离机制,保证事务在不受外部并发操作影响的独立环境下运行。

持久性(Durability):事务一旦提交或回滚,它对数据库中的数据的改变是永久的。

3.3 并发事务问题

  1. 脏读:一个事务读到另一个事务还没有提交的数据。
  2. 不可重复读:一个事务先后读取同一条记录,但两次读取的数据不相同,称之为不可重复读。
  3. 幻读:一个事务按照条件查询数据时,没有对应的数据行,但是在插入数据时,又发现这行数据已经存在,好像出现了“幻觉”。

3.4 事务的隔离级别

为了解决并发事务所引发的问题,在数据库中引入了事务隔离级别。主要有以下四种:

隔离级别脏读不可重复读幻读
读未提交(Read uncommitted)
读已提交(Read committed)×
可重复读(Repeatable Read)××
串行化(Serializable)×××

MySQL数据库的默认事务隔离级别为:可重复读(Repeatable Read)

// 查看事务隔离级别
SELECT @@transaction_isolation;

注意:事务隔离级别越高,数据越安全,但是性能越低

4. 索引

索引是一个单独的,存储在磁盘上的数据库结构,包含着对数据表里所有记录的引用指针。

MySQL中索引的存储类型有两种:BTree和Hash

索引是在存储引擎中实现的。(InnoDB、MyISAM、Memory、Heap)

InnoDB/MyISAM只支持 BTree 索引

Memory/Heap 支持 BTree 和 Hash 索引

索引的优缺点:

优点:

  • 提高数据的查询效率(类似于书的目录)
  • 可以保证数据库表中每一行数据的唯一性(唯一索引)
  • 减少分组和排序的时间(当使用分组和排序进行数据查询时)
    • 被索引的列会自动进行分组和排序

缺点:

  • 占用磁盘空间
  • 降低更新表的效率(不仅要更新表中的数据,还要更新相应的索引文件)

4.1 索引的分类

  1. 普通索引和唯一索引
  • 普通索引:是MySQL中的基本索引类型,允许在定义索引的列中插入重复值和空值
  • 唯一索引:要求索引列的值必须唯一,但允许有空值
    • 如果是组合索引,则列值的组合必须唯一
    • 主键索引是一种特殊的唯一索引,不允许有空值
  1. 单列索引和组合索引
  • 单列索引:一个索引只包含单个列,一个表可以有多个单列索引

  • 组合索引:在表的多个字段组合上创建的索引

    • 只有在查询条件中使用了这些字段的左边字段时,索引才会被使用(最左前缀原则)

    例如:表中有 gender,stuno,stuname,age,tel,… 字段,将stuno和stuname作为组合索引,在查询条件中如果使用了stuno字段,组合索引就会被使用。

  1. 全文索引
  • 全文索引的类型为 fulltext
  • 在定义索引的列上支持 值的全文查找,允许在这些索引列中插入重复值和空值
  • 全文索引可以在 char、varchar 和 text 类型的列上创建
  1. 空间索引
  • 空间索引是对空间数据类型的字段建立的索引
  • MySQL中的空间数据类型有4种,分别是 Geometry、Point、Linestring和 Polygon
  • MySQL 使用 Spatial关键字进行扩展,使得能够用创建正规索引类似的语法创建空间索引
  • 创建空间索引的列,不允许为空值,且只能在 MyISAM 的表中创建
  1. 前缀索引
  • 在char、varchar和text类型的列上创建索引时,可以指定索引列的长度

4.2 MySQL索引的使用

  1. 索引的基本语法

定义主键约束、外键约束、唯一约束 等约束时,相当于同时在指定的列上创建了一个索引

  1. 判断是否要添加索引

加索引:

  • 数据本身具有某种性质,例如:唯一性,非空性…
  • 要频繁进行分组或排序的列,例如:经常要按类别、价格、销量等字段排序
  • 如果待排序的列有多个,可以建立组合索引

不加索引:

  • 经常更新的列
  • 列的值类型很少,例如:性别字段
  • where条件中用不到的列(很少使用该列作为查询条件)
  • 参与计算的列
  • 数据量小的表
  1. 只要创建了索引,就一定会生效吗?

不一定,当使用组合索引时,如果没有遵循最左匹配原则,索引不生效

例如:创建 id、name、age 组合索引

  • id、(id、name)、(id、name、age)查询,索引生效
  • age、(age、name)查询,索引不生效
  1. 怎样判断索引是否生效?

使用 explain 关键字

  • possible_keys:MySQL在搜索数据记录时可选用的各个索引
  • key:MySQL实际选用的索引
  1. 怎么避免索引失效?
  • 使用组合索引时,遵循最左匹配原则
  • 不在索引列上进行任何操作,操作有:计算、函数、类型转换
  • 尽量使用覆盖索引
  • 索引列尽量不使用 不等于条件,通配符开头的模糊查询
  • 字符串加单引号(不加可能会发生索引列的隐式转换,导致索引失效)

5. MySQL性能优化

记得比较零散:

选择最合适的字段属性,因为MySQL是一种关系型数据库,可以很好地支持大数据量的存储,一般来说,表越小,查询越快,所以在创建表的时候,字段的宽度尽可能小;

尽量把字段设置为非空(not null),在执行数据库查询时,不用去比较null值;

对于某些文本字段来说,例如省份或者性别,可以将它们定义为枚举(enum)类型,该类型会被当做数值类型来处理,比文本类型的处理速度要快;

使用连接(join)来代替子查询,使用连接不需要在内存中创建临时表,如果你的应用程序有很多join查询,你应该确认被连接的两个表的字段上是有索引的,这样存储引擎再执行查询时会启动查询优化

当执行多表连接查询时,select * from a,b,返回的是笛卡尔乘积,不建议使用该写法,都使用join连接,当使用左连接时,left join 左边的表为主表,右边的表为从表,返回主表的所有记录,如果从表中没有对应的记录,则返回null,右连接反之;

不使用子查询;

避免函数索引,尽量不要在索引列上使用函数,如果使用函数或进行计算,会直接全表扫描;

使用in来替换or,select * from emp where id in(1,2,3)的性能要优于select * from emp where id=1 or id=2 or id=3;

like 双百分号无法使用到索引,select * from emp where name like ‘%章%’;

大偏移量的查询,如:select * from emp limit 90000000,10 其查询性能就不如:select * from emp where id > 90000000 limit 10,先过滤id(因为id使用了索引)再limit;

避免数据类型不一致;

分组统计可以禁止排序,默认情况下mysql对所有group by的字段进行排序,可以指定order by null 禁止排序;

连接配置优化:服务端配置提高,增加服务端可用连接数;客户端优化:程序连接数据库,使用第三方数据源连接池,比较好的阿里的druid,springboot内置的hikari;

连接池的设置的官方建议公式:cpu核心数*2+1,假设服务器的cpu核心数是8,将连接池设置为17就可以了;

架构优化:

  • 使用缓存
  • 读写分离(集群,主从复制)
  • 分库分表

不要使用外键,触发器和视图功能。降低了可读性,检查代码的同时还得查看数据库的代码;

把计算的工作交给程序,数据库只做好存储的工作,

数据的完整性校验工作交给开发人员完成,而不是依赖于外键关系;

图片、音频、视频的存储,不要直接存储大文件,而是存储大文件的访问地址;

大字段的拆分和数据冗余;

6. 总结

通过本文,我们初步学习了Mysql的基本概念、SQL语句,提供了一个练习题来练习。我们还学习了Mysql的索引、性能优化。

本文部分内容来自于一些参考资料与学习笔记(作者:Jack,Kevin),侵删。

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值