区分大小写的唯一性和不区分大小写的搜索

时间:2012-01-02 15:17:20

标签: mysql collation

我有一个带有字段的表a使用编码utf8和collat​​ion utf8_unicode_ci:

CREATE TABLE dictionary (
    a varchar(128) NOT NULL
) DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;

对于带有扩展和连接的高效不区分大小写的搜索,需要使用排序规则utf8_unicode_ci。为此,我有索引:

CREATE INDEX a_idx on dictionary(a);

问题:此外,我必须确保字段a的所有存储值都是唯一的,但采用区分大小写方式。 德国的例子:“blühen”和“Blühen”都必须存储在表格中。但是第二次加入“Blühen”是不可能的。

MySQL中是否有内置功能可以兼顾两者?

不幸的是,似乎无法在MySQL 5.1中为索引设置排序规则。

此问题的解决方案包括插入或触发前的唯一性检查。两者都不如使用唯一索引那么优雅。

3 个答案:

答案 0 :(得分:4)

嗯,有两种方法可以做到这一点:

  1. 使用_bin collat​​ion
  2. 将您的数据类型更改为VARBINARY
  3. 案例1:使用_bin collat​​ion

    按如下方式创建表:

    CREATE TABLE `dictionary` (
     `a` VARCHAR(128) CHARACTER SET utf8 COLLATE utf8_bin NOT NULL,
     UNIQUE KEY `idx_un_a` (`a`)
    ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;
    

    请注意:

    1. a
    2. 的数据类型
    3. a
    4. 上的UNIQUE索引

      案例2:使用VARBINARY dataype

      按如下方式创建表:

      CREATE TABLE `dictionary` (
       `a` VARBINARY(128) NOT NULL,
       UNIQUE KEY `idx_uniq_a` (`a`)
      ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;
      

      请注意:

      1. 新数据类型VARBINARY
      2. a
      3. 上的UNIQUE索引

        因此,以上两点都将解决您的目的。也就是说,它们都允许使用“abc”,“Abc”,“ABC”,“aBc”等值,但如果大小写匹配,则不允许再次使用相同的值。

        请注意,提供“_bin”排序规则与使用二进制数据类型不同。所以请随时参考以下链接:

        1. The BINARY and VARBINARY datatypes
        2. The _bin and binary Collations
        3. 我希望以上有所帮助!

答案 1 :(得分:1)

您可以通过添加additinal column' column_lower'来实现此目的。

CREATE TABLE `dictionary` (
  `a` VARCHAR(128) NOT NULL,
  `a_lower` VARCHAR(128) NOT NULL,
  UNIQUE KEY `idx_un_a_lower` (`a_lower`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin;

插入如下:

insert into dictionary set a = x, a_lower = lower(x);

选择现在可以不区分大小写:

select * from dictionary where a_lower like lower('search_term%')

请注意,包含索引的列最多可以存储191个字符。 MySQL可以具有最大767字节长的索引,即767/4(如果使用utf8mb4校对,则unicode最多可占用4个字节)= 191.75 = 191个字符。如果使用utf8排序规则,每个字符最多占用3个字节,则列最多可存储767/3 = 255个字符。

答案 2 :(得分:0)

SELECT * FROM dictionary WHERE a COLLATE utf8_general_ci = 'abc'

试试这个它会起作用..它对我有用。