ygo*_*goe 2 sql database unique case-insensitive
我想确保当用户想要在我的系统(Web 应用程序)中注册用户名时,即使不考虑大小写,用户名也是唯一的。因此,如果名为“SuperMan”的用户已经注册,则不得允许其他用户注册为“superman”或“SUPERman”。必须在数据库级别检查这一点。
\n\n在我当前的实现中,我执行以下操作:
\n\n\nselect count(*) from user where lower(name) = lower(?) for update;\n-- 如果计数大于 0,则错误中止\n-- 确定用户的新 ID\n插入转换为用户 (id, name, \xe2\x80\xa6) 值 (?, ?, \xe2\x80\xa6);\n\n\n
我不确定“for update”是否会将数据库锁定得足够远,以便其他用户无法使用上述两个 SQL 语句之间的无效名称进行注册。可能这不是 100% 安全的解决方案。不幸的是我不能在 SQL 中使用唯一键,因为它们只会区分大小写进行比较。
\n\n还有其他解决方案吗?为了增加更多的安全性,下面的怎么样?
\n\n\nselect count(*) from user where lower(name) = lower(?) for update;\n-- 如果计数大于 0,则错误中止\n-- 确定用户的新 ID\n插入进入用户 (id, name, \xe2\x80\xa6) 值 (?, ?, \xe2\x80\xa6);\n-- 现在再次计数\n从用户中选择 count(*),其中 lower(name) = lower (?);\n-- 如果计数现在大于 1,请执行以下操作:\n从 id = ? 的用户中删除;\n-- 或者回滚事务\n\n
我这样做的方法是为用户名创建第二列,将其转换为全部大写或全部小写。我在上面放了一个唯一的索引。我使用触发器来生成另一列中的值,因此代码不必担心它。
想想看,您可以使用基于函数的索引来获得相同的结果:
创建唯一索引 user_name_ui1 ON user (lower(name))