代码之旅

I love Coding !

尝试复现问题

  • 首先创建数据库。
1
2
3
CREATE SCHEMA `tmp` DEFAULT CHARACTER SET utf8 COLLATE utf8_danish_ci ;
flush privileges;
grant all privileges on tmp.* to 'victorchu'@'localhost' ;
  • 接下来创建表A。
1
2
3
4
5
6
7
8
9
10
11
CREATE TABLE IF NOT EXISTS `tmp`.`A`(
`id` INT NOT NULL,
`name` VARCHAR(45) NULL,
`b_name` VARCHAR(45) NULL,
PRIMARY KEY (`id`))
ENGINE = InnoDB
DEFAULT CHARACTER SET = utf8;

INSERT INTO `tmp`.`A` (`id`, `name`, `b_name`) VALUES ('1', '1', '1');
INSERT INTO `tmp`.`A` (`id`, `name`, `b_name`) VALUES ('2', '2', '2');
INSERT INTO `tmp`.`A` (`id`, `name`, `b_name`) VALUES ('3', '3', '3');

接着创建表B。

1
2
3
4
5
6
7
8
9
10
CREATE TABLE IF NOT EXISTS `tmp`.`B`(
`id` INT NOT NULL,
`name` VARCHAR(45) NULL,
`result` VARCHAR(45) NULL,
PRIMARY KEY (`id`))
ENGINE = InnoDB;

INSERT INTO `tmp`.`B` (`id`, `name`, `result`) VALUES ('1', '1', '1');
INSERT INTO `tmp`.`B` (`id`, `name`, `result`) VALUES ('2', '2', '2');
INSERT INTO `tmp`.`B` (`id`, `name`, `result`) VALUES ('3', '3', '3');

异常查询。

1
2
3
4
5
6
7
use tmp;
select A.id , B.result
from A
left join B on A.b_name = B.name
where A.id =1;

-- Error Code: 1267. Illegal mix of collations (utf8_general_ci,IMPLICIT) and (utf8_danish_ci,IMPLICIT) for operation '=' 0.0011 sec

出现这个错的原因是相等的两个字段字符集不统一的问题。为了确认这一问题,我们来查看数据库字符集编码.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
-- 查看MYSQL数据库服务器和数据库字符集
mysql> show variables like 'collation%';
+----------------------+--------------------+
| Variable_name | Value |
+----------------------+--------------------+
| collation_connection | utf8mb4_0900_ai_ci |
| collation_database | utf8_danish_ci |
| collation_server | utf8mb4_0900_ai_ci |
+----------------------+--------------------+
-- 查看库的字符集
-- 结果省略部分
mysql> SHOW CREATE DATABASE tmp;
+----------+------------------------------------------------------------------------------+
| Database | Create Database |
+----------+------------------------------------------------------------------------------+
| tmp | CREATE DATABASE `tmp` /*DEFAULT CHARACTER SET utf8 COLLATE utf8_danish_ci */ |
+----------+------------------------------------------------------------------------------+

-- 查看表的字符集
-- 结果省略部分列
mysql> show table status from tmp like 'A';
+-----------------+
| Collation |
+-----------------+
| utf8_general_ci |
+-----------------+
mysql> show table status from tmp like 'B';
+----------------+
Collation |
+----------------+
| utf8_danish_ci |
+----------------+

-- 查看表中所有列的字符集
-- 结果省略部分列
mysql> show full columns from A;
+--------+-------------+-----------------+
| Field | Type | Collation |
+--------+-------------+-----------------+
| id | int | NULL |
| name | varchar(45) | utf8_general_ci |
| b_name | varchar(45) | utf8_general_ci |
+--------+-------------+-----------------+
mysql> show full columns from B;
+--------+-------------+----------------+
| Field | Type | Collation |
+--------+-------------+----------------+
| id | int | NULL |
| name | varchar(45) | utf8_danish_ci |
| result | varchar(45) | utf8_danish_ci |
+--------+-------------+----------------+

解决方案

  • 修改数据库字符集:ALTER DATABASE db_name DEFAULT CHARACTER SET character_name [COLLATE ...];
  • 把表默认的字符集和所有字符列(CHAR,VARCHAR,TEXT)改为新的字符集:ALTER TABLE tbl_name CONVERT TO CHARACTER SET character_name [COLLATE ...]
  • 修改表的默认字符集:ALTER TABLE tbl_name DEFAULT CHARACTER SET character_name [COLLATE...];
  • 修改字段的字符集:ALTER TABLE tbl_name CHANGE c_name c_name CHARACTER SET character_name [COLLATE ...];

MySQL提供的group_concat()函数可以拼接某个字段值成字符串,如 select group_concat(user_name) from sys_user,默认的分隔符是逗号,即,,如果需要自定义分隔符可以使用 SEPARATOR.如:select group_concat(user_name SEPARATOR '_') from sys_user

但是如果 user_name 拼接的字符串的长度字节超过1024 则会被截断。通过命令show variables like 'group_concat_max_len'来查看group_concat 默认的长度:

1
2
3
4
5
6
7
mysql> show variables like 'group_concat_max_len';
+----------------------+-------+
| Variable_name | Value |
+----------------------+-------+
| group_concat_max_len | 1024 |
+----------------------+-------+
1 row in set

在MySQL配置文件中添加配置:group_concat_max_len = -1 (-1为最大值或根据实际需求设置长度),配置后需要重启MySQL服务,查看如下所示:

1
2
3
4
5
6
7
mysql> show variables like 'group_concat_max_len';
+----------------------+------------+
| Variable_name | Value |
+----------------------+------------+
| group_concat_max_len | 4294967295 |
+----------------------+------------+
1 row in set

如果是生产环境下,不能擅自重启MySQL服务,则可以通过语句设置group_concat的作用范围,如:

1
2
3
4
SET GLOBAL group_concat_max_len=-1;

SET SESSION group_concat_max_len=-1;
-- 使用mybatis时,可以在选择xml中设置 SESSION 中的 group_concat_max_len

java命令用于启动JVM虚拟机。Java启动参数分为3种:

  1. 标准参数: 所有的JVM实现都必须实现这些参数的功能,而且向后兼容。JVM的标准参数都是以”-“开头。
  2. 非标准参数: 默认JVM(HotSpot虚拟机)实现这些参数的功能,但是并不保证所有jvm实现都满足,且不保证向后兼容.JVM的非标准参数都是以”-x“开头。
  3. 非stable参数:此类参数通常具有特定的系统要求,并且可能需要对系统配置参数的特权访问。各个jvm实现会有所不同,将来可能会随时取消,需要慎重使用。JVM的非stable参数都是以”-xx“开头。
阅读全文 »

有一个文本串S,和一个模式串P,现在要查找P在S中的位置,怎么查找呢?

假设主串target为: a b a c a a b a c a b a c a b a a b b,模式串pattern: a b a c a b(为了方便查看,每个字符间用空格隔开)。

用暴力算法匹配字符串过程中,我们会把target[0]pattern[0] 匹配,如果相同则匹配下一个字符,直到出现不相同的情况,此时我们会丢弃前面的匹配信息,然后把target[1]pattern[0] 匹配,循环进行,直到主串结束,或者出现匹配成功的情况。这种丢弃前面的匹配信息的方法,极大地降低了匹配效率。

以上面的字符为例子:pattern的前5个字符abaca可以匹配target的前5个字符,但是pattern[5]target[5]不匹配。下面重新从target[1]开始和pattern匹配。

显然效率很差,因为你要把"搜索位置"移到已经比较过的位置,重比一遍。

阅读全文 »

上下文无关的组成部分:

  • 终结符号
  • 非终结符号
  • 一个开始符号
  • 一组产生式

例如,下面数学表达式:

exprexpr+termexpr \to expr+term

exprexprtermexpr \to expr-term

exprtermexpr \to term

termtermfactorterm \to term * factor

termterm/factorterm \to term/factor

termfactorterm \to factor

factor(expr)factor \to (expr)

factoridfactor \to id

  1. 终结符号(词法单元)是组成串的基本符号,例如上面的 +,-
  2. 非终结符号是表示串的集合的语法变量,例如上面的term和factor。非终结符号表示的串集合用于定义由文法生成的语言。
阅读全文 »

算法之trie字典树

Trie树,又称字典树、前缀树、单词查找树、键树,是一种多叉树形结构,是一种哈希树的变种。Trie树典型应用是用于快速检索(最长前缀匹配),统计,排序和保存大量的字符串,所以经常被搜索引擎系统用于文本词频统计,搜索提示等场景。它的优点是最大限度地减少无谓的字符串比较,查询效率比较高。

Trie的核心思想是空间换时间,利用字符串的公共前缀来降低查询时间的开销以达到提高效率的目的。

阅读全文 »

google 提出了 Jump consistent hash 算法,跳转一致性哈希不需要存储,速度更快,并且在均匀划分key方面做得更好。它的主要限制是桶必须按顺序编号,这使得它 比分布式 Web 缓存更适合数据存储应用程序

阅读全文 »

哈希环法是最常用的、最经典的一致性哈希算法, 也叫做割环法。 这个算法易于理解、应用广泛(例如亚马逊的Dynamo1), 实现了最小化的重新映射。

阅读全文 »

一致性哈希算法是一种特殊的哈希算法, 当目标槽位数量发生变化时,它会尽力降低的重新映射的数量。 传统的哈希表设计中,添加或者删除一个槽位,会造成全量的重新映射, 一致性哈希则追求的是增量式重新映射。

阅读全文 »