当前位置: 首页 > news >正文

第二部分 Mysql数据库管理_第二篇 数据库MySql

<1> 在数据库系统中,SQL语句不区分大小写(建议用大写) 。但字符串常量区分大小写。建议命令大写,表名库名小写;

<2> SQL语句可单行或多行书写,以“;”结尾。关键词不能跨多行或简写。

<3> 用空格和缩进来提高语句的可读性。子句通常位于独立行,便于编辑,提高可读性。

SELECT * FROMtb_tableWHERE NAME="YUAN";

<4> 注释:单行注释:--

多行注释:/*......*/

<5>sql语句可以折行操作

<6> DDL,DML和DCL,三部分共同构成了sql语句

DDL:定义语言;

DML:操作语言,如:增删改查

DCL:控制语言;如:权限控制

---- DML(data manipulation language):--它们是SELECT、UPDATE、INSERT、DELETE,就象它的名字一样,这4条命令是用来对数据库里的--数据进行操作的语言-- ---- DDL(data definition language):--DDL比DML要多,主要的命令有CREATE、ALTER、DROP等,DDL主要是用在定义或改变表(TABLE)的结构,数据类型,表之间的链接和约束等初始化工作上,

他们大多在建立表时使用-- ---- DCL(Data Control Language):--是数据库控制功能。是用来设置或更改数据库用户或角色权限的语句,包括(grant,deny,revoke等)--语句。在默认状态下,只有sysadmin,dbcreator,db_owner或db_securityadmin等人员才有权力执行DCL

数据库操作(DDL)

--1.创建数据库(在磁盘上创建一个对应的文件夹)

create database [if not exists] db_name [character set xxx]

--2.查看数据库

show databases;查看所有数据库

showcreate database db_name; 查看某个数据库的创建方式--3.修改数据库

alter database db_name [character set 编码格式]

--4.删除数据库

drop database [if exists] db_name;--5.使用数据库

切换数据库 use db_name; --注意:进入到某个数据库后没办法再退回之前状态,但可以通过use进行切换

查看当前使用的数据库 select database();

-- 6. 查看错误信息

show warnings;

mysql数据类型

MySQL支持多种类型,大致可以分为三类:数值、日期/时间和字符串(字符)类型。

数值类型

下面的表显示了需要的每个整数类型的存储和范围。

ef117fcde49fe6dfb884c1ec65f31439.png

日期和时间类型

表示时间值的日期和时间类型为DATETIME、DATE、TIMESTAMP、TIME和YEAR。

每个时间类型有一个有效值范围和一个"零"值,当指定不合法的MySQL不能表示的值时使用"零"值。

510ceef200ccb3057bcbfc3d8aaa081c.png

字符串类型

字符串类型指CHAR、VARCHAR、BINARY、VARBINARY、BLOB、TEXT、ENUM和SET。该节描述了这些类型如何工作以及如何在查询中使用这些类型。

285f497b7cce6a7410d8e27a743b44f6.png

CHAR和VARCHAR类型类似,但它们保存和检索的方式不同。它们的最大长度和是否尾部空格被保留等方面也不同。在存储或检索过程中不进行大小写转换。

BINARY和VARBINARY类类似于CHAR和VARCHAR,不同的是它们包含二进制字符串而不要非二进制字符串。也就是说,它们包含字节字符串而不是字符字符串。

BLOB是一个二进制大对象,可以容纳可变数量的数据。有4种BLOB类型:TINYBLOB、BLOB、MEDIUMBLOB和LONGBLOB。它们只是可容纳值的最大长度不同。

有4种TEXT类型:TINYTEXT、TEXT、MEDIUMTEXT和LONGTEXT。这些对应4种BLOB类型,有相同的最大长度和存储需求。

数据表操作(对表字段的操作)

基础操作

--1.创建表(类似于一个excel表)

create tabletable_name(

field1 type[完整性约束条件],

field2 type,

...

fieldn type

)[character set xxx];--示例:创建一个员工表employee

create tableemployee(

idint primary keyauto_increment ,

namevarchar(20),

genderbit default 1, --gender char(1) default 1 ----- 或者 TINYINT(1)

birthday date,

entry_date date,

jobvarchar(20),

salarydouble(4,2) unsigned,

resumetext --注意,这里作为最后一个字段不加逗号

);/*约束:

primary key (非空且唯一) :能够唯一区分出当前记录的字段称为主键!

unique

not null

auto_increment 主键字段必须是数字类型。

外键约束 foreign key*/

--2.查看表信息

desctab_name 查看表结构

show columnsfromtab_name 查看表结构

show tables 查看当前数据库中的所有的表

showcreate tabletab_name 查看当前数据库表建表语句--3.修改表结构

--(1)增加列(字段)

alter table tab_name add [column]列名 类型[完整性约束条件][first|after 字段名];alter table user add addr varchar(20) not null unique first/after username;

#添加多个字段alter tableusers2add addr varchar(20),add age intfirst,add birth varchar(20) after name;--(2)修改一列类型

alter table tab_name modify 列名 类型 [完整性约束条件][first|after 字段名];alter table users2 modify age tinyint default 20;alter table users2 modify age intafter id;--(3)修改列名

alter table tab_name change [column] 列名 新列名 类型 [完整性约束条件][first|after 字段名];alter table users2 change age Age int default 28first;--(4)删除一列

alter table tab_name drop [column]列名;--思考:删除多列呢?删一个填一个呢?

alter tableusers2add salary float(6,2) unsigned not nullafter name,dropaddr;--(5)修改表名

rename table 表名 to新表名;--(6)修该表所用的字符集

alter table student character setutf8;--4.删除表

drop tabletab_name;---5 添加主键,删除主键

alter table tab_name add primary key(字段名称,...)alter table users drop primary key;

eg:

mysql> create table test5(num intauto_increment);

ERROR1075 (42000): Incorrect table definition; there can be only one auto column and it must be defined as a key

create table test(num int primary keyauto_increment);--思考,如何删除主键?

alter table test modify id int; --auto_increment没了,但这样写主键依然存在,所以还要加上下面这句

alter table test drop primary key;--仅仅用这句也无法直接删除主键

--唯一索引

alter table tab_name add unique [index|key] [索引名称](字段名称,...)alter table users add unique(name)--索引值默认为字段名show create table users;

alter table users add unique key user_name(name);--索引值为user_name

--添加联合索引

alter table users add unique index name_age(name,age);#show create tableusers;--删除唯一索引

alter table tab_name drop {index|key} index_name

创建文章表

8f900a89c6347c561fdf2122f13be562.png

961ddebeb323a10fe0623af514929fc1.png

create tablearticle(

idint primary keyauto_increment ,

titlevarchar(20),

publish_dateINT,

click_numINT,

is_topTINYINT(1),

contentTEXT);

示例

完整性约束条件之主键约束

单字段主键

主键字段特点:非空(not null)且唯一(unique)

create tableusers(

idINT primary key,

namevarchar(20),

cityvarchar(20)

);

多字段联合主键

create tableusers2(

idINT,

namevarchar(20),

cityvarchar(20),primary key(name,id)

);

<1> 一张表只能有一个主键

<2> 主键类型不一定非是整型

表纪录操作(具体表里数据的操作)

表纪录之增,删,改

-- 1.增加一条记录insert

/*insert [into] tab_name (field1,filed2,.......) values (value1,value2,.......);*/

create tableemployee_new(

idint primary keyauto_increment,

namevarchar(20) not null unique,

birthdayvarchar(20),

salaryfloat(7,2)

);insert into employee_new (id,name,birthday,salary) values(1,'yuan','1990-09-09',9000);

-- 不写字段,按找字段一一对应插入insert into employee_new values(2,'alex','1989-08-08',3000);

-- 按照字段插入insert into employee_new (name,salary) values('xialv',1000);--插入多条数据

insert into employee_new values(4,'alvin1','1993-04-20',3000),

(5,'alvin2','1995-05-12',5000);--set插入: 以键值对方式插入

insert [into] tab_name set 字段名=值

insert into employee_new set id=12,name="alvin3";-- 2.修改表记录 update tab_name set field1=value1,field2=value2,......[where 语句]

/*UPDATE语法可以用新值更新原有表行中的各列。

SET子句指示要修改哪些列和要给予哪些值。 WHERE子句指定应更新哪些行。如没有WHERE子句,则更新所有的行。*/

update employee_new set birthday="1989-10-24" WHERE id=1;--- 将yuan的薪水在原有基础上增加1000元。

update employee_new set salary=salary+4000 where name='yuan';--3.删除表纪录

delete from tab_name [where ....]

/*如果不跟where语句则删除整张表中的数据

1) delete只能用来删除一行记录

2) delete语句只能删除表中的内容,不能删除表本身,想要删除表,用drop

3) TRUNCATE TABLE也可以删除表中的所有数据,此语句首先摧毁表,再重新创建要给同名的新表。此种方式删除的数据不能在事务中恢复。

truncate 使用场景:比如某表有几万条数据,delete删除太慢,就用truncate,直接把这张表先删掉,然后再重新创建个同名表。*/

--删除表中名称为’alex’的记录。

delete from employee_new where name='alex';--删除表中所有记录。

delete from employee_new;--注意auto_increment没有被重置:alter table employee auto_increment=1;

--使用truncate删除表中记录。

truncate table emp_new;

思考:

<1>  存储时间用varchar可不可以呢?它与date数据类型又有什么区别呢?

-- 可以的(如果只是用来显示,不对时间进行操作的时候就可以用varchar)

<2>  表中数据三条,id分别为1,2,3,突然插入一个id=7,那么下次作为主键的字增长的id会从几开始增长呢?(从7开始)

表纪录之查(单表查询)

--查询表达式

SELECT *|field1,filed2 ... FROMtab_nameWHERE条件GROUP BYfieldHAVING筛选ORDER BYfield

LIMIT 限制条数---准备表

CREATE TABLEExamResult(

idINT PRIMARY KEYauto_increment,

nameVARCHAR (20),

JSDOUBLE,

DjangoDOUBLE,

OpenStackDOUBLE);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);--(1)select [distinct] *|field1,field2,...... from tab_name

--其中from指定从哪张表筛选,*表示查找所有列,也可以指定一个列

--表明确指定要查找的列,distinct用来剔除重复行。

--查询表中所有学生的信息。

select * fromExamResult;--查询表中所有学生的姓名和对应的英语成绩。

select name,JS fromExamResult;--过滤表中重复数据。distinct后面跟要去重的字段

select distinct JS ,name fromExamResult;--(2)select 也可以使用表达式,并且可以使用: 字段 as 别名或者:字段 别名

--在所有学生分数上加10分特长分显示。

select name,JS+10,Django+10,OpenStack+10 fromExamResult; -- 仅仅是当次显示的时候加了分数,数据库里可没存上哦。--统计每个学生的总分。

select name,JS+Django+OpenStack fromExamResult;--使用别名表示学生总分。

select name as 姓名,JS+Django+OpenStack as 总成绩 fromExamResult;select name,JS+Django+OpenStack 总成绩 fromExamResult; -- as 可以去掉,但是要取别名,推荐加上select name JS from ExamResult; --what will happen?---->记得加逗号

--(3)使用where子句,进行过滤查询。

--查询姓名为XXX的学生成绩

select * from ExamResult where name='yuan';--查询英语成绩大于90分的同学

select id,name,JS from ExamResult where JS>90;--查询总分大于200分的所有同学

select name,JS+Django+OpenStack as 总成绩 fromExamResultwhere JS+Django+OpenStack>200;--where字句中可以使用:

--比较运算符:

> < >= <= <> != (<> 和 != 都表示不等于,推荐用 !=)

between 80 and 100值在10到20之间in(80,90,100) 值是10或20或30like 'yuan%'

/*pattern可以是%或者_,

如果是%则表示任意多字符,此例如唐僧,唐国强

如果是_则表示一个字符唐_,只有唐僧符合。两个_则表示两个字符:__*/

--逻辑运算符

在多个条件直接可以使用逻辑运算符 and or not

--练习

--查询JS分数在 70-100之间的同学。

select name ,JS from ExamResult where JS between 80 and 100;--查询Django分数为75,76,77的同学。

select name ,Django from ExamResult where Django in (75,98,77);--查询所有姓王的学生成绩。

select * from ExamResult where name like '王%';--查询JS分>90,Django分>90的同学。

select id,name from ExamResult where JS>90 and Django >90;--查找缺考数学的学生的姓名

select name from ExamResult where Database is null;--(4)Order by 指定排序的列,排序的列即可是表中的列名,也可以是select 语句后指定的别名。

--select *|field1,field2... from tab_name order by field [Asc|Desc]

--Asc 升序、Desc 降序,其中asc为默认值 ORDER BY 子句应位于SELECT语句的结尾。

--练习:

--对JS成绩排序后输出。

select * from ExamResult order byJS;--对总分排序按从高到低的顺序输出

select name ,(ifnull(JS,0)+ifnull(Django,0)+ifnull(Database,0))

总成绩from ExamResult order by 总成绩 desc;

select name, JS+Django+Database as 总成绩 from examresult order by 总成绩 desc; -- 按总成绩从高到低排序--对姓李的学生成绩排序输出

-- ifnull(参数一,0):表示如果参数一的字段值为null,就转换成0

select name ,(ifnull(JS,0)+ifnull(Django,0)+ifnull(OpenStack,0))

总成绩from ExamResult where name like 'a%'

order by 总成绩 desc;--(5)group by 分组查询--用的最多,最重要,也是最不好理解的一个:

CREATE TABLEorder_menu(

idINT PRIMARY KEYauto_increment,

product_nameVARCHAR (20),

priceFLOAT(6,2),

born_date DATE,

classVARCHAR (20)

);INSERT INTO order_menu (product_name,price,born_date,class) VALUES("苹果",20,20170612,"水果"),

("香蕉",80,20170602,"水果"),

("水壶",120,20170612,"电器"),

("被罩",70,20170612,"床上用品"),

("音响",420,20170612,"电器"),

("床单",55,20170612,"床上用品"),

("草莓",34,20170612,"水果");-- 注意,按分组条件分组后每一组只会显示第一条记录

--group by字句,其后可以接多个列名,也可以跟having子句,对group by 的结果进行筛选。

--按位置字段筛选

select * from order_menu group by 5; -- 按照第5个字段分组--练习:对购物表按类名分组后显示每一组商品的价格总和

select class,SUM(price)from order_menu group byclass;--练习:对购物表按类名分组后显示每一组商品价格总和超过150的商品

select class,SUM(price)from order_menu group byclassHAVINGSUM(price)>150;/*having 和 where两者都可以对查询结果进行进一步的过滤,差别有:

<1>where语句只能用在分组之前的筛选,having可以用在分组之后的筛选;

<2>使用where语句的地方都可以用having进行替换

<3>having中可以用聚合函数,where中就不行。*/

--GROUP_CONCAT() 函数

SELECT id,GROUP_CONCAT(name),GROUP_CONCAT(JS) from ExamResult GROUP BYid;--(6)聚合函数: 先不要管聚合函数要干嘛,先把要求的内容查出来再包上聚合函数即可。

--(一般和分组查询配合使用)

--<1> 统计表中所有记录

--COUNT(列名):统计行的个数

--统计一个班级共有多少学生?先查出所有的学生,再用count包上

select count(*) fromExamResult;--统计JS成绩大于70的学生有多少个?

select count(JS) from ExamResult where JS>70;--统计总分大于280的人数有多少?

select count(name) fromExamResultwhere (ifnull(JS,0)+ifnull(Django,0)+ifnull(OpenStack,0))>280;--注意:count(*)统计所有行; count(字段)不统计null值.

--SUM(列名):统计满足条件的行的内容和

--统计一个班级JS总成绩?先查出所有的JS成绩,再用sum包上

select JS as JS总成绩 fromExamResult;select sum(JS) as JS总成绩 fromExamResult;--统计一个班级各科分别的总成绩

select sum(JS) asJS总成绩,sum(Django) asDjango总成绩,sum(OpenStack) as OpenStack fromExamResult;--统计一个班级各科的成绩总和

select sum(ifnull(JS,0)+ifnull(Django,0)+ifnull(Database,0))as 总成绩 fromExamResult;--统计一个班级JS成绩平均分

select sum(JS)/count(*) fromExamResult ;--注意:sum仅对数值起作用,否则会报错。

--AVG(列名):

--求一个班级JS平均分?先查出所有的JS分,然后用avg包上。

select avg(ifnull(JS,0)) fromExamResult;--求一个班级总分平均分

select avg((ifnull(JS,0)+ifnull(Django,0)+ifnull(Database,0)))fromExamResult ;--Max、Min

--求班级最高分和最低分(数值范围在统计中特别有用)

select Max((ifnull(JS,0)+ifnull(Django,0)+ifnull(OpenStack,0)))

最高分fromExamResult;select Min((ifnull(JS,0)+ifnull(Django,0)+ifnull(OpenStack,0)))

最低分fromExamResult;--求购物表中单价最高的商品名称及价格

---SELECT id, MAX(price) FROM order_menu;--id和最高价商品是一个商品吗?

SELECT MAX(price) FROMorder_menu;--注意:null 和所有的数计算都是null,所以需要用ifnull将null转换为0!

-------ifnull(JS,0)

--with rollup的使用

--<2> 统计分组后的组记录

--(7) 重点:Select from where group by having order by

--Mysql在执行sql语句时的执行顺序:

--from where select group by having order by

--分析:

select JS as JS成绩 from ExamResult where JS成绩 >70; ---- 不成功

select JS as JS成绩 from ExamResult having JS成绩 >90; --- 成功

--(8) limit

SELECT * from ExamResult limit 1; -- 只显示查到的前3条数据SELECT * from ExamResult limit 2,5;--跳过前两条显示接下来的五条纪录

SELECT * from ExamResult limit 2,2;--- (9) 使用正则表达式查询

SELECT * FROM employee WHERE emp_name REGEXP '^yu';SELECT * FROM employee WHERE emp_name REGEXP 'yun$';SELECT * FROM employee WHERE emp_name REGEXP 'm{2}'; -- 有2个m的名字

外键约束

创建外键

--- 每一个班主任会对应多个学生 , 而每个学生只能对应一个班主任

----主表

CREATE TABLEClassCharger(

idTINYINT PRIMARY KEYauto_increment,

nameVARCHAR (20),

ageINT,

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);----子表: 有foreign key的就是字表

CREATE TABLEStudent(

idINT PRIMARY KEYauto_increment,

nameVARCHAR (20),

charger_idTINYINT, --切记:作为外键一定要和关联主键的数据类型保持一致

--[ADD CONSTRAINT charger_fk_stu]FOREIGN KEY (charger_id) REFERENCES ClassCharger(id)

) ENGINE=INNODB;

--charger_fk_stu 外键名字

示例:关联外键

create table student2(

id int primary key auto_increment,

name varchar (20),

charger_id tinyint,

-- student2表里的charger_id 字段的外键是classcharger表里的id字段

-- 要对student2表里charger_id字段绑定外键,于 classcharger 表里的id字段相关联

foreign key (charger_id) references classcharger(id)

)ENGINE=INNODB;

INSERT INTO Student(name,charger_id) VALUES ("alvin1",2),

("alvin2",4),

("alvin3",1),

("alvin4",3),

("alvin5",1),

("alvin6",3),

("alvin7",2);DELETE FROM ClassCharger WHERE name="冰冰";INSERT student (name,charger_id) VALUES ("yuan",1);--删除居然成功,可是 alvin3显示还是有班主任id=1的冰冰的;

-----------增加外键和删除外键---------

ALTER TABLE student ADD CONSTRAINTabc -- 给外键起个名字叫 abcFOREIGN KEY(charger_id) -- 指定哪个字段作为外键REFERENCESclasscharger(id); -- 关联到哪张表的哪个字段

-- 删除外键ALTER TABLE student DROP FOREIGN KEY abc;

INNODB支持的ON语句

--外键约束对子表的含义: 如果在父表中找不到候选键,则不允许在子表上进行insert/update

--外键约束对父表的含义: 在父表上进行update/delete以更新或删除在子表中有一条或多条对应匹配行的候选键时,父表的行为取决于:在定义子表的外键时指定的on update/on delete子句

-----------------innodb支持的四种方式---------------------------------------

-----cascade方式 在父表上update/delete记录时,同步update/delete掉子表的匹配记录

-----外键的级联删除:如果父表中的记录被删除,则子表中对应的记录自动被删除--------

FOREIGN KEY (charger_id) REFERENCESClassCharger(id)ON DELETE CASCADE --级联删除

示例:

create table student3(

id int primary key auto_increment,

name varchar (20),

charger_id tinyint,

foreign key (charger_id) references classcharger(id) on delete cascade

) ENGINE = INNODB;

------set null方式: 在父表上update/delete记录时,将子表上匹配记录的列设为null;

------要注意子表的外键列不能为not null

FOREIGN KEY (charger_id) REFERENCESClassCharger(id)ON DELETE SET NULL

示例:

可以将student3里的外键删除,然后改成set null

-- 先删除外键

alter tablestudent3 drop froeign key 外键名字;

-- 将外键改为set null

alter table student3 add constraint s3_fk_ss foreign key (charger_id) references classcharger (id) on delete set null;

------Restrict方式 :拒绝对父表进行删除更新操作(了解)

------No action方式 在mysql中同Restrict,如果子表中有匹配的记录,则不允许对父表对应候选键

--进行update/delete操作(了解)

多表查询

准备表

--准备两张表--company.employee--company.department

create tableemployee(

emp_idint auto_increment primary key not null,

emp_namevarchar(50),

ageint,

dept_idint);insert into employee(emp_name,age,dept_id) values('A',19,200),

('B',26,201),

('C',30,201),

('D',24,202),

('E',20,200),

('F',38,204);create tabledepartment(

dept_idint,

dept_namevarchar(100)

);insert into department values(200,'人事部'),

(201,'技术部'),

(202,'销售部'),

(203,'财政部');

mysql> select * fromemployee;+--------+----------+------+---------+

| emp_id | emp_name | age | dept_id |

+--------+----------+------+---------+

| 1 | A | 19 | 200 |

| 2 | B | 26 | 201 |

| 3 | C | 30 | 201 |

| 4 | D | 24 | 202 |

| 5 | E | 20 | 200 |

| 6 | F | 38 | 204 |

+--------+----------+------+---------+

rows in set (0.00sec)

mysql> select * fromdepartment;+---------+-----------+

| dept_id | dept_name |

+---------+-----------+

| 200 | 人事部 |

| 201 | 技术部 |

| 202 | 销售部 |

| 203 | 财政部 |

+---------+-----------+

rows in set (0.01 sec)

多表查询之连接查询

1.笛卡尔积查询

mysql> SELECT * FROMemployee,department;--select employee.emp_id,employee.emp_name,employee.age,--department.dept_name from employee,department;

+--------+----------+------+---------+---------+-----------+

| emp_id | emp_name | age | dept_id | dept_id | dept_name |

+--------+----------+------+---------+---------+-----------+

| 1 | A | 19 | 200 | 200 | 人事部 |

| 1 | A | 19 | 200 | 201 | 技术部 |

| 1 | A | 19 | 200 | 202 | 销售部 |

| 1 | A | 19 | 200 | 203 | 财政部 |

| 2 | B | 26 | 201 | 200 | 人事部 |

| 2 | B | 26 | 201 | 201 | 技术部 |

| 2 | B | 26 | 201 | 202 | 销售部 |

| 2 | B | 26 | 201 | 203 | 财政部 |

| 3 | C | 30 | 201 | 200 | 人事部 |

| 3 | C | 30 | 201 | 201 | 技术部 |

| 3 | C | 30 | 201 | 202 | 销售部 |

| 3 | C | 30 | 201 | 203 | 财政部 |

| 4 | D | 24 | 202 | 200 | 人事部 |

| 4 | D | 24 | 202 | 201 | 技术部 |

| 4 | D | 24 | 202 | 202 | 销售部 |

| 4 | D | 24 | 202 | 203 | 财政部 |

| 5 | E | 20 | 200 | 200 | 人事部 |

| 5 | E | 20 | 200 | 201 | 技术部 |

| 5 | E | 20 | 200 | 202 | 销售部 |

| 5 | E | 20 | 200 | 203 | 财政部 |

| 6 | F | 38 | 204 | 200 | 人事部 |

| 6 | F | 38 | 204 | 201 | 技术部 |

| 6 | F | 38 | 204 | 202 | 销售部 |

| 6 | F | 38 | 204 | 203 | 财政部 |

+--------+----------+------+---------+---------+-----------+

2.内连接--查询两张表中都有的关联数据,相当于利用条件从笛卡尔积结果中筛选出了正确的结果。 -- 用的多

select * from employee,department where employee.dept_id =department.dept_id;select * from employee inner join department on employee.dept_id =department.dept_id;+--------+----------+------+---------+---------+-----------+

| emp_id | emp_name | age | dept_id | dept_id | dept_name |

+--------+----------+------+---------+---------+-----------+

| 1 | A | 19 | 200 | 200 | 人事部 |

| 2 | B | 26 | 201 | 201 | 技术部 |

| 3 | C | 30 | 201 | 201 | 技术部 |

| 4 | D | 24 | 202 | 202 | 销售部 |

| 5 | E | 20 | 200 | 200 | 人事部 |

+--------+----------+------+---------+---------+-----------+

示例:筛选出A所在的部门select employee.emp_name,department.dept_name fromemployee,departmentwhere employee.dept_id = department.dept_id and employee.emp_name ="A";select employee.emp_name,department.dept_name from department inner joinemployeeon employee.dept_id = department.dept_id and employee.emp_name = "A";

33f98b90d2c1562dfbf079492ecc2c3e.png

3.外连接

--(1)左外连接:在内连接的基础上增加左边有右边没有的结果 -- 用的多

左连接以左边的employee表为主,employee表的全部字段都显示,没有匹配上的就显示空null

select * from employee left join department on employee.dept_id =department.dept_id;+--------+----------+------+---------+---------+-----------+

| emp_id | emp_name | age | dept_id | dept_id | dept_name |

+--------+----------+------+---------+---------+-----------+

| 1 | A | 19 | 200 | 200 | 人事部 |

| 5 | E | 20 | 200 | 200 | 人事部 |

| 2 | B | 26 | 201 | 201 | 技术部 |

| 3 | C | 30 | 201 | 201 | 技术部 |

| 4 | D | 24 | 202 | 202 | 销售部 |

| 6 | F | 38 | 204 | NULL | NULL |

+--------+----------+------+---------+---------+-----------+

--(2)右外连接:在内连接的基础上增加右边有左边没有的结果

右外连接以右边的department表为主,department表的全部字段都显示

select * from employee RIGHT JOIN department on employee.dept_id =department.dept_id;+--------+----------+------+---------+---------+-----------+

| emp_id | emp_name | age | dept_id | dept_id | dept_name |

+--------+----------+------+---------+---------+-----------+

| 1 | A | 19 | 200 | 200 | 人事部 |

| 2 | B | 26 | 201 | 201 | 技术部 |

| 3 | C | 30 | 201 | 201 | 技术部 |

| 4 | D | 24 | 202 | 202 | 销售部 |

| 5 | E | 20 | 200 | 200 | 人事部 |

| NULL | NULL | NULL | NULL | 203 | 财政部 |

+--------+----------+------+---------+---------+-----------+

--(3)全外连接:在内连接的基础上增加左边有右边没有的和右边有左边没有的结果

--mysql不支持全外连接 full JOIN

--mysql可以使用Union方式间接实现全外连接

select * from employee RIGHT JOIN department on employee.dept_id =department.dept_idUNION

select * from employee LEFT JOIN department on employee.dept_id =department.dept_id;+--------+----------+------+---------+---------+-----------+

| emp_id | emp_name | age | dept_id | dept_id | dept_name |

+--------+----------+------+---------+---------+-----------+

| 1 | A | 19 | 200 | 200 | 人事部 |

| 2 | B | 26 | 201 | 201 | 技术部 |

| 3 | C | 30 | 201 | 201 | 技术部 |

| 4 | D | 24 | 202 | 202 | 销售部 |

| 5 | E | 20 | 200 | 200 | 人事部 |

| NULL | NULL | NULL | NULL | 203 | 财政部 |

| 6 | F | 38 | 204 | NULL | NULL |

+--------+----------+------+---------+---------+-----------+

--注意 union与union all的区别:union会去掉相同的纪录

多表查询之复合条件连接查询

--找出年龄大于等于25岁的员工所在的部门

-- 筛选出的是技术部,需要去重,加个 distinct 去重

SELECT DISTINCTdepartment.dept_nameFROMemployee,departmentWHERE employee.dept_id =department.dept_idAND age>25;--以内连接的方式查询employee和department表,并且以age字段的升序方式显示

selectemployee.emp_id,employee.emp_name,employee.age,department.dept_namefromemployee,departmentwhere employee.dept_id =department.dept_idorder by age asc;

多表查询之子查询

--子查询是将一个查询语句嵌套在另一个查询语句中。--内层查询语句的查询结果,可以为外层查询语句提供查询条件。--子查询中可以包含:IN、NOT IN、ANY、ALL、EXISTS 和 NOT EXISTS等关键字--还可以包含比较运算符:= 、 !=、> 、

--1. 带IN关键字的子查询

---查询employee表,但dept_id必须在department表中出现过

select * fromemployeewhere dept_id IN(select dept_id fromdepartment);+--------+----------+------+---------+

| emp_id | emp_name | age | dept_id |

+--------+----------+------+---------+

| 1 | A | 19 | 200 |

| 2 | B | 26 | 201 |

| 3 | C | 30 | 201 |

| 4 | D | 24 | 202 |

| 5 | E | 20 | 200 |

+--------+----------+------+---------+

rows in set (0.01sec)--2. 带比较运算符的子查询

--=、!=、>、>=、

--查询员工年龄大于等于25岁的部门

select dept_id,dept_name fromdepartmentwhere dept_id IN(select DISTINCT dept_id from employee where age>=25);--3. 带EXISTS关键字的子查询

--EXISTS关字键字表示存在。在使用EXISTS关键字时,内层查询语句不返回查询的记录。--而是返回一个真假值。Ture或False--当返回Ture时,外层查询语句将进行查询;当返回值为False时,外层查询语句不进行查询

select * fromemployeeWHERE EXISTS(SELECT dept_name from department where dept_id=203);--department表中存在dept_id=203,Ture

select * fromemployeeWHERE EXISTS(SELECT dept_name from department where dept_id=205);--Empty set (0.00 sec)

ps:create table t1(select * from t2);

索引

索引简介

索引在MySql中也叫做“键”,是存储引擎用于快速找到记录的一种数据结构。索引对于良好的性能非常关键,尤其是当表中的数据量越来越大时,索引对于性能

的影响愈发重要。

索引优化应该是对查询性能优化最有效的手段了。

索引能够轻易将查询性能提高好几个数量级。

索引相当于字典的音序表,如果要查某个字,如果不使用音序表,则需要从几百页中逐页去查。(或者理解为目录)

索引的特点:

创建与维护索引会消耗很多时间与磁盘空间,但查询速度大大提高。

索引语法

--创建表时--语法

create table表名(

字段名1 数据类型[完整性约束条件],

字段名2 数据类型[完整性约束条件],

字段名3 数据类型[完整性约束条件],[unique | FULLTEXT | SPATIAL] INDEX | KEY [索引名](字段名[长度]) [asc | desc]);--[unique | FULLTEXT | SPATIAL]: 可加可不加的--unique:唯一索引;不能重复--FULLTEXT:全局索引;--SPATIAL:空间索引--如果不加上面三个,直接用index 或者 key: 创建普通索引--index 或者 key 后面跟的是索引名字--索引名可写可不写,不写的话,默认就与字段名一样

--创建普通索引示例:

create tabletest1(

idint primary keyauto_increment,

namevarchar (20),index index_name (name ) --创建普通索引 可以用 index,也可以用key, 两个是完全一样的,index_name可写可不写

sarlay int default 1000);--创建唯一索引

--对已经存在的表添加个唯一索引示例:

alter table test1 modify name varchar (20) unique;--创建唯一索引示例

create tableemp2(

idint,

namevarchar (20),

bank_numchar (19) unique,

resumevarchar (50),unique indexindex_emp_name(name )

);--创建全文索引示例

create tableemp3(

idint,

namevarchar (20),

resumevarchar (500),

FULLTEXTindexindex_resume (resume )

)--创建多列索引示例:

create tableemp4(

idint,

namevarchar (20),

resumevarchar (500),Index index_name_resume (name,resume ) --给 name 和 resume 两列都共用一个索引

)

添加索引(在已经创建好表的情况下,添加索引)

--create在已经存在的表上创建索引

create [unique | FULLTEXT | SPATIAL] index索引名on 表名 (字段名[(长度)] [asc | desc]); --on 表示给哪张表下的哪个字段添加索引

--alter table 在已经存在的表上创建索引--alter是先把表找到,然后再给该表下的哪个字段添加索引

alter table 表名 add [unique | FULLTEXT | SPATIAL] index索引名 (字段名[(长度)] [asc | desc]);

删除索引

--语法

drop index 索引名 on表名;--示例

drop index index_name on t2;

索引测试实验

--创建表

create table Indexdb.t1(id int ,name varchar (40));--存储过程--通过循环,插入50条数据

delimiter !--修改结束符的,比如上面一个sql语句结束,都是以;结尾,可以修改为!

create procedure autoinsert() --procedure:是个关键字,表示存储过程,autoinsert() 是定义的函数名字

begin

declare i int default 1; --声明一个变量i,从1开始

while (i <500000) doinsert into Indexdb.t1 values(i,"yuan");set i = i+1;end while;end!

delimiter ;--分隔符再改会来

--调用函数插入50万条数据

call autoinsert();--花费时间比较--创建索引前

select * from Indexdb.t1 where id=300000; --0.32s

--添加索引

alter table Indexdb.t1 add indexindex_id (id);--添加索引后

select * from Indexdb.t1 where id=300000; --0.01s

相关文章:

  • mysql 从库基于主库binlog恢复_MySQL利用binlog来恢复数据库
  • python可迭代对象相关的内建函数_第八章 Python可迭代对象、迭代器和生成器
  • mysql workbench连接jsp_JSP连接sql server2000数据库
  • 爱可生 mysql监控_数据库Prometheus 数据采集3-爱可生
  • java分割_Java中分割字符串的两种方法实例详解
  • java https 证书_JavaHTTPS客户端证书认证
  • java byte to hex_java 转换byte位hex字符串的工具代码
  • java泛型设计_使用java泛型设计通用方法
  • java线程 数据队列_java多线程从队列中取出数据执行
  • java 给url增加参数_Java给指定URL字符串添加值和获取URL字符串中的参数值
  • java copy object_Java Object 对象拷贝
  • java 几种样式_JAVA几种常见的编码格式
  • mysql5.7解压版停止_MySQL5.7.13解压版安装及常见问题
  • ios java 加密_iOS与Java的RSA加密解密
  • java 动态页面_Java中的动态网页:如何在Java中创建网页?
  • Android 控件背景颜色处理
  • egg(89)--egg之redis的发布和订阅
  • ES6核心特性
  • js算法-归并排序(merge_sort)
  • js学习笔记
  • mysql常用命令汇总
  • mysql外键的使用
  • python学习笔记 - ThreadLocal
  • uni-app项目数字滚动
  • V4L2视频输入框架概述
  • 爱情 北京女病人
  • 海量大数据大屏分析展示一步到位:DataWorks数据服务+MaxCompute Lightning对接DataV最佳实践...
  • 深度解析利用ES6进行Promise封装总结
  • 微信支付JSAPI,实测!终极方案
  • 鱼骨图 - 如何绘制?
  • 3月27日云栖精选夜读 | 从 “城市大脑”实践,瞭望未来城市源起 ...
  • 支付宝花15年解决的这个问题,顶得上做出十个支付宝 ...
  • (09)Hive——CTE 公共表达式
  • (C语言)编写程序将一个4×4的数组进行顺时针旋转90度后输出。
  • (DenseNet)Densely Connected Convolutional Networks--Gao Huang
  • (紀錄)[ASP.NET MVC][jQuery]-2 純手工打造屬於自己的 jQuery GridView (含完整程式碼下載)...
  • (十六)Flask之蓝图
  • (算法)N皇后问题
  • (终章)[图像识别]13.OpenCV案例 自定义训练集分类器物体检测
  • (转)创业家杂志:UCWEB天使第一步
  • .htaccess配置重写url引擎
  • .Net 访问电子邮箱-LumiSoft.Net,好用
  • .net 生成二级域名
  • .net6使用Sejil可视化日志
  • [ vulhub漏洞复现篇 ] AppWeb认证绕过漏洞(CVE-2018-8715)
  • [Apio2012]dispatching 左偏树
  • [BZOJ4566][HAOI2016]找相同字符(SAM)
  • [C++随笔录] 红黑树
  • [COI2007] Sabor
  • [CQOI 2011]动态逆序对
  • [CTF]2022美团CTF WEB WP
  • [hihocoder1395] 最大权闭合子图
  • [k8s系列]:kubernetes·概念入门
  • [MicroPython]TPYBoard v102 CAN总线通信
  • [NOI2005]月下柠檬树[计算几何(simpson)]