三、各种数据库的关系、实践
3.1、自制简单文本格式(甚至在PHP中,用数据保存配置)
A、比如有一个AngularJS的示例项目,就用json保存示例数据的格式。
![请输入图片描述][1]
B、PHP保存配置数据就更加常见了,TP就是一个典型。
![请输入图片描述][2]
3.2、文本数据库(php text dbapi)
我们从 [http://www.c-worker.ch/txtdbapi/index.php#download][3] 下载了这个比较有名的 文本数据库引擎。
文本数据的使用场景这些交待一下。
1、比如你的虚拟主机,支持PHP,但是不支持MySQL ,也不支持SQLite的时候就可以发挥用场了。
下载了需要修改一下,
txt-db-api.php 的两个配置。
$API_HOME_DIR=dirname(__FILE__).DIRECTORY_SEPARATOR;
$DB_DIR=dirname(__FILE__).DIRECTORY_SEPARATOR;
通过[http://samples.app.ucai.cn/20140603/phptxtdb/examples/addressbook.php?lang=de&char=M][3]
就可以看到这个文本数据库的运行的例子。
然后就可以看到结果保存了。
![请输入图片描述][4]
果真是文本不是?
3.3、SQLite 数据库
SQLite 数据库也是一个文件数据库,但是不是文本数据库。它是一种自有的二进制格式。最早是由C写的一个库,并且很早也发布PHP的访问扩展,现在一般用的是sqlite3,PHP模块名也叫sqlite3。
Sqlite 有两个特点:
1、目前已经是非常流行的文件数据库,尤其是嵌入式数据库,在移动应用中也应用得十分普遍。
2、其访问的接口同 MySQL的非常地相似。
具体安装很简单,就是从官网下了代码, make 就可以了,不过代码可真不是一个小个。
3、SQLite3 已经是属于关系数据库大家庭的一员,所以它遵循ACID。对于SQL语句的支持也不错,网上也有人写了它和SQL互相导入互出的代码。
也有同MySQL 类似的管理工具,
[http://sourceforge.net/projects/sqlitemanager/][5]
大家可以搜索SQLite Manager 就能搜索到一堆。
至于具体的操作,不在这里展开,我们五月份的公开课,专门有一讲讲这个。将会比较详细地讲解SQLite 以及应用。
3.4、MySQL 数据库
MySQL 从使用上讲,大家都比较熟悉了。但是值得注意的是,mysql_query 这样的方法在php 5.5 时过时。
我们这里做三个简单的例子。分别用即将废弃的 mysql 和 mysqli 以 PDO 来操作数据库。
第一个例子,是过程式地操作MySQL。用的是很普遍的数据库操作函数,也就是php mysql 扩展的函数。这些函数将在 5.5版中过时,所以我们要抓紧改变了。
<?php/**
* 优才网公开课示例代码
*
*mysql 过程式操作MySQL的例子
*
*@author 伍星
*@see http://www.ucai.cn
*/ $conn = mysql_connect("127.0.0.1", "samples","ftly5qb");if(!mysql_select_db("samples", $conn))
{ echo mysql_error(); exit;
}
// 这应该由用户提供,下面是一个示例
$name = 'wxstars';
// 构造查询
// 这是执行 SQL 最好的方式
// 更多例子参见mysql_real_escape_string()
$query = sprintf("SELECT * FROM users
WHERE name='%s'",
mysql_real_escape_string($name));
// 执行查询
$result = mysql_query($query);
// 检查结果
// 下面显示了实际发送给 MySQL 的查询,以及出现的错误。这对调试很有帮助。
if (!$result) { $message = 'Invalid query: ' . mysql_error() . "\n"; $message .= 'Whole query: ' . $query; die($message);
}
// 结果的使用
// 尝试 print $result 并不会取出结果资源中的信息
// 所以必须至少使用其中一个 mysql 结果函数
// 参见 mysql_result(),mysql_fetch_array(), mysql_fetch_row() 等。
while ($row = mysql_fetch_assoc($result)){ echo $row['id']."\n"; echo $row['name']."\n"; echo $row['email']."\n";
}
// 释放关联结果集的资源
// 在脚本结束的时候会自动进行
mysql_free_result($result);mysql_close($conn);
?>
第二个例子是过程式和面向对象的myqli操作数据库的例子。
<?php/**
* 优才网公开课示例代码
*
*mysqli 过程式操作MySQL的例子
*
*@author 伍星
*@see http://www.ucai.cn
*/$mysqli =mysqli_connect("127.0.0.1", "samples", "ftly5qb","samples", 3306);/* check connection */if (!$mysqli)
{
printf("Connect failed: %s\n", mysqli_connect_error()); exit();
}// 这应该由用户提供,下面是一个示例$name= 'wxstars';// 构造查询// 这是执行 SQL 最好的方式// 更多例子参见 mysql_real_escape_string()$query = sprintf("SELECT * FROMusers WHERE name='%s'", mysqli_escape_string($mysqli, $name));echo$query;/* Select queries return a resultset */if ($result =mysqli_query($mysqli, $query))
{
printf("Selectreturned %d rows.\n", mysqli_num_rows($result)); $row = mysqli_fetch_assoc($result);
print_r($row); /* free resultset */
mysqli_free_result($result);
}
mysqli_close($mysqli);?><?php/**
* 优才网公开课示例代码
*
*mysqli 面向对象操作MySQL的例子
*
*@author 伍星
*@see http://www.ucai.cn
*/ $mysqli = new mysqli("127.0.0.1", "samples","ftly5qb", "samples");/* check connection */if($mysqli->connect_errno) {
printf("Connect failed: %s\n",$mysqli->connect_error); exit();
} // 这应该由用户提供,下面是一个示例$name= 'wxstars';// 构造查询// 这是执行 SQL 最好的方式// 更多例子参见 mysql_real_escape_string()$query = sprintf("SELECT * FROMusers WHERE name='%s'", $mysqli->real_escape_string($name));echo $query;/* Select queriesreturn a resultset */if ($result = $mysqli->query($query)) {
printf("Select returned %d rows.\n",$result->num_rows); $row =$result->fetch_assoc();
print_r($row); /* free resultset */
$result->close();
}$mysqli->close();?><?php/**
* 优才网公开课示例代码
*
*PDO 操作MySQL的例子
*
*@author 伍星
*@see http://www.ucai.cn
*/ /* ** mysql hostname ** */$hostname = '127.0.0.1';/* * * mysql username ***/$username = 'samples';/* * * mysql password ** */$password = 'ftly5qb';try{ $dbh = newPDO("mysql:host=$hostname;dbname=samples", $username,$password); /* * * echo a message saying we haveconnected ** */
echo 'Connected to database'."\n"; /* * * The SQL SELECT statement ** */
$sql = "SELECT * FROM users"; foreach ($dbh->query($sql) as $row)
{ print $row['id'] . ' - ' . $row['name'] .' - ' . $row['email'] . "\n";
} /* * * close the database connection ** */
$dbh = null;
} catch (PDOException $e)
{ echo $e->getMessage();
}?>
总结,我们上面使用了三个不同的php 模块,一个是phpmysql,一个是mysqli,一个是 pdo_mysql 三个模块来分别干同样的事情。如果你单独学习这三个库,会觉得比较枯燥,当你学到一定程度,融会贯通时,特别是对比学习时发现,你学习了其中一个,学习其他的也就并不难了。无非就是如下几步:
1、建立连接,在建立 连接时需要提交用户名,密码,主机,库名,端口等数据。
2、检测连接是否建立成功。
3、组装查询,注意不同的模块,对查询组装时的过滤方法也是不同的。
4、执行查询,获得结果句柄,而不是直接的数据。
5、通过非常相近的函数,从结果句柄中取得数据。
6、把数据放到结果句柄里输出。
7、在离开程序时,需要释放结果集资源。
8、在最后,需要关系开启的数据库连接。
3.5、MySQL KVDB的一个插件
为什么要用这个插件,并演示这个插件,有几个目的。
一、让大家知道MySQL和KVDB,这些软件之间,并没有明显的界限,像KVDB的出现,只是它的处理能力更强,而MySQL由于很多的限制,导致了在简单的场景下,处理能力并不如KVDB强。并不是说不能做。
二、其实有人,将MySQL进行改造,已达到了甚至超过 KVDB的一个高度。就是这个插件所做的,据说做到了 75万QPS。并且是生产中可以使用的了,一些发行版均将这个模块包含了进去。
http://yoshinorimatsunobu.blogspot.com/2010/10/using-mysql-as-nosql-story-for.html
三、也让大家了解一下MySQL插件的安装。进一步了解MySQL的强大。
[https://github.com/DeNA/HandlerSocket-Plugin-for-MySQL][6]
wgethttps://github.com/DeNA/HandlerSocket-Plugin-for-MySQL/archive/master.zip -OHandlerSocket-Plugin-for-MySQL.zip
unzip HandlerSocket-Plugin-for-MySQL.zip
进去目录
cd HandlerSocket-Plugin-for-MySQL-master/shautogen.sh
./configure
发现出错,要求连同mysql 的源码目录一起配置。
下载了一个5.5版的源码,配置
./configure--with-mysql-source=../MySQL/mysql-5.5.37/
发现出错。
checking mysql binary... yes: Using/usr/bin/mysql_config, version 5.1.73configure: error: MySQL source versiondoes not match MySQL binary version
只好查看了一下版本,
[root@localhost HandlerSocket-Plugin-for-MySQL-master]#mysqladmin --versionmysqladmin Ver 8.42Distrib 5.1.73, for redhat-linux-gnu on x86_64
发现是5.1.73 的版本
于是乎下了一个5.1.73 的源码。
成功配置,
./configure--with-mysql-source=../MySQL/mysql-5.1.73/
然后
make
make install
成功安装。下面再在mysql 中启用
mysql –uroot –p
执行 install plugin handlersocket soname 'handlersocket.so'; 安装插件。
![请输入图片描述][7]
插件成功安装。
再在
/etc/my.cnf 的 [mysqld] 版块下加入
loose_handlersocket_port = 9998loose_handlersocket_port_wr = 9999loose_handlersocket_threads = 4loose_handlersocket_threads_wr = 1loose_handlersocket_address = [你要监听的IP地址]
然后重启 mysqld
再show processlist
![请输入图片描述][8]
我们看到,已经成功运行,再netstat看一眼。
![请输入图片描述][9]
端口监听成功。
说明,此插件在MySQL的另一个发行版 Percona Server中已包含。
[http://www.mysqlperformanceblog.com/2010/12/14/percona-server-now-both-sql-and-nosql/][10]
我们来使用它的 PHP 客户端来测试一下。
下载:
[https://code.google.com/p/php-handlersocket/downloads/detail?name=php-handlersocket-0.3.1.tar.gz&can=2&q=][11]
安装模块。
新建测试代码。
新建表格
~~~
create database hstestdb;
CREATE TABLE `hstesttbl` (
`k`int(11) NOT NULL AUTO_INCREMENT,
`v`char(255) NOT NULL DEFAULT '',
PRIMARY KEY (`k`)
) ENGINE=InnoDB DEFAULTCHARSET=utf8<?php$host = '101.251.196.91';$port = 9998;$port_wr =9999;$dbname = 'hstestdb';$table = 'hstesttbl';//GET$hs = newHandlerSocket($host, $port);if (!($hs->openIndex(1, $dbname, $table,HandlerSocket::PRIMARY, 'k,v')))
{ echo $hs->getError(), PHP_EOL; echo "get Error!\n"; die();
}$retval = $hs->executeSingle(1, '=',array('k1'), 1, 0);
var_dump($retval);$retval =$hs->executeMulti( array(array(1,'=', array('k1'), 1, 0), array(1, '=', array('k2'), 1, 0)));
var_dump($retval);unset($hs);//UPDATE$hs =new HandlerSocket($host, $port_wr);if (!($hs->openIndex(2, $dbname, $table,'', 'v')))
{ echo $hs->getError(), PHP_EOL; die();
}if ($hs->executeUpdate(2, '=',array('k1'), array('V1'), 1, 0) === false)
{ echo $hs->getError(), PHP_EOL; die();
}unset($hs);//INSERT$hs = newHandlerSocket($host, $port_wr);if (!($hs->openIndex(3, $dbname, $table, '','k,v')))
{ echo $hs->getError(), PHP_EOL; die();
}if ($hs->executeInsert(3, array('k2','v2')) === false)
{ echo $hs->getError(), PHP_EOL;
}if ($hs->executeInsert(3, array('k3','v3')) === false)
{ echo 'A', $hs->getError(), PHP_EOL;
}if ($hs->executeInsert(3, array('k4','v4')) === false)
{ echo 'B', $hs->getError(), PHP_EOL;
}unset($hs);//DELETE$hs = newHandlerSocket($host, $port_wr);if (!($hs->openIndex(4, $dbname, $table, '','')))
{ echo $hs->getError(), PHP_EOL; die();
}if ($hs->executeDelete(4, '=',array('k2')) === false)
{ echo $hs->getError(), PHP_EOL; die();
}
~~~
3.6、全文检索
全文检索是不一个不同于数据检索的领域。有几个特点:
A、精确的数据库查询,无论是在顺序,还是在数据结构上都是非常地确定的。
B、全文检索一般面向大数据量,所以查询结果,在顺序上和结果上,都不是需要达到 100%精确,当然也有一些技术指标来衡量向着最好的方向前进。
C、精确查询所查询的内容,一般是数字型的比较或者是前置匹配等。
D、全文检索所查的内容,往往是一段文字中的一个或者多个词。所以只查文本型的数据。
E、精确查询往往随着数据量的记录数到了一定程度,如果是针对文本的查询,整个速度会下降比较明显。
F、而全文检索一般,随着数据量的增长,下降不能那么明显。
全文检索在PHP中有三种实现方式,一是用MySQL 的MyISAM引擎的全文检索功能。二是使用同MySQL结合紧密的 Sphinx。三是使用较为专业的全文检索引擎,Lucene。而用Slor来实现量询。
下载solr
wget -chttp://mirrors.cnnic.cn/apache/lucene/solr/4.8.1/solr-4.8.1.zip
cd solr-4.8.1/example
java –jar start.jar
按教程建立好索引:
[http://lucene.apache.org/solr/4_8_1/tutorial.html][12]
[http://101.251.196.91:8983/solr/collection1/select?q=%E6%9C%8D%E5%8A%A1][13]
PHP模块下载:
[http://pecl.php.net/package/solr][14]
~~~
<?php
/**
* 优才网公开课示例代码
*
*Solr 全文检索客户端测试
*
*@author 伍星
*@see http://www.ucai.cn
*/ $options = array
( 'hostname' => 'localhost', // 'login' => 'username', // 'password' => 'password', 'port' => '8983',
);$client = new SolrClient($options);$query= new SolrQuery();$query->setQuery('服务器');$query->setStart(0);$query->setRows(50);$query->addField('cat')->addField('features')->addField('id')->addField('timestamp');$query_response= $client->query($query);$response = $query_response->getResponse();
print_r($response);
~~~
?>
四、课程总结
通过上面的这一节课,我们站在一个比较高的高度讨论了数据库的出现和应用场景。其次,从实用和学术两方面,探讨了一些常用的术语和概念。第三,就是通过实例,分别讲解了不同情况下,对数据库的不同的使用情况。希望这一讲给大家指出一些基本的概念,能让大家对继续参与下面的课程有利。
- PHP技术文章
- PHP中session和cookie的区别
- php设计模式(一):简介及创建型模式
- php设计模式结构型模式
- Php设计模式(三):行为型模式
- 十款最出色的 PHP 安全开发库中文详细介绍
- 12个提问频率最高的PHP面试题
- PHP 语言需要避免的 10 大误区
- PHP 死锁问题分析
- 致PHP路上的“年轻人”
- PHP网站常见安全漏洞,及相应防范措施总结
- 各开源框架使用与设计总结(一)
- 数据库的本质、概念及其应用实践(二)
- PHP导出MySQL数据到Excel文件(fputcsv)
- PHP中14种排序算法评测
- 深入理解PHP原理之--echo的实现
- PHP性能分析相关的函数
- PHP 性能分析10则
- 10 位顶级 PHP 大师的开发原则
- 30条爆笑的程序员梗 PHP是最好的语言
- PHP底层的运行机制与原理
- PHP 性能分析与实验——性能的宏观分析
- PHP7 性能翻倍关键大揭露
- 鸟哥:写在PHP7发布之际一些话
- PHP与MySQL通讯那点事
- Php session内部执行流程的再次剖析
- 关于 PHP 中的 Class 的几点个人看法
- PHP Socket 编程过程详解
- PHP过往及现在及变革
- PHP吉祥物大象的由来
- PHP生成静态页面的方法
- 吊炸天的 PHP 7 ,你值得拥有!
- PHP开发中文件操作疑难问答
- MongoDB PHP Driver的连接处理解析
- PHP 杂谈《重构-改善既有代码的设计》之二 对象
- 在php中判断一个请求是ajax请求还是普通请求的方法
- 使用HAProxy、PHP、Redis和MySQL支撑10亿请求每周架构细节
- HTML、HTML5、XHTML、CSS、SQL、JavaScript、PHP、Web Services 是什么?
- 重构-改善既有代码的设计
- PHP场景中getshell防御思路分享
- 移动互联时代,你看看除了PHP你还会些什么
- 安卓系统上搭建本地php服务器环境
- PHP中常见的缓存技术!
- PHP里10个鲜为人知但却非常有用的函数
- 成为一名PHP专家其实并不难
- PHP 命令行?是的,您可以!
- PHP开发提高效率技巧
- PHP八大安全函数解析
- PHP实现四种基本排序算法
- PHP开发中的中文编码问题
- php.get.post
- php发送get、post请求的6种方法简明总结
- 中高级PHP开发者应该掌握哪些技术?
- 前端开发
- web前端知识体系大全
- 前端工程与性能优化(下)
- 前端工程与性能优化(上)
- 2016 年技术发展方向
- Web应用检查清单
- 如何成为一名优秀的web前端工程师
- 前端组件化开发实践
- 移动端H5页面高清多屏适配方案
- 2015前端框架何去何从
- 从前端看“百度迁徙”的技术实现(一)
- 从前端看“百度迁徙”的技术实现(二)
- 前端路上的旅行
- 大公司里怎样开发和部署前端代码?
- 5个经典的前端面试问题
- 前端工程师新手必读
- 手机淘宝前端的图片相关工作流程梳理
- 一个自动化的前端项目实现(附源码)
- 前端代码异常日志收集与监控
- 15年双11手淘前端技术总结 - H5性能最佳实践
- 深入理解javascript原型和闭包系列
- 一切都是对象
- 函数和对象的关系
- prototype原型
- 隐式原型
- instanceof
- 继承
- 原型的灵活性
- 简述【执行上下文】上
- 简述【执行上下文】下
- this
- 执行上下文栈
- 简介【作用域】
- 【作用域】和【上下文环境】
- 从【自由变量】到【作用域链】
- 闭包
- 完结
- 补充:上下文环境和作用域的关系
- Linux私房菜