当前位置:

首页 > 编程开发 > MySQL FT 指的是什么?

MySQL FT 指的是什么?

mysqlft指的是FullText,即全文索引;全文索引是为了解决需要基于相似度的查询,而不是精确数值比较;全文索引在大量的数据面前,能比like快N倍,速度不是一个数量级。MySQL全文索引(FullText)一、简介基本概念全文索引是为了解决需要基于相似度的查询,而不是精确数值比较。虽然使用like+%也可以实现模糊匹配,但是对于大量的文本数据检索,是不可想象的。全文索引在大量的数据面前,能比like快N倍,速度不是一个数量级。版本支持MySQL5.6以前的版本,只有MyISAM存储引擎支持全文索引

本文目录

    mysql ft指的是FullText,即全文索引;全文索引是为了解决需要基于相似度的查询,而不是精确数值比较;全文索引在大量的数据面前,能比like快N倍,速度不是一个数量级。

    MySQL 全文索引 (FullText)

    一、简介

    基本概念

    全文索引是为了解决需要基于相似度的查询,而不是精确数值比较。

    虽然使用 like + % 也可以实现模糊匹配,但是对于大量的文本数据检索,是不可想象的。全文索引在大量的数据面前,能比 like 快 N 倍,速度不是一个数量级。

    版本支持

    1. MySQL 5.6 以前的版本,只有 MyISAM 存储引擎支持全文索引

    2. MySQL 5.6 及以后的版本,MyISAM 和 InnoDB 存储引擎均支持全文索引

    3. MySQL 5.7.6 中,提供了支持中文、日文和韩文(CJK)的内置全文 ngram 解析器,以及用于日文的可安装 MeCab 全文解析器插件

    4. 全文索引只能用于InnoDB或MyISAM表,只能为CHAR、VARCHAR、TEXT列创建

    5. 对于大型数据集,将数据加载到没有全文索引的表中然后创建索引要比将数据加载到具有现有全文索引的表中快得多

    6. RDS MySQL 5.6 虽然也支持中文全文检索,但存在BUG

    限制与缺点

    • 导致磁盘资源的大量占用。全文索引本身就是一个利用磁盘空间换取性能的方法。全文索引大的原因是,按照某种语言来进行分词

    • 全文索引创建速度慢,而且对有全文索引的各种数据修改操作也慢

    • 使用全文索引并不是对应用透明的。如果要想利用全文索引,必须修改查询语句。原有的查询语句是不可能利用全文索引的,需要改成全文索引规定的语法

    • 不区分大小写

    • 分区表不支持全文搜索

    • 由多列组合而成的全文检索的索引必须使用相同的字符集与排序规则

    • 全文索引可能存在精度问题,即全文索引找到的数据,可能和like到的不一致

    • MATCH()函数中的列必须与FULLTEXT索引中定义的列完全一致,除非是在MyISAM表中使用IN BOOLEAN MODE模式的全文搜索(可在没有建立索引的列执行搜索,但速度很慢)

    • 单列分别建立全文索引时,多列模糊查询时不生效

    • 不同表的全文索引不能放在一起查询,可以两个语句中加上OR

    二、操作全文索引

    2.1 配置最小搜索长度

    我们可以通过 SQL 命令查看当前配置的最小搜索长度(分词长度):

    SHOW VARIABLES LIKE 'ft%';
    Variable_nameValue
    ft_boolean_syntax+ -><()~*:""&|
    ft_max_word_len84
    ft_min_word_len1
    ft_query_expansion_limit20
    ft_stopword_file(built-in)

    全文索引的相关参数都无法进行动态修改,必须通过修改 MySQL 的配置文件来完成。修改最小搜索长度的值为 1,首先打开 MySQL 的配置文件 /etc/my.cnf,在 [mysqld] 的下面追加以下内容:

    [mysqld]
    innodb_ft_min_token_size = 1
    # 最短的索引字符串,默认值为4
    ft_min_word_len = 1

    配置完后重启 MySQL 服务器,并修复或重建全文索引方可生效。
    可使用下面的命令修复:

    repair table test quick;

    2.2 创建索引

    • 建表时创建全文索引

    CREATE TABLE fulltext_test (
      id int(11) NOT NULL AUTO_INCREMENT,
    	content TEXT NOT NULL,
    	tag VARCHAR(255),
    	PRIMARY KEY (id),
    	FULLTEXT KEY content_tag_fulltext(content, tag) WITH PARSER ngram
    ) ENGINE = InnoDB DEFAULT CHARSET=utf8mb4;
    • 在已存在的表上创建全文索引

    CREATE FULLTEXT INDEX content_fulltext ON fulltext_test(content) with parser ngram;
    • 通过 SQL 语句 ALTER TABLE 创建全文索引

    ALTER TABLE fulltext_test ADD FULLTEXT INDEX content_fulltext(content) with parser ngram;

    2.3 删除索引

    • 使用 DROP INDEX 删除全文索引

    DROP INDEX content_fulltext ON fulltext_test;
    • 通过 SQL 语句 ALTER TABLE 删除全文索引

    ALTER TABLE fulltext_test DROP INDEX content_fulltext;

    三、检索数据

    3.1 自然语言的全文检索

    默认情况下,或者使用 in natural language mode 修饰符时,match() 函数对文本集合执行自然语言搜索。

    SELECT * FROM 表名 WHERE Match(列名1,列名2) Against (检索内容1 检索内容2);

    检索内容不需要用逗号隔开!

    自然语言搜索引擎将计算每一个文档对象和查询的相关度。这里,相关度是基于匹配的关键词的个数,以及关键词在文档中出现的次数。在整个索引中出现次数越少的词语,匹配时的相关度就越高。相反,非常常见的单词将不会被搜索,如果一个词语的在超过 50% 的记录中都出现了,那么自然语言的搜索将不会搜索这类词语。

    3.2 布尔全文检索

    在布尔搜索中,我们可以在查询中自定义某个被搜索的词语的相关性,当编写一个布尔搜索查询时,可以通过一些前缀修饰符来定制搜索。

    • 空(也就是默认状况),表示可选的,包含该词的顺序较高

    • + 表示必须包含

    • - 表示必须排除

    • “>” 表示出现该单词时增加相关性,查询的结果靠前

    • “<” 表示出现该单词时降低相关性,查询的结果靠后

    • * 表示通配符,只能接在词后面

    • ~ 允许出现该单词,但是出现时相关性为负,表示拥有该字会下降相关性,但不像「-」将之排除,只是排在较后面

    • "" 双引号表示短语,表示要彻底相符,不可拆字效果,类同于 like '%keyword%'

    • () 经过括号来使用字条件:

    +aaa +(>bbb 李秀琴 <练习册 <不是人>是个鬼' in boolean mode);

    四、测试结果

    测试环境:本机4核16G Windows10,MySQL 8.0
    测试数据量:salebilldetail 表 1276万行,salebill 表 269 万行, customer 表 30 万行, goods 表 75 万行。

    争对测试用的SQL语句,增加了以下全文索引:

    CREATE FULLTEXT INDEX billno_fulltext ON salebill(billno) WITH PARSER ngram;
    CREATE FULLTEXT INDEX remarks_fulltext ON salebill(remarks) WITH PARSER ngram;
    CREATE FULLTEXT INDEX remarks_fulltext ON salebilldetail(remarks) WITH PARSER ngram;
    CREATE FULLTEXT INDEX goodsremarks_fulltext ON salebilldetail(goodsremarks) WITH PARSER ngram;
    CREATE FULLTEXT INDEX remarks_goodsremarks_fulltext ON salebilldetail(remarks, goodsremarks) WITH PARSER ngram;
    CREATE FULLTEXT INDEX custname_fulltext ON customer(custname) WITH PARSER ngram;
    CREATE FULLTEXT INDEX goodsname_fulltext ON goods(goodsname) WITH PARSER ngram;
    CREATE FULLTEXT INDEX goodscode_fulltext ON goods(goodscode) WITH PARSER ngram;

    测试结果,总的来说很魔幻。
    为什么魔幻,看下面几个语句:

    test_1
    -- 测试1,原始 like 查询方式,用时 0.765s
    select 1 from salebilldetail d where d.tid=260434 and ((d.remarks like concat('%','葡萄','%')) or (d.goodsremarks like concat('%','葡萄','%')));
    test_2
    -- 测试2,使用全文索引 remarks_fulltext、goodsremarks_fulltext, 用时 0.834s
    select 1 from salebilldetail d where d.tid=260434 and ((match(d.remarks) Against(concat('"','葡萄','"') in boolean mode)) or (match(d.goodsremarks) Against(concat('"','葡萄','"')  in boolean mode)));
    test_3
    -- 测试3,使用全文索引 remarks_goodsremarks_fulltext, 用时 0.242s
    select 1 from salebilldetail d where d.tid=260434 and ((match(d.remarks,d.goodsremarks) Against(concat('"','葡萄','"') in boolean mode)));
    test_4
    -- 测试4,原始 like 查询方式,不过滤 tid ,用时 22.654s
    select t from salebilldetail d where ((d.remarks like concat('%','葡萄','%')) or (d.goodsremarks like concat('%','葡萄','%')));
    test_5
    -- 测试5,使用全文索引 remarks_fulltext、goodsremarks_fulltext,  不过滤 tid ,用时 24.855s
    select 1 from salebilldetail d where ((match(d.remarks) Against(concat('"','葡萄','"') in boolean mode)) or (match(d.goodsremarks) Against(concat('"','葡萄','"')  in boolean mode)));
    test_6
    -- 测试6,使用全文索引 remarks_goodsremarks_fulltext, 不过滤 tid ,用时 0.213s
    select 1 from salebilldetail d where ((match(d.remarks,d.goodsremarks) Against(concat('"','葡萄','"') in boolean mode)));
    test_7
    -- 测试7,使用全文索引 remarks_goodsremarks_fulltext, 用时 0.22s
    select count(1) from salebilldetail d where d.tid=260434 and  ((match(d.remarks,d.goodsremarks) Against(concat('"','葡萄','"') in boolean mode)));
    test_8
    -- 测试8,使用全文索引 remarks_goodsremarks_fulltext, 不过滤 tid ,用时 0.007s
    select count(1) from salebilldetail d where ((match(d.remarks,d.goodsremarks) Against(concat('"','葡萄','"') in boolean mode)));

    从上面的测试语句可以看出,数据量越多,查询越简单,全文索引的效果越好。

    再来看看我们的业务测试SQL:

    test_9
    -- 测试9
    select 
        i.billid
        ,if(0,0,i.qty) as qty  
        ,if(0,0,i.goodstotal) as total          
        ,if(0,0,i.chktotal) as selfchktotal   
        ,if(0,0,i.distotal) as distotal 
        ,if(0,0,i.otherpay) as feetotal  
        ,if(0,0,ifnull(d.costtotal,0)) as costtotal  
        ,if(0,0,ifnull(d.maoli,0)) as maoli         
        ,i.billno
        ,from_unixtime(i.billdate,'%Y-%m-%d') as billdate /*单据日期*/
        ,from_unixtime(i.createdate,'%Y-%m-%d %H:%i:%s') as createdate /*制单日期*/
        ,if(i.sdate=0,'',from_unixtime(i.sdate,'%Y-%m-%d  %H:%i:%s')) as sdate /*过账日期*/
        ,from_unixtime(i.udate,'%Y-%m-%d %H:%i:%s') as udate /*最后修改时间*/
        ,i.custid ,c.custname
        ,i.storeid ,k.storename
        ,i.empid ,e.empname
        ,i.userid ,u.username
        ,i.remarks                               /*单据备注*/
        ,i.effect,i.settle,i.redold,i.rednew     /*单据状态*/
        ,i.printtimes /* 打印次数 */
        ,(case  when i.rednew=1 then 1  when i.redold=1 then 2  when i.settle=1 then 3  when i.effect=1 then 4  else 9 end) as state /*单据状态*/
        ,(case  when i.rednew=1 then '红冲单'  when i.redold=1 then '已红冲'  when i.settle=1 then '已结算'  when i.effect=1 then '已过账'  else '草稿' end) as statetext
        ,'' as susername /* 操作人 */
        ,'' as accname /* 科目 */
    from salebill i
    left join coursecentersale d on d.tid=i.tid and d.billid=i.billid
    left join customer c on c.tid=i.tid and c.custid=i.custid
    left join store k on k.tid=i.tid and k.storeid=i.storeid
    left join employee e on e.tid=i.tid and e.empid=i.empid
    left join user u on u.tid=i.tid and u.userid=i.userid
    where i.tid=260434 and (i.billtype = 5 or i.effect = 1)
        and ('_billdate_f_'!='')
        and ('_billdate_t_'!='')
        and ('_sdate_f_'!='')
        and ('_sdate_t_'!='')
        and ('_udate_f_'!='')
        and ('_udate_t_'!='')
        and ('_cdate_f_'!='')
        and ('_cdate_t_'!='')
        and ('_billid_'!='')      /*单据id*/
        and ('_custid_'!='')      /*客户ID*/
        and ('_storeid_'!='')     /*店仓ID*/
        and ('_empid_'!='')       /*业务员ID*/
        and ('_custstop_'!='')       /*客户是否停用*/
        and (
            (i.billno like concat('%','葡萄','%'))
            or (i.remarks like concat('%','葡萄','%'))
            or exists(select 1 from salebilldetail d where d.tid=260434 and d.billid=i.billid and ((d.remarks like concat('%','葡萄','%')) or (d.goodsremarks like concat('%','葡萄','%'))))
            or exists(select 1 from customer c where c.tid=260434 and c.custid=i.custid and (c.custname like concat('%','葡萄','%')))
            or exists(select 1 from goods g join salebilldetail d on d.tid=g.tid and d.goodsid=g.goodsid where d.tid=260434 and d.billid=i.billid and ((g.goodsname like concat('%','葡萄','%')) or (g.goodscode like concat('%','葡萄','%'))))
        )
        and i.rednew=0 /*单据列表不含红冲单*/ 
        and i.billid not in (select billid from coursecenter_del t where t.tid=260434)
        and ((i.settle=1 and i.effect=1 and i.redold=0 and i.rednew=0)) /*已结算*/
    order by udate desc,billno desc
    limit 0,100;

    执行时间约 1.6 秒,使用的是 like 方式。

    改成使用全文索引方式:

    test_10
    -- 测试10
    select 
        i.billid
        ,if(0,0,i.qty) as qty         
        ,if(0,0,i.goodstotal) as total   
        ,if(0,0,i.chktotal) as selfchktotal  
        ,if(0,0,i.distotal) as distotal 
        ,if(0,0,i.otherpay) as feetotal  
        ,if(0,0,ifnull(d.costtotal,0)) as costtotal 
        ,if(0,0,ifnull(d.maoli,0)) as maoli  
        ,i.billno
        ,from_unixtime(i.billdate,'%Y-%m-%d') as billdate /*单据日期*/
        ,from_unixtime(i.createdate,'%Y-%m-%d %H:%i:%s') as createdate /*制单日期*/
        ,if(i.sdate=0,'',from_unixtime(i.sdate,'%Y-%m-%d  %H:%i:%s')) as sdate /*过账日期*/
        ,from_unixtime(i.udate,'%Y-%m-%d %H:%i:%s') as udate /*最后修改时间*/
        ,i.custid ,c.custname
        ,i.storeid ,k.storename
        ,i.empid ,e.empname
        ,i.userid ,u.username
        ,i.remarks                               /*单据备注*/
        ,i.effect,i.settle,i.redold,i.rednew     /*单据状态*/
        ,i.printtimes /* 打印次数 */
        ,(case  when i.rednew=1 then 1  when i.redold=1 then 2  when i.settle=1 then 3  when i.effect=1 then 4  else 9 end) as state /*单据状态*/
        ,(case  when i.rednew=1 then '红冲单'  when i.redold=1 then '已红冲'  when i.settle=1 then '已结算'  when i.effect=1 then '已过账'  else '草稿' end) as statetext
        ,'' as susername /* 操作人 */
        ,'' as accname /* 科目 */
    from salebill i
    left join coursecentersale d on d.tid=i.tid and d.billid=i.billid
    left join customer c on c.tid=i.tid and c.custid=i.custid
    left join store k on k.tid=i.tid and k.storeid=i.storeid
    left join employee e on e.tid=i.tid and e.empid=i.empid
    left join user u on u.tid=i.tid and u.userid=i.userid
    where i.tid=260434 and (i.billtype = 5 or i.effect = 1)
        and ('_billdate_f_'!='')
        and ('_billdate_t_'!='')
        and ('_sdate_f_'!='')
        and ('_sdate_t_'!='')
        and ('_udate_f_'!='')
        and ('_udate_t_'!='')
        and ('_cdate_f_'!='')
        and ('_cdate_t_'!='')
        and ('_billid_'!='')      /*单据id*/
        and ('_custid_'!='')      /*客户ID*/
        and ('_storeid_'!='')     /*店仓ID*/
        and ('_empid_'!='')       /*业务员ID*/
        and ('_custstop_'!='')       /*客户是否停用*/
        and (
            (match(i.billno) against(concat('"','葡萄','"') in boolean mode))
            or (match(i.remarks) against(concat('"','葡萄','"') in boolean mode))
            or exists(select 1 from salebilldetail d where d.tid=260434 and d.billid=i.billid and ((match(d.remarks) Against(concat('"','葡萄','"') in boolean mode)) or (match(d.goodsremarks) Against(concat('"','葡萄','"')  in boolean mode))))
            or exists(select 1 from customer c where c.tid=260434 and c.custid=i.custid and (match(c.custname) Against(concat('"','葡萄','"') in boolean mode)))
            or exists(select 1 from goods g join salebilldetail d on d.tid=g.tid and d.goodsid=g.goodsid where d.tid=260434 and d.billid=i.billid 
         and ((match(g.goodsname) Against(concat('"','葡萄','"') in boolean mode))
         or (match(g.goodscode) Against(concat('"','葡萄','"') in boolean mode))))
        )
        and i.rednew=0 /*单据列表不含红冲单*/ 
        and i.billid not in (select billid from coursecenter_del t where t.tid=260434)
        and ((i.settle=1 and i.effect=1 and i.redold=0 and i.rednew=0)) /*已结算*/
    order by udate desc,billno desc
    limit 0,100;

    执行时间约 1.6 秒,与使用的是 like 方式差不多。

    最魔幻的地方来了,如果将上面的SQL语句中(salebilldetail表使用全文索引 remarks_fulltext、goodsremarks_fulltext的地方)

    exists(select 1 from salebilldetail d where d.tid=260434 and d.billid=i.billid and ((match(d.remarks) Against(concat('"','葡萄','"') in boolean mode)) or (match(d.goodsremarks) Against(concat('"','葡萄','"')  in boolean mode))))
    test_11

    改成使用全文索引 remarks_goodsremarks_fulltext

    -- 测试11
    exists(select 1 from salebilldetail d where d.tid=260434 and d.billid=i.billid and ((match(d.remarks,d.goodsremarks) Against(concat('"','葡萄','"') in boolean mode))))

    执行时间无限长(跑了半天没成功)?
    经分析,在 where 子句中,一个条件子句中包含一个以上 match 时会出现这样的情况。即:

    -- and 中只有一个全文检索时正常, 用时0.2秒
    select xxx from xxx
    ...
    and (
    	exists(select 1 from salebilldetail d where d.tid=260434 and d.billid=i.billid and ((match(d.remarks,d.goodsremarks) Against(concat('"','葡萄','"') in boolean mode))))
    )
    ...
    
    -- 下面这样就异常了,会慢成百上千倍,用时 160 秒, 如果有更多的 match ,会更夸张的慢下去
    select xxx from xxx
    ...
    and (
    	exists(select 1 from salebilldetail d where d.tid=260434 and d.billid=i.billid and ((match(d.remarks,d.goodsremarks) Against(concat('"','葡萄','"') in boolean mode))))
    	or match(i.billno) against(concat('"','葡萄','"') in boolean mode)
    )
    ...

    测试结果汇总:

    查询用时(秒)备注
    test 10.765原始like查询
    test 20.834全文索引 remarks_fulltext、goodsremarks_fulltext
    test 30.242全文索引 remarks_goodsremarks_fulltext
    ---

    test 422.654原始like查询,不过滤 tid
    test 524.855全文索引 remarks_fulltext、goodsremarks_fulltext,  不过滤 tid
    test 60.213全文索引 remarks_goodsremarks_fulltext, 不过滤 tid
    ---

    test 70.22全文索引 remarks_goodsremarks_fulltext, count
    test 80.007全文索引 remarks_goodsremarks_fulltext, 不过滤 tid, count
    ---

    test 91.6业务测试SQL,原始like查询
    test 101.6业务测试SQL,全文索引 remarks_fulltext、goodsremarks_fulltext
    test 11失败业务测试SQL,全文索引 remarks_goodsremarks_fulltext

    五、MySQL 版本升级

    因线上系统目前是 RDS MySQL 5.6,故简单描述升级相关问题。

    • Group By: 在 MySQL 5.7 之后,默认使用增加了限制,一些在 MySQL 5.6 可执行的Group By语句,在 5.7 之后会报错,可以更改新版本 MySQL 的 sqlModel


      -- 查询 sql_mode
      select @@SESSION.sql_mode;
      -- 设置
      SET GLOBAL sql_mode = 'STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_ENGINE_SUBSTITUTION';
      -- 或 设置 (修改于当前会 话,关闭当前会话后失效)
      SET SESSION sql_mode = 'STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_ENGINE_SUBSTITUTION';
      -- 刷新
      flush PRIVILEGES;
      


      • ONLY_FULL_GROUP_BY: 对于GROUP BY聚合操作,如果在SELECT中的列,没有在GROUP BY中出现,那么这个SQL是不合法的,因为列不在GROUP BY从句中

      • NO_AUTO_VALUE_ON_ZERO: 该值影响自增长列的插入。默认设置下,插入0或NULL代表生成下一个自增长值。如果用户希望插入的值为0,而该列又是自增长的,那么这个选项就有用了。

      • STRICT_TRANS_TABLES:在该模式下,如果一个值不能插入到一个事务中,则中断当前的操作,对非事务表不做限制

      • NO_ZERO_IN_DATE:在严格模式下,不允许日期和月份为零

      • NO_ZERO_DATE:设置该值,mysql数据库不允许插入零日期,插入零日期会抛出错误而不是警告

      • ERROR_FOR_DIVISION_BY_ZERO:在insert或update过程中,如果数据被零除,则产生错误而非警告。如果未给出该模式,那么数据被零除时MySql返回NULL

      • NO_AUTO_CREATE_USER: 禁止GRANT创建密码为空的用户

      • NO_ENGINE_SUBSTITUTION:如果需要的存储引擎被禁用或未编译,那么抛出错误。不设置此值时,用默认的存储引擎替代,并抛出一个异常

      • PIPES_AS_CONCAT:将"||"视为字符串的连接操作符而非或运算符,这和Oracle数据库是一样是,也和字符串的拼接函数Concat想类似

      • ANSI_QUOTES:启用后,不能用双引号来引用字符串,因为它被解释为识别符

      • 方式2:在配置文件中添加 sql_mode = '对应需要的模式'

      • sql_mode 模式说明:

      • 方式1:重启 MySQL 后失效

    • MySQL8.0 修改了账号密码加密策略 (默认的认证插件由mysql_native_password更改为caching_sha2_password),导致一些可视化软件无法连接 mysql8.0 版本的数据库。如果需要,可以修改默认的策略或者账号密码的认证策略


      [mysqld]
      default_authentication_plugin = mysql_native_password
      

      -- 修改加密规则 
      ALTER USER 'root'@'localhost' IDENTIFIED BY 'password' PASSWORD EXPIRE NEVER; 
      -- 更新用户密码
      ALTER USER '账号'@'%' IDENTIFIED WITH mysql_native_password BY '密码';
      -- 刷新权限
      FLUSH PRIVILEGES;
      


      • 方式2:执行语句修改某账号密码验证策略

      • 方式1:配置文件中添加, 让mysql使用原密码策略 (需重启mysql服务)

    • MySQL8.0 授权用户账号语法变更,创建用户的操作已经不支持grant的同时创建用户方式,需要先创建用户再进行授权。


      -- 原来的流程:
      mysql> grant all on *.* to 'admin'@'%' identified by 'admin';
      -- 新的正确流程:
      mysql> create user 'admin'@'%' identified by 'admin';
      mysql> grant all on *.* to 'admin'@'%' ;
      mysql> flush privileges;
      


    • 数据库连接区别


      jdbc:mysql://{ip}:{port}/{db}?characterEncoding=utf8&useSSL=false&serverTimezone=UTC
      // useSSL  如果不配置false 项目可以正常启动但是会提示ssl问题
      // serverTimezone=UTC 必须配置【时区设置成自己对应的时区】否则项目会报错
      

      show variables like '%time_zone%';
      set global time_zone='+8:00';
      


      • 如果时区问题还不能解决:

      • JDBC 连接串修改如下(首先需要驱动使用8.0对应连接的驱动):

    • MySQL 5.7 原生支持JSON类型,并引入了众多JSON函数

    • MySQL 8.0 JSON字段的部分更新(JSON Partial Updates)

    • MySQL 8.0 默认字符集由latin1修改为utf8mb4

    • MySQL 8.0 正则表达式的增强,新增了4个相关函数,REGEXP_INSTR(),REGEXP_LIKE(),REGEXP_REPLACE(),REGEXP_SUBSTR()

    • MySQL 8.0 GROUP BY语句不再隐式排序 (忽略在Group By中的排序命令,如 desc, asc)

    本站声明:本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系bd@zhengruan.com
    作者最新文章
    编程开发 MySQL
    相关文章 更多
    navicat导入数据库步骤详解及常见问题处理教程
    navicat导入数据库步骤详解及常见问题处理教程

    详解Navicat导入数据库的标准步骤,涵盖SQL脚本执行与CSV数据导入两种核心场景。针对导入过程中常见的字符集乱码、主键冲突及外键约束错误,提供具体的设置方法与修复建议,确保数据迁移准确无误。

    SQL主键约束和唯一约束有什么区别
    SQL主键约束和唯一约束有什么区别

    深入理解SQL PRIMARY KEY与UNIQUE约束的区别。文章从行标识与重复限制的目标出发,详解主键的非空特性、外键引用角色以及多数据库对NULL值的处理差异。结合users表实战示例,指导开发者如何根据字段稳定性与业务语义合理选择约束类型,避免设计误区。

    SQL约束有哪些类型及作用
    SQL约束有哪些类型及作用

    刚开始设计关系型数据库?了解PRIMARY KEY、FOREIGN KEY、UNIQUE、NOT NULL、CHECK、DEFAULT等约束的作用、语法和排错方法。本文以PostgreSQL语法为主,结合用户订单场景,清晰展示如何防止脏数据并处理常见约束冲突。

    SQL游标常见错误排查:死锁与资源未释放问题
    SQL游标常见错误排查:死锁与资源未释放问题

    深入解析SQL游标导致的死锁与资源未释放问题。通过PostgreSQL与MySQL语法对比,展示如何识别长事务持锁、分析锁等待链,并提供短事务提交、异常清理及批量处理的最佳实践,确保数据库连接与锁资源及时释放。

    SQL中怎么创建和删除约束
    SQL中怎么创建和删除约束

    后端开发者在维护数据库时,常需对现有表添加主键、唯一或外键约束。若直接执行ADD CONSTRAINT,往往因存量数据不合规导致报错。本文详解操作前的数据清洗步骤、标准SQL语法及MySQL等特殊写法,帮助你在生产环境安全完成结构变更。

    SQL分组统计查询:GROUP BY与HAVING子句用法示例
    SQL分组统计查询:GROUP BY与HAVING子句用法示例

    针对 SQL 初学者的分组统计实战指南。深入解析 GROUP BY 分组机制、WHERE 与 HAVING 的执行时机差异,以及 COUNT 函数对 NULL 值的处理逻辑。通过具体代码示例演示如何正确筛选聚合结果,并排查因 JOIN 连接导致的统计数据异常,提升报表准确性。

    SQL Server与MySQL游标基本语法及完整代码示例
    SQL Server与MySQL游标基本语法及完整代码示例

    本文详细对比SQL Server和MySQL中游标的基本用法。从DECLARE声明到FETCH遍历,再到CLOSE关闭与DEALLOCATE/Handler清理,解析两者在语法结构、变量接收及异常处理上的核心差异。通过标准代码示例展示如何安全使用游标,避免资源泄漏,适用于需要进行数据库存储过程开发或跨平台迁移的开发者。

    SQL多表连接区别:INNER JOIN与LEFT JOIN的使用场景
    SQL多表连接区别:INNER JOIN与LEFT JOIN的使用场景

    深入解析SQL中INNER JOIN与LEFT JOIN的核心区别。通过users和orders表实例,展示匹配行保留与NULL补位机制,重点讲解ON与WHERE子句中放置右表过滤条件的不同后果,提供防止LEFT JOIN退化的实战技巧及行数异常排查步骤。

    SQL CHECK约束的用法与取值范围限制
    SQL CHECK约束的用法与取值范围限制

    深入理解 SQL CHECK 约束在 PostgreSQL、MySQL 等数据库中的实现差异。文章通过订单业务场景,讲解如何定义单列范围与多列逻辑约束,分析 NULL 值对布尔条件的影响,并提供修改已有表结构时的安全操作建议,帮助开发者构建更健壮的数据完整性防线。

    SQL外键约束怎么用及级联操作说明
    SQL外键约束怎么用及级联操作说明

    后端开发中,如何正确使用 SQL 外键约束来维护订单与明细表的关系?本文通过 PostgreSQL 示例,深入讲解外键的创建语法、插入顺序要求,以及 ON DELETE CASCADE、RESTRICT、SET NULL 等策略的实际影响与风险控制,助你构建健壮的数据库结构。

    查看更多
    精品专题 更多
    装机必备
    装机必备

    正软商城装机必备专区,精选办公、浏览器、安全防护、影音播放、压缩解压、设计创作和系统工具等电脑常用正版软件,帮助用户快速完成新电脑软件配置。

    Windows
    Windows

    正软商城Windows软件专区,汇集适用于Windows电脑的办公、设计、安全防护、影音播放、开发工具和系统优化软件,提供软件介绍、系统要求、正版授权及购买下载服务。

    PDF教程
    PDF教程

    正软商城PDF教程频道提供PDF编辑、转换、合并、拆分、压缩及格式处理方法,同时介绍常用PDF软件和工具的使用技巧。

    Mac软件 更多
    讯飞智作 网页版
    讯飞智作 网页版
    Windows/ macOS/ Linux

    讯飞智作是一款基于语音合成技术、虚拟人驱动技术与数字人形象声音构建能力的 AI 数字人音视频创作平台。

    火山引擎 网页版
    火山引擎 网页版
    Windows/ macOS/ Linux

    火山引擎是字节跳动旗下企业级云与AI服务平台。聚焦大模型核心能力,依托字节自研豆包多模态大模型,凭借火山方舟一站式平台,提供模型精调、推理部署、智能应用搭建等全链路服务,结合高性能AI算力,助力各行业快速落地大模型数字化与智能化应用。

    Aperty macOS版
    Aperty macOS版
    macOS

    Aperty 是 Skylum 推出的 AI 人像修图软件,支持自然肤质修饰、瑕疵处理、面部与身体调整、预设及批量同步。

    WINDOWS 更多
    讯飞智作 网页版
    讯飞智作 网页版
    Windows/ macOS/ Linux

    讯飞智作是一款基于语音合成技术、虚拟人驱动技术与数字人形象声音构建能力的 AI 数字人音视频创作平台。

    火山引擎 网页版
    火山引擎 网页版
    Windows/ macOS/ Linux

    火山引擎是字节跳动旗下企业级云与AI服务平台。聚焦大模型核心能力,依托字节自研豆包多模态大模型,凭借火山方舟一站式平台,提供模型精调、推理部署、智能应用搭建等全链路服务,结合高性能AI算力,助力各行业快速落地大模型数字化与智能化应用。

    PixTV 网页版
    PixTV 网页版
    Windows

    PixTV 是一款在浏览器中使用的 AI 视觉内容创作平台,提供图片、视频、音频、文字生成、AI 分镜、局部重绘、提示词反推和无限画布等工具,适合短剧、漫剧、广告及社交媒体内容制作。