读Mysql索引

最近一直在忙,只有晚上才有时间抽空看《高性能MYSQL》看完后收获挺多。

下面主要就两个方面进行探讨

  1. innodb 和 MYISAM 引擎的区别
  2. B-tree 和 哈希索引的区别

INNODBy引擎和B-TREE存储

之前一问innodb有什么特别?一说支持事务,支持乐观锁(行级锁),写入比查询快。然后就没了

这不能怪我,主要是我之前读书少,之前的状态就是:读书少,想的多(这是很多应届生通病,我正视)

上面的说的innodb的三个特点,我现在只信服两个,因为自从mysql5.0以后,innodb的读写速度差距已经不是那么大了。

因为这个innodb的存储引擎有关系。B-tree存储。

  1. B-TREE存储引擎对索引的是顺序存储。
  2. B-TREE的索引会包含被索引的列的数据(看懂到这个我瞬间明白了,select * from tablename 为会被不建议了,因为这样会使用不到索引覆盖(之前听得没听过的))

MYISAM引擎

之前一说:myisam引擎,之前的理解是:读的数据快,但不支持事务,支持悲观锁(表锁)

现在的理解是 Myisamz支持全文索引(是一种关键字提取),在没有where的条件下select count(*)速度块,因为它有一个AUTO_INCREMENT

myisam的存储方式是三个文件,这三个文件是跨平台的。如果存储在CD-ROM这类只读的介质上面,而且MYISAM支持压缩。它就有,空间小,速度快的特点。有这个特性,它立足MYSQL众多引擎中的一员是完全有地位的。

说到最后:使用什么引擎或者建立什么类型的索引都是看应用场景。在我现在的工作中80%的场景都是innodb。

但如果可以容忍数据错误,或者对数据的正确性不是很强烈的要求。那么myisam也是不错的选择。

在说说哈希索引:

哈希索引是顺序存储的,而哈希索引的存储比较紧凑,所有查找会比较快速。(这里只有memory引擎是用的哈希索引,mysql的临时表都是用的这个引擎,如果临时表太大,临时表就没被写到硬盘上,那时的引擎是MYISAM)

基于这个原因,索引插入的开销比较大,需要维护哈希表。这就是为什么读越快于写了。

最后在说两句:

然后再说一个,之前一直觉得很高大的上的东西,就是读写分离

如果做到读写分离,我之后会写一个博文专门说实现过程。这里先说原理:MYSQL的主从复制

MYSQL5.0以后支持了二进制同步。这样,就做一个数据库做主库专门用来写数据,然后另一个数据库做从库专门用来查数据。

SQL虚表–视图

很多人在做网站的时候,用到过连表查询。在关系型数据库中,根据3NF的要求,数据要尽量的分开,因为原子性。

但在多表,多数据连接的时候,就会出现一个问题,查询速度直线下降。1s-2s还是可以接受,但10s我真接受不了。

今天介绍一个方法对付多表联查速度过慢的情况的解决方法–建立视图

视图是虚拟的表,是不存在的,在PHPmyadmin里面,你可以在数据库里面看到你建立的视图。

视图图片

视图图片

建立视图很简单一行SQL代码

[php]
create view [V_name] as (select);
[/php]
上面就是说了一个公式,看不懂没关系,我下面会接着说
[php]
create view v_table as select * from dwz_tong
[/php]

继续阅读

MYSQL操作入门

今天有一哥们问我关于数据库的问题,他说他百度了N久也百度不出个答案。

其实他不知道,有一种东西叫工具书,每个类型的数据都相应的工具书,你可以理解为指导手册,今天我先推荐这个MYSQL的手册。跟PHP的手册是一样的。

MYSQL入门手册

MYSQL入门手册

这里我随便说说,MYSQL中最常用的也是功能很强大的一个函数alter,这里介绍这个函数几个特别常用的功能 继续阅读

MySQL优化之索引的应用

(0)什么叫索引

说到索引,很多人都不知道索引是什么东西?有什么用?好,我用一个很简单的例子说明,比如说:“我们去图书馆找书,是直接快?还是现查目录快?索引就是充当数据目录的角色”。但方法都是有利有弊,索引在方便你查询的时候,也要牺牲磁盘的空间为代价。

MySQL索引类型包括:

(1)普通索引

这是最基本的索引,它没有任何限制。它有以下几种创建方式:

◆创建索引

[php]

CREATE INDEX indexName ON mytable(username(length));

//如果是CHAR,VARCHAR类型,length可以小于字段实际长度;如果是BLOB和TEXT类型,必须指定 length,下同。

[/php]

◆修改表结构

[php]

ALTER mytable ADD INDEX [indexName] ON (username(length));  //创建表的时候直接指定

CREATE TABLE mytable(   ID INT NOT NULL,    username VARCHAR(16) NOT NULL,   INDEX [indexName] (username(length))   );  //删除索引的语法:

DROP INDEX [indexName] ON mytable;

[/php]

继续阅读

thinkPHP远程抓取数据批量存入数据库

今天做了一个抓取一组数据,批量存入数据库的实例。

开始的想法:

把数据抓过来,再循环存入数据库中,但发现一个问题,有时候远程页面数据更新了,这样可以要增加新的数据,也可以要删除不要数据,还有可以只更新。

   针对这三种情况分别做了下面的设计(下面只是几个核心的对象,不是完整的代码,如果需要完整代码请留言)

[php]

public function save_array($array)
{
//获取数组中数据的条数
$tmp_array = array();
$tmp_array_2 = array(); //数据存储数组
$oj = M("oj_question");
$sql_url = $oj->getField(‘id,url’); //数组的键名是ID,值是URL,这样下面的操作就方便了
$sql_url_num = count($sql_url);
$num = count($array);
if($sql_url_num > $num)
{
$this->delete_question($num,$sql_url_num);
foreach($sql_url as $key => $value )
{
array_push($tmp_array,$array[$key-1]);  //将改变了数据存储到过渡数组中
$this->update_question($tmp_array);
}

}
else if($sql_url_num == $num)
{
foreach($sql_url as $key => $value )
{

if( $value[$key-1] != $array[$key-1] )
{
// $value[$key] = $array[$key];
array_push($tmp_array,$array[$key-1]);
}
else
{
array_push($tmp_array,$value[$key]);
}
}
dump($tmp_array);
$this->update_question($tmp_array);
}
else{
//表示有数据要添加
$more = $num – $sql_url_num;
//更新已经有的数据
foreach($sql_url as $key => $value )
{
if( $value[$key-1] != $array[$key-1] )
{
// $value[$key] = $array[$key];
array_push($tmp_array,$array[$key-1]);
}
else
{
array_push($tmp_array,$value[$key-1]);
}
}
$this->update_question($tmp_array);
//添加新加的数据
for($i=$sql_url_num+1;$i<$num;$i++)
{
array_push($tmp_array_2,$array[$i]);
}
$this->add_question($tmp_array_2,$sql_url_num);
}
}

[/php]

上面只是分类处理跟着情况,还没有跟数据库管理清理

下面是更新数据的代码

[php]

//更新数据库
public function update_question($tmp_array)
{
$url = ‘http://openoj.awaysoft.com/JudgeOnline/’;
$oj = M("oj_question");
foreach($tmp_array as $key => $value)
{
$data["url"] = $url.$value;
$data["time"] = time();
$oj->where("id=".$key)->data($data)->save();
}
}

[/php]

删除数据里多余数据的代码

[php]

//删除多余数据并优化数据
public function delete_question($start,$end)
{
$oj = M("oj_question");
for($i=$start;$i<=$end;$i++)
{
$oj->where("id=".$i)->delete();
}
}

PS: 删除数据后,MYSQL里面会有残留的字节,但是数据库优化还不会,先留下这个问题,以后再解决。

[/php]

新曾数据

[php]

//新增数据
public function add_question($array,$num=NULL)
{   //参数设计是因为项目需要,$NUM参数的默认值是空。
$oj = M("oj_question");
$url = ‘http://openoj.awaysoft.com/JudgeOnline/’;
foreach($array as $key => $value)
{
$num = $num + $key;
$data["url"] = $url.$value;
$data["name"] = "promble".$num;
$data["time"] = time();
$oj->add($data);
}
}

[/php]

思想很简单,实现很蛋疼。做了一天,开始就这数据批量存储老存问题。后来发现是代码写的不够细致,照成了一些不必要的BUG.

PS: 把问题都思考到位,是写好代码的不二法门。