0

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

我看到了三种方法:

首先,我可以像这样查询我的用户表:

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);

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

任何见解将不胜感激。

几乎可以肯定,之前已经回答了这个问题,所以请指出我之前任何帖子的方向,因为我无法找到我正在寻找的内容。

4

2 回答 2

2

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

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

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

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

除了加快检索速度之外,这将防止添加两个仅大小写不同的用户名。在客户端,只需不要担心套管。当用户登录时,只要做一个正常的比较,即使只是大小写不同,数据库也会匹配他们。对于注册,请INSERT立即进行,如果存在大小写差异,数据库将炸毁并拒绝它,您可以从中向用户显示“用户名已被占用”消息。

还请看这篇文章(我从那里得到了基本的想法):https ://stackoverflow.com/a/20914992/2557263

于 2018-04-14T17:33:22.833 回答
1

这取决于您的优先级是什么,您的应用程序应该快速还是使用较少的数据库空间,我认为这里的时差可以忽略不计,您应该使用第一种方法。

这是一篇关于这个困境的维基百科文章https://en.wikipedia.org/wiki/Space%E2%80%93time_tradeoff

于 2018-04-14T17:08:32.330 回答