SQL
1:什么是数据库:
数据是数据库中存储的基本对象,种类包括文字,图片,声音,图形 数据库(database)是以某种有组织的方式存储的数据集合,保存有组织的数据的容器,统层是一个文件或者一组文件(文字图像图像,有组织的放在一起,作为一个集合就形成一个数据库 ,保存有组织数据的一个容器,通常是一个文件,或者一组文件) 理解数据库的一种最简单的办法就是将他想象成一个文件柜,次文件柜是一个存放数据的物理位置,不管数据是什么以及如何组织的 数据库管理系统---后面的数据库--- 数据库---文件柜--容器, 抽屉,格子(次文件柜,次文件柜,空间进行不同的划分,划分不同的类型,次文件柜存放的是数据的物理地址--指向数据真正存放的地方,
数据实际存放在电脑磁盘里面的,数据库里面不管电脑里面的 数据如何进行存储,管理的只是存储的地址--这就是数据库) 数据库管理软件----DBMS 数据库存放于文件中,管理该数据库的软件称为数据库管理软件(DBMS) 对数据库的操作进行管理是通过数据库管理软件来完成的 行业中主流的数据库管理软件有OEACLE,SQLSERVER,MYSQL(属于OEACLE公司)等---语法有点差异, mysql的使用 用户---应用系统---应用开发工具---数据库管理系统(mysql管理数据库--这些数据存储之后需要对他进行调用,抽取,再存放,
对数据库进行移动管理,数据库自己本身捉不到,所有开发了数据库管理系统取管理数据库,
用户接触到的就是数据管理系统,通过数据库管理系统才能真正管理数据库,我们学习的是数据库管理系统)
----数据库(最底层存放数据的物理地址) 用户---应用系统---应用开发工具---数据库管理系统--数据库管理员--数据库
mysql--用的是标准的sql语法,熟悉了mysql只需要很短时间学习OEACLE语法
2:什么是mysql
mysql是一个关系型数据库管理系统,web应用方面mysql是最好的关系型数据库管理系统应用软件之一
3:mysql数据库特点
mysql是一种关系型数据库管理系统,关系型数据库将数据保存再不同的表中,而不是所有的数据放在一个大仓库内,增加了速度并提高了灵活性
mysql所使用的sql语言是用于访问数据库的最常用的标准化语言
mysql分为社区版和商业版,体积小,速度快,总体拥有成本低,尤其是开放源码这一特点,一般中小型网站的开发都选择mysql作为网站的数据库
4:mysql数据库架构
mysql是基于客户机-服务器模式的数据库管理软件,客户机-服务器应用分为两个不同部分
服务器是负责所有数据访问和处理的软件,这个软件运行在称为数据库服务器的计算机上,与数据文件打交道的只有服务器软件,
数据添加,删除,更新和所有的请求操作都由服务器去软件完成
客户机是与客户打交道的软件,服务器处理客户机发送的请求,并把处理结果返回给客户机
客户机服务器(qq:我们安装的是客户端, 服务器在腾讯----客户端服务器通信需要网络,登录动作,验证服务器是否由这个数据)
5:mysql服务器和客户端
mysql服务器(server)和mysql客户端()
6:mysql概叙和架构
MySQL一般特制完整的MySQLRDBMS,是一个开源的关系型数据库管理系统(Relational Database Management System)
现在属于Oracle公司。随着MySQL功能的不断完善,性能不断提高,又有开源免费的优势,越来越多的企业选择使用MySQL,而放弃商用收费的Oracle。
mysql--传统的关系型数据库管理系统,--瑞典的mysql ab公司开发的,java和mysql都是属于Oracle公司,
mysql免费
7:mysql的架构,
1:客户端 2:mysql服务端(连接/线程处理-----解析器----查询缓存-----优化器-----存储引擎) 服务端最外层关于:连接/线程处理,数据库可以支持很多并发,很多线程同时来连接,所有有连接和线程处理的模块 还有解析器:对sql进行解析的 还有查询缓存:就是mysql查询是有缓存的,目的为了提示性能 优化器:对sql进行优化 上面是核心服务器 真正的数据是通过底层的存储引擎进行读取的,底层有个存储引起,通过引擎读到数据,存储我们的数据,数据是放在磁盘上面的,通过存储引擎从磁盘里面 读取或者写入我们大的数据 上面就是mysql的基本架构--了解就行
8:mysql--windows版本下载安装
1:下载mysql 5.7-windows ---目前最新的mysql是8.0,5.7下一个版本就是8,倒数第二个版本5.7
一般般情况不用最新的,因为公司服务器上装的最新的,最新的里面可能有一些坑(兼容性问题,一般用次新的版本,稍微老一点的版本,稳定一些)
2:双击安装-下一步-完成
cmd下:
1.停止MySQL服务:net stop mysql
2.卸载MySQL :mysqld --remove mysql
9:windows下登录mysql
windows
开始菜单--所有程序--mysql-mysqol5.7 command line client--输入密码
linux
执行命令:mysql-u root -p
windows客户端进行数据库的链接登录
10:mysql基本命令:window和linux这些命令一样
查看所有数据库:show databases; -----s复数,代表多个数据库,后面一定要加分号 ;
分号代表结束,没有输入根号会有小箭头,不会执行结束,出现小箭头可以输入分号(这个可以多行命令)
切换到xxx库:use xxx; ----数据库切换成功--库里面有哪些表(库里面放表)
Database changed打印这个表示切换成功
查看库中所有的表:show tables;
查看morder表结构:desc morder; 表是怎么构成的,表里有哪些字段--id userid 等等
exit 直接退出
11:navicate premium安装
官方的客户端操作,比较麻烦,都是输入命令失效效果,为了提高工作效率使用第三方工具来连接mysql,而不是使用官方的客户端)
常用的第三方工具:navicate
navicate premium这个一个工具能连接很多种数据库:mysql orcal等都支持,这个比较方便
12:mssql远程连接失败的原因:
1:远程mysql没有启动成功
2:本地和远程mysql服务器网络不通 --windows机器和远程的linux机器网络不通,连接不上
3:本地mysql服务器开启防火墙 --不运行访问3306端口,需要关闭防火墙,或者配置防火墙允许访问某个端口,
4:远程mysql没有授权远程访问 --默认情况下mysql数据库只允许在本机上访问,也就是本机连接windsows数据库ok,连接远程的不行,远程服务器上做授权操作
linux mysql版本安装的时候最后一步做个授权--命令需要在远程机器上支持一下,才可以连接成功
远程连接:通过navicate premium连接一个远程的mysql,连接linux数据库可能失败,失败原因如上:一般都是以上四种情况
13:数据库常见的操作
数据库的创建和删除: create database drop database
navicate操作数据库,windos还是linux 使用navicate操作方法都是一样的,不区分是什么版本的数据库
windows版本学习就行,操作简单
一::数据库的创建和删除两种方式:
1:通过navicate来操作
一:navicate 提供的功能来创建库,
1:建立数据库的连接,
2:然后双击数据库
3:右键新建数据库
4:输入数据库的基本信息,名称:mtx_2 字符集:一般选择:utf-8 排序规则:不用选择,为空即可
5:点击确定
6:这时候就创建了一个库就mtx_2
mtx_2创建是空库,没有表,
二:navicate 提供功能删除库:
选中库——>右键——>选中删除数据库即可
删除数据库是一个比较危险的操作,确定要删除删对了,不要删错了,那就比较危险了
2:通过mysql命令行的方式来操作
一:命令行创建数据库,可以打开mysql客户端,使用navicate也可以输命令行进行操作 :create database mtx default character set='utf8'; 1:打开mysql客户端输入:create database mtx default character set='utf8' 2:navicate ——> 点击选中连接的数据库 ——> 点击右键——> 点击命令行界面 ——> 就能进入mysql命令行界面,也可以输入命令行 windows还是linux的mysql都是这些界面---这里就可以直接输入命令 create database mtx default character set='utf8'; ----命令后面记得加分号 创建数据库 mtx default character set='utf8'这里的意思是字符集等于utf8----固定的写法 输入命令后会打印:Query OK, 1 row affected (0.00 sec) ---代表创建成功 二:数据库删除命令: drop database order; #删除单个库,database后面不能加s,order代表数据库名称, 实例:drop database mtx; 删除成功后打印:Query OK, 0 rows affected (0.00 sec)
一般选中效率较快的方式,直接navicate方式创建和删除,面试需要直到命令行:
14:mysql支持的数据类型 数字 日期 字符串
学习了数据类型就可以创建表了
mysql支持很多种数据类型,大体上三类:数值(数字)、日期/时间和字符串(字符)类型。
一:数字类型:mysql数据库写入一些整数之类的数据的时候用到这种类型,大类型里面细分很多小类型。7.8个小类型
7.8个小类型里面包含了整数和小数两部分,
整数分为:(按照int值的范围来划分的) 类型 大小 范围(有符号) 范围(无符号) 用途 TINYINT 1 byte (-128,127) (0,255) 小整数值 这些数字范围可以定义成TINYIN SMALLINT 2 bytes (-32 768,32 767) (0,65 535) 大整数值 MEDIUMINT 3 bytes (-8 388 608,8 388 607) (0,16 777 215) 大整数值 INT或INTEGER 4 bytes (-2 147 483 648,2 147 483 647) (0,4 294 967 295) 大整数值 BIGINT 8 bytes (-9,223,372,036,854,775,808, (0,18 446 744 073 709 551 615) 极大整数值 9 223 372 036 854 775 807) 如果比极大整数值还大,那么不该定义成int应该定义成字符串之类的, 小数类型的分为: 类型 大小 范围(有符号) 范围(无符号) 用途 FLOAT 4 bytes (-3.402 823 466 E+38,-1.175 494 351 E-38), 0,(1.175 494 351 E-38, 0,(1.175 494 351 E-38,3.402 823 466 351 E+38) 3.402 823 466 E+38) 单精度,浮点数值
DOUBLE 8 bytes (-1.797 693 134 862 315 7 E+308,-2.225 073 858 507 201 4 E-308), 0,(2.225 073 858 507 201 4 E-308 双精度,浮点数值 0,(2.225 073 858 507 201 4 E-308,1.797 693 134 862 315 7 E+308) 1.797 693 134 862 315 7 E+308
DECIMAL 对DECIMAL(M,D) ,依赖于M和D的值 依赖于M和D的值 小数值 如果M>D, 为M+2否则为D+2 DECIMAL类型:可以自定义小数点后面的长度,定义这种类型需要两个参数,一个是总长度,一个是小数点后面的长度,人为精确定义小数的长度了 上面就是数据类型,字节数,范围等各种属性 根据自己些的数据的范围来选择到底使用哪一种数据类型 原则能用小的就不要用大的,定义越大占用的字节数越多,浪费内存
二:日期和时间类型
日期类型全部是和日期相关的数据类型, 类型 大小( bytes) 范围 格式 用途 DATE 3 1000-01-01/9999-12-31 YYYY-MM-DD 日期值 DATE就是---年月日 TIME 3 '-838:59:59'/'838:59:59' HH:MM:SS 时间值或持续时间 TIME--指的时间,几点几分几秒 YEAR 1 1901/2155 YYYY 年份值 DATETIME 8 1000-01-01 00:00:00/9999-12-31 23:59:59 YYYY-MM-DD HH:MM:SS 混合日期和时间值 DATETIME--就是日期+时间 2019/10/17/几点几分几秒 TIMESTAMP 4 1970-01-01 00:00:00/2038 YYYYMMDD HHMMSS 混合日期和时间值,时间戳 TIMESTAMP--时间戳,一串数字,不区分什么格式, 结束时间是第 2147483647 秒, 北京时间 2038-1-19 11:14:07, 格林尼治时间 2038年1月19日 凌晨 03:14:07 时间戳是指格林威治时间1970年01月01日00时00分du00秒(北京时间1970年01月01日08时00分00秒)起至现在的总秒数。通俗的讲, 时间戳是一份能够表示一份数据在一个特定时间点已经存在的完整的可验证的数据
三:字符串类型(定义非数字一些文本之类的使用字符串。和int数字类型差不多,按照字节数大小长度,来划分类型)
类型 大小 用途 CHAR 0-255 bytes 定长字符串 0-255字节 VARCHAR 0-65535 bytes 变长字符串 TINYBLOB 0-255 bytes 不超过 255 个字符的二进制字符串 TINYTEXT 0-255 bytes 短文本字符串 BLOB 0-65 535 bytes 二进制形式的长文本数据 TEXT 0-65 535 bytes 长文本数据 MEDIUMBLOB 0-16 777 215 bytes 二进制形式的中等长度文本数据 MEDIUMTEXT 0-16 777 215 bytes 中等长度文本数据 LONGBLOB 0-4 294 967 295 bytes 二进制形式的极大文本数据 LONGTEXT 0-4 294 967 295 bytes 极大文本数据 根据业务进行选择那种类型,一般前面两个用的多
15:表的创建和删除操作
一:通过navicate 界面的方式创建表 库里面创建表:使用navicate 点击navicate上面的新建表-- 表里面通常有很多字段,需要一个字段一个字段的写,并且指定类型和长度, 比如创建一个订单表: 来个字段id,一般表都有个字段叫id的,id唯一标识出来,id一般都是int类型的,如果表的数据量不是特别高选择int就够了, 长度预计10位, id字段一般设置成主键 创建表也就是创建最上面的目录 二:使用命令方式创建表 :创建表:如果使用IF NOT EXISTS `runoob_tbl`这个的意思是如果没有runoob_tbl这个表就创建这个表 CREATE TABLE `mtx_order` ( `id` int(10) NOT NULL, `phone_num` varchar(11) NOT NULL, `address` varchar(256) NOT NULL, `price` float NOT NULL, `type` tinyint(2) NOT NULL, `create_time` datetime DEFAULT NULL, PRIMARY KEY (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8; CREATE TABLE创建表 `runoob_tbl`--指定表明 `runoob_id` INT UNSIGNED AUTO_INCREMENT, `runoob_title` VARCHAR(100) NOT NULL, `runoob_author` VARCHAR(40) NOT NULL, `submission_date` DATE, PRIMARY KEY ( `runoob_id` ) 上面是各种各种字段的名称和类型和长度等信息 使用navicate创建号列表可以很方便的看到这个表的对应的sql语句 选中表---右键---点击对象信息----点击ddl(就可以查看表对应的sql语句,弄出来放到命令行执行也算ok的)---不同得navicate版本操作不同 三:使用命令删除表: drop table xxx; navicate可以直接界面操作删除 CREATE TABLE `ywt_order` ( `id` int(10) NOT NULL, `phone_num` varchar(11) NOT NULL, `address` varchar(256) NOT NULL, `price` float NOT NULL, `type` tinyint(2) NOT NULL, `create_time` datetime DEFAULT NULL, PRIMARY KEY (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8; 1.ENGINE=INNODB:将数据库的引擎设置为InnoDB(mysql中两种数据库引擎 :MyISAM 、InnoDB) 2.AUTO_INCREMENT=1:自动增长的起始值为1 3.DEFAULT CHARSET=utf8:设置数据库的默认字符集为utf8 创建表需要在数据库里面,想要在某个数据库里面创建表,只有1:use mtx_1;切换到 mtx_1这个数据库,2:然后输入上面得创建表得命令就会在这个数据库里面创建一个表
16:MySQL 插入数据
表创建ok,对表进行数据操作了,需要使用sql语句
sql:结构化查询语言(structured Query language)简称sql,是一种特殊目的得编程语言,
是一种数据库查询和程序设计语言,用于存取数据以及查询,更新和管理关系数据库系统
也算一种编程语言,数据查询语言,sql是通用得规范。并不止只能使用mysql,所有的数据库他们的sql语言都是一样的
sql基础:增删改查
增加数据:可以使用navicate客户端直接双击写入数据,输入后点击下面的小对符号就是提交就ok
sql语句插入:
sql需要在一个窗口上写一些sql命令的,navicate操作 1:点击查询 2:点击新建查询 然后跳出的空白页就可以写sql语句了
一:单条数据插入 insert into user(user_name,age)values('test'100);
insert into user(user_name,age)values('test'100); id字段一般都不需要自己插入,因为正常来讲创建数据库表的时候都会id设置字段设置成自增,让数据库来维护它 插入第一条id为1,插入第二条适合id变成2了 自增--数据库维护的,用户不需要关系 id设置自增的方法:navicate 1:选择操作的表 2:右键点击设计表--就能看到创建表的选项了 3:选中id字段 4:勾选下面的自动递增选项就ok了 5:点击上面的保存 id设置自增后那么写sql语句的时候,id字段不用管了,直接从第二个字段开始写,增加sql语句如下: INSERT INTO mtx_order (phone_num,address,price,type,create_time)
VALUES('18397500597','深圳',9.9,1,'2019-10-16 18:00:00') 然后点击运行
二:insert支持批量数据插入,一条sql语句里面可以同时insert多个语句
INSERT INTO mtx_order (phone_num,address,price,type,create_time) VALUES ('18397500596','深圳',9.9,1,'2019-10-16 18:00:00'), ('18397500597','上海',9.9,1,'2019-10-16 18:01:00'), ('18397500598','北京',9.9,1,'2019-10-16 18:02:00')
navicate增加数据的窗口左上角的点击运行是运行多个sql语句,如果想单条执行可以选中要执行的sql语句然后鼠标右键--点击运行已选择的下·
单个inert语句也可以插入多条数据
17:MySQL 查询数据
一:查询
select * from user where id =1 #user是表名 where id =1 过滤条件指定一个条件id=1
语法: SELECT column_name,column_name FROM table_name [WHERE Clause] [LIMIT N][ OFFSET M] column_name 表示数据库表中所有列的名称,想要查询的数据 SELECT phone_num FROM mtx_order WHERE id =3; 从mtx_order表查询id=3的数据的phone_num SELECT phone_num,address FROM mtx_order WHERE id =3 select可以查询一个字段也可以查询多个字段,如果查询多个字段中间逗号分隔,查询多个字段 SELECT * FROM mtx_order WHERE id =3 查询mtx_order表的id =3的数据的所有字段,用*查询,全部字段全部查询出来 SELECT * FROM mtx_order #不加过滤条件也算可以,查询 mtx_order表里所有的数据 SELECT phone_num FROM mtx_order WHERE address="北京" #北京是字符串所以需要加引号,打印北京的两条数据
18:数据更新:update set
UPDATE mtx_order SET address="杭州" WHERE id =2 #UPDATE mtx_order SET 表明某些字段进行更新,把address改成杭州,把id等于2的数据选中修改 运行成功打印: UPDATE mtx_order SET address="杭州" WHERE id =2 > Affected rows: 1 > 时间: 0.004s 进行set时候可以同时可以修改多个字段 UPDATE mtx_order SET address="杭州",type =2 WHERE id =2 把id等于2的数据,值改成杭州,并且type改成2 前面的set字段可以用一个组合,后面的where可以任意组合,该多个字段中间逗号分隔
19:删除语句 delete删除数据
DELETE FROM mtx_order WHERE id=4 #where后面表示删除的 条件,想要删除id=4的 ,w
20:模糊查询,找到不是精准确定条件的数据 模糊查询:like
不知道精准条件,只知道条件一部分,比如说:查询数据手机号包含111,222,或者333的,并不知道完整准确的数据使用模糊查询 查询手机号码包含111的,不是精准条件 SELECT * FROM mtx_order WHERE phone_num LIKE '111' 模糊查询like ,%通配符:代表条件里面不确定的部分, 模糊匹配的111是在数据尾部,那么前面不确定的部分用%代替,:SELECT * FROM mtx_order WHERE phone_num LIKE '%111' ---代表搜索以111结尾的数据,前面的不确定 如果111是在前面的,后面的部分是不确定的,:假如寻找价格是85开头的,后面的东西不太确定: SELECT * FROM mtx_order WHERE price LIKE '85%' 寻找以85开头的数据 如果前后都不确定,但是中间是包含某个东西的话,可以前面后面都加%,找到字符段中间包含85的就行:SELECT * FROM mtx_order WHERE price LIKE '%85%' 开头和结尾都是85的也能找到
21:范围查询,条件在某一个范围之间的,这是使用特殊的查询表达式 where age BETWEEN 30 AND 50
查询从30岁到60岁之间的人:---范围查询 SELECT * FROM morder WHERE age BETWEEN 30 AND 50 查询什么到什么时间用BETWEEN,BETWEEN字段代表从什么到什么,30 AND 50 --30到50连续区间 查询的数据包含30和50,包含关系 SELECT * FROM morder WHERE age IN (23,32,38) ---这时候指定年龄必须在23,32,38三个数值中间,这些值才能查出来,指定确切得数据,这些多个数据必须逗号分隔 in指定了具体有哪些值得集合,BETWEEN AND是某个连续范围从30到50,用in得话必须指定具体得值 SELECT * FROM morder WHERE age NOT IN (23,32,38) ---NOT IN表示没有在这个范围之内得,不是23,32和38岁的之外的其他人都会搜索出来
22:sql基础 :聚合函数 max min avg sum count
聚合函数:针对某些数据进行聚合统计--包含最大,最小等统计 max(最大) min(最小) avg(平均) sum(求和) count(总数) 最大:订单表里有个很多数据,价格字段,统计这些数据里面最大的价格是多少----使用max聚合函数,统计某个字段的最大值 最小 平均值等等。。。。常用的聚合函数 查询表里所有的数据年龄最大的: SELECT MAX(age) FROM morder WHERE user_name ='周老师' :查询user_name ='周老师'的age最大的哪一个 最小 SELECT MIN(age) FROM morder WHERE user_name ='周老师' 评价:姓名为周老师的平均值 SELECT AVG(age) FROM morder WHERE user_name ='周老师' ---平均值可能算出来小数,自动会带上小数 求和 :姓名为周老师的总年龄 SELECT SUM(age) FROM morder WHERE user_name ='周老师' 统计符合这些条件的数据的行数,比如查询姓名为周老师的有多少个(或者查询北京地区订单一共有多少订单)count SELECT COUNT(*) FROM morder WHERE user_name ='周老师' ----姓名为周老师的人一共才一个
23:sql:数据的排序去重和限制
排序:根据某个字段把我们查询出来的数据进行一个排序,假如想根据年龄排序需要用到order by SELECT * FROM morder ORDER BY age 这种是按照年龄升序排序的,上面小,下面大,从小到大 SELECT * FROM morder ORDER BY age DESC 加DESC就是倒叙排序的,不加DESC就是升序的,默认升序的 去重:去除重复的数据 distinct去重 去除掉重复年龄的数据 SELECT DISTINCT(age) FROM morder 现在查询没有年龄的重复项的,去除重复的数据 限制:数据查询的时候会查询到很多数据,如果说只想看三条数据,加LIMIT 3 SELECT * FROM morder LIMIT 3 ---显示原本数据的前三个,LIMIT还可以指定第几条数据开始,一个显示几条如下: SELECT * FROM morder LIMIT 2,5 ----不包含第二个,从2+1条开始,也就是3.4.5.6.7 SELECT * FROM morder LIMIT 0,5
24:sql:分组查询: GROUP BY
SELECT region,gender,SUM(age) FROM morder GROUP BY region,gender 按照region区域和gender 类型进行分组
MySQL: GROUP BY 语句 分组 按照表中某一个或者多个字段,将数据进行分组,一般用于将数据进行分类汇总 ---分类汇总 实例:对morder表的数据,按照区域和类型进行分组,展示每个区域和类型订单的总金额 订单表:有个区域字段,想按照区域进行划分之后一些相应的数据,每个区域多少订单,订单的总金额,--加工的数据,首先必须把数据订单按照区域进行分组, SELECT * FROM morder GROUP BY region 每组可能多条数据,到底查询什么数据, SELECT * FROM morder GROUP BY region 这个能查询北京,上海,广州,深圳每组数据的全部数据,查到四个数据 一般情况下如果我们如果按照区域进行分组,这时候只能用来查询到底几组 :
SELECT region FROM morder GROUP BY region :这个只能查到:上海,北京,广州,深圳四个地区,也就是四组
分组的目的为了统计每一组种的数据:比如统计北京老师的年龄总和,上海老师的的总年龄,广州深圳等和集合函数结合使用---统计多条数据汇总的结果 SELECT region,SUM(age) FROM morder GROUP BY region
region,SUM(age)前面查询分组名称,后面查询这组年龄总和,GROUP BY region--通过区域进行分组 SELECT region,SUM(age),user_id FROM morder GROUP BY region
这样写的话region区域已经分组了,只有一个组,,SUM(age)年龄求和了,但是user_id这个区域有很多个user_id的 那么会展示这组的那个user_id,它把这组数据里面的第一个user_id打印出来了, 如果这组里面想要查看那种他不是相同数据的资料,默认展示第一条(意义不大)---- 使用group by的sql语句,selct后的字段,只能是group by后的字段,如果想展示其他的列,需要给该列使用聚合函数,否则默认展示分组里的第一行数据 通过什么字段进行分组,前面查询那个字段就行了,因为这个字段肯定在这组都是一样的,这样的显示才有意义,并没有通过user_id进行分组,只能展示第一条(没有太大的意义) mysql早期版本,这样使用加载user_id会报错的,现在不会报错,加载第一条,但是可以使用聚合函数统计一个总数目,比如总价格,总年龄,一组统计一个总价格会有一个唯一的确定值 ,但是不能查看分组后单个的年龄或者价格---- GROUP BY支持同时对多个字段进行进行分组,上面是按照区域进行分组的,还可以按照gender类型进行更加详细的分组: SELECT region,gender,SUM(age) FROM morder GROUP BY region,gender
按照区域和类型进行分组,上海类型0的和上海类型1的都算一个组,分组变得更细了,支持多个字段进行分组
25:分组之后的数据过滤,对分组之后现在的数据再想做一个筛选: having:对分组之后的数据进行过滤操作
使用having一般都是配合GROUP BY使用的,搭配使用 按照区域和类型进行分组之后求了年龄总和SUM(age),还想查看总年龄大于200的,有的总年龄小于200,统计大于200的。这时候不可以使用where, where只能处理原表的数据现在的数据经过分组之后又经过sum求和加工的数据,这时候只能使用having,对分组时候的数据进行过滤 SELECT region,gender,SUM(age) FROM morder GROUP BY region,gender HAVING SUM(age) > 200 :having分组之后的数据过滤,统计分组之后的数据规律, 我们想统计总年龄大于200的:HAVING SUM(age) > 200 上面的用法查询的是第三个字段是SUM(age)标题显示的,很多时候可以做一些重命名 使用as如下 SELECT region,gender,SUM(age) as region_age FROM morder GROUP BY region,gender HAVING SUM(age) > 200 把函数SUM(age)重命名的一个操作,展示出来位置的字符串改成region_age,更加容易理解
26:sql语句执行顺序
我们的sql按照什么顺序执行的: from(后面加表名,从什么表).... where(后面+过滤条件) group by (后面+分组条件,按照什么进行分组,如年龄,区域,类型等) :GROUP BY region,gender 按照region地区,gender类型进行分组 having (后面+过滤条件,绑定group by一起使用) GROUP BY region,gender HAVING SUM(age) > 200 分组后查询总年龄大于200的 select (后面+查询内容) SELECT region,gender,SUM(age) --查询区域region,类型gender,总年龄SUM(age) order by (后面+排序方法)ORDER BY age 按照年纪进行升序排序 sql并不是按照写的数据从前往后执行的,有先后顺序的, sql语句执行顺序 1:from 先确定那个表里面找 2:where 找到表之后按照条件进行数据过滤,没有数据过滤where不用进行这一步, 3:group by 找group by,进行数据分组 4:having 分组之后对分组之后的数据进行过滤having 5:selcet selcet最后的时候执行,展示时候执行的 6:order by 执行select之后,找到了要展示的数据,再找order by进行排序,排序放在最后一位,优先级最低的(sql语句这种执行顺序)
27:sql高级-内连接查询 inner join
前面的sql都是基于单表查询的---很多时候数据需要从多表里面进行查询,2个表,三个表,需要使用多表连接查询 连接查询通常有很多种连接: 1:等值连接(内连接) 关键字:inner join 以某字段为条件,取左表和右表中同时存在的相同数据的行,相当于两个表的交集 一个user表和一个morder表,user表里面有userid和一些用户的信息等,moeder有订单的一些信息,这两个表有关联关系的 订单表存在一些字段叫user_id对应的这个id是user表里面的id字段--每个订单要所属于某个用户的,---这两个表是有关联关系的 用户的id和和user_id字段进行关联---他们一一对应的,这两个表做连接查询 我想查询一下我这个订单表morder里面每个订单所属用户的一些信息,如果手机号,用户名等这些信息 数据两个表查询,订单表和user表里面找到数据 SELECT * FROM morder2 INNER JOIN user ON morder2.user_id=user.id FROM后面+表名,两个表才能获取到信息,需要两个表连接起来:INNER JOIN+user表,通过什么字段进行连接,通过关联的字段,morder2表的user_id和user表的id字段关联起来 ON+关联的条件--ON morder2.user_id=user.id --通过这么一个关系把两个表关联起来了, SELECT * FROM morder2 m INNER JOIN user u ON m.user_id=u.id
如果觉得写关联条件的时候ON后面的部分需要写:表名.字段名的,如果表名比较长可以对这个表取一个外号 as 上面的 m代表morder2表,u代表user表---简介写法 上面的写法把两个表通过user_id和id这个数据字段进行关联起来了 这时候打印的数据左边是morder2表的数据,后面是user表的数据,就是两个表通过id这个字段连接打印成一个表, 连接查询就是通过某个字段把两个表合并成一个表 这时候可以查询里面的各种数据,如 user_name,phone_num手机号,region区域,total_price总价格,如下: SELECT user_name,phone_num,region,total_price FROM morder2 m INNER JOIN user u ON m.user_id=u.id 两个表合并成一个表后里面获取数据 上面内连接查询-- 内建立的时候的特点: 现在查询的数据一共17条记录,用户表一共12条记录,订单表morder一共18条记录, 订单表的user_id里面有一个user_id是13,13这个用户再user表里面没有,用户表是从1-12 所有内连接查询会把左表中和右表中同时存在的某个字段的数据(所关联的字段)的行展示出来,不存在的不展示 内连接会把两个表连接字段都存在的数据过滤出来放在一张大表里面,---两个表都存在,两个表的交集(根据某个字段来判断,两个表关联字段的交集,大家同时读存在的)
28:sql高级-左连接和右连接
一:左连接 left join 以某字段为连接条件,取左表中的全部数据——右表于该字段对应的数据,可能会有某些数据在左表存在但是右表不存在的情况 左连接和内连接差不多,也算把两个表的数据通过某个字段关联起来, SELECT * FROM morder2 m LEFT JOIN user u ON m.user_id=u.id 左连接,以左边表morder2表为基础,把左边表里面的所有数据全部打印出来,然后再去和右边建立连接,如果右表中不存在左表中对应的数据的话就展示为空,---左连接(以左表为基础去建立连接) 左连接反正左表的表的数据都会打印,右表里面和左表id相同的部分会打印出来,左表里面有的id但是右表没有这个id的话只大于左表的一部分,右边为空 使用左连接很有可能出现右表某些字段时为空的情况 二:与左连接对应有右连接 rignt join 右连接和左连接正好相反:--以右表为基础 以某字段为连接条件,取右表中的全部数据+左表与该字段对应的数据,可能会有某些数据再右表存在但是左表不存在的情况 SELECT * FROM morder2 m RIGHT JOIN user u ON m.user_id=u.id 右连接,左边出现几条数据为空的情况,用户id为1的等数据订单表里面没有,所有不会显示左边订单表里面的内容, 左连接和右连接主要基于那个表为基础,左表为基础的左连接,右表为基础的右连接,同时两个表都存在的数据叫内连接----三种常见的连接方式 上面合并后的所有数据还是可以数据过滤的,后面可以+where条件的:如下 SELECT * FROM morder2 INNER JOIN user ON morder2.user_id=user.id WHERE morder2.region='北京' :只想看双表连接后,订单表里面区域是北京的, 内连接的基础上过滤出来数据等于北京的一些数据,后面可以继续加group by,order by等条件,拼接之后的表理解成一个新的大表,可以进行各种操作,如排序,分组 等操作 组合成大表可以加任意上面学习过的字段,都是可行的 表明过长也可以简写:如下 : SELECT * FROM morder2 m INNER JOIN user u ON m.user_id=u.id WHERE m.region='北京' 其实两个表没有相同的字段m也可以不写 SELECT * FROM morder2 INNER JOIN user ON morder2.user_id=user.id WHERE region='北京'
29:嵌套查询,连接查询是把多个表连接成一个表,嵌套查询是多个sql语句拼接成一个sql语句进行查询
嵌套查询:多个select语句进行嵌套,嵌套的位置可以再select后from后,where后 需求:查询一下订单区域是北京的这几个用户的手机号,这个需求用连接查询ok的,表拼到一起也算可以实现,嵌套查询也能完成需求 嵌套查询实现:区域位于北京的用户的手机号,订单信息在订单表的,手机信息在用户表的,想查询手机号,先查询手机号,需要首先先查询位于北京的用户的id,然后根据id再到user表里 查询手机号 1:查询北京用户的id:SELECT user_id FROM morder2 WHERE region='北京' ,user_id输出 :3,8,6 2:知道3,8,6查询这几个用户的手机号:SELECT phone_num FROM user WHERE id in(3,8,6) ---使用范围查询 in 知道3,8,6可以使用in范围查询, 上面是使用了两个sql语句实现了结果,嵌套可以把多个语句拼成一个语句: 第一个语句SELECT user_id FROM morder2 WHERE region='北京'查出3,8,6,那么这个语句放在第二个语句的3,8,6位置即可 SELECT phone_num FROM user WHERE id in(SELECT user_id FROM morder2 WHERE region='北京') :第一个语句放在第二个语句的3.8.6位置,变成sql嵌套 这样变成把两个语句拼成一个,先执行in里面的语句,然后执行外面的语句,执行结果也是一样的,这就是嵌套语句,多个sql语句拼接到一个里面 内连接实现方式: SELECT phone_num FROM morder2 INNER JOIN user ON morder2.user_id=user.id WHERE morder2.region='北京' 嵌套语句可以嵌套在哪些位置: SELECT phone_num FROM user WHERE id in(SELECT user_id FROM morder2 WHERE region='北京')这个语句是嵌套在where条件里面的
二:实际工作中嵌套你就灵活的,可以放在where后面也可以放在from和selct后面,嵌套一般需要加小括号 放在from后面的情况: SELECT * FROM (SELECT region,total_price FROM morder2) m SELECT region,total_price FROM morder2:从订单表里面查询区域和总价格,一般来说这个嵌套语句放在from后面的话,需要给这个语句的结果取个名字,比如叫:m 这时候会查询SELECT region,total_price FROM morder2这个语句查询出来的所有数据, 如果只想找区域的话,可以*换成m.region--语句如下 SELECT m.region FROM (SELECT region,total_price FROM morder2) m :这个只查询嵌套语句里面的结果里面的区域信息 或者直接不加m也能输出: SELECT region FROM (SELECT region,total_price FROM morder2) m 嵌套位置放在from后面需要加名称m或者其他,不加就会报错,
三:放在select后面的嵌套语句 SELECT (SELECT region FROM morder2 WHERE user_id =2), phone_num FROM user SELECT region FROM morder2 WHERE user_id =2:查询了一个订单表里user_id =2用户的区域,把他作为另外selct其中的一部分 从订单表里查询了一个区域信息,然后从user表里面查了一个手机号信息,把所有的user表的手机号都查出来了,并且分解对应id等于2上海这个区域配上去了 这么写的话,放在selct后面的嵌套语句,条件只能查询一行数据才行,如果查询出多行数据就不行了 SELECT region FROM morder2 WHERE user_id =2只能查询一行数据,如果查询多行话执行语句就会报错, 能不能写多列呢,SELECT (SELECT region,total_price FROM morder2 WHERE user_id =2), phone_num FROM user,这样也是不行的:- Operand should contain 1 column(s) 子查询,放在select后面嵌套语的话只能写一行一列的表达式,只有这样才能进行匹配,否则不知道如何取匹配的, SELECT (SELECT region FROM morder2 WHERE user_id =2), phone_num,id,user_name FROM user SELECT region FROM morder2 WHERE user_id =2等同 '上海' 上面的语句可以写成:SELECT '上海', phone_num,id,user_name FROM user 放在selct后面的嵌套语句,意思就是打印user表里面的phone_num,id,user_name,前面每行都全部加上SELECT region FROM morder2 WHERE user_id =2,也就是前面都加上'上海'这个字符
30:sql高级 -union语句
一:union :可以将多个selct语句的结果合并成为一个,合并后会删除重复的数据,和连接查询(两个表的数据关联起来的)和嵌套查询(两个sql嵌套执行) union把两个完全独立的sql语句的结果取合并,合并的是结果,这两个sql语句都是独立去执行的,执行之后只是把结果合并汇总一下 订单表里面有个字段recv_phone 指的是订单的收货电话,user表里面每个用户有自己手机号信息的,如果说想统计一下订单上的手机号和用户自己手机号,怎么实现,写两个sql语句来完成 SELECT phone_num FROM user 查询的是用户表手机号 SELECT recv_phone FROM morder2 查询的是订单表收货手机号 想两个结果合并到一起展示,有些常见需要多数据统一处理---使用 union,放在两个sql语句中间,两个结果的合并 SELECT phone_num FROM user UNION SELECT recv_phone FROM morder2
#先把第一个表里面手机号0-11全部查询出来,然后把第二个表里面的手机号也全部查出来, 合并的时候把重复的数据全部删除掉了,第一个表和第二个表里面重复的数据全部删除了,这时候查询出来的 数据是一个完整唯一的不重复的数据, union很多场景有时候从数据库层面可以多个表里面的某个数据合并后去重,很重要 二:union all 可以将多个selcet语句的结果合并为一个,合并后不会删除重复的数据 SELECT phone_num FROM user UNION ALL SELECT recv_phone FROM morder2 #union all重复数据不会删除, 注意:union 和union all语句中,两个select查询的字段数量必须一样, 只能查一个数据:如下: SELECT phone_num,age FROM user UNION SELECT recv_phone FROM morder2 第一个表查询phone_num,age两个字段,第二个表查询recv_phone一个字段,查询的数量不同就会报错,列必须一样,前面一列,后面也是一列,
31:sql面试题讲解
一个订单表,表里面有用户id,价格,区域之类的 面试题: 统计每个地区订单总金额占全国订单总金额的比例,按照顺序排序,取占比最高的前5位----很常见 综合运用:复杂的,一定需要学会审题,分析, 每个区域都有一些订单,每个区域有一个订单的总和,值,北京多少上海多少 全国订单的总和--也是一个值 每个区域占全国订单的比例,可以计算出来的, 占比从大大小排列,取前几名--- 分析:1:需要统计每个地区的订单总金额,分组, :SELECT region,sum(total_price) FROM morder2 GROUP BY region SELECT region,sum(total_price) as region_price FROM morder2 GROUP BY region 2:全国订单总金额算出来 :SELECT sum(total_price) as all_price FROM morder2 3:然后相除,就是比例然后排序 做计算的话需要把上面两个sql放到一起才能计算,嵌套查询 ---把这两个结果放到一个结果里面,现在是上海北京深圳广州四个城市的结果,如果后面再加个字段显示全国的订单总金额 这时候相当于上海这一行上面有本地价格,全国价格,深圳,等地方也有本地价格和全国价格,放在同一行上面的,这时候做运算非常简单,如下: 需要把全国总价格嵌套在,每个地区选择的sql的selcet当中:嵌套语句可以放在selct后面,
并且selct里面嵌套的sql语句需要一页一行,显示的会把嵌套的数据现在外面的sql语句 单独显示一列,外面的sql语句查询到多少列就显示多少列重复的 SELECT region,sum(total_price) as region_price,(SELECT sum(total_price) FROM morder2) as all_price FROM morder2 GROUP BY region 现在已经完成了一个嵌套 4:运算+排序 region_price除一下all_price,再做一个嵌套语句,这个嵌套语句主要从上个输出的数据做一些数据的运算,如下: SELECT * FROM (SELECT region,sum(total_price) as region_price,(SELECT sum(total_price) FROM morder2) as all_price FROM morder2 GROUP BY region) m 我们从结果里面再做一次查询,在做查询的时候去做计算,嵌套语句放在from后面充当一个表的角色的话需要起别的名字如 m 看到每这个字大概率要使用分组,按照地区进行分组,再算地区的订单总金额,嵌套语句放在from的后面。 全写如下: SELECT m.region,m.region_price/m.all_price * 100 as ratio FROM (SELECT region,sum(total_price)
as region_price,(SELECT sum(total_price) FROM morder2) as all_price FROM morder2 GROUP BY region) m ORDER BY ratio DESC LIMIT 3 一步步层层分析 复杂的sql需要一步步拆分需求,先做什么事情,后做什么。按照思路写sql,面试过程碰到复杂sql经常需要使用到嵌套,涉及数据来源于多个表的还要做多表, 多表的操作还是把多表变成一个表,然后再一个表上进行操作
32:数据库mysql运算符
一:算术运算符 MySQL 支持的算术运算符包括: 运算符 作用 + 加法 - 减法 * 乘法 / 或 DIV 除法 % 或 MOD 取余 在除法运算和模运算中,如果除数为0,将是非法除数,返回结果为NULL。 数据运算加减乘除,取余等运算 算术运算符演示: 表里面有个价格,我想,id等于2的订单的价格+上一个小数: SELECT total_price+2.2 FROM morder2 WHERE user_id =2 :user_id=2的用户的订单的总价格加上一个小数2.2(在原来的基础上加2.2) ,原来是45,现在加2.2,现在变成47.2 减乘除一样的效果,
二:比较运算符 SELECT 语句中的条件语句经常要使用比较运算符。通过这些比较运算符,可以判断表中的哪些记录是符合条件的。比较结果为真,则返回 1,为假则返回 0,比较结果不确定则返回 NULL。 符号 描述 备注 = 等于 <>, != 不等于 > 大于 < 小于 <= 小于等于 >= 大于等于 BETWEEN 在两值之间 >=min&&<=max NOT BETWEEN 不在两值之间 IN 在集合中 NOT IN 不在集合中 <=> 严格比较两个NULL值是否相等 两个操作码均为NULL时,其所得值为1;而当一个操作码为NULL时,其所得值为0 LIKE 模糊匹配 REGEXP 或 RLIKE 正则式匹配 IS NULL 为空 IS NOT NULL 不为空 比较运算符,等于不等于,大于小于 比较运算符演示:这个一般用在条件里面的(where后面) SELECT * FROM morder2 WHERE region='北京' 等于=:查询地址为北京的订单的数据 SELECT * FROM morder2 WHERE total_price >100 大于>:查询订单总价大于100的数据 SELECT * FROM morder2 WHERE total_price != 12 不等于!= ,查询订单总价不等于12的数据 SELECT * FROM morder2 WHERE total_price <> 12 这种写法也是不等于 SELECT * FROM morder2 WHERE total_price is NULL 为空null,查询总价为空的数据 SELECT * FROM morder2 WHERE total_price is not NULL 不为空 not NULL,查询总结不为空的数据
三:逻辑运算符 逻辑运算符用来判断表达式的真假。如果表达式是真,结果返回 1。如果表达式是假,结果返回 0。 运算符号 作用 NOT 或 ! 逻辑非 AND 逻辑与 OR 逻辑或 XOR 逻辑异或 逻辑运算符一般也是用在条件where里面,可以把多个条件进行组合 and:比如我想查询total_price总价不为空的并且region地址是北京的 SELECT * FROM morder2 WHERE total_price is not NULL AND region ='北京' and,并且,要求条件1和条件2同时满足 or或者,两个条件满足一个就行了 SELECT * FROM morder2 WHERE region ='北京' OR recv_phone='18397500000' #选择地址等于北京或者手机号是18397500000的数据全部打印 not 非,不是什么的,满足手机号不是18397500000全部打印,满足相反的条件 SELECT * FROM morder2 WHERE not recv_phone='18397500000' :满足手机号不是18397500000全部打印
33:数据库索引:数据里面有很多表,很多sql语句,数据多了后,几百万上千万,执行查询语句会变得很慢,索引主要为了提示查询的速度 ,
mysql表字段添加索引可以大大提高mysql的检索速度,数据库就像是一本字典,那么索引就是字典的目录,一般会针对where条件后面的字段条件索引,
我们一般把表里面的一些经常用到的字段添加索引,这样以后根据字段查询,速度大大提升
如果给user表的手机号,给手机号的字段加上索引的话,他就会把这个字段的数据缓存到mysql内部,他有一定的数据结构的,后续根据手机号来查询不需要表里一行行找了
去索引先找到这行数据,然后确定这条数据的位置就可以快速找到了,这个过程类似于字典,如果使用索引,索引类似建立目录,查数据先去目录里面查询,目录很短。快速
从目录里面找到这条数据在第几页,然后进入到这个页面快速查找,---索引跟数据库性能息息相关的
一:native客户端添加普通索引 一般情况下针对where条件后面的字段添加索引,sql语句where手机号等于多少,我们添加手机号就行了 添加时候可以在新建表的时候就可以添加了,大多数情况都是后加的 native客户端可以添加: 1:选中表----右键----设计表 打开后里面有索引的设置,点击索引 然后添加取名字 1:设置名字(idx_phone_num)2:设置字段phone_num(以表什么字段为索引) 3:设置索引类型(一般选择nomal或者unique)nomal是普通的。unique唯一的 这两种选择取决业务,比如说手机号会不会重复,手机号不会重复的话选择unique,如果允许重复的使用nomal普通的 4:后面的字段不用填了,直接点击保存 就设置成功了 然后根据phone_num手机号码进行查询速度变得很快,
二:命令添加索引 添加普通索引: ALTER TABLE morder2 ADD INDEX mdx_phone_num(phone_num) :ALTER TABLE+表名称 ADD INDEX+索引名称(括号里面放索引的字段) 添加唯一索引 ALTER TABLE morder2 ADD UNIQUE mdx_phone_num(phone_num) 删除索引 DROP INDEX mdx_phone_num ON morder2 :DROP(删除)+索引名称 ON+表名 :删除那个表的那个索引 注意:主键本身就是一种唯一索引(表里面都有主键),所以主键不需要加索引,本身天然就是唯一性的一种索引,主键id查询速度非常快的
34:sql表的复制
mysql可以通过sql语句快速复制表,并完成数据的复制 两个表,需要对表中的数据做一个备份,或者做一个测试,不希望在原有的表的基础上去做修改,sql语句写错的话会造成数据的修改和污染,所以需要备份一模一样的表去做测试 这种场景会用到复制表,表整个去复制一份 一:navicate方法复制: 1:选择这个表--2:右键就有复制表的功能 3点击复制数据和结构就会出现一个copy一模一样的表(结构数据都一样) 二:命令的操作如下,通过复制表和复制数据两个过程 1:复制表 CREATE TABLE morder2_copy LIKE morder2; CREATE TABLE+copy表名 LIKE+被复制的表名 需要到mysql命令行界面输入, 现在只是复制了表,没有复制数据 2:复制数据 insert into morder2_copy select * from morder2; insert into+copy表名 select * from +被复制的表 :把后面表的数据insert到前面这个表里面, 复制数据前提需要这两个表的字段数量和类型是一样的,否则不能进行复制,用于数据复制 select * from morder2表示从这个表里面数据全部查询然后insert into到另外一个复制表里面
35:mysql字符串函数 (很多函数,)
字符串相关的函数
1:concat()函数--,将两个或者多个字符串组合成一个字符串(拼接函数,sql造数据比较多) CONCAT(str1,str2,...) CONCAT可以拼接任意数量的字符串 SELECT CONCAT('test',2,'ok') ;直接展示拼接后的字符串内容 SELECT CONCAT(user_name,phone_num) FROM user :SELEC CONCAT后面+字段名称,拼接user_name和phone_num,运行后打印一列数据内容, 把user_name和phone_num用户名和手机号两列的数据拼到一列, 这个user_name不能写引号,加引号'user_name'就变成字符串了,不加引号等于使用变量名--user表里面的user_name, 既可以写一些固定的数据CONCAT,也可以从表里找一些字段进行CONCAT---这就是字符串拼接
2:length()函数 --获取字符串的长度 LENGTH(str) SELECT LENGTH('xxx') :这样写等于查询xxx字符串的长度,输出3 sql语句方法: SELECT LENGTH(phone_num) FROM user :查询user表里面每个phone_num手机号的字符串长度, 每一个函数在sql语句中执行,至少加select,如果想去对表中某些数据进行函数处理的话,需要加from那个表
3:replace()函数--搜索并替换字符串中的子字符串(替换函数) REPLACE(str,from_str,to_str) 三个参数,第一个str字符串,第二个from_str,第三个to_str,表示我可以把某个字段的值进行一个替换 比如替换user表里面的email SELECT replace(email,'ywt','test')FROM user :括号传顺序--1:表里想替换的字段 2:表里面替换字段的某个字符端 3:想要替换成什么字符串 表示替换user表的email字段,把ywt替换成test,固定数据ywt和test需要加引号,只是改变打印输出内容,不改变后端里面的真实数据 SELECT replace(email,'ywt','test')FROM user WHERE id in(1,2,3,4) 后面还可以加各种条件where
4:substring()函数--从具有特定长度的位置开始提前一个子字符串(把字符串其中的一部分数据提取出来) 场景:用户表里面的字段的手机号,现在想获取每个用户手机号的后四位---子字符串 SUBSTRING(str,pos,len) #主要使用三个参数的这个,第一个参数:字符串 第二个参数:从什么位置开始取值 第三个参数:取值的长度 SELECT SUBSTRING(phone_num,8,4) FROM user :打印每个用户手机号的后四位,从第8位开始,包含第8位,8+4
36:时间函数,也是常用函数的一种,造数据很多时候需要处理时间
时间函数: 1:curdate()函数,--返回当前日期 SELECT CURRENT_DATE 打印当前时间,打印当前日期,只到天数 2:now() 函数,----返回当前日期和时间 SELECT NOW() 打印日期+具体小时,分组和秒,非常精切的时间 curdate()函数和now() 两个函数不需要加任何参数就可以调用的函数,可以获取不同精度的时间 3:year() 函数,--返回日期中的年份 YEAR(date) ----year里面需要加个data,必须传一个时间参数,给他一个时间,可以自己写的固定时间 SELECT YEAR ('2019-10-10') 也可以以表中的某个表示时间的字段:cerat_time SELECT YEAR(create_time) FROM user -,括号里面的参数现在不写对应的值,而写表里面的字段,打印表里面每一行所有的年 4:month()函数--返回日期中的月份 SELECT MONTH(create_time) FROM user 5:day()函数,--返回日期中的天数 SELECT DAY(create_time) FROM user 6:hour() ----返回日期中的小时 SELECT HOUR(create_time) FROM user 7:minute()--分钟 SELECT MINUTE(create_time) FROM user 8:second ---秒 SELECT SECOND(create_time) FROM user
上面的函数都可以对时间进行处理的,可以获取时间的任何部分。前两个用的比较多
37:mysql处理数据函数
数据处理函数: rand() ,返回0-1之间随机小数 floor(),小数取整 上面两个函数一般用来做一些数据处理的, 使用场景:比如我想获取一个随机数, 一:RAND() :返回0-1之间随机小数,这个函数没有任何参数---随机的, 有时候做insert语句的时候,我们想对某个字段生成一个随机值,比如我想对年龄生成一个随机值,每次insert的时候都不一样--随机的,使用RAND()函数,写在insert语句里面 大多情况下希望有一个随机的整数,需要使用到数学计算,如下: RAND()*100 --乘100后变成0-100的小数了,对这个小数取整, SELECT FLOOR(RAND() * 100 ) :这个表达式取0-100的整数 二:FLOOR(X)函数,小数取整 SELECT FLOOR(3.141212) ---输出3,取整,把把后面小数去掉(不会四舍五入) 三:取值0-200开始的随机小数 SELECT FLOOR(RAND() * 200 ) 4:获取从10-100的随机小数 SELECT FLOOR(RAND() * 100 ) ---这个取值0-100 SELECT FLOOR(10 + RAND() * 100 ) ----这个取值10-110 SELECT FLOOR(10 + RAND() * 90 ) -----这个取值10-100 ,如果起始这个值不是0的话,后面乘以的值就要用期望后边界的值减去期望起始值
38:mysql的主键和外键,
主键和外键都是mysql的一种约束
一:mysql主键(primary key)是唯一标识表中每行的的列或一组列,当定义表的主键时,保修遵循以下规则 1:主键必须包含唯一值,如果主键由多个列组成,则这些列中的值的组合必须唯一 2:主键不能包含null值,这意味着必须使用not null属性声明主键列,如果没有指定not null,mysql将强制为主键列为not null 3:一张表只有一个主键,主键字段的数据类型必须为整数类型 主键就是一个字段,比如用户表里面有个id字段,这个id是不重复,是唯一的,这个id就可以代表某一行数据,选择id作为主键, 当成主键之后以后在这个表里写数据,数据库层面可以保证不重复的,因为id具有唯一性 以后查询操作的时候,通过主键查询,比如查询id=1的数据,性能会非常好, 定义主键的时候需要满足上面三个规则:如果有一条id=12的数据,如果再insert一条id=12的就会报错,机制上保证这个字段不会出现重复的,数据库层面来保证的 如果 说id和age两列组合为主键,列中的值的组合必须唯一 一般情况下选择一个列就是id这列的为主键 主键列不能包含空值,定义表的时候把这个字段定义成非空 一张表只有一个主键,主键字段的数据类型必须为整数类型 1:navicate设置主键,新建表有这个操作 1:选中表点击鼠标右键 2:选中设计表 3:每个字段后面有个键的设置(小钥匙代表它就是主键,可以选中和取消),主键不允许为空(允许空值框不能勾选) 4:设置号后点击保存 而且主键一般都是自动递增(数据库自动维护的)勾选自动递增的选项 一般设置主键都是在表新建的时候就创建好了,可以使用navicate客户端创建新表的时候勾选设置保存 2:sql语句建表的时候指定主键 CREATE TABLE users ( user_id int(10) AUTO_INCREMENT PRIMARY KEY, #这行user_id设置成主键,对应字段上加上PRIMARY KEY代表是主键,AUTO_INCREMENT代表自动递增 user_name varchar(255) DEFAULT NULL, password varchar(255) DEFAULT NULL, age int(10) DEFAULT NULL, ) ;
二:外键:外键表示一个表中的一个字段被另一个表中的一个字段引用,外键可以在数据库层面保证数据的完整性 外键一般是用来做数据约束, morder订单表里面的user_id数据来源user表里面的id,订单表里面每一个对应user_id必须都在user表里面id里面存在的,如果不存在就说明出现了异常数据了 出现异常的数据很可能是程序的bug,程序层面做这种限制异常数据限制,还可以数据库层面来做--使用外键 外键:外键表示一个表中的一个字段被另一个表中的一个字段引用,外键可以在数据库层面保证数据的完整性 morder订单表它有自己的主键id,不重复,user_id这个字段引用的user表的id字段,这样的话数据库可以保证这两页的数据必须数存在的情况( 比如订单表里面的user_id都是必须user表里面存在的id) insert插入表的时候,如果新建数据的user_id这个字段在user表里id字段不存在的话,异常情况报错,不可能成功插入,解决脏数据的问题 1:navicate设置外键, 1:选中表点击鼠标右键 2:选中设计表 3:表的最上层有个外键选项 --点击设置 4: 进行设置 名字:随便起 · 字段/栏位你要对应那个字段加外键(user_id) 外键必然引像另外某个表,这个表在那个数据库里面的(mtx_2) 参考表:mtx_2的那个表user user表里面的那个字段(id字段) -------这样就设置成功了,把morder里面的user_id和user表里面的id通过外键关联起来了,点击保存即可 如果保存的时候关联失败的话,一般是因为morder表里存在异常数据,morder表的user_id字段的值必须都在user表字段id里面的值的范围内,否则无法外键关联起来 删除异常数据才可以正常关联, morder操作:外键关联后如果再像morder表里写异常数据(user_id不在user表id字段的范围内的话)会报错,不会成功,外键的存在不允许里面写脏数据,数据库层面保证数据的唯一性 user表操作:外键关联后user表不可以随便删除被morder里关联的数据(删除user表中被关联的id=2的数据,那么morder表里user_id等于2的数据就变成脏数据了)--数据库不允许这种 情况发送,数据库层面维护这两个表数据关联性,真的想删除user表中被关联的id=2的数据必须先删除morder表里user_id等于2的数据才能删除 主键和外键应用很广泛的,外键:数据库层面保证数据的完整性, 主键:主要是为了保证这列不重复, 还可以提升性能 ----主键和外键的作用 2:sql设置外键 CREATE TABLE new_table ( user_id int(10), user_name varchar(255) DEFAULT NULL, password varchar(255) DEFAULT NULL, age int(10) DEFAULT NULL, PRIMARY KEY(id) FOREIGN KEY ('user_id') REFERENCES `user`(id) on DELETE RESTRICT on UPDATE RESTRICT #设置外键的sql语法 ) ; 把当前表的user_id字段和user表的id字段外键关联起来
39:sql存储过程语法
存储过程(stored procedure)是在大型数据库系统中,一组为了完成特定功能的sql语句集,(很多条sql语句组成的一个集合),存储过程他是存储在数据库中的, 一次编译后永久有效,用户通过指定存储过程的名字并给出参数(如果该存储过程带有参数)来执行它,存储过程是数据库中的一个重要对象 存储过程类似于写的java或者python写的脚本函数一样,带一定逻辑的,并且这种逻辑代码存储到数据库之中的,只要你想用的时候调用一下这个存储过程就行 一般情况下存储过程,在数据库里面用来造数据,批量快速造一系列数据 很多开发都会用到存储过程,很多公司里面的业务放在存储过程里面的,代码里面调用一下存储过程,相当于把数据进行了一下修改或者新增之类的,做一些逻辑方面的东西 总结:存储过程=逻辑+一定sql语句 逻辑和编程语言逻辑一样,if else 循环之类的,把sql语句嵌套到某逻辑里面可以快速构造很多数据和其他功能-----这就是存储过程 常用的逻辑: 1:while循环 while 条件 do do,表示开始做某些事情,事情在语句内容里面,可以写很多sql语句=满足一定条件下就执行sql语句 语句; end while; 条件执行完一次后接着再去循环再去判断一次这条件是否满足,如果满足再接着执行 所以说while循环 可以用他来设置一个条件,比如我想产生一千条数据怎么做,我就定义某个数据,某个变量,初始值等于1,然后判断它如果小于1000就执行 insert语句,执行完后变量+1,这样循环执行,一直到不满足条件就不再执行了--while循环 2:if 判断 语法 if 条件 then 语句; else 语句; end if; if通常做一些逻辑判断, 这两个语法的话很明显看到存储过程里面它这种逻辑判断,有开始就结束,有while 最后就是end while 有if 最后就是end if ---都有这种特定
40:存储数据实战:
需求:某项目联调前,需要构造10000个测试账号----使用存储过程来解决,注册账号其实账号账号存储再数据库里面,只要数据库有的账号,就相当于注册,满足注册规则才能是有效的账号 需要知道你知道注册的用户写在那个表里面,然后找到这个表,看正常注册用户都是什么格式的然后模拟它往里面insert一些语句就行了, INSERT INTO user (user_name,password,age,gender,phone_num,email,create_time) VALUES( 'test0','123456',10,0,'18397508888','test0@qq.com',NOW() ) 写入单个用户的sql语句,制造1w个账户,需要想办法循环执行sql语句,并且循环执行过程中这些数据需要发送变化,满足业务规则---才能完成需求--存储过程while循环来完成需求 while条件就是小于1w然后执行insert语句他就可以帮我们做成这件时事情 写存储过程不能在写sql语句的地方,因为这个地方只能写sql语句,不能写存储过程,需要 navicat---点击上面的函数按钮 ----然后点击新建函数--------选中函数类型,(过程--存储过程)----这时候出现一个另外的窗口专门写存储过程的 生成的脚本模板里面有个BEGIN和END;存储过程以BEGIN开头END结尾的中间是要真正想写的东西, 怎么写: 写存储过程需要掌握思路:目的,造数据,必须要执行insert语句,使用while循环循环起来 注意:每一个语句的结束要加分号 ;,否则报错,sql语句如下: 构造10000个测试账号sql语句: CREATE DEFINER=`root`@`localhost` PROCEDURE `create_user`() BEGIN ----定义所需要的变量----- DECLARE i INT(6) DEFAULT 0; DECLARE u_name VARCHAR(10); DECLARE u_age int(4); DECLARE u_gender int(2); DECLARE u_phone VARCHAR(11); DECLARE u_email VARCHAR(20); -----while循环来批量构造数据---- WHILE i<10000 DO ----if用来判断奇数偶数定义性别数据----- if i % 2 =0 THEN set u_gender =0; ELSE set u_gender =1; END IF; ----赋值操作----------------- set u_name=CONCAT('test_',i); set u_age=FLOOR(RAND()*100); set u_phone=CONCAT('183975',i+10000); set u_email=CONCAT(u_name,'@qq.com'); -----添加数据的操作--------------- INSERT INTO user (user_name,password,age,gender,phone_num,email,create_time) VALUES(u_name,'123456',u_age,u_gender,u_phone,u_email,NOW()); SET i=i+1; END WHILE; END
使用navicate注意小细节,它这边展示的数据默认情况就展示1000条,如果更多的数据是放在第二页了,或者后面的页 BEGIN DECLARE i INT(6) DEFAULT 0; DECLARE u_phone VARCHAR(10); DECLARE u_type INT(2); DECLARE u_address VARCHAR(10); DECLARE u_price INT(10) WHILE i<10000 DO if i % 2 =0 THEN set u_type =0; ELSE set u_type =1; END IF; SET u_phone=CONCAT("183975",10000+i); set u_price=10+i; INSERT INTO morder2_copy(phone_num,address,price,type,create_time) VALUES (u_phone,u_address,u_price,u_type,NOW()); SET i =i+1; END WHILE; END
41:数据的导入和导出
使用mysql提供的命令进行导入和导出,通过navicate工具导入导出比较简单 一:命令导出:把数据和表全部导出来备份,文件放在某个位置后续可以导入, 使用mysql提供的mysqldump工具,在mysql的bin目录下执行 二:navicat工具的方法导出数据, 1:数据库的导出---选中数据库,点击鼠标右键----2:转储数据库-----3选择一个路径点击保存-----4然后点击关闭 2:单表的导出-----选中表,点击鼠标右键----2:转储sql文件----选择一个路径点击保存-----4然后点击关闭 单表只导出某些字段用-使用导出向导(数据库里面的手机号和用户名导出) 单表的导出-----选中表,点击鼠标右键----2:导出向导()-----3:选择保存文本 4:选择要导出的表 +要导出的位置 5:选择导出哪些列 6:选择分割符号,因为导出来就两列,中间用什么分隔(一般情况下用逗号分隔) 6:下一步点击开始 7:点击关闭 整库的导出,单表的导出,还要某些字段的导出 导出的数据里面既包含了表结构也包含了数据,都是有的, 三:navicat工具导入数据, 1:表菜单空白的地方右键 2:运行sql文件 3:选择后面的目录按钮点击找到文件路径 点击打开 4:点击开始 5:点击关闭 :整个表的导入 1:选择一个数据库连接右键 2:点击运行sql文件 3:选择后面的目录按钮点击找到文件路径 点击打开 4:点击开始 5:点击关闭 上面导入数据库操作失败:因为导出的一些数据库,sql语句里面都是要在某个库上进行操作的,一些sql语句根据执行不了,数据库无法恢复 整库的导入需要先新建一个数据库, 1:新建数据库mtx(字符集utf8点击确定) 2:选择mtx新建的数据库 3:右键点击运行运行sql文件 4:选择后面的目录按钮点击找到文件路径 点击打开 4:点击开始 5:点击关闭 navicat方式来做数据的导入和导出
42:使用sql命令进行数据的导入和导出 ,使用工具比较简单
一:命令导出: 使用mysql提供的mysqldump工具,在mysql的bin目录下执行,mysqldump这个工具在mysql bin目录下,如果在linux系统也是在bin目录下有这个工具 我的windows版本安装目录:C:\Program Files\MySQL\MySQL Server 5.7\bin :mysqldump.exe 在这里这个文件不能双击执行,导出的时候需要加参数,在命令行下执行 在windows下的命令行,这是exe程序,我们使用这个工具去导出的,在windows下的命名行执行命令: 1:打开命令行,进入到bin文件目录:cd C:\Program Files\MySQL\MySQL Server 5.7\bin, 2:执行 mysqldump -u root -p mtx_2 > D:\mtx.sql 命令 :u root--u+用户名 -p--后面可以加密码也可以不加,不加输入命令点击回车后会再让你输入密码的,mtx_2数据库的名称 D:\mtx.sql:库的数据导入到那个路径并命名,不要写c盘的路径,c盘很可能有管理员权限的控制不让写, 上面是语句是windows的命令不是一个sql 密码输入点击回车后就结束了:还是在C:\Program Files\MySQL\MySQL Server 5.7\bin>路径 上面就导出成功了 导出的时候如果只想导某个表,不想导出整个库,想导出mtx库下面的user表 命令换成如下:mtx_2库后面+空格+表名 mysqldump -u root -p mtx_2 user > D:\user.sql 表和库的导出就差了后面多了一个空格+表名 二:数据的导入: 首先我想导入D:\mtx.sql整个数据库 1:把D:\mtx.sql的文件拷贝到mysql的bin目录下面, 2:在bin目录的cmd下登录mysql 导出的时候用的是mysql提供的exe的工具,因为导入的时候需要用到sql命令的,需要进入到mysql里面 3:登录使用 :mysql -u root -p 回车后输入密码:123456就登录了,现在进入到mysql命令行的模式下了 倒库之前必须先选择一个库:use mtx 选择mtx_2这个数据库 4:source mtx.sql; #现在 mtx.sql数据库没有被删除,但是也可以导入,会完全覆盖,删除的话数据会重新回来 使用mysql自带的方式做导入和导出 导出用到mysql提供的工具mysqldump 导入用source命令+文件名称,然后这个mtx.sql这个sql文件要放在mysql的bin目录下
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 【自荐】一款简洁、开源的在线白板工具 Drawnix
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY
· Docker 太简单,K8s 太复杂?w7panel 让容器管理更轻松!