Home  >  Article  >  Database  >  What does mysql ft refer to?

What does mysql ft refer to?

PHPz
PHPzforward
2023-04-14 17:42:031595browse

mysql ft refers to FullText, that is, full-text index; full-text index is to solve queries that need to be based on similarity, rather than precise numerical comparison; full-text index can be N times faster than like in the face of a large amount of data. Speed ​​is not an order of magnitude.

MySQL full-text index (FullText)

1. Introduction

Basic concepts

Full-text index is to solve the needs Queries based on similarity rather than exact numerical comparisons.

Although fuzzy matching can also be achieved using like %, it is unimaginable for retrieval of large amounts of text data. In the face of a large amount of data, full-text indexing can be N times faster than like, but the speed is not an order of magnitude.

Version support

  1. MySQL 5.6 In previous versions, only MyISAM storage engine supports full-text index

  2. MySQL 5.6 and later versions, MyISAM and InnoDB storage engines support full-text index

  3. MySQL 5.7.6 provides a built-in full-text ngram parser that supports Chinese, Japanese, and Korean (CJK), as well as an installable MeCab for Japanese Full-text parser plug-in

  4. Full-text index can only be used for InnoDB or MyISAM tables, and can only be used for CHAR, VARCHAR, TEXTColumn creation

  5. For large data sets, e2a5cfc322b0fffd61a8c4e2ec9a2d2bLoading data into a table without a full-text index and then creating an index is much faster than loading data into a table with an existing full-text index

  6. RDS MySQL 5.6 Although it also supports Chinese full-text search, there are BUG

Restrictions and shortcomings

  • Causes a lot of disk resources usage. Full-text indexing itself is a method of using disk space for performance. The reason why the full-text index is large is that word segmentation based on a certain language

  • The creation of the full-text index is slow, and the modification of various data with the full-text index is also slow

  • Using full-text indexing is not transparent to the application. If you want to use the full-text index, you must modify the query statement. It is impossible to use the full-text index for the original query statement and needs to be changed to the syntax specified by the full-text index

  • Case-insensitive

  • ##Partition The table does not support full-text search

  • The index for full-text search composed of multiple columns must use the same character set and sorting rules

  • Full-text index may have accuracy issues, that is, the data found by the full-text index may be inconsistent with the like columns in the MATCH() function Must be exactly the same as the columns defined in the FULLTEXT index, unless full-text search using IN BOOLEAN MODE mode is used in the MyISAM table (search can be performed on columns that are not indexed, but the speed is very slow)

  • When creating full-text indexes for single columns separately, multi-column fuzzy queries will not take effect

  • Full-text indexes of different tables cannot be queried together. You can add OR## to the two statements.

  • #2. Operation of full-text index
  • 2.1 Configure the minimum search length

  • We can view the currently configured minimum search length (word segmentation length) through SQL commands:
SHOW VARIABLES LIKE 'ft%';

Variable_name

Value##ft_boolean_syntax -> ;2b7da4bc8b0b7a3041e9bf8984b6eb0a” 表示出现该单词时增加相关性,查询的结果靠前
  • “<” 表示出现该单词时降低相关性,查询的结果靠后

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

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

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

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

  • +aaa +(>bbb <ccc) aaa="aaa" sql="sql" select="select" from="from" test="test" where="where" match="match" against="against" in="in" boolean="boolean" mode="mode" select="select" from="from" tommy="tommy" where="where" match="match" against="against" in="in" boolean="boolean" mode="mode" select="select" from="from" tommy="tommy" where="where" match="match" against="against">李秀琴 <练习册 <不是人>是个鬼&#39; in boolean mode);

    四、测试结果

    测试环境:本机4核16G Windows10,MySQL 8.0
    测试数据量salebilldetail1276万行,salebill269 万行, customer30 万行, goods75 万行。

    争对测试用的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(&#39;%&#39;,&#39;葡萄&#39;,&#39;%&#39;)) or (d.goodsremarks like concat(&#39;%&#39;,&#39;葡萄&#39;,&#39;%&#39;)));
    test_2
    -- 测试2,使用全文索引 remarks_fulltext、goodsremarks_fulltext, 用时 0.834s
    select 1 from salebilldetail d where d.tid=260434 and ((match(d.remarks) Against(concat(&#39;"&#39;,&#39;葡萄&#39;,&#39;"&#39;) in boolean mode)) or (match(d.goodsremarks) Against(concat(&#39;"&#39;,&#39;葡萄&#39;,&#39;"&#39;)  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(&#39;"&#39;,&#39;葡萄&#39;,&#39;"&#39;) in boolean mode)));
    test_4
    -- 测试4,原始 like 查询方式,不过滤 tid ,用时 22.654s
    select t from salebilldetail d where ((d.remarks like concat(&#39;%&#39;,&#39;葡萄&#39;,&#39;%&#39;)) or (d.goodsremarks like concat(&#39;%&#39;,&#39;葡萄&#39;,&#39;%&#39;)));
    test_5
    -- 测试5,使用全文索引 remarks_fulltext、goodsremarks_fulltext,  不过滤 tid ,用时 24.855s
    select 1 from salebilldetail d where ((match(d.remarks) Against(concat(&#39;"&#39;,&#39;葡萄&#39;,&#39;"&#39;) in boolean mode)) or (match(d.goodsremarks) Against(concat(&#39;"&#39;,&#39;葡萄&#39;,&#39;"&#39;)  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(&#39;"&#39;,&#39;葡萄&#39;,&#39;"&#39;) 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(&#39;"&#39;,&#39;葡萄&#39;,&#39;"&#39;) 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(&#39;"&#39;,&#39;葡萄&#39;,&#39;"&#39;) 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,&#39;%Y-%m-%d&#39;) as billdate /*单据日期*/
        ,from_unixtime(i.createdate,&#39;%Y-%m-%d %H:%i:%s&#39;) as createdate /*制单日期*/
        ,if(i.sdate=0,&#39;&#39;,from_unixtime(i.sdate,&#39;%Y-%m-%d  %H:%i:%s&#39;)) as sdate /*过账日期*/
        ,from_unixtime(i.udate,&#39;%Y-%m-%d %H:%i:%s&#39;) 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 &#39;红冲单&#39;  when i.redold=1 then &#39;已红冲&#39;  when i.settle=1 then &#39;已结算&#39;  when i.effect=1 then &#39;已过账&#39;  else &#39;草稿&#39; end) as statetext
        ,&#39;&#39; as susername /* 操作人 */
        ,&#39;&#39; 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 (&#39;_billdate_f_&#39;!=&#39;&#39;)
        and (&#39;_billdate_t_&#39;!=&#39;&#39;)
        and (&#39;_sdate_f_&#39;!=&#39;&#39;)
        and (&#39;_sdate_t_&#39;!=&#39;&#39;)
        and (&#39;_udate_f_&#39;!=&#39;&#39;)
        and (&#39;_udate_t_&#39;!=&#39;&#39;)
        and (&#39;_cdate_f_&#39;!=&#39;&#39;)
        and (&#39;_cdate_t_&#39;!=&#39;&#39;)
        and (&#39;_billid_&#39;!=&#39;&#39;)      /*单据id*/
        and (&#39;_custid_&#39;!=&#39;&#39;)      /*客户ID*/
        and (&#39;_storeid_&#39;!=&#39;&#39;)     /*店仓ID*/
        and (&#39;_empid_&#39;!=&#39;&#39;)       /*业务员ID*/
        and (&#39;_custstop_&#39;!=&#39;&#39;)       /*客户是否停用*/
        and (
            (i.billno like concat(&#39;%&#39;,&#39;葡萄&#39;,&#39;%&#39;))
            or (i.remarks like concat(&#39;%&#39;,&#39;葡萄&#39;,&#39;%&#39;))
            or exists(select 1 from salebilldetail d where d.tid=260434 and d.billid=i.billid and ((d.remarks like concat(&#39;%&#39;,&#39;葡萄&#39;,&#39;%&#39;)) or (d.goodsremarks like concat(&#39;%&#39;,&#39;葡萄&#39;,&#39;%&#39;))))
            or exists(select 1 from customer c where c.tid=260434 and c.custid=i.custid and (c.custname like concat(&#39;%&#39;,&#39;葡萄&#39;,&#39;%&#39;)))
            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(&#39;%&#39;,&#39;葡萄&#39;,&#39;%&#39;)) or (g.goodscode like concat(&#39;%&#39;,&#39;葡萄&#39;,&#39;%&#39;))))
        )
        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,&#39;%Y-%m-%d&#39;) as billdate /*单据日期*/
        ,from_unixtime(i.createdate,&#39;%Y-%m-%d %H:%i:%s&#39;) as createdate /*制单日期*/
        ,if(i.sdate=0,&#39;&#39;,from_unixtime(i.sdate,&#39;%Y-%m-%d  %H:%i:%s&#39;)) as sdate /*过账日期*/
        ,from_unixtime(i.udate,&#39;%Y-%m-%d %H:%i:%s&#39;) 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 &#39;红冲单&#39;  when i.redold=1 then &#39;已红冲&#39;  when i.settle=1 then &#39;已结算&#39;  when i.effect=1 then &#39;已过账&#39;  else &#39;草稿&#39; end) as statetext
        ,&#39;&#39; as susername /* 操作人 */
        ,&#39;&#39; 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 (&#39;_billdate_f_&#39;!=&#39;&#39;)
        and (&#39;_billdate_t_&#39;!=&#39;&#39;)
        and (&#39;_sdate_f_&#39;!=&#39;&#39;)
        and (&#39;_sdate_t_&#39;!=&#39;&#39;)
        and (&#39;_udate_f_&#39;!=&#39;&#39;)
        and (&#39;_udate_t_&#39;!=&#39;&#39;)
        and (&#39;_cdate_f_&#39;!=&#39;&#39;)
        and (&#39;_cdate_t_&#39;!=&#39;&#39;)
        and (&#39;_billid_&#39;!=&#39;&#39;)      /*单据id*/
        and (&#39;_custid_&#39;!=&#39;&#39;)      /*客户ID*/
        and (&#39;_storeid_&#39;!=&#39;&#39;)     /*店仓ID*/
        and (&#39;_empid_&#39;!=&#39;&#39;)       /*业务员ID*/
        and (&#39;_custstop_&#39;!=&#39;&#39;)       /*客户是否停用*/
        and (
            (match(i.billno) against(concat(&#39;"&#39;,&#39;葡萄&#39;,&#39;"&#39;) in boolean mode))
            or (match(i.remarks) against(concat(&#39;"&#39;,&#39;葡萄&#39;,&#39;"&#39;) 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(&#39;"&#39;,&#39;葡萄&#39;,&#39;"&#39;) in boolean mode)) or (match(d.goodsremarks) Against(concat(&#39;"&#39;,&#39;葡萄&#39;,&#39;"&#39;)  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(&#39;"&#39;,&#39;葡萄&#39;,&#39;"&#39;) 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(&#39;"&#39;,&#39;葡萄&#39;,&#39;"&#39;) in boolean mode))
         or (match(g.goodscode) Against(concat(&#39;"&#39;,&#39;葡萄&#39;,&#39;"&#39;) 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_fulltextgoodsremarks_fulltext的地方)

    exists(select 1 from salebilldetail d where d.tid=260434 and d.billid=i.billid and ((match(d.remarks) Against(concat(&#39;"&#39;,&#39;葡萄&#39;,&#39;"&#39;) in boolean mode)) or (match(d.goodsremarks) Against(concat(&#39;"&#39;,&#39;葡萄&#39;,&#39;"&#39;)  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(&#39;"&#39;,&#39;葡萄&#39;,&#39;"&#39;) 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(&#39;"&#39;,&#39;葡萄&#39;,&#39;"&#39;) 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(&#39;"&#39;,&#39;葡萄&#39;,&#39;"&#39;) in boolean mode))))
    	or match(i.billno) against(concat(&#39;"&#39;,&#39;葡萄&#39;,&#39;"&#39;) in boolean mode)
    )
    ...

    测试结果汇总

    查询 用时(秒) 备注
    test 1 0.765 原始like查询
    test 2 0.834 全文索引 remarks_fulltextgoodsremarks_fulltext
    test 3 0.242 全文索引 remarks_goodsremarks_fulltext
    ---

    test 4 22.654 原始like查询,不过滤 tid
    test 5 24.855 全文索引 remarks_fulltextgoodsremarks_fulltext,  不过滤 tid
    test 6 0.213 全文索引 remarks_goodsremarks_fulltext, 不过滤 tid
    ---

    test 7 0.22 全文索引 remarks_goodsremarks_fulltext, count
    test 8 0.007 全文索引 remarks_goodsremarks_fulltext, 不过滤 tid, count
    ---

    test 9 1.6 业务测试SQL,原始like查询
    test 10 1.6 业务测试SQL,全文索引 remarks_fulltextgoodsremarks_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 = &#39;STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_ENGINE_SUBSTITUTION&#39;;
      -- 或 设置 (修改于当前会 话,关闭当前会话后失效)
      SET SESSION sql_mode = &#39;STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_ENGINE_SUBSTITUTION&#39;;
      -- 刷新
      flush PRIVILEGES;
      
      • ONLY_FULL_GROUP_BY: 对于GROUP BY聚合操作,如果在SELECT中的列,没有在GROUP BY中出现,那么这个SQL是不合法的,因为列不在GROUP BY从句中

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

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

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

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

      • ERROR_FOR_DIVISION_BY_ZERO:在insertupdate过程中,如果数据被零除,则产生错误而非警告。如果未给出该模式,那么数据被零除时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 &#39;root&#39;@&#39;localhost&#39; IDENTIFIED BY &#39;password&#39; PASSWORD EXPIRE NEVER; 
      -- 更新用户密码
      ALTER USER &#39;账号&#39;@&#39;%&#39; IDENTIFIED WITH mysql_native_password BY &#39;密码&#39;;
      -- 刷新权限
      FLUSH PRIVILEGES;
      

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

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

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

      -- 原来的流程:
      mysql> grant all on *.* to &#39;admin&#39;@&#39;%&#39; identified by &#39;admin&#39;;
      -- 新的正确流程:
      mysql> create user &#39;admin&#39;@&#39;%&#39; identified by &#39;admin&#39;;
      mysql> grant all on *.* to &#39;admin&#39;@&#39;%&#39; ;
      mysql> flush privileges;
      
    • 数据库连接区别

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

      show variables like &#39;%time_zone%&#39;;
      set global time_zone=&#39;+8:00&#39;;
      

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

      • 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)

    The above is the detailed content of What does mysql ft refer to?. For more information, please follow other related articles on the PHP Chinese website!

    Statement:
    This article is reproduced at:yisu.com. If there is any infringement, please contact admin@php.cn delete