数据库学习之MySQL基础
Posted 超级英雄拯救世界之前成长的日子
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了数据库学习之MySQL基础相关的知识,希望对你有一定的参考价值。
数据库基础
一、数据库简介
数据库:存放数据的仓库
sql及其规范
sql是Structured Query Language(结构化查询语言)的缩写。SQL是专为数据库而建立的操作命令集,是一种功能齐全的数据库语言。
在使用它时,只需要发出“做什么”的命令,“怎么做”是不用使用者考虑的。SQL功能强大、简单易学、使用方便,已经成为了数据库操作的基础,并且现在几乎所有的数据库均支持sql。
<1> 在数据库系统中,SQL语句不区分大小写(建议用大写) 。但字符串常量区分大小写。建议命令大写,表名库名小写; <2> SQL语句可单行或多行书写,以“;”结尾。关键词不能跨多行或简写。 <3> 用空格和缩进来提高语句的可读性。子句通常位于独立行,便于编辑,提高可读性。 SELECT * FROM tb_table WHERE NAME="YUAN"; <4> 注释:单行注释:-- 多行注释:/*......*/ <5>sql语句可以折行操作 <6> DDL,DML和DCL
mysql常用命令
--
-- 启动mysql服务与停止mysql服务命令:
--
-- net start mysql
-- net stop mysql
--
--
-- 登陆与退出命令:
--
-- mysql -h 服务器IP -P 端口号 -u 用户名 -p 密码 --prompt 命令提示符 --delimiter 指定分隔符
-- mysql -h 127.0.0.1 -P 3306 -uroot -p123
-- quit------exit----\\q;
--
--
-- \\s; ------my.ini文件:[mysql] default-character-set=gbk [mysqld] character-set-server=gbk
--
-- prompt 命令提示符(\\D:当前日期 \\d:当前数据库 \\u:当前用户)
--
-- \\T(开始日志) \\t(结束日志)
--
-- show warnings;
--
-- help() ? \\h
--
-- \\G;
--
-- select now();
-- select version();
-- select user;
--
-- \\c 取消命令
--
-- delimiter 指定分隔符
二、.数据库操作(DDL)
1.查看:
(1)查看所有数据库:show databases;
(2)查看某一数据库创建编码:show create database num;
2.创建:
create database if not exists sxmu; (如果不存在则创建,若存在不创建也不报错,但会warning.查看warning:show warnings;)
create database if not exists num character set gbk;
3.删除:drop database if exists kokusho;
4.修改:alter database num character set gbk;
5 使用:切换:use sxmu;
检测当前数据库:select database();
注:数据库文件默认存放路径(C:\\ProgramData\\MySQL\\MySQL Server 5.7\\Data)
默认创建的所有数据库都是一个文件夹,每一张表都是该文件夹下的一个文件。
故如果要迁移数据库文件,可直接复制数据库文件夹
select user();
select now();
三、数据表操作
主键:非空且唯一(not null,unique)
数据类型:
数值类型
日期和时间类型
字符串类型
创建表:
create table tab_name(
field1 type[完整性约束条件],
field2 type,
...
fieldn type
)[character set xxx];
创建员工表:
CREATE TABLE employee(
id TINYINT PRIMARY KEY AUTO_INCREMENT,
name VARCHAR(25),
gender BOOLEAN,
age INT,
department VARCHAR(20),
salary DOUBLE(7,2)
)
表结构:
1.查看
查看表结构:desc employee;
show columns from employee;
查看创建表语句:show create table employee;
查看当前数据库所有表:show tables;
2.增加字段:alter table employee add is_married tinyint(1);
alter table employee add entry_date date not null;
alter table employee add A int,add b varchar(20);
3.删除字段:alter table employee drop A;
alter table employee drop b,drop entry_date;
删除表:drop table emp;
4.修改字段信息:alter table employee modify age smallint not null default 18 after name;
alter table employee change department depart varchar(20) after salary;
修改表名: rename table employee to emp;
修改表所用字符集: alter table student character set utf8;
四、表记录操作
准备表数据
CREATE TABLE ExamResult( id INT PRIMARY KEY auto_increment, name VARCHAR (20), JS DOUBLE , Django DOUBLE , OpenStack DOUBLE );
插入:insert [into] tab_name (field1,filed2,.......) values (value1,value2,.......)
删除:DELETE FROM emp WHERE id=11 OR id=2;
修改:UPDATE emp SET salary=salary+20000 WHERE name=\'yuan\';
查询:select [distinct] *|filed1,field2| [as 别名]|[别名] from tab_name;
mysql中五种查询字句
- where子句(条件查询):按照“条件表达式”指定的条件进行查询。
- group by子句(分组):按照“属性名”指定的字段进行分组。group by子句通常和count()、sum()等聚合函数一起使用。
- having子句(筛选):有group by才能having子句,只有满足“条件表达式”中指定的条件的才能够输出。
- order by子句(排序):按照“属性名”指定的字段进行排序。排序方式由“asc”和“desc”两个参数指出,默认是按照“asc”来排序,即升序
- limit(限制结果集)。
mysql查询执行顺序
(7) SELECT (8) DISTINCT <select_list> (1) FROM <left_table> (3) <join_type> JOIN <right_table> (2) ON <join_condition> (4) WHERE <where_condition> (5) GROUP BY <group_by_list> (6) HAVING <having_condition> (9) ORDER BY <order_by_condition> (10) LIMIT <limit_number>
(1)增删改查 insert into emp (id,age,name,gender,salary,depart,is_married) values(1,18,\'alex\',0,1700,\'技术部\',1); INSERT INTO emp(name,salary,depart) VALUES (\'瞎驴\',30000,\'python\'); INSERT INTO emp(name,salary,depart) VALUES (\'xialv\',30000,\'python\'), (\'小雨\',5000,\'销售部\'), (\'冰冰\',9000,\'销售部\'); insert emp set name=\'珊珊\'; insert into emp values(10,\'丹丹\',29,0,3000,\'销售部\',1); INSERT INTO emp(name,salary,depart) VALUES (\'yuan\',30000,\'python\'); UPDATE emp SET salary=salary+20000,depart=\'保安部\' WHERE name=\'xialv\'; delete from emp; (删除表内容) truncate table emp; (先直接删除整个表,在创建一个相同表结构的空表。大量数据时使用,直接删除表速度快。) insert into examresult(name) value(\'周守成\'); INSERT INTO ExamResult VALUES (1,"yuan",98,98,98), (2,"xialv",35,98,67), (3,"alex",59,59,62), (4,"wusir",88,89,82), (5,"alvin",88,98,67), (6,"yuan",86,100,55); 练习:select * from examresult; select name,JS,Django,flask from examresult; select name 姓名,JS+10 as JS,Django+10 as Django,flask+10 as flask from examresult; select distinct name from examresult; //去重 (1)where:where字句中可使用[比较运算符:< > <= >= <> !=,between and,in,like,逻辑运算符:and or not] 练习:select name,JS+Django+flask as 总成绩 from examresult where JS+flask+Django>200; select name,JS from examresult where JS!=80; select name,JS from examresult where JS between 90 and 100; select name,JS from examresult where JS in(88,99,77); select name,JS from examresult where name like \'y%\'; // %: 任意多个字符 select name,JS from examresult where name like \'y_\'; // _:一个字符 select name,JS from examresult where name=\'yuan\' and JS>80; select name from examresult where JS is null; //空考的学生 (2)order by 指定排序的列(排序的列可以使表中的列名,也可以是select语句中的别名) --asc为升序,desc为降序,默认为asc,order by应为于select语句的结尾 select name,JS from examresult order by JS; select name,JS from examresult where JS between 70 and 100 order by JS; //默认升序 select name,JS from examresult where JS between 70 and 100 order by JS desc; //降序 select name,JS+Django+flask as 总成绩 from examresult order by 总成绩 desc; select name,JS+Django+flask as 总成绩 from examresult where name=\'yuan\' order by 总成绩 desc; 注:select JS as JS总成绩 from examresult where JS总成绩>70; 这条语句不能正确执行 select语句的执行顺序:from 表名 -> where -> select ->......->order by (3)group by:分组查询 --常和聚合函数配合使用 注:-- 按分组条件分组后每一组只会显示第一条记录 -- group by字句,其后可以接多个列名,也可以跟having子句,对group by 的结果进行筛选。 按列名分组 select * from examresult group by name; 按位置字段分组 select * from examresult group by 2; 将成绩表按名字分组后,显示每一组JS成绩的分数总和 select name,sum(JS) from examresult group by name; 将成绩表按照名字分组后,显示每一类名字的Django的分数总和>150的类名字和Django总分 select name,sum(Django) from examresult group by name having sum(Django)>150; 查询每个部门中男性和女性的人数 select depart,gender,count(id) from emp group by depart,gender; having 和 where两者都可以对查询结果进行进一步的过滤,差别有: <1>where语句只能用在分组之前的筛选,having可以用在分组之后的筛选; <2>使用where语句的地方都可以用having进行替换 <3>having中可以用聚合函数,where中就不行。 (4)聚合函数:[count,sum,avg,max,min]--常和分组函数配合使用 --统计JS>70的人数 select count(id) from examresult where JS>70; --统计JS的平均分 select sum(JS)/count(name) from examresult; //算上了JS为null的情况 select avg(JS) from examresult; //不算JS为null -- 统计总分大于280的人数有多少? select count(name) from ExamResult where (ifnull(JS,0)+ifnull(Django,0)+ifnull(OpenStack,0))>280; --查询JS总分中最小值 select min(JS) from examresult; select min(ifnull(JS,0)) from examresult; --查询JS+Django+flask总分中最大的 select max(JS+Django+flask) from examresult; (5)limit: select * from examresult limit 3;显示前3条 select * from examresult limit 2,3; //跳过前两条显示接下来的3条 (6)重点: --sql语句书写顺序:select from where group by having order by --sql语句执行顺序:from where select group by having order by 例子: select JS as JS成绩 from examresult where JS成绩>70; //执行不成功 select JS as JS成绩 from examresult where JS成绩>70; //成功执行 (7)使用正则表达式查询 SELECT * FROM employee WHERE name REGEXP \'^yu\'; SELECT * FROM employee WHERE name REGEXP \'yun$\'; SELECT * FROM employee WHERE name REGEXP \'m{2}\';
五、外键约束
创建外键
--- 每一个班主任会对应多个学生 , 而每个学生只能对应一个班主任
--1.数据准备:
----主表
CREATE TABLE ClassCharger(
id TINYINT PRIMARY KEY auto_increment,
name VARCHAR (20),
age INT ,
is_marriged boolean -- show create table ClassCharger: tinyint(1)
);
INSERT INTO ClassCharger (name,age,is_marriged) VALUES ("冰冰",12,0),
("丹丹",14,0),
("歪歪",22,0),
("姗姗",20,0),
("小雨",21,0);
----子表
CREATE TABLE Student(
id INT PRIMARY KEY auto_increment,
name VARCHAR (20),
charger_id TINYINT,
foreign key (charger_id) references classcharger(id) on delete cascade
) ENGINE=INNODB;
--切记:作为外键一定要和关联主键的数据类型保持一致
-- [ADD CONSTRAINT charger_fk_stu]FOREIGN KEY (charger_id) REFERENCES ClassCharger(id)
INSERT INTO Student2(name,charger_id) VALUES ("alvin1",2),
("alvin2",4),
("alvin3",1),
("alvin4",3),
("alvin5",5),
("alvin6",3),
("alvin7",3);
--2.外键约束练习
删除班主任丹丹
delete from classcharger where id=2; --会报错
先删除班主任丹丹关联的学生
update student set charger_id=4 where id=1 or id=7;
delete from classcharger where id=2; --成功执行
添加一个学生,班主任选择丹丹
insert into student(name,charger_id) values(\'sasa\',2); --添加失败
-----------增加外键和删除外键---------
ALTER TABLE student ADD CONSTRAINT abc
FOREIGN KEY(charger_id)
REFERENCES classcharger(id);
ALTER TABLE student DROP FOREIGN KEY abc;
alter table student3 drop foreign key student3_ibfk_1;
alter table student3 add constraint s3_fk_c foreign key(charger_id) references C(id) on delete set null;
3.INNODB支持的on语句
--外键约束对子表的含义: 如果在父表中找不到候选键,则不允许在子表上进行insert/update
--外键约束对父表的含义: 在父表上进行update/delete以更新或删除在子表中有一条或多条对
-- 应匹配行的候选键时,父表的行为取决于:在定义子表的外键时指定的
-- on update/on delete子句
-----------------innodb支持的四种方式---------------------------------------
-----cascade方式 在父表上update/delete记录时,同步update/delete掉子表的匹配记录
-----外键的级联删除:如果父表中的记录被删除,则子表中对应的记录自动被删除--------
FOREIGN KEY (charger_id) REFERENCES ClassCharger(id)
ON DELETE CASCADE
------set null方式 在父表上update/delete记录时,将子表上匹配记录的列设为null
-- 要注意子表的外键列不能为not null
FOREIGN KEY (charger_id) REFERENCES ClassCharger(id)
ON DELETE SET NULL
------Restrict方式 :拒绝对父表进行删除更新操作(了解)
------No action方式 在mysql中同Restrict,如果子表中有匹配的记录,则不允许对父表对应候选键
-- 进行update/delete操作(了解)
六、连表查询
1、内联接(典型的联接运算,使用像 = 或 <> 之类的比较运算符)。包括相等联接和自然联接。
- inner join(等值连接) 只返回两个表中联结字段相等的行
2、外联接。外联接可以是左向外联接、右向外联接或完整外部联接。
- left join(左联接) 返回包括左表中的所有记录和右表中联结字段相等的记录
- right join(右联接) 返回包括右表中的所有记录和左表中联结字段相等的记录
- full join(全联接) 返回包括右表中的所有记录和左表中所有的记录
3、交叉联接
交叉联接返回左表中的所有行,左表中的每一行与右表中的所有行组合。交叉联接也称作笛卡尔积。
FROM 子句中的表或视图可通过内联接或完整外部联接按任意顺序指定;但是,用左或右向外联接指定表或视图时,表或视图的顺序很重要。有关使用左或右向外联接排列表的更多信息,请参见使用外联接。
mysql> use flask_code Database changed mysql> show tables; +----------------------+ | Tables_in_flask_code | +----------------------+ | record | | userinfo | +----------------------+ 2 rows in set (0.00 sec) mysql> select * from record; +----+------+------------+---------+ | id | line | ctime | user_id | +----+------+------------+---------+ | 1 | 1000 | 2018-12-19 | 1 | | 2 | 5000 | 2018-12-17 | 3 | | 3 | 3000 | 2018-12-21 | 3 | | 5 | 269 | 2018-12-26 | 3 | | 6 | 269 | 2018-12-27 | 3 | +----+------+------------+---------+ 5 rows in set (0.00 sec) mysql> select * from userinfo; +----+------------+----------------------------------+--------------+ | id | username | password | nickname | +----+------------+----------------------------------+--------------+ | 1 | zhangsan | 317bc264bfd3d562fa415dbb905e2d8a | 就是这么牛逼 | | 2 | lisi | 317bc264bfd3d562fa415dbb905e2d8a | 看把你牛逼的 | | 3 | zhangyafei | 317bc264bfd3d562fa415dbb905e2d8a | 张亚飞 | +----+------------+----------------------------------+--------------+ 3 rows in set (0.00 sec) mysql> select userinfo.nickname,record.line from record,userinfo where record.us er_id = userinfo.id; +--------------+------+ | nickname | line | +--------------+------+ | 就是这么牛逼 | 1000 | | 张亚飞 | 5000 | | 张亚飞 | 3000 | | 张亚飞 | 269 | | 张亚飞 | 269 | +--------------+------+ 5 rows in set (0.00 sec) mysql> select userinfo.nickname,record.line from record inner join userinfo on u serinfo.id = record.user_id; +--------------+------+ | nickname | line | +--------------+------+ | 就是这么牛逼 | 1000 | | 张亚飞 | 5000 | | 张亚飞 | 3000 | | 张亚飞 | 269 | | 张亚飞 | 269 | +--------------+------+ 5 rows in set (0.00 sec) mysql> select userinfo.nickname,record.line from record left join userinfo on us erinfo.id = record.user_id; +--------------+------+ | nickname | line | +--------------+------+ | 就是这么牛逼 | 1000 | | 张亚飞 | 5000 | | 张亚飞 | 3000 | | 张亚飞 | 269 | | 张亚飞 | 269 | +--------------+------+ 5 rows in set (0.00 sec) mysql> select userinfo.nickname,record.line from record right join userinfo on u serinfo.id = record.user_id; +--------------+------+ | nickname | line | +--------------+------+ | 就是这么牛逼 | 1000 | | 张亚飞 | 5000 | | 张亚飞 | 3000 | | 张亚飞 | 269 | | 张亚飞 | 269 | | 看把你牛逼的 | NULL | +--------------+------+ 6 rows in set (0.00 sec) mysql> select * from record right join userinfo on userinfo.id = record.user_id; +------+------+------------+---------+----+------------+------------------------ ----------+--------------+ | id | line | ctime | user_id | id | username | password | nickname | +------+------+------------+---------+----+------------+------------------------ ----------+--------------+ | 1 | 1000 | 2018-12-19 | 1 | 1 | zhangsan | 317bc264bfd3d562fa415db b905e2d8a | 就是这么牛逼 | | 2 | 5000 | 2018-12-17 | 3 | 3 | zhangyafei | 317bc264bfd3d562fa415db b905e2d8a | 张亚飞 | | 3 | 3000 | 2018-12-21 | 3 | 3 | zhangyafei | 317bc264bfd3d562fa415db b905e2d8a | 张亚飞 | | 5 | 269 | 2018-12-26 | 3 | 3 | zhangyafei | 317bc264bfd3d562fa415db b905e2d8a | 张亚飞 | | 6 | 269 | 2018-12-27 | 3 | 3 | zhangyafei | 317bc264bfd3d562fa415db b905e2d8a | 张亚飞 | | NULL | NULL | NULL | NULL | 2 | lisi | 317bc264bfd3d562fa415db b905e2d8a | 看把你牛逼的 | +------+------+------------+---------+----+------------+------------------------ ----------+--------------+ 6 rows in set (0.00 sec) mysql> select userinfo.id,nickname,ifnull(sum(line),0) as line from record right join userinfo on userinfo.id=record.user_id group by userinfo.id order by line desc; +----+--------------+------+ | id | nickname | line | +----+--------------+------+ | 3 | 张亚飞 | 8538 | | 1 | 就是这么牛逼 | 1000 | | 2 | 看把你牛逼的 | 0 | +----+--------------+------+ 3 rows in set (0.00 sec)
mysql> select * from record; +----+------+------------+---------+ | id | line | ctime | user_id | +----+------+------------+---------+ | 1 | 1000 | 2018-12-19 | 1 | | 2 | 5000 | 2018-12-17 | 3 | | 3 | 3000 | 2018-12-21 | 3 | | 5 | 269 | 2018-12-26 | 3 | | 6 | 269 | 2018-12-27 | 3 | +----+------+------------+---------+ 5 rows in set (0.00 sec) mysql> select * from userinfo; +----+------------+----------------------------------+--------------+ | id | username | password | nickname | +----+------------+----------------------------------+--------------+ | 1 | zhangsan | 317bc264bfd3d562fa415dbb905e2d8a | 就是这么牛逼 | | 2 | lisi | 317bc264bfd3d562fa415dbb905e2d8a | 看把你牛逼的 | | 3 | zhangyafei | 317bc264bfd3d562fa415dbb905e2d8a | 张亚飞 | | 4 | yaoming | 317bc264bfd3d562fa415dbb905e2d8a | 姚明 | +----+------------+----------------------------------+--------------+ 4 rows in set (0.00 sec) mysql> select * from record cross join userinfo; +----+------+------------+---------+----+------------+-------------------------- --------+--------------+ | id | line | ctime | user_id | id | username | password | nickname | +----+------+------------+---------+----+------------+-------------------------- --------+--------------+ | 1 | 1000 | 2018-12-19 | 1 | 1 | zhangsan | 317bc264bfd3d562fa415dbb9 05e2d8a | 就是这么牛逼 | | 1 | 1000 | 2018-12-19 | 1 | 2 | lisi | 317bc264bfd3d562fa415dbb9 05e2d8a | 看把你牛逼的 | | 1 | 1000 | 2018-12-19 | 1 | 3 | zhangyafei | 317bc264bfd3d562fa415dbb9 05e2d8a | 张亚飞 | | 1 | 1000 | 2018-12-19 | 1 | 4 | yaoming | 317bc264bfd3d562fa415dbb9 05e2d8a | 姚明 | | 2 | 5000 | 2018-12-17 | 3 | 1 | zhangsan | 317bc264bfd3d562fa415dbb9 05e2d8a | 就是这么牛逼 | | 2 | 5000 | 2018-12-17 | 3 | 2 | lisi | 317bc264bfd3d562fa415dbb9 05e2d8a | 看把你牛逼的 | | 2 | 5000 | 2018-12-17 | 3 | 3 | zhangyafei | 317bc264bfd3d562fa415dbb9 05e2d8a | 张亚飞 | | 2 | 5000 | 2018-12-17 | 3 | 4 | yaoming | 317bc264bfd3d562fa415dbb9 05e2d8a | 姚明 | | 3 | 3000 | 2018-12-21 | 3 | 1 | zhangsan | 317bc264bfd3d562fa415dbb9 05e2d8a | 就是这么牛逼 | | 3 | 3000 | 2018-12-21 | 3 | 2 | lisi | 317bc264bfd3d562fa415dbb9 05e2d8a | 看把你牛逼的 | | 3 | 3000 | 2018-12-21 | 3 | 3 | zhangyafei | 317bc264bfd3d562fa415dbb9 05e2d8a | 张亚飞 | | 3 | 3000 | 2018-12-21 | 3 | 4 | yaoming | 317bc264bfd3d562fa415dbb9 05e2d8a | 姚明 | | 5 | 269 | 2018-12-26 | 3 | 1 | zhangsan | 317bc264bfd3d562fa415dbb9 05e2d8a | 就是这么牛逼 | | 5 | 269 | 2018-12-26 | 3 | 2 | lisi | 317bc264bfd3d562fa415dbb9 05e2d8a | 看把你牛逼的 | | 5 | 269 | 2018-12-26 | 3 | 3 | zhangyafei | 317bc264bfd3d562fa415dbb9 05e2d8a | 张亚飞 | | 5 | 269 | 2018-12-26 | 3 | 4 | yaoming | 317bc264bfd3d562fa415dbb9 05e2d8a | 姚明 | | 6 | 269 | 2018-12-27 | 3 | 1 | zhangsan | 317bc264bfd3d562fa415dbb9 05e2d8a | 就是这么牛逼 | | 6 | 269 | 2018-12-27 | 3 | 2 | lisi | 317bc264bfd3d562fa415dbb9 05e2d8a | 看把你牛逼的 | | 6 | 269 | 2018-12-27 | 3 | 3 | zhangyafei | 317bc264bfd3d562fa415dbb9 05e2d8a | 张亚飞 | | 6 | 269 | 2018-12-27 | 3 | 4 | yaoming | 317bc264bfd3d562fa415dbb9 05e2d8a | 姚明 | +----+------+------------+---------+----+------------+-------------------------- --------+--------------+ 20 rows in set (0.00 sec) mysql> select * from record,userinfo; +----+------+------------+---------+----+------------+-------------------------- --------+--------------+ | id | line | ctime | user_id | id | username | password | nickname | +----+------+------------+---------+----+------------+-------------------------- --------+--------------+ | 1 | 1000 | 2018-12-19 | 1 | 1 | zhangsan | 317bc264bfd3d562fa415dbb9 05e2d8a | 就是这么牛逼 | | 1 | 1000 | 2018-12-19 | 1 | 2 | lisi | 317bc264bfd3d562fa415dbb9 05e2d8a | 看把你牛逼的 | | 1 | 1000 | 2018-12-19 | 1 | 3 | zhangyafei | 317bc264bfd3d562fa415dbb9 05e2d8a | 张亚飞 | | 1 | 1000 | 2018-12-19 | 1 | 4 | yaoming | 317bc264bfd3d562fa415dbb9 05e2d8a | 姚明 | | 2 | 5000 | 2018-12-17 | 3 | 1 | zhangsan | 317bc264bfd3d562fa415dbb9 05e2d8a | 就是这么牛逼 | | 2 | 5000 | 2018-12-17 | 3 | 2 | lisi | 317bc264bfd3d562fa415dbb9 05e2d8a | 看把你牛逼的 | | 2 | 5000 | 2018-12-17 | 3 | 3 | zhangyafei | 317bc264bfd3d562fa415dbb9 05e2d8a | 张亚飞 | | 2 | 5000 | 2018-12-17 | 3 | 4 | yaoming | 317bc264bfd3d562fa415dbb9 05e2d8a | 姚明 | | 3 | 3000 | 2018-12-21 | 3 | 1 | zhangsan | 317bc264bfd3d562fa415dbb9 05e2d8a | 就是这么牛逼 | | 3 | 3000 | 2018-12-21 | 3 | 2 | lisi | 317bc264bfd3d562fa415dbb9 05e2d8a | 看把你牛逼的 | | 3 | 3000 | 2018-12-21 | 3 | 3 | zhangyafei | 317bc264bfd3d562fa415dbb9 05e2d8a | 张亚飞 | | 3 | 3000 | 2018-12-21 | 3 | 4 | yaoming | 317bc264bfd3d562fa415dbb9 05e2d8a | 姚明 | | 5 | 269 | 2018-12-26 | 3 | 1 | zhangsan | 317bc264bfd3d562fa415dbb9 05e2d8a | 就是这么牛逼 | | 5 | 269 | 2018-12-26 | 3 | 2 | lisi | 317bc264bfd3d562fa415dbb9 05e2d8a | 看把你牛逼的 | | 5 | 269 | 2018-12-26 | 3 | 3 | zhangyafei | 317bc264bfd3d562fa415dbb9 05e2d8a | 张亚飞 | | 5 | 269 | 2018-12-26 | 3 | 4 | yaoming | 317bc264bfd3d562fa415dbb9 05e2d8a | 姚明 | | 6 | 269 | 2018-12-27 | 3 | 1 | zhangsan | 317bc264bfd3d562fa415dbb9 05e2d8a | 就是这么牛逼 | | 6 | 269 | 2018-12-27 | 3 | 2 | lisi | 317bc264bfd3d562fa415dbb9 05e2d8a | 看把你牛逼的 | | 6 | 269 | 2018-12-27 | 3 | 3 | zhangyafei | 317bc264bfd3d562fa415dbb9 05e2d8a | 张亚飞 | | 6 | 269 | 2018-12-27 | 3 | 4 | yaoming | 317bc264bfd3d562fa415dbb9 05e2d8a | 姚明 | +----+------+------------+---------+----+------------+-------------------------- --------+--------------+ 20 rows in set (0.00 sec)
七、联合查询
一、UNION和UNION ALL的作用和语法
UNION 用于合并两个或多个 SELECT 语句的结果集,并消去表中任何重复行。
UNION 内部的 SELECT 语句必须拥有相同数量的列,列也必须拥有相似的数据类型。
同时,每条 SELECT 语句中的列的顺序必须相同.
SQL UNION 语法:
sql脚本代码如下:
1 SELECT column_name FROM table1 2 UNION 3 SELECT column_name FROM table2
注释:默认地,UNION 操作符选取不同的值。如果允许重复的值,请使用 UNION ALL。
当 ALL 随 UNION 一起使用时(即 UNION ALL),不消除重复行
SQL UNION ALL 语法
sql脚本代码如下:
1 SELECT column_name FROM table1 2 UNION ALL 3 SELECT column_name FROM table2
注释:另外,UNION 结果集中的列名总是等于 UNION 中第一个 SELECT 语句中的列名。
注意:1、UNION 结果集中的列名总是等于第一个 SELECT 语句中的列名
2、UNION 内部的 SELECT 语句必须拥有相同数量的列。列也必须拥有相似的数据类型。同时,每条 SELECT 语句中的列的顺序必须相同
二、union的用法及注意事项
union:联合的意思,即把两次或多次查询结果合并起来。
要求:两次查询的列数必须一致
推荐:列的类型可以不一样,但推荐查询的每一列,想对应的类型以一样
可以来自多张表的数据:多次sql语句取出的列名可以不一致,此时以第一个sql语句的列名为准。
如果不同的语句中取出的行,有完全相同(这里表示的是每个列的值都相同),那么union会将相同的行合并,最终只保留一行。也可以这样理解,union会去掉重复的行。
如果不想去掉重复的行,可以使用union all。
如果子句中有order by,limit,需用括号()包起来。推荐放到所有子句之后,即对最终合并的结果来排序或筛选。
如:sql脚本代码如下:
1 (select * from a order by id) union (select * from b order id);
在子句中,order by 需要配合limit使用才有意义。如果不配合limit使用,会被语法分析器优化分析时去除。
三、学习例子
# 选择数据库 mysql> use flask_code Database changed # 查看表 mysql> show tables; +----------------------+ | Tables_in_flask_code | +----------------------+ | record | | userinfo | +----------------------+ 2 rows in set (0.01 sec) mysql> select * from userinfo; +----+------------+----------------------------------+--------------+ | id | username | password | nickname | +----+------------+----------------------------------+--------------+ | 1 | zhangsan | 317bc264bfd3d562fa415dbb905e2d8a | 就是这么牛逼 | | 2 | lisi | 317bc264bfd3d562fa415dbb905e2d8a | 看把你牛逼的 | | 3 | zhangyafei | 317bc264bfd3d562fa415dbb905e2d8a | 张亚飞 | | 4 | yaoming | 317bc264bfd3d562fa415dbb905e2d8a | 姚明 | +----+------------+----------------------------------+--------------+ 4 rows in set (0.08 sec) # 创建和已有表结构相同的额表 mysql> create table userinfo2 like userinfo; Query OK, 0 rows affected (0.48 sec) # 插入和另一个结构相同的表的数据 mysql> insert into userinfo2 select * from userinfo limit 1,3; Query OK, 3 rows affected (0.12 sec) Records: 3 Duplicates: 0 Warnings: 0 mysql> insert into userinfo2(username,password,nickname) values(\'kobe\', \'317b 64bfd3d562fa415dbb905e2d8a\', \'科比\'); Query OK, 1 row affected (0.05 sec) mysql> select * from userinfo2; +----+------------+----------------------------------+--------------+ | id | username | password | nickname | +----+------------+----------------------------------+--------------+ | 2 | lisi | 317bc264bfd3d562fa415dbb905e2d8a | 看把你牛逼的 | | 3 | zhangyafei | 317bc264bfd3d562fa415dbb905e2d8a | 张亚飞 | | 4 | yaoming | 317bc264bfd3d562fa415dbb905e2d8a | 姚明 | | 5 | kobe | 317bc264bfd3d562fa415dbb905e2d8a | 科比 | +----+------------+----------------------------------+--------------+ 4 rows in set (0.00 sec) # union:上下连接两张表,且去重重复的行 mysql> select * from userinfo -> union -> select * from userinfo2; +----+------------+----------------------------------+--------------+ | id | username | password | nickname | +----+------------+----------------------------------+--------------+ | 1 | zhangsan | 317bc264bfd3d562fa415dbb905e2d8a | 就是这么牛逼 | | 2 | lisi | 317bc264bfd3d562fa415dbb905e2d8a | 看把你牛逼的 | | 3 | zhangyafei | 317bc264bfd3d562fa415dbb905e2d8a | 张亚飞 | | 4 | yaoming | 317bc264bfd3d562fa415dbb905e2d8a | 姚明 | | 5 | kobe | 317bc264bfd3d562fa415dbb905e2d8a | 科比 | +----+------------+----------------------------------+--------------+ 5 rows in set (0.00 sec) # union all:上下连接两张表,不去除重复的行 mysql> select * from userinfo union all select * from userinfo2; +----+------------+----------------------------------+--------------+ | id | username | password | nickname | +----+------------+----------------------------------+--------------+ | 1 | zhangsan | 317bc264bfd3d562fa415dbb905e2d8a | 就是这么牛逼 | | 2 | lisi | 317bc264bfd3d562fa415dbb905e2d8a | 看把你牛逼的 | | 3 | zhangyafei | 317bc264bfd3d562fa415dbb905e2d8a | 张亚飞 | | 4 | yaoming | 317bc264bfd3d562fa415dbb905e2d8a | 姚明 | | 2 | lisi | 317bc264bfd3d562fa415dbb905e2d8a | 看把你牛逼的 | | 3 | zhangyafei | 317bc264bfd3d562fa415dbb905e2d8a | 张亚飞 | | 4 | yaoming | 317bc264bfd3d562fa415dbb905e2d8a | 姚明 | | 5 | kobe | 317bc264bfd3d562fa415dbb905e2d8a | 科比 | +----+------------+----------------------------------+--------------+ 8 rows in set (0.00 sec)
八、limit分页
Limit子句可以被用于强制 SELECT 语句返回指定的记录数。Limit接受一个或两个数字参数。参数必须是一个整数常量。如果给定两个参数,第一个参数指定第一个返回记录行的偏移量,第二个参数指定返回记录行的最大数目。
//初始记录行的偏移量是 0(而不是 1):
mysql> SELECT * FROM table LIMIT 5,10; //检索记录行6-15
//如果只给定一个参数,它表示返回最大的记录行数目。换句话说,LIMIT n 等价于 LIMIT 0,n:
mysql> SELECT * FROM table LIMIT 5; //检索前 5 个记录行
Limit的效率高?
常说的Limit的执行效率高,是对于一种特定条件下来说的:即数据库的数量很大,但是只需要查询一部分数据的情况。
高效率的原理是:避免全表扫描,提高查询效率。
比如:每个用户的email是唯一的,如果用户使用email作为用户名登陆的话,就需要查询出email对应的一条记录。
SELECT * FROM t_user WHERE email=?;
上面的语句实现了查询email对应的一条用户信息,但是由于email这一列没有加索引,会导致全表扫描,效率会很低。
SELECT * FROM t_user WHERE email=? LIMIT 1;
加上LIMIT 1,只要找到了对应的一条记录,就不会继续向下扫描了,效率会大大提高。
Limit的效率低?
在一种情况下,使用limit效率低,那就是:只使用limit来查询语句,并且偏移量特别大的情况
做以下实验:
语句1:
select * from table limit 150000,1000;
语句2:
select * from table while id>=150000 limit 1000;
语句1为0.2077秒;语句2为0.0063秒
两条语句的时间比是:语句1/语句2=32.968
比较以上的数据时,我们可以发现采用where...limit....性能基本稳定,受偏移量和行数的影响不大,而单纯采用limit的话,受偏移量的影响很大,当偏移量大到一定后性能开始大幅下降。不过在数据量不大的情况下,两者的区别不大。
所以应当先使用where等查询语句,配合limit使用,效率才高
ps:在sql语句中,limt关键字是最后才用到的。以下条件的出现顺序一般是:where->group by->having-order by->limit
附录:OFFSET
为了与 PostgreSQL 兼容,MySQL 也支持句法: LIMIT # OFFSET #。
经常用到在数据库中查询中间几条数据的需求
比如下面的sql语句:
① selete * from testtable limit 2,1;
② selete * from testtable limit 2 offset 1;
注意:
1.数据库数据计算是从0开始的
2.offset X是跳过X个数据,limit Y是选取Y个数据
3.limit X,Y 中X表示跳过X个数据,读取Y个数据
这两个都是能完成需要,但是他们之间是有区别的:
①是从数据库中第三条开始查询,取一条数据,即第三条数据读取,一二条跳过
②是从数据库中的第二条数据开始查询两条数据,即第二条和第三条。
mysql> select * from proxy limit 5; +----+-----------------+-------+----------+-------+-------+-----------+--------- --------+ | ID | IP | PORT | POSITION | TYPE | SPEED | LIVE_TIME | LAST_CHE CK_TIME | +----+-----------------+-------+----------+-------+-------+-----------+--------- --------+ | 1 | 111.72.154.107 | 53128 | 江西宜春 | HTTPS | 1.221 | 17分钟 | 18-07-17 09:01 | | 2 | 125.121.120.14 | 6666 | 浙江杭州 | HTTPS | 1.542 | 1分钟 | 18-07-17 21:01 | | 3 | 1.197.59.174 | 41869 | 河南漯河 | HTTPS | 3.032 | 292天 | 18-07-17 08:55 | | 4 | 125.118.247.32 | 6666 | 浙江杭州 | HTTPS | 0.19 | 33天 | 18-07-18 09:22 | | 5 | 125.121.117.139 | 6666 | 浙江杭州 | HTTP | 0.161 | 4分钟 | 18-07-18 05:20 | +----+-----------------+-------+----------+-------+-------+-----------+--------- --------+ 5 rows in set (0.00 sec) mysql> select * from proxy limit 5,10; +----+----------------+-------+----------+-------+-------+-----------+---------- -------+ | ID | IP | PORT | POSITION | TYPE | SPEED | LIVE_TIME | LAST_CHEC K_TIME | +----+----------------+-------+----------+-------+-------+-----------+---------- -------+ | 6 | 117.86.19.111 | 18118 | 江苏南通 | HTTPS | 4.954 | 1分钟 | 18-07-17 21:01 | | 7 | 110.73.41.238 | 8123 | 广西南宁 | HTTP | 3.16 | 609天 | 18-07-17 12:30 | | 8 | 182.86.189.123 | 48148 | 江西 | HTTPS | 0.224 | 1分钟 | 18-07-17 16:22 | | 9 | 221.228.17.172 | 8181 | 江苏无锡 | HTTPS | 6.462 | 73天 | 18-07-18 17:41 | | 10 | 115.223.65.147 | 8010 | 浙江温州 | HTTPS | 0.785 | 1分钟 | 18-07-17 08:46 | | 11 | 49.87.135.30 | 53128 | 江苏淮安 | HTTPS | 0.3 | 1分钟 | 18-07-18 09:22 | | 12 | 183.15.121.130 | 28094 | 广东深圳 | HTTP | 0.481 | 1分钟 | 18-07-17 06:30 | | 13 | 183.128.241.77 | 6666 | 浙江杭州 | HTTPS | 3.093 | 25天 | 18-07-18 01:40 | | 14 | 49.74.91.98 | 53281 | 江苏南京 | HTTP | 7.233 | 14天 | 18-07-18 05:20 | | 15 | 114.231.68.16 | 18118 | 江苏南通 | HTTPS | 6.159 | 5分钟 | 18-07-17 21:01 | +----+----------------+-------+----------+-------+-------+-----------+---------- -------+ 10 rows in set (0.00 sec) mysql> select count(*) from proxy; +----------+ | count(*) | +----------+ | 1800 | +-以上是关于数据库学习之MySQL基础的主要内容,如果未能解决你的问题,请参考以下文章