zoukankan      html  css  js  c++  java
  • 014.科普.有生产力的Sql语句


    题图: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.

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

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

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

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

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

    观看视频

    内容摘要

    • 安迪-比尔定律(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 安全和速度

    参考资源

    欢迎围观

    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();
        }
    }
    

    测试SQL

    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;
    
    
  • 相关阅读:
    【分布式】SpringCloud(2)--SpringCloud分布式架构思想的理解
    【分布式】SpringCloud(1)--基于RestTemplate构建简易微服务调用框架
    【问题管理】-- MyBatis实体类的属性名和数据库列名不一致解决方法汇总
    【开发工具】-- 一文全面解析 Postman 工具
    【数据库】Redis(4)--Redis进阶Redis配置与持久化
    【数据库】Redis(3)--Redis事务、Jedis、SpringBoot整合Redis
    分享的面试问题,java学习教程
    怎么保证缓存和数据库一致性
    详解一条 SQL 的执行过程
    json字符串{"1-3": 29},{"8-": 50},{"8-": 50},返回 1-3天 29,大于8天 100
  • 原文地址:https://www.cnblogs.com/moilioncircle/p/4371445.html
Copyright © 2011-2022 走看看