IgnoreCase与ToUpper / ToLower数据库查询

时间:2018-04-14 17:04:41

标签: c# case-sensitive toupper tolower

我将用户名存储在我的数据库中但希望保留用户名框,以便用户可以拥有诸如“FooBAR”之类的用户名。
我也希望用户名是唯一的(无论大小写) - “BaR”会导致“bar”不可用。

我看到三种方法:

首先,我可以这样查询我的Users表:

bool usernameAvailable = !_context.Users.Any(u => String.Equals(u.Username, username, StringComparison.OrdinalIgnoreCase));

其次,我可以将两个用户名转换为大写或小写,如下所示:

username = username.ToUpper();
bool usernameAvailable = !_context.Users.Any(u => u.Username.ToUpper() == username);

第三,我可以在我的表中创建第二列,用于存储用户名的大写/小写版本:

username = username.ToUpper();
bool usernameAvailable = !_context.Users.Any(u => u.UsernameUpper == username);

这将需要数据库中更多的空间,但最容易查询。

任何见解都将受到赞赏。

这几乎肯定已经得到了回答,所以请指点我以前的帖子,因为我无法找到我想要的东西。

2 个答案:

答案 0 :(得分:2)

两者都不是一个好选择。此问题非常适合数据库端的简单UNIQUE INDEX,以及用户名列中不区分大小写的COLLATION。因此,客户端只需要进行简单的相等检查,数据库将使用索引来查找是否存在匹配的名称,包括不区分大小写的检查(如果需要)

当您添加新用户(以检查重复项)以及用户尝试登录时(因此您检查该帐户是否存在)时,请考虑您需要进行此类检查。在这两种情况下,索引都可以确保用户名所需的唯一性并加快查询速度。

对于SQLite的特殊情况,可以像这样创建一个不区分大小写的唯一索引:

CREATE TABLE users (
    UserName TEXT
    /*Other columns go here*/
    UNIQUE (UserName COLLATE NOCASE)
)

除了加快检索速度之外,这还会阻止添加两个仅在大小写上不同的用户名。在客户端,只是不要打扰套管。当用户登录时,只需进行正常比较,即使DB只是在外壳上有所不同,DB也会匹配它们。对于注册,请立即执行INSERT,如果存在套管差异,数据库将会爆炸并拒绝它,您可以向用户显示“已用户名”消息。

另请看这篇文章(从我的基本想法出发):https://stackoverflow.com/a/20914992/2557263

答案 1 :(得分:1)

这取决于你的优先级是什么,如果你的应用程序速度快或者它应该使用更少的数据库空间,我认为时间差在这里是可以忽略的,你应该使用第一种方法。

这是关于维基百科关于这种困境https://en.wikipedia.org/wiki/Space%E2%80%93time_tradeoff

的文章