一、进入和退出数据库
1.进入mysql数据库
mysql -uusername -ppassword
mysql -uusername -p #按下enter键再输入密码,密码会隐藏
2.退出mysql数据库
exit
quit
#强制退出(不建议使用)
Ctrl+D
二、库级操作语句
1.显示(当前数据库的)所有库
SHOW DATABASES;
2.创建数据库
CREATE DATABASE tanzhou;
3.显示库的创建信息
SHOW CREATE DATABASE tanzhou;
4.删除库
DROP DATABASE tanzhou;
#分号;和\G代表一条语句的结束
DROP DATABASE tanzhou\G
5.切换当前数据库
USE tanzhou;
6.显示当前所在(默认)数据库
SELECT DATABASE();
三、表级操作语句
1.显示所有表
SHOW TABLES;
2.创建表(创建表时必须提供字段)
CREATE TABLE mytable(id INT);
3.显示表的创建信息
SHOW CREATE TABLE mytable;
4.删除表
DROP TABLE mytable;
5.显示其他数据库(如:mysql)的所有表
SHOW TABLES FROM mysql;
6.注意事项:
#mysql库的所有表都不能更改
#语句结束符:每条语句都以;号或者\G结束
#SQL语句不严格区分大小写
#类型:强制数据类型,任何数据都有自己的类型(SQL语句中的变量必须声明类型)
#逗号:最后一列不需要逗号
四、数据库CRUD操作
C:CREATE/INSERT #创建/插入
R:READ/SELECT #读取/查询
U:UPDATE #更新
D:DELETE #删除
1.插入操作
指定列插入:插入某列某值,单行操作
全列插入:需要给所有列赋值,单行操作
多行插入:一次性插入多行数据
#创建students表
CREATE TABLE students(
number CHAR(9),
name VARCHAR(20),
age INT,
birth DATE
);
#查看students表
SHOW TABLES;
#指定列插入(没指定插入的列默认值是NULL)
INSERT INTO students(number,name,birth) VALUES('001','zhangsan','2000-01-12');
#查看此时students表的所有内容
SELECT * FROM students;
#全列插入
INSERT INTO students VALUES('002','lisi',18,'1994-08-09');
#查看此时students表的所有内容
SELECT * FROM students;
#多行插入
INSERT INTO students VALUES('003','wangwu',23,'1989-03-27'),
('004','chencheng',22,'1990-03-01'),
('005','liuqi',20,'1881-03-27'),
('006','huangba',10,'1010-07-27');
#查看此时students表的所有内容
SELECT * FROM students;
2.查询操作
指定列查询
全列查询
带条件的查询
#指定列查询(关键字:select、from)
SELECT name,birth FROM students;
#全列查询(关键字:select、from)
SELECT * FROM students;
#带条件的查询(关键字:select、from、where)
SELECT * FROM students WHERE age<18;
SELECT name,age FROM students WHERE age<18;
3.更新操作
update:关键字:update、set、where
#更改某值(的方法)
UPDATE students SET age = 15 WHERE number = '004';
#查询此时students表的所有内容
SELECT * FROM students;
4.删除操作
delete:关键字:delete、from、where
#删除某行数值(的方法):删除只能删除一行,不能删除单独一个值。
DELETE FROM students WHERE number = '001';
五、约束条件
1.默认值
默认值关键字:default
在没有设置默认值的情况下,默认为NULL
#设置默认值:8
CREATE TABLE default_test(
id INT(5),
number INT(10) DEFAULT 8
);
INSERT INTO default_test(id) VALUES(1);
SELECT * FROM default_test;
2.非空
非空关键字:NOT NULL
作用:限制一个列的值不能为空
CREATE TABLE not_null(
id INT(5) NOT NULL,
number INT(10)
);
#此时会出现报错,报错信息如下:
#ERROR 1364 (HY000): Field 'id' doesn't have a default value
INSERT INTO not_null(number) VALUES(2018);
#如下语句可以正常运行
INSERT INTO not_null VALUES(1,2019);
SHOW TABLES;
SELECT * FROM not_null;
3.唯一键
唯一键的关键字:unique key
作用:使某列的值不能重复
CREATE TABLE unique_key(
id INT(5),
number INT(10),
UNIQUE KEY(id)
);
SHOW TABLES;
#此时运行下述语句会报错,报错信息如下:
#ERROR 1062 (23000): Duplicate entry '1' for key 'id'
INSERT INTO unique_key VALUES
(1,2000),
(1,2013);
#此时运行正常
INSERT INTO unique_key VALUES
(1,2000),
(2,2013);
SELECT * FROM unique_key;
4.主键
主键 = 非空 + 唯一
通常每张表都需要一个主键来体现唯一性
主键关键字:primary key
CREATE TABLE prinmary_key(
id INT(5),
number INT(10),
PRIMARY KEY(id)
);
INSERT INTO primar_key VALUES(1,10); #插入成功
INSERT INTO primar_key VALUES(2,12); #插入成功
INSERT INTO primar_key VALUES(1,12); #插入报错,体现唯一性
INSERT INTO primar_key(number) VALUES(12); #插入报错,体现非空
SELECT * FROM primary_key;
5.复合主键
复合主键:表内的主键由一个以上的字段组成
当表中只有一个主键时,它是唯一的索引;
当表中有多个主键时,称为复合主键,复合主键联合保证唯一索引”
即如下述代码,只有当id+name都一样时才会报错(体现唯一性),
复合主键的单个主键是可以重复的。
CREATE TABLE complex_primary(
id INT(5),
name VARCHAR(20),
age INT(3),
PRIMARY KEY(id,name)
);
#运行正常
INSERT INTO complex_primary(id,name) VALUES
(1,'zhangsan'),
(2,'zhangsan');
#运行报错,报错信息如下:
#ERROR 1062 (23000): Duplicate entry '3-lisi' for key 'PRIMARY'
INSERT INTO complex_primary(id,name,age) VALUES
(3,'lisi',18),
(3,'lisi',20);
#运行正常
INSERT INTO complex_primary(id,name,age) VALUES
(3,'lisi',18),
(3,'王五',20);
SHOW TABLES;
SELECT * FROM complex_primary;
6.自增长
某整数列的值,自动增加,默认+1填充;
自增长用在主键上;
自增长的关键字:auto increment
#设置自增长
CREATE TABLE auto_increment(
id INT(5) AUTO_INCREMENT,
number INT(10),
PRIMARY KEY(id)
);
INSERT INTO auto_increment VALUES(NULL,90); #此处id=1
INSERT INTO auto_increment VALUES(NULL,99); #此处id=2
INSERT INTO auto_increment VALUES(NULL,99); #此处id=3
INSERT INTO auto_increment VALUES(8,78); #此处id=8
INSERT INTO auto_increment VALUES(NULL,88); #此处id=9
INSERT INTO auto_increment VALUES(NULL,88); #此处id=10
7.外键
外键(我)和主键(你)的关系:你有我才能有,你没有我一定没有
外键的关键词:foreign key references
#设置外键
CREATE TABLE a(
id INT(5) AUTO INCREMENT,
PRIMARY KEY(id)
);
CREATE TABLE b(
id INT(5),
FOREIGN KEY(id) REFERENCES a(id)
);
INSERT INTO a VALUES(1),(2),(3);
SELECT * FROM a;
INSERT INTO b VALUES(1); #插入成功
INSERT INTO b VALUES(2); #插入成功
INSERT INTO b VALUES(3); #插入成功
INSERT INTO b VALUES(4); #插入报错,因为a(id)没有4
SELECT * FROM b;
INSERT INTO a VALUES(4);
INSERT INTO b VALUES(4); #此时插入成功,因为上行代码就在a中插入了4
六、事务、编码和索引
1.事务
事务主要用来处理操作量大、复杂度高的数据。比如说,在人员管理系统中,你删除一个人员,你即需要删除人员的基本资料,也要删除和该人员相关的信息,如信箱,文章等等,这样,这些数据库操作语句就构成了一个事务。
- 在mysql中,innodb数据库引擎才支持事务,故而要使用事务,必须指定数据库引擎为innodb
- 事务用来管理insert,update,delete语句
原子性:所做操作要么全部完成执行,要么都不执行
一致性:执行前和执行后,数据的完整性没有被破坏
隔离性:同时读写修改同一数据,保证数据的一致性
持久性:对数据的修改是持久的,即使系统被破坏数据也不会消失
在mysql控制台中使用事务:
mysql> begin; #开始一个事务
mysql> insert into a(a) values(555);
mysql> rollback; #回滚,这样数据是不会写入的
mysql> commit; #提交数据并结束事务
2.编码问题
#编辑配置文件
vim /etc/mysql/mysql.conf.d/mysqld.cnf
#重启数据库
sudo service mysql restart
#设置编码(创建数据库自定义编码)
CREATE DATABASE db_code CHARACTER SET gbk;
SHOW CREATE DATABASE db_code;
#设置编码(创建数据表自定义编码)
CREATE TABLE tb_code(
id INT(5),
number INT(10)
)CHARSET utf8;
SHOW CREATE TABLE tb_code;
3.索引
索引用于快速找出在某个列中有一特定值的行,不使用索引,mysql必须从第一条记录开始往下找,直到找到符合条件的行。
表越大,查询数据所花费的时间就越多,而如果表中查询的列有一个索引,mysql就能够快速到达一个位置去搜索数据文件,而不用查看所有数据,那么将会节省很大一部分时间。
eg:一张person表,有2w条记录,记录着2w个人的信息,其中phone字段记录着每个人的电话号码,现在需求如下:想查询出电话号码为XXXX的人的信息!
如果没有索引,那么将从表中第一条记录一条条的往下遍历,指导找到匹配的为止。
如果有了索引,那么会将phone字段通过一定的方法进行存储(mysql中索引的存储类型有两种:BTREE、HASH),好让查询该字段信息时能快速找到对应的数据,而不必遍历2w条数据。
七、表结构修改
表描述、添加列、删除列、修改字段类型、
修改字段名称、修改字段默认值、修改表名
1.表描述
表描述:显示表的具体信息
表描述的关键字:desc
DESC student;
2.添加列
添加列的关键字:add
#添加列(默认放在最后一列)
ALTER TABLE student
ADD number INT;
#添加列(指定位置添加)
#FIRST:添加在第一列
ALTER TABLE student
ADD number INT FIRST;
#AFTER col_name:在col_name列之后添加列
ALTER TABLE student
ADD number INT AFTER id;
3.删除列
删除列的关键字:drop
#删除列
ALTER TABLE student
DROP number;
4.修改列字段类型
修改列字段类型的关键字:modify
#修改字段类型(将id由int类型变为char类型)
ALTER TABLE student
MODIFY id CHAR(5);
5.修改字段名称
修改字段名称的关键字:change
#将字段id改为字段number
ALTER TABLE student
CHANGE id number INT(10);
6.修改字段默认值
修改字段默认值的关键字:alter set
#修改默认值
ALTER TABLE student
ALTER address SET DEFAULT 'earth';
7.修改表名
修改表名的关键字:rename to
#修改表名
ALTER TABLE student
RENAME TO new_student;
八、子查询
子查询:将一条语句的结果当作另外一条语句的条件。
CREATE DATABASE zhipeng;
USE zhipeng;
CREATE TABLE students(
number CHAR(9), #学号
name VARCHAR(20), #姓名
age INT, #年龄
birth DATE, #生日
PRIMARY KEY(number)
);
INSERT INTO students VALUES ('201804001', '刘一', 16, '2002-01-01');
INSERT INTO students VALUES ('201804002', '陈二', 17, '2001-01-02');
INSERT INTO students VALUES ('201804003', '张三', 18, '2000-01-03');
INSERT INTO students VALUES ('201804004', '李四', 19, '2001-01-04');
INSERT INTO students VALUES ('201804005', '王五', 20, '2000-01-05');
INSERT INTO students VALUES ('201804006', '赵六', 21, '1999-01-06');
INSERT INTO students VALUES ('201804007', '孙七', 22, '1999-01-07');
INSERT INTO students VALUES ('201804008', '周八', 23, '1999-01-08');
INSERT INTO students VALUES ('201804009', '吴九', 24, '1999-01-09');
INSERT INTO students VALUES ('201804010', '郑十', 25, '1999-01-10');
SELECT * FROM students;
#创建科目表
CREATE TABLE subjects(
number CHAR(4), #科目号
title VARCHAR(30), #科目名
duration INT, #课时时长
PRIMARY KEY(number)
);
INSERT INTO subjects VALUES
('0001', 'Python基础', 32),
('0002', 'Python进阶', 16),
('0003', 'Web前端', 16),
('0004', 'Python框架', 32),
('0005', 'Python项目', 32);
SELECT * FROM subjects;
#创建成绩表
CREATE TABLE grades(
student_number CHAR(9), #学生号
subject_number CHAR(4), #科目号
grade INT #成绩
);
INSERT INTO grades VALUES ('201804001', '0001', 90);
INSERT INTO grades VALUES ('201804002', '0001', 89);
INSERT INTO grades VALUES ('201804003', '0001', 88);
INSERT INTO grades VALUES ('201804004', '0001', 87);
INSERT INTO grades VALUES ('201804005', '0001', 86);
INSERT INTO grades VALUES ('201804006', '0001', 85);
INSERT INTO grades VALUES ('201804007', '0001', 84);
INSERT INTO grades VALUES ('201804008', '0001', 83);
INSERT INTO grades VALUES ('201804009', '0001', 82);
INSERT INTO grades VALUES ('201804010', '0001', 81);
INSERT INTO grades VALUES ('201804001', '0002', 80);
INSERT INTO grades VALUES ('201804002', '0002', 79);
INSERT INTO grades VALUES ('201804003', '0002', 78);
INSERT INTO grades VALUES ('201804004', '0002', 77);
INSERT INTO grades VALUES ('201804005', '0002', 76);
INSERT INTO grades VALUES ('201804006', '0002', 75);
INSERT INTO grades VALUES ('201804007', '0002', 74);
INSERT INTO grades VALUES ('201804008', '0002', 73);
INSERT INTO grades VALUES ('201804009', '0002', 72);
INSERT INTO grades VALUES ('201804010', '0002', 71);
SELECT * FROM grades;
"""
#如何找到张三的成绩?
#先找到张三的学号,再用这个学号去筛选成绩表就能找到。
"""
#首先获取学生张三的学号:201804003
SELECT number FROM students WHERE name = '张三';
#根据学号获取成绩
SELECT * FROM grades
WHERE student_number = 201804003;
#上述两个语句的合并版(子查询):
SELECT * FROM grades
WHERE student_number=(SELECT number FROM students WHERE name='张三');
九、连接查询
join按照功能大致分为三类:
- inner join(内连接或者等值连接):获取两个表中字段匹配关系的记录;
- left join (左连接):获取左表所有记录,即使右表没有对应匹配的记录;
- right join(右连接):获取右表所有记录,即使左表没有对应匹配的记录。
内连接关键字:join on 或者 inner join on
on表示连接条件
#成绩表和科目表连接
SELECT student_number,title,grade FROM subjects JOIN grades
ON grades.subject_number = subjects.number;
#再将学生表加进去(即在上面代码的基础上再加上一个join语句)
SELECT name,title,grade FROM subjects
JOIN grades ON grades.subject_number = subjects.number
JOIN students ON grades.student_number = students.number;
理解inner join、left join、right join、full join的区别:
假设有两张表,数据如下:
inner join(查交集)
left join(查差集)
right join(查差集)
full join(查并集)
注意:对于full join,其实mysql并不支持full join,故而上述sql语句是错误的,正确的写法如下: