我正在为这类问题寻找MySQL和PostgreSQL解决方案。
假设我有一些title
字段的记录。标题是书籍或电影名称,如“帽子里的猫”和“罗宾汉”。但是虽然标题必须以原始形式显示,但它们应该按照图书馆对它们进行排序的方式进行排序,即通过将任何文章(如“The”或“An”)移动到标题的末尾。
所以“帽子里的猫”就好像它是“帽子里的猫”一样。
设计架构或编写查询的最佳方法是什么,以便这些记录按标题排序,就像库对标题排序一样? (我也希望我知道这种按标题排序的技术术语。)另外,我应该注意哪些性能考虑因素以及应该创建哪些索引?
答案 0 :(得分:4)
为什么不在表格中添加“title_prefix”字段并将所有这些“the”和“a”字符串移到那里?在您订购时,您将使用“标题”字段,当您展示标题时,您可以以任何方式进行连接。
答案 1 :(得分:3)
创建一个自定义函数(sortableTitle,也许?),它将修改以不需要的单词开头的字符串。使用order by sortableTitle(title)
完成查询语句。这将产生额外的CPU成本,但你必须通过基准来知道多少。
您可以创建一个由触发器填充的额外列(sortTitle)。这将占用一些空间,但随后您的服务器将能够按索引对行进行排序。
除了上述内容,您不能(不修改数据库服务器代码)直接创建所需顺序的索引。据我所知,这适用于MySQL和PostgreSQL。
答案 2 :(得分:2)
iTunes通过第二个字段实现了这一点,其中标题以所需的排序格式存储,并对其进行排序而不是标题。听起来好像很便宜,但是当你考虑每次执行一个按标题排序的select语句对每个标题进行字符串操作的性能影响时,每次插入或更新标题时都要对字符串进行操作,它会有道理。
答案 3 :(得分:1)
Select * from TitleTable
Order by
Case when substring(title,0,4) = 'The ' then substring(title, 4, len(title)-4)
when substring(title,0,3) = 'An ' then substring(title, 3, len(title)-3)
when substring(title,0,2) = 'A ' then substring(title, 2, len(title)-2)
else title
end
答案 4 :(得分:1)
我建议您将title
字段拆分为两个字段:mainTitle
和pre
。
添加标题时,检查它是否以“A”,“The”或其他前缀开头,并将其分割(可能带有触发器)到两个字段中。你的桌子看起来像这样:
| pre | mainTitle |
|-----|----------------|
| The | Cat in the Hat |
| A | Space Odyssey |
| | Eyes Wide Shut |
因此,您可以在mainTitle
字段上添加索引并将其用于排序。
如果要显示完整标题,请以两种形式之一连接两个字段。
如果选择这种方式,则必须相应地修改用户在表格中搜索标题的代码。在搜索mainTitle
字段之前,必须以相同的方式拆分给定的标题。
您必须非常非常小心执行拆分的代码(触发器或其他),以便正确捕获某些特殊情况。您不希望显示A = B
或A B C: learn the alphabet
本书并将其排序为= B, A
和B C: learn the alphabet, A