在mysql中索引email列的正确方法

oknrviil  于 2021-06-18  发布在  Mysql
关注(0)|答案(2)|浏览(292)

所以我在做一个互联网服务,在我的数据库里有一个users表。我想索引电子邮件列,但我遇到了索引不同长度的字符串的问题。
所以我想到了一个解决方案,我创建了另一个int类型的列,在存储用户的记录之前,我将他/她的电子邮件转换为电子邮件字符的ascii值之和。我只是在知道过去没有人用过同一封邮件的情况下才创建总和,所以这个字符串不可能是相同的。
但我猜这个数字还可以和其他记录相匹配。我想知道不同邮件的总数相同的可能性有多大。
如果这样做的话,我可以很容易地索引一个索引列。
下面是我用来将电子邮件字符串转换为int的算法。

String email="testing@test.com"; // Allowed characters: 0-9 A-B a-b + - . _

    int sum=0;

    for(int i=0;i<email.length();i++){
        int ch=(int)email.charAt(i);
        if(ch>47 && ch<58){
            sum+=ch;
        }else if(ch>96 && ch<123){
            sum+=ch;
        }else if(ch>64 && ch<91){
            sum+=ch;
        }else if(ch==43 || ch==45 || ch==46 || ch==95 || ch==64){
            sum+=ch;
        }else{
            sum=0;
            break;
        }
    }

    System.out.println(sum);
5fjcxozz

5fjcxozz1#

假设我们要索引一个电子邮件地址,以确保没有重复的电子邮件地址,因此用户,比你不能使用散列或总和,因为你会有一个冲突的时候。
即使这不太可能,但并不意味着它不可能发生。当这种情况发生时,没有人知道软件为什么不能工作,因为“冲突用户”或者更糟的是,用户可以接管一个帐户。
这就是为什么,我强烈建议在电子邮件地址上放置一个数据库索引,不管怎样。
这很简单,在所有情况下都是独立的。
创建表将避免重复,并且易于实现(关键字:“unique key”):

CREATE TABLE IF NOT EXISTS `test` (
  `email_address` varchar(250) COLLATE latin1_german2_ci NOT NULL,
  UNIQUE KEY `email_address` (`email_address`)
) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_german2_ci;

测试记录是否已经存在也很容易:

SELECT * FROM `test` WHERE email_address = "abc@google.com"

根据fyrye的评论,使用我选择的排序规则(以“ci”结尾,不区分大小写)可以存储区分大小写的内容。但会避免插入不同大小写(上/下)的重复电子邮件地址。
示例:该表已包含电子邮件地址为“”的记录d@mysql.com“,那么

INSERT INTO `db1080787-1`.`test` (
`email_address`
)
VALUES (
'abCd@mysql.com'
)

将导致


# 1062 - Duplicate entry 'abCd@mysql.com' for key 'email_address
i2loujxw

i2loujxw2#

我不认为索引电子邮件字段本身有问题。它甚至可能是一个部分索引,大小为10或接近于此。
ascii字符的总和将导致很多很多的冲突。最好对电子邮件进行散列,并将散列存储为二进制甚至int。

相关问题