我想确保当用户想要在我的系统(网络应用程序)中注册用户名时,即使不考虑大小写,用户名也是唯一的。因此,如果名为“SuperMan”的用户已经注册,则不得允许其他用户注册为“superman”或“SUPERman”。这必须在数据库级别进行检查。
在我当前的实现中,我执行以下操作:
select count(*) from user where lower(name) = lower(?) for update; -- If the count is greater than 0, abort with an error -- Determine a new ID for the user insert into user (id, name, …) values (?, ?, …);
我不确定“for update”是否会将数据库锁定得足够远,以致其他用户无法在上述两个 SQL 语句之间使用无效名称进行注册。可能这不是 100% 安全的解决方案。不幸的是,我不能在 SQL 中使用唯一键,因为它们只会区分大小写进行比较。
还有其他解决方案吗?为了增加安全性,以下内容如何?
select count(*) from user where lower(name) = lower(?) for update; -- If the count is greater than 0, abort with an error -- Determine a new ID for the user insert into user (id, name, …) values (?, ?, …); -- Now count again select count(*) from user where lower(name) = lower(?); -- If the count is now greater than 1, do the following: delete from user where id = ?; -- Or alternatively roll back the transaction
最佳答案
我这样做的方法是为用户名创建第二列,将其转换为全部大写或全部小写。我在上面放了一个唯一索引。我使用触发器在另一列中生成值,因此代码不必担心它。
想想看,您可以使用基于函数的索引来获得相同的结果:
在用户 (lower(name)) 上创建唯一索引 user_name_ui1
关于sql - 使字符串在数据库中保持不区分大小写的唯一性,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4485221/