• <ruby id="5koa6"></ruby>
    <ruby id="5koa6"><option id="5koa6"><thead id="5koa6"></thead></option></ruby>

    <progress id="5koa6"></progress>

  • <strong id="5koa6"></strong>
  • 基于MySQL的高性能數據庫應用開發

    發表于:2007-07-02來源:作者:點擊數: 標簽:
    在數據庫的應用 開發 中,常常會遇到 性能 和代價的之間矛盾。以作者在開發股市行情查詢和交易系統中遇到的問題為例,要在實時記錄1000多只股票每分鐘更新一次的行情數據的同時,響應大量并發用戶的數據查詢請求??紤]到性價比和易維護性,系統又要求在基于P

    在數據庫的應用開發中,常常會遇到性能和代價的之間矛盾。以作者在開發股市行情查詢和交易系統中遇到的問題為例,要在實時記錄1000多只股票每分鐘更新一次的行情數據的同時,響應大量并發用戶的數據查詢請求??紤]到性價比和易維護性,系統又要求在基于PC服務器,Windows NT平臺的軟硬件環境下實現。開始,我們采用了MS SQL Server 6.5 作為數據庫系統,用Visual C++ 6.0開發了訪問數據庫的前端,應用ODBC數據接口,在進行了大量的數據庫配置和程序優化后,發現仍不能滿足性能要求。后采用SQL Server的DB-Library接口,繞過了ODBC解釋層,可以每秒更新行情數據30次,同時支持20-30個左右的并發用戶進行行情查詢,基本滿足要求(單臺PC服務器,單PII350 CPU,內存128M,SCSI硬盤)。有沒有可能進一步提高系統的性能和負載能力呢?經過分析,數據庫服務器是系統的瓶頸。當然,可以采用UNIX服務器+大型數據庫的系統平臺,但其開發、運行、維護的費用比微機+Windows NT平臺的費用高出數倍。我們在其它一些系統的開發中,也經常遇到這樣的矛盾。如何在微機平臺上建立大容量、高效率、易維護、高性價比的數據庫系統呢?

    ---- 考察國內基于微機平臺的數據庫應用系統,典型的如網易的分布式郵件系統,采用了FreeBSD+MySQL的平臺,其容量、負載能力和響應速度都很優秀。作者查閱了MySQL的相關文檔,發現MySQL是GNU軟件(即OpenSource自由軟件)中非常優秀的數據庫系統,它完全符合SQL92 (Entry level)和 ODBC( level 0-2)規范,在符合POSIX規范的操作系統上實現了非常高效的關系型數據庫管理系統。根據MySQL提供的文檔,它的數據操作堪稱所有數據庫中最高效的,Benchmark如下表:

    Reading 2000000 rows by index
    Database Seconds
    mysql 367
    mysql_odbc 464
    db2_odbc 1206
    informix_odbc 121126
    ms-sql_odbc 1634
    oracle_odbc 20800
    solid_odbc 877
    sybase_odbc 17614

    Inserting (350768) rows
    Database Seconds
    mysql 381
    mysql_odbc 619
    db2_odbc 3460
    informix_odbc 2692
    ms-sql_odbc 4012
    oracle_odbc 11291
    solid_odbc 1801
    sybase_odbc 4802
    (run on the same NT 4.0 machine)

    ---- 從MySQL的Benchmark中可以看到,MySQL的性能非常出眾(當然,測試的MySQL系統可能作了優化,被測數據可能是針對MySQL選擇的),而且MySQL提供了對Windows NT的支持。Windows NT+MySQL能否成為構建高性能數據庫應用的理想選擇呢?作者用MySQL的數據接口改寫了程序,經過一段時間的運行,證明MySQL確實是高效而穩定的數據庫,非常適合構建大容量、高效率、易維護、高性價比的數據庫應用系統?,F將MySQL的安裝、運行、開發的心得與大家共享。
    二、MySQL的安裝和運行

    ---- 首先從(國內用戶可以從)下載MySQL的執行代碼及源代碼。注意,Windows NT用戶要選擇NT下的執行代碼,我下載的是mysql-shareware-3.22.32-win.zip。解包后執行Setup,按屏幕提示即可完成安裝。

    ---- 拷貝MySQL根目錄(c:mysql)下的my-example.cnf到c:my.cnf,按文件中的提示編輯my.cnf(如果MySQL的根目錄是c:mysql,可暫不改動my.cnf)。在NT的控制臺窗口中,進入MySQL的執行目錄(c:mysqlbin),執行

    ---- C:mysqlbinmysqld-shareware --standalone
    ---- 則MySQL的數據庫引擎啟動。打開另一NT控制臺窗口,執行
    ---- C:mysqlbinmysql mysql
    ---- 建立數據庫連接,出現“mysql>”提示符后,執行
    ---- mysql > DELETE FROM user WHERE Host="localhost" AND User="";
    ---- mysql > QUIT
    ---- 刪除所有的非授權用戶。
    ---- 然后執行
    ---- C:mysqlbinmysqladmin reload
    ---- C:mysqlbinmysqladmin -u root password your_password
    ---- 其中,your_password是你選擇的數據庫管理員的口令,必須妥善保管。

    ---- 如果要每次都以管理員身份連接數據庫,則編輯c:my.cnf,在[client]段中加入:

    user=root
    password= your_password
    如果要停止MySQL的數據庫引擎,可以執行
    C:mysqlbinmysqladmin -u=root -p shutdown
    按提示輸入管理員口令后,MySQL的數據庫引擎停止。

    三、MySQL客戶端應用的開發
    ---- MySQL提供了豐富的數據接口API,包括C、C++、Perl、PHP、Python、TCL等API和JDBC,ODBC接口。出于性能考慮,我們采用了MySQL的C API進行開發?,F以Visual C++環境為例,作一簡單介紹。

    ---- 新建一Win32 Console Application的Project,把“c:mysqlinclude”添加到編譯選項的包含路徑中(在Project Options中加入 /I "d:mysqlinclude")。新建一main.c文件,主體如下:

    #include
    #include
    #include
    #include
    int main( int argc, char * argv[] )
    {
    char szTargetDSN[] = "test";
    char szSqlText[500]="";
    char aszFlds[ 25 ][ 25 ];
    MYSQL * myData ;
    MYSQL_RES * res ;
    MYSQL_FIELD * fd ;
    MYSQL_ROW row ;
    int i,j,k;
    BOOL bCreate = TRUE;

    if ( (myData = mysql_init((MYSQL*) 0))
    //初始化數據結構
    && mysql_real_connect( myData, NULL,
    //連接數據庫
    "root", " your_password ", szTargetDSN,
    MYSQL_PORT, NULL, 0 ) )
    {
    if(bCreate)
    {
    sprintf(szSqlText, //構造SQL語句
    "create table mytable "
    //新建一張表
    "(time datetime, s1 char(6), "
    "s2 char(11), s3 int, s4 int)");
    if (mysql_query( myData, szSqlText))
    //執行SQL語句
    {//執行SQL語句出錯
    ErrLog( "Can"t create table") ;
    mysql_close( myData ) ;
    return FALSE ;
    }

    sprintf(szSqlText,
    "insert into mytable "
    //向表中插入數據
    "values("2000-3-10 21:01:30","
    //注意時間的格式
    ""Test","MySQLTest",2000,3)");
    if (mysql_query( myData, szSqlText))
    {//執行SQL語句出錯
    ErrLog( "Can"t insert data to table") ;
    mysql_close( myData ) ;
    return FALSE ;
    }

    sprintf(szSqlText, "select * from mytable ");
    if (mysql_query( myData, szSqlText))
    //進行數據檢索
    {
    //執行SQL語句出錯
    mysql_close( myData ) ;
    return FALSE ;
    }
    else
    {
    res = mysql_store_result( myData ) ;
    //取得查詢結果
    i = (int) mysql_num_rows( res ) ;
    //取得有效記錄數
    printf( "Query: %sn%ld records found:
    n", szSqlText, i ) ;
    for ( i = 0 ; fd = mysql_fetch_field( res ) ;
    i++ )
    strcpy( aszFlds[ i ], fd->name ) ;
    //取得各字段名
    for (i=1; row = mysql_fetch_row( res ); )
    //依次讀取各條記錄
    {j = mysql_num_fields( res ) ;
    //取得記錄中的字段數
    printf( "Record #%ld:-n", i++ ) ;
    for ( k = 0 ; k < j ; k++ )
    //輸出各字段的值
    printf( " Fld #%d (%s): %sn", k + 1, aszFlds[ k ],
    (((row[k]==NULL)||
    (!strlen(row[k])))?"NULL":row[k])) ;
    puts( "==============================n" ) ;
    }
    mysql_free_result( res ) ;
    }
    }
    else
    {//連接數據庫出錯
    ErrLog( "Can"t connect to the mysql server ") ;
    mysql_close( myData ) ;
    return FALSE ;
    }
    mysql_close( myData ) ;
    return TRUE ;
    }

    ---- 對其中幾個函數作簡單說明,詳細說明,可參考MySQL文檔:
    ---- 1. MYSQL *mysql_init(MYSQL *mysql)

    ---- 初始化一個類型為MYSQL的數據結構,為執行mysql_real_connect()做準備。參數mysql為指向該結構的指針,如果mysql為NULL,則新建并初始化一個MYSQL的數據結構。新建的結構將在mysql_close()中釋放。

    ---- 若成功,返回初始化的MYSQL數據結構的指針,否則返回NULL。

    ---- 2. MYSQL *mysql_real_connect(MYSQL *mysql, const char *host,
    ---- const char *user, const char *passwd, const char *db,
    ---- unsigned int port, const char *unix_socket, unsigned int client_flag)

    ---- 與MySQL數據庫引擎建立連接。在執行進一步的數據操作之前,必須保證mysql_real_connect()成功返回。
    ---- 參數mysql是mysql_init()的返回值;
    ---- 參數host是運行MySQL數據庫引擎的機器的TCP/IP主機名,如為NULL則默認為“localhost”;
    ---- 參數user和passwd是MySQL數據庫的合法用戶和口令;
    ---- 參數db是連接的數據庫名;
    ---- 參數port,unix_socket和client_flag一般取默認值。

    ---- 3. int mysql_query(MYSQL *mysql, const char *query)
    ---- 執行query字符串中的SQL語句,query必須以0結尾。如果成功,返回0。

    ---- 4. MYSQL_RES *mysql_store_result(MYSQL *mysql)

    ---- 返回SELECT,SHOW,DESCRIBE, EXPLAIN等語句執行的結果。函數新建一個MYSQL_RES的數據結構,把結果存儲在該結構中。如果查詢沒有匹配的結果,則返回空數據集。處理完結果集后,必須調用mysql_free_result()。

    ---- 如果出錯,返回NULL,否則返回MYSQL_RES結構的指針。

    ---- 5. MYSQL_ROW mysql_fetch_row(MYSQL_RES *result)

    ---- 取回結果集中的下一條記錄,如果沒有記錄或出錯,返回NULL。一條記錄中的字段數可以用mysql_num_fields(result)獲得,各字段的值可以用row[0] 到 row[mysql_num_fields(result)-1]的數組來訪問。

    ---- 在工程的鏈接選項中,加入c:mysqlliblibmysql.lib的接口庫,把libmysql.dll復制到操作系統的system目錄下(c:winntsystem32),就可以編譯運行了。

    ---- 到這里,一個簡單的數據庫應用就開發完成了。當然,MySQL有一套功能豐富的API,大家可以查看文檔。另外,如果需要跨平臺的移植性,可以考慮用MySQL的ODBC接口??梢宰约号渲肕ySQL的ODBC連接屬性,也可以下載myodbc-2.50.29-nt.zip工具包來配置。

    四、總結

    ---- 作者用MySQL在Windows NT上構建了高性能、高穩定性的數據庫系統。這樣,既可以利用Windows NT和Visual C++的友好界面,又可以獲得MySQL的強大功能。實踐證明,這種方案成本低(別忘了MySQL是免費的)、效率高、開發周期短、運行穩定(MySQL的穩定性在Yahoo、163、263等站點獲得了極高的評價)。

    ---- 目前,我的股市行情查詢和交易系統已經獲得了每秒鐘記錄70-100條股票行情數據,同時響應50個并發用戶進行數據查詢的性能,而系統的開發、運行成本卻大幅降低。如果您正為PC上的數據庫效率發愁,不妨也來試試MySQL吧。
    (作者:李蔚清)

    原文轉自:http://www.kjueaiud.com

    老湿亚洲永久精品ww47香蕉图片_日韩欧美中文字幕北美法律_国产AV永久无码天堂影院_久久婷婷综合色丁香五月

  • <ruby id="5koa6"></ruby>
    <ruby id="5koa6"><option id="5koa6"><thead id="5koa6"></thead></option></ruby>

    <progress id="5koa6"></progress>

  • <strong id="5koa6"></strong>