【Mysql】mysql使用触发器创建hash索引
概述
若设计的数据表中,包含较长的字段,比如URL(通常都会比较长),查询时需要根据该字段进行过滤:
select * from table_xxx where url = 'xxxxxxx';
为了提高查询性能,通常需要对字段做索引,在Innodb中,如果使用URL做索引,将会导致:
- 索引存储占用空间大;
- 索引查询比较性能差;
为了解决上面的问题,有如下解决方案:
- 对URL做hash,hash作为记录的一个字段,查询时,使用该hash值做过滤;
- 使用触发器对更新和插入的数据做hash,不需要手动计算hash;
- hash碰撞:如果表中记录条数很多,则应该选择合适的hash,避免大量的hash碰撞;
- hash碰撞: 查询时,除了使用hash进行过滤,还需要使用url进行过滤;
创建数据表 + 触发器进行hash运算
假设需要使用如下查询:
select id from table where url='http://xxx.xxx.com/xxxxxxxxxxxxxxxxxxxx';
分析:
- URL通常比较长,如果在URL上创建索引,无论是存储和检索,效率都会非常低;
- 可以对URL做Hash,在该HASH值进行索引,这样的查询性能会非常高;
** 使用触发器创建表和hash索引**
CREATE TABLE `url_hash` (
`id` int(10) unsigned NOT NULL AUTO_INCREMENT,
`url` varchar(255) COLLATE utf8_bin NOT NULL,
`url_crc` int(10) unsigned NOT NULL DEFAULT '0',
PRIMARY KEY (`id`),
KEY `url_crc_idx` (`url_crc`)
) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=utf8 COLLATE=utf8_bin;
DELIMITER //
CREATE TRIGGER `urlhash_crc_insert` BEFORE INSERT ON `url_hash` FOR EACH ROW
set NEW.url_crc=crc32(NEW.url);
END;
//
CREATE TRIGGER `urlhash_crc_update` BEFORE UPDATE ON `url_hash` FOR EACH ROW
set NEW.url_crc=crc32(NEW.url);
END;
//
DELIMITER ;
说明:
- DELIMITER :先修改一下语句分隔符,这样就可以在触发器中使用分号;
- 在insert和update前设置触发器,对每一条记录的URL做crc32 Hash运算;
验证
插入数据
insert into url_hash(url) values('http://www.baidu.com');
insert into url_hash(url) values('http://www.cnblogs.com/ssslinppp');
*结果
select * from url_hash;
+----+----------------------------------+------------+
| id | url | url_crc |
+----+----------------------------------+------------+
| 1 | http://www.baidu.com | 3500265894 |
| 2 | http://www.cnblogs.com/ssslinppp | 3363624100 |
+----+----------------------------------+------------+
如何查询
select * from url_hash where url='http://www.baidu.com' and url_crc=crc32('http://www.baidu.com');
+----+----------------------+------------+
| id | url | url_crc |
+----+----------------------+------------+
| 1 | http://www.baidu.com | 3500265894 |
+----+----------------------+------------+
注意点:
- 查询时,必须将url作为过滤条件,因为可以产生hash碰撞;
选择合适的Hash计算方式
不要使用sha1()和md5作为hash函数
因为上面两个计算的hash值通常都会特别长,浪费空间,比较时也会更慢;
数据表非常大,不建议使用crc32()进行hash计算
crc32()返回的是32位的整数,因为所谓的生日悖论,当数据表非常大时,将会产生大量的hash碰撞;
当条数>9.3w时,碰撞的概率:1%;
自定义hash函数
返回一个64位的整数(不是字符串)就可以;
比如:fnv64()函数作为hash函数(改函数默认不包含,可以移植进来);
【Mysql】mysql使用触发器创建hash索引的更多相关文章
- 【转载】Mysql中的Btree与Hash索引比较
转载地址:http://www.jb51.net/article/62533.htm 这篇文章主要介绍了Mysql中的Btree与Hash索引比较,本文起讲解了B-Tree 索引特征.Hash 索引特 ...
- 警惕 InnoDB 和 MyISAM 创建 Hash 索引陷阱
MySql 最经常使用存储引擎 InnoDB 和 MyISAM 都不支持 Hash 索引,它们默认的索引都是 B-Tree.可是假设你在创建索引的时候定义其类型为 Hash,MySql 并不会报错,并 ...
- mysql触发器与hash索引
url查询哈希值的维护 触发器 2.1 创建表 pseudohash. 2.2 创建触发器,当对表进行插入和更新时,触发 触发器 delimiter |create trigger pseudohas ...
- mysql InnoDB引擎是否支持hash索引
看一下mysql官方文档:https://dev.mysql.com/doc/refman/5.7/en/create-index.html , 从上面的图中可以得知,mysql 是支持hash索引的 ...
- Mysql中的Btree与Hash索引
B-Tree 索引特征 B-Tree索引可以被用在像=,>,>=,<,<=和BETWEEN这些比较操作符上.而且还可以用于LIKE操作符,只要它的查询条件是一个不以通配符开头的 ...
- MySQL的btree索引和hash索引的区别
Hash 索引结构的特殊性,其检索效率非常高,索引的检索可以一次定位,不像B-Tree 索引需要从根节点到枝节点,最后才能访问到页节点这样多次的IO访问,所以 Hash 索引的查询效率要远高于 B-T ...
- MySQL索引类型 btree索引和hash索引的区别
来源一 Hash 索引结构的特殊性,其检索效率非常高,索引的检索可以一次定位,不像B-Tree 索引需要从根节点到枝节点,最后才能访问到页节点这样多次的IO访问,所以 Hash 索引的查询效率要远高于 ...
- mysql索引hash索引和b-tree索引的区别
Hash 索引结构的特殊性,其检索效率非常高,索引的检索可以一次定位,不像B-Tree 索引需要从根节点到枝节点,最后才能访问到页节点这样多次的IO访问,所以 Hash 索引的查询效率要远高于 B-T ...
- MySQL的btree索引和hash索引的区别 (转)
Hash 索引结构的特殊性,其检索效率非常高,索引的检索可以一次定位,不像B-Tree 索引需要从根节点到枝节点,最后才能访问到页节点这样多次的IO访问,所以 Hash 索引的查询效率要远高于 B-T ...
随机推荐
- [LeetCode&Python] Problem 598. Range Addition II
Given an m * n matrix M initialized with all 0's and several update operations. Operations are repre ...
- seo:网站地图提交
对于SEO,网站地图的好处就更多了: 1.为搜索引擎蜘蛛提供可以浏览整个网站的链接简单的体现出网站的整体框架出来给搜索引擎看: 2.为搜索引擎蜘蛛提供一些链接,指向动态页面或者采用其他方法比较难以到达 ...
- python---map 用法 [转载]
map()函数 map()是 Python 内置的高阶函数,它接收一个函数 f 和一个 list,并通过把函数 f 依次作用在 list 的每个元素上,得到一个新的 list 并返回. 1.当seq只 ...
- PHP5和PHP7的安装、PHP和apache的整合!
1.PHP5的安装: 下载: wget -c http://cn2.php.net/distributions/php-5.6.36.tar.gz (php5) wget -c http://cn2 ...
- PTA——天平找小球
PTA 7-22 用天平找小球 #include<stdio.h> int main() { int a,b,c; scanf("%d%d%d",&a,& ...
- java 编译 运行 及 引用外部 jar 包的方法
1. 环境变量配置 JAVA_HOMEC:\Program Files\Java\jdk1.8.0_121; PATH%PATH%;C:\Java\jdk1.6.0_30\bin; CLASSPATH ...
- mysql(mariadb)新建用户及用户授权管理
仅新建一个newuser用户 方法一: MariaDB [(none)]> create user newuser@localhost identified by '123456'; Query ...
- C语言指针入门
指针指包含地址 声明指针: int num:声明整数 int *num:声明指针,下面的声明也是等价的,空格的使用指示个人爱好 int* num; int * num; int *num; in ...
- lch 儿童围棋课堂 启蒙篇 (李昌镐 著)
第1章 了解围棋 第2章 无气不活 棋子的"气"第3章 有目数才能赢空第4章 常用术语第5章 吃子第6章 死活:眼第7章 死活:典型棋形第8章 布局:术语篇 第1章 了解围棋 (已 ...
- oracle故障解决
修改了字符集,修改错了,然后不能启动 alter system set nls_language='AMERICA'; shutdown immediate; startup 报错 [oracle@o ...