我们的QA团队简直是怪物,你知道的!
不管我在下次公司聚会上怎么用请客喝酒贿赂他们,让他们停止找我代码里的问题,他们总是提出一些不合理的要求和所谓的“预期行为”……真恶心,呕!
别相信我吧?
他们最近要求将列表按照字母和数字的顺序排列。
你能相信吗?我告诉你,怪物啊!
我的意思是,毕竟一般用户不会期望清单是自动排序的。
测试 1
测试 2
测试 12
全屏模式 退出全屏
...为什么就不能按照MySQL那种方式来排序呢
以下为测试代码:
测试用例 1
测试用例 12
测试用例 2
全屏,退出全屏
有道理吧?是吧?
随便怎么说,我们不要纠结谁对谁错(顺便说一句,他们是对的),我觉得最好试着解决一下。
我说……这有啥难的?(暗示)
简短的说我知道你可能很忙的,简单来说就是用JS、PHP或其他语言来处理。不要用MySQL来处理。
真的,直接返回你的数据集,然后在你用的是 Node 时使用 Intl.Collator
,或者在 PHP 中,你可以使用 natsort()
。
你知道,那样做也还好。问题解决了,我就可以继续我的日常生活。质量保证那边会满意,列表也整理好了,一切就都好了。
然而,如果你和我一样,你的CTO在审查你的PR时说:
请查看图片。
我心领神会!
真的,他真是太对了。
我们为什么还要在代码里手动分类?MySQL应该能为我们搞定这些。
接着发生的是超过4小时的捣鼓和骂娘,试图让MySQL屈从于我。
没完全做到,但差不多成功了。
在这个特定情况下,我最终采用的方法在用户输入方面还算过得去,并且比我发现的其他方案都好很多,但也有它的局限性。
但现在我们说得太超前了,我想展示一下在 MySQL 中试着解决这个问题是怎样的吧!
测试数据让我们首先来谈谈我用的测试数据,这样你就能检查我是否遗漏了什么。
测试数据
测试资料
INSERT INTO test_data (data_value) VALUES
('2 test'),
('12 test'),
('1 test'),
('20 test'),
('10 test'),
('1test'),
('2test'),
('test 1'),
('my data 2020-01-01'),
('my data 2020-02-01'),
('01-02-24 data'),
('12 test'),
('4a test'),
('my 2020-01-01 data 2020-01-01'),
('my 2020-02-01 data 2020-01-01'),
('my 2020-02-01 data 202-01-01'),
('my 2020-02-01 data 20-01-01'),
('my 2020-02-01 data 1-01-01'),
('my 2020-02-01 data 2-01-01'),
('my 2020-02-01 data 12-01-01'),
('my 2020-02-01 data 01-01-01'),
('my 2020-01-01 data 2020-02-01'),
('my 2020-01-01 data 2021-01-01'),
('my 2020-01-01 data 2120-01-01'),
('my 2120-01-01 data 2020-01-01'),
('4b test'),
('my test'),
('my 12 magic test'),
('my magic 12 test'),
('cheese and test 12'),
('42-a-1'),
('40-a-1'),
('40a'),
('FoClSy4727'),
('Pthw068bf'),
('6bfS'),
('HOFAp_Yx7920'),
('25hWTX'),
('dnjLlW1'),
('RHrIt72402eaLr'),
('cIhb42WFNQ'),
('9244uVCpGa'),
('yDKrkCp7960'),
('GeGIrPM-H86'),
('wrOae537LGCT'),
('WffSPaBA318'),
('kQ33596c'),
('3uEKHmHePf'),
('796h-eYWy'),
('833HufIZAS'),
('utjtV03Xns'),
('dlCSh87811'),
('13IUkOxEVl'),
('VHCok55901XYVk'),
('2RnSVwq'),
('AwtwQdn09'),
('gvSV6z'),
('uxWLO039hb'),
('vTg946');
全屏模式 退出全屏
一些字符串中夹杂着各种位置的数字,这在我看来还算有点道理。
这可能不是完美的数据集,但对我来说已经足够了!
所以我有了些数据,每个开发者都会做的事我也做了,向谷歌大神求助。
在 MySQL 中查找自然排序法的方法看来这第一步挺有道理的,是吧?
MySQL 已经存在了 30 年了,字母数字排序可能是很多人会经常遇到的需求,所以应该已经有现成的方法了吧?
简而言之……这太令人筋疲力尽了。每篇文章、Stack Overflow帖子等等都说的都是没用的废话,要么不管用,要么只适用于特定数据格式。Stack Overflow帖子等。
我想要一个通用的,这样在任何地方都可以按字母数字顺序排列。
让我带你经历我经历过的痛苦,这样你就不用再经历同样的痛苦了,也能判断我的回答是否更好……或者我只是让你的痛苦更多了。
我们来试试别人提过的常见排序方式:
测试一:‘+0’方法
SELECT
*
FROM
test_data
ORDER BY
`data_value`+0 ASC
-- 这将从test_data表中选择所有数据,并按data_value的数值升序排列。
点击全屏 点击退出
目的是让它尝试让MySQL使用数值顺序,而不是按字典顺序。
如果每一行都有数字或单词,这会工作得很好(这样的话,数字会按顺序排列,然后是单词)。
然而,由于我们的数据杂乱无章,它只是输出了一堆无意义的内容。
第1次测试结果
id | data_value |
---|---|
44 | GeGIrPM-H86 |
25 | 2020-01-01 的数据 |
27 | 我的测试 |
28 | 我的12魔法测试 |
29 | 我的魔法12测试 |
34 | FoClSy4727 |
测试1的完整结果如下
id | data_value |
---|---|
44 | GeGIrPM-H86 |
25 | 我 2020-01-01 数据 2020-01-01 |
27 | 测试 |
28 | 带有魔法数字12的测试 |
29 | 带有数字12魔法的测试 |
34 | FoClSy4727 |
35 | Pthw068bf |
37 | HOFAp_Yx7920 |
39 | dnjLlW1 |
40 | RHrIt72402eaLr |
41 | cIhb42WFNQ |
43 | yDKrkCp7960 |
30 | 奶酪和12号测试 |
45 | wrOae537LGCT |
46 | WffSPaBA318 |
47 | kQ33596c |
51 | utjtV03Xns |
52 | dlCSh87811 |
54 | VHCok55901XYVk |
56 | AwtwQdn09 |
57 | gvSV6z |
58 | uxWLO039hb |
59 | vTg946 |
17 | 我 2020-02-01 数据 20-01-01 |
8 | 测试 1 |
9 | 我 2020-01-01 数据 |
10 | 我 2020-02-01 数据 |
14 | 我 2020-01-01 数据 2020-01-01 |
15 | 我 2020-02-01 数据 2020-01-01 |
16 | 我 2020-02-01 数据 202-01-01 |
18 | 我 2020-02-01 数据 1-01-01 |
19 | 我 2020-02-01 数据 2-01-01 |
21 | 我 2020-02-01 数据 01-01-01 |
23 | 我 2020-01-01 数据 2021-01-01 |
22 | 我 2020-01-01 数据 2020-02-01 |
20 | 我 2020-02-01 数据 12-01-01 |
24 | 我 2020-01-01 数据 2120-01-01 |
6 | 1test |
11 | 01-02-24 数据 |
3 | 1 测试 |
55 | 2RnSVwq |
1 | 2 测试 |
7 | 2test |
48 | 3uEKHmHePf |
13 | 4a 测试 |
26 | 4b 测试 |
36 | 6bfS |
5 | 10 测试 |
2 | 12 测试 |
12 | 12 测试 |
53 | 13IUkOxEVl |
4 | 20 测试 |
38 | 25hWTX |
33 | 40a |
32 | 40-a-1 |
31 | 42-a-1 |
49 | 796h-eYWy |
50 | 833HufIZAS |
42 | 9244uVCpGa |
好的,这没成功(其实我也没指望它会成功)。
我们试试别的东西吧:
测试 2: '长度' 小技巧
SELECT
字符和数字, 整型
FROM
排序测试表
ORDER BY
LENGTH(字符和数字), 字符和数字
点击全屏 点击退出全屏
这也是一个挺有趣的尝试。
显然,“12”比“1”要长,所以在那里应该没问题。
它也适用于您使用标准的数据格式,比如我之前提到的“test 1, test 12, test 2”这样的格式。
不过,对于我们的数据来说,它给出更多的无意义信息:
第二次测试的结果是
id | data_value |
---|---|
33 | 40a |
36 | 6bfS |
6 | 1test |
7 | 2test |
3 | 1 test |
1 | 2 test |
38 | 25hWTX |
32 | 40-a-1 |
31 | 42-a-1 |
57 | gvSV6z |
8 | test 1 |
59 | vTg946 |
5 | 10 test |
测试 2 的全部结果
id | data_value |
---|---|
33 | 40a |
36 | 6bfS |
6 | 1test |
7 | 2test |
3 | 1 test |
1 | 2 test |
38 | 25hWTX |
32 | 40-a-1 |
31 | 42-a-1 |
57 | gvSV6z |
8 | test 1 |
59 | vTg946 |
5 | 10 test |
2 | 12 test |
12 | 12 test |
4 | 20 test |
55 | 2RnSVwq |
13 | 4a test |
26 | 4b test |
39 | dnjLlW1 |
27 | my test |
47 | kQ33596c |
49 | 796h-eYWy |
56 | AwtwQdn09 |
35 | Pthw068bf |
53 | 13IUkOxEVl |
48 | 3uEKHmHePf |
50 | 833HufIZAS |
42 | 9244uVCpGa |
41 | cIhb42WFNQ |
52 | dlCSh87811 |
34 | FoClSy4727 |
51 | utjtV03Xns |
58 | uxWLO039hb |
44 | GeGIrPM-H86 |
46 | WffSPaBA318 |
43 | yDKrkCp7960 |
37 | HOFAp_Yx7920 |
45 | wrOae537LGCT |
11 | 01-02-24 数据 |
40 | RHrIt72402eaLr |
54 | VHCok55901XYVk |
28 | 我的12个魔法测试 |
29 | 我的魔法测试12 |
30 | 奶酪和测试12 |
9 | 我的数据2020-01-01 |
10 | 我的数据2020-02-01 |
18 | 我的2020-02-01 数据 1-01-01 |
19 | 我的2020-02-01 数据 2-01-01 |
21 | 我的2020-02-01 数据 01-01-01 |
20 | 我的2020-02-01 数据 12-01-01 |
17 | 我的2020-02-01 数据 20-01-01 |
16 | 我的2020-02-01 数据 202-01-01 |
14 | 我的2020-01-01 数据 2020-01-01 |
22 | 我的2020-01-01 数据 2020-02-01 |
23 | 我的2020-01-01 数据 2021-01-01 |
24 | 我的2020-01-01 数据 2120-01-01 |
15 | 我的2020-02-01 数据 2020-01-01 |
25 | 我的2120-01-01 数据 2020-01-01 |
而且这也说得通,它只是按长度排序。
按字符串长度排序,'a1' 会排在 '1potato' 前面。
测试3:豪连肯
看看这个美女:
或
看看这件漂亮的东西:
(注:如果上下文明确是指物品,建议使用“看看这个漂亮的物品”以使句子更加自然。)
SELECT
*
FROM
test_data
ORDER BY
REPLACE(
REPLACE(
REPLACE(
REPLACE(
REPLACE(
REPLACE(
REPLACE(
REPLACE(
REPLACE(
REPLACE(
data_value,
'0', 'Ā'),
'1', 'ā'),
'2', 'Ă'),
'3', 'ă'),
'4', 'Ą'),
'5', 'ą'),
'6', 'Ć'),
'7', 'ć'),
'8', 'Ĉ'),
'9', 'ĉ')
COLLATE utf8_bin; -- 对data_value进行替换并按utf8_bin排序规则排序
进入全屏,退出全屏
这梗是真的火!
但是尽管如此,这个方法基本上有效(虽然和我原本想的不同)。
这种方法很巧妙,因为它将每个数值替换为一个根据它们在Unicode中的二进制表示排序的字符。
测试3的结果如下
id | data_value |
---|---|
56 | AwtwQdn09 |
34 | FoClSy4727 |
44 | GeGIrPM-H86 |
37 | HOFAp_Yx7920 |
35 | Pthw068bf |
40 | RHrIt72402eaLr |
54 | VHCok55901XYVk |
46 | WffSPaBA318 |
41 | cIhb42WFNQ |
30 | 奶酪和测试12 |
测试3的完整结果
id | data_value |
---|---|
56 | AwtwQdn09 |
34 | FoClSy4727 |
44 | GeGIrPM-H86 |
37 | HOFAp_Yx7920 |
35 | Pthw068bf |
40 | RHrIt72402eaLr |
54 | VHCok55901XYVk |
46 | WffSPaBA318 |
41 | cIhb42WFNQ |
30 | 奶酪测试 12 |
52 | dlCSh87811 |
39 | dnjLlW1 |
57 | gvSV6z |
47 | kQ33596c |
9 | 2020年01月01日的数据 |
10 | 2020年02月01日的数据 |
29 | 魔法测试 12 |
27 | 测试 |
28 | 魔法测试 12 |
14 | 2020年01月01日的数据 |
22 | 2020年01月01日的数据 |
23 | 2020年01月01日的数据 |
24 | 2020年01月01日的数据 |
21 | 2020年02月01日的数据 |
18 | 2020年02月01日的数据 |
20 | 2020年02月01日的数据 |
19 | 2020年02月01日的数据 |
17 | 2020年02月01日的数据 |
16 | 2020年02月01日的数据 |
15 | 2020年02月01日的数据 |
25 | 2120年01月01日的数据 |
8 | 测试一 |
51 | utjtV03Xns |
58 | uxWLO039hb |
59 | vTg946 |
45 | wrOae537LGCT |
43 | yDKrkCp7960 |
11 | 01月02日24日的数据 |
3 | 一测试 |
6 | 一test |
5 | 十测试 |
2 | 十二测试 |
12 | 十二测试 |
53 | 13IUkOxEVl |
1 | 二测试 |
55 | 2RnSVwq |
7 | 二test |
4 | 二十测试 |
38 | 25hWTX |
48 | 3uEKHmHePf |
13 | 四a测试 |
26 | 四b测试 |
32 | 40-a-1 |
33 | 40a |
31 | 42-a-1 |
36 | 6bfS |
49 | 796h-eYWy |
50 | 833HufIZAS |
42 | 9244uVCpGa |
你知道吗,如果不是因为一件事,我会用这个的。但是这意味着我们不能再接受如 'Ā' 等输入了。
不幸的是,我们的软件产品将被国际使用,所以我们不能做出那样的选择。
此外,如果你决定使用这个,你的数据库中的这一列也应使用 COLLATE 'utf8_bin'
,否则可能会出错。
当谷歌搜索没用的时候,总能帮上忙的是ChatGPT,是吧?
我不会展示所有的结果,但这么说吧,以下只是它没成功的几个!
第 4 测试:GPT 的幻想
SELECT
data_value,
-- 将数字替换成 'a',将字母替换成 'b',其他字符则保持原样
(
SELECT GROUP_CONCAT(
CASE
WHEN c REGEXP '[0-9]' THEN 'a' -- 将数字替换成 'a'
WHEN c REGEXP '[a-zA-Z]' THEN 'b' -- 将字母替换成 'b'
ELSE c -- 其他字符则保持原样
END
ORDER BY seq
) SEPARATOR ''
FROM (
SELECT SUBSTRING(data_value, seq, 1) AS c, seq
FROM (
SELECT data_value, seq
FROM test_data
JOIN (
SELECT n AS seq
FROM (SELECT 1 n UNION ALL SELECT 2 UNION ALL SELECT 3 UNION ALL SELECT 4 UNION ALL SELECT 5 UNION ALL SELECT 6 UNION ALL SELECT 7 UNION ALL SELECT 8 UNION ALL SELECT 9 UNION ALL SELECT 10) numbers
WHERE n <= 255 -- 最多处理 255 个字符的字符串
) seq_table
ON seq <= CHAR_LENGTH(data_value)
) char_table
) char_map
) AS sort_key
FROM test_data
ORDER BY sort_key;
全屏,退出全屏
它没运行起来,我也没太搞清楚原因,但它看起来还是挺酷的吧!
进行比较,生成类似'aabaaa, aabba, abbaa'这样的字符串,它似乎想要将所有数字字符替换为"a",将所有字母字符替换为"b"。
如果它没有问题,我可能会花更多时间来修复它。
11ab1 变成 aabba
111ab1 变成 aaaba
所以按照 MySQL 的排序方式,111ab1 本来就会排在 11ab1 之前,因为 'aaa' 比 'aab' 更靠前。
不错的想法,但是可惜不太对路。
第五次测试:GPT 差一点就成功了!
这让我挺惊讶的。
我之前在别的地方见过这种情况(正如我们所知,GPT只是在重复它之前见过的内容,并不是真正的有创造力),但它的解释更合理!
SELECT
*
FROM
test_data
ORDER BY
CAST(data_value AS UNSIGNED), data_value ASC;
全屏模式 退出全屏
啊哈,差点儿。我还以为这就是答案呢
不过,在像 "Test 1, Test 12, Test 2" 这样的测试中失败了。不过,如果数字在前面,它还是适合用来排序。
轮到我了我试了好几次还是没能得到我想要的,但看了几项技巧后,我现在离答案已经近多了。
挠了挠头,哭了一会儿,我想我找到了解决办法!
这个勉强凑合...
这是我想到的一个点子:
CREATE TABLE test_data (
id INT AUTO_INCREMENT PRIMARY KEY,
data_value VARCHAR(255) NOT NULL,
transformed_column VARCHAR(255) AS (
CASE
WHEN REGEXP_SUBSTR(data_value, '[0-9]+') IS NOT NULL THEN
REGEXP_REPLACE(
data_value,
'[0-9]+',
LPAD(REGEXP_SUBSTR(data_value, '[0-9]+'), 8, '0')
)
ELSE data_value -- 或默认值如 '无数字'
END
) STORED
);
进入全屏模式 退出全屏模式
我们就可以这样查一下。
SELECT
*
FROM
test_data
ORDER BY
transformed_column, data_value;
全屏(点击进入/点击退出)
这几乎得到了我们预料中的结果。
测试 6 结果
数据值 | 转换后的列 |
---|---|
1 test | 00000001 test |
01-02-24 | 00000001-00000001-00000001 数据 |
1test | 00000001test |
2 test | 00000002 test |
2RnSVwq | 00000002RnSVwq |
2test | 00000002test |
3uEKHmHePf | 00000003uEKHmHePf |
4a test | 00000004a test |
完整结果 - 测试6
数据值 | 转换后的列 |
---|---|
1 test | 00000001 test |
01-02-24 日期 | 00000001-00000001-00000001 日期 |
1test | 00000001test |
2 test | 00000002 test |
2RnSVwq | 00000002RnSVwq |
2test | 00000002test |
3uEKHmHePf | 00000003uEKHmHePf |
4a test | 00000004a test |
4b test | 00000004b test |
6bfS | 00000006bfS |
10 test | 00000010 test |
12 test | 00000012 test |
12 test | 00000012 test |
13IUkOxEVl | 00000013IUkOxEVl |
20 test | 00000020 test |
25hWTX | 00000025hWTX |
40-a-1 | 00000040-a-00000040 |
40a | 00000040a |
42-a-1 | 00000042-a-00000042 |
796h-eYWy | 00000796h-eYWy |
833HufIZAS | 00000833HufIZAS |
9244uVCpGa | 00009244uVCpGa |
AB-34Y67846 | AB-34Y67846 |
AwtwQdn09 | AwtwQdn09 |
奶酪和测试 12 | 奶酪和测试 12 |
cIhb42WFNQ | cIhb00000042WFNQ |
dlCSh87811 | dlCSh00087811 |
dnjLlW1 | dnjLlW00000001 |
E5-RMT893Y9 | E00000005-RMT00000005Y00000005 |
EV-489RY3DA | EV-00000489RY00000489DA |
FoClSy4727 | FoClSy00004727 |
GeGIrPM-H86 | GeGIrPM-H00000086 |
gvSV6z | gvSV00000006z |
HOFAp_Yx7920 | HOFAp_Yx00007920 |
kQ33596c | kQ00033596c |
我的 12 个魔法测试 | 我的 12 个魔法测试 |
我的 2020-01-01 数据 2020-01-01 | 我的 2020-01-01 数据 2020-01-01 |
我的 2020-01-01 数据 2020-02-01 | 我的 2020-01-01 数据 2020-02-01 |
我的 2020-01-01 数据 2021-01-01 | 我的 2020-01-01 数据 2021-01-01 |
我的 2020-01-01 数据 2120-01-01 | 我的 2020-01-01 数据 2120-01-01 |
我的 2020-02-01 数据 01-01-01 | 我的 2020-02-01 数据 01-01-01 |
我的 2020-02-01 数据 1-01-01 | 我的 2020-02-01 数据 1-01-01 |
我的 2020-02-01 数据 12-01-01 | 我的 2020-02-01 数据 12-01-01 |
我的 2020-02-01 数据 2-01-01 | 我的 2020-02-01 数据 2-01-01 |
我的 2020-02-01 数据 20-01-01 | 我的 2020-02-01 数据 20-01-01 |
我的 2020-02-01 数据 202-01-01 | 我的 2020-02-01 数据 202-01-01 |
我的 2020-02-01 数据 2020-01-01 | 我的 2020-02-01 数据 2020-01-01 |
我的 2120-01-01 数据 2020-01-01 | 我的 2120-01-01 数据 2020-01-01 |
我的数据 2020-01-01 | 我的数据 2020-01-01 |
我的数据 2020-02-01 | 我的数据 2020-02-01 |
我的魔法 12 测试 | 我的魔法 12 测试 |
我的测试 | 我的测试 |
Pthw068bf | Pthw00000068bf |
RHrIt72402eaLr | RHrIt00072402eaLr |
测试 1 | 测试 1 |
utjtV03Xns | utjtV00000003Xns |
uxWLO039hb | uxWLO00000039hb |
VHCok55901XYVk | VHCok00055901XYVk |
vTg946 | vTg00000946 |
WffSPaBA318 | WffSPaBA00000318 |
wrOae537LGCT | wrOae00000537LGCT |
yDKrkCp7960 | yDKrkCp00007960 |
数据值 | 转换后的列 |
---|---|
2020-02-01 数据 1-01-01 | 2020-02-01 数据 2020-02-01-01-01 |
2020-02-01 数据 12-01-01 | 2020-02-01 数据 2020-02-01-12-01 |
2020-02-01 数据 2-01-01 | 2020-02-01 数据 2020-02-01-02-01 |
就像你看到的那样,不过我觉得这暂时能符合我们的需求。
这是根据我看到的一个LPAD
示例。然而,它存在同样的问题,即它只能处理以数字开头的字符串。
于是我把那个原则应用到了所有的数列。
这里也用了一个生成列,这样读取速度快(如果我们不太关心读取性能,或者更关心写入性能,我们很快就可以把它加到查询里)。
主要的问题是这个方法通过“强行处理”来绕过MySQL将“11”视为小于“2”这一现象,因为MySQL是逐字符比较(这是简化了的解释)。通过将所有数字统一为8位数来避免此问题。
它还将 transformed_column
中的所有数字替换为它找到的第一个数字。据我了解,除此之外,我没找到其他方法可以避免这种行为模式,除此之外,只能通过嵌套大约 20 个语句或使用 coalesce
等功能来避免这种问题。
我不太确定,MySQL 是否应该提供像其他数据库那样的字母数字排序功能?
虽然我们希望事情能够发生,我觉得就这篇文章来说,我还没找到解决这个难题的方法。
但话说回来,我觉得第六次测试的答案比我在外面找到的其他信息更接近正确答案,说不定哪天对谁来说有用呢?
显然,如果你期望的数字长度超过8位数,你可能需要调整LPAD
参数,因为这是一一个限制。
(注:此处“一一个限制”中的“一”多余,应去掉。)
显然,如果你期望的数字长度超过8位数,你可能需要调整LPAD
参数,因为这是 一个 限制。
此外,它也不是完美的,所以除了帮用户轻松找信息,它做不了其他的事。
我认为现在最好的选择可能是把这个问题抛向社区,看看是否有比我聪明的人能把它正确解决!(我可能需要更深入地了解MySQL中的排序知识,才能真正解决这个问题!)
如果有人能解决我遇到的问题,即如果能将所有数字都补足到8位,那么这样效果会更好!(所以“我的数据2020-02-01 2-01-01”会变成“我的数据00002020-00000002-00000001 00000002-00000001-00000001”)。
或许有一个我遗漏的一句话解决方案?(如果有,我保证我只会稍微哭一会儿!)
总之,这是我最好的了,但还是希望能看到更好的东西!
最后终于这里有一个 DB Fiddle(一个在线数据库工具)可以试试
如果你认为你能找到改进的地方,可以看看这里,这里是一个基于生成列版本的DB Fiddle。
https://www.db-fiddle.com/f/o2ohcGVAgHZQg4teg1s9jW/1034
感谢您的阅读,很快见!
共同学习,写下你的评论
评论加载中...
作者其他优质文章