• 数据库的本质、概念及其应用实践(二)


    原文请详见:http://www.ucai.cn/blogdetail/7034?mid=1

    能够在线执行查看效果哦!


    三、各种数据库的关系、实践

    3.1、自制简单文本格式(甚至在PHP中,用数据保存配置)

    A、比方有一个AngularJS的演示样例项目,就用json保存演示样例数据的格式。


    B、PHP保存配置数据就更加常见了。TP就是一个典型。


    3.2、文本数据库(php text db api)

    我们从 http://www.c-worker.ch/txtdbapi/index.php#download 下载了这个比較有名的文本数据库引擎。

    文本数据的使用场景这些交待一下。

    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.3、SQLite 数据库

    SQLite 数据库也是一个文件数据库。可是不是文本数据库。它是一种自有的二进制格式。

    最早是由C写的一个库,而且非常早也公布PHP的訪问扩展,如今一般用的是sqlite3,PHP模块名也叫sqlite3。

    Sqlite 有两个特点:

    1、眼下已经是很流行的文件数据库,尤其是嵌入式数据库。在移动应用中也应用得十分普遍。

    2、其訪问的接口同 MySQL的很地相似。

    详细安装非常easy,就是从官网下了代码, make 就能够了,只是代码可真不是一个小个。

    3、SQLite3 已经是属于关系数据库大家庭的一员,所以它遵循ACID。对于SQL语句的支持也不错,网上也有人写了它和SQL互相导入互出的代码。

    也有同MySQL 类似的管理工具,

    http://sourceforge.net/projects/sqlitemanager/

    大家能够搜索SQLite Manager 就能搜索到一堆。

    至于具体的操作,不在这里展开。我们五月份的公开课,专门有一讲讲这个。将会比較具体地解说SQLite 以及应用。

    3.4、MySQL 数据库

     MySQL 从使用上讲,大家都比較熟悉了。

    可是值得注意的是。mysql_query 这个方案在php 5.5 时过时。

    我们这里做三个简单的样例。分别用即将废弃的 mysql 和mysqli 以 PDO 来操作数据库。

    第一个样例,是过程式地操作MySQL。用的是非常普遍的数据库操作函数,也就是php mysql 扩展的函数。这些函数将在 5.5版中过时。所以我们要抓紧改变了。

    <?php
     
    /**
     * 优才网公开课演示样例代码
     *
     * mysql 过程式操作MySQL的样例
     *
     * @author 伍星
     * @seehttp://www.ucai.cn
     */ 
     
     
    $conn = mysql_connect("127.0.0.1","samples", "ftly5qb");
     
    if(!mysql_select_db("samples", $conn))
    {
        echomysql_error();
        exit;
    }

    // 这应该由用户提供,以下是一个演示样例

    $name = 'wxstars';

    // 构造查询

    // 这是运行 SQL 最好的方式

    // 很多其它样例參见 mysql_real_escape_string()

    $query = sprintf("SELECT * FROM users
        WHEREname='%s'",
       mysql_real_escape_string($name));

    // 运行查询

    $result = mysql_query($query);<span style="font-family: Arial, Helvetica, sans-serif; background-color: rgb(255, 255, 255);"> </span>

    // 检查结果

    // 以下显示了实际发送给 MySQL 的查询,以及出现的错误。

    这对调试非常有帮助。

    if (!$result) {
       $message  = 'Invalid query: ' .mysql_error() . "
    ";
        $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']."
    ";
        echo$row['name']."
    ";
        echo$row['email']."
    ";
    }

    // 释放关联结果集的资源

    // 在脚本结束的时候会自己主动进行

    mysql_free_result($result);
    mysql_close($conn);
    ?>
     

    第二个样例是过程式和面向对象的myqli操作数据库的样例。

    <?

    php /** * 优才网公开课演示样例代码 * * mysqli 过程式操作MySQL的样例 * * @author 伍星 * @seehttp://www.ucai.cn */ $mysqli = mysqli_connect("127.0.0.1","samples", "ftly5qb", "samples", 3306); /* check connection */ if (!$mysqli) { printf("Connect failed: %s ", 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.
    ",mysqli_num_rows($result));
     
     
        $row =mysqli_fetch_assoc($result);
       print_r($row);
        /* freeresult set */
     
       mysqli_free_result($result);
    }
     
    mysqli_close($mysqli);
    ?>
     
    <?php
    /**
     * 优才网公开课演示样例代码
     *
     * mysqli 面向对象操作MySQL的样例
     *
     * @author 伍星
     * @seehttp://www.ucai.cn
     */ 
     
    $mysqli = new mysqli("127.0.0.1","samples", "ftly5qb", "samples");
     
    /* check connection */
    if ($mysqli->connect_errno) {
       printf("Connect failed: %s
    ", $mysqli->connect_error);
        exit();
    }


     // 这应该由用户提供,以下是一个演示样例

    $name = 'wxstars';

    // 构造查询

    // 这是运行 SQL 最好的方式

    // 很多其它样例參见 mysql_real_escape_string()

    $query = sprintf("SELECT * FROM users WHEREname='%s'",
       $mysqli->real_escape_string($name));
     
    echo $query;
    /* Select queries return a resultset */
    if ($result = $mysqli->query($query)) {
       printf("Select returned %d rows.
    ", $result->num_rows);
     
       
        $row =$result->fetch_assoc();
       print_r($row);
        /* freeresult set */
       
       $result->close();
    }
     
     
    $mysqli->close();
    ?

    > <?php /** * 优才网公开课演示样例代码 * * PDO 操作MySQL的样例 * * @author 伍星 * @seehttp://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 haveconnected ** */ echo'Connected to database'." "; /* * * The SQL SELECT statement ** */ $sql ="SELECT * FROM users"; foreach($dbh->query($sql) as $row) { print$row['id'] . ' - ' . $row['name'] . ' - ' . $row['email'] . " "; } /* * * close the database connection ** */ $dbh =null; } catch (PDOException $e) { echo$e->getMessage(); } ?

    >


    总结。我们上面使用了三个不同的php 模块。一个是phpmysql,一个是mysqli,一个是 pdo_mysql 三个模块来分别干相同的事情。

    假设你单独学习这三个库。会认为比較枯燥。当你学到一定程度,融会贯通时。特别是对照学习时发现,你学习了当中一个,学习其它的也就并不难了。无非就是例如以下几步:

    1、建立连接,在建立 连接时须要提交username,password,主机,库名,port等数据。

    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 

    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 notmatch MySQL binary version
     

    仅仅好查看了一下版本号,

    [root@localhostHandlerSocket-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'; 安装插件。


    插件安装成功。

    再在

    /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


    我们看到,已经成功执行,再netstat看一眼。


    port监听成功。

    说明。此插件在MySQL的还有一个发行版 PerconaServer中已包括。

    http://www.mysqlperformanceblog.com/2010/12/14/percona-server-now-both-sql-and-nosql/

    我们来使用它的 PHP client来測试一下。

     下载:

    https://code.google.com/p/php-handlersocket/downloads/detail?

    name=php-handlersocket-0.3.1.tar.gz&can=2&q=

     安装模块。

     新建測试代码。

    新建表格

    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!
    ";
        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.6、全文检索

    全文检索是不一个不同于数据检索的领域。有几个特点:

    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

    http://101.251.196.91:8983/solr/collection1/select?

    q=%E6%9C%8D%E5%8A%A1

    PHP模块下载:

    http://pecl.php.net/package/solr

      

    <?php
    /**
     * 优才网公开课演示样例代码
     *
     * Solr 全文检索客户端測试
     *
     * @author 伍星
     * @seehttp://www.ucai.cn
     */ 
     
    $options = array
    (
       'hostname' => 'localhost',
      //  'login'   => 'username',
      //  'password' => 'password',
       'port'     => '8983',
    );
     
    $client = new SolrClient($options);
     
    $query = new SolrQuery();
     
    $query->setQuery('server');
     
    $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);
     
    ?>
     

    四、课程总结

    通过上面的这一节课,我们站在一个比較高的高度讨论了数据库的出现和应用场景。其次,从有用和学术双方面。探讨了一些经常使用的术语和概念。第三,就是通过实例,分别解说了不同情况下,对数据库的不同的使用情况。希望这一讲给大家指出一些主要的概念,能让大家对继续參与以下的课程有利。


  • 相关阅读:
    Request源码总结
    jmeter并发顺序问题
    mysql函数应用
    读《飘》之后的感受
    itchat源码阅读一
    python将print的内容输出到txt文件
    说一下StoreBoard和纯代码编程各有什么好处吧
    CocoaPods 安装
    Silverlight调用WebSite类型的WebService,Debug时的跨域问题
    ComboBox的奇怪属性
  • 原文地址:https://www.cnblogs.com/lcchuguo/p/5219239.html
Copyright © 2020-2023  润新知