使用字符集 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'))
我想使用 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'))