您如何向用户公开区分大小写?
Posted
技术标签:
【中文标题】您如何向用户公开区分大小写?【英文标题】:How do you expose case sensitivity to users? 【发布时间】:2009-03-27 17:09:07 【问题描述】:好的,我明白了。 PostgreSQL 中的数据区分大小写。而且我知道我可以使用 LOWER() 使我的查询不区分大小写。我知道在 PostgreSQL 的未来版本中甚至可能会有一个“citext”类型。我的问题是,今天,您在设计用户界面时如何处理这个问题?我正在特别考虑唯一性约束。
假设我的应用程序的数据看起来或多或少像一个文件系统(想想 Google Docs,除了 Google Docs 实际上允许重复名称 :-P)。如果情况不同,我怎样才能让我们的用户更容易理解他们可以有重复名称的事实?我认为对大多数人来说,这只是看起来奇怪。
让我们先发制人地解决一些问题:
我来自 Windows 背景,所以我的“想法”是不区分大小写的。我现在主要使用 Mac OS X,(你知道吗?)是also case-insensitive。我们的大多数用户都属于这两个相同的类别。
我是 PostgreSQL 新手。我的大部分经验是使用 mysql,但我也使用过 Oracle,它像 PostgreSQL 一样区分大小写。我当时也对这个问题想了很多,但最终还是让一切保持原样,让我们的用户自己解决。
我对技术解决方案(即解决此问题)和 UI 设计解决方案(即帮助用户对系统感到满意)都感兴趣。
总结:
在设计用户界面时如何处理不区分大小写的问题? 如果情况不同,我怎样才能让我们的用户更容易理解他们可以有重复的名字这一事实?编辑:我感谢迄今为止的所有反馈。但是,如果答案是“如果大小写不同,则不允许重复名称”,那么 如何在 PostgreSQL 中实现它? 我考虑过的一种解决方案是静默维护一个单独的列,该列始终是数据的 LOWER() 版本,并将唯一约束置于该列上。
【问题讨论】:
【参考方案1】:您现在可以使用citext 数据类型。虽然它可能比未来的内置版本有更多的限制。
编辑至于unique constraint:
CREATE UNIQUE INDEX
example_unique_idx
ON
example_table ((LOWER(case_insensitive_field)));
【讨论】:
谢谢,我会更详细地研究这个。 也感谢 INDEX ON LOWER() 的跟进。我把这个归功于 depesz,因为他首先提出了这个建议。【参考方案2】:也许您不知道这一事实,但您可以在函数上创建唯一索引。甚至使它们成为部分索引。
例如:
create unique index some_name on users (lower(username));
无论大小写如何,都会使用户名唯一。
您还可以进一步移动 1 步(例如,这在您的环境中可能不是一个好主意),以便仅对活跃用户强制执行唯一性:
create unique index some_name on users (lower(username)) where is_active = true;
另外,请注意,对于不区分大小写的搜索,您不应使用 ILIKE。问题是 ILIKE 不能(出于某种我不太了解的原因)使用索引。
因此,虽然可以使用功能索引来加快查询速度:
select * from users where lower(username) = '...'
或
select * from users where lower(username) like '...'
(至少对于“...”的某些值)
index 不会被使用(据我所知):
select * from users where username ilike '...'
【讨论】:
非常真实和有用,但请记住该函数有一些限制,以便在索引中使用它postgresql.org/docs/current/interactive/xfunc-volatility.html 这非常有效。谢谢! @bortzmeyer,我怎么知道 LOWER() 是否设置为 IMMUTABLE?使用“\df+ LOWER”似乎没有显示出来。 回答我自己的评论:LOWER() 绝对是 IMMUTABLE,否则 PostgreSQL 不允许在索引中使用它。 Matt - 从 pg_proc 中选择 provolatile where proname = '...';您可以在这里查看这些值的含义:postgresql.org/docs/current/interactive/catalog-pg-proc.html 更好:在 PostgreSQL 8.3 中,"\df+" 输出包括它:-)【参考方案3】: 在设计用户界面时如何处理不区分大小写的问题?在不区分大小写的情况下,您不允许用户创建具有相同名称的对象,除非您有非常具体的目标受众已经“了解”。普通计算机用户 Emily Executive 不会理解为什么她有两个“季度报告”和“季度报告”文件 - 除非应用程序或使用场景需要区分大小写,否则只会损害产品的可用性。
换句话说,除非是要求,否则假定不区分大小写。
如果情况不同,我怎样才能让我们的用户更容易理解他们可以有重复的名字这一事实?如果您必须这样做,请强制使用一种字体,使名称明显不同。提供一个打开和关闭警告的用户选项框,“此文件的名称与其他文件类似,您确定要将其另存为此名称吗?”它在开始时自动打开(选择退出,而不是选择接受一般警告)
-亚当
【讨论】:
【参考方案4】:区分大小写迫使您的用户处理计算机世界中的问题。
请勿区分大小写!
你刚刚告诉我 Windows 和 Mac 都不区分大小写,它们是为了减少用户的混淆。
您想要处理的方式是,您保留用户选择的大小写(用户输入是神圣的),但是当您进行搜索或比较时,它总是不区分大小写。
【讨论】:
如果用户输入被吓到了,可能是 UI 中的某些东西吓到了用户。 对此要小心,我已经看到那些拥有区分大小写数据但不区分大小写的搜索和查询的人的错误。这导致游戏有 2 个用户,其中一个“重影”另一个并获得他们的利益。 感谢您的建议。但是,进行搜索或比较并不是问题(我可以使用 LOWER() 和/或 ILIKE)。我更倾向于考虑独特的约束。 区分大小写取决于区域设置。 Win/Mac 可以轻松做到这一点,因为它们是具有一种语言环境的桌面系统:用户的。在网络上,这是一个更难的问题。您的系统区域设置和用户的区域设置不一定相同。 在现实世界中,情况也很重要。你想让你的名字以大写开头吗?因此,向最终用户解释应该不会太难。【参考方案5】:实现不区分大小写的另一种技术解决方案是 create your own type 内置折叠到小写。这样,用户(和应用程序)就不会出错。
【讨论】:
以上是关于您如何向用户公开区分大小写?的主要内容,如果未能解决你的问题,请参考以下文章
如何在 SQL 2000/2005 中执行区分大小写的搜索和替换?