存档

‘数据库’ 分类的存档
页: 1 2 3 4 5 6 7 后页

讨论一下CRC32的碰撞

2009年6月4日

数据库的索引字段的size真是寸土寸金,也是兵家必争之地,我尽力将这些字段的size降到最低,所以想了很多办法,包括对一些字符串类的字段取hash然后再存储。但是这样会担心有碰撞的情况发生,也就是说两个字符串本来不一样,但hash计算的结果却一样了,CRC32的计算结果是一个32位整数,理论上说,碰撞的几率大概是四十亿分之一,但我对近200万的邮件地址进行了计算,发现很不乐观:发现了大概800个发生碰撞的邮件地址,以下是部分计算结果,为了保护用户隐私,邮件地址部分做了处理:

| 12670487 | li**an15333838900@163.com |
| 12670487 | sh**lyzyh@163.net |
| 44119406 | lx**at326@163.com |
| 44119406 | sh**leyfeng305@live.cn |
| 55678026 | xi**eng@9010sina.com |
| 55678026 | zh**gtong0508@yahoo.com.cn |
| 87492793 | lu**811123@sina.com.cn |
| 87492793 | wo**203@126.com |
| 104224050 | lr**72310@sina.com |
| 104224050 | xx**dy@sina.com |
| 111133190 | wa**ingalice@163.com |
| 111133190 | zh**grongrong05624@163.com |
| 121282991 | sz**lb@163.com |
| 121282991 | zh**gpengpeng1991@163.com |
| 122865341 | wr**wrln@126.com |
| 122865341 | zk**979@126.com |
| 153868011 | li**ng7510@163.com |
| 153868011 | sc**u@163.com |
| 158081872 | qq**46904866.com |
| 158081872 | ti**r1009@sina.com |
| 173541473 | ly**y@hotmail.com |
| 173541473 | wa**.ok@163.com |
| 179173510 | zo**zhiyong@163.com |
| 179173510 | zp**99077@126.com |
| 186547905 | li**eqiao0408@sina.com |
| 186547905 | mo**cashu452@gmail.com |
| 195555720 | li**izhi1991@sina.com |
| 195555720 | ta**ao584201314@sina.com |
| 198793857 | qu**ng880521@126.com |
| 198793857 | sm**5201314@yahoo.cn |
| 201351361 | pi**n_2000@163.com |
| 201351361 | xi**mao9521@hotmail.com |
| 206841534 | qi**nianwenzhai3@sina.com |
| 206841534 | xh**72@163.com |

看来CRC32还是不能做这个用,如果用MD5的计算结果来保存,又显得很大了,MD5计算出来是128位的整数,占用16个字节。
呵呵,后来想想,还是用MD5的一半吧,占用8个字节,估计还是可以的,稍后再做实验。

mengguang 互联网, 数据库, 系统

说说一个数据库的查询方法

2009年6月2日

最近做了博客关注系统的方案设计,主要的数据表有两个:
数据内容表:

CREATE TABLE `story` (
`id` int(10) unsigned NOT NULL AUTO_INCREMENT,
`uid` int(10) unsigned NOT NULL,
`type` tinyint(3) unsigned NOT NULL,
`time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
`data` varbinary(8192) DEFAULT NULL,
PRIMARY KEY (`id`),
KEY `i_ut` (`uid`,`type`,`time`)
) ENGINE=InnoDB;

以及关注关系表:

CREATE TABLE `attention` (
`uid` int(10) unsigned NOT NULL,
`aid` int(10) unsigned NOT NULL,
`time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
PRIMARY KEY (`uid`,`aid`),
KEY `i_a` (`aid`)
) ENGINE=InnoDB;

我们的要查询出uid为1001的用户A关注的所有人最近发表的内容,结果集大概在10000条,我们只取前20条。
简单直接的查询方法可以是:

select id,data from story,attention
where story.uid=attention.aid and attention.uid=1001 order by time desc,id desc limit 20;

但是这个查询语句效率很低,换用一种貌似比较复杂的查询:

select story.* from
story,
(select id from story,attention
where story.uid=attention.aid and attention.uid=1001 order by time desc,id desc
) relation
where story.id=relation.id limit 20;

这个查询效率就很好了,通过对比发现,至少比上一个查询快几十倍。

我认为这样的差异主要取决于数据库中“查询优化”的实现,可能MySQL在这方面做的有限,需要我们精确的告诉他一个比较优化的查询方案。

mengguang 互联网, 数据库, 测试, 算法

页: 1 2 3 4 5 6 7 后页
页: 1 2 3 4 5 6 7 后页