MySQL基础

1.数据库的操作

1)创建数据库

创建数据库

create database 数据库名;

如果数据库不存在,再创建表,否则不创建

create database if not exists 数据库名;

创建数据库的同时指定字符集编码

create databse 数据库名 character set utf-8;

2)查询数据库

查询所有的数据库名

show databases;

查询某个数据库的创建语句

show create database 数据库名;

3)修改数据库

修改数据库的字符集编码

alter database 数据库名 set character 字符集名;

4)删除数据库

直接删除数据集库

drop database 数据库名;

当数据库存在时再删除

drop database if exists 数据库名;

5)使用数据库

查看正在使用的数据库

select database();

使用数据库

use 数据库名; 

2.表的操作

1)创建表

create table 表名(
    列名1 数据类型1,
    列名2 数据类型2,
    ....
    列名n 数据类型n
);

注意:最后一列,不需要加逗号

复制表

create table 表名 like 被复制的表名

2)查询表信息

查询某个数据库的所有表

show tables;

查看表结构

desc 表名;

3)修改表和列

修改表名

alter table 表名 rename to 新表名

修改表的字符集

alter table  表名 set character 字符集名

添加一列

alter table 表名 add 列名 数据类型

修改列的数据类型

alter table 表名 modify 列名 新数据类型

修改列名和数据类型

alter table 表名 change 列名 新列名 新数据类型

删除列

alter table 表名 drop 列名

4)删除表

直接删除表

drop table 表名

如果表存在再删除

drop table if exists 表名

3.增删改表中数据

1)添加数据

insert into 表名(列名1,列名2,...列名n) values(值1,值2,...值n);

除了数字类型,其他类型需要使用引号(单双都可以)引起来

2)删除数据

delete from 表名 [where 条件]

*删除所有记录

delete from 表名;

不推荐使用。有多少条记录就会执行多少次删除操作

truncate table 表名;

推荐使用,效率更高 先删除表,然后再创建一张一样的表。

3)修改数据

update 表名 set 列名1 = 值1, 列名2 = 值2,... [where 条件];

如果不加任何条件,则会将表中所有记录全部修改

4.查询表中的记录

4.1总语法

select  字段列表
from  表名列表
where  条件列表
group by  分组字段
order by  排序
limit  分页限定

4.2基础查询

1)多个字段的查询

select 字段名1,字段名2... from 表名;

如果查询所有字段,则可以使用*来替代字段列表

select * from 表名;

2)去掉重复的结果集distinct

select distinct(列名) from 表名

例如:查询学生表中的学生都来自哪些地方,不要重复的

select distinct(address)  from student;

3)判断属性是否为空ifnull

select ifnull(列名,要替换的值) from 表名

例如:如果学生的成绩为null,就显示0而不显示null

select name,ifnull(score,0) from student;

4)起别名as(as可省略)

seelct 列名 as 别名 from 表名

例如:查询学生的名字,起别名是姓名

select name as 姓名 from student;

4.3条件查询

查询年龄大于20岁的学生

SELECT * FROM student WHERE age > 20;

查询年龄等于20岁的学生

SELECT * FROM student WHERE age = 20;

查询年龄不等于20岁的学生  

SELECT * FROM student WHERE age != 20;
SELECT * FROM student WHERE age <> 20;

查询年龄大于等于20 小于等于30的学生  

SELECT * FROM student WHERE age BETWEEN 20 AND 30;

查询年龄22岁,18岁,25岁的学生 

SELECT * FROM student WHERE age = 22 OR age = 18 OR age = 25
SELECT * FROM student WHERE age IN (22,18,25);

查询英语成绩为null的学生

SELECT * FROM student WHERE english IS NULL;

查询英语成绩不为null的学生

SELECT * FROM student WHERE english  IS NOT NULL;

查询姓马的有哪些?

SELECT * FROM student WHERE NAME LIKE '马%';

查询姓名第二个字是化的人  

SELECT * FROM student WHERE NAME LIKE "_化%";

查询姓名是3个字的人  

SELECT * FROM student WHERE NAME LIKE '___';

查询姓名中包含德的人  

SELECT * FROM student WHERE NAME LIKE '%德%';

4.4排序查询

order by 排序字段1 排序方式1 ,  排序字段2 排序方式2...

排序方式:ASC:升序,默认的;DESC:降序。

注意:如果有多个排序条件,则当前边的条件值一样时,才会判断第二条件

举例:

1)按照学生的数学成绩进行升序排序

select * from student order by math;

2)按照学生的数学成绩升序排序,如果数学成绩一样的则按英语成绩降序排序 

select * from student order by math,englisg desc;

4.5聚合函数

将一列数据作为一个整体,进行纵向的计算。

1. count:计算个数  

2. max:计算最大值

3. min:计算最小值

4. sum:计算和

5. avg:计算平均值

4.6分组查询

分组就是把相同特征的数据分为一组

group by 分组字段

注意:分组之后查询的字段要么是分组的字段,要么是聚合函数,其他的字段没有意义。

举例:

1)按照性别分组。分别查询男、女同学数学的平均分

SELECT sex , AVG(math) FROM student GROUP BY sex;

2)按照性别分组。分别查询男、女同学数学的平均分,人数  

SELECT sex , AVG(math),COUNT(id) FROM student GROUP BY sex;

3)按照性别分组。分别查询男、女同学数学的平均分,人数。要求:分数低于70分的人,不参与分组   

SELECT sex , AVG(math),COUNT(id) FROM student WHERE math > 70 GROUP BY sex;

4)按照性别分组。分别查询男、女同学数学的平均分,人数。要求:分数低于70分的人,不参与分组,分组之后,人数要大于2个人  

SELECT sex , AVG(math),COUNT(id) FROM student WHERE math > 70 GROUP BY sex HAVING COUNT(id) > 2;

4.7分页查询

limit 开始的索引,每页查询的条数

开始的索引 = (当前的页码 - 1) * 每页显示的条数

举例:

1)查询第一页数据,每页显示5条数据

SELECT * FROM student LIMIT 0,5;

2)查询第三页数据,每页显示5条数据

SELECT * FROM student LIMIT 10,5;

limit 是一个MySQL"方言" 

4.8where 和 having 的区别?

1)where 在分组之前进行限定,如果不满足条件,则不参与分组。having在分组之后进行限定,如果不满足结果,则不会被查询出来
2)where 后不可以跟聚合函数,having可以进行聚合函数的判断。

5.cmd连接数据库

5.1连接本地服务

mysql -u 用户名 -p

回车后输入密码即可登录

5.2连接远程服务

远程连接需要指定ip地址:

mysql -u 用户名 -p -h ip地址

回车后输入密码即可登录

6.约束

对表中的数据进行限定,保证数据的正确性、有效性和完整性(以下均举例说明)。

6.1非空约束:not null,值不能为null

1)创建表时添加约束 

CREATE TABLE stu(
	id INT,
	NAME VARCHAR(20) NOT NULL -- name为非空
);  

2)创建表完后,添加非空约束

alter table stu modify  name varchar(20) not null;

3)删除name的非空约束

alter table stu modify name varchar(20);

6.2唯一约束:unique,值不能重复

注意:mysql中,唯一约束限定的列的值可以有多个null

1)创建表时,添加唯一约束

CREATE TABLE stu(
	id INT,
	phone_number VARCHAR(20) UNIQUE -- 添加唯一约束
);

2)在创建表后,添加唯一约束

alter table stu modify phone_number varchar(20) unique;

3)删除唯一约束

alter table stu drop index phone_number;

6.3主键约束:primary key。

非空且唯一,一张表只能有一个字段为主键,主键就是表中记录的唯一标识。

1)在创建表时,添加主键约束

create table stu(
	id int primary key,-- 给id添加主键约束
	name varchar(20)
);

2)创建完表后,添加主键

alter table stu modify id int primary key;

3)删除主键  

alter table stu drop primary key;

6.4自动增长: auto_increment

如果某一列是数值类型的,使用 auto_increment 可以来完成值得自动增长

1)在创建表时,添加主键约束,并且完成主键自增长

create table stu(
	id int primary key auto_increment,-- 给id添加主键约束
	name varchar(20)
);

2)创建表后(主键已存在),添加自动增长  

alter table stu modify id int auto_increment;

3)删除自动增长

alter table stu modify id int;

6.5外键约束:foreign key

让表于表产生关系,从而保证数据的正确性

1)在创建表时,可以添加外键

create table 表名(
	....
	外键列,
	constraint 外键名称 foreign key (外键列名称) references 主表名称(主表列名称)
);

2)创建表之后,添加外键

alter table 表名 add constraint 外键名 foreign key (外键字段名) references 主表名(主表列名);

3)删除外键

alter table 表名 drop foreign key 外键名;

4)级联操作:当主表的主列发送改变时,对应的外键的值也会动态的发送改变。

级联更新:on update cascade  

级联删除:on delete cascade。(删除要谨慎操作)

alter table 表名 add constraint 外键名 foreign key (外键字段名) references 主表名(主表列名) on update cascade on delete cascade;

7.多表查询

7.1准备sql

# 创建部门表
CREATE TABLE dept(
    id INT PRIMARY KEY AUTO_INCREMENT,
    NAME VARCHAR(20)
);
INSERT INTO dept (NAME) VALUES ('开发部'),('市场部'),('财务部');
# 创建员工表
CREATE TABLE emp (
    id INT PRIMARY KEY AUTO_INCREMENT,
    NAME VARCHAR(10),
    gender CHAR(1), -- 性别
    salary DOUBLE, -- 工资
    join_date DATE, -- 入职日期
    dept_id INT,
    FOREIGN KEY (dept_id) REFERENCES dept(id) -- 外键,关联部门表(部门表的主键)
);
INSERT INTO emp(NAME,gender,salary,join_date,dept_id) VALUES('孙悟空','男',7200,'2013-02-24',1);
INSERT INTO emp(NAME,gender,salary,join_date,dept_id) VALUES('猪八戒','男',3600,'2010-12-02',2);
INSERT INTO emp(NAME,gender,salary,join_date,dept_id) VALUES('唐僧','男',9000,'2008-08-08',2);
INSERT INTO emp(NAME,gender,salary,join_date,dept_id) VALUES('白骨精','女',5000,'2015-10-07',3);
INSERT INTO emp(NAME,gender,salary,join_date,dept_id) VALUES('蜘蛛精','女',4500,'2011-03-14',1);

7.2笛卡尔积

1)有两个集合A,B .取这两个集合的所有组成情况。
2)要完成多表查询,需要消除无用的数据

7.3内连接查询

1)隐式内连接:使用where条件消除无用数据  

#查询所有员工信息和对应的部门信息
SELECT * FROM emp,dept WHERE emp.`dept_id` = dept.`id`;
#查询员工表的名称,性别。部门表的名称
SELECT emp.name,emp.gender,dept.name FROM emp,dept WHERE emp.`dept_id` = dept.`id`;

2)显式内连接:select 字段列表 from 表名1 [inner] join 表名2 on 条件

#查询员工表的名称,性别。部门表的名称
SELECT emp.name,emp.gender,dept.name FROM emp join dept on emp.`dept_id` = dept.`id`;

7.4外连接查询

1)左外连接 left join on

select 字段列表 from 表1 left [outer] join 表2 on 条件;

查询左表所有数据以及其与右表的交集部分  

#查询所有员工信息,如果员工有部门,则查询部门名称,没有部门,则不显示部门名称
SELECT 	t1.*,t2.`name` FROM emp t1 LEFT JOIN dept t2 ON t1.`dept_id` = t2.`id`;

2)右外连接right join on

select 字段列表 from 表1 right [outer] join 表2 on 条件;

查询右表所有数据以及其与左表的交集部分  

#查询所有部门信息和对应的员工信息
SELECT 	t1.*,t2.`name` FROM emp t1 right JOIN dept t2 ON t1.`dept_id` = t2.`id`;

7.5子查询

查询中嵌套查询,称嵌套查询为子查询。

#查询工资最高的员工信息
# 1 查询最高的工资是多少 9000
SELECT MAX(salary) FROM emp;
                
# 2 查询员工信息,并且工资等于9000的
SELECT * FROM emp WHERE emp.`salary` = 9000;
                
# 一条sql就完成这个操作。子查询
SELECT * FROM emp WHERE emp.`salary` = (SELECT MAX(salary) FROM emp);

子查询不同情况

1)子查询的结果是单行单列的:

子查询可以作为条件,使用运算符去判断。 运算符: > >= < <= =

# 查询员工工资小于平均工资的人
SELECT * FROM emp WHERE emp.salary < (SELECT AVG(salary) FROM emp);

2)子查询的结果是多行单列的

子查询可以作为条件,使用运算符in来判断

#查询'财务部'和'市场部'所有的员工信息
SELECT * FROM emp WHERE dept_id IN (SELECT id FROM dept WHERE NAME = '财务部' OR NAME = '市场部'); 

3)子查询的结果是多行多列的

子查询可以作为一张虚拟表参与查询

#查询员工入职日期是2011-11-11日之后的员工信息和部门信息
SELECT * FROM dept t1 ,(SELECT * FROM emp WHERE emp.`join_date` > '2011-11-11') t2 WHERE t1.id = t2.dept_id;

8.事务

如果一个包含多个步骤的业务操作,被事务管理,要么同时成功,要么同时失败。

8.1事务的操作

1)开启事务start transaction:在事务执行之前开启事务

2)回滚rollback:出现错误时会回滚到开启事务的地方

3)提交commit:事务提交之后数据库才能变化

8.2事务的两种提交方式

1)自动提交

mysql默认是自动提交的,一条增删改语句就自动提交一次事务

2)手动提交

查看事务的提交方式

select @@autocommit # 1代表自动提交,0代表手动提交  

修改事务的提交方式 

set @@autocommit=0;

8.3事务的四大特征

1)原子性(Atomicity):事务是不可分割的最小操作单位,要么同时成功,要么同时失败

2)一致性(Consistemcy):事务操作前后,数据总量保持不变

3)持久性(Isolation):当事务提交或回滚后,数据库持久化的保存数据

4)隔离性(Durability):多个事务之间相互独立,互不影响 

8.4事务的隔离级别

多个事务之间隔离的,相互独立的。但是如果多个事务操作同一批数据,则会引发一些问题,设置不同的隔离级别就可以解决这些问题。 

1)问题

脏读:一个事务,读取到另一个事务中没有提交的数据 

不可重复读(虚读):在同一个事务中,两次读取到的数据不一样。

幻读:一个事务操作(DML)数据表中所有记录,另一个事务添加了一条数据,则第一个事务查询不到自己的修改

2)隔离级别

read uncommitted:读未提交。产生的问题:脏读、不可重复读、幻读

read committed:读已提交 (Oracle)。产生的问题:不可重复读、幻读

repeatable read:可重复读 (MySQL默认。 产生的问题:幻读

serializable:串行化。可以解决所有的问题

隔离级别从小到大安全性越来越高,但是效率越来越低 

查询隔离级别

select @@tx_isolation;

设置隔离级别

set global transaction isolation level  级别字符串;

9.数据库设计的范式

设计数据库时,需要遵循的一些规范。要遵循后边的范式要求,必须先遵循前边的所有范式要求。

目前关系数据库有六种范式:第一范式(1NF)、第二范式(2NF)、第三范式(3NF)、巴斯-科德范式(BCNF)、第四范式(4NF)和第五范式(5NF,又称完美范式)。  

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

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

1)函数依赖:A-->B,如果通过A的属性或属性组的值,可以唯一确定B属性的值,则称B依赖于A。

例如:学号-->姓名

2)完全函数依赖:A-->B,如果A是一个属性组,则B属性值的确定要依赖于A属性组的所有属性值。

例如:(学号,课程名)-->成绩

3)部分函数依赖:A-->B,如果A是一个属性组,则B属性值的确定要依赖于A属性组的部分属性值即可。

例如:(学号,课程名)-->姓名

4)传递函数依赖:A-->B,B-->C。如果通过A的属性或属性组的值,可以唯一确定B属性的值,通过B属性或属性组的值,又可以唯一确定C属性的值,则称C传递函数依赖于A.

例如:学号-->系名,系名-->系主任

5)码:在一张表中,如果一个属性或属性组,被其他所有的属性完全依赖,则称这个属性是这个表的码。

例如:该表的码为(学号,课程名称)

主属性:码属性组中的所有属性

非主属性:除了码属性组以外的属性  

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

 

posted @ 2019-09-22 16:14  钟小嘿  阅读(296)  评论(0编辑  收藏  举报