Mysql 增删改查 学习笔记

【】 表述可选的意思
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 indexignore indexforce 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快。

猜你喜欢

转载自blog.csdn.net/weixin_37646636/article/details/121450092