mysql asc_mysql – 在字符串列上使用asc和desc的索引

当我们想要通过asc和desc订购时,我知道一个通​​过查询更快地进行排序的技巧.

对于整数存储否定值.

因此,如果我存储-7,-11,-8,-5,-1,-2,则asc的顺序将给出-11,-8,-7,5,-2,-1,因此实际的行将是按该列排序desc(例如,如果我显示非否定版本).

问题:如何在字符串中使用此技巧?

如何将字符串“否定”或反转,以便该字符串也适用于字符串列?

更新

MySQL无法使用索引进行类型的查询:

ORDER BY col1 ASC col2 DESC

如果我想要下降的列是一个整数,我可以存储否定值并执行以下查询:

ORDER BY col1 ASC col2 ASC

在这种情况下,可以使用索引,实际上由于否定-11,-8,-7,5,-2,-1升序,我将按降序获取值,但是如果删除否定则是降序.

我的问题是我不清楚如何将这种方法应用于字符串列.我可以以某种方式获得字符串的算术值吗?

解决方法:

虽然CREATE INDEX的语法支持将索引定义为升序或降序的选项,但在最常见的两个存储引擎(InnoDB和MyISAM)中,此索引选项是无操作.没有“升序”或“降序”索引,它们只是索引,可以用于任何方向的排序.

但是在你描述的情况下,你有一个多列索引,你想按一列升序排序而另一列降序,这是一个不同的故事.如果列使用索引,则排序顺序必须在两个列的相同方向上.

(并不是说每种方法都必须使用索引.您当然可以运行查询并让它使用filesort对匹配的行进行排序.)

但是您必须使用新的排序规则来存储字符串,并重建索引.该索引仅对反向排序有用.

来自@Cratylus的评论:

整理是将“A”定义为在“B”之前以及所有其他字母顺序.因此,如果您定义一个表示“B”在“A”之前的排序规则,并在列定义中使用该排序规则,那么对该列进行排序或在列上创建索引将采用相反的顺序.

注意:以下内容不会创建正确的排序规则,它只是演示了创建排序规则的步骤.

>编辑/usr/share/mysql/charsets/Index.xml并进行此编辑:

. . . leave other collations alone . . .

Dutch

English

French

German Duden

Italian

Latin

Portuguese

Spanish

>编辑/usr/share/mysql/charsets/latin1.xml并进行此编辑:

. . . leave other collations alone . . .

AE B1 AC A2 A0 9E 9C 8D BE 8B 89 87 85 83 7F 59

73 71 6F 6D 63 61 5F 5D 55 4F 4D 4B 49 47 45 43

97 B1 AC A2 A0 9E 9C 8D BD 8B 89 87 85 83 7F 59

73 71 6F 6D 63 61 5F 5D 55 4F 4D 4B 49 47 45 43

FF FE FD FC FB FA F9 F8 F7 F6 F5 F4 F3 F2 F1 F0

EF EE ED EC EB EA E9 E8 E7 E6 E5 E4 E3 E2 E1 E0

DF DE DD DC DB DA D9 D8 D7 D6 D5 D4 D3 D2 D1 D0

CF CE CD CC CB CA C9 C8 C7 C6 C5 C4 C3 C2 C1 C0

BF BC BB BA B9 AF AA A8 A6 A4 9A 98 95 93 91 8F

81 7D 7B 79 77 75 6B 69 67 65 5B 57 53 51 41 B8

B7 B6 B5 B4 B3 AF AA A8 A6 A4 9A 98 95 93 91 8F

81 7D 7B 79 77 75 6B 69 67 65 5B 57 53 51 41 40

3F 3E 3D 3C 3B 3A 39 38 37 36 35 34 33 32 31 30

2F 2E 2D 2C 2B 2A 29 28 27 26 25 24 23 22 21 20

1F 1E 1D 1C 1B 1A 19 18 17 16 15 14 13 12 11 10

0F 0E 0D 0C 0B 0A 09 08 07 06 05 04 03 02 01 00

. . .

>重启mysqld.

>确认您有新的排序规则:

mysql> SHOW COLLATION LIKE 'latin1%';

+---------------------+---------+-----+---------+----------+---------+

| Collation | Charset | Id | Default | Compiled | Sortlen |

+---------------------+---------+-----+---------+----------+---------+

. . .

| latin1_general_ci | latin1 | 48 | | Yes | 1 |

| latin1_general_cs | latin1 | 49 | | Yes | 1 |

| latin1_spanish_ci | latin1 | 94 | | Yes | 1 |

| latin1_reverse_ci | latin1 | 251 | | | 0 |

. . .

>创建一个表并用一些文本填充它:

mysql> CREATE TABLE foo (

id INT AUTO_INCREMENT PRIMARY KEY,

t VARCHAR(60) COLLATE latin1_reverse_ci,

x DATE,

KEY(t)

);

mysql> INSERT INTO foo (t) VALUES ('Harry'), ('Ron'), ('Hermione');

>证明排序顺序与您认为应该是的相反:

mysql> SELECT * FROM foo ORDER BY t ASC;

+----+----------+------+

| id | t | x |

+----+----------+------+

| 2 | Ron | NULL |

| 3 | Hermione | NULL |

| 1 | Harry | NULL |

+----+----------+------+

>确认它不使用filesort:

mysql> EXPLAIN SELECT * FROM foo WHERE t LIKE 'H%' ORDER BY t\G

*************************** 1. row ***************************

id: 1

select_type: SIMPLE

table: foo

partitions: NULL

type: range

possible_keys: t

key: t

key_len: 63

ref: NULL

rows: 2

filtered: 100.00

Extra: Using index condition

我不得不在行上添加条件,因为否则它会认为它将读取表中的所有行,并且它执行了表扫描和文件输出.

来自@ypercube的评论:

它不会像REVERSE()那样反转给定字符串中字符的顺序,它会在比较两个字符串时反转哪些字符被认为大于或小于彼此.所以不,CHAR填充空格无关紧要,它们仍然在两个字符串的末尾.

示例(这次没有索引,仅使用顺序):

mysql> create table t (c char(20) collate latin1_reverse_ci);

mysql> insert into t values ('A'), ('B'), ('C');

mysql> select * from t order by c;

+------+

| c |

+------+

| C |

| B |

| A |

+------+

编辑:不,@ yycube是正确的,这对CHAR不起作用,因为空格字符位于错误的位置,当我简单地通过将所有字节按相反的顺序重新排序来重新排序整理.这不是设计校对的正确方法.

所以这个答案应该作为创建整理的机制的演示,而不是作为逆转字母顺序的正确整理.

标签:mysql,string,index,order-by

来源: https://codeday.me/bug/20190806/1597399.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值