Miscellaneous work

 

record bits and pieces

【MYSQL】

  • connection method . The connection to the mysql server can be through tcp/ip or through socket (local only). When the mysql server ip is specified in the connection command, the connection method is tcp/ip. When the connection command does not specify the connection ip or when the ip is localhost, the connection mode is socket. If socket connection is used, mysql searches for the mysql.sock file from the /tmp directory by default. If it is not found and is not specified in the global option file, it will report "Can't connect to local MYSQL server through socket '/tmp/ mysql.sock'" error. In this case, you can try to restart the mysql server. After restarting, enter the /tmp directory to check whether mysql.sock is generated. If not, use the command to check whether the mysql.sock file exists. For example: find / -name mysql.sock, or whereis mysql.sock. After querying the location, you can modify the /etc/my.cnf file by:
    [mysqld]
    # example location
    socket=/opt/mysql/tmp/mysql.sock
    [client]
    socket=/opt/mysql/tmp/mysql.sock
     Specify the location in the file and restart mysql. Note that both client and server need to specify the same location at the same time!
  • mysql 5.7 When creating a union primary key, each primary key cannot be null! i.e. NOT NULL.
  • Trigger trigger . Now suppose there are two tables A and B. After performing the INSERT operation in table A, update the VERSION field of table B with + 1:
    -- -----------------
    -- trigger
    -- -----------------
    DROP TRIGGER IF EXISTS `test_trigger`;
    DELIMITER ;;
    CREATE TRIGGER `test_trigger` AFTER INSERT ON `A`
    FOR EACH ROW
    BEGIN
        UPDATE `B` SET VERSION = VERSION + 1 WHERE ID = NEW.B_ID;
    END
    ;;
    DELIMITER ;
     Among them, DELIMITER is the delimiter in mysql, and the default delimiter is semicolon ";". When the input statement is more than one line and there is a semicolon between the lines, the delimiter needs to be redefined for this paragraph of statement. DELIMITER ;; Indicates that the delimiter from this line is ;;, when the statement needs to be changed back to the original single semicolon, then specify DELIMITER ;. NEW in NEW.B_ID represents the data inserted in table A, which is a specific syntax, and corresponds to OLD .
  • View VIEW
       What is a view? A view is a virtual table that stores the result of executing a pre-written query statement. For some complex queries, when we need to execute a complex query again, we don’t need to rewrite the lengthy query statement. You can query in the virtual table.
-- AS is followed by the statement that needs to be queried
CREATE VIEW `test_view` AS
(SELECT A.xx, B.yy FROM `A` LEFT JOIN `B` ON A.b_id = B.id)
2. Modify the view
CREATE OR REPLACE VIEW `test_view` AS
(SELECT ...)
 When using a view, it can be used directly as a normal table.
  • CREATE PARTITION PARTITION 

        通过 show plugins; 指令可以查看当前 mysql 数据库所拥有的插件,如果存在名为 partition 的插件,说明该数据库支持创建表分区。另: show engines; 指令可以查看所有支持的存储引擎。

 

  • 索引 INDEX

1. 索引的分类

 

 

 

【问题定位】

  •  遇到一个“每天刷卡记录都会丢失一小部分”的问题,由于有主动从门禁设备中获取已保存的数据的接口,因此每天“丢失”的那部分,可以通过 web 页面操作补上,但终归是个问题。在第一次排查问题时,发现后台处理(批量处理)刷卡记录的速度明显跟不上记录上报的速度并且发现“补数据”的操作发生时,后台尚未处理完刷卡记录,于是认为数据并未丢失而是尚未处理完成,然后通过添加索引优化了后台处理的速度。但是,之后的一两天,发现这个问题依然是存在的。于是,再次分析日志,但是似乎并没有和刷卡记录入库相关的异常发生(存在一个与此问题无关的异常,且数量较多)。然后我想,这个业务是一条线程单独处理的,会不会是分配任务队列的 Size 不够,可是也不对,上报的刷卡记录数量总数与队列 Size 相差 半个到一个数量级,不可能满,而且就算队列满了也会抛出相应异常的。于是陷入僵局...最后在查询异常日志时,用一个在 catch 块中打印的字符串搜到了这个异常,巧合的是,这个异常的原因竟然与那个狂打的,无关的异常一摸一样,都是由 mybatis 产生的“期望得到一个结果,但是找到了多个”异常,这就是在一开始按异常查找没发现问题的原因,然后就转为了“为什么会得到两个结果”的问题......其实一开始如果提出问题时可以更具体到“每天都是缺少几十条数据”,亦或者是“谁的数据每天都会缺失”,那么会比较肯定是批量执行时异常(查异常时,差点就以为批量执行没发生异常)。而且每天批量的数据操作,一旦中间数据出错,会出现比较规律性的一组数据失败,这给我的印象是比较深刻的。

 

【Controller 的处理】

  • BaseController。在 controller 中,许多步骤是重复的,比如:分页对象封装,Session 的获取以及返回形式的封装(如:返回json,返回文件上传结果等);
  • 对象转换。接收客户端数据的通常为 VO(Value Object)对象,它是一个值对象,也可以说是业务对象,这个对象需要具备一个方法将 VO convert to(转换为) PO (Persistent Object)对象。PO 对象的字段通常对应的是数据表的字段,因此 VO 对象字段与 PO 对象字段可能不同(可以相同),这一点在完全 ORM 框架中特别明显,在 mybatis 中不太明显;在 service 接口数据返回后,需要将 PO 对象转换为 VO 对象,因为有时候数据库存储的并不是具体的中文,而是类似“0/1”,“YES/NO”,或者存的是个枚举的值,这些数据在返回 客户端之前需要转换为具体的内容,一些不需要的数据也可以直接丢弃。
  • 返回对象。对于返回给客户端的数据,除了具体后台处理后得到的(通常是个对象)外,最好有个请求结果的提示,如 success 或 error(failed);还可以定义错误码等。那么可以,将这些数据再封装为一个返回对象。这样代码的整体性会比较好。

【关于分页】

  • 接收参数。对于接收分页参数的 VO 对象,可以抽取出一个父类,带有 pageNum,pageSize 字段,如果考虑到可能有排序的需求,那么加上排序字段对象,和排序顺序字段,这样可以通过客户端传递排序参数就能完成不同的排序,而服务端代码无需变动(前提是在 sql 中预先判断排序字段非空则排序)。
  • Page对象。通常分页参数至少有三个:当前页,每页数量,查询条件,在每个接口中传递略有些麻烦,可以封装一个 Page 对象,除上述参数外作为字段外,还需加上结果总数字段。

【log4j】

格式参数表示及含义:

  • %d:日期,通过大括号定义格式,如:%d{yyyy-MM-dd hh:mm:ss.SSS}
  • %p:日志等级,包括 DEBUG,INFO,WARN,ERROR,FATAL,等级依次提高
  • %t:线程名称
  • %m:具体日志信息
  • %c:打印日志的类(在哪个类打印的)
  • %F:日志类的名称
  • %n:换行符
  • %L:日志发生的位置(类名,方法名,行号等)

 

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=326004844&siteId=291194637