使用字符集 utf8mb4 获得准确的过滤结果

Get exact filter results with charset utf8mb4

我想使用 CHARACTER SET utf8mb4 精确匹配过滤结果。

ALTER DATABASE test CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci;

CREATE TABLE users (    
username VARCHAR(25) NOT NULL,    
password VARCHAR(25) NULL NULL
) 
ENGINE=innodb DEFAULT CHARSET=utf8mb4 
COLLATE=utf8mb4_general_ci ROW_FORMAT=DYNAMIC;
CREATE  INDEX  users_username_idx ON users (username); 

我插入了 100 万行,还包含以下行。

INSERT INTO users SELECT 'üsasdasd','somepassword';
INSERT INTO users SELECT 'usasdasd','somepassword';
INSERT INTO users SELECT 'pğasdasdasd','somepassword';
INSERT INTO users SELECT 'anfüs','somepassword';
INSERT INTO users SELECT 'anfus','somepassword';

然后应用了一些查询。

SELECT * FROM users WHERE username LIKE 'üs%';
SELECT * FROM users WHERE username LIKE 'us%';
SELECT * FROM users WHERE username LIKE 'pğ%';
SELECT * FROM users WHERE username = 'anfüs';
SELECT * FROM users WHERE username = 'anfus';

当我过滤为 "LIKE 'us%'"" = 'anfus'"
时,为什么我得到的结果也有 ü 字母(如 üsasdasd 或 anfüs) 要么 当我过滤为 "LIKE 'üs%'"" = 'anfüs'" 时,为什么我得到的结果也有 u 字母(如 usasdasd 或 anfus)?

当我过滤为 "LIKE 'üs%'"" = 'anfüs'" 反之亦然时,如何获得只有 ü 字母(如 üsasdasd 或 anfüs)的结果?

ANSWER:

我不知道为什么,但是 COLLATE=utf8mb4_0900_as_cs 解决了这个问题。

对于密码,您想忽略 所有 大小写折叠、重音去除等,因此请使用 COLLATE utf8mb4_bin.

我怀疑 utf8mb4_0900_as_cs_bin 不太一样。

另一方面,您真的要存储 "plaintext" 密码吗?一种常见的技术是存储密码的散列并在测试时进行散列。一个简单的散列,可以防止偶然的黑客攻击:

MD5(CONCAT(password, 'my secret salt'))