zoukankan      html  css  js  c++  java
  • fastjson框架如何处理boolean?CURRENT_TIMESTAMP使用报错?什么是 ONLINE DDL 及 pt-online-schema-change ? getBytes引起的乱码问题?

    一、使用fastjson框架进行序列化时,若莫个参数为Boolean类型,而json里的值是其它类型时,框架如何处理?

    1、true, false,正常赋值
    2、int类型,若为1,则为true,否则为false
    3、number类型,若强转int为1,则为true,否则为false
    4、string类型,若为空串、"null"、"NULL"则为null;若为"true","1"则为true;若为"false","0"则为false
    4、其它情况抛错can not cast to boolean

    二、关于CURRENT_TIMESTAMP的问题:
    执行以下SQL报错:

    CREATE TABLE `test` (
    `id` bigint(19) NOT NULL AUTO_INCREMENT,
    `create_time` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
    `update_time` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP
    ) ENGINE=INNODB;

    错误:there can be only one TIMESTAMP column with CURRENT_TIMESTAMP in DEFAULT or ON UPDATE clause
    原因:MYSQL 5.6以下的版本只支持一个字段将当前时间戳为默认值
    四种处理方法:
    1、当更新数据时,用触发器去设置 update_time 为当前时间
    2、当插入数据时,用触发器去设置 create_time 为当前时间
    3、create_time 设为 CURRENT_TIMESTAMP,update_time设为 '0000-00-00 00:00:00',更新、插入时去重新设置更新时间
    4、更新MYSQL版本到5.6

    三、什么是DDL,什么是ONLINE DDL, 什么是pt-online-schema-change?
    DDL:数据定义语言DDL,用来创建数据库中的各种对象-----表、视图、索引、同义词、聚簇
    DML: insert, update, delete
    DQL: select
    DCL: 授予或回收访问数据库的某种特权,并控制数据库操纵事务发生的时间及效果,对数据库实行监视

    MYSQL 5.1的DDL(添加索引):
    建新表(包括新加的索引),锁旧表,拷数据到新表,改表名,删旧表

    MYSQL 5.5,引入FIC(Fast Index Creation):
    支持在新增删除二级索引时,不去新建表,但仍需锁表

    MYSQL 5.6引入ONLINE DDL:
    支持在修改表结构的同时,依然允许DML操作,不是所有DDL操作都支持,具体需参考MYSQL官方文档:https://dev.mysql.com/doc/refman/5.6/en/innodb-online-ddl-operations.html

    ONLINE DDL的一些限制:
    1、无论是涉及到copy table还是添加索引,都需要保证有足够的磁盘大小
    2、主从结构,主库在DDL时,会同时执行DML操作,但是从库由于是单个SQL THREAD按顺序应用log,所以得等ALTER语句执行完,才可以执行下一条,这时会有主从延迟。
    3、在进行 DDL 操作时会保存操作时间内产生的日志,这与 facebook OSC 的临时表,但是其保存在内存中,而该内存的大小由参数 innodb_online_alter_log_max_size 定义,默认大小为 128M,若请求比较频繁,需要进行调整。
    4、ONLINE DDL执行期间,仍会有短时间的排它锁,如准备阶段,提交阶段。

    pt-online-schema-change:
    第三方工具,支持ONLINE DDL

    pt-online-schema-change 工作过程:
    1、建新表
    2、新表进行DDL操作
    3、原表创建三种触发器对应insert,update,delete
    3、从原表拷贝数据到新表,期间的DML操作,通过触发器更新到新表
    4、锁原表,改表名
    5、删旧表

    pt-online-schema-change的一些限制:
    1、原表不允许有触发器
    2、原表必须有主键

    参考博客:
    https://cloud.tencent.com/developer/article/1005177
    http://seanlook.com/2016/05/24/mysql-online-ddl-concept/
    http://keithlan.github.io/2018/11/23/mysql_online_ddl_inside/

    四、关于getBytes方法
    背景:

    使用第三方SDK,出现中文乱码,依赖的SDK,有以下代码:

    headers.put(key, Base64Utils.encodeAsString(value.getBytes()));

    出错原因:
    vlaue.getBytes方法,在没有设置字符集时,会默认以JVM默认的字符集(默认操作系统的字符集)进行处理。而服务器上,操作系统的字符集默认为US-ASCII,而value实际上是UTF-8的,这时候就出现了乱码情况。

    解决方案:
    配置JVM参数,设置JVM默认的字符集为UTF-8:-Dfile.encoding=UTF-8

    分析源码:

    public byte[] getBytes() {
        return StringCoding.encode(value, 0, value.length);
    }
    static byte[] encode(char[] ca, int off, int len) {
        String csn = Charset.defaultCharset().name();
        try {
            // use charset name encode() variant which provides caching.
            return encode(csn, ca, off, len);
        } catch (UnsupportedEncodingException x) {
            warnUnsupportedCharset(csn);
        }
        try {
            return encode("ISO-8859-1", ca, off, len);
        } catch (UnsupportedEncodingException x) {
            // If this code is hit during VM initialization, MessageUtils is
            // the only way we will be able to get any kind of error message.
            MessageUtils.err("ISO-8859-1 charset not available: " + x.toString());
            // If we can not find ISO-8859-1 (a required encoding) then things
            // are seriously wrong with the installation.
            System.exit(1);
            return null;
        }
    }

    可以发现在使用getBytes方法时,默认取使用Charset.defaultCharset()方法来获得字符集
    然后再看defaultCharset()方法的源码

    private static volatile Charset defaultCharset;
    public static Charset defaultCharset() {
        if (defaultCharset == null) {
            synchronized (Charset.class) {
                String csn = AccessController.doPrivileged(new GetPropertyAction("file.encoding"));
                Charset cs = lookup(csn);
                if (cs != null)
                    defaultCharset = cs;
                else
                    defaultCharset = forName("UTF-8");
            }
        }
        return defaultCharset;
    }

    defaultCharset其实是个单例,JVM启动后,只会取加载一次file.encoding。
    而file.encoding在没有配置的情况,取的是操作系统的字符集。
    若想改变默认字符集,则可以设置JVM参数:-Dfile.encoding=UTF-8

  • 相关阅读:
    使用js打开和关闭窗体的几种方法
    使用代码格式化word文档
    批量删除.svn文件的方法
    创业公司老板管理常识
    Google Chrome Source Code 浏览器源码(下载)
    uboot_smdkv210 分析七:Makefile详解
    uboot_smdkv210 分析四:启动代码汇编部分总结
    uboot_smdkv210 分析八:MMU地址映射
    uboot_smdkv210 分析六:内存分配
    uboot_smdkv210 分析五:硬件启动过程
  • 原文地址:https://www.cnblogs.com/dj3839/p/10864272.html
Copyright © 2011-2022 走看看