【】 表述可选的意思
MySQL中的SQL语句是不区分大小写的。许多开发人员习惯将关键字使用大写,而数据列和表名使用小写。
数据库操作
create database if not exists mysql8 default charset utf8 collate utf8_general_ci
create database [IF NOT EXISTS] mysql8 [default charset utf8 COLLATE utf8_general_ci]
数据库名:mysql8
数据库选项:
字符集:utf8
校验规则:utf8_general_ci
新建表
create [temporary] table [if not exists] [库名.]表名 (
字段名 数据类型 [not null|null] [default def_val] [auto_increment] [unique key]|[primary key] [comment 'string'],
字段名 数据类型 [not null|null] [default def_val] [auto_increment] [unique key]|[primary key] [comment 'string'],
字段名 数据类型 [not null|null] [default def_val] [auto_increment] [unique key]|[primary key] [comment 'string'],
字段名 数据类型 [not null|null] [default def_val] [auto_increment] [unique key]|[primary key] [comment 'string'],
字段名 数据类型 [not null|null] [default def_val] [auto_increment] [unique key]|[primary key] [comment 'string'],
字段名 数据类型 [not null|null] [default def_val] [auto_increment] [unique key]|[primary key] [comment 'string'],
字段名 数据类型 [not null|null] [default def_val] [auto_increment] [unique key]|[primary key] [comment 'string']
)[表选项]
create table if not exists `user` (
`id` int (13) not null auto_increment comment '主键',
`name` varchar (33) default null comment '姓名',
`age` int (3) default null comment '年龄',
`money` double default null comment '账户余额',
primary key (`id`)
)
engine = innodb
auto_increment = 5
default charset = utf8
collate=utf8_general_ci;
temporary临时表,会话结束时表自动消失;
engine = innodb 存储引擎
auto_increment = 5 通常用于主键,表示主键自增,数值会自动+1,可配置起始值
default charset = utf8
collate=utf8_general_ci;
主键约束(Primary Key Constraint)
主键又称主码 | 解释说明 |
---|---|
表中一列或多列的组合 | 单字段主键 和 多字段联合主键 |
主键约束要求主键列的数据唯一,并且不允许为空 | 主键能够唯一地标识表中的一条记录 |
create table if not exists `user` (
`id` int (13) primary key, --单字段主键
`name` varchar (33)
)
create table if not exists `user` (
`id` int (13),
`name` varchar (33),
primary key (id) --单字段主键
)
create table if not exists `user` (
`id` int (13),
`name` varchar (33),
`age` int (3),
primary key (id,name) --多字段联合主键
)
唯一性约束(Unique Constraint)
唯一性约束 |
---|
要求该列唯一,允许为空,但只能出现一个空值 |
唯一性约束可以确保一列或者几列不出现重复值 |
create table if not exists `department` (
`id` int (13),
`name` varchar (33),
primary key (id),
constraint thename unique(name)
)
PRIMARY KEY | UNIQUE |
---|---|
一个表中只能有一个字段声明为 PRIMARY KEY | 一个表中可以有多个字段声明为 UNIQUE |
声明为 PRIMARY KEY的列不允许有空值 | 声明为UNIQUE的字段允许空值的存在,但只能出现一个空值 |
外键约束
外键 |
---|
可以是一列或者多列 |
子表可以有一个或多个外键;外键可以为空值,若不为空值,则每一个外键值必须等于主表中主键的某个值 |
子表的外键必须关联父表的主键,子表数据没删除的情况下,不允许删除其在主表中具有关联关系的行 |
外键的作用:在两个表的数据之间建立连接、保持数据的一致性、参照完整性; |
create table if not exists `department` (
`id` int (13),
`name` varchar (33),
primary key (id)
)
create table if not exists `user` (
`id` int (13),
`name` varchar (33),
`dep_id` int (13),
primary key (id),
constraint fk_user_department foreign key (dep_id) references department(id)
)
非空约束(Not Null Constraint)
Not Null |
---|
指字段的值不能为空 |
对于使用了非空约束的字段,如果用户在添加数据时没有指定值,数据库系统就会报错 |
create table if not exists `department` (
`id` int (13),
`name` varchar (33) not null,
primary key (id)
)
默认约束(Default Constraint)
default |
---|
指定某列的默认值 |
如果插入一条新的记录时没有为这个字段赋值,那么系统会自动为这个字段赋值 |
create table if not exists `department` (
`id` int (13),
`name` varchar (33) default 'name',
primary key (id)
)
设置表的属性值自动增加
AUTO_INCREMENT |
---|
希望在每次插入新记录时,系统自动生成字段的主键值。可以通过为表主键添加AUTO_INCREMENT关键字来实现 |
在mysql 中,AUTO_INCREMENT的初始值是1,也可以指定起始行数,每新增一条记录,字段值自动加1 |
一个表只能有一个字段使用AUTO_INCREMENT约束,且该字段必须为主键的一部分 |
AUTO_INCREMENT 约束的字段可以是任何整数类型(TINYINT、SMALLINT、INT、BIGINT等) |
create table if not exists `department` (
`id` int (13) primary key auto_increment,
`name` varchar (33) default 'name'
)
查询数据
select
[ all | distinct ] { select_expression }
from
->
where
->
group by
[ 集合函数 ] ->
having
->
order by
->
limit
[all|distinct] 选项
distinct :去除查询结果的重复记录
要对多列进行降序排序,必须在每一列的列名后面加DESC关键字。而DISTINCT不同,DISTINCT不能部分使用。换句话说,DISTINCT关键字应用于所有列,而不仅是它后面的第一个指定列
all: 全部记录,默认值
select_expression
-- 可以用 * 表示所有字段。
select * from
-- 可以使用表达式(计算公式、函数调用、字段也是个表达式)
select age, 29+25, now() from
-- 可以为每个列使用别名
- 使用 as 关键字,也可省略 as.
select age+10 as add10 from
- 在SELECT语句中使用星号(*)通配符查询所有字段(或者在SELECT语句中指定所有字段)
- 查询指定字段 (查询指定字段、查询多个字段)
from 子句用于标识查询来源
-- 可以同时出现多个表,他们会横向叠加到一起,数据会形成一个笛卡尔积。
select * from tb1, tb2;
-- 可以为表起别名
from tb1 as tt, tb2 as bb;
-- 向优化符提示如何选择索引
use index、ignore index、force index
select * from table1 use index (key1,key2) where key1=1 and key2=2 and key3=3;
select * from table1 ignore index (key3) where key1=1 and key2=2 and key3=3;
where 子句
-- 从from 获得的数据源中进行筛选, 整型1表示真,0表示假
-- 条件判断符
=
<>, !=
<=
<
>=
>
(not) between and
-- IN操作符
(not) in
-- 带LIKE的字符匹配查询
(not) like
% 用于匹配在指定位置的任意数目的字符,甚至包括零字符
“b%”告诉MySQL,返回所有以字母b开头的记录,无论b后面有多少个字符
“%b%”只要名字中有字母g,无论前面或后面有多少个字符
_ 一次只能匹配任意一个字符,如果要匹配多个字符,就需要使用相同个数的“_”
-- 查询空值
is (not) null
-- 带AND的多条件查询
and
-- 带OR的多条件查询 (AND的优先级高于OR)
or
其他未整理
-- 表达式由运算符和运算数组成。
-- 运算数:变量(字段)、值、函数返回值
-- 运算符:
!, &&, ||
not, xor
is (not) 加上ture/false/unknown,检验某个值的真假
<=>与<>功能相同,<=>可用于null比较
group by 子句, 对数据进行分组
group by 字段/别名 [排序方式]
-- 分组后会进行排序。
升序:asc,降序:desc
-- GROUP BY关键字通常和集合函数一起使用:
count()函数
count(*):计算表中总的行数,无论某列有数值或者为空值。
count(字段名):计算指定列下总的行数,计算时将忽略空值的行
sum() 求和
sum()函数在计算时,忽略列值为NULL的行
max() 求最大值
min() 求最小值
max()、min()函数不仅适用于查找数值类型,也可应用于字符类型、日期
在对字符类型数据进行比较时,按照字符的ASCII码值大小进行比较,从a~z,a的ASCII码最小,z的ASCII码最大。在比较时,先比较第一个字符,如果相等,继续比较下一个字符,一直到两个字符不相等或者字符结束为止
avg() 求平均值
avg()函数使用时,其参数为要计算的列名称,如果要得到多个列的多个平均值,就需要在每一列上使用AVG()函数
group_concat() 将每个分组中各个字段的值(非null)连接起来成一个字符串
-- 使用WITH ROLLUP关键字之后,在所有查询出的分组记录之后增加一条记录,该记录计算查询出的所有记录的总和,即统计记录数量
group by id with rollup
--当使用ROLLUP时,不能同时使用ORDER BY子句进行结果排序,即ROLLUP和ORDER BY是互相排斥的
--多字段分组,MySQL根据多字段的值来进行层次分组
group by id,name
having 子句,使用HAVING过滤分组
与 where 功能、用法相同,执行时机不同
where | having |
---|---|
对原数据进行过滤 | 对筛选出的结果再次进行过滤 |
字段必须是数据表存在的 | 字段必须是查询出来的 |
不可以使用字段的别名 因为执行where代码时,尚未确定列值 |
可以,????表示怀疑 |
不可以使用合计函数 | 一般需用集合函数才会用 having |
sql标准要求having必须引用group by子句中的列或用于集合函数中的列 |
order by 子句,对查询的结果进行排序
-- 单列排序
-- 多列排序
order by 字段/别名 排序方式 [,字段/别名 排序方式]...
-- 在对多列进行排序的时候,首先排序的第一列必须有相同的列值,才会对第二列进行排序。如果第一列数据中所有值都是唯一的,将不再对第二列进行排序
asc 升序、默认值
desc 降序
limit 子句,使用LIMIT限制查询结果的数量
仅对处理好的结果进行数量限制,将处理好的结果的看作是一个集合,按照记录出现的顺序,索引从0开始
limit 位置偏移量, 获取条数
-- 第一个“位置偏移量”参数指示MySQL从哪一行开始显示,是一个可选参数,如果不指定“位置偏移量”,就会从表中的第一条记录开始(第一条记录的位置偏移量是0,第二条记录的位置偏移量是1,以此类推);
-- 第二个参数“行数”指示返回的记录条数。
“LIMIT n” 与 “LIMIT 0,n”等价
“LIMIT 4 OFFSET 3” 与 “LIMIT 4,3” 等价
在使用ORDER BY子句时,应保证其位于FROM子句之后,如果使用LIMIT,就必须位于ORDER BY之后,如果子句顺序不正确,MySQL就会产生错误消息
在查询的时候,会看到在WHERE子句中使用条件,有的值加上了单引号,而有的值未加。单引号用来限定字符串,如果将值与字符串类型列进行比较,就需要限定引号;而用来与数值进行比较,则不需要用引号
在MySQL中存储字符串数据时,可能会不小心把两端带有空格的字符串保存到记录中,解决的方法是使用TRIM函数将字符串两端的空格删除之后再进行匹配。
连接查询
内连接查询(INNER JOIN)
使用比较运算符进行表间某(些)列数据的比较操作,并列出这些表中与连接条件相匹配的数据行,组合成新的记录,也就是说,在内连接查询中,只有满足条件的记录才能出现在结果关系中。
where
inner join on
使用WHERE子句定义连接条件比较简单明了,而INNER JOIN语法是ANSI SQL的标准规范,使用INNER JOIN连接语法能够确保不会忘记连接条件
而且WHERE子句在某些时候会影响查询的性能
自连接查询
如果在一个连接查询中涉及的两个表是同一个表,这种查询称为自连接查询。
自连接是一种特殊的内连接,它是指相互连接的表在物理上为同一个表,但可以在逻辑上分为两个表。
左外连接或左连接
left join
如果左表的某行在右表中没有匹配行,右表就会返回空值
右外连接或右连接
right join
如果右表的某行在左表中没有匹配行,左表就会返回空值
复合条件连接查询
子查询
子查询是指一个查询语句嵌套在另一个查询语句内部的查询
在SELECT子句中先计算子查询,子查询结果作为外层另一个查询的过滤条件,查询可以基于一个表或者多个表。
子查询中常用的操作符有ANY(SOME)、ALL、IN、EXISTS。
子查询可以添加到SELECT、UPDATE和DELETE语句中,而且可以进行多层嵌套。
子查询中也可以使用比较运算符,如“<”“<=”“>”“>=”和“!=”等。
带ANY、SOME关键字的子查询
ANY和SOME关键字是同义词,表示满足其中任一内层查询的条件
select * from user where age > any (select age from pays where money < 10000)
带ALL关键字的子查询
ALL关键字与ANY和SOME不同,使用ALL时需要同时满足所有内层查询的条件
select * from user where age > all (select age from pays where money < 10000)
带EXISTS关键字的子查询
EXISTS关键字后面的参数是一个任意的子查询,如果至少返回一行,那么EXISTS的结果为TRUE,此时外层查询语句将进行查询;如果子查询没有返回任何行,那么EXISTS返回的结果是FALSE,此时外层语句将不进行查询。
select * from user where age exists (select age from pays where money < 10000)
select * from user where age noy exists (select age from pays where money < 10000)
EXISTS和NOT EXISTS的结果只取决于是否会返回行,而不取决于这些行的内容,所以这个子查询输入列表通常是无关紧要的
带IN关键字的子查询
IN关键字进行子查询时,内层查询语句仅仅返回一个数据列,这个数据列里的值将提供给外层查询语句进行比较操作
select * from user where age in (select age from pays where money < 10000)
带比较运算符的子查询
在前面介绍的带ANY、ALL关键字的子查询时使用了“>”比较运算符,子查询中还可以使用其他的比较运算符,如“<”“<=”“=”“>=”和“!=”等
select * from user where age <> (select age from pays where money = 10000)
合并查询结果
利用UNION关键字,可以给出多条SELECT语句,并将它们的结果组合成单个结果集。合并时,两个表对应的列数和数据类型必须相同。
各个SELECT语句之间使用UNION或UNION ALL关键字分隔。
UNION不使用关键字ALL,执行的时候删除重复的记录,所有返回的行都是唯一的;
使用关键字ALL的作用是不删除重复行,也不对结果进行自动排序。
select id,name from user where age =18
union
select id,name from user where age =19
select id,name from user where age =18
union all
select id,name from user where age =19
UNION和UNION ALL的区别:
使用UNION ALL的功能是不删除重复行,加上ALL关键字语句执行时所需要的资源少,所以尽可能使用它,当知道有重复行但是想保留这些行,确定查询结果中不会有重复数据或者不需要去掉重复数据的时候,应当使用UNION ALL以提高查询效率。
使用正则表达式查询
在MySQL中,使用REGEXP关键字指定正则表达式的字符匹配模式
查询以特定字符或字符串开头的记录
查询以特定字符或字符串结尾的记录
用符号“.”来替代字符串中的任意一个字符
使用“*”和“+”来匹配多个字符
匹配指定字符串
匹配指定字符中的任意一个
匹配指定字符以外的字符
使用{n,}或者{n,m}来指定字符串连续出现的次数
注意:
LIKE运算符也可以匹配指定的字符串,但与REGEXP不同,LIKE匹配的字符串如果在文本中间出现,就找不到它,相应的行也不会返回。而REGEXP在文本内进行匹配,如果被匹配的字符串在文本中出现,REGEXP就会找到它,相应的行也会被返回
插入数据
插入完整的记录
指定所有字段名 | 完全不指定字段名 |
---|---|
insert into user (id,name,age) values (1,‘lingling’,20) | insert into user values (1,‘lingling’,20) |
INSERT语句后面的列名称顺序可以不是person表定义时的顺序,即插入数据时,不需要按照表定义的顺序插入,只要保证值的顺序与列字段的顺序相同就可以 | 如果不包含列名称,那么VALUES关键字后面的值不仅要求完整,而且顺序必须和表定义时列的顺序相同 |
如果表的结构被修改,对列进行增加、删除或者位置改变操作、因为指定列名称,就不会受到表结构改变的影响 | 如果表的结构被修改,对列进行增加、删除或者位置改变操作,这些操作将使得用这种方式插入数据时的顺序同时改变 |
插入记录的一部分
只向部分字段中插入值,而其他字段的值为表定义时的默认值
insert into user (name,age) values ('lingling',20);
要保证每个插入值的类型和对应列的数据类型匹配,如果类型不同,就无法插入,并且MySQL会产生错误
插入多条记录
insert into user (id, name, age)
values
(1, ‘lingling’, 20),
(2, ‘daming’, 20),
(3, ‘sam’, 20),
(4, ‘amy’, 20);
insert into user
values
(1, ‘lingling’, 20),
(2, ‘daming’, 20),
(3, ‘sam’, 20),
(null, ‘amy’, 20) -- 带有AUTO_INCREMENT属性的id字段插入NULL值,系统会自动为该字段插入唯一的自增编号
一个同时插入多行记录的INSERT语句等同于多个单行插入的INSERT语句,因为MySQL执行单条INSERT语句插入多行数据比使用多条INSERT语句快,所以在插入多条记录时,最好选择使用单条INSERT语句的方式插入;
使用INSERT同时插入多条记录时,MySQL会返回一些在执行单行插入时没有的额外信息,这些信息的含义如下:
· Records:表明插入的记录条数。
· Duplicates:表明插入时被忽略的记录,原因可能是这些记录包含重复的主键值。
· Warnings:表明有问题的数据值,例如发生数据类型转换
插入另一个查询的结果
insert into user (id,name,age) select id,name,age from user;
这里的id字段为自增的主键,在插入的时候,要保证该字段值的唯一性;如果不能确定,那么可以在插入的时候忽略该字段,只插入其他字段的值。
事实上,MySQL不关心SELECT返回的列名,它根据列的位置进行插入,SELECT的第1列对应待插入表的第1列,第2列对应待插入表的第2列,等等。即使不同结果的表之间也可以方便地转移数据。
无论使用哪种INSERT语法,都必须给出VALUES的正确数目。如果不提供字段名,就必须给每个字段提供一个值,否则将产生一条错误消息。
如果要在INSERT操作中省略某些字段,这些字段需要满足一定条件:该列定义为允许空值,或者表定义时给出默认值,如果不给出值,将使用默认值。
更新数据
update user set name = 'lingling2',age = 22 where id between 2 and 6;
update user set name = 'lingling2',age = 22;
保证UPDATE以WHERE子句结束,通过WHERE子句指定被更新的记录所需要满足的条件,如果忽略WHERE子句,MySQL将更新表中所有的行。
删除数据
delete from user where id =11;
delete from user where id between 2 and 6;
delete from user ;
如果想删除表中的所有记录,还可以使用TRUNCATE TABLE语句;
TRUNCATE将直接删除原来的表,并重新创建一个表,其语法结构为TRUNCATE TABLE table_name。TRUNCATE直接删除表而不是删除记录,因此执行速度比DELETE快。