第六章 数据库和缓存
1、列举常见的关系型数据库和非关系型数据库。
- 关系型数据库:Oracle、MySQL、DB2、Microsoft SQL Server、Microsoft Access
- 非关系型数据库:mongodb,redis,elasticsearch,NoSql
2、Mysql常见数据库引擎及区别
- InnoDB:支持事务、行级锁、支持外键;用于事务处理应用程序,具有众多特性,包括ACID事务支持;
- MyISAM:支持表级锁,innodb支持的它都不支持;
- Memory:将所有数据保存再RAM中,断电消失;
- blackhole:用来做多级主从复制,往里写什么没什么;
3、简述事务及其特性
- 事务是用户定义的一个数据库操作序列,这些操作要么全做要么全不做,是一个不可分割的工作单位
- 事务具有4个特性:原子性、一致性、隔离性和持续性。
- 原子性:事务是数据库的逻辑工作单位,事务中包括的诸操作要么都做,要么都不做。
- 一致性:事务执行的结果必须是使数据库从一个一致性状态变到另一个一致性状态。
- 隔离性:一个事务的执行不能被其他事务干扰。即一个事务内部的操作及使用的数据对其他并发事务是隔离的,并发执行的各个事务之间不能互相干扰。
- 持续性:持续性也称永久性,指一个事务一旦提交,它对数据库中数据的改变就应该是永久性的。接下来的其他操作或故障不应该对其执行结果有任何影响。
4、简述触发器、函数、视图和存储过程
- 触发器:触发器是一个特殊的存储过程,它是MySQL在insert、update、delete的时候自动执行的代码块
- 函数:MySQL中提供了许多内置函数,还可以自定义函数(实现程序员需要sql逻辑处理)
- 视图:视图是由查询结果形成的一张虚拟表,是表通过某种运算得到的一个投影
- 存储过程:把一段代码封装起来,当要执行这一段代码的时候,可以通过调用该存储过程来实现(经过第一次编译后再次调用不需要再次编译,比一个个执行sql语句效率高)
5、mysql索引种类
- 普通索引:仅加速查询
- 唯一索引:加速查询 + 列值唯一(可以有null)
- 主键索引:加速查询 + 列值唯一(不可以有null)+ 表中只有一个
- 组合索引:多列值组成一个索引,专门用于组合搜索,其效率大于索引合并
- 全文索引:对文本的内容进行分词,进行搜索
6、索引在什么情况下遵循最左前缀的规则?
- 在多字段进行索引的时候,会遵循以上原则
7、Mysql常见的函数
- ABS(x):返回x的绝对值
- ROUND(x):返回参数x的四舍五入的一个整数
- TRIM(str):去除字符串两边的空白
- COUNT():返回值的个数
- AVG():返回平均值
- SUM():求和
8、列举创建索引但是无法命中索引的情况
- 如果条件中有or,即使其中有条件带索引也不会使用(这也是为什么尽量少用or的原因)
- 对于多列索引,不是使用的第一部分(第一个),则不会使用索引
- like查询是以%开头
- 如果列类型是字符串,那一定要在条件中将数据使用引号引用起来,否则不使用索引
- 如果mysql估计使用全表扫描要比使用索引快,则不使用索引
9、数据库的导入与导出命令
- 导出(mysqldump)
- 导出数据和表结构
- mysqldump -uroot -p dbname > dbname .sql
- 只导出表结构
- mysqldump -uroot -p -d dbname > dbname .sql
- 导出数据和表结构
- 导入
- mysql -u用户名 -p密码 数据库名 < 数据库名.sql
10、你了解哪些数据库优化方案
- 减少数据访问-创建并正确使用索引
- 返回更少的数据
- 数据分页处理
- 只返回需要的字段
- 减少交互次数
- 使用存储过程
- 优化业务逻辑
- 减少服务器的cpu运算
- 使用绑定变量
- 合理使用排序
- 减少比较操作
- 大量复杂运算在客户端处理
- 利用更多资源
- 客户端多进程访问
- 数据库并行处理
11、char和varchar的区别
- 保存方式不一样
- char有固定的长度,而varchar属于可变长的字符类型
- char的效率比varchar高
12、MySQL执行计划的作用和使用方法
- 作用:用来进行查询分析,比如整个查询涉及多少防,使用哪些索引,运行时间等
- 使用方法:使用explain关键字,如explain select xxx from xxx;
13、为什么数据很大的时候使用limit offset分页时,越往后翻速度越慢,如何优化?
- 使用limit分页时,比如limit 10000,20的意思是扫描满足条件的10020行,扔掉前面的10000行,最后返回20行,问题就出在这,当数据量大的时候,大量时间花在了扫描上面了。
- 优化方法:
- 当一个数据库表过于庞大,LIMIT offset, length中的offset值过大,则SQL查询语句会非常缓慢,你需增加order by,并且order by字段需要建立索引。
- 如果使用子查询去优化LIMIT的话,则子查询必须是连续的,某种意义来讲,子查询不应该有where条件,where会过滤数据,使数据失去连续性
14、什么是索引合并
- 索引合并是把几个索引的范围扫描合并成一个索引。
- 索引合并的时候,会对索引进行并集,交集或者先交集再并集操作,以便合并成一个索引。
- 这些需要合并的索引只能是一个表的。不能对多表进行索引合并。
15、什么是覆盖索引
覆盖索引又可以称为索引覆盖。
- 解释一: 就是select的数据列只用从索引中就能够取得,不必从数据表中读取,换句话说查询列要被所使用的索引覆盖。
- 解释二: 索引是高效找到行的一个方法,当能通过检索索引就可以读取想要的数据,那就不需要再到数据表中读取行了。如果一个索引包含了(或覆盖了)满足查询语句中字段与条件的数据就叫做覆盖索引。
- 解释三: 是非聚集组合索引的一种形式,它包括在查询里的Select、Join和Where子句用到的所有列(即建立索引的字段正好是覆盖查询语句[select子句]与查询条件[Where子句]中所涉及的字段,也即,索引包含了查询正在查找的所有数据)。
16、简述数据库的读写分离
- 读写分离就是在主服务器上修改,数据会同步到从服务器,从服务器只能提供读取数据,不能写入,实现备份的同时也实现了数据库性能的优化,以及提升了服务器安全。
17、简述数据库分库分表
- 垂直切分
- 垂直分库:
- 就是根据业务耦合性,将关联度低的不同表存储在不同的数据库
- 垂直分表:
- 基于数据库中的"列"进行,某个表字段较多,可以新建一张扩展表,将不经常用或字段长度较大的字段拆分出去到扩展表中。
- 垂直分库:
- 横向切分:
- 水平切分分为库内分表和分库分表,是根据表内数据内在的逻辑关系,将同一个表按不同的条件分散到多个数据库或多个表中,每个表中只包含一部分数据,从而使得单个表的数据量变小,达到分布式的效果。
18、数据库锁的作用
- 锁分为三种:乐观锁,悲观锁和共享锁
- 数据库和操作系统一样,是一个多用户使用的共享资源。当多个用户并发地存取数据 时,在数据库中就会产生多个事务同时存取同一数据的情况。若对并发操作不加控制就可能会读取和存储不正确的数据,破坏数据库的一致性。加锁是实现数据库并 发控制的一个非常重要的技术。在实际应用中经常会遇到的与锁相关的异常情况,当两个事务需要一组有冲突的锁,而不能将事务继续下去的话,就会出现死锁,严 重影响应用的正常执行。
24、MySQL的半同步复制原理
- 半同步复制,介于异步复制和全同步复制之间,主库在执行完客户端提交的事务后不是立刻返回给客户端,而是等待至少一个从库接收到并写到relay log中才返回给客户端。相对于异步复制,半同步复制牺牲了一定的性能,提高了数据的安全性。
- 异步复制,MySQL默认的复制是异步的,主库在执行完客户端提交的事务后会立即将结果返给给客户端,并不关心从库是否已经接收并处理。原理最简单,性能最好,但是主从之间数据不一致的概率很大。
- 全同步复制,指当主库执行完一个事务,所有的从库都执行了该事务才返回给客户端。因为需要等待所有从库执行完该事务才能返回,所以全同步复制的性能必然会收到严重的影响。
28、MySQL如何创建索引
- ALTER TABLE
- ALTER TABLE用来创建普通索引、UNIQUE索引或PRIMARY KEY索引。
- ALTER TABLE table_name ADD INDEX index_name (column_list)
- ALTER TABLE table_name ADD UNIQUE (column_list)
- ALTER TABLE table_name ADD PRIMARY KEY (column_list)
- ALTER TABLE用来创建普通索引、UNIQUE索引或PRIMARY KEY索引。
- CREATE INDEX
- CREATE INDEX可对表增加普通索引或UNIQUE索引。
- CREATE INDEX index_name ON table_name (column_list)
- CREATE UNIQUE INDEX index_name ON table_name (column_list)
- CREATE INDEX可对表增加普通索引或UNIQUE索引。
29、简述SQL注入原理,以及如何在代码层面防止sql注入
通俗点讲,SQL注入的根本原因是: "用户输入数据"意外变成了代码被执行。 "用户输入数据"我这里可以指Web前端$_POST,$_GET获取的数据,也可以指从数据库获取的数据,当然也不排除程序猿无意中使用的特殊字符串。 在SQL语句的拼接中,一些含特殊字符的变量在拼接时破坏了SQL语句的结构,导致"用户输入数据"意外变成了代码被执行。
规避方法:
- 理语句法 (解析协议层面上完全规避SQL注入)
- 字符串转义(不要在sql中拼接字符) # query作为sql模板,args为将要传入的参数 execute(query, args=None)
30、使用python将数据库的student表中的数据写入db.txt
import pymysql connect=pymysql.Connect( host='', port=, user='', passwd='', db='', charset='', ) cursor=connect.cursor() sql='select * from student' cursor.execute(sql) students=cursor.fetchall() with open('db.txt','w') as f: for student in students: f.write(student) cursor.close() connect.close()
31、简述left join和right join的区别
- 左连接和右连接很相似,只是左右表位置的不同罢了。
- left join(左连接) 返回包括左表中的所有记录和右表中连接字段相等的记录
- right join(右连接) 返回包括右表中的所有记录和左表中连接字段相等的记录
32、索引有什么作用,有哪些分类,有什么好处和坏处?
- 作用:为了增加查询速度,提高系统性能
- 分类:
- 唯一索引:不允许其中任何两行具有相同索引值的索引。
- 非唯一索引:允许其中任何两行具有相同索引值的索引。
- 主键索引:有一列或列组合,其值唯一标识表中的每一行。
- 聚集索引:表中行的物理顺序与键值的逻辑(索引)顺序相同。一个表只能包含一个聚集索引。
- 好处:
- 帮助用户提高查询速度
- 利用索引的唯一性来控制记录的唯一性
- 可以加速表与表之间的连接
- 降低查询中分组和排序的时间
- 坏处:
- 存储索引占用磁盘空间
- 执行数据修改操作(INSERT、UPDATE、DELETE)产生索引维护
39、mysql慢日志
- MySQL的慢查询日志是MySQL提供的一种日志记录,它用来记录在MySQL中响应时间超过阀值的语句,具体指运行时间超过long_query_time值的SQL,则会被记录到慢查询日志中。
- 存储方式:
- Memecache把数据全部存在内存之中,断电后会挂掉,数据不能超过内存大小。Redis有部份存在硬盘上,这样能保证数据的持久性。
- 数据支持类型
- Memcache对数据类型支持相对简单。Redis有复杂的数据类型。
- 使用底层模型不同
- 它们之间底层实现方式 以及与客户端之间通信的应用协议不一样。Redis直接自己构建了VM 机制 ,因为一般的系统调用系统函数的话,会浪费一定的时间去移动和请求。
- value大小
- redis最大可以达到1GB,而memcache只有1MB
43、如何高效的找到redis中所有以oldboy开头的key
- scan 0 match oldboy* count 5
- 表示从游标0开始查询felix开头的key,每次返回5条,但是这个5条不一定
44、什么是一致性哈希
- 一致性哈希简称DHT,是麻省理工学院提出的一种算法,目前主要应用于分布式缓存当中。一致性哈希可以有效地解决分布式存储结构下动态增加和删除节点所带来的问题。
45、redis是单进程单线程的吗?
- Redis采用的是基于内存的采用的是单进程单线程模型的KV数据库
46、redis默认多少个db及作用?
- 默认有16个数据库
47、如果redis中的某个列表中的数据量非常大,如何实现循环显示每一个值?
- 使用生成器一个一个取
48、redis如何实现主从复制?以及数据同步机制?
- redis从主从结构可以采用一主多从或者级联结构,主从复制可以根据是否全量分为全量同步和增量同步。
- 全量同步:redis全量复制一般发生在slave初始化阶段,这时slave需要将master上的所有数据都复制一份步骤如下:
- 从服务器连接主服务器,发送SYNC命令;
- 主服务器接收到SYNC命名后,开始执行BGSAVE命令生成RDB文件并使用缓冲区记录此后执行的所有写命令;
- 主服务器BGSAVE执行完后,向所有从服务器发送快照文件,并在发送期间继续记录被执行的写命令;
- 从服务器收到快照文件后丢弃所有旧数据,载入收到的快照;
- 主服务器快照发送完毕后开始向从服务器发送缓冲区中的写命令;
- 从服务器完成对快照的载入,开始接收命令请求,并执行来自主服务器缓冲区的写命令;
- 增量同步:
- Redis增量复制是指Slave初始化后开始正常工作时主服务器发生的写操作同步到从服务器的过程。 增量复制的过程主要是主服务器每执行一个写命令就会向从服务器发送相同的写命令,从服务器接收并执行收到的写命令。
- Redis主从同步策略
- 主从刚刚连接的时候,进行全量同步;全同步结束后,进行增量同步。当然,如果有需要,slave 在任何时候都可以发起全量同步。redis 策略是,无论如何,首先会尝试进行增量同步,如不成功,要求从机进行全量同步
49、redis中sentinel的作用
- Redis Sentinel是一个用来监控redis集群中节点的状态,不用来存储数据。当集群中的某个节点有故障时,可以自动的进行故障转移的操作。通常为了保证sentinel的高可用,sentinel也会部署多个
50、如何实现redis集群
- Twitter开发的twemproxy
- 豌豆荚开发的codis
- redis官方的redis-cluster
51、redis中默认有多少个哈希槽
- 2^14个
- Redis 集群没有使用一致性hash, 而是引入了哈希槽的概念。
52、简述redis的有几种持久化策略以及比较?
- RDB 持久化可以在指定的时间间隔内生成数据集的时间点快照。
- AOF 持久化记录服务器执行的所有写操作命令,并在服务器启动时,通过重新执行这些命令来还原数据集。 AOF 文件中的命令全部以 Redis 协议的格式来保存,新命令会被追加到文件的末尾。 Redis 还可以在后台对 AOF 文件进行重写(rewrite),使得 AOF 文件的体积不会超出保存数据集状态所需的实际大小。
- 区别:
RDB持久化是指在指定的时间间隔内将内存中的数据集快照写入磁盘,实际操作过程是fork一个子进程,先将数据集写入临时文件,写入成功后,再替换之前的文件,用二进制压缩存储。
AOF持久化以日志的形式记录服务器所处理的每一个写、删除操作,查询操作不会记录,以文本的方式记录,可以打开文件看到详细的操作记录。
53、列举redis支持的过期策略
- 定时删除
- 在设置key的过期时间的同时,为该key创建一个定时器,让定时器在key的过期时间来临时,对key进行删除
- 惰性删除
- key过期的时候不删除,每次从数据库获取key的时候去检查是否过期,若过期,则删除,返回null。
- 定期删除
- 每隔一段时间执行一次删除(在redis.conf配置文件设置hz,1s刷新的频率)过期key操作
54、mysql里有2000w数据,redis中只存20w得数据,如何保证redis中的数据都是热点数据
redis 内存数据集大小上升到一定大小的时候,就会施行数据淘汰策略。redis 提供 6种数据淘汰策略:
- volatile-lru:从已设置过期时间的数据集(server.db[i].expires)中挑选最近最少使用的数据淘汰
- volatile-ttl:从已设置过期时间的数据集(server.db[i].expires)中挑选将要过期的数据淘汰
- volatile-random:从已设置过期时间的数据集(server.db[i].expires)中任意选择数据淘汰
- allkeys-lru:从数据集(server.db[i].dict)中挑选最近最少使用的数据淘汰
- allkeys-random:从数据集(server.db[i].dict)中任意选择数据淘汰
- no-enviction(驱逐):禁止驱逐数据
57、如何基于redis实现发布订阅
# 发布者 #coding:utf-8import time import redis number_list = ['300033', '300032', '300031', '300030'] signal = ['1', '-1', '1', '-1'] rc = redis.StrictRedis(host='***', port='6379', db=3, password='********') for i in range(len(number_list)): value_new = str(number_list[i]) + ' ' + str(signal[i]) rc.publish("liao", value_new) #发布消息到liao # 订阅者 #coding:utf-8import time import redis rc = redis.StrictRedis(host='****', port='6379', db=3, password='******') ps = rc.pubsub() ps.subscribe('liao') #从liao订阅消息for item in ps.listen(): #监听状态:有消息发布了就拿过来 if item['type'] == 'message': print item['channel'] print item['data']
58、什么是codis
- Codis 是一个分布式 Redis 解决方案, 对于上层的应用来说, 连接到 Codis Proxy 和连接原生的 Redis Server 没有明显的区别 (有一些命令不支持), 上层应用可以像使用单机的 Redis 一样使用, Codis 底层会处理请求的转发, 不停机的数据迁移等工作, 所有后边的一切事情, 对于前面的客户端来说是透明的, 可以简单的认为后边连接的是一个内存无限大的 Redis 服务,当然,前段时间redis官方的3.0出了稳定版,3.0支持集群功能,codis的实现原理和3.0的集群功能差不多。
59、什么是Twemproxy
- Twemproxy是一种代理分片机制,由Twitter开源。Twemproxy作为代理,可接受来自多个程序的访问,按照路由规则,转发给后台的各个Redis服务器,再原路返回。该方案很好的解决了单个Redis实例承载能力的问题。当然,Twemproxy本身也是单点,需要用Keepalived做高可用方案。通过Twemproxy可以使用多台服务器来水平扩张redis服务,可以有效的避免单点故障问题。虽然使用Twemproxy需要更多的硬件资源和在redis性能有一定的损失(twitter测试约20%),但是能够提高整个系统的HA也是相当划算的。不熟悉twemproxy的同学,如果玩过nginx反向代理或者mysql proxy,那么你肯定也懂twemproxy了。其实twemproxy不光实现了redis协议
60、redis如何实现事务
61、redis中watch的作用
watch 用于在进行事务操作的最后一步也就是在执行exec 之前对某个key进行监视 如果这个被监视的key被改动,那么事务就被取消,否则事务正常执行. 一般在MULTI 命令前就用watch命令对某个key进行监控.如果想让key取消被监控,可以用unwatch命令
64、了解过Hbase,DB2,SQLServer,Access吗
- Hbase:HBase是一个分布式的、面向列的开源数据库
- DB2:一套关系型数据库管理系统,
- SQLServer:SQL Server是由Microsoft开发和推广的关系数据库管理系统
- Sccess:Access是由微软发布的关系数据库管理系统。
65、DNS域名解析过程
- 浏览器检查缓存中有没有这个域名对应的解析后的IP地址,如果缓存中有,解析过程结束。缓存大小、时间都有限制,时间由TTL属性决定;
- 如果浏览器缓存中么有,浏览器会查找操作系统缓存中有无这个域名DNS解析后的结果。操作系统也有一个域名解析的过程,windows通过C:\Windows\System32\drivers\etc\hosts,浏览器会优先使用这个解析结果(Win7已将hosts设置为只读),linux系统中/etc/named.conf。目前为止都是在本机完成,如果未完成,才会真正请求域名服务器解析域名。
- “网络配置”中都会有“DNX服务器地址”,操作系统会把域名发送给这个LDNS,本地区的域名服务器,通常都会提供一个本地互联网接入的DNS解析服务。就在你所在城市的某个角落,通过ipconfig可以看到。
- 如果LDNS仍然没有命中,则向RootServer域名服务器请求解析。
- 根域名服务器向本地域名服务器返回一个所查询域的主域名服务器(gTLD Server)。国际顶级域名服务器(.com、.cn、.org等),全球13台。
- 本地域名服务器(Local DNS Server)再向上一步返回的gTLD发送请求。
- gTLD返回域名对应NameServer域名服务器地址,通常由你购买域名的服务商提供。
- NameServer服务器查询域名与IP映射关系表,返回目标IP记录和TTL值给DNS Server域名服务器。
- Local DNS Server根据TTL缓存该IP解析。
- 缓存结果返回给用户,用户根据TTL缓存到本地操作系统中,域名解析过程结束。
66、MySQL的建表语句
# 创建表,例子 # 所谓的建表就是声明列的过程,所以要首先分析列 create table member( id int unsigned auto_increment primary key, username varchar(20) not null default '', gender char(1) not null default '', weight tinyint unsigned not null default 0, birth date not null default '0000-00-00', salary decimal(8,2) not null default 0.00, lastlogin int unsigned not null default 0 )engine myisam charset utf8;
67、MySQL的增删改查
- 增
- 指定字段名
- 语法:INSERT INTO 表名(字段名1,字段名2,…)VALUES(值1,值2,…);
- 举例:INSERT INTO student(id,name,grade) VALUES(1,'zhangshan',98);
- 不指定字段名
- 语法:INSERT INTO 表名 VALUES(值11,值2,…);
- 举例:INSERT INTO student VALUES (2,'lisi',62);
- 其他写法
- 语法:INSERT INTO 表名 SET 字段名1=值1[,字段名2=值2,…]
- 举例:INSERT INTO student SET id=4,name='zhaoliu',grade=72;
- 同时添加多条数据
- 语法:INSERT INTO 表名[(字段名1,字段名2,…)] VALUES (值1,值2,…),(值1,值2,…),…(值1,值2,…)
- 举例:INSERT INTO student VALUES (5,‘lilei’,99), (6,'hanmeimei',87), (8,'poly',76);
- 指定字段名
- 删
- 删除部分数据
- 语法:DELETE FROM 表名 [WHERE 条件表达式]
- 命令:DELETE FROM student WHERE id=7;
- 删除全部数据
- 语法:DELETE FROM 表名
- 命令:DELETE FROM student;
- 推荐的删除全部数据
- 语法:TRUNCTE [TABLE ] 表名
- 举例:TRUNCATE TABLE student
- 删除部分数据
- 改
- 更新部分数据
- 语法:UPDATE 表名 SET 字段名1=值1,[ ,字段名2=值2,…] [ WHERE 条件表达式 ]
- 命令:UPDATE student SET name=‘caocao’,grade=50 WHERE id=1;
- 更新全部数据
- 语法:UPDATE 表名 SET 字段名=值
- 命令:UPDATE student SET grade=80;
- 更新部分数据
- 查
- 查询所有字段
- 语法:SELECT 字段名1,字段名2,… FROM 表名 (该语法也可以查询部分字段)
- 语法:SELECT * FROM 表名;
- 按条件查询
- 语法:SELECT 字段名1,字段名2,… FROM 表名 WHERE 条件表达式
- 命令:SELECT id,name FROM student2 WHERE id=4;
- 带IN关键字的查询
- 语法:SELECT * | 字段名1,字段名2,… FROM 表名 WHERE 字段名 [ NOT ] IN (元素1,元素2,…)
- 命令:SELECT * FROM student2 WHERE id IN (1,2,3);
- 带 BETWEEN AND 关键字的查询
- 语法:SELECT * | { 字段名1,字段名2,… } FROM 表名 WHERE 字段名 [ NOT ] BETWEEN 值1 AND 值2;
- 命令:SELECT id,name FROM students WHERE id BETWEEN 2 AND 5;
- 空值查询
- 语法:SELECT * | 字段名1,字段名2,… FROM 表名 WHERE 字段名 IS [ NOT ] NULL
- 命令:SELECT * FROM student2 WHERE gender IS NULL;
- 带 DISTINCT 关键字的查询
- 语法:SELECT DISTINCT 字段名 FROM 表名;
- 命令:SELECT DISTINCT gender FROM student2;
- 带 LIKE 关键字的查询
- 语法:SELECT * | 字段名1,字段名2,… FROM 表名 WHERE 字段名 [ NOT ] LIKE ‘匹配字符串’;
- 注意:%表示匹配任意长度的字符串,_表示匹配单个字符串
- 命令:SELECT id,name FROM student2 WHERE name LIKE "S%";
- 命令:SELECT id,name FROM student2 WHERE name LIKE 'w%g';
- 命令:SELECT id,name FROM student2 WHERE name NOT LIKE '%y%';
- 命令:SELECT * FROM student2 WHERE name LIKE 'wu_ong';
- 带 AND 关键字的多条件查询
- 语法:SELECT * | 字段名1,字段名2,… FROM 表名 WHERE 条件表达式1 AND 条件表达式2 [ … AND 条件表达式 n ];
- 命令:SELECT id,name FROM student2 WHERE id<5 AND gender='女';
- 带 OR 关键字的多条件查询
- 语法:SELECT * | 字段名1,字段名2,… FROM 表名 WHERE 条件表达式1 OR 条件表达式2 [ … OR 条件表达式 n ];
- 命令:SELECT id,name ,gender FROM student2 WHERE id<3 OR gender='女';
- AND和OR一起使用时,AND的优先级高于OR
- 聚合函数
- COUNT()函数:统计记录的条数
- 语法:SELECT COUNT(*) FROM 表名举例:
- 命令:SELECT COUNT(*) FROM student2;
- SUM()函数:求出表中某个字段所有值的总和
- 语法:SELECT SUM(字段名) FROM 表名;
- 命令:SELECT SUM(grade) FROM student2;
- AVG()函数:求出表中某个字段所有值的平均值
- 语法:SELECT AVG(字段名) FROM 表名;
- 命令:SELECT AVG(grade) FROM student2;
- MAX()函数:求出表中某个字段所有值的最大值
- 语法:SELECT MAX(字段名) FROM 表名;
- 命令:SELECT MAX(grade) FROM student2;
- MIN()函数:求出表中某个字段所有值的最小值
- 语法:SELECT MIN(字段名) FROM 表名;
- 命令:SELECT MIN(grade) FROM student2;
- COUNT()函数:统计记录的条数
- 对查询结果进行排序
- 语法:SELECT 字段名1,字段名2,… FROM 表名 ORDER BY 字段名1 [ ASC | DESC ],字段名2 [ ASC | DESC ]
- (升序)命令:SELECT * FROM student2 ORDER BY grade;
- (降序)命令:命令:SELECT * FROM student2 ORDER BY grade DESC;
- 分组查询
- 语法:SELECT 字段名1,字段名2,… FROM 表名 GROUP BY 字段名1,字段名2,… [ HAVING 条件表达式 ];
- 单独使用 GROUP BY 进行分组
- 命令:SELECT * FROM student2 GROUP BY gender;
- GROUP BY 和聚合函数一起使用
- 命令:SELECT COUNT(*) ,gender FROM student2 GROUP BY gender;
- GROUP BY 和 HAVING 关键字一起使用
- 命令:SELECT sum(grade),gender FROM student2 GROUP BY gender HAVING SUM(grade) < 300;
- 使用 LIMIT 限制查询结果的数量
- 语法:SELECT 字段名2,字段名2,… FROM 表名 LIMIT [ OFFSET ,] 记录数
- (从0开始的4条)命令:SELECT * FROM student LIMIT 4;
- (从第五条开始的4条)命令:SELECT * FROM student2 ORDER BY grade DESC LIMIT 4,4;
- 为表和字段取别名
- 语法:SELECT * FROM 表名 [ AS ] 别名;
- 命令:SELECT * FROM student2 AS s WHERE s.gender='女';
- 为字段取别名
- 语法:SELECT 字段名 [ AS ] 别名 [ ,字段名 [AS] 别名,…] FROM 表名 ;
- 命令:SELECT name AS stu_name,gender AS stu_gender FROM student2;
- 查询所有字段
浙公网安备 33010602011771号