我正在实现一个数据库,其中几个表具有字符串数据作为候选键(例如:用户名),并将被相应地编制索引。对于我想要的这些字段:
当有人在这些键上查询表时不区分大小写
以某种方式保留最初编写的案例,以便应用程序可以使用原始案例将数据呈现给用户
我还希望数据库模式尽可能独立于数据库,因为应用程序代码不(或不应该)从属于特定的 RDBMS。
另外值得注意的是,对数据库进行的绝大多数查询将由应用程序代码完成,而不是通过客户端直接访问表。
在实现这一点时,我遇到了很多烦人的问题。一是并非所有 RDBMS 都以相同的方式实现 COLLATE(在这种情况下,区分大小写似乎可以在模式级别进行调整)。另一个问题是排序规则和区分大小写选项可以设置在多个级别(服务器、数据库、表(?)、列),我无法向应用程序保证它将获得什么设置。另一个问题是 COLLATE 本身可能会变得毛茸茸,因为除了区分大小写之外,还有更多内容(例如:unicode 选项)。
为了避免所有这些令人头疼的问题,我正在考虑通过为一个数据存储两列来完全避开这个问题。一列使用原始大小写,另一列被应用层降为小写。
eg:表中的两个字段
user_name = "fredflintstone"(这个唯一索引) orig_name = "FredFlintstone" (只是数据......没有限制)
在我看来,这样做的优点和缺点是:
优点:
没有歧义 - 应用程序代码将管理案例转换,当底层 RDBMS/设置发生变化时,我永远不需要担心单元测试“神秘地”失败。
索引上的搜索将是干净的,并且永远不会因整理功能或调用 LOWER() 或任何东西而减慢(假设这些事情会减慢索引,这似乎是合乎逻辑的)
缺点:
双倍数据需要额外的存储空间
好像有点野蛮
我知道它会起作用,但同时它闻起来不对劲。
这样做是疯狂/毫无意义吗?是否有什么我不知道的东西使区分大小写的问题不像我现在认为的那样棘手?