我将用户名存储在我的数据库中但希望保留用户名框,以便用户可以拥有诸如“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);
这将需要数据库中更多的空间,但最容易查询。
任何见解都将受到赞赏。
这几乎肯定已经得到了回答,所以请指点我以前的帖子,因为我无法找到我想要的东西。
答案 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
的文章