數據庫的本質、概念及其應用實踐(二)

3、各類數據庫的關係、實踐
3.一、自制簡單文本格式(甚至在PHP中,用數據保存配置)
A、好比有一個AngularJS的示例項目,就用json保存示例數據的格式。
![請輸入圖片描述][1]php

B、PHP保存配置數據就更加常見了,TP就是一個典型。
![請輸入圖片描述][2]html

3.二、文本數據庫(php text db api)java

咱們從 [http://www.c-worker.ch/txtdbapi/index.php#download][3] 下載了這個比較有名的 文本數據庫引擎。
文本數據的使用場景這些交待一下。
一、好比你的虛擬主機,支持PHP,可是不支持MySQL ,也不支持SQLite的時候就能夠發揮用場了。mysql

下載了須要修改一下,
txt-db-api.php 的兩個配置。linux

$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]git

果然是文本不是?github

3.三、SQLite 數據庫
SQLite 數據庫也是一個文件數據庫,可是不是文本數據庫。它是一種自有的二進制格式。最先是由C寫的一個庫,而且很早也發佈PHP的訪問擴展,如今通常用的是sqlite3,PHP模塊名也叫sqlite3。
Sqlite 有兩個特色:
一、目前已是很是流行的文件數據庫,尤爲是嵌入式數據庫,在移動應用中也應用得十分廣泛。
二、其訪問的接口同 MySQL的很是地類似。
具體安裝很簡單,就是從官網下了代碼, make 就能夠了,不過代碼可真不是一個小個。
三、SQLite3 已是屬於關係數據庫你們庭的一員,因此它遵循ACID。對於SQL語句的支持也不錯,網上也有人寫了它和SQL互相導入互出的代碼。
也有同MySQL 相似的管理工具,
[http://sourceforge.net/projects/sqlitemanager/][5]sql

你們能夠搜索SQLite Manager 就能搜索到一堆。
至於具體的操做,不在這裏展開,咱們五月份的公開課,專門有一講講這個。將會比較詳細地講解SQLite 以及應用。數據庫

3.四、MySQL 數據庫
MySQL 從使用上講,你們都比較熟悉了。可是值得注意的是,mysql_query 這樣的方法在php 5.5 時過期。
咱們這裏作三個簡單的例子。分別用即將廢棄的 mysql 和 mysqli 以 PDO 來操做數據庫。apache

第一個例子,是過程式地操做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 * FROM users WHERE name='%s'", mysqli_escape_string($mysqli, $name));

echo $query;
/* Select queries return a resultset */
if ($result = mysqli_query($mysqli, $query))
{
    printf("Select returned %d rows.\n", mysqli_num_rows($result));


    $row = mysqli_fetch_assoc($result);
    print_r($row);
    /* free result set */

    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 * FROM users WHERE name='%s'",
    $mysqli->real_escape_string($name));

echo $query;
/* Select queries return a resultset */
if ($result = $mysqli->query($query)) {
    printf("Select returned %d rows.\n", $result->num_rows);


    $row = $result->fetch_assoc();
    print_r($row);
    /* free result set */

    $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 = new PDO("mysql:host=$hostname;dbname=samples", $username, $password);
    /*     * * echo a message saying we have connected ** */
    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 模塊,一個是php mysql,一個是mysqli,一個是 pdo_mysql 三個模塊來分別幹一樣的事情。若是你單獨學習這三個庫,會以爲比較枯燥,當你學到必定程度,融會貫通時,特別是對比學習時發現,你學習了其中一個,學習其餘的也就並不難了。無非就是以下幾步:

一、創建鏈接,在創建 鏈接時須要提交用戶名,密碼,主機,庫名,端口等數據。
二、檢測鏈接是否創建成功。
三、組裝查詢,注意不一樣的模塊,對查詢組裝時的過濾方法也是不一樣的。
四、執行查詢,得到結果句柄,而不是直接的數據。
五、經過很是相近的函數,從結果句柄中取得數據。
六、把數據放到結果句柄裏輸出。
七、在離開程序時,須要釋放結果集資源。
八、在最後,須要關係開啓的數據庫鏈接。

3.五、MySQL KVDB的一個插件
爲何要用這個插件,並演示這個插件,有幾個目的。

一,讓你們知道MySQL和KVDB,這些軟件之間,並無明顯的界限,像KVDB的出現,只是它的處理能力更強,而MySQL因爲不少的限制,致使了在簡單的場景下,處理能力並不如KVDB強。並非說不能作。

2、其實有人,將MySQL進行改造,已達到了甚至超過 KVDB的一個高度。就是這個插件所作的,聽說作到了 75萬QPS。而且是生產中可使用的了,一些發行版均將這個模塊包含了進去。
http://yoshinorimatsunobu.blogspot.com/2010/10/using-mysql-as-nosql-story-for.html

3、也讓你們瞭解一下MySQL插件的安裝。進一步瞭解MySQL的強大 。

[https://github.com/DeNA/HandlerSocket-Plugin-for-MySQL][6]

wget https://github.com/DeNA/HandlerSocket-Plugin-for-MySQL/archive/master.zip -O HandlerSocket-Plugin-for-MySQL.zip

unzip HandlerSocket-Plugin-for-MySQL.zip

進去目錄

cd HandlerSocket-Plugin-for-MySQL-master/

sh autogen.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.73
configure: error: MySQL source version does not match MySQL binary version

只好查看了一下版本,

[root@localhost HandlerSocket-Plugin-for-MySQL-master]# mysqladmin --version
mysqladmin  Ver 8.42 Distrib 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    = 9998
loose_handlersocket_port_wr    = 9999
loose_handlersocket_threads    = 4
loose_handlersocket_threads_wr  = 1
loose_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 DEFAULT CHARSET=utf8

<?php
$host = '101.251.196.91';
$port = 9998;
$port_wr = 9999;
$dbname = 'hstestdb';
$table = 'hstesttbl';

//GET
$hs = new HandlerSocket($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 = new HandlerSocket($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 = new HandlerSocket($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.六、全文檢索
全文檢索是不一個不一樣於數據檢索的領域。有幾個特色:
A、精確的數據庫查詢,不管是在順序,仍是在數據結構上都是很是地肯定的。
B、全文檢索通常面向大數據量,因此查詢結果,在順序上和結果上,都不是須要達到 100%精確,固然也有一些技術指標來衡量向着最好的方向前進。
C、精確查詢所查詢的內容,通常是數字型的比較或者是前置匹配等。
D、全文檢索所查的內容,每每是一段文字中的一個或者多個詞。因此只查文本型的數據。
E、精確查詢每每隨着數據量的記錄數到了必定程度,若是是針對文本的查詢,整個速度會降低比較明顯。
F、而全文檢索通常,隨着數據量的增加,降低不能那麼明顯。

全文檢索在PHP中有三種實現方式,一是用MySQL 的MyISAM引擎的全文檢索功能 。二是使用同MySQL結合緊密的 Sphinx。三是使用較爲專業的全文檢索引擎,Lucene。而用Slor來實現量詢。

下載solr
wget -c http://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);

?>

4、課程總結 經過上面的這一節課,咱們站在一個比較高的高度討論了數據庫的出現和應用場景 。其次,從實用和學術兩方面,探討了一些經常使用的術語和概念。第三,就是經過實例,分別講解了不一樣狀況下,對數據庫的不一樣的使用狀況。但願這一講給你們指出一些基本的概念,能讓你們對繼續參與下面的課程有利。

相關文章
相關標籤/搜索