014.科普.有生产力的Sql语句

[img]http://www.moilioncircle.com/images/post/release/014.jpg[/img]

[b]# 014.科普.有生产力的Sql语句[/b]

不等不靠,有囧有料。终日乾乾,或跃在渊。

如果,我们做足了一些细节,敲出不够烂的代码,
那么,不少企业就会倒闭,信息化建设就会倒退。

如果,我们做不足一些细节,依赖于流水线。
那么,高效生产的同时,我们会退化为码工。

@史荣久 / 2015-03-27 / CC-BY-SA-3.0

[b]## 观看视频[/b]

* [优酷视频(被转720P)](http://v.youku.com/v_show/id_XOTIwODUyNDA4.html)
* [腾讯视频(被转720P)](http://v.qq.com/page/g/u/k/g0150g2ftuk.html)
* [百度网盘(原始1080P)](http://pan.baidu.com/share/link?shareid=3935315343&uk=1380913564&fid=395714801385233)

## 内容摘要

* 安迪-比尔定律(Andy and Bill’s Law)
* 依赖于框架流水线,我们会从手艺人退化为流水线上的码工
* 解释和部分解决Mysql的order-by-limit巨慢
* 分页问题,引申出的sublist,substring
* 一条语句,显示学生所选的课程:GROUP_CONCAT
* 各GROUP的TOP-N问题(分组内,各取前N个)
* 自增主键是个坑,尽量避免(尤其分布式)
* 大量插入(bulk insert),VALUES
* 插入忽略:INSERT IGNORE
* 插入更新:ON DUPLICATE KEY UPDATE(有bug变的特性)
* 替换插入:REPLACE INTO
* 大量删除:DELETE & TRUNCATE(索引,事务,自增)
* 多表联合删除,子查询删除,快速删除
* 关联更新:单个字段,多个字段
* 执行计划:explain,其他优化
* 建立索引:根据sql和explain建立必要的索引
* JDBC: PreparedStatement(DML) vs Statement(DDL)
* JDBC: addBatch, executeBatch 的性能
* JDBC: allowMultiQueries,maxAllowedPacket 安全和速度

[b]## 参考资源[/b]

* [安迪-比尔定律](http://www.baike.com/wiki/安迪-比尔定律)
* [解释:mysql-order-by-limit](http://explainextended.com/2009/10/23/mysql-order-by-limit-performance-late-row-lookups/)
* [解释:late-row-lookups](http://explainextended.com/2011/02/11/late-row-lookups-innodb)
* [subList OOM,注意jdk版本](http://skydream.iteye.com/blog/1672745)
* [Mysql-5.5 性能优化](http://dev.mysql.com/doc/refman/5.5/en/statement-optimization.html)

* [Mysql-5.5 DML:增(insert)](http://dev.mysql.com/doc/refman/5.5/en/insert.html)
* [Mysql-5.5 DML:删(delete)](http://dev.mysql.com/doc/refman/5.5/en/delete.html)
* [Mysql-5.5 DML:改(update)](http://dev.mysql.com/doc/refman/5.5/en/update.html)
* [Mysql-5.5 DML:查(select)](http://dev.mysql.com/doc/refman/5.5/en/select.html)

* [Mysql-5.5 子查询(subqueries)](http://dev.mysql.com/doc/refman/5.5/en/subqueries.html)
* [Mysql-5.5 插入或替换(replace)](http://dev.mysql.com/doc/refman/5.5/en/replace.html)
* [Mysql-5.5 重复时更新(duplicate)](http://dev.mysql.com/doc/refman/5.5/en/insert-on-duplicate.html)
* [Mysql-5.5 聚集:列变行](http://dev.mysql.com/doc/refman/5.5/en/group-by-functions.html)
* [Mysql-5.5 聚集:合计](http://dev.mysql.com/doc/refman/5.5/en/group-by-modifiers.html)

* [Statement vs PreparedStatement](http://stackoverflow.com/questions/3271249)
* [Values vs JDBC批量预处理](http://brian.pontarelli.com/2011/06/21/jdbc-batch-vs-multi-row-inserts)
* [JDBC-URL 能用到的参数](http://dev.mysql.com/doc/connector-j/en/connector-j-reference-configuration-properties.html)

[b]## 欢迎围观[/b]


if (you.accept(MoilionCircle.SPIRIT)) {
if(you.haveADL()){
MoilionCircle we = you.search(MoilionCircle.SLOGAN);
we.welcome(you);
}
if(you.share(this)){
We.thank(you);
We.mayFind7Moilion();
}
}


[b]## 测试SQL[/b]


select version();
-- 5.5.41-0ubuntu0.14.04.1

-- 建库
DROP DATABASE IF EXISTS `moilioincircle_r014`;
CREATE DATABASE `moilioincircle_r014`
DEFAULT CHARACTER SET utf8 COLLATE utf8_bin;
USE moilioincircle_r014;

-- 建表
DROP TABLE IF EXISTS `STUDENT`;
CREATE TABLE `STUDENT` (
`ID` int(11) NOT NULL,
`NAME` varchar(45) NOT NULL,
`GENDER` int(11) NOT NULL DEFAULT '1',
PRIMARY KEY (`ID`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin;

DROP TABLE IF EXISTS `COURSE`;
CREATE TABLE `COURSE` (
`ID` int(11) NOT NULL,
`NAME` varchar(45) COLLATE utf8_bin NOT NULL,
PRIMARY KEY (`ID`),
UNIQUE KEY `NAME_UNIQUE` (`NAME`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin;

DROP TABLE IF EXISTS `STUDENT_COURSE_MAP`;
CREATE TABLE `STUDENT_COURSE_MAP` (
`STUDENT_ID` int(11) NOT NULL,
`COURSE_ID` int(11) NOT NULL,
PRIMARY KEY (`STUDENT_ID`,`COURSE_ID`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin;

DROP TABLE IF EXISTS `EXAM`;
CREATE TABLE `EXAM` (
`STUDENT_ID` int(11) NOT NULL,
`COURSE_ID` int(11) NOT NULL,
`SCORE` int(11) NOT NULL,
PRIMARY KEY (`STUDENT_ID`,`COURSE_ID`),
KEY `IDX_SCORE` (`SCORE`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin;

DROP TABLE IF EXISTS `AUTOINCR`;
CREATE TABLE `AUTOINCR` (
`ID` int(11) NOT NULL AUTO_INCREMENT,
`NAME` varchar(45),
PRIMARY KEY (`ID`)
) AUTO_INCREMENT = 100
ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin;

-- 数据
INSERT INTO STUDENT (ID,NAME,GENDER)
VALUES
(1,'学生1',2),
(2,'学生2',1),
(3,'学生3',NULL),
(4,'学生4',DEFAULT);

INSERT INTO COURSE (ID,NAME)
VALUES
(1,'课程1'),
(2,'课程2'),
(3,'课程3'),
(4,'课程4');

INSERT INTO STUDENT_COURSE_MAP (STUDENT_ID,COURSE_ID)
VALUES
(1,1),
(2,1),(2,2),
(3,1),(3,2),(3,3),
(4,1),(4,2),(4,3),(4,4);

INSERT INTO EXAM (STUDENT_ID,COURSE_ID,SCORE)
VALUES
(1,1,90),(1,2,70),(1,3,85),(1,4,80),
(2,1,70),(2,2,85),(2,3,75),(2,4,80),
(3,1,75),(3,2,85),(3,3,85),(3,4,65),
(4,1,60),(4,2,75),(4,3,80),(4,4,85);

INSERT INTO AUTOINCR (ID,NAME)
VALUES
(1,'自增1'),
(DEFAULT,'自增#1'),
(5,'自增5'),
(DEFAULT,'自增#2');

-- 查 -----------------

-- 学生都选了什么课(把列换成行显示)
-- set group_concat_max_len=10000;
SELECT
S.NAME,
GROUP_CONCAT(C.NAME ORDER BY C.NAME ) AS COURSES
FROM
STUDENT AS S,
COURSE AS C,
STUDENT_COURSE_MAP AS M
WHERE
S.ID = M.STUDENT_ID
AND C.ID = M.COURSE_ID
GROUP BY S.NAME
HAVING COUNT(C.NAME)>1;

-- 把各科考试,前三名取出来。
-- MYSQL 没有 ROW_NUMBER() OVER(PARTITION BY A ORDER BY B DESC)
SELECT
C.NAME AS COURSE,
S.NAME AS STUDENT,
E.SCORE
FROM
EXAM AS E ,
STUDENT AS S,
COURSE AS C
WHERE
(SELECT COUNT(*) FROM EXAM AS B
WHERE B.COURSE_ID = E.COURSE_ID
AND B.SCORE >= E.SCORE
) <= 3
AND E.STUDENT_ID = S.ID
AND E.COURSE_ID = C.ID
ORDER BY COURSE ASC, SCORE DESC;

SELECT * FROM STUDENT
WHERE (ID,NAME) IN ((1,'学生1'),(2,'学生2'));

-- ------- 增 ----------
SELECT * FROM COURSE;

INSERT IGNORE INTO COURSE (ID,NAME)
VALUES
(1,'课程1'),
(11,'课程1'),
(5,'课程5'),
(6,'课程6');

REPLACE INTO COURSE (ID,NAME)
VALUES
(5,'课程55'),
(66,'课程6'),
(7,'课程7');

INSERT INTO COURSE (ID,NAME)
VALUES (5,'课程5'),(6,'课程6'),(8,'课程6')
ON DUPLICATE KEY UPDATE
NAME=VALUES(NAME),ID=VALUES(ID);

INSERT INTO COURSE (ID,NAME)
VALUES (5,'课程5'),(6,'课程6'),(7,'课程7')
ON DUPLICATE KEY UPDATE
NAME=VALUES(NAME),
ID=(CASE WHEN NAME = VALUES(NAME)
THEN VALUES(ID)
ELSE ID
END);

-- 删
CREATE TABLE AUTOINCR_1 LIKE AUTOINCR; -- 表结构相同
INSERT INTO AUTOINCR_1 SELECT * FROM AUTOINCR;
DESCRIBE AUTOINCR_1;

CREATE TABLE AUTOINCR_2 SELECT * FROM AUTOINCR WHERE ID <10; -- 不相同
DESCRIBE AUTOINCR_2;

SELECT * FROM AUTOINCR_1;
SELECT * FROM AUTOINCR_2;

DELETE FROM AUTOINCR_1;
INSERT INTO AUTOINCR_1 (NAME) VALUES ('课程1');
TRUNCATE TABLE AUTOINCR_1;

DELETE T1,T2
FROM AUTOINCR_1 AS T1,AUTOINCR_2 AS T2
WHERE T1.ID = T2.ID;

DELETE QUICK FROM AUTOINCR_2;
OPTIMIZE TABLE AUTOINCR_2;

-- 改 ------
INSERT INTO AUTOINCR_1 SELECT ID,NULL FROM AUTOINCR;
INSERT INTO AUTOINCR_2 SELECT * FROM AUTOINCR WHERE ID <10;

-- 更新单个字段
UPDATE AUTOINCR_2 AS T2, AUTOINCR_1 AS T1
SET T1.NAME = T2.NAME
WHERE T2.ID = T1.ID;

UPDATE AUTOINCR_1 SET NAME=NULL;
UPDATE AUTOINCR_1 AS T1
SET T1.NAME = (SELECT T2.NAME FROM AUTOINCR_2 AS T2 WHERE T2.ID = T1.ID);

CREATE TABLE STUDENT_1 LIKE STUDENT;
INSERT INTO STUDENT_1 SELECT ID,CONCAT(NAME,'#'),0 FROM STUDENT;

SELECT * FROM STUDENT;
SELECT * FROM STUDENT_1;

-- 更新多个字段
UPDATE STUDENT_1 AS T1
INNER JOIN (SELECT T.ID, T.NAME, T.GENDER FROM STUDENT AS T) AS T2
ON T2.ID = T1.ID
SET T1.NAME = T2.NAME ,T1.GENDER = T2.GENDER;


题图:Intel Corp. President Andy Grove, right, shakes hands with Microsoft Chairman Bill Gates at a meeting in Burlingame, Ca., on Monday Nov. 9, 1992, as they team up to offer a new product of videos on personal computers.。
原文:[url]http://www.moilioncircle.com/release/014.know.productive-crud-mysql.html[/url]
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
提供的源码资源涵盖了安卓应用、小程序、Python应用和Java应用等多个领域,每个领域都包含了丰富的实例和项目。这些源码都是基于各自平台的最新技术和标准编写,确保了在对应环境下能够无缝运行。同时,源码中配备了详细的注释和文档,帮助用户快速理解代码结构和实现逻辑。 适用人群: 这些源码资源特别适合大学生群体。无论你是计算机相关专业的学生,还是对其他领域编程感兴趣的学生,这些资源都能为你提供宝贵的学习和实践机会。通过学习和运行这些源码,你可以掌握各平台开发的基础知识,提升编程能力和项目实战经验。 使用场景及目标: 在学习阶段,你可以利用这些源码资源进行课程实践、课外项目或毕业设计。通过分析和运行源码,你将深入了解各平台开发的技术细节和最佳实践,逐步培养起自己的项目开发和问题解决能力。此外,在求职或创业过程中,具备跨平台开发能力的大学生将更具竞争力。 其他说明: 为了确保源码资源的可运行性和易用性,特别注意了以下几点:首先,每份源码都提供了详细的运行环境和依赖说明,确保用户能够轻松搭建起开发环境;其次,源码中的注释和文档都非常完善,方便用户快速上手和理解代码;最后,我会定期更新这些源码资源,以适应各平台技术的最新发展和市场需求。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值