SQL 使用小记
0、SQL基础Note
wehre:行过滤
group by:分组
having:分组过滤
exists:相关子查询
where和having:针对行过滤 与 针对分组结果过滤的区别
where子查询和exists子查询:where包含子查询时先查得where后的子查询的结果再根据结果进行where前的主查询;exists先执行exists前的主查询得到结果再对每个结果进行子查询,可见后者在数据量大时会很耗时,慎用。
视图:视图通常用于查询而很少用于更新,并非所有的视图都可以进行更新操作,如视图中存在分组(group by)、联结、子查询、并(unoin)、聚合函数(sum/count等)、计算字段、DISTINCT等都不能对视图进行更新操作。
索引:单列索引、复合索引、唯一索引、主键索引 聚簇索引 等。
索引的设计:
where子句中的列可能最适合做为索引
不要尝试为性别或者有无这类字段等建立索引(因为类似性别的列,一般只含有“0”和“1”,无论搜索结果如何都会大约得出一半的数据)
如果创建复合索引,要遵守最左前缀法则。即查询从索引的最左前列开始,并且不跳过索引中的列
不要过度使用索引。每一次的更新,删除,插入都会维护该表的索引,更多的索引意味着占用更多的空间
使用InnoDB存储引擎时,记录(行)默认会按照一定的顺序存储,如果已定义主键,则按照主键顺序存储,由于普通索引都会保存主键的键值,因此主键应尽可能的选择较短的数据类型,以便节省存储空间
不要尝试在索引列上使用函数。
聚簇索引(clustered index)和非聚簇索引(nonclustered index):
区别:聚簇索引中index key和data一起存储在叶节点,因此索引项顺序和数据顺序一样;非聚簇索引中数据不在叶节点而是单独存储,叶节点存储index key和指向数据的指针,故两者顺序不一样。可见,聚簇索引和非聚簇索引分别相当于数据的一级索引和二级索引。
一张表最多只能有一个聚簇索引,因数据顺序只会有一种。
例子:按拼音查字典和按部首查字典分别是聚簇索引和非聚簇索引,前者拼音列表的顺序与字的组织顺序一样,后者部首的顺序与字的顺序不一样。
使用场景:由于聚簇索引索引项与数据的顺序一致,因此索引项改时要相应地调整数据位置,因此聚簇索引适合的场景有 更新少、范围查询多、数据有序(如自增id)、不同值不是很多等。如果数据无序,则插入新数据时索引项可能插入到中间从而导致需要移动已存储的数据保持一致顺序。
MySQL InnoDB存储引擎默认对主键用聚簇索引。
字符串类型字段不适合用聚簇索引,因为字符串值随机,插入后通常需要调整已由数据的位置。
使用场景的区别:
MySQL中若使用了聚簇索引,则普通列的索引项的value为primary key;若未使用聚簇索引,则上述value为指向数据的地址,因此存在聚簇索引时对于普通列查询比不存在聚簇索引时需要更多IO。示例图如下:
(1) 、(2)
更多可参阅:https://www.cnblogs.com/z-sm/p/6005901.html
为什么索引字段要尽可能小(如用int比字符串好)?原因:
数据量固定时要使树高尽可能小 -> 每个节点中的索引项应尽可能多 ;而数据库中索引树(如B+树)节点占用空间大小(是OS页大小)是固定的,此时要使得索引项尽可能多,索引项的大小应该尽可能小。
另外,小的索引字段在磁盘、内存、CPU中占用空间更小,更容易处理
子查询与join查询:一般来说前者效率通常比后者低。
假设 用户订单表user_order有10w条数据,商品表goods有1000条数据,其间通过商品id关联,且g.type=1的goods有100条数据。前者子查询后需要100个子查询数据每个用户10w数据集进行查询、后者则不需要。
select uo.* from user_order uo where uo.gid in ( select g.id from goods g where g.type=1 ); select uo.* from user_order uo inner join goods g on uo.gid=g.id and g.type=1;
逗号分隔多表的多表查询其实就是inner join查询:from a, b where a.id=b.aid 与 from a inner join b on a.id=b.aid 等价
count(1)、count(*):不会忽略值为null的字段
count(列名):会忽略值为null的字段
20190825
联合主键(Composite Primary Key)的使用场景有两个:
- 从属关系的子表。如一个Experiment有多个ExperimentStep,则ExperimentStep中可以用experimentId、stepNum作为联合主键;
- 多对多关系的关联表:如Student、Course间的关系是多对多的,则其关联表Student_Course可以用studentId、courseId作为联合主键。
实际经验总结:如果业务中要求有软删除,则上述两种场景都不能设置联合主键不然可能会报主键冲突。相反,应该都额外加个id字段作为主键,并去掉联合主键。
修改表的字符集:
alter table course_export convert to character set utf8mb4 collate utf8mb4_unicode_ci;
1、 针对返回结果的case语句
示例
select
id,
name,
case user_role
when 0 then
"管理员"
when 1 then
"未注册用户"
when 2 then
"注册用户"
else
concat("未知值:", user_role)
end
“角色”
from
user
2、动态添加where条件
SELECT id, name, school_number AS schoolNumber, gender, grade FROM student where (?4 is NULL or name like %?4% or school_number like %?4%) and (?5 is NULL or gender= ?5) and (?6 is NULL or grade like %?6%)
该句应用背景为支持用户搜索返回模糊匹配结果,特点在于用户可以动态选择搜索条件的个数,?4、?5、?6 三个参数用户传不传均可。即不用因为用户传送参数个数的不同进行写多条SQL语句或在业务层面进行if判断,而只用一条SQL。
也可以使用if语句,示例:
update course c set c.is_enable= if (c.license_expire_time > now() , true, false), c.disable_time= if (c.is_enable =true, null, now());
3、SQL事件
可以让事件只发生一次或多次或周期性发生。
详见:https://www.yiibai.com/mysql/working-mysql-scheduled-event.html
示例:
-- '以下为course表中is_enable, disable_time自动更新的事件';
SET GLOBAL event_scheduler = ON;
drop event if exists `autoDisableCourse`;
create event `autoDisableCourse`
on schedule every 1 minute
DO
update course c set c.is_enable= if (c.license_expire_time > now() , true, false), c.disable_time= if (c.is_enable =true, null, now());
4、SQL触发器
示例:
-- '以下为course表中exp_num字段自动更新有关的两个触发器'; drop trigger if exists `updateExpNumInCourseTableAfterInsertExp` ;
DELIMITER ;;
CREATE trigger `updateExpNumInCourseTableAfterInsertExp`
after insert
on experiment for each row
begin
-- '插入一个实验时更新课程表中的实验数字段';
update course c set c.exp_num =(select count(e.id) from experiment e where e.course_id=NEW.course_id) where c.id = NEW.course_id;
end ;;
DELIMITER ; drop trigger if exists `updateExpNumInCourseTableAfterDeleteExp` ;
DELIMITER ;;
CREATE trigger `updateExpNumInCourseTableAfterDeleteExp`
after delete
on experiment for each row
begin
-- '删除一个实验时更新课程表中的实验数字段';
update course c set c.exp_num =(select count(e.id) from experiment e where e.course_id=OLD.course_id) where c.id = OLD.course_id;
end ;;
DELIMITER ;
5、关联表组织和命名
一对一、一对多关系通过外键来关联表,外键存储在主动关联的表即reference table(而非被管理表即referenced table)中;命名采用user、user_role
多对多关系通过主键来关联表,将reference table和referenced table的主键单独存在第三张表中来维护关联关系;命名采用user、region、user_region
可以看到,两者都会有下划线,此时不好快速区分到底 带下划线的表是 一张详细表(如user_role)还是一张 用来表示两张表关联关系的表(如user_region)。解决方法:一种是前者去掉 "user_" 前缀;另一种是后者统一加上 可区分的前缀如 "re_user_region" 。
7、字符串当做数字比较
如对于chapter="2"、"12",在sql中order by chapter asc得到的结果是字典序升序排序结果 "12"、"2"。若想使之与被当成数字时的升序排序结果一样,可以用语句order by chapter+0,得到的是"12"、"2"。
在native sql和JPQL中都可用此法。
可参阅:https://stackoverflow.com/questions/16242769/mysql-order-by-0-then-largest
8、查询时返回字段值的初始化
通过sql的 ifnull 函数,示例: select ifnull(t.courseNum, 0) as courseNun from course;
更好的方法是使用 COALESCE 函数,COALESCE(expression_1, expression_2, ...,expression_n)依次参考各参数表达式,遇到非null值即停止并返回该值。如果所有的表达式都是空值,最终将返回一个空值。
SQL 使用小记的更多相关文章
- WINDOWS Server2008上部署Oracle10g及oracle SQL语法小记
首先安装10G客户端 情况一:一般都会安装到一般报错.因为10G是32BIT客户端.而操作系统是64位的.但是不会影响配置监听程序.自主开发的应用程序依然可以运行. 情况二:报错但是配置完监听程序始终 ...
- sql server 小记——分区表(上)
我们知道很多事情都存在一个分治的思想,同样的道理我们也可以用到数据表上,当一个表很大很大的时候,我们就会想到将表拆 分成很多小表,查询的时候就到各个小表去查,最后进行汇总返回给调用方来加速我们的查询速 ...
- sql server 小记——分区表
我们知道很多事情都存在一个分治的思想,同样的道理我们也可以用到数据表上,当一个表很大很大的时候,我们就会想到将表拆 分成很多小表,查询的时候就到各个小表去查,最后进行汇总返回给调用方来加速我们的查询速 ...
- MS SQL 维护小记
--查看当前连接的会话信息(进程号1--50是SQL Server系统内部用的) SELECT * FROM sys.dm_exec_sessions WHERE session_id >=51 ...
- Impala SQL 使用小记
1. impala端创建的表,DROP. hive会自动同步到. 但是通过hive DROP时,数据还会在,只是表的元数据没有了. 所以完全DROP表,需要impala端的DROP 2. impal ...
- SQL函数小记
写一篇笔记,记录一下常见的sql函数,以备之后的查找需要. 算数函数 abs(num):绝对值函数 mod(被除数,除数):求余函数 round(num,保留小数的位数):四舍五入函数 字符串函数 c ...
- sql知识小记
1.在sql语句中,单引号嵌套时,使用单引号做转义
- 简单SQL注入试探、二
DVWA——简单SQL注入小记 今天我们来记录简单的盲注过程 简单的SQL injection(blind) Level:low 登陆后选择SQL Injection(Blind) 能看到这样的界面 ...
- 简单SQL注入试探、一
DVWA——简单SQL注入小记 前不久刚开始接触SQL注入,今天来记录一些最近的一些收获和一些SQL注入方面的知识. 主要是基于DVWA这个开源的平台来进行练习. 废话不多说开始解题. 从简单的SQL ...
随机推荐
- Retrofit 2.1 入门
Retrofit 2.1入门 , map); try { Response<String>body=call.execute(); System.out. ...
- Django-Model 使用
添加 更改 删除 查找 /1 使用get 方式查找,只有一条数据,并如果数据不存在的时候会报错,建议不用 User.objects.get(uname=xxx) User. 模型 get(uname= ...
- NHibernate中session.update()及session.merge()的区别
今天的工作中遇到一个奇怪的问题,如下: "a different object with the same identifier value was already associated w ...
- Activity的四种launchMode
来源:http://blog.csdn.net/liuhe688/article/details/6754323/ 我们今天要讲的是Activity的四种launchMode. launchMode在 ...
- 绑定: x:Bind 绑定, x:Bind 绑定之 x:Phase, 使用绑定过程中的一些技巧
背水一战 Windows 10 之 绑定 x:Bind 绑定 x:Bind 绑定之 x:Phase 使用绑定过程中的一些技巧 示例1.演示 x:Bind 绑定的相关知识点Bind/BindDemo.x ...
- 中间值为什么为l+(r-l)/2,而不是(l+r)/2
二分法的算法中,我们看到一些代码里取中间值: MID=l+(r-l)/2; 为什么是这个呢?不就是(l+r)/2吗?为什么要多此一举呢? 其实还是有不一样的,看看他们的区别吧: l,r是指针的时候只能 ...
- linux删除文件后没有释放空间
转载 http://blog.csdn.net/wyzxg/article/details/4971843 今天发现一台服务器的home空间满了,于是要清空无用的文件,当我删除文件后,发现可用空间没有 ...
- Leetcode 300 Longest Increasing Subsequence
Given an unsorted array of integers, find the length of longest increasing subsequence. For example, ...
- 【BZOJ-2503】相框 并查集 + 分类讨论
2503: 相框 Time Limit: 3 Sec Memory Limit: 128 MBSubmit: 71 Solved: 31[Submit][Status][Discuss] Desc ...
- SELINUX、Security Access Control Strategy && Method And Technology Research - 安全访问控制策略及其方法技术研究
catalog . 引言 . 访问控制策略 . 访问控制方法.实现技术 . SELINUX 0. 引言 访问控制是网络安全防范和客户端安全防御的主要策略,它的主要任务是保证资源不被非法使用.保证网络/ ...