database server standard operation procedureebooks.lib.ntu.edu.tw/1_file/oss/63/93doc4-5.pdf ·...

98
COSA-SOP-03-006 Version 1.1 資料庫伺服器 架設標準作業程序書 DataBase Server Standard Operation Procedure 中華民國開放系統協會 CHINESE OPEN SYSTEMS ASSOCIATION

Upload: letram

Post on 29-Jul-2018

242 views

Category:

Documents


0 download

TRANSCRIPT

Page 1: DataBase Server Standard Operation Procedureebooks.lib.ntu.edu.tw/1_file/oss/63/93doc4-5.pdf · 業務的公司帶來了不少壓力,譬如微軟,甲骨文 ... 外的錢用在第三方的資料庫產品上,譬如就可以不用再購買甲骨文公司

COSA-SOP-03-006 Version 11

資料庫伺服器 架設標準作業程序書

DataBase Server

Standard Operation Procedure

中華民國開放系統協會

CHINESE OPEN SYSTEMS ASSOCIATION

中 華 民 國 九 十 三 年 十 月

經濟部工業局

九十三年度自由軟體產業推動計畫專案

開放原始碼軟體標準作業程序書

作者群

編號 程序書名稱 作者 COSA-SOP-03-001 開放原始碼軟體標準作業程序書總論 吳鴻煦 COSA-SOP-03-002 Linux 作業系統標準作業程序書 洪宗勝 COSA-SOP-03-003 網站伺服器架設標準作業程序書 林彥明 COSA-SOP-03-004 電子郵件伺服器架設標準作業程序書 簡碩文 COSA-SOP-03-005 資源分享伺服器架設標準作業程序書 顏朝蒼 COSA-SOP-03-006 資料庫伺服器架設標準作業程序書 林彥明 COSA-SOP-04-001 OpenWebmail架設標準作業程序書 林毓能 COSA-SOP-04-002 PHPNUKE 內容管理系統標準作業程序書 蔡邦洲 COSA-SOP-04-003 Linux 防火牆標準作業程序書 吳鴻煦 COSA-SOP-04-004 Tomcat 應用伺服系統標準作業程序書 林彥明 COSA-SOP-04-005 OpenOfficeorg標準作業程序書 江明宗

審查者

許清琦 中華民國開放系統協會 理事長 柯森 國家高速網路與計算中心

指導委員

郭大維 台大資工系 教授 陳秋華 台科大資工系 教授 劉龍龍 翔威國際股份有限公司 總經理

單 位

主辦單位經濟部工業局 委託單位財團法人資訊工業策進會 執行單位中華民國開放系統協會

目錄

第一章 簡介 5

11適用對象 (AUDIENCE) 5 12 MYSQL本身 5 13 MYSQL 40版跟 50版重大的改進功能 7 14 各家資料庫軟體比較 8

第二章 前置需求 11

第三章 安裝 12

31 MYSQL安裝 12 32 PHPMYADMIN安裝 17 33 升級及注意事項 24

第四章 MYSQL管理 27

41 WEBMIN 管理介面 27 412建立資料庫 27 412 建立資料表 30 413 使用者管理 35

42 PHPMYADMIN 的操作介面 39 421建立資料庫 39 422 建立資料表 39 423使用者管理 44

43管理指令介紹 46 431 利用mysqladmin設定root的密碼46 432 連線 MySQL 47 433 建立資料庫 47 434 建立資料表 48

第五章 實用範例 50

51 任務一WEB BASE客戶通訊錄 50 511 Web Base客戶通訊錄架構 50 512 Web Base通訊錄測試 51 513 程式內容及說明 53

52 任務二WEB BASE群組軟體 ( TWIG ) 59

第六章 維護及更新程序 64

61 日常維護 64

3

62 更新程序 64 63 備份重要檔案 64 64 離線備份與還原 64

641 離線備份64 642 離線還原65

65 線上備份與還原 65 651 線上備份65 652 線上還原66

第七章 問題與解答 68

第八章 參考資料 78

附錄一 SQL COMMAND 介紹 80

附錄二REPLICATION 91

4

第一章 簡介

MySQL 是一種 跨平台多使用者多執行緒支援 SQL語言 (結構化查詢語言)執行速度快廣受全球網站大量採用的網路資料庫系統最重要的

是在大部份情形下使用 MySQL 是完全免費的( MySQL自 32319之後已改為 GPL版權宣告囉)整體而言MySQL 免費原始碼開放入門容易

執行速度快跨平台 (亦支援 Windows 2000)支援工具眾多等特性十分適合中小企業用來開發各種資訊系統企業不必再花費數十萬元去購買一些費而

不惠的資料庫 MySQL 沒有所謂連線使用者限制其它商用資料庫系統一定數量以上的

連線使用者數可是要付出相當可觀的費用的像 Yahoo等大公司也是用 MySQL 哩 連這麼大的入口網站都安心地挑選 MySQL 一般的中小企業更

無需擔心 MySQL的穩定性

11適用對象 (Audience)

本 SOP的對象適合一般的使用者及系統管理者編排的方式大部分皆採操

作步驟的模式進行方便一般入門的使用者

12 MySQL本身

在 Unix平台上最受到歡迎的一套資料庫系統就是 MySQL MySQL於1990中期開始發展當時Michael Mothnty Widenius在位於瑞典的 TcX DataKonsultAB開始開發這套軟體並在 1995 年公開釋放第一個版本

MySQL 同時擁有頗為可觀跨平台能力它能 Unix Like平台工作例如 AIX

SolarisFreeBSD及 Linux也能在 Mac OS X及Windows NT2000 server亦或是 Microsoft Wrokstation 系統上如 9xMEXP上開發程式更重要的是它是

讓您擁有原始碼 在 MySQL 在 323之後的版本在每個系統元件上在釋放時都會加上一個

完成度的註解如由「gamma」階段到「stale」階段「beat」階段到「alpha」階段階段愈低愈不穩定查詢目前的發展版本可以在 MySQL 參考手冊及線上

文件找到

5

MySQL經過考驗證明是值得信賴的資料庫系統如果您是 stable版的使用者您大可以放心MySQL對於版本的控制是十分注意並提供廣大的使用者原始碼下載Bug也因此很快就被解決

MySQL主要是以技術支援和經銷資料庫為主和 Red Hat在 Linux上的做

法非常類似背後則是由創投資金在支持客戶可以下載 MySQL並遵照 GPL授權規定使用MySQL公司則以技術服務作為收入

MySQL也提供付費的解決方案給想要整合 MySQL和其他軟體產品但是

又不想讓客戶取得程式碼的公司MySQL表示MySQL資料庫在全球已經有

400萬的使用者但是並不清楚其中有多少付費用戶到目前為止MySQL也已經引起企業用戶的興趣甚至包括 Yahoo和 Google等網際網路的領導廠商

MySQL最原始的構想嚐試克服自由軟體資料庫系統「mSQL」的一些功能

上的限制MySQL成長進步的非常的快尤其當贊助者由網際網路應用中看出

MySQL能提供網站所需強健資料庫的潛能對於 MySQL成長的速度幫助不少

而近來更有令人振奮的好消息( 2003 年 5月 ) ERP的龍頭 SAP正在與 MySQL就開放源代碼資料庫軟體進行合作這項

交易將會使得 MySQL這樣更小的公司能夠加速它的開發計畫此舉將允許

MySQL公司在未來的兩年內為其資料庫軟體添加更高端的一些特徵MySQL公司的首席執行官 Marten Mickos 說公司早在四年前就希望能夠進軍高端資料

庫業務這次交易在資料庫市場上還引起了另外一些影響它給那些開發資料庫

業務的公司帶來了不少壓力譬如微軟甲骨文以及 IBM等因為這項交易為

這些公司不斷樹立了一個越來越強大的開放源代碼軟體的競爭者而開放源代碼

軟體最終也許會吞噬它們的資料庫市場 SAP公司一直是銷售那些管理核心業務的一些軟體譬如會計軟體存貨

管理軟體這些產品以前一直是各大公司的暢銷軟體為了吸引那些中等規模的

公司客戶從而進行業務擴張這家德國的公司開始在他們的一些產品中加入SAP DB這是一個開放源代碼的資料庫軟體該軟體就可以免除 SAP公司客戶花額外的錢用在第三方的資料庫產品上譬如就可以不用再購買甲骨文公司的資料庫

軟體 根據他們的技術交錯式授權協議MySQL公司將會主宰 SAP DB的絕大部

分再開發業務並且 MySQL也會使用該程式的設計作為該公司未來改進的資料

庫軟體的模型SAP公司的一位元代表稱隨著 MySQL資料庫軟體的不斷成

熟SAP公司將會用新的 MySQL的資料庫軟體代替 SAP DBMickos 說在

6

這項交易中這家瑞典公司 MySQL將會得到其軟體的版稅但他拒絕透露這次

合作的一些經濟方面的細節 SAP的代表稱在更長一段時間後該開放源代碼資料庫軟體將會和 SAP

公司的旗艦產品 R3一起銷售 不久之後SAP與 MySQL將會完成他們合作計畫的第一個階段那

就是 SAP將會發佈一個 MySQL的資料庫版本從而它可以無縫地替代現在使

用的 SAP DB這對 MySQL而言無異是如虎添翼想必在不久的將來MySQL定能擔任企業更重要的任務

13 MySQL 40版跟 50版重大的改進功能

以下是 40版跟 50版一些重大的改進功能 MySQL 40 版httpwwwmysqlcomdocenNews-40xhtml

內建提供InnoDB table type支援 standard binaries adding transactions row-level locking 和foreign keys

提昇 Query速度 改善 boolean mode truncation and phrase searching全文檢索效

率 加強MERGE tables 並支援INSERT statements and

AUTO_INCREMENT 在SELECT 中支援UNION 語法 支援Multi-table DELETE statements libmysqld the embedded server library 更多的GRANT 參數來加強安全性 提供更多動態參數來降低停止 MySQL的必要 改善 replication code and features 改善執行效率並增加可靠性

MySQL 50 版httpwwwmysqlcomdocenTODO_MySQL_50html改善執行效率並增加可靠性 提供 Stored Procedures 機制 支援 cursor Dynamic length rows for HEAP tables Add true VARCHAR support

7

加強執行效率 更好的國際語系支援 提供可用性

14 各家資料庫軟體比較

目前市面上較被廣為使用資料庫除了 MySQL之外尚有下列幾種

1 MS SQL Server 2000 2 Oracle 8i 3 IBM DB2 4 Informix

過去幾年來在總值 120億美元的資料庫市場上如果廠商想要誇讚自家的

產品那就一定得要有強大的資料庫支援最嚴苛的任務才站得上檯面不過

到了今天似乎光是這樣並不夠客戶除了要求足以負擔嚴苛的任務之外還希

望擁有聰明又便宜的資料庫 Meta Group的分析師 Charlie Garry表示 ( 2003 年 5 月)MySQL的商業

模式是以開放原始碼為基礎以便讓客戶盡快接受 MySQLGarry指出MySQL甚至適合用在甲骨文IBM微軟等大廠爭相搶食的企業資料中心

Information Resources的資訊長 Marshall Gibbs就表示他們沒有任何品

牌的偏好只要「功能效能價格的最佳組合」 由研究近兩年來資料庫客戶

愈來愈注重總體成本(圖 1-1)

8

圖 1-1 資料庫優先性

整體擁有成本 大致說來MySQL是免費的MySQL需要付費的規定只限於下列兩種情

形 1 以 Embedded的方式使用 MySQL 2 使用 MySQL的商業用途軟體

且其授權費用一台 MySQL Pro License只需美金 $440比起其他任何資料庫軟體來得容易負擔多了加上其易於管理的特性著實可大大降低企業資料

庫的整體擁有成本 擴充性

MySQL同時提供高度多樣性能夠提供給很多不同的使用者介面包括命

令列操作網頁瀏覽器以及各式各樣的程式語言介面例如JavaC++PerlPHP及 PhythonMySQL可用 UnixWindows以及 OS2hellip等平台因此它可以用個人電腦或是伺服器上 性能 事實上大部份的網站的開發者都認為 MySQL是目前市面跑得最快的資料

9

庫對資料庫的最佳化主要在於你對他的設定和資料庫結構的設計如果你的

資料庫結構設計得非常差你的存取速度還是會受到影響而變得比較慢

10

第二章 前置需求

在安裝 MySQL之前請確定 Apache及 MySQL亦巳安裝相關步驟請參考

Apache SOP安裝 Apache及 PHP相關章節

11

第三章 安裝

31 MySQL安裝

在 RedHat 90上安裝 MySQL是件很容易的事因為 RedHat 90提供了一

個很方便的 GUI套件管理工具「redhat-config-packages」各位只要把 RedHat 90第一片光碟放入並以 root的身份登入系統鍵入 redhat-config-packages勾選「SQL資料庫伺服器」即可然後按「更新」如果遇到任何相依性問題

系統會提示您更換光碟片 ( 圖 3-1 ~ 3-3 ) Step 1 執行 redhat-config-packes

圖 3-1

Step 2 選擇資料伺服器

12

圖 3-2

Step 3檢查是否安裝成功 待安裝後您可以用利用「rpm -qa | grpe ^mysql」檢查是否安裝成功

圖 3-3

啟動 MySQL ( Command Mode )馬上啟動 MySQL的指令為「service mysqld start」如果您希望一開機就自動啟動 MySQL請執行「chkconfig mysqld on」

13

圖 3-4

啟動 MySQL ( WebMin 介面 ) 我們也可以利用WebMin 來啟動 MySQL步驟如下 Step 1登入Webmin

圖 3-5 登入WebMin

Step 2 選擇伺服器

14

圖 3-6 伺服器畫面

Step 2 選擇 MySQL資料庫伺服器

圖 3-7 伺服器畫面

15

Step 3 啟動 MySQL資料庫伺服器

圖 3-8 啟動 MySQL

更改資料庫管理者密碼

成功啟動 MySQL後因為資料庫管理者預設沒有密碼建議使用前更改系

統管理者密碼請輸入下列指令

mysqladmin ndashu root ndashh cosaexamplecom password lsquo1234rsquo -u 表示使用者帳號root 為 MySQL預設的管理帳號

-h 表示 MySQL主機的主機名稱也可使用 IP Address password 表示使用者的密碼因為字串請使用單引號將密碼括起來

圖 3-9 修改 MySQL 的密碼

16

32 phpMyAdmin安裝

本書除了會介紹利用當今 Linux上最紅的整合管理工具Webmin 來管理

MySQL外還會為各位介紹專門管理 MySQL的工具 phpMyAdmin phpMyAdmin是免費的 PHP原始程式碼的Web網站可用來管理整個

MySQL伺服器這是一套Web介面的 MySQL管理程式支援中文的使用者介

面 phpMyAdmin只需透過瀏覽器就可管理 MySQL伺服器換句話說不論

MySQL是安裝在 Linux或是Windows 作業系統都可以使用相同步驟在

MySQL上建立資料庫(Database)資料表(Table)和編輯紀錄(Record) Step 1 下載phpMyAdmin ( httpwwwphpmyadminnet )選擇最櫎新穩定的版

本 253

圖 3-10 httpwwwphpmyadminnet

17

圖 3-11 下載 phpMyAdmin-253-phptarbz2

Step 2 將 phpMyAdmin-253-phptarbz2收至 tmp 並執行下列指令將其解壓

縮至varwww tar jxvf phpMyAdmin-253-phptarbz ndashC varwwwhtml

圖 3-12 解壓縮安裝 phpMyadmin-253

Step 3 為了操作方便起見建立 Soft link ln ndashs phpMyAdmin-253 phpMyAdmin

圖 3-13 修改 phpMyadmin 設定檔 configincphp

18

Step 4 修改 phpMyadmin 設定檔 configincphp gedit varwwwhtmlphpMyAdminconfigincphp

圖 3-14 configincphp設定檔

Step 5 設定顯示行號以方便修改 configincphp 設定檔

19

圖 3-15 顯示行號

Step 6 修改下列設定 第 39 行 設定 phpMyAdmin的 URL 第 69 行 MySQL Server 的 ip 第 80 行 利用何帳號存取 MySQL 第 81 行 如果 root有設定 password此處即填入 root的 password

30 In most cases you can leave this variable empty as the correct value

31 will be detected automatically However we recommend that you do

32 test to see that the auto-detection code works in your system A good

33 test is to browse a table then edit a row and save it There will be

34 an error message if phpMyAdmin cannot auto-detect the correct value

35

36 If the auto-detection code does work properly you can set to TRUE the

37 $cfg[PmaAbsoluteUri_DisableWarning] variable below

38

39 $cfg[PmaAbsoluteUri] = httpossccosaorgtwphpMyAdmin

hellip

20

hellip

69 $cfg[Servers][$i][host] = localhost MySQL hostname or IP address hellip 80 $cfg[Servers][$i][user] = root MySQL user

81 $cfg[Servers][$i][password] = 1234 MySQL password (only needed

圖 3-16 修改 configincphp

21

圖 3-17 修改 configincphp

圖 3-18 修改 configincphp p

Step 7 設定語系

22

圖 3-19 設定語系

圖 3-20 執行 phpMyAdmin

23

33 升級及注意事項

RedHat 90附的 MySQL版本為 323 MySQL所釋出最新穩定版本為

40若是您不想用系統預附的 323請先利用下列移除之前 323的版本

rpm ndashe mysql-devel rpm ndashe mysql-server rpm ndashe mysql --nodeps 然後到下列網址下載您所想要的版本進行安裝在這裏我們用 4014版為例 Step 1 下載相關套件( httpwwwmysqlcomdownloadsmysql-40html )

圖 3-21 Download MySQL 4014 相關 RPM Step 2 利用 rpm 指令安裝

24

圖 3-22 Install MySQL 4014 相關 RPM

圖 3-23 Install MySQL 4014 相關 RPM

Step 3 啟動 MySQL

25

圖 3-24 啟動 MySQL 4014 並修改密碼

26

第四章 MySQL管理

本章將我們介紹利用WebminphpAdminCommand的方式建立一個名為

CONTACT的資料庫內有一個 address的 Table作為我們客戶通訊錄程式使

用的資料庫

41 Webmin 管理介面

412建立資料庫

Step 1 登入Webmin

圖 4-1 登入WebMin

Step 2 點選伺服器

27

圖 4-2 伺服器畫面

Step 3 點選 MySQL資料庫伺服器

圖 4-3 MySQL資料庫伺服器

28

Step 4 建立一個新的資料庫

圖 4-4 建立 MySQL資料庫

Step 5 建立名為 CONTACT的資料庫

29

圖 4-5 指定資料庫名稱

412 建立資料表

假設我們要建立一個名為 address的 Table其結構如下 欄位名稱 資料型態 長度 說明 id INT (自動編號) 連絡人編號 name varchar文字 20 連絡人姓名 tel Varchar文字 15 連絡人電話 Step 1 選擇 CONTACT資料庫

30

圖 4-6 選擇資料庫

Step 2 指定欄位數目

31

圖 4-7 設定欄位數目

Step 3設定表格欄位屬性

圖 3-8 設定表格欄位屬性

Step 4建立表格資料

32

圖 4-9 建立表格資料

圖 4-10 檢視資料

33

圖 4-11 新增資料

圖 4-12

34

圖 4-13

413 使用者管理

接下來我們要利用Webmin 來建立資料庫使用者並給予某些權限 Step1建立使用者

35

圖 4-14 選擇使用者權限

圖 4-15

36

Step2 賦予權限

圖 4-16

Step3 權限列表

37

圖 4-17

38

42 phpMyAdmin 的操作介面

421建立資料庫

Step 填入資料庫名稱並按「建立」

圖 4-18建立資料庫

422 建立資料表

Step1 填入資料表名稱並指定欄位數量 執行

39

圖 4-19填入資料表名稱並指定欄位數量

Step2 設定欄位屬性

圖 4-20設定欄位屬性

40

Step3 phpMyAdmin會產生相關的 SQL Command

圖 4-21 資料表結構及相關 SQL Command

Step4新增 Record

41

圖 4-22

圖 4-23

42

圖 4-24

圖 4-25

43

423使用者管理

Step1建立使用者

圖 4-26

44

圖 4-27

Step2 給予權限

圖 4-28

Step3權限列表

45

圖 4-29

43管理指令介紹

431 利用 mysqladmin設定 root的密碼

當您在Windows 或 Linux 中安裝好 MySQL後系統會自動幫您建立兩個

帳分別是 root 和 匿名者MySQL的 root 跟 Linux 最高權限使用者 root無關MySQL的 root使用者相當於 MS SQL 中的 sa 帳號擁有最高的 Database管理權限但系統預設 MySQL的 root 是不需要密碼所以通常我們一安裝

MySQL後首要任務便是修改 root的密碼 我們可以利用 mysqladmin工具或是直接修改 MySQL內部資料庫的使用者資

料 mysqladmin ndashu root ndashh cosaexamplecom password lsquo1234rsquo

46

-u 表示使用者帳號root 為 MySQL預設的管理帳號

-h 表示 MySQL主機的主機名稱也可使用 IP Address password 表示使用者的密碼因為字串請使用單引號將密碼括起來 密碼設定完成之後還是可以利用 mysqladmin修改密碼但是你必須提供目前的密碼

432 連線 MySQL

mysql -uroot -p密碼 (-p和密碼之間不能有空白) 或 mysql -uroot -p (此方式會在進入後要求密碼) [rootossc phpMyAdmin] mysql -u root -p1234

Welcome to the MySQL monitor Commands end with or g

Your MySQL connection id is 25 to server version 32354

Type help or h for help Type c to clear the buffer

mysqlgt show databases

+----------+

| Database |

+----------+

| mysql |

| test |

+----------+

2 rows in set (000 sec)

mysqlgt exit

Bye

[rootossc phpMyAdmin]

433 建立資料庫

可利用 mysqladmin指令建立 CONTACT資料庫 mysqladmin -u root -p1234 create CONTACT

47

或是利用 mysql指令 [rootossc bluepage] mysql -u root -p1234 Welcome to the MySQL monitor Commands end with or g Your MySQL connection id is 1057 to server version 32354 Type help or h for help Type c to clear the buffer mysqlgt create database CONTACT Query OK 1 row affected (000 sec) mysqlgt show databases +----------+ | Database | +----------+ | CONTACT | | address | | hello | | mysql | | nuke | | test | +----------+ 6 rows in set (000 sec) mysqlgt exit

434 建立資料表

編寫 adresssql內容如下 -- Table structure for table address CREATE TABLE address ( id int(11) NOT NULL auto_increment name varchar(20) NOT NULL default tel varchar(15) NOT NULL default PRIMARY KEY (id) ) TYPE=MyISAM

48

-- Dumping data for table address INSERT INTO address VALUES (1林小明0800016888) INSERT INTO address VALUES (2黃大雄0800016888) INSERT INTO address VALUES (3劉小芬0800024365) 然後執行此 sql script mysql -u root -p1234 CONTACT lt addresssql 或是利 mysql command [rootossc bluepage] mysql -u root -p1234 Welcome to the MySQL monitor Commands end with or g Your MySQL connection id is 1090 to server version 32354 Type help or h for help Type c to clear the buffer mysqlgt use CONTACT Database changed Database changed mysqlgt CREATE TABLE address ( -gt id int(11) NOT NULL auto_increment -gt name varchar(20) NOT NULL default -gt tel varchar(15) NOT NULL default -gt PRIMARY KEY (id) -gt ) TYPE=MyISAM Query OK 0 rows affected (000 sec) mysqlgt INSERT INTO address VALUES (1林小明0800016888) Query OK 1 row affected (000 sec) mysqlgt INSERT INTO address VALUES (2黃大雄0800016888) Query OK 1 row affected (000 sec) mysqlgt INSERT INTO address VALUES (3劉小芬0800024365) Query OK 1 row affected (000 sec) mysqlgt exit Bye

49

第五章 實用範例

51 任務一Web Base客戶通訊錄

任職於開放科技公司的林小明前些日子在最符合成本效益的條件下快

速地完成公司網站的建置老闆因此對小明讚譽有加最近因為公司存放客戶資

料的 SQL Server主機屢遭病毒攻擊加上作業系統本身的問題當機次數頻繁

老闆希望能儘快把公司的客戶通訊錄程式移轉到較穩定的環境上因為此客戶通

訊錄程式最主要給內部人員使用所以介面美觀並不特別要求只求穩定且能快

速得到查詢結果老闆希望在短時間先看到程式的雛型並鍵入資料對其效率

及穩定性進行測試因為上次小明表現突出所以這次不可能的任務自然又落到

小明身上 小明想來想去既然要快速又穩定他而且又不希望所有人都得安裝 Client

程式於是小明決定)捨棄他的舊愛「Delphi+MS SQL」投向新歡「Apache + MySQL + PHP」利用此架構來設計一個簡單實用的Web Base客戶通訊錄程式

511 Web Base客戶通訊錄架構

此程式需要建立 CONTACT的資料庫並建立 adress Tables其結構如下表建立步驟請參考第三章 欄位名稱 資料型態 長度 說明 id INT (自動編號) 連絡人編號 name varchar文字 20 連絡人姓名 tel Varchar文字 15 連絡人電話 Web Base通訊錄共有下列幾個檔案功能如下表

檔案名稱 說明 Indexhtml Web Base通訊錄首頁 addphp 新增連絡人的 php程式 searchphp 尋找連絡人的 php程式 editphp 具有更新及刪除功能的 php程式

50

我們將這些檔案放至varwwwhtmlbluepage (預設無 bluepage目錄)

512 Web Base通訊錄測試

httpwwwopencombluepage 新增資料

圖 5-1 新增連絡人

圖 5-2 填入資料

51

圖 5-3 新增成功

搜尋及異動資料

圖 5-4 搜尋通訊錄

52

圖 5-5 編輯資料

圖 5-6 更新資料

513 程式內容及說明

lt-- 程式範例indexhtml--gt lthtmlgt ltheadgtlttitlegt通訊錄lttitlegtltheadgt ltbodygt ltcentergt

53

lth2gt通訊錄lth2gtlthrgt lta href=indexhtmlgt通訊錄ltagt | lta href=addphpgt新增連絡人ltagt | lta href=searchphpgt搜尋通訊錄ltagt ltcentergt ltbodygt lthtmlgt lt-- 程式範例addphp --gt lthtmlgt ltheadgtlttitlegt新增連絡人lttitlegtltheadgt ltbodygt ltcentergtlth2gt新增連絡人lth2gtltcentergtlthrgt lt 取得欄位資料 if (isset($_POST[Name]) ampamp isset($_POST[Tel]) ) $name = $_POST[Name] $tel = $_POST[Tel] 檢查是否有輸入欄位資料 if ($name = ampamp $tel = ) 建立 SQL字串 $sql = INSERT INTO address (name tel) values( $sql= $name $tel) 建立 MySQL 連結 $link = mysql_connect(localhostroot1234) 選擇資料庫 mysql_select_db(CONTACT) 執行 SQL指令 mysql_query($sql) mysql_close($link) echo ltfont color=redgt新增連絡人成功ltfontgtltbrgt gt ltform action=addphp method=postgt lttable border=0 width=300gt lttrgtlttdgt姓名 lttdgt

54

lttdgtltinput type=text name=Name size=20 maxlength=10gtlttdgtlttrgt lttrgtlttdgt電話 lttdgt lttdgtltinput type=text name=Tel size=20 maxlength=20gtlttdgtlttrgt lttrgtlttd colspan=2 align=centergt ltinput type=submit value=新增連絡人gtlttdgtlttrgt lttablegt ltformgt ltbrgtlta href=indexhtmlgt通訊錄ltagt | lta href=addphpgt新增連絡人ltagt | lta href=searchphpgt搜尋通訊錄ltagt ltbodygt lthtmlgt

lt-- 程式範例searchphp --gt lthtmlgt ltheadgtlttitlegt搜尋通訊錄lttitlegtltheadgt ltbodygt ltcentergtlth2gt搜尋通訊錄lth2gtlthrgt lt if (isset($_POST[Search])) 建立資料庫連結並選定資料庫 $link = mysql_connect(localhostroot1234) mysql_select_db(CONTACT) 建立基本的 SQL字串 $sql = SELECT FROM address 檢查是否輸入姓名 if (chop($_POST[Name]) = ) $name = name LIKE $_POST[Name] else $name = 檢查是否輸入電話號碼 if (chop($_POST[Tel]) = ) $tel = tel LIKE $_POST[Tel] else $tel =

55

if條件組合 SQL字串 if (chop($name) = ampamp chop($tel) = ) $sql= WHERE $name AND $tel elseif (chop($name) = ) 只有姓名 $sql = WHERE $name elseif (chop($tel) = ) 只有電話號碼 $sql = WHERE $tel $sql= ORDER BY name 最後加上排序 $result = mysql_query($sql) 取得欄位數 $total_fields = mysql_num_fields($result) echo lttable border=1gt echo lttrgtlttdgt編號lttdgtlttdgt姓名lttdgtlttdgt電話lttdgtlttd colspan=2gt功能選項lttdgtlttrgt 表格顯示查詢結果 while ($rows = mysql_fetch_array($result MYSQL_NUM)) echo lttrgt for ($i = 0 $i lt $total_fields $i++) echo lttdgt$rows[$i]lttdgt echo lttdgtlta href=editphpaction=editampid= echo $rows[0]gtltbgt編輯ltbgtlttdgt echo lttdgtlta href=editphpaction=delampid= echo $rows[0]gtltbgt刪除ltbgtlttdgt echo lttrgt echo lttablegtlthrgt mysql_free_result($result) mysql_close($link) gt ltcentergt ltform action=searchphp method=postgt lttable border=0 width=450gt lttrgtlttdgt搜尋姓名 lttdgt lttdgtltinput type=text name=Name size=10 maxlength=20gtlttdgtlttrgt lttrgtlttdgt搜尋電話 lttdgt lttdgtltinput type=text name=Tel

56

size=20 maxlength=20gtlttdgtlttrgt lttrgtlttd colspan=2 align=centergt ltinput type=submit name=Search value=搜尋gtlttdgtlttrgt lttablegt ltformgt ltbrgtlta href=indexhtmlgt通訊錄ltagt | lta href=addphpgt新增連絡人ltagt | lta href=searchphpgt搜尋通訊錄ltagt ltbodygt lthtmlgt

lt ob_start() gt lt-- 程式範例editphp --gt lthtmlgt ltheadgtlttitlegt編輯通訊錄lttitlegtltheadgt ltbodygt lt 取得 URL 參數 $id = $_GET[id] $action = $_GET[action] 建立資料庫連結 $link = mysql_connect(localhostroot1234) mysql_select_db(CONTACT) 選擇資料庫 執行的操作 switch ($action) case update 更新 取得欄位資料 $name = $_POST[Name] $tel = $_POST[Tel] $sql = UPDATE address SET name=$name tel=$tel WHERE id=$id mysql_query($sql) 執行 SQL指令 mysql_close($link) header(Location searchphp) 轉向到 serachphp break case del 刪除 $sql = DELETE FROM address WHERE id=$id

57

mysql_query($sql) 執行 SQL指令 mysql_close($link) header(Location searchphp) 轉向到 serachphp break case edit 編輯 $sql = SELECT FROM address WHERE id=$id $result = mysql_query($sql) 執行 SQL指令 $row = mysql_fetch_row($result) 取回記錄 $name = $row[1] 取得欄位 name $tel = $row[2] 取得欄位 tel mysql_close($link) 顯示編輯表單 gt ltcentergtlth2gt更新通訊錄lth2gtltcentergtlthrgt ltform action=editphpaction=updateampid=lt echo $id gt method=postgt lttable border=0 width=300gt lttrgtlttdgt姓名 lttdgt lttdgtltinput type=text name=Name size=20 maxlength=10 value=lt echo $name gtgtlttdgtlttrgt lttrgtlttdgt電話 lttdgt lttdgtltinput type=text name=Tel size=20 maxlength=20 value=lt echo $tel gtgtlttdgtlttrgt lttrgtlttd colspan=2 align=centergt ltinput type=submit value=更新連絡人gtlttdgtlttrgt lttablegt ltformgt ltbrgtlta href=indexhtmlgt通訊錄ltagt | lta href=addphpgt新增連絡人ltagt | lta href=searchphpgt搜尋通訊錄ltagt lt break gt ltbodygt lthtmlgt

58

52 任務二Web Base群組軟體 ( twig )

順利完成Web Base客戶通訊錄程式測試一段時間後「Apache + MySQL + PHP」架構的穩定與快速巳深得老闆與公司所有同事的認同隨著公司業績蒸

蒸日上人員組織編罝愈來愈龐大跨部門的會議愈來愈多業務員每日排滿拜

訪客戶的行程跟客戶的 Email的往來也愈來愈頻繁 愈來愈多部門的同事希望公司能建置一套群組軟體提供 web mail可讓業

務人員方便收發 mail還有連絡人議事日程待辦工作書簽等功能讓整個

公司運作及個人時間管理更有效率

老闆問小明對這些需求有什麼看法小明認為如果這些功能完全由程式部

門開發必定曠日費時而且耗費公司資源小明在網路尋找是否有提供這些功能

的Free Software皇天不負苦心人小明發現了TWIG (The Web Information Gateway) httptwigscrewdrivernet這個群組軟體它在 Web 上整合郵件新聞聯絡人議事日程工作序書簽等功能非常符合公司的需求 Step 1 下載 twig-277targz 下載網址 httptwigscrewdrivernetdownloadphp3

Step 2 解開 twig-277targz tar -xzvf twig-277targz

59

Step 3 執行安裝動作安裝到 varwwwhtmltwig 目錄 cd twig-277 twig-install varwwwhtmltwig

Step 4 建立 MySQL 資料庫(twig)及各資料表

cd setup mysql -u root -p1234 mysqlgt create database twig Query OK 1 row affected (001 sec) mysqlgt quit mysql -u root ndashp1234 twiglt twigtablemysql

Step 5 修改 configincphp3 參數設定 vi varwwwhtmltwigconfigconfigincphp3 $config[fromdomain] = opencom 網域 $config[language] = chinesebig5 中文訊息 $config[imap_port] = 143notls

60

Step 6 修改連結 MySQL 的帳號密碼 vi varwwwhtmltwigconfigdbconfigincphp3 $dbconfig[sqlusername] = root username $dbconfig[sqlpassword] = 1234 password

Step 7 其他設定檔

vi etchttpdconfhttpdconf 加入 AddType applicationx-httpd-php php3 在 DirectoryIndex最後加入 indexphp3 DirectoryIndex indexhtml indexhtmlvar indexphp3 在 AddDefaultCharset ISO-8859-1加上 AddDefaultCharset ISO-8859-1

vi etcphpini register_globals = On service httpd restart Step 8 sendmail 設定 vi etcmailsendmailcf在 264 行前面加上並重新啟動 sendmail「service snedmail restart」 262 SMTP daemon options 263 264 O DaemonPortOptions=Port=smtpAddr=127001 Name=MTA 265 266 SMTP client options 267 O ClientPortOptions=Family=inet Address=00

61

Step 9 檢查設定有無錯誤 http主機名稱twigtestphp3

62

Step 10 登入 twig ( http主機名稱twig)

63

第六章 維護及更新程序

61 日常維護

系統管理員最好定期以 root 身份登入看看信件在 RedHat Linux 中有一支 logwatch 程式會定時去分析 log file如果發現異常便會發信給 root除此之外筆者建議讀者平時就檢查 MySQL log file ( varlogmysqldlog)是否有異常情形

62 更新程序

讀者可至httprpmfindnet 尋找MySQL相關套件至於升級的相關步驟請參

考Linux OS SOP 第 54節

63 備份重要檔案

預設 MySQL 的 DB 檔案是存在 varlibmysql 內以 DB名稱為目錄目錄

內就是該 DB 的所有資料通常得定期備份還有 MySQL的設定檔 etcmycnf也別忘了一起備份

64 離線備份與還原

641 離線備份

預設 MySQL 的 DB 檔案是存在 varlibmysql 內以 DB 名稱為目錄目錄內

就是該 DB 的所有資料像 CRM 這個 DB就是存在 varlibmysqlCRM 內在備份前因為怕資料尚未完全寫入磁碟而且 MySQL 會 Lock 在使用的 DB 檔案所以應該是要先把 MySQL 先 Shutdown 一下整個備份的程序可以下像下面的指令去完成 cd varlibmysql

64

service mysqld stop tar cvfz CRM_db_20030905tgz CRM service mysqld start 對這樣就可以了 不過要注意的是怕 DB 內每個 Tables 間的資料有關關

聯性所以最好是把整個 DB 一次備起來單獨只備哪個 Tables 的檔案以後回存時怕會有資料關聯不一致的問題

642 離線還原

DB 發生錯誤而要回存時其實也不難先找出最近一次完整正常的備份先把現在錯誤的網頁或 DB 先更名或 tar 起來再把好的備份給解開回原來目錄位

置就行了需要注意的是 MySQL 服務最好也是要先停止回存完成後再啟動服務回存 DB 的整個程序可能像下面 cd varlibmysql service mysqldstop mv CRM CRM_OLD tar xvfz CRM_db_20030905tg service mysqld start

65 線上備份與還原

651 線上備份

使用像上面的檔案方式備份是個不錯的方法它最少可以保持該主機某個時間點的完整檔案備份但還是有一些問題需要考慮到有些主機就不只建立一個 DB 而已總不能為了備份某個 DB 而把整個 MySQL 服務停止備份檔案的方式回存在原主機上一定適用但假如 MySQL 版本升級或是在那天該網頁空間需遷機移機到別的主機時那就沒人敢保證備出來的資料檔可以用所以我們可以考慮另一種備份的方式是使用 MySQL 本身提供的功能 MySQL Data Dump指令是 mysqldump

65

使用 MySQL 的 Dump 功能可以把 DB 的結構資料或結構加資料 Dump 成文字檔 mysqldump 指令提供的彈性很大你可以選擇把整個 DB Dump 成一個檔或是每個 Table 為一個檔甚至是把結構檔和資料分開儲存都

可以 mysqladmin -uroot -p flush-logs mysqldump CRM -uroot -p --opt gt CRM_20030905sql (CRM 是 DB 名稱 opt 是一個使用完整 Dump 參數) 假如只是要單獨 Dump 某個 Table 時只要在上面的指令後轉出符號 gt 前加個 Table 名稱就可以如只要 phpbb2_users 這個 Table 的 Dump 時只要下 mysqldump CRM -uroot -p --opt CUSTOMER gt CRM_CUSTOMER_20030905sql

652 線上還原

若要回存整個資料庫只需將壓縮的備份檔還原成 Dump 的檔案再用下面的指令回存 mysql CRM -uroot -p lt CRM_20030905sql 這邊需注意的是若建立備份時是以--opt或--add-drop-table為參數時回存的 動作是先將舊的 Table 先刪除重建 Table 的結構後再把 Data 匯入所以回存後所有的資料會回到你當時備份那個時間點因此在回存資料時可以考慮把現有錯誤或不完整的 DB 先備份一份下來以備不時之需或是拿來比對錯誤的地

方在那裡當然你也可以把資料回存到另一個測試用的 DB 內只要把上面指令

的 DB 名稱改成你的測試用 DB 名稱即可 使用這種回存方式 MySQL 服務不需停止也不會動到其他正在使用的 DB 在一些提供 MySQL 服務的虛擬主機可用這種方式作你自己的 DB 備份及回存

66

另外假如你是系統重建或是移機時切需在新的 MySQL 內新建一個空白 DB 後才行作回存的工作你可以用下面的指令建立 mysql -uroot -p -e CREATE DATABASE CRM (上面的 CRM是你要新建的 DB 名稱) 另一種作法先用 mysql 指令進入 mysql client console 然後再用 CREATE DATABASE CRM 這樣就行了記得尾端要加個 符號該行指令才會執行

67

第七章 問題與解答

Q1RedHat 90預附的 MySQL到底有無支援 Transcation機制 Ans MySQL自 32334a之後的 MySQL-Max版本加入 InnoDB的資料庫類型透過

InnoDBMySQL同樣可以進行 COMMIT與 ROLLRACK的動作RedHat 90預附的 MySQL為 32354a-11巳支援 InnoDB的資料庫類型不過必須做以

下設定 1cp usrsharedocmysql-server-32354amy-mediumcnf to etcmycnf 2 vi etcmycnf 將以下設定前的拿掉 innodb_data_home_dir = varlibmysql innodb_data_file_path = ibdata110Mautoextend innodb_log_group_home_dir = varlibmysql innodb_log_arch_dir = varlibmysql 3service mysqld restart 如此一來各位在建立Table時便可指定Table Type為 innodb ( ex create table with type=innodb ) Q2如何解決 php+mysql 許功蓋等字變亂的問題 Ans 方法一 【確定 MySQL 預設的字元集】 1 打開 WinMySQLadmin 管理畫面(在視窗右下角狀態列紅綠燈圖示中按滑鼠

右鍵點選 Show me 選項) 2 點選管理畫面中 [Variables] 標籤選項其中 character_set變數就是您預設

字元集的變數其預設是 latin1 字元集(我們要將他改回 big5)而 chatacters_set 變數則是 MySQL 可以支援哪些字元集 【修改預設字元集變數 character_set 】 1 請點選管理畫面中 [myini Setup] 標籤選項設定 myini 2 按一下 [Pick-up and Edit myini values] 按鈕以便編輯目前的 myini 設定 3 在 [mysqld] 設定區塊底下新增一行 default-character-set = big5 變數設

68

定 4 新增一個 [client] 設定區塊並加入第三步驟的變數設定(游標往下移到空白處新增兩行 [client] 和 default-character-set=big5) 5 按一下畫面左下方 [Save Modification] 按鈕儲存設定 6 重新啟動 MySQL 或 Windows 方法二 Server端注意事項 phpini 中有關的設定為(預設值) Magic quotes for incoming GETPOSTCookie data magic_quotes_gpc = On Use Sybase-style magic quotes (escape with instead of ) magic_quotes_sybase = Off Client端注意事項 1中文資料送進 mysql 前請用 addslashes($str) 處理 2處理後送進 mysql 時請用 括起來並在參數後留一個空白如 $sql = UPDATE ezf_table set tablename=$tname tableend=$endtime table inguser=$tguser tableingid=$tguserid tableallnumber=$tnumber tableloca l=$tablelocal tableanyone=$tableopen tabletext=$ttext WHERE tableid=$t ableid tablename=$tname c 取出時請用 stripslashes($str) Q3MySQL root 密碼忘了該怎麼辦 Ans 1先停掉 mysql etcrcdinitdmysql stop 2以--skip-grant-table 的參數啟動 mysql safe_mysql --skip-grant-tableamp 3 更改 root 密碼 mysql mysql mysqlgt UPDATE user SET password=password(newpassword)

69

WHERE user=root mysqlgt FLUSH PRIVILEGES mysqlgt exit 4停掉 mysql再重跑 mysqladmin -uroot -p shutdown Enter password 輸入新設定的密碼 etcrcdinitdmysql start

Q4NULL值問題

Ans

NULL值的概念是造成 SQL的新手的混淆的普遍原因他們經常認為 NULL是和一個空字符串的一樣的東西不是這樣的例如下列語句是完全不同的

mysqlgt INSERT INTO my_table (phone) VALUES (NULL)

mysqlgt INSERT INTO my_table (phone) VALUES ()

兩個語句把值插入到 phone 列但是第一個插入一個 NULL值而第二個插入一個空字符串第一個的含義可以認為是ldquo電話號碼不知道而第二個則可意味

著ldquo她沒有電話

在 SQL中NULL值在于任何其他值甚至 NULL值比較時總是假的(FALSE)包含 NULL的一個表達式總是產生一個 NULL值除非在包含在表達式中的運算符和函數的文檔中指出在下列例子所有的列返回 NULL

mysqlgt SELECT NULL1+NULLCONCAT(InvisibleNULL)

如果你想要尋找值是 NULL的列你不能使用=NULL測試下列語句不返回任

何行因為對任何表達式expr = NULL是假的

mysqlgt SELECT FROM my_table WHERE phone = NULL

要想尋找 NULL值你必須使用 IS NULL測試下例顯示如何找出 NULL電話號碼和空的電話號碼

70

mysqlgt SELECT FROM my_table WHERE phone IS NULL mysqlgt SELECT FROM my_table WHERE phone =

在 MySQL中就像很多其他的 SQL服務器一樣你不能索引可以有 NULL值的列你必須聲明這樣的列為 NOT NULL而且你不能插入 NULL到索引的

列中

當用 LOAD DATA INFILE 讀取數據時空列用更新如果你想要在一個列中有

NULL值你應該在文本文件中使用N字面上的詞NULL也可以在某些情形下使用

當使用 ORDER BY時首先呈現 NULL值如果你用 DESC以降序排序NULL值最後顯示當使用 GROUP BY時所有的 NULL值被認為是相等的

為了有助于NULL的處理你能使用 IS NULL和 IS NOT NULL運算符和 IFNULL()函數

對某些列類型NULL值被特殊地處理如果你將 NULL插入表的第一個TIMESTAMP 列則插入當前的日期和時間如果你將 NULL插入一個AUTO_INCREMENT 列則插入順序中的下一個數字

Q5如何將圖片存放於 MySQL中

Ans

Step 1建立資料庫 test

Step 2 建立表格 binary_data

CREATE TABLE binary_data (

id INT(4) NOT NULL AUTO_INCREMENT PRIMARY KEY

description CHAR(50)

bin_data LONGBLOB

filename CHAR(50)

filesize CHAR(50)

filetype CHAR(50)

71

)

Step 3 利用 storephp 寫入圖片

storephp 程式碼

ltHTMLgt ltHEADgtltTITLEgtStore binary data into SQL DatabaseltTITLEgtltHEADgt ltBODYgt lt code that will be executed if the form has been submitted

if ($submit) mysql_connect(localhostrootYOUR_PASSWORD) mysql_select_db(test) $data=Base64_Encode(fread(fopen($form_data r) filesize($form_data))) $result=MYSQL_QUERY(INSERT INTO binary_data (descriptionbin_datafilenamefilesizefiletype) VALUES ($form_description$data$form_data_name$form_data_size$form_data_type)) $id= mysql_insert_id() print ltpgtThis file has the following Database ID ltbgt$idltbgt MYSQL_CLOSE() else else show the form to submit new data

gt

ltform method=post action=ltphp echo $PHP_SELF gt enctype=multipartform-datagt File Descriptionltbrgt ltinput type=text name=form_description size=40gt ltINPUT TYPE=hidden name=MAX_FILE_SIZE value=4000000gt ltbrgtFile to uploadstore in databaseltbrgt ltinput type=file name=form_data size=40gt ltpgtltinput type=submit name=submit value=submitgt ltformgt lt

72

gt ltBODYgt ltHTMLgt

Step 3 利用 storephp 取出圖片

getdataphp 程式碼

lt Syntax getdataphp3id=ltidgt if($id) you may have to modify login information for your database server MYSQL_CONNECT(localhostrootYOUR_PASSWORD) mysql_select_db(test) $query = select bin_datafiletype from binary_data where id=$id $result = MYSQL_QUERY($query) $data = Base64_Decode(MYSQL_RESULT($result0bin_data)) $type = MYSQL_RESULT($result0filetype) Header( Content-type $type) echo $data gt

Q6MySQL裝好之後啟動時或是執行 mysqladmin會出現如下訊息 Cant connect to local MYSQL Server through Socket varlibmysqlmysqlsock或是

Cant connect to local MYSQL Server through Socket tmpmysqldsock

Ans 可能有下列幾個原因

1這個 mysqldsock 不見了被某人刪除了或是被一些系統自動執行程式給刪

了例如有些 cron任務便會設定定期刪除 tmp 裡的東西所以呢您只能修改

cron 裡的設定讓它不要清除 mysqldsock 2在啟動時也可以改變 mysqldsock的位置您在啟動 MySQL的時候可以加入此參數usrlocalmysqlbinsafe_mysqld --user=mysql --socket=其他路

徑socket amp 同時得去設定環境變數 MYSQL_UNIX_PORT的值以指定新的

73

路徑 3若是您沒改 MYSQL_UNIX_PORT的值那麼您可以在執行指令的時候才打

例如mysqladmin --socket=其他路徑socket version Q7How to get the last insert id Ans CREATE TABLE product ( id INT(4) NOT NULL AUTO_INCREMENT PRIMARY KEY description VARCHAR(50) ) 1利用 SQL的話 mysqlgt insert into product(description) values(123) Query OK 1 row affected (000 sec) mysqlgt select last_insert_id() +------------------+ | last_insert_id() | +------------------+ +------------------+ 1 row in set (000 sec) ======================================== 2如果是 PHP的話 你可以用mysql_insert_id()取得該 id PHP example $result=MYSQL_QUERY(INSERT INTO product (description) VALUES ($description)) $id= mysql_insert_id() print This file has the following Database ID $id Q8如何將文字檔匯入資料庫 Ans $addr=homehttpdhtmlphpschool001txt $sql_select = load data infile $addr into table test fields terminated by t 解說 $sql_select = load data infile 文字檔名 into table 表格名 fields terminated by

74

t

(欄位分隔以 TAB鍵) 該文字檔須與資料表欄位格式相符 例如欄位有三個 則文字檔為每行一筆資料如下 欄 1資料ltTABgt欄 2資料ltTABgt欄 3資料 欄 1資料ltTABgt欄 2資料ltTABgt欄 3資料 欄 1資料ltTABgt欄 2資料ltTABgt欄 3資料 欄 1資料ltTABgtltTABgt欄 3資料

Q9如何撰寫 MySQL C API Ans Step 1利用文字編輯器撰寫以下程式碼 mysqlcc

include ltstdiohgt

include ltmysqlmysqlhgt

int main (int argc char argv[])

MYSQL mysql

MYSQL_RES res

MYSQL_ROW row

if (argc = 2)

fputs (Usage myc ltdatabasegt stderr)

return 1

if ((mysql_connect(ampmysqllocalhostrootYour_Password)))

fputs (Error connecting stderr)

abort()

75

if (mysql_select_db(ampmysqlargv[1]))

fputs (Error selecting database stderr)

abort()

if (mysql_query(ampmysqlSELECT FROM test_table))

fputs (Error processing query stderr)

abort()

if ((res = mysql_store_result(ampmysql)))

fputs (Error storing results stderr)

abort()

while((row = mysql_fetch_row(res)))

uint i = 0

for (i=0 i lt mysql_num_fields(res) i++)

printf(s row[i])

printf(n)

return 0

Step 2 Compile

gcc -Iusrlocalmysqlinclude -Lusrlocalmysqllibmysql mysqlcc ndashlm -lmysqlclient

(其中 include path與 library path取決於你的 MySQL安裝路徑)

76

如果執行時發生如下 error Run problemerror in loading shared libraries libmysqlclientsoX 將你的 MySQL library path(for exampleusrlocalmysqllibmysql) 加入etcldsoconf and run sbinldconfig -v Q9ASP + MySQL 範例程式 Ans Dim myconn As New ADODBConnection Dim myrs As New Recordset Dim mySQL As String Dim myrows As Long myconnOpen DSN=MyODBCsample mySQL = SELECT from user myrsSource = mySQL Set myrsActiveConnection = myconn myrsCursorLocation = adUseClient myrsOpen myrows = myrsRecordCount myrsClose myconnClose 可參考 httpwwwdwamnetmysqlasp_myodbcasp 有詳細的資料 Q10如何將 MySQL中的資料庫匯出成txt檔 Ans select from TableName into outfile textxls all result fields will seperate by tab

77

第八章 參考資料

英文部份 網址 1 httpwwwmysqlcom MySQL 網站有第一手有關 MySQL的資料 2 httpwwwmysqlcomdocenReplicationhtml 有關 MySQL Replication 的文件 3 httpwwwgeocitiescomsqlhomefaqstore_blobhtml 如何在 MySQL 存放 BLOB的資料 4httpwwwsapdborg 有關 SAP跟 MySQL相關合作的網站 書藉 1 Cooking with MySQL

Paul DuBois has selected sample recipes from the hundreds youll find in his book MySQL

Cookbook In this third and final series of excerpts showcasing these recipes learn how to

compute team standings how to calculate the differences between successive Dec 26

2002 2 Tips for Building Web Database Applications with PHP and MySQL by Hugh E Williams co-author of Web Database Applications with PHP amp MySQL 04042002

3 Managing and Using MySQL 2nd Edition By Tim King George Reese Randy Jay Yarger

4 MySQL Cookbook By Paul DuBoisPublisher OReillyPub Date October 2002

中文部份

78

1 httplinuxtncedutwtechdocmysqlmysql_docmanual_tochtml MySQL 中文手冊 2 httpchenshloxaedutwphpZ_1php PHP+MySQ程式研習設計網站 3 httplinuxtncedutwtechdocbanicdownhtml PHP 4 手冊 4 httpwwwtncedutwadmin_zonephp台南縣教育網網路中心有很多 Linux相關文件 5 httpdobtncedutw網站建置百寶箱有很多 PHP MySQL 相關範例程式 5 httpwwwdbworldcomtw資料庫專家電子雜誌介紹資料庫的重要觀念及名詞

79

附錄一 SQL Command 介紹

SQL (讀音ess-que-el) 是一種結構查詢語法SQL 使用於資料庫交流

傳遞相容於 ANSI (American National Standards Institute) 是一套標準的關聯

式資料庫語言 SQL 語言是執行更新或從資料系統獲取資料一般常見的關聯

資料庫系統都有提供 SQL 如 Oracle Sybase Microsoft SQL Server Access Ingres 等雖然大部份的資料庫都有提供 SQL 但也多提供了自已獨特的語

法造成了不相容的情形但標準基本的語法是相通的如Select Insert Update Delete Create and Drop 每一個系統都有支援

Table相關 Command

Create Table

關聯式資料庫包含有很多元件稱為資料表(tables) 把資料或訊息放在資

料表中 資料表是以不同的名稱做分別資料表由欄列所構成的二維陣列

欄包含欄位名資料型態 及其他可判斷的資訊列是由全部欄位構成一筆一

筆的紀錄 create table 語法用在建立一個新的資料表語法格式如下

create table tablename (column1 data type column2 data type column3 data type)

Format of create table if you were to use optional constraints

create table tablename (column1 data type [constraint] column2 data type [constraint] column3 data type [constraint]) [ ] = optional

Note You may have as many columns as youd like and the constraints are optional

80

Example

create table employee (first varchar(15) last varchar(20) age number(3) address varchar(30) city varchar(20) state varchar(20))

注意建立資料表格式要以括號把前後框住而最後以(分號)做結尾

欄位名不要超過 30個字元長而且不要使用 sql 的關鍵字(如 where select等)而在後面接是型態的宣告(如字串數字日期格式等)

資料型態是來描述欄位的方式如一個欄位Last_Name 是一個姓氏可以使用varchar (可變動長度字串) 資料型態

以下是幾個常見的資料庫型態 char(size) 固定長度字串最長為 255 位元 varchar(size) 變動長度字串最大字元數以 size 來指定 number(size) 數值格式可以是整數也可以是小數最大數字以 size 位數判

斷未指定小數位數由系統內定 date 日期格式 number(sized) 數值格式最大數字以 size 位數判斷d 為小數位數整數位

數為 size-d 位

有何限制當資料表被建立通常有一或數個欄位是要使用來做關聯的功

能 例如unique 限制(唯一值)兩筆記錄不可以相同的值 not null (非空值)該欄位一定要輸入資料不可是空的primary key (主鍵)是每一筆記錄識別的主要方式

Drop a table drop table 刪除資料表(其中的資料也會一併刪除)

drop table tablename

Example

81

drop table 和刪除全部資料是不同的刪除全部資料欄位名稱資訊等還會

存在但刪除資料表會把這一些也一併移除掉

如何查詢資料

Select 基本用法

select 語法是關連式資料庫最常用的部份可以取得你想要的資料這是一個

簡單的範例 select column1[column2etc] from tablename [where condition] [] = optional 在 select 之後所列欄位名則是要顯示的資料部份你可以一一列出各欄位

名或是以 (星號)來代表選擇全部的欄位 from 之後放資料表名稱 where 子句 (選項) 指定要過濾的條件符合者才會顯現 where 可使用的條件運算元 = 等於 gt 大於 lt 小於 gt= 大或等於 lt= 小或等於 ltgt 大相等 LIKE 相似 For example select first last city

82

from empinfo where first LIKE Er 以Er 為開頭的字串就符合要以單引號框住 Or you can specify select first last from empinfo where last LIKE s 最後一字為 S 就符合 select from empinfo where first = Eric 則表示 first name 一定要是 Eric 才可以 範例資料表empinfo 統計函數

MIN 傳回指定欄位最小值

MAX 傳回指定欄位最大值

SUM 傳回指定欄位總和

AVG 傳回指定欄位平均值

COUNT 傳回指定欄位的筆數

COUNT() 傳回資料庫中的總筆數

統計函數使用於資料表中的數值欄位配合 SELECT 語法使用 只用於總結特定單一欄位可以配合 GROUP BY 做篩選但也可以不使用 GROUP BY 語句For example

SELECT AVG(salary) FROM employee

83

傳回全部 salary 平均值

Another example

SELECT AVG(salary) FROM employee WHERE title = Programmer

傳回 salary 平均值條件為 employees 資料表中當 title 等於 Programmer

Example

SELECT Count() FROM employees

傳回 employees 資料表中紀錄總筆數

GROUP BY 語法 SELECT column1 SUM(column2) FROM list-of-tables GROUP BY column-list The GROUP BY 語句可以先以所列的欄位為條件分組排序在一起(可以多欄

位) example 要列出每一個 dept 中最高 salary 值 SELECT max(salary) dept FROM employee GROUP BY dept HAVING 語法

SELECT column1 SUM(column2) FROM list-of-tables GROUP BY column-list HAVING condition

HAVING 子句是 GROUP BY 的一部份用來過濾在 GROUP BY 所選出的資料功能如同 select 命令中 where 條件式一樣只是 HAVING 必需配合 GROUP BY 使用

我們以例子來說明我們要取得每一公司名及每一公司的薪水平均值輸入如下

84

SELECT dept avg(salary) FROM employee GROUP BY dept

但如果我們只列出薪資平均值超過 20000元的公司資料

SELECT dept avg(salary) FROM employee GROUP BY dept HAVING avg(salary) gt 20000

ORDER BY子句語法

SELECT column1 SUM(column2) FROM list-of-tables ORDER BY column-list [ASC | DESC]

[ ] =選項

ORDER BY是一個選項子句當你以排序方式來顯示資料(正向由小到大反向由大到小)以指定的欄位資料做排序

ASC = 正向- 預設值 DESC = 反向排序

For example

SELECT employee_id dept name age salary FROM employee_info WHERE dept = Sales ORDER BY salary

以上列出公司代號公司名銷售員人名年紀及薪資而條件是公司名為 Sales 顯示順序以薪資多少排序(由小到大為預設值)

如果要以多個欄位做排序要以逗號做分隔如下

SELECT employee_id dept name age salary FROM employee_info WHERE dept = Sales ORDER BY salary age DESC

85

結合條件及布林運算 SELECT column1 SUM(column2) FROM list-of-tables WHERE condition1 AND condition2 AND運算可以結兩個或以上的條件放在 WHERE子句中 兩者都要為真才

會顯示該筆記錄 OR 運算可以結兩個或以上敘述放在 WHERE子句中只要其中一個為直就

會顯示該筆記錄 For example SELECT employeeid firstname lastname title salary FROM employee_info WHERE salary gt= 5000000 AND title = Programmer 必需要薪資大於等於 50000而且職稱為 Programmer同時符合才會顯示該筆資料 以下以括號括住雖然不是必需的但如此比較容易讀 SELECT employeeid firstname lastname title salary FROM employee_info WHERE (salary gt= 5000000) AND (title = Programmer) 另外範例 SELECT firstname lastname title salary FROM employee_info WHERE (title = Sales) OR (title = Programmer) 條件為只要是 Sales 或 Programmer 職稱的就會被列出 IN and BETWEEN 子句

SELECT column1 SUM(column2) FROM list-of-tables WHERE column3 IN (list-of-values) SELECT column1 SUM(column2) FROM list-of-tables WHERE column3 BETWEEN value1 AND value2 IN 子句使用在列舉項目的使用上也就是分別測試是否符合所列的值 For example

86

SELECT employeeid lastname salary FROM employee_info WHERE lastname IN (Hernandez Jones Roberts Ruiz) 條件為姓氏(astname)要符合 Hernandez Jones Roberts or Ruiz 其中一個才會被傳回 IN運算元也可以使用 OR 的語法來取代如下結果相同 SELECT employeeid lastname salary FROM employee_info WHERE lastname = Hernandez OR lastname = Jones OR lastname = Roberts OR lastname = Ruiz 但使用 IN 句子比較短也比較易懂 你也可以使用 NOT IN 來去掉不要的記錄 BETWEEN 運算元使用在判斷是否存在兩個數值之間 For example SELECT employeeid age lastname salary FROM employee_info WHERE age BETWEEN 30 AND 40 傳回年紀 30歲到 40歲之間的資料(含 30及 40歲者) 相同的也可以使用以下語法來達到相同的結果 SELECT employeeid age lastname salary FROM employee_info WHERE age gt= 30 AND age lt= 40 你也可使用 NOT BETWEEN 來濾掉中間值的資料 數學運算 標準 ANSI SQL-92 提供以下運算

87

+ 加

- 減

餘數

餘數為除法後剩整數這不在標準的 ANSI SQL 中但大部份的資料庫都會支

援這運算元以下列出有用的函數雖不在 ANSI SQL-92 提供但一般資料庫

也會支援他們

ABS(x) 傳回 x 絕對值

SIGN(x) returns the sign of input x as -1 0 or 1 (negative zero or positive respectively)

MOD(xy) 餘數 - returns the integer remainder of x divided by y (同 xy)

FLOOR(x) 傳回小或等於 x 的最大整數值

CEILING(x) or CEIL(x)

傳回大或等於 x 的最小整數值

POWER(xy) x的 y 次方

ROUND(x) 把 x 四捨五入為整數

ROUND(xd) 四捨五入取到小數 d 位

SQRT(x) x 開平方

For example SELECT round(salary) firstname FROM employee_info 傳回薪資取到整數位

如何新增資料

insert 加入一筆新紀錄到資料表中 insert into tablename (first_columnlast_column) values (first_valuelast_value) [] = optional Example insert into employee

88

(first last age address city state) values (Luke Duke 45 2130 Boars Nest Hazard Co Georgia) Note 字串要以單引號住如string 數字框住也無妨 insert into 後面接資料表名稱再接以括號括住的欄位名在 values 後括號分別對映各欄位的值 以上的例子新增了一筆名(first) 為 Luke而住所(state) 為 Georgia 的資料

如何刪除資料

delete 可以刪除單筆或多筆紀錄 delete from tablename where columnname OPERATOR value [and|or column OPERATOR value] [ ] = optional Examples delete from employee Note 如果你沒有指定 where 子句那麼全部的紀錄都會被刪除 delete from employee where lastname = May delete from employee where firstname = Mike or firstname = Eric delete from 接著資料表名 再接著是條件式判斷沒有條件式則全部紀錄會

被刪除

如何更新資料

update 用來更新你所指定的記錄要和 WHERE 配合小心使用 語法 update tablename set columnname = newvalue[nextcolumn = newvalue2] where columnname OPERATOR value [and|or column OPERATOR value] [] = optional Examples

89

update phone_book set area_code = 623 where prefix = 979 update phone_book set last_name = Smith prefix=555 suffix=9292 where last_name = Jones update employee set age = age+1 where first_name=Mary and last_name=Williams

90

附錄二Replication

測試環境

RedHat 90 + MySQL 32358 MySQL資料庫路徑 varlibmysql MySQL設定檔 etcmycnf Master IP 1921680100 Slave IP 1921680200 請至下列網址下載最新MySQL 32358套件並利用rpm ndashUvh 更新 httpupdatesredhatcom9enosi386

圖 最新 MySQL 套件

測試架構圖

91

1921680100

1921680200Master Server

erveSlave S r

圖 測試架構圖

測試步驟

Master server 部份 Step1 確認 MasterSlave機器上所裝的 MySQL版本能進行

replication( 32329 or higher ) Step2 在 Master MySQL上開放一個帳號給 Slave mysql ndashu root ndashp mysqlgtGRANT FILE ON TO repl1921680200 IDENTIFIED BY lsquoabc123rsquo mysqlgtq 上面是 Master開放一個帳號 repl密碼 abc123給 IP1921680200有檔案處理

的權限 Step3 shutdown MySQL on the Master mysqladmin ndashu root ndashp shutdown Step4 備份 Master所有資料庫 tar ndashcvf tmpmysql-snapshottar varlibmysql 注意tar的時候MySQL是要在 stop情況下 在mysql (wwwmysqlcom) 網站的FAQ有不用shutdown的方法

92

Step5 在 master機器上修改etcmycnf 在[mysqld]區段內加入參數 log-bin server-id=這邊設定 server-id=1 sql-bin-update-same binlog-do-db=CRM只針對 CRM資料庫做紀錄 Step6 Restart MySQL on the master service mysqld start 此時因為有加入 log-bin 參數因此開始有 index產生了在varlibmysql目錄下

有index檔案紀錄資料庫的異動 log Slave server 部份 Step1 在 slave設定etcmycnf 在[mysqld]區段加入 master-host= master-user= master-password= master-port= server-id= 這邊設定 master-host=1921680100 master-user=repl master-password=abc123 master-port=3306 server-id=2 master-connect-retry=60預設重試間隔 60秒 replicate-do-db=CRM告訴 slave只做 CRM資料庫的更新 log-slave-updates Step2 將 master上的 mysql-snapshottar copy到 slave上 用 ftp傳到 slave的tmp Step3 解壓縮 Master資料庫至 Slave Server上 cd varlib tar xvf tmpmysql-snapshottar chown ndashR mysqlmysql mysql

93

chmod ndashR 770 mysql (視情況) Step4 Restart MySQL on the slave server 這時在varlibmysql目錄會出現 masterinfo此檔案紀錄了 Master MySQL server的資訊

狀況測試

One-way replication

1921680100

1921680200Master Server

erveSlave S r

圖 One-way replication架構圖 Step1 Master跟 Slave網路及服務都正常情況下由 Master端異動資料後 到 Slave端瀏覽資料檢視是否有進行 replication Step2 模擬 Slave Server 當機 可用在於 slave真的當機或是 Slave 不一定需要一直跟 master connect將Slave MySQL server shutdown由 Master端異動資料到 slave端瀏覽此時Slave應該沒有被 replication 更新然後再將 Slave端 MySQL server start起來

預設 60秒後 Slave會嘗試跟 Master要求進行 replication再去 Slave端檢視是否有更新資料

94

Step3 模擬 Master當機因為是設定 One-way replication一旦 Master Server Slave端沒有 Master的 source可以 download Two-way replication 基於 Master當機狀況於是發展雙向 Replication即 1921680100 ( Host A ) 1921680200 ( Host B )都分別擔任 MasterSlave身分

1921680100

1921680200er

Server B MasterSlave Server

Server A MasterSlave Serv

圖 Two-way replication架構圖 以下是針對兩台 MySQL伺服器進行雙向 Replication Step1觀念同單向 replication只是改成 Master也有 Slave身分 Slave也有Master的身分先分別在 Server AServer B 都去 grant一個進行 replication的身分 [A]mysqlgtGRANT FILE ON TO repl1921680200 IDENTIFIED BY lsquoabc123rsquo [B]mysqlgt GRANT FILE ON TO repl1921680100 IDENTIFIED BY lsquoabc123rsquo Step2做完單向 replication後stop Server Aserver B MySQL service此時 AB資料是一樣的

95

修改etcmycnf設定 範例 Server A [mysqld] datadir=varlibmysql socket=varlibmysqlmysqlsock server-id=1 log-bin sql-bin-update-same binlog-do-db=CRM master-host=1921680200 master-user=repl master-password=abc123 log-slave-updates master-connect-retry=60 replicate-do-db=CRM Server B [mysqld] datadir=varlibmysql socket=varlibmysqlmysqlsock server-id=2 log-bin sql-bin-update-same binlog-do-db=CRM master-host=1921680100 master-user=repl master-password=abc123 log-slave-updates master-connect-retry=60 replicate-do-db=CRM 分別 start Server AServer B MySQL後此時雙方都是 MasterSlave身分一旦哪一方資料異動就會通知對方來 replication-若 replication失效則必須將Server AServer B的masterinfo及index00x 都砍掉然後分別 restart MySQL server進行測試檢視成果 實務上通常如果需要做Two-way replication通常會搭配Virtual Server使用

96

在前端架設一台Virtual Server不過此部份不在此份SOP討論範圍內有興趣

的讀者可參考 httpwwwlinuxvirtualserverorg 網站

1921680100 1921680200

Host A MasterSlave Server

Host B MasterSlave Server

Virtual Host

圖 Virtual Server + Two-way replication 架構圖

97

圖 High Availability Linux Virtual Server架構圖

98

  • COSA-SOP-03-006
  • 第一章 簡介
    • 11適用對象 (Audience)
    • 12 MySQL本身
    • 13 MySQL 40版跟50版重大的改進功能
    • 14 各家資料庫軟體比較
      • 第二章 前置需求
      • 第三章 安裝
        • 31 MySQL安裝
        • 32 phpMyAdmin安裝
        • 33 升級及注意事項
          • 第四章 MySQL管理
            • 41 Webmin 管理介面
            • 42 phpMyAdmin 的操作介面
            • 43管理指令介紹
              • 431 利用mysqladmin設定root的密碼
                  • 第五章 實用範例
                    • 51 任務一Web Base客戶通訊錄
                    • 52 任務二Web Base群組軟體 ( twig )
                      • 第六章 維護及更新程序
                        • 61 日常維護
                        • 62 更新程序
                        • 63 備份重要檔案
                        • 64 離線備份與還原
                        • 65 線上備份與還原
                          • 第七章 問題與解答
                          • 第八章 參考資料
                          • 附錄一 SQL Command 介紹
                          • 附錄二Replication
Page 2: DataBase Server Standard Operation Procedureebooks.lib.ntu.edu.tw/1_file/oss/63/93doc4-5.pdf · 業務的公司帶來了不少壓力,譬如微軟,甲骨文 ... 外的錢用在第三方的資料庫產品上,譬如就可以不用再購買甲骨文公司

經濟部工業局

九十三年度自由軟體產業推動計畫專案

開放原始碼軟體標準作業程序書

作者群

編號 程序書名稱 作者 COSA-SOP-03-001 開放原始碼軟體標準作業程序書總論 吳鴻煦 COSA-SOP-03-002 Linux 作業系統標準作業程序書 洪宗勝 COSA-SOP-03-003 網站伺服器架設標準作業程序書 林彥明 COSA-SOP-03-004 電子郵件伺服器架設標準作業程序書 簡碩文 COSA-SOP-03-005 資源分享伺服器架設標準作業程序書 顏朝蒼 COSA-SOP-03-006 資料庫伺服器架設標準作業程序書 林彥明 COSA-SOP-04-001 OpenWebmail架設標準作業程序書 林毓能 COSA-SOP-04-002 PHPNUKE 內容管理系統標準作業程序書 蔡邦洲 COSA-SOP-04-003 Linux 防火牆標準作業程序書 吳鴻煦 COSA-SOP-04-004 Tomcat 應用伺服系統標準作業程序書 林彥明 COSA-SOP-04-005 OpenOfficeorg標準作業程序書 江明宗

審查者

許清琦 中華民國開放系統協會 理事長 柯森 國家高速網路與計算中心

指導委員

郭大維 台大資工系 教授 陳秋華 台科大資工系 教授 劉龍龍 翔威國際股份有限公司 總經理

單 位

主辦單位經濟部工業局 委託單位財團法人資訊工業策進會 執行單位中華民國開放系統協會

目錄

第一章 簡介 5

11適用對象 (AUDIENCE) 5 12 MYSQL本身 5 13 MYSQL 40版跟 50版重大的改進功能 7 14 各家資料庫軟體比較 8

第二章 前置需求 11

第三章 安裝 12

31 MYSQL安裝 12 32 PHPMYADMIN安裝 17 33 升級及注意事項 24

第四章 MYSQL管理 27

41 WEBMIN 管理介面 27 412建立資料庫 27 412 建立資料表 30 413 使用者管理 35

42 PHPMYADMIN 的操作介面 39 421建立資料庫 39 422 建立資料表 39 423使用者管理 44

43管理指令介紹 46 431 利用mysqladmin設定root的密碼46 432 連線 MySQL 47 433 建立資料庫 47 434 建立資料表 48

第五章 實用範例 50

51 任務一WEB BASE客戶通訊錄 50 511 Web Base客戶通訊錄架構 50 512 Web Base通訊錄測試 51 513 程式內容及說明 53

52 任務二WEB BASE群組軟體 ( TWIG ) 59

第六章 維護及更新程序 64

61 日常維護 64

3

62 更新程序 64 63 備份重要檔案 64 64 離線備份與還原 64

641 離線備份64 642 離線還原65

65 線上備份與還原 65 651 線上備份65 652 線上還原66

第七章 問題與解答 68

第八章 參考資料 78

附錄一 SQL COMMAND 介紹 80

附錄二REPLICATION 91

4

第一章 簡介

MySQL 是一種 跨平台多使用者多執行緒支援 SQL語言 (結構化查詢語言)執行速度快廣受全球網站大量採用的網路資料庫系統最重要的

是在大部份情形下使用 MySQL 是完全免費的( MySQL自 32319之後已改為 GPL版權宣告囉)整體而言MySQL 免費原始碼開放入門容易

執行速度快跨平台 (亦支援 Windows 2000)支援工具眾多等特性十分適合中小企業用來開發各種資訊系統企業不必再花費數十萬元去購買一些費而

不惠的資料庫 MySQL 沒有所謂連線使用者限制其它商用資料庫系統一定數量以上的

連線使用者數可是要付出相當可觀的費用的像 Yahoo等大公司也是用 MySQL 哩 連這麼大的入口網站都安心地挑選 MySQL 一般的中小企業更

無需擔心 MySQL的穩定性

11適用對象 (Audience)

本 SOP的對象適合一般的使用者及系統管理者編排的方式大部分皆採操

作步驟的模式進行方便一般入門的使用者

12 MySQL本身

在 Unix平台上最受到歡迎的一套資料庫系統就是 MySQL MySQL於1990中期開始發展當時Michael Mothnty Widenius在位於瑞典的 TcX DataKonsultAB開始開發這套軟體並在 1995 年公開釋放第一個版本

MySQL 同時擁有頗為可觀跨平台能力它能 Unix Like平台工作例如 AIX

SolarisFreeBSD及 Linux也能在 Mac OS X及Windows NT2000 server亦或是 Microsoft Wrokstation 系統上如 9xMEXP上開發程式更重要的是它是

讓您擁有原始碼 在 MySQL 在 323之後的版本在每個系統元件上在釋放時都會加上一個

完成度的註解如由「gamma」階段到「stale」階段「beat」階段到「alpha」階段階段愈低愈不穩定查詢目前的發展版本可以在 MySQL 參考手冊及線上

文件找到

5

MySQL經過考驗證明是值得信賴的資料庫系統如果您是 stable版的使用者您大可以放心MySQL對於版本的控制是十分注意並提供廣大的使用者原始碼下載Bug也因此很快就被解決

MySQL主要是以技術支援和經銷資料庫為主和 Red Hat在 Linux上的做

法非常類似背後則是由創投資金在支持客戶可以下載 MySQL並遵照 GPL授權規定使用MySQL公司則以技術服務作為收入

MySQL也提供付費的解決方案給想要整合 MySQL和其他軟體產品但是

又不想讓客戶取得程式碼的公司MySQL表示MySQL資料庫在全球已經有

400萬的使用者但是並不清楚其中有多少付費用戶到目前為止MySQL也已經引起企業用戶的興趣甚至包括 Yahoo和 Google等網際網路的領導廠商

MySQL最原始的構想嚐試克服自由軟體資料庫系統「mSQL」的一些功能

上的限制MySQL成長進步的非常的快尤其當贊助者由網際網路應用中看出

MySQL能提供網站所需強健資料庫的潛能對於 MySQL成長的速度幫助不少

而近來更有令人振奮的好消息( 2003 年 5月 ) ERP的龍頭 SAP正在與 MySQL就開放源代碼資料庫軟體進行合作這項

交易將會使得 MySQL這樣更小的公司能夠加速它的開發計畫此舉將允許

MySQL公司在未來的兩年內為其資料庫軟體添加更高端的一些特徵MySQL公司的首席執行官 Marten Mickos 說公司早在四年前就希望能夠進軍高端資料

庫業務這次交易在資料庫市場上還引起了另外一些影響它給那些開發資料庫

業務的公司帶來了不少壓力譬如微軟甲骨文以及 IBM等因為這項交易為

這些公司不斷樹立了一個越來越強大的開放源代碼軟體的競爭者而開放源代碼

軟體最終也許會吞噬它們的資料庫市場 SAP公司一直是銷售那些管理核心業務的一些軟體譬如會計軟體存貨

管理軟體這些產品以前一直是各大公司的暢銷軟體為了吸引那些中等規模的

公司客戶從而進行業務擴張這家德國的公司開始在他們的一些產品中加入SAP DB這是一個開放源代碼的資料庫軟體該軟體就可以免除 SAP公司客戶花額外的錢用在第三方的資料庫產品上譬如就可以不用再購買甲骨文公司的資料庫

軟體 根據他們的技術交錯式授權協議MySQL公司將會主宰 SAP DB的絕大部

分再開發業務並且 MySQL也會使用該程式的設計作為該公司未來改進的資料

庫軟體的模型SAP公司的一位元代表稱隨著 MySQL資料庫軟體的不斷成

熟SAP公司將會用新的 MySQL的資料庫軟體代替 SAP DBMickos 說在

6

這項交易中這家瑞典公司 MySQL將會得到其軟體的版稅但他拒絕透露這次

合作的一些經濟方面的細節 SAP的代表稱在更長一段時間後該開放源代碼資料庫軟體將會和 SAP

公司的旗艦產品 R3一起銷售 不久之後SAP與 MySQL將會完成他們合作計畫的第一個階段那

就是 SAP將會發佈一個 MySQL的資料庫版本從而它可以無縫地替代現在使

用的 SAP DB這對 MySQL而言無異是如虎添翼想必在不久的將來MySQL定能擔任企業更重要的任務

13 MySQL 40版跟 50版重大的改進功能

以下是 40版跟 50版一些重大的改進功能 MySQL 40 版httpwwwmysqlcomdocenNews-40xhtml

內建提供InnoDB table type支援 standard binaries adding transactions row-level locking 和foreign keys

提昇 Query速度 改善 boolean mode truncation and phrase searching全文檢索效

率 加強MERGE tables 並支援INSERT statements and

AUTO_INCREMENT 在SELECT 中支援UNION 語法 支援Multi-table DELETE statements libmysqld the embedded server library 更多的GRANT 參數來加強安全性 提供更多動態參數來降低停止 MySQL的必要 改善 replication code and features 改善執行效率並增加可靠性

MySQL 50 版httpwwwmysqlcomdocenTODO_MySQL_50html改善執行效率並增加可靠性 提供 Stored Procedures 機制 支援 cursor Dynamic length rows for HEAP tables Add true VARCHAR support

7

加強執行效率 更好的國際語系支援 提供可用性

14 各家資料庫軟體比較

目前市面上較被廣為使用資料庫除了 MySQL之外尚有下列幾種

1 MS SQL Server 2000 2 Oracle 8i 3 IBM DB2 4 Informix

過去幾年來在總值 120億美元的資料庫市場上如果廠商想要誇讚自家的

產品那就一定得要有強大的資料庫支援最嚴苛的任務才站得上檯面不過

到了今天似乎光是這樣並不夠客戶除了要求足以負擔嚴苛的任務之外還希

望擁有聰明又便宜的資料庫 Meta Group的分析師 Charlie Garry表示 ( 2003 年 5 月)MySQL的商業

模式是以開放原始碼為基礎以便讓客戶盡快接受 MySQLGarry指出MySQL甚至適合用在甲骨文IBM微軟等大廠爭相搶食的企業資料中心

Information Resources的資訊長 Marshall Gibbs就表示他們沒有任何品

牌的偏好只要「功能效能價格的最佳組合」 由研究近兩年來資料庫客戶

愈來愈注重總體成本(圖 1-1)

8

圖 1-1 資料庫優先性

整體擁有成本 大致說來MySQL是免費的MySQL需要付費的規定只限於下列兩種情

形 1 以 Embedded的方式使用 MySQL 2 使用 MySQL的商業用途軟體

且其授權費用一台 MySQL Pro License只需美金 $440比起其他任何資料庫軟體來得容易負擔多了加上其易於管理的特性著實可大大降低企業資料

庫的整體擁有成本 擴充性

MySQL同時提供高度多樣性能夠提供給很多不同的使用者介面包括命

令列操作網頁瀏覽器以及各式各樣的程式語言介面例如JavaC++PerlPHP及 PhythonMySQL可用 UnixWindows以及 OS2hellip等平台因此它可以用個人電腦或是伺服器上 性能 事實上大部份的網站的開發者都認為 MySQL是目前市面跑得最快的資料

9

庫對資料庫的最佳化主要在於你對他的設定和資料庫結構的設計如果你的

資料庫結構設計得非常差你的存取速度還是會受到影響而變得比較慢

10

第二章 前置需求

在安裝 MySQL之前請確定 Apache及 MySQL亦巳安裝相關步驟請參考

Apache SOP安裝 Apache及 PHP相關章節

11

第三章 安裝

31 MySQL安裝

在 RedHat 90上安裝 MySQL是件很容易的事因為 RedHat 90提供了一

個很方便的 GUI套件管理工具「redhat-config-packages」各位只要把 RedHat 90第一片光碟放入並以 root的身份登入系統鍵入 redhat-config-packages勾選「SQL資料庫伺服器」即可然後按「更新」如果遇到任何相依性問題

系統會提示您更換光碟片 ( 圖 3-1 ~ 3-3 ) Step 1 執行 redhat-config-packes

圖 3-1

Step 2 選擇資料伺服器

12

圖 3-2

Step 3檢查是否安裝成功 待安裝後您可以用利用「rpm -qa | grpe ^mysql」檢查是否安裝成功

圖 3-3

啟動 MySQL ( Command Mode )馬上啟動 MySQL的指令為「service mysqld start」如果您希望一開機就自動啟動 MySQL請執行「chkconfig mysqld on」

13

圖 3-4

啟動 MySQL ( WebMin 介面 ) 我們也可以利用WebMin 來啟動 MySQL步驟如下 Step 1登入Webmin

圖 3-5 登入WebMin

Step 2 選擇伺服器

14

圖 3-6 伺服器畫面

Step 2 選擇 MySQL資料庫伺服器

圖 3-7 伺服器畫面

15

Step 3 啟動 MySQL資料庫伺服器

圖 3-8 啟動 MySQL

更改資料庫管理者密碼

成功啟動 MySQL後因為資料庫管理者預設沒有密碼建議使用前更改系

統管理者密碼請輸入下列指令

mysqladmin ndashu root ndashh cosaexamplecom password lsquo1234rsquo -u 表示使用者帳號root 為 MySQL預設的管理帳號

-h 表示 MySQL主機的主機名稱也可使用 IP Address password 表示使用者的密碼因為字串請使用單引號將密碼括起來

圖 3-9 修改 MySQL 的密碼

16

32 phpMyAdmin安裝

本書除了會介紹利用當今 Linux上最紅的整合管理工具Webmin 來管理

MySQL外還會為各位介紹專門管理 MySQL的工具 phpMyAdmin phpMyAdmin是免費的 PHP原始程式碼的Web網站可用來管理整個

MySQL伺服器這是一套Web介面的 MySQL管理程式支援中文的使用者介

面 phpMyAdmin只需透過瀏覽器就可管理 MySQL伺服器換句話說不論

MySQL是安裝在 Linux或是Windows 作業系統都可以使用相同步驟在

MySQL上建立資料庫(Database)資料表(Table)和編輯紀錄(Record) Step 1 下載phpMyAdmin ( httpwwwphpmyadminnet )選擇最櫎新穩定的版

本 253

圖 3-10 httpwwwphpmyadminnet

17

圖 3-11 下載 phpMyAdmin-253-phptarbz2

Step 2 將 phpMyAdmin-253-phptarbz2收至 tmp 並執行下列指令將其解壓

縮至varwww tar jxvf phpMyAdmin-253-phptarbz ndashC varwwwhtml

圖 3-12 解壓縮安裝 phpMyadmin-253

Step 3 為了操作方便起見建立 Soft link ln ndashs phpMyAdmin-253 phpMyAdmin

圖 3-13 修改 phpMyadmin 設定檔 configincphp

18

Step 4 修改 phpMyadmin 設定檔 configincphp gedit varwwwhtmlphpMyAdminconfigincphp

圖 3-14 configincphp設定檔

Step 5 設定顯示行號以方便修改 configincphp 設定檔

19

圖 3-15 顯示行號

Step 6 修改下列設定 第 39 行 設定 phpMyAdmin的 URL 第 69 行 MySQL Server 的 ip 第 80 行 利用何帳號存取 MySQL 第 81 行 如果 root有設定 password此處即填入 root的 password

30 In most cases you can leave this variable empty as the correct value

31 will be detected automatically However we recommend that you do

32 test to see that the auto-detection code works in your system A good

33 test is to browse a table then edit a row and save it There will be

34 an error message if phpMyAdmin cannot auto-detect the correct value

35

36 If the auto-detection code does work properly you can set to TRUE the

37 $cfg[PmaAbsoluteUri_DisableWarning] variable below

38

39 $cfg[PmaAbsoluteUri] = httpossccosaorgtwphpMyAdmin

hellip

20

hellip

69 $cfg[Servers][$i][host] = localhost MySQL hostname or IP address hellip 80 $cfg[Servers][$i][user] = root MySQL user

81 $cfg[Servers][$i][password] = 1234 MySQL password (only needed

圖 3-16 修改 configincphp

21

圖 3-17 修改 configincphp

圖 3-18 修改 configincphp p

Step 7 設定語系

22

圖 3-19 設定語系

圖 3-20 執行 phpMyAdmin

23

33 升級及注意事項

RedHat 90附的 MySQL版本為 323 MySQL所釋出最新穩定版本為

40若是您不想用系統預附的 323請先利用下列移除之前 323的版本

rpm ndashe mysql-devel rpm ndashe mysql-server rpm ndashe mysql --nodeps 然後到下列網址下載您所想要的版本進行安裝在這裏我們用 4014版為例 Step 1 下載相關套件( httpwwwmysqlcomdownloadsmysql-40html )

圖 3-21 Download MySQL 4014 相關 RPM Step 2 利用 rpm 指令安裝

24

圖 3-22 Install MySQL 4014 相關 RPM

圖 3-23 Install MySQL 4014 相關 RPM

Step 3 啟動 MySQL

25

圖 3-24 啟動 MySQL 4014 並修改密碼

26

第四章 MySQL管理

本章將我們介紹利用WebminphpAdminCommand的方式建立一個名為

CONTACT的資料庫內有一個 address的 Table作為我們客戶通訊錄程式使

用的資料庫

41 Webmin 管理介面

412建立資料庫

Step 1 登入Webmin

圖 4-1 登入WebMin

Step 2 點選伺服器

27

圖 4-2 伺服器畫面

Step 3 點選 MySQL資料庫伺服器

圖 4-3 MySQL資料庫伺服器

28

Step 4 建立一個新的資料庫

圖 4-4 建立 MySQL資料庫

Step 5 建立名為 CONTACT的資料庫

29

圖 4-5 指定資料庫名稱

412 建立資料表

假設我們要建立一個名為 address的 Table其結構如下 欄位名稱 資料型態 長度 說明 id INT (自動編號) 連絡人編號 name varchar文字 20 連絡人姓名 tel Varchar文字 15 連絡人電話 Step 1 選擇 CONTACT資料庫

30

圖 4-6 選擇資料庫

Step 2 指定欄位數目

31

圖 4-7 設定欄位數目

Step 3設定表格欄位屬性

圖 3-8 設定表格欄位屬性

Step 4建立表格資料

32

圖 4-9 建立表格資料

圖 4-10 檢視資料

33

圖 4-11 新增資料

圖 4-12

34

圖 4-13

413 使用者管理

接下來我們要利用Webmin 來建立資料庫使用者並給予某些權限 Step1建立使用者

35

圖 4-14 選擇使用者權限

圖 4-15

36

Step2 賦予權限

圖 4-16

Step3 權限列表

37

圖 4-17

38

42 phpMyAdmin 的操作介面

421建立資料庫

Step 填入資料庫名稱並按「建立」

圖 4-18建立資料庫

422 建立資料表

Step1 填入資料表名稱並指定欄位數量 執行

39

圖 4-19填入資料表名稱並指定欄位數量

Step2 設定欄位屬性

圖 4-20設定欄位屬性

40

Step3 phpMyAdmin會產生相關的 SQL Command

圖 4-21 資料表結構及相關 SQL Command

Step4新增 Record

41

圖 4-22

圖 4-23

42

圖 4-24

圖 4-25

43

423使用者管理

Step1建立使用者

圖 4-26

44

圖 4-27

Step2 給予權限

圖 4-28

Step3權限列表

45

圖 4-29

43管理指令介紹

431 利用 mysqladmin設定 root的密碼

當您在Windows 或 Linux 中安裝好 MySQL後系統會自動幫您建立兩個

帳分別是 root 和 匿名者MySQL的 root 跟 Linux 最高權限使用者 root無關MySQL的 root使用者相當於 MS SQL 中的 sa 帳號擁有最高的 Database管理權限但系統預設 MySQL的 root 是不需要密碼所以通常我們一安裝

MySQL後首要任務便是修改 root的密碼 我們可以利用 mysqladmin工具或是直接修改 MySQL內部資料庫的使用者資

料 mysqladmin ndashu root ndashh cosaexamplecom password lsquo1234rsquo

46

-u 表示使用者帳號root 為 MySQL預設的管理帳號

-h 表示 MySQL主機的主機名稱也可使用 IP Address password 表示使用者的密碼因為字串請使用單引號將密碼括起來 密碼設定完成之後還是可以利用 mysqladmin修改密碼但是你必須提供目前的密碼

432 連線 MySQL

mysql -uroot -p密碼 (-p和密碼之間不能有空白) 或 mysql -uroot -p (此方式會在進入後要求密碼) [rootossc phpMyAdmin] mysql -u root -p1234

Welcome to the MySQL monitor Commands end with or g

Your MySQL connection id is 25 to server version 32354

Type help or h for help Type c to clear the buffer

mysqlgt show databases

+----------+

| Database |

+----------+

| mysql |

| test |

+----------+

2 rows in set (000 sec)

mysqlgt exit

Bye

[rootossc phpMyAdmin]

433 建立資料庫

可利用 mysqladmin指令建立 CONTACT資料庫 mysqladmin -u root -p1234 create CONTACT

47

或是利用 mysql指令 [rootossc bluepage] mysql -u root -p1234 Welcome to the MySQL monitor Commands end with or g Your MySQL connection id is 1057 to server version 32354 Type help or h for help Type c to clear the buffer mysqlgt create database CONTACT Query OK 1 row affected (000 sec) mysqlgt show databases +----------+ | Database | +----------+ | CONTACT | | address | | hello | | mysql | | nuke | | test | +----------+ 6 rows in set (000 sec) mysqlgt exit

434 建立資料表

編寫 adresssql內容如下 -- Table structure for table address CREATE TABLE address ( id int(11) NOT NULL auto_increment name varchar(20) NOT NULL default tel varchar(15) NOT NULL default PRIMARY KEY (id) ) TYPE=MyISAM

48

-- Dumping data for table address INSERT INTO address VALUES (1林小明0800016888) INSERT INTO address VALUES (2黃大雄0800016888) INSERT INTO address VALUES (3劉小芬0800024365) 然後執行此 sql script mysql -u root -p1234 CONTACT lt addresssql 或是利 mysql command [rootossc bluepage] mysql -u root -p1234 Welcome to the MySQL monitor Commands end with or g Your MySQL connection id is 1090 to server version 32354 Type help or h for help Type c to clear the buffer mysqlgt use CONTACT Database changed Database changed mysqlgt CREATE TABLE address ( -gt id int(11) NOT NULL auto_increment -gt name varchar(20) NOT NULL default -gt tel varchar(15) NOT NULL default -gt PRIMARY KEY (id) -gt ) TYPE=MyISAM Query OK 0 rows affected (000 sec) mysqlgt INSERT INTO address VALUES (1林小明0800016888) Query OK 1 row affected (000 sec) mysqlgt INSERT INTO address VALUES (2黃大雄0800016888) Query OK 1 row affected (000 sec) mysqlgt INSERT INTO address VALUES (3劉小芬0800024365) Query OK 1 row affected (000 sec) mysqlgt exit Bye

49

第五章 實用範例

51 任務一Web Base客戶通訊錄

任職於開放科技公司的林小明前些日子在最符合成本效益的條件下快

速地完成公司網站的建置老闆因此對小明讚譽有加最近因為公司存放客戶資

料的 SQL Server主機屢遭病毒攻擊加上作業系統本身的問題當機次數頻繁

老闆希望能儘快把公司的客戶通訊錄程式移轉到較穩定的環境上因為此客戶通

訊錄程式最主要給內部人員使用所以介面美觀並不特別要求只求穩定且能快

速得到查詢結果老闆希望在短時間先看到程式的雛型並鍵入資料對其效率

及穩定性進行測試因為上次小明表現突出所以這次不可能的任務自然又落到

小明身上 小明想來想去既然要快速又穩定他而且又不希望所有人都得安裝 Client

程式於是小明決定)捨棄他的舊愛「Delphi+MS SQL」投向新歡「Apache + MySQL + PHP」利用此架構來設計一個簡單實用的Web Base客戶通訊錄程式

511 Web Base客戶通訊錄架構

此程式需要建立 CONTACT的資料庫並建立 adress Tables其結構如下表建立步驟請參考第三章 欄位名稱 資料型態 長度 說明 id INT (自動編號) 連絡人編號 name varchar文字 20 連絡人姓名 tel Varchar文字 15 連絡人電話 Web Base通訊錄共有下列幾個檔案功能如下表

檔案名稱 說明 Indexhtml Web Base通訊錄首頁 addphp 新增連絡人的 php程式 searchphp 尋找連絡人的 php程式 editphp 具有更新及刪除功能的 php程式

50

我們將這些檔案放至varwwwhtmlbluepage (預設無 bluepage目錄)

512 Web Base通訊錄測試

httpwwwopencombluepage 新增資料

圖 5-1 新增連絡人

圖 5-2 填入資料

51

圖 5-3 新增成功

搜尋及異動資料

圖 5-4 搜尋通訊錄

52

圖 5-5 編輯資料

圖 5-6 更新資料

513 程式內容及說明

lt-- 程式範例indexhtml--gt lthtmlgt ltheadgtlttitlegt通訊錄lttitlegtltheadgt ltbodygt ltcentergt

53

lth2gt通訊錄lth2gtlthrgt lta href=indexhtmlgt通訊錄ltagt | lta href=addphpgt新增連絡人ltagt | lta href=searchphpgt搜尋通訊錄ltagt ltcentergt ltbodygt lthtmlgt lt-- 程式範例addphp --gt lthtmlgt ltheadgtlttitlegt新增連絡人lttitlegtltheadgt ltbodygt ltcentergtlth2gt新增連絡人lth2gtltcentergtlthrgt lt 取得欄位資料 if (isset($_POST[Name]) ampamp isset($_POST[Tel]) ) $name = $_POST[Name] $tel = $_POST[Tel] 檢查是否有輸入欄位資料 if ($name = ampamp $tel = ) 建立 SQL字串 $sql = INSERT INTO address (name tel) values( $sql= $name $tel) 建立 MySQL 連結 $link = mysql_connect(localhostroot1234) 選擇資料庫 mysql_select_db(CONTACT) 執行 SQL指令 mysql_query($sql) mysql_close($link) echo ltfont color=redgt新增連絡人成功ltfontgtltbrgt gt ltform action=addphp method=postgt lttable border=0 width=300gt lttrgtlttdgt姓名 lttdgt

54

lttdgtltinput type=text name=Name size=20 maxlength=10gtlttdgtlttrgt lttrgtlttdgt電話 lttdgt lttdgtltinput type=text name=Tel size=20 maxlength=20gtlttdgtlttrgt lttrgtlttd colspan=2 align=centergt ltinput type=submit value=新增連絡人gtlttdgtlttrgt lttablegt ltformgt ltbrgtlta href=indexhtmlgt通訊錄ltagt | lta href=addphpgt新增連絡人ltagt | lta href=searchphpgt搜尋通訊錄ltagt ltbodygt lthtmlgt

lt-- 程式範例searchphp --gt lthtmlgt ltheadgtlttitlegt搜尋通訊錄lttitlegtltheadgt ltbodygt ltcentergtlth2gt搜尋通訊錄lth2gtlthrgt lt if (isset($_POST[Search])) 建立資料庫連結並選定資料庫 $link = mysql_connect(localhostroot1234) mysql_select_db(CONTACT) 建立基本的 SQL字串 $sql = SELECT FROM address 檢查是否輸入姓名 if (chop($_POST[Name]) = ) $name = name LIKE $_POST[Name] else $name = 檢查是否輸入電話號碼 if (chop($_POST[Tel]) = ) $tel = tel LIKE $_POST[Tel] else $tel =

55

if條件組合 SQL字串 if (chop($name) = ampamp chop($tel) = ) $sql= WHERE $name AND $tel elseif (chop($name) = ) 只有姓名 $sql = WHERE $name elseif (chop($tel) = ) 只有電話號碼 $sql = WHERE $tel $sql= ORDER BY name 最後加上排序 $result = mysql_query($sql) 取得欄位數 $total_fields = mysql_num_fields($result) echo lttable border=1gt echo lttrgtlttdgt編號lttdgtlttdgt姓名lttdgtlttdgt電話lttdgtlttd colspan=2gt功能選項lttdgtlttrgt 表格顯示查詢結果 while ($rows = mysql_fetch_array($result MYSQL_NUM)) echo lttrgt for ($i = 0 $i lt $total_fields $i++) echo lttdgt$rows[$i]lttdgt echo lttdgtlta href=editphpaction=editampid= echo $rows[0]gtltbgt編輯ltbgtlttdgt echo lttdgtlta href=editphpaction=delampid= echo $rows[0]gtltbgt刪除ltbgtlttdgt echo lttrgt echo lttablegtlthrgt mysql_free_result($result) mysql_close($link) gt ltcentergt ltform action=searchphp method=postgt lttable border=0 width=450gt lttrgtlttdgt搜尋姓名 lttdgt lttdgtltinput type=text name=Name size=10 maxlength=20gtlttdgtlttrgt lttrgtlttdgt搜尋電話 lttdgt lttdgtltinput type=text name=Tel

56

size=20 maxlength=20gtlttdgtlttrgt lttrgtlttd colspan=2 align=centergt ltinput type=submit name=Search value=搜尋gtlttdgtlttrgt lttablegt ltformgt ltbrgtlta href=indexhtmlgt通訊錄ltagt | lta href=addphpgt新增連絡人ltagt | lta href=searchphpgt搜尋通訊錄ltagt ltbodygt lthtmlgt

lt ob_start() gt lt-- 程式範例editphp --gt lthtmlgt ltheadgtlttitlegt編輯通訊錄lttitlegtltheadgt ltbodygt lt 取得 URL 參數 $id = $_GET[id] $action = $_GET[action] 建立資料庫連結 $link = mysql_connect(localhostroot1234) mysql_select_db(CONTACT) 選擇資料庫 執行的操作 switch ($action) case update 更新 取得欄位資料 $name = $_POST[Name] $tel = $_POST[Tel] $sql = UPDATE address SET name=$name tel=$tel WHERE id=$id mysql_query($sql) 執行 SQL指令 mysql_close($link) header(Location searchphp) 轉向到 serachphp break case del 刪除 $sql = DELETE FROM address WHERE id=$id

57

mysql_query($sql) 執行 SQL指令 mysql_close($link) header(Location searchphp) 轉向到 serachphp break case edit 編輯 $sql = SELECT FROM address WHERE id=$id $result = mysql_query($sql) 執行 SQL指令 $row = mysql_fetch_row($result) 取回記錄 $name = $row[1] 取得欄位 name $tel = $row[2] 取得欄位 tel mysql_close($link) 顯示編輯表單 gt ltcentergtlth2gt更新通訊錄lth2gtltcentergtlthrgt ltform action=editphpaction=updateampid=lt echo $id gt method=postgt lttable border=0 width=300gt lttrgtlttdgt姓名 lttdgt lttdgtltinput type=text name=Name size=20 maxlength=10 value=lt echo $name gtgtlttdgtlttrgt lttrgtlttdgt電話 lttdgt lttdgtltinput type=text name=Tel size=20 maxlength=20 value=lt echo $tel gtgtlttdgtlttrgt lttrgtlttd colspan=2 align=centergt ltinput type=submit value=更新連絡人gtlttdgtlttrgt lttablegt ltformgt ltbrgtlta href=indexhtmlgt通訊錄ltagt | lta href=addphpgt新增連絡人ltagt | lta href=searchphpgt搜尋通訊錄ltagt lt break gt ltbodygt lthtmlgt

58

52 任務二Web Base群組軟體 ( twig )

順利完成Web Base客戶通訊錄程式測試一段時間後「Apache + MySQL + PHP」架構的穩定與快速巳深得老闆與公司所有同事的認同隨著公司業績蒸

蒸日上人員組織編罝愈來愈龐大跨部門的會議愈來愈多業務員每日排滿拜

訪客戶的行程跟客戶的 Email的往來也愈來愈頻繁 愈來愈多部門的同事希望公司能建置一套群組軟體提供 web mail可讓業

務人員方便收發 mail還有連絡人議事日程待辦工作書簽等功能讓整個

公司運作及個人時間管理更有效率

老闆問小明對這些需求有什麼看法小明認為如果這些功能完全由程式部

門開發必定曠日費時而且耗費公司資源小明在網路尋找是否有提供這些功能

的Free Software皇天不負苦心人小明發現了TWIG (The Web Information Gateway) httptwigscrewdrivernet這個群組軟體它在 Web 上整合郵件新聞聯絡人議事日程工作序書簽等功能非常符合公司的需求 Step 1 下載 twig-277targz 下載網址 httptwigscrewdrivernetdownloadphp3

Step 2 解開 twig-277targz tar -xzvf twig-277targz

59

Step 3 執行安裝動作安裝到 varwwwhtmltwig 目錄 cd twig-277 twig-install varwwwhtmltwig

Step 4 建立 MySQL 資料庫(twig)及各資料表

cd setup mysql -u root -p1234 mysqlgt create database twig Query OK 1 row affected (001 sec) mysqlgt quit mysql -u root ndashp1234 twiglt twigtablemysql

Step 5 修改 configincphp3 參數設定 vi varwwwhtmltwigconfigconfigincphp3 $config[fromdomain] = opencom 網域 $config[language] = chinesebig5 中文訊息 $config[imap_port] = 143notls

60

Step 6 修改連結 MySQL 的帳號密碼 vi varwwwhtmltwigconfigdbconfigincphp3 $dbconfig[sqlusername] = root username $dbconfig[sqlpassword] = 1234 password

Step 7 其他設定檔

vi etchttpdconfhttpdconf 加入 AddType applicationx-httpd-php php3 在 DirectoryIndex最後加入 indexphp3 DirectoryIndex indexhtml indexhtmlvar indexphp3 在 AddDefaultCharset ISO-8859-1加上 AddDefaultCharset ISO-8859-1

vi etcphpini register_globals = On service httpd restart Step 8 sendmail 設定 vi etcmailsendmailcf在 264 行前面加上並重新啟動 sendmail「service snedmail restart」 262 SMTP daemon options 263 264 O DaemonPortOptions=Port=smtpAddr=127001 Name=MTA 265 266 SMTP client options 267 O ClientPortOptions=Family=inet Address=00

61

Step 9 檢查設定有無錯誤 http主機名稱twigtestphp3

62

Step 10 登入 twig ( http主機名稱twig)

63

第六章 維護及更新程序

61 日常維護

系統管理員最好定期以 root 身份登入看看信件在 RedHat Linux 中有一支 logwatch 程式會定時去分析 log file如果發現異常便會發信給 root除此之外筆者建議讀者平時就檢查 MySQL log file ( varlogmysqldlog)是否有異常情形

62 更新程序

讀者可至httprpmfindnet 尋找MySQL相關套件至於升級的相關步驟請參

考Linux OS SOP 第 54節

63 備份重要檔案

預設 MySQL 的 DB 檔案是存在 varlibmysql 內以 DB名稱為目錄目錄

內就是該 DB 的所有資料通常得定期備份還有 MySQL的設定檔 etcmycnf也別忘了一起備份

64 離線備份與還原

641 離線備份

預設 MySQL 的 DB 檔案是存在 varlibmysql 內以 DB 名稱為目錄目錄內

就是該 DB 的所有資料像 CRM 這個 DB就是存在 varlibmysqlCRM 內在備份前因為怕資料尚未完全寫入磁碟而且 MySQL 會 Lock 在使用的 DB 檔案所以應該是要先把 MySQL 先 Shutdown 一下整個備份的程序可以下像下面的指令去完成 cd varlibmysql

64

service mysqld stop tar cvfz CRM_db_20030905tgz CRM service mysqld start 對這樣就可以了 不過要注意的是怕 DB 內每個 Tables 間的資料有關關

聯性所以最好是把整個 DB 一次備起來單獨只備哪個 Tables 的檔案以後回存時怕會有資料關聯不一致的問題

642 離線還原

DB 發生錯誤而要回存時其實也不難先找出最近一次完整正常的備份先把現在錯誤的網頁或 DB 先更名或 tar 起來再把好的備份給解開回原來目錄位

置就行了需要注意的是 MySQL 服務最好也是要先停止回存完成後再啟動服務回存 DB 的整個程序可能像下面 cd varlibmysql service mysqldstop mv CRM CRM_OLD tar xvfz CRM_db_20030905tg service mysqld start

65 線上備份與還原

651 線上備份

使用像上面的檔案方式備份是個不錯的方法它最少可以保持該主機某個時間點的完整檔案備份但還是有一些問題需要考慮到有些主機就不只建立一個 DB 而已總不能為了備份某個 DB 而把整個 MySQL 服務停止備份檔案的方式回存在原主機上一定適用但假如 MySQL 版本升級或是在那天該網頁空間需遷機移機到別的主機時那就沒人敢保證備出來的資料檔可以用所以我們可以考慮另一種備份的方式是使用 MySQL 本身提供的功能 MySQL Data Dump指令是 mysqldump

65

使用 MySQL 的 Dump 功能可以把 DB 的結構資料或結構加資料 Dump 成文字檔 mysqldump 指令提供的彈性很大你可以選擇把整個 DB Dump 成一個檔或是每個 Table 為一個檔甚至是把結構檔和資料分開儲存都

可以 mysqladmin -uroot -p flush-logs mysqldump CRM -uroot -p --opt gt CRM_20030905sql (CRM 是 DB 名稱 opt 是一個使用完整 Dump 參數) 假如只是要單獨 Dump 某個 Table 時只要在上面的指令後轉出符號 gt 前加個 Table 名稱就可以如只要 phpbb2_users 這個 Table 的 Dump 時只要下 mysqldump CRM -uroot -p --opt CUSTOMER gt CRM_CUSTOMER_20030905sql

652 線上還原

若要回存整個資料庫只需將壓縮的備份檔還原成 Dump 的檔案再用下面的指令回存 mysql CRM -uroot -p lt CRM_20030905sql 這邊需注意的是若建立備份時是以--opt或--add-drop-table為參數時回存的 動作是先將舊的 Table 先刪除重建 Table 的結構後再把 Data 匯入所以回存後所有的資料會回到你當時備份那個時間點因此在回存資料時可以考慮把現有錯誤或不完整的 DB 先備份一份下來以備不時之需或是拿來比對錯誤的地

方在那裡當然你也可以把資料回存到另一個測試用的 DB 內只要把上面指令

的 DB 名稱改成你的測試用 DB 名稱即可 使用這種回存方式 MySQL 服務不需停止也不會動到其他正在使用的 DB 在一些提供 MySQL 服務的虛擬主機可用這種方式作你自己的 DB 備份及回存

66

另外假如你是系統重建或是移機時切需在新的 MySQL 內新建一個空白 DB 後才行作回存的工作你可以用下面的指令建立 mysql -uroot -p -e CREATE DATABASE CRM (上面的 CRM是你要新建的 DB 名稱) 另一種作法先用 mysql 指令進入 mysql client console 然後再用 CREATE DATABASE CRM 這樣就行了記得尾端要加個 符號該行指令才會執行

67

第七章 問題與解答

Q1RedHat 90預附的 MySQL到底有無支援 Transcation機制 Ans MySQL自 32334a之後的 MySQL-Max版本加入 InnoDB的資料庫類型透過

InnoDBMySQL同樣可以進行 COMMIT與 ROLLRACK的動作RedHat 90預附的 MySQL為 32354a-11巳支援 InnoDB的資料庫類型不過必須做以

下設定 1cp usrsharedocmysql-server-32354amy-mediumcnf to etcmycnf 2 vi etcmycnf 將以下設定前的拿掉 innodb_data_home_dir = varlibmysql innodb_data_file_path = ibdata110Mautoextend innodb_log_group_home_dir = varlibmysql innodb_log_arch_dir = varlibmysql 3service mysqld restart 如此一來各位在建立Table時便可指定Table Type為 innodb ( ex create table with type=innodb ) Q2如何解決 php+mysql 許功蓋等字變亂的問題 Ans 方法一 【確定 MySQL 預設的字元集】 1 打開 WinMySQLadmin 管理畫面(在視窗右下角狀態列紅綠燈圖示中按滑鼠

右鍵點選 Show me 選項) 2 點選管理畫面中 [Variables] 標籤選項其中 character_set變數就是您預設

字元集的變數其預設是 latin1 字元集(我們要將他改回 big5)而 chatacters_set 變數則是 MySQL 可以支援哪些字元集 【修改預設字元集變數 character_set 】 1 請點選管理畫面中 [myini Setup] 標籤選項設定 myini 2 按一下 [Pick-up and Edit myini values] 按鈕以便編輯目前的 myini 設定 3 在 [mysqld] 設定區塊底下新增一行 default-character-set = big5 變數設

68

定 4 新增一個 [client] 設定區塊並加入第三步驟的變數設定(游標往下移到空白處新增兩行 [client] 和 default-character-set=big5) 5 按一下畫面左下方 [Save Modification] 按鈕儲存設定 6 重新啟動 MySQL 或 Windows 方法二 Server端注意事項 phpini 中有關的設定為(預設值) Magic quotes for incoming GETPOSTCookie data magic_quotes_gpc = On Use Sybase-style magic quotes (escape with instead of ) magic_quotes_sybase = Off Client端注意事項 1中文資料送進 mysql 前請用 addslashes($str) 處理 2處理後送進 mysql 時請用 括起來並在參數後留一個空白如 $sql = UPDATE ezf_table set tablename=$tname tableend=$endtime table inguser=$tguser tableingid=$tguserid tableallnumber=$tnumber tableloca l=$tablelocal tableanyone=$tableopen tabletext=$ttext WHERE tableid=$t ableid tablename=$tname c 取出時請用 stripslashes($str) Q3MySQL root 密碼忘了該怎麼辦 Ans 1先停掉 mysql etcrcdinitdmysql stop 2以--skip-grant-table 的參數啟動 mysql safe_mysql --skip-grant-tableamp 3 更改 root 密碼 mysql mysql mysqlgt UPDATE user SET password=password(newpassword)

69

WHERE user=root mysqlgt FLUSH PRIVILEGES mysqlgt exit 4停掉 mysql再重跑 mysqladmin -uroot -p shutdown Enter password 輸入新設定的密碼 etcrcdinitdmysql start

Q4NULL值問題

Ans

NULL值的概念是造成 SQL的新手的混淆的普遍原因他們經常認為 NULL是和一個空字符串的一樣的東西不是這樣的例如下列語句是完全不同的

mysqlgt INSERT INTO my_table (phone) VALUES (NULL)

mysqlgt INSERT INTO my_table (phone) VALUES ()

兩個語句把值插入到 phone 列但是第一個插入一個 NULL值而第二個插入一個空字符串第一個的含義可以認為是ldquo電話號碼不知道而第二個則可意味

著ldquo她沒有電話

在 SQL中NULL值在于任何其他值甚至 NULL值比較時總是假的(FALSE)包含 NULL的一個表達式總是產生一個 NULL值除非在包含在表達式中的運算符和函數的文檔中指出在下列例子所有的列返回 NULL

mysqlgt SELECT NULL1+NULLCONCAT(InvisibleNULL)

如果你想要尋找值是 NULL的列你不能使用=NULL測試下列語句不返回任

何行因為對任何表達式expr = NULL是假的

mysqlgt SELECT FROM my_table WHERE phone = NULL

要想尋找 NULL值你必須使用 IS NULL測試下例顯示如何找出 NULL電話號碼和空的電話號碼

70

mysqlgt SELECT FROM my_table WHERE phone IS NULL mysqlgt SELECT FROM my_table WHERE phone =

在 MySQL中就像很多其他的 SQL服務器一樣你不能索引可以有 NULL值的列你必須聲明這樣的列為 NOT NULL而且你不能插入 NULL到索引的

列中

當用 LOAD DATA INFILE 讀取數據時空列用更新如果你想要在一個列中有

NULL值你應該在文本文件中使用N字面上的詞NULL也可以在某些情形下使用

當使用 ORDER BY時首先呈現 NULL值如果你用 DESC以降序排序NULL值最後顯示當使用 GROUP BY時所有的 NULL值被認為是相等的

為了有助于NULL的處理你能使用 IS NULL和 IS NOT NULL運算符和 IFNULL()函數

對某些列類型NULL值被特殊地處理如果你將 NULL插入表的第一個TIMESTAMP 列則插入當前的日期和時間如果你將 NULL插入一個AUTO_INCREMENT 列則插入順序中的下一個數字

Q5如何將圖片存放於 MySQL中

Ans

Step 1建立資料庫 test

Step 2 建立表格 binary_data

CREATE TABLE binary_data (

id INT(4) NOT NULL AUTO_INCREMENT PRIMARY KEY

description CHAR(50)

bin_data LONGBLOB

filename CHAR(50)

filesize CHAR(50)

filetype CHAR(50)

71

)

Step 3 利用 storephp 寫入圖片

storephp 程式碼

ltHTMLgt ltHEADgtltTITLEgtStore binary data into SQL DatabaseltTITLEgtltHEADgt ltBODYgt lt code that will be executed if the form has been submitted

if ($submit) mysql_connect(localhostrootYOUR_PASSWORD) mysql_select_db(test) $data=Base64_Encode(fread(fopen($form_data r) filesize($form_data))) $result=MYSQL_QUERY(INSERT INTO binary_data (descriptionbin_datafilenamefilesizefiletype) VALUES ($form_description$data$form_data_name$form_data_size$form_data_type)) $id= mysql_insert_id() print ltpgtThis file has the following Database ID ltbgt$idltbgt MYSQL_CLOSE() else else show the form to submit new data

gt

ltform method=post action=ltphp echo $PHP_SELF gt enctype=multipartform-datagt File Descriptionltbrgt ltinput type=text name=form_description size=40gt ltINPUT TYPE=hidden name=MAX_FILE_SIZE value=4000000gt ltbrgtFile to uploadstore in databaseltbrgt ltinput type=file name=form_data size=40gt ltpgtltinput type=submit name=submit value=submitgt ltformgt lt

72

gt ltBODYgt ltHTMLgt

Step 3 利用 storephp 取出圖片

getdataphp 程式碼

lt Syntax getdataphp3id=ltidgt if($id) you may have to modify login information for your database server MYSQL_CONNECT(localhostrootYOUR_PASSWORD) mysql_select_db(test) $query = select bin_datafiletype from binary_data where id=$id $result = MYSQL_QUERY($query) $data = Base64_Decode(MYSQL_RESULT($result0bin_data)) $type = MYSQL_RESULT($result0filetype) Header( Content-type $type) echo $data gt

Q6MySQL裝好之後啟動時或是執行 mysqladmin會出現如下訊息 Cant connect to local MYSQL Server through Socket varlibmysqlmysqlsock或是

Cant connect to local MYSQL Server through Socket tmpmysqldsock

Ans 可能有下列幾個原因

1這個 mysqldsock 不見了被某人刪除了或是被一些系統自動執行程式給刪

了例如有些 cron任務便會設定定期刪除 tmp 裡的東西所以呢您只能修改

cron 裡的設定讓它不要清除 mysqldsock 2在啟動時也可以改變 mysqldsock的位置您在啟動 MySQL的時候可以加入此參數usrlocalmysqlbinsafe_mysqld --user=mysql --socket=其他路

徑socket amp 同時得去設定環境變數 MYSQL_UNIX_PORT的值以指定新的

73

路徑 3若是您沒改 MYSQL_UNIX_PORT的值那麼您可以在執行指令的時候才打

例如mysqladmin --socket=其他路徑socket version Q7How to get the last insert id Ans CREATE TABLE product ( id INT(4) NOT NULL AUTO_INCREMENT PRIMARY KEY description VARCHAR(50) ) 1利用 SQL的話 mysqlgt insert into product(description) values(123) Query OK 1 row affected (000 sec) mysqlgt select last_insert_id() +------------------+ | last_insert_id() | +------------------+ +------------------+ 1 row in set (000 sec) ======================================== 2如果是 PHP的話 你可以用mysql_insert_id()取得該 id PHP example $result=MYSQL_QUERY(INSERT INTO product (description) VALUES ($description)) $id= mysql_insert_id() print This file has the following Database ID $id Q8如何將文字檔匯入資料庫 Ans $addr=homehttpdhtmlphpschool001txt $sql_select = load data infile $addr into table test fields terminated by t 解說 $sql_select = load data infile 文字檔名 into table 表格名 fields terminated by

74

t

(欄位分隔以 TAB鍵) 該文字檔須與資料表欄位格式相符 例如欄位有三個 則文字檔為每行一筆資料如下 欄 1資料ltTABgt欄 2資料ltTABgt欄 3資料 欄 1資料ltTABgt欄 2資料ltTABgt欄 3資料 欄 1資料ltTABgt欄 2資料ltTABgt欄 3資料 欄 1資料ltTABgtltTABgt欄 3資料

Q9如何撰寫 MySQL C API Ans Step 1利用文字編輯器撰寫以下程式碼 mysqlcc

include ltstdiohgt

include ltmysqlmysqlhgt

int main (int argc char argv[])

MYSQL mysql

MYSQL_RES res

MYSQL_ROW row

if (argc = 2)

fputs (Usage myc ltdatabasegt stderr)

return 1

if ((mysql_connect(ampmysqllocalhostrootYour_Password)))

fputs (Error connecting stderr)

abort()

75

if (mysql_select_db(ampmysqlargv[1]))

fputs (Error selecting database stderr)

abort()

if (mysql_query(ampmysqlSELECT FROM test_table))

fputs (Error processing query stderr)

abort()

if ((res = mysql_store_result(ampmysql)))

fputs (Error storing results stderr)

abort()

while((row = mysql_fetch_row(res)))

uint i = 0

for (i=0 i lt mysql_num_fields(res) i++)

printf(s row[i])

printf(n)

return 0

Step 2 Compile

gcc -Iusrlocalmysqlinclude -Lusrlocalmysqllibmysql mysqlcc ndashlm -lmysqlclient

(其中 include path與 library path取決於你的 MySQL安裝路徑)

76

如果執行時發生如下 error Run problemerror in loading shared libraries libmysqlclientsoX 將你的 MySQL library path(for exampleusrlocalmysqllibmysql) 加入etcldsoconf and run sbinldconfig -v Q9ASP + MySQL 範例程式 Ans Dim myconn As New ADODBConnection Dim myrs As New Recordset Dim mySQL As String Dim myrows As Long myconnOpen DSN=MyODBCsample mySQL = SELECT from user myrsSource = mySQL Set myrsActiveConnection = myconn myrsCursorLocation = adUseClient myrsOpen myrows = myrsRecordCount myrsClose myconnClose 可參考 httpwwwdwamnetmysqlasp_myodbcasp 有詳細的資料 Q10如何將 MySQL中的資料庫匯出成txt檔 Ans select from TableName into outfile textxls all result fields will seperate by tab

77

第八章 參考資料

英文部份 網址 1 httpwwwmysqlcom MySQL 網站有第一手有關 MySQL的資料 2 httpwwwmysqlcomdocenReplicationhtml 有關 MySQL Replication 的文件 3 httpwwwgeocitiescomsqlhomefaqstore_blobhtml 如何在 MySQL 存放 BLOB的資料 4httpwwwsapdborg 有關 SAP跟 MySQL相關合作的網站 書藉 1 Cooking with MySQL

Paul DuBois has selected sample recipes from the hundreds youll find in his book MySQL

Cookbook In this third and final series of excerpts showcasing these recipes learn how to

compute team standings how to calculate the differences between successive Dec 26

2002 2 Tips for Building Web Database Applications with PHP and MySQL by Hugh E Williams co-author of Web Database Applications with PHP amp MySQL 04042002

3 Managing and Using MySQL 2nd Edition By Tim King George Reese Randy Jay Yarger

4 MySQL Cookbook By Paul DuBoisPublisher OReillyPub Date October 2002

中文部份

78

1 httplinuxtncedutwtechdocmysqlmysql_docmanual_tochtml MySQL 中文手冊 2 httpchenshloxaedutwphpZ_1php PHP+MySQ程式研習設計網站 3 httplinuxtncedutwtechdocbanicdownhtml PHP 4 手冊 4 httpwwwtncedutwadmin_zonephp台南縣教育網網路中心有很多 Linux相關文件 5 httpdobtncedutw網站建置百寶箱有很多 PHP MySQL 相關範例程式 5 httpwwwdbworldcomtw資料庫專家電子雜誌介紹資料庫的重要觀念及名詞

79

附錄一 SQL Command 介紹

SQL (讀音ess-que-el) 是一種結構查詢語法SQL 使用於資料庫交流

傳遞相容於 ANSI (American National Standards Institute) 是一套標準的關聯

式資料庫語言 SQL 語言是執行更新或從資料系統獲取資料一般常見的關聯

資料庫系統都有提供 SQL 如 Oracle Sybase Microsoft SQL Server Access Ingres 等雖然大部份的資料庫都有提供 SQL 但也多提供了自已獨特的語

法造成了不相容的情形但標準基本的語法是相通的如Select Insert Update Delete Create and Drop 每一個系統都有支援

Table相關 Command

Create Table

關聯式資料庫包含有很多元件稱為資料表(tables) 把資料或訊息放在資

料表中 資料表是以不同的名稱做分別資料表由欄列所構成的二維陣列

欄包含欄位名資料型態 及其他可判斷的資訊列是由全部欄位構成一筆一

筆的紀錄 create table 語法用在建立一個新的資料表語法格式如下

create table tablename (column1 data type column2 data type column3 data type)

Format of create table if you were to use optional constraints

create table tablename (column1 data type [constraint] column2 data type [constraint] column3 data type [constraint]) [ ] = optional

Note You may have as many columns as youd like and the constraints are optional

80

Example

create table employee (first varchar(15) last varchar(20) age number(3) address varchar(30) city varchar(20) state varchar(20))

注意建立資料表格式要以括號把前後框住而最後以(分號)做結尾

欄位名不要超過 30個字元長而且不要使用 sql 的關鍵字(如 where select等)而在後面接是型態的宣告(如字串數字日期格式等)

資料型態是來描述欄位的方式如一個欄位Last_Name 是一個姓氏可以使用varchar (可變動長度字串) 資料型態

以下是幾個常見的資料庫型態 char(size) 固定長度字串最長為 255 位元 varchar(size) 變動長度字串最大字元數以 size 來指定 number(size) 數值格式可以是整數也可以是小數最大數字以 size 位數判

斷未指定小數位數由系統內定 date 日期格式 number(sized) 數值格式最大數字以 size 位數判斷d 為小數位數整數位

數為 size-d 位

有何限制當資料表被建立通常有一或數個欄位是要使用來做關聯的功

能 例如unique 限制(唯一值)兩筆記錄不可以相同的值 not null (非空值)該欄位一定要輸入資料不可是空的primary key (主鍵)是每一筆記錄識別的主要方式

Drop a table drop table 刪除資料表(其中的資料也會一併刪除)

drop table tablename

Example

81

drop table 和刪除全部資料是不同的刪除全部資料欄位名稱資訊等還會

存在但刪除資料表會把這一些也一併移除掉

如何查詢資料

Select 基本用法

select 語法是關連式資料庫最常用的部份可以取得你想要的資料這是一個

簡單的範例 select column1[column2etc] from tablename [where condition] [] = optional 在 select 之後所列欄位名則是要顯示的資料部份你可以一一列出各欄位

名或是以 (星號)來代表選擇全部的欄位 from 之後放資料表名稱 where 子句 (選項) 指定要過濾的條件符合者才會顯現 where 可使用的條件運算元 = 等於 gt 大於 lt 小於 gt= 大或等於 lt= 小或等於 ltgt 大相等 LIKE 相似 For example select first last city

82

from empinfo where first LIKE Er 以Er 為開頭的字串就符合要以單引號框住 Or you can specify select first last from empinfo where last LIKE s 最後一字為 S 就符合 select from empinfo where first = Eric 則表示 first name 一定要是 Eric 才可以 範例資料表empinfo 統計函數

MIN 傳回指定欄位最小值

MAX 傳回指定欄位最大值

SUM 傳回指定欄位總和

AVG 傳回指定欄位平均值

COUNT 傳回指定欄位的筆數

COUNT() 傳回資料庫中的總筆數

統計函數使用於資料表中的數值欄位配合 SELECT 語法使用 只用於總結特定單一欄位可以配合 GROUP BY 做篩選但也可以不使用 GROUP BY 語句For example

SELECT AVG(salary) FROM employee

83

傳回全部 salary 平均值

Another example

SELECT AVG(salary) FROM employee WHERE title = Programmer

傳回 salary 平均值條件為 employees 資料表中當 title 等於 Programmer

Example

SELECT Count() FROM employees

傳回 employees 資料表中紀錄總筆數

GROUP BY 語法 SELECT column1 SUM(column2) FROM list-of-tables GROUP BY column-list The GROUP BY 語句可以先以所列的欄位為條件分組排序在一起(可以多欄

位) example 要列出每一個 dept 中最高 salary 值 SELECT max(salary) dept FROM employee GROUP BY dept HAVING 語法

SELECT column1 SUM(column2) FROM list-of-tables GROUP BY column-list HAVING condition

HAVING 子句是 GROUP BY 的一部份用來過濾在 GROUP BY 所選出的資料功能如同 select 命令中 where 條件式一樣只是 HAVING 必需配合 GROUP BY 使用

我們以例子來說明我們要取得每一公司名及每一公司的薪水平均值輸入如下

84

SELECT dept avg(salary) FROM employee GROUP BY dept

但如果我們只列出薪資平均值超過 20000元的公司資料

SELECT dept avg(salary) FROM employee GROUP BY dept HAVING avg(salary) gt 20000

ORDER BY子句語法

SELECT column1 SUM(column2) FROM list-of-tables ORDER BY column-list [ASC | DESC]

[ ] =選項

ORDER BY是一個選項子句當你以排序方式來顯示資料(正向由小到大反向由大到小)以指定的欄位資料做排序

ASC = 正向- 預設值 DESC = 反向排序

For example

SELECT employee_id dept name age salary FROM employee_info WHERE dept = Sales ORDER BY salary

以上列出公司代號公司名銷售員人名年紀及薪資而條件是公司名為 Sales 顯示順序以薪資多少排序(由小到大為預設值)

如果要以多個欄位做排序要以逗號做分隔如下

SELECT employee_id dept name age salary FROM employee_info WHERE dept = Sales ORDER BY salary age DESC

85

結合條件及布林運算 SELECT column1 SUM(column2) FROM list-of-tables WHERE condition1 AND condition2 AND運算可以結兩個或以上的條件放在 WHERE子句中 兩者都要為真才

會顯示該筆記錄 OR 運算可以結兩個或以上敘述放在 WHERE子句中只要其中一個為直就

會顯示該筆記錄 For example SELECT employeeid firstname lastname title salary FROM employee_info WHERE salary gt= 5000000 AND title = Programmer 必需要薪資大於等於 50000而且職稱為 Programmer同時符合才會顯示該筆資料 以下以括號括住雖然不是必需的但如此比較容易讀 SELECT employeeid firstname lastname title salary FROM employee_info WHERE (salary gt= 5000000) AND (title = Programmer) 另外範例 SELECT firstname lastname title salary FROM employee_info WHERE (title = Sales) OR (title = Programmer) 條件為只要是 Sales 或 Programmer 職稱的就會被列出 IN and BETWEEN 子句

SELECT column1 SUM(column2) FROM list-of-tables WHERE column3 IN (list-of-values) SELECT column1 SUM(column2) FROM list-of-tables WHERE column3 BETWEEN value1 AND value2 IN 子句使用在列舉項目的使用上也就是分別測試是否符合所列的值 For example

86

SELECT employeeid lastname salary FROM employee_info WHERE lastname IN (Hernandez Jones Roberts Ruiz) 條件為姓氏(astname)要符合 Hernandez Jones Roberts or Ruiz 其中一個才會被傳回 IN運算元也可以使用 OR 的語法來取代如下結果相同 SELECT employeeid lastname salary FROM employee_info WHERE lastname = Hernandez OR lastname = Jones OR lastname = Roberts OR lastname = Ruiz 但使用 IN 句子比較短也比較易懂 你也可以使用 NOT IN 來去掉不要的記錄 BETWEEN 運算元使用在判斷是否存在兩個數值之間 For example SELECT employeeid age lastname salary FROM employee_info WHERE age BETWEEN 30 AND 40 傳回年紀 30歲到 40歲之間的資料(含 30及 40歲者) 相同的也可以使用以下語法來達到相同的結果 SELECT employeeid age lastname salary FROM employee_info WHERE age gt= 30 AND age lt= 40 你也可使用 NOT BETWEEN 來濾掉中間值的資料 數學運算 標準 ANSI SQL-92 提供以下運算

87

+ 加

- 減

餘數

餘數為除法後剩整數這不在標準的 ANSI SQL 中但大部份的資料庫都會支

援這運算元以下列出有用的函數雖不在 ANSI SQL-92 提供但一般資料庫

也會支援他們

ABS(x) 傳回 x 絕對值

SIGN(x) returns the sign of input x as -1 0 or 1 (negative zero or positive respectively)

MOD(xy) 餘數 - returns the integer remainder of x divided by y (同 xy)

FLOOR(x) 傳回小或等於 x 的最大整數值

CEILING(x) or CEIL(x)

傳回大或等於 x 的最小整數值

POWER(xy) x的 y 次方

ROUND(x) 把 x 四捨五入為整數

ROUND(xd) 四捨五入取到小數 d 位

SQRT(x) x 開平方

For example SELECT round(salary) firstname FROM employee_info 傳回薪資取到整數位

如何新增資料

insert 加入一筆新紀錄到資料表中 insert into tablename (first_columnlast_column) values (first_valuelast_value) [] = optional Example insert into employee

88

(first last age address city state) values (Luke Duke 45 2130 Boars Nest Hazard Co Georgia) Note 字串要以單引號住如string 數字框住也無妨 insert into 後面接資料表名稱再接以括號括住的欄位名在 values 後括號分別對映各欄位的值 以上的例子新增了一筆名(first) 為 Luke而住所(state) 為 Georgia 的資料

如何刪除資料

delete 可以刪除單筆或多筆紀錄 delete from tablename where columnname OPERATOR value [and|or column OPERATOR value] [ ] = optional Examples delete from employee Note 如果你沒有指定 where 子句那麼全部的紀錄都會被刪除 delete from employee where lastname = May delete from employee where firstname = Mike or firstname = Eric delete from 接著資料表名 再接著是條件式判斷沒有條件式則全部紀錄會

被刪除

如何更新資料

update 用來更新你所指定的記錄要和 WHERE 配合小心使用 語法 update tablename set columnname = newvalue[nextcolumn = newvalue2] where columnname OPERATOR value [and|or column OPERATOR value] [] = optional Examples

89

update phone_book set area_code = 623 where prefix = 979 update phone_book set last_name = Smith prefix=555 suffix=9292 where last_name = Jones update employee set age = age+1 where first_name=Mary and last_name=Williams

90

附錄二Replication

測試環境

RedHat 90 + MySQL 32358 MySQL資料庫路徑 varlibmysql MySQL設定檔 etcmycnf Master IP 1921680100 Slave IP 1921680200 請至下列網址下載最新MySQL 32358套件並利用rpm ndashUvh 更新 httpupdatesredhatcom9enosi386

圖 最新 MySQL 套件

測試架構圖

91

1921680100

1921680200Master Server

erveSlave S r

圖 測試架構圖

測試步驟

Master server 部份 Step1 確認 MasterSlave機器上所裝的 MySQL版本能進行

replication( 32329 or higher ) Step2 在 Master MySQL上開放一個帳號給 Slave mysql ndashu root ndashp mysqlgtGRANT FILE ON TO repl1921680200 IDENTIFIED BY lsquoabc123rsquo mysqlgtq 上面是 Master開放一個帳號 repl密碼 abc123給 IP1921680200有檔案處理

的權限 Step3 shutdown MySQL on the Master mysqladmin ndashu root ndashp shutdown Step4 備份 Master所有資料庫 tar ndashcvf tmpmysql-snapshottar varlibmysql 注意tar的時候MySQL是要在 stop情況下 在mysql (wwwmysqlcom) 網站的FAQ有不用shutdown的方法

92

Step5 在 master機器上修改etcmycnf 在[mysqld]區段內加入參數 log-bin server-id=這邊設定 server-id=1 sql-bin-update-same binlog-do-db=CRM只針對 CRM資料庫做紀錄 Step6 Restart MySQL on the master service mysqld start 此時因為有加入 log-bin 參數因此開始有 index產生了在varlibmysql目錄下

有index檔案紀錄資料庫的異動 log Slave server 部份 Step1 在 slave設定etcmycnf 在[mysqld]區段加入 master-host= master-user= master-password= master-port= server-id= 這邊設定 master-host=1921680100 master-user=repl master-password=abc123 master-port=3306 server-id=2 master-connect-retry=60預設重試間隔 60秒 replicate-do-db=CRM告訴 slave只做 CRM資料庫的更新 log-slave-updates Step2 將 master上的 mysql-snapshottar copy到 slave上 用 ftp傳到 slave的tmp Step3 解壓縮 Master資料庫至 Slave Server上 cd varlib tar xvf tmpmysql-snapshottar chown ndashR mysqlmysql mysql

93

chmod ndashR 770 mysql (視情況) Step4 Restart MySQL on the slave server 這時在varlibmysql目錄會出現 masterinfo此檔案紀錄了 Master MySQL server的資訊

狀況測試

One-way replication

1921680100

1921680200Master Server

erveSlave S r

圖 One-way replication架構圖 Step1 Master跟 Slave網路及服務都正常情況下由 Master端異動資料後 到 Slave端瀏覽資料檢視是否有進行 replication Step2 模擬 Slave Server 當機 可用在於 slave真的當機或是 Slave 不一定需要一直跟 master connect將Slave MySQL server shutdown由 Master端異動資料到 slave端瀏覽此時Slave應該沒有被 replication 更新然後再將 Slave端 MySQL server start起來

預設 60秒後 Slave會嘗試跟 Master要求進行 replication再去 Slave端檢視是否有更新資料

94

Step3 模擬 Master當機因為是設定 One-way replication一旦 Master Server Slave端沒有 Master的 source可以 download Two-way replication 基於 Master當機狀況於是發展雙向 Replication即 1921680100 ( Host A ) 1921680200 ( Host B )都分別擔任 MasterSlave身分

1921680100

1921680200er

Server B MasterSlave Server

Server A MasterSlave Serv

圖 Two-way replication架構圖 以下是針對兩台 MySQL伺服器進行雙向 Replication Step1觀念同單向 replication只是改成 Master也有 Slave身分 Slave也有Master的身分先分別在 Server AServer B 都去 grant一個進行 replication的身分 [A]mysqlgtGRANT FILE ON TO repl1921680200 IDENTIFIED BY lsquoabc123rsquo [B]mysqlgt GRANT FILE ON TO repl1921680100 IDENTIFIED BY lsquoabc123rsquo Step2做完單向 replication後stop Server Aserver B MySQL service此時 AB資料是一樣的

95

修改etcmycnf設定 範例 Server A [mysqld] datadir=varlibmysql socket=varlibmysqlmysqlsock server-id=1 log-bin sql-bin-update-same binlog-do-db=CRM master-host=1921680200 master-user=repl master-password=abc123 log-slave-updates master-connect-retry=60 replicate-do-db=CRM Server B [mysqld] datadir=varlibmysql socket=varlibmysqlmysqlsock server-id=2 log-bin sql-bin-update-same binlog-do-db=CRM master-host=1921680100 master-user=repl master-password=abc123 log-slave-updates master-connect-retry=60 replicate-do-db=CRM 分別 start Server AServer B MySQL後此時雙方都是 MasterSlave身分一旦哪一方資料異動就會通知對方來 replication-若 replication失效則必須將Server AServer B的masterinfo及index00x 都砍掉然後分別 restart MySQL server進行測試檢視成果 實務上通常如果需要做Two-way replication通常會搭配Virtual Server使用

96

在前端架設一台Virtual Server不過此部份不在此份SOP討論範圍內有興趣

的讀者可參考 httpwwwlinuxvirtualserverorg 網站

1921680100 1921680200

Host A MasterSlave Server

Host B MasterSlave Server

Virtual Host

圖 Virtual Server + Two-way replication 架構圖

97

圖 High Availability Linux Virtual Server架構圖

98

  • COSA-SOP-03-006
  • 第一章 簡介
    • 11適用對象 (Audience)
    • 12 MySQL本身
    • 13 MySQL 40版跟50版重大的改進功能
    • 14 各家資料庫軟體比較
      • 第二章 前置需求
      • 第三章 安裝
        • 31 MySQL安裝
        • 32 phpMyAdmin安裝
        • 33 升級及注意事項
          • 第四章 MySQL管理
            • 41 Webmin 管理介面
            • 42 phpMyAdmin 的操作介面
            • 43管理指令介紹
              • 431 利用mysqladmin設定root的密碼
                  • 第五章 實用範例
                    • 51 任務一Web Base客戶通訊錄
                    • 52 任務二Web Base群組軟體 ( twig )
                      • 第六章 維護及更新程序
                        • 61 日常維護
                        • 62 更新程序
                        • 63 備份重要檔案
                        • 64 離線備份與還原
                        • 65 線上備份與還原
                          • 第七章 問題與解答
                          • 第八章 參考資料
                          • 附錄一 SQL Command 介紹
                          • 附錄二Replication
Page 3: DataBase Server Standard Operation Procedureebooks.lib.ntu.edu.tw/1_file/oss/63/93doc4-5.pdf · 業務的公司帶來了不少壓力,譬如微軟,甲骨文 ... 外的錢用在第三方的資料庫產品上,譬如就可以不用再購買甲骨文公司

目錄

第一章 簡介 5

11適用對象 (AUDIENCE) 5 12 MYSQL本身 5 13 MYSQL 40版跟 50版重大的改進功能 7 14 各家資料庫軟體比較 8

第二章 前置需求 11

第三章 安裝 12

31 MYSQL安裝 12 32 PHPMYADMIN安裝 17 33 升級及注意事項 24

第四章 MYSQL管理 27

41 WEBMIN 管理介面 27 412建立資料庫 27 412 建立資料表 30 413 使用者管理 35

42 PHPMYADMIN 的操作介面 39 421建立資料庫 39 422 建立資料表 39 423使用者管理 44

43管理指令介紹 46 431 利用mysqladmin設定root的密碼46 432 連線 MySQL 47 433 建立資料庫 47 434 建立資料表 48

第五章 實用範例 50

51 任務一WEB BASE客戶通訊錄 50 511 Web Base客戶通訊錄架構 50 512 Web Base通訊錄測試 51 513 程式內容及說明 53

52 任務二WEB BASE群組軟體 ( TWIG ) 59

第六章 維護及更新程序 64

61 日常維護 64

3

62 更新程序 64 63 備份重要檔案 64 64 離線備份與還原 64

641 離線備份64 642 離線還原65

65 線上備份與還原 65 651 線上備份65 652 線上還原66

第七章 問題與解答 68

第八章 參考資料 78

附錄一 SQL COMMAND 介紹 80

附錄二REPLICATION 91

4

第一章 簡介

MySQL 是一種 跨平台多使用者多執行緒支援 SQL語言 (結構化查詢語言)執行速度快廣受全球網站大量採用的網路資料庫系統最重要的

是在大部份情形下使用 MySQL 是完全免費的( MySQL自 32319之後已改為 GPL版權宣告囉)整體而言MySQL 免費原始碼開放入門容易

執行速度快跨平台 (亦支援 Windows 2000)支援工具眾多等特性十分適合中小企業用來開發各種資訊系統企業不必再花費數十萬元去購買一些費而

不惠的資料庫 MySQL 沒有所謂連線使用者限制其它商用資料庫系統一定數量以上的

連線使用者數可是要付出相當可觀的費用的像 Yahoo等大公司也是用 MySQL 哩 連這麼大的入口網站都安心地挑選 MySQL 一般的中小企業更

無需擔心 MySQL的穩定性

11適用對象 (Audience)

本 SOP的對象適合一般的使用者及系統管理者編排的方式大部分皆採操

作步驟的模式進行方便一般入門的使用者

12 MySQL本身

在 Unix平台上最受到歡迎的一套資料庫系統就是 MySQL MySQL於1990中期開始發展當時Michael Mothnty Widenius在位於瑞典的 TcX DataKonsultAB開始開發這套軟體並在 1995 年公開釋放第一個版本

MySQL 同時擁有頗為可觀跨平台能力它能 Unix Like平台工作例如 AIX

SolarisFreeBSD及 Linux也能在 Mac OS X及Windows NT2000 server亦或是 Microsoft Wrokstation 系統上如 9xMEXP上開發程式更重要的是它是

讓您擁有原始碼 在 MySQL 在 323之後的版本在每個系統元件上在釋放時都會加上一個

完成度的註解如由「gamma」階段到「stale」階段「beat」階段到「alpha」階段階段愈低愈不穩定查詢目前的發展版本可以在 MySQL 參考手冊及線上

文件找到

5

MySQL經過考驗證明是值得信賴的資料庫系統如果您是 stable版的使用者您大可以放心MySQL對於版本的控制是十分注意並提供廣大的使用者原始碼下載Bug也因此很快就被解決

MySQL主要是以技術支援和經銷資料庫為主和 Red Hat在 Linux上的做

法非常類似背後則是由創投資金在支持客戶可以下載 MySQL並遵照 GPL授權規定使用MySQL公司則以技術服務作為收入

MySQL也提供付費的解決方案給想要整合 MySQL和其他軟體產品但是

又不想讓客戶取得程式碼的公司MySQL表示MySQL資料庫在全球已經有

400萬的使用者但是並不清楚其中有多少付費用戶到目前為止MySQL也已經引起企業用戶的興趣甚至包括 Yahoo和 Google等網際網路的領導廠商

MySQL最原始的構想嚐試克服自由軟體資料庫系統「mSQL」的一些功能

上的限制MySQL成長進步的非常的快尤其當贊助者由網際網路應用中看出

MySQL能提供網站所需強健資料庫的潛能對於 MySQL成長的速度幫助不少

而近來更有令人振奮的好消息( 2003 年 5月 ) ERP的龍頭 SAP正在與 MySQL就開放源代碼資料庫軟體進行合作這項

交易將會使得 MySQL這樣更小的公司能夠加速它的開發計畫此舉將允許

MySQL公司在未來的兩年內為其資料庫軟體添加更高端的一些特徵MySQL公司的首席執行官 Marten Mickos 說公司早在四年前就希望能夠進軍高端資料

庫業務這次交易在資料庫市場上還引起了另外一些影響它給那些開發資料庫

業務的公司帶來了不少壓力譬如微軟甲骨文以及 IBM等因為這項交易為

這些公司不斷樹立了一個越來越強大的開放源代碼軟體的競爭者而開放源代碼

軟體最終也許會吞噬它們的資料庫市場 SAP公司一直是銷售那些管理核心業務的一些軟體譬如會計軟體存貨

管理軟體這些產品以前一直是各大公司的暢銷軟體為了吸引那些中等規模的

公司客戶從而進行業務擴張這家德國的公司開始在他們的一些產品中加入SAP DB這是一個開放源代碼的資料庫軟體該軟體就可以免除 SAP公司客戶花額外的錢用在第三方的資料庫產品上譬如就可以不用再購買甲骨文公司的資料庫

軟體 根據他們的技術交錯式授權協議MySQL公司將會主宰 SAP DB的絕大部

分再開發業務並且 MySQL也會使用該程式的設計作為該公司未來改進的資料

庫軟體的模型SAP公司的一位元代表稱隨著 MySQL資料庫軟體的不斷成

熟SAP公司將會用新的 MySQL的資料庫軟體代替 SAP DBMickos 說在

6

這項交易中這家瑞典公司 MySQL將會得到其軟體的版稅但他拒絕透露這次

合作的一些經濟方面的細節 SAP的代表稱在更長一段時間後該開放源代碼資料庫軟體將會和 SAP

公司的旗艦產品 R3一起銷售 不久之後SAP與 MySQL將會完成他們合作計畫的第一個階段那

就是 SAP將會發佈一個 MySQL的資料庫版本從而它可以無縫地替代現在使

用的 SAP DB這對 MySQL而言無異是如虎添翼想必在不久的將來MySQL定能擔任企業更重要的任務

13 MySQL 40版跟 50版重大的改進功能

以下是 40版跟 50版一些重大的改進功能 MySQL 40 版httpwwwmysqlcomdocenNews-40xhtml

內建提供InnoDB table type支援 standard binaries adding transactions row-level locking 和foreign keys

提昇 Query速度 改善 boolean mode truncation and phrase searching全文檢索效

率 加強MERGE tables 並支援INSERT statements and

AUTO_INCREMENT 在SELECT 中支援UNION 語法 支援Multi-table DELETE statements libmysqld the embedded server library 更多的GRANT 參數來加強安全性 提供更多動態參數來降低停止 MySQL的必要 改善 replication code and features 改善執行效率並增加可靠性

MySQL 50 版httpwwwmysqlcomdocenTODO_MySQL_50html改善執行效率並增加可靠性 提供 Stored Procedures 機制 支援 cursor Dynamic length rows for HEAP tables Add true VARCHAR support

7

加強執行效率 更好的國際語系支援 提供可用性

14 各家資料庫軟體比較

目前市面上較被廣為使用資料庫除了 MySQL之外尚有下列幾種

1 MS SQL Server 2000 2 Oracle 8i 3 IBM DB2 4 Informix

過去幾年來在總值 120億美元的資料庫市場上如果廠商想要誇讚自家的

產品那就一定得要有強大的資料庫支援最嚴苛的任務才站得上檯面不過

到了今天似乎光是這樣並不夠客戶除了要求足以負擔嚴苛的任務之外還希

望擁有聰明又便宜的資料庫 Meta Group的分析師 Charlie Garry表示 ( 2003 年 5 月)MySQL的商業

模式是以開放原始碼為基礎以便讓客戶盡快接受 MySQLGarry指出MySQL甚至適合用在甲骨文IBM微軟等大廠爭相搶食的企業資料中心

Information Resources的資訊長 Marshall Gibbs就表示他們沒有任何品

牌的偏好只要「功能效能價格的最佳組合」 由研究近兩年來資料庫客戶

愈來愈注重總體成本(圖 1-1)

8

圖 1-1 資料庫優先性

整體擁有成本 大致說來MySQL是免費的MySQL需要付費的規定只限於下列兩種情

形 1 以 Embedded的方式使用 MySQL 2 使用 MySQL的商業用途軟體

且其授權費用一台 MySQL Pro License只需美金 $440比起其他任何資料庫軟體來得容易負擔多了加上其易於管理的特性著實可大大降低企業資料

庫的整體擁有成本 擴充性

MySQL同時提供高度多樣性能夠提供給很多不同的使用者介面包括命

令列操作網頁瀏覽器以及各式各樣的程式語言介面例如JavaC++PerlPHP及 PhythonMySQL可用 UnixWindows以及 OS2hellip等平台因此它可以用個人電腦或是伺服器上 性能 事實上大部份的網站的開發者都認為 MySQL是目前市面跑得最快的資料

9

庫對資料庫的最佳化主要在於你對他的設定和資料庫結構的設計如果你的

資料庫結構設計得非常差你的存取速度還是會受到影響而變得比較慢

10

第二章 前置需求

在安裝 MySQL之前請確定 Apache及 MySQL亦巳安裝相關步驟請參考

Apache SOP安裝 Apache及 PHP相關章節

11

第三章 安裝

31 MySQL安裝

在 RedHat 90上安裝 MySQL是件很容易的事因為 RedHat 90提供了一

個很方便的 GUI套件管理工具「redhat-config-packages」各位只要把 RedHat 90第一片光碟放入並以 root的身份登入系統鍵入 redhat-config-packages勾選「SQL資料庫伺服器」即可然後按「更新」如果遇到任何相依性問題

系統會提示您更換光碟片 ( 圖 3-1 ~ 3-3 ) Step 1 執行 redhat-config-packes

圖 3-1

Step 2 選擇資料伺服器

12

圖 3-2

Step 3檢查是否安裝成功 待安裝後您可以用利用「rpm -qa | grpe ^mysql」檢查是否安裝成功

圖 3-3

啟動 MySQL ( Command Mode )馬上啟動 MySQL的指令為「service mysqld start」如果您希望一開機就自動啟動 MySQL請執行「chkconfig mysqld on」

13

圖 3-4

啟動 MySQL ( WebMin 介面 ) 我們也可以利用WebMin 來啟動 MySQL步驟如下 Step 1登入Webmin

圖 3-5 登入WebMin

Step 2 選擇伺服器

14

圖 3-6 伺服器畫面

Step 2 選擇 MySQL資料庫伺服器

圖 3-7 伺服器畫面

15

Step 3 啟動 MySQL資料庫伺服器

圖 3-8 啟動 MySQL

更改資料庫管理者密碼

成功啟動 MySQL後因為資料庫管理者預設沒有密碼建議使用前更改系

統管理者密碼請輸入下列指令

mysqladmin ndashu root ndashh cosaexamplecom password lsquo1234rsquo -u 表示使用者帳號root 為 MySQL預設的管理帳號

-h 表示 MySQL主機的主機名稱也可使用 IP Address password 表示使用者的密碼因為字串請使用單引號將密碼括起來

圖 3-9 修改 MySQL 的密碼

16

32 phpMyAdmin安裝

本書除了會介紹利用當今 Linux上最紅的整合管理工具Webmin 來管理

MySQL外還會為各位介紹專門管理 MySQL的工具 phpMyAdmin phpMyAdmin是免費的 PHP原始程式碼的Web網站可用來管理整個

MySQL伺服器這是一套Web介面的 MySQL管理程式支援中文的使用者介

面 phpMyAdmin只需透過瀏覽器就可管理 MySQL伺服器換句話說不論

MySQL是安裝在 Linux或是Windows 作業系統都可以使用相同步驟在

MySQL上建立資料庫(Database)資料表(Table)和編輯紀錄(Record) Step 1 下載phpMyAdmin ( httpwwwphpmyadminnet )選擇最櫎新穩定的版

本 253

圖 3-10 httpwwwphpmyadminnet

17

圖 3-11 下載 phpMyAdmin-253-phptarbz2

Step 2 將 phpMyAdmin-253-phptarbz2收至 tmp 並執行下列指令將其解壓

縮至varwww tar jxvf phpMyAdmin-253-phptarbz ndashC varwwwhtml

圖 3-12 解壓縮安裝 phpMyadmin-253

Step 3 為了操作方便起見建立 Soft link ln ndashs phpMyAdmin-253 phpMyAdmin

圖 3-13 修改 phpMyadmin 設定檔 configincphp

18

Step 4 修改 phpMyadmin 設定檔 configincphp gedit varwwwhtmlphpMyAdminconfigincphp

圖 3-14 configincphp設定檔

Step 5 設定顯示行號以方便修改 configincphp 設定檔

19

圖 3-15 顯示行號

Step 6 修改下列設定 第 39 行 設定 phpMyAdmin的 URL 第 69 行 MySQL Server 的 ip 第 80 行 利用何帳號存取 MySQL 第 81 行 如果 root有設定 password此處即填入 root的 password

30 In most cases you can leave this variable empty as the correct value

31 will be detected automatically However we recommend that you do

32 test to see that the auto-detection code works in your system A good

33 test is to browse a table then edit a row and save it There will be

34 an error message if phpMyAdmin cannot auto-detect the correct value

35

36 If the auto-detection code does work properly you can set to TRUE the

37 $cfg[PmaAbsoluteUri_DisableWarning] variable below

38

39 $cfg[PmaAbsoluteUri] = httpossccosaorgtwphpMyAdmin

hellip

20

hellip

69 $cfg[Servers][$i][host] = localhost MySQL hostname or IP address hellip 80 $cfg[Servers][$i][user] = root MySQL user

81 $cfg[Servers][$i][password] = 1234 MySQL password (only needed

圖 3-16 修改 configincphp

21

圖 3-17 修改 configincphp

圖 3-18 修改 configincphp p

Step 7 設定語系

22

圖 3-19 設定語系

圖 3-20 執行 phpMyAdmin

23

33 升級及注意事項

RedHat 90附的 MySQL版本為 323 MySQL所釋出最新穩定版本為

40若是您不想用系統預附的 323請先利用下列移除之前 323的版本

rpm ndashe mysql-devel rpm ndashe mysql-server rpm ndashe mysql --nodeps 然後到下列網址下載您所想要的版本進行安裝在這裏我們用 4014版為例 Step 1 下載相關套件( httpwwwmysqlcomdownloadsmysql-40html )

圖 3-21 Download MySQL 4014 相關 RPM Step 2 利用 rpm 指令安裝

24

圖 3-22 Install MySQL 4014 相關 RPM

圖 3-23 Install MySQL 4014 相關 RPM

Step 3 啟動 MySQL

25

圖 3-24 啟動 MySQL 4014 並修改密碼

26

第四章 MySQL管理

本章將我們介紹利用WebminphpAdminCommand的方式建立一個名為

CONTACT的資料庫內有一個 address的 Table作為我們客戶通訊錄程式使

用的資料庫

41 Webmin 管理介面

412建立資料庫

Step 1 登入Webmin

圖 4-1 登入WebMin

Step 2 點選伺服器

27

圖 4-2 伺服器畫面

Step 3 點選 MySQL資料庫伺服器

圖 4-3 MySQL資料庫伺服器

28

Step 4 建立一個新的資料庫

圖 4-4 建立 MySQL資料庫

Step 5 建立名為 CONTACT的資料庫

29

圖 4-5 指定資料庫名稱

412 建立資料表

假設我們要建立一個名為 address的 Table其結構如下 欄位名稱 資料型態 長度 說明 id INT (自動編號) 連絡人編號 name varchar文字 20 連絡人姓名 tel Varchar文字 15 連絡人電話 Step 1 選擇 CONTACT資料庫

30

圖 4-6 選擇資料庫

Step 2 指定欄位數目

31

圖 4-7 設定欄位數目

Step 3設定表格欄位屬性

圖 3-8 設定表格欄位屬性

Step 4建立表格資料

32

圖 4-9 建立表格資料

圖 4-10 檢視資料

33

圖 4-11 新增資料

圖 4-12

34

圖 4-13

413 使用者管理

接下來我們要利用Webmin 來建立資料庫使用者並給予某些權限 Step1建立使用者

35

圖 4-14 選擇使用者權限

圖 4-15

36

Step2 賦予權限

圖 4-16

Step3 權限列表

37

圖 4-17

38

42 phpMyAdmin 的操作介面

421建立資料庫

Step 填入資料庫名稱並按「建立」

圖 4-18建立資料庫

422 建立資料表

Step1 填入資料表名稱並指定欄位數量 執行

39

圖 4-19填入資料表名稱並指定欄位數量

Step2 設定欄位屬性

圖 4-20設定欄位屬性

40

Step3 phpMyAdmin會產生相關的 SQL Command

圖 4-21 資料表結構及相關 SQL Command

Step4新增 Record

41

圖 4-22

圖 4-23

42

圖 4-24

圖 4-25

43

423使用者管理

Step1建立使用者

圖 4-26

44

圖 4-27

Step2 給予權限

圖 4-28

Step3權限列表

45

圖 4-29

43管理指令介紹

431 利用 mysqladmin設定 root的密碼

當您在Windows 或 Linux 中安裝好 MySQL後系統會自動幫您建立兩個

帳分別是 root 和 匿名者MySQL的 root 跟 Linux 最高權限使用者 root無關MySQL的 root使用者相當於 MS SQL 中的 sa 帳號擁有最高的 Database管理權限但系統預設 MySQL的 root 是不需要密碼所以通常我們一安裝

MySQL後首要任務便是修改 root的密碼 我們可以利用 mysqladmin工具或是直接修改 MySQL內部資料庫的使用者資

料 mysqladmin ndashu root ndashh cosaexamplecom password lsquo1234rsquo

46

-u 表示使用者帳號root 為 MySQL預設的管理帳號

-h 表示 MySQL主機的主機名稱也可使用 IP Address password 表示使用者的密碼因為字串請使用單引號將密碼括起來 密碼設定完成之後還是可以利用 mysqladmin修改密碼但是你必須提供目前的密碼

432 連線 MySQL

mysql -uroot -p密碼 (-p和密碼之間不能有空白) 或 mysql -uroot -p (此方式會在進入後要求密碼) [rootossc phpMyAdmin] mysql -u root -p1234

Welcome to the MySQL monitor Commands end with or g

Your MySQL connection id is 25 to server version 32354

Type help or h for help Type c to clear the buffer

mysqlgt show databases

+----------+

| Database |

+----------+

| mysql |

| test |

+----------+

2 rows in set (000 sec)

mysqlgt exit

Bye

[rootossc phpMyAdmin]

433 建立資料庫

可利用 mysqladmin指令建立 CONTACT資料庫 mysqladmin -u root -p1234 create CONTACT

47

或是利用 mysql指令 [rootossc bluepage] mysql -u root -p1234 Welcome to the MySQL monitor Commands end with or g Your MySQL connection id is 1057 to server version 32354 Type help or h for help Type c to clear the buffer mysqlgt create database CONTACT Query OK 1 row affected (000 sec) mysqlgt show databases +----------+ | Database | +----------+ | CONTACT | | address | | hello | | mysql | | nuke | | test | +----------+ 6 rows in set (000 sec) mysqlgt exit

434 建立資料表

編寫 adresssql內容如下 -- Table structure for table address CREATE TABLE address ( id int(11) NOT NULL auto_increment name varchar(20) NOT NULL default tel varchar(15) NOT NULL default PRIMARY KEY (id) ) TYPE=MyISAM

48

-- Dumping data for table address INSERT INTO address VALUES (1林小明0800016888) INSERT INTO address VALUES (2黃大雄0800016888) INSERT INTO address VALUES (3劉小芬0800024365) 然後執行此 sql script mysql -u root -p1234 CONTACT lt addresssql 或是利 mysql command [rootossc bluepage] mysql -u root -p1234 Welcome to the MySQL monitor Commands end with or g Your MySQL connection id is 1090 to server version 32354 Type help or h for help Type c to clear the buffer mysqlgt use CONTACT Database changed Database changed mysqlgt CREATE TABLE address ( -gt id int(11) NOT NULL auto_increment -gt name varchar(20) NOT NULL default -gt tel varchar(15) NOT NULL default -gt PRIMARY KEY (id) -gt ) TYPE=MyISAM Query OK 0 rows affected (000 sec) mysqlgt INSERT INTO address VALUES (1林小明0800016888) Query OK 1 row affected (000 sec) mysqlgt INSERT INTO address VALUES (2黃大雄0800016888) Query OK 1 row affected (000 sec) mysqlgt INSERT INTO address VALUES (3劉小芬0800024365) Query OK 1 row affected (000 sec) mysqlgt exit Bye

49

第五章 實用範例

51 任務一Web Base客戶通訊錄

任職於開放科技公司的林小明前些日子在最符合成本效益的條件下快

速地完成公司網站的建置老闆因此對小明讚譽有加最近因為公司存放客戶資

料的 SQL Server主機屢遭病毒攻擊加上作業系統本身的問題當機次數頻繁

老闆希望能儘快把公司的客戶通訊錄程式移轉到較穩定的環境上因為此客戶通

訊錄程式最主要給內部人員使用所以介面美觀並不特別要求只求穩定且能快

速得到查詢結果老闆希望在短時間先看到程式的雛型並鍵入資料對其效率

及穩定性進行測試因為上次小明表現突出所以這次不可能的任務自然又落到

小明身上 小明想來想去既然要快速又穩定他而且又不希望所有人都得安裝 Client

程式於是小明決定)捨棄他的舊愛「Delphi+MS SQL」投向新歡「Apache + MySQL + PHP」利用此架構來設計一個簡單實用的Web Base客戶通訊錄程式

511 Web Base客戶通訊錄架構

此程式需要建立 CONTACT的資料庫並建立 adress Tables其結構如下表建立步驟請參考第三章 欄位名稱 資料型態 長度 說明 id INT (自動編號) 連絡人編號 name varchar文字 20 連絡人姓名 tel Varchar文字 15 連絡人電話 Web Base通訊錄共有下列幾個檔案功能如下表

檔案名稱 說明 Indexhtml Web Base通訊錄首頁 addphp 新增連絡人的 php程式 searchphp 尋找連絡人的 php程式 editphp 具有更新及刪除功能的 php程式

50

我們將這些檔案放至varwwwhtmlbluepage (預設無 bluepage目錄)

512 Web Base通訊錄測試

httpwwwopencombluepage 新增資料

圖 5-1 新增連絡人

圖 5-2 填入資料

51

圖 5-3 新增成功

搜尋及異動資料

圖 5-4 搜尋通訊錄

52

圖 5-5 編輯資料

圖 5-6 更新資料

513 程式內容及說明

lt-- 程式範例indexhtml--gt lthtmlgt ltheadgtlttitlegt通訊錄lttitlegtltheadgt ltbodygt ltcentergt

53

lth2gt通訊錄lth2gtlthrgt lta href=indexhtmlgt通訊錄ltagt | lta href=addphpgt新增連絡人ltagt | lta href=searchphpgt搜尋通訊錄ltagt ltcentergt ltbodygt lthtmlgt lt-- 程式範例addphp --gt lthtmlgt ltheadgtlttitlegt新增連絡人lttitlegtltheadgt ltbodygt ltcentergtlth2gt新增連絡人lth2gtltcentergtlthrgt lt 取得欄位資料 if (isset($_POST[Name]) ampamp isset($_POST[Tel]) ) $name = $_POST[Name] $tel = $_POST[Tel] 檢查是否有輸入欄位資料 if ($name = ampamp $tel = ) 建立 SQL字串 $sql = INSERT INTO address (name tel) values( $sql= $name $tel) 建立 MySQL 連結 $link = mysql_connect(localhostroot1234) 選擇資料庫 mysql_select_db(CONTACT) 執行 SQL指令 mysql_query($sql) mysql_close($link) echo ltfont color=redgt新增連絡人成功ltfontgtltbrgt gt ltform action=addphp method=postgt lttable border=0 width=300gt lttrgtlttdgt姓名 lttdgt

54

lttdgtltinput type=text name=Name size=20 maxlength=10gtlttdgtlttrgt lttrgtlttdgt電話 lttdgt lttdgtltinput type=text name=Tel size=20 maxlength=20gtlttdgtlttrgt lttrgtlttd colspan=2 align=centergt ltinput type=submit value=新增連絡人gtlttdgtlttrgt lttablegt ltformgt ltbrgtlta href=indexhtmlgt通訊錄ltagt | lta href=addphpgt新增連絡人ltagt | lta href=searchphpgt搜尋通訊錄ltagt ltbodygt lthtmlgt

lt-- 程式範例searchphp --gt lthtmlgt ltheadgtlttitlegt搜尋通訊錄lttitlegtltheadgt ltbodygt ltcentergtlth2gt搜尋通訊錄lth2gtlthrgt lt if (isset($_POST[Search])) 建立資料庫連結並選定資料庫 $link = mysql_connect(localhostroot1234) mysql_select_db(CONTACT) 建立基本的 SQL字串 $sql = SELECT FROM address 檢查是否輸入姓名 if (chop($_POST[Name]) = ) $name = name LIKE $_POST[Name] else $name = 檢查是否輸入電話號碼 if (chop($_POST[Tel]) = ) $tel = tel LIKE $_POST[Tel] else $tel =

55

if條件組合 SQL字串 if (chop($name) = ampamp chop($tel) = ) $sql= WHERE $name AND $tel elseif (chop($name) = ) 只有姓名 $sql = WHERE $name elseif (chop($tel) = ) 只有電話號碼 $sql = WHERE $tel $sql= ORDER BY name 最後加上排序 $result = mysql_query($sql) 取得欄位數 $total_fields = mysql_num_fields($result) echo lttable border=1gt echo lttrgtlttdgt編號lttdgtlttdgt姓名lttdgtlttdgt電話lttdgtlttd colspan=2gt功能選項lttdgtlttrgt 表格顯示查詢結果 while ($rows = mysql_fetch_array($result MYSQL_NUM)) echo lttrgt for ($i = 0 $i lt $total_fields $i++) echo lttdgt$rows[$i]lttdgt echo lttdgtlta href=editphpaction=editampid= echo $rows[0]gtltbgt編輯ltbgtlttdgt echo lttdgtlta href=editphpaction=delampid= echo $rows[0]gtltbgt刪除ltbgtlttdgt echo lttrgt echo lttablegtlthrgt mysql_free_result($result) mysql_close($link) gt ltcentergt ltform action=searchphp method=postgt lttable border=0 width=450gt lttrgtlttdgt搜尋姓名 lttdgt lttdgtltinput type=text name=Name size=10 maxlength=20gtlttdgtlttrgt lttrgtlttdgt搜尋電話 lttdgt lttdgtltinput type=text name=Tel

56

size=20 maxlength=20gtlttdgtlttrgt lttrgtlttd colspan=2 align=centergt ltinput type=submit name=Search value=搜尋gtlttdgtlttrgt lttablegt ltformgt ltbrgtlta href=indexhtmlgt通訊錄ltagt | lta href=addphpgt新增連絡人ltagt | lta href=searchphpgt搜尋通訊錄ltagt ltbodygt lthtmlgt

lt ob_start() gt lt-- 程式範例editphp --gt lthtmlgt ltheadgtlttitlegt編輯通訊錄lttitlegtltheadgt ltbodygt lt 取得 URL 參數 $id = $_GET[id] $action = $_GET[action] 建立資料庫連結 $link = mysql_connect(localhostroot1234) mysql_select_db(CONTACT) 選擇資料庫 執行的操作 switch ($action) case update 更新 取得欄位資料 $name = $_POST[Name] $tel = $_POST[Tel] $sql = UPDATE address SET name=$name tel=$tel WHERE id=$id mysql_query($sql) 執行 SQL指令 mysql_close($link) header(Location searchphp) 轉向到 serachphp break case del 刪除 $sql = DELETE FROM address WHERE id=$id

57

mysql_query($sql) 執行 SQL指令 mysql_close($link) header(Location searchphp) 轉向到 serachphp break case edit 編輯 $sql = SELECT FROM address WHERE id=$id $result = mysql_query($sql) 執行 SQL指令 $row = mysql_fetch_row($result) 取回記錄 $name = $row[1] 取得欄位 name $tel = $row[2] 取得欄位 tel mysql_close($link) 顯示編輯表單 gt ltcentergtlth2gt更新通訊錄lth2gtltcentergtlthrgt ltform action=editphpaction=updateampid=lt echo $id gt method=postgt lttable border=0 width=300gt lttrgtlttdgt姓名 lttdgt lttdgtltinput type=text name=Name size=20 maxlength=10 value=lt echo $name gtgtlttdgtlttrgt lttrgtlttdgt電話 lttdgt lttdgtltinput type=text name=Tel size=20 maxlength=20 value=lt echo $tel gtgtlttdgtlttrgt lttrgtlttd colspan=2 align=centergt ltinput type=submit value=更新連絡人gtlttdgtlttrgt lttablegt ltformgt ltbrgtlta href=indexhtmlgt通訊錄ltagt | lta href=addphpgt新增連絡人ltagt | lta href=searchphpgt搜尋通訊錄ltagt lt break gt ltbodygt lthtmlgt

58

52 任務二Web Base群組軟體 ( twig )

順利完成Web Base客戶通訊錄程式測試一段時間後「Apache + MySQL + PHP」架構的穩定與快速巳深得老闆與公司所有同事的認同隨著公司業績蒸

蒸日上人員組織編罝愈來愈龐大跨部門的會議愈來愈多業務員每日排滿拜

訪客戶的行程跟客戶的 Email的往來也愈來愈頻繁 愈來愈多部門的同事希望公司能建置一套群組軟體提供 web mail可讓業

務人員方便收發 mail還有連絡人議事日程待辦工作書簽等功能讓整個

公司運作及個人時間管理更有效率

老闆問小明對這些需求有什麼看法小明認為如果這些功能完全由程式部

門開發必定曠日費時而且耗費公司資源小明在網路尋找是否有提供這些功能

的Free Software皇天不負苦心人小明發現了TWIG (The Web Information Gateway) httptwigscrewdrivernet這個群組軟體它在 Web 上整合郵件新聞聯絡人議事日程工作序書簽等功能非常符合公司的需求 Step 1 下載 twig-277targz 下載網址 httptwigscrewdrivernetdownloadphp3

Step 2 解開 twig-277targz tar -xzvf twig-277targz

59

Step 3 執行安裝動作安裝到 varwwwhtmltwig 目錄 cd twig-277 twig-install varwwwhtmltwig

Step 4 建立 MySQL 資料庫(twig)及各資料表

cd setup mysql -u root -p1234 mysqlgt create database twig Query OK 1 row affected (001 sec) mysqlgt quit mysql -u root ndashp1234 twiglt twigtablemysql

Step 5 修改 configincphp3 參數設定 vi varwwwhtmltwigconfigconfigincphp3 $config[fromdomain] = opencom 網域 $config[language] = chinesebig5 中文訊息 $config[imap_port] = 143notls

60

Step 6 修改連結 MySQL 的帳號密碼 vi varwwwhtmltwigconfigdbconfigincphp3 $dbconfig[sqlusername] = root username $dbconfig[sqlpassword] = 1234 password

Step 7 其他設定檔

vi etchttpdconfhttpdconf 加入 AddType applicationx-httpd-php php3 在 DirectoryIndex最後加入 indexphp3 DirectoryIndex indexhtml indexhtmlvar indexphp3 在 AddDefaultCharset ISO-8859-1加上 AddDefaultCharset ISO-8859-1

vi etcphpini register_globals = On service httpd restart Step 8 sendmail 設定 vi etcmailsendmailcf在 264 行前面加上並重新啟動 sendmail「service snedmail restart」 262 SMTP daemon options 263 264 O DaemonPortOptions=Port=smtpAddr=127001 Name=MTA 265 266 SMTP client options 267 O ClientPortOptions=Family=inet Address=00

61

Step 9 檢查設定有無錯誤 http主機名稱twigtestphp3

62

Step 10 登入 twig ( http主機名稱twig)

63

第六章 維護及更新程序

61 日常維護

系統管理員最好定期以 root 身份登入看看信件在 RedHat Linux 中有一支 logwatch 程式會定時去分析 log file如果發現異常便會發信給 root除此之外筆者建議讀者平時就檢查 MySQL log file ( varlogmysqldlog)是否有異常情形

62 更新程序

讀者可至httprpmfindnet 尋找MySQL相關套件至於升級的相關步驟請參

考Linux OS SOP 第 54節

63 備份重要檔案

預設 MySQL 的 DB 檔案是存在 varlibmysql 內以 DB名稱為目錄目錄

內就是該 DB 的所有資料通常得定期備份還有 MySQL的設定檔 etcmycnf也別忘了一起備份

64 離線備份與還原

641 離線備份

預設 MySQL 的 DB 檔案是存在 varlibmysql 內以 DB 名稱為目錄目錄內

就是該 DB 的所有資料像 CRM 這個 DB就是存在 varlibmysqlCRM 內在備份前因為怕資料尚未完全寫入磁碟而且 MySQL 會 Lock 在使用的 DB 檔案所以應該是要先把 MySQL 先 Shutdown 一下整個備份的程序可以下像下面的指令去完成 cd varlibmysql

64

service mysqld stop tar cvfz CRM_db_20030905tgz CRM service mysqld start 對這樣就可以了 不過要注意的是怕 DB 內每個 Tables 間的資料有關關

聯性所以最好是把整個 DB 一次備起來單獨只備哪個 Tables 的檔案以後回存時怕會有資料關聯不一致的問題

642 離線還原

DB 發生錯誤而要回存時其實也不難先找出最近一次完整正常的備份先把現在錯誤的網頁或 DB 先更名或 tar 起來再把好的備份給解開回原來目錄位

置就行了需要注意的是 MySQL 服務最好也是要先停止回存完成後再啟動服務回存 DB 的整個程序可能像下面 cd varlibmysql service mysqldstop mv CRM CRM_OLD tar xvfz CRM_db_20030905tg service mysqld start

65 線上備份與還原

651 線上備份

使用像上面的檔案方式備份是個不錯的方法它最少可以保持該主機某個時間點的完整檔案備份但還是有一些問題需要考慮到有些主機就不只建立一個 DB 而已總不能為了備份某個 DB 而把整個 MySQL 服務停止備份檔案的方式回存在原主機上一定適用但假如 MySQL 版本升級或是在那天該網頁空間需遷機移機到別的主機時那就沒人敢保證備出來的資料檔可以用所以我們可以考慮另一種備份的方式是使用 MySQL 本身提供的功能 MySQL Data Dump指令是 mysqldump

65

使用 MySQL 的 Dump 功能可以把 DB 的結構資料或結構加資料 Dump 成文字檔 mysqldump 指令提供的彈性很大你可以選擇把整個 DB Dump 成一個檔或是每個 Table 為一個檔甚至是把結構檔和資料分開儲存都

可以 mysqladmin -uroot -p flush-logs mysqldump CRM -uroot -p --opt gt CRM_20030905sql (CRM 是 DB 名稱 opt 是一個使用完整 Dump 參數) 假如只是要單獨 Dump 某個 Table 時只要在上面的指令後轉出符號 gt 前加個 Table 名稱就可以如只要 phpbb2_users 這個 Table 的 Dump 時只要下 mysqldump CRM -uroot -p --opt CUSTOMER gt CRM_CUSTOMER_20030905sql

652 線上還原

若要回存整個資料庫只需將壓縮的備份檔還原成 Dump 的檔案再用下面的指令回存 mysql CRM -uroot -p lt CRM_20030905sql 這邊需注意的是若建立備份時是以--opt或--add-drop-table為參數時回存的 動作是先將舊的 Table 先刪除重建 Table 的結構後再把 Data 匯入所以回存後所有的資料會回到你當時備份那個時間點因此在回存資料時可以考慮把現有錯誤或不完整的 DB 先備份一份下來以備不時之需或是拿來比對錯誤的地

方在那裡當然你也可以把資料回存到另一個測試用的 DB 內只要把上面指令

的 DB 名稱改成你的測試用 DB 名稱即可 使用這種回存方式 MySQL 服務不需停止也不會動到其他正在使用的 DB 在一些提供 MySQL 服務的虛擬主機可用這種方式作你自己的 DB 備份及回存

66

另外假如你是系統重建或是移機時切需在新的 MySQL 內新建一個空白 DB 後才行作回存的工作你可以用下面的指令建立 mysql -uroot -p -e CREATE DATABASE CRM (上面的 CRM是你要新建的 DB 名稱) 另一種作法先用 mysql 指令進入 mysql client console 然後再用 CREATE DATABASE CRM 這樣就行了記得尾端要加個 符號該行指令才會執行

67

第七章 問題與解答

Q1RedHat 90預附的 MySQL到底有無支援 Transcation機制 Ans MySQL自 32334a之後的 MySQL-Max版本加入 InnoDB的資料庫類型透過

InnoDBMySQL同樣可以進行 COMMIT與 ROLLRACK的動作RedHat 90預附的 MySQL為 32354a-11巳支援 InnoDB的資料庫類型不過必須做以

下設定 1cp usrsharedocmysql-server-32354amy-mediumcnf to etcmycnf 2 vi etcmycnf 將以下設定前的拿掉 innodb_data_home_dir = varlibmysql innodb_data_file_path = ibdata110Mautoextend innodb_log_group_home_dir = varlibmysql innodb_log_arch_dir = varlibmysql 3service mysqld restart 如此一來各位在建立Table時便可指定Table Type為 innodb ( ex create table with type=innodb ) Q2如何解決 php+mysql 許功蓋等字變亂的問題 Ans 方法一 【確定 MySQL 預設的字元集】 1 打開 WinMySQLadmin 管理畫面(在視窗右下角狀態列紅綠燈圖示中按滑鼠

右鍵點選 Show me 選項) 2 點選管理畫面中 [Variables] 標籤選項其中 character_set變數就是您預設

字元集的變數其預設是 latin1 字元集(我們要將他改回 big5)而 chatacters_set 變數則是 MySQL 可以支援哪些字元集 【修改預設字元集變數 character_set 】 1 請點選管理畫面中 [myini Setup] 標籤選項設定 myini 2 按一下 [Pick-up and Edit myini values] 按鈕以便編輯目前的 myini 設定 3 在 [mysqld] 設定區塊底下新增一行 default-character-set = big5 變數設

68

定 4 新增一個 [client] 設定區塊並加入第三步驟的變數設定(游標往下移到空白處新增兩行 [client] 和 default-character-set=big5) 5 按一下畫面左下方 [Save Modification] 按鈕儲存設定 6 重新啟動 MySQL 或 Windows 方法二 Server端注意事項 phpini 中有關的設定為(預設值) Magic quotes for incoming GETPOSTCookie data magic_quotes_gpc = On Use Sybase-style magic quotes (escape with instead of ) magic_quotes_sybase = Off Client端注意事項 1中文資料送進 mysql 前請用 addslashes($str) 處理 2處理後送進 mysql 時請用 括起來並在參數後留一個空白如 $sql = UPDATE ezf_table set tablename=$tname tableend=$endtime table inguser=$tguser tableingid=$tguserid tableallnumber=$tnumber tableloca l=$tablelocal tableanyone=$tableopen tabletext=$ttext WHERE tableid=$t ableid tablename=$tname c 取出時請用 stripslashes($str) Q3MySQL root 密碼忘了該怎麼辦 Ans 1先停掉 mysql etcrcdinitdmysql stop 2以--skip-grant-table 的參數啟動 mysql safe_mysql --skip-grant-tableamp 3 更改 root 密碼 mysql mysql mysqlgt UPDATE user SET password=password(newpassword)

69

WHERE user=root mysqlgt FLUSH PRIVILEGES mysqlgt exit 4停掉 mysql再重跑 mysqladmin -uroot -p shutdown Enter password 輸入新設定的密碼 etcrcdinitdmysql start

Q4NULL值問題

Ans

NULL值的概念是造成 SQL的新手的混淆的普遍原因他們經常認為 NULL是和一個空字符串的一樣的東西不是這樣的例如下列語句是完全不同的

mysqlgt INSERT INTO my_table (phone) VALUES (NULL)

mysqlgt INSERT INTO my_table (phone) VALUES ()

兩個語句把值插入到 phone 列但是第一個插入一個 NULL值而第二個插入一個空字符串第一個的含義可以認為是ldquo電話號碼不知道而第二個則可意味

著ldquo她沒有電話

在 SQL中NULL值在于任何其他值甚至 NULL值比較時總是假的(FALSE)包含 NULL的一個表達式總是產生一個 NULL值除非在包含在表達式中的運算符和函數的文檔中指出在下列例子所有的列返回 NULL

mysqlgt SELECT NULL1+NULLCONCAT(InvisibleNULL)

如果你想要尋找值是 NULL的列你不能使用=NULL測試下列語句不返回任

何行因為對任何表達式expr = NULL是假的

mysqlgt SELECT FROM my_table WHERE phone = NULL

要想尋找 NULL值你必須使用 IS NULL測試下例顯示如何找出 NULL電話號碼和空的電話號碼

70

mysqlgt SELECT FROM my_table WHERE phone IS NULL mysqlgt SELECT FROM my_table WHERE phone =

在 MySQL中就像很多其他的 SQL服務器一樣你不能索引可以有 NULL值的列你必須聲明這樣的列為 NOT NULL而且你不能插入 NULL到索引的

列中

當用 LOAD DATA INFILE 讀取數據時空列用更新如果你想要在一個列中有

NULL值你應該在文本文件中使用N字面上的詞NULL也可以在某些情形下使用

當使用 ORDER BY時首先呈現 NULL值如果你用 DESC以降序排序NULL值最後顯示當使用 GROUP BY時所有的 NULL值被認為是相等的

為了有助于NULL的處理你能使用 IS NULL和 IS NOT NULL運算符和 IFNULL()函數

對某些列類型NULL值被特殊地處理如果你將 NULL插入表的第一個TIMESTAMP 列則插入當前的日期和時間如果你將 NULL插入一個AUTO_INCREMENT 列則插入順序中的下一個數字

Q5如何將圖片存放於 MySQL中

Ans

Step 1建立資料庫 test

Step 2 建立表格 binary_data

CREATE TABLE binary_data (

id INT(4) NOT NULL AUTO_INCREMENT PRIMARY KEY

description CHAR(50)

bin_data LONGBLOB

filename CHAR(50)

filesize CHAR(50)

filetype CHAR(50)

71

)

Step 3 利用 storephp 寫入圖片

storephp 程式碼

ltHTMLgt ltHEADgtltTITLEgtStore binary data into SQL DatabaseltTITLEgtltHEADgt ltBODYgt lt code that will be executed if the form has been submitted

if ($submit) mysql_connect(localhostrootYOUR_PASSWORD) mysql_select_db(test) $data=Base64_Encode(fread(fopen($form_data r) filesize($form_data))) $result=MYSQL_QUERY(INSERT INTO binary_data (descriptionbin_datafilenamefilesizefiletype) VALUES ($form_description$data$form_data_name$form_data_size$form_data_type)) $id= mysql_insert_id() print ltpgtThis file has the following Database ID ltbgt$idltbgt MYSQL_CLOSE() else else show the form to submit new data

gt

ltform method=post action=ltphp echo $PHP_SELF gt enctype=multipartform-datagt File Descriptionltbrgt ltinput type=text name=form_description size=40gt ltINPUT TYPE=hidden name=MAX_FILE_SIZE value=4000000gt ltbrgtFile to uploadstore in databaseltbrgt ltinput type=file name=form_data size=40gt ltpgtltinput type=submit name=submit value=submitgt ltformgt lt

72

gt ltBODYgt ltHTMLgt

Step 3 利用 storephp 取出圖片

getdataphp 程式碼

lt Syntax getdataphp3id=ltidgt if($id) you may have to modify login information for your database server MYSQL_CONNECT(localhostrootYOUR_PASSWORD) mysql_select_db(test) $query = select bin_datafiletype from binary_data where id=$id $result = MYSQL_QUERY($query) $data = Base64_Decode(MYSQL_RESULT($result0bin_data)) $type = MYSQL_RESULT($result0filetype) Header( Content-type $type) echo $data gt

Q6MySQL裝好之後啟動時或是執行 mysqladmin會出現如下訊息 Cant connect to local MYSQL Server through Socket varlibmysqlmysqlsock或是

Cant connect to local MYSQL Server through Socket tmpmysqldsock

Ans 可能有下列幾個原因

1這個 mysqldsock 不見了被某人刪除了或是被一些系統自動執行程式給刪

了例如有些 cron任務便會設定定期刪除 tmp 裡的東西所以呢您只能修改

cron 裡的設定讓它不要清除 mysqldsock 2在啟動時也可以改變 mysqldsock的位置您在啟動 MySQL的時候可以加入此參數usrlocalmysqlbinsafe_mysqld --user=mysql --socket=其他路

徑socket amp 同時得去設定環境變數 MYSQL_UNIX_PORT的值以指定新的

73

路徑 3若是您沒改 MYSQL_UNIX_PORT的值那麼您可以在執行指令的時候才打

例如mysqladmin --socket=其他路徑socket version Q7How to get the last insert id Ans CREATE TABLE product ( id INT(4) NOT NULL AUTO_INCREMENT PRIMARY KEY description VARCHAR(50) ) 1利用 SQL的話 mysqlgt insert into product(description) values(123) Query OK 1 row affected (000 sec) mysqlgt select last_insert_id() +------------------+ | last_insert_id() | +------------------+ +------------------+ 1 row in set (000 sec) ======================================== 2如果是 PHP的話 你可以用mysql_insert_id()取得該 id PHP example $result=MYSQL_QUERY(INSERT INTO product (description) VALUES ($description)) $id= mysql_insert_id() print This file has the following Database ID $id Q8如何將文字檔匯入資料庫 Ans $addr=homehttpdhtmlphpschool001txt $sql_select = load data infile $addr into table test fields terminated by t 解說 $sql_select = load data infile 文字檔名 into table 表格名 fields terminated by

74

t

(欄位分隔以 TAB鍵) 該文字檔須與資料表欄位格式相符 例如欄位有三個 則文字檔為每行一筆資料如下 欄 1資料ltTABgt欄 2資料ltTABgt欄 3資料 欄 1資料ltTABgt欄 2資料ltTABgt欄 3資料 欄 1資料ltTABgt欄 2資料ltTABgt欄 3資料 欄 1資料ltTABgtltTABgt欄 3資料

Q9如何撰寫 MySQL C API Ans Step 1利用文字編輯器撰寫以下程式碼 mysqlcc

include ltstdiohgt

include ltmysqlmysqlhgt

int main (int argc char argv[])

MYSQL mysql

MYSQL_RES res

MYSQL_ROW row

if (argc = 2)

fputs (Usage myc ltdatabasegt stderr)

return 1

if ((mysql_connect(ampmysqllocalhostrootYour_Password)))

fputs (Error connecting stderr)

abort()

75

if (mysql_select_db(ampmysqlargv[1]))

fputs (Error selecting database stderr)

abort()

if (mysql_query(ampmysqlSELECT FROM test_table))

fputs (Error processing query stderr)

abort()

if ((res = mysql_store_result(ampmysql)))

fputs (Error storing results stderr)

abort()

while((row = mysql_fetch_row(res)))

uint i = 0

for (i=0 i lt mysql_num_fields(res) i++)

printf(s row[i])

printf(n)

return 0

Step 2 Compile

gcc -Iusrlocalmysqlinclude -Lusrlocalmysqllibmysql mysqlcc ndashlm -lmysqlclient

(其中 include path與 library path取決於你的 MySQL安裝路徑)

76

如果執行時發生如下 error Run problemerror in loading shared libraries libmysqlclientsoX 將你的 MySQL library path(for exampleusrlocalmysqllibmysql) 加入etcldsoconf and run sbinldconfig -v Q9ASP + MySQL 範例程式 Ans Dim myconn As New ADODBConnection Dim myrs As New Recordset Dim mySQL As String Dim myrows As Long myconnOpen DSN=MyODBCsample mySQL = SELECT from user myrsSource = mySQL Set myrsActiveConnection = myconn myrsCursorLocation = adUseClient myrsOpen myrows = myrsRecordCount myrsClose myconnClose 可參考 httpwwwdwamnetmysqlasp_myodbcasp 有詳細的資料 Q10如何將 MySQL中的資料庫匯出成txt檔 Ans select from TableName into outfile textxls all result fields will seperate by tab

77

第八章 參考資料

英文部份 網址 1 httpwwwmysqlcom MySQL 網站有第一手有關 MySQL的資料 2 httpwwwmysqlcomdocenReplicationhtml 有關 MySQL Replication 的文件 3 httpwwwgeocitiescomsqlhomefaqstore_blobhtml 如何在 MySQL 存放 BLOB的資料 4httpwwwsapdborg 有關 SAP跟 MySQL相關合作的網站 書藉 1 Cooking with MySQL

Paul DuBois has selected sample recipes from the hundreds youll find in his book MySQL

Cookbook In this third and final series of excerpts showcasing these recipes learn how to

compute team standings how to calculate the differences between successive Dec 26

2002 2 Tips for Building Web Database Applications with PHP and MySQL by Hugh E Williams co-author of Web Database Applications with PHP amp MySQL 04042002

3 Managing and Using MySQL 2nd Edition By Tim King George Reese Randy Jay Yarger

4 MySQL Cookbook By Paul DuBoisPublisher OReillyPub Date October 2002

中文部份

78

1 httplinuxtncedutwtechdocmysqlmysql_docmanual_tochtml MySQL 中文手冊 2 httpchenshloxaedutwphpZ_1php PHP+MySQ程式研習設計網站 3 httplinuxtncedutwtechdocbanicdownhtml PHP 4 手冊 4 httpwwwtncedutwadmin_zonephp台南縣教育網網路中心有很多 Linux相關文件 5 httpdobtncedutw網站建置百寶箱有很多 PHP MySQL 相關範例程式 5 httpwwwdbworldcomtw資料庫專家電子雜誌介紹資料庫的重要觀念及名詞

79

附錄一 SQL Command 介紹

SQL (讀音ess-que-el) 是一種結構查詢語法SQL 使用於資料庫交流

傳遞相容於 ANSI (American National Standards Institute) 是一套標準的關聯

式資料庫語言 SQL 語言是執行更新或從資料系統獲取資料一般常見的關聯

資料庫系統都有提供 SQL 如 Oracle Sybase Microsoft SQL Server Access Ingres 等雖然大部份的資料庫都有提供 SQL 但也多提供了自已獨特的語

法造成了不相容的情形但標準基本的語法是相通的如Select Insert Update Delete Create and Drop 每一個系統都有支援

Table相關 Command

Create Table

關聯式資料庫包含有很多元件稱為資料表(tables) 把資料或訊息放在資

料表中 資料表是以不同的名稱做分別資料表由欄列所構成的二維陣列

欄包含欄位名資料型態 及其他可判斷的資訊列是由全部欄位構成一筆一

筆的紀錄 create table 語法用在建立一個新的資料表語法格式如下

create table tablename (column1 data type column2 data type column3 data type)

Format of create table if you were to use optional constraints

create table tablename (column1 data type [constraint] column2 data type [constraint] column3 data type [constraint]) [ ] = optional

Note You may have as many columns as youd like and the constraints are optional

80

Example

create table employee (first varchar(15) last varchar(20) age number(3) address varchar(30) city varchar(20) state varchar(20))

注意建立資料表格式要以括號把前後框住而最後以(分號)做結尾

欄位名不要超過 30個字元長而且不要使用 sql 的關鍵字(如 where select等)而在後面接是型態的宣告(如字串數字日期格式等)

資料型態是來描述欄位的方式如一個欄位Last_Name 是一個姓氏可以使用varchar (可變動長度字串) 資料型態

以下是幾個常見的資料庫型態 char(size) 固定長度字串最長為 255 位元 varchar(size) 變動長度字串最大字元數以 size 來指定 number(size) 數值格式可以是整數也可以是小數最大數字以 size 位數判

斷未指定小數位數由系統內定 date 日期格式 number(sized) 數值格式最大數字以 size 位數判斷d 為小數位數整數位

數為 size-d 位

有何限制當資料表被建立通常有一或數個欄位是要使用來做關聯的功

能 例如unique 限制(唯一值)兩筆記錄不可以相同的值 not null (非空值)該欄位一定要輸入資料不可是空的primary key (主鍵)是每一筆記錄識別的主要方式

Drop a table drop table 刪除資料表(其中的資料也會一併刪除)

drop table tablename

Example

81

drop table 和刪除全部資料是不同的刪除全部資料欄位名稱資訊等還會

存在但刪除資料表會把這一些也一併移除掉

如何查詢資料

Select 基本用法

select 語法是關連式資料庫最常用的部份可以取得你想要的資料這是一個

簡單的範例 select column1[column2etc] from tablename [where condition] [] = optional 在 select 之後所列欄位名則是要顯示的資料部份你可以一一列出各欄位

名或是以 (星號)來代表選擇全部的欄位 from 之後放資料表名稱 where 子句 (選項) 指定要過濾的條件符合者才會顯現 where 可使用的條件運算元 = 等於 gt 大於 lt 小於 gt= 大或等於 lt= 小或等於 ltgt 大相等 LIKE 相似 For example select first last city

82

from empinfo where first LIKE Er 以Er 為開頭的字串就符合要以單引號框住 Or you can specify select first last from empinfo where last LIKE s 最後一字為 S 就符合 select from empinfo where first = Eric 則表示 first name 一定要是 Eric 才可以 範例資料表empinfo 統計函數

MIN 傳回指定欄位最小值

MAX 傳回指定欄位最大值

SUM 傳回指定欄位總和

AVG 傳回指定欄位平均值

COUNT 傳回指定欄位的筆數

COUNT() 傳回資料庫中的總筆數

統計函數使用於資料表中的數值欄位配合 SELECT 語法使用 只用於總結特定單一欄位可以配合 GROUP BY 做篩選但也可以不使用 GROUP BY 語句For example

SELECT AVG(salary) FROM employee

83

傳回全部 salary 平均值

Another example

SELECT AVG(salary) FROM employee WHERE title = Programmer

傳回 salary 平均值條件為 employees 資料表中當 title 等於 Programmer

Example

SELECT Count() FROM employees

傳回 employees 資料表中紀錄總筆數

GROUP BY 語法 SELECT column1 SUM(column2) FROM list-of-tables GROUP BY column-list The GROUP BY 語句可以先以所列的欄位為條件分組排序在一起(可以多欄

位) example 要列出每一個 dept 中最高 salary 值 SELECT max(salary) dept FROM employee GROUP BY dept HAVING 語法

SELECT column1 SUM(column2) FROM list-of-tables GROUP BY column-list HAVING condition

HAVING 子句是 GROUP BY 的一部份用來過濾在 GROUP BY 所選出的資料功能如同 select 命令中 where 條件式一樣只是 HAVING 必需配合 GROUP BY 使用

我們以例子來說明我們要取得每一公司名及每一公司的薪水平均值輸入如下

84

SELECT dept avg(salary) FROM employee GROUP BY dept

但如果我們只列出薪資平均值超過 20000元的公司資料

SELECT dept avg(salary) FROM employee GROUP BY dept HAVING avg(salary) gt 20000

ORDER BY子句語法

SELECT column1 SUM(column2) FROM list-of-tables ORDER BY column-list [ASC | DESC]

[ ] =選項

ORDER BY是一個選項子句當你以排序方式來顯示資料(正向由小到大反向由大到小)以指定的欄位資料做排序

ASC = 正向- 預設值 DESC = 反向排序

For example

SELECT employee_id dept name age salary FROM employee_info WHERE dept = Sales ORDER BY salary

以上列出公司代號公司名銷售員人名年紀及薪資而條件是公司名為 Sales 顯示順序以薪資多少排序(由小到大為預設值)

如果要以多個欄位做排序要以逗號做分隔如下

SELECT employee_id dept name age salary FROM employee_info WHERE dept = Sales ORDER BY salary age DESC

85

結合條件及布林運算 SELECT column1 SUM(column2) FROM list-of-tables WHERE condition1 AND condition2 AND運算可以結兩個或以上的條件放在 WHERE子句中 兩者都要為真才

會顯示該筆記錄 OR 運算可以結兩個或以上敘述放在 WHERE子句中只要其中一個為直就

會顯示該筆記錄 For example SELECT employeeid firstname lastname title salary FROM employee_info WHERE salary gt= 5000000 AND title = Programmer 必需要薪資大於等於 50000而且職稱為 Programmer同時符合才會顯示該筆資料 以下以括號括住雖然不是必需的但如此比較容易讀 SELECT employeeid firstname lastname title salary FROM employee_info WHERE (salary gt= 5000000) AND (title = Programmer) 另外範例 SELECT firstname lastname title salary FROM employee_info WHERE (title = Sales) OR (title = Programmer) 條件為只要是 Sales 或 Programmer 職稱的就會被列出 IN and BETWEEN 子句

SELECT column1 SUM(column2) FROM list-of-tables WHERE column3 IN (list-of-values) SELECT column1 SUM(column2) FROM list-of-tables WHERE column3 BETWEEN value1 AND value2 IN 子句使用在列舉項目的使用上也就是分別測試是否符合所列的值 For example

86

SELECT employeeid lastname salary FROM employee_info WHERE lastname IN (Hernandez Jones Roberts Ruiz) 條件為姓氏(astname)要符合 Hernandez Jones Roberts or Ruiz 其中一個才會被傳回 IN運算元也可以使用 OR 的語法來取代如下結果相同 SELECT employeeid lastname salary FROM employee_info WHERE lastname = Hernandez OR lastname = Jones OR lastname = Roberts OR lastname = Ruiz 但使用 IN 句子比較短也比較易懂 你也可以使用 NOT IN 來去掉不要的記錄 BETWEEN 運算元使用在判斷是否存在兩個數值之間 For example SELECT employeeid age lastname salary FROM employee_info WHERE age BETWEEN 30 AND 40 傳回年紀 30歲到 40歲之間的資料(含 30及 40歲者) 相同的也可以使用以下語法來達到相同的結果 SELECT employeeid age lastname salary FROM employee_info WHERE age gt= 30 AND age lt= 40 你也可使用 NOT BETWEEN 來濾掉中間值的資料 數學運算 標準 ANSI SQL-92 提供以下運算

87

+ 加

- 減

餘數

餘數為除法後剩整數這不在標準的 ANSI SQL 中但大部份的資料庫都會支

援這運算元以下列出有用的函數雖不在 ANSI SQL-92 提供但一般資料庫

也會支援他們

ABS(x) 傳回 x 絕對值

SIGN(x) returns the sign of input x as -1 0 or 1 (negative zero or positive respectively)

MOD(xy) 餘數 - returns the integer remainder of x divided by y (同 xy)

FLOOR(x) 傳回小或等於 x 的最大整數值

CEILING(x) or CEIL(x)

傳回大或等於 x 的最小整數值

POWER(xy) x的 y 次方

ROUND(x) 把 x 四捨五入為整數

ROUND(xd) 四捨五入取到小數 d 位

SQRT(x) x 開平方

For example SELECT round(salary) firstname FROM employee_info 傳回薪資取到整數位

如何新增資料

insert 加入一筆新紀錄到資料表中 insert into tablename (first_columnlast_column) values (first_valuelast_value) [] = optional Example insert into employee

88

(first last age address city state) values (Luke Duke 45 2130 Boars Nest Hazard Co Georgia) Note 字串要以單引號住如string 數字框住也無妨 insert into 後面接資料表名稱再接以括號括住的欄位名在 values 後括號分別對映各欄位的值 以上的例子新增了一筆名(first) 為 Luke而住所(state) 為 Georgia 的資料

如何刪除資料

delete 可以刪除單筆或多筆紀錄 delete from tablename where columnname OPERATOR value [and|or column OPERATOR value] [ ] = optional Examples delete from employee Note 如果你沒有指定 where 子句那麼全部的紀錄都會被刪除 delete from employee where lastname = May delete from employee where firstname = Mike or firstname = Eric delete from 接著資料表名 再接著是條件式判斷沒有條件式則全部紀錄會

被刪除

如何更新資料

update 用來更新你所指定的記錄要和 WHERE 配合小心使用 語法 update tablename set columnname = newvalue[nextcolumn = newvalue2] where columnname OPERATOR value [and|or column OPERATOR value] [] = optional Examples

89

update phone_book set area_code = 623 where prefix = 979 update phone_book set last_name = Smith prefix=555 suffix=9292 where last_name = Jones update employee set age = age+1 where first_name=Mary and last_name=Williams

90

附錄二Replication

測試環境

RedHat 90 + MySQL 32358 MySQL資料庫路徑 varlibmysql MySQL設定檔 etcmycnf Master IP 1921680100 Slave IP 1921680200 請至下列網址下載最新MySQL 32358套件並利用rpm ndashUvh 更新 httpupdatesredhatcom9enosi386

圖 最新 MySQL 套件

測試架構圖

91

1921680100

1921680200Master Server

erveSlave S r

圖 測試架構圖

測試步驟

Master server 部份 Step1 確認 MasterSlave機器上所裝的 MySQL版本能進行

replication( 32329 or higher ) Step2 在 Master MySQL上開放一個帳號給 Slave mysql ndashu root ndashp mysqlgtGRANT FILE ON TO repl1921680200 IDENTIFIED BY lsquoabc123rsquo mysqlgtq 上面是 Master開放一個帳號 repl密碼 abc123給 IP1921680200有檔案處理

的權限 Step3 shutdown MySQL on the Master mysqladmin ndashu root ndashp shutdown Step4 備份 Master所有資料庫 tar ndashcvf tmpmysql-snapshottar varlibmysql 注意tar的時候MySQL是要在 stop情況下 在mysql (wwwmysqlcom) 網站的FAQ有不用shutdown的方法

92

Step5 在 master機器上修改etcmycnf 在[mysqld]區段內加入參數 log-bin server-id=這邊設定 server-id=1 sql-bin-update-same binlog-do-db=CRM只針對 CRM資料庫做紀錄 Step6 Restart MySQL on the master service mysqld start 此時因為有加入 log-bin 參數因此開始有 index產生了在varlibmysql目錄下

有index檔案紀錄資料庫的異動 log Slave server 部份 Step1 在 slave設定etcmycnf 在[mysqld]區段加入 master-host= master-user= master-password= master-port= server-id= 這邊設定 master-host=1921680100 master-user=repl master-password=abc123 master-port=3306 server-id=2 master-connect-retry=60預設重試間隔 60秒 replicate-do-db=CRM告訴 slave只做 CRM資料庫的更新 log-slave-updates Step2 將 master上的 mysql-snapshottar copy到 slave上 用 ftp傳到 slave的tmp Step3 解壓縮 Master資料庫至 Slave Server上 cd varlib tar xvf tmpmysql-snapshottar chown ndashR mysqlmysql mysql

93

chmod ndashR 770 mysql (視情況) Step4 Restart MySQL on the slave server 這時在varlibmysql目錄會出現 masterinfo此檔案紀錄了 Master MySQL server的資訊

狀況測試

One-way replication

1921680100

1921680200Master Server

erveSlave S r

圖 One-way replication架構圖 Step1 Master跟 Slave網路及服務都正常情況下由 Master端異動資料後 到 Slave端瀏覽資料檢視是否有進行 replication Step2 模擬 Slave Server 當機 可用在於 slave真的當機或是 Slave 不一定需要一直跟 master connect將Slave MySQL server shutdown由 Master端異動資料到 slave端瀏覽此時Slave應該沒有被 replication 更新然後再將 Slave端 MySQL server start起來

預設 60秒後 Slave會嘗試跟 Master要求進行 replication再去 Slave端檢視是否有更新資料

94

Step3 模擬 Master當機因為是設定 One-way replication一旦 Master Server Slave端沒有 Master的 source可以 download Two-way replication 基於 Master當機狀況於是發展雙向 Replication即 1921680100 ( Host A ) 1921680200 ( Host B )都分別擔任 MasterSlave身分

1921680100

1921680200er

Server B MasterSlave Server

Server A MasterSlave Serv

圖 Two-way replication架構圖 以下是針對兩台 MySQL伺服器進行雙向 Replication Step1觀念同單向 replication只是改成 Master也有 Slave身分 Slave也有Master的身分先分別在 Server AServer B 都去 grant一個進行 replication的身分 [A]mysqlgtGRANT FILE ON TO repl1921680200 IDENTIFIED BY lsquoabc123rsquo [B]mysqlgt GRANT FILE ON TO repl1921680100 IDENTIFIED BY lsquoabc123rsquo Step2做完單向 replication後stop Server Aserver B MySQL service此時 AB資料是一樣的

95

修改etcmycnf設定 範例 Server A [mysqld] datadir=varlibmysql socket=varlibmysqlmysqlsock server-id=1 log-bin sql-bin-update-same binlog-do-db=CRM master-host=1921680200 master-user=repl master-password=abc123 log-slave-updates master-connect-retry=60 replicate-do-db=CRM Server B [mysqld] datadir=varlibmysql socket=varlibmysqlmysqlsock server-id=2 log-bin sql-bin-update-same binlog-do-db=CRM master-host=1921680100 master-user=repl master-password=abc123 log-slave-updates master-connect-retry=60 replicate-do-db=CRM 分別 start Server AServer B MySQL後此時雙方都是 MasterSlave身分一旦哪一方資料異動就會通知對方來 replication-若 replication失效則必須將Server AServer B的masterinfo及index00x 都砍掉然後分別 restart MySQL server進行測試檢視成果 實務上通常如果需要做Two-way replication通常會搭配Virtual Server使用

96

在前端架設一台Virtual Server不過此部份不在此份SOP討論範圍內有興趣

的讀者可參考 httpwwwlinuxvirtualserverorg 網站

1921680100 1921680200

Host A MasterSlave Server

Host B MasterSlave Server

Virtual Host

圖 Virtual Server + Two-way replication 架構圖

97

圖 High Availability Linux Virtual Server架構圖

98

  • COSA-SOP-03-006
  • 第一章 簡介
    • 11適用對象 (Audience)
    • 12 MySQL本身
    • 13 MySQL 40版跟50版重大的改進功能
    • 14 各家資料庫軟體比較
      • 第二章 前置需求
      • 第三章 安裝
        • 31 MySQL安裝
        • 32 phpMyAdmin安裝
        • 33 升級及注意事項
          • 第四章 MySQL管理
            • 41 Webmin 管理介面
            • 42 phpMyAdmin 的操作介面
            • 43管理指令介紹
              • 431 利用mysqladmin設定root的密碼
                  • 第五章 實用範例
                    • 51 任務一Web Base客戶通訊錄
                    • 52 任務二Web Base群組軟體 ( twig )
                      • 第六章 維護及更新程序
                        • 61 日常維護
                        • 62 更新程序
                        • 63 備份重要檔案
                        • 64 離線備份與還原
                        • 65 線上備份與還原
                          • 第七章 問題與解答
                          • 第八章 參考資料
                          • 附錄一 SQL Command 介紹
                          • 附錄二Replication
Page 4: DataBase Server Standard Operation Procedureebooks.lib.ntu.edu.tw/1_file/oss/63/93doc4-5.pdf · 業務的公司帶來了不少壓力,譬如微軟,甲骨文 ... 外的錢用在第三方的資料庫產品上,譬如就可以不用再購買甲骨文公司

62 更新程序 64 63 備份重要檔案 64 64 離線備份與還原 64

641 離線備份64 642 離線還原65

65 線上備份與還原 65 651 線上備份65 652 線上還原66

第七章 問題與解答 68

第八章 參考資料 78

附錄一 SQL COMMAND 介紹 80

附錄二REPLICATION 91

4

第一章 簡介

MySQL 是一種 跨平台多使用者多執行緒支援 SQL語言 (結構化查詢語言)執行速度快廣受全球網站大量採用的網路資料庫系統最重要的

是在大部份情形下使用 MySQL 是完全免費的( MySQL自 32319之後已改為 GPL版權宣告囉)整體而言MySQL 免費原始碼開放入門容易

執行速度快跨平台 (亦支援 Windows 2000)支援工具眾多等特性十分適合中小企業用來開發各種資訊系統企業不必再花費數十萬元去購買一些費而

不惠的資料庫 MySQL 沒有所謂連線使用者限制其它商用資料庫系統一定數量以上的

連線使用者數可是要付出相當可觀的費用的像 Yahoo等大公司也是用 MySQL 哩 連這麼大的入口網站都安心地挑選 MySQL 一般的中小企業更

無需擔心 MySQL的穩定性

11適用對象 (Audience)

本 SOP的對象適合一般的使用者及系統管理者編排的方式大部分皆採操

作步驟的模式進行方便一般入門的使用者

12 MySQL本身

在 Unix平台上最受到歡迎的一套資料庫系統就是 MySQL MySQL於1990中期開始發展當時Michael Mothnty Widenius在位於瑞典的 TcX DataKonsultAB開始開發這套軟體並在 1995 年公開釋放第一個版本

MySQL 同時擁有頗為可觀跨平台能力它能 Unix Like平台工作例如 AIX

SolarisFreeBSD及 Linux也能在 Mac OS X及Windows NT2000 server亦或是 Microsoft Wrokstation 系統上如 9xMEXP上開發程式更重要的是它是

讓您擁有原始碼 在 MySQL 在 323之後的版本在每個系統元件上在釋放時都會加上一個

完成度的註解如由「gamma」階段到「stale」階段「beat」階段到「alpha」階段階段愈低愈不穩定查詢目前的發展版本可以在 MySQL 參考手冊及線上

文件找到

5

MySQL經過考驗證明是值得信賴的資料庫系統如果您是 stable版的使用者您大可以放心MySQL對於版本的控制是十分注意並提供廣大的使用者原始碼下載Bug也因此很快就被解決

MySQL主要是以技術支援和經銷資料庫為主和 Red Hat在 Linux上的做

法非常類似背後則是由創投資金在支持客戶可以下載 MySQL並遵照 GPL授權規定使用MySQL公司則以技術服務作為收入

MySQL也提供付費的解決方案給想要整合 MySQL和其他軟體產品但是

又不想讓客戶取得程式碼的公司MySQL表示MySQL資料庫在全球已經有

400萬的使用者但是並不清楚其中有多少付費用戶到目前為止MySQL也已經引起企業用戶的興趣甚至包括 Yahoo和 Google等網際網路的領導廠商

MySQL最原始的構想嚐試克服自由軟體資料庫系統「mSQL」的一些功能

上的限制MySQL成長進步的非常的快尤其當贊助者由網際網路應用中看出

MySQL能提供網站所需強健資料庫的潛能對於 MySQL成長的速度幫助不少

而近來更有令人振奮的好消息( 2003 年 5月 ) ERP的龍頭 SAP正在與 MySQL就開放源代碼資料庫軟體進行合作這項

交易將會使得 MySQL這樣更小的公司能夠加速它的開發計畫此舉將允許

MySQL公司在未來的兩年內為其資料庫軟體添加更高端的一些特徵MySQL公司的首席執行官 Marten Mickos 說公司早在四年前就希望能夠進軍高端資料

庫業務這次交易在資料庫市場上還引起了另外一些影響它給那些開發資料庫

業務的公司帶來了不少壓力譬如微軟甲骨文以及 IBM等因為這項交易為

這些公司不斷樹立了一個越來越強大的開放源代碼軟體的競爭者而開放源代碼

軟體最終也許會吞噬它們的資料庫市場 SAP公司一直是銷售那些管理核心業務的一些軟體譬如會計軟體存貨

管理軟體這些產品以前一直是各大公司的暢銷軟體為了吸引那些中等規模的

公司客戶從而進行業務擴張這家德國的公司開始在他們的一些產品中加入SAP DB這是一個開放源代碼的資料庫軟體該軟體就可以免除 SAP公司客戶花額外的錢用在第三方的資料庫產品上譬如就可以不用再購買甲骨文公司的資料庫

軟體 根據他們的技術交錯式授權協議MySQL公司將會主宰 SAP DB的絕大部

分再開發業務並且 MySQL也會使用該程式的設計作為該公司未來改進的資料

庫軟體的模型SAP公司的一位元代表稱隨著 MySQL資料庫軟體的不斷成

熟SAP公司將會用新的 MySQL的資料庫軟體代替 SAP DBMickos 說在

6

這項交易中這家瑞典公司 MySQL將會得到其軟體的版稅但他拒絕透露這次

合作的一些經濟方面的細節 SAP的代表稱在更長一段時間後該開放源代碼資料庫軟體將會和 SAP

公司的旗艦產品 R3一起銷售 不久之後SAP與 MySQL將會完成他們合作計畫的第一個階段那

就是 SAP將會發佈一個 MySQL的資料庫版本從而它可以無縫地替代現在使

用的 SAP DB這對 MySQL而言無異是如虎添翼想必在不久的將來MySQL定能擔任企業更重要的任務

13 MySQL 40版跟 50版重大的改進功能

以下是 40版跟 50版一些重大的改進功能 MySQL 40 版httpwwwmysqlcomdocenNews-40xhtml

內建提供InnoDB table type支援 standard binaries adding transactions row-level locking 和foreign keys

提昇 Query速度 改善 boolean mode truncation and phrase searching全文檢索效

率 加強MERGE tables 並支援INSERT statements and

AUTO_INCREMENT 在SELECT 中支援UNION 語法 支援Multi-table DELETE statements libmysqld the embedded server library 更多的GRANT 參數來加強安全性 提供更多動態參數來降低停止 MySQL的必要 改善 replication code and features 改善執行效率並增加可靠性

MySQL 50 版httpwwwmysqlcomdocenTODO_MySQL_50html改善執行效率並增加可靠性 提供 Stored Procedures 機制 支援 cursor Dynamic length rows for HEAP tables Add true VARCHAR support

7

加強執行效率 更好的國際語系支援 提供可用性

14 各家資料庫軟體比較

目前市面上較被廣為使用資料庫除了 MySQL之外尚有下列幾種

1 MS SQL Server 2000 2 Oracle 8i 3 IBM DB2 4 Informix

過去幾年來在總值 120億美元的資料庫市場上如果廠商想要誇讚自家的

產品那就一定得要有強大的資料庫支援最嚴苛的任務才站得上檯面不過

到了今天似乎光是這樣並不夠客戶除了要求足以負擔嚴苛的任務之外還希

望擁有聰明又便宜的資料庫 Meta Group的分析師 Charlie Garry表示 ( 2003 年 5 月)MySQL的商業

模式是以開放原始碼為基礎以便讓客戶盡快接受 MySQLGarry指出MySQL甚至適合用在甲骨文IBM微軟等大廠爭相搶食的企業資料中心

Information Resources的資訊長 Marshall Gibbs就表示他們沒有任何品

牌的偏好只要「功能效能價格的最佳組合」 由研究近兩年來資料庫客戶

愈來愈注重總體成本(圖 1-1)

8

圖 1-1 資料庫優先性

整體擁有成本 大致說來MySQL是免費的MySQL需要付費的規定只限於下列兩種情

形 1 以 Embedded的方式使用 MySQL 2 使用 MySQL的商業用途軟體

且其授權費用一台 MySQL Pro License只需美金 $440比起其他任何資料庫軟體來得容易負擔多了加上其易於管理的特性著實可大大降低企業資料

庫的整體擁有成本 擴充性

MySQL同時提供高度多樣性能夠提供給很多不同的使用者介面包括命

令列操作網頁瀏覽器以及各式各樣的程式語言介面例如JavaC++PerlPHP及 PhythonMySQL可用 UnixWindows以及 OS2hellip等平台因此它可以用個人電腦或是伺服器上 性能 事實上大部份的網站的開發者都認為 MySQL是目前市面跑得最快的資料

9

庫對資料庫的最佳化主要在於你對他的設定和資料庫結構的設計如果你的

資料庫結構設計得非常差你的存取速度還是會受到影響而變得比較慢

10

第二章 前置需求

在安裝 MySQL之前請確定 Apache及 MySQL亦巳安裝相關步驟請參考

Apache SOP安裝 Apache及 PHP相關章節

11

第三章 安裝

31 MySQL安裝

在 RedHat 90上安裝 MySQL是件很容易的事因為 RedHat 90提供了一

個很方便的 GUI套件管理工具「redhat-config-packages」各位只要把 RedHat 90第一片光碟放入並以 root的身份登入系統鍵入 redhat-config-packages勾選「SQL資料庫伺服器」即可然後按「更新」如果遇到任何相依性問題

系統會提示您更換光碟片 ( 圖 3-1 ~ 3-3 ) Step 1 執行 redhat-config-packes

圖 3-1

Step 2 選擇資料伺服器

12

圖 3-2

Step 3檢查是否安裝成功 待安裝後您可以用利用「rpm -qa | grpe ^mysql」檢查是否安裝成功

圖 3-3

啟動 MySQL ( Command Mode )馬上啟動 MySQL的指令為「service mysqld start」如果您希望一開機就自動啟動 MySQL請執行「chkconfig mysqld on」

13

圖 3-4

啟動 MySQL ( WebMin 介面 ) 我們也可以利用WebMin 來啟動 MySQL步驟如下 Step 1登入Webmin

圖 3-5 登入WebMin

Step 2 選擇伺服器

14

圖 3-6 伺服器畫面

Step 2 選擇 MySQL資料庫伺服器

圖 3-7 伺服器畫面

15

Step 3 啟動 MySQL資料庫伺服器

圖 3-8 啟動 MySQL

更改資料庫管理者密碼

成功啟動 MySQL後因為資料庫管理者預設沒有密碼建議使用前更改系

統管理者密碼請輸入下列指令

mysqladmin ndashu root ndashh cosaexamplecom password lsquo1234rsquo -u 表示使用者帳號root 為 MySQL預設的管理帳號

-h 表示 MySQL主機的主機名稱也可使用 IP Address password 表示使用者的密碼因為字串請使用單引號將密碼括起來

圖 3-9 修改 MySQL 的密碼

16

32 phpMyAdmin安裝

本書除了會介紹利用當今 Linux上最紅的整合管理工具Webmin 來管理

MySQL外還會為各位介紹專門管理 MySQL的工具 phpMyAdmin phpMyAdmin是免費的 PHP原始程式碼的Web網站可用來管理整個

MySQL伺服器這是一套Web介面的 MySQL管理程式支援中文的使用者介

面 phpMyAdmin只需透過瀏覽器就可管理 MySQL伺服器換句話說不論

MySQL是安裝在 Linux或是Windows 作業系統都可以使用相同步驟在

MySQL上建立資料庫(Database)資料表(Table)和編輯紀錄(Record) Step 1 下載phpMyAdmin ( httpwwwphpmyadminnet )選擇最櫎新穩定的版

本 253

圖 3-10 httpwwwphpmyadminnet

17

圖 3-11 下載 phpMyAdmin-253-phptarbz2

Step 2 將 phpMyAdmin-253-phptarbz2收至 tmp 並執行下列指令將其解壓

縮至varwww tar jxvf phpMyAdmin-253-phptarbz ndashC varwwwhtml

圖 3-12 解壓縮安裝 phpMyadmin-253

Step 3 為了操作方便起見建立 Soft link ln ndashs phpMyAdmin-253 phpMyAdmin

圖 3-13 修改 phpMyadmin 設定檔 configincphp

18

Step 4 修改 phpMyadmin 設定檔 configincphp gedit varwwwhtmlphpMyAdminconfigincphp

圖 3-14 configincphp設定檔

Step 5 設定顯示行號以方便修改 configincphp 設定檔

19

圖 3-15 顯示行號

Step 6 修改下列設定 第 39 行 設定 phpMyAdmin的 URL 第 69 行 MySQL Server 的 ip 第 80 行 利用何帳號存取 MySQL 第 81 行 如果 root有設定 password此處即填入 root的 password

30 In most cases you can leave this variable empty as the correct value

31 will be detected automatically However we recommend that you do

32 test to see that the auto-detection code works in your system A good

33 test is to browse a table then edit a row and save it There will be

34 an error message if phpMyAdmin cannot auto-detect the correct value

35

36 If the auto-detection code does work properly you can set to TRUE the

37 $cfg[PmaAbsoluteUri_DisableWarning] variable below

38

39 $cfg[PmaAbsoluteUri] = httpossccosaorgtwphpMyAdmin

hellip

20

hellip

69 $cfg[Servers][$i][host] = localhost MySQL hostname or IP address hellip 80 $cfg[Servers][$i][user] = root MySQL user

81 $cfg[Servers][$i][password] = 1234 MySQL password (only needed

圖 3-16 修改 configincphp

21

圖 3-17 修改 configincphp

圖 3-18 修改 configincphp p

Step 7 設定語系

22

圖 3-19 設定語系

圖 3-20 執行 phpMyAdmin

23

33 升級及注意事項

RedHat 90附的 MySQL版本為 323 MySQL所釋出最新穩定版本為

40若是您不想用系統預附的 323請先利用下列移除之前 323的版本

rpm ndashe mysql-devel rpm ndashe mysql-server rpm ndashe mysql --nodeps 然後到下列網址下載您所想要的版本進行安裝在這裏我們用 4014版為例 Step 1 下載相關套件( httpwwwmysqlcomdownloadsmysql-40html )

圖 3-21 Download MySQL 4014 相關 RPM Step 2 利用 rpm 指令安裝

24

圖 3-22 Install MySQL 4014 相關 RPM

圖 3-23 Install MySQL 4014 相關 RPM

Step 3 啟動 MySQL

25

圖 3-24 啟動 MySQL 4014 並修改密碼

26

第四章 MySQL管理

本章將我們介紹利用WebminphpAdminCommand的方式建立一個名為

CONTACT的資料庫內有一個 address的 Table作為我們客戶通訊錄程式使

用的資料庫

41 Webmin 管理介面

412建立資料庫

Step 1 登入Webmin

圖 4-1 登入WebMin

Step 2 點選伺服器

27

圖 4-2 伺服器畫面

Step 3 點選 MySQL資料庫伺服器

圖 4-3 MySQL資料庫伺服器

28

Step 4 建立一個新的資料庫

圖 4-4 建立 MySQL資料庫

Step 5 建立名為 CONTACT的資料庫

29

圖 4-5 指定資料庫名稱

412 建立資料表

假設我們要建立一個名為 address的 Table其結構如下 欄位名稱 資料型態 長度 說明 id INT (自動編號) 連絡人編號 name varchar文字 20 連絡人姓名 tel Varchar文字 15 連絡人電話 Step 1 選擇 CONTACT資料庫

30

圖 4-6 選擇資料庫

Step 2 指定欄位數目

31

圖 4-7 設定欄位數目

Step 3設定表格欄位屬性

圖 3-8 設定表格欄位屬性

Step 4建立表格資料

32

圖 4-9 建立表格資料

圖 4-10 檢視資料

33

圖 4-11 新增資料

圖 4-12

34

圖 4-13

413 使用者管理

接下來我們要利用Webmin 來建立資料庫使用者並給予某些權限 Step1建立使用者

35

圖 4-14 選擇使用者權限

圖 4-15

36

Step2 賦予權限

圖 4-16

Step3 權限列表

37

圖 4-17

38

42 phpMyAdmin 的操作介面

421建立資料庫

Step 填入資料庫名稱並按「建立」

圖 4-18建立資料庫

422 建立資料表

Step1 填入資料表名稱並指定欄位數量 執行

39

圖 4-19填入資料表名稱並指定欄位數量

Step2 設定欄位屬性

圖 4-20設定欄位屬性

40

Step3 phpMyAdmin會產生相關的 SQL Command

圖 4-21 資料表結構及相關 SQL Command

Step4新增 Record

41

圖 4-22

圖 4-23

42

圖 4-24

圖 4-25

43

423使用者管理

Step1建立使用者

圖 4-26

44

圖 4-27

Step2 給予權限

圖 4-28

Step3權限列表

45

圖 4-29

43管理指令介紹

431 利用 mysqladmin設定 root的密碼

當您在Windows 或 Linux 中安裝好 MySQL後系統會自動幫您建立兩個

帳分別是 root 和 匿名者MySQL的 root 跟 Linux 最高權限使用者 root無關MySQL的 root使用者相當於 MS SQL 中的 sa 帳號擁有最高的 Database管理權限但系統預設 MySQL的 root 是不需要密碼所以通常我們一安裝

MySQL後首要任務便是修改 root的密碼 我們可以利用 mysqladmin工具或是直接修改 MySQL內部資料庫的使用者資

料 mysqladmin ndashu root ndashh cosaexamplecom password lsquo1234rsquo

46

-u 表示使用者帳號root 為 MySQL預設的管理帳號

-h 表示 MySQL主機的主機名稱也可使用 IP Address password 表示使用者的密碼因為字串請使用單引號將密碼括起來 密碼設定完成之後還是可以利用 mysqladmin修改密碼但是你必須提供目前的密碼

432 連線 MySQL

mysql -uroot -p密碼 (-p和密碼之間不能有空白) 或 mysql -uroot -p (此方式會在進入後要求密碼) [rootossc phpMyAdmin] mysql -u root -p1234

Welcome to the MySQL monitor Commands end with or g

Your MySQL connection id is 25 to server version 32354

Type help or h for help Type c to clear the buffer

mysqlgt show databases

+----------+

| Database |

+----------+

| mysql |

| test |

+----------+

2 rows in set (000 sec)

mysqlgt exit

Bye

[rootossc phpMyAdmin]

433 建立資料庫

可利用 mysqladmin指令建立 CONTACT資料庫 mysqladmin -u root -p1234 create CONTACT

47

或是利用 mysql指令 [rootossc bluepage] mysql -u root -p1234 Welcome to the MySQL monitor Commands end with or g Your MySQL connection id is 1057 to server version 32354 Type help or h for help Type c to clear the buffer mysqlgt create database CONTACT Query OK 1 row affected (000 sec) mysqlgt show databases +----------+ | Database | +----------+ | CONTACT | | address | | hello | | mysql | | nuke | | test | +----------+ 6 rows in set (000 sec) mysqlgt exit

434 建立資料表

編寫 adresssql內容如下 -- Table structure for table address CREATE TABLE address ( id int(11) NOT NULL auto_increment name varchar(20) NOT NULL default tel varchar(15) NOT NULL default PRIMARY KEY (id) ) TYPE=MyISAM

48

-- Dumping data for table address INSERT INTO address VALUES (1林小明0800016888) INSERT INTO address VALUES (2黃大雄0800016888) INSERT INTO address VALUES (3劉小芬0800024365) 然後執行此 sql script mysql -u root -p1234 CONTACT lt addresssql 或是利 mysql command [rootossc bluepage] mysql -u root -p1234 Welcome to the MySQL monitor Commands end with or g Your MySQL connection id is 1090 to server version 32354 Type help or h for help Type c to clear the buffer mysqlgt use CONTACT Database changed Database changed mysqlgt CREATE TABLE address ( -gt id int(11) NOT NULL auto_increment -gt name varchar(20) NOT NULL default -gt tel varchar(15) NOT NULL default -gt PRIMARY KEY (id) -gt ) TYPE=MyISAM Query OK 0 rows affected (000 sec) mysqlgt INSERT INTO address VALUES (1林小明0800016888) Query OK 1 row affected (000 sec) mysqlgt INSERT INTO address VALUES (2黃大雄0800016888) Query OK 1 row affected (000 sec) mysqlgt INSERT INTO address VALUES (3劉小芬0800024365) Query OK 1 row affected (000 sec) mysqlgt exit Bye

49

第五章 實用範例

51 任務一Web Base客戶通訊錄

任職於開放科技公司的林小明前些日子在最符合成本效益的條件下快

速地完成公司網站的建置老闆因此對小明讚譽有加最近因為公司存放客戶資

料的 SQL Server主機屢遭病毒攻擊加上作業系統本身的問題當機次數頻繁

老闆希望能儘快把公司的客戶通訊錄程式移轉到較穩定的環境上因為此客戶通

訊錄程式最主要給內部人員使用所以介面美觀並不特別要求只求穩定且能快

速得到查詢結果老闆希望在短時間先看到程式的雛型並鍵入資料對其效率

及穩定性進行測試因為上次小明表現突出所以這次不可能的任務自然又落到

小明身上 小明想來想去既然要快速又穩定他而且又不希望所有人都得安裝 Client

程式於是小明決定)捨棄他的舊愛「Delphi+MS SQL」投向新歡「Apache + MySQL + PHP」利用此架構來設計一個簡單實用的Web Base客戶通訊錄程式

511 Web Base客戶通訊錄架構

此程式需要建立 CONTACT的資料庫並建立 adress Tables其結構如下表建立步驟請參考第三章 欄位名稱 資料型態 長度 說明 id INT (自動編號) 連絡人編號 name varchar文字 20 連絡人姓名 tel Varchar文字 15 連絡人電話 Web Base通訊錄共有下列幾個檔案功能如下表

檔案名稱 說明 Indexhtml Web Base通訊錄首頁 addphp 新增連絡人的 php程式 searchphp 尋找連絡人的 php程式 editphp 具有更新及刪除功能的 php程式

50

我們將這些檔案放至varwwwhtmlbluepage (預設無 bluepage目錄)

512 Web Base通訊錄測試

httpwwwopencombluepage 新增資料

圖 5-1 新增連絡人

圖 5-2 填入資料

51

圖 5-3 新增成功

搜尋及異動資料

圖 5-4 搜尋通訊錄

52

圖 5-5 編輯資料

圖 5-6 更新資料

513 程式內容及說明

lt-- 程式範例indexhtml--gt lthtmlgt ltheadgtlttitlegt通訊錄lttitlegtltheadgt ltbodygt ltcentergt

53

lth2gt通訊錄lth2gtlthrgt lta href=indexhtmlgt通訊錄ltagt | lta href=addphpgt新增連絡人ltagt | lta href=searchphpgt搜尋通訊錄ltagt ltcentergt ltbodygt lthtmlgt lt-- 程式範例addphp --gt lthtmlgt ltheadgtlttitlegt新增連絡人lttitlegtltheadgt ltbodygt ltcentergtlth2gt新增連絡人lth2gtltcentergtlthrgt lt 取得欄位資料 if (isset($_POST[Name]) ampamp isset($_POST[Tel]) ) $name = $_POST[Name] $tel = $_POST[Tel] 檢查是否有輸入欄位資料 if ($name = ampamp $tel = ) 建立 SQL字串 $sql = INSERT INTO address (name tel) values( $sql= $name $tel) 建立 MySQL 連結 $link = mysql_connect(localhostroot1234) 選擇資料庫 mysql_select_db(CONTACT) 執行 SQL指令 mysql_query($sql) mysql_close($link) echo ltfont color=redgt新增連絡人成功ltfontgtltbrgt gt ltform action=addphp method=postgt lttable border=0 width=300gt lttrgtlttdgt姓名 lttdgt

54

lttdgtltinput type=text name=Name size=20 maxlength=10gtlttdgtlttrgt lttrgtlttdgt電話 lttdgt lttdgtltinput type=text name=Tel size=20 maxlength=20gtlttdgtlttrgt lttrgtlttd colspan=2 align=centergt ltinput type=submit value=新增連絡人gtlttdgtlttrgt lttablegt ltformgt ltbrgtlta href=indexhtmlgt通訊錄ltagt | lta href=addphpgt新增連絡人ltagt | lta href=searchphpgt搜尋通訊錄ltagt ltbodygt lthtmlgt

lt-- 程式範例searchphp --gt lthtmlgt ltheadgtlttitlegt搜尋通訊錄lttitlegtltheadgt ltbodygt ltcentergtlth2gt搜尋通訊錄lth2gtlthrgt lt if (isset($_POST[Search])) 建立資料庫連結並選定資料庫 $link = mysql_connect(localhostroot1234) mysql_select_db(CONTACT) 建立基本的 SQL字串 $sql = SELECT FROM address 檢查是否輸入姓名 if (chop($_POST[Name]) = ) $name = name LIKE $_POST[Name] else $name = 檢查是否輸入電話號碼 if (chop($_POST[Tel]) = ) $tel = tel LIKE $_POST[Tel] else $tel =

55

if條件組合 SQL字串 if (chop($name) = ampamp chop($tel) = ) $sql= WHERE $name AND $tel elseif (chop($name) = ) 只有姓名 $sql = WHERE $name elseif (chop($tel) = ) 只有電話號碼 $sql = WHERE $tel $sql= ORDER BY name 最後加上排序 $result = mysql_query($sql) 取得欄位數 $total_fields = mysql_num_fields($result) echo lttable border=1gt echo lttrgtlttdgt編號lttdgtlttdgt姓名lttdgtlttdgt電話lttdgtlttd colspan=2gt功能選項lttdgtlttrgt 表格顯示查詢結果 while ($rows = mysql_fetch_array($result MYSQL_NUM)) echo lttrgt for ($i = 0 $i lt $total_fields $i++) echo lttdgt$rows[$i]lttdgt echo lttdgtlta href=editphpaction=editampid= echo $rows[0]gtltbgt編輯ltbgtlttdgt echo lttdgtlta href=editphpaction=delampid= echo $rows[0]gtltbgt刪除ltbgtlttdgt echo lttrgt echo lttablegtlthrgt mysql_free_result($result) mysql_close($link) gt ltcentergt ltform action=searchphp method=postgt lttable border=0 width=450gt lttrgtlttdgt搜尋姓名 lttdgt lttdgtltinput type=text name=Name size=10 maxlength=20gtlttdgtlttrgt lttrgtlttdgt搜尋電話 lttdgt lttdgtltinput type=text name=Tel

56

size=20 maxlength=20gtlttdgtlttrgt lttrgtlttd colspan=2 align=centergt ltinput type=submit name=Search value=搜尋gtlttdgtlttrgt lttablegt ltformgt ltbrgtlta href=indexhtmlgt通訊錄ltagt | lta href=addphpgt新增連絡人ltagt | lta href=searchphpgt搜尋通訊錄ltagt ltbodygt lthtmlgt

lt ob_start() gt lt-- 程式範例editphp --gt lthtmlgt ltheadgtlttitlegt編輯通訊錄lttitlegtltheadgt ltbodygt lt 取得 URL 參數 $id = $_GET[id] $action = $_GET[action] 建立資料庫連結 $link = mysql_connect(localhostroot1234) mysql_select_db(CONTACT) 選擇資料庫 執行的操作 switch ($action) case update 更新 取得欄位資料 $name = $_POST[Name] $tel = $_POST[Tel] $sql = UPDATE address SET name=$name tel=$tel WHERE id=$id mysql_query($sql) 執行 SQL指令 mysql_close($link) header(Location searchphp) 轉向到 serachphp break case del 刪除 $sql = DELETE FROM address WHERE id=$id

57

mysql_query($sql) 執行 SQL指令 mysql_close($link) header(Location searchphp) 轉向到 serachphp break case edit 編輯 $sql = SELECT FROM address WHERE id=$id $result = mysql_query($sql) 執行 SQL指令 $row = mysql_fetch_row($result) 取回記錄 $name = $row[1] 取得欄位 name $tel = $row[2] 取得欄位 tel mysql_close($link) 顯示編輯表單 gt ltcentergtlth2gt更新通訊錄lth2gtltcentergtlthrgt ltform action=editphpaction=updateampid=lt echo $id gt method=postgt lttable border=0 width=300gt lttrgtlttdgt姓名 lttdgt lttdgtltinput type=text name=Name size=20 maxlength=10 value=lt echo $name gtgtlttdgtlttrgt lttrgtlttdgt電話 lttdgt lttdgtltinput type=text name=Tel size=20 maxlength=20 value=lt echo $tel gtgtlttdgtlttrgt lttrgtlttd colspan=2 align=centergt ltinput type=submit value=更新連絡人gtlttdgtlttrgt lttablegt ltformgt ltbrgtlta href=indexhtmlgt通訊錄ltagt | lta href=addphpgt新增連絡人ltagt | lta href=searchphpgt搜尋通訊錄ltagt lt break gt ltbodygt lthtmlgt

58

52 任務二Web Base群組軟體 ( twig )

順利完成Web Base客戶通訊錄程式測試一段時間後「Apache + MySQL + PHP」架構的穩定與快速巳深得老闆與公司所有同事的認同隨著公司業績蒸

蒸日上人員組織編罝愈來愈龐大跨部門的會議愈來愈多業務員每日排滿拜

訪客戶的行程跟客戶的 Email的往來也愈來愈頻繁 愈來愈多部門的同事希望公司能建置一套群組軟體提供 web mail可讓業

務人員方便收發 mail還有連絡人議事日程待辦工作書簽等功能讓整個

公司運作及個人時間管理更有效率

老闆問小明對這些需求有什麼看法小明認為如果這些功能完全由程式部

門開發必定曠日費時而且耗費公司資源小明在網路尋找是否有提供這些功能

的Free Software皇天不負苦心人小明發現了TWIG (The Web Information Gateway) httptwigscrewdrivernet這個群組軟體它在 Web 上整合郵件新聞聯絡人議事日程工作序書簽等功能非常符合公司的需求 Step 1 下載 twig-277targz 下載網址 httptwigscrewdrivernetdownloadphp3

Step 2 解開 twig-277targz tar -xzvf twig-277targz

59

Step 3 執行安裝動作安裝到 varwwwhtmltwig 目錄 cd twig-277 twig-install varwwwhtmltwig

Step 4 建立 MySQL 資料庫(twig)及各資料表

cd setup mysql -u root -p1234 mysqlgt create database twig Query OK 1 row affected (001 sec) mysqlgt quit mysql -u root ndashp1234 twiglt twigtablemysql

Step 5 修改 configincphp3 參數設定 vi varwwwhtmltwigconfigconfigincphp3 $config[fromdomain] = opencom 網域 $config[language] = chinesebig5 中文訊息 $config[imap_port] = 143notls

60

Step 6 修改連結 MySQL 的帳號密碼 vi varwwwhtmltwigconfigdbconfigincphp3 $dbconfig[sqlusername] = root username $dbconfig[sqlpassword] = 1234 password

Step 7 其他設定檔

vi etchttpdconfhttpdconf 加入 AddType applicationx-httpd-php php3 在 DirectoryIndex最後加入 indexphp3 DirectoryIndex indexhtml indexhtmlvar indexphp3 在 AddDefaultCharset ISO-8859-1加上 AddDefaultCharset ISO-8859-1

vi etcphpini register_globals = On service httpd restart Step 8 sendmail 設定 vi etcmailsendmailcf在 264 行前面加上並重新啟動 sendmail「service snedmail restart」 262 SMTP daemon options 263 264 O DaemonPortOptions=Port=smtpAddr=127001 Name=MTA 265 266 SMTP client options 267 O ClientPortOptions=Family=inet Address=00

61

Step 9 檢查設定有無錯誤 http主機名稱twigtestphp3

62

Step 10 登入 twig ( http主機名稱twig)

63

第六章 維護及更新程序

61 日常維護

系統管理員最好定期以 root 身份登入看看信件在 RedHat Linux 中有一支 logwatch 程式會定時去分析 log file如果發現異常便會發信給 root除此之外筆者建議讀者平時就檢查 MySQL log file ( varlogmysqldlog)是否有異常情形

62 更新程序

讀者可至httprpmfindnet 尋找MySQL相關套件至於升級的相關步驟請參

考Linux OS SOP 第 54節

63 備份重要檔案

預設 MySQL 的 DB 檔案是存在 varlibmysql 內以 DB名稱為目錄目錄

內就是該 DB 的所有資料通常得定期備份還有 MySQL的設定檔 etcmycnf也別忘了一起備份

64 離線備份與還原

641 離線備份

預設 MySQL 的 DB 檔案是存在 varlibmysql 內以 DB 名稱為目錄目錄內

就是該 DB 的所有資料像 CRM 這個 DB就是存在 varlibmysqlCRM 內在備份前因為怕資料尚未完全寫入磁碟而且 MySQL 會 Lock 在使用的 DB 檔案所以應該是要先把 MySQL 先 Shutdown 一下整個備份的程序可以下像下面的指令去完成 cd varlibmysql

64

service mysqld stop tar cvfz CRM_db_20030905tgz CRM service mysqld start 對這樣就可以了 不過要注意的是怕 DB 內每個 Tables 間的資料有關關

聯性所以最好是把整個 DB 一次備起來單獨只備哪個 Tables 的檔案以後回存時怕會有資料關聯不一致的問題

642 離線還原

DB 發生錯誤而要回存時其實也不難先找出最近一次完整正常的備份先把現在錯誤的網頁或 DB 先更名或 tar 起來再把好的備份給解開回原來目錄位

置就行了需要注意的是 MySQL 服務最好也是要先停止回存完成後再啟動服務回存 DB 的整個程序可能像下面 cd varlibmysql service mysqldstop mv CRM CRM_OLD tar xvfz CRM_db_20030905tg service mysqld start

65 線上備份與還原

651 線上備份

使用像上面的檔案方式備份是個不錯的方法它最少可以保持該主機某個時間點的完整檔案備份但還是有一些問題需要考慮到有些主機就不只建立一個 DB 而已總不能為了備份某個 DB 而把整個 MySQL 服務停止備份檔案的方式回存在原主機上一定適用但假如 MySQL 版本升級或是在那天該網頁空間需遷機移機到別的主機時那就沒人敢保證備出來的資料檔可以用所以我們可以考慮另一種備份的方式是使用 MySQL 本身提供的功能 MySQL Data Dump指令是 mysqldump

65

使用 MySQL 的 Dump 功能可以把 DB 的結構資料或結構加資料 Dump 成文字檔 mysqldump 指令提供的彈性很大你可以選擇把整個 DB Dump 成一個檔或是每個 Table 為一個檔甚至是把結構檔和資料分開儲存都

可以 mysqladmin -uroot -p flush-logs mysqldump CRM -uroot -p --opt gt CRM_20030905sql (CRM 是 DB 名稱 opt 是一個使用完整 Dump 參數) 假如只是要單獨 Dump 某個 Table 時只要在上面的指令後轉出符號 gt 前加個 Table 名稱就可以如只要 phpbb2_users 這個 Table 的 Dump 時只要下 mysqldump CRM -uroot -p --opt CUSTOMER gt CRM_CUSTOMER_20030905sql

652 線上還原

若要回存整個資料庫只需將壓縮的備份檔還原成 Dump 的檔案再用下面的指令回存 mysql CRM -uroot -p lt CRM_20030905sql 這邊需注意的是若建立備份時是以--opt或--add-drop-table為參數時回存的 動作是先將舊的 Table 先刪除重建 Table 的結構後再把 Data 匯入所以回存後所有的資料會回到你當時備份那個時間點因此在回存資料時可以考慮把現有錯誤或不完整的 DB 先備份一份下來以備不時之需或是拿來比對錯誤的地

方在那裡當然你也可以把資料回存到另一個測試用的 DB 內只要把上面指令

的 DB 名稱改成你的測試用 DB 名稱即可 使用這種回存方式 MySQL 服務不需停止也不會動到其他正在使用的 DB 在一些提供 MySQL 服務的虛擬主機可用這種方式作你自己的 DB 備份及回存

66

另外假如你是系統重建或是移機時切需在新的 MySQL 內新建一個空白 DB 後才行作回存的工作你可以用下面的指令建立 mysql -uroot -p -e CREATE DATABASE CRM (上面的 CRM是你要新建的 DB 名稱) 另一種作法先用 mysql 指令進入 mysql client console 然後再用 CREATE DATABASE CRM 這樣就行了記得尾端要加個 符號該行指令才會執行

67

第七章 問題與解答

Q1RedHat 90預附的 MySQL到底有無支援 Transcation機制 Ans MySQL自 32334a之後的 MySQL-Max版本加入 InnoDB的資料庫類型透過

InnoDBMySQL同樣可以進行 COMMIT與 ROLLRACK的動作RedHat 90預附的 MySQL為 32354a-11巳支援 InnoDB的資料庫類型不過必須做以

下設定 1cp usrsharedocmysql-server-32354amy-mediumcnf to etcmycnf 2 vi etcmycnf 將以下設定前的拿掉 innodb_data_home_dir = varlibmysql innodb_data_file_path = ibdata110Mautoextend innodb_log_group_home_dir = varlibmysql innodb_log_arch_dir = varlibmysql 3service mysqld restart 如此一來各位在建立Table時便可指定Table Type為 innodb ( ex create table with type=innodb ) Q2如何解決 php+mysql 許功蓋等字變亂的問題 Ans 方法一 【確定 MySQL 預設的字元集】 1 打開 WinMySQLadmin 管理畫面(在視窗右下角狀態列紅綠燈圖示中按滑鼠

右鍵點選 Show me 選項) 2 點選管理畫面中 [Variables] 標籤選項其中 character_set變數就是您預設

字元集的變數其預設是 latin1 字元集(我們要將他改回 big5)而 chatacters_set 變數則是 MySQL 可以支援哪些字元集 【修改預設字元集變數 character_set 】 1 請點選管理畫面中 [myini Setup] 標籤選項設定 myini 2 按一下 [Pick-up and Edit myini values] 按鈕以便編輯目前的 myini 設定 3 在 [mysqld] 設定區塊底下新增一行 default-character-set = big5 變數設

68

定 4 新增一個 [client] 設定區塊並加入第三步驟的變數設定(游標往下移到空白處新增兩行 [client] 和 default-character-set=big5) 5 按一下畫面左下方 [Save Modification] 按鈕儲存設定 6 重新啟動 MySQL 或 Windows 方法二 Server端注意事項 phpini 中有關的設定為(預設值) Magic quotes for incoming GETPOSTCookie data magic_quotes_gpc = On Use Sybase-style magic quotes (escape with instead of ) magic_quotes_sybase = Off Client端注意事項 1中文資料送進 mysql 前請用 addslashes($str) 處理 2處理後送進 mysql 時請用 括起來並在參數後留一個空白如 $sql = UPDATE ezf_table set tablename=$tname tableend=$endtime table inguser=$tguser tableingid=$tguserid tableallnumber=$tnumber tableloca l=$tablelocal tableanyone=$tableopen tabletext=$ttext WHERE tableid=$t ableid tablename=$tname c 取出時請用 stripslashes($str) Q3MySQL root 密碼忘了該怎麼辦 Ans 1先停掉 mysql etcrcdinitdmysql stop 2以--skip-grant-table 的參數啟動 mysql safe_mysql --skip-grant-tableamp 3 更改 root 密碼 mysql mysql mysqlgt UPDATE user SET password=password(newpassword)

69

WHERE user=root mysqlgt FLUSH PRIVILEGES mysqlgt exit 4停掉 mysql再重跑 mysqladmin -uroot -p shutdown Enter password 輸入新設定的密碼 etcrcdinitdmysql start

Q4NULL值問題

Ans

NULL值的概念是造成 SQL的新手的混淆的普遍原因他們經常認為 NULL是和一個空字符串的一樣的東西不是這樣的例如下列語句是完全不同的

mysqlgt INSERT INTO my_table (phone) VALUES (NULL)

mysqlgt INSERT INTO my_table (phone) VALUES ()

兩個語句把值插入到 phone 列但是第一個插入一個 NULL值而第二個插入一個空字符串第一個的含義可以認為是ldquo電話號碼不知道而第二個則可意味

著ldquo她沒有電話

在 SQL中NULL值在于任何其他值甚至 NULL值比較時總是假的(FALSE)包含 NULL的一個表達式總是產生一個 NULL值除非在包含在表達式中的運算符和函數的文檔中指出在下列例子所有的列返回 NULL

mysqlgt SELECT NULL1+NULLCONCAT(InvisibleNULL)

如果你想要尋找值是 NULL的列你不能使用=NULL測試下列語句不返回任

何行因為對任何表達式expr = NULL是假的

mysqlgt SELECT FROM my_table WHERE phone = NULL

要想尋找 NULL值你必須使用 IS NULL測試下例顯示如何找出 NULL電話號碼和空的電話號碼

70

mysqlgt SELECT FROM my_table WHERE phone IS NULL mysqlgt SELECT FROM my_table WHERE phone =

在 MySQL中就像很多其他的 SQL服務器一樣你不能索引可以有 NULL值的列你必須聲明這樣的列為 NOT NULL而且你不能插入 NULL到索引的

列中

當用 LOAD DATA INFILE 讀取數據時空列用更新如果你想要在一個列中有

NULL值你應該在文本文件中使用N字面上的詞NULL也可以在某些情形下使用

當使用 ORDER BY時首先呈現 NULL值如果你用 DESC以降序排序NULL值最後顯示當使用 GROUP BY時所有的 NULL值被認為是相等的

為了有助于NULL的處理你能使用 IS NULL和 IS NOT NULL運算符和 IFNULL()函數

對某些列類型NULL值被特殊地處理如果你將 NULL插入表的第一個TIMESTAMP 列則插入當前的日期和時間如果你將 NULL插入一個AUTO_INCREMENT 列則插入順序中的下一個數字

Q5如何將圖片存放於 MySQL中

Ans

Step 1建立資料庫 test

Step 2 建立表格 binary_data

CREATE TABLE binary_data (

id INT(4) NOT NULL AUTO_INCREMENT PRIMARY KEY

description CHAR(50)

bin_data LONGBLOB

filename CHAR(50)

filesize CHAR(50)

filetype CHAR(50)

71

)

Step 3 利用 storephp 寫入圖片

storephp 程式碼

ltHTMLgt ltHEADgtltTITLEgtStore binary data into SQL DatabaseltTITLEgtltHEADgt ltBODYgt lt code that will be executed if the form has been submitted

if ($submit) mysql_connect(localhostrootYOUR_PASSWORD) mysql_select_db(test) $data=Base64_Encode(fread(fopen($form_data r) filesize($form_data))) $result=MYSQL_QUERY(INSERT INTO binary_data (descriptionbin_datafilenamefilesizefiletype) VALUES ($form_description$data$form_data_name$form_data_size$form_data_type)) $id= mysql_insert_id() print ltpgtThis file has the following Database ID ltbgt$idltbgt MYSQL_CLOSE() else else show the form to submit new data

gt

ltform method=post action=ltphp echo $PHP_SELF gt enctype=multipartform-datagt File Descriptionltbrgt ltinput type=text name=form_description size=40gt ltINPUT TYPE=hidden name=MAX_FILE_SIZE value=4000000gt ltbrgtFile to uploadstore in databaseltbrgt ltinput type=file name=form_data size=40gt ltpgtltinput type=submit name=submit value=submitgt ltformgt lt

72

gt ltBODYgt ltHTMLgt

Step 3 利用 storephp 取出圖片

getdataphp 程式碼

lt Syntax getdataphp3id=ltidgt if($id) you may have to modify login information for your database server MYSQL_CONNECT(localhostrootYOUR_PASSWORD) mysql_select_db(test) $query = select bin_datafiletype from binary_data where id=$id $result = MYSQL_QUERY($query) $data = Base64_Decode(MYSQL_RESULT($result0bin_data)) $type = MYSQL_RESULT($result0filetype) Header( Content-type $type) echo $data gt

Q6MySQL裝好之後啟動時或是執行 mysqladmin會出現如下訊息 Cant connect to local MYSQL Server through Socket varlibmysqlmysqlsock或是

Cant connect to local MYSQL Server through Socket tmpmysqldsock

Ans 可能有下列幾個原因

1這個 mysqldsock 不見了被某人刪除了或是被一些系統自動執行程式給刪

了例如有些 cron任務便會設定定期刪除 tmp 裡的東西所以呢您只能修改

cron 裡的設定讓它不要清除 mysqldsock 2在啟動時也可以改變 mysqldsock的位置您在啟動 MySQL的時候可以加入此參數usrlocalmysqlbinsafe_mysqld --user=mysql --socket=其他路

徑socket amp 同時得去設定環境變數 MYSQL_UNIX_PORT的值以指定新的

73

路徑 3若是您沒改 MYSQL_UNIX_PORT的值那麼您可以在執行指令的時候才打

例如mysqladmin --socket=其他路徑socket version Q7How to get the last insert id Ans CREATE TABLE product ( id INT(4) NOT NULL AUTO_INCREMENT PRIMARY KEY description VARCHAR(50) ) 1利用 SQL的話 mysqlgt insert into product(description) values(123) Query OK 1 row affected (000 sec) mysqlgt select last_insert_id() +------------------+ | last_insert_id() | +------------------+ +------------------+ 1 row in set (000 sec) ======================================== 2如果是 PHP的話 你可以用mysql_insert_id()取得該 id PHP example $result=MYSQL_QUERY(INSERT INTO product (description) VALUES ($description)) $id= mysql_insert_id() print This file has the following Database ID $id Q8如何將文字檔匯入資料庫 Ans $addr=homehttpdhtmlphpschool001txt $sql_select = load data infile $addr into table test fields terminated by t 解說 $sql_select = load data infile 文字檔名 into table 表格名 fields terminated by

74

t

(欄位分隔以 TAB鍵) 該文字檔須與資料表欄位格式相符 例如欄位有三個 則文字檔為每行一筆資料如下 欄 1資料ltTABgt欄 2資料ltTABgt欄 3資料 欄 1資料ltTABgt欄 2資料ltTABgt欄 3資料 欄 1資料ltTABgt欄 2資料ltTABgt欄 3資料 欄 1資料ltTABgtltTABgt欄 3資料

Q9如何撰寫 MySQL C API Ans Step 1利用文字編輯器撰寫以下程式碼 mysqlcc

include ltstdiohgt

include ltmysqlmysqlhgt

int main (int argc char argv[])

MYSQL mysql

MYSQL_RES res

MYSQL_ROW row

if (argc = 2)

fputs (Usage myc ltdatabasegt stderr)

return 1

if ((mysql_connect(ampmysqllocalhostrootYour_Password)))

fputs (Error connecting stderr)

abort()

75

if (mysql_select_db(ampmysqlargv[1]))

fputs (Error selecting database stderr)

abort()

if (mysql_query(ampmysqlSELECT FROM test_table))

fputs (Error processing query stderr)

abort()

if ((res = mysql_store_result(ampmysql)))

fputs (Error storing results stderr)

abort()

while((row = mysql_fetch_row(res)))

uint i = 0

for (i=0 i lt mysql_num_fields(res) i++)

printf(s row[i])

printf(n)

return 0

Step 2 Compile

gcc -Iusrlocalmysqlinclude -Lusrlocalmysqllibmysql mysqlcc ndashlm -lmysqlclient

(其中 include path與 library path取決於你的 MySQL安裝路徑)

76

如果執行時發生如下 error Run problemerror in loading shared libraries libmysqlclientsoX 將你的 MySQL library path(for exampleusrlocalmysqllibmysql) 加入etcldsoconf and run sbinldconfig -v Q9ASP + MySQL 範例程式 Ans Dim myconn As New ADODBConnection Dim myrs As New Recordset Dim mySQL As String Dim myrows As Long myconnOpen DSN=MyODBCsample mySQL = SELECT from user myrsSource = mySQL Set myrsActiveConnection = myconn myrsCursorLocation = adUseClient myrsOpen myrows = myrsRecordCount myrsClose myconnClose 可參考 httpwwwdwamnetmysqlasp_myodbcasp 有詳細的資料 Q10如何將 MySQL中的資料庫匯出成txt檔 Ans select from TableName into outfile textxls all result fields will seperate by tab

77

第八章 參考資料

英文部份 網址 1 httpwwwmysqlcom MySQL 網站有第一手有關 MySQL的資料 2 httpwwwmysqlcomdocenReplicationhtml 有關 MySQL Replication 的文件 3 httpwwwgeocitiescomsqlhomefaqstore_blobhtml 如何在 MySQL 存放 BLOB的資料 4httpwwwsapdborg 有關 SAP跟 MySQL相關合作的網站 書藉 1 Cooking with MySQL

Paul DuBois has selected sample recipes from the hundreds youll find in his book MySQL

Cookbook In this third and final series of excerpts showcasing these recipes learn how to

compute team standings how to calculate the differences between successive Dec 26

2002 2 Tips for Building Web Database Applications with PHP and MySQL by Hugh E Williams co-author of Web Database Applications with PHP amp MySQL 04042002

3 Managing and Using MySQL 2nd Edition By Tim King George Reese Randy Jay Yarger

4 MySQL Cookbook By Paul DuBoisPublisher OReillyPub Date October 2002

中文部份

78

1 httplinuxtncedutwtechdocmysqlmysql_docmanual_tochtml MySQL 中文手冊 2 httpchenshloxaedutwphpZ_1php PHP+MySQ程式研習設計網站 3 httplinuxtncedutwtechdocbanicdownhtml PHP 4 手冊 4 httpwwwtncedutwadmin_zonephp台南縣教育網網路中心有很多 Linux相關文件 5 httpdobtncedutw網站建置百寶箱有很多 PHP MySQL 相關範例程式 5 httpwwwdbworldcomtw資料庫專家電子雜誌介紹資料庫的重要觀念及名詞

79

附錄一 SQL Command 介紹

SQL (讀音ess-que-el) 是一種結構查詢語法SQL 使用於資料庫交流

傳遞相容於 ANSI (American National Standards Institute) 是一套標準的關聯

式資料庫語言 SQL 語言是執行更新或從資料系統獲取資料一般常見的關聯

資料庫系統都有提供 SQL 如 Oracle Sybase Microsoft SQL Server Access Ingres 等雖然大部份的資料庫都有提供 SQL 但也多提供了自已獨特的語

法造成了不相容的情形但標準基本的語法是相通的如Select Insert Update Delete Create and Drop 每一個系統都有支援

Table相關 Command

Create Table

關聯式資料庫包含有很多元件稱為資料表(tables) 把資料或訊息放在資

料表中 資料表是以不同的名稱做分別資料表由欄列所構成的二維陣列

欄包含欄位名資料型態 及其他可判斷的資訊列是由全部欄位構成一筆一

筆的紀錄 create table 語法用在建立一個新的資料表語法格式如下

create table tablename (column1 data type column2 data type column3 data type)

Format of create table if you were to use optional constraints

create table tablename (column1 data type [constraint] column2 data type [constraint] column3 data type [constraint]) [ ] = optional

Note You may have as many columns as youd like and the constraints are optional

80

Example

create table employee (first varchar(15) last varchar(20) age number(3) address varchar(30) city varchar(20) state varchar(20))

注意建立資料表格式要以括號把前後框住而最後以(分號)做結尾

欄位名不要超過 30個字元長而且不要使用 sql 的關鍵字(如 where select等)而在後面接是型態的宣告(如字串數字日期格式等)

資料型態是來描述欄位的方式如一個欄位Last_Name 是一個姓氏可以使用varchar (可變動長度字串) 資料型態

以下是幾個常見的資料庫型態 char(size) 固定長度字串最長為 255 位元 varchar(size) 變動長度字串最大字元數以 size 來指定 number(size) 數值格式可以是整數也可以是小數最大數字以 size 位數判

斷未指定小數位數由系統內定 date 日期格式 number(sized) 數值格式最大數字以 size 位數判斷d 為小數位數整數位

數為 size-d 位

有何限制當資料表被建立通常有一或數個欄位是要使用來做關聯的功

能 例如unique 限制(唯一值)兩筆記錄不可以相同的值 not null (非空值)該欄位一定要輸入資料不可是空的primary key (主鍵)是每一筆記錄識別的主要方式

Drop a table drop table 刪除資料表(其中的資料也會一併刪除)

drop table tablename

Example

81

drop table 和刪除全部資料是不同的刪除全部資料欄位名稱資訊等還會

存在但刪除資料表會把這一些也一併移除掉

如何查詢資料

Select 基本用法

select 語法是關連式資料庫最常用的部份可以取得你想要的資料這是一個

簡單的範例 select column1[column2etc] from tablename [where condition] [] = optional 在 select 之後所列欄位名則是要顯示的資料部份你可以一一列出各欄位

名或是以 (星號)來代表選擇全部的欄位 from 之後放資料表名稱 where 子句 (選項) 指定要過濾的條件符合者才會顯現 where 可使用的條件運算元 = 等於 gt 大於 lt 小於 gt= 大或等於 lt= 小或等於 ltgt 大相等 LIKE 相似 For example select first last city

82

from empinfo where first LIKE Er 以Er 為開頭的字串就符合要以單引號框住 Or you can specify select first last from empinfo where last LIKE s 最後一字為 S 就符合 select from empinfo where first = Eric 則表示 first name 一定要是 Eric 才可以 範例資料表empinfo 統計函數

MIN 傳回指定欄位最小值

MAX 傳回指定欄位最大值

SUM 傳回指定欄位總和

AVG 傳回指定欄位平均值

COUNT 傳回指定欄位的筆數

COUNT() 傳回資料庫中的總筆數

統計函數使用於資料表中的數值欄位配合 SELECT 語法使用 只用於總結特定單一欄位可以配合 GROUP BY 做篩選但也可以不使用 GROUP BY 語句For example

SELECT AVG(salary) FROM employee

83

傳回全部 salary 平均值

Another example

SELECT AVG(salary) FROM employee WHERE title = Programmer

傳回 salary 平均值條件為 employees 資料表中當 title 等於 Programmer

Example

SELECT Count() FROM employees

傳回 employees 資料表中紀錄總筆數

GROUP BY 語法 SELECT column1 SUM(column2) FROM list-of-tables GROUP BY column-list The GROUP BY 語句可以先以所列的欄位為條件分組排序在一起(可以多欄

位) example 要列出每一個 dept 中最高 salary 值 SELECT max(salary) dept FROM employee GROUP BY dept HAVING 語法

SELECT column1 SUM(column2) FROM list-of-tables GROUP BY column-list HAVING condition

HAVING 子句是 GROUP BY 的一部份用來過濾在 GROUP BY 所選出的資料功能如同 select 命令中 where 條件式一樣只是 HAVING 必需配合 GROUP BY 使用

我們以例子來說明我們要取得每一公司名及每一公司的薪水平均值輸入如下

84

SELECT dept avg(salary) FROM employee GROUP BY dept

但如果我們只列出薪資平均值超過 20000元的公司資料

SELECT dept avg(salary) FROM employee GROUP BY dept HAVING avg(salary) gt 20000

ORDER BY子句語法

SELECT column1 SUM(column2) FROM list-of-tables ORDER BY column-list [ASC | DESC]

[ ] =選項

ORDER BY是一個選項子句當你以排序方式來顯示資料(正向由小到大反向由大到小)以指定的欄位資料做排序

ASC = 正向- 預設值 DESC = 反向排序

For example

SELECT employee_id dept name age salary FROM employee_info WHERE dept = Sales ORDER BY salary

以上列出公司代號公司名銷售員人名年紀及薪資而條件是公司名為 Sales 顯示順序以薪資多少排序(由小到大為預設值)

如果要以多個欄位做排序要以逗號做分隔如下

SELECT employee_id dept name age salary FROM employee_info WHERE dept = Sales ORDER BY salary age DESC

85

結合條件及布林運算 SELECT column1 SUM(column2) FROM list-of-tables WHERE condition1 AND condition2 AND運算可以結兩個或以上的條件放在 WHERE子句中 兩者都要為真才

會顯示該筆記錄 OR 運算可以結兩個或以上敘述放在 WHERE子句中只要其中一個為直就

會顯示該筆記錄 For example SELECT employeeid firstname lastname title salary FROM employee_info WHERE salary gt= 5000000 AND title = Programmer 必需要薪資大於等於 50000而且職稱為 Programmer同時符合才會顯示該筆資料 以下以括號括住雖然不是必需的但如此比較容易讀 SELECT employeeid firstname lastname title salary FROM employee_info WHERE (salary gt= 5000000) AND (title = Programmer) 另外範例 SELECT firstname lastname title salary FROM employee_info WHERE (title = Sales) OR (title = Programmer) 條件為只要是 Sales 或 Programmer 職稱的就會被列出 IN and BETWEEN 子句

SELECT column1 SUM(column2) FROM list-of-tables WHERE column3 IN (list-of-values) SELECT column1 SUM(column2) FROM list-of-tables WHERE column3 BETWEEN value1 AND value2 IN 子句使用在列舉項目的使用上也就是分別測試是否符合所列的值 For example

86

SELECT employeeid lastname salary FROM employee_info WHERE lastname IN (Hernandez Jones Roberts Ruiz) 條件為姓氏(astname)要符合 Hernandez Jones Roberts or Ruiz 其中一個才會被傳回 IN運算元也可以使用 OR 的語法來取代如下結果相同 SELECT employeeid lastname salary FROM employee_info WHERE lastname = Hernandez OR lastname = Jones OR lastname = Roberts OR lastname = Ruiz 但使用 IN 句子比較短也比較易懂 你也可以使用 NOT IN 來去掉不要的記錄 BETWEEN 運算元使用在判斷是否存在兩個數值之間 For example SELECT employeeid age lastname salary FROM employee_info WHERE age BETWEEN 30 AND 40 傳回年紀 30歲到 40歲之間的資料(含 30及 40歲者) 相同的也可以使用以下語法來達到相同的結果 SELECT employeeid age lastname salary FROM employee_info WHERE age gt= 30 AND age lt= 40 你也可使用 NOT BETWEEN 來濾掉中間值的資料 數學運算 標準 ANSI SQL-92 提供以下運算

87

+ 加

- 減

餘數

餘數為除法後剩整數這不在標準的 ANSI SQL 中但大部份的資料庫都會支

援這運算元以下列出有用的函數雖不在 ANSI SQL-92 提供但一般資料庫

也會支援他們

ABS(x) 傳回 x 絕對值

SIGN(x) returns the sign of input x as -1 0 or 1 (negative zero or positive respectively)

MOD(xy) 餘數 - returns the integer remainder of x divided by y (同 xy)

FLOOR(x) 傳回小或等於 x 的最大整數值

CEILING(x) or CEIL(x)

傳回大或等於 x 的最小整數值

POWER(xy) x的 y 次方

ROUND(x) 把 x 四捨五入為整數

ROUND(xd) 四捨五入取到小數 d 位

SQRT(x) x 開平方

For example SELECT round(salary) firstname FROM employee_info 傳回薪資取到整數位

如何新增資料

insert 加入一筆新紀錄到資料表中 insert into tablename (first_columnlast_column) values (first_valuelast_value) [] = optional Example insert into employee

88

(first last age address city state) values (Luke Duke 45 2130 Boars Nest Hazard Co Georgia) Note 字串要以單引號住如string 數字框住也無妨 insert into 後面接資料表名稱再接以括號括住的欄位名在 values 後括號分別對映各欄位的值 以上的例子新增了一筆名(first) 為 Luke而住所(state) 為 Georgia 的資料

如何刪除資料

delete 可以刪除單筆或多筆紀錄 delete from tablename where columnname OPERATOR value [and|or column OPERATOR value] [ ] = optional Examples delete from employee Note 如果你沒有指定 where 子句那麼全部的紀錄都會被刪除 delete from employee where lastname = May delete from employee where firstname = Mike or firstname = Eric delete from 接著資料表名 再接著是條件式判斷沒有條件式則全部紀錄會

被刪除

如何更新資料

update 用來更新你所指定的記錄要和 WHERE 配合小心使用 語法 update tablename set columnname = newvalue[nextcolumn = newvalue2] where columnname OPERATOR value [and|or column OPERATOR value] [] = optional Examples

89

update phone_book set area_code = 623 where prefix = 979 update phone_book set last_name = Smith prefix=555 suffix=9292 where last_name = Jones update employee set age = age+1 where first_name=Mary and last_name=Williams

90

附錄二Replication

測試環境

RedHat 90 + MySQL 32358 MySQL資料庫路徑 varlibmysql MySQL設定檔 etcmycnf Master IP 1921680100 Slave IP 1921680200 請至下列網址下載最新MySQL 32358套件並利用rpm ndashUvh 更新 httpupdatesredhatcom9enosi386

圖 最新 MySQL 套件

測試架構圖

91

1921680100

1921680200Master Server

erveSlave S r

圖 測試架構圖

測試步驟

Master server 部份 Step1 確認 MasterSlave機器上所裝的 MySQL版本能進行

replication( 32329 or higher ) Step2 在 Master MySQL上開放一個帳號給 Slave mysql ndashu root ndashp mysqlgtGRANT FILE ON TO repl1921680200 IDENTIFIED BY lsquoabc123rsquo mysqlgtq 上面是 Master開放一個帳號 repl密碼 abc123給 IP1921680200有檔案處理

的權限 Step3 shutdown MySQL on the Master mysqladmin ndashu root ndashp shutdown Step4 備份 Master所有資料庫 tar ndashcvf tmpmysql-snapshottar varlibmysql 注意tar的時候MySQL是要在 stop情況下 在mysql (wwwmysqlcom) 網站的FAQ有不用shutdown的方法

92

Step5 在 master機器上修改etcmycnf 在[mysqld]區段內加入參數 log-bin server-id=這邊設定 server-id=1 sql-bin-update-same binlog-do-db=CRM只針對 CRM資料庫做紀錄 Step6 Restart MySQL on the master service mysqld start 此時因為有加入 log-bin 參數因此開始有 index產生了在varlibmysql目錄下

有index檔案紀錄資料庫的異動 log Slave server 部份 Step1 在 slave設定etcmycnf 在[mysqld]區段加入 master-host= master-user= master-password= master-port= server-id= 這邊設定 master-host=1921680100 master-user=repl master-password=abc123 master-port=3306 server-id=2 master-connect-retry=60預設重試間隔 60秒 replicate-do-db=CRM告訴 slave只做 CRM資料庫的更新 log-slave-updates Step2 將 master上的 mysql-snapshottar copy到 slave上 用 ftp傳到 slave的tmp Step3 解壓縮 Master資料庫至 Slave Server上 cd varlib tar xvf tmpmysql-snapshottar chown ndashR mysqlmysql mysql

93

chmod ndashR 770 mysql (視情況) Step4 Restart MySQL on the slave server 這時在varlibmysql目錄會出現 masterinfo此檔案紀錄了 Master MySQL server的資訊

狀況測試

One-way replication

1921680100

1921680200Master Server

erveSlave S r

圖 One-way replication架構圖 Step1 Master跟 Slave網路及服務都正常情況下由 Master端異動資料後 到 Slave端瀏覽資料檢視是否有進行 replication Step2 模擬 Slave Server 當機 可用在於 slave真的當機或是 Slave 不一定需要一直跟 master connect將Slave MySQL server shutdown由 Master端異動資料到 slave端瀏覽此時Slave應該沒有被 replication 更新然後再將 Slave端 MySQL server start起來

預設 60秒後 Slave會嘗試跟 Master要求進行 replication再去 Slave端檢視是否有更新資料

94

Step3 模擬 Master當機因為是設定 One-way replication一旦 Master Server Slave端沒有 Master的 source可以 download Two-way replication 基於 Master當機狀況於是發展雙向 Replication即 1921680100 ( Host A ) 1921680200 ( Host B )都分別擔任 MasterSlave身分

1921680100

1921680200er

Server B MasterSlave Server

Server A MasterSlave Serv

圖 Two-way replication架構圖 以下是針對兩台 MySQL伺服器進行雙向 Replication Step1觀念同單向 replication只是改成 Master也有 Slave身分 Slave也有Master的身分先分別在 Server AServer B 都去 grant一個進行 replication的身分 [A]mysqlgtGRANT FILE ON TO repl1921680200 IDENTIFIED BY lsquoabc123rsquo [B]mysqlgt GRANT FILE ON TO repl1921680100 IDENTIFIED BY lsquoabc123rsquo Step2做完單向 replication後stop Server Aserver B MySQL service此時 AB資料是一樣的

95

修改etcmycnf設定 範例 Server A [mysqld] datadir=varlibmysql socket=varlibmysqlmysqlsock server-id=1 log-bin sql-bin-update-same binlog-do-db=CRM master-host=1921680200 master-user=repl master-password=abc123 log-slave-updates master-connect-retry=60 replicate-do-db=CRM Server B [mysqld] datadir=varlibmysql socket=varlibmysqlmysqlsock server-id=2 log-bin sql-bin-update-same binlog-do-db=CRM master-host=1921680100 master-user=repl master-password=abc123 log-slave-updates master-connect-retry=60 replicate-do-db=CRM 分別 start Server AServer B MySQL後此時雙方都是 MasterSlave身分一旦哪一方資料異動就會通知對方來 replication-若 replication失效則必須將Server AServer B的masterinfo及index00x 都砍掉然後分別 restart MySQL server進行測試檢視成果 實務上通常如果需要做Two-way replication通常會搭配Virtual Server使用

96

在前端架設一台Virtual Server不過此部份不在此份SOP討論範圍內有興趣

的讀者可參考 httpwwwlinuxvirtualserverorg 網站

1921680100 1921680200

Host A MasterSlave Server

Host B MasterSlave Server

Virtual Host

圖 Virtual Server + Two-way replication 架構圖

97

圖 High Availability Linux Virtual Server架構圖

98

  • COSA-SOP-03-006
  • 第一章 簡介
    • 11適用對象 (Audience)
    • 12 MySQL本身
    • 13 MySQL 40版跟50版重大的改進功能
    • 14 各家資料庫軟體比較
      • 第二章 前置需求
      • 第三章 安裝
        • 31 MySQL安裝
        • 32 phpMyAdmin安裝
        • 33 升級及注意事項
          • 第四章 MySQL管理
            • 41 Webmin 管理介面
            • 42 phpMyAdmin 的操作介面
            • 43管理指令介紹
              • 431 利用mysqladmin設定root的密碼
                  • 第五章 實用範例
                    • 51 任務一Web Base客戶通訊錄
                    • 52 任務二Web Base群組軟體 ( twig )
                      • 第六章 維護及更新程序
                        • 61 日常維護
                        • 62 更新程序
                        • 63 備份重要檔案
                        • 64 離線備份與還原
                        • 65 線上備份與還原
                          • 第七章 問題與解答
                          • 第八章 參考資料
                          • 附錄一 SQL Command 介紹
                          • 附錄二Replication
Page 5: DataBase Server Standard Operation Procedureebooks.lib.ntu.edu.tw/1_file/oss/63/93doc4-5.pdf · 業務的公司帶來了不少壓力,譬如微軟,甲骨文 ... 外的錢用在第三方的資料庫產品上,譬如就可以不用再購買甲骨文公司

第一章 簡介

MySQL 是一種 跨平台多使用者多執行緒支援 SQL語言 (結構化查詢語言)執行速度快廣受全球網站大量採用的網路資料庫系統最重要的

是在大部份情形下使用 MySQL 是完全免費的( MySQL自 32319之後已改為 GPL版權宣告囉)整體而言MySQL 免費原始碼開放入門容易

執行速度快跨平台 (亦支援 Windows 2000)支援工具眾多等特性十分適合中小企業用來開發各種資訊系統企業不必再花費數十萬元去購買一些費而

不惠的資料庫 MySQL 沒有所謂連線使用者限制其它商用資料庫系統一定數量以上的

連線使用者數可是要付出相當可觀的費用的像 Yahoo等大公司也是用 MySQL 哩 連這麼大的入口網站都安心地挑選 MySQL 一般的中小企業更

無需擔心 MySQL的穩定性

11適用對象 (Audience)

本 SOP的對象適合一般的使用者及系統管理者編排的方式大部分皆採操

作步驟的模式進行方便一般入門的使用者

12 MySQL本身

在 Unix平台上最受到歡迎的一套資料庫系統就是 MySQL MySQL於1990中期開始發展當時Michael Mothnty Widenius在位於瑞典的 TcX DataKonsultAB開始開發這套軟體並在 1995 年公開釋放第一個版本

MySQL 同時擁有頗為可觀跨平台能力它能 Unix Like平台工作例如 AIX

SolarisFreeBSD及 Linux也能在 Mac OS X及Windows NT2000 server亦或是 Microsoft Wrokstation 系統上如 9xMEXP上開發程式更重要的是它是

讓您擁有原始碼 在 MySQL 在 323之後的版本在每個系統元件上在釋放時都會加上一個

完成度的註解如由「gamma」階段到「stale」階段「beat」階段到「alpha」階段階段愈低愈不穩定查詢目前的發展版本可以在 MySQL 參考手冊及線上

文件找到

5

MySQL經過考驗證明是值得信賴的資料庫系統如果您是 stable版的使用者您大可以放心MySQL對於版本的控制是十分注意並提供廣大的使用者原始碼下載Bug也因此很快就被解決

MySQL主要是以技術支援和經銷資料庫為主和 Red Hat在 Linux上的做

法非常類似背後則是由創投資金在支持客戶可以下載 MySQL並遵照 GPL授權規定使用MySQL公司則以技術服務作為收入

MySQL也提供付費的解決方案給想要整合 MySQL和其他軟體產品但是

又不想讓客戶取得程式碼的公司MySQL表示MySQL資料庫在全球已經有

400萬的使用者但是並不清楚其中有多少付費用戶到目前為止MySQL也已經引起企業用戶的興趣甚至包括 Yahoo和 Google等網際網路的領導廠商

MySQL最原始的構想嚐試克服自由軟體資料庫系統「mSQL」的一些功能

上的限制MySQL成長進步的非常的快尤其當贊助者由網際網路應用中看出

MySQL能提供網站所需強健資料庫的潛能對於 MySQL成長的速度幫助不少

而近來更有令人振奮的好消息( 2003 年 5月 ) ERP的龍頭 SAP正在與 MySQL就開放源代碼資料庫軟體進行合作這項

交易將會使得 MySQL這樣更小的公司能夠加速它的開發計畫此舉將允許

MySQL公司在未來的兩年內為其資料庫軟體添加更高端的一些特徵MySQL公司的首席執行官 Marten Mickos 說公司早在四年前就希望能夠進軍高端資料

庫業務這次交易在資料庫市場上還引起了另外一些影響它給那些開發資料庫

業務的公司帶來了不少壓力譬如微軟甲骨文以及 IBM等因為這項交易為

這些公司不斷樹立了一個越來越強大的開放源代碼軟體的競爭者而開放源代碼

軟體最終也許會吞噬它們的資料庫市場 SAP公司一直是銷售那些管理核心業務的一些軟體譬如會計軟體存貨

管理軟體這些產品以前一直是各大公司的暢銷軟體為了吸引那些中等規模的

公司客戶從而進行業務擴張這家德國的公司開始在他們的一些產品中加入SAP DB這是一個開放源代碼的資料庫軟體該軟體就可以免除 SAP公司客戶花額外的錢用在第三方的資料庫產品上譬如就可以不用再購買甲骨文公司的資料庫

軟體 根據他們的技術交錯式授權協議MySQL公司將會主宰 SAP DB的絕大部

分再開發業務並且 MySQL也會使用該程式的設計作為該公司未來改進的資料

庫軟體的模型SAP公司的一位元代表稱隨著 MySQL資料庫軟體的不斷成

熟SAP公司將會用新的 MySQL的資料庫軟體代替 SAP DBMickos 說在

6

這項交易中這家瑞典公司 MySQL將會得到其軟體的版稅但他拒絕透露這次

合作的一些經濟方面的細節 SAP的代表稱在更長一段時間後該開放源代碼資料庫軟體將會和 SAP

公司的旗艦產品 R3一起銷售 不久之後SAP與 MySQL將會完成他們合作計畫的第一個階段那

就是 SAP將會發佈一個 MySQL的資料庫版本從而它可以無縫地替代現在使

用的 SAP DB這對 MySQL而言無異是如虎添翼想必在不久的將來MySQL定能擔任企業更重要的任務

13 MySQL 40版跟 50版重大的改進功能

以下是 40版跟 50版一些重大的改進功能 MySQL 40 版httpwwwmysqlcomdocenNews-40xhtml

內建提供InnoDB table type支援 standard binaries adding transactions row-level locking 和foreign keys

提昇 Query速度 改善 boolean mode truncation and phrase searching全文檢索效

率 加強MERGE tables 並支援INSERT statements and

AUTO_INCREMENT 在SELECT 中支援UNION 語法 支援Multi-table DELETE statements libmysqld the embedded server library 更多的GRANT 參數來加強安全性 提供更多動態參數來降低停止 MySQL的必要 改善 replication code and features 改善執行效率並增加可靠性

MySQL 50 版httpwwwmysqlcomdocenTODO_MySQL_50html改善執行效率並增加可靠性 提供 Stored Procedures 機制 支援 cursor Dynamic length rows for HEAP tables Add true VARCHAR support

7

加強執行效率 更好的國際語系支援 提供可用性

14 各家資料庫軟體比較

目前市面上較被廣為使用資料庫除了 MySQL之外尚有下列幾種

1 MS SQL Server 2000 2 Oracle 8i 3 IBM DB2 4 Informix

過去幾年來在總值 120億美元的資料庫市場上如果廠商想要誇讚自家的

產品那就一定得要有強大的資料庫支援最嚴苛的任務才站得上檯面不過

到了今天似乎光是這樣並不夠客戶除了要求足以負擔嚴苛的任務之外還希

望擁有聰明又便宜的資料庫 Meta Group的分析師 Charlie Garry表示 ( 2003 年 5 月)MySQL的商業

模式是以開放原始碼為基礎以便讓客戶盡快接受 MySQLGarry指出MySQL甚至適合用在甲骨文IBM微軟等大廠爭相搶食的企業資料中心

Information Resources的資訊長 Marshall Gibbs就表示他們沒有任何品

牌的偏好只要「功能效能價格的最佳組合」 由研究近兩年來資料庫客戶

愈來愈注重總體成本(圖 1-1)

8

圖 1-1 資料庫優先性

整體擁有成本 大致說來MySQL是免費的MySQL需要付費的規定只限於下列兩種情

形 1 以 Embedded的方式使用 MySQL 2 使用 MySQL的商業用途軟體

且其授權費用一台 MySQL Pro License只需美金 $440比起其他任何資料庫軟體來得容易負擔多了加上其易於管理的特性著實可大大降低企業資料

庫的整體擁有成本 擴充性

MySQL同時提供高度多樣性能夠提供給很多不同的使用者介面包括命

令列操作網頁瀏覽器以及各式各樣的程式語言介面例如JavaC++PerlPHP及 PhythonMySQL可用 UnixWindows以及 OS2hellip等平台因此它可以用個人電腦或是伺服器上 性能 事實上大部份的網站的開發者都認為 MySQL是目前市面跑得最快的資料

9

庫對資料庫的最佳化主要在於你對他的設定和資料庫結構的設計如果你的

資料庫結構設計得非常差你的存取速度還是會受到影響而變得比較慢

10

第二章 前置需求

在安裝 MySQL之前請確定 Apache及 MySQL亦巳安裝相關步驟請參考

Apache SOP安裝 Apache及 PHP相關章節

11

第三章 安裝

31 MySQL安裝

在 RedHat 90上安裝 MySQL是件很容易的事因為 RedHat 90提供了一

個很方便的 GUI套件管理工具「redhat-config-packages」各位只要把 RedHat 90第一片光碟放入並以 root的身份登入系統鍵入 redhat-config-packages勾選「SQL資料庫伺服器」即可然後按「更新」如果遇到任何相依性問題

系統會提示您更換光碟片 ( 圖 3-1 ~ 3-3 ) Step 1 執行 redhat-config-packes

圖 3-1

Step 2 選擇資料伺服器

12

圖 3-2

Step 3檢查是否安裝成功 待安裝後您可以用利用「rpm -qa | grpe ^mysql」檢查是否安裝成功

圖 3-3

啟動 MySQL ( Command Mode )馬上啟動 MySQL的指令為「service mysqld start」如果您希望一開機就自動啟動 MySQL請執行「chkconfig mysqld on」

13

圖 3-4

啟動 MySQL ( WebMin 介面 ) 我們也可以利用WebMin 來啟動 MySQL步驟如下 Step 1登入Webmin

圖 3-5 登入WebMin

Step 2 選擇伺服器

14

圖 3-6 伺服器畫面

Step 2 選擇 MySQL資料庫伺服器

圖 3-7 伺服器畫面

15

Step 3 啟動 MySQL資料庫伺服器

圖 3-8 啟動 MySQL

更改資料庫管理者密碼

成功啟動 MySQL後因為資料庫管理者預設沒有密碼建議使用前更改系

統管理者密碼請輸入下列指令

mysqladmin ndashu root ndashh cosaexamplecom password lsquo1234rsquo -u 表示使用者帳號root 為 MySQL預設的管理帳號

-h 表示 MySQL主機的主機名稱也可使用 IP Address password 表示使用者的密碼因為字串請使用單引號將密碼括起來

圖 3-9 修改 MySQL 的密碼

16

32 phpMyAdmin安裝

本書除了會介紹利用當今 Linux上最紅的整合管理工具Webmin 來管理

MySQL外還會為各位介紹專門管理 MySQL的工具 phpMyAdmin phpMyAdmin是免費的 PHP原始程式碼的Web網站可用來管理整個

MySQL伺服器這是一套Web介面的 MySQL管理程式支援中文的使用者介

面 phpMyAdmin只需透過瀏覽器就可管理 MySQL伺服器換句話說不論

MySQL是安裝在 Linux或是Windows 作業系統都可以使用相同步驟在

MySQL上建立資料庫(Database)資料表(Table)和編輯紀錄(Record) Step 1 下載phpMyAdmin ( httpwwwphpmyadminnet )選擇最櫎新穩定的版

本 253

圖 3-10 httpwwwphpmyadminnet

17

圖 3-11 下載 phpMyAdmin-253-phptarbz2

Step 2 將 phpMyAdmin-253-phptarbz2收至 tmp 並執行下列指令將其解壓

縮至varwww tar jxvf phpMyAdmin-253-phptarbz ndashC varwwwhtml

圖 3-12 解壓縮安裝 phpMyadmin-253

Step 3 為了操作方便起見建立 Soft link ln ndashs phpMyAdmin-253 phpMyAdmin

圖 3-13 修改 phpMyadmin 設定檔 configincphp

18

Step 4 修改 phpMyadmin 設定檔 configincphp gedit varwwwhtmlphpMyAdminconfigincphp

圖 3-14 configincphp設定檔

Step 5 設定顯示行號以方便修改 configincphp 設定檔

19

圖 3-15 顯示行號

Step 6 修改下列設定 第 39 行 設定 phpMyAdmin的 URL 第 69 行 MySQL Server 的 ip 第 80 行 利用何帳號存取 MySQL 第 81 行 如果 root有設定 password此處即填入 root的 password

30 In most cases you can leave this variable empty as the correct value

31 will be detected automatically However we recommend that you do

32 test to see that the auto-detection code works in your system A good

33 test is to browse a table then edit a row and save it There will be

34 an error message if phpMyAdmin cannot auto-detect the correct value

35

36 If the auto-detection code does work properly you can set to TRUE the

37 $cfg[PmaAbsoluteUri_DisableWarning] variable below

38

39 $cfg[PmaAbsoluteUri] = httpossccosaorgtwphpMyAdmin

hellip

20

hellip

69 $cfg[Servers][$i][host] = localhost MySQL hostname or IP address hellip 80 $cfg[Servers][$i][user] = root MySQL user

81 $cfg[Servers][$i][password] = 1234 MySQL password (only needed

圖 3-16 修改 configincphp

21

圖 3-17 修改 configincphp

圖 3-18 修改 configincphp p

Step 7 設定語系

22

圖 3-19 設定語系

圖 3-20 執行 phpMyAdmin

23

33 升級及注意事項

RedHat 90附的 MySQL版本為 323 MySQL所釋出最新穩定版本為

40若是您不想用系統預附的 323請先利用下列移除之前 323的版本

rpm ndashe mysql-devel rpm ndashe mysql-server rpm ndashe mysql --nodeps 然後到下列網址下載您所想要的版本進行安裝在這裏我們用 4014版為例 Step 1 下載相關套件( httpwwwmysqlcomdownloadsmysql-40html )

圖 3-21 Download MySQL 4014 相關 RPM Step 2 利用 rpm 指令安裝

24

圖 3-22 Install MySQL 4014 相關 RPM

圖 3-23 Install MySQL 4014 相關 RPM

Step 3 啟動 MySQL

25

圖 3-24 啟動 MySQL 4014 並修改密碼

26

第四章 MySQL管理

本章將我們介紹利用WebminphpAdminCommand的方式建立一個名為

CONTACT的資料庫內有一個 address的 Table作為我們客戶通訊錄程式使

用的資料庫

41 Webmin 管理介面

412建立資料庫

Step 1 登入Webmin

圖 4-1 登入WebMin

Step 2 點選伺服器

27

圖 4-2 伺服器畫面

Step 3 點選 MySQL資料庫伺服器

圖 4-3 MySQL資料庫伺服器

28

Step 4 建立一個新的資料庫

圖 4-4 建立 MySQL資料庫

Step 5 建立名為 CONTACT的資料庫

29

圖 4-5 指定資料庫名稱

412 建立資料表

假設我們要建立一個名為 address的 Table其結構如下 欄位名稱 資料型態 長度 說明 id INT (自動編號) 連絡人編號 name varchar文字 20 連絡人姓名 tel Varchar文字 15 連絡人電話 Step 1 選擇 CONTACT資料庫

30

圖 4-6 選擇資料庫

Step 2 指定欄位數目

31

圖 4-7 設定欄位數目

Step 3設定表格欄位屬性

圖 3-8 設定表格欄位屬性

Step 4建立表格資料

32

圖 4-9 建立表格資料

圖 4-10 檢視資料

33

圖 4-11 新增資料

圖 4-12

34

圖 4-13

413 使用者管理

接下來我們要利用Webmin 來建立資料庫使用者並給予某些權限 Step1建立使用者

35

圖 4-14 選擇使用者權限

圖 4-15

36

Step2 賦予權限

圖 4-16

Step3 權限列表

37

圖 4-17

38

42 phpMyAdmin 的操作介面

421建立資料庫

Step 填入資料庫名稱並按「建立」

圖 4-18建立資料庫

422 建立資料表

Step1 填入資料表名稱並指定欄位數量 執行

39

圖 4-19填入資料表名稱並指定欄位數量

Step2 設定欄位屬性

圖 4-20設定欄位屬性

40

Step3 phpMyAdmin會產生相關的 SQL Command

圖 4-21 資料表結構及相關 SQL Command

Step4新增 Record

41

圖 4-22

圖 4-23

42

圖 4-24

圖 4-25

43

423使用者管理

Step1建立使用者

圖 4-26

44

圖 4-27

Step2 給予權限

圖 4-28

Step3權限列表

45

圖 4-29

43管理指令介紹

431 利用 mysqladmin設定 root的密碼

當您在Windows 或 Linux 中安裝好 MySQL後系統會自動幫您建立兩個

帳分別是 root 和 匿名者MySQL的 root 跟 Linux 最高權限使用者 root無關MySQL的 root使用者相當於 MS SQL 中的 sa 帳號擁有最高的 Database管理權限但系統預設 MySQL的 root 是不需要密碼所以通常我們一安裝

MySQL後首要任務便是修改 root的密碼 我們可以利用 mysqladmin工具或是直接修改 MySQL內部資料庫的使用者資

料 mysqladmin ndashu root ndashh cosaexamplecom password lsquo1234rsquo

46

-u 表示使用者帳號root 為 MySQL預設的管理帳號

-h 表示 MySQL主機的主機名稱也可使用 IP Address password 表示使用者的密碼因為字串請使用單引號將密碼括起來 密碼設定完成之後還是可以利用 mysqladmin修改密碼但是你必須提供目前的密碼

432 連線 MySQL

mysql -uroot -p密碼 (-p和密碼之間不能有空白) 或 mysql -uroot -p (此方式會在進入後要求密碼) [rootossc phpMyAdmin] mysql -u root -p1234

Welcome to the MySQL monitor Commands end with or g

Your MySQL connection id is 25 to server version 32354

Type help or h for help Type c to clear the buffer

mysqlgt show databases

+----------+

| Database |

+----------+

| mysql |

| test |

+----------+

2 rows in set (000 sec)

mysqlgt exit

Bye

[rootossc phpMyAdmin]

433 建立資料庫

可利用 mysqladmin指令建立 CONTACT資料庫 mysqladmin -u root -p1234 create CONTACT

47

或是利用 mysql指令 [rootossc bluepage] mysql -u root -p1234 Welcome to the MySQL monitor Commands end with or g Your MySQL connection id is 1057 to server version 32354 Type help or h for help Type c to clear the buffer mysqlgt create database CONTACT Query OK 1 row affected (000 sec) mysqlgt show databases +----------+ | Database | +----------+ | CONTACT | | address | | hello | | mysql | | nuke | | test | +----------+ 6 rows in set (000 sec) mysqlgt exit

434 建立資料表

編寫 adresssql內容如下 -- Table structure for table address CREATE TABLE address ( id int(11) NOT NULL auto_increment name varchar(20) NOT NULL default tel varchar(15) NOT NULL default PRIMARY KEY (id) ) TYPE=MyISAM

48

-- Dumping data for table address INSERT INTO address VALUES (1林小明0800016888) INSERT INTO address VALUES (2黃大雄0800016888) INSERT INTO address VALUES (3劉小芬0800024365) 然後執行此 sql script mysql -u root -p1234 CONTACT lt addresssql 或是利 mysql command [rootossc bluepage] mysql -u root -p1234 Welcome to the MySQL monitor Commands end with or g Your MySQL connection id is 1090 to server version 32354 Type help or h for help Type c to clear the buffer mysqlgt use CONTACT Database changed Database changed mysqlgt CREATE TABLE address ( -gt id int(11) NOT NULL auto_increment -gt name varchar(20) NOT NULL default -gt tel varchar(15) NOT NULL default -gt PRIMARY KEY (id) -gt ) TYPE=MyISAM Query OK 0 rows affected (000 sec) mysqlgt INSERT INTO address VALUES (1林小明0800016888) Query OK 1 row affected (000 sec) mysqlgt INSERT INTO address VALUES (2黃大雄0800016888) Query OK 1 row affected (000 sec) mysqlgt INSERT INTO address VALUES (3劉小芬0800024365) Query OK 1 row affected (000 sec) mysqlgt exit Bye

49

第五章 實用範例

51 任務一Web Base客戶通訊錄

任職於開放科技公司的林小明前些日子在最符合成本效益的條件下快

速地完成公司網站的建置老闆因此對小明讚譽有加最近因為公司存放客戶資

料的 SQL Server主機屢遭病毒攻擊加上作業系統本身的問題當機次數頻繁

老闆希望能儘快把公司的客戶通訊錄程式移轉到較穩定的環境上因為此客戶通

訊錄程式最主要給內部人員使用所以介面美觀並不特別要求只求穩定且能快

速得到查詢結果老闆希望在短時間先看到程式的雛型並鍵入資料對其效率

及穩定性進行測試因為上次小明表現突出所以這次不可能的任務自然又落到

小明身上 小明想來想去既然要快速又穩定他而且又不希望所有人都得安裝 Client

程式於是小明決定)捨棄他的舊愛「Delphi+MS SQL」投向新歡「Apache + MySQL + PHP」利用此架構來設計一個簡單實用的Web Base客戶通訊錄程式

511 Web Base客戶通訊錄架構

此程式需要建立 CONTACT的資料庫並建立 adress Tables其結構如下表建立步驟請參考第三章 欄位名稱 資料型態 長度 說明 id INT (自動編號) 連絡人編號 name varchar文字 20 連絡人姓名 tel Varchar文字 15 連絡人電話 Web Base通訊錄共有下列幾個檔案功能如下表

檔案名稱 說明 Indexhtml Web Base通訊錄首頁 addphp 新增連絡人的 php程式 searchphp 尋找連絡人的 php程式 editphp 具有更新及刪除功能的 php程式

50

我們將這些檔案放至varwwwhtmlbluepage (預設無 bluepage目錄)

512 Web Base通訊錄測試

httpwwwopencombluepage 新增資料

圖 5-1 新增連絡人

圖 5-2 填入資料

51

圖 5-3 新增成功

搜尋及異動資料

圖 5-4 搜尋通訊錄

52

圖 5-5 編輯資料

圖 5-6 更新資料

513 程式內容及說明

lt-- 程式範例indexhtml--gt lthtmlgt ltheadgtlttitlegt通訊錄lttitlegtltheadgt ltbodygt ltcentergt

53

lth2gt通訊錄lth2gtlthrgt lta href=indexhtmlgt通訊錄ltagt | lta href=addphpgt新增連絡人ltagt | lta href=searchphpgt搜尋通訊錄ltagt ltcentergt ltbodygt lthtmlgt lt-- 程式範例addphp --gt lthtmlgt ltheadgtlttitlegt新增連絡人lttitlegtltheadgt ltbodygt ltcentergtlth2gt新增連絡人lth2gtltcentergtlthrgt lt 取得欄位資料 if (isset($_POST[Name]) ampamp isset($_POST[Tel]) ) $name = $_POST[Name] $tel = $_POST[Tel] 檢查是否有輸入欄位資料 if ($name = ampamp $tel = ) 建立 SQL字串 $sql = INSERT INTO address (name tel) values( $sql= $name $tel) 建立 MySQL 連結 $link = mysql_connect(localhostroot1234) 選擇資料庫 mysql_select_db(CONTACT) 執行 SQL指令 mysql_query($sql) mysql_close($link) echo ltfont color=redgt新增連絡人成功ltfontgtltbrgt gt ltform action=addphp method=postgt lttable border=0 width=300gt lttrgtlttdgt姓名 lttdgt

54

lttdgtltinput type=text name=Name size=20 maxlength=10gtlttdgtlttrgt lttrgtlttdgt電話 lttdgt lttdgtltinput type=text name=Tel size=20 maxlength=20gtlttdgtlttrgt lttrgtlttd colspan=2 align=centergt ltinput type=submit value=新增連絡人gtlttdgtlttrgt lttablegt ltformgt ltbrgtlta href=indexhtmlgt通訊錄ltagt | lta href=addphpgt新增連絡人ltagt | lta href=searchphpgt搜尋通訊錄ltagt ltbodygt lthtmlgt

lt-- 程式範例searchphp --gt lthtmlgt ltheadgtlttitlegt搜尋通訊錄lttitlegtltheadgt ltbodygt ltcentergtlth2gt搜尋通訊錄lth2gtlthrgt lt if (isset($_POST[Search])) 建立資料庫連結並選定資料庫 $link = mysql_connect(localhostroot1234) mysql_select_db(CONTACT) 建立基本的 SQL字串 $sql = SELECT FROM address 檢查是否輸入姓名 if (chop($_POST[Name]) = ) $name = name LIKE $_POST[Name] else $name = 檢查是否輸入電話號碼 if (chop($_POST[Tel]) = ) $tel = tel LIKE $_POST[Tel] else $tel =

55

if條件組合 SQL字串 if (chop($name) = ampamp chop($tel) = ) $sql= WHERE $name AND $tel elseif (chop($name) = ) 只有姓名 $sql = WHERE $name elseif (chop($tel) = ) 只有電話號碼 $sql = WHERE $tel $sql= ORDER BY name 最後加上排序 $result = mysql_query($sql) 取得欄位數 $total_fields = mysql_num_fields($result) echo lttable border=1gt echo lttrgtlttdgt編號lttdgtlttdgt姓名lttdgtlttdgt電話lttdgtlttd colspan=2gt功能選項lttdgtlttrgt 表格顯示查詢結果 while ($rows = mysql_fetch_array($result MYSQL_NUM)) echo lttrgt for ($i = 0 $i lt $total_fields $i++) echo lttdgt$rows[$i]lttdgt echo lttdgtlta href=editphpaction=editampid= echo $rows[0]gtltbgt編輯ltbgtlttdgt echo lttdgtlta href=editphpaction=delampid= echo $rows[0]gtltbgt刪除ltbgtlttdgt echo lttrgt echo lttablegtlthrgt mysql_free_result($result) mysql_close($link) gt ltcentergt ltform action=searchphp method=postgt lttable border=0 width=450gt lttrgtlttdgt搜尋姓名 lttdgt lttdgtltinput type=text name=Name size=10 maxlength=20gtlttdgtlttrgt lttrgtlttdgt搜尋電話 lttdgt lttdgtltinput type=text name=Tel

56

size=20 maxlength=20gtlttdgtlttrgt lttrgtlttd colspan=2 align=centergt ltinput type=submit name=Search value=搜尋gtlttdgtlttrgt lttablegt ltformgt ltbrgtlta href=indexhtmlgt通訊錄ltagt | lta href=addphpgt新增連絡人ltagt | lta href=searchphpgt搜尋通訊錄ltagt ltbodygt lthtmlgt

lt ob_start() gt lt-- 程式範例editphp --gt lthtmlgt ltheadgtlttitlegt編輯通訊錄lttitlegtltheadgt ltbodygt lt 取得 URL 參數 $id = $_GET[id] $action = $_GET[action] 建立資料庫連結 $link = mysql_connect(localhostroot1234) mysql_select_db(CONTACT) 選擇資料庫 執行的操作 switch ($action) case update 更新 取得欄位資料 $name = $_POST[Name] $tel = $_POST[Tel] $sql = UPDATE address SET name=$name tel=$tel WHERE id=$id mysql_query($sql) 執行 SQL指令 mysql_close($link) header(Location searchphp) 轉向到 serachphp break case del 刪除 $sql = DELETE FROM address WHERE id=$id

57

mysql_query($sql) 執行 SQL指令 mysql_close($link) header(Location searchphp) 轉向到 serachphp break case edit 編輯 $sql = SELECT FROM address WHERE id=$id $result = mysql_query($sql) 執行 SQL指令 $row = mysql_fetch_row($result) 取回記錄 $name = $row[1] 取得欄位 name $tel = $row[2] 取得欄位 tel mysql_close($link) 顯示編輯表單 gt ltcentergtlth2gt更新通訊錄lth2gtltcentergtlthrgt ltform action=editphpaction=updateampid=lt echo $id gt method=postgt lttable border=0 width=300gt lttrgtlttdgt姓名 lttdgt lttdgtltinput type=text name=Name size=20 maxlength=10 value=lt echo $name gtgtlttdgtlttrgt lttrgtlttdgt電話 lttdgt lttdgtltinput type=text name=Tel size=20 maxlength=20 value=lt echo $tel gtgtlttdgtlttrgt lttrgtlttd colspan=2 align=centergt ltinput type=submit value=更新連絡人gtlttdgtlttrgt lttablegt ltformgt ltbrgtlta href=indexhtmlgt通訊錄ltagt | lta href=addphpgt新增連絡人ltagt | lta href=searchphpgt搜尋通訊錄ltagt lt break gt ltbodygt lthtmlgt

58

52 任務二Web Base群組軟體 ( twig )

順利完成Web Base客戶通訊錄程式測試一段時間後「Apache + MySQL + PHP」架構的穩定與快速巳深得老闆與公司所有同事的認同隨著公司業績蒸

蒸日上人員組織編罝愈來愈龐大跨部門的會議愈來愈多業務員每日排滿拜

訪客戶的行程跟客戶的 Email的往來也愈來愈頻繁 愈來愈多部門的同事希望公司能建置一套群組軟體提供 web mail可讓業

務人員方便收發 mail還有連絡人議事日程待辦工作書簽等功能讓整個

公司運作及個人時間管理更有效率

老闆問小明對這些需求有什麼看法小明認為如果這些功能完全由程式部

門開發必定曠日費時而且耗費公司資源小明在網路尋找是否有提供這些功能

的Free Software皇天不負苦心人小明發現了TWIG (The Web Information Gateway) httptwigscrewdrivernet這個群組軟體它在 Web 上整合郵件新聞聯絡人議事日程工作序書簽等功能非常符合公司的需求 Step 1 下載 twig-277targz 下載網址 httptwigscrewdrivernetdownloadphp3

Step 2 解開 twig-277targz tar -xzvf twig-277targz

59

Step 3 執行安裝動作安裝到 varwwwhtmltwig 目錄 cd twig-277 twig-install varwwwhtmltwig

Step 4 建立 MySQL 資料庫(twig)及各資料表

cd setup mysql -u root -p1234 mysqlgt create database twig Query OK 1 row affected (001 sec) mysqlgt quit mysql -u root ndashp1234 twiglt twigtablemysql

Step 5 修改 configincphp3 參數設定 vi varwwwhtmltwigconfigconfigincphp3 $config[fromdomain] = opencom 網域 $config[language] = chinesebig5 中文訊息 $config[imap_port] = 143notls

60

Step 6 修改連結 MySQL 的帳號密碼 vi varwwwhtmltwigconfigdbconfigincphp3 $dbconfig[sqlusername] = root username $dbconfig[sqlpassword] = 1234 password

Step 7 其他設定檔

vi etchttpdconfhttpdconf 加入 AddType applicationx-httpd-php php3 在 DirectoryIndex最後加入 indexphp3 DirectoryIndex indexhtml indexhtmlvar indexphp3 在 AddDefaultCharset ISO-8859-1加上 AddDefaultCharset ISO-8859-1

vi etcphpini register_globals = On service httpd restart Step 8 sendmail 設定 vi etcmailsendmailcf在 264 行前面加上並重新啟動 sendmail「service snedmail restart」 262 SMTP daemon options 263 264 O DaemonPortOptions=Port=smtpAddr=127001 Name=MTA 265 266 SMTP client options 267 O ClientPortOptions=Family=inet Address=00

61

Step 9 檢查設定有無錯誤 http主機名稱twigtestphp3

62

Step 10 登入 twig ( http主機名稱twig)

63

第六章 維護及更新程序

61 日常維護

系統管理員最好定期以 root 身份登入看看信件在 RedHat Linux 中有一支 logwatch 程式會定時去分析 log file如果發現異常便會發信給 root除此之外筆者建議讀者平時就檢查 MySQL log file ( varlogmysqldlog)是否有異常情形

62 更新程序

讀者可至httprpmfindnet 尋找MySQL相關套件至於升級的相關步驟請參

考Linux OS SOP 第 54節

63 備份重要檔案

預設 MySQL 的 DB 檔案是存在 varlibmysql 內以 DB名稱為目錄目錄

內就是該 DB 的所有資料通常得定期備份還有 MySQL的設定檔 etcmycnf也別忘了一起備份

64 離線備份與還原

641 離線備份

預設 MySQL 的 DB 檔案是存在 varlibmysql 內以 DB 名稱為目錄目錄內

就是該 DB 的所有資料像 CRM 這個 DB就是存在 varlibmysqlCRM 內在備份前因為怕資料尚未完全寫入磁碟而且 MySQL 會 Lock 在使用的 DB 檔案所以應該是要先把 MySQL 先 Shutdown 一下整個備份的程序可以下像下面的指令去完成 cd varlibmysql

64

service mysqld stop tar cvfz CRM_db_20030905tgz CRM service mysqld start 對這樣就可以了 不過要注意的是怕 DB 內每個 Tables 間的資料有關關

聯性所以最好是把整個 DB 一次備起來單獨只備哪個 Tables 的檔案以後回存時怕會有資料關聯不一致的問題

642 離線還原

DB 發生錯誤而要回存時其實也不難先找出最近一次完整正常的備份先把現在錯誤的網頁或 DB 先更名或 tar 起來再把好的備份給解開回原來目錄位

置就行了需要注意的是 MySQL 服務最好也是要先停止回存完成後再啟動服務回存 DB 的整個程序可能像下面 cd varlibmysql service mysqldstop mv CRM CRM_OLD tar xvfz CRM_db_20030905tg service mysqld start

65 線上備份與還原

651 線上備份

使用像上面的檔案方式備份是個不錯的方法它最少可以保持該主機某個時間點的完整檔案備份但還是有一些問題需要考慮到有些主機就不只建立一個 DB 而已總不能為了備份某個 DB 而把整個 MySQL 服務停止備份檔案的方式回存在原主機上一定適用但假如 MySQL 版本升級或是在那天該網頁空間需遷機移機到別的主機時那就沒人敢保證備出來的資料檔可以用所以我們可以考慮另一種備份的方式是使用 MySQL 本身提供的功能 MySQL Data Dump指令是 mysqldump

65

使用 MySQL 的 Dump 功能可以把 DB 的結構資料或結構加資料 Dump 成文字檔 mysqldump 指令提供的彈性很大你可以選擇把整個 DB Dump 成一個檔或是每個 Table 為一個檔甚至是把結構檔和資料分開儲存都

可以 mysqladmin -uroot -p flush-logs mysqldump CRM -uroot -p --opt gt CRM_20030905sql (CRM 是 DB 名稱 opt 是一個使用完整 Dump 參數) 假如只是要單獨 Dump 某個 Table 時只要在上面的指令後轉出符號 gt 前加個 Table 名稱就可以如只要 phpbb2_users 這個 Table 的 Dump 時只要下 mysqldump CRM -uroot -p --opt CUSTOMER gt CRM_CUSTOMER_20030905sql

652 線上還原

若要回存整個資料庫只需將壓縮的備份檔還原成 Dump 的檔案再用下面的指令回存 mysql CRM -uroot -p lt CRM_20030905sql 這邊需注意的是若建立備份時是以--opt或--add-drop-table為參數時回存的 動作是先將舊的 Table 先刪除重建 Table 的結構後再把 Data 匯入所以回存後所有的資料會回到你當時備份那個時間點因此在回存資料時可以考慮把現有錯誤或不完整的 DB 先備份一份下來以備不時之需或是拿來比對錯誤的地

方在那裡當然你也可以把資料回存到另一個測試用的 DB 內只要把上面指令

的 DB 名稱改成你的測試用 DB 名稱即可 使用這種回存方式 MySQL 服務不需停止也不會動到其他正在使用的 DB 在一些提供 MySQL 服務的虛擬主機可用這種方式作你自己的 DB 備份及回存

66

另外假如你是系統重建或是移機時切需在新的 MySQL 內新建一個空白 DB 後才行作回存的工作你可以用下面的指令建立 mysql -uroot -p -e CREATE DATABASE CRM (上面的 CRM是你要新建的 DB 名稱) 另一種作法先用 mysql 指令進入 mysql client console 然後再用 CREATE DATABASE CRM 這樣就行了記得尾端要加個 符號該行指令才會執行

67

第七章 問題與解答

Q1RedHat 90預附的 MySQL到底有無支援 Transcation機制 Ans MySQL自 32334a之後的 MySQL-Max版本加入 InnoDB的資料庫類型透過

InnoDBMySQL同樣可以進行 COMMIT與 ROLLRACK的動作RedHat 90預附的 MySQL為 32354a-11巳支援 InnoDB的資料庫類型不過必須做以

下設定 1cp usrsharedocmysql-server-32354amy-mediumcnf to etcmycnf 2 vi etcmycnf 將以下設定前的拿掉 innodb_data_home_dir = varlibmysql innodb_data_file_path = ibdata110Mautoextend innodb_log_group_home_dir = varlibmysql innodb_log_arch_dir = varlibmysql 3service mysqld restart 如此一來各位在建立Table時便可指定Table Type為 innodb ( ex create table with type=innodb ) Q2如何解決 php+mysql 許功蓋等字變亂的問題 Ans 方法一 【確定 MySQL 預設的字元集】 1 打開 WinMySQLadmin 管理畫面(在視窗右下角狀態列紅綠燈圖示中按滑鼠

右鍵點選 Show me 選項) 2 點選管理畫面中 [Variables] 標籤選項其中 character_set變數就是您預設

字元集的變數其預設是 latin1 字元集(我們要將他改回 big5)而 chatacters_set 變數則是 MySQL 可以支援哪些字元集 【修改預設字元集變數 character_set 】 1 請點選管理畫面中 [myini Setup] 標籤選項設定 myini 2 按一下 [Pick-up and Edit myini values] 按鈕以便編輯目前的 myini 設定 3 在 [mysqld] 設定區塊底下新增一行 default-character-set = big5 變數設

68

定 4 新增一個 [client] 設定區塊並加入第三步驟的變數設定(游標往下移到空白處新增兩行 [client] 和 default-character-set=big5) 5 按一下畫面左下方 [Save Modification] 按鈕儲存設定 6 重新啟動 MySQL 或 Windows 方法二 Server端注意事項 phpini 中有關的設定為(預設值) Magic quotes for incoming GETPOSTCookie data magic_quotes_gpc = On Use Sybase-style magic quotes (escape with instead of ) magic_quotes_sybase = Off Client端注意事項 1中文資料送進 mysql 前請用 addslashes($str) 處理 2處理後送進 mysql 時請用 括起來並在參數後留一個空白如 $sql = UPDATE ezf_table set tablename=$tname tableend=$endtime table inguser=$tguser tableingid=$tguserid tableallnumber=$tnumber tableloca l=$tablelocal tableanyone=$tableopen tabletext=$ttext WHERE tableid=$t ableid tablename=$tname c 取出時請用 stripslashes($str) Q3MySQL root 密碼忘了該怎麼辦 Ans 1先停掉 mysql etcrcdinitdmysql stop 2以--skip-grant-table 的參數啟動 mysql safe_mysql --skip-grant-tableamp 3 更改 root 密碼 mysql mysql mysqlgt UPDATE user SET password=password(newpassword)

69

WHERE user=root mysqlgt FLUSH PRIVILEGES mysqlgt exit 4停掉 mysql再重跑 mysqladmin -uroot -p shutdown Enter password 輸入新設定的密碼 etcrcdinitdmysql start

Q4NULL值問題

Ans

NULL值的概念是造成 SQL的新手的混淆的普遍原因他們經常認為 NULL是和一個空字符串的一樣的東西不是這樣的例如下列語句是完全不同的

mysqlgt INSERT INTO my_table (phone) VALUES (NULL)

mysqlgt INSERT INTO my_table (phone) VALUES ()

兩個語句把值插入到 phone 列但是第一個插入一個 NULL值而第二個插入一個空字符串第一個的含義可以認為是ldquo電話號碼不知道而第二個則可意味

著ldquo她沒有電話

在 SQL中NULL值在于任何其他值甚至 NULL值比較時總是假的(FALSE)包含 NULL的一個表達式總是產生一個 NULL值除非在包含在表達式中的運算符和函數的文檔中指出在下列例子所有的列返回 NULL

mysqlgt SELECT NULL1+NULLCONCAT(InvisibleNULL)

如果你想要尋找值是 NULL的列你不能使用=NULL測試下列語句不返回任

何行因為對任何表達式expr = NULL是假的

mysqlgt SELECT FROM my_table WHERE phone = NULL

要想尋找 NULL值你必須使用 IS NULL測試下例顯示如何找出 NULL電話號碼和空的電話號碼

70

mysqlgt SELECT FROM my_table WHERE phone IS NULL mysqlgt SELECT FROM my_table WHERE phone =

在 MySQL中就像很多其他的 SQL服務器一樣你不能索引可以有 NULL值的列你必須聲明這樣的列為 NOT NULL而且你不能插入 NULL到索引的

列中

當用 LOAD DATA INFILE 讀取數據時空列用更新如果你想要在一個列中有

NULL值你應該在文本文件中使用N字面上的詞NULL也可以在某些情形下使用

當使用 ORDER BY時首先呈現 NULL值如果你用 DESC以降序排序NULL值最後顯示當使用 GROUP BY時所有的 NULL值被認為是相等的

為了有助于NULL的處理你能使用 IS NULL和 IS NOT NULL運算符和 IFNULL()函數

對某些列類型NULL值被特殊地處理如果你將 NULL插入表的第一個TIMESTAMP 列則插入當前的日期和時間如果你將 NULL插入一個AUTO_INCREMENT 列則插入順序中的下一個數字

Q5如何將圖片存放於 MySQL中

Ans

Step 1建立資料庫 test

Step 2 建立表格 binary_data

CREATE TABLE binary_data (

id INT(4) NOT NULL AUTO_INCREMENT PRIMARY KEY

description CHAR(50)

bin_data LONGBLOB

filename CHAR(50)

filesize CHAR(50)

filetype CHAR(50)

71

)

Step 3 利用 storephp 寫入圖片

storephp 程式碼

ltHTMLgt ltHEADgtltTITLEgtStore binary data into SQL DatabaseltTITLEgtltHEADgt ltBODYgt lt code that will be executed if the form has been submitted

if ($submit) mysql_connect(localhostrootYOUR_PASSWORD) mysql_select_db(test) $data=Base64_Encode(fread(fopen($form_data r) filesize($form_data))) $result=MYSQL_QUERY(INSERT INTO binary_data (descriptionbin_datafilenamefilesizefiletype) VALUES ($form_description$data$form_data_name$form_data_size$form_data_type)) $id= mysql_insert_id() print ltpgtThis file has the following Database ID ltbgt$idltbgt MYSQL_CLOSE() else else show the form to submit new data

gt

ltform method=post action=ltphp echo $PHP_SELF gt enctype=multipartform-datagt File Descriptionltbrgt ltinput type=text name=form_description size=40gt ltINPUT TYPE=hidden name=MAX_FILE_SIZE value=4000000gt ltbrgtFile to uploadstore in databaseltbrgt ltinput type=file name=form_data size=40gt ltpgtltinput type=submit name=submit value=submitgt ltformgt lt

72

gt ltBODYgt ltHTMLgt

Step 3 利用 storephp 取出圖片

getdataphp 程式碼

lt Syntax getdataphp3id=ltidgt if($id) you may have to modify login information for your database server MYSQL_CONNECT(localhostrootYOUR_PASSWORD) mysql_select_db(test) $query = select bin_datafiletype from binary_data where id=$id $result = MYSQL_QUERY($query) $data = Base64_Decode(MYSQL_RESULT($result0bin_data)) $type = MYSQL_RESULT($result0filetype) Header( Content-type $type) echo $data gt

Q6MySQL裝好之後啟動時或是執行 mysqladmin會出現如下訊息 Cant connect to local MYSQL Server through Socket varlibmysqlmysqlsock或是

Cant connect to local MYSQL Server through Socket tmpmysqldsock

Ans 可能有下列幾個原因

1這個 mysqldsock 不見了被某人刪除了或是被一些系統自動執行程式給刪

了例如有些 cron任務便會設定定期刪除 tmp 裡的東西所以呢您只能修改

cron 裡的設定讓它不要清除 mysqldsock 2在啟動時也可以改變 mysqldsock的位置您在啟動 MySQL的時候可以加入此參數usrlocalmysqlbinsafe_mysqld --user=mysql --socket=其他路

徑socket amp 同時得去設定環境變數 MYSQL_UNIX_PORT的值以指定新的

73

路徑 3若是您沒改 MYSQL_UNIX_PORT的值那麼您可以在執行指令的時候才打

例如mysqladmin --socket=其他路徑socket version Q7How to get the last insert id Ans CREATE TABLE product ( id INT(4) NOT NULL AUTO_INCREMENT PRIMARY KEY description VARCHAR(50) ) 1利用 SQL的話 mysqlgt insert into product(description) values(123) Query OK 1 row affected (000 sec) mysqlgt select last_insert_id() +------------------+ | last_insert_id() | +------------------+ +------------------+ 1 row in set (000 sec) ======================================== 2如果是 PHP的話 你可以用mysql_insert_id()取得該 id PHP example $result=MYSQL_QUERY(INSERT INTO product (description) VALUES ($description)) $id= mysql_insert_id() print This file has the following Database ID $id Q8如何將文字檔匯入資料庫 Ans $addr=homehttpdhtmlphpschool001txt $sql_select = load data infile $addr into table test fields terminated by t 解說 $sql_select = load data infile 文字檔名 into table 表格名 fields terminated by

74

t

(欄位分隔以 TAB鍵) 該文字檔須與資料表欄位格式相符 例如欄位有三個 則文字檔為每行一筆資料如下 欄 1資料ltTABgt欄 2資料ltTABgt欄 3資料 欄 1資料ltTABgt欄 2資料ltTABgt欄 3資料 欄 1資料ltTABgt欄 2資料ltTABgt欄 3資料 欄 1資料ltTABgtltTABgt欄 3資料

Q9如何撰寫 MySQL C API Ans Step 1利用文字編輯器撰寫以下程式碼 mysqlcc

include ltstdiohgt

include ltmysqlmysqlhgt

int main (int argc char argv[])

MYSQL mysql

MYSQL_RES res

MYSQL_ROW row

if (argc = 2)

fputs (Usage myc ltdatabasegt stderr)

return 1

if ((mysql_connect(ampmysqllocalhostrootYour_Password)))

fputs (Error connecting stderr)

abort()

75

if (mysql_select_db(ampmysqlargv[1]))

fputs (Error selecting database stderr)

abort()

if (mysql_query(ampmysqlSELECT FROM test_table))

fputs (Error processing query stderr)

abort()

if ((res = mysql_store_result(ampmysql)))

fputs (Error storing results stderr)

abort()

while((row = mysql_fetch_row(res)))

uint i = 0

for (i=0 i lt mysql_num_fields(res) i++)

printf(s row[i])

printf(n)

return 0

Step 2 Compile

gcc -Iusrlocalmysqlinclude -Lusrlocalmysqllibmysql mysqlcc ndashlm -lmysqlclient

(其中 include path與 library path取決於你的 MySQL安裝路徑)

76

如果執行時發生如下 error Run problemerror in loading shared libraries libmysqlclientsoX 將你的 MySQL library path(for exampleusrlocalmysqllibmysql) 加入etcldsoconf and run sbinldconfig -v Q9ASP + MySQL 範例程式 Ans Dim myconn As New ADODBConnection Dim myrs As New Recordset Dim mySQL As String Dim myrows As Long myconnOpen DSN=MyODBCsample mySQL = SELECT from user myrsSource = mySQL Set myrsActiveConnection = myconn myrsCursorLocation = adUseClient myrsOpen myrows = myrsRecordCount myrsClose myconnClose 可參考 httpwwwdwamnetmysqlasp_myodbcasp 有詳細的資料 Q10如何將 MySQL中的資料庫匯出成txt檔 Ans select from TableName into outfile textxls all result fields will seperate by tab

77

第八章 參考資料

英文部份 網址 1 httpwwwmysqlcom MySQL 網站有第一手有關 MySQL的資料 2 httpwwwmysqlcomdocenReplicationhtml 有關 MySQL Replication 的文件 3 httpwwwgeocitiescomsqlhomefaqstore_blobhtml 如何在 MySQL 存放 BLOB的資料 4httpwwwsapdborg 有關 SAP跟 MySQL相關合作的網站 書藉 1 Cooking with MySQL

Paul DuBois has selected sample recipes from the hundreds youll find in his book MySQL

Cookbook In this third and final series of excerpts showcasing these recipes learn how to

compute team standings how to calculate the differences between successive Dec 26

2002 2 Tips for Building Web Database Applications with PHP and MySQL by Hugh E Williams co-author of Web Database Applications with PHP amp MySQL 04042002

3 Managing and Using MySQL 2nd Edition By Tim King George Reese Randy Jay Yarger

4 MySQL Cookbook By Paul DuBoisPublisher OReillyPub Date October 2002

中文部份

78

1 httplinuxtncedutwtechdocmysqlmysql_docmanual_tochtml MySQL 中文手冊 2 httpchenshloxaedutwphpZ_1php PHP+MySQ程式研習設計網站 3 httplinuxtncedutwtechdocbanicdownhtml PHP 4 手冊 4 httpwwwtncedutwadmin_zonephp台南縣教育網網路中心有很多 Linux相關文件 5 httpdobtncedutw網站建置百寶箱有很多 PHP MySQL 相關範例程式 5 httpwwwdbworldcomtw資料庫專家電子雜誌介紹資料庫的重要觀念及名詞

79

附錄一 SQL Command 介紹

SQL (讀音ess-que-el) 是一種結構查詢語法SQL 使用於資料庫交流

傳遞相容於 ANSI (American National Standards Institute) 是一套標準的關聯

式資料庫語言 SQL 語言是執行更新或從資料系統獲取資料一般常見的關聯

資料庫系統都有提供 SQL 如 Oracle Sybase Microsoft SQL Server Access Ingres 等雖然大部份的資料庫都有提供 SQL 但也多提供了自已獨特的語

法造成了不相容的情形但標準基本的語法是相通的如Select Insert Update Delete Create and Drop 每一個系統都有支援

Table相關 Command

Create Table

關聯式資料庫包含有很多元件稱為資料表(tables) 把資料或訊息放在資

料表中 資料表是以不同的名稱做分別資料表由欄列所構成的二維陣列

欄包含欄位名資料型態 及其他可判斷的資訊列是由全部欄位構成一筆一

筆的紀錄 create table 語法用在建立一個新的資料表語法格式如下

create table tablename (column1 data type column2 data type column3 data type)

Format of create table if you were to use optional constraints

create table tablename (column1 data type [constraint] column2 data type [constraint] column3 data type [constraint]) [ ] = optional

Note You may have as many columns as youd like and the constraints are optional

80

Example

create table employee (first varchar(15) last varchar(20) age number(3) address varchar(30) city varchar(20) state varchar(20))

注意建立資料表格式要以括號把前後框住而最後以(分號)做結尾

欄位名不要超過 30個字元長而且不要使用 sql 的關鍵字(如 where select等)而在後面接是型態的宣告(如字串數字日期格式等)

資料型態是來描述欄位的方式如一個欄位Last_Name 是一個姓氏可以使用varchar (可變動長度字串) 資料型態

以下是幾個常見的資料庫型態 char(size) 固定長度字串最長為 255 位元 varchar(size) 變動長度字串最大字元數以 size 來指定 number(size) 數值格式可以是整數也可以是小數最大數字以 size 位數判

斷未指定小數位數由系統內定 date 日期格式 number(sized) 數值格式最大數字以 size 位數判斷d 為小數位數整數位

數為 size-d 位

有何限制當資料表被建立通常有一或數個欄位是要使用來做關聯的功

能 例如unique 限制(唯一值)兩筆記錄不可以相同的值 not null (非空值)該欄位一定要輸入資料不可是空的primary key (主鍵)是每一筆記錄識別的主要方式

Drop a table drop table 刪除資料表(其中的資料也會一併刪除)

drop table tablename

Example

81

drop table 和刪除全部資料是不同的刪除全部資料欄位名稱資訊等還會

存在但刪除資料表會把這一些也一併移除掉

如何查詢資料

Select 基本用法

select 語法是關連式資料庫最常用的部份可以取得你想要的資料這是一個

簡單的範例 select column1[column2etc] from tablename [where condition] [] = optional 在 select 之後所列欄位名則是要顯示的資料部份你可以一一列出各欄位

名或是以 (星號)來代表選擇全部的欄位 from 之後放資料表名稱 where 子句 (選項) 指定要過濾的條件符合者才會顯現 where 可使用的條件運算元 = 等於 gt 大於 lt 小於 gt= 大或等於 lt= 小或等於 ltgt 大相等 LIKE 相似 For example select first last city

82

from empinfo where first LIKE Er 以Er 為開頭的字串就符合要以單引號框住 Or you can specify select first last from empinfo where last LIKE s 最後一字為 S 就符合 select from empinfo where first = Eric 則表示 first name 一定要是 Eric 才可以 範例資料表empinfo 統計函數

MIN 傳回指定欄位最小值

MAX 傳回指定欄位最大值

SUM 傳回指定欄位總和

AVG 傳回指定欄位平均值

COUNT 傳回指定欄位的筆數

COUNT() 傳回資料庫中的總筆數

統計函數使用於資料表中的數值欄位配合 SELECT 語法使用 只用於總結特定單一欄位可以配合 GROUP BY 做篩選但也可以不使用 GROUP BY 語句For example

SELECT AVG(salary) FROM employee

83

傳回全部 salary 平均值

Another example

SELECT AVG(salary) FROM employee WHERE title = Programmer

傳回 salary 平均值條件為 employees 資料表中當 title 等於 Programmer

Example

SELECT Count() FROM employees

傳回 employees 資料表中紀錄總筆數

GROUP BY 語法 SELECT column1 SUM(column2) FROM list-of-tables GROUP BY column-list The GROUP BY 語句可以先以所列的欄位為條件分組排序在一起(可以多欄

位) example 要列出每一個 dept 中最高 salary 值 SELECT max(salary) dept FROM employee GROUP BY dept HAVING 語法

SELECT column1 SUM(column2) FROM list-of-tables GROUP BY column-list HAVING condition

HAVING 子句是 GROUP BY 的一部份用來過濾在 GROUP BY 所選出的資料功能如同 select 命令中 where 條件式一樣只是 HAVING 必需配合 GROUP BY 使用

我們以例子來說明我們要取得每一公司名及每一公司的薪水平均值輸入如下

84

SELECT dept avg(salary) FROM employee GROUP BY dept

但如果我們只列出薪資平均值超過 20000元的公司資料

SELECT dept avg(salary) FROM employee GROUP BY dept HAVING avg(salary) gt 20000

ORDER BY子句語法

SELECT column1 SUM(column2) FROM list-of-tables ORDER BY column-list [ASC | DESC]

[ ] =選項

ORDER BY是一個選項子句當你以排序方式來顯示資料(正向由小到大反向由大到小)以指定的欄位資料做排序

ASC = 正向- 預設值 DESC = 反向排序

For example

SELECT employee_id dept name age salary FROM employee_info WHERE dept = Sales ORDER BY salary

以上列出公司代號公司名銷售員人名年紀及薪資而條件是公司名為 Sales 顯示順序以薪資多少排序(由小到大為預設值)

如果要以多個欄位做排序要以逗號做分隔如下

SELECT employee_id dept name age salary FROM employee_info WHERE dept = Sales ORDER BY salary age DESC

85

結合條件及布林運算 SELECT column1 SUM(column2) FROM list-of-tables WHERE condition1 AND condition2 AND運算可以結兩個或以上的條件放在 WHERE子句中 兩者都要為真才

會顯示該筆記錄 OR 運算可以結兩個或以上敘述放在 WHERE子句中只要其中一個為直就

會顯示該筆記錄 For example SELECT employeeid firstname lastname title salary FROM employee_info WHERE salary gt= 5000000 AND title = Programmer 必需要薪資大於等於 50000而且職稱為 Programmer同時符合才會顯示該筆資料 以下以括號括住雖然不是必需的但如此比較容易讀 SELECT employeeid firstname lastname title salary FROM employee_info WHERE (salary gt= 5000000) AND (title = Programmer) 另外範例 SELECT firstname lastname title salary FROM employee_info WHERE (title = Sales) OR (title = Programmer) 條件為只要是 Sales 或 Programmer 職稱的就會被列出 IN and BETWEEN 子句

SELECT column1 SUM(column2) FROM list-of-tables WHERE column3 IN (list-of-values) SELECT column1 SUM(column2) FROM list-of-tables WHERE column3 BETWEEN value1 AND value2 IN 子句使用在列舉項目的使用上也就是分別測試是否符合所列的值 For example

86

SELECT employeeid lastname salary FROM employee_info WHERE lastname IN (Hernandez Jones Roberts Ruiz) 條件為姓氏(astname)要符合 Hernandez Jones Roberts or Ruiz 其中一個才會被傳回 IN運算元也可以使用 OR 的語法來取代如下結果相同 SELECT employeeid lastname salary FROM employee_info WHERE lastname = Hernandez OR lastname = Jones OR lastname = Roberts OR lastname = Ruiz 但使用 IN 句子比較短也比較易懂 你也可以使用 NOT IN 來去掉不要的記錄 BETWEEN 運算元使用在判斷是否存在兩個數值之間 For example SELECT employeeid age lastname salary FROM employee_info WHERE age BETWEEN 30 AND 40 傳回年紀 30歲到 40歲之間的資料(含 30及 40歲者) 相同的也可以使用以下語法來達到相同的結果 SELECT employeeid age lastname salary FROM employee_info WHERE age gt= 30 AND age lt= 40 你也可使用 NOT BETWEEN 來濾掉中間值的資料 數學運算 標準 ANSI SQL-92 提供以下運算

87

+ 加

- 減

餘數

餘數為除法後剩整數這不在標準的 ANSI SQL 中但大部份的資料庫都會支

援這運算元以下列出有用的函數雖不在 ANSI SQL-92 提供但一般資料庫

也會支援他們

ABS(x) 傳回 x 絕對值

SIGN(x) returns the sign of input x as -1 0 or 1 (negative zero or positive respectively)

MOD(xy) 餘數 - returns the integer remainder of x divided by y (同 xy)

FLOOR(x) 傳回小或等於 x 的最大整數值

CEILING(x) or CEIL(x)

傳回大或等於 x 的最小整數值

POWER(xy) x的 y 次方

ROUND(x) 把 x 四捨五入為整數

ROUND(xd) 四捨五入取到小數 d 位

SQRT(x) x 開平方

For example SELECT round(salary) firstname FROM employee_info 傳回薪資取到整數位

如何新增資料

insert 加入一筆新紀錄到資料表中 insert into tablename (first_columnlast_column) values (first_valuelast_value) [] = optional Example insert into employee

88

(first last age address city state) values (Luke Duke 45 2130 Boars Nest Hazard Co Georgia) Note 字串要以單引號住如string 數字框住也無妨 insert into 後面接資料表名稱再接以括號括住的欄位名在 values 後括號分別對映各欄位的值 以上的例子新增了一筆名(first) 為 Luke而住所(state) 為 Georgia 的資料

如何刪除資料

delete 可以刪除單筆或多筆紀錄 delete from tablename where columnname OPERATOR value [and|or column OPERATOR value] [ ] = optional Examples delete from employee Note 如果你沒有指定 where 子句那麼全部的紀錄都會被刪除 delete from employee where lastname = May delete from employee where firstname = Mike or firstname = Eric delete from 接著資料表名 再接著是條件式判斷沒有條件式則全部紀錄會

被刪除

如何更新資料

update 用來更新你所指定的記錄要和 WHERE 配合小心使用 語法 update tablename set columnname = newvalue[nextcolumn = newvalue2] where columnname OPERATOR value [and|or column OPERATOR value] [] = optional Examples

89

update phone_book set area_code = 623 where prefix = 979 update phone_book set last_name = Smith prefix=555 suffix=9292 where last_name = Jones update employee set age = age+1 where first_name=Mary and last_name=Williams

90

附錄二Replication

測試環境

RedHat 90 + MySQL 32358 MySQL資料庫路徑 varlibmysql MySQL設定檔 etcmycnf Master IP 1921680100 Slave IP 1921680200 請至下列網址下載最新MySQL 32358套件並利用rpm ndashUvh 更新 httpupdatesredhatcom9enosi386

圖 最新 MySQL 套件

測試架構圖

91

1921680100

1921680200Master Server

erveSlave S r

圖 測試架構圖

測試步驟

Master server 部份 Step1 確認 MasterSlave機器上所裝的 MySQL版本能進行

replication( 32329 or higher ) Step2 在 Master MySQL上開放一個帳號給 Slave mysql ndashu root ndashp mysqlgtGRANT FILE ON TO repl1921680200 IDENTIFIED BY lsquoabc123rsquo mysqlgtq 上面是 Master開放一個帳號 repl密碼 abc123給 IP1921680200有檔案處理

的權限 Step3 shutdown MySQL on the Master mysqladmin ndashu root ndashp shutdown Step4 備份 Master所有資料庫 tar ndashcvf tmpmysql-snapshottar varlibmysql 注意tar的時候MySQL是要在 stop情況下 在mysql (wwwmysqlcom) 網站的FAQ有不用shutdown的方法

92

Step5 在 master機器上修改etcmycnf 在[mysqld]區段內加入參數 log-bin server-id=這邊設定 server-id=1 sql-bin-update-same binlog-do-db=CRM只針對 CRM資料庫做紀錄 Step6 Restart MySQL on the master service mysqld start 此時因為有加入 log-bin 參數因此開始有 index產生了在varlibmysql目錄下

有index檔案紀錄資料庫的異動 log Slave server 部份 Step1 在 slave設定etcmycnf 在[mysqld]區段加入 master-host= master-user= master-password= master-port= server-id= 這邊設定 master-host=1921680100 master-user=repl master-password=abc123 master-port=3306 server-id=2 master-connect-retry=60預設重試間隔 60秒 replicate-do-db=CRM告訴 slave只做 CRM資料庫的更新 log-slave-updates Step2 將 master上的 mysql-snapshottar copy到 slave上 用 ftp傳到 slave的tmp Step3 解壓縮 Master資料庫至 Slave Server上 cd varlib tar xvf tmpmysql-snapshottar chown ndashR mysqlmysql mysql

93

chmod ndashR 770 mysql (視情況) Step4 Restart MySQL on the slave server 這時在varlibmysql目錄會出現 masterinfo此檔案紀錄了 Master MySQL server的資訊

狀況測試

One-way replication

1921680100

1921680200Master Server

erveSlave S r

圖 One-way replication架構圖 Step1 Master跟 Slave網路及服務都正常情況下由 Master端異動資料後 到 Slave端瀏覽資料檢視是否有進行 replication Step2 模擬 Slave Server 當機 可用在於 slave真的當機或是 Slave 不一定需要一直跟 master connect將Slave MySQL server shutdown由 Master端異動資料到 slave端瀏覽此時Slave應該沒有被 replication 更新然後再將 Slave端 MySQL server start起來

預設 60秒後 Slave會嘗試跟 Master要求進行 replication再去 Slave端檢視是否有更新資料

94

Step3 模擬 Master當機因為是設定 One-way replication一旦 Master Server Slave端沒有 Master的 source可以 download Two-way replication 基於 Master當機狀況於是發展雙向 Replication即 1921680100 ( Host A ) 1921680200 ( Host B )都分別擔任 MasterSlave身分

1921680100

1921680200er

Server B MasterSlave Server

Server A MasterSlave Serv

圖 Two-way replication架構圖 以下是針對兩台 MySQL伺服器進行雙向 Replication Step1觀念同單向 replication只是改成 Master也有 Slave身分 Slave也有Master的身分先分別在 Server AServer B 都去 grant一個進行 replication的身分 [A]mysqlgtGRANT FILE ON TO repl1921680200 IDENTIFIED BY lsquoabc123rsquo [B]mysqlgt GRANT FILE ON TO repl1921680100 IDENTIFIED BY lsquoabc123rsquo Step2做完單向 replication後stop Server Aserver B MySQL service此時 AB資料是一樣的

95

修改etcmycnf設定 範例 Server A [mysqld] datadir=varlibmysql socket=varlibmysqlmysqlsock server-id=1 log-bin sql-bin-update-same binlog-do-db=CRM master-host=1921680200 master-user=repl master-password=abc123 log-slave-updates master-connect-retry=60 replicate-do-db=CRM Server B [mysqld] datadir=varlibmysql socket=varlibmysqlmysqlsock server-id=2 log-bin sql-bin-update-same binlog-do-db=CRM master-host=1921680100 master-user=repl master-password=abc123 log-slave-updates master-connect-retry=60 replicate-do-db=CRM 分別 start Server AServer B MySQL後此時雙方都是 MasterSlave身分一旦哪一方資料異動就會通知對方來 replication-若 replication失效則必須將Server AServer B的masterinfo及index00x 都砍掉然後分別 restart MySQL server進行測試檢視成果 實務上通常如果需要做Two-way replication通常會搭配Virtual Server使用

96

在前端架設一台Virtual Server不過此部份不在此份SOP討論範圍內有興趣

的讀者可參考 httpwwwlinuxvirtualserverorg 網站

1921680100 1921680200

Host A MasterSlave Server

Host B MasterSlave Server

Virtual Host

圖 Virtual Server + Two-way replication 架構圖

97

圖 High Availability Linux Virtual Server架構圖

98

  • COSA-SOP-03-006
  • 第一章 簡介
    • 11適用對象 (Audience)
    • 12 MySQL本身
    • 13 MySQL 40版跟50版重大的改進功能
    • 14 各家資料庫軟體比較
      • 第二章 前置需求
      • 第三章 安裝
        • 31 MySQL安裝
        • 32 phpMyAdmin安裝
        • 33 升級及注意事項
          • 第四章 MySQL管理
            • 41 Webmin 管理介面
            • 42 phpMyAdmin 的操作介面
            • 43管理指令介紹
              • 431 利用mysqladmin設定root的密碼
                  • 第五章 實用範例
                    • 51 任務一Web Base客戶通訊錄
                    • 52 任務二Web Base群組軟體 ( twig )
                      • 第六章 維護及更新程序
                        • 61 日常維護
                        • 62 更新程序
                        • 63 備份重要檔案
                        • 64 離線備份與還原
                        • 65 線上備份與還原
                          • 第七章 問題與解答
                          • 第八章 參考資料
                          • 附錄一 SQL Command 介紹
                          • 附錄二Replication
Page 6: DataBase Server Standard Operation Procedureebooks.lib.ntu.edu.tw/1_file/oss/63/93doc4-5.pdf · 業務的公司帶來了不少壓力,譬如微軟,甲骨文 ... 外的錢用在第三方的資料庫產品上,譬如就可以不用再購買甲骨文公司

MySQL經過考驗證明是值得信賴的資料庫系統如果您是 stable版的使用者您大可以放心MySQL對於版本的控制是十分注意並提供廣大的使用者原始碼下載Bug也因此很快就被解決

MySQL主要是以技術支援和經銷資料庫為主和 Red Hat在 Linux上的做

法非常類似背後則是由創投資金在支持客戶可以下載 MySQL並遵照 GPL授權規定使用MySQL公司則以技術服務作為收入

MySQL也提供付費的解決方案給想要整合 MySQL和其他軟體產品但是

又不想讓客戶取得程式碼的公司MySQL表示MySQL資料庫在全球已經有

400萬的使用者但是並不清楚其中有多少付費用戶到目前為止MySQL也已經引起企業用戶的興趣甚至包括 Yahoo和 Google等網際網路的領導廠商

MySQL最原始的構想嚐試克服自由軟體資料庫系統「mSQL」的一些功能

上的限制MySQL成長進步的非常的快尤其當贊助者由網際網路應用中看出

MySQL能提供網站所需強健資料庫的潛能對於 MySQL成長的速度幫助不少

而近來更有令人振奮的好消息( 2003 年 5月 ) ERP的龍頭 SAP正在與 MySQL就開放源代碼資料庫軟體進行合作這項

交易將會使得 MySQL這樣更小的公司能夠加速它的開發計畫此舉將允許

MySQL公司在未來的兩年內為其資料庫軟體添加更高端的一些特徵MySQL公司的首席執行官 Marten Mickos 說公司早在四年前就希望能夠進軍高端資料

庫業務這次交易在資料庫市場上還引起了另外一些影響它給那些開發資料庫

業務的公司帶來了不少壓力譬如微軟甲骨文以及 IBM等因為這項交易為

這些公司不斷樹立了一個越來越強大的開放源代碼軟體的競爭者而開放源代碼

軟體最終也許會吞噬它們的資料庫市場 SAP公司一直是銷售那些管理核心業務的一些軟體譬如會計軟體存貨

管理軟體這些產品以前一直是各大公司的暢銷軟體為了吸引那些中等規模的

公司客戶從而進行業務擴張這家德國的公司開始在他們的一些產品中加入SAP DB這是一個開放源代碼的資料庫軟體該軟體就可以免除 SAP公司客戶花額外的錢用在第三方的資料庫產品上譬如就可以不用再購買甲骨文公司的資料庫

軟體 根據他們的技術交錯式授權協議MySQL公司將會主宰 SAP DB的絕大部

分再開發業務並且 MySQL也會使用該程式的設計作為該公司未來改進的資料

庫軟體的模型SAP公司的一位元代表稱隨著 MySQL資料庫軟體的不斷成

熟SAP公司將會用新的 MySQL的資料庫軟體代替 SAP DBMickos 說在

6

這項交易中這家瑞典公司 MySQL將會得到其軟體的版稅但他拒絕透露這次

合作的一些經濟方面的細節 SAP的代表稱在更長一段時間後該開放源代碼資料庫軟體將會和 SAP

公司的旗艦產品 R3一起銷售 不久之後SAP與 MySQL將會完成他們合作計畫的第一個階段那

就是 SAP將會發佈一個 MySQL的資料庫版本從而它可以無縫地替代現在使

用的 SAP DB這對 MySQL而言無異是如虎添翼想必在不久的將來MySQL定能擔任企業更重要的任務

13 MySQL 40版跟 50版重大的改進功能

以下是 40版跟 50版一些重大的改進功能 MySQL 40 版httpwwwmysqlcomdocenNews-40xhtml

內建提供InnoDB table type支援 standard binaries adding transactions row-level locking 和foreign keys

提昇 Query速度 改善 boolean mode truncation and phrase searching全文檢索效

率 加強MERGE tables 並支援INSERT statements and

AUTO_INCREMENT 在SELECT 中支援UNION 語法 支援Multi-table DELETE statements libmysqld the embedded server library 更多的GRANT 參數來加強安全性 提供更多動態參數來降低停止 MySQL的必要 改善 replication code and features 改善執行效率並增加可靠性

MySQL 50 版httpwwwmysqlcomdocenTODO_MySQL_50html改善執行效率並增加可靠性 提供 Stored Procedures 機制 支援 cursor Dynamic length rows for HEAP tables Add true VARCHAR support

7

加強執行效率 更好的國際語系支援 提供可用性

14 各家資料庫軟體比較

目前市面上較被廣為使用資料庫除了 MySQL之外尚有下列幾種

1 MS SQL Server 2000 2 Oracle 8i 3 IBM DB2 4 Informix

過去幾年來在總值 120億美元的資料庫市場上如果廠商想要誇讚自家的

產品那就一定得要有強大的資料庫支援最嚴苛的任務才站得上檯面不過

到了今天似乎光是這樣並不夠客戶除了要求足以負擔嚴苛的任務之外還希

望擁有聰明又便宜的資料庫 Meta Group的分析師 Charlie Garry表示 ( 2003 年 5 月)MySQL的商業

模式是以開放原始碼為基礎以便讓客戶盡快接受 MySQLGarry指出MySQL甚至適合用在甲骨文IBM微軟等大廠爭相搶食的企業資料中心

Information Resources的資訊長 Marshall Gibbs就表示他們沒有任何品

牌的偏好只要「功能效能價格的最佳組合」 由研究近兩年來資料庫客戶

愈來愈注重總體成本(圖 1-1)

8

圖 1-1 資料庫優先性

整體擁有成本 大致說來MySQL是免費的MySQL需要付費的規定只限於下列兩種情

形 1 以 Embedded的方式使用 MySQL 2 使用 MySQL的商業用途軟體

且其授權費用一台 MySQL Pro License只需美金 $440比起其他任何資料庫軟體來得容易負擔多了加上其易於管理的特性著實可大大降低企業資料

庫的整體擁有成本 擴充性

MySQL同時提供高度多樣性能夠提供給很多不同的使用者介面包括命

令列操作網頁瀏覽器以及各式各樣的程式語言介面例如JavaC++PerlPHP及 PhythonMySQL可用 UnixWindows以及 OS2hellip等平台因此它可以用個人電腦或是伺服器上 性能 事實上大部份的網站的開發者都認為 MySQL是目前市面跑得最快的資料

9

庫對資料庫的最佳化主要在於你對他的設定和資料庫結構的設計如果你的

資料庫結構設計得非常差你的存取速度還是會受到影響而變得比較慢

10

第二章 前置需求

在安裝 MySQL之前請確定 Apache及 MySQL亦巳安裝相關步驟請參考

Apache SOP安裝 Apache及 PHP相關章節

11

第三章 安裝

31 MySQL安裝

在 RedHat 90上安裝 MySQL是件很容易的事因為 RedHat 90提供了一

個很方便的 GUI套件管理工具「redhat-config-packages」各位只要把 RedHat 90第一片光碟放入並以 root的身份登入系統鍵入 redhat-config-packages勾選「SQL資料庫伺服器」即可然後按「更新」如果遇到任何相依性問題

系統會提示您更換光碟片 ( 圖 3-1 ~ 3-3 ) Step 1 執行 redhat-config-packes

圖 3-1

Step 2 選擇資料伺服器

12

圖 3-2

Step 3檢查是否安裝成功 待安裝後您可以用利用「rpm -qa | grpe ^mysql」檢查是否安裝成功

圖 3-3

啟動 MySQL ( Command Mode )馬上啟動 MySQL的指令為「service mysqld start」如果您希望一開機就自動啟動 MySQL請執行「chkconfig mysqld on」

13

圖 3-4

啟動 MySQL ( WebMin 介面 ) 我們也可以利用WebMin 來啟動 MySQL步驟如下 Step 1登入Webmin

圖 3-5 登入WebMin

Step 2 選擇伺服器

14

圖 3-6 伺服器畫面

Step 2 選擇 MySQL資料庫伺服器

圖 3-7 伺服器畫面

15

Step 3 啟動 MySQL資料庫伺服器

圖 3-8 啟動 MySQL

更改資料庫管理者密碼

成功啟動 MySQL後因為資料庫管理者預設沒有密碼建議使用前更改系

統管理者密碼請輸入下列指令

mysqladmin ndashu root ndashh cosaexamplecom password lsquo1234rsquo -u 表示使用者帳號root 為 MySQL預設的管理帳號

-h 表示 MySQL主機的主機名稱也可使用 IP Address password 表示使用者的密碼因為字串請使用單引號將密碼括起來

圖 3-9 修改 MySQL 的密碼

16

32 phpMyAdmin安裝

本書除了會介紹利用當今 Linux上最紅的整合管理工具Webmin 來管理

MySQL外還會為各位介紹專門管理 MySQL的工具 phpMyAdmin phpMyAdmin是免費的 PHP原始程式碼的Web網站可用來管理整個

MySQL伺服器這是一套Web介面的 MySQL管理程式支援中文的使用者介

面 phpMyAdmin只需透過瀏覽器就可管理 MySQL伺服器換句話說不論

MySQL是安裝在 Linux或是Windows 作業系統都可以使用相同步驟在

MySQL上建立資料庫(Database)資料表(Table)和編輯紀錄(Record) Step 1 下載phpMyAdmin ( httpwwwphpmyadminnet )選擇最櫎新穩定的版

本 253

圖 3-10 httpwwwphpmyadminnet

17

圖 3-11 下載 phpMyAdmin-253-phptarbz2

Step 2 將 phpMyAdmin-253-phptarbz2收至 tmp 並執行下列指令將其解壓

縮至varwww tar jxvf phpMyAdmin-253-phptarbz ndashC varwwwhtml

圖 3-12 解壓縮安裝 phpMyadmin-253

Step 3 為了操作方便起見建立 Soft link ln ndashs phpMyAdmin-253 phpMyAdmin

圖 3-13 修改 phpMyadmin 設定檔 configincphp

18

Step 4 修改 phpMyadmin 設定檔 configincphp gedit varwwwhtmlphpMyAdminconfigincphp

圖 3-14 configincphp設定檔

Step 5 設定顯示行號以方便修改 configincphp 設定檔

19

圖 3-15 顯示行號

Step 6 修改下列設定 第 39 行 設定 phpMyAdmin的 URL 第 69 行 MySQL Server 的 ip 第 80 行 利用何帳號存取 MySQL 第 81 行 如果 root有設定 password此處即填入 root的 password

30 In most cases you can leave this variable empty as the correct value

31 will be detected automatically However we recommend that you do

32 test to see that the auto-detection code works in your system A good

33 test is to browse a table then edit a row and save it There will be

34 an error message if phpMyAdmin cannot auto-detect the correct value

35

36 If the auto-detection code does work properly you can set to TRUE the

37 $cfg[PmaAbsoluteUri_DisableWarning] variable below

38

39 $cfg[PmaAbsoluteUri] = httpossccosaorgtwphpMyAdmin

hellip

20

hellip

69 $cfg[Servers][$i][host] = localhost MySQL hostname or IP address hellip 80 $cfg[Servers][$i][user] = root MySQL user

81 $cfg[Servers][$i][password] = 1234 MySQL password (only needed

圖 3-16 修改 configincphp

21

圖 3-17 修改 configincphp

圖 3-18 修改 configincphp p

Step 7 設定語系

22

圖 3-19 設定語系

圖 3-20 執行 phpMyAdmin

23

33 升級及注意事項

RedHat 90附的 MySQL版本為 323 MySQL所釋出最新穩定版本為

40若是您不想用系統預附的 323請先利用下列移除之前 323的版本

rpm ndashe mysql-devel rpm ndashe mysql-server rpm ndashe mysql --nodeps 然後到下列網址下載您所想要的版本進行安裝在這裏我們用 4014版為例 Step 1 下載相關套件( httpwwwmysqlcomdownloadsmysql-40html )

圖 3-21 Download MySQL 4014 相關 RPM Step 2 利用 rpm 指令安裝

24

圖 3-22 Install MySQL 4014 相關 RPM

圖 3-23 Install MySQL 4014 相關 RPM

Step 3 啟動 MySQL

25

圖 3-24 啟動 MySQL 4014 並修改密碼

26

第四章 MySQL管理

本章將我們介紹利用WebminphpAdminCommand的方式建立一個名為

CONTACT的資料庫內有一個 address的 Table作為我們客戶通訊錄程式使

用的資料庫

41 Webmin 管理介面

412建立資料庫

Step 1 登入Webmin

圖 4-1 登入WebMin

Step 2 點選伺服器

27

圖 4-2 伺服器畫面

Step 3 點選 MySQL資料庫伺服器

圖 4-3 MySQL資料庫伺服器

28

Step 4 建立一個新的資料庫

圖 4-4 建立 MySQL資料庫

Step 5 建立名為 CONTACT的資料庫

29

圖 4-5 指定資料庫名稱

412 建立資料表

假設我們要建立一個名為 address的 Table其結構如下 欄位名稱 資料型態 長度 說明 id INT (自動編號) 連絡人編號 name varchar文字 20 連絡人姓名 tel Varchar文字 15 連絡人電話 Step 1 選擇 CONTACT資料庫

30

圖 4-6 選擇資料庫

Step 2 指定欄位數目

31

圖 4-7 設定欄位數目

Step 3設定表格欄位屬性

圖 3-8 設定表格欄位屬性

Step 4建立表格資料

32

圖 4-9 建立表格資料

圖 4-10 檢視資料

33

圖 4-11 新增資料

圖 4-12

34

圖 4-13

413 使用者管理

接下來我們要利用Webmin 來建立資料庫使用者並給予某些權限 Step1建立使用者

35

圖 4-14 選擇使用者權限

圖 4-15

36

Step2 賦予權限

圖 4-16

Step3 權限列表

37

圖 4-17

38

42 phpMyAdmin 的操作介面

421建立資料庫

Step 填入資料庫名稱並按「建立」

圖 4-18建立資料庫

422 建立資料表

Step1 填入資料表名稱並指定欄位數量 執行

39

圖 4-19填入資料表名稱並指定欄位數量

Step2 設定欄位屬性

圖 4-20設定欄位屬性

40

Step3 phpMyAdmin會產生相關的 SQL Command

圖 4-21 資料表結構及相關 SQL Command

Step4新增 Record

41

圖 4-22

圖 4-23

42

圖 4-24

圖 4-25

43

423使用者管理

Step1建立使用者

圖 4-26

44

圖 4-27

Step2 給予權限

圖 4-28

Step3權限列表

45

圖 4-29

43管理指令介紹

431 利用 mysqladmin設定 root的密碼

當您在Windows 或 Linux 中安裝好 MySQL後系統會自動幫您建立兩個

帳分別是 root 和 匿名者MySQL的 root 跟 Linux 最高權限使用者 root無關MySQL的 root使用者相當於 MS SQL 中的 sa 帳號擁有最高的 Database管理權限但系統預設 MySQL的 root 是不需要密碼所以通常我們一安裝

MySQL後首要任務便是修改 root的密碼 我們可以利用 mysqladmin工具或是直接修改 MySQL內部資料庫的使用者資

料 mysqladmin ndashu root ndashh cosaexamplecom password lsquo1234rsquo

46

-u 表示使用者帳號root 為 MySQL預設的管理帳號

-h 表示 MySQL主機的主機名稱也可使用 IP Address password 表示使用者的密碼因為字串請使用單引號將密碼括起來 密碼設定完成之後還是可以利用 mysqladmin修改密碼但是你必須提供目前的密碼

432 連線 MySQL

mysql -uroot -p密碼 (-p和密碼之間不能有空白) 或 mysql -uroot -p (此方式會在進入後要求密碼) [rootossc phpMyAdmin] mysql -u root -p1234

Welcome to the MySQL monitor Commands end with or g

Your MySQL connection id is 25 to server version 32354

Type help or h for help Type c to clear the buffer

mysqlgt show databases

+----------+

| Database |

+----------+

| mysql |

| test |

+----------+

2 rows in set (000 sec)

mysqlgt exit

Bye

[rootossc phpMyAdmin]

433 建立資料庫

可利用 mysqladmin指令建立 CONTACT資料庫 mysqladmin -u root -p1234 create CONTACT

47

或是利用 mysql指令 [rootossc bluepage] mysql -u root -p1234 Welcome to the MySQL monitor Commands end with or g Your MySQL connection id is 1057 to server version 32354 Type help or h for help Type c to clear the buffer mysqlgt create database CONTACT Query OK 1 row affected (000 sec) mysqlgt show databases +----------+ | Database | +----------+ | CONTACT | | address | | hello | | mysql | | nuke | | test | +----------+ 6 rows in set (000 sec) mysqlgt exit

434 建立資料表

編寫 adresssql內容如下 -- Table structure for table address CREATE TABLE address ( id int(11) NOT NULL auto_increment name varchar(20) NOT NULL default tel varchar(15) NOT NULL default PRIMARY KEY (id) ) TYPE=MyISAM

48

-- Dumping data for table address INSERT INTO address VALUES (1林小明0800016888) INSERT INTO address VALUES (2黃大雄0800016888) INSERT INTO address VALUES (3劉小芬0800024365) 然後執行此 sql script mysql -u root -p1234 CONTACT lt addresssql 或是利 mysql command [rootossc bluepage] mysql -u root -p1234 Welcome to the MySQL monitor Commands end with or g Your MySQL connection id is 1090 to server version 32354 Type help or h for help Type c to clear the buffer mysqlgt use CONTACT Database changed Database changed mysqlgt CREATE TABLE address ( -gt id int(11) NOT NULL auto_increment -gt name varchar(20) NOT NULL default -gt tel varchar(15) NOT NULL default -gt PRIMARY KEY (id) -gt ) TYPE=MyISAM Query OK 0 rows affected (000 sec) mysqlgt INSERT INTO address VALUES (1林小明0800016888) Query OK 1 row affected (000 sec) mysqlgt INSERT INTO address VALUES (2黃大雄0800016888) Query OK 1 row affected (000 sec) mysqlgt INSERT INTO address VALUES (3劉小芬0800024365) Query OK 1 row affected (000 sec) mysqlgt exit Bye

49

第五章 實用範例

51 任務一Web Base客戶通訊錄

任職於開放科技公司的林小明前些日子在最符合成本效益的條件下快

速地完成公司網站的建置老闆因此對小明讚譽有加最近因為公司存放客戶資

料的 SQL Server主機屢遭病毒攻擊加上作業系統本身的問題當機次數頻繁

老闆希望能儘快把公司的客戶通訊錄程式移轉到較穩定的環境上因為此客戶通

訊錄程式最主要給內部人員使用所以介面美觀並不特別要求只求穩定且能快

速得到查詢結果老闆希望在短時間先看到程式的雛型並鍵入資料對其效率

及穩定性進行測試因為上次小明表現突出所以這次不可能的任務自然又落到

小明身上 小明想來想去既然要快速又穩定他而且又不希望所有人都得安裝 Client

程式於是小明決定)捨棄他的舊愛「Delphi+MS SQL」投向新歡「Apache + MySQL + PHP」利用此架構來設計一個簡單實用的Web Base客戶通訊錄程式

511 Web Base客戶通訊錄架構

此程式需要建立 CONTACT的資料庫並建立 adress Tables其結構如下表建立步驟請參考第三章 欄位名稱 資料型態 長度 說明 id INT (自動編號) 連絡人編號 name varchar文字 20 連絡人姓名 tel Varchar文字 15 連絡人電話 Web Base通訊錄共有下列幾個檔案功能如下表

檔案名稱 說明 Indexhtml Web Base通訊錄首頁 addphp 新增連絡人的 php程式 searchphp 尋找連絡人的 php程式 editphp 具有更新及刪除功能的 php程式

50

我們將這些檔案放至varwwwhtmlbluepage (預設無 bluepage目錄)

512 Web Base通訊錄測試

httpwwwopencombluepage 新增資料

圖 5-1 新增連絡人

圖 5-2 填入資料

51

圖 5-3 新增成功

搜尋及異動資料

圖 5-4 搜尋通訊錄

52

圖 5-5 編輯資料

圖 5-6 更新資料

513 程式內容及說明

lt-- 程式範例indexhtml--gt lthtmlgt ltheadgtlttitlegt通訊錄lttitlegtltheadgt ltbodygt ltcentergt

53

lth2gt通訊錄lth2gtlthrgt lta href=indexhtmlgt通訊錄ltagt | lta href=addphpgt新增連絡人ltagt | lta href=searchphpgt搜尋通訊錄ltagt ltcentergt ltbodygt lthtmlgt lt-- 程式範例addphp --gt lthtmlgt ltheadgtlttitlegt新增連絡人lttitlegtltheadgt ltbodygt ltcentergtlth2gt新增連絡人lth2gtltcentergtlthrgt lt 取得欄位資料 if (isset($_POST[Name]) ampamp isset($_POST[Tel]) ) $name = $_POST[Name] $tel = $_POST[Tel] 檢查是否有輸入欄位資料 if ($name = ampamp $tel = ) 建立 SQL字串 $sql = INSERT INTO address (name tel) values( $sql= $name $tel) 建立 MySQL 連結 $link = mysql_connect(localhostroot1234) 選擇資料庫 mysql_select_db(CONTACT) 執行 SQL指令 mysql_query($sql) mysql_close($link) echo ltfont color=redgt新增連絡人成功ltfontgtltbrgt gt ltform action=addphp method=postgt lttable border=0 width=300gt lttrgtlttdgt姓名 lttdgt

54

lttdgtltinput type=text name=Name size=20 maxlength=10gtlttdgtlttrgt lttrgtlttdgt電話 lttdgt lttdgtltinput type=text name=Tel size=20 maxlength=20gtlttdgtlttrgt lttrgtlttd colspan=2 align=centergt ltinput type=submit value=新增連絡人gtlttdgtlttrgt lttablegt ltformgt ltbrgtlta href=indexhtmlgt通訊錄ltagt | lta href=addphpgt新增連絡人ltagt | lta href=searchphpgt搜尋通訊錄ltagt ltbodygt lthtmlgt

lt-- 程式範例searchphp --gt lthtmlgt ltheadgtlttitlegt搜尋通訊錄lttitlegtltheadgt ltbodygt ltcentergtlth2gt搜尋通訊錄lth2gtlthrgt lt if (isset($_POST[Search])) 建立資料庫連結並選定資料庫 $link = mysql_connect(localhostroot1234) mysql_select_db(CONTACT) 建立基本的 SQL字串 $sql = SELECT FROM address 檢查是否輸入姓名 if (chop($_POST[Name]) = ) $name = name LIKE $_POST[Name] else $name = 檢查是否輸入電話號碼 if (chop($_POST[Tel]) = ) $tel = tel LIKE $_POST[Tel] else $tel =

55

if條件組合 SQL字串 if (chop($name) = ampamp chop($tel) = ) $sql= WHERE $name AND $tel elseif (chop($name) = ) 只有姓名 $sql = WHERE $name elseif (chop($tel) = ) 只有電話號碼 $sql = WHERE $tel $sql= ORDER BY name 最後加上排序 $result = mysql_query($sql) 取得欄位數 $total_fields = mysql_num_fields($result) echo lttable border=1gt echo lttrgtlttdgt編號lttdgtlttdgt姓名lttdgtlttdgt電話lttdgtlttd colspan=2gt功能選項lttdgtlttrgt 表格顯示查詢結果 while ($rows = mysql_fetch_array($result MYSQL_NUM)) echo lttrgt for ($i = 0 $i lt $total_fields $i++) echo lttdgt$rows[$i]lttdgt echo lttdgtlta href=editphpaction=editampid= echo $rows[0]gtltbgt編輯ltbgtlttdgt echo lttdgtlta href=editphpaction=delampid= echo $rows[0]gtltbgt刪除ltbgtlttdgt echo lttrgt echo lttablegtlthrgt mysql_free_result($result) mysql_close($link) gt ltcentergt ltform action=searchphp method=postgt lttable border=0 width=450gt lttrgtlttdgt搜尋姓名 lttdgt lttdgtltinput type=text name=Name size=10 maxlength=20gtlttdgtlttrgt lttrgtlttdgt搜尋電話 lttdgt lttdgtltinput type=text name=Tel

56

size=20 maxlength=20gtlttdgtlttrgt lttrgtlttd colspan=2 align=centergt ltinput type=submit name=Search value=搜尋gtlttdgtlttrgt lttablegt ltformgt ltbrgtlta href=indexhtmlgt通訊錄ltagt | lta href=addphpgt新增連絡人ltagt | lta href=searchphpgt搜尋通訊錄ltagt ltbodygt lthtmlgt

lt ob_start() gt lt-- 程式範例editphp --gt lthtmlgt ltheadgtlttitlegt編輯通訊錄lttitlegtltheadgt ltbodygt lt 取得 URL 參數 $id = $_GET[id] $action = $_GET[action] 建立資料庫連結 $link = mysql_connect(localhostroot1234) mysql_select_db(CONTACT) 選擇資料庫 執行的操作 switch ($action) case update 更新 取得欄位資料 $name = $_POST[Name] $tel = $_POST[Tel] $sql = UPDATE address SET name=$name tel=$tel WHERE id=$id mysql_query($sql) 執行 SQL指令 mysql_close($link) header(Location searchphp) 轉向到 serachphp break case del 刪除 $sql = DELETE FROM address WHERE id=$id

57

mysql_query($sql) 執行 SQL指令 mysql_close($link) header(Location searchphp) 轉向到 serachphp break case edit 編輯 $sql = SELECT FROM address WHERE id=$id $result = mysql_query($sql) 執行 SQL指令 $row = mysql_fetch_row($result) 取回記錄 $name = $row[1] 取得欄位 name $tel = $row[2] 取得欄位 tel mysql_close($link) 顯示編輯表單 gt ltcentergtlth2gt更新通訊錄lth2gtltcentergtlthrgt ltform action=editphpaction=updateampid=lt echo $id gt method=postgt lttable border=0 width=300gt lttrgtlttdgt姓名 lttdgt lttdgtltinput type=text name=Name size=20 maxlength=10 value=lt echo $name gtgtlttdgtlttrgt lttrgtlttdgt電話 lttdgt lttdgtltinput type=text name=Tel size=20 maxlength=20 value=lt echo $tel gtgtlttdgtlttrgt lttrgtlttd colspan=2 align=centergt ltinput type=submit value=更新連絡人gtlttdgtlttrgt lttablegt ltformgt ltbrgtlta href=indexhtmlgt通訊錄ltagt | lta href=addphpgt新增連絡人ltagt | lta href=searchphpgt搜尋通訊錄ltagt lt break gt ltbodygt lthtmlgt

58

52 任務二Web Base群組軟體 ( twig )

順利完成Web Base客戶通訊錄程式測試一段時間後「Apache + MySQL + PHP」架構的穩定與快速巳深得老闆與公司所有同事的認同隨著公司業績蒸

蒸日上人員組織編罝愈來愈龐大跨部門的會議愈來愈多業務員每日排滿拜

訪客戶的行程跟客戶的 Email的往來也愈來愈頻繁 愈來愈多部門的同事希望公司能建置一套群組軟體提供 web mail可讓業

務人員方便收發 mail還有連絡人議事日程待辦工作書簽等功能讓整個

公司運作及個人時間管理更有效率

老闆問小明對這些需求有什麼看法小明認為如果這些功能完全由程式部

門開發必定曠日費時而且耗費公司資源小明在網路尋找是否有提供這些功能

的Free Software皇天不負苦心人小明發現了TWIG (The Web Information Gateway) httptwigscrewdrivernet這個群組軟體它在 Web 上整合郵件新聞聯絡人議事日程工作序書簽等功能非常符合公司的需求 Step 1 下載 twig-277targz 下載網址 httptwigscrewdrivernetdownloadphp3

Step 2 解開 twig-277targz tar -xzvf twig-277targz

59

Step 3 執行安裝動作安裝到 varwwwhtmltwig 目錄 cd twig-277 twig-install varwwwhtmltwig

Step 4 建立 MySQL 資料庫(twig)及各資料表

cd setup mysql -u root -p1234 mysqlgt create database twig Query OK 1 row affected (001 sec) mysqlgt quit mysql -u root ndashp1234 twiglt twigtablemysql

Step 5 修改 configincphp3 參數設定 vi varwwwhtmltwigconfigconfigincphp3 $config[fromdomain] = opencom 網域 $config[language] = chinesebig5 中文訊息 $config[imap_port] = 143notls

60

Step 6 修改連結 MySQL 的帳號密碼 vi varwwwhtmltwigconfigdbconfigincphp3 $dbconfig[sqlusername] = root username $dbconfig[sqlpassword] = 1234 password

Step 7 其他設定檔

vi etchttpdconfhttpdconf 加入 AddType applicationx-httpd-php php3 在 DirectoryIndex最後加入 indexphp3 DirectoryIndex indexhtml indexhtmlvar indexphp3 在 AddDefaultCharset ISO-8859-1加上 AddDefaultCharset ISO-8859-1

vi etcphpini register_globals = On service httpd restart Step 8 sendmail 設定 vi etcmailsendmailcf在 264 行前面加上並重新啟動 sendmail「service snedmail restart」 262 SMTP daemon options 263 264 O DaemonPortOptions=Port=smtpAddr=127001 Name=MTA 265 266 SMTP client options 267 O ClientPortOptions=Family=inet Address=00

61

Step 9 檢查設定有無錯誤 http主機名稱twigtestphp3

62

Step 10 登入 twig ( http主機名稱twig)

63

第六章 維護及更新程序

61 日常維護

系統管理員最好定期以 root 身份登入看看信件在 RedHat Linux 中有一支 logwatch 程式會定時去分析 log file如果發現異常便會發信給 root除此之外筆者建議讀者平時就檢查 MySQL log file ( varlogmysqldlog)是否有異常情形

62 更新程序

讀者可至httprpmfindnet 尋找MySQL相關套件至於升級的相關步驟請參

考Linux OS SOP 第 54節

63 備份重要檔案

預設 MySQL 的 DB 檔案是存在 varlibmysql 內以 DB名稱為目錄目錄

內就是該 DB 的所有資料通常得定期備份還有 MySQL的設定檔 etcmycnf也別忘了一起備份

64 離線備份與還原

641 離線備份

預設 MySQL 的 DB 檔案是存在 varlibmysql 內以 DB 名稱為目錄目錄內

就是該 DB 的所有資料像 CRM 這個 DB就是存在 varlibmysqlCRM 內在備份前因為怕資料尚未完全寫入磁碟而且 MySQL 會 Lock 在使用的 DB 檔案所以應該是要先把 MySQL 先 Shutdown 一下整個備份的程序可以下像下面的指令去完成 cd varlibmysql

64

service mysqld stop tar cvfz CRM_db_20030905tgz CRM service mysqld start 對這樣就可以了 不過要注意的是怕 DB 內每個 Tables 間的資料有關關

聯性所以最好是把整個 DB 一次備起來單獨只備哪個 Tables 的檔案以後回存時怕會有資料關聯不一致的問題

642 離線還原

DB 發生錯誤而要回存時其實也不難先找出最近一次完整正常的備份先把現在錯誤的網頁或 DB 先更名或 tar 起來再把好的備份給解開回原來目錄位

置就行了需要注意的是 MySQL 服務最好也是要先停止回存完成後再啟動服務回存 DB 的整個程序可能像下面 cd varlibmysql service mysqldstop mv CRM CRM_OLD tar xvfz CRM_db_20030905tg service mysqld start

65 線上備份與還原

651 線上備份

使用像上面的檔案方式備份是個不錯的方法它最少可以保持該主機某個時間點的完整檔案備份但還是有一些問題需要考慮到有些主機就不只建立一個 DB 而已總不能為了備份某個 DB 而把整個 MySQL 服務停止備份檔案的方式回存在原主機上一定適用但假如 MySQL 版本升級或是在那天該網頁空間需遷機移機到別的主機時那就沒人敢保證備出來的資料檔可以用所以我們可以考慮另一種備份的方式是使用 MySQL 本身提供的功能 MySQL Data Dump指令是 mysqldump

65

使用 MySQL 的 Dump 功能可以把 DB 的結構資料或結構加資料 Dump 成文字檔 mysqldump 指令提供的彈性很大你可以選擇把整個 DB Dump 成一個檔或是每個 Table 為一個檔甚至是把結構檔和資料分開儲存都

可以 mysqladmin -uroot -p flush-logs mysqldump CRM -uroot -p --opt gt CRM_20030905sql (CRM 是 DB 名稱 opt 是一個使用完整 Dump 參數) 假如只是要單獨 Dump 某個 Table 時只要在上面的指令後轉出符號 gt 前加個 Table 名稱就可以如只要 phpbb2_users 這個 Table 的 Dump 時只要下 mysqldump CRM -uroot -p --opt CUSTOMER gt CRM_CUSTOMER_20030905sql

652 線上還原

若要回存整個資料庫只需將壓縮的備份檔還原成 Dump 的檔案再用下面的指令回存 mysql CRM -uroot -p lt CRM_20030905sql 這邊需注意的是若建立備份時是以--opt或--add-drop-table為參數時回存的 動作是先將舊的 Table 先刪除重建 Table 的結構後再把 Data 匯入所以回存後所有的資料會回到你當時備份那個時間點因此在回存資料時可以考慮把現有錯誤或不完整的 DB 先備份一份下來以備不時之需或是拿來比對錯誤的地

方在那裡當然你也可以把資料回存到另一個測試用的 DB 內只要把上面指令

的 DB 名稱改成你的測試用 DB 名稱即可 使用這種回存方式 MySQL 服務不需停止也不會動到其他正在使用的 DB 在一些提供 MySQL 服務的虛擬主機可用這種方式作你自己的 DB 備份及回存

66

另外假如你是系統重建或是移機時切需在新的 MySQL 內新建一個空白 DB 後才行作回存的工作你可以用下面的指令建立 mysql -uroot -p -e CREATE DATABASE CRM (上面的 CRM是你要新建的 DB 名稱) 另一種作法先用 mysql 指令進入 mysql client console 然後再用 CREATE DATABASE CRM 這樣就行了記得尾端要加個 符號該行指令才會執行

67

第七章 問題與解答

Q1RedHat 90預附的 MySQL到底有無支援 Transcation機制 Ans MySQL自 32334a之後的 MySQL-Max版本加入 InnoDB的資料庫類型透過

InnoDBMySQL同樣可以進行 COMMIT與 ROLLRACK的動作RedHat 90預附的 MySQL為 32354a-11巳支援 InnoDB的資料庫類型不過必須做以

下設定 1cp usrsharedocmysql-server-32354amy-mediumcnf to etcmycnf 2 vi etcmycnf 將以下設定前的拿掉 innodb_data_home_dir = varlibmysql innodb_data_file_path = ibdata110Mautoextend innodb_log_group_home_dir = varlibmysql innodb_log_arch_dir = varlibmysql 3service mysqld restart 如此一來各位在建立Table時便可指定Table Type為 innodb ( ex create table with type=innodb ) Q2如何解決 php+mysql 許功蓋等字變亂的問題 Ans 方法一 【確定 MySQL 預設的字元集】 1 打開 WinMySQLadmin 管理畫面(在視窗右下角狀態列紅綠燈圖示中按滑鼠

右鍵點選 Show me 選項) 2 點選管理畫面中 [Variables] 標籤選項其中 character_set變數就是您預設

字元集的變數其預設是 latin1 字元集(我們要將他改回 big5)而 chatacters_set 變數則是 MySQL 可以支援哪些字元集 【修改預設字元集變數 character_set 】 1 請點選管理畫面中 [myini Setup] 標籤選項設定 myini 2 按一下 [Pick-up and Edit myini values] 按鈕以便編輯目前的 myini 設定 3 在 [mysqld] 設定區塊底下新增一行 default-character-set = big5 變數設

68

定 4 新增一個 [client] 設定區塊並加入第三步驟的變數設定(游標往下移到空白處新增兩行 [client] 和 default-character-set=big5) 5 按一下畫面左下方 [Save Modification] 按鈕儲存設定 6 重新啟動 MySQL 或 Windows 方法二 Server端注意事項 phpini 中有關的設定為(預設值) Magic quotes for incoming GETPOSTCookie data magic_quotes_gpc = On Use Sybase-style magic quotes (escape with instead of ) magic_quotes_sybase = Off Client端注意事項 1中文資料送進 mysql 前請用 addslashes($str) 處理 2處理後送進 mysql 時請用 括起來並在參數後留一個空白如 $sql = UPDATE ezf_table set tablename=$tname tableend=$endtime table inguser=$tguser tableingid=$tguserid tableallnumber=$tnumber tableloca l=$tablelocal tableanyone=$tableopen tabletext=$ttext WHERE tableid=$t ableid tablename=$tname c 取出時請用 stripslashes($str) Q3MySQL root 密碼忘了該怎麼辦 Ans 1先停掉 mysql etcrcdinitdmysql stop 2以--skip-grant-table 的參數啟動 mysql safe_mysql --skip-grant-tableamp 3 更改 root 密碼 mysql mysql mysqlgt UPDATE user SET password=password(newpassword)

69

WHERE user=root mysqlgt FLUSH PRIVILEGES mysqlgt exit 4停掉 mysql再重跑 mysqladmin -uroot -p shutdown Enter password 輸入新設定的密碼 etcrcdinitdmysql start

Q4NULL值問題

Ans

NULL值的概念是造成 SQL的新手的混淆的普遍原因他們經常認為 NULL是和一個空字符串的一樣的東西不是這樣的例如下列語句是完全不同的

mysqlgt INSERT INTO my_table (phone) VALUES (NULL)

mysqlgt INSERT INTO my_table (phone) VALUES ()

兩個語句把值插入到 phone 列但是第一個插入一個 NULL值而第二個插入一個空字符串第一個的含義可以認為是ldquo電話號碼不知道而第二個則可意味

著ldquo她沒有電話

在 SQL中NULL值在于任何其他值甚至 NULL值比較時總是假的(FALSE)包含 NULL的一個表達式總是產生一個 NULL值除非在包含在表達式中的運算符和函數的文檔中指出在下列例子所有的列返回 NULL

mysqlgt SELECT NULL1+NULLCONCAT(InvisibleNULL)

如果你想要尋找值是 NULL的列你不能使用=NULL測試下列語句不返回任

何行因為對任何表達式expr = NULL是假的

mysqlgt SELECT FROM my_table WHERE phone = NULL

要想尋找 NULL值你必須使用 IS NULL測試下例顯示如何找出 NULL電話號碼和空的電話號碼

70

mysqlgt SELECT FROM my_table WHERE phone IS NULL mysqlgt SELECT FROM my_table WHERE phone =

在 MySQL中就像很多其他的 SQL服務器一樣你不能索引可以有 NULL值的列你必須聲明這樣的列為 NOT NULL而且你不能插入 NULL到索引的

列中

當用 LOAD DATA INFILE 讀取數據時空列用更新如果你想要在一個列中有

NULL值你應該在文本文件中使用N字面上的詞NULL也可以在某些情形下使用

當使用 ORDER BY時首先呈現 NULL值如果你用 DESC以降序排序NULL值最後顯示當使用 GROUP BY時所有的 NULL值被認為是相等的

為了有助于NULL的處理你能使用 IS NULL和 IS NOT NULL運算符和 IFNULL()函數

對某些列類型NULL值被特殊地處理如果你將 NULL插入表的第一個TIMESTAMP 列則插入當前的日期和時間如果你將 NULL插入一個AUTO_INCREMENT 列則插入順序中的下一個數字

Q5如何將圖片存放於 MySQL中

Ans

Step 1建立資料庫 test

Step 2 建立表格 binary_data

CREATE TABLE binary_data (

id INT(4) NOT NULL AUTO_INCREMENT PRIMARY KEY

description CHAR(50)

bin_data LONGBLOB

filename CHAR(50)

filesize CHAR(50)

filetype CHAR(50)

71

)

Step 3 利用 storephp 寫入圖片

storephp 程式碼

ltHTMLgt ltHEADgtltTITLEgtStore binary data into SQL DatabaseltTITLEgtltHEADgt ltBODYgt lt code that will be executed if the form has been submitted

if ($submit) mysql_connect(localhostrootYOUR_PASSWORD) mysql_select_db(test) $data=Base64_Encode(fread(fopen($form_data r) filesize($form_data))) $result=MYSQL_QUERY(INSERT INTO binary_data (descriptionbin_datafilenamefilesizefiletype) VALUES ($form_description$data$form_data_name$form_data_size$form_data_type)) $id= mysql_insert_id() print ltpgtThis file has the following Database ID ltbgt$idltbgt MYSQL_CLOSE() else else show the form to submit new data

gt

ltform method=post action=ltphp echo $PHP_SELF gt enctype=multipartform-datagt File Descriptionltbrgt ltinput type=text name=form_description size=40gt ltINPUT TYPE=hidden name=MAX_FILE_SIZE value=4000000gt ltbrgtFile to uploadstore in databaseltbrgt ltinput type=file name=form_data size=40gt ltpgtltinput type=submit name=submit value=submitgt ltformgt lt

72

gt ltBODYgt ltHTMLgt

Step 3 利用 storephp 取出圖片

getdataphp 程式碼

lt Syntax getdataphp3id=ltidgt if($id) you may have to modify login information for your database server MYSQL_CONNECT(localhostrootYOUR_PASSWORD) mysql_select_db(test) $query = select bin_datafiletype from binary_data where id=$id $result = MYSQL_QUERY($query) $data = Base64_Decode(MYSQL_RESULT($result0bin_data)) $type = MYSQL_RESULT($result0filetype) Header( Content-type $type) echo $data gt

Q6MySQL裝好之後啟動時或是執行 mysqladmin會出現如下訊息 Cant connect to local MYSQL Server through Socket varlibmysqlmysqlsock或是

Cant connect to local MYSQL Server through Socket tmpmysqldsock

Ans 可能有下列幾個原因

1這個 mysqldsock 不見了被某人刪除了或是被一些系統自動執行程式給刪

了例如有些 cron任務便會設定定期刪除 tmp 裡的東西所以呢您只能修改

cron 裡的設定讓它不要清除 mysqldsock 2在啟動時也可以改變 mysqldsock的位置您在啟動 MySQL的時候可以加入此參數usrlocalmysqlbinsafe_mysqld --user=mysql --socket=其他路

徑socket amp 同時得去設定環境變數 MYSQL_UNIX_PORT的值以指定新的

73

路徑 3若是您沒改 MYSQL_UNIX_PORT的值那麼您可以在執行指令的時候才打

例如mysqladmin --socket=其他路徑socket version Q7How to get the last insert id Ans CREATE TABLE product ( id INT(4) NOT NULL AUTO_INCREMENT PRIMARY KEY description VARCHAR(50) ) 1利用 SQL的話 mysqlgt insert into product(description) values(123) Query OK 1 row affected (000 sec) mysqlgt select last_insert_id() +------------------+ | last_insert_id() | +------------------+ +------------------+ 1 row in set (000 sec) ======================================== 2如果是 PHP的話 你可以用mysql_insert_id()取得該 id PHP example $result=MYSQL_QUERY(INSERT INTO product (description) VALUES ($description)) $id= mysql_insert_id() print This file has the following Database ID $id Q8如何將文字檔匯入資料庫 Ans $addr=homehttpdhtmlphpschool001txt $sql_select = load data infile $addr into table test fields terminated by t 解說 $sql_select = load data infile 文字檔名 into table 表格名 fields terminated by

74

t

(欄位分隔以 TAB鍵) 該文字檔須與資料表欄位格式相符 例如欄位有三個 則文字檔為每行一筆資料如下 欄 1資料ltTABgt欄 2資料ltTABgt欄 3資料 欄 1資料ltTABgt欄 2資料ltTABgt欄 3資料 欄 1資料ltTABgt欄 2資料ltTABgt欄 3資料 欄 1資料ltTABgtltTABgt欄 3資料

Q9如何撰寫 MySQL C API Ans Step 1利用文字編輯器撰寫以下程式碼 mysqlcc

include ltstdiohgt

include ltmysqlmysqlhgt

int main (int argc char argv[])

MYSQL mysql

MYSQL_RES res

MYSQL_ROW row

if (argc = 2)

fputs (Usage myc ltdatabasegt stderr)

return 1

if ((mysql_connect(ampmysqllocalhostrootYour_Password)))

fputs (Error connecting stderr)

abort()

75

if (mysql_select_db(ampmysqlargv[1]))

fputs (Error selecting database stderr)

abort()

if (mysql_query(ampmysqlSELECT FROM test_table))

fputs (Error processing query stderr)

abort()

if ((res = mysql_store_result(ampmysql)))

fputs (Error storing results stderr)

abort()

while((row = mysql_fetch_row(res)))

uint i = 0

for (i=0 i lt mysql_num_fields(res) i++)

printf(s row[i])

printf(n)

return 0

Step 2 Compile

gcc -Iusrlocalmysqlinclude -Lusrlocalmysqllibmysql mysqlcc ndashlm -lmysqlclient

(其中 include path與 library path取決於你的 MySQL安裝路徑)

76

如果執行時發生如下 error Run problemerror in loading shared libraries libmysqlclientsoX 將你的 MySQL library path(for exampleusrlocalmysqllibmysql) 加入etcldsoconf and run sbinldconfig -v Q9ASP + MySQL 範例程式 Ans Dim myconn As New ADODBConnection Dim myrs As New Recordset Dim mySQL As String Dim myrows As Long myconnOpen DSN=MyODBCsample mySQL = SELECT from user myrsSource = mySQL Set myrsActiveConnection = myconn myrsCursorLocation = adUseClient myrsOpen myrows = myrsRecordCount myrsClose myconnClose 可參考 httpwwwdwamnetmysqlasp_myodbcasp 有詳細的資料 Q10如何將 MySQL中的資料庫匯出成txt檔 Ans select from TableName into outfile textxls all result fields will seperate by tab

77

第八章 參考資料

英文部份 網址 1 httpwwwmysqlcom MySQL 網站有第一手有關 MySQL的資料 2 httpwwwmysqlcomdocenReplicationhtml 有關 MySQL Replication 的文件 3 httpwwwgeocitiescomsqlhomefaqstore_blobhtml 如何在 MySQL 存放 BLOB的資料 4httpwwwsapdborg 有關 SAP跟 MySQL相關合作的網站 書藉 1 Cooking with MySQL

Paul DuBois has selected sample recipes from the hundreds youll find in his book MySQL

Cookbook In this third and final series of excerpts showcasing these recipes learn how to

compute team standings how to calculate the differences between successive Dec 26

2002 2 Tips for Building Web Database Applications with PHP and MySQL by Hugh E Williams co-author of Web Database Applications with PHP amp MySQL 04042002

3 Managing and Using MySQL 2nd Edition By Tim King George Reese Randy Jay Yarger

4 MySQL Cookbook By Paul DuBoisPublisher OReillyPub Date October 2002

中文部份

78

1 httplinuxtncedutwtechdocmysqlmysql_docmanual_tochtml MySQL 中文手冊 2 httpchenshloxaedutwphpZ_1php PHP+MySQ程式研習設計網站 3 httplinuxtncedutwtechdocbanicdownhtml PHP 4 手冊 4 httpwwwtncedutwadmin_zonephp台南縣教育網網路中心有很多 Linux相關文件 5 httpdobtncedutw網站建置百寶箱有很多 PHP MySQL 相關範例程式 5 httpwwwdbworldcomtw資料庫專家電子雜誌介紹資料庫的重要觀念及名詞

79

附錄一 SQL Command 介紹

SQL (讀音ess-que-el) 是一種結構查詢語法SQL 使用於資料庫交流

傳遞相容於 ANSI (American National Standards Institute) 是一套標準的關聯

式資料庫語言 SQL 語言是執行更新或從資料系統獲取資料一般常見的關聯

資料庫系統都有提供 SQL 如 Oracle Sybase Microsoft SQL Server Access Ingres 等雖然大部份的資料庫都有提供 SQL 但也多提供了自已獨特的語

法造成了不相容的情形但標準基本的語法是相通的如Select Insert Update Delete Create and Drop 每一個系統都有支援

Table相關 Command

Create Table

關聯式資料庫包含有很多元件稱為資料表(tables) 把資料或訊息放在資

料表中 資料表是以不同的名稱做分別資料表由欄列所構成的二維陣列

欄包含欄位名資料型態 及其他可判斷的資訊列是由全部欄位構成一筆一

筆的紀錄 create table 語法用在建立一個新的資料表語法格式如下

create table tablename (column1 data type column2 data type column3 data type)

Format of create table if you were to use optional constraints

create table tablename (column1 data type [constraint] column2 data type [constraint] column3 data type [constraint]) [ ] = optional

Note You may have as many columns as youd like and the constraints are optional

80

Example

create table employee (first varchar(15) last varchar(20) age number(3) address varchar(30) city varchar(20) state varchar(20))

注意建立資料表格式要以括號把前後框住而最後以(分號)做結尾

欄位名不要超過 30個字元長而且不要使用 sql 的關鍵字(如 where select等)而在後面接是型態的宣告(如字串數字日期格式等)

資料型態是來描述欄位的方式如一個欄位Last_Name 是一個姓氏可以使用varchar (可變動長度字串) 資料型態

以下是幾個常見的資料庫型態 char(size) 固定長度字串最長為 255 位元 varchar(size) 變動長度字串最大字元數以 size 來指定 number(size) 數值格式可以是整數也可以是小數最大數字以 size 位數判

斷未指定小數位數由系統內定 date 日期格式 number(sized) 數值格式最大數字以 size 位數判斷d 為小數位數整數位

數為 size-d 位

有何限制當資料表被建立通常有一或數個欄位是要使用來做關聯的功

能 例如unique 限制(唯一值)兩筆記錄不可以相同的值 not null (非空值)該欄位一定要輸入資料不可是空的primary key (主鍵)是每一筆記錄識別的主要方式

Drop a table drop table 刪除資料表(其中的資料也會一併刪除)

drop table tablename

Example

81

drop table 和刪除全部資料是不同的刪除全部資料欄位名稱資訊等還會

存在但刪除資料表會把這一些也一併移除掉

如何查詢資料

Select 基本用法

select 語法是關連式資料庫最常用的部份可以取得你想要的資料這是一個

簡單的範例 select column1[column2etc] from tablename [where condition] [] = optional 在 select 之後所列欄位名則是要顯示的資料部份你可以一一列出各欄位

名或是以 (星號)來代表選擇全部的欄位 from 之後放資料表名稱 where 子句 (選項) 指定要過濾的條件符合者才會顯現 where 可使用的條件運算元 = 等於 gt 大於 lt 小於 gt= 大或等於 lt= 小或等於 ltgt 大相等 LIKE 相似 For example select first last city

82

from empinfo where first LIKE Er 以Er 為開頭的字串就符合要以單引號框住 Or you can specify select first last from empinfo where last LIKE s 最後一字為 S 就符合 select from empinfo where first = Eric 則表示 first name 一定要是 Eric 才可以 範例資料表empinfo 統計函數

MIN 傳回指定欄位最小值

MAX 傳回指定欄位最大值

SUM 傳回指定欄位總和

AVG 傳回指定欄位平均值

COUNT 傳回指定欄位的筆數

COUNT() 傳回資料庫中的總筆數

統計函數使用於資料表中的數值欄位配合 SELECT 語法使用 只用於總結特定單一欄位可以配合 GROUP BY 做篩選但也可以不使用 GROUP BY 語句For example

SELECT AVG(salary) FROM employee

83

傳回全部 salary 平均值

Another example

SELECT AVG(salary) FROM employee WHERE title = Programmer

傳回 salary 平均值條件為 employees 資料表中當 title 等於 Programmer

Example

SELECT Count() FROM employees

傳回 employees 資料表中紀錄總筆數

GROUP BY 語法 SELECT column1 SUM(column2) FROM list-of-tables GROUP BY column-list The GROUP BY 語句可以先以所列的欄位為條件分組排序在一起(可以多欄

位) example 要列出每一個 dept 中最高 salary 值 SELECT max(salary) dept FROM employee GROUP BY dept HAVING 語法

SELECT column1 SUM(column2) FROM list-of-tables GROUP BY column-list HAVING condition

HAVING 子句是 GROUP BY 的一部份用來過濾在 GROUP BY 所選出的資料功能如同 select 命令中 where 條件式一樣只是 HAVING 必需配合 GROUP BY 使用

我們以例子來說明我們要取得每一公司名及每一公司的薪水平均值輸入如下

84

SELECT dept avg(salary) FROM employee GROUP BY dept

但如果我們只列出薪資平均值超過 20000元的公司資料

SELECT dept avg(salary) FROM employee GROUP BY dept HAVING avg(salary) gt 20000

ORDER BY子句語法

SELECT column1 SUM(column2) FROM list-of-tables ORDER BY column-list [ASC | DESC]

[ ] =選項

ORDER BY是一個選項子句當你以排序方式來顯示資料(正向由小到大反向由大到小)以指定的欄位資料做排序

ASC = 正向- 預設值 DESC = 反向排序

For example

SELECT employee_id dept name age salary FROM employee_info WHERE dept = Sales ORDER BY salary

以上列出公司代號公司名銷售員人名年紀及薪資而條件是公司名為 Sales 顯示順序以薪資多少排序(由小到大為預設值)

如果要以多個欄位做排序要以逗號做分隔如下

SELECT employee_id dept name age salary FROM employee_info WHERE dept = Sales ORDER BY salary age DESC

85

結合條件及布林運算 SELECT column1 SUM(column2) FROM list-of-tables WHERE condition1 AND condition2 AND運算可以結兩個或以上的條件放在 WHERE子句中 兩者都要為真才

會顯示該筆記錄 OR 運算可以結兩個或以上敘述放在 WHERE子句中只要其中一個為直就

會顯示該筆記錄 For example SELECT employeeid firstname lastname title salary FROM employee_info WHERE salary gt= 5000000 AND title = Programmer 必需要薪資大於等於 50000而且職稱為 Programmer同時符合才會顯示該筆資料 以下以括號括住雖然不是必需的但如此比較容易讀 SELECT employeeid firstname lastname title salary FROM employee_info WHERE (salary gt= 5000000) AND (title = Programmer) 另外範例 SELECT firstname lastname title salary FROM employee_info WHERE (title = Sales) OR (title = Programmer) 條件為只要是 Sales 或 Programmer 職稱的就會被列出 IN and BETWEEN 子句

SELECT column1 SUM(column2) FROM list-of-tables WHERE column3 IN (list-of-values) SELECT column1 SUM(column2) FROM list-of-tables WHERE column3 BETWEEN value1 AND value2 IN 子句使用在列舉項目的使用上也就是分別測試是否符合所列的值 For example

86

SELECT employeeid lastname salary FROM employee_info WHERE lastname IN (Hernandez Jones Roberts Ruiz) 條件為姓氏(astname)要符合 Hernandez Jones Roberts or Ruiz 其中一個才會被傳回 IN運算元也可以使用 OR 的語法來取代如下結果相同 SELECT employeeid lastname salary FROM employee_info WHERE lastname = Hernandez OR lastname = Jones OR lastname = Roberts OR lastname = Ruiz 但使用 IN 句子比較短也比較易懂 你也可以使用 NOT IN 來去掉不要的記錄 BETWEEN 運算元使用在判斷是否存在兩個數值之間 For example SELECT employeeid age lastname salary FROM employee_info WHERE age BETWEEN 30 AND 40 傳回年紀 30歲到 40歲之間的資料(含 30及 40歲者) 相同的也可以使用以下語法來達到相同的結果 SELECT employeeid age lastname salary FROM employee_info WHERE age gt= 30 AND age lt= 40 你也可使用 NOT BETWEEN 來濾掉中間值的資料 數學運算 標準 ANSI SQL-92 提供以下運算

87

+ 加

- 減

餘數

餘數為除法後剩整數這不在標準的 ANSI SQL 中但大部份的資料庫都會支

援這運算元以下列出有用的函數雖不在 ANSI SQL-92 提供但一般資料庫

也會支援他們

ABS(x) 傳回 x 絕對值

SIGN(x) returns the sign of input x as -1 0 or 1 (negative zero or positive respectively)

MOD(xy) 餘數 - returns the integer remainder of x divided by y (同 xy)

FLOOR(x) 傳回小或等於 x 的最大整數值

CEILING(x) or CEIL(x)

傳回大或等於 x 的最小整數值

POWER(xy) x的 y 次方

ROUND(x) 把 x 四捨五入為整數

ROUND(xd) 四捨五入取到小數 d 位

SQRT(x) x 開平方

For example SELECT round(salary) firstname FROM employee_info 傳回薪資取到整數位

如何新增資料

insert 加入一筆新紀錄到資料表中 insert into tablename (first_columnlast_column) values (first_valuelast_value) [] = optional Example insert into employee

88

(first last age address city state) values (Luke Duke 45 2130 Boars Nest Hazard Co Georgia) Note 字串要以單引號住如string 數字框住也無妨 insert into 後面接資料表名稱再接以括號括住的欄位名在 values 後括號分別對映各欄位的值 以上的例子新增了一筆名(first) 為 Luke而住所(state) 為 Georgia 的資料

如何刪除資料

delete 可以刪除單筆或多筆紀錄 delete from tablename where columnname OPERATOR value [and|or column OPERATOR value] [ ] = optional Examples delete from employee Note 如果你沒有指定 where 子句那麼全部的紀錄都會被刪除 delete from employee where lastname = May delete from employee where firstname = Mike or firstname = Eric delete from 接著資料表名 再接著是條件式判斷沒有條件式則全部紀錄會

被刪除

如何更新資料

update 用來更新你所指定的記錄要和 WHERE 配合小心使用 語法 update tablename set columnname = newvalue[nextcolumn = newvalue2] where columnname OPERATOR value [and|or column OPERATOR value] [] = optional Examples

89

update phone_book set area_code = 623 where prefix = 979 update phone_book set last_name = Smith prefix=555 suffix=9292 where last_name = Jones update employee set age = age+1 where first_name=Mary and last_name=Williams

90

附錄二Replication

測試環境

RedHat 90 + MySQL 32358 MySQL資料庫路徑 varlibmysql MySQL設定檔 etcmycnf Master IP 1921680100 Slave IP 1921680200 請至下列網址下載最新MySQL 32358套件並利用rpm ndashUvh 更新 httpupdatesredhatcom9enosi386

圖 最新 MySQL 套件

測試架構圖

91

1921680100

1921680200Master Server

erveSlave S r

圖 測試架構圖

測試步驟

Master server 部份 Step1 確認 MasterSlave機器上所裝的 MySQL版本能進行

replication( 32329 or higher ) Step2 在 Master MySQL上開放一個帳號給 Slave mysql ndashu root ndashp mysqlgtGRANT FILE ON TO repl1921680200 IDENTIFIED BY lsquoabc123rsquo mysqlgtq 上面是 Master開放一個帳號 repl密碼 abc123給 IP1921680200有檔案處理

的權限 Step3 shutdown MySQL on the Master mysqladmin ndashu root ndashp shutdown Step4 備份 Master所有資料庫 tar ndashcvf tmpmysql-snapshottar varlibmysql 注意tar的時候MySQL是要在 stop情況下 在mysql (wwwmysqlcom) 網站的FAQ有不用shutdown的方法

92

Step5 在 master機器上修改etcmycnf 在[mysqld]區段內加入參數 log-bin server-id=這邊設定 server-id=1 sql-bin-update-same binlog-do-db=CRM只針對 CRM資料庫做紀錄 Step6 Restart MySQL on the master service mysqld start 此時因為有加入 log-bin 參數因此開始有 index產生了在varlibmysql目錄下

有index檔案紀錄資料庫的異動 log Slave server 部份 Step1 在 slave設定etcmycnf 在[mysqld]區段加入 master-host= master-user= master-password= master-port= server-id= 這邊設定 master-host=1921680100 master-user=repl master-password=abc123 master-port=3306 server-id=2 master-connect-retry=60預設重試間隔 60秒 replicate-do-db=CRM告訴 slave只做 CRM資料庫的更新 log-slave-updates Step2 將 master上的 mysql-snapshottar copy到 slave上 用 ftp傳到 slave的tmp Step3 解壓縮 Master資料庫至 Slave Server上 cd varlib tar xvf tmpmysql-snapshottar chown ndashR mysqlmysql mysql

93

chmod ndashR 770 mysql (視情況) Step4 Restart MySQL on the slave server 這時在varlibmysql目錄會出現 masterinfo此檔案紀錄了 Master MySQL server的資訊

狀況測試

One-way replication

1921680100

1921680200Master Server

erveSlave S r

圖 One-way replication架構圖 Step1 Master跟 Slave網路及服務都正常情況下由 Master端異動資料後 到 Slave端瀏覽資料檢視是否有進行 replication Step2 模擬 Slave Server 當機 可用在於 slave真的當機或是 Slave 不一定需要一直跟 master connect將Slave MySQL server shutdown由 Master端異動資料到 slave端瀏覽此時Slave應該沒有被 replication 更新然後再將 Slave端 MySQL server start起來

預設 60秒後 Slave會嘗試跟 Master要求進行 replication再去 Slave端檢視是否有更新資料

94

Step3 模擬 Master當機因為是設定 One-way replication一旦 Master Server Slave端沒有 Master的 source可以 download Two-way replication 基於 Master當機狀況於是發展雙向 Replication即 1921680100 ( Host A ) 1921680200 ( Host B )都分別擔任 MasterSlave身分

1921680100

1921680200er

Server B MasterSlave Server

Server A MasterSlave Serv

圖 Two-way replication架構圖 以下是針對兩台 MySQL伺服器進行雙向 Replication Step1觀念同單向 replication只是改成 Master也有 Slave身分 Slave也有Master的身分先分別在 Server AServer B 都去 grant一個進行 replication的身分 [A]mysqlgtGRANT FILE ON TO repl1921680200 IDENTIFIED BY lsquoabc123rsquo [B]mysqlgt GRANT FILE ON TO repl1921680100 IDENTIFIED BY lsquoabc123rsquo Step2做完單向 replication後stop Server Aserver B MySQL service此時 AB資料是一樣的

95

修改etcmycnf設定 範例 Server A [mysqld] datadir=varlibmysql socket=varlibmysqlmysqlsock server-id=1 log-bin sql-bin-update-same binlog-do-db=CRM master-host=1921680200 master-user=repl master-password=abc123 log-slave-updates master-connect-retry=60 replicate-do-db=CRM Server B [mysqld] datadir=varlibmysql socket=varlibmysqlmysqlsock server-id=2 log-bin sql-bin-update-same binlog-do-db=CRM master-host=1921680100 master-user=repl master-password=abc123 log-slave-updates master-connect-retry=60 replicate-do-db=CRM 分別 start Server AServer B MySQL後此時雙方都是 MasterSlave身分一旦哪一方資料異動就會通知對方來 replication-若 replication失效則必須將Server AServer B的masterinfo及index00x 都砍掉然後分別 restart MySQL server進行測試檢視成果 實務上通常如果需要做Two-way replication通常會搭配Virtual Server使用

96

在前端架設一台Virtual Server不過此部份不在此份SOP討論範圍內有興趣

的讀者可參考 httpwwwlinuxvirtualserverorg 網站

1921680100 1921680200

Host A MasterSlave Server

Host B MasterSlave Server

Virtual Host

圖 Virtual Server + Two-way replication 架構圖

97

圖 High Availability Linux Virtual Server架構圖

98

  • COSA-SOP-03-006
  • 第一章 簡介
    • 11適用對象 (Audience)
    • 12 MySQL本身
    • 13 MySQL 40版跟50版重大的改進功能
    • 14 各家資料庫軟體比較
      • 第二章 前置需求
      • 第三章 安裝
        • 31 MySQL安裝
        • 32 phpMyAdmin安裝
        • 33 升級及注意事項
          • 第四章 MySQL管理
            • 41 Webmin 管理介面
            • 42 phpMyAdmin 的操作介面
            • 43管理指令介紹
              • 431 利用mysqladmin設定root的密碼
                  • 第五章 實用範例
                    • 51 任務一Web Base客戶通訊錄
                    • 52 任務二Web Base群組軟體 ( twig )
                      • 第六章 維護及更新程序
                        • 61 日常維護
                        • 62 更新程序
                        • 63 備份重要檔案
                        • 64 離線備份與還原
                        • 65 線上備份與還原
                          • 第七章 問題與解答
                          • 第八章 參考資料
                          • 附錄一 SQL Command 介紹
                          • 附錄二Replication
Page 7: DataBase Server Standard Operation Procedureebooks.lib.ntu.edu.tw/1_file/oss/63/93doc4-5.pdf · 業務的公司帶來了不少壓力,譬如微軟,甲骨文 ... 外的錢用在第三方的資料庫產品上,譬如就可以不用再購買甲骨文公司

這項交易中這家瑞典公司 MySQL將會得到其軟體的版稅但他拒絕透露這次

合作的一些經濟方面的細節 SAP的代表稱在更長一段時間後該開放源代碼資料庫軟體將會和 SAP

公司的旗艦產品 R3一起銷售 不久之後SAP與 MySQL將會完成他們合作計畫的第一個階段那

就是 SAP將會發佈一個 MySQL的資料庫版本從而它可以無縫地替代現在使

用的 SAP DB這對 MySQL而言無異是如虎添翼想必在不久的將來MySQL定能擔任企業更重要的任務

13 MySQL 40版跟 50版重大的改進功能

以下是 40版跟 50版一些重大的改進功能 MySQL 40 版httpwwwmysqlcomdocenNews-40xhtml

內建提供InnoDB table type支援 standard binaries adding transactions row-level locking 和foreign keys

提昇 Query速度 改善 boolean mode truncation and phrase searching全文檢索效

率 加強MERGE tables 並支援INSERT statements and

AUTO_INCREMENT 在SELECT 中支援UNION 語法 支援Multi-table DELETE statements libmysqld the embedded server library 更多的GRANT 參數來加強安全性 提供更多動態參數來降低停止 MySQL的必要 改善 replication code and features 改善執行效率並增加可靠性

MySQL 50 版httpwwwmysqlcomdocenTODO_MySQL_50html改善執行效率並增加可靠性 提供 Stored Procedures 機制 支援 cursor Dynamic length rows for HEAP tables Add true VARCHAR support

7

加強執行效率 更好的國際語系支援 提供可用性

14 各家資料庫軟體比較

目前市面上較被廣為使用資料庫除了 MySQL之外尚有下列幾種

1 MS SQL Server 2000 2 Oracle 8i 3 IBM DB2 4 Informix

過去幾年來在總值 120億美元的資料庫市場上如果廠商想要誇讚自家的

產品那就一定得要有強大的資料庫支援最嚴苛的任務才站得上檯面不過

到了今天似乎光是這樣並不夠客戶除了要求足以負擔嚴苛的任務之外還希

望擁有聰明又便宜的資料庫 Meta Group的分析師 Charlie Garry表示 ( 2003 年 5 月)MySQL的商業

模式是以開放原始碼為基礎以便讓客戶盡快接受 MySQLGarry指出MySQL甚至適合用在甲骨文IBM微軟等大廠爭相搶食的企業資料中心

Information Resources的資訊長 Marshall Gibbs就表示他們沒有任何品

牌的偏好只要「功能效能價格的最佳組合」 由研究近兩年來資料庫客戶

愈來愈注重總體成本(圖 1-1)

8

圖 1-1 資料庫優先性

整體擁有成本 大致說來MySQL是免費的MySQL需要付費的規定只限於下列兩種情

形 1 以 Embedded的方式使用 MySQL 2 使用 MySQL的商業用途軟體

且其授權費用一台 MySQL Pro License只需美金 $440比起其他任何資料庫軟體來得容易負擔多了加上其易於管理的特性著實可大大降低企業資料

庫的整體擁有成本 擴充性

MySQL同時提供高度多樣性能夠提供給很多不同的使用者介面包括命

令列操作網頁瀏覽器以及各式各樣的程式語言介面例如JavaC++PerlPHP及 PhythonMySQL可用 UnixWindows以及 OS2hellip等平台因此它可以用個人電腦或是伺服器上 性能 事實上大部份的網站的開發者都認為 MySQL是目前市面跑得最快的資料

9

庫對資料庫的最佳化主要在於你對他的設定和資料庫結構的設計如果你的

資料庫結構設計得非常差你的存取速度還是會受到影響而變得比較慢

10

第二章 前置需求

在安裝 MySQL之前請確定 Apache及 MySQL亦巳安裝相關步驟請參考

Apache SOP安裝 Apache及 PHP相關章節

11

第三章 安裝

31 MySQL安裝

在 RedHat 90上安裝 MySQL是件很容易的事因為 RedHat 90提供了一

個很方便的 GUI套件管理工具「redhat-config-packages」各位只要把 RedHat 90第一片光碟放入並以 root的身份登入系統鍵入 redhat-config-packages勾選「SQL資料庫伺服器」即可然後按「更新」如果遇到任何相依性問題

系統會提示您更換光碟片 ( 圖 3-1 ~ 3-3 ) Step 1 執行 redhat-config-packes

圖 3-1

Step 2 選擇資料伺服器

12

圖 3-2

Step 3檢查是否安裝成功 待安裝後您可以用利用「rpm -qa | grpe ^mysql」檢查是否安裝成功

圖 3-3

啟動 MySQL ( Command Mode )馬上啟動 MySQL的指令為「service mysqld start」如果您希望一開機就自動啟動 MySQL請執行「chkconfig mysqld on」

13

圖 3-4

啟動 MySQL ( WebMin 介面 ) 我們也可以利用WebMin 來啟動 MySQL步驟如下 Step 1登入Webmin

圖 3-5 登入WebMin

Step 2 選擇伺服器

14

圖 3-6 伺服器畫面

Step 2 選擇 MySQL資料庫伺服器

圖 3-7 伺服器畫面

15

Step 3 啟動 MySQL資料庫伺服器

圖 3-8 啟動 MySQL

更改資料庫管理者密碼

成功啟動 MySQL後因為資料庫管理者預設沒有密碼建議使用前更改系

統管理者密碼請輸入下列指令

mysqladmin ndashu root ndashh cosaexamplecom password lsquo1234rsquo -u 表示使用者帳號root 為 MySQL預設的管理帳號

-h 表示 MySQL主機的主機名稱也可使用 IP Address password 表示使用者的密碼因為字串請使用單引號將密碼括起來

圖 3-9 修改 MySQL 的密碼

16

32 phpMyAdmin安裝

本書除了會介紹利用當今 Linux上最紅的整合管理工具Webmin 來管理

MySQL外還會為各位介紹專門管理 MySQL的工具 phpMyAdmin phpMyAdmin是免費的 PHP原始程式碼的Web網站可用來管理整個

MySQL伺服器這是一套Web介面的 MySQL管理程式支援中文的使用者介

面 phpMyAdmin只需透過瀏覽器就可管理 MySQL伺服器換句話說不論

MySQL是安裝在 Linux或是Windows 作業系統都可以使用相同步驟在

MySQL上建立資料庫(Database)資料表(Table)和編輯紀錄(Record) Step 1 下載phpMyAdmin ( httpwwwphpmyadminnet )選擇最櫎新穩定的版

本 253

圖 3-10 httpwwwphpmyadminnet

17

圖 3-11 下載 phpMyAdmin-253-phptarbz2

Step 2 將 phpMyAdmin-253-phptarbz2收至 tmp 並執行下列指令將其解壓

縮至varwww tar jxvf phpMyAdmin-253-phptarbz ndashC varwwwhtml

圖 3-12 解壓縮安裝 phpMyadmin-253

Step 3 為了操作方便起見建立 Soft link ln ndashs phpMyAdmin-253 phpMyAdmin

圖 3-13 修改 phpMyadmin 設定檔 configincphp

18

Step 4 修改 phpMyadmin 設定檔 configincphp gedit varwwwhtmlphpMyAdminconfigincphp

圖 3-14 configincphp設定檔

Step 5 設定顯示行號以方便修改 configincphp 設定檔

19

圖 3-15 顯示行號

Step 6 修改下列設定 第 39 行 設定 phpMyAdmin的 URL 第 69 行 MySQL Server 的 ip 第 80 行 利用何帳號存取 MySQL 第 81 行 如果 root有設定 password此處即填入 root的 password

30 In most cases you can leave this variable empty as the correct value

31 will be detected automatically However we recommend that you do

32 test to see that the auto-detection code works in your system A good

33 test is to browse a table then edit a row and save it There will be

34 an error message if phpMyAdmin cannot auto-detect the correct value

35

36 If the auto-detection code does work properly you can set to TRUE the

37 $cfg[PmaAbsoluteUri_DisableWarning] variable below

38

39 $cfg[PmaAbsoluteUri] = httpossccosaorgtwphpMyAdmin

hellip

20

hellip

69 $cfg[Servers][$i][host] = localhost MySQL hostname or IP address hellip 80 $cfg[Servers][$i][user] = root MySQL user

81 $cfg[Servers][$i][password] = 1234 MySQL password (only needed

圖 3-16 修改 configincphp

21

圖 3-17 修改 configincphp

圖 3-18 修改 configincphp p

Step 7 設定語系

22

圖 3-19 設定語系

圖 3-20 執行 phpMyAdmin

23

33 升級及注意事項

RedHat 90附的 MySQL版本為 323 MySQL所釋出最新穩定版本為

40若是您不想用系統預附的 323請先利用下列移除之前 323的版本

rpm ndashe mysql-devel rpm ndashe mysql-server rpm ndashe mysql --nodeps 然後到下列網址下載您所想要的版本進行安裝在這裏我們用 4014版為例 Step 1 下載相關套件( httpwwwmysqlcomdownloadsmysql-40html )

圖 3-21 Download MySQL 4014 相關 RPM Step 2 利用 rpm 指令安裝

24

圖 3-22 Install MySQL 4014 相關 RPM

圖 3-23 Install MySQL 4014 相關 RPM

Step 3 啟動 MySQL

25

圖 3-24 啟動 MySQL 4014 並修改密碼

26

第四章 MySQL管理

本章將我們介紹利用WebminphpAdminCommand的方式建立一個名為

CONTACT的資料庫內有一個 address的 Table作為我們客戶通訊錄程式使

用的資料庫

41 Webmin 管理介面

412建立資料庫

Step 1 登入Webmin

圖 4-1 登入WebMin

Step 2 點選伺服器

27

圖 4-2 伺服器畫面

Step 3 點選 MySQL資料庫伺服器

圖 4-3 MySQL資料庫伺服器

28

Step 4 建立一個新的資料庫

圖 4-4 建立 MySQL資料庫

Step 5 建立名為 CONTACT的資料庫

29

圖 4-5 指定資料庫名稱

412 建立資料表

假設我們要建立一個名為 address的 Table其結構如下 欄位名稱 資料型態 長度 說明 id INT (自動編號) 連絡人編號 name varchar文字 20 連絡人姓名 tel Varchar文字 15 連絡人電話 Step 1 選擇 CONTACT資料庫

30

圖 4-6 選擇資料庫

Step 2 指定欄位數目

31

圖 4-7 設定欄位數目

Step 3設定表格欄位屬性

圖 3-8 設定表格欄位屬性

Step 4建立表格資料

32

圖 4-9 建立表格資料

圖 4-10 檢視資料

33

圖 4-11 新增資料

圖 4-12

34

圖 4-13

413 使用者管理

接下來我們要利用Webmin 來建立資料庫使用者並給予某些權限 Step1建立使用者

35

圖 4-14 選擇使用者權限

圖 4-15

36

Step2 賦予權限

圖 4-16

Step3 權限列表

37

圖 4-17

38

42 phpMyAdmin 的操作介面

421建立資料庫

Step 填入資料庫名稱並按「建立」

圖 4-18建立資料庫

422 建立資料表

Step1 填入資料表名稱並指定欄位數量 執行

39

圖 4-19填入資料表名稱並指定欄位數量

Step2 設定欄位屬性

圖 4-20設定欄位屬性

40

Step3 phpMyAdmin會產生相關的 SQL Command

圖 4-21 資料表結構及相關 SQL Command

Step4新增 Record

41

圖 4-22

圖 4-23

42

圖 4-24

圖 4-25

43

423使用者管理

Step1建立使用者

圖 4-26

44

圖 4-27

Step2 給予權限

圖 4-28

Step3權限列表

45

圖 4-29

43管理指令介紹

431 利用 mysqladmin設定 root的密碼

當您在Windows 或 Linux 中安裝好 MySQL後系統會自動幫您建立兩個

帳分別是 root 和 匿名者MySQL的 root 跟 Linux 最高權限使用者 root無關MySQL的 root使用者相當於 MS SQL 中的 sa 帳號擁有最高的 Database管理權限但系統預設 MySQL的 root 是不需要密碼所以通常我們一安裝

MySQL後首要任務便是修改 root的密碼 我們可以利用 mysqladmin工具或是直接修改 MySQL內部資料庫的使用者資

料 mysqladmin ndashu root ndashh cosaexamplecom password lsquo1234rsquo

46

-u 表示使用者帳號root 為 MySQL預設的管理帳號

-h 表示 MySQL主機的主機名稱也可使用 IP Address password 表示使用者的密碼因為字串請使用單引號將密碼括起來 密碼設定完成之後還是可以利用 mysqladmin修改密碼但是你必須提供目前的密碼

432 連線 MySQL

mysql -uroot -p密碼 (-p和密碼之間不能有空白) 或 mysql -uroot -p (此方式會在進入後要求密碼) [rootossc phpMyAdmin] mysql -u root -p1234

Welcome to the MySQL monitor Commands end with or g

Your MySQL connection id is 25 to server version 32354

Type help or h for help Type c to clear the buffer

mysqlgt show databases

+----------+

| Database |

+----------+

| mysql |

| test |

+----------+

2 rows in set (000 sec)

mysqlgt exit

Bye

[rootossc phpMyAdmin]

433 建立資料庫

可利用 mysqladmin指令建立 CONTACT資料庫 mysqladmin -u root -p1234 create CONTACT

47

或是利用 mysql指令 [rootossc bluepage] mysql -u root -p1234 Welcome to the MySQL monitor Commands end with or g Your MySQL connection id is 1057 to server version 32354 Type help or h for help Type c to clear the buffer mysqlgt create database CONTACT Query OK 1 row affected (000 sec) mysqlgt show databases +----------+ | Database | +----------+ | CONTACT | | address | | hello | | mysql | | nuke | | test | +----------+ 6 rows in set (000 sec) mysqlgt exit

434 建立資料表

編寫 adresssql內容如下 -- Table structure for table address CREATE TABLE address ( id int(11) NOT NULL auto_increment name varchar(20) NOT NULL default tel varchar(15) NOT NULL default PRIMARY KEY (id) ) TYPE=MyISAM

48

-- Dumping data for table address INSERT INTO address VALUES (1林小明0800016888) INSERT INTO address VALUES (2黃大雄0800016888) INSERT INTO address VALUES (3劉小芬0800024365) 然後執行此 sql script mysql -u root -p1234 CONTACT lt addresssql 或是利 mysql command [rootossc bluepage] mysql -u root -p1234 Welcome to the MySQL monitor Commands end with or g Your MySQL connection id is 1090 to server version 32354 Type help or h for help Type c to clear the buffer mysqlgt use CONTACT Database changed Database changed mysqlgt CREATE TABLE address ( -gt id int(11) NOT NULL auto_increment -gt name varchar(20) NOT NULL default -gt tel varchar(15) NOT NULL default -gt PRIMARY KEY (id) -gt ) TYPE=MyISAM Query OK 0 rows affected (000 sec) mysqlgt INSERT INTO address VALUES (1林小明0800016888) Query OK 1 row affected (000 sec) mysqlgt INSERT INTO address VALUES (2黃大雄0800016888) Query OK 1 row affected (000 sec) mysqlgt INSERT INTO address VALUES (3劉小芬0800024365) Query OK 1 row affected (000 sec) mysqlgt exit Bye

49

第五章 實用範例

51 任務一Web Base客戶通訊錄

任職於開放科技公司的林小明前些日子在最符合成本效益的條件下快

速地完成公司網站的建置老闆因此對小明讚譽有加最近因為公司存放客戶資

料的 SQL Server主機屢遭病毒攻擊加上作業系統本身的問題當機次數頻繁

老闆希望能儘快把公司的客戶通訊錄程式移轉到較穩定的環境上因為此客戶通

訊錄程式最主要給內部人員使用所以介面美觀並不特別要求只求穩定且能快

速得到查詢結果老闆希望在短時間先看到程式的雛型並鍵入資料對其效率

及穩定性進行測試因為上次小明表現突出所以這次不可能的任務自然又落到

小明身上 小明想來想去既然要快速又穩定他而且又不希望所有人都得安裝 Client

程式於是小明決定)捨棄他的舊愛「Delphi+MS SQL」投向新歡「Apache + MySQL + PHP」利用此架構來設計一個簡單實用的Web Base客戶通訊錄程式

511 Web Base客戶通訊錄架構

此程式需要建立 CONTACT的資料庫並建立 adress Tables其結構如下表建立步驟請參考第三章 欄位名稱 資料型態 長度 說明 id INT (自動編號) 連絡人編號 name varchar文字 20 連絡人姓名 tel Varchar文字 15 連絡人電話 Web Base通訊錄共有下列幾個檔案功能如下表

檔案名稱 說明 Indexhtml Web Base通訊錄首頁 addphp 新增連絡人的 php程式 searchphp 尋找連絡人的 php程式 editphp 具有更新及刪除功能的 php程式

50

我們將這些檔案放至varwwwhtmlbluepage (預設無 bluepage目錄)

512 Web Base通訊錄測試

httpwwwopencombluepage 新增資料

圖 5-1 新增連絡人

圖 5-2 填入資料

51

圖 5-3 新增成功

搜尋及異動資料

圖 5-4 搜尋通訊錄

52

圖 5-5 編輯資料

圖 5-6 更新資料

513 程式內容及說明

lt-- 程式範例indexhtml--gt lthtmlgt ltheadgtlttitlegt通訊錄lttitlegtltheadgt ltbodygt ltcentergt

53

lth2gt通訊錄lth2gtlthrgt lta href=indexhtmlgt通訊錄ltagt | lta href=addphpgt新增連絡人ltagt | lta href=searchphpgt搜尋通訊錄ltagt ltcentergt ltbodygt lthtmlgt lt-- 程式範例addphp --gt lthtmlgt ltheadgtlttitlegt新增連絡人lttitlegtltheadgt ltbodygt ltcentergtlth2gt新增連絡人lth2gtltcentergtlthrgt lt 取得欄位資料 if (isset($_POST[Name]) ampamp isset($_POST[Tel]) ) $name = $_POST[Name] $tel = $_POST[Tel] 檢查是否有輸入欄位資料 if ($name = ampamp $tel = ) 建立 SQL字串 $sql = INSERT INTO address (name tel) values( $sql= $name $tel) 建立 MySQL 連結 $link = mysql_connect(localhostroot1234) 選擇資料庫 mysql_select_db(CONTACT) 執行 SQL指令 mysql_query($sql) mysql_close($link) echo ltfont color=redgt新增連絡人成功ltfontgtltbrgt gt ltform action=addphp method=postgt lttable border=0 width=300gt lttrgtlttdgt姓名 lttdgt

54

lttdgtltinput type=text name=Name size=20 maxlength=10gtlttdgtlttrgt lttrgtlttdgt電話 lttdgt lttdgtltinput type=text name=Tel size=20 maxlength=20gtlttdgtlttrgt lttrgtlttd colspan=2 align=centergt ltinput type=submit value=新增連絡人gtlttdgtlttrgt lttablegt ltformgt ltbrgtlta href=indexhtmlgt通訊錄ltagt | lta href=addphpgt新增連絡人ltagt | lta href=searchphpgt搜尋通訊錄ltagt ltbodygt lthtmlgt

lt-- 程式範例searchphp --gt lthtmlgt ltheadgtlttitlegt搜尋通訊錄lttitlegtltheadgt ltbodygt ltcentergtlth2gt搜尋通訊錄lth2gtlthrgt lt if (isset($_POST[Search])) 建立資料庫連結並選定資料庫 $link = mysql_connect(localhostroot1234) mysql_select_db(CONTACT) 建立基本的 SQL字串 $sql = SELECT FROM address 檢查是否輸入姓名 if (chop($_POST[Name]) = ) $name = name LIKE $_POST[Name] else $name = 檢查是否輸入電話號碼 if (chop($_POST[Tel]) = ) $tel = tel LIKE $_POST[Tel] else $tel =

55

if條件組合 SQL字串 if (chop($name) = ampamp chop($tel) = ) $sql= WHERE $name AND $tel elseif (chop($name) = ) 只有姓名 $sql = WHERE $name elseif (chop($tel) = ) 只有電話號碼 $sql = WHERE $tel $sql= ORDER BY name 最後加上排序 $result = mysql_query($sql) 取得欄位數 $total_fields = mysql_num_fields($result) echo lttable border=1gt echo lttrgtlttdgt編號lttdgtlttdgt姓名lttdgtlttdgt電話lttdgtlttd colspan=2gt功能選項lttdgtlttrgt 表格顯示查詢結果 while ($rows = mysql_fetch_array($result MYSQL_NUM)) echo lttrgt for ($i = 0 $i lt $total_fields $i++) echo lttdgt$rows[$i]lttdgt echo lttdgtlta href=editphpaction=editampid= echo $rows[0]gtltbgt編輯ltbgtlttdgt echo lttdgtlta href=editphpaction=delampid= echo $rows[0]gtltbgt刪除ltbgtlttdgt echo lttrgt echo lttablegtlthrgt mysql_free_result($result) mysql_close($link) gt ltcentergt ltform action=searchphp method=postgt lttable border=0 width=450gt lttrgtlttdgt搜尋姓名 lttdgt lttdgtltinput type=text name=Name size=10 maxlength=20gtlttdgtlttrgt lttrgtlttdgt搜尋電話 lttdgt lttdgtltinput type=text name=Tel

56

size=20 maxlength=20gtlttdgtlttrgt lttrgtlttd colspan=2 align=centergt ltinput type=submit name=Search value=搜尋gtlttdgtlttrgt lttablegt ltformgt ltbrgtlta href=indexhtmlgt通訊錄ltagt | lta href=addphpgt新增連絡人ltagt | lta href=searchphpgt搜尋通訊錄ltagt ltbodygt lthtmlgt

lt ob_start() gt lt-- 程式範例editphp --gt lthtmlgt ltheadgtlttitlegt編輯通訊錄lttitlegtltheadgt ltbodygt lt 取得 URL 參數 $id = $_GET[id] $action = $_GET[action] 建立資料庫連結 $link = mysql_connect(localhostroot1234) mysql_select_db(CONTACT) 選擇資料庫 執行的操作 switch ($action) case update 更新 取得欄位資料 $name = $_POST[Name] $tel = $_POST[Tel] $sql = UPDATE address SET name=$name tel=$tel WHERE id=$id mysql_query($sql) 執行 SQL指令 mysql_close($link) header(Location searchphp) 轉向到 serachphp break case del 刪除 $sql = DELETE FROM address WHERE id=$id

57

mysql_query($sql) 執行 SQL指令 mysql_close($link) header(Location searchphp) 轉向到 serachphp break case edit 編輯 $sql = SELECT FROM address WHERE id=$id $result = mysql_query($sql) 執行 SQL指令 $row = mysql_fetch_row($result) 取回記錄 $name = $row[1] 取得欄位 name $tel = $row[2] 取得欄位 tel mysql_close($link) 顯示編輯表單 gt ltcentergtlth2gt更新通訊錄lth2gtltcentergtlthrgt ltform action=editphpaction=updateampid=lt echo $id gt method=postgt lttable border=0 width=300gt lttrgtlttdgt姓名 lttdgt lttdgtltinput type=text name=Name size=20 maxlength=10 value=lt echo $name gtgtlttdgtlttrgt lttrgtlttdgt電話 lttdgt lttdgtltinput type=text name=Tel size=20 maxlength=20 value=lt echo $tel gtgtlttdgtlttrgt lttrgtlttd colspan=2 align=centergt ltinput type=submit value=更新連絡人gtlttdgtlttrgt lttablegt ltformgt ltbrgtlta href=indexhtmlgt通訊錄ltagt | lta href=addphpgt新增連絡人ltagt | lta href=searchphpgt搜尋通訊錄ltagt lt break gt ltbodygt lthtmlgt

58

52 任務二Web Base群組軟體 ( twig )

順利完成Web Base客戶通訊錄程式測試一段時間後「Apache + MySQL + PHP」架構的穩定與快速巳深得老闆與公司所有同事的認同隨著公司業績蒸

蒸日上人員組織編罝愈來愈龐大跨部門的會議愈來愈多業務員每日排滿拜

訪客戶的行程跟客戶的 Email的往來也愈來愈頻繁 愈來愈多部門的同事希望公司能建置一套群組軟體提供 web mail可讓業

務人員方便收發 mail還有連絡人議事日程待辦工作書簽等功能讓整個

公司運作及個人時間管理更有效率

老闆問小明對這些需求有什麼看法小明認為如果這些功能完全由程式部

門開發必定曠日費時而且耗費公司資源小明在網路尋找是否有提供這些功能

的Free Software皇天不負苦心人小明發現了TWIG (The Web Information Gateway) httptwigscrewdrivernet這個群組軟體它在 Web 上整合郵件新聞聯絡人議事日程工作序書簽等功能非常符合公司的需求 Step 1 下載 twig-277targz 下載網址 httptwigscrewdrivernetdownloadphp3

Step 2 解開 twig-277targz tar -xzvf twig-277targz

59

Step 3 執行安裝動作安裝到 varwwwhtmltwig 目錄 cd twig-277 twig-install varwwwhtmltwig

Step 4 建立 MySQL 資料庫(twig)及各資料表

cd setup mysql -u root -p1234 mysqlgt create database twig Query OK 1 row affected (001 sec) mysqlgt quit mysql -u root ndashp1234 twiglt twigtablemysql

Step 5 修改 configincphp3 參數設定 vi varwwwhtmltwigconfigconfigincphp3 $config[fromdomain] = opencom 網域 $config[language] = chinesebig5 中文訊息 $config[imap_port] = 143notls

60

Step 6 修改連結 MySQL 的帳號密碼 vi varwwwhtmltwigconfigdbconfigincphp3 $dbconfig[sqlusername] = root username $dbconfig[sqlpassword] = 1234 password

Step 7 其他設定檔

vi etchttpdconfhttpdconf 加入 AddType applicationx-httpd-php php3 在 DirectoryIndex最後加入 indexphp3 DirectoryIndex indexhtml indexhtmlvar indexphp3 在 AddDefaultCharset ISO-8859-1加上 AddDefaultCharset ISO-8859-1

vi etcphpini register_globals = On service httpd restart Step 8 sendmail 設定 vi etcmailsendmailcf在 264 行前面加上並重新啟動 sendmail「service snedmail restart」 262 SMTP daemon options 263 264 O DaemonPortOptions=Port=smtpAddr=127001 Name=MTA 265 266 SMTP client options 267 O ClientPortOptions=Family=inet Address=00

61

Step 9 檢查設定有無錯誤 http主機名稱twigtestphp3

62

Step 10 登入 twig ( http主機名稱twig)

63

第六章 維護及更新程序

61 日常維護

系統管理員最好定期以 root 身份登入看看信件在 RedHat Linux 中有一支 logwatch 程式會定時去分析 log file如果發現異常便會發信給 root除此之外筆者建議讀者平時就檢查 MySQL log file ( varlogmysqldlog)是否有異常情形

62 更新程序

讀者可至httprpmfindnet 尋找MySQL相關套件至於升級的相關步驟請參

考Linux OS SOP 第 54節

63 備份重要檔案

預設 MySQL 的 DB 檔案是存在 varlibmysql 內以 DB名稱為目錄目錄

內就是該 DB 的所有資料通常得定期備份還有 MySQL的設定檔 etcmycnf也別忘了一起備份

64 離線備份與還原

641 離線備份

預設 MySQL 的 DB 檔案是存在 varlibmysql 內以 DB 名稱為目錄目錄內

就是該 DB 的所有資料像 CRM 這個 DB就是存在 varlibmysqlCRM 內在備份前因為怕資料尚未完全寫入磁碟而且 MySQL 會 Lock 在使用的 DB 檔案所以應該是要先把 MySQL 先 Shutdown 一下整個備份的程序可以下像下面的指令去完成 cd varlibmysql

64

service mysqld stop tar cvfz CRM_db_20030905tgz CRM service mysqld start 對這樣就可以了 不過要注意的是怕 DB 內每個 Tables 間的資料有關關

聯性所以最好是把整個 DB 一次備起來單獨只備哪個 Tables 的檔案以後回存時怕會有資料關聯不一致的問題

642 離線還原

DB 發生錯誤而要回存時其實也不難先找出最近一次完整正常的備份先把現在錯誤的網頁或 DB 先更名或 tar 起來再把好的備份給解開回原來目錄位

置就行了需要注意的是 MySQL 服務最好也是要先停止回存完成後再啟動服務回存 DB 的整個程序可能像下面 cd varlibmysql service mysqldstop mv CRM CRM_OLD tar xvfz CRM_db_20030905tg service mysqld start

65 線上備份與還原

651 線上備份

使用像上面的檔案方式備份是個不錯的方法它最少可以保持該主機某個時間點的完整檔案備份但還是有一些問題需要考慮到有些主機就不只建立一個 DB 而已總不能為了備份某個 DB 而把整個 MySQL 服務停止備份檔案的方式回存在原主機上一定適用但假如 MySQL 版本升級或是在那天該網頁空間需遷機移機到別的主機時那就沒人敢保證備出來的資料檔可以用所以我們可以考慮另一種備份的方式是使用 MySQL 本身提供的功能 MySQL Data Dump指令是 mysqldump

65

使用 MySQL 的 Dump 功能可以把 DB 的結構資料或結構加資料 Dump 成文字檔 mysqldump 指令提供的彈性很大你可以選擇把整個 DB Dump 成一個檔或是每個 Table 為一個檔甚至是把結構檔和資料分開儲存都

可以 mysqladmin -uroot -p flush-logs mysqldump CRM -uroot -p --opt gt CRM_20030905sql (CRM 是 DB 名稱 opt 是一個使用完整 Dump 參數) 假如只是要單獨 Dump 某個 Table 時只要在上面的指令後轉出符號 gt 前加個 Table 名稱就可以如只要 phpbb2_users 這個 Table 的 Dump 時只要下 mysqldump CRM -uroot -p --opt CUSTOMER gt CRM_CUSTOMER_20030905sql

652 線上還原

若要回存整個資料庫只需將壓縮的備份檔還原成 Dump 的檔案再用下面的指令回存 mysql CRM -uroot -p lt CRM_20030905sql 這邊需注意的是若建立備份時是以--opt或--add-drop-table為參數時回存的 動作是先將舊的 Table 先刪除重建 Table 的結構後再把 Data 匯入所以回存後所有的資料會回到你當時備份那個時間點因此在回存資料時可以考慮把現有錯誤或不完整的 DB 先備份一份下來以備不時之需或是拿來比對錯誤的地

方在那裡當然你也可以把資料回存到另一個測試用的 DB 內只要把上面指令

的 DB 名稱改成你的測試用 DB 名稱即可 使用這種回存方式 MySQL 服務不需停止也不會動到其他正在使用的 DB 在一些提供 MySQL 服務的虛擬主機可用這種方式作你自己的 DB 備份及回存

66

另外假如你是系統重建或是移機時切需在新的 MySQL 內新建一個空白 DB 後才行作回存的工作你可以用下面的指令建立 mysql -uroot -p -e CREATE DATABASE CRM (上面的 CRM是你要新建的 DB 名稱) 另一種作法先用 mysql 指令進入 mysql client console 然後再用 CREATE DATABASE CRM 這樣就行了記得尾端要加個 符號該行指令才會執行

67

第七章 問題與解答

Q1RedHat 90預附的 MySQL到底有無支援 Transcation機制 Ans MySQL自 32334a之後的 MySQL-Max版本加入 InnoDB的資料庫類型透過

InnoDBMySQL同樣可以進行 COMMIT與 ROLLRACK的動作RedHat 90預附的 MySQL為 32354a-11巳支援 InnoDB的資料庫類型不過必須做以

下設定 1cp usrsharedocmysql-server-32354amy-mediumcnf to etcmycnf 2 vi etcmycnf 將以下設定前的拿掉 innodb_data_home_dir = varlibmysql innodb_data_file_path = ibdata110Mautoextend innodb_log_group_home_dir = varlibmysql innodb_log_arch_dir = varlibmysql 3service mysqld restart 如此一來各位在建立Table時便可指定Table Type為 innodb ( ex create table with type=innodb ) Q2如何解決 php+mysql 許功蓋等字變亂的問題 Ans 方法一 【確定 MySQL 預設的字元集】 1 打開 WinMySQLadmin 管理畫面(在視窗右下角狀態列紅綠燈圖示中按滑鼠

右鍵點選 Show me 選項) 2 點選管理畫面中 [Variables] 標籤選項其中 character_set變數就是您預設

字元集的變數其預設是 latin1 字元集(我們要將他改回 big5)而 chatacters_set 變數則是 MySQL 可以支援哪些字元集 【修改預設字元集變數 character_set 】 1 請點選管理畫面中 [myini Setup] 標籤選項設定 myini 2 按一下 [Pick-up and Edit myini values] 按鈕以便編輯目前的 myini 設定 3 在 [mysqld] 設定區塊底下新增一行 default-character-set = big5 變數設

68

定 4 新增一個 [client] 設定區塊並加入第三步驟的變數設定(游標往下移到空白處新增兩行 [client] 和 default-character-set=big5) 5 按一下畫面左下方 [Save Modification] 按鈕儲存設定 6 重新啟動 MySQL 或 Windows 方法二 Server端注意事項 phpini 中有關的設定為(預設值) Magic quotes for incoming GETPOSTCookie data magic_quotes_gpc = On Use Sybase-style magic quotes (escape with instead of ) magic_quotes_sybase = Off Client端注意事項 1中文資料送進 mysql 前請用 addslashes($str) 處理 2處理後送進 mysql 時請用 括起來並在參數後留一個空白如 $sql = UPDATE ezf_table set tablename=$tname tableend=$endtime table inguser=$tguser tableingid=$tguserid tableallnumber=$tnumber tableloca l=$tablelocal tableanyone=$tableopen tabletext=$ttext WHERE tableid=$t ableid tablename=$tname c 取出時請用 stripslashes($str) Q3MySQL root 密碼忘了該怎麼辦 Ans 1先停掉 mysql etcrcdinitdmysql stop 2以--skip-grant-table 的參數啟動 mysql safe_mysql --skip-grant-tableamp 3 更改 root 密碼 mysql mysql mysqlgt UPDATE user SET password=password(newpassword)

69

WHERE user=root mysqlgt FLUSH PRIVILEGES mysqlgt exit 4停掉 mysql再重跑 mysqladmin -uroot -p shutdown Enter password 輸入新設定的密碼 etcrcdinitdmysql start

Q4NULL值問題

Ans

NULL值的概念是造成 SQL的新手的混淆的普遍原因他們經常認為 NULL是和一個空字符串的一樣的東西不是這樣的例如下列語句是完全不同的

mysqlgt INSERT INTO my_table (phone) VALUES (NULL)

mysqlgt INSERT INTO my_table (phone) VALUES ()

兩個語句把值插入到 phone 列但是第一個插入一個 NULL值而第二個插入一個空字符串第一個的含義可以認為是ldquo電話號碼不知道而第二個則可意味

著ldquo她沒有電話

在 SQL中NULL值在于任何其他值甚至 NULL值比較時總是假的(FALSE)包含 NULL的一個表達式總是產生一個 NULL值除非在包含在表達式中的運算符和函數的文檔中指出在下列例子所有的列返回 NULL

mysqlgt SELECT NULL1+NULLCONCAT(InvisibleNULL)

如果你想要尋找值是 NULL的列你不能使用=NULL測試下列語句不返回任

何行因為對任何表達式expr = NULL是假的

mysqlgt SELECT FROM my_table WHERE phone = NULL

要想尋找 NULL值你必須使用 IS NULL測試下例顯示如何找出 NULL電話號碼和空的電話號碼

70

mysqlgt SELECT FROM my_table WHERE phone IS NULL mysqlgt SELECT FROM my_table WHERE phone =

在 MySQL中就像很多其他的 SQL服務器一樣你不能索引可以有 NULL值的列你必須聲明這樣的列為 NOT NULL而且你不能插入 NULL到索引的

列中

當用 LOAD DATA INFILE 讀取數據時空列用更新如果你想要在一個列中有

NULL值你應該在文本文件中使用N字面上的詞NULL也可以在某些情形下使用

當使用 ORDER BY時首先呈現 NULL值如果你用 DESC以降序排序NULL值最後顯示當使用 GROUP BY時所有的 NULL值被認為是相等的

為了有助于NULL的處理你能使用 IS NULL和 IS NOT NULL運算符和 IFNULL()函數

對某些列類型NULL值被特殊地處理如果你將 NULL插入表的第一個TIMESTAMP 列則插入當前的日期和時間如果你將 NULL插入一個AUTO_INCREMENT 列則插入順序中的下一個數字

Q5如何將圖片存放於 MySQL中

Ans

Step 1建立資料庫 test

Step 2 建立表格 binary_data

CREATE TABLE binary_data (

id INT(4) NOT NULL AUTO_INCREMENT PRIMARY KEY

description CHAR(50)

bin_data LONGBLOB

filename CHAR(50)

filesize CHAR(50)

filetype CHAR(50)

71

)

Step 3 利用 storephp 寫入圖片

storephp 程式碼

ltHTMLgt ltHEADgtltTITLEgtStore binary data into SQL DatabaseltTITLEgtltHEADgt ltBODYgt lt code that will be executed if the form has been submitted

if ($submit) mysql_connect(localhostrootYOUR_PASSWORD) mysql_select_db(test) $data=Base64_Encode(fread(fopen($form_data r) filesize($form_data))) $result=MYSQL_QUERY(INSERT INTO binary_data (descriptionbin_datafilenamefilesizefiletype) VALUES ($form_description$data$form_data_name$form_data_size$form_data_type)) $id= mysql_insert_id() print ltpgtThis file has the following Database ID ltbgt$idltbgt MYSQL_CLOSE() else else show the form to submit new data

gt

ltform method=post action=ltphp echo $PHP_SELF gt enctype=multipartform-datagt File Descriptionltbrgt ltinput type=text name=form_description size=40gt ltINPUT TYPE=hidden name=MAX_FILE_SIZE value=4000000gt ltbrgtFile to uploadstore in databaseltbrgt ltinput type=file name=form_data size=40gt ltpgtltinput type=submit name=submit value=submitgt ltformgt lt

72

gt ltBODYgt ltHTMLgt

Step 3 利用 storephp 取出圖片

getdataphp 程式碼

lt Syntax getdataphp3id=ltidgt if($id) you may have to modify login information for your database server MYSQL_CONNECT(localhostrootYOUR_PASSWORD) mysql_select_db(test) $query = select bin_datafiletype from binary_data where id=$id $result = MYSQL_QUERY($query) $data = Base64_Decode(MYSQL_RESULT($result0bin_data)) $type = MYSQL_RESULT($result0filetype) Header( Content-type $type) echo $data gt

Q6MySQL裝好之後啟動時或是執行 mysqladmin會出現如下訊息 Cant connect to local MYSQL Server through Socket varlibmysqlmysqlsock或是

Cant connect to local MYSQL Server through Socket tmpmysqldsock

Ans 可能有下列幾個原因

1這個 mysqldsock 不見了被某人刪除了或是被一些系統自動執行程式給刪

了例如有些 cron任務便會設定定期刪除 tmp 裡的東西所以呢您只能修改

cron 裡的設定讓它不要清除 mysqldsock 2在啟動時也可以改變 mysqldsock的位置您在啟動 MySQL的時候可以加入此參數usrlocalmysqlbinsafe_mysqld --user=mysql --socket=其他路

徑socket amp 同時得去設定環境變數 MYSQL_UNIX_PORT的值以指定新的

73

路徑 3若是您沒改 MYSQL_UNIX_PORT的值那麼您可以在執行指令的時候才打

例如mysqladmin --socket=其他路徑socket version Q7How to get the last insert id Ans CREATE TABLE product ( id INT(4) NOT NULL AUTO_INCREMENT PRIMARY KEY description VARCHAR(50) ) 1利用 SQL的話 mysqlgt insert into product(description) values(123) Query OK 1 row affected (000 sec) mysqlgt select last_insert_id() +------------------+ | last_insert_id() | +------------------+ +------------------+ 1 row in set (000 sec) ======================================== 2如果是 PHP的話 你可以用mysql_insert_id()取得該 id PHP example $result=MYSQL_QUERY(INSERT INTO product (description) VALUES ($description)) $id= mysql_insert_id() print This file has the following Database ID $id Q8如何將文字檔匯入資料庫 Ans $addr=homehttpdhtmlphpschool001txt $sql_select = load data infile $addr into table test fields terminated by t 解說 $sql_select = load data infile 文字檔名 into table 表格名 fields terminated by

74

t

(欄位分隔以 TAB鍵) 該文字檔須與資料表欄位格式相符 例如欄位有三個 則文字檔為每行一筆資料如下 欄 1資料ltTABgt欄 2資料ltTABgt欄 3資料 欄 1資料ltTABgt欄 2資料ltTABgt欄 3資料 欄 1資料ltTABgt欄 2資料ltTABgt欄 3資料 欄 1資料ltTABgtltTABgt欄 3資料

Q9如何撰寫 MySQL C API Ans Step 1利用文字編輯器撰寫以下程式碼 mysqlcc

include ltstdiohgt

include ltmysqlmysqlhgt

int main (int argc char argv[])

MYSQL mysql

MYSQL_RES res

MYSQL_ROW row

if (argc = 2)

fputs (Usage myc ltdatabasegt stderr)

return 1

if ((mysql_connect(ampmysqllocalhostrootYour_Password)))

fputs (Error connecting stderr)

abort()

75

if (mysql_select_db(ampmysqlargv[1]))

fputs (Error selecting database stderr)

abort()

if (mysql_query(ampmysqlSELECT FROM test_table))

fputs (Error processing query stderr)

abort()

if ((res = mysql_store_result(ampmysql)))

fputs (Error storing results stderr)

abort()

while((row = mysql_fetch_row(res)))

uint i = 0

for (i=0 i lt mysql_num_fields(res) i++)

printf(s row[i])

printf(n)

return 0

Step 2 Compile

gcc -Iusrlocalmysqlinclude -Lusrlocalmysqllibmysql mysqlcc ndashlm -lmysqlclient

(其中 include path與 library path取決於你的 MySQL安裝路徑)

76

如果執行時發生如下 error Run problemerror in loading shared libraries libmysqlclientsoX 將你的 MySQL library path(for exampleusrlocalmysqllibmysql) 加入etcldsoconf and run sbinldconfig -v Q9ASP + MySQL 範例程式 Ans Dim myconn As New ADODBConnection Dim myrs As New Recordset Dim mySQL As String Dim myrows As Long myconnOpen DSN=MyODBCsample mySQL = SELECT from user myrsSource = mySQL Set myrsActiveConnection = myconn myrsCursorLocation = adUseClient myrsOpen myrows = myrsRecordCount myrsClose myconnClose 可參考 httpwwwdwamnetmysqlasp_myodbcasp 有詳細的資料 Q10如何將 MySQL中的資料庫匯出成txt檔 Ans select from TableName into outfile textxls all result fields will seperate by tab

77

第八章 參考資料

英文部份 網址 1 httpwwwmysqlcom MySQL 網站有第一手有關 MySQL的資料 2 httpwwwmysqlcomdocenReplicationhtml 有關 MySQL Replication 的文件 3 httpwwwgeocitiescomsqlhomefaqstore_blobhtml 如何在 MySQL 存放 BLOB的資料 4httpwwwsapdborg 有關 SAP跟 MySQL相關合作的網站 書藉 1 Cooking with MySQL

Paul DuBois has selected sample recipes from the hundreds youll find in his book MySQL

Cookbook In this third and final series of excerpts showcasing these recipes learn how to

compute team standings how to calculate the differences between successive Dec 26

2002 2 Tips for Building Web Database Applications with PHP and MySQL by Hugh E Williams co-author of Web Database Applications with PHP amp MySQL 04042002

3 Managing and Using MySQL 2nd Edition By Tim King George Reese Randy Jay Yarger

4 MySQL Cookbook By Paul DuBoisPublisher OReillyPub Date October 2002

中文部份

78

1 httplinuxtncedutwtechdocmysqlmysql_docmanual_tochtml MySQL 中文手冊 2 httpchenshloxaedutwphpZ_1php PHP+MySQ程式研習設計網站 3 httplinuxtncedutwtechdocbanicdownhtml PHP 4 手冊 4 httpwwwtncedutwadmin_zonephp台南縣教育網網路中心有很多 Linux相關文件 5 httpdobtncedutw網站建置百寶箱有很多 PHP MySQL 相關範例程式 5 httpwwwdbworldcomtw資料庫專家電子雜誌介紹資料庫的重要觀念及名詞

79

附錄一 SQL Command 介紹

SQL (讀音ess-que-el) 是一種結構查詢語法SQL 使用於資料庫交流

傳遞相容於 ANSI (American National Standards Institute) 是一套標準的關聯

式資料庫語言 SQL 語言是執行更新或從資料系統獲取資料一般常見的關聯

資料庫系統都有提供 SQL 如 Oracle Sybase Microsoft SQL Server Access Ingres 等雖然大部份的資料庫都有提供 SQL 但也多提供了自已獨特的語

法造成了不相容的情形但標準基本的語法是相通的如Select Insert Update Delete Create and Drop 每一個系統都有支援

Table相關 Command

Create Table

關聯式資料庫包含有很多元件稱為資料表(tables) 把資料或訊息放在資

料表中 資料表是以不同的名稱做分別資料表由欄列所構成的二維陣列

欄包含欄位名資料型態 及其他可判斷的資訊列是由全部欄位構成一筆一

筆的紀錄 create table 語法用在建立一個新的資料表語法格式如下

create table tablename (column1 data type column2 data type column3 data type)

Format of create table if you were to use optional constraints

create table tablename (column1 data type [constraint] column2 data type [constraint] column3 data type [constraint]) [ ] = optional

Note You may have as many columns as youd like and the constraints are optional

80

Example

create table employee (first varchar(15) last varchar(20) age number(3) address varchar(30) city varchar(20) state varchar(20))

注意建立資料表格式要以括號把前後框住而最後以(分號)做結尾

欄位名不要超過 30個字元長而且不要使用 sql 的關鍵字(如 where select等)而在後面接是型態的宣告(如字串數字日期格式等)

資料型態是來描述欄位的方式如一個欄位Last_Name 是一個姓氏可以使用varchar (可變動長度字串) 資料型態

以下是幾個常見的資料庫型態 char(size) 固定長度字串最長為 255 位元 varchar(size) 變動長度字串最大字元數以 size 來指定 number(size) 數值格式可以是整數也可以是小數最大數字以 size 位數判

斷未指定小數位數由系統內定 date 日期格式 number(sized) 數值格式最大數字以 size 位數判斷d 為小數位數整數位

數為 size-d 位

有何限制當資料表被建立通常有一或數個欄位是要使用來做關聯的功

能 例如unique 限制(唯一值)兩筆記錄不可以相同的值 not null (非空值)該欄位一定要輸入資料不可是空的primary key (主鍵)是每一筆記錄識別的主要方式

Drop a table drop table 刪除資料表(其中的資料也會一併刪除)

drop table tablename

Example

81

drop table 和刪除全部資料是不同的刪除全部資料欄位名稱資訊等還會

存在但刪除資料表會把這一些也一併移除掉

如何查詢資料

Select 基本用法

select 語法是關連式資料庫最常用的部份可以取得你想要的資料這是一個

簡單的範例 select column1[column2etc] from tablename [where condition] [] = optional 在 select 之後所列欄位名則是要顯示的資料部份你可以一一列出各欄位

名或是以 (星號)來代表選擇全部的欄位 from 之後放資料表名稱 where 子句 (選項) 指定要過濾的條件符合者才會顯現 where 可使用的條件運算元 = 等於 gt 大於 lt 小於 gt= 大或等於 lt= 小或等於 ltgt 大相等 LIKE 相似 For example select first last city

82

from empinfo where first LIKE Er 以Er 為開頭的字串就符合要以單引號框住 Or you can specify select first last from empinfo where last LIKE s 最後一字為 S 就符合 select from empinfo where first = Eric 則表示 first name 一定要是 Eric 才可以 範例資料表empinfo 統計函數

MIN 傳回指定欄位最小值

MAX 傳回指定欄位最大值

SUM 傳回指定欄位總和

AVG 傳回指定欄位平均值

COUNT 傳回指定欄位的筆數

COUNT() 傳回資料庫中的總筆數

統計函數使用於資料表中的數值欄位配合 SELECT 語法使用 只用於總結特定單一欄位可以配合 GROUP BY 做篩選但也可以不使用 GROUP BY 語句For example

SELECT AVG(salary) FROM employee

83

傳回全部 salary 平均值

Another example

SELECT AVG(salary) FROM employee WHERE title = Programmer

傳回 salary 平均值條件為 employees 資料表中當 title 等於 Programmer

Example

SELECT Count() FROM employees

傳回 employees 資料表中紀錄總筆數

GROUP BY 語法 SELECT column1 SUM(column2) FROM list-of-tables GROUP BY column-list The GROUP BY 語句可以先以所列的欄位為條件分組排序在一起(可以多欄

位) example 要列出每一個 dept 中最高 salary 值 SELECT max(salary) dept FROM employee GROUP BY dept HAVING 語法

SELECT column1 SUM(column2) FROM list-of-tables GROUP BY column-list HAVING condition

HAVING 子句是 GROUP BY 的一部份用來過濾在 GROUP BY 所選出的資料功能如同 select 命令中 where 條件式一樣只是 HAVING 必需配合 GROUP BY 使用

我們以例子來說明我們要取得每一公司名及每一公司的薪水平均值輸入如下

84

SELECT dept avg(salary) FROM employee GROUP BY dept

但如果我們只列出薪資平均值超過 20000元的公司資料

SELECT dept avg(salary) FROM employee GROUP BY dept HAVING avg(salary) gt 20000

ORDER BY子句語法

SELECT column1 SUM(column2) FROM list-of-tables ORDER BY column-list [ASC | DESC]

[ ] =選項

ORDER BY是一個選項子句當你以排序方式來顯示資料(正向由小到大反向由大到小)以指定的欄位資料做排序

ASC = 正向- 預設值 DESC = 反向排序

For example

SELECT employee_id dept name age salary FROM employee_info WHERE dept = Sales ORDER BY salary

以上列出公司代號公司名銷售員人名年紀及薪資而條件是公司名為 Sales 顯示順序以薪資多少排序(由小到大為預設值)

如果要以多個欄位做排序要以逗號做分隔如下

SELECT employee_id dept name age salary FROM employee_info WHERE dept = Sales ORDER BY salary age DESC

85

結合條件及布林運算 SELECT column1 SUM(column2) FROM list-of-tables WHERE condition1 AND condition2 AND運算可以結兩個或以上的條件放在 WHERE子句中 兩者都要為真才

會顯示該筆記錄 OR 運算可以結兩個或以上敘述放在 WHERE子句中只要其中一個為直就

會顯示該筆記錄 For example SELECT employeeid firstname lastname title salary FROM employee_info WHERE salary gt= 5000000 AND title = Programmer 必需要薪資大於等於 50000而且職稱為 Programmer同時符合才會顯示該筆資料 以下以括號括住雖然不是必需的但如此比較容易讀 SELECT employeeid firstname lastname title salary FROM employee_info WHERE (salary gt= 5000000) AND (title = Programmer) 另外範例 SELECT firstname lastname title salary FROM employee_info WHERE (title = Sales) OR (title = Programmer) 條件為只要是 Sales 或 Programmer 職稱的就會被列出 IN and BETWEEN 子句

SELECT column1 SUM(column2) FROM list-of-tables WHERE column3 IN (list-of-values) SELECT column1 SUM(column2) FROM list-of-tables WHERE column3 BETWEEN value1 AND value2 IN 子句使用在列舉項目的使用上也就是分別測試是否符合所列的值 For example

86

SELECT employeeid lastname salary FROM employee_info WHERE lastname IN (Hernandez Jones Roberts Ruiz) 條件為姓氏(astname)要符合 Hernandez Jones Roberts or Ruiz 其中一個才會被傳回 IN運算元也可以使用 OR 的語法來取代如下結果相同 SELECT employeeid lastname salary FROM employee_info WHERE lastname = Hernandez OR lastname = Jones OR lastname = Roberts OR lastname = Ruiz 但使用 IN 句子比較短也比較易懂 你也可以使用 NOT IN 來去掉不要的記錄 BETWEEN 運算元使用在判斷是否存在兩個數值之間 For example SELECT employeeid age lastname salary FROM employee_info WHERE age BETWEEN 30 AND 40 傳回年紀 30歲到 40歲之間的資料(含 30及 40歲者) 相同的也可以使用以下語法來達到相同的結果 SELECT employeeid age lastname salary FROM employee_info WHERE age gt= 30 AND age lt= 40 你也可使用 NOT BETWEEN 來濾掉中間值的資料 數學運算 標準 ANSI SQL-92 提供以下運算

87

+ 加

- 減

餘數

餘數為除法後剩整數這不在標準的 ANSI SQL 中但大部份的資料庫都會支

援這運算元以下列出有用的函數雖不在 ANSI SQL-92 提供但一般資料庫

也會支援他們

ABS(x) 傳回 x 絕對值

SIGN(x) returns the sign of input x as -1 0 or 1 (negative zero or positive respectively)

MOD(xy) 餘數 - returns the integer remainder of x divided by y (同 xy)

FLOOR(x) 傳回小或等於 x 的最大整數值

CEILING(x) or CEIL(x)

傳回大或等於 x 的最小整數值

POWER(xy) x的 y 次方

ROUND(x) 把 x 四捨五入為整數

ROUND(xd) 四捨五入取到小數 d 位

SQRT(x) x 開平方

For example SELECT round(salary) firstname FROM employee_info 傳回薪資取到整數位

如何新增資料

insert 加入一筆新紀錄到資料表中 insert into tablename (first_columnlast_column) values (first_valuelast_value) [] = optional Example insert into employee

88

(first last age address city state) values (Luke Duke 45 2130 Boars Nest Hazard Co Georgia) Note 字串要以單引號住如string 數字框住也無妨 insert into 後面接資料表名稱再接以括號括住的欄位名在 values 後括號分別對映各欄位的值 以上的例子新增了一筆名(first) 為 Luke而住所(state) 為 Georgia 的資料

如何刪除資料

delete 可以刪除單筆或多筆紀錄 delete from tablename where columnname OPERATOR value [and|or column OPERATOR value] [ ] = optional Examples delete from employee Note 如果你沒有指定 where 子句那麼全部的紀錄都會被刪除 delete from employee where lastname = May delete from employee where firstname = Mike or firstname = Eric delete from 接著資料表名 再接著是條件式判斷沒有條件式則全部紀錄會

被刪除

如何更新資料

update 用來更新你所指定的記錄要和 WHERE 配合小心使用 語法 update tablename set columnname = newvalue[nextcolumn = newvalue2] where columnname OPERATOR value [and|or column OPERATOR value] [] = optional Examples

89

update phone_book set area_code = 623 where prefix = 979 update phone_book set last_name = Smith prefix=555 suffix=9292 where last_name = Jones update employee set age = age+1 where first_name=Mary and last_name=Williams

90

附錄二Replication

測試環境

RedHat 90 + MySQL 32358 MySQL資料庫路徑 varlibmysql MySQL設定檔 etcmycnf Master IP 1921680100 Slave IP 1921680200 請至下列網址下載最新MySQL 32358套件並利用rpm ndashUvh 更新 httpupdatesredhatcom9enosi386

圖 最新 MySQL 套件

測試架構圖

91

1921680100

1921680200Master Server

erveSlave S r

圖 測試架構圖

測試步驟

Master server 部份 Step1 確認 MasterSlave機器上所裝的 MySQL版本能進行

replication( 32329 or higher ) Step2 在 Master MySQL上開放一個帳號給 Slave mysql ndashu root ndashp mysqlgtGRANT FILE ON TO repl1921680200 IDENTIFIED BY lsquoabc123rsquo mysqlgtq 上面是 Master開放一個帳號 repl密碼 abc123給 IP1921680200有檔案處理

的權限 Step3 shutdown MySQL on the Master mysqladmin ndashu root ndashp shutdown Step4 備份 Master所有資料庫 tar ndashcvf tmpmysql-snapshottar varlibmysql 注意tar的時候MySQL是要在 stop情況下 在mysql (wwwmysqlcom) 網站的FAQ有不用shutdown的方法

92

Step5 在 master機器上修改etcmycnf 在[mysqld]區段內加入參數 log-bin server-id=這邊設定 server-id=1 sql-bin-update-same binlog-do-db=CRM只針對 CRM資料庫做紀錄 Step6 Restart MySQL on the master service mysqld start 此時因為有加入 log-bin 參數因此開始有 index產生了在varlibmysql目錄下

有index檔案紀錄資料庫的異動 log Slave server 部份 Step1 在 slave設定etcmycnf 在[mysqld]區段加入 master-host= master-user= master-password= master-port= server-id= 這邊設定 master-host=1921680100 master-user=repl master-password=abc123 master-port=3306 server-id=2 master-connect-retry=60預設重試間隔 60秒 replicate-do-db=CRM告訴 slave只做 CRM資料庫的更新 log-slave-updates Step2 將 master上的 mysql-snapshottar copy到 slave上 用 ftp傳到 slave的tmp Step3 解壓縮 Master資料庫至 Slave Server上 cd varlib tar xvf tmpmysql-snapshottar chown ndashR mysqlmysql mysql

93

chmod ndashR 770 mysql (視情況) Step4 Restart MySQL on the slave server 這時在varlibmysql目錄會出現 masterinfo此檔案紀錄了 Master MySQL server的資訊

狀況測試

One-way replication

1921680100

1921680200Master Server

erveSlave S r

圖 One-way replication架構圖 Step1 Master跟 Slave網路及服務都正常情況下由 Master端異動資料後 到 Slave端瀏覽資料檢視是否有進行 replication Step2 模擬 Slave Server 當機 可用在於 slave真的當機或是 Slave 不一定需要一直跟 master connect將Slave MySQL server shutdown由 Master端異動資料到 slave端瀏覽此時Slave應該沒有被 replication 更新然後再將 Slave端 MySQL server start起來

預設 60秒後 Slave會嘗試跟 Master要求進行 replication再去 Slave端檢視是否有更新資料

94

Step3 模擬 Master當機因為是設定 One-way replication一旦 Master Server Slave端沒有 Master的 source可以 download Two-way replication 基於 Master當機狀況於是發展雙向 Replication即 1921680100 ( Host A ) 1921680200 ( Host B )都分別擔任 MasterSlave身分

1921680100

1921680200er

Server B MasterSlave Server

Server A MasterSlave Serv

圖 Two-way replication架構圖 以下是針對兩台 MySQL伺服器進行雙向 Replication Step1觀念同單向 replication只是改成 Master也有 Slave身分 Slave也有Master的身分先分別在 Server AServer B 都去 grant一個進行 replication的身分 [A]mysqlgtGRANT FILE ON TO repl1921680200 IDENTIFIED BY lsquoabc123rsquo [B]mysqlgt GRANT FILE ON TO repl1921680100 IDENTIFIED BY lsquoabc123rsquo Step2做完單向 replication後stop Server Aserver B MySQL service此時 AB資料是一樣的

95

修改etcmycnf設定 範例 Server A [mysqld] datadir=varlibmysql socket=varlibmysqlmysqlsock server-id=1 log-bin sql-bin-update-same binlog-do-db=CRM master-host=1921680200 master-user=repl master-password=abc123 log-slave-updates master-connect-retry=60 replicate-do-db=CRM Server B [mysqld] datadir=varlibmysql socket=varlibmysqlmysqlsock server-id=2 log-bin sql-bin-update-same binlog-do-db=CRM master-host=1921680100 master-user=repl master-password=abc123 log-slave-updates master-connect-retry=60 replicate-do-db=CRM 分別 start Server AServer B MySQL後此時雙方都是 MasterSlave身分一旦哪一方資料異動就會通知對方來 replication-若 replication失效則必須將Server AServer B的masterinfo及index00x 都砍掉然後分別 restart MySQL server進行測試檢視成果 實務上通常如果需要做Two-way replication通常會搭配Virtual Server使用

96

在前端架設一台Virtual Server不過此部份不在此份SOP討論範圍內有興趣

的讀者可參考 httpwwwlinuxvirtualserverorg 網站

1921680100 1921680200

Host A MasterSlave Server

Host B MasterSlave Server

Virtual Host

圖 Virtual Server + Two-way replication 架構圖

97

圖 High Availability Linux Virtual Server架構圖

98

  • COSA-SOP-03-006
  • 第一章 簡介
    • 11適用對象 (Audience)
    • 12 MySQL本身
    • 13 MySQL 40版跟50版重大的改進功能
    • 14 各家資料庫軟體比較
      • 第二章 前置需求
      • 第三章 安裝
        • 31 MySQL安裝
        • 32 phpMyAdmin安裝
        • 33 升級及注意事項
          • 第四章 MySQL管理
            • 41 Webmin 管理介面
            • 42 phpMyAdmin 的操作介面
            • 43管理指令介紹
              • 431 利用mysqladmin設定root的密碼
                  • 第五章 實用範例
                    • 51 任務一Web Base客戶通訊錄
                    • 52 任務二Web Base群組軟體 ( twig )
                      • 第六章 維護及更新程序
                        • 61 日常維護
                        • 62 更新程序
                        • 63 備份重要檔案
                        • 64 離線備份與還原
                        • 65 線上備份與還原
                          • 第七章 問題與解答
                          • 第八章 參考資料
                          • 附錄一 SQL Command 介紹
                          • 附錄二Replication
Page 8: DataBase Server Standard Operation Procedureebooks.lib.ntu.edu.tw/1_file/oss/63/93doc4-5.pdf · 業務的公司帶來了不少壓力,譬如微軟,甲骨文 ... 外的錢用在第三方的資料庫產品上,譬如就可以不用再購買甲骨文公司

加強執行效率 更好的國際語系支援 提供可用性

14 各家資料庫軟體比較

目前市面上較被廣為使用資料庫除了 MySQL之外尚有下列幾種

1 MS SQL Server 2000 2 Oracle 8i 3 IBM DB2 4 Informix

過去幾年來在總值 120億美元的資料庫市場上如果廠商想要誇讚自家的

產品那就一定得要有強大的資料庫支援最嚴苛的任務才站得上檯面不過

到了今天似乎光是這樣並不夠客戶除了要求足以負擔嚴苛的任務之外還希

望擁有聰明又便宜的資料庫 Meta Group的分析師 Charlie Garry表示 ( 2003 年 5 月)MySQL的商業

模式是以開放原始碼為基礎以便讓客戶盡快接受 MySQLGarry指出MySQL甚至適合用在甲骨文IBM微軟等大廠爭相搶食的企業資料中心

Information Resources的資訊長 Marshall Gibbs就表示他們沒有任何品

牌的偏好只要「功能效能價格的最佳組合」 由研究近兩年來資料庫客戶

愈來愈注重總體成本(圖 1-1)

8

圖 1-1 資料庫優先性

整體擁有成本 大致說來MySQL是免費的MySQL需要付費的規定只限於下列兩種情

形 1 以 Embedded的方式使用 MySQL 2 使用 MySQL的商業用途軟體

且其授權費用一台 MySQL Pro License只需美金 $440比起其他任何資料庫軟體來得容易負擔多了加上其易於管理的特性著實可大大降低企業資料

庫的整體擁有成本 擴充性

MySQL同時提供高度多樣性能夠提供給很多不同的使用者介面包括命

令列操作網頁瀏覽器以及各式各樣的程式語言介面例如JavaC++PerlPHP及 PhythonMySQL可用 UnixWindows以及 OS2hellip等平台因此它可以用個人電腦或是伺服器上 性能 事實上大部份的網站的開發者都認為 MySQL是目前市面跑得最快的資料

9

庫對資料庫的最佳化主要在於你對他的設定和資料庫結構的設計如果你的

資料庫結構設計得非常差你的存取速度還是會受到影響而變得比較慢

10

第二章 前置需求

在安裝 MySQL之前請確定 Apache及 MySQL亦巳安裝相關步驟請參考

Apache SOP安裝 Apache及 PHP相關章節

11

第三章 安裝

31 MySQL安裝

在 RedHat 90上安裝 MySQL是件很容易的事因為 RedHat 90提供了一

個很方便的 GUI套件管理工具「redhat-config-packages」各位只要把 RedHat 90第一片光碟放入並以 root的身份登入系統鍵入 redhat-config-packages勾選「SQL資料庫伺服器」即可然後按「更新」如果遇到任何相依性問題

系統會提示您更換光碟片 ( 圖 3-1 ~ 3-3 ) Step 1 執行 redhat-config-packes

圖 3-1

Step 2 選擇資料伺服器

12

圖 3-2

Step 3檢查是否安裝成功 待安裝後您可以用利用「rpm -qa | grpe ^mysql」檢查是否安裝成功

圖 3-3

啟動 MySQL ( Command Mode )馬上啟動 MySQL的指令為「service mysqld start」如果您希望一開機就自動啟動 MySQL請執行「chkconfig mysqld on」

13

圖 3-4

啟動 MySQL ( WebMin 介面 ) 我們也可以利用WebMin 來啟動 MySQL步驟如下 Step 1登入Webmin

圖 3-5 登入WebMin

Step 2 選擇伺服器

14

圖 3-6 伺服器畫面

Step 2 選擇 MySQL資料庫伺服器

圖 3-7 伺服器畫面

15

Step 3 啟動 MySQL資料庫伺服器

圖 3-8 啟動 MySQL

更改資料庫管理者密碼

成功啟動 MySQL後因為資料庫管理者預設沒有密碼建議使用前更改系

統管理者密碼請輸入下列指令

mysqladmin ndashu root ndashh cosaexamplecom password lsquo1234rsquo -u 表示使用者帳號root 為 MySQL預設的管理帳號

-h 表示 MySQL主機的主機名稱也可使用 IP Address password 表示使用者的密碼因為字串請使用單引號將密碼括起來

圖 3-9 修改 MySQL 的密碼

16

32 phpMyAdmin安裝

本書除了會介紹利用當今 Linux上最紅的整合管理工具Webmin 來管理

MySQL外還會為各位介紹專門管理 MySQL的工具 phpMyAdmin phpMyAdmin是免費的 PHP原始程式碼的Web網站可用來管理整個

MySQL伺服器這是一套Web介面的 MySQL管理程式支援中文的使用者介

面 phpMyAdmin只需透過瀏覽器就可管理 MySQL伺服器換句話說不論

MySQL是安裝在 Linux或是Windows 作業系統都可以使用相同步驟在

MySQL上建立資料庫(Database)資料表(Table)和編輯紀錄(Record) Step 1 下載phpMyAdmin ( httpwwwphpmyadminnet )選擇最櫎新穩定的版

本 253

圖 3-10 httpwwwphpmyadminnet

17

圖 3-11 下載 phpMyAdmin-253-phptarbz2

Step 2 將 phpMyAdmin-253-phptarbz2收至 tmp 並執行下列指令將其解壓

縮至varwww tar jxvf phpMyAdmin-253-phptarbz ndashC varwwwhtml

圖 3-12 解壓縮安裝 phpMyadmin-253

Step 3 為了操作方便起見建立 Soft link ln ndashs phpMyAdmin-253 phpMyAdmin

圖 3-13 修改 phpMyadmin 設定檔 configincphp

18

Step 4 修改 phpMyadmin 設定檔 configincphp gedit varwwwhtmlphpMyAdminconfigincphp

圖 3-14 configincphp設定檔

Step 5 設定顯示行號以方便修改 configincphp 設定檔

19

圖 3-15 顯示行號

Step 6 修改下列設定 第 39 行 設定 phpMyAdmin的 URL 第 69 行 MySQL Server 的 ip 第 80 行 利用何帳號存取 MySQL 第 81 行 如果 root有設定 password此處即填入 root的 password

30 In most cases you can leave this variable empty as the correct value

31 will be detected automatically However we recommend that you do

32 test to see that the auto-detection code works in your system A good

33 test is to browse a table then edit a row and save it There will be

34 an error message if phpMyAdmin cannot auto-detect the correct value

35

36 If the auto-detection code does work properly you can set to TRUE the

37 $cfg[PmaAbsoluteUri_DisableWarning] variable below

38

39 $cfg[PmaAbsoluteUri] = httpossccosaorgtwphpMyAdmin

hellip

20

hellip

69 $cfg[Servers][$i][host] = localhost MySQL hostname or IP address hellip 80 $cfg[Servers][$i][user] = root MySQL user

81 $cfg[Servers][$i][password] = 1234 MySQL password (only needed

圖 3-16 修改 configincphp

21

圖 3-17 修改 configincphp

圖 3-18 修改 configincphp p

Step 7 設定語系

22

圖 3-19 設定語系

圖 3-20 執行 phpMyAdmin

23

33 升級及注意事項

RedHat 90附的 MySQL版本為 323 MySQL所釋出最新穩定版本為

40若是您不想用系統預附的 323請先利用下列移除之前 323的版本

rpm ndashe mysql-devel rpm ndashe mysql-server rpm ndashe mysql --nodeps 然後到下列網址下載您所想要的版本進行安裝在這裏我們用 4014版為例 Step 1 下載相關套件( httpwwwmysqlcomdownloadsmysql-40html )

圖 3-21 Download MySQL 4014 相關 RPM Step 2 利用 rpm 指令安裝

24

圖 3-22 Install MySQL 4014 相關 RPM

圖 3-23 Install MySQL 4014 相關 RPM

Step 3 啟動 MySQL

25

圖 3-24 啟動 MySQL 4014 並修改密碼

26

第四章 MySQL管理

本章將我們介紹利用WebminphpAdminCommand的方式建立一個名為

CONTACT的資料庫內有一個 address的 Table作為我們客戶通訊錄程式使

用的資料庫

41 Webmin 管理介面

412建立資料庫

Step 1 登入Webmin

圖 4-1 登入WebMin

Step 2 點選伺服器

27

圖 4-2 伺服器畫面

Step 3 點選 MySQL資料庫伺服器

圖 4-3 MySQL資料庫伺服器

28

Step 4 建立一個新的資料庫

圖 4-4 建立 MySQL資料庫

Step 5 建立名為 CONTACT的資料庫

29

圖 4-5 指定資料庫名稱

412 建立資料表

假設我們要建立一個名為 address的 Table其結構如下 欄位名稱 資料型態 長度 說明 id INT (自動編號) 連絡人編號 name varchar文字 20 連絡人姓名 tel Varchar文字 15 連絡人電話 Step 1 選擇 CONTACT資料庫

30

圖 4-6 選擇資料庫

Step 2 指定欄位數目

31

圖 4-7 設定欄位數目

Step 3設定表格欄位屬性

圖 3-8 設定表格欄位屬性

Step 4建立表格資料

32

圖 4-9 建立表格資料

圖 4-10 檢視資料

33

圖 4-11 新增資料

圖 4-12

34

圖 4-13

413 使用者管理

接下來我們要利用Webmin 來建立資料庫使用者並給予某些權限 Step1建立使用者

35

圖 4-14 選擇使用者權限

圖 4-15

36

Step2 賦予權限

圖 4-16

Step3 權限列表

37

圖 4-17

38

42 phpMyAdmin 的操作介面

421建立資料庫

Step 填入資料庫名稱並按「建立」

圖 4-18建立資料庫

422 建立資料表

Step1 填入資料表名稱並指定欄位數量 執行

39

圖 4-19填入資料表名稱並指定欄位數量

Step2 設定欄位屬性

圖 4-20設定欄位屬性

40

Step3 phpMyAdmin會產生相關的 SQL Command

圖 4-21 資料表結構及相關 SQL Command

Step4新增 Record

41

圖 4-22

圖 4-23

42

圖 4-24

圖 4-25

43

423使用者管理

Step1建立使用者

圖 4-26

44

圖 4-27

Step2 給予權限

圖 4-28

Step3權限列表

45

圖 4-29

43管理指令介紹

431 利用 mysqladmin設定 root的密碼

當您在Windows 或 Linux 中安裝好 MySQL後系統會自動幫您建立兩個

帳分別是 root 和 匿名者MySQL的 root 跟 Linux 最高權限使用者 root無關MySQL的 root使用者相當於 MS SQL 中的 sa 帳號擁有最高的 Database管理權限但系統預設 MySQL的 root 是不需要密碼所以通常我們一安裝

MySQL後首要任務便是修改 root的密碼 我們可以利用 mysqladmin工具或是直接修改 MySQL內部資料庫的使用者資

料 mysqladmin ndashu root ndashh cosaexamplecom password lsquo1234rsquo

46

-u 表示使用者帳號root 為 MySQL預設的管理帳號

-h 表示 MySQL主機的主機名稱也可使用 IP Address password 表示使用者的密碼因為字串請使用單引號將密碼括起來 密碼設定完成之後還是可以利用 mysqladmin修改密碼但是你必須提供目前的密碼

432 連線 MySQL

mysql -uroot -p密碼 (-p和密碼之間不能有空白) 或 mysql -uroot -p (此方式會在進入後要求密碼) [rootossc phpMyAdmin] mysql -u root -p1234

Welcome to the MySQL monitor Commands end with or g

Your MySQL connection id is 25 to server version 32354

Type help or h for help Type c to clear the buffer

mysqlgt show databases

+----------+

| Database |

+----------+

| mysql |

| test |

+----------+

2 rows in set (000 sec)

mysqlgt exit

Bye

[rootossc phpMyAdmin]

433 建立資料庫

可利用 mysqladmin指令建立 CONTACT資料庫 mysqladmin -u root -p1234 create CONTACT

47

或是利用 mysql指令 [rootossc bluepage] mysql -u root -p1234 Welcome to the MySQL monitor Commands end with or g Your MySQL connection id is 1057 to server version 32354 Type help or h for help Type c to clear the buffer mysqlgt create database CONTACT Query OK 1 row affected (000 sec) mysqlgt show databases +----------+ | Database | +----------+ | CONTACT | | address | | hello | | mysql | | nuke | | test | +----------+ 6 rows in set (000 sec) mysqlgt exit

434 建立資料表

編寫 adresssql內容如下 -- Table structure for table address CREATE TABLE address ( id int(11) NOT NULL auto_increment name varchar(20) NOT NULL default tel varchar(15) NOT NULL default PRIMARY KEY (id) ) TYPE=MyISAM

48

-- Dumping data for table address INSERT INTO address VALUES (1林小明0800016888) INSERT INTO address VALUES (2黃大雄0800016888) INSERT INTO address VALUES (3劉小芬0800024365) 然後執行此 sql script mysql -u root -p1234 CONTACT lt addresssql 或是利 mysql command [rootossc bluepage] mysql -u root -p1234 Welcome to the MySQL monitor Commands end with or g Your MySQL connection id is 1090 to server version 32354 Type help or h for help Type c to clear the buffer mysqlgt use CONTACT Database changed Database changed mysqlgt CREATE TABLE address ( -gt id int(11) NOT NULL auto_increment -gt name varchar(20) NOT NULL default -gt tel varchar(15) NOT NULL default -gt PRIMARY KEY (id) -gt ) TYPE=MyISAM Query OK 0 rows affected (000 sec) mysqlgt INSERT INTO address VALUES (1林小明0800016888) Query OK 1 row affected (000 sec) mysqlgt INSERT INTO address VALUES (2黃大雄0800016888) Query OK 1 row affected (000 sec) mysqlgt INSERT INTO address VALUES (3劉小芬0800024365) Query OK 1 row affected (000 sec) mysqlgt exit Bye

49

第五章 實用範例

51 任務一Web Base客戶通訊錄

任職於開放科技公司的林小明前些日子在最符合成本效益的條件下快

速地完成公司網站的建置老闆因此對小明讚譽有加最近因為公司存放客戶資

料的 SQL Server主機屢遭病毒攻擊加上作業系統本身的問題當機次數頻繁

老闆希望能儘快把公司的客戶通訊錄程式移轉到較穩定的環境上因為此客戶通

訊錄程式最主要給內部人員使用所以介面美觀並不特別要求只求穩定且能快

速得到查詢結果老闆希望在短時間先看到程式的雛型並鍵入資料對其效率

及穩定性進行測試因為上次小明表現突出所以這次不可能的任務自然又落到

小明身上 小明想來想去既然要快速又穩定他而且又不希望所有人都得安裝 Client

程式於是小明決定)捨棄他的舊愛「Delphi+MS SQL」投向新歡「Apache + MySQL + PHP」利用此架構來設計一個簡單實用的Web Base客戶通訊錄程式

511 Web Base客戶通訊錄架構

此程式需要建立 CONTACT的資料庫並建立 adress Tables其結構如下表建立步驟請參考第三章 欄位名稱 資料型態 長度 說明 id INT (自動編號) 連絡人編號 name varchar文字 20 連絡人姓名 tel Varchar文字 15 連絡人電話 Web Base通訊錄共有下列幾個檔案功能如下表

檔案名稱 說明 Indexhtml Web Base通訊錄首頁 addphp 新增連絡人的 php程式 searchphp 尋找連絡人的 php程式 editphp 具有更新及刪除功能的 php程式

50

我們將這些檔案放至varwwwhtmlbluepage (預設無 bluepage目錄)

512 Web Base通訊錄測試

httpwwwopencombluepage 新增資料

圖 5-1 新增連絡人

圖 5-2 填入資料

51

圖 5-3 新增成功

搜尋及異動資料

圖 5-4 搜尋通訊錄

52

圖 5-5 編輯資料

圖 5-6 更新資料

513 程式內容及說明

lt-- 程式範例indexhtml--gt lthtmlgt ltheadgtlttitlegt通訊錄lttitlegtltheadgt ltbodygt ltcentergt

53

lth2gt通訊錄lth2gtlthrgt lta href=indexhtmlgt通訊錄ltagt | lta href=addphpgt新增連絡人ltagt | lta href=searchphpgt搜尋通訊錄ltagt ltcentergt ltbodygt lthtmlgt lt-- 程式範例addphp --gt lthtmlgt ltheadgtlttitlegt新增連絡人lttitlegtltheadgt ltbodygt ltcentergtlth2gt新增連絡人lth2gtltcentergtlthrgt lt 取得欄位資料 if (isset($_POST[Name]) ampamp isset($_POST[Tel]) ) $name = $_POST[Name] $tel = $_POST[Tel] 檢查是否有輸入欄位資料 if ($name = ampamp $tel = ) 建立 SQL字串 $sql = INSERT INTO address (name tel) values( $sql= $name $tel) 建立 MySQL 連結 $link = mysql_connect(localhostroot1234) 選擇資料庫 mysql_select_db(CONTACT) 執行 SQL指令 mysql_query($sql) mysql_close($link) echo ltfont color=redgt新增連絡人成功ltfontgtltbrgt gt ltform action=addphp method=postgt lttable border=0 width=300gt lttrgtlttdgt姓名 lttdgt

54

lttdgtltinput type=text name=Name size=20 maxlength=10gtlttdgtlttrgt lttrgtlttdgt電話 lttdgt lttdgtltinput type=text name=Tel size=20 maxlength=20gtlttdgtlttrgt lttrgtlttd colspan=2 align=centergt ltinput type=submit value=新增連絡人gtlttdgtlttrgt lttablegt ltformgt ltbrgtlta href=indexhtmlgt通訊錄ltagt | lta href=addphpgt新增連絡人ltagt | lta href=searchphpgt搜尋通訊錄ltagt ltbodygt lthtmlgt

lt-- 程式範例searchphp --gt lthtmlgt ltheadgtlttitlegt搜尋通訊錄lttitlegtltheadgt ltbodygt ltcentergtlth2gt搜尋通訊錄lth2gtlthrgt lt if (isset($_POST[Search])) 建立資料庫連結並選定資料庫 $link = mysql_connect(localhostroot1234) mysql_select_db(CONTACT) 建立基本的 SQL字串 $sql = SELECT FROM address 檢查是否輸入姓名 if (chop($_POST[Name]) = ) $name = name LIKE $_POST[Name] else $name = 檢查是否輸入電話號碼 if (chop($_POST[Tel]) = ) $tel = tel LIKE $_POST[Tel] else $tel =

55

if條件組合 SQL字串 if (chop($name) = ampamp chop($tel) = ) $sql= WHERE $name AND $tel elseif (chop($name) = ) 只有姓名 $sql = WHERE $name elseif (chop($tel) = ) 只有電話號碼 $sql = WHERE $tel $sql= ORDER BY name 最後加上排序 $result = mysql_query($sql) 取得欄位數 $total_fields = mysql_num_fields($result) echo lttable border=1gt echo lttrgtlttdgt編號lttdgtlttdgt姓名lttdgtlttdgt電話lttdgtlttd colspan=2gt功能選項lttdgtlttrgt 表格顯示查詢結果 while ($rows = mysql_fetch_array($result MYSQL_NUM)) echo lttrgt for ($i = 0 $i lt $total_fields $i++) echo lttdgt$rows[$i]lttdgt echo lttdgtlta href=editphpaction=editampid= echo $rows[0]gtltbgt編輯ltbgtlttdgt echo lttdgtlta href=editphpaction=delampid= echo $rows[0]gtltbgt刪除ltbgtlttdgt echo lttrgt echo lttablegtlthrgt mysql_free_result($result) mysql_close($link) gt ltcentergt ltform action=searchphp method=postgt lttable border=0 width=450gt lttrgtlttdgt搜尋姓名 lttdgt lttdgtltinput type=text name=Name size=10 maxlength=20gtlttdgtlttrgt lttrgtlttdgt搜尋電話 lttdgt lttdgtltinput type=text name=Tel

56

size=20 maxlength=20gtlttdgtlttrgt lttrgtlttd colspan=2 align=centergt ltinput type=submit name=Search value=搜尋gtlttdgtlttrgt lttablegt ltformgt ltbrgtlta href=indexhtmlgt通訊錄ltagt | lta href=addphpgt新增連絡人ltagt | lta href=searchphpgt搜尋通訊錄ltagt ltbodygt lthtmlgt

lt ob_start() gt lt-- 程式範例editphp --gt lthtmlgt ltheadgtlttitlegt編輯通訊錄lttitlegtltheadgt ltbodygt lt 取得 URL 參數 $id = $_GET[id] $action = $_GET[action] 建立資料庫連結 $link = mysql_connect(localhostroot1234) mysql_select_db(CONTACT) 選擇資料庫 執行的操作 switch ($action) case update 更新 取得欄位資料 $name = $_POST[Name] $tel = $_POST[Tel] $sql = UPDATE address SET name=$name tel=$tel WHERE id=$id mysql_query($sql) 執行 SQL指令 mysql_close($link) header(Location searchphp) 轉向到 serachphp break case del 刪除 $sql = DELETE FROM address WHERE id=$id

57

mysql_query($sql) 執行 SQL指令 mysql_close($link) header(Location searchphp) 轉向到 serachphp break case edit 編輯 $sql = SELECT FROM address WHERE id=$id $result = mysql_query($sql) 執行 SQL指令 $row = mysql_fetch_row($result) 取回記錄 $name = $row[1] 取得欄位 name $tel = $row[2] 取得欄位 tel mysql_close($link) 顯示編輯表單 gt ltcentergtlth2gt更新通訊錄lth2gtltcentergtlthrgt ltform action=editphpaction=updateampid=lt echo $id gt method=postgt lttable border=0 width=300gt lttrgtlttdgt姓名 lttdgt lttdgtltinput type=text name=Name size=20 maxlength=10 value=lt echo $name gtgtlttdgtlttrgt lttrgtlttdgt電話 lttdgt lttdgtltinput type=text name=Tel size=20 maxlength=20 value=lt echo $tel gtgtlttdgtlttrgt lttrgtlttd colspan=2 align=centergt ltinput type=submit value=更新連絡人gtlttdgtlttrgt lttablegt ltformgt ltbrgtlta href=indexhtmlgt通訊錄ltagt | lta href=addphpgt新增連絡人ltagt | lta href=searchphpgt搜尋通訊錄ltagt lt break gt ltbodygt lthtmlgt

58

52 任務二Web Base群組軟體 ( twig )

順利完成Web Base客戶通訊錄程式測試一段時間後「Apache + MySQL + PHP」架構的穩定與快速巳深得老闆與公司所有同事的認同隨著公司業績蒸

蒸日上人員組織編罝愈來愈龐大跨部門的會議愈來愈多業務員每日排滿拜

訪客戶的行程跟客戶的 Email的往來也愈來愈頻繁 愈來愈多部門的同事希望公司能建置一套群組軟體提供 web mail可讓業

務人員方便收發 mail還有連絡人議事日程待辦工作書簽等功能讓整個

公司運作及個人時間管理更有效率

老闆問小明對這些需求有什麼看法小明認為如果這些功能完全由程式部

門開發必定曠日費時而且耗費公司資源小明在網路尋找是否有提供這些功能

的Free Software皇天不負苦心人小明發現了TWIG (The Web Information Gateway) httptwigscrewdrivernet這個群組軟體它在 Web 上整合郵件新聞聯絡人議事日程工作序書簽等功能非常符合公司的需求 Step 1 下載 twig-277targz 下載網址 httptwigscrewdrivernetdownloadphp3

Step 2 解開 twig-277targz tar -xzvf twig-277targz

59

Step 3 執行安裝動作安裝到 varwwwhtmltwig 目錄 cd twig-277 twig-install varwwwhtmltwig

Step 4 建立 MySQL 資料庫(twig)及各資料表

cd setup mysql -u root -p1234 mysqlgt create database twig Query OK 1 row affected (001 sec) mysqlgt quit mysql -u root ndashp1234 twiglt twigtablemysql

Step 5 修改 configincphp3 參數設定 vi varwwwhtmltwigconfigconfigincphp3 $config[fromdomain] = opencom 網域 $config[language] = chinesebig5 中文訊息 $config[imap_port] = 143notls

60

Step 6 修改連結 MySQL 的帳號密碼 vi varwwwhtmltwigconfigdbconfigincphp3 $dbconfig[sqlusername] = root username $dbconfig[sqlpassword] = 1234 password

Step 7 其他設定檔

vi etchttpdconfhttpdconf 加入 AddType applicationx-httpd-php php3 在 DirectoryIndex最後加入 indexphp3 DirectoryIndex indexhtml indexhtmlvar indexphp3 在 AddDefaultCharset ISO-8859-1加上 AddDefaultCharset ISO-8859-1

vi etcphpini register_globals = On service httpd restart Step 8 sendmail 設定 vi etcmailsendmailcf在 264 行前面加上並重新啟動 sendmail「service snedmail restart」 262 SMTP daemon options 263 264 O DaemonPortOptions=Port=smtpAddr=127001 Name=MTA 265 266 SMTP client options 267 O ClientPortOptions=Family=inet Address=00

61

Step 9 檢查設定有無錯誤 http主機名稱twigtestphp3

62

Step 10 登入 twig ( http主機名稱twig)

63

第六章 維護及更新程序

61 日常維護

系統管理員最好定期以 root 身份登入看看信件在 RedHat Linux 中有一支 logwatch 程式會定時去分析 log file如果發現異常便會發信給 root除此之外筆者建議讀者平時就檢查 MySQL log file ( varlogmysqldlog)是否有異常情形

62 更新程序

讀者可至httprpmfindnet 尋找MySQL相關套件至於升級的相關步驟請參

考Linux OS SOP 第 54節

63 備份重要檔案

預設 MySQL 的 DB 檔案是存在 varlibmysql 內以 DB名稱為目錄目錄

內就是該 DB 的所有資料通常得定期備份還有 MySQL的設定檔 etcmycnf也別忘了一起備份

64 離線備份與還原

641 離線備份

預設 MySQL 的 DB 檔案是存在 varlibmysql 內以 DB 名稱為目錄目錄內

就是該 DB 的所有資料像 CRM 這個 DB就是存在 varlibmysqlCRM 內在備份前因為怕資料尚未完全寫入磁碟而且 MySQL 會 Lock 在使用的 DB 檔案所以應該是要先把 MySQL 先 Shutdown 一下整個備份的程序可以下像下面的指令去完成 cd varlibmysql

64

service mysqld stop tar cvfz CRM_db_20030905tgz CRM service mysqld start 對這樣就可以了 不過要注意的是怕 DB 內每個 Tables 間的資料有關關

聯性所以最好是把整個 DB 一次備起來單獨只備哪個 Tables 的檔案以後回存時怕會有資料關聯不一致的問題

642 離線還原

DB 發生錯誤而要回存時其實也不難先找出最近一次完整正常的備份先把現在錯誤的網頁或 DB 先更名或 tar 起來再把好的備份給解開回原來目錄位

置就行了需要注意的是 MySQL 服務最好也是要先停止回存完成後再啟動服務回存 DB 的整個程序可能像下面 cd varlibmysql service mysqldstop mv CRM CRM_OLD tar xvfz CRM_db_20030905tg service mysqld start

65 線上備份與還原

651 線上備份

使用像上面的檔案方式備份是個不錯的方法它最少可以保持該主機某個時間點的完整檔案備份但還是有一些問題需要考慮到有些主機就不只建立一個 DB 而已總不能為了備份某個 DB 而把整個 MySQL 服務停止備份檔案的方式回存在原主機上一定適用但假如 MySQL 版本升級或是在那天該網頁空間需遷機移機到別的主機時那就沒人敢保證備出來的資料檔可以用所以我們可以考慮另一種備份的方式是使用 MySQL 本身提供的功能 MySQL Data Dump指令是 mysqldump

65

使用 MySQL 的 Dump 功能可以把 DB 的結構資料或結構加資料 Dump 成文字檔 mysqldump 指令提供的彈性很大你可以選擇把整個 DB Dump 成一個檔或是每個 Table 為一個檔甚至是把結構檔和資料分開儲存都

可以 mysqladmin -uroot -p flush-logs mysqldump CRM -uroot -p --opt gt CRM_20030905sql (CRM 是 DB 名稱 opt 是一個使用完整 Dump 參數) 假如只是要單獨 Dump 某個 Table 時只要在上面的指令後轉出符號 gt 前加個 Table 名稱就可以如只要 phpbb2_users 這個 Table 的 Dump 時只要下 mysqldump CRM -uroot -p --opt CUSTOMER gt CRM_CUSTOMER_20030905sql

652 線上還原

若要回存整個資料庫只需將壓縮的備份檔還原成 Dump 的檔案再用下面的指令回存 mysql CRM -uroot -p lt CRM_20030905sql 這邊需注意的是若建立備份時是以--opt或--add-drop-table為參數時回存的 動作是先將舊的 Table 先刪除重建 Table 的結構後再把 Data 匯入所以回存後所有的資料會回到你當時備份那個時間點因此在回存資料時可以考慮把現有錯誤或不完整的 DB 先備份一份下來以備不時之需或是拿來比對錯誤的地

方在那裡當然你也可以把資料回存到另一個測試用的 DB 內只要把上面指令

的 DB 名稱改成你的測試用 DB 名稱即可 使用這種回存方式 MySQL 服務不需停止也不會動到其他正在使用的 DB 在一些提供 MySQL 服務的虛擬主機可用這種方式作你自己的 DB 備份及回存

66

另外假如你是系統重建或是移機時切需在新的 MySQL 內新建一個空白 DB 後才行作回存的工作你可以用下面的指令建立 mysql -uroot -p -e CREATE DATABASE CRM (上面的 CRM是你要新建的 DB 名稱) 另一種作法先用 mysql 指令進入 mysql client console 然後再用 CREATE DATABASE CRM 這樣就行了記得尾端要加個 符號該行指令才會執行

67

第七章 問題與解答

Q1RedHat 90預附的 MySQL到底有無支援 Transcation機制 Ans MySQL自 32334a之後的 MySQL-Max版本加入 InnoDB的資料庫類型透過

InnoDBMySQL同樣可以進行 COMMIT與 ROLLRACK的動作RedHat 90預附的 MySQL為 32354a-11巳支援 InnoDB的資料庫類型不過必須做以

下設定 1cp usrsharedocmysql-server-32354amy-mediumcnf to etcmycnf 2 vi etcmycnf 將以下設定前的拿掉 innodb_data_home_dir = varlibmysql innodb_data_file_path = ibdata110Mautoextend innodb_log_group_home_dir = varlibmysql innodb_log_arch_dir = varlibmysql 3service mysqld restart 如此一來各位在建立Table時便可指定Table Type為 innodb ( ex create table with type=innodb ) Q2如何解決 php+mysql 許功蓋等字變亂的問題 Ans 方法一 【確定 MySQL 預設的字元集】 1 打開 WinMySQLadmin 管理畫面(在視窗右下角狀態列紅綠燈圖示中按滑鼠

右鍵點選 Show me 選項) 2 點選管理畫面中 [Variables] 標籤選項其中 character_set變數就是您預設

字元集的變數其預設是 latin1 字元集(我們要將他改回 big5)而 chatacters_set 變數則是 MySQL 可以支援哪些字元集 【修改預設字元集變數 character_set 】 1 請點選管理畫面中 [myini Setup] 標籤選項設定 myini 2 按一下 [Pick-up and Edit myini values] 按鈕以便編輯目前的 myini 設定 3 在 [mysqld] 設定區塊底下新增一行 default-character-set = big5 變數設

68

定 4 新增一個 [client] 設定區塊並加入第三步驟的變數設定(游標往下移到空白處新增兩行 [client] 和 default-character-set=big5) 5 按一下畫面左下方 [Save Modification] 按鈕儲存設定 6 重新啟動 MySQL 或 Windows 方法二 Server端注意事項 phpini 中有關的設定為(預設值) Magic quotes for incoming GETPOSTCookie data magic_quotes_gpc = On Use Sybase-style magic quotes (escape with instead of ) magic_quotes_sybase = Off Client端注意事項 1中文資料送進 mysql 前請用 addslashes($str) 處理 2處理後送進 mysql 時請用 括起來並在參數後留一個空白如 $sql = UPDATE ezf_table set tablename=$tname tableend=$endtime table inguser=$tguser tableingid=$tguserid tableallnumber=$tnumber tableloca l=$tablelocal tableanyone=$tableopen tabletext=$ttext WHERE tableid=$t ableid tablename=$tname c 取出時請用 stripslashes($str) Q3MySQL root 密碼忘了該怎麼辦 Ans 1先停掉 mysql etcrcdinitdmysql stop 2以--skip-grant-table 的參數啟動 mysql safe_mysql --skip-grant-tableamp 3 更改 root 密碼 mysql mysql mysqlgt UPDATE user SET password=password(newpassword)

69

WHERE user=root mysqlgt FLUSH PRIVILEGES mysqlgt exit 4停掉 mysql再重跑 mysqladmin -uroot -p shutdown Enter password 輸入新設定的密碼 etcrcdinitdmysql start

Q4NULL值問題

Ans

NULL值的概念是造成 SQL的新手的混淆的普遍原因他們經常認為 NULL是和一個空字符串的一樣的東西不是這樣的例如下列語句是完全不同的

mysqlgt INSERT INTO my_table (phone) VALUES (NULL)

mysqlgt INSERT INTO my_table (phone) VALUES ()

兩個語句把值插入到 phone 列但是第一個插入一個 NULL值而第二個插入一個空字符串第一個的含義可以認為是ldquo電話號碼不知道而第二個則可意味

著ldquo她沒有電話

在 SQL中NULL值在于任何其他值甚至 NULL值比較時總是假的(FALSE)包含 NULL的一個表達式總是產生一個 NULL值除非在包含在表達式中的運算符和函數的文檔中指出在下列例子所有的列返回 NULL

mysqlgt SELECT NULL1+NULLCONCAT(InvisibleNULL)

如果你想要尋找值是 NULL的列你不能使用=NULL測試下列語句不返回任

何行因為對任何表達式expr = NULL是假的

mysqlgt SELECT FROM my_table WHERE phone = NULL

要想尋找 NULL值你必須使用 IS NULL測試下例顯示如何找出 NULL電話號碼和空的電話號碼

70

mysqlgt SELECT FROM my_table WHERE phone IS NULL mysqlgt SELECT FROM my_table WHERE phone =

在 MySQL中就像很多其他的 SQL服務器一樣你不能索引可以有 NULL值的列你必須聲明這樣的列為 NOT NULL而且你不能插入 NULL到索引的

列中

當用 LOAD DATA INFILE 讀取數據時空列用更新如果你想要在一個列中有

NULL值你應該在文本文件中使用N字面上的詞NULL也可以在某些情形下使用

當使用 ORDER BY時首先呈現 NULL值如果你用 DESC以降序排序NULL值最後顯示當使用 GROUP BY時所有的 NULL值被認為是相等的

為了有助于NULL的處理你能使用 IS NULL和 IS NOT NULL運算符和 IFNULL()函數

對某些列類型NULL值被特殊地處理如果你將 NULL插入表的第一個TIMESTAMP 列則插入當前的日期和時間如果你將 NULL插入一個AUTO_INCREMENT 列則插入順序中的下一個數字

Q5如何將圖片存放於 MySQL中

Ans

Step 1建立資料庫 test

Step 2 建立表格 binary_data

CREATE TABLE binary_data (

id INT(4) NOT NULL AUTO_INCREMENT PRIMARY KEY

description CHAR(50)

bin_data LONGBLOB

filename CHAR(50)

filesize CHAR(50)

filetype CHAR(50)

71

)

Step 3 利用 storephp 寫入圖片

storephp 程式碼

ltHTMLgt ltHEADgtltTITLEgtStore binary data into SQL DatabaseltTITLEgtltHEADgt ltBODYgt lt code that will be executed if the form has been submitted

if ($submit) mysql_connect(localhostrootYOUR_PASSWORD) mysql_select_db(test) $data=Base64_Encode(fread(fopen($form_data r) filesize($form_data))) $result=MYSQL_QUERY(INSERT INTO binary_data (descriptionbin_datafilenamefilesizefiletype) VALUES ($form_description$data$form_data_name$form_data_size$form_data_type)) $id= mysql_insert_id() print ltpgtThis file has the following Database ID ltbgt$idltbgt MYSQL_CLOSE() else else show the form to submit new data

gt

ltform method=post action=ltphp echo $PHP_SELF gt enctype=multipartform-datagt File Descriptionltbrgt ltinput type=text name=form_description size=40gt ltINPUT TYPE=hidden name=MAX_FILE_SIZE value=4000000gt ltbrgtFile to uploadstore in databaseltbrgt ltinput type=file name=form_data size=40gt ltpgtltinput type=submit name=submit value=submitgt ltformgt lt

72

gt ltBODYgt ltHTMLgt

Step 3 利用 storephp 取出圖片

getdataphp 程式碼

lt Syntax getdataphp3id=ltidgt if($id) you may have to modify login information for your database server MYSQL_CONNECT(localhostrootYOUR_PASSWORD) mysql_select_db(test) $query = select bin_datafiletype from binary_data where id=$id $result = MYSQL_QUERY($query) $data = Base64_Decode(MYSQL_RESULT($result0bin_data)) $type = MYSQL_RESULT($result0filetype) Header( Content-type $type) echo $data gt

Q6MySQL裝好之後啟動時或是執行 mysqladmin會出現如下訊息 Cant connect to local MYSQL Server through Socket varlibmysqlmysqlsock或是

Cant connect to local MYSQL Server through Socket tmpmysqldsock

Ans 可能有下列幾個原因

1這個 mysqldsock 不見了被某人刪除了或是被一些系統自動執行程式給刪

了例如有些 cron任務便會設定定期刪除 tmp 裡的東西所以呢您只能修改

cron 裡的設定讓它不要清除 mysqldsock 2在啟動時也可以改變 mysqldsock的位置您在啟動 MySQL的時候可以加入此參數usrlocalmysqlbinsafe_mysqld --user=mysql --socket=其他路

徑socket amp 同時得去設定環境變數 MYSQL_UNIX_PORT的值以指定新的

73

路徑 3若是您沒改 MYSQL_UNIX_PORT的值那麼您可以在執行指令的時候才打

例如mysqladmin --socket=其他路徑socket version Q7How to get the last insert id Ans CREATE TABLE product ( id INT(4) NOT NULL AUTO_INCREMENT PRIMARY KEY description VARCHAR(50) ) 1利用 SQL的話 mysqlgt insert into product(description) values(123) Query OK 1 row affected (000 sec) mysqlgt select last_insert_id() +------------------+ | last_insert_id() | +------------------+ +------------------+ 1 row in set (000 sec) ======================================== 2如果是 PHP的話 你可以用mysql_insert_id()取得該 id PHP example $result=MYSQL_QUERY(INSERT INTO product (description) VALUES ($description)) $id= mysql_insert_id() print This file has the following Database ID $id Q8如何將文字檔匯入資料庫 Ans $addr=homehttpdhtmlphpschool001txt $sql_select = load data infile $addr into table test fields terminated by t 解說 $sql_select = load data infile 文字檔名 into table 表格名 fields terminated by

74

t

(欄位分隔以 TAB鍵) 該文字檔須與資料表欄位格式相符 例如欄位有三個 則文字檔為每行一筆資料如下 欄 1資料ltTABgt欄 2資料ltTABgt欄 3資料 欄 1資料ltTABgt欄 2資料ltTABgt欄 3資料 欄 1資料ltTABgt欄 2資料ltTABgt欄 3資料 欄 1資料ltTABgtltTABgt欄 3資料

Q9如何撰寫 MySQL C API Ans Step 1利用文字編輯器撰寫以下程式碼 mysqlcc

include ltstdiohgt

include ltmysqlmysqlhgt

int main (int argc char argv[])

MYSQL mysql

MYSQL_RES res

MYSQL_ROW row

if (argc = 2)

fputs (Usage myc ltdatabasegt stderr)

return 1

if ((mysql_connect(ampmysqllocalhostrootYour_Password)))

fputs (Error connecting stderr)

abort()

75

if (mysql_select_db(ampmysqlargv[1]))

fputs (Error selecting database stderr)

abort()

if (mysql_query(ampmysqlSELECT FROM test_table))

fputs (Error processing query stderr)

abort()

if ((res = mysql_store_result(ampmysql)))

fputs (Error storing results stderr)

abort()

while((row = mysql_fetch_row(res)))

uint i = 0

for (i=0 i lt mysql_num_fields(res) i++)

printf(s row[i])

printf(n)

return 0

Step 2 Compile

gcc -Iusrlocalmysqlinclude -Lusrlocalmysqllibmysql mysqlcc ndashlm -lmysqlclient

(其中 include path與 library path取決於你的 MySQL安裝路徑)

76

如果執行時發生如下 error Run problemerror in loading shared libraries libmysqlclientsoX 將你的 MySQL library path(for exampleusrlocalmysqllibmysql) 加入etcldsoconf and run sbinldconfig -v Q9ASP + MySQL 範例程式 Ans Dim myconn As New ADODBConnection Dim myrs As New Recordset Dim mySQL As String Dim myrows As Long myconnOpen DSN=MyODBCsample mySQL = SELECT from user myrsSource = mySQL Set myrsActiveConnection = myconn myrsCursorLocation = adUseClient myrsOpen myrows = myrsRecordCount myrsClose myconnClose 可參考 httpwwwdwamnetmysqlasp_myodbcasp 有詳細的資料 Q10如何將 MySQL中的資料庫匯出成txt檔 Ans select from TableName into outfile textxls all result fields will seperate by tab

77

第八章 參考資料

英文部份 網址 1 httpwwwmysqlcom MySQL 網站有第一手有關 MySQL的資料 2 httpwwwmysqlcomdocenReplicationhtml 有關 MySQL Replication 的文件 3 httpwwwgeocitiescomsqlhomefaqstore_blobhtml 如何在 MySQL 存放 BLOB的資料 4httpwwwsapdborg 有關 SAP跟 MySQL相關合作的網站 書藉 1 Cooking with MySQL

Paul DuBois has selected sample recipes from the hundreds youll find in his book MySQL

Cookbook In this third and final series of excerpts showcasing these recipes learn how to

compute team standings how to calculate the differences between successive Dec 26

2002 2 Tips for Building Web Database Applications with PHP and MySQL by Hugh E Williams co-author of Web Database Applications with PHP amp MySQL 04042002

3 Managing and Using MySQL 2nd Edition By Tim King George Reese Randy Jay Yarger

4 MySQL Cookbook By Paul DuBoisPublisher OReillyPub Date October 2002

中文部份

78

1 httplinuxtncedutwtechdocmysqlmysql_docmanual_tochtml MySQL 中文手冊 2 httpchenshloxaedutwphpZ_1php PHP+MySQ程式研習設計網站 3 httplinuxtncedutwtechdocbanicdownhtml PHP 4 手冊 4 httpwwwtncedutwadmin_zonephp台南縣教育網網路中心有很多 Linux相關文件 5 httpdobtncedutw網站建置百寶箱有很多 PHP MySQL 相關範例程式 5 httpwwwdbworldcomtw資料庫專家電子雜誌介紹資料庫的重要觀念及名詞

79

附錄一 SQL Command 介紹

SQL (讀音ess-que-el) 是一種結構查詢語法SQL 使用於資料庫交流

傳遞相容於 ANSI (American National Standards Institute) 是一套標準的關聯

式資料庫語言 SQL 語言是執行更新或從資料系統獲取資料一般常見的關聯

資料庫系統都有提供 SQL 如 Oracle Sybase Microsoft SQL Server Access Ingres 等雖然大部份的資料庫都有提供 SQL 但也多提供了自已獨特的語

法造成了不相容的情形但標準基本的語法是相通的如Select Insert Update Delete Create and Drop 每一個系統都有支援

Table相關 Command

Create Table

關聯式資料庫包含有很多元件稱為資料表(tables) 把資料或訊息放在資

料表中 資料表是以不同的名稱做分別資料表由欄列所構成的二維陣列

欄包含欄位名資料型態 及其他可判斷的資訊列是由全部欄位構成一筆一

筆的紀錄 create table 語法用在建立一個新的資料表語法格式如下

create table tablename (column1 data type column2 data type column3 data type)

Format of create table if you were to use optional constraints

create table tablename (column1 data type [constraint] column2 data type [constraint] column3 data type [constraint]) [ ] = optional

Note You may have as many columns as youd like and the constraints are optional

80

Example

create table employee (first varchar(15) last varchar(20) age number(3) address varchar(30) city varchar(20) state varchar(20))

注意建立資料表格式要以括號把前後框住而最後以(分號)做結尾

欄位名不要超過 30個字元長而且不要使用 sql 的關鍵字(如 where select等)而在後面接是型態的宣告(如字串數字日期格式等)

資料型態是來描述欄位的方式如一個欄位Last_Name 是一個姓氏可以使用varchar (可變動長度字串) 資料型態

以下是幾個常見的資料庫型態 char(size) 固定長度字串最長為 255 位元 varchar(size) 變動長度字串最大字元數以 size 來指定 number(size) 數值格式可以是整數也可以是小數最大數字以 size 位數判

斷未指定小數位數由系統內定 date 日期格式 number(sized) 數值格式最大數字以 size 位數判斷d 為小數位數整數位

數為 size-d 位

有何限制當資料表被建立通常有一或數個欄位是要使用來做關聯的功

能 例如unique 限制(唯一值)兩筆記錄不可以相同的值 not null (非空值)該欄位一定要輸入資料不可是空的primary key (主鍵)是每一筆記錄識別的主要方式

Drop a table drop table 刪除資料表(其中的資料也會一併刪除)

drop table tablename

Example

81

drop table 和刪除全部資料是不同的刪除全部資料欄位名稱資訊等還會

存在但刪除資料表會把這一些也一併移除掉

如何查詢資料

Select 基本用法

select 語法是關連式資料庫最常用的部份可以取得你想要的資料這是一個

簡單的範例 select column1[column2etc] from tablename [where condition] [] = optional 在 select 之後所列欄位名則是要顯示的資料部份你可以一一列出各欄位

名或是以 (星號)來代表選擇全部的欄位 from 之後放資料表名稱 where 子句 (選項) 指定要過濾的條件符合者才會顯現 where 可使用的條件運算元 = 等於 gt 大於 lt 小於 gt= 大或等於 lt= 小或等於 ltgt 大相等 LIKE 相似 For example select first last city

82

from empinfo where first LIKE Er 以Er 為開頭的字串就符合要以單引號框住 Or you can specify select first last from empinfo where last LIKE s 最後一字為 S 就符合 select from empinfo where first = Eric 則表示 first name 一定要是 Eric 才可以 範例資料表empinfo 統計函數

MIN 傳回指定欄位最小值

MAX 傳回指定欄位最大值

SUM 傳回指定欄位總和

AVG 傳回指定欄位平均值

COUNT 傳回指定欄位的筆數

COUNT() 傳回資料庫中的總筆數

統計函數使用於資料表中的數值欄位配合 SELECT 語法使用 只用於總結特定單一欄位可以配合 GROUP BY 做篩選但也可以不使用 GROUP BY 語句For example

SELECT AVG(salary) FROM employee

83

傳回全部 salary 平均值

Another example

SELECT AVG(salary) FROM employee WHERE title = Programmer

傳回 salary 平均值條件為 employees 資料表中當 title 等於 Programmer

Example

SELECT Count() FROM employees

傳回 employees 資料表中紀錄總筆數

GROUP BY 語法 SELECT column1 SUM(column2) FROM list-of-tables GROUP BY column-list The GROUP BY 語句可以先以所列的欄位為條件分組排序在一起(可以多欄

位) example 要列出每一個 dept 中最高 salary 值 SELECT max(salary) dept FROM employee GROUP BY dept HAVING 語法

SELECT column1 SUM(column2) FROM list-of-tables GROUP BY column-list HAVING condition

HAVING 子句是 GROUP BY 的一部份用來過濾在 GROUP BY 所選出的資料功能如同 select 命令中 where 條件式一樣只是 HAVING 必需配合 GROUP BY 使用

我們以例子來說明我們要取得每一公司名及每一公司的薪水平均值輸入如下

84

SELECT dept avg(salary) FROM employee GROUP BY dept

但如果我們只列出薪資平均值超過 20000元的公司資料

SELECT dept avg(salary) FROM employee GROUP BY dept HAVING avg(salary) gt 20000

ORDER BY子句語法

SELECT column1 SUM(column2) FROM list-of-tables ORDER BY column-list [ASC | DESC]

[ ] =選項

ORDER BY是一個選項子句當你以排序方式來顯示資料(正向由小到大反向由大到小)以指定的欄位資料做排序

ASC = 正向- 預設值 DESC = 反向排序

For example

SELECT employee_id dept name age salary FROM employee_info WHERE dept = Sales ORDER BY salary

以上列出公司代號公司名銷售員人名年紀及薪資而條件是公司名為 Sales 顯示順序以薪資多少排序(由小到大為預設值)

如果要以多個欄位做排序要以逗號做分隔如下

SELECT employee_id dept name age salary FROM employee_info WHERE dept = Sales ORDER BY salary age DESC

85

結合條件及布林運算 SELECT column1 SUM(column2) FROM list-of-tables WHERE condition1 AND condition2 AND運算可以結兩個或以上的條件放在 WHERE子句中 兩者都要為真才

會顯示該筆記錄 OR 運算可以結兩個或以上敘述放在 WHERE子句中只要其中一個為直就

會顯示該筆記錄 For example SELECT employeeid firstname lastname title salary FROM employee_info WHERE salary gt= 5000000 AND title = Programmer 必需要薪資大於等於 50000而且職稱為 Programmer同時符合才會顯示該筆資料 以下以括號括住雖然不是必需的但如此比較容易讀 SELECT employeeid firstname lastname title salary FROM employee_info WHERE (salary gt= 5000000) AND (title = Programmer) 另外範例 SELECT firstname lastname title salary FROM employee_info WHERE (title = Sales) OR (title = Programmer) 條件為只要是 Sales 或 Programmer 職稱的就會被列出 IN and BETWEEN 子句

SELECT column1 SUM(column2) FROM list-of-tables WHERE column3 IN (list-of-values) SELECT column1 SUM(column2) FROM list-of-tables WHERE column3 BETWEEN value1 AND value2 IN 子句使用在列舉項目的使用上也就是分別測試是否符合所列的值 For example

86

SELECT employeeid lastname salary FROM employee_info WHERE lastname IN (Hernandez Jones Roberts Ruiz) 條件為姓氏(astname)要符合 Hernandez Jones Roberts or Ruiz 其中一個才會被傳回 IN運算元也可以使用 OR 的語法來取代如下結果相同 SELECT employeeid lastname salary FROM employee_info WHERE lastname = Hernandez OR lastname = Jones OR lastname = Roberts OR lastname = Ruiz 但使用 IN 句子比較短也比較易懂 你也可以使用 NOT IN 來去掉不要的記錄 BETWEEN 運算元使用在判斷是否存在兩個數值之間 For example SELECT employeeid age lastname salary FROM employee_info WHERE age BETWEEN 30 AND 40 傳回年紀 30歲到 40歲之間的資料(含 30及 40歲者) 相同的也可以使用以下語法來達到相同的結果 SELECT employeeid age lastname salary FROM employee_info WHERE age gt= 30 AND age lt= 40 你也可使用 NOT BETWEEN 來濾掉中間值的資料 數學運算 標準 ANSI SQL-92 提供以下運算

87

+ 加

- 減

餘數

餘數為除法後剩整數這不在標準的 ANSI SQL 中但大部份的資料庫都會支

援這運算元以下列出有用的函數雖不在 ANSI SQL-92 提供但一般資料庫

也會支援他們

ABS(x) 傳回 x 絕對值

SIGN(x) returns the sign of input x as -1 0 or 1 (negative zero or positive respectively)

MOD(xy) 餘數 - returns the integer remainder of x divided by y (同 xy)

FLOOR(x) 傳回小或等於 x 的最大整數值

CEILING(x) or CEIL(x)

傳回大或等於 x 的最小整數值

POWER(xy) x的 y 次方

ROUND(x) 把 x 四捨五入為整數

ROUND(xd) 四捨五入取到小數 d 位

SQRT(x) x 開平方

For example SELECT round(salary) firstname FROM employee_info 傳回薪資取到整數位

如何新增資料

insert 加入一筆新紀錄到資料表中 insert into tablename (first_columnlast_column) values (first_valuelast_value) [] = optional Example insert into employee

88

(first last age address city state) values (Luke Duke 45 2130 Boars Nest Hazard Co Georgia) Note 字串要以單引號住如string 數字框住也無妨 insert into 後面接資料表名稱再接以括號括住的欄位名在 values 後括號分別對映各欄位的值 以上的例子新增了一筆名(first) 為 Luke而住所(state) 為 Georgia 的資料

如何刪除資料

delete 可以刪除單筆或多筆紀錄 delete from tablename where columnname OPERATOR value [and|or column OPERATOR value] [ ] = optional Examples delete from employee Note 如果你沒有指定 where 子句那麼全部的紀錄都會被刪除 delete from employee where lastname = May delete from employee where firstname = Mike or firstname = Eric delete from 接著資料表名 再接著是條件式判斷沒有條件式則全部紀錄會

被刪除

如何更新資料

update 用來更新你所指定的記錄要和 WHERE 配合小心使用 語法 update tablename set columnname = newvalue[nextcolumn = newvalue2] where columnname OPERATOR value [and|or column OPERATOR value] [] = optional Examples

89

update phone_book set area_code = 623 where prefix = 979 update phone_book set last_name = Smith prefix=555 suffix=9292 where last_name = Jones update employee set age = age+1 where first_name=Mary and last_name=Williams

90

附錄二Replication

測試環境

RedHat 90 + MySQL 32358 MySQL資料庫路徑 varlibmysql MySQL設定檔 etcmycnf Master IP 1921680100 Slave IP 1921680200 請至下列網址下載最新MySQL 32358套件並利用rpm ndashUvh 更新 httpupdatesredhatcom9enosi386

圖 最新 MySQL 套件

測試架構圖

91

1921680100

1921680200Master Server

erveSlave S r

圖 測試架構圖

測試步驟

Master server 部份 Step1 確認 MasterSlave機器上所裝的 MySQL版本能進行

replication( 32329 or higher ) Step2 在 Master MySQL上開放一個帳號給 Slave mysql ndashu root ndashp mysqlgtGRANT FILE ON TO repl1921680200 IDENTIFIED BY lsquoabc123rsquo mysqlgtq 上面是 Master開放一個帳號 repl密碼 abc123給 IP1921680200有檔案處理

的權限 Step3 shutdown MySQL on the Master mysqladmin ndashu root ndashp shutdown Step4 備份 Master所有資料庫 tar ndashcvf tmpmysql-snapshottar varlibmysql 注意tar的時候MySQL是要在 stop情況下 在mysql (wwwmysqlcom) 網站的FAQ有不用shutdown的方法

92

Step5 在 master機器上修改etcmycnf 在[mysqld]區段內加入參數 log-bin server-id=這邊設定 server-id=1 sql-bin-update-same binlog-do-db=CRM只針對 CRM資料庫做紀錄 Step6 Restart MySQL on the master service mysqld start 此時因為有加入 log-bin 參數因此開始有 index產生了在varlibmysql目錄下

有index檔案紀錄資料庫的異動 log Slave server 部份 Step1 在 slave設定etcmycnf 在[mysqld]區段加入 master-host= master-user= master-password= master-port= server-id= 這邊設定 master-host=1921680100 master-user=repl master-password=abc123 master-port=3306 server-id=2 master-connect-retry=60預設重試間隔 60秒 replicate-do-db=CRM告訴 slave只做 CRM資料庫的更新 log-slave-updates Step2 將 master上的 mysql-snapshottar copy到 slave上 用 ftp傳到 slave的tmp Step3 解壓縮 Master資料庫至 Slave Server上 cd varlib tar xvf tmpmysql-snapshottar chown ndashR mysqlmysql mysql

93

chmod ndashR 770 mysql (視情況) Step4 Restart MySQL on the slave server 這時在varlibmysql目錄會出現 masterinfo此檔案紀錄了 Master MySQL server的資訊

狀況測試

One-way replication

1921680100

1921680200Master Server

erveSlave S r

圖 One-way replication架構圖 Step1 Master跟 Slave網路及服務都正常情況下由 Master端異動資料後 到 Slave端瀏覽資料檢視是否有進行 replication Step2 模擬 Slave Server 當機 可用在於 slave真的當機或是 Slave 不一定需要一直跟 master connect將Slave MySQL server shutdown由 Master端異動資料到 slave端瀏覽此時Slave應該沒有被 replication 更新然後再將 Slave端 MySQL server start起來

預設 60秒後 Slave會嘗試跟 Master要求進行 replication再去 Slave端檢視是否有更新資料

94

Step3 模擬 Master當機因為是設定 One-way replication一旦 Master Server Slave端沒有 Master的 source可以 download Two-way replication 基於 Master當機狀況於是發展雙向 Replication即 1921680100 ( Host A ) 1921680200 ( Host B )都分別擔任 MasterSlave身分

1921680100

1921680200er

Server B MasterSlave Server

Server A MasterSlave Serv

圖 Two-way replication架構圖 以下是針對兩台 MySQL伺服器進行雙向 Replication Step1觀念同單向 replication只是改成 Master也有 Slave身分 Slave也有Master的身分先分別在 Server AServer B 都去 grant一個進行 replication的身分 [A]mysqlgtGRANT FILE ON TO repl1921680200 IDENTIFIED BY lsquoabc123rsquo [B]mysqlgt GRANT FILE ON TO repl1921680100 IDENTIFIED BY lsquoabc123rsquo Step2做完單向 replication後stop Server Aserver B MySQL service此時 AB資料是一樣的

95

修改etcmycnf設定 範例 Server A [mysqld] datadir=varlibmysql socket=varlibmysqlmysqlsock server-id=1 log-bin sql-bin-update-same binlog-do-db=CRM master-host=1921680200 master-user=repl master-password=abc123 log-slave-updates master-connect-retry=60 replicate-do-db=CRM Server B [mysqld] datadir=varlibmysql socket=varlibmysqlmysqlsock server-id=2 log-bin sql-bin-update-same binlog-do-db=CRM master-host=1921680100 master-user=repl master-password=abc123 log-slave-updates master-connect-retry=60 replicate-do-db=CRM 分別 start Server AServer B MySQL後此時雙方都是 MasterSlave身分一旦哪一方資料異動就會通知對方來 replication-若 replication失效則必須將Server AServer B的masterinfo及index00x 都砍掉然後分別 restart MySQL server進行測試檢視成果 實務上通常如果需要做Two-way replication通常會搭配Virtual Server使用

96

在前端架設一台Virtual Server不過此部份不在此份SOP討論範圍內有興趣

的讀者可參考 httpwwwlinuxvirtualserverorg 網站

1921680100 1921680200

Host A MasterSlave Server

Host B MasterSlave Server

Virtual Host

圖 Virtual Server + Two-way replication 架構圖

97

圖 High Availability Linux Virtual Server架構圖

98

  • COSA-SOP-03-006
  • 第一章 簡介
    • 11適用對象 (Audience)
    • 12 MySQL本身
    • 13 MySQL 40版跟50版重大的改進功能
    • 14 各家資料庫軟體比較
      • 第二章 前置需求
      • 第三章 安裝
        • 31 MySQL安裝
        • 32 phpMyAdmin安裝
        • 33 升級及注意事項
          • 第四章 MySQL管理
            • 41 Webmin 管理介面
            • 42 phpMyAdmin 的操作介面
            • 43管理指令介紹
              • 431 利用mysqladmin設定root的密碼
                  • 第五章 實用範例
                    • 51 任務一Web Base客戶通訊錄
                    • 52 任務二Web Base群組軟體 ( twig )
                      • 第六章 維護及更新程序
                        • 61 日常維護
                        • 62 更新程序
                        • 63 備份重要檔案
                        • 64 離線備份與還原
                        • 65 線上備份與還原
                          • 第七章 問題與解答
                          • 第八章 參考資料
                          • 附錄一 SQL Command 介紹
                          • 附錄二Replication
Page 9: DataBase Server Standard Operation Procedureebooks.lib.ntu.edu.tw/1_file/oss/63/93doc4-5.pdf · 業務的公司帶來了不少壓力,譬如微軟,甲骨文 ... 外的錢用在第三方的資料庫產品上,譬如就可以不用再購買甲骨文公司

圖 1-1 資料庫優先性

整體擁有成本 大致說來MySQL是免費的MySQL需要付費的規定只限於下列兩種情

形 1 以 Embedded的方式使用 MySQL 2 使用 MySQL的商業用途軟體

且其授權費用一台 MySQL Pro License只需美金 $440比起其他任何資料庫軟體來得容易負擔多了加上其易於管理的特性著實可大大降低企業資料

庫的整體擁有成本 擴充性

MySQL同時提供高度多樣性能夠提供給很多不同的使用者介面包括命

令列操作網頁瀏覽器以及各式各樣的程式語言介面例如JavaC++PerlPHP及 PhythonMySQL可用 UnixWindows以及 OS2hellip等平台因此它可以用個人電腦或是伺服器上 性能 事實上大部份的網站的開發者都認為 MySQL是目前市面跑得最快的資料

9

庫對資料庫的最佳化主要在於你對他的設定和資料庫結構的設計如果你的

資料庫結構設計得非常差你的存取速度還是會受到影響而變得比較慢

10

第二章 前置需求

在安裝 MySQL之前請確定 Apache及 MySQL亦巳安裝相關步驟請參考

Apache SOP安裝 Apache及 PHP相關章節

11

第三章 安裝

31 MySQL安裝

在 RedHat 90上安裝 MySQL是件很容易的事因為 RedHat 90提供了一

個很方便的 GUI套件管理工具「redhat-config-packages」各位只要把 RedHat 90第一片光碟放入並以 root的身份登入系統鍵入 redhat-config-packages勾選「SQL資料庫伺服器」即可然後按「更新」如果遇到任何相依性問題

系統會提示您更換光碟片 ( 圖 3-1 ~ 3-3 ) Step 1 執行 redhat-config-packes

圖 3-1

Step 2 選擇資料伺服器

12

圖 3-2

Step 3檢查是否安裝成功 待安裝後您可以用利用「rpm -qa | grpe ^mysql」檢查是否安裝成功

圖 3-3

啟動 MySQL ( Command Mode )馬上啟動 MySQL的指令為「service mysqld start」如果您希望一開機就自動啟動 MySQL請執行「chkconfig mysqld on」

13

圖 3-4

啟動 MySQL ( WebMin 介面 ) 我們也可以利用WebMin 來啟動 MySQL步驟如下 Step 1登入Webmin

圖 3-5 登入WebMin

Step 2 選擇伺服器

14

圖 3-6 伺服器畫面

Step 2 選擇 MySQL資料庫伺服器

圖 3-7 伺服器畫面

15

Step 3 啟動 MySQL資料庫伺服器

圖 3-8 啟動 MySQL

更改資料庫管理者密碼

成功啟動 MySQL後因為資料庫管理者預設沒有密碼建議使用前更改系

統管理者密碼請輸入下列指令

mysqladmin ndashu root ndashh cosaexamplecom password lsquo1234rsquo -u 表示使用者帳號root 為 MySQL預設的管理帳號

-h 表示 MySQL主機的主機名稱也可使用 IP Address password 表示使用者的密碼因為字串請使用單引號將密碼括起來

圖 3-9 修改 MySQL 的密碼

16

32 phpMyAdmin安裝

本書除了會介紹利用當今 Linux上最紅的整合管理工具Webmin 來管理

MySQL外還會為各位介紹專門管理 MySQL的工具 phpMyAdmin phpMyAdmin是免費的 PHP原始程式碼的Web網站可用來管理整個

MySQL伺服器這是一套Web介面的 MySQL管理程式支援中文的使用者介

面 phpMyAdmin只需透過瀏覽器就可管理 MySQL伺服器換句話說不論

MySQL是安裝在 Linux或是Windows 作業系統都可以使用相同步驟在

MySQL上建立資料庫(Database)資料表(Table)和編輯紀錄(Record) Step 1 下載phpMyAdmin ( httpwwwphpmyadminnet )選擇最櫎新穩定的版

本 253

圖 3-10 httpwwwphpmyadminnet

17

圖 3-11 下載 phpMyAdmin-253-phptarbz2

Step 2 將 phpMyAdmin-253-phptarbz2收至 tmp 並執行下列指令將其解壓

縮至varwww tar jxvf phpMyAdmin-253-phptarbz ndashC varwwwhtml

圖 3-12 解壓縮安裝 phpMyadmin-253

Step 3 為了操作方便起見建立 Soft link ln ndashs phpMyAdmin-253 phpMyAdmin

圖 3-13 修改 phpMyadmin 設定檔 configincphp

18

Step 4 修改 phpMyadmin 設定檔 configincphp gedit varwwwhtmlphpMyAdminconfigincphp

圖 3-14 configincphp設定檔

Step 5 設定顯示行號以方便修改 configincphp 設定檔

19

圖 3-15 顯示行號

Step 6 修改下列設定 第 39 行 設定 phpMyAdmin的 URL 第 69 行 MySQL Server 的 ip 第 80 行 利用何帳號存取 MySQL 第 81 行 如果 root有設定 password此處即填入 root的 password

30 In most cases you can leave this variable empty as the correct value

31 will be detected automatically However we recommend that you do

32 test to see that the auto-detection code works in your system A good

33 test is to browse a table then edit a row and save it There will be

34 an error message if phpMyAdmin cannot auto-detect the correct value

35

36 If the auto-detection code does work properly you can set to TRUE the

37 $cfg[PmaAbsoluteUri_DisableWarning] variable below

38

39 $cfg[PmaAbsoluteUri] = httpossccosaorgtwphpMyAdmin

hellip

20

hellip

69 $cfg[Servers][$i][host] = localhost MySQL hostname or IP address hellip 80 $cfg[Servers][$i][user] = root MySQL user

81 $cfg[Servers][$i][password] = 1234 MySQL password (only needed

圖 3-16 修改 configincphp

21

圖 3-17 修改 configincphp

圖 3-18 修改 configincphp p

Step 7 設定語系

22

圖 3-19 設定語系

圖 3-20 執行 phpMyAdmin

23

33 升級及注意事項

RedHat 90附的 MySQL版本為 323 MySQL所釋出最新穩定版本為

40若是您不想用系統預附的 323請先利用下列移除之前 323的版本

rpm ndashe mysql-devel rpm ndashe mysql-server rpm ndashe mysql --nodeps 然後到下列網址下載您所想要的版本進行安裝在這裏我們用 4014版為例 Step 1 下載相關套件( httpwwwmysqlcomdownloadsmysql-40html )

圖 3-21 Download MySQL 4014 相關 RPM Step 2 利用 rpm 指令安裝

24

圖 3-22 Install MySQL 4014 相關 RPM

圖 3-23 Install MySQL 4014 相關 RPM

Step 3 啟動 MySQL

25

圖 3-24 啟動 MySQL 4014 並修改密碼

26

第四章 MySQL管理

本章將我們介紹利用WebminphpAdminCommand的方式建立一個名為

CONTACT的資料庫內有一個 address的 Table作為我們客戶通訊錄程式使

用的資料庫

41 Webmin 管理介面

412建立資料庫

Step 1 登入Webmin

圖 4-1 登入WebMin

Step 2 點選伺服器

27

圖 4-2 伺服器畫面

Step 3 點選 MySQL資料庫伺服器

圖 4-3 MySQL資料庫伺服器

28

Step 4 建立一個新的資料庫

圖 4-4 建立 MySQL資料庫

Step 5 建立名為 CONTACT的資料庫

29

圖 4-5 指定資料庫名稱

412 建立資料表

假設我們要建立一個名為 address的 Table其結構如下 欄位名稱 資料型態 長度 說明 id INT (自動編號) 連絡人編號 name varchar文字 20 連絡人姓名 tel Varchar文字 15 連絡人電話 Step 1 選擇 CONTACT資料庫

30

圖 4-6 選擇資料庫

Step 2 指定欄位數目

31

圖 4-7 設定欄位數目

Step 3設定表格欄位屬性

圖 3-8 設定表格欄位屬性

Step 4建立表格資料

32

圖 4-9 建立表格資料

圖 4-10 檢視資料

33

圖 4-11 新增資料

圖 4-12

34

圖 4-13

413 使用者管理

接下來我們要利用Webmin 來建立資料庫使用者並給予某些權限 Step1建立使用者

35

圖 4-14 選擇使用者權限

圖 4-15

36

Step2 賦予權限

圖 4-16

Step3 權限列表

37

圖 4-17

38

42 phpMyAdmin 的操作介面

421建立資料庫

Step 填入資料庫名稱並按「建立」

圖 4-18建立資料庫

422 建立資料表

Step1 填入資料表名稱並指定欄位數量 執行

39

圖 4-19填入資料表名稱並指定欄位數量

Step2 設定欄位屬性

圖 4-20設定欄位屬性

40

Step3 phpMyAdmin會產生相關的 SQL Command

圖 4-21 資料表結構及相關 SQL Command

Step4新增 Record

41

圖 4-22

圖 4-23

42

圖 4-24

圖 4-25

43

423使用者管理

Step1建立使用者

圖 4-26

44

圖 4-27

Step2 給予權限

圖 4-28

Step3權限列表

45

圖 4-29

43管理指令介紹

431 利用 mysqladmin設定 root的密碼

當您在Windows 或 Linux 中安裝好 MySQL後系統會自動幫您建立兩個

帳分別是 root 和 匿名者MySQL的 root 跟 Linux 最高權限使用者 root無關MySQL的 root使用者相當於 MS SQL 中的 sa 帳號擁有最高的 Database管理權限但系統預設 MySQL的 root 是不需要密碼所以通常我們一安裝

MySQL後首要任務便是修改 root的密碼 我們可以利用 mysqladmin工具或是直接修改 MySQL內部資料庫的使用者資

料 mysqladmin ndashu root ndashh cosaexamplecom password lsquo1234rsquo

46

-u 表示使用者帳號root 為 MySQL預設的管理帳號

-h 表示 MySQL主機的主機名稱也可使用 IP Address password 表示使用者的密碼因為字串請使用單引號將密碼括起來 密碼設定完成之後還是可以利用 mysqladmin修改密碼但是你必須提供目前的密碼

432 連線 MySQL

mysql -uroot -p密碼 (-p和密碼之間不能有空白) 或 mysql -uroot -p (此方式會在進入後要求密碼) [rootossc phpMyAdmin] mysql -u root -p1234

Welcome to the MySQL monitor Commands end with or g

Your MySQL connection id is 25 to server version 32354

Type help or h for help Type c to clear the buffer

mysqlgt show databases

+----------+

| Database |

+----------+

| mysql |

| test |

+----------+

2 rows in set (000 sec)

mysqlgt exit

Bye

[rootossc phpMyAdmin]

433 建立資料庫

可利用 mysqladmin指令建立 CONTACT資料庫 mysqladmin -u root -p1234 create CONTACT

47

或是利用 mysql指令 [rootossc bluepage] mysql -u root -p1234 Welcome to the MySQL monitor Commands end with or g Your MySQL connection id is 1057 to server version 32354 Type help or h for help Type c to clear the buffer mysqlgt create database CONTACT Query OK 1 row affected (000 sec) mysqlgt show databases +----------+ | Database | +----------+ | CONTACT | | address | | hello | | mysql | | nuke | | test | +----------+ 6 rows in set (000 sec) mysqlgt exit

434 建立資料表

編寫 adresssql內容如下 -- Table structure for table address CREATE TABLE address ( id int(11) NOT NULL auto_increment name varchar(20) NOT NULL default tel varchar(15) NOT NULL default PRIMARY KEY (id) ) TYPE=MyISAM

48

-- Dumping data for table address INSERT INTO address VALUES (1林小明0800016888) INSERT INTO address VALUES (2黃大雄0800016888) INSERT INTO address VALUES (3劉小芬0800024365) 然後執行此 sql script mysql -u root -p1234 CONTACT lt addresssql 或是利 mysql command [rootossc bluepage] mysql -u root -p1234 Welcome to the MySQL monitor Commands end with or g Your MySQL connection id is 1090 to server version 32354 Type help or h for help Type c to clear the buffer mysqlgt use CONTACT Database changed Database changed mysqlgt CREATE TABLE address ( -gt id int(11) NOT NULL auto_increment -gt name varchar(20) NOT NULL default -gt tel varchar(15) NOT NULL default -gt PRIMARY KEY (id) -gt ) TYPE=MyISAM Query OK 0 rows affected (000 sec) mysqlgt INSERT INTO address VALUES (1林小明0800016888) Query OK 1 row affected (000 sec) mysqlgt INSERT INTO address VALUES (2黃大雄0800016888) Query OK 1 row affected (000 sec) mysqlgt INSERT INTO address VALUES (3劉小芬0800024365) Query OK 1 row affected (000 sec) mysqlgt exit Bye

49

第五章 實用範例

51 任務一Web Base客戶通訊錄

任職於開放科技公司的林小明前些日子在最符合成本效益的條件下快

速地完成公司網站的建置老闆因此對小明讚譽有加最近因為公司存放客戶資

料的 SQL Server主機屢遭病毒攻擊加上作業系統本身的問題當機次數頻繁

老闆希望能儘快把公司的客戶通訊錄程式移轉到較穩定的環境上因為此客戶通

訊錄程式最主要給內部人員使用所以介面美觀並不特別要求只求穩定且能快

速得到查詢結果老闆希望在短時間先看到程式的雛型並鍵入資料對其效率

及穩定性進行測試因為上次小明表現突出所以這次不可能的任務自然又落到

小明身上 小明想來想去既然要快速又穩定他而且又不希望所有人都得安裝 Client

程式於是小明決定)捨棄他的舊愛「Delphi+MS SQL」投向新歡「Apache + MySQL + PHP」利用此架構來設計一個簡單實用的Web Base客戶通訊錄程式

511 Web Base客戶通訊錄架構

此程式需要建立 CONTACT的資料庫並建立 adress Tables其結構如下表建立步驟請參考第三章 欄位名稱 資料型態 長度 說明 id INT (自動編號) 連絡人編號 name varchar文字 20 連絡人姓名 tel Varchar文字 15 連絡人電話 Web Base通訊錄共有下列幾個檔案功能如下表

檔案名稱 說明 Indexhtml Web Base通訊錄首頁 addphp 新增連絡人的 php程式 searchphp 尋找連絡人的 php程式 editphp 具有更新及刪除功能的 php程式

50

我們將這些檔案放至varwwwhtmlbluepage (預設無 bluepage目錄)

512 Web Base通訊錄測試

httpwwwopencombluepage 新增資料

圖 5-1 新增連絡人

圖 5-2 填入資料

51

圖 5-3 新增成功

搜尋及異動資料

圖 5-4 搜尋通訊錄

52

圖 5-5 編輯資料

圖 5-6 更新資料

513 程式內容及說明

lt-- 程式範例indexhtml--gt lthtmlgt ltheadgtlttitlegt通訊錄lttitlegtltheadgt ltbodygt ltcentergt

53

lth2gt通訊錄lth2gtlthrgt lta href=indexhtmlgt通訊錄ltagt | lta href=addphpgt新增連絡人ltagt | lta href=searchphpgt搜尋通訊錄ltagt ltcentergt ltbodygt lthtmlgt lt-- 程式範例addphp --gt lthtmlgt ltheadgtlttitlegt新增連絡人lttitlegtltheadgt ltbodygt ltcentergtlth2gt新增連絡人lth2gtltcentergtlthrgt lt 取得欄位資料 if (isset($_POST[Name]) ampamp isset($_POST[Tel]) ) $name = $_POST[Name] $tel = $_POST[Tel] 檢查是否有輸入欄位資料 if ($name = ampamp $tel = ) 建立 SQL字串 $sql = INSERT INTO address (name tel) values( $sql= $name $tel) 建立 MySQL 連結 $link = mysql_connect(localhostroot1234) 選擇資料庫 mysql_select_db(CONTACT) 執行 SQL指令 mysql_query($sql) mysql_close($link) echo ltfont color=redgt新增連絡人成功ltfontgtltbrgt gt ltform action=addphp method=postgt lttable border=0 width=300gt lttrgtlttdgt姓名 lttdgt

54

lttdgtltinput type=text name=Name size=20 maxlength=10gtlttdgtlttrgt lttrgtlttdgt電話 lttdgt lttdgtltinput type=text name=Tel size=20 maxlength=20gtlttdgtlttrgt lttrgtlttd colspan=2 align=centergt ltinput type=submit value=新增連絡人gtlttdgtlttrgt lttablegt ltformgt ltbrgtlta href=indexhtmlgt通訊錄ltagt | lta href=addphpgt新增連絡人ltagt | lta href=searchphpgt搜尋通訊錄ltagt ltbodygt lthtmlgt

lt-- 程式範例searchphp --gt lthtmlgt ltheadgtlttitlegt搜尋通訊錄lttitlegtltheadgt ltbodygt ltcentergtlth2gt搜尋通訊錄lth2gtlthrgt lt if (isset($_POST[Search])) 建立資料庫連結並選定資料庫 $link = mysql_connect(localhostroot1234) mysql_select_db(CONTACT) 建立基本的 SQL字串 $sql = SELECT FROM address 檢查是否輸入姓名 if (chop($_POST[Name]) = ) $name = name LIKE $_POST[Name] else $name = 檢查是否輸入電話號碼 if (chop($_POST[Tel]) = ) $tel = tel LIKE $_POST[Tel] else $tel =

55

if條件組合 SQL字串 if (chop($name) = ampamp chop($tel) = ) $sql= WHERE $name AND $tel elseif (chop($name) = ) 只有姓名 $sql = WHERE $name elseif (chop($tel) = ) 只有電話號碼 $sql = WHERE $tel $sql= ORDER BY name 最後加上排序 $result = mysql_query($sql) 取得欄位數 $total_fields = mysql_num_fields($result) echo lttable border=1gt echo lttrgtlttdgt編號lttdgtlttdgt姓名lttdgtlttdgt電話lttdgtlttd colspan=2gt功能選項lttdgtlttrgt 表格顯示查詢結果 while ($rows = mysql_fetch_array($result MYSQL_NUM)) echo lttrgt for ($i = 0 $i lt $total_fields $i++) echo lttdgt$rows[$i]lttdgt echo lttdgtlta href=editphpaction=editampid= echo $rows[0]gtltbgt編輯ltbgtlttdgt echo lttdgtlta href=editphpaction=delampid= echo $rows[0]gtltbgt刪除ltbgtlttdgt echo lttrgt echo lttablegtlthrgt mysql_free_result($result) mysql_close($link) gt ltcentergt ltform action=searchphp method=postgt lttable border=0 width=450gt lttrgtlttdgt搜尋姓名 lttdgt lttdgtltinput type=text name=Name size=10 maxlength=20gtlttdgtlttrgt lttrgtlttdgt搜尋電話 lttdgt lttdgtltinput type=text name=Tel

56

size=20 maxlength=20gtlttdgtlttrgt lttrgtlttd colspan=2 align=centergt ltinput type=submit name=Search value=搜尋gtlttdgtlttrgt lttablegt ltformgt ltbrgtlta href=indexhtmlgt通訊錄ltagt | lta href=addphpgt新增連絡人ltagt | lta href=searchphpgt搜尋通訊錄ltagt ltbodygt lthtmlgt

lt ob_start() gt lt-- 程式範例editphp --gt lthtmlgt ltheadgtlttitlegt編輯通訊錄lttitlegtltheadgt ltbodygt lt 取得 URL 參數 $id = $_GET[id] $action = $_GET[action] 建立資料庫連結 $link = mysql_connect(localhostroot1234) mysql_select_db(CONTACT) 選擇資料庫 執行的操作 switch ($action) case update 更新 取得欄位資料 $name = $_POST[Name] $tel = $_POST[Tel] $sql = UPDATE address SET name=$name tel=$tel WHERE id=$id mysql_query($sql) 執行 SQL指令 mysql_close($link) header(Location searchphp) 轉向到 serachphp break case del 刪除 $sql = DELETE FROM address WHERE id=$id

57

mysql_query($sql) 執行 SQL指令 mysql_close($link) header(Location searchphp) 轉向到 serachphp break case edit 編輯 $sql = SELECT FROM address WHERE id=$id $result = mysql_query($sql) 執行 SQL指令 $row = mysql_fetch_row($result) 取回記錄 $name = $row[1] 取得欄位 name $tel = $row[2] 取得欄位 tel mysql_close($link) 顯示編輯表單 gt ltcentergtlth2gt更新通訊錄lth2gtltcentergtlthrgt ltform action=editphpaction=updateampid=lt echo $id gt method=postgt lttable border=0 width=300gt lttrgtlttdgt姓名 lttdgt lttdgtltinput type=text name=Name size=20 maxlength=10 value=lt echo $name gtgtlttdgtlttrgt lttrgtlttdgt電話 lttdgt lttdgtltinput type=text name=Tel size=20 maxlength=20 value=lt echo $tel gtgtlttdgtlttrgt lttrgtlttd colspan=2 align=centergt ltinput type=submit value=更新連絡人gtlttdgtlttrgt lttablegt ltformgt ltbrgtlta href=indexhtmlgt通訊錄ltagt | lta href=addphpgt新增連絡人ltagt | lta href=searchphpgt搜尋通訊錄ltagt lt break gt ltbodygt lthtmlgt

58

52 任務二Web Base群組軟體 ( twig )

順利完成Web Base客戶通訊錄程式測試一段時間後「Apache + MySQL + PHP」架構的穩定與快速巳深得老闆與公司所有同事的認同隨著公司業績蒸

蒸日上人員組織編罝愈來愈龐大跨部門的會議愈來愈多業務員每日排滿拜

訪客戶的行程跟客戶的 Email的往來也愈來愈頻繁 愈來愈多部門的同事希望公司能建置一套群組軟體提供 web mail可讓業

務人員方便收發 mail還有連絡人議事日程待辦工作書簽等功能讓整個

公司運作及個人時間管理更有效率

老闆問小明對這些需求有什麼看法小明認為如果這些功能完全由程式部

門開發必定曠日費時而且耗費公司資源小明在網路尋找是否有提供這些功能

的Free Software皇天不負苦心人小明發現了TWIG (The Web Information Gateway) httptwigscrewdrivernet這個群組軟體它在 Web 上整合郵件新聞聯絡人議事日程工作序書簽等功能非常符合公司的需求 Step 1 下載 twig-277targz 下載網址 httptwigscrewdrivernetdownloadphp3

Step 2 解開 twig-277targz tar -xzvf twig-277targz

59

Step 3 執行安裝動作安裝到 varwwwhtmltwig 目錄 cd twig-277 twig-install varwwwhtmltwig

Step 4 建立 MySQL 資料庫(twig)及各資料表

cd setup mysql -u root -p1234 mysqlgt create database twig Query OK 1 row affected (001 sec) mysqlgt quit mysql -u root ndashp1234 twiglt twigtablemysql

Step 5 修改 configincphp3 參數設定 vi varwwwhtmltwigconfigconfigincphp3 $config[fromdomain] = opencom 網域 $config[language] = chinesebig5 中文訊息 $config[imap_port] = 143notls

60

Step 6 修改連結 MySQL 的帳號密碼 vi varwwwhtmltwigconfigdbconfigincphp3 $dbconfig[sqlusername] = root username $dbconfig[sqlpassword] = 1234 password

Step 7 其他設定檔

vi etchttpdconfhttpdconf 加入 AddType applicationx-httpd-php php3 在 DirectoryIndex最後加入 indexphp3 DirectoryIndex indexhtml indexhtmlvar indexphp3 在 AddDefaultCharset ISO-8859-1加上 AddDefaultCharset ISO-8859-1

vi etcphpini register_globals = On service httpd restart Step 8 sendmail 設定 vi etcmailsendmailcf在 264 行前面加上並重新啟動 sendmail「service snedmail restart」 262 SMTP daemon options 263 264 O DaemonPortOptions=Port=smtpAddr=127001 Name=MTA 265 266 SMTP client options 267 O ClientPortOptions=Family=inet Address=00

61

Step 9 檢查設定有無錯誤 http主機名稱twigtestphp3

62

Step 10 登入 twig ( http主機名稱twig)

63

第六章 維護及更新程序

61 日常維護

系統管理員最好定期以 root 身份登入看看信件在 RedHat Linux 中有一支 logwatch 程式會定時去分析 log file如果發現異常便會發信給 root除此之外筆者建議讀者平時就檢查 MySQL log file ( varlogmysqldlog)是否有異常情形

62 更新程序

讀者可至httprpmfindnet 尋找MySQL相關套件至於升級的相關步驟請參

考Linux OS SOP 第 54節

63 備份重要檔案

預設 MySQL 的 DB 檔案是存在 varlibmysql 內以 DB名稱為目錄目錄

內就是該 DB 的所有資料通常得定期備份還有 MySQL的設定檔 etcmycnf也別忘了一起備份

64 離線備份與還原

641 離線備份

預設 MySQL 的 DB 檔案是存在 varlibmysql 內以 DB 名稱為目錄目錄內

就是該 DB 的所有資料像 CRM 這個 DB就是存在 varlibmysqlCRM 內在備份前因為怕資料尚未完全寫入磁碟而且 MySQL 會 Lock 在使用的 DB 檔案所以應該是要先把 MySQL 先 Shutdown 一下整個備份的程序可以下像下面的指令去完成 cd varlibmysql

64

service mysqld stop tar cvfz CRM_db_20030905tgz CRM service mysqld start 對這樣就可以了 不過要注意的是怕 DB 內每個 Tables 間的資料有關關

聯性所以最好是把整個 DB 一次備起來單獨只備哪個 Tables 的檔案以後回存時怕會有資料關聯不一致的問題

642 離線還原

DB 發生錯誤而要回存時其實也不難先找出最近一次完整正常的備份先把現在錯誤的網頁或 DB 先更名或 tar 起來再把好的備份給解開回原來目錄位

置就行了需要注意的是 MySQL 服務最好也是要先停止回存完成後再啟動服務回存 DB 的整個程序可能像下面 cd varlibmysql service mysqldstop mv CRM CRM_OLD tar xvfz CRM_db_20030905tg service mysqld start

65 線上備份與還原

651 線上備份

使用像上面的檔案方式備份是個不錯的方法它最少可以保持該主機某個時間點的完整檔案備份但還是有一些問題需要考慮到有些主機就不只建立一個 DB 而已總不能為了備份某個 DB 而把整個 MySQL 服務停止備份檔案的方式回存在原主機上一定適用但假如 MySQL 版本升級或是在那天該網頁空間需遷機移機到別的主機時那就沒人敢保證備出來的資料檔可以用所以我們可以考慮另一種備份的方式是使用 MySQL 本身提供的功能 MySQL Data Dump指令是 mysqldump

65

使用 MySQL 的 Dump 功能可以把 DB 的結構資料或結構加資料 Dump 成文字檔 mysqldump 指令提供的彈性很大你可以選擇把整個 DB Dump 成一個檔或是每個 Table 為一個檔甚至是把結構檔和資料分開儲存都

可以 mysqladmin -uroot -p flush-logs mysqldump CRM -uroot -p --opt gt CRM_20030905sql (CRM 是 DB 名稱 opt 是一個使用完整 Dump 參數) 假如只是要單獨 Dump 某個 Table 時只要在上面的指令後轉出符號 gt 前加個 Table 名稱就可以如只要 phpbb2_users 這個 Table 的 Dump 時只要下 mysqldump CRM -uroot -p --opt CUSTOMER gt CRM_CUSTOMER_20030905sql

652 線上還原

若要回存整個資料庫只需將壓縮的備份檔還原成 Dump 的檔案再用下面的指令回存 mysql CRM -uroot -p lt CRM_20030905sql 這邊需注意的是若建立備份時是以--opt或--add-drop-table為參數時回存的 動作是先將舊的 Table 先刪除重建 Table 的結構後再把 Data 匯入所以回存後所有的資料會回到你當時備份那個時間點因此在回存資料時可以考慮把現有錯誤或不完整的 DB 先備份一份下來以備不時之需或是拿來比對錯誤的地

方在那裡當然你也可以把資料回存到另一個測試用的 DB 內只要把上面指令

的 DB 名稱改成你的測試用 DB 名稱即可 使用這種回存方式 MySQL 服務不需停止也不會動到其他正在使用的 DB 在一些提供 MySQL 服務的虛擬主機可用這種方式作你自己的 DB 備份及回存

66

另外假如你是系統重建或是移機時切需在新的 MySQL 內新建一個空白 DB 後才行作回存的工作你可以用下面的指令建立 mysql -uroot -p -e CREATE DATABASE CRM (上面的 CRM是你要新建的 DB 名稱) 另一種作法先用 mysql 指令進入 mysql client console 然後再用 CREATE DATABASE CRM 這樣就行了記得尾端要加個 符號該行指令才會執行

67

第七章 問題與解答

Q1RedHat 90預附的 MySQL到底有無支援 Transcation機制 Ans MySQL自 32334a之後的 MySQL-Max版本加入 InnoDB的資料庫類型透過

InnoDBMySQL同樣可以進行 COMMIT與 ROLLRACK的動作RedHat 90預附的 MySQL為 32354a-11巳支援 InnoDB的資料庫類型不過必須做以

下設定 1cp usrsharedocmysql-server-32354amy-mediumcnf to etcmycnf 2 vi etcmycnf 將以下設定前的拿掉 innodb_data_home_dir = varlibmysql innodb_data_file_path = ibdata110Mautoextend innodb_log_group_home_dir = varlibmysql innodb_log_arch_dir = varlibmysql 3service mysqld restart 如此一來各位在建立Table時便可指定Table Type為 innodb ( ex create table with type=innodb ) Q2如何解決 php+mysql 許功蓋等字變亂的問題 Ans 方法一 【確定 MySQL 預設的字元集】 1 打開 WinMySQLadmin 管理畫面(在視窗右下角狀態列紅綠燈圖示中按滑鼠

右鍵點選 Show me 選項) 2 點選管理畫面中 [Variables] 標籤選項其中 character_set變數就是您預設

字元集的變數其預設是 latin1 字元集(我們要將他改回 big5)而 chatacters_set 變數則是 MySQL 可以支援哪些字元集 【修改預設字元集變數 character_set 】 1 請點選管理畫面中 [myini Setup] 標籤選項設定 myini 2 按一下 [Pick-up and Edit myini values] 按鈕以便編輯目前的 myini 設定 3 在 [mysqld] 設定區塊底下新增一行 default-character-set = big5 變數設

68

定 4 新增一個 [client] 設定區塊並加入第三步驟的變數設定(游標往下移到空白處新增兩行 [client] 和 default-character-set=big5) 5 按一下畫面左下方 [Save Modification] 按鈕儲存設定 6 重新啟動 MySQL 或 Windows 方法二 Server端注意事項 phpini 中有關的設定為(預設值) Magic quotes for incoming GETPOSTCookie data magic_quotes_gpc = On Use Sybase-style magic quotes (escape with instead of ) magic_quotes_sybase = Off Client端注意事項 1中文資料送進 mysql 前請用 addslashes($str) 處理 2處理後送進 mysql 時請用 括起來並在參數後留一個空白如 $sql = UPDATE ezf_table set tablename=$tname tableend=$endtime table inguser=$tguser tableingid=$tguserid tableallnumber=$tnumber tableloca l=$tablelocal tableanyone=$tableopen tabletext=$ttext WHERE tableid=$t ableid tablename=$tname c 取出時請用 stripslashes($str) Q3MySQL root 密碼忘了該怎麼辦 Ans 1先停掉 mysql etcrcdinitdmysql stop 2以--skip-grant-table 的參數啟動 mysql safe_mysql --skip-grant-tableamp 3 更改 root 密碼 mysql mysql mysqlgt UPDATE user SET password=password(newpassword)

69

WHERE user=root mysqlgt FLUSH PRIVILEGES mysqlgt exit 4停掉 mysql再重跑 mysqladmin -uroot -p shutdown Enter password 輸入新設定的密碼 etcrcdinitdmysql start

Q4NULL值問題

Ans

NULL值的概念是造成 SQL的新手的混淆的普遍原因他們經常認為 NULL是和一個空字符串的一樣的東西不是這樣的例如下列語句是完全不同的

mysqlgt INSERT INTO my_table (phone) VALUES (NULL)

mysqlgt INSERT INTO my_table (phone) VALUES ()

兩個語句把值插入到 phone 列但是第一個插入一個 NULL值而第二個插入一個空字符串第一個的含義可以認為是ldquo電話號碼不知道而第二個則可意味

著ldquo她沒有電話

在 SQL中NULL值在于任何其他值甚至 NULL值比較時總是假的(FALSE)包含 NULL的一個表達式總是產生一個 NULL值除非在包含在表達式中的運算符和函數的文檔中指出在下列例子所有的列返回 NULL

mysqlgt SELECT NULL1+NULLCONCAT(InvisibleNULL)

如果你想要尋找值是 NULL的列你不能使用=NULL測試下列語句不返回任

何行因為對任何表達式expr = NULL是假的

mysqlgt SELECT FROM my_table WHERE phone = NULL

要想尋找 NULL值你必須使用 IS NULL測試下例顯示如何找出 NULL電話號碼和空的電話號碼

70

mysqlgt SELECT FROM my_table WHERE phone IS NULL mysqlgt SELECT FROM my_table WHERE phone =

在 MySQL中就像很多其他的 SQL服務器一樣你不能索引可以有 NULL值的列你必須聲明這樣的列為 NOT NULL而且你不能插入 NULL到索引的

列中

當用 LOAD DATA INFILE 讀取數據時空列用更新如果你想要在一個列中有

NULL值你應該在文本文件中使用N字面上的詞NULL也可以在某些情形下使用

當使用 ORDER BY時首先呈現 NULL值如果你用 DESC以降序排序NULL值最後顯示當使用 GROUP BY時所有的 NULL值被認為是相等的

為了有助于NULL的處理你能使用 IS NULL和 IS NOT NULL運算符和 IFNULL()函數

對某些列類型NULL值被特殊地處理如果你將 NULL插入表的第一個TIMESTAMP 列則插入當前的日期和時間如果你將 NULL插入一個AUTO_INCREMENT 列則插入順序中的下一個數字

Q5如何將圖片存放於 MySQL中

Ans

Step 1建立資料庫 test

Step 2 建立表格 binary_data

CREATE TABLE binary_data (

id INT(4) NOT NULL AUTO_INCREMENT PRIMARY KEY

description CHAR(50)

bin_data LONGBLOB

filename CHAR(50)

filesize CHAR(50)

filetype CHAR(50)

71

)

Step 3 利用 storephp 寫入圖片

storephp 程式碼

ltHTMLgt ltHEADgtltTITLEgtStore binary data into SQL DatabaseltTITLEgtltHEADgt ltBODYgt lt code that will be executed if the form has been submitted

if ($submit) mysql_connect(localhostrootYOUR_PASSWORD) mysql_select_db(test) $data=Base64_Encode(fread(fopen($form_data r) filesize($form_data))) $result=MYSQL_QUERY(INSERT INTO binary_data (descriptionbin_datafilenamefilesizefiletype) VALUES ($form_description$data$form_data_name$form_data_size$form_data_type)) $id= mysql_insert_id() print ltpgtThis file has the following Database ID ltbgt$idltbgt MYSQL_CLOSE() else else show the form to submit new data

gt

ltform method=post action=ltphp echo $PHP_SELF gt enctype=multipartform-datagt File Descriptionltbrgt ltinput type=text name=form_description size=40gt ltINPUT TYPE=hidden name=MAX_FILE_SIZE value=4000000gt ltbrgtFile to uploadstore in databaseltbrgt ltinput type=file name=form_data size=40gt ltpgtltinput type=submit name=submit value=submitgt ltformgt lt

72

gt ltBODYgt ltHTMLgt

Step 3 利用 storephp 取出圖片

getdataphp 程式碼

lt Syntax getdataphp3id=ltidgt if($id) you may have to modify login information for your database server MYSQL_CONNECT(localhostrootYOUR_PASSWORD) mysql_select_db(test) $query = select bin_datafiletype from binary_data where id=$id $result = MYSQL_QUERY($query) $data = Base64_Decode(MYSQL_RESULT($result0bin_data)) $type = MYSQL_RESULT($result0filetype) Header( Content-type $type) echo $data gt

Q6MySQL裝好之後啟動時或是執行 mysqladmin會出現如下訊息 Cant connect to local MYSQL Server through Socket varlibmysqlmysqlsock或是

Cant connect to local MYSQL Server through Socket tmpmysqldsock

Ans 可能有下列幾個原因

1這個 mysqldsock 不見了被某人刪除了或是被一些系統自動執行程式給刪

了例如有些 cron任務便會設定定期刪除 tmp 裡的東西所以呢您只能修改

cron 裡的設定讓它不要清除 mysqldsock 2在啟動時也可以改變 mysqldsock的位置您在啟動 MySQL的時候可以加入此參數usrlocalmysqlbinsafe_mysqld --user=mysql --socket=其他路

徑socket amp 同時得去設定環境變數 MYSQL_UNIX_PORT的值以指定新的

73

路徑 3若是您沒改 MYSQL_UNIX_PORT的值那麼您可以在執行指令的時候才打

例如mysqladmin --socket=其他路徑socket version Q7How to get the last insert id Ans CREATE TABLE product ( id INT(4) NOT NULL AUTO_INCREMENT PRIMARY KEY description VARCHAR(50) ) 1利用 SQL的話 mysqlgt insert into product(description) values(123) Query OK 1 row affected (000 sec) mysqlgt select last_insert_id() +------------------+ | last_insert_id() | +------------------+ +------------------+ 1 row in set (000 sec) ======================================== 2如果是 PHP的話 你可以用mysql_insert_id()取得該 id PHP example $result=MYSQL_QUERY(INSERT INTO product (description) VALUES ($description)) $id= mysql_insert_id() print This file has the following Database ID $id Q8如何將文字檔匯入資料庫 Ans $addr=homehttpdhtmlphpschool001txt $sql_select = load data infile $addr into table test fields terminated by t 解說 $sql_select = load data infile 文字檔名 into table 表格名 fields terminated by

74

t

(欄位分隔以 TAB鍵) 該文字檔須與資料表欄位格式相符 例如欄位有三個 則文字檔為每行一筆資料如下 欄 1資料ltTABgt欄 2資料ltTABgt欄 3資料 欄 1資料ltTABgt欄 2資料ltTABgt欄 3資料 欄 1資料ltTABgt欄 2資料ltTABgt欄 3資料 欄 1資料ltTABgtltTABgt欄 3資料

Q9如何撰寫 MySQL C API Ans Step 1利用文字編輯器撰寫以下程式碼 mysqlcc

include ltstdiohgt

include ltmysqlmysqlhgt

int main (int argc char argv[])

MYSQL mysql

MYSQL_RES res

MYSQL_ROW row

if (argc = 2)

fputs (Usage myc ltdatabasegt stderr)

return 1

if ((mysql_connect(ampmysqllocalhostrootYour_Password)))

fputs (Error connecting stderr)

abort()

75

if (mysql_select_db(ampmysqlargv[1]))

fputs (Error selecting database stderr)

abort()

if (mysql_query(ampmysqlSELECT FROM test_table))

fputs (Error processing query stderr)

abort()

if ((res = mysql_store_result(ampmysql)))

fputs (Error storing results stderr)

abort()

while((row = mysql_fetch_row(res)))

uint i = 0

for (i=0 i lt mysql_num_fields(res) i++)

printf(s row[i])

printf(n)

return 0

Step 2 Compile

gcc -Iusrlocalmysqlinclude -Lusrlocalmysqllibmysql mysqlcc ndashlm -lmysqlclient

(其中 include path與 library path取決於你的 MySQL安裝路徑)

76

如果執行時發生如下 error Run problemerror in loading shared libraries libmysqlclientsoX 將你的 MySQL library path(for exampleusrlocalmysqllibmysql) 加入etcldsoconf and run sbinldconfig -v Q9ASP + MySQL 範例程式 Ans Dim myconn As New ADODBConnection Dim myrs As New Recordset Dim mySQL As String Dim myrows As Long myconnOpen DSN=MyODBCsample mySQL = SELECT from user myrsSource = mySQL Set myrsActiveConnection = myconn myrsCursorLocation = adUseClient myrsOpen myrows = myrsRecordCount myrsClose myconnClose 可參考 httpwwwdwamnetmysqlasp_myodbcasp 有詳細的資料 Q10如何將 MySQL中的資料庫匯出成txt檔 Ans select from TableName into outfile textxls all result fields will seperate by tab

77

第八章 參考資料

英文部份 網址 1 httpwwwmysqlcom MySQL 網站有第一手有關 MySQL的資料 2 httpwwwmysqlcomdocenReplicationhtml 有關 MySQL Replication 的文件 3 httpwwwgeocitiescomsqlhomefaqstore_blobhtml 如何在 MySQL 存放 BLOB的資料 4httpwwwsapdborg 有關 SAP跟 MySQL相關合作的網站 書藉 1 Cooking with MySQL

Paul DuBois has selected sample recipes from the hundreds youll find in his book MySQL

Cookbook In this third and final series of excerpts showcasing these recipes learn how to

compute team standings how to calculate the differences between successive Dec 26

2002 2 Tips for Building Web Database Applications with PHP and MySQL by Hugh E Williams co-author of Web Database Applications with PHP amp MySQL 04042002

3 Managing and Using MySQL 2nd Edition By Tim King George Reese Randy Jay Yarger

4 MySQL Cookbook By Paul DuBoisPublisher OReillyPub Date October 2002

中文部份

78

1 httplinuxtncedutwtechdocmysqlmysql_docmanual_tochtml MySQL 中文手冊 2 httpchenshloxaedutwphpZ_1php PHP+MySQ程式研習設計網站 3 httplinuxtncedutwtechdocbanicdownhtml PHP 4 手冊 4 httpwwwtncedutwadmin_zonephp台南縣教育網網路中心有很多 Linux相關文件 5 httpdobtncedutw網站建置百寶箱有很多 PHP MySQL 相關範例程式 5 httpwwwdbworldcomtw資料庫專家電子雜誌介紹資料庫的重要觀念及名詞

79

附錄一 SQL Command 介紹

SQL (讀音ess-que-el) 是一種結構查詢語法SQL 使用於資料庫交流

傳遞相容於 ANSI (American National Standards Institute) 是一套標準的關聯

式資料庫語言 SQL 語言是執行更新或從資料系統獲取資料一般常見的關聯

資料庫系統都有提供 SQL 如 Oracle Sybase Microsoft SQL Server Access Ingres 等雖然大部份的資料庫都有提供 SQL 但也多提供了自已獨特的語

法造成了不相容的情形但標準基本的語法是相通的如Select Insert Update Delete Create and Drop 每一個系統都有支援

Table相關 Command

Create Table

關聯式資料庫包含有很多元件稱為資料表(tables) 把資料或訊息放在資

料表中 資料表是以不同的名稱做分別資料表由欄列所構成的二維陣列

欄包含欄位名資料型態 及其他可判斷的資訊列是由全部欄位構成一筆一

筆的紀錄 create table 語法用在建立一個新的資料表語法格式如下

create table tablename (column1 data type column2 data type column3 data type)

Format of create table if you were to use optional constraints

create table tablename (column1 data type [constraint] column2 data type [constraint] column3 data type [constraint]) [ ] = optional

Note You may have as many columns as youd like and the constraints are optional

80

Example

create table employee (first varchar(15) last varchar(20) age number(3) address varchar(30) city varchar(20) state varchar(20))

注意建立資料表格式要以括號把前後框住而最後以(分號)做結尾

欄位名不要超過 30個字元長而且不要使用 sql 的關鍵字(如 where select等)而在後面接是型態的宣告(如字串數字日期格式等)

資料型態是來描述欄位的方式如一個欄位Last_Name 是一個姓氏可以使用varchar (可變動長度字串) 資料型態

以下是幾個常見的資料庫型態 char(size) 固定長度字串最長為 255 位元 varchar(size) 變動長度字串最大字元數以 size 來指定 number(size) 數值格式可以是整數也可以是小數最大數字以 size 位數判

斷未指定小數位數由系統內定 date 日期格式 number(sized) 數值格式最大數字以 size 位數判斷d 為小數位數整數位

數為 size-d 位

有何限制當資料表被建立通常有一或數個欄位是要使用來做關聯的功

能 例如unique 限制(唯一值)兩筆記錄不可以相同的值 not null (非空值)該欄位一定要輸入資料不可是空的primary key (主鍵)是每一筆記錄識別的主要方式

Drop a table drop table 刪除資料表(其中的資料也會一併刪除)

drop table tablename

Example

81

drop table 和刪除全部資料是不同的刪除全部資料欄位名稱資訊等還會

存在但刪除資料表會把這一些也一併移除掉

如何查詢資料

Select 基本用法

select 語法是關連式資料庫最常用的部份可以取得你想要的資料這是一個

簡單的範例 select column1[column2etc] from tablename [where condition] [] = optional 在 select 之後所列欄位名則是要顯示的資料部份你可以一一列出各欄位

名或是以 (星號)來代表選擇全部的欄位 from 之後放資料表名稱 where 子句 (選項) 指定要過濾的條件符合者才會顯現 where 可使用的條件運算元 = 等於 gt 大於 lt 小於 gt= 大或等於 lt= 小或等於 ltgt 大相等 LIKE 相似 For example select first last city

82

from empinfo where first LIKE Er 以Er 為開頭的字串就符合要以單引號框住 Or you can specify select first last from empinfo where last LIKE s 最後一字為 S 就符合 select from empinfo where first = Eric 則表示 first name 一定要是 Eric 才可以 範例資料表empinfo 統計函數

MIN 傳回指定欄位最小值

MAX 傳回指定欄位最大值

SUM 傳回指定欄位總和

AVG 傳回指定欄位平均值

COUNT 傳回指定欄位的筆數

COUNT() 傳回資料庫中的總筆數

統計函數使用於資料表中的數值欄位配合 SELECT 語法使用 只用於總結特定單一欄位可以配合 GROUP BY 做篩選但也可以不使用 GROUP BY 語句For example

SELECT AVG(salary) FROM employee

83

傳回全部 salary 平均值

Another example

SELECT AVG(salary) FROM employee WHERE title = Programmer

傳回 salary 平均值條件為 employees 資料表中當 title 等於 Programmer

Example

SELECT Count() FROM employees

傳回 employees 資料表中紀錄總筆數

GROUP BY 語法 SELECT column1 SUM(column2) FROM list-of-tables GROUP BY column-list The GROUP BY 語句可以先以所列的欄位為條件分組排序在一起(可以多欄

位) example 要列出每一個 dept 中最高 salary 值 SELECT max(salary) dept FROM employee GROUP BY dept HAVING 語法

SELECT column1 SUM(column2) FROM list-of-tables GROUP BY column-list HAVING condition

HAVING 子句是 GROUP BY 的一部份用來過濾在 GROUP BY 所選出的資料功能如同 select 命令中 where 條件式一樣只是 HAVING 必需配合 GROUP BY 使用

我們以例子來說明我們要取得每一公司名及每一公司的薪水平均值輸入如下

84

SELECT dept avg(salary) FROM employee GROUP BY dept

但如果我們只列出薪資平均值超過 20000元的公司資料

SELECT dept avg(salary) FROM employee GROUP BY dept HAVING avg(salary) gt 20000

ORDER BY子句語法

SELECT column1 SUM(column2) FROM list-of-tables ORDER BY column-list [ASC | DESC]

[ ] =選項

ORDER BY是一個選項子句當你以排序方式來顯示資料(正向由小到大反向由大到小)以指定的欄位資料做排序

ASC = 正向- 預設值 DESC = 反向排序

For example

SELECT employee_id dept name age salary FROM employee_info WHERE dept = Sales ORDER BY salary

以上列出公司代號公司名銷售員人名年紀及薪資而條件是公司名為 Sales 顯示順序以薪資多少排序(由小到大為預設值)

如果要以多個欄位做排序要以逗號做分隔如下

SELECT employee_id dept name age salary FROM employee_info WHERE dept = Sales ORDER BY salary age DESC

85

結合條件及布林運算 SELECT column1 SUM(column2) FROM list-of-tables WHERE condition1 AND condition2 AND運算可以結兩個或以上的條件放在 WHERE子句中 兩者都要為真才

會顯示該筆記錄 OR 運算可以結兩個或以上敘述放在 WHERE子句中只要其中一個為直就

會顯示該筆記錄 For example SELECT employeeid firstname lastname title salary FROM employee_info WHERE salary gt= 5000000 AND title = Programmer 必需要薪資大於等於 50000而且職稱為 Programmer同時符合才會顯示該筆資料 以下以括號括住雖然不是必需的但如此比較容易讀 SELECT employeeid firstname lastname title salary FROM employee_info WHERE (salary gt= 5000000) AND (title = Programmer) 另外範例 SELECT firstname lastname title salary FROM employee_info WHERE (title = Sales) OR (title = Programmer) 條件為只要是 Sales 或 Programmer 職稱的就會被列出 IN and BETWEEN 子句

SELECT column1 SUM(column2) FROM list-of-tables WHERE column3 IN (list-of-values) SELECT column1 SUM(column2) FROM list-of-tables WHERE column3 BETWEEN value1 AND value2 IN 子句使用在列舉項目的使用上也就是分別測試是否符合所列的值 For example

86

SELECT employeeid lastname salary FROM employee_info WHERE lastname IN (Hernandez Jones Roberts Ruiz) 條件為姓氏(astname)要符合 Hernandez Jones Roberts or Ruiz 其中一個才會被傳回 IN運算元也可以使用 OR 的語法來取代如下結果相同 SELECT employeeid lastname salary FROM employee_info WHERE lastname = Hernandez OR lastname = Jones OR lastname = Roberts OR lastname = Ruiz 但使用 IN 句子比較短也比較易懂 你也可以使用 NOT IN 來去掉不要的記錄 BETWEEN 運算元使用在判斷是否存在兩個數值之間 For example SELECT employeeid age lastname salary FROM employee_info WHERE age BETWEEN 30 AND 40 傳回年紀 30歲到 40歲之間的資料(含 30及 40歲者) 相同的也可以使用以下語法來達到相同的結果 SELECT employeeid age lastname salary FROM employee_info WHERE age gt= 30 AND age lt= 40 你也可使用 NOT BETWEEN 來濾掉中間值的資料 數學運算 標準 ANSI SQL-92 提供以下運算

87

+ 加

- 減

餘數

餘數為除法後剩整數這不在標準的 ANSI SQL 中但大部份的資料庫都會支

援這運算元以下列出有用的函數雖不在 ANSI SQL-92 提供但一般資料庫

也會支援他們

ABS(x) 傳回 x 絕對值

SIGN(x) returns the sign of input x as -1 0 or 1 (negative zero or positive respectively)

MOD(xy) 餘數 - returns the integer remainder of x divided by y (同 xy)

FLOOR(x) 傳回小或等於 x 的最大整數值

CEILING(x) or CEIL(x)

傳回大或等於 x 的最小整數值

POWER(xy) x的 y 次方

ROUND(x) 把 x 四捨五入為整數

ROUND(xd) 四捨五入取到小數 d 位

SQRT(x) x 開平方

For example SELECT round(salary) firstname FROM employee_info 傳回薪資取到整數位

如何新增資料

insert 加入一筆新紀錄到資料表中 insert into tablename (first_columnlast_column) values (first_valuelast_value) [] = optional Example insert into employee

88

(first last age address city state) values (Luke Duke 45 2130 Boars Nest Hazard Co Georgia) Note 字串要以單引號住如string 數字框住也無妨 insert into 後面接資料表名稱再接以括號括住的欄位名在 values 後括號分別對映各欄位的值 以上的例子新增了一筆名(first) 為 Luke而住所(state) 為 Georgia 的資料

如何刪除資料

delete 可以刪除單筆或多筆紀錄 delete from tablename where columnname OPERATOR value [and|or column OPERATOR value] [ ] = optional Examples delete from employee Note 如果你沒有指定 where 子句那麼全部的紀錄都會被刪除 delete from employee where lastname = May delete from employee where firstname = Mike or firstname = Eric delete from 接著資料表名 再接著是條件式判斷沒有條件式則全部紀錄會

被刪除

如何更新資料

update 用來更新你所指定的記錄要和 WHERE 配合小心使用 語法 update tablename set columnname = newvalue[nextcolumn = newvalue2] where columnname OPERATOR value [and|or column OPERATOR value] [] = optional Examples

89

update phone_book set area_code = 623 where prefix = 979 update phone_book set last_name = Smith prefix=555 suffix=9292 where last_name = Jones update employee set age = age+1 where first_name=Mary and last_name=Williams

90

附錄二Replication

測試環境

RedHat 90 + MySQL 32358 MySQL資料庫路徑 varlibmysql MySQL設定檔 etcmycnf Master IP 1921680100 Slave IP 1921680200 請至下列網址下載最新MySQL 32358套件並利用rpm ndashUvh 更新 httpupdatesredhatcom9enosi386

圖 最新 MySQL 套件

測試架構圖

91

1921680100

1921680200Master Server

erveSlave S r

圖 測試架構圖

測試步驟

Master server 部份 Step1 確認 MasterSlave機器上所裝的 MySQL版本能進行

replication( 32329 or higher ) Step2 在 Master MySQL上開放一個帳號給 Slave mysql ndashu root ndashp mysqlgtGRANT FILE ON TO repl1921680200 IDENTIFIED BY lsquoabc123rsquo mysqlgtq 上面是 Master開放一個帳號 repl密碼 abc123給 IP1921680200有檔案處理

的權限 Step3 shutdown MySQL on the Master mysqladmin ndashu root ndashp shutdown Step4 備份 Master所有資料庫 tar ndashcvf tmpmysql-snapshottar varlibmysql 注意tar的時候MySQL是要在 stop情況下 在mysql (wwwmysqlcom) 網站的FAQ有不用shutdown的方法

92

Step5 在 master機器上修改etcmycnf 在[mysqld]區段內加入參數 log-bin server-id=這邊設定 server-id=1 sql-bin-update-same binlog-do-db=CRM只針對 CRM資料庫做紀錄 Step6 Restart MySQL on the master service mysqld start 此時因為有加入 log-bin 參數因此開始有 index產生了在varlibmysql目錄下

有index檔案紀錄資料庫的異動 log Slave server 部份 Step1 在 slave設定etcmycnf 在[mysqld]區段加入 master-host= master-user= master-password= master-port= server-id= 這邊設定 master-host=1921680100 master-user=repl master-password=abc123 master-port=3306 server-id=2 master-connect-retry=60預設重試間隔 60秒 replicate-do-db=CRM告訴 slave只做 CRM資料庫的更新 log-slave-updates Step2 將 master上的 mysql-snapshottar copy到 slave上 用 ftp傳到 slave的tmp Step3 解壓縮 Master資料庫至 Slave Server上 cd varlib tar xvf tmpmysql-snapshottar chown ndashR mysqlmysql mysql

93

chmod ndashR 770 mysql (視情況) Step4 Restart MySQL on the slave server 這時在varlibmysql目錄會出現 masterinfo此檔案紀錄了 Master MySQL server的資訊

狀況測試

One-way replication

1921680100

1921680200Master Server

erveSlave S r

圖 One-way replication架構圖 Step1 Master跟 Slave網路及服務都正常情況下由 Master端異動資料後 到 Slave端瀏覽資料檢視是否有進行 replication Step2 模擬 Slave Server 當機 可用在於 slave真的當機或是 Slave 不一定需要一直跟 master connect將Slave MySQL server shutdown由 Master端異動資料到 slave端瀏覽此時Slave應該沒有被 replication 更新然後再將 Slave端 MySQL server start起來

預設 60秒後 Slave會嘗試跟 Master要求進行 replication再去 Slave端檢視是否有更新資料

94

Step3 模擬 Master當機因為是設定 One-way replication一旦 Master Server Slave端沒有 Master的 source可以 download Two-way replication 基於 Master當機狀況於是發展雙向 Replication即 1921680100 ( Host A ) 1921680200 ( Host B )都分別擔任 MasterSlave身分

1921680100

1921680200er

Server B MasterSlave Server

Server A MasterSlave Serv

圖 Two-way replication架構圖 以下是針對兩台 MySQL伺服器進行雙向 Replication Step1觀念同單向 replication只是改成 Master也有 Slave身分 Slave也有Master的身分先分別在 Server AServer B 都去 grant一個進行 replication的身分 [A]mysqlgtGRANT FILE ON TO repl1921680200 IDENTIFIED BY lsquoabc123rsquo [B]mysqlgt GRANT FILE ON TO repl1921680100 IDENTIFIED BY lsquoabc123rsquo Step2做完單向 replication後stop Server Aserver B MySQL service此時 AB資料是一樣的

95

修改etcmycnf設定 範例 Server A [mysqld] datadir=varlibmysql socket=varlibmysqlmysqlsock server-id=1 log-bin sql-bin-update-same binlog-do-db=CRM master-host=1921680200 master-user=repl master-password=abc123 log-slave-updates master-connect-retry=60 replicate-do-db=CRM Server B [mysqld] datadir=varlibmysql socket=varlibmysqlmysqlsock server-id=2 log-bin sql-bin-update-same binlog-do-db=CRM master-host=1921680100 master-user=repl master-password=abc123 log-slave-updates master-connect-retry=60 replicate-do-db=CRM 分別 start Server AServer B MySQL後此時雙方都是 MasterSlave身分一旦哪一方資料異動就會通知對方來 replication-若 replication失效則必須將Server AServer B的masterinfo及index00x 都砍掉然後分別 restart MySQL server進行測試檢視成果 實務上通常如果需要做Two-way replication通常會搭配Virtual Server使用

96

在前端架設一台Virtual Server不過此部份不在此份SOP討論範圍內有興趣

的讀者可參考 httpwwwlinuxvirtualserverorg 網站

1921680100 1921680200

Host A MasterSlave Server

Host B MasterSlave Server

Virtual Host

圖 Virtual Server + Two-way replication 架構圖

97

圖 High Availability Linux Virtual Server架構圖

98

  • COSA-SOP-03-006
  • 第一章 簡介
    • 11適用對象 (Audience)
    • 12 MySQL本身
    • 13 MySQL 40版跟50版重大的改進功能
    • 14 各家資料庫軟體比較
      • 第二章 前置需求
      • 第三章 安裝
        • 31 MySQL安裝
        • 32 phpMyAdmin安裝
        • 33 升級及注意事項
          • 第四章 MySQL管理
            • 41 Webmin 管理介面
            • 42 phpMyAdmin 的操作介面
            • 43管理指令介紹
              • 431 利用mysqladmin設定root的密碼
                  • 第五章 實用範例
                    • 51 任務一Web Base客戶通訊錄
                    • 52 任務二Web Base群組軟體 ( twig )
                      • 第六章 維護及更新程序
                        • 61 日常維護
                        • 62 更新程序
                        • 63 備份重要檔案
                        • 64 離線備份與還原
                        • 65 線上備份與還原
                          • 第七章 問題與解答
                          • 第八章 參考資料
                          • 附錄一 SQL Command 介紹
                          • 附錄二Replication
Page 10: DataBase Server Standard Operation Procedureebooks.lib.ntu.edu.tw/1_file/oss/63/93doc4-5.pdf · 業務的公司帶來了不少壓力,譬如微軟,甲骨文 ... 外的錢用在第三方的資料庫產品上,譬如就可以不用再購買甲骨文公司

庫對資料庫的最佳化主要在於你對他的設定和資料庫結構的設計如果你的

資料庫結構設計得非常差你的存取速度還是會受到影響而變得比較慢

10

第二章 前置需求

在安裝 MySQL之前請確定 Apache及 MySQL亦巳安裝相關步驟請參考

Apache SOP安裝 Apache及 PHP相關章節

11

第三章 安裝

31 MySQL安裝

在 RedHat 90上安裝 MySQL是件很容易的事因為 RedHat 90提供了一

個很方便的 GUI套件管理工具「redhat-config-packages」各位只要把 RedHat 90第一片光碟放入並以 root的身份登入系統鍵入 redhat-config-packages勾選「SQL資料庫伺服器」即可然後按「更新」如果遇到任何相依性問題

系統會提示您更換光碟片 ( 圖 3-1 ~ 3-3 ) Step 1 執行 redhat-config-packes

圖 3-1

Step 2 選擇資料伺服器

12

圖 3-2

Step 3檢查是否安裝成功 待安裝後您可以用利用「rpm -qa | grpe ^mysql」檢查是否安裝成功

圖 3-3

啟動 MySQL ( Command Mode )馬上啟動 MySQL的指令為「service mysqld start」如果您希望一開機就自動啟動 MySQL請執行「chkconfig mysqld on」

13

圖 3-4

啟動 MySQL ( WebMin 介面 ) 我們也可以利用WebMin 來啟動 MySQL步驟如下 Step 1登入Webmin

圖 3-5 登入WebMin

Step 2 選擇伺服器

14

圖 3-6 伺服器畫面

Step 2 選擇 MySQL資料庫伺服器

圖 3-7 伺服器畫面

15

Step 3 啟動 MySQL資料庫伺服器

圖 3-8 啟動 MySQL

更改資料庫管理者密碼

成功啟動 MySQL後因為資料庫管理者預設沒有密碼建議使用前更改系

統管理者密碼請輸入下列指令

mysqladmin ndashu root ndashh cosaexamplecom password lsquo1234rsquo -u 表示使用者帳號root 為 MySQL預設的管理帳號

-h 表示 MySQL主機的主機名稱也可使用 IP Address password 表示使用者的密碼因為字串請使用單引號將密碼括起來

圖 3-9 修改 MySQL 的密碼

16

32 phpMyAdmin安裝

本書除了會介紹利用當今 Linux上最紅的整合管理工具Webmin 來管理

MySQL外還會為各位介紹專門管理 MySQL的工具 phpMyAdmin phpMyAdmin是免費的 PHP原始程式碼的Web網站可用來管理整個

MySQL伺服器這是一套Web介面的 MySQL管理程式支援中文的使用者介

面 phpMyAdmin只需透過瀏覽器就可管理 MySQL伺服器換句話說不論

MySQL是安裝在 Linux或是Windows 作業系統都可以使用相同步驟在

MySQL上建立資料庫(Database)資料表(Table)和編輯紀錄(Record) Step 1 下載phpMyAdmin ( httpwwwphpmyadminnet )選擇最櫎新穩定的版

本 253

圖 3-10 httpwwwphpmyadminnet

17

圖 3-11 下載 phpMyAdmin-253-phptarbz2

Step 2 將 phpMyAdmin-253-phptarbz2收至 tmp 並執行下列指令將其解壓

縮至varwww tar jxvf phpMyAdmin-253-phptarbz ndashC varwwwhtml

圖 3-12 解壓縮安裝 phpMyadmin-253

Step 3 為了操作方便起見建立 Soft link ln ndashs phpMyAdmin-253 phpMyAdmin

圖 3-13 修改 phpMyadmin 設定檔 configincphp

18

Step 4 修改 phpMyadmin 設定檔 configincphp gedit varwwwhtmlphpMyAdminconfigincphp

圖 3-14 configincphp設定檔

Step 5 設定顯示行號以方便修改 configincphp 設定檔

19

圖 3-15 顯示行號

Step 6 修改下列設定 第 39 行 設定 phpMyAdmin的 URL 第 69 行 MySQL Server 的 ip 第 80 行 利用何帳號存取 MySQL 第 81 行 如果 root有設定 password此處即填入 root的 password

30 In most cases you can leave this variable empty as the correct value

31 will be detected automatically However we recommend that you do

32 test to see that the auto-detection code works in your system A good

33 test is to browse a table then edit a row and save it There will be

34 an error message if phpMyAdmin cannot auto-detect the correct value

35

36 If the auto-detection code does work properly you can set to TRUE the

37 $cfg[PmaAbsoluteUri_DisableWarning] variable below

38

39 $cfg[PmaAbsoluteUri] = httpossccosaorgtwphpMyAdmin

hellip

20

hellip

69 $cfg[Servers][$i][host] = localhost MySQL hostname or IP address hellip 80 $cfg[Servers][$i][user] = root MySQL user

81 $cfg[Servers][$i][password] = 1234 MySQL password (only needed

圖 3-16 修改 configincphp

21

圖 3-17 修改 configincphp

圖 3-18 修改 configincphp p

Step 7 設定語系

22

圖 3-19 設定語系

圖 3-20 執行 phpMyAdmin

23

33 升級及注意事項

RedHat 90附的 MySQL版本為 323 MySQL所釋出最新穩定版本為

40若是您不想用系統預附的 323請先利用下列移除之前 323的版本

rpm ndashe mysql-devel rpm ndashe mysql-server rpm ndashe mysql --nodeps 然後到下列網址下載您所想要的版本進行安裝在這裏我們用 4014版為例 Step 1 下載相關套件( httpwwwmysqlcomdownloadsmysql-40html )

圖 3-21 Download MySQL 4014 相關 RPM Step 2 利用 rpm 指令安裝

24

圖 3-22 Install MySQL 4014 相關 RPM

圖 3-23 Install MySQL 4014 相關 RPM

Step 3 啟動 MySQL

25

圖 3-24 啟動 MySQL 4014 並修改密碼

26

第四章 MySQL管理

本章將我們介紹利用WebminphpAdminCommand的方式建立一個名為

CONTACT的資料庫內有一個 address的 Table作為我們客戶通訊錄程式使

用的資料庫

41 Webmin 管理介面

412建立資料庫

Step 1 登入Webmin

圖 4-1 登入WebMin

Step 2 點選伺服器

27

圖 4-2 伺服器畫面

Step 3 點選 MySQL資料庫伺服器

圖 4-3 MySQL資料庫伺服器

28

Step 4 建立一個新的資料庫

圖 4-4 建立 MySQL資料庫

Step 5 建立名為 CONTACT的資料庫

29

圖 4-5 指定資料庫名稱

412 建立資料表

假設我們要建立一個名為 address的 Table其結構如下 欄位名稱 資料型態 長度 說明 id INT (自動編號) 連絡人編號 name varchar文字 20 連絡人姓名 tel Varchar文字 15 連絡人電話 Step 1 選擇 CONTACT資料庫

30

圖 4-6 選擇資料庫

Step 2 指定欄位數目

31

圖 4-7 設定欄位數目

Step 3設定表格欄位屬性

圖 3-8 設定表格欄位屬性

Step 4建立表格資料

32

圖 4-9 建立表格資料

圖 4-10 檢視資料

33

圖 4-11 新增資料

圖 4-12

34

圖 4-13

413 使用者管理

接下來我們要利用Webmin 來建立資料庫使用者並給予某些權限 Step1建立使用者

35

圖 4-14 選擇使用者權限

圖 4-15

36

Step2 賦予權限

圖 4-16

Step3 權限列表

37

圖 4-17

38

42 phpMyAdmin 的操作介面

421建立資料庫

Step 填入資料庫名稱並按「建立」

圖 4-18建立資料庫

422 建立資料表

Step1 填入資料表名稱並指定欄位數量 執行

39

圖 4-19填入資料表名稱並指定欄位數量

Step2 設定欄位屬性

圖 4-20設定欄位屬性

40

Step3 phpMyAdmin會產生相關的 SQL Command

圖 4-21 資料表結構及相關 SQL Command

Step4新增 Record

41

圖 4-22

圖 4-23

42

圖 4-24

圖 4-25

43

423使用者管理

Step1建立使用者

圖 4-26

44

圖 4-27

Step2 給予權限

圖 4-28

Step3權限列表

45

圖 4-29

43管理指令介紹

431 利用 mysqladmin設定 root的密碼

當您在Windows 或 Linux 中安裝好 MySQL後系統會自動幫您建立兩個

帳分別是 root 和 匿名者MySQL的 root 跟 Linux 最高權限使用者 root無關MySQL的 root使用者相當於 MS SQL 中的 sa 帳號擁有最高的 Database管理權限但系統預設 MySQL的 root 是不需要密碼所以通常我們一安裝

MySQL後首要任務便是修改 root的密碼 我們可以利用 mysqladmin工具或是直接修改 MySQL內部資料庫的使用者資

料 mysqladmin ndashu root ndashh cosaexamplecom password lsquo1234rsquo

46

-u 表示使用者帳號root 為 MySQL預設的管理帳號

-h 表示 MySQL主機的主機名稱也可使用 IP Address password 表示使用者的密碼因為字串請使用單引號將密碼括起來 密碼設定完成之後還是可以利用 mysqladmin修改密碼但是你必須提供目前的密碼

432 連線 MySQL

mysql -uroot -p密碼 (-p和密碼之間不能有空白) 或 mysql -uroot -p (此方式會在進入後要求密碼) [rootossc phpMyAdmin] mysql -u root -p1234

Welcome to the MySQL monitor Commands end with or g

Your MySQL connection id is 25 to server version 32354

Type help or h for help Type c to clear the buffer

mysqlgt show databases

+----------+

| Database |

+----------+

| mysql |

| test |

+----------+

2 rows in set (000 sec)

mysqlgt exit

Bye

[rootossc phpMyAdmin]

433 建立資料庫

可利用 mysqladmin指令建立 CONTACT資料庫 mysqladmin -u root -p1234 create CONTACT

47

或是利用 mysql指令 [rootossc bluepage] mysql -u root -p1234 Welcome to the MySQL monitor Commands end with or g Your MySQL connection id is 1057 to server version 32354 Type help or h for help Type c to clear the buffer mysqlgt create database CONTACT Query OK 1 row affected (000 sec) mysqlgt show databases +----------+ | Database | +----------+ | CONTACT | | address | | hello | | mysql | | nuke | | test | +----------+ 6 rows in set (000 sec) mysqlgt exit

434 建立資料表

編寫 adresssql內容如下 -- Table structure for table address CREATE TABLE address ( id int(11) NOT NULL auto_increment name varchar(20) NOT NULL default tel varchar(15) NOT NULL default PRIMARY KEY (id) ) TYPE=MyISAM

48

-- Dumping data for table address INSERT INTO address VALUES (1林小明0800016888) INSERT INTO address VALUES (2黃大雄0800016888) INSERT INTO address VALUES (3劉小芬0800024365) 然後執行此 sql script mysql -u root -p1234 CONTACT lt addresssql 或是利 mysql command [rootossc bluepage] mysql -u root -p1234 Welcome to the MySQL monitor Commands end with or g Your MySQL connection id is 1090 to server version 32354 Type help or h for help Type c to clear the buffer mysqlgt use CONTACT Database changed Database changed mysqlgt CREATE TABLE address ( -gt id int(11) NOT NULL auto_increment -gt name varchar(20) NOT NULL default -gt tel varchar(15) NOT NULL default -gt PRIMARY KEY (id) -gt ) TYPE=MyISAM Query OK 0 rows affected (000 sec) mysqlgt INSERT INTO address VALUES (1林小明0800016888) Query OK 1 row affected (000 sec) mysqlgt INSERT INTO address VALUES (2黃大雄0800016888) Query OK 1 row affected (000 sec) mysqlgt INSERT INTO address VALUES (3劉小芬0800024365) Query OK 1 row affected (000 sec) mysqlgt exit Bye

49

第五章 實用範例

51 任務一Web Base客戶通訊錄

任職於開放科技公司的林小明前些日子在最符合成本效益的條件下快

速地完成公司網站的建置老闆因此對小明讚譽有加最近因為公司存放客戶資

料的 SQL Server主機屢遭病毒攻擊加上作業系統本身的問題當機次數頻繁

老闆希望能儘快把公司的客戶通訊錄程式移轉到較穩定的環境上因為此客戶通

訊錄程式最主要給內部人員使用所以介面美觀並不特別要求只求穩定且能快

速得到查詢結果老闆希望在短時間先看到程式的雛型並鍵入資料對其效率

及穩定性進行測試因為上次小明表現突出所以這次不可能的任務自然又落到

小明身上 小明想來想去既然要快速又穩定他而且又不希望所有人都得安裝 Client

程式於是小明決定)捨棄他的舊愛「Delphi+MS SQL」投向新歡「Apache + MySQL + PHP」利用此架構來設計一個簡單實用的Web Base客戶通訊錄程式

511 Web Base客戶通訊錄架構

此程式需要建立 CONTACT的資料庫並建立 adress Tables其結構如下表建立步驟請參考第三章 欄位名稱 資料型態 長度 說明 id INT (自動編號) 連絡人編號 name varchar文字 20 連絡人姓名 tel Varchar文字 15 連絡人電話 Web Base通訊錄共有下列幾個檔案功能如下表

檔案名稱 說明 Indexhtml Web Base通訊錄首頁 addphp 新增連絡人的 php程式 searchphp 尋找連絡人的 php程式 editphp 具有更新及刪除功能的 php程式

50

我們將這些檔案放至varwwwhtmlbluepage (預設無 bluepage目錄)

512 Web Base通訊錄測試

httpwwwopencombluepage 新增資料

圖 5-1 新增連絡人

圖 5-2 填入資料

51

圖 5-3 新增成功

搜尋及異動資料

圖 5-4 搜尋通訊錄

52

圖 5-5 編輯資料

圖 5-6 更新資料

513 程式內容及說明

lt-- 程式範例indexhtml--gt lthtmlgt ltheadgtlttitlegt通訊錄lttitlegtltheadgt ltbodygt ltcentergt

53

lth2gt通訊錄lth2gtlthrgt lta href=indexhtmlgt通訊錄ltagt | lta href=addphpgt新增連絡人ltagt | lta href=searchphpgt搜尋通訊錄ltagt ltcentergt ltbodygt lthtmlgt lt-- 程式範例addphp --gt lthtmlgt ltheadgtlttitlegt新增連絡人lttitlegtltheadgt ltbodygt ltcentergtlth2gt新增連絡人lth2gtltcentergtlthrgt lt 取得欄位資料 if (isset($_POST[Name]) ampamp isset($_POST[Tel]) ) $name = $_POST[Name] $tel = $_POST[Tel] 檢查是否有輸入欄位資料 if ($name = ampamp $tel = ) 建立 SQL字串 $sql = INSERT INTO address (name tel) values( $sql= $name $tel) 建立 MySQL 連結 $link = mysql_connect(localhostroot1234) 選擇資料庫 mysql_select_db(CONTACT) 執行 SQL指令 mysql_query($sql) mysql_close($link) echo ltfont color=redgt新增連絡人成功ltfontgtltbrgt gt ltform action=addphp method=postgt lttable border=0 width=300gt lttrgtlttdgt姓名 lttdgt

54

lttdgtltinput type=text name=Name size=20 maxlength=10gtlttdgtlttrgt lttrgtlttdgt電話 lttdgt lttdgtltinput type=text name=Tel size=20 maxlength=20gtlttdgtlttrgt lttrgtlttd colspan=2 align=centergt ltinput type=submit value=新增連絡人gtlttdgtlttrgt lttablegt ltformgt ltbrgtlta href=indexhtmlgt通訊錄ltagt | lta href=addphpgt新增連絡人ltagt | lta href=searchphpgt搜尋通訊錄ltagt ltbodygt lthtmlgt

lt-- 程式範例searchphp --gt lthtmlgt ltheadgtlttitlegt搜尋通訊錄lttitlegtltheadgt ltbodygt ltcentergtlth2gt搜尋通訊錄lth2gtlthrgt lt if (isset($_POST[Search])) 建立資料庫連結並選定資料庫 $link = mysql_connect(localhostroot1234) mysql_select_db(CONTACT) 建立基本的 SQL字串 $sql = SELECT FROM address 檢查是否輸入姓名 if (chop($_POST[Name]) = ) $name = name LIKE $_POST[Name] else $name = 檢查是否輸入電話號碼 if (chop($_POST[Tel]) = ) $tel = tel LIKE $_POST[Tel] else $tel =

55

if條件組合 SQL字串 if (chop($name) = ampamp chop($tel) = ) $sql= WHERE $name AND $tel elseif (chop($name) = ) 只有姓名 $sql = WHERE $name elseif (chop($tel) = ) 只有電話號碼 $sql = WHERE $tel $sql= ORDER BY name 最後加上排序 $result = mysql_query($sql) 取得欄位數 $total_fields = mysql_num_fields($result) echo lttable border=1gt echo lttrgtlttdgt編號lttdgtlttdgt姓名lttdgtlttdgt電話lttdgtlttd colspan=2gt功能選項lttdgtlttrgt 表格顯示查詢結果 while ($rows = mysql_fetch_array($result MYSQL_NUM)) echo lttrgt for ($i = 0 $i lt $total_fields $i++) echo lttdgt$rows[$i]lttdgt echo lttdgtlta href=editphpaction=editampid= echo $rows[0]gtltbgt編輯ltbgtlttdgt echo lttdgtlta href=editphpaction=delampid= echo $rows[0]gtltbgt刪除ltbgtlttdgt echo lttrgt echo lttablegtlthrgt mysql_free_result($result) mysql_close($link) gt ltcentergt ltform action=searchphp method=postgt lttable border=0 width=450gt lttrgtlttdgt搜尋姓名 lttdgt lttdgtltinput type=text name=Name size=10 maxlength=20gtlttdgtlttrgt lttrgtlttdgt搜尋電話 lttdgt lttdgtltinput type=text name=Tel

56

size=20 maxlength=20gtlttdgtlttrgt lttrgtlttd colspan=2 align=centergt ltinput type=submit name=Search value=搜尋gtlttdgtlttrgt lttablegt ltformgt ltbrgtlta href=indexhtmlgt通訊錄ltagt | lta href=addphpgt新增連絡人ltagt | lta href=searchphpgt搜尋通訊錄ltagt ltbodygt lthtmlgt

lt ob_start() gt lt-- 程式範例editphp --gt lthtmlgt ltheadgtlttitlegt編輯通訊錄lttitlegtltheadgt ltbodygt lt 取得 URL 參數 $id = $_GET[id] $action = $_GET[action] 建立資料庫連結 $link = mysql_connect(localhostroot1234) mysql_select_db(CONTACT) 選擇資料庫 執行的操作 switch ($action) case update 更新 取得欄位資料 $name = $_POST[Name] $tel = $_POST[Tel] $sql = UPDATE address SET name=$name tel=$tel WHERE id=$id mysql_query($sql) 執行 SQL指令 mysql_close($link) header(Location searchphp) 轉向到 serachphp break case del 刪除 $sql = DELETE FROM address WHERE id=$id

57

mysql_query($sql) 執行 SQL指令 mysql_close($link) header(Location searchphp) 轉向到 serachphp break case edit 編輯 $sql = SELECT FROM address WHERE id=$id $result = mysql_query($sql) 執行 SQL指令 $row = mysql_fetch_row($result) 取回記錄 $name = $row[1] 取得欄位 name $tel = $row[2] 取得欄位 tel mysql_close($link) 顯示編輯表單 gt ltcentergtlth2gt更新通訊錄lth2gtltcentergtlthrgt ltform action=editphpaction=updateampid=lt echo $id gt method=postgt lttable border=0 width=300gt lttrgtlttdgt姓名 lttdgt lttdgtltinput type=text name=Name size=20 maxlength=10 value=lt echo $name gtgtlttdgtlttrgt lttrgtlttdgt電話 lttdgt lttdgtltinput type=text name=Tel size=20 maxlength=20 value=lt echo $tel gtgtlttdgtlttrgt lttrgtlttd colspan=2 align=centergt ltinput type=submit value=更新連絡人gtlttdgtlttrgt lttablegt ltformgt ltbrgtlta href=indexhtmlgt通訊錄ltagt | lta href=addphpgt新增連絡人ltagt | lta href=searchphpgt搜尋通訊錄ltagt lt break gt ltbodygt lthtmlgt

58

52 任務二Web Base群組軟體 ( twig )

順利完成Web Base客戶通訊錄程式測試一段時間後「Apache + MySQL + PHP」架構的穩定與快速巳深得老闆與公司所有同事的認同隨著公司業績蒸

蒸日上人員組織編罝愈來愈龐大跨部門的會議愈來愈多業務員每日排滿拜

訪客戶的行程跟客戶的 Email的往來也愈來愈頻繁 愈來愈多部門的同事希望公司能建置一套群組軟體提供 web mail可讓業

務人員方便收發 mail還有連絡人議事日程待辦工作書簽等功能讓整個

公司運作及個人時間管理更有效率

老闆問小明對這些需求有什麼看法小明認為如果這些功能完全由程式部

門開發必定曠日費時而且耗費公司資源小明在網路尋找是否有提供這些功能

的Free Software皇天不負苦心人小明發現了TWIG (The Web Information Gateway) httptwigscrewdrivernet這個群組軟體它在 Web 上整合郵件新聞聯絡人議事日程工作序書簽等功能非常符合公司的需求 Step 1 下載 twig-277targz 下載網址 httptwigscrewdrivernetdownloadphp3

Step 2 解開 twig-277targz tar -xzvf twig-277targz

59

Step 3 執行安裝動作安裝到 varwwwhtmltwig 目錄 cd twig-277 twig-install varwwwhtmltwig

Step 4 建立 MySQL 資料庫(twig)及各資料表

cd setup mysql -u root -p1234 mysqlgt create database twig Query OK 1 row affected (001 sec) mysqlgt quit mysql -u root ndashp1234 twiglt twigtablemysql

Step 5 修改 configincphp3 參數設定 vi varwwwhtmltwigconfigconfigincphp3 $config[fromdomain] = opencom 網域 $config[language] = chinesebig5 中文訊息 $config[imap_port] = 143notls

60

Step 6 修改連結 MySQL 的帳號密碼 vi varwwwhtmltwigconfigdbconfigincphp3 $dbconfig[sqlusername] = root username $dbconfig[sqlpassword] = 1234 password

Step 7 其他設定檔

vi etchttpdconfhttpdconf 加入 AddType applicationx-httpd-php php3 在 DirectoryIndex最後加入 indexphp3 DirectoryIndex indexhtml indexhtmlvar indexphp3 在 AddDefaultCharset ISO-8859-1加上 AddDefaultCharset ISO-8859-1

vi etcphpini register_globals = On service httpd restart Step 8 sendmail 設定 vi etcmailsendmailcf在 264 行前面加上並重新啟動 sendmail「service snedmail restart」 262 SMTP daemon options 263 264 O DaemonPortOptions=Port=smtpAddr=127001 Name=MTA 265 266 SMTP client options 267 O ClientPortOptions=Family=inet Address=00

61

Step 9 檢查設定有無錯誤 http主機名稱twigtestphp3

62

Step 10 登入 twig ( http主機名稱twig)

63

第六章 維護及更新程序

61 日常維護

系統管理員最好定期以 root 身份登入看看信件在 RedHat Linux 中有一支 logwatch 程式會定時去分析 log file如果發現異常便會發信給 root除此之外筆者建議讀者平時就檢查 MySQL log file ( varlogmysqldlog)是否有異常情形

62 更新程序

讀者可至httprpmfindnet 尋找MySQL相關套件至於升級的相關步驟請參

考Linux OS SOP 第 54節

63 備份重要檔案

預設 MySQL 的 DB 檔案是存在 varlibmysql 內以 DB名稱為目錄目錄

內就是該 DB 的所有資料通常得定期備份還有 MySQL的設定檔 etcmycnf也別忘了一起備份

64 離線備份與還原

641 離線備份

預設 MySQL 的 DB 檔案是存在 varlibmysql 內以 DB 名稱為目錄目錄內

就是該 DB 的所有資料像 CRM 這個 DB就是存在 varlibmysqlCRM 內在備份前因為怕資料尚未完全寫入磁碟而且 MySQL 會 Lock 在使用的 DB 檔案所以應該是要先把 MySQL 先 Shutdown 一下整個備份的程序可以下像下面的指令去完成 cd varlibmysql

64

service mysqld stop tar cvfz CRM_db_20030905tgz CRM service mysqld start 對這樣就可以了 不過要注意的是怕 DB 內每個 Tables 間的資料有關關

聯性所以最好是把整個 DB 一次備起來單獨只備哪個 Tables 的檔案以後回存時怕會有資料關聯不一致的問題

642 離線還原

DB 發生錯誤而要回存時其實也不難先找出最近一次完整正常的備份先把現在錯誤的網頁或 DB 先更名或 tar 起來再把好的備份給解開回原來目錄位

置就行了需要注意的是 MySQL 服務最好也是要先停止回存完成後再啟動服務回存 DB 的整個程序可能像下面 cd varlibmysql service mysqldstop mv CRM CRM_OLD tar xvfz CRM_db_20030905tg service mysqld start

65 線上備份與還原

651 線上備份

使用像上面的檔案方式備份是個不錯的方法它最少可以保持該主機某個時間點的完整檔案備份但還是有一些問題需要考慮到有些主機就不只建立一個 DB 而已總不能為了備份某個 DB 而把整個 MySQL 服務停止備份檔案的方式回存在原主機上一定適用但假如 MySQL 版本升級或是在那天該網頁空間需遷機移機到別的主機時那就沒人敢保證備出來的資料檔可以用所以我們可以考慮另一種備份的方式是使用 MySQL 本身提供的功能 MySQL Data Dump指令是 mysqldump

65

使用 MySQL 的 Dump 功能可以把 DB 的結構資料或結構加資料 Dump 成文字檔 mysqldump 指令提供的彈性很大你可以選擇把整個 DB Dump 成一個檔或是每個 Table 為一個檔甚至是把結構檔和資料分開儲存都

可以 mysqladmin -uroot -p flush-logs mysqldump CRM -uroot -p --opt gt CRM_20030905sql (CRM 是 DB 名稱 opt 是一個使用完整 Dump 參數) 假如只是要單獨 Dump 某個 Table 時只要在上面的指令後轉出符號 gt 前加個 Table 名稱就可以如只要 phpbb2_users 這個 Table 的 Dump 時只要下 mysqldump CRM -uroot -p --opt CUSTOMER gt CRM_CUSTOMER_20030905sql

652 線上還原

若要回存整個資料庫只需將壓縮的備份檔還原成 Dump 的檔案再用下面的指令回存 mysql CRM -uroot -p lt CRM_20030905sql 這邊需注意的是若建立備份時是以--opt或--add-drop-table為參數時回存的 動作是先將舊的 Table 先刪除重建 Table 的結構後再把 Data 匯入所以回存後所有的資料會回到你當時備份那個時間點因此在回存資料時可以考慮把現有錯誤或不完整的 DB 先備份一份下來以備不時之需或是拿來比對錯誤的地

方在那裡當然你也可以把資料回存到另一個測試用的 DB 內只要把上面指令

的 DB 名稱改成你的測試用 DB 名稱即可 使用這種回存方式 MySQL 服務不需停止也不會動到其他正在使用的 DB 在一些提供 MySQL 服務的虛擬主機可用這種方式作你自己的 DB 備份及回存

66

另外假如你是系統重建或是移機時切需在新的 MySQL 內新建一個空白 DB 後才行作回存的工作你可以用下面的指令建立 mysql -uroot -p -e CREATE DATABASE CRM (上面的 CRM是你要新建的 DB 名稱) 另一種作法先用 mysql 指令進入 mysql client console 然後再用 CREATE DATABASE CRM 這樣就行了記得尾端要加個 符號該行指令才會執行

67

第七章 問題與解答

Q1RedHat 90預附的 MySQL到底有無支援 Transcation機制 Ans MySQL自 32334a之後的 MySQL-Max版本加入 InnoDB的資料庫類型透過

InnoDBMySQL同樣可以進行 COMMIT與 ROLLRACK的動作RedHat 90預附的 MySQL為 32354a-11巳支援 InnoDB的資料庫類型不過必須做以

下設定 1cp usrsharedocmysql-server-32354amy-mediumcnf to etcmycnf 2 vi etcmycnf 將以下設定前的拿掉 innodb_data_home_dir = varlibmysql innodb_data_file_path = ibdata110Mautoextend innodb_log_group_home_dir = varlibmysql innodb_log_arch_dir = varlibmysql 3service mysqld restart 如此一來各位在建立Table時便可指定Table Type為 innodb ( ex create table with type=innodb ) Q2如何解決 php+mysql 許功蓋等字變亂的問題 Ans 方法一 【確定 MySQL 預設的字元集】 1 打開 WinMySQLadmin 管理畫面(在視窗右下角狀態列紅綠燈圖示中按滑鼠

右鍵點選 Show me 選項) 2 點選管理畫面中 [Variables] 標籤選項其中 character_set變數就是您預設

字元集的變數其預設是 latin1 字元集(我們要將他改回 big5)而 chatacters_set 變數則是 MySQL 可以支援哪些字元集 【修改預設字元集變數 character_set 】 1 請點選管理畫面中 [myini Setup] 標籤選項設定 myini 2 按一下 [Pick-up and Edit myini values] 按鈕以便編輯目前的 myini 設定 3 在 [mysqld] 設定區塊底下新增一行 default-character-set = big5 變數設

68

定 4 新增一個 [client] 設定區塊並加入第三步驟的變數設定(游標往下移到空白處新增兩行 [client] 和 default-character-set=big5) 5 按一下畫面左下方 [Save Modification] 按鈕儲存設定 6 重新啟動 MySQL 或 Windows 方法二 Server端注意事項 phpini 中有關的設定為(預設值) Magic quotes for incoming GETPOSTCookie data magic_quotes_gpc = On Use Sybase-style magic quotes (escape with instead of ) magic_quotes_sybase = Off Client端注意事項 1中文資料送進 mysql 前請用 addslashes($str) 處理 2處理後送進 mysql 時請用 括起來並在參數後留一個空白如 $sql = UPDATE ezf_table set tablename=$tname tableend=$endtime table inguser=$tguser tableingid=$tguserid tableallnumber=$tnumber tableloca l=$tablelocal tableanyone=$tableopen tabletext=$ttext WHERE tableid=$t ableid tablename=$tname c 取出時請用 stripslashes($str) Q3MySQL root 密碼忘了該怎麼辦 Ans 1先停掉 mysql etcrcdinitdmysql stop 2以--skip-grant-table 的參數啟動 mysql safe_mysql --skip-grant-tableamp 3 更改 root 密碼 mysql mysql mysqlgt UPDATE user SET password=password(newpassword)

69

WHERE user=root mysqlgt FLUSH PRIVILEGES mysqlgt exit 4停掉 mysql再重跑 mysqladmin -uroot -p shutdown Enter password 輸入新設定的密碼 etcrcdinitdmysql start

Q4NULL值問題

Ans

NULL值的概念是造成 SQL的新手的混淆的普遍原因他們經常認為 NULL是和一個空字符串的一樣的東西不是這樣的例如下列語句是完全不同的

mysqlgt INSERT INTO my_table (phone) VALUES (NULL)

mysqlgt INSERT INTO my_table (phone) VALUES ()

兩個語句把值插入到 phone 列但是第一個插入一個 NULL值而第二個插入一個空字符串第一個的含義可以認為是ldquo電話號碼不知道而第二個則可意味

著ldquo她沒有電話

在 SQL中NULL值在于任何其他值甚至 NULL值比較時總是假的(FALSE)包含 NULL的一個表達式總是產生一個 NULL值除非在包含在表達式中的運算符和函數的文檔中指出在下列例子所有的列返回 NULL

mysqlgt SELECT NULL1+NULLCONCAT(InvisibleNULL)

如果你想要尋找值是 NULL的列你不能使用=NULL測試下列語句不返回任

何行因為對任何表達式expr = NULL是假的

mysqlgt SELECT FROM my_table WHERE phone = NULL

要想尋找 NULL值你必須使用 IS NULL測試下例顯示如何找出 NULL電話號碼和空的電話號碼

70

mysqlgt SELECT FROM my_table WHERE phone IS NULL mysqlgt SELECT FROM my_table WHERE phone =

在 MySQL中就像很多其他的 SQL服務器一樣你不能索引可以有 NULL值的列你必須聲明這樣的列為 NOT NULL而且你不能插入 NULL到索引的

列中

當用 LOAD DATA INFILE 讀取數據時空列用更新如果你想要在一個列中有

NULL值你應該在文本文件中使用N字面上的詞NULL也可以在某些情形下使用

當使用 ORDER BY時首先呈現 NULL值如果你用 DESC以降序排序NULL值最後顯示當使用 GROUP BY時所有的 NULL值被認為是相等的

為了有助于NULL的處理你能使用 IS NULL和 IS NOT NULL運算符和 IFNULL()函數

對某些列類型NULL值被特殊地處理如果你將 NULL插入表的第一個TIMESTAMP 列則插入當前的日期和時間如果你將 NULL插入一個AUTO_INCREMENT 列則插入順序中的下一個數字

Q5如何將圖片存放於 MySQL中

Ans

Step 1建立資料庫 test

Step 2 建立表格 binary_data

CREATE TABLE binary_data (

id INT(4) NOT NULL AUTO_INCREMENT PRIMARY KEY

description CHAR(50)

bin_data LONGBLOB

filename CHAR(50)

filesize CHAR(50)

filetype CHAR(50)

71

)

Step 3 利用 storephp 寫入圖片

storephp 程式碼

ltHTMLgt ltHEADgtltTITLEgtStore binary data into SQL DatabaseltTITLEgtltHEADgt ltBODYgt lt code that will be executed if the form has been submitted

if ($submit) mysql_connect(localhostrootYOUR_PASSWORD) mysql_select_db(test) $data=Base64_Encode(fread(fopen($form_data r) filesize($form_data))) $result=MYSQL_QUERY(INSERT INTO binary_data (descriptionbin_datafilenamefilesizefiletype) VALUES ($form_description$data$form_data_name$form_data_size$form_data_type)) $id= mysql_insert_id() print ltpgtThis file has the following Database ID ltbgt$idltbgt MYSQL_CLOSE() else else show the form to submit new data

gt

ltform method=post action=ltphp echo $PHP_SELF gt enctype=multipartform-datagt File Descriptionltbrgt ltinput type=text name=form_description size=40gt ltINPUT TYPE=hidden name=MAX_FILE_SIZE value=4000000gt ltbrgtFile to uploadstore in databaseltbrgt ltinput type=file name=form_data size=40gt ltpgtltinput type=submit name=submit value=submitgt ltformgt lt

72

gt ltBODYgt ltHTMLgt

Step 3 利用 storephp 取出圖片

getdataphp 程式碼

lt Syntax getdataphp3id=ltidgt if($id) you may have to modify login information for your database server MYSQL_CONNECT(localhostrootYOUR_PASSWORD) mysql_select_db(test) $query = select bin_datafiletype from binary_data where id=$id $result = MYSQL_QUERY($query) $data = Base64_Decode(MYSQL_RESULT($result0bin_data)) $type = MYSQL_RESULT($result0filetype) Header( Content-type $type) echo $data gt

Q6MySQL裝好之後啟動時或是執行 mysqladmin會出現如下訊息 Cant connect to local MYSQL Server through Socket varlibmysqlmysqlsock或是

Cant connect to local MYSQL Server through Socket tmpmysqldsock

Ans 可能有下列幾個原因

1這個 mysqldsock 不見了被某人刪除了或是被一些系統自動執行程式給刪

了例如有些 cron任務便會設定定期刪除 tmp 裡的東西所以呢您只能修改

cron 裡的設定讓它不要清除 mysqldsock 2在啟動時也可以改變 mysqldsock的位置您在啟動 MySQL的時候可以加入此參數usrlocalmysqlbinsafe_mysqld --user=mysql --socket=其他路

徑socket amp 同時得去設定環境變數 MYSQL_UNIX_PORT的值以指定新的

73

路徑 3若是您沒改 MYSQL_UNIX_PORT的值那麼您可以在執行指令的時候才打

例如mysqladmin --socket=其他路徑socket version Q7How to get the last insert id Ans CREATE TABLE product ( id INT(4) NOT NULL AUTO_INCREMENT PRIMARY KEY description VARCHAR(50) ) 1利用 SQL的話 mysqlgt insert into product(description) values(123) Query OK 1 row affected (000 sec) mysqlgt select last_insert_id() +------------------+ | last_insert_id() | +------------------+ +------------------+ 1 row in set (000 sec) ======================================== 2如果是 PHP的話 你可以用mysql_insert_id()取得該 id PHP example $result=MYSQL_QUERY(INSERT INTO product (description) VALUES ($description)) $id= mysql_insert_id() print This file has the following Database ID $id Q8如何將文字檔匯入資料庫 Ans $addr=homehttpdhtmlphpschool001txt $sql_select = load data infile $addr into table test fields terminated by t 解說 $sql_select = load data infile 文字檔名 into table 表格名 fields terminated by

74

t

(欄位分隔以 TAB鍵) 該文字檔須與資料表欄位格式相符 例如欄位有三個 則文字檔為每行一筆資料如下 欄 1資料ltTABgt欄 2資料ltTABgt欄 3資料 欄 1資料ltTABgt欄 2資料ltTABgt欄 3資料 欄 1資料ltTABgt欄 2資料ltTABgt欄 3資料 欄 1資料ltTABgtltTABgt欄 3資料

Q9如何撰寫 MySQL C API Ans Step 1利用文字編輯器撰寫以下程式碼 mysqlcc

include ltstdiohgt

include ltmysqlmysqlhgt

int main (int argc char argv[])

MYSQL mysql

MYSQL_RES res

MYSQL_ROW row

if (argc = 2)

fputs (Usage myc ltdatabasegt stderr)

return 1

if ((mysql_connect(ampmysqllocalhostrootYour_Password)))

fputs (Error connecting stderr)

abort()

75

if (mysql_select_db(ampmysqlargv[1]))

fputs (Error selecting database stderr)

abort()

if (mysql_query(ampmysqlSELECT FROM test_table))

fputs (Error processing query stderr)

abort()

if ((res = mysql_store_result(ampmysql)))

fputs (Error storing results stderr)

abort()

while((row = mysql_fetch_row(res)))

uint i = 0

for (i=0 i lt mysql_num_fields(res) i++)

printf(s row[i])

printf(n)

return 0

Step 2 Compile

gcc -Iusrlocalmysqlinclude -Lusrlocalmysqllibmysql mysqlcc ndashlm -lmysqlclient

(其中 include path與 library path取決於你的 MySQL安裝路徑)

76

如果執行時發生如下 error Run problemerror in loading shared libraries libmysqlclientsoX 將你的 MySQL library path(for exampleusrlocalmysqllibmysql) 加入etcldsoconf and run sbinldconfig -v Q9ASP + MySQL 範例程式 Ans Dim myconn As New ADODBConnection Dim myrs As New Recordset Dim mySQL As String Dim myrows As Long myconnOpen DSN=MyODBCsample mySQL = SELECT from user myrsSource = mySQL Set myrsActiveConnection = myconn myrsCursorLocation = adUseClient myrsOpen myrows = myrsRecordCount myrsClose myconnClose 可參考 httpwwwdwamnetmysqlasp_myodbcasp 有詳細的資料 Q10如何將 MySQL中的資料庫匯出成txt檔 Ans select from TableName into outfile textxls all result fields will seperate by tab

77

第八章 參考資料

英文部份 網址 1 httpwwwmysqlcom MySQL 網站有第一手有關 MySQL的資料 2 httpwwwmysqlcomdocenReplicationhtml 有關 MySQL Replication 的文件 3 httpwwwgeocitiescomsqlhomefaqstore_blobhtml 如何在 MySQL 存放 BLOB的資料 4httpwwwsapdborg 有關 SAP跟 MySQL相關合作的網站 書藉 1 Cooking with MySQL

Paul DuBois has selected sample recipes from the hundreds youll find in his book MySQL

Cookbook In this third and final series of excerpts showcasing these recipes learn how to

compute team standings how to calculate the differences between successive Dec 26

2002 2 Tips for Building Web Database Applications with PHP and MySQL by Hugh E Williams co-author of Web Database Applications with PHP amp MySQL 04042002

3 Managing and Using MySQL 2nd Edition By Tim King George Reese Randy Jay Yarger

4 MySQL Cookbook By Paul DuBoisPublisher OReillyPub Date October 2002

中文部份

78

1 httplinuxtncedutwtechdocmysqlmysql_docmanual_tochtml MySQL 中文手冊 2 httpchenshloxaedutwphpZ_1php PHP+MySQ程式研習設計網站 3 httplinuxtncedutwtechdocbanicdownhtml PHP 4 手冊 4 httpwwwtncedutwadmin_zonephp台南縣教育網網路中心有很多 Linux相關文件 5 httpdobtncedutw網站建置百寶箱有很多 PHP MySQL 相關範例程式 5 httpwwwdbworldcomtw資料庫專家電子雜誌介紹資料庫的重要觀念及名詞

79

附錄一 SQL Command 介紹

SQL (讀音ess-que-el) 是一種結構查詢語法SQL 使用於資料庫交流

傳遞相容於 ANSI (American National Standards Institute) 是一套標準的關聯

式資料庫語言 SQL 語言是執行更新或從資料系統獲取資料一般常見的關聯

資料庫系統都有提供 SQL 如 Oracle Sybase Microsoft SQL Server Access Ingres 等雖然大部份的資料庫都有提供 SQL 但也多提供了自已獨特的語

法造成了不相容的情形但標準基本的語法是相通的如Select Insert Update Delete Create and Drop 每一個系統都有支援

Table相關 Command

Create Table

關聯式資料庫包含有很多元件稱為資料表(tables) 把資料或訊息放在資

料表中 資料表是以不同的名稱做分別資料表由欄列所構成的二維陣列

欄包含欄位名資料型態 及其他可判斷的資訊列是由全部欄位構成一筆一

筆的紀錄 create table 語法用在建立一個新的資料表語法格式如下

create table tablename (column1 data type column2 data type column3 data type)

Format of create table if you were to use optional constraints

create table tablename (column1 data type [constraint] column2 data type [constraint] column3 data type [constraint]) [ ] = optional

Note You may have as many columns as youd like and the constraints are optional

80

Example

create table employee (first varchar(15) last varchar(20) age number(3) address varchar(30) city varchar(20) state varchar(20))

注意建立資料表格式要以括號把前後框住而最後以(分號)做結尾

欄位名不要超過 30個字元長而且不要使用 sql 的關鍵字(如 where select等)而在後面接是型態的宣告(如字串數字日期格式等)

資料型態是來描述欄位的方式如一個欄位Last_Name 是一個姓氏可以使用varchar (可變動長度字串) 資料型態

以下是幾個常見的資料庫型態 char(size) 固定長度字串最長為 255 位元 varchar(size) 變動長度字串最大字元數以 size 來指定 number(size) 數值格式可以是整數也可以是小數最大數字以 size 位數判

斷未指定小數位數由系統內定 date 日期格式 number(sized) 數值格式最大數字以 size 位數判斷d 為小數位數整數位

數為 size-d 位

有何限制當資料表被建立通常有一或數個欄位是要使用來做關聯的功

能 例如unique 限制(唯一值)兩筆記錄不可以相同的值 not null (非空值)該欄位一定要輸入資料不可是空的primary key (主鍵)是每一筆記錄識別的主要方式

Drop a table drop table 刪除資料表(其中的資料也會一併刪除)

drop table tablename

Example

81

drop table 和刪除全部資料是不同的刪除全部資料欄位名稱資訊等還會

存在但刪除資料表會把這一些也一併移除掉

如何查詢資料

Select 基本用法

select 語法是關連式資料庫最常用的部份可以取得你想要的資料這是一個

簡單的範例 select column1[column2etc] from tablename [where condition] [] = optional 在 select 之後所列欄位名則是要顯示的資料部份你可以一一列出各欄位

名或是以 (星號)來代表選擇全部的欄位 from 之後放資料表名稱 where 子句 (選項) 指定要過濾的條件符合者才會顯現 where 可使用的條件運算元 = 等於 gt 大於 lt 小於 gt= 大或等於 lt= 小或等於 ltgt 大相等 LIKE 相似 For example select first last city

82

from empinfo where first LIKE Er 以Er 為開頭的字串就符合要以單引號框住 Or you can specify select first last from empinfo where last LIKE s 最後一字為 S 就符合 select from empinfo where first = Eric 則表示 first name 一定要是 Eric 才可以 範例資料表empinfo 統計函數

MIN 傳回指定欄位最小值

MAX 傳回指定欄位最大值

SUM 傳回指定欄位總和

AVG 傳回指定欄位平均值

COUNT 傳回指定欄位的筆數

COUNT() 傳回資料庫中的總筆數

統計函數使用於資料表中的數值欄位配合 SELECT 語法使用 只用於總結特定單一欄位可以配合 GROUP BY 做篩選但也可以不使用 GROUP BY 語句For example

SELECT AVG(salary) FROM employee

83

傳回全部 salary 平均值

Another example

SELECT AVG(salary) FROM employee WHERE title = Programmer

傳回 salary 平均值條件為 employees 資料表中當 title 等於 Programmer

Example

SELECT Count() FROM employees

傳回 employees 資料表中紀錄總筆數

GROUP BY 語法 SELECT column1 SUM(column2) FROM list-of-tables GROUP BY column-list The GROUP BY 語句可以先以所列的欄位為條件分組排序在一起(可以多欄

位) example 要列出每一個 dept 中最高 salary 值 SELECT max(salary) dept FROM employee GROUP BY dept HAVING 語法

SELECT column1 SUM(column2) FROM list-of-tables GROUP BY column-list HAVING condition

HAVING 子句是 GROUP BY 的一部份用來過濾在 GROUP BY 所選出的資料功能如同 select 命令中 where 條件式一樣只是 HAVING 必需配合 GROUP BY 使用

我們以例子來說明我們要取得每一公司名及每一公司的薪水平均值輸入如下

84

SELECT dept avg(salary) FROM employee GROUP BY dept

但如果我們只列出薪資平均值超過 20000元的公司資料

SELECT dept avg(salary) FROM employee GROUP BY dept HAVING avg(salary) gt 20000

ORDER BY子句語法

SELECT column1 SUM(column2) FROM list-of-tables ORDER BY column-list [ASC | DESC]

[ ] =選項

ORDER BY是一個選項子句當你以排序方式來顯示資料(正向由小到大反向由大到小)以指定的欄位資料做排序

ASC = 正向- 預設值 DESC = 反向排序

For example

SELECT employee_id dept name age salary FROM employee_info WHERE dept = Sales ORDER BY salary

以上列出公司代號公司名銷售員人名年紀及薪資而條件是公司名為 Sales 顯示順序以薪資多少排序(由小到大為預設值)

如果要以多個欄位做排序要以逗號做分隔如下

SELECT employee_id dept name age salary FROM employee_info WHERE dept = Sales ORDER BY salary age DESC

85

結合條件及布林運算 SELECT column1 SUM(column2) FROM list-of-tables WHERE condition1 AND condition2 AND運算可以結兩個或以上的條件放在 WHERE子句中 兩者都要為真才

會顯示該筆記錄 OR 運算可以結兩個或以上敘述放在 WHERE子句中只要其中一個為直就

會顯示該筆記錄 For example SELECT employeeid firstname lastname title salary FROM employee_info WHERE salary gt= 5000000 AND title = Programmer 必需要薪資大於等於 50000而且職稱為 Programmer同時符合才會顯示該筆資料 以下以括號括住雖然不是必需的但如此比較容易讀 SELECT employeeid firstname lastname title salary FROM employee_info WHERE (salary gt= 5000000) AND (title = Programmer) 另外範例 SELECT firstname lastname title salary FROM employee_info WHERE (title = Sales) OR (title = Programmer) 條件為只要是 Sales 或 Programmer 職稱的就會被列出 IN and BETWEEN 子句

SELECT column1 SUM(column2) FROM list-of-tables WHERE column3 IN (list-of-values) SELECT column1 SUM(column2) FROM list-of-tables WHERE column3 BETWEEN value1 AND value2 IN 子句使用在列舉項目的使用上也就是分別測試是否符合所列的值 For example

86

SELECT employeeid lastname salary FROM employee_info WHERE lastname IN (Hernandez Jones Roberts Ruiz) 條件為姓氏(astname)要符合 Hernandez Jones Roberts or Ruiz 其中一個才會被傳回 IN運算元也可以使用 OR 的語法來取代如下結果相同 SELECT employeeid lastname salary FROM employee_info WHERE lastname = Hernandez OR lastname = Jones OR lastname = Roberts OR lastname = Ruiz 但使用 IN 句子比較短也比較易懂 你也可以使用 NOT IN 來去掉不要的記錄 BETWEEN 運算元使用在判斷是否存在兩個數值之間 For example SELECT employeeid age lastname salary FROM employee_info WHERE age BETWEEN 30 AND 40 傳回年紀 30歲到 40歲之間的資料(含 30及 40歲者) 相同的也可以使用以下語法來達到相同的結果 SELECT employeeid age lastname salary FROM employee_info WHERE age gt= 30 AND age lt= 40 你也可使用 NOT BETWEEN 來濾掉中間值的資料 數學運算 標準 ANSI SQL-92 提供以下運算

87

+ 加

- 減

餘數

餘數為除法後剩整數這不在標準的 ANSI SQL 中但大部份的資料庫都會支

援這運算元以下列出有用的函數雖不在 ANSI SQL-92 提供但一般資料庫

也會支援他們

ABS(x) 傳回 x 絕對值

SIGN(x) returns the sign of input x as -1 0 or 1 (negative zero or positive respectively)

MOD(xy) 餘數 - returns the integer remainder of x divided by y (同 xy)

FLOOR(x) 傳回小或等於 x 的最大整數值

CEILING(x) or CEIL(x)

傳回大或等於 x 的最小整數值

POWER(xy) x的 y 次方

ROUND(x) 把 x 四捨五入為整數

ROUND(xd) 四捨五入取到小數 d 位

SQRT(x) x 開平方

For example SELECT round(salary) firstname FROM employee_info 傳回薪資取到整數位

如何新增資料

insert 加入一筆新紀錄到資料表中 insert into tablename (first_columnlast_column) values (first_valuelast_value) [] = optional Example insert into employee

88

(first last age address city state) values (Luke Duke 45 2130 Boars Nest Hazard Co Georgia) Note 字串要以單引號住如string 數字框住也無妨 insert into 後面接資料表名稱再接以括號括住的欄位名在 values 後括號分別對映各欄位的值 以上的例子新增了一筆名(first) 為 Luke而住所(state) 為 Georgia 的資料

如何刪除資料

delete 可以刪除單筆或多筆紀錄 delete from tablename where columnname OPERATOR value [and|or column OPERATOR value] [ ] = optional Examples delete from employee Note 如果你沒有指定 where 子句那麼全部的紀錄都會被刪除 delete from employee where lastname = May delete from employee where firstname = Mike or firstname = Eric delete from 接著資料表名 再接著是條件式判斷沒有條件式則全部紀錄會

被刪除

如何更新資料

update 用來更新你所指定的記錄要和 WHERE 配合小心使用 語法 update tablename set columnname = newvalue[nextcolumn = newvalue2] where columnname OPERATOR value [and|or column OPERATOR value] [] = optional Examples

89

update phone_book set area_code = 623 where prefix = 979 update phone_book set last_name = Smith prefix=555 suffix=9292 where last_name = Jones update employee set age = age+1 where first_name=Mary and last_name=Williams

90

附錄二Replication

測試環境

RedHat 90 + MySQL 32358 MySQL資料庫路徑 varlibmysql MySQL設定檔 etcmycnf Master IP 1921680100 Slave IP 1921680200 請至下列網址下載最新MySQL 32358套件並利用rpm ndashUvh 更新 httpupdatesredhatcom9enosi386

圖 最新 MySQL 套件

測試架構圖

91

1921680100

1921680200Master Server

erveSlave S r

圖 測試架構圖

測試步驟

Master server 部份 Step1 確認 MasterSlave機器上所裝的 MySQL版本能進行

replication( 32329 or higher ) Step2 在 Master MySQL上開放一個帳號給 Slave mysql ndashu root ndashp mysqlgtGRANT FILE ON TO repl1921680200 IDENTIFIED BY lsquoabc123rsquo mysqlgtq 上面是 Master開放一個帳號 repl密碼 abc123給 IP1921680200有檔案處理

的權限 Step3 shutdown MySQL on the Master mysqladmin ndashu root ndashp shutdown Step4 備份 Master所有資料庫 tar ndashcvf tmpmysql-snapshottar varlibmysql 注意tar的時候MySQL是要在 stop情況下 在mysql (wwwmysqlcom) 網站的FAQ有不用shutdown的方法

92

Step5 在 master機器上修改etcmycnf 在[mysqld]區段內加入參數 log-bin server-id=這邊設定 server-id=1 sql-bin-update-same binlog-do-db=CRM只針對 CRM資料庫做紀錄 Step6 Restart MySQL on the master service mysqld start 此時因為有加入 log-bin 參數因此開始有 index產生了在varlibmysql目錄下

有index檔案紀錄資料庫的異動 log Slave server 部份 Step1 在 slave設定etcmycnf 在[mysqld]區段加入 master-host= master-user= master-password= master-port= server-id= 這邊設定 master-host=1921680100 master-user=repl master-password=abc123 master-port=3306 server-id=2 master-connect-retry=60預設重試間隔 60秒 replicate-do-db=CRM告訴 slave只做 CRM資料庫的更新 log-slave-updates Step2 將 master上的 mysql-snapshottar copy到 slave上 用 ftp傳到 slave的tmp Step3 解壓縮 Master資料庫至 Slave Server上 cd varlib tar xvf tmpmysql-snapshottar chown ndashR mysqlmysql mysql

93

chmod ndashR 770 mysql (視情況) Step4 Restart MySQL on the slave server 這時在varlibmysql目錄會出現 masterinfo此檔案紀錄了 Master MySQL server的資訊

狀況測試

One-way replication

1921680100

1921680200Master Server

erveSlave S r

圖 One-way replication架構圖 Step1 Master跟 Slave網路及服務都正常情況下由 Master端異動資料後 到 Slave端瀏覽資料檢視是否有進行 replication Step2 模擬 Slave Server 當機 可用在於 slave真的當機或是 Slave 不一定需要一直跟 master connect將Slave MySQL server shutdown由 Master端異動資料到 slave端瀏覽此時Slave應該沒有被 replication 更新然後再將 Slave端 MySQL server start起來

預設 60秒後 Slave會嘗試跟 Master要求進行 replication再去 Slave端檢視是否有更新資料

94

Step3 模擬 Master當機因為是設定 One-way replication一旦 Master Server Slave端沒有 Master的 source可以 download Two-way replication 基於 Master當機狀況於是發展雙向 Replication即 1921680100 ( Host A ) 1921680200 ( Host B )都分別擔任 MasterSlave身分

1921680100

1921680200er

Server B MasterSlave Server

Server A MasterSlave Serv

圖 Two-way replication架構圖 以下是針對兩台 MySQL伺服器進行雙向 Replication Step1觀念同單向 replication只是改成 Master也有 Slave身分 Slave也有Master的身分先分別在 Server AServer B 都去 grant一個進行 replication的身分 [A]mysqlgtGRANT FILE ON TO repl1921680200 IDENTIFIED BY lsquoabc123rsquo [B]mysqlgt GRANT FILE ON TO repl1921680100 IDENTIFIED BY lsquoabc123rsquo Step2做完單向 replication後stop Server Aserver B MySQL service此時 AB資料是一樣的

95

修改etcmycnf設定 範例 Server A [mysqld] datadir=varlibmysql socket=varlibmysqlmysqlsock server-id=1 log-bin sql-bin-update-same binlog-do-db=CRM master-host=1921680200 master-user=repl master-password=abc123 log-slave-updates master-connect-retry=60 replicate-do-db=CRM Server B [mysqld] datadir=varlibmysql socket=varlibmysqlmysqlsock server-id=2 log-bin sql-bin-update-same binlog-do-db=CRM master-host=1921680100 master-user=repl master-password=abc123 log-slave-updates master-connect-retry=60 replicate-do-db=CRM 分別 start Server AServer B MySQL後此時雙方都是 MasterSlave身分一旦哪一方資料異動就會通知對方來 replication-若 replication失效則必須將Server AServer B的masterinfo及index00x 都砍掉然後分別 restart MySQL server進行測試檢視成果 實務上通常如果需要做Two-way replication通常會搭配Virtual Server使用

96

在前端架設一台Virtual Server不過此部份不在此份SOP討論範圍內有興趣

的讀者可參考 httpwwwlinuxvirtualserverorg 網站

1921680100 1921680200

Host A MasterSlave Server

Host B MasterSlave Server

Virtual Host

圖 Virtual Server + Two-way replication 架構圖

97

圖 High Availability Linux Virtual Server架構圖

98

  • COSA-SOP-03-006
  • 第一章 簡介
    • 11適用對象 (Audience)
    • 12 MySQL本身
    • 13 MySQL 40版跟50版重大的改進功能
    • 14 各家資料庫軟體比較
      • 第二章 前置需求
      • 第三章 安裝
        • 31 MySQL安裝
        • 32 phpMyAdmin安裝
        • 33 升級及注意事項
          • 第四章 MySQL管理
            • 41 Webmin 管理介面
            • 42 phpMyAdmin 的操作介面
            • 43管理指令介紹
              • 431 利用mysqladmin設定root的密碼
                  • 第五章 實用範例
                    • 51 任務一Web Base客戶通訊錄
                    • 52 任務二Web Base群組軟體 ( twig )
                      • 第六章 維護及更新程序
                        • 61 日常維護
                        • 62 更新程序
                        • 63 備份重要檔案
                        • 64 離線備份與還原
                        • 65 線上備份與還原
                          • 第七章 問題與解答
                          • 第八章 參考資料
                          • 附錄一 SQL Command 介紹
                          • 附錄二Replication
Page 11: DataBase Server Standard Operation Procedureebooks.lib.ntu.edu.tw/1_file/oss/63/93doc4-5.pdf · 業務的公司帶來了不少壓力,譬如微軟,甲骨文 ... 外的錢用在第三方的資料庫產品上,譬如就可以不用再購買甲骨文公司

第二章 前置需求

在安裝 MySQL之前請確定 Apache及 MySQL亦巳安裝相關步驟請參考

Apache SOP安裝 Apache及 PHP相關章節

11

第三章 安裝

31 MySQL安裝

在 RedHat 90上安裝 MySQL是件很容易的事因為 RedHat 90提供了一

個很方便的 GUI套件管理工具「redhat-config-packages」各位只要把 RedHat 90第一片光碟放入並以 root的身份登入系統鍵入 redhat-config-packages勾選「SQL資料庫伺服器」即可然後按「更新」如果遇到任何相依性問題

系統會提示您更換光碟片 ( 圖 3-1 ~ 3-3 ) Step 1 執行 redhat-config-packes

圖 3-1

Step 2 選擇資料伺服器

12

圖 3-2

Step 3檢查是否安裝成功 待安裝後您可以用利用「rpm -qa | grpe ^mysql」檢查是否安裝成功

圖 3-3

啟動 MySQL ( Command Mode )馬上啟動 MySQL的指令為「service mysqld start」如果您希望一開機就自動啟動 MySQL請執行「chkconfig mysqld on」

13

圖 3-4

啟動 MySQL ( WebMin 介面 ) 我們也可以利用WebMin 來啟動 MySQL步驟如下 Step 1登入Webmin

圖 3-5 登入WebMin

Step 2 選擇伺服器

14

圖 3-6 伺服器畫面

Step 2 選擇 MySQL資料庫伺服器

圖 3-7 伺服器畫面

15

Step 3 啟動 MySQL資料庫伺服器

圖 3-8 啟動 MySQL

更改資料庫管理者密碼

成功啟動 MySQL後因為資料庫管理者預設沒有密碼建議使用前更改系

統管理者密碼請輸入下列指令

mysqladmin ndashu root ndashh cosaexamplecom password lsquo1234rsquo -u 表示使用者帳號root 為 MySQL預設的管理帳號

-h 表示 MySQL主機的主機名稱也可使用 IP Address password 表示使用者的密碼因為字串請使用單引號將密碼括起來

圖 3-9 修改 MySQL 的密碼

16

32 phpMyAdmin安裝

本書除了會介紹利用當今 Linux上最紅的整合管理工具Webmin 來管理

MySQL外還會為各位介紹專門管理 MySQL的工具 phpMyAdmin phpMyAdmin是免費的 PHP原始程式碼的Web網站可用來管理整個

MySQL伺服器這是一套Web介面的 MySQL管理程式支援中文的使用者介

面 phpMyAdmin只需透過瀏覽器就可管理 MySQL伺服器換句話說不論

MySQL是安裝在 Linux或是Windows 作業系統都可以使用相同步驟在

MySQL上建立資料庫(Database)資料表(Table)和編輯紀錄(Record) Step 1 下載phpMyAdmin ( httpwwwphpmyadminnet )選擇最櫎新穩定的版

本 253

圖 3-10 httpwwwphpmyadminnet

17

圖 3-11 下載 phpMyAdmin-253-phptarbz2

Step 2 將 phpMyAdmin-253-phptarbz2收至 tmp 並執行下列指令將其解壓

縮至varwww tar jxvf phpMyAdmin-253-phptarbz ndashC varwwwhtml

圖 3-12 解壓縮安裝 phpMyadmin-253

Step 3 為了操作方便起見建立 Soft link ln ndashs phpMyAdmin-253 phpMyAdmin

圖 3-13 修改 phpMyadmin 設定檔 configincphp

18

Step 4 修改 phpMyadmin 設定檔 configincphp gedit varwwwhtmlphpMyAdminconfigincphp

圖 3-14 configincphp設定檔

Step 5 設定顯示行號以方便修改 configincphp 設定檔

19

圖 3-15 顯示行號

Step 6 修改下列設定 第 39 行 設定 phpMyAdmin的 URL 第 69 行 MySQL Server 的 ip 第 80 行 利用何帳號存取 MySQL 第 81 行 如果 root有設定 password此處即填入 root的 password

30 In most cases you can leave this variable empty as the correct value

31 will be detected automatically However we recommend that you do

32 test to see that the auto-detection code works in your system A good

33 test is to browse a table then edit a row and save it There will be

34 an error message if phpMyAdmin cannot auto-detect the correct value

35

36 If the auto-detection code does work properly you can set to TRUE the

37 $cfg[PmaAbsoluteUri_DisableWarning] variable below

38

39 $cfg[PmaAbsoluteUri] = httpossccosaorgtwphpMyAdmin

hellip

20

hellip

69 $cfg[Servers][$i][host] = localhost MySQL hostname or IP address hellip 80 $cfg[Servers][$i][user] = root MySQL user

81 $cfg[Servers][$i][password] = 1234 MySQL password (only needed

圖 3-16 修改 configincphp

21

圖 3-17 修改 configincphp

圖 3-18 修改 configincphp p

Step 7 設定語系

22

圖 3-19 設定語系

圖 3-20 執行 phpMyAdmin

23

33 升級及注意事項

RedHat 90附的 MySQL版本為 323 MySQL所釋出最新穩定版本為

40若是您不想用系統預附的 323請先利用下列移除之前 323的版本

rpm ndashe mysql-devel rpm ndashe mysql-server rpm ndashe mysql --nodeps 然後到下列網址下載您所想要的版本進行安裝在這裏我們用 4014版為例 Step 1 下載相關套件( httpwwwmysqlcomdownloadsmysql-40html )

圖 3-21 Download MySQL 4014 相關 RPM Step 2 利用 rpm 指令安裝

24

圖 3-22 Install MySQL 4014 相關 RPM

圖 3-23 Install MySQL 4014 相關 RPM

Step 3 啟動 MySQL

25

圖 3-24 啟動 MySQL 4014 並修改密碼

26

第四章 MySQL管理

本章將我們介紹利用WebminphpAdminCommand的方式建立一個名為

CONTACT的資料庫內有一個 address的 Table作為我們客戶通訊錄程式使

用的資料庫

41 Webmin 管理介面

412建立資料庫

Step 1 登入Webmin

圖 4-1 登入WebMin

Step 2 點選伺服器

27

圖 4-2 伺服器畫面

Step 3 點選 MySQL資料庫伺服器

圖 4-3 MySQL資料庫伺服器

28

Step 4 建立一個新的資料庫

圖 4-4 建立 MySQL資料庫

Step 5 建立名為 CONTACT的資料庫

29

圖 4-5 指定資料庫名稱

412 建立資料表

假設我們要建立一個名為 address的 Table其結構如下 欄位名稱 資料型態 長度 說明 id INT (自動編號) 連絡人編號 name varchar文字 20 連絡人姓名 tel Varchar文字 15 連絡人電話 Step 1 選擇 CONTACT資料庫

30

圖 4-6 選擇資料庫

Step 2 指定欄位數目

31

圖 4-7 設定欄位數目

Step 3設定表格欄位屬性

圖 3-8 設定表格欄位屬性

Step 4建立表格資料

32

圖 4-9 建立表格資料

圖 4-10 檢視資料

33

圖 4-11 新增資料

圖 4-12

34

圖 4-13

413 使用者管理

接下來我們要利用Webmin 來建立資料庫使用者並給予某些權限 Step1建立使用者

35

圖 4-14 選擇使用者權限

圖 4-15

36

Step2 賦予權限

圖 4-16

Step3 權限列表

37

圖 4-17

38

42 phpMyAdmin 的操作介面

421建立資料庫

Step 填入資料庫名稱並按「建立」

圖 4-18建立資料庫

422 建立資料表

Step1 填入資料表名稱並指定欄位數量 執行

39

圖 4-19填入資料表名稱並指定欄位數量

Step2 設定欄位屬性

圖 4-20設定欄位屬性

40

Step3 phpMyAdmin會產生相關的 SQL Command

圖 4-21 資料表結構及相關 SQL Command

Step4新增 Record

41

圖 4-22

圖 4-23

42

圖 4-24

圖 4-25

43

423使用者管理

Step1建立使用者

圖 4-26

44

圖 4-27

Step2 給予權限

圖 4-28

Step3權限列表

45

圖 4-29

43管理指令介紹

431 利用 mysqladmin設定 root的密碼

當您在Windows 或 Linux 中安裝好 MySQL後系統會自動幫您建立兩個

帳分別是 root 和 匿名者MySQL的 root 跟 Linux 最高權限使用者 root無關MySQL的 root使用者相當於 MS SQL 中的 sa 帳號擁有最高的 Database管理權限但系統預設 MySQL的 root 是不需要密碼所以通常我們一安裝

MySQL後首要任務便是修改 root的密碼 我們可以利用 mysqladmin工具或是直接修改 MySQL內部資料庫的使用者資

料 mysqladmin ndashu root ndashh cosaexamplecom password lsquo1234rsquo

46

-u 表示使用者帳號root 為 MySQL預設的管理帳號

-h 表示 MySQL主機的主機名稱也可使用 IP Address password 表示使用者的密碼因為字串請使用單引號將密碼括起來 密碼設定完成之後還是可以利用 mysqladmin修改密碼但是你必須提供目前的密碼

432 連線 MySQL

mysql -uroot -p密碼 (-p和密碼之間不能有空白) 或 mysql -uroot -p (此方式會在進入後要求密碼) [rootossc phpMyAdmin] mysql -u root -p1234

Welcome to the MySQL monitor Commands end with or g

Your MySQL connection id is 25 to server version 32354

Type help or h for help Type c to clear the buffer

mysqlgt show databases

+----------+

| Database |

+----------+

| mysql |

| test |

+----------+

2 rows in set (000 sec)

mysqlgt exit

Bye

[rootossc phpMyAdmin]

433 建立資料庫

可利用 mysqladmin指令建立 CONTACT資料庫 mysqladmin -u root -p1234 create CONTACT

47

或是利用 mysql指令 [rootossc bluepage] mysql -u root -p1234 Welcome to the MySQL monitor Commands end with or g Your MySQL connection id is 1057 to server version 32354 Type help or h for help Type c to clear the buffer mysqlgt create database CONTACT Query OK 1 row affected (000 sec) mysqlgt show databases +----------+ | Database | +----------+ | CONTACT | | address | | hello | | mysql | | nuke | | test | +----------+ 6 rows in set (000 sec) mysqlgt exit

434 建立資料表

編寫 adresssql內容如下 -- Table structure for table address CREATE TABLE address ( id int(11) NOT NULL auto_increment name varchar(20) NOT NULL default tel varchar(15) NOT NULL default PRIMARY KEY (id) ) TYPE=MyISAM

48

-- Dumping data for table address INSERT INTO address VALUES (1林小明0800016888) INSERT INTO address VALUES (2黃大雄0800016888) INSERT INTO address VALUES (3劉小芬0800024365) 然後執行此 sql script mysql -u root -p1234 CONTACT lt addresssql 或是利 mysql command [rootossc bluepage] mysql -u root -p1234 Welcome to the MySQL monitor Commands end with or g Your MySQL connection id is 1090 to server version 32354 Type help or h for help Type c to clear the buffer mysqlgt use CONTACT Database changed Database changed mysqlgt CREATE TABLE address ( -gt id int(11) NOT NULL auto_increment -gt name varchar(20) NOT NULL default -gt tel varchar(15) NOT NULL default -gt PRIMARY KEY (id) -gt ) TYPE=MyISAM Query OK 0 rows affected (000 sec) mysqlgt INSERT INTO address VALUES (1林小明0800016888) Query OK 1 row affected (000 sec) mysqlgt INSERT INTO address VALUES (2黃大雄0800016888) Query OK 1 row affected (000 sec) mysqlgt INSERT INTO address VALUES (3劉小芬0800024365) Query OK 1 row affected (000 sec) mysqlgt exit Bye

49

第五章 實用範例

51 任務一Web Base客戶通訊錄

任職於開放科技公司的林小明前些日子在最符合成本效益的條件下快

速地完成公司網站的建置老闆因此對小明讚譽有加最近因為公司存放客戶資

料的 SQL Server主機屢遭病毒攻擊加上作業系統本身的問題當機次數頻繁

老闆希望能儘快把公司的客戶通訊錄程式移轉到較穩定的環境上因為此客戶通

訊錄程式最主要給內部人員使用所以介面美觀並不特別要求只求穩定且能快

速得到查詢結果老闆希望在短時間先看到程式的雛型並鍵入資料對其效率

及穩定性進行測試因為上次小明表現突出所以這次不可能的任務自然又落到

小明身上 小明想來想去既然要快速又穩定他而且又不希望所有人都得安裝 Client

程式於是小明決定)捨棄他的舊愛「Delphi+MS SQL」投向新歡「Apache + MySQL + PHP」利用此架構來設計一個簡單實用的Web Base客戶通訊錄程式

511 Web Base客戶通訊錄架構

此程式需要建立 CONTACT的資料庫並建立 adress Tables其結構如下表建立步驟請參考第三章 欄位名稱 資料型態 長度 說明 id INT (自動編號) 連絡人編號 name varchar文字 20 連絡人姓名 tel Varchar文字 15 連絡人電話 Web Base通訊錄共有下列幾個檔案功能如下表

檔案名稱 說明 Indexhtml Web Base通訊錄首頁 addphp 新增連絡人的 php程式 searchphp 尋找連絡人的 php程式 editphp 具有更新及刪除功能的 php程式

50

我們將這些檔案放至varwwwhtmlbluepage (預設無 bluepage目錄)

512 Web Base通訊錄測試

httpwwwopencombluepage 新增資料

圖 5-1 新增連絡人

圖 5-2 填入資料

51

圖 5-3 新增成功

搜尋及異動資料

圖 5-4 搜尋通訊錄

52

圖 5-5 編輯資料

圖 5-6 更新資料

513 程式內容及說明

lt-- 程式範例indexhtml--gt lthtmlgt ltheadgtlttitlegt通訊錄lttitlegtltheadgt ltbodygt ltcentergt

53

lth2gt通訊錄lth2gtlthrgt lta href=indexhtmlgt通訊錄ltagt | lta href=addphpgt新增連絡人ltagt | lta href=searchphpgt搜尋通訊錄ltagt ltcentergt ltbodygt lthtmlgt lt-- 程式範例addphp --gt lthtmlgt ltheadgtlttitlegt新增連絡人lttitlegtltheadgt ltbodygt ltcentergtlth2gt新增連絡人lth2gtltcentergtlthrgt lt 取得欄位資料 if (isset($_POST[Name]) ampamp isset($_POST[Tel]) ) $name = $_POST[Name] $tel = $_POST[Tel] 檢查是否有輸入欄位資料 if ($name = ampamp $tel = ) 建立 SQL字串 $sql = INSERT INTO address (name tel) values( $sql= $name $tel) 建立 MySQL 連結 $link = mysql_connect(localhostroot1234) 選擇資料庫 mysql_select_db(CONTACT) 執行 SQL指令 mysql_query($sql) mysql_close($link) echo ltfont color=redgt新增連絡人成功ltfontgtltbrgt gt ltform action=addphp method=postgt lttable border=0 width=300gt lttrgtlttdgt姓名 lttdgt

54

lttdgtltinput type=text name=Name size=20 maxlength=10gtlttdgtlttrgt lttrgtlttdgt電話 lttdgt lttdgtltinput type=text name=Tel size=20 maxlength=20gtlttdgtlttrgt lttrgtlttd colspan=2 align=centergt ltinput type=submit value=新增連絡人gtlttdgtlttrgt lttablegt ltformgt ltbrgtlta href=indexhtmlgt通訊錄ltagt | lta href=addphpgt新增連絡人ltagt | lta href=searchphpgt搜尋通訊錄ltagt ltbodygt lthtmlgt

lt-- 程式範例searchphp --gt lthtmlgt ltheadgtlttitlegt搜尋通訊錄lttitlegtltheadgt ltbodygt ltcentergtlth2gt搜尋通訊錄lth2gtlthrgt lt if (isset($_POST[Search])) 建立資料庫連結並選定資料庫 $link = mysql_connect(localhostroot1234) mysql_select_db(CONTACT) 建立基本的 SQL字串 $sql = SELECT FROM address 檢查是否輸入姓名 if (chop($_POST[Name]) = ) $name = name LIKE $_POST[Name] else $name = 檢查是否輸入電話號碼 if (chop($_POST[Tel]) = ) $tel = tel LIKE $_POST[Tel] else $tel =

55

if條件組合 SQL字串 if (chop($name) = ampamp chop($tel) = ) $sql= WHERE $name AND $tel elseif (chop($name) = ) 只有姓名 $sql = WHERE $name elseif (chop($tel) = ) 只有電話號碼 $sql = WHERE $tel $sql= ORDER BY name 最後加上排序 $result = mysql_query($sql) 取得欄位數 $total_fields = mysql_num_fields($result) echo lttable border=1gt echo lttrgtlttdgt編號lttdgtlttdgt姓名lttdgtlttdgt電話lttdgtlttd colspan=2gt功能選項lttdgtlttrgt 表格顯示查詢結果 while ($rows = mysql_fetch_array($result MYSQL_NUM)) echo lttrgt for ($i = 0 $i lt $total_fields $i++) echo lttdgt$rows[$i]lttdgt echo lttdgtlta href=editphpaction=editampid= echo $rows[0]gtltbgt編輯ltbgtlttdgt echo lttdgtlta href=editphpaction=delampid= echo $rows[0]gtltbgt刪除ltbgtlttdgt echo lttrgt echo lttablegtlthrgt mysql_free_result($result) mysql_close($link) gt ltcentergt ltform action=searchphp method=postgt lttable border=0 width=450gt lttrgtlttdgt搜尋姓名 lttdgt lttdgtltinput type=text name=Name size=10 maxlength=20gtlttdgtlttrgt lttrgtlttdgt搜尋電話 lttdgt lttdgtltinput type=text name=Tel

56

size=20 maxlength=20gtlttdgtlttrgt lttrgtlttd colspan=2 align=centergt ltinput type=submit name=Search value=搜尋gtlttdgtlttrgt lttablegt ltformgt ltbrgtlta href=indexhtmlgt通訊錄ltagt | lta href=addphpgt新增連絡人ltagt | lta href=searchphpgt搜尋通訊錄ltagt ltbodygt lthtmlgt

lt ob_start() gt lt-- 程式範例editphp --gt lthtmlgt ltheadgtlttitlegt編輯通訊錄lttitlegtltheadgt ltbodygt lt 取得 URL 參數 $id = $_GET[id] $action = $_GET[action] 建立資料庫連結 $link = mysql_connect(localhostroot1234) mysql_select_db(CONTACT) 選擇資料庫 執行的操作 switch ($action) case update 更新 取得欄位資料 $name = $_POST[Name] $tel = $_POST[Tel] $sql = UPDATE address SET name=$name tel=$tel WHERE id=$id mysql_query($sql) 執行 SQL指令 mysql_close($link) header(Location searchphp) 轉向到 serachphp break case del 刪除 $sql = DELETE FROM address WHERE id=$id

57

mysql_query($sql) 執行 SQL指令 mysql_close($link) header(Location searchphp) 轉向到 serachphp break case edit 編輯 $sql = SELECT FROM address WHERE id=$id $result = mysql_query($sql) 執行 SQL指令 $row = mysql_fetch_row($result) 取回記錄 $name = $row[1] 取得欄位 name $tel = $row[2] 取得欄位 tel mysql_close($link) 顯示編輯表單 gt ltcentergtlth2gt更新通訊錄lth2gtltcentergtlthrgt ltform action=editphpaction=updateampid=lt echo $id gt method=postgt lttable border=0 width=300gt lttrgtlttdgt姓名 lttdgt lttdgtltinput type=text name=Name size=20 maxlength=10 value=lt echo $name gtgtlttdgtlttrgt lttrgtlttdgt電話 lttdgt lttdgtltinput type=text name=Tel size=20 maxlength=20 value=lt echo $tel gtgtlttdgtlttrgt lttrgtlttd colspan=2 align=centergt ltinput type=submit value=更新連絡人gtlttdgtlttrgt lttablegt ltformgt ltbrgtlta href=indexhtmlgt通訊錄ltagt | lta href=addphpgt新增連絡人ltagt | lta href=searchphpgt搜尋通訊錄ltagt lt break gt ltbodygt lthtmlgt

58

52 任務二Web Base群組軟體 ( twig )

順利完成Web Base客戶通訊錄程式測試一段時間後「Apache + MySQL + PHP」架構的穩定與快速巳深得老闆與公司所有同事的認同隨著公司業績蒸

蒸日上人員組織編罝愈來愈龐大跨部門的會議愈來愈多業務員每日排滿拜

訪客戶的行程跟客戶的 Email的往來也愈來愈頻繁 愈來愈多部門的同事希望公司能建置一套群組軟體提供 web mail可讓業

務人員方便收發 mail還有連絡人議事日程待辦工作書簽等功能讓整個

公司運作及個人時間管理更有效率

老闆問小明對這些需求有什麼看法小明認為如果這些功能完全由程式部

門開發必定曠日費時而且耗費公司資源小明在網路尋找是否有提供這些功能

的Free Software皇天不負苦心人小明發現了TWIG (The Web Information Gateway) httptwigscrewdrivernet這個群組軟體它在 Web 上整合郵件新聞聯絡人議事日程工作序書簽等功能非常符合公司的需求 Step 1 下載 twig-277targz 下載網址 httptwigscrewdrivernetdownloadphp3

Step 2 解開 twig-277targz tar -xzvf twig-277targz

59

Step 3 執行安裝動作安裝到 varwwwhtmltwig 目錄 cd twig-277 twig-install varwwwhtmltwig

Step 4 建立 MySQL 資料庫(twig)及各資料表

cd setup mysql -u root -p1234 mysqlgt create database twig Query OK 1 row affected (001 sec) mysqlgt quit mysql -u root ndashp1234 twiglt twigtablemysql

Step 5 修改 configincphp3 參數設定 vi varwwwhtmltwigconfigconfigincphp3 $config[fromdomain] = opencom 網域 $config[language] = chinesebig5 中文訊息 $config[imap_port] = 143notls

60

Step 6 修改連結 MySQL 的帳號密碼 vi varwwwhtmltwigconfigdbconfigincphp3 $dbconfig[sqlusername] = root username $dbconfig[sqlpassword] = 1234 password

Step 7 其他設定檔

vi etchttpdconfhttpdconf 加入 AddType applicationx-httpd-php php3 在 DirectoryIndex最後加入 indexphp3 DirectoryIndex indexhtml indexhtmlvar indexphp3 在 AddDefaultCharset ISO-8859-1加上 AddDefaultCharset ISO-8859-1

vi etcphpini register_globals = On service httpd restart Step 8 sendmail 設定 vi etcmailsendmailcf在 264 行前面加上並重新啟動 sendmail「service snedmail restart」 262 SMTP daemon options 263 264 O DaemonPortOptions=Port=smtpAddr=127001 Name=MTA 265 266 SMTP client options 267 O ClientPortOptions=Family=inet Address=00

61

Step 9 檢查設定有無錯誤 http主機名稱twigtestphp3

62

Step 10 登入 twig ( http主機名稱twig)

63

第六章 維護及更新程序

61 日常維護

系統管理員最好定期以 root 身份登入看看信件在 RedHat Linux 中有一支 logwatch 程式會定時去分析 log file如果發現異常便會發信給 root除此之外筆者建議讀者平時就檢查 MySQL log file ( varlogmysqldlog)是否有異常情形

62 更新程序

讀者可至httprpmfindnet 尋找MySQL相關套件至於升級的相關步驟請參

考Linux OS SOP 第 54節

63 備份重要檔案

預設 MySQL 的 DB 檔案是存在 varlibmysql 內以 DB名稱為目錄目錄

內就是該 DB 的所有資料通常得定期備份還有 MySQL的設定檔 etcmycnf也別忘了一起備份

64 離線備份與還原

641 離線備份

預設 MySQL 的 DB 檔案是存在 varlibmysql 內以 DB 名稱為目錄目錄內

就是該 DB 的所有資料像 CRM 這個 DB就是存在 varlibmysqlCRM 內在備份前因為怕資料尚未完全寫入磁碟而且 MySQL 會 Lock 在使用的 DB 檔案所以應該是要先把 MySQL 先 Shutdown 一下整個備份的程序可以下像下面的指令去完成 cd varlibmysql

64

service mysqld stop tar cvfz CRM_db_20030905tgz CRM service mysqld start 對這樣就可以了 不過要注意的是怕 DB 內每個 Tables 間的資料有關關

聯性所以最好是把整個 DB 一次備起來單獨只備哪個 Tables 的檔案以後回存時怕會有資料關聯不一致的問題

642 離線還原

DB 發生錯誤而要回存時其實也不難先找出最近一次完整正常的備份先把現在錯誤的網頁或 DB 先更名或 tar 起來再把好的備份給解開回原來目錄位

置就行了需要注意的是 MySQL 服務最好也是要先停止回存完成後再啟動服務回存 DB 的整個程序可能像下面 cd varlibmysql service mysqldstop mv CRM CRM_OLD tar xvfz CRM_db_20030905tg service mysqld start

65 線上備份與還原

651 線上備份

使用像上面的檔案方式備份是個不錯的方法它最少可以保持該主機某個時間點的完整檔案備份但還是有一些問題需要考慮到有些主機就不只建立一個 DB 而已總不能為了備份某個 DB 而把整個 MySQL 服務停止備份檔案的方式回存在原主機上一定適用但假如 MySQL 版本升級或是在那天該網頁空間需遷機移機到別的主機時那就沒人敢保證備出來的資料檔可以用所以我們可以考慮另一種備份的方式是使用 MySQL 本身提供的功能 MySQL Data Dump指令是 mysqldump

65

使用 MySQL 的 Dump 功能可以把 DB 的結構資料或結構加資料 Dump 成文字檔 mysqldump 指令提供的彈性很大你可以選擇把整個 DB Dump 成一個檔或是每個 Table 為一個檔甚至是把結構檔和資料分開儲存都

可以 mysqladmin -uroot -p flush-logs mysqldump CRM -uroot -p --opt gt CRM_20030905sql (CRM 是 DB 名稱 opt 是一個使用完整 Dump 參數) 假如只是要單獨 Dump 某個 Table 時只要在上面的指令後轉出符號 gt 前加個 Table 名稱就可以如只要 phpbb2_users 這個 Table 的 Dump 時只要下 mysqldump CRM -uroot -p --opt CUSTOMER gt CRM_CUSTOMER_20030905sql

652 線上還原

若要回存整個資料庫只需將壓縮的備份檔還原成 Dump 的檔案再用下面的指令回存 mysql CRM -uroot -p lt CRM_20030905sql 這邊需注意的是若建立備份時是以--opt或--add-drop-table為參數時回存的 動作是先將舊的 Table 先刪除重建 Table 的結構後再把 Data 匯入所以回存後所有的資料會回到你當時備份那個時間點因此在回存資料時可以考慮把現有錯誤或不完整的 DB 先備份一份下來以備不時之需或是拿來比對錯誤的地

方在那裡當然你也可以把資料回存到另一個測試用的 DB 內只要把上面指令

的 DB 名稱改成你的測試用 DB 名稱即可 使用這種回存方式 MySQL 服務不需停止也不會動到其他正在使用的 DB 在一些提供 MySQL 服務的虛擬主機可用這種方式作你自己的 DB 備份及回存

66

另外假如你是系統重建或是移機時切需在新的 MySQL 內新建一個空白 DB 後才行作回存的工作你可以用下面的指令建立 mysql -uroot -p -e CREATE DATABASE CRM (上面的 CRM是你要新建的 DB 名稱) 另一種作法先用 mysql 指令進入 mysql client console 然後再用 CREATE DATABASE CRM 這樣就行了記得尾端要加個 符號該行指令才會執行

67

第七章 問題與解答

Q1RedHat 90預附的 MySQL到底有無支援 Transcation機制 Ans MySQL自 32334a之後的 MySQL-Max版本加入 InnoDB的資料庫類型透過

InnoDBMySQL同樣可以進行 COMMIT與 ROLLRACK的動作RedHat 90預附的 MySQL為 32354a-11巳支援 InnoDB的資料庫類型不過必須做以

下設定 1cp usrsharedocmysql-server-32354amy-mediumcnf to etcmycnf 2 vi etcmycnf 將以下設定前的拿掉 innodb_data_home_dir = varlibmysql innodb_data_file_path = ibdata110Mautoextend innodb_log_group_home_dir = varlibmysql innodb_log_arch_dir = varlibmysql 3service mysqld restart 如此一來各位在建立Table時便可指定Table Type為 innodb ( ex create table with type=innodb ) Q2如何解決 php+mysql 許功蓋等字變亂的問題 Ans 方法一 【確定 MySQL 預設的字元集】 1 打開 WinMySQLadmin 管理畫面(在視窗右下角狀態列紅綠燈圖示中按滑鼠

右鍵點選 Show me 選項) 2 點選管理畫面中 [Variables] 標籤選項其中 character_set變數就是您預設

字元集的變數其預設是 latin1 字元集(我們要將他改回 big5)而 chatacters_set 變數則是 MySQL 可以支援哪些字元集 【修改預設字元集變數 character_set 】 1 請點選管理畫面中 [myini Setup] 標籤選項設定 myini 2 按一下 [Pick-up and Edit myini values] 按鈕以便編輯目前的 myini 設定 3 在 [mysqld] 設定區塊底下新增一行 default-character-set = big5 變數設

68

定 4 新增一個 [client] 設定區塊並加入第三步驟的變數設定(游標往下移到空白處新增兩行 [client] 和 default-character-set=big5) 5 按一下畫面左下方 [Save Modification] 按鈕儲存設定 6 重新啟動 MySQL 或 Windows 方法二 Server端注意事項 phpini 中有關的設定為(預設值) Magic quotes for incoming GETPOSTCookie data magic_quotes_gpc = On Use Sybase-style magic quotes (escape with instead of ) magic_quotes_sybase = Off Client端注意事項 1中文資料送進 mysql 前請用 addslashes($str) 處理 2處理後送進 mysql 時請用 括起來並在參數後留一個空白如 $sql = UPDATE ezf_table set tablename=$tname tableend=$endtime table inguser=$tguser tableingid=$tguserid tableallnumber=$tnumber tableloca l=$tablelocal tableanyone=$tableopen tabletext=$ttext WHERE tableid=$t ableid tablename=$tname c 取出時請用 stripslashes($str) Q3MySQL root 密碼忘了該怎麼辦 Ans 1先停掉 mysql etcrcdinitdmysql stop 2以--skip-grant-table 的參數啟動 mysql safe_mysql --skip-grant-tableamp 3 更改 root 密碼 mysql mysql mysqlgt UPDATE user SET password=password(newpassword)

69

WHERE user=root mysqlgt FLUSH PRIVILEGES mysqlgt exit 4停掉 mysql再重跑 mysqladmin -uroot -p shutdown Enter password 輸入新設定的密碼 etcrcdinitdmysql start

Q4NULL值問題

Ans

NULL值的概念是造成 SQL的新手的混淆的普遍原因他們經常認為 NULL是和一個空字符串的一樣的東西不是這樣的例如下列語句是完全不同的

mysqlgt INSERT INTO my_table (phone) VALUES (NULL)

mysqlgt INSERT INTO my_table (phone) VALUES ()

兩個語句把值插入到 phone 列但是第一個插入一個 NULL值而第二個插入一個空字符串第一個的含義可以認為是ldquo電話號碼不知道而第二個則可意味

著ldquo她沒有電話

在 SQL中NULL值在于任何其他值甚至 NULL值比較時總是假的(FALSE)包含 NULL的一個表達式總是產生一個 NULL值除非在包含在表達式中的運算符和函數的文檔中指出在下列例子所有的列返回 NULL

mysqlgt SELECT NULL1+NULLCONCAT(InvisibleNULL)

如果你想要尋找值是 NULL的列你不能使用=NULL測試下列語句不返回任

何行因為對任何表達式expr = NULL是假的

mysqlgt SELECT FROM my_table WHERE phone = NULL

要想尋找 NULL值你必須使用 IS NULL測試下例顯示如何找出 NULL電話號碼和空的電話號碼

70

mysqlgt SELECT FROM my_table WHERE phone IS NULL mysqlgt SELECT FROM my_table WHERE phone =

在 MySQL中就像很多其他的 SQL服務器一樣你不能索引可以有 NULL值的列你必須聲明這樣的列為 NOT NULL而且你不能插入 NULL到索引的

列中

當用 LOAD DATA INFILE 讀取數據時空列用更新如果你想要在一個列中有

NULL值你應該在文本文件中使用N字面上的詞NULL也可以在某些情形下使用

當使用 ORDER BY時首先呈現 NULL值如果你用 DESC以降序排序NULL值最後顯示當使用 GROUP BY時所有的 NULL值被認為是相等的

為了有助于NULL的處理你能使用 IS NULL和 IS NOT NULL運算符和 IFNULL()函數

對某些列類型NULL值被特殊地處理如果你將 NULL插入表的第一個TIMESTAMP 列則插入當前的日期和時間如果你將 NULL插入一個AUTO_INCREMENT 列則插入順序中的下一個數字

Q5如何將圖片存放於 MySQL中

Ans

Step 1建立資料庫 test

Step 2 建立表格 binary_data

CREATE TABLE binary_data (

id INT(4) NOT NULL AUTO_INCREMENT PRIMARY KEY

description CHAR(50)

bin_data LONGBLOB

filename CHAR(50)

filesize CHAR(50)

filetype CHAR(50)

71

)

Step 3 利用 storephp 寫入圖片

storephp 程式碼

ltHTMLgt ltHEADgtltTITLEgtStore binary data into SQL DatabaseltTITLEgtltHEADgt ltBODYgt lt code that will be executed if the form has been submitted

if ($submit) mysql_connect(localhostrootYOUR_PASSWORD) mysql_select_db(test) $data=Base64_Encode(fread(fopen($form_data r) filesize($form_data))) $result=MYSQL_QUERY(INSERT INTO binary_data (descriptionbin_datafilenamefilesizefiletype) VALUES ($form_description$data$form_data_name$form_data_size$form_data_type)) $id= mysql_insert_id() print ltpgtThis file has the following Database ID ltbgt$idltbgt MYSQL_CLOSE() else else show the form to submit new data

gt

ltform method=post action=ltphp echo $PHP_SELF gt enctype=multipartform-datagt File Descriptionltbrgt ltinput type=text name=form_description size=40gt ltINPUT TYPE=hidden name=MAX_FILE_SIZE value=4000000gt ltbrgtFile to uploadstore in databaseltbrgt ltinput type=file name=form_data size=40gt ltpgtltinput type=submit name=submit value=submitgt ltformgt lt

72

gt ltBODYgt ltHTMLgt

Step 3 利用 storephp 取出圖片

getdataphp 程式碼

lt Syntax getdataphp3id=ltidgt if($id) you may have to modify login information for your database server MYSQL_CONNECT(localhostrootYOUR_PASSWORD) mysql_select_db(test) $query = select bin_datafiletype from binary_data where id=$id $result = MYSQL_QUERY($query) $data = Base64_Decode(MYSQL_RESULT($result0bin_data)) $type = MYSQL_RESULT($result0filetype) Header( Content-type $type) echo $data gt

Q6MySQL裝好之後啟動時或是執行 mysqladmin會出現如下訊息 Cant connect to local MYSQL Server through Socket varlibmysqlmysqlsock或是

Cant connect to local MYSQL Server through Socket tmpmysqldsock

Ans 可能有下列幾個原因

1這個 mysqldsock 不見了被某人刪除了或是被一些系統自動執行程式給刪

了例如有些 cron任務便會設定定期刪除 tmp 裡的東西所以呢您只能修改

cron 裡的設定讓它不要清除 mysqldsock 2在啟動時也可以改變 mysqldsock的位置您在啟動 MySQL的時候可以加入此參數usrlocalmysqlbinsafe_mysqld --user=mysql --socket=其他路

徑socket amp 同時得去設定環境變數 MYSQL_UNIX_PORT的值以指定新的

73

路徑 3若是您沒改 MYSQL_UNIX_PORT的值那麼您可以在執行指令的時候才打

例如mysqladmin --socket=其他路徑socket version Q7How to get the last insert id Ans CREATE TABLE product ( id INT(4) NOT NULL AUTO_INCREMENT PRIMARY KEY description VARCHAR(50) ) 1利用 SQL的話 mysqlgt insert into product(description) values(123) Query OK 1 row affected (000 sec) mysqlgt select last_insert_id() +------------------+ | last_insert_id() | +------------------+ +------------------+ 1 row in set (000 sec) ======================================== 2如果是 PHP的話 你可以用mysql_insert_id()取得該 id PHP example $result=MYSQL_QUERY(INSERT INTO product (description) VALUES ($description)) $id= mysql_insert_id() print This file has the following Database ID $id Q8如何將文字檔匯入資料庫 Ans $addr=homehttpdhtmlphpschool001txt $sql_select = load data infile $addr into table test fields terminated by t 解說 $sql_select = load data infile 文字檔名 into table 表格名 fields terminated by

74

t

(欄位分隔以 TAB鍵) 該文字檔須與資料表欄位格式相符 例如欄位有三個 則文字檔為每行一筆資料如下 欄 1資料ltTABgt欄 2資料ltTABgt欄 3資料 欄 1資料ltTABgt欄 2資料ltTABgt欄 3資料 欄 1資料ltTABgt欄 2資料ltTABgt欄 3資料 欄 1資料ltTABgtltTABgt欄 3資料

Q9如何撰寫 MySQL C API Ans Step 1利用文字編輯器撰寫以下程式碼 mysqlcc

include ltstdiohgt

include ltmysqlmysqlhgt

int main (int argc char argv[])

MYSQL mysql

MYSQL_RES res

MYSQL_ROW row

if (argc = 2)

fputs (Usage myc ltdatabasegt stderr)

return 1

if ((mysql_connect(ampmysqllocalhostrootYour_Password)))

fputs (Error connecting stderr)

abort()

75

if (mysql_select_db(ampmysqlargv[1]))

fputs (Error selecting database stderr)

abort()

if (mysql_query(ampmysqlSELECT FROM test_table))

fputs (Error processing query stderr)

abort()

if ((res = mysql_store_result(ampmysql)))

fputs (Error storing results stderr)

abort()

while((row = mysql_fetch_row(res)))

uint i = 0

for (i=0 i lt mysql_num_fields(res) i++)

printf(s row[i])

printf(n)

return 0

Step 2 Compile

gcc -Iusrlocalmysqlinclude -Lusrlocalmysqllibmysql mysqlcc ndashlm -lmysqlclient

(其中 include path與 library path取決於你的 MySQL安裝路徑)

76

如果執行時發生如下 error Run problemerror in loading shared libraries libmysqlclientsoX 將你的 MySQL library path(for exampleusrlocalmysqllibmysql) 加入etcldsoconf and run sbinldconfig -v Q9ASP + MySQL 範例程式 Ans Dim myconn As New ADODBConnection Dim myrs As New Recordset Dim mySQL As String Dim myrows As Long myconnOpen DSN=MyODBCsample mySQL = SELECT from user myrsSource = mySQL Set myrsActiveConnection = myconn myrsCursorLocation = adUseClient myrsOpen myrows = myrsRecordCount myrsClose myconnClose 可參考 httpwwwdwamnetmysqlasp_myodbcasp 有詳細的資料 Q10如何將 MySQL中的資料庫匯出成txt檔 Ans select from TableName into outfile textxls all result fields will seperate by tab

77

第八章 參考資料

英文部份 網址 1 httpwwwmysqlcom MySQL 網站有第一手有關 MySQL的資料 2 httpwwwmysqlcomdocenReplicationhtml 有關 MySQL Replication 的文件 3 httpwwwgeocitiescomsqlhomefaqstore_blobhtml 如何在 MySQL 存放 BLOB的資料 4httpwwwsapdborg 有關 SAP跟 MySQL相關合作的網站 書藉 1 Cooking with MySQL

Paul DuBois has selected sample recipes from the hundreds youll find in his book MySQL

Cookbook In this third and final series of excerpts showcasing these recipes learn how to

compute team standings how to calculate the differences between successive Dec 26

2002 2 Tips for Building Web Database Applications with PHP and MySQL by Hugh E Williams co-author of Web Database Applications with PHP amp MySQL 04042002

3 Managing and Using MySQL 2nd Edition By Tim King George Reese Randy Jay Yarger

4 MySQL Cookbook By Paul DuBoisPublisher OReillyPub Date October 2002

中文部份

78

1 httplinuxtncedutwtechdocmysqlmysql_docmanual_tochtml MySQL 中文手冊 2 httpchenshloxaedutwphpZ_1php PHP+MySQ程式研習設計網站 3 httplinuxtncedutwtechdocbanicdownhtml PHP 4 手冊 4 httpwwwtncedutwadmin_zonephp台南縣教育網網路中心有很多 Linux相關文件 5 httpdobtncedutw網站建置百寶箱有很多 PHP MySQL 相關範例程式 5 httpwwwdbworldcomtw資料庫專家電子雜誌介紹資料庫的重要觀念及名詞

79

附錄一 SQL Command 介紹

SQL (讀音ess-que-el) 是一種結構查詢語法SQL 使用於資料庫交流

傳遞相容於 ANSI (American National Standards Institute) 是一套標準的關聯

式資料庫語言 SQL 語言是執行更新或從資料系統獲取資料一般常見的關聯

資料庫系統都有提供 SQL 如 Oracle Sybase Microsoft SQL Server Access Ingres 等雖然大部份的資料庫都有提供 SQL 但也多提供了自已獨特的語

法造成了不相容的情形但標準基本的語法是相通的如Select Insert Update Delete Create and Drop 每一個系統都有支援

Table相關 Command

Create Table

關聯式資料庫包含有很多元件稱為資料表(tables) 把資料或訊息放在資

料表中 資料表是以不同的名稱做分別資料表由欄列所構成的二維陣列

欄包含欄位名資料型態 及其他可判斷的資訊列是由全部欄位構成一筆一

筆的紀錄 create table 語法用在建立一個新的資料表語法格式如下

create table tablename (column1 data type column2 data type column3 data type)

Format of create table if you were to use optional constraints

create table tablename (column1 data type [constraint] column2 data type [constraint] column3 data type [constraint]) [ ] = optional

Note You may have as many columns as youd like and the constraints are optional

80

Example

create table employee (first varchar(15) last varchar(20) age number(3) address varchar(30) city varchar(20) state varchar(20))

注意建立資料表格式要以括號把前後框住而最後以(分號)做結尾

欄位名不要超過 30個字元長而且不要使用 sql 的關鍵字(如 where select等)而在後面接是型態的宣告(如字串數字日期格式等)

資料型態是來描述欄位的方式如一個欄位Last_Name 是一個姓氏可以使用varchar (可變動長度字串) 資料型態

以下是幾個常見的資料庫型態 char(size) 固定長度字串最長為 255 位元 varchar(size) 變動長度字串最大字元數以 size 來指定 number(size) 數值格式可以是整數也可以是小數最大數字以 size 位數判

斷未指定小數位數由系統內定 date 日期格式 number(sized) 數值格式最大數字以 size 位數判斷d 為小數位數整數位

數為 size-d 位

有何限制當資料表被建立通常有一或數個欄位是要使用來做關聯的功

能 例如unique 限制(唯一值)兩筆記錄不可以相同的值 not null (非空值)該欄位一定要輸入資料不可是空的primary key (主鍵)是每一筆記錄識別的主要方式

Drop a table drop table 刪除資料表(其中的資料也會一併刪除)

drop table tablename

Example

81

drop table 和刪除全部資料是不同的刪除全部資料欄位名稱資訊等還會

存在但刪除資料表會把這一些也一併移除掉

如何查詢資料

Select 基本用法

select 語法是關連式資料庫最常用的部份可以取得你想要的資料這是一個

簡單的範例 select column1[column2etc] from tablename [where condition] [] = optional 在 select 之後所列欄位名則是要顯示的資料部份你可以一一列出各欄位

名或是以 (星號)來代表選擇全部的欄位 from 之後放資料表名稱 where 子句 (選項) 指定要過濾的條件符合者才會顯現 where 可使用的條件運算元 = 等於 gt 大於 lt 小於 gt= 大或等於 lt= 小或等於 ltgt 大相等 LIKE 相似 For example select first last city

82

from empinfo where first LIKE Er 以Er 為開頭的字串就符合要以單引號框住 Or you can specify select first last from empinfo where last LIKE s 最後一字為 S 就符合 select from empinfo where first = Eric 則表示 first name 一定要是 Eric 才可以 範例資料表empinfo 統計函數

MIN 傳回指定欄位最小值

MAX 傳回指定欄位最大值

SUM 傳回指定欄位總和

AVG 傳回指定欄位平均值

COUNT 傳回指定欄位的筆數

COUNT() 傳回資料庫中的總筆數

統計函數使用於資料表中的數值欄位配合 SELECT 語法使用 只用於總結特定單一欄位可以配合 GROUP BY 做篩選但也可以不使用 GROUP BY 語句For example

SELECT AVG(salary) FROM employee

83

傳回全部 salary 平均值

Another example

SELECT AVG(salary) FROM employee WHERE title = Programmer

傳回 salary 平均值條件為 employees 資料表中當 title 等於 Programmer

Example

SELECT Count() FROM employees

傳回 employees 資料表中紀錄總筆數

GROUP BY 語法 SELECT column1 SUM(column2) FROM list-of-tables GROUP BY column-list The GROUP BY 語句可以先以所列的欄位為條件分組排序在一起(可以多欄

位) example 要列出每一個 dept 中最高 salary 值 SELECT max(salary) dept FROM employee GROUP BY dept HAVING 語法

SELECT column1 SUM(column2) FROM list-of-tables GROUP BY column-list HAVING condition

HAVING 子句是 GROUP BY 的一部份用來過濾在 GROUP BY 所選出的資料功能如同 select 命令中 where 條件式一樣只是 HAVING 必需配合 GROUP BY 使用

我們以例子來說明我們要取得每一公司名及每一公司的薪水平均值輸入如下

84

SELECT dept avg(salary) FROM employee GROUP BY dept

但如果我們只列出薪資平均值超過 20000元的公司資料

SELECT dept avg(salary) FROM employee GROUP BY dept HAVING avg(salary) gt 20000

ORDER BY子句語法

SELECT column1 SUM(column2) FROM list-of-tables ORDER BY column-list [ASC | DESC]

[ ] =選項

ORDER BY是一個選項子句當你以排序方式來顯示資料(正向由小到大反向由大到小)以指定的欄位資料做排序

ASC = 正向- 預設值 DESC = 反向排序

For example

SELECT employee_id dept name age salary FROM employee_info WHERE dept = Sales ORDER BY salary

以上列出公司代號公司名銷售員人名年紀及薪資而條件是公司名為 Sales 顯示順序以薪資多少排序(由小到大為預設值)

如果要以多個欄位做排序要以逗號做分隔如下

SELECT employee_id dept name age salary FROM employee_info WHERE dept = Sales ORDER BY salary age DESC

85

結合條件及布林運算 SELECT column1 SUM(column2) FROM list-of-tables WHERE condition1 AND condition2 AND運算可以結兩個或以上的條件放在 WHERE子句中 兩者都要為真才

會顯示該筆記錄 OR 運算可以結兩個或以上敘述放在 WHERE子句中只要其中一個為直就

會顯示該筆記錄 For example SELECT employeeid firstname lastname title salary FROM employee_info WHERE salary gt= 5000000 AND title = Programmer 必需要薪資大於等於 50000而且職稱為 Programmer同時符合才會顯示該筆資料 以下以括號括住雖然不是必需的但如此比較容易讀 SELECT employeeid firstname lastname title salary FROM employee_info WHERE (salary gt= 5000000) AND (title = Programmer) 另外範例 SELECT firstname lastname title salary FROM employee_info WHERE (title = Sales) OR (title = Programmer) 條件為只要是 Sales 或 Programmer 職稱的就會被列出 IN and BETWEEN 子句

SELECT column1 SUM(column2) FROM list-of-tables WHERE column3 IN (list-of-values) SELECT column1 SUM(column2) FROM list-of-tables WHERE column3 BETWEEN value1 AND value2 IN 子句使用在列舉項目的使用上也就是分別測試是否符合所列的值 For example

86

SELECT employeeid lastname salary FROM employee_info WHERE lastname IN (Hernandez Jones Roberts Ruiz) 條件為姓氏(astname)要符合 Hernandez Jones Roberts or Ruiz 其中一個才會被傳回 IN運算元也可以使用 OR 的語法來取代如下結果相同 SELECT employeeid lastname salary FROM employee_info WHERE lastname = Hernandez OR lastname = Jones OR lastname = Roberts OR lastname = Ruiz 但使用 IN 句子比較短也比較易懂 你也可以使用 NOT IN 來去掉不要的記錄 BETWEEN 運算元使用在判斷是否存在兩個數值之間 For example SELECT employeeid age lastname salary FROM employee_info WHERE age BETWEEN 30 AND 40 傳回年紀 30歲到 40歲之間的資料(含 30及 40歲者) 相同的也可以使用以下語法來達到相同的結果 SELECT employeeid age lastname salary FROM employee_info WHERE age gt= 30 AND age lt= 40 你也可使用 NOT BETWEEN 來濾掉中間值的資料 數學運算 標準 ANSI SQL-92 提供以下運算

87

+ 加

- 減

餘數

餘數為除法後剩整數這不在標準的 ANSI SQL 中但大部份的資料庫都會支

援這運算元以下列出有用的函數雖不在 ANSI SQL-92 提供但一般資料庫

也會支援他們

ABS(x) 傳回 x 絕對值

SIGN(x) returns the sign of input x as -1 0 or 1 (negative zero or positive respectively)

MOD(xy) 餘數 - returns the integer remainder of x divided by y (同 xy)

FLOOR(x) 傳回小或等於 x 的最大整數值

CEILING(x) or CEIL(x)

傳回大或等於 x 的最小整數值

POWER(xy) x的 y 次方

ROUND(x) 把 x 四捨五入為整數

ROUND(xd) 四捨五入取到小數 d 位

SQRT(x) x 開平方

For example SELECT round(salary) firstname FROM employee_info 傳回薪資取到整數位

如何新增資料

insert 加入一筆新紀錄到資料表中 insert into tablename (first_columnlast_column) values (first_valuelast_value) [] = optional Example insert into employee

88

(first last age address city state) values (Luke Duke 45 2130 Boars Nest Hazard Co Georgia) Note 字串要以單引號住如string 數字框住也無妨 insert into 後面接資料表名稱再接以括號括住的欄位名在 values 後括號分別對映各欄位的值 以上的例子新增了一筆名(first) 為 Luke而住所(state) 為 Georgia 的資料

如何刪除資料

delete 可以刪除單筆或多筆紀錄 delete from tablename where columnname OPERATOR value [and|or column OPERATOR value] [ ] = optional Examples delete from employee Note 如果你沒有指定 where 子句那麼全部的紀錄都會被刪除 delete from employee where lastname = May delete from employee where firstname = Mike or firstname = Eric delete from 接著資料表名 再接著是條件式判斷沒有條件式則全部紀錄會

被刪除

如何更新資料

update 用來更新你所指定的記錄要和 WHERE 配合小心使用 語法 update tablename set columnname = newvalue[nextcolumn = newvalue2] where columnname OPERATOR value [and|or column OPERATOR value] [] = optional Examples

89

update phone_book set area_code = 623 where prefix = 979 update phone_book set last_name = Smith prefix=555 suffix=9292 where last_name = Jones update employee set age = age+1 where first_name=Mary and last_name=Williams

90

附錄二Replication

測試環境

RedHat 90 + MySQL 32358 MySQL資料庫路徑 varlibmysql MySQL設定檔 etcmycnf Master IP 1921680100 Slave IP 1921680200 請至下列網址下載最新MySQL 32358套件並利用rpm ndashUvh 更新 httpupdatesredhatcom9enosi386

圖 最新 MySQL 套件

測試架構圖

91

1921680100

1921680200Master Server

erveSlave S r

圖 測試架構圖

測試步驟

Master server 部份 Step1 確認 MasterSlave機器上所裝的 MySQL版本能進行

replication( 32329 or higher ) Step2 在 Master MySQL上開放一個帳號給 Slave mysql ndashu root ndashp mysqlgtGRANT FILE ON TO repl1921680200 IDENTIFIED BY lsquoabc123rsquo mysqlgtq 上面是 Master開放一個帳號 repl密碼 abc123給 IP1921680200有檔案處理

的權限 Step3 shutdown MySQL on the Master mysqladmin ndashu root ndashp shutdown Step4 備份 Master所有資料庫 tar ndashcvf tmpmysql-snapshottar varlibmysql 注意tar的時候MySQL是要在 stop情況下 在mysql (wwwmysqlcom) 網站的FAQ有不用shutdown的方法

92

Step5 在 master機器上修改etcmycnf 在[mysqld]區段內加入參數 log-bin server-id=這邊設定 server-id=1 sql-bin-update-same binlog-do-db=CRM只針對 CRM資料庫做紀錄 Step6 Restart MySQL on the master service mysqld start 此時因為有加入 log-bin 參數因此開始有 index產生了在varlibmysql目錄下

有index檔案紀錄資料庫的異動 log Slave server 部份 Step1 在 slave設定etcmycnf 在[mysqld]區段加入 master-host= master-user= master-password= master-port= server-id= 這邊設定 master-host=1921680100 master-user=repl master-password=abc123 master-port=3306 server-id=2 master-connect-retry=60預設重試間隔 60秒 replicate-do-db=CRM告訴 slave只做 CRM資料庫的更新 log-slave-updates Step2 將 master上的 mysql-snapshottar copy到 slave上 用 ftp傳到 slave的tmp Step3 解壓縮 Master資料庫至 Slave Server上 cd varlib tar xvf tmpmysql-snapshottar chown ndashR mysqlmysql mysql

93

chmod ndashR 770 mysql (視情況) Step4 Restart MySQL on the slave server 這時在varlibmysql目錄會出現 masterinfo此檔案紀錄了 Master MySQL server的資訊

狀況測試

One-way replication

1921680100

1921680200Master Server

erveSlave S r

圖 One-way replication架構圖 Step1 Master跟 Slave網路及服務都正常情況下由 Master端異動資料後 到 Slave端瀏覽資料檢視是否有進行 replication Step2 模擬 Slave Server 當機 可用在於 slave真的當機或是 Slave 不一定需要一直跟 master connect將Slave MySQL server shutdown由 Master端異動資料到 slave端瀏覽此時Slave應該沒有被 replication 更新然後再將 Slave端 MySQL server start起來

預設 60秒後 Slave會嘗試跟 Master要求進行 replication再去 Slave端檢視是否有更新資料

94

Step3 模擬 Master當機因為是設定 One-way replication一旦 Master Server Slave端沒有 Master的 source可以 download Two-way replication 基於 Master當機狀況於是發展雙向 Replication即 1921680100 ( Host A ) 1921680200 ( Host B )都分別擔任 MasterSlave身分

1921680100

1921680200er

Server B MasterSlave Server

Server A MasterSlave Serv

圖 Two-way replication架構圖 以下是針對兩台 MySQL伺服器進行雙向 Replication Step1觀念同單向 replication只是改成 Master也有 Slave身分 Slave也有Master的身分先分別在 Server AServer B 都去 grant一個進行 replication的身分 [A]mysqlgtGRANT FILE ON TO repl1921680200 IDENTIFIED BY lsquoabc123rsquo [B]mysqlgt GRANT FILE ON TO repl1921680100 IDENTIFIED BY lsquoabc123rsquo Step2做完單向 replication後stop Server Aserver B MySQL service此時 AB資料是一樣的

95

修改etcmycnf設定 範例 Server A [mysqld] datadir=varlibmysql socket=varlibmysqlmysqlsock server-id=1 log-bin sql-bin-update-same binlog-do-db=CRM master-host=1921680200 master-user=repl master-password=abc123 log-slave-updates master-connect-retry=60 replicate-do-db=CRM Server B [mysqld] datadir=varlibmysql socket=varlibmysqlmysqlsock server-id=2 log-bin sql-bin-update-same binlog-do-db=CRM master-host=1921680100 master-user=repl master-password=abc123 log-slave-updates master-connect-retry=60 replicate-do-db=CRM 分別 start Server AServer B MySQL後此時雙方都是 MasterSlave身分一旦哪一方資料異動就會通知對方來 replication-若 replication失效則必須將Server AServer B的masterinfo及index00x 都砍掉然後分別 restart MySQL server進行測試檢視成果 實務上通常如果需要做Two-way replication通常會搭配Virtual Server使用

96

在前端架設一台Virtual Server不過此部份不在此份SOP討論範圍內有興趣

的讀者可參考 httpwwwlinuxvirtualserverorg 網站

1921680100 1921680200

Host A MasterSlave Server

Host B MasterSlave Server

Virtual Host

圖 Virtual Server + Two-way replication 架構圖

97

圖 High Availability Linux Virtual Server架構圖

98

  • COSA-SOP-03-006
  • 第一章 簡介
    • 11適用對象 (Audience)
    • 12 MySQL本身
    • 13 MySQL 40版跟50版重大的改進功能
    • 14 各家資料庫軟體比較
      • 第二章 前置需求
      • 第三章 安裝
        • 31 MySQL安裝
        • 32 phpMyAdmin安裝
        • 33 升級及注意事項
          • 第四章 MySQL管理
            • 41 Webmin 管理介面
            • 42 phpMyAdmin 的操作介面
            • 43管理指令介紹
              • 431 利用mysqladmin設定root的密碼
                  • 第五章 實用範例
                    • 51 任務一Web Base客戶通訊錄
                    • 52 任務二Web Base群組軟體 ( twig )
                      • 第六章 維護及更新程序
                        • 61 日常維護
                        • 62 更新程序
                        • 63 備份重要檔案
                        • 64 離線備份與還原
                        • 65 線上備份與還原
                          • 第七章 問題與解答
                          • 第八章 參考資料
                          • 附錄一 SQL Command 介紹
                          • 附錄二Replication
Page 12: DataBase Server Standard Operation Procedureebooks.lib.ntu.edu.tw/1_file/oss/63/93doc4-5.pdf · 業務的公司帶來了不少壓力,譬如微軟,甲骨文 ... 外的錢用在第三方的資料庫產品上,譬如就可以不用再購買甲骨文公司

第三章 安裝

31 MySQL安裝

在 RedHat 90上安裝 MySQL是件很容易的事因為 RedHat 90提供了一

個很方便的 GUI套件管理工具「redhat-config-packages」各位只要把 RedHat 90第一片光碟放入並以 root的身份登入系統鍵入 redhat-config-packages勾選「SQL資料庫伺服器」即可然後按「更新」如果遇到任何相依性問題

系統會提示您更換光碟片 ( 圖 3-1 ~ 3-3 ) Step 1 執行 redhat-config-packes

圖 3-1

Step 2 選擇資料伺服器

12

圖 3-2

Step 3檢查是否安裝成功 待安裝後您可以用利用「rpm -qa | grpe ^mysql」檢查是否安裝成功

圖 3-3

啟動 MySQL ( Command Mode )馬上啟動 MySQL的指令為「service mysqld start」如果您希望一開機就自動啟動 MySQL請執行「chkconfig mysqld on」

13

圖 3-4

啟動 MySQL ( WebMin 介面 ) 我們也可以利用WebMin 來啟動 MySQL步驟如下 Step 1登入Webmin

圖 3-5 登入WebMin

Step 2 選擇伺服器

14

圖 3-6 伺服器畫面

Step 2 選擇 MySQL資料庫伺服器

圖 3-7 伺服器畫面

15

Step 3 啟動 MySQL資料庫伺服器

圖 3-8 啟動 MySQL

更改資料庫管理者密碼

成功啟動 MySQL後因為資料庫管理者預設沒有密碼建議使用前更改系

統管理者密碼請輸入下列指令

mysqladmin ndashu root ndashh cosaexamplecom password lsquo1234rsquo -u 表示使用者帳號root 為 MySQL預設的管理帳號

-h 表示 MySQL主機的主機名稱也可使用 IP Address password 表示使用者的密碼因為字串請使用單引號將密碼括起來

圖 3-9 修改 MySQL 的密碼

16

32 phpMyAdmin安裝

本書除了會介紹利用當今 Linux上最紅的整合管理工具Webmin 來管理

MySQL外還會為各位介紹專門管理 MySQL的工具 phpMyAdmin phpMyAdmin是免費的 PHP原始程式碼的Web網站可用來管理整個

MySQL伺服器這是一套Web介面的 MySQL管理程式支援中文的使用者介

面 phpMyAdmin只需透過瀏覽器就可管理 MySQL伺服器換句話說不論

MySQL是安裝在 Linux或是Windows 作業系統都可以使用相同步驟在

MySQL上建立資料庫(Database)資料表(Table)和編輯紀錄(Record) Step 1 下載phpMyAdmin ( httpwwwphpmyadminnet )選擇最櫎新穩定的版

本 253

圖 3-10 httpwwwphpmyadminnet

17

圖 3-11 下載 phpMyAdmin-253-phptarbz2

Step 2 將 phpMyAdmin-253-phptarbz2收至 tmp 並執行下列指令將其解壓

縮至varwww tar jxvf phpMyAdmin-253-phptarbz ndashC varwwwhtml

圖 3-12 解壓縮安裝 phpMyadmin-253

Step 3 為了操作方便起見建立 Soft link ln ndashs phpMyAdmin-253 phpMyAdmin

圖 3-13 修改 phpMyadmin 設定檔 configincphp

18

Step 4 修改 phpMyadmin 設定檔 configincphp gedit varwwwhtmlphpMyAdminconfigincphp

圖 3-14 configincphp設定檔

Step 5 設定顯示行號以方便修改 configincphp 設定檔

19

圖 3-15 顯示行號

Step 6 修改下列設定 第 39 行 設定 phpMyAdmin的 URL 第 69 行 MySQL Server 的 ip 第 80 行 利用何帳號存取 MySQL 第 81 行 如果 root有設定 password此處即填入 root的 password

30 In most cases you can leave this variable empty as the correct value

31 will be detected automatically However we recommend that you do

32 test to see that the auto-detection code works in your system A good

33 test is to browse a table then edit a row and save it There will be

34 an error message if phpMyAdmin cannot auto-detect the correct value

35

36 If the auto-detection code does work properly you can set to TRUE the

37 $cfg[PmaAbsoluteUri_DisableWarning] variable below

38

39 $cfg[PmaAbsoluteUri] = httpossccosaorgtwphpMyAdmin

hellip

20

hellip

69 $cfg[Servers][$i][host] = localhost MySQL hostname or IP address hellip 80 $cfg[Servers][$i][user] = root MySQL user

81 $cfg[Servers][$i][password] = 1234 MySQL password (only needed

圖 3-16 修改 configincphp

21

圖 3-17 修改 configincphp

圖 3-18 修改 configincphp p

Step 7 設定語系

22

圖 3-19 設定語系

圖 3-20 執行 phpMyAdmin

23

33 升級及注意事項

RedHat 90附的 MySQL版本為 323 MySQL所釋出最新穩定版本為

40若是您不想用系統預附的 323請先利用下列移除之前 323的版本

rpm ndashe mysql-devel rpm ndashe mysql-server rpm ndashe mysql --nodeps 然後到下列網址下載您所想要的版本進行安裝在這裏我們用 4014版為例 Step 1 下載相關套件( httpwwwmysqlcomdownloadsmysql-40html )

圖 3-21 Download MySQL 4014 相關 RPM Step 2 利用 rpm 指令安裝

24

圖 3-22 Install MySQL 4014 相關 RPM

圖 3-23 Install MySQL 4014 相關 RPM

Step 3 啟動 MySQL

25

圖 3-24 啟動 MySQL 4014 並修改密碼

26

第四章 MySQL管理

本章將我們介紹利用WebminphpAdminCommand的方式建立一個名為

CONTACT的資料庫內有一個 address的 Table作為我們客戶通訊錄程式使

用的資料庫

41 Webmin 管理介面

412建立資料庫

Step 1 登入Webmin

圖 4-1 登入WebMin

Step 2 點選伺服器

27

圖 4-2 伺服器畫面

Step 3 點選 MySQL資料庫伺服器

圖 4-3 MySQL資料庫伺服器

28

Step 4 建立一個新的資料庫

圖 4-4 建立 MySQL資料庫

Step 5 建立名為 CONTACT的資料庫

29

圖 4-5 指定資料庫名稱

412 建立資料表

假設我們要建立一個名為 address的 Table其結構如下 欄位名稱 資料型態 長度 說明 id INT (自動編號) 連絡人編號 name varchar文字 20 連絡人姓名 tel Varchar文字 15 連絡人電話 Step 1 選擇 CONTACT資料庫

30

圖 4-6 選擇資料庫

Step 2 指定欄位數目

31

圖 4-7 設定欄位數目

Step 3設定表格欄位屬性

圖 3-8 設定表格欄位屬性

Step 4建立表格資料

32

圖 4-9 建立表格資料

圖 4-10 檢視資料

33

圖 4-11 新增資料

圖 4-12

34

圖 4-13

413 使用者管理

接下來我們要利用Webmin 來建立資料庫使用者並給予某些權限 Step1建立使用者

35

圖 4-14 選擇使用者權限

圖 4-15

36

Step2 賦予權限

圖 4-16

Step3 權限列表

37

圖 4-17

38

42 phpMyAdmin 的操作介面

421建立資料庫

Step 填入資料庫名稱並按「建立」

圖 4-18建立資料庫

422 建立資料表

Step1 填入資料表名稱並指定欄位數量 執行

39

圖 4-19填入資料表名稱並指定欄位數量

Step2 設定欄位屬性

圖 4-20設定欄位屬性

40

Step3 phpMyAdmin會產生相關的 SQL Command

圖 4-21 資料表結構及相關 SQL Command

Step4新增 Record

41

圖 4-22

圖 4-23

42

圖 4-24

圖 4-25

43

423使用者管理

Step1建立使用者

圖 4-26

44

圖 4-27

Step2 給予權限

圖 4-28

Step3權限列表

45

圖 4-29

43管理指令介紹

431 利用 mysqladmin設定 root的密碼

當您在Windows 或 Linux 中安裝好 MySQL後系統會自動幫您建立兩個

帳分別是 root 和 匿名者MySQL的 root 跟 Linux 最高權限使用者 root無關MySQL的 root使用者相當於 MS SQL 中的 sa 帳號擁有最高的 Database管理權限但系統預設 MySQL的 root 是不需要密碼所以通常我們一安裝

MySQL後首要任務便是修改 root的密碼 我們可以利用 mysqladmin工具或是直接修改 MySQL內部資料庫的使用者資

料 mysqladmin ndashu root ndashh cosaexamplecom password lsquo1234rsquo

46

-u 表示使用者帳號root 為 MySQL預設的管理帳號

-h 表示 MySQL主機的主機名稱也可使用 IP Address password 表示使用者的密碼因為字串請使用單引號將密碼括起來 密碼設定完成之後還是可以利用 mysqladmin修改密碼但是你必須提供目前的密碼

432 連線 MySQL

mysql -uroot -p密碼 (-p和密碼之間不能有空白) 或 mysql -uroot -p (此方式會在進入後要求密碼) [rootossc phpMyAdmin] mysql -u root -p1234

Welcome to the MySQL monitor Commands end with or g

Your MySQL connection id is 25 to server version 32354

Type help or h for help Type c to clear the buffer

mysqlgt show databases

+----------+

| Database |

+----------+

| mysql |

| test |

+----------+

2 rows in set (000 sec)

mysqlgt exit

Bye

[rootossc phpMyAdmin]

433 建立資料庫

可利用 mysqladmin指令建立 CONTACT資料庫 mysqladmin -u root -p1234 create CONTACT

47

或是利用 mysql指令 [rootossc bluepage] mysql -u root -p1234 Welcome to the MySQL monitor Commands end with or g Your MySQL connection id is 1057 to server version 32354 Type help or h for help Type c to clear the buffer mysqlgt create database CONTACT Query OK 1 row affected (000 sec) mysqlgt show databases +----------+ | Database | +----------+ | CONTACT | | address | | hello | | mysql | | nuke | | test | +----------+ 6 rows in set (000 sec) mysqlgt exit

434 建立資料表

編寫 adresssql內容如下 -- Table structure for table address CREATE TABLE address ( id int(11) NOT NULL auto_increment name varchar(20) NOT NULL default tel varchar(15) NOT NULL default PRIMARY KEY (id) ) TYPE=MyISAM

48

-- Dumping data for table address INSERT INTO address VALUES (1林小明0800016888) INSERT INTO address VALUES (2黃大雄0800016888) INSERT INTO address VALUES (3劉小芬0800024365) 然後執行此 sql script mysql -u root -p1234 CONTACT lt addresssql 或是利 mysql command [rootossc bluepage] mysql -u root -p1234 Welcome to the MySQL monitor Commands end with or g Your MySQL connection id is 1090 to server version 32354 Type help or h for help Type c to clear the buffer mysqlgt use CONTACT Database changed Database changed mysqlgt CREATE TABLE address ( -gt id int(11) NOT NULL auto_increment -gt name varchar(20) NOT NULL default -gt tel varchar(15) NOT NULL default -gt PRIMARY KEY (id) -gt ) TYPE=MyISAM Query OK 0 rows affected (000 sec) mysqlgt INSERT INTO address VALUES (1林小明0800016888) Query OK 1 row affected (000 sec) mysqlgt INSERT INTO address VALUES (2黃大雄0800016888) Query OK 1 row affected (000 sec) mysqlgt INSERT INTO address VALUES (3劉小芬0800024365) Query OK 1 row affected (000 sec) mysqlgt exit Bye

49

第五章 實用範例

51 任務一Web Base客戶通訊錄

任職於開放科技公司的林小明前些日子在最符合成本效益的條件下快

速地完成公司網站的建置老闆因此對小明讚譽有加最近因為公司存放客戶資

料的 SQL Server主機屢遭病毒攻擊加上作業系統本身的問題當機次數頻繁

老闆希望能儘快把公司的客戶通訊錄程式移轉到較穩定的環境上因為此客戶通

訊錄程式最主要給內部人員使用所以介面美觀並不特別要求只求穩定且能快

速得到查詢結果老闆希望在短時間先看到程式的雛型並鍵入資料對其效率

及穩定性進行測試因為上次小明表現突出所以這次不可能的任務自然又落到

小明身上 小明想來想去既然要快速又穩定他而且又不希望所有人都得安裝 Client

程式於是小明決定)捨棄他的舊愛「Delphi+MS SQL」投向新歡「Apache + MySQL + PHP」利用此架構來設計一個簡單實用的Web Base客戶通訊錄程式

511 Web Base客戶通訊錄架構

此程式需要建立 CONTACT的資料庫並建立 adress Tables其結構如下表建立步驟請參考第三章 欄位名稱 資料型態 長度 說明 id INT (自動編號) 連絡人編號 name varchar文字 20 連絡人姓名 tel Varchar文字 15 連絡人電話 Web Base通訊錄共有下列幾個檔案功能如下表

檔案名稱 說明 Indexhtml Web Base通訊錄首頁 addphp 新增連絡人的 php程式 searchphp 尋找連絡人的 php程式 editphp 具有更新及刪除功能的 php程式

50

我們將這些檔案放至varwwwhtmlbluepage (預設無 bluepage目錄)

512 Web Base通訊錄測試

httpwwwopencombluepage 新增資料

圖 5-1 新增連絡人

圖 5-2 填入資料

51

圖 5-3 新增成功

搜尋及異動資料

圖 5-4 搜尋通訊錄

52

圖 5-5 編輯資料

圖 5-6 更新資料

513 程式內容及說明

lt-- 程式範例indexhtml--gt lthtmlgt ltheadgtlttitlegt通訊錄lttitlegtltheadgt ltbodygt ltcentergt

53

lth2gt通訊錄lth2gtlthrgt lta href=indexhtmlgt通訊錄ltagt | lta href=addphpgt新增連絡人ltagt | lta href=searchphpgt搜尋通訊錄ltagt ltcentergt ltbodygt lthtmlgt lt-- 程式範例addphp --gt lthtmlgt ltheadgtlttitlegt新增連絡人lttitlegtltheadgt ltbodygt ltcentergtlth2gt新增連絡人lth2gtltcentergtlthrgt lt 取得欄位資料 if (isset($_POST[Name]) ampamp isset($_POST[Tel]) ) $name = $_POST[Name] $tel = $_POST[Tel] 檢查是否有輸入欄位資料 if ($name = ampamp $tel = ) 建立 SQL字串 $sql = INSERT INTO address (name tel) values( $sql= $name $tel) 建立 MySQL 連結 $link = mysql_connect(localhostroot1234) 選擇資料庫 mysql_select_db(CONTACT) 執行 SQL指令 mysql_query($sql) mysql_close($link) echo ltfont color=redgt新增連絡人成功ltfontgtltbrgt gt ltform action=addphp method=postgt lttable border=0 width=300gt lttrgtlttdgt姓名 lttdgt

54

lttdgtltinput type=text name=Name size=20 maxlength=10gtlttdgtlttrgt lttrgtlttdgt電話 lttdgt lttdgtltinput type=text name=Tel size=20 maxlength=20gtlttdgtlttrgt lttrgtlttd colspan=2 align=centergt ltinput type=submit value=新增連絡人gtlttdgtlttrgt lttablegt ltformgt ltbrgtlta href=indexhtmlgt通訊錄ltagt | lta href=addphpgt新增連絡人ltagt | lta href=searchphpgt搜尋通訊錄ltagt ltbodygt lthtmlgt

lt-- 程式範例searchphp --gt lthtmlgt ltheadgtlttitlegt搜尋通訊錄lttitlegtltheadgt ltbodygt ltcentergtlth2gt搜尋通訊錄lth2gtlthrgt lt if (isset($_POST[Search])) 建立資料庫連結並選定資料庫 $link = mysql_connect(localhostroot1234) mysql_select_db(CONTACT) 建立基本的 SQL字串 $sql = SELECT FROM address 檢查是否輸入姓名 if (chop($_POST[Name]) = ) $name = name LIKE $_POST[Name] else $name = 檢查是否輸入電話號碼 if (chop($_POST[Tel]) = ) $tel = tel LIKE $_POST[Tel] else $tel =

55

if條件組合 SQL字串 if (chop($name) = ampamp chop($tel) = ) $sql= WHERE $name AND $tel elseif (chop($name) = ) 只有姓名 $sql = WHERE $name elseif (chop($tel) = ) 只有電話號碼 $sql = WHERE $tel $sql= ORDER BY name 最後加上排序 $result = mysql_query($sql) 取得欄位數 $total_fields = mysql_num_fields($result) echo lttable border=1gt echo lttrgtlttdgt編號lttdgtlttdgt姓名lttdgtlttdgt電話lttdgtlttd colspan=2gt功能選項lttdgtlttrgt 表格顯示查詢結果 while ($rows = mysql_fetch_array($result MYSQL_NUM)) echo lttrgt for ($i = 0 $i lt $total_fields $i++) echo lttdgt$rows[$i]lttdgt echo lttdgtlta href=editphpaction=editampid= echo $rows[0]gtltbgt編輯ltbgtlttdgt echo lttdgtlta href=editphpaction=delampid= echo $rows[0]gtltbgt刪除ltbgtlttdgt echo lttrgt echo lttablegtlthrgt mysql_free_result($result) mysql_close($link) gt ltcentergt ltform action=searchphp method=postgt lttable border=0 width=450gt lttrgtlttdgt搜尋姓名 lttdgt lttdgtltinput type=text name=Name size=10 maxlength=20gtlttdgtlttrgt lttrgtlttdgt搜尋電話 lttdgt lttdgtltinput type=text name=Tel

56

size=20 maxlength=20gtlttdgtlttrgt lttrgtlttd colspan=2 align=centergt ltinput type=submit name=Search value=搜尋gtlttdgtlttrgt lttablegt ltformgt ltbrgtlta href=indexhtmlgt通訊錄ltagt | lta href=addphpgt新增連絡人ltagt | lta href=searchphpgt搜尋通訊錄ltagt ltbodygt lthtmlgt

lt ob_start() gt lt-- 程式範例editphp --gt lthtmlgt ltheadgtlttitlegt編輯通訊錄lttitlegtltheadgt ltbodygt lt 取得 URL 參數 $id = $_GET[id] $action = $_GET[action] 建立資料庫連結 $link = mysql_connect(localhostroot1234) mysql_select_db(CONTACT) 選擇資料庫 執行的操作 switch ($action) case update 更新 取得欄位資料 $name = $_POST[Name] $tel = $_POST[Tel] $sql = UPDATE address SET name=$name tel=$tel WHERE id=$id mysql_query($sql) 執行 SQL指令 mysql_close($link) header(Location searchphp) 轉向到 serachphp break case del 刪除 $sql = DELETE FROM address WHERE id=$id

57

mysql_query($sql) 執行 SQL指令 mysql_close($link) header(Location searchphp) 轉向到 serachphp break case edit 編輯 $sql = SELECT FROM address WHERE id=$id $result = mysql_query($sql) 執行 SQL指令 $row = mysql_fetch_row($result) 取回記錄 $name = $row[1] 取得欄位 name $tel = $row[2] 取得欄位 tel mysql_close($link) 顯示編輯表單 gt ltcentergtlth2gt更新通訊錄lth2gtltcentergtlthrgt ltform action=editphpaction=updateampid=lt echo $id gt method=postgt lttable border=0 width=300gt lttrgtlttdgt姓名 lttdgt lttdgtltinput type=text name=Name size=20 maxlength=10 value=lt echo $name gtgtlttdgtlttrgt lttrgtlttdgt電話 lttdgt lttdgtltinput type=text name=Tel size=20 maxlength=20 value=lt echo $tel gtgtlttdgtlttrgt lttrgtlttd colspan=2 align=centergt ltinput type=submit value=更新連絡人gtlttdgtlttrgt lttablegt ltformgt ltbrgtlta href=indexhtmlgt通訊錄ltagt | lta href=addphpgt新增連絡人ltagt | lta href=searchphpgt搜尋通訊錄ltagt lt break gt ltbodygt lthtmlgt

58

52 任務二Web Base群組軟體 ( twig )

順利完成Web Base客戶通訊錄程式測試一段時間後「Apache + MySQL + PHP」架構的穩定與快速巳深得老闆與公司所有同事的認同隨著公司業績蒸

蒸日上人員組織編罝愈來愈龐大跨部門的會議愈來愈多業務員每日排滿拜

訪客戶的行程跟客戶的 Email的往來也愈來愈頻繁 愈來愈多部門的同事希望公司能建置一套群組軟體提供 web mail可讓業

務人員方便收發 mail還有連絡人議事日程待辦工作書簽等功能讓整個

公司運作及個人時間管理更有效率

老闆問小明對這些需求有什麼看法小明認為如果這些功能完全由程式部

門開發必定曠日費時而且耗費公司資源小明在網路尋找是否有提供這些功能

的Free Software皇天不負苦心人小明發現了TWIG (The Web Information Gateway) httptwigscrewdrivernet這個群組軟體它在 Web 上整合郵件新聞聯絡人議事日程工作序書簽等功能非常符合公司的需求 Step 1 下載 twig-277targz 下載網址 httptwigscrewdrivernetdownloadphp3

Step 2 解開 twig-277targz tar -xzvf twig-277targz

59

Step 3 執行安裝動作安裝到 varwwwhtmltwig 目錄 cd twig-277 twig-install varwwwhtmltwig

Step 4 建立 MySQL 資料庫(twig)及各資料表

cd setup mysql -u root -p1234 mysqlgt create database twig Query OK 1 row affected (001 sec) mysqlgt quit mysql -u root ndashp1234 twiglt twigtablemysql

Step 5 修改 configincphp3 參數設定 vi varwwwhtmltwigconfigconfigincphp3 $config[fromdomain] = opencom 網域 $config[language] = chinesebig5 中文訊息 $config[imap_port] = 143notls

60

Step 6 修改連結 MySQL 的帳號密碼 vi varwwwhtmltwigconfigdbconfigincphp3 $dbconfig[sqlusername] = root username $dbconfig[sqlpassword] = 1234 password

Step 7 其他設定檔

vi etchttpdconfhttpdconf 加入 AddType applicationx-httpd-php php3 在 DirectoryIndex最後加入 indexphp3 DirectoryIndex indexhtml indexhtmlvar indexphp3 在 AddDefaultCharset ISO-8859-1加上 AddDefaultCharset ISO-8859-1

vi etcphpini register_globals = On service httpd restart Step 8 sendmail 設定 vi etcmailsendmailcf在 264 行前面加上並重新啟動 sendmail「service snedmail restart」 262 SMTP daemon options 263 264 O DaemonPortOptions=Port=smtpAddr=127001 Name=MTA 265 266 SMTP client options 267 O ClientPortOptions=Family=inet Address=00

61

Step 9 檢查設定有無錯誤 http主機名稱twigtestphp3

62

Step 10 登入 twig ( http主機名稱twig)

63

第六章 維護及更新程序

61 日常維護

系統管理員最好定期以 root 身份登入看看信件在 RedHat Linux 中有一支 logwatch 程式會定時去分析 log file如果發現異常便會發信給 root除此之外筆者建議讀者平時就檢查 MySQL log file ( varlogmysqldlog)是否有異常情形

62 更新程序

讀者可至httprpmfindnet 尋找MySQL相關套件至於升級的相關步驟請參

考Linux OS SOP 第 54節

63 備份重要檔案

預設 MySQL 的 DB 檔案是存在 varlibmysql 內以 DB名稱為目錄目錄

內就是該 DB 的所有資料通常得定期備份還有 MySQL的設定檔 etcmycnf也別忘了一起備份

64 離線備份與還原

641 離線備份

預設 MySQL 的 DB 檔案是存在 varlibmysql 內以 DB 名稱為目錄目錄內

就是該 DB 的所有資料像 CRM 這個 DB就是存在 varlibmysqlCRM 內在備份前因為怕資料尚未完全寫入磁碟而且 MySQL 會 Lock 在使用的 DB 檔案所以應該是要先把 MySQL 先 Shutdown 一下整個備份的程序可以下像下面的指令去完成 cd varlibmysql

64

service mysqld stop tar cvfz CRM_db_20030905tgz CRM service mysqld start 對這樣就可以了 不過要注意的是怕 DB 內每個 Tables 間的資料有關關

聯性所以最好是把整個 DB 一次備起來單獨只備哪個 Tables 的檔案以後回存時怕會有資料關聯不一致的問題

642 離線還原

DB 發生錯誤而要回存時其實也不難先找出最近一次完整正常的備份先把現在錯誤的網頁或 DB 先更名或 tar 起來再把好的備份給解開回原來目錄位

置就行了需要注意的是 MySQL 服務最好也是要先停止回存完成後再啟動服務回存 DB 的整個程序可能像下面 cd varlibmysql service mysqldstop mv CRM CRM_OLD tar xvfz CRM_db_20030905tg service mysqld start

65 線上備份與還原

651 線上備份

使用像上面的檔案方式備份是個不錯的方法它最少可以保持該主機某個時間點的完整檔案備份但還是有一些問題需要考慮到有些主機就不只建立一個 DB 而已總不能為了備份某個 DB 而把整個 MySQL 服務停止備份檔案的方式回存在原主機上一定適用但假如 MySQL 版本升級或是在那天該網頁空間需遷機移機到別的主機時那就沒人敢保證備出來的資料檔可以用所以我們可以考慮另一種備份的方式是使用 MySQL 本身提供的功能 MySQL Data Dump指令是 mysqldump

65

使用 MySQL 的 Dump 功能可以把 DB 的結構資料或結構加資料 Dump 成文字檔 mysqldump 指令提供的彈性很大你可以選擇把整個 DB Dump 成一個檔或是每個 Table 為一個檔甚至是把結構檔和資料分開儲存都

可以 mysqladmin -uroot -p flush-logs mysqldump CRM -uroot -p --opt gt CRM_20030905sql (CRM 是 DB 名稱 opt 是一個使用完整 Dump 參數) 假如只是要單獨 Dump 某個 Table 時只要在上面的指令後轉出符號 gt 前加個 Table 名稱就可以如只要 phpbb2_users 這個 Table 的 Dump 時只要下 mysqldump CRM -uroot -p --opt CUSTOMER gt CRM_CUSTOMER_20030905sql

652 線上還原

若要回存整個資料庫只需將壓縮的備份檔還原成 Dump 的檔案再用下面的指令回存 mysql CRM -uroot -p lt CRM_20030905sql 這邊需注意的是若建立備份時是以--opt或--add-drop-table為參數時回存的 動作是先將舊的 Table 先刪除重建 Table 的結構後再把 Data 匯入所以回存後所有的資料會回到你當時備份那個時間點因此在回存資料時可以考慮把現有錯誤或不完整的 DB 先備份一份下來以備不時之需或是拿來比對錯誤的地

方在那裡當然你也可以把資料回存到另一個測試用的 DB 內只要把上面指令

的 DB 名稱改成你的測試用 DB 名稱即可 使用這種回存方式 MySQL 服務不需停止也不會動到其他正在使用的 DB 在一些提供 MySQL 服務的虛擬主機可用這種方式作你自己的 DB 備份及回存

66

另外假如你是系統重建或是移機時切需在新的 MySQL 內新建一個空白 DB 後才行作回存的工作你可以用下面的指令建立 mysql -uroot -p -e CREATE DATABASE CRM (上面的 CRM是你要新建的 DB 名稱) 另一種作法先用 mysql 指令進入 mysql client console 然後再用 CREATE DATABASE CRM 這樣就行了記得尾端要加個 符號該行指令才會執行

67

第七章 問題與解答

Q1RedHat 90預附的 MySQL到底有無支援 Transcation機制 Ans MySQL自 32334a之後的 MySQL-Max版本加入 InnoDB的資料庫類型透過

InnoDBMySQL同樣可以進行 COMMIT與 ROLLRACK的動作RedHat 90預附的 MySQL為 32354a-11巳支援 InnoDB的資料庫類型不過必須做以

下設定 1cp usrsharedocmysql-server-32354amy-mediumcnf to etcmycnf 2 vi etcmycnf 將以下設定前的拿掉 innodb_data_home_dir = varlibmysql innodb_data_file_path = ibdata110Mautoextend innodb_log_group_home_dir = varlibmysql innodb_log_arch_dir = varlibmysql 3service mysqld restart 如此一來各位在建立Table時便可指定Table Type為 innodb ( ex create table with type=innodb ) Q2如何解決 php+mysql 許功蓋等字變亂的問題 Ans 方法一 【確定 MySQL 預設的字元集】 1 打開 WinMySQLadmin 管理畫面(在視窗右下角狀態列紅綠燈圖示中按滑鼠

右鍵點選 Show me 選項) 2 點選管理畫面中 [Variables] 標籤選項其中 character_set變數就是您預設

字元集的變數其預設是 latin1 字元集(我們要將他改回 big5)而 chatacters_set 變數則是 MySQL 可以支援哪些字元集 【修改預設字元集變數 character_set 】 1 請點選管理畫面中 [myini Setup] 標籤選項設定 myini 2 按一下 [Pick-up and Edit myini values] 按鈕以便編輯目前的 myini 設定 3 在 [mysqld] 設定區塊底下新增一行 default-character-set = big5 變數設

68

定 4 新增一個 [client] 設定區塊並加入第三步驟的變數設定(游標往下移到空白處新增兩行 [client] 和 default-character-set=big5) 5 按一下畫面左下方 [Save Modification] 按鈕儲存設定 6 重新啟動 MySQL 或 Windows 方法二 Server端注意事項 phpini 中有關的設定為(預設值) Magic quotes for incoming GETPOSTCookie data magic_quotes_gpc = On Use Sybase-style magic quotes (escape with instead of ) magic_quotes_sybase = Off Client端注意事項 1中文資料送進 mysql 前請用 addslashes($str) 處理 2處理後送進 mysql 時請用 括起來並在參數後留一個空白如 $sql = UPDATE ezf_table set tablename=$tname tableend=$endtime table inguser=$tguser tableingid=$tguserid tableallnumber=$tnumber tableloca l=$tablelocal tableanyone=$tableopen tabletext=$ttext WHERE tableid=$t ableid tablename=$tname c 取出時請用 stripslashes($str) Q3MySQL root 密碼忘了該怎麼辦 Ans 1先停掉 mysql etcrcdinitdmysql stop 2以--skip-grant-table 的參數啟動 mysql safe_mysql --skip-grant-tableamp 3 更改 root 密碼 mysql mysql mysqlgt UPDATE user SET password=password(newpassword)

69

WHERE user=root mysqlgt FLUSH PRIVILEGES mysqlgt exit 4停掉 mysql再重跑 mysqladmin -uroot -p shutdown Enter password 輸入新設定的密碼 etcrcdinitdmysql start

Q4NULL值問題

Ans

NULL值的概念是造成 SQL的新手的混淆的普遍原因他們經常認為 NULL是和一個空字符串的一樣的東西不是這樣的例如下列語句是完全不同的

mysqlgt INSERT INTO my_table (phone) VALUES (NULL)

mysqlgt INSERT INTO my_table (phone) VALUES ()

兩個語句把值插入到 phone 列但是第一個插入一個 NULL值而第二個插入一個空字符串第一個的含義可以認為是ldquo電話號碼不知道而第二個則可意味

著ldquo她沒有電話

在 SQL中NULL值在于任何其他值甚至 NULL值比較時總是假的(FALSE)包含 NULL的一個表達式總是產生一個 NULL值除非在包含在表達式中的運算符和函數的文檔中指出在下列例子所有的列返回 NULL

mysqlgt SELECT NULL1+NULLCONCAT(InvisibleNULL)

如果你想要尋找值是 NULL的列你不能使用=NULL測試下列語句不返回任

何行因為對任何表達式expr = NULL是假的

mysqlgt SELECT FROM my_table WHERE phone = NULL

要想尋找 NULL值你必須使用 IS NULL測試下例顯示如何找出 NULL電話號碼和空的電話號碼

70

mysqlgt SELECT FROM my_table WHERE phone IS NULL mysqlgt SELECT FROM my_table WHERE phone =

在 MySQL中就像很多其他的 SQL服務器一樣你不能索引可以有 NULL值的列你必須聲明這樣的列為 NOT NULL而且你不能插入 NULL到索引的

列中

當用 LOAD DATA INFILE 讀取數據時空列用更新如果你想要在一個列中有

NULL值你應該在文本文件中使用N字面上的詞NULL也可以在某些情形下使用

當使用 ORDER BY時首先呈現 NULL值如果你用 DESC以降序排序NULL值最後顯示當使用 GROUP BY時所有的 NULL值被認為是相等的

為了有助于NULL的處理你能使用 IS NULL和 IS NOT NULL運算符和 IFNULL()函數

對某些列類型NULL值被特殊地處理如果你將 NULL插入表的第一個TIMESTAMP 列則插入當前的日期和時間如果你將 NULL插入一個AUTO_INCREMENT 列則插入順序中的下一個數字

Q5如何將圖片存放於 MySQL中

Ans

Step 1建立資料庫 test

Step 2 建立表格 binary_data

CREATE TABLE binary_data (

id INT(4) NOT NULL AUTO_INCREMENT PRIMARY KEY

description CHAR(50)

bin_data LONGBLOB

filename CHAR(50)

filesize CHAR(50)

filetype CHAR(50)

71

)

Step 3 利用 storephp 寫入圖片

storephp 程式碼

ltHTMLgt ltHEADgtltTITLEgtStore binary data into SQL DatabaseltTITLEgtltHEADgt ltBODYgt lt code that will be executed if the form has been submitted

if ($submit) mysql_connect(localhostrootYOUR_PASSWORD) mysql_select_db(test) $data=Base64_Encode(fread(fopen($form_data r) filesize($form_data))) $result=MYSQL_QUERY(INSERT INTO binary_data (descriptionbin_datafilenamefilesizefiletype) VALUES ($form_description$data$form_data_name$form_data_size$form_data_type)) $id= mysql_insert_id() print ltpgtThis file has the following Database ID ltbgt$idltbgt MYSQL_CLOSE() else else show the form to submit new data

gt

ltform method=post action=ltphp echo $PHP_SELF gt enctype=multipartform-datagt File Descriptionltbrgt ltinput type=text name=form_description size=40gt ltINPUT TYPE=hidden name=MAX_FILE_SIZE value=4000000gt ltbrgtFile to uploadstore in databaseltbrgt ltinput type=file name=form_data size=40gt ltpgtltinput type=submit name=submit value=submitgt ltformgt lt

72

gt ltBODYgt ltHTMLgt

Step 3 利用 storephp 取出圖片

getdataphp 程式碼

lt Syntax getdataphp3id=ltidgt if($id) you may have to modify login information for your database server MYSQL_CONNECT(localhostrootYOUR_PASSWORD) mysql_select_db(test) $query = select bin_datafiletype from binary_data where id=$id $result = MYSQL_QUERY($query) $data = Base64_Decode(MYSQL_RESULT($result0bin_data)) $type = MYSQL_RESULT($result0filetype) Header( Content-type $type) echo $data gt

Q6MySQL裝好之後啟動時或是執行 mysqladmin會出現如下訊息 Cant connect to local MYSQL Server through Socket varlibmysqlmysqlsock或是

Cant connect to local MYSQL Server through Socket tmpmysqldsock

Ans 可能有下列幾個原因

1這個 mysqldsock 不見了被某人刪除了或是被一些系統自動執行程式給刪

了例如有些 cron任務便會設定定期刪除 tmp 裡的東西所以呢您只能修改

cron 裡的設定讓它不要清除 mysqldsock 2在啟動時也可以改變 mysqldsock的位置您在啟動 MySQL的時候可以加入此參數usrlocalmysqlbinsafe_mysqld --user=mysql --socket=其他路

徑socket amp 同時得去設定環境變數 MYSQL_UNIX_PORT的值以指定新的

73

路徑 3若是您沒改 MYSQL_UNIX_PORT的值那麼您可以在執行指令的時候才打

例如mysqladmin --socket=其他路徑socket version Q7How to get the last insert id Ans CREATE TABLE product ( id INT(4) NOT NULL AUTO_INCREMENT PRIMARY KEY description VARCHAR(50) ) 1利用 SQL的話 mysqlgt insert into product(description) values(123) Query OK 1 row affected (000 sec) mysqlgt select last_insert_id() +------------------+ | last_insert_id() | +------------------+ +------------------+ 1 row in set (000 sec) ======================================== 2如果是 PHP的話 你可以用mysql_insert_id()取得該 id PHP example $result=MYSQL_QUERY(INSERT INTO product (description) VALUES ($description)) $id= mysql_insert_id() print This file has the following Database ID $id Q8如何將文字檔匯入資料庫 Ans $addr=homehttpdhtmlphpschool001txt $sql_select = load data infile $addr into table test fields terminated by t 解說 $sql_select = load data infile 文字檔名 into table 表格名 fields terminated by

74

t

(欄位分隔以 TAB鍵) 該文字檔須與資料表欄位格式相符 例如欄位有三個 則文字檔為每行一筆資料如下 欄 1資料ltTABgt欄 2資料ltTABgt欄 3資料 欄 1資料ltTABgt欄 2資料ltTABgt欄 3資料 欄 1資料ltTABgt欄 2資料ltTABgt欄 3資料 欄 1資料ltTABgtltTABgt欄 3資料

Q9如何撰寫 MySQL C API Ans Step 1利用文字編輯器撰寫以下程式碼 mysqlcc

include ltstdiohgt

include ltmysqlmysqlhgt

int main (int argc char argv[])

MYSQL mysql

MYSQL_RES res

MYSQL_ROW row

if (argc = 2)

fputs (Usage myc ltdatabasegt stderr)

return 1

if ((mysql_connect(ampmysqllocalhostrootYour_Password)))

fputs (Error connecting stderr)

abort()

75

if (mysql_select_db(ampmysqlargv[1]))

fputs (Error selecting database stderr)

abort()

if (mysql_query(ampmysqlSELECT FROM test_table))

fputs (Error processing query stderr)

abort()

if ((res = mysql_store_result(ampmysql)))

fputs (Error storing results stderr)

abort()

while((row = mysql_fetch_row(res)))

uint i = 0

for (i=0 i lt mysql_num_fields(res) i++)

printf(s row[i])

printf(n)

return 0

Step 2 Compile

gcc -Iusrlocalmysqlinclude -Lusrlocalmysqllibmysql mysqlcc ndashlm -lmysqlclient

(其中 include path與 library path取決於你的 MySQL安裝路徑)

76

如果執行時發生如下 error Run problemerror in loading shared libraries libmysqlclientsoX 將你的 MySQL library path(for exampleusrlocalmysqllibmysql) 加入etcldsoconf and run sbinldconfig -v Q9ASP + MySQL 範例程式 Ans Dim myconn As New ADODBConnection Dim myrs As New Recordset Dim mySQL As String Dim myrows As Long myconnOpen DSN=MyODBCsample mySQL = SELECT from user myrsSource = mySQL Set myrsActiveConnection = myconn myrsCursorLocation = adUseClient myrsOpen myrows = myrsRecordCount myrsClose myconnClose 可參考 httpwwwdwamnetmysqlasp_myodbcasp 有詳細的資料 Q10如何將 MySQL中的資料庫匯出成txt檔 Ans select from TableName into outfile textxls all result fields will seperate by tab

77

第八章 參考資料

英文部份 網址 1 httpwwwmysqlcom MySQL 網站有第一手有關 MySQL的資料 2 httpwwwmysqlcomdocenReplicationhtml 有關 MySQL Replication 的文件 3 httpwwwgeocitiescomsqlhomefaqstore_blobhtml 如何在 MySQL 存放 BLOB的資料 4httpwwwsapdborg 有關 SAP跟 MySQL相關合作的網站 書藉 1 Cooking with MySQL

Paul DuBois has selected sample recipes from the hundreds youll find in his book MySQL

Cookbook In this third and final series of excerpts showcasing these recipes learn how to

compute team standings how to calculate the differences between successive Dec 26

2002 2 Tips for Building Web Database Applications with PHP and MySQL by Hugh E Williams co-author of Web Database Applications with PHP amp MySQL 04042002

3 Managing and Using MySQL 2nd Edition By Tim King George Reese Randy Jay Yarger

4 MySQL Cookbook By Paul DuBoisPublisher OReillyPub Date October 2002

中文部份

78

1 httplinuxtncedutwtechdocmysqlmysql_docmanual_tochtml MySQL 中文手冊 2 httpchenshloxaedutwphpZ_1php PHP+MySQ程式研習設計網站 3 httplinuxtncedutwtechdocbanicdownhtml PHP 4 手冊 4 httpwwwtncedutwadmin_zonephp台南縣教育網網路中心有很多 Linux相關文件 5 httpdobtncedutw網站建置百寶箱有很多 PHP MySQL 相關範例程式 5 httpwwwdbworldcomtw資料庫專家電子雜誌介紹資料庫的重要觀念及名詞

79

附錄一 SQL Command 介紹

SQL (讀音ess-que-el) 是一種結構查詢語法SQL 使用於資料庫交流

傳遞相容於 ANSI (American National Standards Institute) 是一套標準的關聯

式資料庫語言 SQL 語言是執行更新或從資料系統獲取資料一般常見的關聯

資料庫系統都有提供 SQL 如 Oracle Sybase Microsoft SQL Server Access Ingres 等雖然大部份的資料庫都有提供 SQL 但也多提供了自已獨特的語

法造成了不相容的情形但標準基本的語法是相通的如Select Insert Update Delete Create and Drop 每一個系統都有支援

Table相關 Command

Create Table

關聯式資料庫包含有很多元件稱為資料表(tables) 把資料或訊息放在資

料表中 資料表是以不同的名稱做分別資料表由欄列所構成的二維陣列

欄包含欄位名資料型態 及其他可判斷的資訊列是由全部欄位構成一筆一

筆的紀錄 create table 語法用在建立一個新的資料表語法格式如下

create table tablename (column1 data type column2 data type column3 data type)

Format of create table if you were to use optional constraints

create table tablename (column1 data type [constraint] column2 data type [constraint] column3 data type [constraint]) [ ] = optional

Note You may have as many columns as youd like and the constraints are optional

80

Example

create table employee (first varchar(15) last varchar(20) age number(3) address varchar(30) city varchar(20) state varchar(20))

注意建立資料表格式要以括號把前後框住而最後以(分號)做結尾

欄位名不要超過 30個字元長而且不要使用 sql 的關鍵字(如 where select等)而在後面接是型態的宣告(如字串數字日期格式等)

資料型態是來描述欄位的方式如一個欄位Last_Name 是一個姓氏可以使用varchar (可變動長度字串) 資料型態

以下是幾個常見的資料庫型態 char(size) 固定長度字串最長為 255 位元 varchar(size) 變動長度字串最大字元數以 size 來指定 number(size) 數值格式可以是整數也可以是小數最大數字以 size 位數判

斷未指定小數位數由系統內定 date 日期格式 number(sized) 數值格式最大數字以 size 位數判斷d 為小數位數整數位

數為 size-d 位

有何限制當資料表被建立通常有一或數個欄位是要使用來做關聯的功

能 例如unique 限制(唯一值)兩筆記錄不可以相同的值 not null (非空值)該欄位一定要輸入資料不可是空的primary key (主鍵)是每一筆記錄識別的主要方式

Drop a table drop table 刪除資料表(其中的資料也會一併刪除)

drop table tablename

Example

81

drop table 和刪除全部資料是不同的刪除全部資料欄位名稱資訊等還會

存在但刪除資料表會把這一些也一併移除掉

如何查詢資料

Select 基本用法

select 語法是關連式資料庫最常用的部份可以取得你想要的資料這是一個

簡單的範例 select column1[column2etc] from tablename [where condition] [] = optional 在 select 之後所列欄位名則是要顯示的資料部份你可以一一列出各欄位

名或是以 (星號)來代表選擇全部的欄位 from 之後放資料表名稱 where 子句 (選項) 指定要過濾的條件符合者才會顯現 where 可使用的條件運算元 = 等於 gt 大於 lt 小於 gt= 大或等於 lt= 小或等於 ltgt 大相等 LIKE 相似 For example select first last city

82

from empinfo where first LIKE Er 以Er 為開頭的字串就符合要以單引號框住 Or you can specify select first last from empinfo where last LIKE s 最後一字為 S 就符合 select from empinfo where first = Eric 則表示 first name 一定要是 Eric 才可以 範例資料表empinfo 統計函數

MIN 傳回指定欄位最小值

MAX 傳回指定欄位最大值

SUM 傳回指定欄位總和

AVG 傳回指定欄位平均值

COUNT 傳回指定欄位的筆數

COUNT() 傳回資料庫中的總筆數

統計函數使用於資料表中的數值欄位配合 SELECT 語法使用 只用於總結特定單一欄位可以配合 GROUP BY 做篩選但也可以不使用 GROUP BY 語句For example

SELECT AVG(salary) FROM employee

83

傳回全部 salary 平均值

Another example

SELECT AVG(salary) FROM employee WHERE title = Programmer

傳回 salary 平均值條件為 employees 資料表中當 title 等於 Programmer

Example

SELECT Count() FROM employees

傳回 employees 資料表中紀錄總筆數

GROUP BY 語法 SELECT column1 SUM(column2) FROM list-of-tables GROUP BY column-list The GROUP BY 語句可以先以所列的欄位為條件分組排序在一起(可以多欄

位) example 要列出每一個 dept 中最高 salary 值 SELECT max(salary) dept FROM employee GROUP BY dept HAVING 語法

SELECT column1 SUM(column2) FROM list-of-tables GROUP BY column-list HAVING condition

HAVING 子句是 GROUP BY 的一部份用來過濾在 GROUP BY 所選出的資料功能如同 select 命令中 where 條件式一樣只是 HAVING 必需配合 GROUP BY 使用

我們以例子來說明我們要取得每一公司名及每一公司的薪水平均值輸入如下

84

SELECT dept avg(salary) FROM employee GROUP BY dept

但如果我們只列出薪資平均值超過 20000元的公司資料

SELECT dept avg(salary) FROM employee GROUP BY dept HAVING avg(salary) gt 20000

ORDER BY子句語法

SELECT column1 SUM(column2) FROM list-of-tables ORDER BY column-list [ASC | DESC]

[ ] =選項

ORDER BY是一個選項子句當你以排序方式來顯示資料(正向由小到大反向由大到小)以指定的欄位資料做排序

ASC = 正向- 預設值 DESC = 反向排序

For example

SELECT employee_id dept name age salary FROM employee_info WHERE dept = Sales ORDER BY salary

以上列出公司代號公司名銷售員人名年紀及薪資而條件是公司名為 Sales 顯示順序以薪資多少排序(由小到大為預設值)

如果要以多個欄位做排序要以逗號做分隔如下

SELECT employee_id dept name age salary FROM employee_info WHERE dept = Sales ORDER BY salary age DESC

85

結合條件及布林運算 SELECT column1 SUM(column2) FROM list-of-tables WHERE condition1 AND condition2 AND運算可以結兩個或以上的條件放在 WHERE子句中 兩者都要為真才

會顯示該筆記錄 OR 運算可以結兩個或以上敘述放在 WHERE子句中只要其中一個為直就

會顯示該筆記錄 For example SELECT employeeid firstname lastname title salary FROM employee_info WHERE salary gt= 5000000 AND title = Programmer 必需要薪資大於等於 50000而且職稱為 Programmer同時符合才會顯示該筆資料 以下以括號括住雖然不是必需的但如此比較容易讀 SELECT employeeid firstname lastname title salary FROM employee_info WHERE (salary gt= 5000000) AND (title = Programmer) 另外範例 SELECT firstname lastname title salary FROM employee_info WHERE (title = Sales) OR (title = Programmer) 條件為只要是 Sales 或 Programmer 職稱的就會被列出 IN and BETWEEN 子句

SELECT column1 SUM(column2) FROM list-of-tables WHERE column3 IN (list-of-values) SELECT column1 SUM(column2) FROM list-of-tables WHERE column3 BETWEEN value1 AND value2 IN 子句使用在列舉項目的使用上也就是分別測試是否符合所列的值 For example

86

SELECT employeeid lastname salary FROM employee_info WHERE lastname IN (Hernandez Jones Roberts Ruiz) 條件為姓氏(astname)要符合 Hernandez Jones Roberts or Ruiz 其中一個才會被傳回 IN運算元也可以使用 OR 的語法來取代如下結果相同 SELECT employeeid lastname salary FROM employee_info WHERE lastname = Hernandez OR lastname = Jones OR lastname = Roberts OR lastname = Ruiz 但使用 IN 句子比較短也比較易懂 你也可以使用 NOT IN 來去掉不要的記錄 BETWEEN 運算元使用在判斷是否存在兩個數值之間 For example SELECT employeeid age lastname salary FROM employee_info WHERE age BETWEEN 30 AND 40 傳回年紀 30歲到 40歲之間的資料(含 30及 40歲者) 相同的也可以使用以下語法來達到相同的結果 SELECT employeeid age lastname salary FROM employee_info WHERE age gt= 30 AND age lt= 40 你也可使用 NOT BETWEEN 來濾掉中間值的資料 數學運算 標準 ANSI SQL-92 提供以下運算

87

+ 加

- 減

餘數

餘數為除法後剩整數這不在標準的 ANSI SQL 中但大部份的資料庫都會支

援這運算元以下列出有用的函數雖不在 ANSI SQL-92 提供但一般資料庫

也會支援他們

ABS(x) 傳回 x 絕對值

SIGN(x) returns the sign of input x as -1 0 or 1 (negative zero or positive respectively)

MOD(xy) 餘數 - returns the integer remainder of x divided by y (同 xy)

FLOOR(x) 傳回小或等於 x 的最大整數值

CEILING(x) or CEIL(x)

傳回大或等於 x 的最小整數值

POWER(xy) x的 y 次方

ROUND(x) 把 x 四捨五入為整數

ROUND(xd) 四捨五入取到小數 d 位

SQRT(x) x 開平方

For example SELECT round(salary) firstname FROM employee_info 傳回薪資取到整數位

如何新增資料

insert 加入一筆新紀錄到資料表中 insert into tablename (first_columnlast_column) values (first_valuelast_value) [] = optional Example insert into employee

88

(first last age address city state) values (Luke Duke 45 2130 Boars Nest Hazard Co Georgia) Note 字串要以單引號住如string 數字框住也無妨 insert into 後面接資料表名稱再接以括號括住的欄位名在 values 後括號分別對映各欄位的值 以上的例子新增了一筆名(first) 為 Luke而住所(state) 為 Georgia 的資料

如何刪除資料

delete 可以刪除單筆或多筆紀錄 delete from tablename where columnname OPERATOR value [and|or column OPERATOR value] [ ] = optional Examples delete from employee Note 如果你沒有指定 where 子句那麼全部的紀錄都會被刪除 delete from employee where lastname = May delete from employee where firstname = Mike or firstname = Eric delete from 接著資料表名 再接著是條件式判斷沒有條件式則全部紀錄會

被刪除

如何更新資料

update 用來更新你所指定的記錄要和 WHERE 配合小心使用 語法 update tablename set columnname = newvalue[nextcolumn = newvalue2] where columnname OPERATOR value [and|or column OPERATOR value] [] = optional Examples

89

update phone_book set area_code = 623 where prefix = 979 update phone_book set last_name = Smith prefix=555 suffix=9292 where last_name = Jones update employee set age = age+1 where first_name=Mary and last_name=Williams

90

附錄二Replication

測試環境

RedHat 90 + MySQL 32358 MySQL資料庫路徑 varlibmysql MySQL設定檔 etcmycnf Master IP 1921680100 Slave IP 1921680200 請至下列網址下載最新MySQL 32358套件並利用rpm ndashUvh 更新 httpupdatesredhatcom9enosi386

圖 最新 MySQL 套件

測試架構圖

91

1921680100

1921680200Master Server

erveSlave S r

圖 測試架構圖

測試步驟

Master server 部份 Step1 確認 MasterSlave機器上所裝的 MySQL版本能進行

replication( 32329 or higher ) Step2 在 Master MySQL上開放一個帳號給 Slave mysql ndashu root ndashp mysqlgtGRANT FILE ON TO repl1921680200 IDENTIFIED BY lsquoabc123rsquo mysqlgtq 上面是 Master開放一個帳號 repl密碼 abc123給 IP1921680200有檔案處理

的權限 Step3 shutdown MySQL on the Master mysqladmin ndashu root ndashp shutdown Step4 備份 Master所有資料庫 tar ndashcvf tmpmysql-snapshottar varlibmysql 注意tar的時候MySQL是要在 stop情況下 在mysql (wwwmysqlcom) 網站的FAQ有不用shutdown的方法

92

Step5 在 master機器上修改etcmycnf 在[mysqld]區段內加入參數 log-bin server-id=這邊設定 server-id=1 sql-bin-update-same binlog-do-db=CRM只針對 CRM資料庫做紀錄 Step6 Restart MySQL on the master service mysqld start 此時因為有加入 log-bin 參數因此開始有 index產生了在varlibmysql目錄下

有index檔案紀錄資料庫的異動 log Slave server 部份 Step1 在 slave設定etcmycnf 在[mysqld]區段加入 master-host= master-user= master-password= master-port= server-id= 這邊設定 master-host=1921680100 master-user=repl master-password=abc123 master-port=3306 server-id=2 master-connect-retry=60預設重試間隔 60秒 replicate-do-db=CRM告訴 slave只做 CRM資料庫的更新 log-slave-updates Step2 將 master上的 mysql-snapshottar copy到 slave上 用 ftp傳到 slave的tmp Step3 解壓縮 Master資料庫至 Slave Server上 cd varlib tar xvf tmpmysql-snapshottar chown ndashR mysqlmysql mysql

93

chmod ndashR 770 mysql (視情況) Step4 Restart MySQL on the slave server 這時在varlibmysql目錄會出現 masterinfo此檔案紀錄了 Master MySQL server的資訊

狀況測試

One-way replication

1921680100

1921680200Master Server

erveSlave S r

圖 One-way replication架構圖 Step1 Master跟 Slave網路及服務都正常情況下由 Master端異動資料後 到 Slave端瀏覽資料檢視是否有進行 replication Step2 模擬 Slave Server 當機 可用在於 slave真的當機或是 Slave 不一定需要一直跟 master connect將Slave MySQL server shutdown由 Master端異動資料到 slave端瀏覽此時Slave應該沒有被 replication 更新然後再將 Slave端 MySQL server start起來

預設 60秒後 Slave會嘗試跟 Master要求進行 replication再去 Slave端檢視是否有更新資料

94

Step3 模擬 Master當機因為是設定 One-way replication一旦 Master Server Slave端沒有 Master的 source可以 download Two-way replication 基於 Master當機狀況於是發展雙向 Replication即 1921680100 ( Host A ) 1921680200 ( Host B )都分別擔任 MasterSlave身分

1921680100

1921680200er

Server B MasterSlave Server

Server A MasterSlave Serv

圖 Two-way replication架構圖 以下是針對兩台 MySQL伺服器進行雙向 Replication Step1觀念同單向 replication只是改成 Master也有 Slave身分 Slave也有Master的身分先分別在 Server AServer B 都去 grant一個進行 replication的身分 [A]mysqlgtGRANT FILE ON TO repl1921680200 IDENTIFIED BY lsquoabc123rsquo [B]mysqlgt GRANT FILE ON TO repl1921680100 IDENTIFIED BY lsquoabc123rsquo Step2做完單向 replication後stop Server Aserver B MySQL service此時 AB資料是一樣的

95

修改etcmycnf設定 範例 Server A [mysqld] datadir=varlibmysql socket=varlibmysqlmysqlsock server-id=1 log-bin sql-bin-update-same binlog-do-db=CRM master-host=1921680200 master-user=repl master-password=abc123 log-slave-updates master-connect-retry=60 replicate-do-db=CRM Server B [mysqld] datadir=varlibmysql socket=varlibmysqlmysqlsock server-id=2 log-bin sql-bin-update-same binlog-do-db=CRM master-host=1921680100 master-user=repl master-password=abc123 log-slave-updates master-connect-retry=60 replicate-do-db=CRM 分別 start Server AServer B MySQL後此時雙方都是 MasterSlave身分一旦哪一方資料異動就會通知對方來 replication-若 replication失效則必須將Server AServer B的masterinfo及index00x 都砍掉然後分別 restart MySQL server進行測試檢視成果 實務上通常如果需要做Two-way replication通常會搭配Virtual Server使用

96

在前端架設一台Virtual Server不過此部份不在此份SOP討論範圍內有興趣

的讀者可參考 httpwwwlinuxvirtualserverorg 網站

1921680100 1921680200

Host A MasterSlave Server

Host B MasterSlave Server

Virtual Host

圖 Virtual Server + Two-way replication 架構圖

97

圖 High Availability Linux Virtual Server架構圖

98

  • COSA-SOP-03-006
  • 第一章 簡介
    • 11適用對象 (Audience)
    • 12 MySQL本身
    • 13 MySQL 40版跟50版重大的改進功能
    • 14 各家資料庫軟體比較
      • 第二章 前置需求
      • 第三章 安裝
        • 31 MySQL安裝
        • 32 phpMyAdmin安裝
        • 33 升級及注意事項
          • 第四章 MySQL管理
            • 41 Webmin 管理介面
            • 42 phpMyAdmin 的操作介面
            • 43管理指令介紹
              • 431 利用mysqladmin設定root的密碼
                  • 第五章 實用範例
                    • 51 任務一Web Base客戶通訊錄
                    • 52 任務二Web Base群組軟體 ( twig )
                      • 第六章 維護及更新程序
                        • 61 日常維護
                        • 62 更新程序
                        • 63 備份重要檔案
                        • 64 離線備份與還原
                        • 65 線上備份與還原
                          • 第七章 問題與解答
                          • 第八章 參考資料
                          • 附錄一 SQL Command 介紹
                          • 附錄二Replication
Page 13: DataBase Server Standard Operation Procedureebooks.lib.ntu.edu.tw/1_file/oss/63/93doc4-5.pdf · 業務的公司帶來了不少壓力,譬如微軟,甲骨文 ... 外的錢用在第三方的資料庫產品上,譬如就可以不用再購買甲骨文公司

圖 3-2

Step 3檢查是否安裝成功 待安裝後您可以用利用「rpm -qa | grpe ^mysql」檢查是否安裝成功

圖 3-3

啟動 MySQL ( Command Mode )馬上啟動 MySQL的指令為「service mysqld start」如果您希望一開機就自動啟動 MySQL請執行「chkconfig mysqld on」

13

圖 3-4

啟動 MySQL ( WebMin 介面 ) 我們也可以利用WebMin 來啟動 MySQL步驟如下 Step 1登入Webmin

圖 3-5 登入WebMin

Step 2 選擇伺服器

14

圖 3-6 伺服器畫面

Step 2 選擇 MySQL資料庫伺服器

圖 3-7 伺服器畫面

15

Step 3 啟動 MySQL資料庫伺服器

圖 3-8 啟動 MySQL

更改資料庫管理者密碼

成功啟動 MySQL後因為資料庫管理者預設沒有密碼建議使用前更改系

統管理者密碼請輸入下列指令

mysqladmin ndashu root ndashh cosaexamplecom password lsquo1234rsquo -u 表示使用者帳號root 為 MySQL預設的管理帳號

-h 表示 MySQL主機的主機名稱也可使用 IP Address password 表示使用者的密碼因為字串請使用單引號將密碼括起來

圖 3-9 修改 MySQL 的密碼

16

32 phpMyAdmin安裝

本書除了會介紹利用當今 Linux上最紅的整合管理工具Webmin 來管理

MySQL外還會為各位介紹專門管理 MySQL的工具 phpMyAdmin phpMyAdmin是免費的 PHP原始程式碼的Web網站可用來管理整個

MySQL伺服器這是一套Web介面的 MySQL管理程式支援中文的使用者介

面 phpMyAdmin只需透過瀏覽器就可管理 MySQL伺服器換句話說不論

MySQL是安裝在 Linux或是Windows 作業系統都可以使用相同步驟在

MySQL上建立資料庫(Database)資料表(Table)和編輯紀錄(Record) Step 1 下載phpMyAdmin ( httpwwwphpmyadminnet )選擇最櫎新穩定的版

本 253

圖 3-10 httpwwwphpmyadminnet

17

圖 3-11 下載 phpMyAdmin-253-phptarbz2

Step 2 將 phpMyAdmin-253-phptarbz2收至 tmp 並執行下列指令將其解壓

縮至varwww tar jxvf phpMyAdmin-253-phptarbz ndashC varwwwhtml

圖 3-12 解壓縮安裝 phpMyadmin-253

Step 3 為了操作方便起見建立 Soft link ln ndashs phpMyAdmin-253 phpMyAdmin

圖 3-13 修改 phpMyadmin 設定檔 configincphp

18

Step 4 修改 phpMyadmin 設定檔 configincphp gedit varwwwhtmlphpMyAdminconfigincphp

圖 3-14 configincphp設定檔

Step 5 設定顯示行號以方便修改 configincphp 設定檔

19

圖 3-15 顯示行號

Step 6 修改下列設定 第 39 行 設定 phpMyAdmin的 URL 第 69 行 MySQL Server 的 ip 第 80 行 利用何帳號存取 MySQL 第 81 行 如果 root有設定 password此處即填入 root的 password

30 In most cases you can leave this variable empty as the correct value

31 will be detected automatically However we recommend that you do

32 test to see that the auto-detection code works in your system A good

33 test is to browse a table then edit a row and save it There will be

34 an error message if phpMyAdmin cannot auto-detect the correct value

35

36 If the auto-detection code does work properly you can set to TRUE the

37 $cfg[PmaAbsoluteUri_DisableWarning] variable below

38

39 $cfg[PmaAbsoluteUri] = httpossccosaorgtwphpMyAdmin

hellip

20

hellip

69 $cfg[Servers][$i][host] = localhost MySQL hostname or IP address hellip 80 $cfg[Servers][$i][user] = root MySQL user

81 $cfg[Servers][$i][password] = 1234 MySQL password (only needed

圖 3-16 修改 configincphp

21

圖 3-17 修改 configincphp

圖 3-18 修改 configincphp p

Step 7 設定語系

22

圖 3-19 設定語系

圖 3-20 執行 phpMyAdmin

23

33 升級及注意事項

RedHat 90附的 MySQL版本為 323 MySQL所釋出最新穩定版本為

40若是您不想用系統預附的 323請先利用下列移除之前 323的版本

rpm ndashe mysql-devel rpm ndashe mysql-server rpm ndashe mysql --nodeps 然後到下列網址下載您所想要的版本進行安裝在這裏我們用 4014版為例 Step 1 下載相關套件( httpwwwmysqlcomdownloadsmysql-40html )

圖 3-21 Download MySQL 4014 相關 RPM Step 2 利用 rpm 指令安裝

24

圖 3-22 Install MySQL 4014 相關 RPM

圖 3-23 Install MySQL 4014 相關 RPM

Step 3 啟動 MySQL

25

圖 3-24 啟動 MySQL 4014 並修改密碼

26

第四章 MySQL管理

本章將我們介紹利用WebminphpAdminCommand的方式建立一個名為

CONTACT的資料庫內有一個 address的 Table作為我們客戶通訊錄程式使

用的資料庫

41 Webmin 管理介面

412建立資料庫

Step 1 登入Webmin

圖 4-1 登入WebMin

Step 2 點選伺服器

27

圖 4-2 伺服器畫面

Step 3 點選 MySQL資料庫伺服器

圖 4-3 MySQL資料庫伺服器

28

Step 4 建立一個新的資料庫

圖 4-4 建立 MySQL資料庫

Step 5 建立名為 CONTACT的資料庫

29

圖 4-5 指定資料庫名稱

412 建立資料表

假設我們要建立一個名為 address的 Table其結構如下 欄位名稱 資料型態 長度 說明 id INT (自動編號) 連絡人編號 name varchar文字 20 連絡人姓名 tel Varchar文字 15 連絡人電話 Step 1 選擇 CONTACT資料庫

30

圖 4-6 選擇資料庫

Step 2 指定欄位數目

31

圖 4-7 設定欄位數目

Step 3設定表格欄位屬性

圖 3-8 設定表格欄位屬性

Step 4建立表格資料

32

圖 4-9 建立表格資料

圖 4-10 檢視資料

33

圖 4-11 新增資料

圖 4-12

34

圖 4-13

413 使用者管理

接下來我們要利用Webmin 來建立資料庫使用者並給予某些權限 Step1建立使用者

35

圖 4-14 選擇使用者權限

圖 4-15

36

Step2 賦予權限

圖 4-16

Step3 權限列表

37

圖 4-17

38

42 phpMyAdmin 的操作介面

421建立資料庫

Step 填入資料庫名稱並按「建立」

圖 4-18建立資料庫

422 建立資料表

Step1 填入資料表名稱並指定欄位數量 執行

39

圖 4-19填入資料表名稱並指定欄位數量

Step2 設定欄位屬性

圖 4-20設定欄位屬性

40

Step3 phpMyAdmin會產生相關的 SQL Command

圖 4-21 資料表結構及相關 SQL Command

Step4新增 Record

41

圖 4-22

圖 4-23

42

圖 4-24

圖 4-25

43

423使用者管理

Step1建立使用者

圖 4-26

44

圖 4-27

Step2 給予權限

圖 4-28

Step3權限列表

45

圖 4-29

43管理指令介紹

431 利用 mysqladmin設定 root的密碼

當您在Windows 或 Linux 中安裝好 MySQL後系統會自動幫您建立兩個

帳分別是 root 和 匿名者MySQL的 root 跟 Linux 最高權限使用者 root無關MySQL的 root使用者相當於 MS SQL 中的 sa 帳號擁有最高的 Database管理權限但系統預設 MySQL的 root 是不需要密碼所以通常我們一安裝

MySQL後首要任務便是修改 root的密碼 我們可以利用 mysqladmin工具或是直接修改 MySQL內部資料庫的使用者資

料 mysqladmin ndashu root ndashh cosaexamplecom password lsquo1234rsquo

46

-u 表示使用者帳號root 為 MySQL預設的管理帳號

-h 表示 MySQL主機的主機名稱也可使用 IP Address password 表示使用者的密碼因為字串請使用單引號將密碼括起來 密碼設定完成之後還是可以利用 mysqladmin修改密碼但是你必須提供目前的密碼

432 連線 MySQL

mysql -uroot -p密碼 (-p和密碼之間不能有空白) 或 mysql -uroot -p (此方式會在進入後要求密碼) [rootossc phpMyAdmin] mysql -u root -p1234

Welcome to the MySQL monitor Commands end with or g

Your MySQL connection id is 25 to server version 32354

Type help or h for help Type c to clear the buffer

mysqlgt show databases

+----------+

| Database |

+----------+

| mysql |

| test |

+----------+

2 rows in set (000 sec)

mysqlgt exit

Bye

[rootossc phpMyAdmin]

433 建立資料庫

可利用 mysqladmin指令建立 CONTACT資料庫 mysqladmin -u root -p1234 create CONTACT

47

或是利用 mysql指令 [rootossc bluepage] mysql -u root -p1234 Welcome to the MySQL monitor Commands end with or g Your MySQL connection id is 1057 to server version 32354 Type help or h for help Type c to clear the buffer mysqlgt create database CONTACT Query OK 1 row affected (000 sec) mysqlgt show databases +----------+ | Database | +----------+ | CONTACT | | address | | hello | | mysql | | nuke | | test | +----------+ 6 rows in set (000 sec) mysqlgt exit

434 建立資料表

編寫 adresssql內容如下 -- Table structure for table address CREATE TABLE address ( id int(11) NOT NULL auto_increment name varchar(20) NOT NULL default tel varchar(15) NOT NULL default PRIMARY KEY (id) ) TYPE=MyISAM

48

-- Dumping data for table address INSERT INTO address VALUES (1林小明0800016888) INSERT INTO address VALUES (2黃大雄0800016888) INSERT INTO address VALUES (3劉小芬0800024365) 然後執行此 sql script mysql -u root -p1234 CONTACT lt addresssql 或是利 mysql command [rootossc bluepage] mysql -u root -p1234 Welcome to the MySQL monitor Commands end with or g Your MySQL connection id is 1090 to server version 32354 Type help or h for help Type c to clear the buffer mysqlgt use CONTACT Database changed Database changed mysqlgt CREATE TABLE address ( -gt id int(11) NOT NULL auto_increment -gt name varchar(20) NOT NULL default -gt tel varchar(15) NOT NULL default -gt PRIMARY KEY (id) -gt ) TYPE=MyISAM Query OK 0 rows affected (000 sec) mysqlgt INSERT INTO address VALUES (1林小明0800016888) Query OK 1 row affected (000 sec) mysqlgt INSERT INTO address VALUES (2黃大雄0800016888) Query OK 1 row affected (000 sec) mysqlgt INSERT INTO address VALUES (3劉小芬0800024365) Query OK 1 row affected (000 sec) mysqlgt exit Bye

49

第五章 實用範例

51 任務一Web Base客戶通訊錄

任職於開放科技公司的林小明前些日子在最符合成本效益的條件下快

速地完成公司網站的建置老闆因此對小明讚譽有加最近因為公司存放客戶資

料的 SQL Server主機屢遭病毒攻擊加上作業系統本身的問題當機次數頻繁

老闆希望能儘快把公司的客戶通訊錄程式移轉到較穩定的環境上因為此客戶通

訊錄程式最主要給內部人員使用所以介面美觀並不特別要求只求穩定且能快

速得到查詢結果老闆希望在短時間先看到程式的雛型並鍵入資料對其效率

及穩定性進行測試因為上次小明表現突出所以這次不可能的任務自然又落到

小明身上 小明想來想去既然要快速又穩定他而且又不希望所有人都得安裝 Client

程式於是小明決定)捨棄他的舊愛「Delphi+MS SQL」投向新歡「Apache + MySQL + PHP」利用此架構來設計一個簡單實用的Web Base客戶通訊錄程式

511 Web Base客戶通訊錄架構

此程式需要建立 CONTACT的資料庫並建立 adress Tables其結構如下表建立步驟請參考第三章 欄位名稱 資料型態 長度 說明 id INT (自動編號) 連絡人編號 name varchar文字 20 連絡人姓名 tel Varchar文字 15 連絡人電話 Web Base通訊錄共有下列幾個檔案功能如下表

檔案名稱 說明 Indexhtml Web Base通訊錄首頁 addphp 新增連絡人的 php程式 searchphp 尋找連絡人的 php程式 editphp 具有更新及刪除功能的 php程式

50

我們將這些檔案放至varwwwhtmlbluepage (預設無 bluepage目錄)

512 Web Base通訊錄測試

httpwwwopencombluepage 新增資料

圖 5-1 新增連絡人

圖 5-2 填入資料

51

圖 5-3 新增成功

搜尋及異動資料

圖 5-4 搜尋通訊錄

52

圖 5-5 編輯資料

圖 5-6 更新資料

513 程式內容及說明

lt-- 程式範例indexhtml--gt lthtmlgt ltheadgtlttitlegt通訊錄lttitlegtltheadgt ltbodygt ltcentergt

53

lth2gt通訊錄lth2gtlthrgt lta href=indexhtmlgt通訊錄ltagt | lta href=addphpgt新增連絡人ltagt | lta href=searchphpgt搜尋通訊錄ltagt ltcentergt ltbodygt lthtmlgt lt-- 程式範例addphp --gt lthtmlgt ltheadgtlttitlegt新增連絡人lttitlegtltheadgt ltbodygt ltcentergtlth2gt新增連絡人lth2gtltcentergtlthrgt lt 取得欄位資料 if (isset($_POST[Name]) ampamp isset($_POST[Tel]) ) $name = $_POST[Name] $tel = $_POST[Tel] 檢查是否有輸入欄位資料 if ($name = ampamp $tel = ) 建立 SQL字串 $sql = INSERT INTO address (name tel) values( $sql= $name $tel) 建立 MySQL 連結 $link = mysql_connect(localhostroot1234) 選擇資料庫 mysql_select_db(CONTACT) 執行 SQL指令 mysql_query($sql) mysql_close($link) echo ltfont color=redgt新增連絡人成功ltfontgtltbrgt gt ltform action=addphp method=postgt lttable border=0 width=300gt lttrgtlttdgt姓名 lttdgt

54

lttdgtltinput type=text name=Name size=20 maxlength=10gtlttdgtlttrgt lttrgtlttdgt電話 lttdgt lttdgtltinput type=text name=Tel size=20 maxlength=20gtlttdgtlttrgt lttrgtlttd colspan=2 align=centergt ltinput type=submit value=新增連絡人gtlttdgtlttrgt lttablegt ltformgt ltbrgtlta href=indexhtmlgt通訊錄ltagt | lta href=addphpgt新增連絡人ltagt | lta href=searchphpgt搜尋通訊錄ltagt ltbodygt lthtmlgt

lt-- 程式範例searchphp --gt lthtmlgt ltheadgtlttitlegt搜尋通訊錄lttitlegtltheadgt ltbodygt ltcentergtlth2gt搜尋通訊錄lth2gtlthrgt lt if (isset($_POST[Search])) 建立資料庫連結並選定資料庫 $link = mysql_connect(localhostroot1234) mysql_select_db(CONTACT) 建立基本的 SQL字串 $sql = SELECT FROM address 檢查是否輸入姓名 if (chop($_POST[Name]) = ) $name = name LIKE $_POST[Name] else $name = 檢查是否輸入電話號碼 if (chop($_POST[Tel]) = ) $tel = tel LIKE $_POST[Tel] else $tel =

55

if條件組合 SQL字串 if (chop($name) = ampamp chop($tel) = ) $sql= WHERE $name AND $tel elseif (chop($name) = ) 只有姓名 $sql = WHERE $name elseif (chop($tel) = ) 只有電話號碼 $sql = WHERE $tel $sql= ORDER BY name 最後加上排序 $result = mysql_query($sql) 取得欄位數 $total_fields = mysql_num_fields($result) echo lttable border=1gt echo lttrgtlttdgt編號lttdgtlttdgt姓名lttdgtlttdgt電話lttdgtlttd colspan=2gt功能選項lttdgtlttrgt 表格顯示查詢結果 while ($rows = mysql_fetch_array($result MYSQL_NUM)) echo lttrgt for ($i = 0 $i lt $total_fields $i++) echo lttdgt$rows[$i]lttdgt echo lttdgtlta href=editphpaction=editampid= echo $rows[0]gtltbgt編輯ltbgtlttdgt echo lttdgtlta href=editphpaction=delampid= echo $rows[0]gtltbgt刪除ltbgtlttdgt echo lttrgt echo lttablegtlthrgt mysql_free_result($result) mysql_close($link) gt ltcentergt ltform action=searchphp method=postgt lttable border=0 width=450gt lttrgtlttdgt搜尋姓名 lttdgt lttdgtltinput type=text name=Name size=10 maxlength=20gtlttdgtlttrgt lttrgtlttdgt搜尋電話 lttdgt lttdgtltinput type=text name=Tel

56

size=20 maxlength=20gtlttdgtlttrgt lttrgtlttd colspan=2 align=centergt ltinput type=submit name=Search value=搜尋gtlttdgtlttrgt lttablegt ltformgt ltbrgtlta href=indexhtmlgt通訊錄ltagt | lta href=addphpgt新增連絡人ltagt | lta href=searchphpgt搜尋通訊錄ltagt ltbodygt lthtmlgt

lt ob_start() gt lt-- 程式範例editphp --gt lthtmlgt ltheadgtlttitlegt編輯通訊錄lttitlegtltheadgt ltbodygt lt 取得 URL 參數 $id = $_GET[id] $action = $_GET[action] 建立資料庫連結 $link = mysql_connect(localhostroot1234) mysql_select_db(CONTACT) 選擇資料庫 執行的操作 switch ($action) case update 更新 取得欄位資料 $name = $_POST[Name] $tel = $_POST[Tel] $sql = UPDATE address SET name=$name tel=$tel WHERE id=$id mysql_query($sql) 執行 SQL指令 mysql_close($link) header(Location searchphp) 轉向到 serachphp break case del 刪除 $sql = DELETE FROM address WHERE id=$id

57

mysql_query($sql) 執行 SQL指令 mysql_close($link) header(Location searchphp) 轉向到 serachphp break case edit 編輯 $sql = SELECT FROM address WHERE id=$id $result = mysql_query($sql) 執行 SQL指令 $row = mysql_fetch_row($result) 取回記錄 $name = $row[1] 取得欄位 name $tel = $row[2] 取得欄位 tel mysql_close($link) 顯示編輯表單 gt ltcentergtlth2gt更新通訊錄lth2gtltcentergtlthrgt ltform action=editphpaction=updateampid=lt echo $id gt method=postgt lttable border=0 width=300gt lttrgtlttdgt姓名 lttdgt lttdgtltinput type=text name=Name size=20 maxlength=10 value=lt echo $name gtgtlttdgtlttrgt lttrgtlttdgt電話 lttdgt lttdgtltinput type=text name=Tel size=20 maxlength=20 value=lt echo $tel gtgtlttdgtlttrgt lttrgtlttd colspan=2 align=centergt ltinput type=submit value=更新連絡人gtlttdgtlttrgt lttablegt ltformgt ltbrgtlta href=indexhtmlgt通訊錄ltagt | lta href=addphpgt新增連絡人ltagt | lta href=searchphpgt搜尋通訊錄ltagt lt break gt ltbodygt lthtmlgt

58

52 任務二Web Base群組軟體 ( twig )

順利完成Web Base客戶通訊錄程式測試一段時間後「Apache + MySQL + PHP」架構的穩定與快速巳深得老闆與公司所有同事的認同隨著公司業績蒸

蒸日上人員組織編罝愈來愈龐大跨部門的會議愈來愈多業務員每日排滿拜

訪客戶的行程跟客戶的 Email的往來也愈來愈頻繁 愈來愈多部門的同事希望公司能建置一套群組軟體提供 web mail可讓業

務人員方便收發 mail還有連絡人議事日程待辦工作書簽等功能讓整個

公司運作及個人時間管理更有效率

老闆問小明對這些需求有什麼看法小明認為如果這些功能完全由程式部

門開發必定曠日費時而且耗費公司資源小明在網路尋找是否有提供這些功能

的Free Software皇天不負苦心人小明發現了TWIG (The Web Information Gateway) httptwigscrewdrivernet這個群組軟體它在 Web 上整合郵件新聞聯絡人議事日程工作序書簽等功能非常符合公司的需求 Step 1 下載 twig-277targz 下載網址 httptwigscrewdrivernetdownloadphp3

Step 2 解開 twig-277targz tar -xzvf twig-277targz

59

Step 3 執行安裝動作安裝到 varwwwhtmltwig 目錄 cd twig-277 twig-install varwwwhtmltwig

Step 4 建立 MySQL 資料庫(twig)及各資料表

cd setup mysql -u root -p1234 mysqlgt create database twig Query OK 1 row affected (001 sec) mysqlgt quit mysql -u root ndashp1234 twiglt twigtablemysql

Step 5 修改 configincphp3 參數設定 vi varwwwhtmltwigconfigconfigincphp3 $config[fromdomain] = opencom 網域 $config[language] = chinesebig5 中文訊息 $config[imap_port] = 143notls

60

Step 6 修改連結 MySQL 的帳號密碼 vi varwwwhtmltwigconfigdbconfigincphp3 $dbconfig[sqlusername] = root username $dbconfig[sqlpassword] = 1234 password

Step 7 其他設定檔

vi etchttpdconfhttpdconf 加入 AddType applicationx-httpd-php php3 在 DirectoryIndex最後加入 indexphp3 DirectoryIndex indexhtml indexhtmlvar indexphp3 在 AddDefaultCharset ISO-8859-1加上 AddDefaultCharset ISO-8859-1

vi etcphpini register_globals = On service httpd restart Step 8 sendmail 設定 vi etcmailsendmailcf在 264 行前面加上並重新啟動 sendmail「service snedmail restart」 262 SMTP daemon options 263 264 O DaemonPortOptions=Port=smtpAddr=127001 Name=MTA 265 266 SMTP client options 267 O ClientPortOptions=Family=inet Address=00

61

Step 9 檢查設定有無錯誤 http主機名稱twigtestphp3

62

Step 10 登入 twig ( http主機名稱twig)

63

第六章 維護及更新程序

61 日常維護

系統管理員最好定期以 root 身份登入看看信件在 RedHat Linux 中有一支 logwatch 程式會定時去分析 log file如果發現異常便會發信給 root除此之外筆者建議讀者平時就檢查 MySQL log file ( varlogmysqldlog)是否有異常情形

62 更新程序

讀者可至httprpmfindnet 尋找MySQL相關套件至於升級的相關步驟請參

考Linux OS SOP 第 54節

63 備份重要檔案

預設 MySQL 的 DB 檔案是存在 varlibmysql 內以 DB名稱為目錄目錄

內就是該 DB 的所有資料通常得定期備份還有 MySQL的設定檔 etcmycnf也別忘了一起備份

64 離線備份與還原

641 離線備份

預設 MySQL 的 DB 檔案是存在 varlibmysql 內以 DB 名稱為目錄目錄內

就是該 DB 的所有資料像 CRM 這個 DB就是存在 varlibmysqlCRM 內在備份前因為怕資料尚未完全寫入磁碟而且 MySQL 會 Lock 在使用的 DB 檔案所以應該是要先把 MySQL 先 Shutdown 一下整個備份的程序可以下像下面的指令去完成 cd varlibmysql

64

service mysqld stop tar cvfz CRM_db_20030905tgz CRM service mysqld start 對這樣就可以了 不過要注意的是怕 DB 內每個 Tables 間的資料有關關

聯性所以最好是把整個 DB 一次備起來單獨只備哪個 Tables 的檔案以後回存時怕會有資料關聯不一致的問題

642 離線還原

DB 發生錯誤而要回存時其實也不難先找出最近一次完整正常的備份先把現在錯誤的網頁或 DB 先更名或 tar 起來再把好的備份給解開回原來目錄位

置就行了需要注意的是 MySQL 服務最好也是要先停止回存完成後再啟動服務回存 DB 的整個程序可能像下面 cd varlibmysql service mysqldstop mv CRM CRM_OLD tar xvfz CRM_db_20030905tg service mysqld start

65 線上備份與還原

651 線上備份

使用像上面的檔案方式備份是個不錯的方法它最少可以保持該主機某個時間點的完整檔案備份但還是有一些問題需要考慮到有些主機就不只建立一個 DB 而已總不能為了備份某個 DB 而把整個 MySQL 服務停止備份檔案的方式回存在原主機上一定適用但假如 MySQL 版本升級或是在那天該網頁空間需遷機移機到別的主機時那就沒人敢保證備出來的資料檔可以用所以我們可以考慮另一種備份的方式是使用 MySQL 本身提供的功能 MySQL Data Dump指令是 mysqldump

65

使用 MySQL 的 Dump 功能可以把 DB 的結構資料或結構加資料 Dump 成文字檔 mysqldump 指令提供的彈性很大你可以選擇把整個 DB Dump 成一個檔或是每個 Table 為一個檔甚至是把結構檔和資料分開儲存都

可以 mysqladmin -uroot -p flush-logs mysqldump CRM -uroot -p --opt gt CRM_20030905sql (CRM 是 DB 名稱 opt 是一個使用完整 Dump 參數) 假如只是要單獨 Dump 某個 Table 時只要在上面的指令後轉出符號 gt 前加個 Table 名稱就可以如只要 phpbb2_users 這個 Table 的 Dump 時只要下 mysqldump CRM -uroot -p --opt CUSTOMER gt CRM_CUSTOMER_20030905sql

652 線上還原

若要回存整個資料庫只需將壓縮的備份檔還原成 Dump 的檔案再用下面的指令回存 mysql CRM -uroot -p lt CRM_20030905sql 這邊需注意的是若建立備份時是以--opt或--add-drop-table為參數時回存的 動作是先將舊的 Table 先刪除重建 Table 的結構後再把 Data 匯入所以回存後所有的資料會回到你當時備份那個時間點因此在回存資料時可以考慮把現有錯誤或不完整的 DB 先備份一份下來以備不時之需或是拿來比對錯誤的地

方在那裡當然你也可以把資料回存到另一個測試用的 DB 內只要把上面指令

的 DB 名稱改成你的測試用 DB 名稱即可 使用這種回存方式 MySQL 服務不需停止也不會動到其他正在使用的 DB 在一些提供 MySQL 服務的虛擬主機可用這種方式作你自己的 DB 備份及回存

66

另外假如你是系統重建或是移機時切需在新的 MySQL 內新建一個空白 DB 後才行作回存的工作你可以用下面的指令建立 mysql -uroot -p -e CREATE DATABASE CRM (上面的 CRM是你要新建的 DB 名稱) 另一種作法先用 mysql 指令進入 mysql client console 然後再用 CREATE DATABASE CRM 這樣就行了記得尾端要加個 符號該行指令才會執行

67

第七章 問題與解答

Q1RedHat 90預附的 MySQL到底有無支援 Transcation機制 Ans MySQL自 32334a之後的 MySQL-Max版本加入 InnoDB的資料庫類型透過

InnoDBMySQL同樣可以進行 COMMIT與 ROLLRACK的動作RedHat 90預附的 MySQL為 32354a-11巳支援 InnoDB的資料庫類型不過必須做以

下設定 1cp usrsharedocmysql-server-32354amy-mediumcnf to etcmycnf 2 vi etcmycnf 將以下設定前的拿掉 innodb_data_home_dir = varlibmysql innodb_data_file_path = ibdata110Mautoextend innodb_log_group_home_dir = varlibmysql innodb_log_arch_dir = varlibmysql 3service mysqld restart 如此一來各位在建立Table時便可指定Table Type為 innodb ( ex create table with type=innodb ) Q2如何解決 php+mysql 許功蓋等字變亂的問題 Ans 方法一 【確定 MySQL 預設的字元集】 1 打開 WinMySQLadmin 管理畫面(在視窗右下角狀態列紅綠燈圖示中按滑鼠

右鍵點選 Show me 選項) 2 點選管理畫面中 [Variables] 標籤選項其中 character_set變數就是您預設

字元集的變數其預設是 latin1 字元集(我們要將他改回 big5)而 chatacters_set 變數則是 MySQL 可以支援哪些字元集 【修改預設字元集變數 character_set 】 1 請點選管理畫面中 [myini Setup] 標籤選項設定 myini 2 按一下 [Pick-up and Edit myini values] 按鈕以便編輯目前的 myini 設定 3 在 [mysqld] 設定區塊底下新增一行 default-character-set = big5 變數設

68

定 4 新增一個 [client] 設定區塊並加入第三步驟的變數設定(游標往下移到空白處新增兩行 [client] 和 default-character-set=big5) 5 按一下畫面左下方 [Save Modification] 按鈕儲存設定 6 重新啟動 MySQL 或 Windows 方法二 Server端注意事項 phpini 中有關的設定為(預設值) Magic quotes for incoming GETPOSTCookie data magic_quotes_gpc = On Use Sybase-style magic quotes (escape with instead of ) magic_quotes_sybase = Off Client端注意事項 1中文資料送進 mysql 前請用 addslashes($str) 處理 2處理後送進 mysql 時請用 括起來並在參數後留一個空白如 $sql = UPDATE ezf_table set tablename=$tname tableend=$endtime table inguser=$tguser tableingid=$tguserid tableallnumber=$tnumber tableloca l=$tablelocal tableanyone=$tableopen tabletext=$ttext WHERE tableid=$t ableid tablename=$tname c 取出時請用 stripslashes($str) Q3MySQL root 密碼忘了該怎麼辦 Ans 1先停掉 mysql etcrcdinitdmysql stop 2以--skip-grant-table 的參數啟動 mysql safe_mysql --skip-grant-tableamp 3 更改 root 密碼 mysql mysql mysqlgt UPDATE user SET password=password(newpassword)

69

WHERE user=root mysqlgt FLUSH PRIVILEGES mysqlgt exit 4停掉 mysql再重跑 mysqladmin -uroot -p shutdown Enter password 輸入新設定的密碼 etcrcdinitdmysql start

Q4NULL值問題

Ans

NULL值的概念是造成 SQL的新手的混淆的普遍原因他們經常認為 NULL是和一個空字符串的一樣的東西不是這樣的例如下列語句是完全不同的

mysqlgt INSERT INTO my_table (phone) VALUES (NULL)

mysqlgt INSERT INTO my_table (phone) VALUES ()

兩個語句把值插入到 phone 列但是第一個插入一個 NULL值而第二個插入一個空字符串第一個的含義可以認為是ldquo電話號碼不知道而第二個則可意味

著ldquo她沒有電話

在 SQL中NULL值在于任何其他值甚至 NULL值比較時總是假的(FALSE)包含 NULL的一個表達式總是產生一個 NULL值除非在包含在表達式中的運算符和函數的文檔中指出在下列例子所有的列返回 NULL

mysqlgt SELECT NULL1+NULLCONCAT(InvisibleNULL)

如果你想要尋找值是 NULL的列你不能使用=NULL測試下列語句不返回任

何行因為對任何表達式expr = NULL是假的

mysqlgt SELECT FROM my_table WHERE phone = NULL

要想尋找 NULL值你必須使用 IS NULL測試下例顯示如何找出 NULL電話號碼和空的電話號碼

70

mysqlgt SELECT FROM my_table WHERE phone IS NULL mysqlgt SELECT FROM my_table WHERE phone =

在 MySQL中就像很多其他的 SQL服務器一樣你不能索引可以有 NULL值的列你必須聲明這樣的列為 NOT NULL而且你不能插入 NULL到索引的

列中

當用 LOAD DATA INFILE 讀取數據時空列用更新如果你想要在一個列中有

NULL值你應該在文本文件中使用N字面上的詞NULL也可以在某些情形下使用

當使用 ORDER BY時首先呈現 NULL值如果你用 DESC以降序排序NULL值最後顯示當使用 GROUP BY時所有的 NULL值被認為是相等的

為了有助于NULL的處理你能使用 IS NULL和 IS NOT NULL運算符和 IFNULL()函數

對某些列類型NULL值被特殊地處理如果你將 NULL插入表的第一個TIMESTAMP 列則插入當前的日期和時間如果你將 NULL插入一個AUTO_INCREMENT 列則插入順序中的下一個數字

Q5如何將圖片存放於 MySQL中

Ans

Step 1建立資料庫 test

Step 2 建立表格 binary_data

CREATE TABLE binary_data (

id INT(4) NOT NULL AUTO_INCREMENT PRIMARY KEY

description CHAR(50)

bin_data LONGBLOB

filename CHAR(50)

filesize CHAR(50)

filetype CHAR(50)

71

)

Step 3 利用 storephp 寫入圖片

storephp 程式碼

ltHTMLgt ltHEADgtltTITLEgtStore binary data into SQL DatabaseltTITLEgtltHEADgt ltBODYgt lt code that will be executed if the form has been submitted

if ($submit) mysql_connect(localhostrootYOUR_PASSWORD) mysql_select_db(test) $data=Base64_Encode(fread(fopen($form_data r) filesize($form_data))) $result=MYSQL_QUERY(INSERT INTO binary_data (descriptionbin_datafilenamefilesizefiletype) VALUES ($form_description$data$form_data_name$form_data_size$form_data_type)) $id= mysql_insert_id() print ltpgtThis file has the following Database ID ltbgt$idltbgt MYSQL_CLOSE() else else show the form to submit new data

gt

ltform method=post action=ltphp echo $PHP_SELF gt enctype=multipartform-datagt File Descriptionltbrgt ltinput type=text name=form_description size=40gt ltINPUT TYPE=hidden name=MAX_FILE_SIZE value=4000000gt ltbrgtFile to uploadstore in databaseltbrgt ltinput type=file name=form_data size=40gt ltpgtltinput type=submit name=submit value=submitgt ltformgt lt

72

gt ltBODYgt ltHTMLgt

Step 3 利用 storephp 取出圖片

getdataphp 程式碼

lt Syntax getdataphp3id=ltidgt if($id) you may have to modify login information for your database server MYSQL_CONNECT(localhostrootYOUR_PASSWORD) mysql_select_db(test) $query = select bin_datafiletype from binary_data where id=$id $result = MYSQL_QUERY($query) $data = Base64_Decode(MYSQL_RESULT($result0bin_data)) $type = MYSQL_RESULT($result0filetype) Header( Content-type $type) echo $data gt

Q6MySQL裝好之後啟動時或是執行 mysqladmin會出現如下訊息 Cant connect to local MYSQL Server through Socket varlibmysqlmysqlsock或是

Cant connect to local MYSQL Server through Socket tmpmysqldsock

Ans 可能有下列幾個原因

1這個 mysqldsock 不見了被某人刪除了或是被一些系統自動執行程式給刪

了例如有些 cron任務便會設定定期刪除 tmp 裡的東西所以呢您只能修改

cron 裡的設定讓它不要清除 mysqldsock 2在啟動時也可以改變 mysqldsock的位置您在啟動 MySQL的時候可以加入此參數usrlocalmysqlbinsafe_mysqld --user=mysql --socket=其他路

徑socket amp 同時得去設定環境變數 MYSQL_UNIX_PORT的值以指定新的

73

路徑 3若是您沒改 MYSQL_UNIX_PORT的值那麼您可以在執行指令的時候才打

例如mysqladmin --socket=其他路徑socket version Q7How to get the last insert id Ans CREATE TABLE product ( id INT(4) NOT NULL AUTO_INCREMENT PRIMARY KEY description VARCHAR(50) ) 1利用 SQL的話 mysqlgt insert into product(description) values(123) Query OK 1 row affected (000 sec) mysqlgt select last_insert_id() +------------------+ | last_insert_id() | +------------------+ +------------------+ 1 row in set (000 sec) ======================================== 2如果是 PHP的話 你可以用mysql_insert_id()取得該 id PHP example $result=MYSQL_QUERY(INSERT INTO product (description) VALUES ($description)) $id= mysql_insert_id() print This file has the following Database ID $id Q8如何將文字檔匯入資料庫 Ans $addr=homehttpdhtmlphpschool001txt $sql_select = load data infile $addr into table test fields terminated by t 解說 $sql_select = load data infile 文字檔名 into table 表格名 fields terminated by

74

t

(欄位分隔以 TAB鍵) 該文字檔須與資料表欄位格式相符 例如欄位有三個 則文字檔為每行一筆資料如下 欄 1資料ltTABgt欄 2資料ltTABgt欄 3資料 欄 1資料ltTABgt欄 2資料ltTABgt欄 3資料 欄 1資料ltTABgt欄 2資料ltTABgt欄 3資料 欄 1資料ltTABgtltTABgt欄 3資料

Q9如何撰寫 MySQL C API Ans Step 1利用文字編輯器撰寫以下程式碼 mysqlcc

include ltstdiohgt

include ltmysqlmysqlhgt

int main (int argc char argv[])

MYSQL mysql

MYSQL_RES res

MYSQL_ROW row

if (argc = 2)

fputs (Usage myc ltdatabasegt stderr)

return 1

if ((mysql_connect(ampmysqllocalhostrootYour_Password)))

fputs (Error connecting stderr)

abort()

75

if (mysql_select_db(ampmysqlargv[1]))

fputs (Error selecting database stderr)

abort()

if (mysql_query(ampmysqlSELECT FROM test_table))

fputs (Error processing query stderr)

abort()

if ((res = mysql_store_result(ampmysql)))

fputs (Error storing results stderr)

abort()

while((row = mysql_fetch_row(res)))

uint i = 0

for (i=0 i lt mysql_num_fields(res) i++)

printf(s row[i])

printf(n)

return 0

Step 2 Compile

gcc -Iusrlocalmysqlinclude -Lusrlocalmysqllibmysql mysqlcc ndashlm -lmysqlclient

(其中 include path與 library path取決於你的 MySQL安裝路徑)

76

如果執行時發生如下 error Run problemerror in loading shared libraries libmysqlclientsoX 將你的 MySQL library path(for exampleusrlocalmysqllibmysql) 加入etcldsoconf and run sbinldconfig -v Q9ASP + MySQL 範例程式 Ans Dim myconn As New ADODBConnection Dim myrs As New Recordset Dim mySQL As String Dim myrows As Long myconnOpen DSN=MyODBCsample mySQL = SELECT from user myrsSource = mySQL Set myrsActiveConnection = myconn myrsCursorLocation = adUseClient myrsOpen myrows = myrsRecordCount myrsClose myconnClose 可參考 httpwwwdwamnetmysqlasp_myodbcasp 有詳細的資料 Q10如何將 MySQL中的資料庫匯出成txt檔 Ans select from TableName into outfile textxls all result fields will seperate by tab

77

第八章 參考資料

英文部份 網址 1 httpwwwmysqlcom MySQL 網站有第一手有關 MySQL的資料 2 httpwwwmysqlcomdocenReplicationhtml 有關 MySQL Replication 的文件 3 httpwwwgeocitiescomsqlhomefaqstore_blobhtml 如何在 MySQL 存放 BLOB的資料 4httpwwwsapdborg 有關 SAP跟 MySQL相關合作的網站 書藉 1 Cooking with MySQL

Paul DuBois has selected sample recipes from the hundreds youll find in his book MySQL

Cookbook In this third and final series of excerpts showcasing these recipes learn how to

compute team standings how to calculate the differences between successive Dec 26

2002 2 Tips for Building Web Database Applications with PHP and MySQL by Hugh E Williams co-author of Web Database Applications with PHP amp MySQL 04042002

3 Managing and Using MySQL 2nd Edition By Tim King George Reese Randy Jay Yarger

4 MySQL Cookbook By Paul DuBoisPublisher OReillyPub Date October 2002

中文部份

78

1 httplinuxtncedutwtechdocmysqlmysql_docmanual_tochtml MySQL 中文手冊 2 httpchenshloxaedutwphpZ_1php PHP+MySQ程式研習設計網站 3 httplinuxtncedutwtechdocbanicdownhtml PHP 4 手冊 4 httpwwwtncedutwadmin_zonephp台南縣教育網網路中心有很多 Linux相關文件 5 httpdobtncedutw網站建置百寶箱有很多 PHP MySQL 相關範例程式 5 httpwwwdbworldcomtw資料庫專家電子雜誌介紹資料庫的重要觀念及名詞

79

附錄一 SQL Command 介紹

SQL (讀音ess-que-el) 是一種結構查詢語法SQL 使用於資料庫交流

傳遞相容於 ANSI (American National Standards Institute) 是一套標準的關聯

式資料庫語言 SQL 語言是執行更新或從資料系統獲取資料一般常見的關聯

資料庫系統都有提供 SQL 如 Oracle Sybase Microsoft SQL Server Access Ingres 等雖然大部份的資料庫都有提供 SQL 但也多提供了自已獨特的語

法造成了不相容的情形但標準基本的語法是相通的如Select Insert Update Delete Create and Drop 每一個系統都有支援

Table相關 Command

Create Table

關聯式資料庫包含有很多元件稱為資料表(tables) 把資料或訊息放在資

料表中 資料表是以不同的名稱做分別資料表由欄列所構成的二維陣列

欄包含欄位名資料型態 及其他可判斷的資訊列是由全部欄位構成一筆一

筆的紀錄 create table 語法用在建立一個新的資料表語法格式如下

create table tablename (column1 data type column2 data type column3 data type)

Format of create table if you were to use optional constraints

create table tablename (column1 data type [constraint] column2 data type [constraint] column3 data type [constraint]) [ ] = optional

Note You may have as many columns as youd like and the constraints are optional

80

Example

create table employee (first varchar(15) last varchar(20) age number(3) address varchar(30) city varchar(20) state varchar(20))

注意建立資料表格式要以括號把前後框住而最後以(分號)做結尾

欄位名不要超過 30個字元長而且不要使用 sql 的關鍵字(如 where select等)而在後面接是型態的宣告(如字串數字日期格式等)

資料型態是來描述欄位的方式如一個欄位Last_Name 是一個姓氏可以使用varchar (可變動長度字串) 資料型態

以下是幾個常見的資料庫型態 char(size) 固定長度字串最長為 255 位元 varchar(size) 變動長度字串最大字元數以 size 來指定 number(size) 數值格式可以是整數也可以是小數最大數字以 size 位數判

斷未指定小數位數由系統內定 date 日期格式 number(sized) 數值格式最大數字以 size 位數判斷d 為小數位數整數位

數為 size-d 位

有何限制當資料表被建立通常有一或數個欄位是要使用來做關聯的功

能 例如unique 限制(唯一值)兩筆記錄不可以相同的值 not null (非空值)該欄位一定要輸入資料不可是空的primary key (主鍵)是每一筆記錄識別的主要方式

Drop a table drop table 刪除資料表(其中的資料也會一併刪除)

drop table tablename

Example

81

drop table 和刪除全部資料是不同的刪除全部資料欄位名稱資訊等還會

存在但刪除資料表會把這一些也一併移除掉

如何查詢資料

Select 基本用法

select 語法是關連式資料庫最常用的部份可以取得你想要的資料這是一個

簡單的範例 select column1[column2etc] from tablename [where condition] [] = optional 在 select 之後所列欄位名則是要顯示的資料部份你可以一一列出各欄位

名或是以 (星號)來代表選擇全部的欄位 from 之後放資料表名稱 where 子句 (選項) 指定要過濾的條件符合者才會顯現 where 可使用的條件運算元 = 等於 gt 大於 lt 小於 gt= 大或等於 lt= 小或等於 ltgt 大相等 LIKE 相似 For example select first last city

82

from empinfo where first LIKE Er 以Er 為開頭的字串就符合要以單引號框住 Or you can specify select first last from empinfo where last LIKE s 最後一字為 S 就符合 select from empinfo where first = Eric 則表示 first name 一定要是 Eric 才可以 範例資料表empinfo 統計函數

MIN 傳回指定欄位最小值

MAX 傳回指定欄位最大值

SUM 傳回指定欄位總和

AVG 傳回指定欄位平均值

COUNT 傳回指定欄位的筆數

COUNT() 傳回資料庫中的總筆數

統計函數使用於資料表中的數值欄位配合 SELECT 語法使用 只用於總結特定單一欄位可以配合 GROUP BY 做篩選但也可以不使用 GROUP BY 語句For example

SELECT AVG(salary) FROM employee

83

傳回全部 salary 平均值

Another example

SELECT AVG(salary) FROM employee WHERE title = Programmer

傳回 salary 平均值條件為 employees 資料表中當 title 等於 Programmer

Example

SELECT Count() FROM employees

傳回 employees 資料表中紀錄總筆數

GROUP BY 語法 SELECT column1 SUM(column2) FROM list-of-tables GROUP BY column-list The GROUP BY 語句可以先以所列的欄位為條件分組排序在一起(可以多欄

位) example 要列出每一個 dept 中最高 salary 值 SELECT max(salary) dept FROM employee GROUP BY dept HAVING 語法

SELECT column1 SUM(column2) FROM list-of-tables GROUP BY column-list HAVING condition

HAVING 子句是 GROUP BY 的一部份用來過濾在 GROUP BY 所選出的資料功能如同 select 命令中 where 條件式一樣只是 HAVING 必需配合 GROUP BY 使用

我們以例子來說明我們要取得每一公司名及每一公司的薪水平均值輸入如下

84

SELECT dept avg(salary) FROM employee GROUP BY dept

但如果我們只列出薪資平均值超過 20000元的公司資料

SELECT dept avg(salary) FROM employee GROUP BY dept HAVING avg(salary) gt 20000

ORDER BY子句語法

SELECT column1 SUM(column2) FROM list-of-tables ORDER BY column-list [ASC | DESC]

[ ] =選項

ORDER BY是一個選項子句當你以排序方式來顯示資料(正向由小到大反向由大到小)以指定的欄位資料做排序

ASC = 正向- 預設值 DESC = 反向排序

For example

SELECT employee_id dept name age salary FROM employee_info WHERE dept = Sales ORDER BY salary

以上列出公司代號公司名銷售員人名年紀及薪資而條件是公司名為 Sales 顯示順序以薪資多少排序(由小到大為預設值)

如果要以多個欄位做排序要以逗號做分隔如下

SELECT employee_id dept name age salary FROM employee_info WHERE dept = Sales ORDER BY salary age DESC

85

結合條件及布林運算 SELECT column1 SUM(column2) FROM list-of-tables WHERE condition1 AND condition2 AND運算可以結兩個或以上的條件放在 WHERE子句中 兩者都要為真才

會顯示該筆記錄 OR 運算可以結兩個或以上敘述放在 WHERE子句中只要其中一個為直就

會顯示該筆記錄 For example SELECT employeeid firstname lastname title salary FROM employee_info WHERE salary gt= 5000000 AND title = Programmer 必需要薪資大於等於 50000而且職稱為 Programmer同時符合才會顯示該筆資料 以下以括號括住雖然不是必需的但如此比較容易讀 SELECT employeeid firstname lastname title salary FROM employee_info WHERE (salary gt= 5000000) AND (title = Programmer) 另外範例 SELECT firstname lastname title salary FROM employee_info WHERE (title = Sales) OR (title = Programmer) 條件為只要是 Sales 或 Programmer 職稱的就會被列出 IN and BETWEEN 子句

SELECT column1 SUM(column2) FROM list-of-tables WHERE column3 IN (list-of-values) SELECT column1 SUM(column2) FROM list-of-tables WHERE column3 BETWEEN value1 AND value2 IN 子句使用在列舉項目的使用上也就是分別測試是否符合所列的值 For example

86

SELECT employeeid lastname salary FROM employee_info WHERE lastname IN (Hernandez Jones Roberts Ruiz) 條件為姓氏(astname)要符合 Hernandez Jones Roberts or Ruiz 其中一個才會被傳回 IN運算元也可以使用 OR 的語法來取代如下結果相同 SELECT employeeid lastname salary FROM employee_info WHERE lastname = Hernandez OR lastname = Jones OR lastname = Roberts OR lastname = Ruiz 但使用 IN 句子比較短也比較易懂 你也可以使用 NOT IN 來去掉不要的記錄 BETWEEN 運算元使用在判斷是否存在兩個數值之間 For example SELECT employeeid age lastname salary FROM employee_info WHERE age BETWEEN 30 AND 40 傳回年紀 30歲到 40歲之間的資料(含 30及 40歲者) 相同的也可以使用以下語法來達到相同的結果 SELECT employeeid age lastname salary FROM employee_info WHERE age gt= 30 AND age lt= 40 你也可使用 NOT BETWEEN 來濾掉中間值的資料 數學運算 標準 ANSI SQL-92 提供以下運算

87

+ 加

- 減

餘數

餘數為除法後剩整數這不在標準的 ANSI SQL 中但大部份的資料庫都會支

援這運算元以下列出有用的函數雖不在 ANSI SQL-92 提供但一般資料庫

也會支援他們

ABS(x) 傳回 x 絕對值

SIGN(x) returns the sign of input x as -1 0 or 1 (negative zero or positive respectively)

MOD(xy) 餘數 - returns the integer remainder of x divided by y (同 xy)

FLOOR(x) 傳回小或等於 x 的最大整數值

CEILING(x) or CEIL(x)

傳回大或等於 x 的最小整數值

POWER(xy) x的 y 次方

ROUND(x) 把 x 四捨五入為整數

ROUND(xd) 四捨五入取到小數 d 位

SQRT(x) x 開平方

For example SELECT round(salary) firstname FROM employee_info 傳回薪資取到整數位

如何新增資料

insert 加入一筆新紀錄到資料表中 insert into tablename (first_columnlast_column) values (first_valuelast_value) [] = optional Example insert into employee

88

(first last age address city state) values (Luke Duke 45 2130 Boars Nest Hazard Co Georgia) Note 字串要以單引號住如string 數字框住也無妨 insert into 後面接資料表名稱再接以括號括住的欄位名在 values 後括號分別對映各欄位的值 以上的例子新增了一筆名(first) 為 Luke而住所(state) 為 Georgia 的資料

如何刪除資料

delete 可以刪除單筆或多筆紀錄 delete from tablename where columnname OPERATOR value [and|or column OPERATOR value] [ ] = optional Examples delete from employee Note 如果你沒有指定 where 子句那麼全部的紀錄都會被刪除 delete from employee where lastname = May delete from employee where firstname = Mike or firstname = Eric delete from 接著資料表名 再接著是條件式判斷沒有條件式則全部紀錄會

被刪除

如何更新資料

update 用來更新你所指定的記錄要和 WHERE 配合小心使用 語法 update tablename set columnname = newvalue[nextcolumn = newvalue2] where columnname OPERATOR value [and|or column OPERATOR value] [] = optional Examples

89

update phone_book set area_code = 623 where prefix = 979 update phone_book set last_name = Smith prefix=555 suffix=9292 where last_name = Jones update employee set age = age+1 where first_name=Mary and last_name=Williams

90

附錄二Replication

測試環境

RedHat 90 + MySQL 32358 MySQL資料庫路徑 varlibmysql MySQL設定檔 etcmycnf Master IP 1921680100 Slave IP 1921680200 請至下列網址下載最新MySQL 32358套件並利用rpm ndashUvh 更新 httpupdatesredhatcom9enosi386

圖 最新 MySQL 套件

測試架構圖

91

1921680100

1921680200Master Server

erveSlave S r

圖 測試架構圖

測試步驟

Master server 部份 Step1 確認 MasterSlave機器上所裝的 MySQL版本能進行

replication( 32329 or higher ) Step2 在 Master MySQL上開放一個帳號給 Slave mysql ndashu root ndashp mysqlgtGRANT FILE ON TO repl1921680200 IDENTIFIED BY lsquoabc123rsquo mysqlgtq 上面是 Master開放一個帳號 repl密碼 abc123給 IP1921680200有檔案處理

的權限 Step3 shutdown MySQL on the Master mysqladmin ndashu root ndashp shutdown Step4 備份 Master所有資料庫 tar ndashcvf tmpmysql-snapshottar varlibmysql 注意tar的時候MySQL是要在 stop情況下 在mysql (wwwmysqlcom) 網站的FAQ有不用shutdown的方法

92

Step5 在 master機器上修改etcmycnf 在[mysqld]區段內加入參數 log-bin server-id=這邊設定 server-id=1 sql-bin-update-same binlog-do-db=CRM只針對 CRM資料庫做紀錄 Step6 Restart MySQL on the master service mysqld start 此時因為有加入 log-bin 參數因此開始有 index產生了在varlibmysql目錄下

有index檔案紀錄資料庫的異動 log Slave server 部份 Step1 在 slave設定etcmycnf 在[mysqld]區段加入 master-host= master-user= master-password= master-port= server-id= 這邊設定 master-host=1921680100 master-user=repl master-password=abc123 master-port=3306 server-id=2 master-connect-retry=60預設重試間隔 60秒 replicate-do-db=CRM告訴 slave只做 CRM資料庫的更新 log-slave-updates Step2 將 master上的 mysql-snapshottar copy到 slave上 用 ftp傳到 slave的tmp Step3 解壓縮 Master資料庫至 Slave Server上 cd varlib tar xvf tmpmysql-snapshottar chown ndashR mysqlmysql mysql

93

chmod ndashR 770 mysql (視情況) Step4 Restart MySQL on the slave server 這時在varlibmysql目錄會出現 masterinfo此檔案紀錄了 Master MySQL server的資訊

狀況測試

One-way replication

1921680100

1921680200Master Server

erveSlave S r

圖 One-way replication架構圖 Step1 Master跟 Slave網路及服務都正常情況下由 Master端異動資料後 到 Slave端瀏覽資料檢視是否有進行 replication Step2 模擬 Slave Server 當機 可用在於 slave真的當機或是 Slave 不一定需要一直跟 master connect將Slave MySQL server shutdown由 Master端異動資料到 slave端瀏覽此時Slave應該沒有被 replication 更新然後再將 Slave端 MySQL server start起來

預設 60秒後 Slave會嘗試跟 Master要求進行 replication再去 Slave端檢視是否有更新資料

94

Step3 模擬 Master當機因為是設定 One-way replication一旦 Master Server Slave端沒有 Master的 source可以 download Two-way replication 基於 Master當機狀況於是發展雙向 Replication即 1921680100 ( Host A ) 1921680200 ( Host B )都分別擔任 MasterSlave身分

1921680100

1921680200er

Server B MasterSlave Server

Server A MasterSlave Serv

圖 Two-way replication架構圖 以下是針對兩台 MySQL伺服器進行雙向 Replication Step1觀念同單向 replication只是改成 Master也有 Slave身分 Slave也有Master的身分先分別在 Server AServer B 都去 grant一個進行 replication的身分 [A]mysqlgtGRANT FILE ON TO repl1921680200 IDENTIFIED BY lsquoabc123rsquo [B]mysqlgt GRANT FILE ON TO repl1921680100 IDENTIFIED BY lsquoabc123rsquo Step2做完單向 replication後stop Server Aserver B MySQL service此時 AB資料是一樣的

95

修改etcmycnf設定 範例 Server A [mysqld] datadir=varlibmysql socket=varlibmysqlmysqlsock server-id=1 log-bin sql-bin-update-same binlog-do-db=CRM master-host=1921680200 master-user=repl master-password=abc123 log-slave-updates master-connect-retry=60 replicate-do-db=CRM Server B [mysqld] datadir=varlibmysql socket=varlibmysqlmysqlsock server-id=2 log-bin sql-bin-update-same binlog-do-db=CRM master-host=1921680100 master-user=repl master-password=abc123 log-slave-updates master-connect-retry=60 replicate-do-db=CRM 分別 start Server AServer B MySQL後此時雙方都是 MasterSlave身分一旦哪一方資料異動就會通知對方來 replication-若 replication失效則必須將Server AServer B的masterinfo及index00x 都砍掉然後分別 restart MySQL server進行測試檢視成果 實務上通常如果需要做Two-way replication通常會搭配Virtual Server使用

96

在前端架設一台Virtual Server不過此部份不在此份SOP討論範圍內有興趣

的讀者可參考 httpwwwlinuxvirtualserverorg 網站

1921680100 1921680200

Host A MasterSlave Server

Host B MasterSlave Server

Virtual Host

圖 Virtual Server + Two-way replication 架構圖

97

圖 High Availability Linux Virtual Server架構圖

98

  • COSA-SOP-03-006
  • 第一章 簡介
    • 11適用對象 (Audience)
    • 12 MySQL本身
    • 13 MySQL 40版跟50版重大的改進功能
    • 14 各家資料庫軟體比較
      • 第二章 前置需求
      • 第三章 安裝
        • 31 MySQL安裝
        • 32 phpMyAdmin安裝
        • 33 升級及注意事項
          • 第四章 MySQL管理
            • 41 Webmin 管理介面
            • 42 phpMyAdmin 的操作介面
            • 43管理指令介紹
              • 431 利用mysqladmin設定root的密碼
                  • 第五章 實用範例
                    • 51 任務一Web Base客戶通訊錄
                    • 52 任務二Web Base群組軟體 ( twig )
                      • 第六章 維護及更新程序
                        • 61 日常維護
                        • 62 更新程序
                        • 63 備份重要檔案
                        • 64 離線備份與還原
                        • 65 線上備份與還原
                          • 第七章 問題與解答
                          • 第八章 參考資料
                          • 附錄一 SQL Command 介紹
                          • 附錄二Replication
Page 14: DataBase Server Standard Operation Procedureebooks.lib.ntu.edu.tw/1_file/oss/63/93doc4-5.pdf · 業務的公司帶來了不少壓力,譬如微軟,甲骨文 ... 外的錢用在第三方的資料庫產品上,譬如就可以不用再購買甲骨文公司

圖 3-4

啟動 MySQL ( WebMin 介面 ) 我們也可以利用WebMin 來啟動 MySQL步驟如下 Step 1登入Webmin

圖 3-5 登入WebMin

Step 2 選擇伺服器

14

圖 3-6 伺服器畫面

Step 2 選擇 MySQL資料庫伺服器

圖 3-7 伺服器畫面

15

Step 3 啟動 MySQL資料庫伺服器

圖 3-8 啟動 MySQL

更改資料庫管理者密碼

成功啟動 MySQL後因為資料庫管理者預設沒有密碼建議使用前更改系

統管理者密碼請輸入下列指令

mysqladmin ndashu root ndashh cosaexamplecom password lsquo1234rsquo -u 表示使用者帳號root 為 MySQL預設的管理帳號

-h 表示 MySQL主機的主機名稱也可使用 IP Address password 表示使用者的密碼因為字串請使用單引號將密碼括起來

圖 3-9 修改 MySQL 的密碼

16

32 phpMyAdmin安裝

本書除了會介紹利用當今 Linux上最紅的整合管理工具Webmin 來管理

MySQL外還會為各位介紹專門管理 MySQL的工具 phpMyAdmin phpMyAdmin是免費的 PHP原始程式碼的Web網站可用來管理整個

MySQL伺服器這是一套Web介面的 MySQL管理程式支援中文的使用者介

面 phpMyAdmin只需透過瀏覽器就可管理 MySQL伺服器換句話說不論

MySQL是安裝在 Linux或是Windows 作業系統都可以使用相同步驟在

MySQL上建立資料庫(Database)資料表(Table)和編輯紀錄(Record) Step 1 下載phpMyAdmin ( httpwwwphpmyadminnet )選擇最櫎新穩定的版

本 253

圖 3-10 httpwwwphpmyadminnet

17

圖 3-11 下載 phpMyAdmin-253-phptarbz2

Step 2 將 phpMyAdmin-253-phptarbz2收至 tmp 並執行下列指令將其解壓

縮至varwww tar jxvf phpMyAdmin-253-phptarbz ndashC varwwwhtml

圖 3-12 解壓縮安裝 phpMyadmin-253

Step 3 為了操作方便起見建立 Soft link ln ndashs phpMyAdmin-253 phpMyAdmin

圖 3-13 修改 phpMyadmin 設定檔 configincphp

18

Step 4 修改 phpMyadmin 設定檔 configincphp gedit varwwwhtmlphpMyAdminconfigincphp

圖 3-14 configincphp設定檔

Step 5 設定顯示行號以方便修改 configincphp 設定檔

19

圖 3-15 顯示行號

Step 6 修改下列設定 第 39 行 設定 phpMyAdmin的 URL 第 69 行 MySQL Server 的 ip 第 80 行 利用何帳號存取 MySQL 第 81 行 如果 root有設定 password此處即填入 root的 password

30 In most cases you can leave this variable empty as the correct value

31 will be detected automatically However we recommend that you do

32 test to see that the auto-detection code works in your system A good

33 test is to browse a table then edit a row and save it There will be

34 an error message if phpMyAdmin cannot auto-detect the correct value

35

36 If the auto-detection code does work properly you can set to TRUE the

37 $cfg[PmaAbsoluteUri_DisableWarning] variable below

38

39 $cfg[PmaAbsoluteUri] = httpossccosaorgtwphpMyAdmin

hellip

20

hellip

69 $cfg[Servers][$i][host] = localhost MySQL hostname or IP address hellip 80 $cfg[Servers][$i][user] = root MySQL user

81 $cfg[Servers][$i][password] = 1234 MySQL password (only needed

圖 3-16 修改 configincphp

21

圖 3-17 修改 configincphp

圖 3-18 修改 configincphp p

Step 7 設定語系

22

圖 3-19 設定語系

圖 3-20 執行 phpMyAdmin

23

33 升級及注意事項

RedHat 90附的 MySQL版本為 323 MySQL所釋出最新穩定版本為

40若是您不想用系統預附的 323請先利用下列移除之前 323的版本

rpm ndashe mysql-devel rpm ndashe mysql-server rpm ndashe mysql --nodeps 然後到下列網址下載您所想要的版本進行安裝在這裏我們用 4014版為例 Step 1 下載相關套件( httpwwwmysqlcomdownloadsmysql-40html )

圖 3-21 Download MySQL 4014 相關 RPM Step 2 利用 rpm 指令安裝

24

圖 3-22 Install MySQL 4014 相關 RPM

圖 3-23 Install MySQL 4014 相關 RPM

Step 3 啟動 MySQL

25

圖 3-24 啟動 MySQL 4014 並修改密碼

26

第四章 MySQL管理

本章將我們介紹利用WebminphpAdminCommand的方式建立一個名為

CONTACT的資料庫內有一個 address的 Table作為我們客戶通訊錄程式使

用的資料庫

41 Webmin 管理介面

412建立資料庫

Step 1 登入Webmin

圖 4-1 登入WebMin

Step 2 點選伺服器

27

圖 4-2 伺服器畫面

Step 3 點選 MySQL資料庫伺服器

圖 4-3 MySQL資料庫伺服器

28

Step 4 建立一個新的資料庫

圖 4-4 建立 MySQL資料庫

Step 5 建立名為 CONTACT的資料庫

29

圖 4-5 指定資料庫名稱

412 建立資料表

假設我們要建立一個名為 address的 Table其結構如下 欄位名稱 資料型態 長度 說明 id INT (自動編號) 連絡人編號 name varchar文字 20 連絡人姓名 tel Varchar文字 15 連絡人電話 Step 1 選擇 CONTACT資料庫

30

圖 4-6 選擇資料庫

Step 2 指定欄位數目

31

圖 4-7 設定欄位數目

Step 3設定表格欄位屬性

圖 3-8 設定表格欄位屬性

Step 4建立表格資料

32

圖 4-9 建立表格資料

圖 4-10 檢視資料

33

圖 4-11 新增資料

圖 4-12

34

圖 4-13

413 使用者管理

接下來我們要利用Webmin 來建立資料庫使用者並給予某些權限 Step1建立使用者

35

圖 4-14 選擇使用者權限

圖 4-15

36

Step2 賦予權限

圖 4-16

Step3 權限列表

37

圖 4-17

38

42 phpMyAdmin 的操作介面

421建立資料庫

Step 填入資料庫名稱並按「建立」

圖 4-18建立資料庫

422 建立資料表

Step1 填入資料表名稱並指定欄位數量 執行

39

圖 4-19填入資料表名稱並指定欄位數量

Step2 設定欄位屬性

圖 4-20設定欄位屬性

40

Step3 phpMyAdmin會產生相關的 SQL Command

圖 4-21 資料表結構及相關 SQL Command

Step4新增 Record

41

圖 4-22

圖 4-23

42

圖 4-24

圖 4-25

43

423使用者管理

Step1建立使用者

圖 4-26

44

圖 4-27

Step2 給予權限

圖 4-28

Step3權限列表

45

圖 4-29

43管理指令介紹

431 利用 mysqladmin設定 root的密碼

當您在Windows 或 Linux 中安裝好 MySQL後系統會自動幫您建立兩個

帳分別是 root 和 匿名者MySQL的 root 跟 Linux 最高權限使用者 root無關MySQL的 root使用者相當於 MS SQL 中的 sa 帳號擁有最高的 Database管理權限但系統預設 MySQL的 root 是不需要密碼所以通常我們一安裝

MySQL後首要任務便是修改 root的密碼 我們可以利用 mysqladmin工具或是直接修改 MySQL內部資料庫的使用者資

料 mysqladmin ndashu root ndashh cosaexamplecom password lsquo1234rsquo

46

-u 表示使用者帳號root 為 MySQL預設的管理帳號

-h 表示 MySQL主機的主機名稱也可使用 IP Address password 表示使用者的密碼因為字串請使用單引號將密碼括起來 密碼設定完成之後還是可以利用 mysqladmin修改密碼但是你必須提供目前的密碼

432 連線 MySQL

mysql -uroot -p密碼 (-p和密碼之間不能有空白) 或 mysql -uroot -p (此方式會在進入後要求密碼) [rootossc phpMyAdmin] mysql -u root -p1234

Welcome to the MySQL monitor Commands end with or g

Your MySQL connection id is 25 to server version 32354

Type help or h for help Type c to clear the buffer

mysqlgt show databases

+----------+

| Database |

+----------+

| mysql |

| test |

+----------+

2 rows in set (000 sec)

mysqlgt exit

Bye

[rootossc phpMyAdmin]

433 建立資料庫

可利用 mysqladmin指令建立 CONTACT資料庫 mysqladmin -u root -p1234 create CONTACT

47

或是利用 mysql指令 [rootossc bluepage] mysql -u root -p1234 Welcome to the MySQL monitor Commands end with or g Your MySQL connection id is 1057 to server version 32354 Type help or h for help Type c to clear the buffer mysqlgt create database CONTACT Query OK 1 row affected (000 sec) mysqlgt show databases +----------+ | Database | +----------+ | CONTACT | | address | | hello | | mysql | | nuke | | test | +----------+ 6 rows in set (000 sec) mysqlgt exit

434 建立資料表

編寫 adresssql內容如下 -- Table structure for table address CREATE TABLE address ( id int(11) NOT NULL auto_increment name varchar(20) NOT NULL default tel varchar(15) NOT NULL default PRIMARY KEY (id) ) TYPE=MyISAM

48

-- Dumping data for table address INSERT INTO address VALUES (1林小明0800016888) INSERT INTO address VALUES (2黃大雄0800016888) INSERT INTO address VALUES (3劉小芬0800024365) 然後執行此 sql script mysql -u root -p1234 CONTACT lt addresssql 或是利 mysql command [rootossc bluepage] mysql -u root -p1234 Welcome to the MySQL monitor Commands end with or g Your MySQL connection id is 1090 to server version 32354 Type help or h for help Type c to clear the buffer mysqlgt use CONTACT Database changed Database changed mysqlgt CREATE TABLE address ( -gt id int(11) NOT NULL auto_increment -gt name varchar(20) NOT NULL default -gt tel varchar(15) NOT NULL default -gt PRIMARY KEY (id) -gt ) TYPE=MyISAM Query OK 0 rows affected (000 sec) mysqlgt INSERT INTO address VALUES (1林小明0800016888) Query OK 1 row affected (000 sec) mysqlgt INSERT INTO address VALUES (2黃大雄0800016888) Query OK 1 row affected (000 sec) mysqlgt INSERT INTO address VALUES (3劉小芬0800024365) Query OK 1 row affected (000 sec) mysqlgt exit Bye

49

第五章 實用範例

51 任務一Web Base客戶通訊錄

任職於開放科技公司的林小明前些日子在最符合成本效益的條件下快

速地完成公司網站的建置老闆因此對小明讚譽有加最近因為公司存放客戶資

料的 SQL Server主機屢遭病毒攻擊加上作業系統本身的問題當機次數頻繁

老闆希望能儘快把公司的客戶通訊錄程式移轉到較穩定的環境上因為此客戶通

訊錄程式最主要給內部人員使用所以介面美觀並不特別要求只求穩定且能快

速得到查詢結果老闆希望在短時間先看到程式的雛型並鍵入資料對其效率

及穩定性進行測試因為上次小明表現突出所以這次不可能的任務自然又落到

小明身上 小明想來想去既然要快速又穩定他而且又不希望所有人都得安裝 Client

程式於是小明決定)捨棄他的舊愛「Delphi+MS SQL」投向新歡「Apache + MySQL + PHP」利用此架構來設計一個簡單實用的Web Base客戶通訊錄程式

511 Web Base客戶通訊錄架構

此程式需要建立 CONTACT的資料庫並建立 adress Tables其結構如下表建立步驟請參考第三章 欄位名稱 資料型態 長度 說明 id INT (自動編號) 連絡人編號 name varchar文字 20 連絡人姓名 tel Varchar文字 15 連絡人電話 Web Base通訊錄共有下列幾個檔案功能如下表

檔案名稱 說明 Indexhtml Web Base通訊錄首頁 addphp 新增連絡人的 php程式 searchphp 尋找連絡人的 php程式 editphp 具有更新及刪除功能的 php程式

50

我們將這些檔案放至varwwwhtmlbluepage (預設無 bluepage目錄)

512 Web Base通訊錄測試

httpwwwopencombluepage 新增資料

圖 5-1 新增連絡人

圖 5-2 填入資料

51

圖 5-3 新增成功

搜尋及異動資料

圖 5-4 搜尋通訊錄

52

圖 5-5 編輯資料

圖 5-6 更新資料

513 程式內容及說明

lt-- 程式範例indexhtml--gt lthtmlgt ltheadgtlttitlegt通訊錄lttitlegtltheadgt ltbodygt ltcentergt

53

lth2gt通訊錄lth2gtlthrgt lta href=indexhtmlgt通訊錄ltagt | lta href=addphpgt新增連絡人ltagt | lta href=searchphpgt搜尋通訊錄ltagt ltcentergt ltbodygt lthtmlgt lt-- 程式範例addphp --gt lthtmlgt ltheadgtlttitlegt新增連絡人lttitlegtltheadgt ltbodygt ltcentergtlth2gt新增連絡人lth2gtltcentergtlthrgt lt 取得欄位資料 if (isset($_POST[Name]) ampamp isset($_POST[Tel]) ) $name = $_POST[Name] $tel = $_POST[Tel] 檢查是否有輸入欄位資料 if ($name = ampamp $tel = ) 建立 SQL字串 $sql = INSERT INTO address (name tel) values( $sql= $name $tel) 建立 MySQL 連結 $link = mysql_connect(localhostroot1234) 選擇資料庫 mysql_select_db(CONTACT) 執行 SQL指令 mysql_query($sql) mysql_close($link) echo ltfont color=redgt新增連絡人成功ltfontgtltbrgt gt ltform action=addphp method=postgt lttable border=0 width=300gt lttrgtlttdgt姓名 lttdgt

54

lttdgtltinput type=text name=Name size=20 maxlength=10gtlttdgtlttrgt lttrgtlttdgt電話 lttdgt lttdgtltinput type=text name=Tel size=20 maxlength=20gtlttdgtlttrgt lttrgtlttd colspan=2 align=centergt ltinput type=submit value=新增連絡人gtlttdgtlttrgt lttablegt ltformgt ltbrgtlta href=indexhtmlgt通訊錄ltagt | lta href=addphpgt新增連絡人ltagt | lta href=searchphpgt搜尋通訊錄ltagt ltbodygt lthtmlgt

lt-- 程式範例searchphp --gt lthtmlgt ltheadgtlttitlegt搜尋通訊錄lttitlegtltheadgt ltbodygt ltcentergtlth2gt搜尋通訊錄lth2gtlthrgt lt if (isset($_POST[Search])) 建立資料庫連結並選定資料庫 $link = mysql_connect(localhostroot1234) mysql_select_db(CONTACT) 建立基本的 SQL字串 $sql = SELECT FROM address 檢查是否輸入姓名 if (chop($_POST[Name]) = ) $name = name LIKE $_POST[Name] else $name = 檢查是否輸入電話號碼 if (chop($_POST[Tel]) = ) $tel = tel LIKE $_POST[Tel] else $tel =

55

if條件組合 SQL字串 if (chop($name) = ampamp chop($tel) = ) $sql= WHERE $name AND $tel elseif (chop($name) = ) 只有姓名 $sql = WHERE $name elseif (chop($tel) = ) 只有電話號碼 $sql = WHERE $tel $sql= ORDER BY name 最後加上排序 $result = mysql_query($sql) 取得欄位數 $total_fields = mysql_num_fields($result) echo lttable border=1gt echo lttrgtlttdgt編號lttdgtlttdgt姓名lttdgtlttdgt電話lttdgtlttd colspan=2gt功能選項lttdgtlttrgt 表格顯示查詢結果 while ($rows = mysql_fetch_array($result MYSQL_NUM)) echo lttrgt for ($i = 0 $i lt $total_fields $i++) echo lttdgt$rows[$i]lttdgt echo lttdgtlta href=editphpaction=editampid= echo $rows[0]gtltbgt編輯ltbgtlttdgt echo lttdgtlta href=editphpaction=delampid= echo $rows[0]gtltbgt刪除ltbgtlttdgt echo lttrgt echo lttablegtlthrgt mysql_free_result($result) mysql_close($link) gt ltcentergt ltform action=searchphp method=postgt lttable border=0 width=450gt lttrgtlttdgt搜尋姓名 lttdgt lttdgtltinput type=text name=Name size=10 maxlength=20gtlttdgtlttrgt lttrgtlttdgt搜尋電話 lttdgt lttdgtltinput type=text name=Tel

56

size=20 maxlength=20gtlttdgtlttrgt lttrgtlttd colspan=2 align=centergt ltinput type=submit name=Search value=搜尋gtlttdgtlttrgt lttablegt ltformgt ltbrgtlta href=indexhtmlgt通訊錄ltagt | lta href=addphpgt新增連絡人ltagt | lta href=searchphpgt搜尋通訊錄ltagt ltbodygt lthtmlgt

lt ob_start() gt lt-- 程式範例editphp --gt lthtmlgt ltheadgtlttitlegt編輯通訊錄lttitlegtltheadgt ltbodygt lt 取得 URL 參數 $id = $_GET[id] $action = $_GET[action] 建立資料庫連結 $link = mysql_connect(localhostroot1234) mysql_select_db(CONTACT) 選擇資料庫 執行的操作 switch ($action) case update 更新 取得欄位資料 $name = $_POST[Name] $tel = $_POST[Tel] $sql = UPDATE address SET name=$name tel=$tel WHERE id=$id mysql_query($sql) 執行 SQL指令 mysql_close($link) header(Location searchphp) 轉向到 serachphp break case del 刪除 $sql = DELETE FROM address WHERE id=$id

57

mysql_query($sql) 執行 SQL指令 mysql_close($link) header(Location searchphp) 轉向到 serachphp break case edit 編輯 $sql = SELECT FROM address WHERE id=$id $result = mysql_query($sql) 執行 SQL指令 $row = mysql_fetch_row($result) 取回記錄 $name = $row[1] 取得欄位 name $tel = $row[2] 取得欄位 tel mysql_close($link) 顯示編輯表單 gt ltcentergtlth2gt更新通訊錄lth2gtltcentergtlthrgt ltform action=editphpaction=updateampid=lt echo $id gt method=postgt lttable border=0 width=300gt lttrgtlttdgt姓名 lttdgt lttdgtltinput type=text name=Name size=20 maxlength=10 value=lt echo $name gtgtlttdgtlttrgt lttrgtlttdgt電話 lttdgt lttdgtltinput type=text name=Tel size=20 maxlength=20 value=lt echo $tel gtgtlttdgtlttrgt lttrgtlttd colspan=2 align=centergt ltinput type=submit value=更新連絡人gtlttdgtlttrgt lttablegt ltformgt ltbrgtlta href=indexhtmlgt通訊錄ltagt | lta href=addphpgt新增連絡人ltagt | lta href=searchphpgt搜尋通訊錄ltagt lt break gt ltbodygt lthtmlgt

58

52 任務二Web Base群組軟體 ( twig )

順利完成Web Base客戶通訊錄程式測試一段時間後「Apache + MySQL + PHP」架構的穩定與快速巳深得老闆與公司所有同事的認同隨著公司業績蒸

蒸日上人員組織編罝愈來愈龐大跨部門的會議愈來愈多業務員每日排滿拜

訪客戶的行程跟客戶的 Email的往來也愈來愈頻繁 愈來愈多部門的同事希望公司能建置一套群組軟體提供 web mail可讓業

務人員方便收發 mail還有連絡人議事日程待辦工作書簽等功能讓整個

公司運作及個人時間管理更有效率

老闆問小明對這些需求有什麼看法小明認為如果這些功能完全由程式部

門開發必定曠日費時而且耗費公司資源小明在網路尋找是否有提供這些功能

的Free Software皇天不負苦心人小明發現了TWIG (The Web Information Gateway) httptwigscrewdrivernet這個群組軟體它在 Web 上整合郵件新聞聯絡人議事日程工作序書簽等功能非常符合公司的需求 Step 1 下載 twig-277targz 下載網址 httptwigscrewdrivernetdownloadphp3

Step 2 解開 twig-277targz tar -xzvf twig-277targz

59

Step 3 執行安裝動作安裝到 varwwwhtmltwig 目錄 cd twig-277 twig-install varwwwhtmltwig

Step 4 建立 MySQL 資料庫(twig)及各資料表

cd setup mysql -u root -p1234 mysqlgt create database twig Query OK 1 row affected (001 sec) mysqlgt quit mysql -u root ndashp1234 twiglt twigtablemysql

Step 5 修改 configincphp3 參數設定 vi varwwwhtmltwigconfigconfigincphp3 $config[fromdomain] = opencom 網域 $config[language] = chinesebig5 中文訊息 $config[imap_port] = 143notls

60

Step 6 修改連結 MySQL 的帳號密碼 vi varwwwhtmltwigconfigdbconfigincphp3 $dbconfig[sqlusername] = root username $dbconfig[sqlpassword] = 1234 password

Step 7 其他設定檔

vi etchttpdconfhttpdconf 加入 AddType applicationx-httpd-php php3 在 DirectoryIndex最後加入 indexphp3 DirectoryIndex indexhtml indexhtmlvar indexphp3 在 AddDefaultCharset ISO-8859-1加上 AddDefaultCharset ISO-8859-1

vi etcphpini register_globals = On service httpd restart Step 8 sendmail 設定 vi etcmailsendmailcf在 264 行前面加上並重新啟動 sendmail「service snedmail restart」 262 SMTP daemon options 263 264 O DaemonPortOptions=Port=smtpAddr=127001 Name=MTA 265 266 SMTP client options 267 O ClientPortOptions=Family=inet Address=00

61

Step 9 檢查設定有無錯誤 http主機名稱twigtestphp3

62

Step 10 登入 twig ( http主機名稱twig)

63

第六章 維護及更新程序

61 日常維護

系統管理員最好定期以 root 身份登入看看信件在 RedHat Linux 中有一支 logwatch 程式會定時去分析 log file如果發現異常便會發信給 root除此之外筆者建議讀者平時就檢查 MySQL log file ( varlogmysqldlog)是否有異常情形

62 更新程序

讀者可至httprpmfindnet 尋找MySQL相關套件至於升級的相關步驟請參

考Linux OS SOP 第 54節

63 備份重要檔案

預設 MySQL 的 DB 檔案是存在 varlibmysql 內以 DB名稱為目錄目錄

內就是該 DB 的所有資料通常得定期備份還有 MySQL的設定檔 etcmycnf也別忘了一起備份

64 離線備份與還原

641 離線備份

預設 MySQL 的 DB 檔案是存在 varlibmysql 內以 DB 名稱為目錄目錄內

就是該 DB 的所有資料像 CRM 這個 DB就是存在 varlibmysqlCRM 內在備份前因為怕資料尚未完全寫入磁碟而且 MySQL 會 Lock 在使用的 DB 檔案所以應該是要先把 MySQL 先 Shutdown 一下整個備份的程序可以下像下面的指令去完成 cd varlibmysql

64

service mysqld stop tar cvfz CRM_db_20030905tgz CRM service mysqld start 對這樣就可以了 不過要注意的是怕 DB 內每個 Tables 間的資料有關關

聯性所以最好是把整個 DB 一次備起來單獨只備哪個 Tables 的檔案以後回存時怕會有資料關聯不一致的問題

642 離線還原

DB 發生錯誤而要回存時其實也不難先找出最近一次完整正常的備份先把現在錯誤的網頁或 DB 先更名或 tar 起來再把好的備份給解開回原來目錄位

置就行了需要注意的是 MySQL 服務最好也是要先停止回存完成後再啟動服務回存 DB 的整個程序可能像下面 cd varlibmysql service mysqldstop mv CRM CRM_OLD tar xvfz CRM_db_20030905tg service mysqld start

65 線上備份與還原

651 線上備份

使用像上面的檔案方式備份是個不錯的方法它最少可以保持該主機某個時間點的完整檔案備份但還是有一些問題需要考慮到有些主機就不只建立一個 DB 而已總不能為了備份某個 DB 而把整個 MySQL 服務停止備份檔案的方式回存在原主機上一定適用但假如 MySQL 版本升級或是在那天該網頁空間需遷機移機到別的主機時那就沒人敢保證備出來的資料檔可以用所以我們可以考慮另一種備份的方式是使用 MySQL 本身提供的功能 MySQL Data Dump指令是 mysqldump

65

使用 MySQL 的 Dump 功能可以把 DB 的結構資料或結構加資料 Dump 成文字檔 mysqldump 指令提供的彈性很大你可以選擇把整個 DB Dump 成一個檔或是每個 Table 為一個檔甚至是把結構檔和資料分開儲存都

可以 mysqladmin -uroot -p flush-logs mysqldump CRM -uroot -p --opt gt CRM_20030905sql (CRM 是 DB 名稱 opt 是一個使用完整 Dump 參數) 假如只是要單獨 Dump 某個 Table 時只要在上面的指令後轉出符號 gt 前加個 Table 名稱就可以如只要 phpbb2_users 這個 Table 的 Dump 時只要下 mysqldump CRM -uroot -p --opt CUSTOMER gt CRM_CUSTOMER_20030905sql

652 線上還原

若要回存整個資料庫只需將壓縮的備份檔還原成 Dump 的檔案再用下面的指令回存 mysql CRM -uroot -p lt CRM_20030905sql 這邊需注意的是若建立備份時是以--opt或--add-drop-table為參數時回存的 動作是先將舊的 Table 先刪除重建 Table 的結構後再把 Data 匯入所以回存後所有的資料會回到你當時備份那個時間點因此在回存資料時可以考慮把現有錯誤或不完整的 DB 先備份一份下來以備不時之需或是拿來比對錯誤的地

方在那裡當然你也可以把資料回存到另一個測試用的 DB 內只要把上面指令

的 DB 名稱改成你的測試用 DB 名稱即可 使用這種回存方式 MySQL 服務不需停止也不會動到其他正在使用的 DB 在一些提供 MySQL 服務的虛擬主機可用這種方式作你自己的 DB 備份及回存

66

另外假如你是系統重建或是移機時切需在新的 MySQL 內新建一個空白 DB 後才行作回存的工作你可以用下面的指令建立 mysql -uroot -p -e CREATE DATABASE CRM (上面的 CRM是你要新建的 DB 名稱) 另一種作法先用 mysql 指令進入 mysql client console 然後再用 CREATE DATABASE CRM 這樣就行了記得尾端要加個 符號該行指令才會執行

67

第七章 問題與解答

Q1RedHat 90預附的 MySQL到底有無支援 Transcation機制 Ans MySQL自 32334a之後的 MySQL-Max版本加入 InnoDB的資料庫類型透過

InnoDBMySQL同樣可以進行 COMMIT與 ROLLRACK的動作RedHat 90預附的 MySQL為 32354a-11巳支援 InnoDB的資料庫類型不過必須做以

下設定 1cp usrsharedocmysql-server-32354amy-mediumcnf to etcmycnf 2 vi etcmycnf 將以下設定前的拿掉 innodb_data_home_dir = varlibmysql innodb_data_file_path = ibdata110Mautoextend innodb_log_group_home_dir = varlibmysql innodb_log_arch_dir = varlibmysql 3service mysqld restart 如此一來各位在建立Table時便可指定Table Type為 innodb ( ex create table with type=innodb ) Q2如何解決 php+mysql 許功蓋等字變亂的問題 Ans 方法一 【確定 MySQL 預設的字元集】 1 打開 WinMySQLadmin 管理畫面(在視窗右下角狀態列紅綠燈圖示中按滑鼠

右鍵點選 Show me 選項) 2 點選管理畫面中 [Variables] 標籤選項其中 character_set變數就是您預設

字元集的變數其預設是 latin1 字元集(我們要將他改回 big5)而 chatacters_set 變數則是 MySQL 可以支援哪些字元集 【修改預設字元集變數 character_set 】 1 請點選管理畫面中 [myini Setup] 標籤選項設定 myini 2 按一下 [Pick-up and Edit myini values] 按鈕以便編輯目前的 myini 設定 3 在 [mysqld] 設定區塊底下新增一行 default-character-set = big5 變數設

68

定 4 新增一個 [client] 設定區塊並加入第三步驟的變數設定(游標往下移到空白處新增兩行 [client] 和 default-character-set=big5) 5 按一下畫面左下方 [Save Modification] 按鈕儲存設定 6 重新啟動 MySQL 或 Windows 方法二 Server端注意事項 phpini 中有關的設定為(預設值) Magic quotes for incoming GETPOSTCookie data magic_quotes_gpc = On Use Sybase-style magic quotes (escape with instead of ) magic_quotes_sybase = Off Client端注意事項 1中文資料送進 mysql 前請用 addslashes($str) 處理 2處理後送進 mysql 時請用 括起來並在參數後留一個空白如 $sql = UPDATE ezf_table set tablename=$tname tableend=$endtime table inguser=$tguser tableingid=$tguserid tableallnumber=$tnumber tableloca l=$tablelocal tableanyone=$tableopen tabletext=$ttext WHERE tableid=$t ableid tablename=$tname c 取出時請用 stripslashes($str) Q3MySQL root 密碼忘了該怎麼辦 Ans 1先停掉 mysql etcrcdinitdmysql stop 2以--skip-grant-table 的參數啟動 mysql safe_mysql --skip-grant-tableamp 3 更改 root 密碼 mysql mysql mysqlgt UPDATE user SET password=password(newpassword)

69

WHERE user=root mysqlgt FLUSH PRIVILEGES mysqlgt exit 4停掉 mysql再重跑 mysqladmin -uroot -p shutdown Enter password 輸入新設定的密碼 etcrcdinitdmysql start

Q4NULL值問題

Ans

NULL值的概念是造成 SQL的新手的混淆的普遍原因他們經常認為 NULL是和一個空字符串的一樣的東西不是這樣的例如下列語句是完全不同的

mysqlgt INSERT INTO my_table (phone) VALUES (NULL)

mysqlgt INSERT INTO my_table (phone) VALUES ()

兩個語句把值插入到 phone 列但是第一個插入一個 NULL值而第二個插入一個空字符串第一個的含義可以認為是ldquo電話號碼不知道而第二個則可意味

著ldquo她沒有電話

在 SQL中NULL值在于任何其他值甚至 NULL值比較時總是假的(FALSE)包含 NULL的一個表達式總是產生一個 NULL值除非在包含在表達式中的運算符和函數的文檔中指出在下列例子所有的列返回 NULL

mysqlgt SELECT NULL1+NULLCONCAT(InvisibleNULL)

如果你想要尋找值是 NULL的列你不能使用=NULL測試下列語句不返回任

何行因為對任何表達式expr = NULL是假的

mysqlgt SELECT FROM my_table WHERE phone = NULL

要想尋找 NULL值你必須使用 IS NULL測試下例顯示如何找出 NULL電話號碼和空的電話號碼

70

mysqlgt SELECT FROM my_table WHERE phone IS NULL mysqlgt SELECT FROM my_table WHERE phone =

在 MySQL中就像很多其他的 SQL服務器一樣你不能索引可以有 NULL值的列你必須聲明這樣的列為 NOT NULL而且你不能插入 NULL到索引的

列中

當用 LOAD DATA INFILE 讀取數據時空列用更新如果你想要在一個列中有

NULL值你應該在文本文件中使用N字面上的詞NULL也可以在某些情形下使用

當使用 ORDER BY時首先呈現 NULL值如果你用 DESC以降序排序NULL值最後顯示當使用 GROUP BY時所有的 NULL值被認為是相等的

為了有助于NULL的處理你能使用 IS NULL和 IS NOT NULL運算符和 IFNULL()函數

對某些列類型NULL值被特殊地處理如果你將 NULL插入表的第一個TIMESTAMP 列則插入當前的日期和時間如果你將 NULL插入一個AUTO_INCREMENT 列則插入順序中的下一個數字

Q5如何將圖片存放於 MySQL中

Ans

Step 1建立資料庫 test

Step 2 建立表格 binary_data

CREATE TABLE binary_data (

id INT(4) NOT NULL AUTO_INCREMENT PRIMARY KEY

description CHAR(50)

bin_data LONGBLOB

filename CHAR(50)

filesize CHAR(50)

filetype CHAR(50)

71

)

Step 3 利用 storephp 寫入圖片

storephp 程式碼

ltHTMLgt ltHEADgtltTITLEgtStore binary data into SQL DatabaseltTITLEgtltHEADgt ltBODYgt lt code that will be executed if the form has been submitted

if ($submit) mysql_connect(localhostrootYOUR_PASSWORD) mysql_select_db(test) $data=Base64_Encode(fread(fopen($form_data r) filesize($form_data))) $result=MYSQL_QUERY(INSERT INTO binary_data (descriptionbin_datafilenamefilesizefiletype) VALUES ($form_description$data$form_data_name$form_data_size$form_data_type)) $id= mysql_insert_id() print ltpgtThis file has the following Database ID ltbgt$idltbgt MYSQL_CLOSE() else else show the form to submit new data

gt

ltform method=post action=ltphp echo $PHP_SELF gt enctype=multipartform-datagt File Descriptionltbrgt ltinput type=text name=form_description size=40gt ltINPUT TYPE=hidden name=MAX_FILE_SIZE value=4000000gt ltbrgtFile to uploadstore in databaseltbrgt ltinput type=file name=form_data size=40gt ltpgtltinput type=submit name=submit value=submitgt ltformgt lt

72

gt ltBODYgt ltHTMLgt

Step 3 利用 storephp 取出圖片

getdataphp 程式碼

lt Syntax getdataphp3id=ltidgt if($id) you may have to modify login information for your database server MYSQL_CONNECT(localhostrootYOUR_PASSWORD) mysql_select_db(test) $query = select bin_datafiletype from binary_data where id=$id $result = MYSQL_QUERY($query) $data = Base64_Decode(MYSQL_RESULT($result0bin_data)) $type = MYSQL_RESULT($result0filetype) Header( Content-type $type) echo $data gt

Q6MySQL裝好之後啟動時或是執行 mysqladmin會出現如下訊息 Cant connect to local MYSQL Server through Socket varlibmysqlmysqlsock或是

Cant connect to local MYSQL Server through Socket tmpmysqldsock

Ans 可能有下列幾個原因

1這個 mysqldsock 不見了被某人刪除了或是被一些系統自動執行程式給刪

了例如有些 cron任務便會設定定期刪除 tmp 裡的東西所以呢您只能修改

cron 裡的設定讓它不要清除 mysqldsock 2在啟動時也可以改變 mysqldsock的位置您在啟動 MySQL的時候可以加入此參數usrlocalmysqlbinsafe_mysqld --user=mysql --socket=其他路

徑socket amp 同時得去設定環境變數 MYSQL_UNIX_PORT的值以指定新的

73

路徑 3若是您沒改 MYSQL_UNIX_PORT的值那麼您可以在執行指令的時候才打

例如mysqladmin --socket=其他路徑socket version Q7How to get the last insert id Ans CREATE TABLE product ( id INT(4) NOT NULL AUTO_INCREMENT PRIMARY KEY description VARCHAR(50) ) 1利用 SQL的話 mysqlgt insert into product(description) values(123) Query OK 1 row affected (000 sec) mysqlgt select last_insert_id() +------------------+ | last_insert_id() | +------------------+ +------------------+ 1 row in set (000 sec) ======================================== 2如果是 PHP的話 你可以用mysql_insert_id()取得該 id PHP example $result=MYSQL_QUERY(INSERT INTO product (description) VALUES ($description)) $id= mysql_insert_id() print This file has the following Database ID $id Q8如何將文字檔匯入資料庫 Ans $addr=homehttpdhtmlphpschool001txt $sql_select = load data infile $addr into table test fields terminated by t 解說 $sql_select = load data infile 文字檔名 into table 表格名 fields terminated by

74

t

(欄位分隔以 TAB鍵) 該文字檔須與資料表欄位格式相符 例如欄位有三個 則文字檔為每行一筆資料如下 欄 1資料ltTABgt欄 2資料ltTABgt欄 3資料 欄 1資料ltTABgt欄 2資料ltTABgt欄 3資料 欄 1資料ltTABgt欄 2資料ltTABgt欄 3資料 欄 1資料ltTABgtltTABgt欄 3資料

Q9如何撰寫 MySQL C API Ans Step 1利用文字編輯器撰寫以下程式碼 mysqlcc

include ltstdiohgt

include ltmysqlmysqlhgt

int main (int argc char argv[])

MYSQL mysql

MYSQL_RES res

MYSQL_ROW row

if (argc = 2)

fputs (Usage myc ltdatabasegt stderr)

return 1

if ((mysql_connect(ampmysqllocalhostrootYour_Password)))

fputs (Error connecting stderr)

abort()

75

if (mysql_select_db(ampmysqlargv[1]))

fputs (Error selecting database stderr)

abort()

if (mysql_query(ampmysqlSELECT FROM test_table))

fputs (Error processing query stderr)

abort()

if ((res = mysql_store_result(ampmysql)))

fputs (Error storing results stderr)

abort()

while((row = mysql_fetch_row(res)))

uint i = 0

for (i=0 i lt mysql_num_fields(res) i++)

printf(s row[i])

printf(n)

return 0

Step 2 Compile

gcc -Iusrlocalmysqlinclude -Lusrlocalmysqllibmysql mysqlcc ndashlm -lmysqlclient

(其中 include path與 library path取決於你的 MySQL安裝路徑)

76

如果執行時發生如下 error Run problemerror in loading shared libraries libmysqlclientsoX 將你的 MySQL library path(for exampleusrlocalmysqllibmysql) 加入etcldsoconf and run sbinldconfig -v Q9ASP + MySQL 範例程式 Ans Dim myconn As New ADODBConnection Dim myrs As New Recordset Dim mySQL As String Dim myrows As Long myconnOpen DSN=MyODBCsample mySQL = SELECT from user myrsSource = mySQL Set myrsActiveConnection = myconn myrsCursorLocation = adUseClient myrsOpen myrows = myrsRecordCount myrsClose myconnClose 可參考 httpwwwdwamnetmysqlasp_myodbcasp 有詳細的資料 Q10如何將 MySQL中的資料庫匯出成txt檔 Ans select from TableName into outfile textxls all result fields will seperate by tab

77

第八章 參考資料

英文部份 網址 1 httpwwwmysqlcom MySQL 網站有第一手有關 MySQL的資料 2 httpwwwmysqlcomdocenReplicationhtml 有關 MySQL Replication 的文件 3 httpwwwgeocitiescomsqlhomefaqstore_blobhtml 如何在 MySQL 存放 BLOB的資料 4httpwwwsapdborg 有關 SAP跟 MySQL相關合作的網站 書藉 1 Cooking with MySQL

Paul DuBois has selected sample recipes from the hundreds youll find in his book MySQL

Cookbook In this third and final series of excerpts showcasing these recipes learn how to

compute team standings how to calculate the differences between successive Dec 26

2002 2 Tips for Building Web Database Applications with PHP and MySQL by Hugh E Williams co-author of Web Database Applications with PHP amp MySQL 04042002

3 Managing and Using MySQL 2nd Edition By Tim King George Reese Randy Jay Yarger

4 MySQL Cookbook By Paul DuBoisPublisher OReillyPub Date October 2002

中文部份

78

1 httplinuxtncedutwtechdocmysqlmysql_docmanual_tochtml MySQL 中文手冊 2 httpchenshloxaedutwphpZ_1php PHP+MySQ程式研習設計網站 3 httplinuxtncedutwtechdocbanicdownhtml PHP 4 手冊 4 httpwwwtncedutwadmin_zonephp台南縣教育網網路中心有很多 Linux相關文件 5 httpdobtncedutw網站建置百寶箱有很多 PHP MySQL 相關範例程式 5 httpwwwdbworldcomtw資料庫專家電子雜誌介紹資料庫的重要觀念及名詞

79

附錄一 SQL Command 介紹

SQL (讀音ess-que-el) 是一種結構查詢語法SQL 使用於資料庫交流

傳遞相容於 ANSI (American National Standards Institute) 是一套標準的關聯

式資料庫語言 SQL 語言是執行更新或從資料系統獲取資料一般常見的關聯

資料庫系統都有提供 SQL 如 Oracle Sybase Microsoft SQL Server Access Ingres 等雖然大部份的資料庫都有提供 SQL 但也多提供了自已獨特的語

法造成了不相容的情形但標準基本的語法是相通的如Select Insert Update Delete Create and Drop 每一個系統都有支援

Table相關 Command

Create Table

關聯式資料庫包含有很多元件稱為資料表(tables) 把資料或訊息放在資

料表中 資料表是以不同的名稱做分別資料表由欄列所構成的二維陣列

欄包含欄位名資料型態 及其他可判斷的資訊列是由全部欄位構成一筆一

筆的紀錄 create table 語法用在建立一個新的資料表語法格式如下

create table tablename (column1 data type column2 data type column3 data type)

Format of create table if you were to use optional constraints

create table tablename (column1 data type [constraint] column2 data type [constraint] column3 data type [constraint]) [ ] = optional

Note You may have as many columns as youd like and the constraints are optional

80

Example

create table employee (first varchar(15) last varchar(20) age number(3) address varchar(30) city varchar(20) state varchar(20))

注意建立資料表格式要以括號把前後框住而最後以(分號)做結尾

欄位名不要超過 30個字元長而且不要使用 sql 的關鍵字(如 where select等)而在後面接是型態的宣告(如字串數字日期格式等)

資料型態是來描述欄位的方式如一個欄位Last_Name 是一個姓氏可以使用varchar (可變動長度字串) 資料型態

以下是幾個常見的資料庫型態 char(size) 固定長度字串最長為 255 位元 varchar(size) 變動長度字串最大字元數以 size 來指定 number(size) 數值格式可以是整數也可以是小數最大數字以 size 位數判

斷未指定小數位數由系統內定 date 日期格式 number(sized) 數值格式最大數字以 size 位數判斷d 為小數位數整數位

數為 size-d 位

有何限制當資料表被建立通常有一或數個欄位是要使用來做關聯的功

能 例如unique 限制(唯一值)兩筆記錄不可以相同的值 not null (非空值)該欄位一定要輸入資料不可是空的primary key (主鍵)是每一筆記錄識別的主要方式

Drop a table drop table 刪除資料表(其中的資料也會一併刪除)

drop table tablename

Example

81

drop table 和刪除全部資料是不同的刪除全部資料欄位名稱資訊等還會

存在但刪除資料表會把這一些也一併移除掉

如何查詢資料

Select 基本用法

select 語法是關連式資料庫最常用的部份可以取得你想要的資料這是一個

簡單的範例 select column1[column2etc] from tablename [where condition] [] = optional 在 select 之後所列欄位名則是要顯示的資料部份你可以一一列出各欄位

名或是以 (星號)來代表選擇全部的欄位 from 之後放資料表名稱 where 子句 (選項) 指定要過濾的條件符合者才會顯現 where 可使用的條件運算元 = 等於 gt 大於 lt 小於 gt= 大或等於 lt= 小或等於 ltgt 大相等 LIKE 相似 For example select first last city

82

from empinfo where first LIKE Er 以Er 為開頭的字串就符合要以單引號框住 Or you can specify select first last from empinfo where last LIKE s 最後一字為 S 就符合 select from empinfo where first = Eric 則表示 first name 一定要是 Eric 才可以 範例資料表empinfo 統計函數

MIN 傳回指定欄位最小值

MAX 傳回指定欄位最大值

SUM 傳回指定欄位總和

AVG 傳回指定欄位平均值

COUNT 傳回指定欄位的筆數

COUNT() 傳回資料庫中的總筆數

統計函數使用於資料表中的數值欄位配合 SELECT 語法使用 只用於總結特定單一欄位可以配合 GROUP BY 做篩選但也可以不使用 GROUP BY 語句For example

SELECT AVG(salary) FROM employee

83

傳回全部 salary 平均值

Another example

SELECT AVG(salary) FROM employee WHERE title = Programmer

傳回 salary 平均值條件為 employees 資料表中當 title 等於 Programmer

Example

SELECT Count() FROM employees

傳回 employees 資料表中紀錄總筆數

GROUP BY 語法 SELECT column1 SUM(column2) FROM list-of-tables GROUP BY column-list The GROUP BY 語句可以先以所列的欄位為條件分組排序在一起(可以多欄

位) example 要列出每一個 dept 中最高 salary 值 SELECT max(salary) dept FROM employee GROUP BY dept HAVING 語法

SELECT column1 SUM(column2) FROM list-of-tables GROUP BY column-list HAVING condition

HAVING 子句是 GROUP BY 的一部份用來過濾在 GROUP BY 所選出的資料功能如同 select 命令中 where 條件式一樣只是 HAVING 必需配合 GROUP BY 使用

我們以例子來說明我們要取得每一公司名及每一公司的薪水平均值輸入如下

84

SELECT dept avg(salary) FROM employee GROUP BY dept

但如果我們只列出薪資平均值超過 20000元的公司資料

SELECT dept avg(salary) FROM employee GROUP BY dept HAVING avg(salary) gt 20000

ORDER BY子句語法

SELECT column1 SUM(column2) FROM list-of-tables ORDER BY column-list [ASC | DESC]

[ ] =選項

ORDER BY是一個選項子句當你以排序方式來顯示資料(正向由小到大反向由大到小)以指定的欄位資料做排序

ASC = 正向- 預設值 DESC = 反向排序

For example

SELECT employee_id dept name age salary FROM employee_info WHERE dept = Sales ORDER BY salary

以上列出公司代號公司名銷售員人名年紀及薪資而條件是公司名為 Sales 顯示順序以薪資多少排序(由小到大為預設值)

如果要以多個欄位做排序要以逗號做分隔如下

SELECT employee_id dept name age salary FROM employee_info WHERE dept = Sales ORDER BY salary age DESC

85

結合條件及布林運算 SELECT column1 SUM(column2) FROM list-of-tables WHERE condition1 AND condition2 AND運算可以結兩個或以上的條件放在 WHERE子句中 兩者都要為真才

會顯示該筆記錄 OR 運算可以結兩個或以上敘述放在 WHERE子句中只要其中一個為直就

會顯示該筆記錄 For example SELECT employeeid firstname lastname title salary FROM employee_info WHERE salary gt= 5000000 AND title = Programmer 必需要薪資大於等於 50000而且職稱為 Programmer同時符合才會顯示該筆資料 以下以括號括住雖然不是必需的但如此比較容易讀 SELECT employeeid firstname lastname title salary FROM employee_info WHERE (salary gt= 5000000) AND (title = Programmer) 另外範例 SELECT firstname lastname title salary FROM employee_info WHERE (title = Sales) OR (title = Programmer) 條件為只要是 Sales 或 Programmer 職稱的就會被列出 IN and BETWEEN 子句

SELECT column1 SUM(column2) FROM list-of-tables WHERE column3 IN (list-of-values) SELECT column1 SUM(column2) FROM list-of-tables WHERE column3 BETWEEN value1 AND value2 IN 子句使用在列舉項目的使用上也就是分別測試是否符合所列的值 For example

86

SELECT employeeid lastname salary FROM employee_info WHERE lastname IN (Hernandez Jones Roberts Ruiz) 條件為姓氏(astname)要符合 Hernandez Jones Roberts or Ruiz 其中一個才會被傳回 IN運算元也可以使用 OR 的語法來取代如下結果相同 SELECT employeeid lastname salary FROM employee_info WHERE lastname = Hernandez OR lastname = Jones OR lastname = Roberts OR lastname = Ruiz 但使用 IN 句子比較短也比較易懂 你也可以使用 NOT IN 來去掉不要的記錄 BETWEEN 運算元使用在判斷是否存在兩個數值之間 For example SELECT employeeid age lastname salary FROM employee_info WHERE age BETWEEN 30 AND 40 傳回年紀 30歲到 40歲之間的資料(含 30及 40歲者) 相同的也可以使用以下語法來達到相同的結果 SELECT employeeid age lastname salary FROM employee_info WHERE age gt= 30 AND age lt= 40 你也可使用 NOT BETWEEN 來濾掉中間值的資料 數學運算 標準 ANSI SQL-92 提供以下運算

87

+ 加

- 減

餘數

餘數為除法後剩整數這不在標準的 ANSI SQL 中但大部份的資料庫都會支

援這運算元以下列出有用的函數雖不在 ANSI SQL-92 提供但一般資料庫

也會支援他們

ABS(x) 傳回 x 絕對值

SIGN(x) returns the sign of input x as -1 0 or 1 (negative zero or positive respectively)

MOD(xy) 餘數 - returns the integer remainder of x divided by y (同 xy)

FLOOR(x) 傳回小或等於 x 的最大整數值

CEILING(x) or CEIL(x)

傳回大或等於 x 的最小整數值

POWER(xy) x的 y 次方

ROUND(x) 把 x 四捨五入為整數

ROUND(xd) 四捨五入取到小數 d 位

SQRT(x) x 開平方

For example SELECT round(salary) firstname FROM employee_info 傳回薪資取到整數位

如何新增資料

insert 加入一筆新紀錄到資料表中 insert into tablename (first_columnlast_column) values (first_valuelast_value) [] = optional Example insert into employee

88

(first last age address city state) values (Luke Duke 45 2130 Boars Nest Hazard Co Georgia) Note 字串要以單引號住如string 數字框住也無妨 insert into 後面接資料表名稱再接以括號括住的欄位名在 values 後括號分別對映各欄位的值 以上的例子新增了一筆名(first) 為 Luke而住所(state) 為 Georgia 的資料

如何刪除資料

delete 可以刪除單筆或多筆紀錄 delete from tablename where columnname OPERATOR value [and|or column OPERATOR value] [ ] = optional Examples delete from employee Note 如果你沒有指定 where 子句那麼全部的紀錄都會被刪除 delete from employee where lastname = May delete from employee where firstname = Mike or firstname = Eric delete from 接著資料表名 再接著是條件式判斷沒有條件式則全部紀錄會

被刪除

如何更新資料

update 用來更新你所指定的記錄要和 WHERE 配合小心使用 語法 update tablename set columnname = newvalue[nextcolumn = newvalue2] where columnname OPERATOR value [and|or column OPERATOR value] [] = optional Examples

89

update phone_book set area_code = 623 where prefix = 979 update phone_book set last_name = Smith prefix=555 suffix=9292 where last_name = Jones update employee set age = age+1 where first_name=Mary and last_name=Williams

90

附錄二Replication

測試環境

RedHat 90 + MySQL 32358 MySQL資料庫路徑 varlibmysql MySQL設定檔 etcmycnf Master IP 1921680100 Slave IP 1921680200 請至下列網址下載最新MySQL 32358套件並利用rpm ndashUvh 更新 httpupdatesredhatcom9enosi386

圖 最新 MySQL 套件

測試架構圖

91

1921680100

1921680200Master Server

erveSlave S r

圖 測試架構圖

測試步驟

Master server 部份 Step1 確認 MasterSlave機器上所裝的 MySQL版本能進行

replication( 32329 or higher ) Step2 在 Master MySQL上開放一個帳號給 Slave mysql ndashu root ndashp mysqlgtGRANT FILE ON TO repl1921680200 IDENTIFIED BY lsquoabc123rsquo mysqlgtq 上面是 Master開放一個帳號 repl密碼 abc123給 IP1921680200有檔案處理

的權限 Step3 shutdown MySQL on the Master mysqladmin ndashu root ndashp shutdown Step4 備份 Master所有資料庫 tar ndashcvf tmpmysql-snapshottar varlibmysql 注意tar的時候MySQL是要在 stop情況下 在mysql (wwwmysqlcom) 網站的FAQ有不用shutdown的方法

92

Step5 在 master機器上修改etcmycnf 在[mysqld]區段內加入參數 log-bin server-id=這邊設定 server-id=1 sql-bin-update-same binlog-do-db=CRM只針對 CRM資料庫做紀錄 Step6 Restart MySQL on the master service mysqld start 此時因為有加入 log-bin 參數因此開始有 index產生了在varlibmysql目錄下

有index檔案紀錄資料庫的異動 log Slave server 部份 Step1 在 slave設定etcmycnf 在[mysqld]區段加入 master-host= master-user= master-password= master-port= server-id= 這邊設定 master-host=1921680100 master-user=repl master-password=abc123 master-port=3306 server-id=2 master-connect-retry=60預設重試間隔 60秒 replicate-do-db=CRM告訴 slave只做 CRM資料庫的更新 log-slave-updates Step2 將 master上的 mysql-snapshottar copy到 slave上 用 ftp傳到 slave的tmp Step3 解壓縮 Master資料庫至 Slave Server上 cd varlib tar xvf tmpmysql-snapshottar chown ndashR mysqlmysql mysql

93

chmod ndashR 770 mysql (視情況) Step4 Restart MySQL on the slave server 這時在varlibmysql目錄會出現 masterinfo此檔案紀錄了 Master MySQL server的資訊

狀況測試

One-way replication

1921680100

1921680200Master Server

erveSlave S r

圖 One-way replication架構圖 Step1 Master跟 Slave網路及服務都正常情況下由 Master端異動資料後 到 Slave端瀏覽資料檢視是否有進行 replication Step2 模擬 Slave Server 當機 可用在於 slave真的當機或是 Slave 不一定需要一直跟 master connect將Slave MySQL server shutdown由 Master端異動資料到 slave端瀏覽此時Slave應該沒有被 replication 更新然後再將 Slave端 MySQL server start起來

預設 60秒後 Slave會嘗試跟 Master要求進行 replication再去 Slave端檢視是否有更新資料

94

Step3 模擬 Master當機因為是設定 One-way replication一旦 Master Server Slave端沒有 Master的 source可以 download Two-way replication 基於 Master當機狀況於是發展雙向 Replication即 1921680100 ( Host A ) 1921680200 ( Host B )都分別擔任 MasterSlave身分

1921680100

1921680200er

Server B MasterSlave Server

Server A MasterSlave Serv

圖 Two-way replication架構圖 以下是針對兩台 MySQL伺服器進行雙向 Replication Step1觀念同單向 replication只是改成 Master也有 Slave身分 Slave也有Master的身分先分別在 Server AServer B 都去 grant一個進行 replication的身分 [A]mysqlgtGRANT FILE ON TO repl1921680200 IDENTIFIED BY lsquoabc123rsquo [B]mysqlgt GRANT FILE ON TO repl1921680100 IDENTIFIED BY lsquoabc123rsquo Step2做完單向 replication後stop Server Aserver B MySQL service此時 AB資料是一樣的

95

修改etcmycnf設定 範例 Server A [mysqld] datadir=varlibmysql socket=varlibmysqlmysqlsock server-id=1 log-bin sql-bin-update-same binlog-do-db=CRM master-host=1921680200 master-user=repl master-password=abc123 log-slave-updates master-connect-retry=60 replicate-do-db=CRM Server B [mysqld] datadir=varlibmysql socket=varlibmysqlmysqlsock server-id=2 log-bin sql-bin-update-same binlog-do-db=CRM master-host=1921680100 master-user=repl master-password=abc123 log-slave-updates master-connect-retry=60 replicate-do-db=CRM 分別 start Server AServer B MySQL後此時雙方都是 MasterSlave身分一旦哪一方資料異動就會通知對方來 replication-若 replication失效則必須將Server AServer B的masterinfo及index00x 都砍掉然後分別 restart MySQL server進行測試檢視成果 實務上通常如果需要做Two-way replication通常會搭配Virtual Server使用

96

在前端架設一台Virtual Server不過此部份不在此份SOP討論範圍內有興趣

的讀者可參考 httpwwwlinuxvirtualserverorg 網站

1921680100 1921680200

Host A MasterSlave Server

Host B MasterSlave Server

Virtual Host

圖 Virtual Server + Two-way replication 架構圖

97

圖 High Availability Linux Virtual Server架構圖

98

  • COSA-SOP-03-006
  • 第一章 簡介
    • 11適用對象 (Audience)
    • 12 MySQL本身
    • 13 MySQL 40版跟50版重大的改進功能
    • 14 各家資料庫軟體比較
      • 第二章 前置需求
      • 第三章 安裝
        • 31 MySQL安裝
        • 32 phpMyAdmin安裝
        • 33 升級及注意事項
          • 第四章 MySQL管理
            • 41 Webmin 管理介面
            • 42 phpMyAdmin 的操作介面
            • 43管理指令介紹
              • 431 利用mysqladmin設定root的密碼
                  • 第五章 實用範例
                    • 51 任務一Web Base客戶通訊錄
                    • 52 任務二Web Base群組軟體 ( twig )
                      • 第六章 維護及更新程序
                        • 61 日常維護
                        • 62 更新程序
                        • 63 備份重要檔案
                        • 64 離線備份與還原
                        • 65 線上備份與還原
                          • 第七章 問題與解答
                          • 第八章 參考資料
                          • 附錄一 SQL Command 介紹
                          • 附錄二Replication
Page 15: DataBase Server Standard Operation Procedureebooks.lib.ntu.edu.tw/1_file/oss/63/93doc4-5.pdf · 業務的公司帶來了不少壓力,譬如微軟,甲骨文 ... 外的錢用在第三方的資料庫產品上,譬如就可以不用再購買甲骨文公司

圖 3-6 伺服器畫面

Step 2 選擇 MySQL資料庫伺服器

圖 3-7 伺服器畫面

15

Step 3 啟動 MySQL資料庫伺服器

圖 3-8 啟動 MySQL

更改資料庫管理者密碼

成功啟動 MySQL後因為資料庫管理者預設沒有密碼建議使用前更改系

統管理者密碼請輸入下列指令

mysqladmin ndashu root ndashh cosaexamplecom password lsquo1234rsquo -u 表示使用者帳號root 為 MySQL預設的管理帳號

-h 表示 MySQL主機的主機名稱也可使用 IP Address password 表示使用者的密碼因為字串請使用單引號將密碼括起來

圖 3-9 修改 MySQL 的密碼

16

32 phpMyAdmin安裝

本書除了會介紹利用當今 Linux上最紅的整合管理工具Webmin 來管理

MySQL外還會為各位介紹專門管理 MySQL的工具 phpMyAdmin phpMyAdmin是免費的 PHP原始程式碼的Web網站可用來管理整個

MySQL伺服器這是一套Web介面的 MySQL管理程式支援中文的使用者介

面 phpMyAdmin只需透過瀏覽器就可管理 MySQL伺服器換句話說不論

MySQL是安裝在 Linux或是Windows 作業系統都可以使用相同步驟在

MySQL上建立資料庫(Database)資料表(Table)和編輯紀錄(Record) Step 1 下載phpMyAdmin ( httpwwwphpmyadminnet )選擇最櫎新穩定的版

本 253

圖 3-10 httpwwwphpmyadminnet

17

圖 3-11 下載 phpMyAdmin-253-phptarbz2

Step 2 將 phpMyAdmin-253-phptarbz2收至 tmp 並執行下列指令將其解壓

縮至varwww tar jxvf phpMyAdmin-253-phptarbz ndashC varwwwhtml

圖 3-12 解壓縮安裝 phpMyadmin-253

Step 3 為了操作方便起見建立 Soft link ln ndashs phpMyAdmin-253 phpMyAdmin

圖 3-13 修改 phpMyadmin 設定檔 configincphp

18

Step 4 修改 phpMyadmin 設定檔 configincphp gedit varwwwhtmlphpMyAdminconfigincphp

圖 3-14 configincphp設定檔

Step 5 設定顯示行號以方便修改 configincphp 設定檔

19

圖 3-15 顯示行號

Step 6 修改下列設定 第 39 行 設定 phpMyAdmin的 URL 第 69 行 MySQL Server 的 ip 第 80 行 利用何帳號存取 MySQL 第 81 行 如果 root有設定 password此處即填入 root的 password

30 In most cases you can leave this variable empty as the correct value

31 will be detected automatically However we recommend that you do

32 test to see that the auto-detection code works in your system A good

33 test is to browse a table then edit a row and save it There will be

34 an error message if phpMyAdmin cannot auto-detect the correct value

35

36 If the auto-detection code does work properly you can set to TRUE the

37 $cfg[PmaAbsoluteUri_DisableWarning] variable below

38

39 $cfg[PmaAbsoluteUri] = httpossccosaorgtwphpMyAdmin

hellip

20

hellip

69 $cfg[Servers][$i][host] = localhost MySQL hostname or IP address hellip 80 $cfg[Servers][$i][user] = root MySQL user

81 $cfg[Servers][$i][password] = 1234 MySQL password (only needed

圖 3-16 修改 configincphp

21

圖 3-17 修改 configincphp

圖 3-18 修改 configincphp p

Step 7 設定語系

22

圖 3-19 設定語系

圖 3-20 執行 phpMyAdmin

23

33 升級及注意事項

RedHat 90附的 MySQL版本為 323 MySQL所釋出最新穩定版本為

40若是您不想用系統預附的 323請先利用下列移除之前 323的版本

rpm ndashe mysql-devel rpm ndashe mysql-server rpm ndashe mysql --nodeps 然後到下列網址下載您所想要的版本進行安裝在這裏我們用 4014版為例 Step 1 下載相關套件( httpwwwmysqlcomdownloadsmysql-40html )

圖 3-21 Download MySQL 4014 相關 RPM Step 2 利用 rpm 指令安裝

24

圖 3-22 Install MySQL 4014 相關 RPM

圖 3-23 Install MySQL 4014 相關 RPM

Step 3 啟動 MySQL

25

圖 3-24 啟動 MySQL 4014 並修改密碼

26

第四章 MySQL管理

本章將我們介紹利用WebminphpAdminCommand的方式建立一個名為

CONTACT的資料庫內有一個 address的 Table作為我們客戶通訊錄程式使

用的資料庫

41 Webmin 管理介面

412建立資料庫

Step 1 登入Webmin

圖 4-1 登入WebMin

Step 2 點選伺服器

27

圖 4-2 伺服器畫面

Step 3 點選 MySQL資料庫伺服器

圖 4-3 MySQL資料庫伺服器

28

Step 4 建立一個新的資料庫

圖 4-4 建立 MySQL資料庫

Step 5 建立名為 CONTACT的資料庫

29

圖 4-5 指定資料庫名稱

412 建立資料表

假設我們要建立一個名為 address的 Table其結構如下 欄位名稱 資料型態 長度 說明 id INT (自動編號) 連絡人編號 name varchar文字 20 連絡人姓名 tel Varchar文字 15 連絡人電話 Step 1 選擇 CONTACT資料庫

30

圖 4-6 選擇資料庫

Step 2 指定欄位數目

31

圖 4-7 設定欄位數目

Step 3設定表格欄位屬性

圖 3-8 設定表格欄位屬性

Step 4建立表格資料

32

圖 4-9 建立表格資料

圖 4-10 檢視資料

33

圖 4-11 新增資料

圖 4-12

34

圖 4-13

413 使用者管理

接下來我們要利用Webmin 來建立資料庫使用者並給予某些權限 Step1建立使用者

35

圖 4-14 選擇使用者權限

圖 4-15

36

Step2 賦予權限

圖 4-16

Step3 權限列表

37

圖 4-17

38

42 phpMyAdmin 的操作介面

421建立資料庫

Step 填入資料庫名稱並按「建立」

圖 4-18建立資料庫

422 建立資料表

Step1 填入資料表名稱並指定欄位數量 執行

39

圖 4-19填入資料表名稱並指定欄位數量

Step2 設定欄位屬性

圖 4-20設定欄位屬性

40

Step3 phpMyAdmin會產生相關的 SQL Command

圖 4-21 資料表結構及相關 SQL Command

Step4新增 Record

41

圖 4-22

圖 4-23

42

圖 4-24

圖 4-25

43

423使用者管理

Step1建立使用者

圖 4-26

44

圖 4-27

Step2 給予權限

圖 4-28

Step3權限列表

45

圖 4-29

43管理指令介紹

431 利用 mysqladmin設定 root的密碼

當您在Windows 或 Linux 中安裝好 MySQL後系統會自動幫您建立兩個

帳分別是 root 和 匿名者MySQL的 root 跟 Linux 最高權限使用者 root無關MySQL的 root使用者相當於 MS SQL 中的 sa 帳號擁有最高的 Database管理權限但系統預設 MySQL的 root 是不需要密碼所以通常我們一安裝

MySQL後首要任務便是修改 root的密碼 我們可以利用 mysqladmin工具或是直接修改 MySQL內部資料庫的使用者資

料 mysqladmin ndashu root ndashh cosaexamplecom password lsquo1234rsquo

46

-u 表示使用者帳號root 為 MySQL預設的管理帳號

-h 表示 MySQL主機的主機名稱也可使用 IP Address password 表示使用者的密碼因為字串請使用單引號將密碼括起來 密碼設定完成之後還是可以利用 mysqladmin修改密碼但是你必須提供目前的密碼

432 連線 MySQL

mysql -uroot -p密碼 (-p和密碼之間不能有空白) 或 mysql -uroot -p (此方式會在進入後要求密碼) [rootossc phpMyAdmin] mysql -u root -p1234

Welcome to the MySQL monitor Commands end with or g

Your MySQL connection id is 25 to server version 32354

Type help or h for help Type c to clear the buffer

mysqlgt show databases

+----------+

| Database |

+----------+

| mysql |

| test |

+----------+

2 rows in set (000 sec)

mysqlgt exit

Bye

[rootossc phpMyAdmin]

433 建立資料庫

可利用 mysqladmin指令建立 CONTACT資料庫 mysqladmin -u root -p1234 create CONTACT

47

或是利用 mysql指令 [rootossc bluepage] mysql -u root -p1234 Welcome to the MySQL monitor Commands end with or g Your MySQL connection id is 1057 to server version 32354 Type help or h for help Type c to clear the buffer mysqlgt create database CONTACT Query OK 1 row affected (000 sec) mysqlgt show databases +----------+ | Database | +----------+ | CONTACT | | address | | hello | | mysql | | nuke | | test | +----------+ 6 rows in set (000 sec) mysqlgt exit

434 建立資料表

編寫 adresssql內容如下 -- Table structure for table address CREATE TABLE address ( id int(11) NOT NULL auto_increment name varchar(20) NOT NULL default tel varchar(15) NOT NULL default PRIMARY KEY (id) ) TYPE=MyISAM

48

-- Dumping data for table address INSERT INTO address VALUES (1林小明0800016888) INSERT INTO address VALUES (2黃大雄0800016888) INSERT INTO address VALUES (3劉小芬0800024365) 然後執行此 sql script mysql -u root -p1234 CONTACT lt addresssql 或是利 mysql command [rootossc bluepage] mysql -u root -p1234 Welcome to the MySQL monitor Commands end with or g Your MySQL connection id is 1090 to server version 32354 Type help or h for help Type c to clear the buffer mysqlgt use CONTACT Database changed Database changed mysqlgt CREATE TABLE address ( -gt id int(11) NOT NULL auto_increment -gt name varchar(20) NOT NULL default -gt tel varchar(15) NOT NULL default -gt PRIMARY KEY (id) -gt ) TYPE=MyISAM Query OK 0 rows affected (000 sec) mysqlgt INSERT INTO address VALUES (1林小明0800016888) Query OK 1 row affected (000 sec) mysqlgt INSERT INTO address VALUES (2黃大雄0800016888) Query OK 1 row affected (000 sec) mysqlgt INSERT INTO address VALUES (3劉小芬0800024365) Query OK 1 row affected (000 sec) mysqlgt exit Bye

49

第五章 實用範例

51 任務一Web Base客戶通訊錄

任職於開放科技公司的林小明前些日子在最符合成本效益的條件下快

速地完成公司網站的建置老闆因此對小明讚譽有加最近因為公司存放客戶資

料的 SQL Server主機屢遭病毒攻擊加上作業系統本身的問題當機次數頻繁

老闆希望能儘快把公司的客戶通訊錄程式移轉到較穩定的環境上因為此客戶通

訊錄程式最主要給內部人員使用所以介面美觀並不特別要求只求穩定且能快

速得到查詢結果老闆希望在短時間先看到程式的雛型並鍵入資料對其效率

及穩定性進行測試因為上次小明表現突出所以這次不可能的任務自然又落到

小明身上 小明想來想去既然要快速又穩定他而且又不希望所有人都得安裝 Client

程式於是小明決定)捨棄他的舊愛「Delphi+MS SQL」投向新歡「Apache + MySQL + PHP」利用此架構來設計一個簡單實用的Web Base客戶通訊錄程式

511 Web Base客戶通訊錄架構

此程式需要建立 CONTACT的資料庫並建立 adress Tables其結構如下表建立步驟請參考第三章 欄位名稱 資料型態 長度 說明 id INT (自動編號) 連絡人編號 name varchar文字 20 連絡人姓名 tel Varchar文字 15 連絡人電話 Web Base通訊錄共有下列幾個檔案功能如下表

檔案名稱 說明 Indexhtml Web Base通訊錄首頁 addphp 新增連絡人的 php程式 searchphp 尋找連絡人的 php程式 editphp 具有更新及刪除功能的 php程式

50

我們將這些檔案放至varwwwhtmlbluepage (預設無 bluepage目錄)

512 Web Base通訊錄測試

httpwwwopencombluepage 新增資料

圖 5-1 新增連絡人

圖 5-2 填入資料

51

圖 5-3 新增成功

搜尋及異動資料

圖 5-4 搜尋通訊錄

52

圖 5-5 編輯資料

圖 5-6 更新資料

513 程式內容及說明

lt-- 程式範例indexhtml--gt lthtmlgt ltheadgtlttitlegt通訊錄lttitlegtltheadgt ltbodygt ltcentergt

53

lth2gt通訊錄lth2gtlthrgt lta href=indexhtmlgt通訊錄ltagt | lta href=addphpgt新增連絡人ltagt | lta href=searchphpgt搜尋通訊錄ltagt ltcentergt ltbodygt lthtmlgt lt-- 程式範例addphp --gt lthtmlgt ltheadgtlttitlegt新增連絡人lttitlegtltheadgt ltbodygt ltcentergtlth2gt新增連絡人lth2gtltcentergtlthrgt lt 取得欄位資料 if (isset($_POST[Name]) ampamp isset($_POST[Tel]) ) $name = $_POST[Name] $tel = $_POST[Tel] 檢查是否有輸入欄位資料 if ($name = ampamp $tel = ) 建立 SQL字串 $sql = INSERT INTO address (name tel) values( $sql= $name $tel) 建立 MySQL 連結 $link = mysql_connect(localhostroot1234) 選擇資料庫 mysql_select_db(CONTACT) 執行 SQL指令 mysql_query($sql) mysql_close($link) echo ltfont color=redgt新增連絡人成功ltfontgtltbrgt gt ltform action=addphp method=postgt lttable border=0 width=300gt lttrgtlttdgt姓名 lttdgt

54

lttdgtltinput type=text name=Name size=20 maxlength=10gtlttdgtlttrgt lttrgtlttdgt電話 lttdgt lttdgtltinput type=text name=Tel size=20 maxlength=20gtlttdgtlttrgt lttrgtlttd colspan=2 align=centergt ltinput type=submit value=新增連絡人gtlttdgtlttrgt lttablegt ltformgt ltbrgtlta href=indexhtmlgt通訊錄ltagt | lta href=addphpgt新增連絡人ltagt | lta href=searchphpgt搜尋通訊錄ltagt ltbodygt lthtmlgt

lt-- 程式範例searchphp --gt lthtmlgt ltheadgtlttitlegt搜尋通訊錄lttitlegtltheadgt ltbodygt ltcentergtlth2gt搜尋通訊錄lth2gtlthrgt lt if (isset($_POST[Search])) 建立資料庫連結並選定資料庫 $link = mysql_connect(localhostroot1234) mysql_select_db(CONTACT) 建立基本的 SQL字串 $sql = SELECT FROM address 檢查是否輸入姓名 if (chop($_POST[Name]) = ) $name = name LIKE $_POST[Name] else $name = 檢查是否輸入電話號碼 if (chop($_POST[Tel]) = ) $tel = tel LIKE $_POST[Tel] else $tel =

55

if條件組合 SQL字串 if (chop($name) = ampamp chop($tel) = ) $sql= WHERE $name AND $tel elseif (chop($name) = ) 只有姓名 $sql = WHERE $name elseif (chop($tel) = ) 只有電話號碼 $sql = WHERE $tel $sql= ORDER BY name 最後加上排序 $result = mysql_query($sql) 取得欄位數 $total_fields = mysql_num_fields($result) echo lttable border=1gt echo lttrgtlttdgt編號lttdgtlttdgt姓名lttdgtlttdgt電話lttdgtlttd colspan=2gt功能選項lttdgtlttrgt 表格顯示查詢結果 while ($rows = mysql_fetch_array($result MYSQL_NUM)) echo lttrgt for ($i = 0 $i lt $total_fields $i++) echo lttdgt$rows[$i]lttdgt echo lttdgtlta href=editphpaction=editampid= echo $rows[0]gtltbgt編輯ltbgtlttdgt echo lttdgtlta href=editphpaction=delampid= echo $rows[0]gtltbgt刪除ltbgtlttdgt echo lttrgt echo lttablegtlthrgt mysql_free_result($result) mysql_close($link) gt ltcentergt ltform action=searchphp method=postgt lttable border=0 width=450gt lttrgtlttdgt搜尋姓名 lttdgt lttdgtltinput type=text name=Name size=10 maxlength=20gtlttdgtlttrgt lttrgtlttdgt搜尋電話 lttdgt lttdgtltinput type=text name=Tel

56

size=20 maxlength=20gtlttdgtlttrgt lttrgtlttd colspan=2 align=centergt ltinput type=submit name=Search value=搜尋gtlttdgtlttrgt lttablegt ltformgt ltbrgtlta href=indexhtmlgt通訊錄ltagt | lta href=addphpgt新增連絡人ltagt | lta href=searchphpgt搜尋通訊錄ltagt ltbodygt lthtmlgt

lt ob_start() gt lt-- 程式範例editphp --gt lthtmlgt ltheadgtlttitlegt編輯通訊錄lttitlegtltheadgt ltbodygt lt 取得 URL 參數 $id = $_GET[id] $action = $_GET[action] 建立資料庫連結 $link = mysql_connect(localhostroot1234) mysql_select_db(CONTACT) 選擇資料庫 執行的操作 switch ($action) case update 更新 取得欄位資料 $name = $_POST[Name] $tel = $_POST[Tel] $sql = UPDATE address SET name=$name tel=$tel WHERE id=$id mysql_query($sql) 執行 SQL指令 mysql_close($link) header(Location searchphp) 轉向到 serachphp break case del 刪除 $sql = DELETE FROM address WHERE id=$id

57

mysql_query($sql) 執行 SQL指令 mysql_close($link) header(Location searchphp) 轉向到 serachphp break case edit 編輯 $sql = SELECT FROM address WHERE id=$id $result = mysql_query($sql) 執行 SQL指令 $row = mysql_fetch_row($result) 取回記錄 $name = $row[1] 取得欄位 name $tel = $row[2] 取得欄位 tel mysql_close($link) 顯示編輯表單 gt ltcentergtlth2gt更新通訊錄lth2gtltcentergtlthrgt ltform action=editphpaction=updateampid=lt echo $id gt method=postgt lttable border=0 width=300gt lttrgtlttdgt姓名 lttdgt lttdgtltinput type=text name=Name size=20 maxlength=10 value=lt echo $name gtgtlttdgtlttrgt lttrgtlttdgt電話 lttdgt lttdgtltinput type=text name=Tel size=20 maxlength=20 value=lt echo $tel gtgtlttdgtlttrgt lttrgtlttd colspan=2 align=centergt ltinput type=submit value=更新連絡人gtlttdgtlttrgt lttablegt ltformgt ltbrgtlta href=indexhtmlgt通訊錄ltagt | lta href=addphpgt新增連絡人ltagt | lta href=searchphpgt搜尋通訊錄ltagt lt break gt ltbodygt lthtmlgt

58

52 任務二Web Base群組軟體 ( twig )

順利完成Web Base客戶通訊錄程式測試一段時間後「Apache + MySQL + PHP」架構的穩定與快速巳深得老闆與公司所有同事的認同隨著公司業績蒸

蒸日上人員組織編罝愈來愈龐大跨部門的會議愈來愈多業務員每日排滿拜

訪客戶的行程跟客戶的 Email的往來也愈來愈頻繁 愈來愈多部門的同事希望公司能建置一套群組軟體提供 web mail可讓業

務人員方便收發 mail還有連絡人議事日程待辦工作書簽等功能讓整個

公司運作及個人時間管理更有效率

老闆問小明對這些需求有什麼看法小明認為如果這些功能完全由程式部

門開發必定曠日費時而且耗費公司資源小明在網路尋找是否有提供這些功能

的Free Software皇天不負苦心人小明發現了TWIG (The Web Information Gateway) httptwigscrewdrivernet這個群組軟體它在 Web 上整合郵件新聞聯絡人議事日程工作序書簽等功能非常符合公司的需求 Step 1 下載 twig-277targz 下載網址 httptwigscrewdrivernetdownloadphp3

Step 2 解開 twig-277targz tar -xzvf twig-277targz

59

Step 3 執行安裝動作安裝到 varwwwhtmltwig 目錄 cd twig-277 twig-install varwwwhtmltwig

Step 4 建立 MySQL 資料庫(twig)及各資料表

cd setup mysql -u root -p1234 mysqlgt create database twig Query OK 1 row affected (001 sec) mysqlgt quit mysql -u root ndashp1234 twiglt twigtablemysql

Step 5 修改 configincphp3 參數設定 vi varwwwhtmltwigconfigconfigincphp3 $config[fromdomain] = opencom 網域 $config[language] = chinesebig5 中文訊息 $config[imap_port] = 143notls

60

Step 6 修改連結 MySQL 的帳號密碼 vi varwwwhtmltwigconfigdbconfigincphp3 $dbconfig[sqlusername] = root username $dbconfig[sqlpassword] = 1234 password

Step 7 其他設定檔

vi etchttpdconfhttpdconf 加入 AddType applicationx-httpd-php php3 在 DirectoryIndex最後加入 indexphp3 DirectoryIndex indexhtml indexhtmlvar indexphp3 在 AddDefaultCharset ISO-8859-1加上 AddDefaultCharset ISO-8859-1

vi etcphpini register_globals = On service httpd restart Step 8 sendmail 設定 vi etcmailsendmailcf在 264 行前面加上並重新啟動 sendmail「service snedmail restart」 262 SMTP daemon options 263 264 O DaemonPortOptions=Port=smtpAddr=127001 Name=MTA 265 266 SMTP client options 267 O ClientPortOptions=Family=inet Address=00

61

Step 9 檢查設定有無錯誤 http主機名稱twigtestphp3

62

Step 10 登入 twig ( http主機名稱twig)

63

第六章 維護及更新程序

61 日常維護

系統管理員最好定期以 root 身份登入看看信件在 RedHat Linux 中有一支 logwatch 程式會定時去分析 log file如果發現異常便會發信給 root除此之外筆者建議讀者平時就檢查 MySQL log file ( varlogmysqldlog)是否有異常情形

62 更新程序

讀者可至httprpmfindnet 尋找MySQL相關套件至於升級的相關步驟請參

考Linux OS SOP 第 54節

63 備份重要檔案

預設 MySQL 的 DB 檔案是存在 varlibmysql 內以 DB名稱為目錄目錄

內就是該 DB 的所有資料通常得定期備份還有 MySQL的設定檔 etcmycnf也別忘了一起備份

64 離線備份與還原

641 離線備份

預設 MySQL 的 DB 檔案是存在 varlibmysql 內以 DB 名稱為目錄目錄內

就是該 DB 的所有資料像 CRM 這個 DB就是存在 varlibmysqlCRM 內在備份前因為怕資料尚未完全寫入磁碟而且 MySQL 會 Lock 在使用的 DB 檔案所以應該是要先把 MySQL 先 Shutdown 一下整個備份的程序可以下像下面的指令去完成 cd varlibmysql

64

service mysqld stop tar cvfz CRM_db_20030905tgz CRM service mysqld start 對這樣就可以了 不過要注意的是怕 DB 內每個 Tables 間的資料有關關

聯性所以最好是把整個 DB 一次備起來單獨只備哪個 Tables 的檔案以後回存時怕會有資料關聯不一致的問題

642 離線還原

DB 發生錯誤而要回存時其實也不難先找出最近一次完整正常的備份先把現在錯誤的網頁或 DB 先更名或 tar 起來再把好的備份給解開回原來目錄位

置就行了需要注意的是 MySQL 服務最好也是要先停止回存完成後再啟動服務回存 DB 的整個程序可能像下面 cd varlibmysql service mysqldstop mv CRM CRM_OLD tar xvfz CRM_db_20030905tg service mysqld start

65 線上備份與還原

651 線上備份

使用像上面的檔案方式備份是個不錯的方法它最少可以保持該主機某個時間點的完整檔案備份但還是有一些問題需要考慮到有些主機就不只建立一個 DB 而已總不能為了備份某個 DB 而把整個 MySQL 服務停止備份檔案的方式回存在原主機上一定適用但假如 MySQL 版本升級或是在那天該網頁空間需遷機移機到別的主機時那就沒人敢保證備出來的資料檔可以用所以我們可以考慮另一種備份的方式是使用 MySQL 本身提供的功能 MySQL Data Dump指令是 mysqldump

65

使用 MySQL 的 Dump 功能可以把 DB 的結構資料或結構加資料 Dump 成文字檔 mysqldump 指令提供的彈性很大你可以選擇把整個 DB Dump 成一個檔或是每個 Table 為一個檔甚至是把結構檔和資料分開儲存都

可以 mysqladmin -uroot -p flush-logs mysqldump CRM -uroot -p --opt gt CRM_20030905sql (CRM 是 DB 名稱 opt 是一個使用完整 Dump 參數) 假如只是要單獨 Dump 某個 Table 時只要在上面的指令後轉出符號 gt 前加個 Table 名稱就可以如只要 phpbb2_users 這個 Table 的 Dump 時只要下 mysqldump CRM -uroot -p --opt CUSTOMER gt CRM_CUSTOMER_20030905sql

652 線上還原

若要回存整個資料庫只需將壓縮的備份檔還原成 Dump 的檔案再用下面的指令回存 mysql CRM -uroot -p lt CRM_20030905sql 這邊需注意的是若建立備份時是以--opt或--add-drop-table為參數時回存的 動作是先將舊的 Table 先刪除重建 Table 的結構後再把 Data 匯入所以回存後所有的資料會回到你當時備份那個時間點因此在回存資料時可以考慮把現有錯誤或不完整的 DB 先備份一份下來以備不時之需或是拿來比對錯誤的地

方在那裡當然你也可以把資料回存到另一個測試用的 DB 內只要把上面指令

的 DB 名稱改成你的測試用 DB 名稱即可 使用這種回存方式 MySQL 服務不需停止也不會動到其他正在使用的 DB 在一些提供 MySQL 服務的虛擬主機可用這種方式作你自己的 DB 備份及回存

66

另外假如你是系統重建或是移機時切需在新的 MySQL 內新建一個空白 DB 後才行作回存的工作你可以用下面的指令建立 mysql -uroot -p -e CREATE DATABASE CRM (上面的 CRM是你要新建的 DB 名稱) 另一種作法先用 mysql 指令進入 mysql client console 然後再用 CREATE DATABASE CRM 這樣就行了記得尾端要加個 符號該行指令才會執行

67

第七章 問題與解答

Q1RedHat 90預附的 MySQL到底有無支援 Transcation機制 Ans MySQL自 32334a之後的 MySQL-Max版本加入 InnoDB的資料庫類型透過

InnoDBMySQL同樣可以進行 COMMIT與 ROLLRACK的動作RedHat 90預附的 MySQL為 32354a-11巳支援 InnoDB的資料庫類型不過必須做以

下設定 1cp usrsharedocmysql-server-32354amy-mediumcnf to etcmycnf 2 vi etcmycnf 將以下設定前的拿掉 innodb_data_home_dir = varlibmysql innodb_data_file_path = ibdata110Mautoextend innodb_log_group_home_dir = varlibmysql innodb_log_arch_dir = varlibmysql 3service mysqld restart 如此一來各位在建立Table時便可指定Table Type為 innodb ( ex create table with type=innodb ) Q2如何解決 php+mysql 許功蓋等字變亂的問題 Ans 方法一 【確定 MySQL 預設的字元集】 1 打開 WinMySQLadmin 管理畫面(在視窗右下角狀態列紅綠燈圖示中按滑鼠

右鍵點選 Show me 選項) 2 點選管理畫面中 [Variables] 標籤選項其中 character_set變數就是您預設

字元集的變數其預設是 latin1 字元集(我們要將他改回 big5)而 chatacters_set 變數則是 MySQL 可以支援哪些字元集 【修改預設字元集變數 character_set 】 1 請點選管理畫面中 [myini Setup] 標籤選項設定 myini 2 按一下 [Pick-up and Edit myini values] 按鈕以便編輯目前的 myini 設定 3 在 [mysqld] 設定區塊底下新增一行 default-character-set = big5 變數設

68

定 4 新增一個 [client] 設定區塊並加入第三步驟的變數設定(游標往下移到空白處新增兩行 [client] 和 default-character-set=big5) 5 按一下畫面左下方 [Save Modification] 按鈕儲存設定 6 重新啟動 MySQL 或 Windows 方法二 Server端注意事項 phpini 中有關的設定為(預設值) Magic quotes for incoming GETPOSTCookie data magic_quotes_gpc = On Use Sybase-style magic quotes (escape with instead of ) magic_quotes_sybase = Off Client端注意事項 1中文資料送進 mysql 前請用 addslashes($str) 處理 2處理後送進 mysql 時請用 括起來並在參數後留一個空白如 $sql = UPDATE ezf_table set tablename=$tname tableend=$endtime table inguser=$tguser tableingid=$tguserid tableallnumber=$tnumber tableloca l=$tablelocal tableanyone=$tableopen tabletext=$ttext WHERE tableid=$t ableid tablename=$tname c 取出時請用 stripslashes($str) Q3MySQL root 密碼忘了該怎麼辦 Ans 1先停掉 mysql etcrcdinitdmysql stop 2以--skip-grant-table 的參數啟動 mysql safe_mysql --skip-grant-tableamp 3 更改 root 密碼 mysql mysql mysqlgt UPDATE user SET password=password(newpassword)

69

WHERE user=root mysqlgt FLUSH PRIVILEGES mysqlgt exit 4停掉 mysql再重跑 mysqladmin -uroot -p shutdown Enter password 輸入新設定的密碼 etcrcdinitdmysql start

Q4NULL值問題

Ans

NULL值的概念是造成 SQL的新手的混淆的普遍原因他們經常認為 NULL是和一個空字符串的一樣的東西不是這樣的例如下列語句是完全不同的

mysqlgt INSERT INTO my_table (phone) VALUES (NULL)

mysqlgt INSERT INTO my_table (phone) VALUES ()

兩個語句把值插入到 phone 列但是第一個插入一個 NULL值而第二個插入一個空字符串第一個的含義可以認為是ldquo電話號碼不知道而第二個則可意味

著ldquo她沒有電話

在 SQL中NULL值在于任何其他值甚至 NULL值比較時總是假的(FALSE)包含 NULL的一個表達式總是產生一個 NULL值除非在包含在表達式中的運算符和函數的文檔中指出在下列例子所有的列返回 NULL

mysqlgt SELECT NULL1+NULLCONCAT(InvisibleNULL)

如果你想要尋找值是 NULL的列你不能使用=NULL測試下列語句不返回任

何行因為對任何表達式expr = NULL是假的

mysqlgt SELECT FROM my_table WHERE phone = NULL

要想尋找 NULL值你必須使用 IS NULL測試下例顯示如何找出 NULL電話號碼和空的電話號碼

70

mysqlgt SELECT FROM my_table WHERE phone IS NULL mysqlgt SELECT FROM my_table WHERE phone =

在 MySQL中就像很多其他的 SQL服務器一樣你不能索引可以有 NULL值的列你必須聲明這樣的列為 NOT NULL而且你不能插入 NULL到索引的

列中

當用 LOAD DATA INFILE 讀取數據時空列用更新如果你想要在一個列中有

NULL值你應該在文本文件中使用N字面上的詞NULL也可以在某些情形下使用

當使用 ORDER BY時首先呈現 NULL值如果你用 DESC以降序排序NULL值最後顯示當使用 GROUP BY時所有的 NULL值被認為是相等的

為了有助于NULL的處理你能使用 IS NULL和 IS NOT NULL運算符和 IFNULL()函數

對某些列類型NULL值被特殊地處理如果你將 NULL插入表的第一個TIMESTAMP 列則插入當前的日期和時間如果你將 NULL插入一個AUTO_INCREMENT 列則插入順序中的下一個數字

Q5如何將圖片存放於 MySQL中

Ans

Step 1建立資料庫 test

Step 2 建立表格 binary_data

CREATE TABLE binary_data (

id INT(4) NOT NULL AUTO_INCREMENT PRIMARY KEY

description CHAR(50)

bin_data LONGBLOB

filename CHAR(50)

filesize CHAR(50)

filetype CHAR(50)

71

)

Step 3 利用 storephp 寫入圖片

storephp 程式碼

ltHTMLgt ltHEADgtltTITLEgtStore binary data into SQL DatabaseltTITLEgtltHEADgt ltBODYgt lt code that will be executed if the form has been submitted

if ($submit) mysql_connect(localhostrootYOUR_PASSWORD) mysql_select_db(test) $data=Base64_Encode(fread(fopen($form_data r) filesize($form_data))) $result=MYSQL_QUERY(INSERT INTO binary_data (descriptionbin_datafilenamefilesizefiletype) VALUES ($form_description$data$form_data_name$form_data_size$form_data_type)) $id= mysql_insert_id() print ltpgtThis file has the following Database ID ltbgt$idltbgt MYSQL_CLOSE() else else show the form to submit new data

gt

ltform method=post action=ltphp echo $PHP_SELF gt enctype=multipartform-datagt File Descriptionltbrgt ltinput type=text name=form_description size=40gt ltINPUT TYPE=hidden name=MAX_FILE_SIZE value=4000000gt ltbrgtFile to uploadstore in databaseltbrgt ltinput type=file name=form_data size=40gt ltpgtltinput type=submit name=submit value=submitgt ltformgt lt

72

gt ltBODYgt ltHTMLgt

Step 3 利用 storephp 取出圖片

getdataphp 程式碼

lt Syntax getdataphp3id=ltidgt if($id) you may have to modify login information for your database server MYSQL_CONNECT(localhostrootYOUR_PASSWORD) mysql_select_db(test) $query = select bin_datafiletype from binary_data where id=$id $result = MYSQL_QUERY($query) $data = Base64_Decode(MYSQL_RESULT($result0bin_data)) $type = MYSQL_RESULT($result0filetype) Header( Content-type $type) echo $data gt

Q6MySQL裝好之後啟動時或是執行 mysqladmin會出現如下訊息 Cant connect to local MYSQL Server through Socket varlibmysqlmysqlsock或是

Cant connect to local MYSQL Server through Socket tmpmysqldsock

Ans 可能有下列幾個原因

1這個 mysqldsock 不見了被某人刪除了或是被一些系統自動執行程式給刪

了例如有些 cron任務便會設定定期刪除 tmp 裡的東西所以呢您只能修改

cron 裡的設定讓它不要清除 mysqldsock 2在啟動時也可以改變 mysqldsock的位置您在啟動 MySQL的時候可以加入此參數usrlocalmysqlbinsafe_mysqld --user=mysql --socket=其他路

徑socket amp 同時得去設定環境變數 MYSQL_UNIX_PORT的值以指定新的

73

路徑 3若是您沒改 MYSQL_UNIX_PORT的值那麼您可以在執行指令的時候才打

例如mysqladmin --socket=其他路徑socket version Q7How to get the last insert id Ans CREATE TABLE product ( id INT(4) NOT NULL AUTO_INCREMENT PRIMARY KEY description VARCHAR(50) ) 1利用 SQL的話 mysqlgt insert into product(description) values(123) Query OK 1 row affected (000 sec) mysqlgt select last_insert_id() +------------------+ | last_insert_id() | +------------------+ +------------------+ 1 row in set (000 sec) ======================================== 2如果是 PHP的話 你可以用mysql_insert_id()取得該 id PHP example $result=MYSQL_QUERY(INSERT INTO product (description) VALUES ($description)) $id= mysql_insert_id() print This file has the following Database ID $id Q8如何將文字檔匯入資料庫 Ans $addr=homehttpdhtmlphpschool001txt $sql_select = load data infile $addr into table test fields terminated by t 解說 $sql_select = load data infile 文字檔名 into table 表格名 fields terminated by

74

t

(欄位分隔以 TAB鍵) 該文字檔須與資料表欄位格式相符 例如欄位有三個 則文字檔為每行一筆資料如下 欄 1資料ltTABgt欄 2資料ltTABgt欄 3資料 欄 1資料ltTABgt欄 2資料ltTABgt欄 3資料 欄 1資料ltTABgt欄 2資料ltTABgt欄 3資料 欄 1資料ltTABgtltTABgt欄 3資料

Q9如何撰寫 MySQL C API Ans Step 1利用文字編輯器撰寫以下程式碼 mysqlcc

include ltstdiohgt

include ltmysqlmysqlhgt

int main (int argc char argv[])

MYSQL mysql

MYSQL_RES res

MYSQL_ROW row

if (argc = 2)

fputs (Usage myc ltdatabasegt stderr)

return 1

if ((mysql_connect(ampmysqllocalhostrootYour_Password)))

fputs (Error connecting stderr)

abort()

75

if (mysql_select_db(ampmysqlargv[1]))

fputs (Error selecting database stderr)

abort()

if (mysql_query(ampmysqlSELECT FROM test_table))

fputs (Error processing query stderr)

abort()

if ((res = mysql_store_result(ampmysql)))

fputs (Error storing results stderr)

abort()

while((row = mysql_fetch_row(res)))

uint i = 0

for (i=0 i lt mysql_num_fields(res) i++)

printf(s row[i])

printf(n)

return 0

Step 2 Compile

gcc -Iusrlocalmysqlinclude -Lusrlocalmysqllibmysql mysqlcc ndashlm -lmysqlclient

(其中 include path與 library path取決於你的 MySQL安裝路徑)

76

如果執行時發生如下 error Run problemerror in loading shared libraries libmysqlclientsoX 將你的 MySQL library path(for exampleusrlocalmysqllibmysql) 加入etcldsoconf and run sbinldconfig -v Q9ASP + MySQL 範例程式 Ans Dim myconn As New ADODBConnection Dim myrs As New Recordset Dim mySQL As String Dim myrows As Long myconnOpen DSN=MyODBCsample mySQL = SELECT from user myrsSource = mySQL Set myrsActiveConnection = myconn myrsCursorLocation = adUseClient myrsOpen myrows = myrsRecordCount myrsClose myconnClose 可參考 httpwwwdwamnetmysqlasp_myodbcasp 有詳細的資料 Q10如何將 MySQL中的資料庫匯出成txt檔 Ans select from TableName into outfile textxls all result fields will seperate by tab

77

第八章 參考資料

英文部份 網址 1 httpwwwmysqlcom MySQL 網站有第一手有關 MySQL的資料 2 httpwwwmysqlcomdocenReplicationhtml 有關 MySQL Replication 的文件 3 httpwwwgeocitiescomsqlhomefaqstore_blobhtml 如何在 MySQL 存放 BLOB的資料 4httpwwwsapdborg 有關 SAP跟 MySQL相關合作的網站 書藉 1 Cooking with MySQL

Paul DuBois has selected sample recipes from the hundreds youll find in his book MySQL

Cookbook In this third and final series of excerpts showcasing these recipes learn how to

compute team standings how to calculate the differences between successive Dec 26

2002 2 Tips for Building Web Database Applications with PHP and MySQL by Hugh E Williams co-author of Web Database Applications with PHP amp MySQL 04042002

3 Managing and Using MySQL 2nd Edition By Tim King George Reese Randy Jay Yarger

4 MySQL Cookbook By Paul DuBoisPublisher OReillyPub Date October 2002

中文部份

78

1 httplinuxtncedutwtechdocmysqlmysql_docmanual_tochtml MySQL 中文手冊 2 httpchenshloxaedutwphpZ_1php PHP+MySQ程式研習設計網站 3 httplinuxtncedutwtechdocbanicdownhtml PHP 4 手冊 4 httpwwwtncedutwadmin_zonephp台南縣教育網網路中心有很多 Linux相關文件 5 httpdobtncedutw網站建置百寶箱有很多 PHP MySQL 相關範例程式 5 httpwwwdbworldcomtw資料庫專家電子雜誌介紹資料庫的重要觀念及名詞

79

附錄一 SQL Command 介紹

SQL (讀音ess-que-el) 是一種結構查詢語法SQL 使用於資料庫交流

傳遞相容於 ANSI (American National Standards Institute) 是一套標準的關聯

式資料庫語言 SQL 語言是執行更新或從資料系統獲取資料一般常見的關聯

資料庫系統都有提供 SQL 如 Oracle Sybase Microsoft SQL Server Access Ingres 等雖然大部份的資料庫都有提供 SQL 但也多提供了自已獨特的語

法造成了不相容的情形但標準基本的語法是相通的如Select Insert Update Delete Create and Drop 每一個系統都有支援

Table相關 Command

Create Table

關聯式資料庫包含有很多元件稱為資料表(tables) 把資料或訊息放在資

料表中 資料表是以不同的名稱做分別資料表由欄列所構成的二維陣列

欄包含欄位名資料型態 及其他可判斷的資訊列是由全部欄位構成一筆一

筆的紀錄 create table 語法用在建立一個新的資料表語法格式如下

create table tablename (column1 data type column2 data type column3 data type)

Format of create table if you were to use optional constraints

create table tablename (column1 data type [constraint] column2 data type [constraint] column3 data type [constraint]) [ ] = optional

Note You may have as many columns as youd like and the constraints are optional

80

Example

create table employee (first varchar(15) last varchar(20) age number(3) address varchar(30) city varchar(20) state varchar(20))

注意建立資料表格式要以括號把前後框住而最後以(分號)做結尾

欄位名不要超過 30個字元長而且不要使用 sql 的關鍵字(如 where select等)而在後面接是型態的宣告(如字串數字日期格式等)

資料型態是來描述欄位的方式如一個欄位Last_Name 是一個姓氏可以使用varchar (可變動長度字串) 資料型態

以下是幾個常見的資料庫型態 char(size) 固定長度字串最長為 255 位元 varchar(size) 變動長度字串最大字元數以 size 來指定 number(size) 數值格式可以是整數也可以是小數最大數字以 size 位數判

斷未指定小數位數由系統內定 date 日期格式 number(sized) 數值格式最大數字以 size 位數判斷d 為小數位數整數位

數為 size-d 位

有何限制當資料表被建立通常有一或數個欄位是要使用來做關聯的功

能 例如unique 限制(唯一值)兩筆記錄不可以相同的值 not null (非空值)該欄位一定要輸入資料不可是空的primary key (主鍵)是每一筆記錄識別的主要方式

Drop a table drop table 刪除資料表(其中的資料也會一併刪除)

drop table tablename

Example

81

drop table 和刪除全部資料是不同的刪除全部資料欄位名稱資訊等還會

存在但刪除資料表會把這一些也一併移除掉

如何查詢資料

Select 基本用法

select 語法是關連式資料庫最常用的部份可以取得你想要的資料這是一個

簡單的範例 select column1[column2etc] from tablename [where condition] [] = optional 在 select 之後所列欄位名則是要顯示的資料部份你可以一一列出各欄位

名或是以 (星號)來代表選擇全部的欄位 from 之後放資料表名稱 where 子句 (選項) 指定要過濾的條件符合者才會顯現 where 可使用的條件運算元 = 等於 gt 大於 lt 小於 gt= 大或等於 lt= 小或等於 ltgt 大相等 LIKE 相似 For example select first last city

82

from empinfo where first LIKE Er 以Er 為開頭的字串就符合要以單引號框住 Or you can specify select first last from empinfo where last LIKE s 最後一字為 S 就符合 select from empinfo where first = Eric 則表示 first name 一定要是 Eric 才可以 範例資料表empinfo 統計函數

MIN 傳回指定欄位最小值

MAX 傳回指定欄位最大值

SUM 傳回指定欄位總和

AVG 傳回指定欄位平均值

COUNT 傳回指定欄位的筆數

COUNT() 傳回資料庫中的總筆數

統計函數使用於資料表中的數值欄位配合 SELECT 語法使用 只用於總結特定單一欄位可以配合 GROUP BY 做篩選但也可以不使用 GROUP BY 語句For example

SELECT AVG(salary) FROM employee

83

傳回全部 salary 平均值

Another example

SELECT AVG(salary) FROM employee WHERE title = Programmer

傳回 salary 平均值條件為 employees 資料表中當 title 等於 Programmer

Example

SELECT Count() FROM employees

傳回 employees 資料表中紀錄總筆數

GROUP BY 語法 SELECT column1 SUM(column2) FROM list-of-tables GROUP BY column-list The GROUP BY 語句可以先以所列的欄位為條件分組排序在一起(可以多欄

位) example 要列出每一個 dept 中最高 salary 值 SELECT max(salary) dept FROM employee GROUP BY dept HAVING 語法

SELECT column1 SUM(column2) FROM list-of-tables GROUP BY column-list HAVING condition

HAVING 子句是 GROUP BY 的一部份用來過濾在 GROUP BY 所選出的資料功能如同 select 命令中 where 條件式一樣只是 HAVING 必需配合 GROUP BY 使用

我們以例子來說明我們要取得每一公司名及每一公司的薪水平均值輸入如下

84

SELECT dept avg(salary) FROM employee GROUP BY dept

但如果我們只列出薪資平均值超過 20000元的公司資料

SELECT dept avg(salary) FROM employee GROUP BY dept HAVING avg(salary) gt 20000

ORDER BY子句語法

SELECT column1 SUM(column2) FROM list-of-tables ORDER BY column-list [ASC | DESC]

[ ] =選項

ORDER BY是一個選項子句當你以排序方式來顯示資料(正向由小到大反向由大到小)以指定的欄位資料做排序

ASC = 正向- 預設值 DESC = 反向排序

For example

SELECT employee_id dept name age salary FROM employee_info WHERE dept = Sales ORDER BY salary

以上列出公司代號公司名銷售員人名年紀及薪資而條件是公司名為 Sales 顯示順序以薪資多少排序(由小到大為預設值)

如果要以多個欄位做排序要以逗號做分隔如下

SELECT employee_id dept name age salary FROM employee_info WHERE dept = Sales ORDER BY salary age DESC

85

結合條件及布林運算 SELECT column1 SUM(column2) FROM list-of-tables WHERE condition1 AND condition2 AND運算可以結兩個或以上的條件放在 WHERE子句中 兩者都要為真才

會顯示該筆記錄 OR 運算可以結兩個或以上敘述放在 WHERE子句中只要其中一個為直就

會顯示該筆記錄 For example SELECT employeeid firstname lastname title salary FROM employee_info WHERE salary gt= 5000000 AND title = Programmer 必需要薪資大於等於 50000而且職稱為 Programmer同時符合才會顯示該筆資料 以下以括號括住雖然不是必需的但如此比較容易讀 SELECT employeeid firstname lastname title salary FROM employee_info WHERE (salary gt= 5000000) AND (title = Programmer) 另外範例 SELECT firstname lastname title salary FROM employee_info WHERE (title = Sales) OR (title = Programmer) 條件為只要是 Sales 或 Programmer 職稱的就會被列出 IN and BETWEEN 子句

SELECT column1 SUM(column2) FROM list-of-tables WHERE column3 IN (list-of-values) SELECT column1 SUM(column2) FROM list-of-tables WHERE column3 BETWEEN value1 AND value2 IN 子句使用在列舉項目的使用上也就是分別測試是否符合所列的值 For example

86

SELECT employeeid lastname salary FROM employee_info WHERE lastname IN (Hernandez Jones Roberts Ruiz) 條件為姓氏(astname)要符合 Hernandez Jones Roberts or Ruiz 其中一個才會被傳回 IN運算元也可以使用 OR 的語法來取代如下結果相同 SELECT employeeid lastname salary FROM employee_info WHERE lastname = Hernandez OR lastname = Jones OR lastname = Roberts OR lastname = Ruiz 但使用 IN 句子比較短也比較易懂 你也可以使用 NOT IN 來去掉不要的記錄 BETWEEN 運算元使用在判斷是否存在兩個數值之間 For example SELECT employeeid age lastname salary FROM employee_info WHERE age BETWEEN 30 AND 40 傳回年紀 30歲到 40歲之間的資料(含 30及 40歲者) 相同的也可以使用以下語法來達到相同的結果 SELECT employeeid age lastname salary FROM employee_info WHERE age gt= 30 AND age lt= 40 你也可使用 NOT BETWEEN 來濾掉中間值的資料 數學運算 標準 ANSI SQL-92 提供以下運算

87

+ 加

- 減

餘數

餘數為除法後剩整數這不在標準的 ANSI SQL 中但大部份的資料庫都會支

援這運算元以下列出有用的函數雖不在 ANSI SQL-92 提供但一般資料庫

也會支援他們

ABS(x) 傳回 x 絕對值

SIGN(x) returns the sign of input x as -1 0 or 1 (negative zero or positive respectively)

MOD(xy) 餘數 - returns the integer remainder of x divided by y (同 xy)

FLOOR(x) 傳回小或等於 x 的最大整數值

CEILING(x) or CEIL(x)

傳回大或等於 x 的最小整數值

POWER(xy) x的 y 次方

ROUND(x) 把 x 四捨五入為整數

ROUND(xd) 四捨五入取到小數 d 位

SQRT(x) x 開平方

For example SELECT round(salary) firstname FROM employee_info 傳回薪資取到整數位

如何新增資料

insert 加入一筆新紀錄到資料表中 insert into tablename (first_columnlast_column) values (first_valuelast_value) [] = optional Example insert into employee

88

(first last age address city state) values (Luke Duke 45 2130 Boars Nest Hazard Co Georgia) Note 字串要以單引號住如string 數字框住也無妨 insert into 後面接資料表名稱再接以括號括住的欄位名在 values 後括號分別對映各欄位的值 以上的例子新增了一筆名(first) 為 Luke而住所(state) 為 Georgia 的資料

如何刪除資料

delete 可以刪除單筆或多筆紀錄 delete from tablename where columnname OPERATOR value [and|or column OPERATOR value] [ ] = optional Examples delete from employee Note 如果你沒有指定 where 子句那麼全部的紀錄都會被刪除 delete from employee where lastname = May delete from employee where firstname = Mike or firstname = Eric delete from 接著資料表名 再接著是條件式判斷沒有條件式則全部紀錄會

被刪除

如何更新資料

update 用來更新你所指定的記錄要和 WHERE 配合小心使用 語法 update tablename set columnname = newvalue[nextcolumn = newvalue2] where columnname OPERATOR value [and|or column OPERATOR value] [] = optional Examples

89

update phone_book set area_code = 623 where prefix = 979 update phone_book set last_name = Smith prefix=555 suffix=9292 where last_name = Jones update employee set age = age+1 where first_name=Mary and last_name=Williams

90

附錄二Replication

測試環境

RedHat 90 + MySQL 32358 MySQL資料庫路徑 varlibmysql MySQL設定檔 etcmycnf Master IP 1921680100 Slave IP 1921680200 請至下列網址下載最新MySQL 32358套件並利用rpm ndashUvh 更新 httpupdatesredhatcom9enosi386

圖 最新 MySQL 套件

測試架構圖

91

1921680100

1921680200Master Server

erveSlave S r

圖 測試架構圖

測試步驟

Master server 部份 Step1 確認 MasterSlave機器上所裝的 MySQL版本能進行

replication( 32329 or higher ) Step2 在 Master MySQL上開放一個帳號給 Slave mysql ndashu root ndashp mysqlgtGRANT FILE ON TO repl1921680200 IDENTIFIED BY lsquoabc123rsquo mysqlgtq 上面是 Master開放一個帳號 repl密碼 abc123給 IP1921680200有檔案處理

的權限 Step3 shutdown MySQL on the Master mysqladmin ndashu root ndashp shutdown Step4 備份 Master所有資料庫 tar ndashcvf tmpmysql-snapshottar varlibmysql 注意tar的時候MySQL是要在 stop情況下 在mysql (wwwmysqlcom) 網站的FAQ有不用shutdown的方法

92

Step5 在 master機器上修改etcmycnf 在[mysqld]區段內加入參數 log-bin server-id=這邊設定 server-id=1 sql-bin-update-same binlog-do-db=CRM只針對 CRM資料庫做紀錄 Step6 Restart MySQL on the master service mysqld start 此時因為有加入 log-bin 參數因此開始有 index產生了在varlibmysql目錄下

有index檔案紀錄資料庫的異動 log Slave server 部份 Step1 在 slave設定etcmycnf 在[mysqld]區段加入 master-host= master-user= master-password= master-port= server-id= 這邊設定 master-host=1921680100 master-user=repl master-password=abc123 master-port=3306 server-id=2 master-connect-retry=60預設重試間隔 60秒 replicate-do-db=CRM告訴 slave只做 CRM資料庫的更新 log-slave-updates Step2 將 master上的 mysql-snapshottar copy到 slave上 用 ftp傳到 slave的tmp Step3 解壓縮 Master資料庫至 Slave Server上 cd varlib tar xvf tmpmysql-snapshottar chown ndashR mysqlmysql mysql

93

chmod ndashR 770 mysql (視情況) Step4 Restart MySQL on the slave server 這時在varlibmysql目錄會出現 masterinfo此檔案紀錄了 Master MySQL server的資訊

狀況測試

One-way replication

1921680100

1921680200Master Server

erveSlave S r

圖 One-way replication架構圖 Step1 Master跟 Slave網路及服務都正常情況下由 Master端異動資料後 到 Slave端瀏覽資料檢視是否有進行 replication Step2 模擬 Slave Server 當機 可用在於 slave真的當機或是 Slave 不一定需要一直跟 master connect將Slave MySQL server shutdown由 Master端異動資料到 slave端瀏覽此時Slave應該沒有被 replication 更新然後再將 Slave端 MySQL server start起來

預設 60秒後 Slave會嘗試跟 Master要求進行 replication再去 Slave端檢視是否有更新資料

94

Step3 模擬 Master當機因為是設定 One-way replication一旦 Master Server Slave端沒有 Master的 source可以 download Two-way replication 基於 Master當機狀況於是發展雙向 Replication即 1921680100 ( Host A ) 1921680200 ( Host B )都分別擔任 MasterSlave身分

1921680100

1921680200er

Server B MasterSlave Server

Server A MasterSlave Serv

圖 Two-way replication架構圖 以下是針對兩台 MySQL伺服器進行雙向 Replication Step1觀念同單向 replication只是改成 Master也有 Slave身分 Slave也有Master的身分先分別在 Server AServer B 都去 grant一個進行 replication的身分 [A]mysqlgtGRANT FILE ON TO repl1921680200 IDENTIFIED BY lsquoabc123rsquo [B]mysqlgt GRANT FILE ON TO repl1921680100 IDENTIFIED BY lsquoabc123rsquo Step2做完單向 replication後stop Server Aserver B MySQL service此時 AB資料是一樣的

95

修改etcmycnf設定 範例 Server A [mysqld] datadir=varlibmysql socket=varlibmysqlmysqlsock server-id=1 log-bin sql-bin-update-same binlog-do-db=CRM master-host=1921680200 master-user=repl master-password=abc123 log-slave-updates master-connect-retry=60 replicate-do-db=CRM Server B [mysqld] datadir=varlibmysql socket=varlibmysqlmysqlsock server-id=2 log-bin sql-bin-update-same binlog-do-db=CRM master-host=1921680100 master-user=repl master-password=abc123 log-slave-updates master-connect-retry=60 replicate-do-db=CRM 分別 start Server AServer B MySQL後此時雙方都是 MasterSlave身分一旦哪一方資料異動就會通知對方來 replication-若 replication失效則必須將Server AServer B的masterinfo及index00x 都砍掉然後分別 restart MySQL server進行測試檢視成果 實務上通常如果需要做Two-way replication通常會搭配Virtual Server使用

96

在前端架設一台Virtual Server不過此部份不在此份SOP討論範圍內有興趣

的讀者可參考 httpwwwlinuxvirtualserverorg 網站

1921680100 1921680200

Host A MasterSlave Server

Host B MasterSlave Server

Virtual Host

圖 Virtual Server + Two-way replication 架構圖

97

圖 High Availability Linux Virtual Server架構圖

98

  • COSA-SOP-03-006
  • 第一章 簡介
    • 11適用對象 (Audience)
    • 12 MySQL本身
    • 13 MySQL 40版跟50版重大的改進功能
    • 14 各家資料庫軟體比較
      • 第二章 前置需求
      • 第三章 安裝
        • 31 MySQL安裝
        • 32 phpMyAdmin安裝
        • 33 升級及注意事項
          • 第四章 MySQL管理
            • 41 Webmin 管理介面
            • 42 phpMyAdmin 的操作介面
            • 43管理指令介紹
              • 431 利用mysqladmin設定root的密碼
                  • 第五章 實用範例
                    • 51 任務一Web Base客戶通訊錄
                    • 52 任務二Web Base群組軟體 ( twig )
                      • 第六章 維護及更新程序
                        • 61 日常維護
                        • 62 更新程序
                        • 63 備份重要檔案
                        • 64 離線備份與還原
                        • 65 線上備份與還原
                          • 第七章 問題與解答
                          • 第八章 參考資料
                          • 附錄一 SQL Command 介紹
                          • 附錄二Replication
Page 16: DataBase Server Standard Operation Procedureebooks.lib.ntu.edu.tw/1_file/oss/63/93doc4-5.pdf · 業務的公司帶來了不少壓力,譬如微軟,甲骨文 ... 外的錢用在第三方的資料庫產品上,譬如就可以不用再購買甲骨文公司

Step 3 啟動 MySQL資料庫伺服器

圖 3-8 啟動 MySQL

更改資料庫管理者密碼

成功啟動 MySQL後因為資料庫管理者預設沒有密碼建議使用前更改系

統管理者密碼請輸入下列指令

mysqladmin ndashu root ndashh cosaexamplecom password lsquo1234rsquo -u 表示使用者帳號root 為 MySQL預設的管理帳號

-h 表示 MySQL主機的主機名稱也可使用 IP Address password 表示使用者的密碼因為字串請使用單引號將密碼括起來

圖 3-9 修改 MySQL 的密碼

16

32 phpMyAdmin安裝

本書除了會介紹利用當今 Linux上最紅的整合管理工具Webmin 來管理

MySQL外還會為各位介紹專門管理 MySQL的工具 phpMyAdmin phpMyAdmin是免費的 PHP原始程式碼的Web網站可用來管理整個

MySQL伺服器這是一套Web介面的 MySQL管理程式支援中文的使用者介

面 phpMyAdmin只需透過瀏覽器就可管理 MySQL伺服器換句話說不論

MySQL是安裝在 Linux或是Windows 作業系統都可以使用相同步驟在

MySQL上建立資料庫(Database)資料表(Table)和編輯紀錄(Record) Step 1 下載phpMyAdmin ( httpwwwphpmyadminnet )選擇最櫎新穩定的版

本 253

圖 3-10 httpwwwphpmyadminnet

17

圖 3-11 下載 phpMyAdmin-253-phptarbz2

Step 2 將 phpMyAdmin-253-phptarbz2收至 tmp 並執行下列指令將其解壓

縮至varwww tar jxvf phpMyAdmin-253-phptarbz ndashC varwwwhtml

圖 3-12 解壓縮安裝 phpMyadmin-253

Step 3 為了操作方便起見建立 Soft link ln ndashs phpMyAdmin-253 phpMyAdmin

圖 3-13 修改 phpMyadmin 設定檔 configincphp

18

Step 4 修改 phpMyadmin 設定檔 configincphp gedit varwwwhtmlphpMyAdminconfigincphp

圖 3-14 configincphp設定檔

Step 5 設定顯示行號以方便修改 configincphp 設定檔

19

圖 3-15 顯示行號

Step 6 修改下列設定 第 39 行 設定 phpMyAdmin的 URL 第 69 行 MySQL Server 的 ip 第 80 行 利用何帳號存取 MySQL 第 81 行 如果 root有設定 password此處即填入 root的 password

30 In most cases you can leave this variable empty as the correct value

31 will be detected automatically However we recommend that you do

32 test to see that the auto-detection code works in your system A good

33 test is to browse a table then edit a row and save it There will be

34 an error message if phpMyAdmin cannot auto-detect the correct value

35

36 If the auto-detection code does work properly you can set to TRUE the

37 $cfg[PmaAbsoluteUri_DisableWarning] variable below

38

39 $cfg[PmaAbsoluteUri] = httpossccosaorgtwphpMyAdmin

hellip

20

hellip

69 $cfg[Servers][$i][host] = localhost MySQL hostname or IP address hellip 80 $cfg[Servers][$i][user] = root MySQL user

81 $cfg[Servers][$i][password] = 1234 MySQL password (only needed

圖 3-16 修改 configincphp

21

圖 3-17 修改 configincphp

圖 3-18 修改 configincphp p

Step 7 設定語系

22

圖 3-19 設定語系

圖 3-20 執行 phpMyAdmin

23

33 升級及注意事項

RedHat 90附的 MySQL版本為 323 MySQL所釋出最新穩定版本為

40若是您不想用系統預附的 323請先利用下列移除之前 323的版本

rpm ndashe mysql-devel rpm ndashe mysql-server rpm ndashe mysql --nodeps 然後到下列網址下載您所想要的版本進行安裝在這裏我們用 4014版為例 Step 1 下載相關套件( httpwwwmysqlcomdownloadsmysql-40html )

圖 3-21 Download MySQL 4014 相關 RPM Step 2 利用 rpm 指令安裝

24

圖 3-22 Install MySQL 4014 相關 RPM

圖 3-23 Install MySQL 4014 相關 RPM

Step 3 啟動 MySQL

25

圖 3-24 啟動 MySQL 4014 並修改密碼

26

第四章 MySQL管理

本章將我們介紹利用WebminphpAdminCommand的方式建立一個名為

CONTACT的資料庫內有一個 address的 Table作為我們客戶通訊錄程式使

用的資料庫

41 Webmin 管理介面

412建立資料庫

Step 1 登入Webmin

圖 4-1 登入WebMin

Step 2 點選伺服器

27

圖 4-2 伺服器畫面

Step 3 點選 MySQL資料庫伺服器

圖 4-3 MySQL資料庫伺服器

28

Step 4 建立一個新的資料庫

圖 4-4 建立 MySQL資料庫

Step 5 建立名為 CONTACT的資料庫

29

圖 4-5 指定資料庫名稱

412 建立資料表

假設我們要建立一個名為 address的 Table其結構如下 欄位名稱 資料型態 長度 說明 id INT (自動編號) 連絡人編號 name varchar文字 20 連絡人姓名 tel Varchar文字 15 連絡人電話 Step 1 選擇 CONTACT資料庫

30

圖 4-6 選擇資料庫

Step 2 指定欄位數目

31

圖 4-7 設定欄位數目

Step 3設定表格欄位屬性

圖 3-8 設定表格欄位屬性

Step 4建立表格資料

32

圖 4-9 建立表格資料

圖 4-10 檢視資料

33

圖 4-11 新增資料

圖 4-12

34

圖 4-13

413 使用者管理

接下來我們要利用Webmin 來建立資料庫使用者並給予某些權限 Step1建立使用者

35

圖 4-14 選擇使用者權限

圖 4-15

36

Step2 賦予權限

圖 4-16

Step3 權限列表

37

圖 4-17

38

42 phpMyAdmin 的操作介面

421建立資料庫

Step 填入資料庫名稱並按「建立」

圖 4-18建立資料庫

422 建立資料表

Step1 填入資料表名稱並指定欄位數量 執行

39

圖 4-19填入資料表名稱並指定欄位數量

Step2 設定欄位屬性

圖 4-20設定欄位屬性

40

Step3 phpMyAdmin會產生相關的 SQL Command

圖 4-21 資料表結構及相關 SQL Command

Step4新增 Record

41

圖 4-22

圖 4-23

42

圖 4-24

圖 4-25

43

423使用者管理

Step1建立使用者

圖 4-26

44

圖 4-27

Step2 給予權限

圖 4-28

Step3權限列表

45

圖 4-29

43管理指令介紹

431 利用 mysqladmin設定 root的密碼

當您在Windows 或 Linux 中安裝好 MySQL後系統會自動幫您建立兩個

帳分別是 root 和 匿名者MySQL的 root 跟 Linux 最高權限使用者 root無關MySQL的 root使用者相當於 MS SQL 中的 sa 帳號擁有最高的 Database管理權限但系統預設 MySQL的 root 是不需要密碼所以通常我們一安裝

MySQL後首要任務便是修改 root的密碼 我們可以利用 mysqladmin工具或是直接修改 MySQL內部資料庫的使用者資

料 mysqladmin ndashu root ndashh cosaexamplecom password lsquo1234rsquo

46

-u 表示使用者帳號root 為 MySQL預設的管理帳號

-h 表示 MySQL主機的主機名稱也可使用 IP Address password 表示使用者的密碼因為字串請使用單引號將密碼括起來 密碼設定完成之後還是可以利用 mysqladmin修改密碼但是你必須提供目前的密碼

432 連線 MySQL

mysql -uroot -p密碼 (-p和密碼之間不能有空白) 或 mysql -uroot -p (此方式會在進入後要求密碼) [rootossc phpMyAdmin] mysql -u root -p1234

Welcome to the MySQL monitor Commands end with or g

Your MySQL connection id is 25 to server version 32354

Type help or h for help Type c to clear the buffer

mysqlgt show databases

+----------+

| Database |

+----------+

| mysql |

| test |

+----------+

2 rows in set (000 sec)

mysqlgt exit

Bye

[rootossc phpMyAdmin]

433 建立資料庫

可利用 mysqladmin指令建立 CONTACT資料庫 mysqladmin -u root -p1234 create CONTACT

47

或是利用 mysql指令 [rootossc bluepage] mysql -u root -p1234 Welcome to the MySQL monitor Commands end with or g Your MySQL connection id is 1057 to server version 32354 Type help or h for help Type c to clear the buffer mysqlgt create database CONTACT Query OK 1 row affected (000 sec) mysqlgt show databases +----------+ | Database | +----------+ | CONTACT | | address | | hello | | mysql | | nuke | | test | +----------+ 6 rows in set (000 sec) mysqlgt exit

434 建立資料表

編寫 adresssql內容如下 -- Table structure for table address CREATE TABLE address ( id int(11) NOT NULL auto_increment name varchar(20) NOT NULL default tel varchar(15) NOT NULL default PRIMARY KEY (id) ) TYPE=MyISAM

48

-- Dumping data for table address INSERT INTO address VALUES (1林小明0800016888) INSERT INTO address VALUES (2黃大雄0800016888) INSERT INTO address VALUES (3劉小芬0800024365) 然後執行此 sql script mysql -u root -p1234 CONTACT lt addresssql 或是利 mysql command [rootossc bluepage] mysql -u root -p1234 Welcome to the MySQL monitor Commands end with or g Your MySQL connection id is 1090 to server version 32354 Type help or h for help Type c to clear the buffer mysqlgt use CONTACT Database changed Database changed mysqlgt CREATE TABLE address ( -gt id int(11) NOT NULL auto_increment -gt name varchar(20) NOT NULL default -gt tel varchar(15) NOT NULL default -gt PRIMARY KEY (id) -gt ) TYPE=MyISAM Query OK 0 rows affected (000 sec) mysqlgt INSERT INTO address VALUES (1林小明0800016888) Query OK 1 row affected (000 sec) mysqlgt INSERT INTO address VALUES (2黃大雄0800016888) Query OK 1 row affected (000 sec) mysqlgt INSERT INTO address VALUES (3劉小芬0800024365) Query OK 1 row affected (000 sec) mysqlgt exit Bye

49

第五章 實用範例

51 任務一Web Base客戶通訊錄

任職於開放科技公司的林小明前些日子在最符合成本效益的條件下快

速地完成公司網站的建置老闆因此對小明讚譽有加最近因為公司存放客戶資

料的 SQL Server主機屢遭病毒攻擊加上作業系統本身的問題當機次數頻繁

老闆希望能儘快把公司的客戶通訊錄程式移轉到較穩定的環境上因為此客戶通

訊錄程式最主要給內部人員使用所以介面美觀並不特別要求只求穩定且能快

速得到查詢結果老闆希望在短時間先看到程式的雛型並鍵入資料對其效率

及穩定性進行測試因為上次小明表現突出所以這次不可能的任務自然又落到

小明身上 小明想來想去既然要快速又穩定他而且又不希望所有人都得安裝 Client

程式於是小明決定)捨棄他的舊愛「Delphi+MS SQL」投向新歡「Apache + MySQL + PHP」利用此架構來設計一個簡單實用的Web Base客戶通訊錄程式

511 Web Base客戶通訊錄架構

此程式需要建立 CONTACT的資料庫並建立 adress Tables其結構如下表建立步驟請參考第三章 欄位名稱 資料型態 長度 說明 id INT (自動編號) 連絡人編號 name varchar文字 20 連絡人姓名 tel Varchar文字 15 連絡人電話 Web Base通訊錄共有下列幾個檔案功能如下表

檔案名稱 說明 Indexhtml Web Base通訊錄首頁 addphp 新增連絡人的 php程式 searchphp 尋找連絡人的 php程式 editphp 具有更新及刪除功能的 php程式

50

我們將這些檔案放至varwwwhtmlbluepage (預設無 bluepage目錄)

512 Web Base通訊錄測試

httpwwwopencombluepage 新增資料

圖 5-1 新增連絡人

圖 5-2 填入資料

51

圖 5-3 新增成功

搜尋及異動資料

圖 5-4 搜尋通訊錄

52

圖 5-5 編輯資料

圖 5-6 更新資料

513 程式內容及說明

lt-- 程式範例indexhtml--gt lthtmlgt ltheadgtlttitlegt通訊錄lttitlegtltheadgt ltbodygt ltcentergt

53

lth2gt通訊錄lth2gtlthrgt lta href=indexhtmlgt通訊錄ltagt | lta href=addphpgt新增連絡人ltagt | lta href=searchphpgt搜尋通訊錄ltagt ltcentergt ltbodygt lthtmlgt lt-- 程式範例addphp --gt lthtmlgt ltheadgtlttitlegt新增連絡人lttitlegtltheadgt ltbodygt ltcentergtlth2gt新增連絡人lth2gtltcentergtlthrgt lt 取得欄位資料 if (isset($_POST[Name]) ampamp isset($_POST[Tel]) ) $name = $_POST[Name] $tel = $_POST[Tel] 檢查是否有輸入欄位資料 if ($name = ampamp $tel = ) 建立 SQL字串 $sql = INSERT INTO address (name tel) values( $sql= $name $tel) 建立 MySQL 連結 $link = mysql_connect(localhostroot1234) 選擇資料庫 mysql_select_db(CONTACT) 執行 SQL指令 mysql_query($sql) mysql_close($link) echo ltfont color=redgt新增連絡人成功ltfontgtltbrgt gt ltform action=addphp method=postgt lttable border=0 width=300gt lttrgtlttdgt姓名 lttdgt

54

lttdgtltinput type=text name=Name size=20 maxlength=10gtlttdgtlttrgt lttrgtlttdgt電話 lttdgt lttdgtltinput type=text name=Tel size=20 maxlength=20gtlttdgtlttrgt lttrgtlttd colspan=2 align=centergt ltinput type=submit value=新增連絡人gtlttdgtlttrgt lttablegt ltformgt ltbrgtlta href=indexhtmlgt通訊錄ltagt | lta href=addphpgt新增連絡人ltagt | lta href=searchphpgt搜尋通訊錄ltagt ltbodygt lthtmlgt

lt-- 程式範例searchphp --gt lthtmlgt ltheadgtlttitlegt搜尋通訊錄lttitlegtltheadgt ltbodygt ltcentergtlth2gt搜尋通訊錄lth2gtlthrgt lt if (isset($_POST[Search])) 建立資料庫連結並選定資料庫 $link = mysql_connect(localhostroot1234) mysql_select_db(CONTACT) 建立基本的 SQL字串 $sql = SELECT FROM address 檢查是否輸入姓名 if (chop($_POST[Name]) = ) $name = name LIKE $_POST[Name] else $name = 檢查是否輸入電話號碼 if (chop($_POST[Tel]) = ) $tel = tel LIKE $_POST[Tel] else $tel =

55

if條件組合 SQL字串 if (chop($name) = ampamp chop($tel) = ) $sql= WHERE $name AND $tel elseif (chop($name) = ) 只有姓名 $sql = WHERE $name elseif (chop($tel) = ) 只有電話號碼 $sql = WHERE $tel $sql= ORDER BY name 最後加上排序 $result = mysql_query($sql) 取得欄位數 $total_fields = mysql_num_fields($result) echo lttable border=1gt echo lttrgtlttdgt編號lttdgtlttdgt姓名lttdgtlttdgt電話lttdgtlttd colspan=2gt功能選項lttdgtlttrgt 表格顯示查詢結果 while ($rows = mysql_fetch_array($result MYSQL_NUM)) echo lttrgt for ($i = 0 $i lt $total_fields $i++) echo lttdgt$rows[$i]lttdgt echo lttdgtlta href=editphpaction=editampid= echo $rows[0]gtltbgt編輯ltbgtlttdgt echo lttdgtlta href=editphpaction=delampid= echo $rows[0]gtltbgt刪除ltbgtlttdgt echo lttrgt echo lttablegtlthrgt mysql_free_result($result) mysql_close($link) gt ltcentergt ltform action=searchphp method=postgt lttable border=0 width=450gt lttrgtlttdgt搜尋姓名 lttdgt lttdgtltinput type=text name=Name size=10 maxlength=20gtlttdgtlttrgt lttrgtlttdgt搜尋電話 lttdgt lttdgtltinput type=text name=Tel

56

size=20 maxlength=20gtlttdgtlttrgt lttrgtlttd colspan=2 align=centergt ltinput type=submit name=Search value=搜尋gtlttdgtlttrgt lttablegt ltformgt ltbrgtlta href=indexhtmlgt通訊錄ltagt | lta href=addphpgt新增連絡人ltagt | lta href=searchphpgt搜尋通訊錄ltagt ltbodygt lthtmlgt

lt ob_start() gt lt-- 程式範例editphp --gt lthtmlgt ltheadgtlttitlegt編輯通訊錄lttitlegtltheadgt ltbodygt lt 取得 URL 參數 $id = $_GET[id] $action = $_GET[action] 建立資料庫連結 $link = mysql_connect(localhostroot1234) mysql_select_db(CONTACT) 選擇資料庫 執行的操作 switch ($action) case update 更新 取得欄位資料 $name = $_POST[Name] $tel = $_POST[Tel] $sql = UPDATE address SET name=$name tel=$tel WHERE id=$id mysql_query($sql) 執行 SQL指令 mysql_close($link) header(Location searchphp) 轉向到 serachphp break case del 刪除 $sql = DELETE FROM address WHERE id=$id

57

mysql_query($sql) 執行 SQL指令 mysql_close($link) header(Location searchphp) 轉向到 serachphp break case edit 編輯 $sql = SELECT FROM address WHERE id=$id $result = mysql_query($sql) 執行 SQL指令 $row = mysql_fetch_row($result) 取回記錄 $name = $row[1] 取得欄位 name $tel = $row[2] 取得欄位 tel mysql_close($link) 顯示編輯表單 gt ltcentergtlth2gt更新通訊錄lth2gtltcentergtlthrgt ltform action=editphpaction=updateampid=lt echo $id gt method=postgt lttable border=0 width=300gt lttrgtlttdgt姓名 lttdgt lttdgtltinput type=text name=Name size=20 maxlength=10 value=lt echo $name gtgtlttdgtlttrgt lttrgtlttdgt電話 lttdgt lttdgtltinput type=text name=Tel size=20 maxlength=20 value=lt echo $tel gtgtlttdgtlttrgt lttrgtlttd colspan=2 align=centergt ltinput type=submit value=更新連絡人gtlttdgtlttrgt lttablegt ltformgt ltbrgtlta href=indexhtmlgt通訊錄ltagt | lta href=addphpgt新增連絡人ltagt | lta href=searchphpgt搜尋通訊錄ltagt lt break gt ltbodygt lthtmlgt

58

52 任務二Web Base群組軟體 ( twig )

順利完成Web Base客戶通訊錄程式測試一段時間後「Apache + MySQL + PHP」架構的穩定與快速巳深得老闆與公司所有同事的認同隨著公司業績蒸

蒸日上人員組織編罝愈來愈龐大跨部門的會議愈來愈多業務員每日排滿拜

訪客戶的行程跟客戶的 Email的往來也愈來愈頻繁 愈來愈多部門的同事希望公司能建置一套群組軟體提供 web mail可讓業

務人員方便收發 mail還有連絡人議事日程待辦工作書簽等功能讓整個

公司運作及個人時間管理更有效率

老闆問小明對這些需求有什麼看法小明認為如果這些功能完全由程式部

門開發必定曠日費時而且耗費公司資源小明在網路尋找是否有提供這些功能

的Free Software皇天不負苦心人小明發現了TWIG (The Web Information Gateway) httptwigscrewdrivernet這個群組軟體它在 Web 上整合郵件新聞聯絡人議事日程工作序書簽等功能非常符合公司的需求 Step 1 下載 twig-277targz 下載網址 httptwigscrewdrivernetdownloadphp3

Step 2 解開 twig-277targz tar -xzvf twig-277targz

59

Step 3 執行安裝動作安裝到 varwwwhtmltwig 目錄 cd twig-277 twig-install varwwwhtmltwig

Step 4 建立 MySQL 資料庫(twig)及各資料表

cd setup mysql -u root -p1234 mysqlgt create database twig Query OK 1 row affected (001 sec) mysqlgt quit mysql -u root ndashp1234 twiglt twigtablemysql

Step 5 修改 configincphp3 參數設定 vi varwwwhtmltwigconfigconfigincphp3 $config[fromdomain] = opencom 網域 $config[language] = chinesebig5 中文訊息 $config[imap_port] = 143notls

60

Step 6 修改連結 MySQL 的帳號密碼 vi varwwwhtmltwigconfigdbconfigincphp3 $dbconfig[sqlusername] = root username $dbconfig[sqlpassword] = 1234 password

Step 7 其他設定檔

vi etchttpdconfhttpdconf 加入 AddType applicationx-httpd-php php3 在 DirectoryIndex最後加入 indexphp3 DirectoryIndex indexhtml indexhtmlvar indexphp3 在 AddDefaultCharset ISO-8859-1加上 AddDefaultCharset ISO-8859-1

vi etcphpini register_globals = On service httpd restart Step 8 sendmail 設定 vi etcmailsendmailcf在 264 行前面加上並重新啟動 sendmail「service snedmail restart」 262 SMTP daemon options 263 264 O DaemonPortOptions=Port=smtpAddr=127001 Name=MTA 265 266 SMTP client options 267 O ClientPortOptions=Family=inet Address=00

61

Step 9 檢查設定有無錯誤 http主機名稱twigtestphp3

62

Step 10 登入 twig ( http主機名稱twig)

63

第六章 維護及更新程序

61 日常維護

系統管理員最好定期以 root 身份登入看看信件在 RedHat Linux 中有一支 logwatch 程式會定時去分析 log file如果發現異常便會發信給 root除此之外筆者建議讀者平時就檢查 MySQL log file ( varlogmysqldlog)是否有異常情形

62 更新程序

讀者可至httprpmfindnet 尋找MySQL相關套件至於升級的相關步驟請參

考Linux OS SOP 第 54節

63 備份重要檔案

預設 MySQL 的 DB 檔案是存在 varlibmysql 內以 DB名稱為目錄目錄

內就是該 DB 的所有資料通常得定期備份還有 MySQL的設定檔 etcmycnf也別忘了一起備份

64 離線備份與還原

641 離線備份

預設 MySQL 的 DB 檔案是存在 varlibmysql 內以 DB 名稱為目錄目錄內

就是該 DB 的所有資料像 CRM 這個 DB就是存在 varlibmysqlCRM 內在備份前因為怕資料尚未完全寫入磁碟而且 MySQL 會 Lock 在使用的 DB 檔案所以應該是要先把 MySQL 先 Shutdown 一下整個備份的程序可以下像下面的指令去完成 cd varlibmysql

64

service mysqld stop tar cvfz CRM_db_20030905tgz CRM service mysqld start 對這樣就可以了 不過要注意的是怕 DB 內每個 Tables 間的資料有關關

聯性所以最好是把整個 DB 一次備起來單獨只備哪個 Tables 的檔案以後回存時怕會有資料關聯不一致的問題

642 離線還原

DB 發生錯誤而要回存時其實也不難先找出最近一次完整正常的備份先把現在錯誤的網頁或 DB 先更名或 tar 起來再把好的備份給解開回原來目錄位

置就行了需要注意的是 MySQL 服務最好也是要先停止回存完成後再啟動服務回存 DB 的整個程序可能像下面 cd varlibmysql service mysqldstop mv CRM CRM_OLD tar xvfz CRM_db_20030905tg service mysqld start

65 線上備份與還原

651 線上備份

使用像上面的檔案方式備份是個不錯的方法它最少可以保持該主機某個時間點的完整檔案備份但還是有一些問題需要考慮到有些主機就不只建立一個 DB 而已總不能為了備份某個 DB 而把整個 MySQL 服務停止備份檔案的方式回存在原主機上一定適用但假如 MySQL 版本升級或是在那天該網頁空間需遷機移機到別的主機時那就沒人敢保證備出來的資料檔可以用所以我們可以考慮另一種備份的方式是使用 MySQL 本身提供的功能 MySQL Data Dump指令是 mysqldump

65

使用 MySQL 的 Dump 功能可以把 DB 的結構資料或結構加資料 Dump 成文字檔 mysqldump 指令提供的彈性很大你可以選擇把整個 DB Dump 成一個檔或是每個 Table 為一個檔甚至是把結構檔和資料分開儲存都

可以 mysqladmin -uroot -p flush-logs mysqldump CRM -uroot -p --opt gt CRM_20030905sql (CRM 是 DB 名稱 opt 是一個使用完整 Dump 參數) 假如只是要單獨 Dump 某個 Table 時只要在上面的指令後轉出符號 gt 前加個 Table 名稱就可以如只要 phpbb2_users 這個 Table 的 Dump 時只要下 mysqldump CRM -uroot -p --opt CUSTOMER gt CRM_CUSTOMER_20030905sql

652 線上還原

若要回存整個資料庫只需將壓縮的備份檔還原成 Dump 的檔案再用下面的指令回存 mysql CRM -uroot -p lt CRM_20030905sql 這邊需注意的是若建立備份時是以--opt或--add-drop-table為參數時回存的 動作是先將舊的 Table 先刪除重建 Table 的結構後再把 Data 匯入所以回存後所有的資料會回到你當時備份那個時間點因此在回存資料時可以考慮把現有錯誤或不完整的 DB 先備份一份下來以備不時之需或是拿來比對錯誤的地

方在那裡當然你也可以把資料回存到另一個測試用的 DB 內只要把上面指令

的 DB 名稱改成你的測試用 DB 名稱即可 使用這種回存方式 MySQL 服務不需停止也不會動到其他正在使用的 DB 在一些提供 MySQL 服務的虛擬主機可用這種方式作你自己的 DB 備份及回存

66

另外假如你是系統重建或是移機時切需在新的 MySQL 內新建一個空白 DB 後才行作回存的工作你可以用下面的指令建立 mysql -uroot -p -e CREATE DATABASE CRM (上面的 CRM是你要新建的 DB 名稱) 另一種作法先用 mysql 指令進入 mysql client console 然後再用 CREATE DATABASE CRM 這樣就行了記得尾端要加個 符號該行指令才會執行

67

第七章 問題與解答

Q1RedHat 90預附的 MySQL到底有無支援 Transcation機制 Ans MySQL自 32334a之後的 MySQL-Max版本加入 InnoDB的資料庫類型透過

InnoDBMySQL同樣可以進行 COMMIT與 ROLLRACK的動作RedHat 90預附的 MySQL為 32354a-11巳支援 InnoDB的資料庫類型不過必須做以

下設定 1cp usrsharedocmysql-server-32354amy-mediumcnf to etcmycnf 2 vi etcmycnf 將以下設定前的拿掉 innodb_data_home_dir = varlibmysql innodb_data_file_path = ibdata110Mautoextend innodb_log_group_home_dir = varlibmysql innodb_log_arch_dir = varlibmysql 3service mysqld restart 如此一來各位在建立Table時便可指定Table Type為 innodb ( ex create table with type=innodb ) Q2如何解決 php+mysql 許功蓋等字變亂的問題 Ans 方法一 【確定 MySQL 預設的字元集】 1 打開 WinMySQLadmin 管理畫面(在視窗右下角狀態列紅綠燈圖示中按滑鼠

右鍵點選 Show me 選項) 2 點選管理畫面中 [Variables] 標籤選項其中 character_set變數就是您預設

字元集的變數其預設是 latin1 字元集(我們要將他改回 big5)而 chatacters_set 變數則是 MySQL 可以支援哪些字元集 【修改預設字元集變數 character_set 】 1 請點選管理畫面中 [myini Setup] 標籤選項設定 myini 2 按一下 [Pick-up and Edit myini values] 按鈕以便編輯目前的 myini 設定 3 在 [mysqld] 設定區塊底下新增一行 default-character-set = big5 變數設

68

定 4 新增一個 [client] 設定區塊並加入第三步驟的變數設定(游標往下移到空白處新增兩行 [client] 和 default-character-set=big5) 5 按一下畫面左下方 [Save Modification] 按鈕儲存設定 6 重新啟動 MySQL 或 Windows 方法二 Server端注意事項 phpini 中有關的設定為(預設值) Magic quotes for incoming GETPOSTCookie data magic_quotes_gpc = On Use Sybase-style magic quotes (escape with instead of ) magic_quotes_sybase = Off Client端注意事項 1中文資料送進 mysql 前請用 addslashes($str) 處理 2處理後送進 mysql 時請用 括起來並在參數後留一個空白如 $sql = UPDATE ezf_table set tablename=$tname tableend=$endtime table inguser=$tguser tableingid=$tguserid tableallnumber=$tnumber tableloca l=$tablelocal tableanyone=$tableopen tabletext=$ttext WHERE tableid=$t ableid tablename=$tname c 取出時請用 stripslashes($str) Q3MySQL root 密碼忘了該怎麼辦 Ans 1先停掉 mysql etcrcdinitdmysql stop 2以--skip-grant-table 的參數啟動 mysql safe_mysql --skip-grant-tableamp 3 更改 root 密碼 mysql mysql mysqlgt UPDATE user SET password=password(newpassword)

69

WHERE user=root mysqlgt FLUSH PRIVILEGES mysqlgt exit 4停掉 mysql再重跑 mysqladmin -uroot -p shutdown Enter password 輸入新設定的密碼 etcrcdinitdmysql start

Q4NULL值問題

Ans

NULL值的概念是造成 SQL的新手的混淆的普遍原因他們經常認為 NULL是和一個空字符串的一樣的東西不是這樣的例如下列語句是完全不同的

mysqlgt INSERT INTO my_table (phone) VALUES (NULL)

mysqlgt INSERT INTO my_table (phone) VALUES ()

兩個語句把值插入到 phone 列但是第一個插入一個 NULL值而第二個插入一個空字符串第一個的含義可以認為是ldquo電話號碼不知道而第二個則可意味

著ldquo她沒有電話

在 SQL中NULL值在于任何其他值甚至 NULL值比較時總是假的(FALSE)包含 NULL的一個表達式總是產生一個 NULL值除非在包含在表達式中的運算符和函數的文檔中指出在下列例子所有的列返回 NULL

mysqlgt SELECT NULL1+NULLCONCAT(InvisibleNULL)

如果你想要尋找值是 NULL的列你不能使用=NULL測試下列語句不返回任

何行因為對任何表達式expr = NULL是假的

mysqlgt SELECT FROM my_table WHERE phone = NULL

要想尋找 NULL值你必須使用 IS NULL測試下例顯示如何找出 NULL電話號碼和空的電話號碼

70

mysqlgt SELECT FROM my_table WHERE phone IS NULL mysqlgt SELECT FROM my_table WHERE phone =

在 MySQL中就像很多其他的 SQL服務器一樣你不能索引可以有 NULL值的列你必須聲明這樣的列為 NOT NULL而且你不能插入 NULL到索引的

列中

當用 LOAD DATA INFILE 讀取數據時空列用更新如果你想要在一個列中有

NULL值你應該在文本文件中使用N字面上的詞NULL也可以在某些情形下使用

當使用 ORDER BY時首先呈現 NULL值如果你用 DESC以降序排序NULL值最後顯示當使用 GROUP BY時所有的 NULL值被認為是相等的

為了有助于NULL的處理你能使用 IS NULL和 IS NOT NULL運算符和 IFNULL()函數

對某些列類型NULL值被特殊地處理如果你將 NULL插入表的第一個TIMESTAMP 列則插入當前的日期和時間如果你將 NULL插入一個AUTO_INCREMENT 列則插入順序中的下一個數字

Q5如何將圖片存放於 MySQL中

Ans

Step 1建立資料庫 test

Step 2 建立表格 binary_data

CREATE TABLE binary_data (

id INT(4) NOT NULL AUTO_INCREMENT PRIMARY KEY

description CHAR(50)

bin_data LONGBLOB

filename CHAR(50)

filesize CHAR(50)

filetype CHAR(50)

71

)

Step 3 利用 storephp 寫入圖片

storephp 程式碼

ltHTMLgt ltHEADgtltTITLEgtStore binary data into SQL DatabaseltTITLEgtltHEADgt ltBODYgt lt code that will be executed if the form has been submitted

if ($submit) mysql_connect(localhostrootYOUR_PASSWORD) mysql_select_db(test) $data=Base64_Encode(fread(fopen($form_data r) filesize($form_data))) $result=MYSQL_QUERY(INSERT INTO binary_data (descriptionbin_datafilenamefilesizefiletype) VALUES ($form_description$data$form_data_name$form_data_size$form_data_type)) $id= mysql_insert_id() print ltpgtThis file has the following Database ID ltbgt$idltbgt MYSQL_CLOSE() else else show the form to submit new data

gt

ltform method=post action=ltphp echo $PHP_SELF gt enctype=multipartform-datagt File Descriptionltbrgt ltinput type=text name=form_description size=40gt ltINPUT TYPE=hidden name=MAX_FILE_SIZE value=4000000gt ltbrgtFile to uploadstore in databaseltbrgt ltinput type=file name=form_data size=40gt ltpgtltinput type=submit name=submit value=submitgt ltformgt lt

72

gt ltBODYgt ltHTMLgt

Step 3 利用 storephp 取出圖片

getdataphp 程式碼

lt Syntax getdataphp3id=ltidgt if($id) you may have to modify login information for your database server MYSQL_CONNECT(localhostrootYOUR_PASSWORD) mysql_select_db(test) $query = select bin_datafiletype from binary_data where id=$id $result = MYSQL_QUERY($query) $data = Base64_Decode(MYSQL_RESULT($result0bin_data)) $type = MYSQL_RESULT($result0filetype) Header( Content-type $type) echo $data gt

Q6MySQL裝好之後啟動時或是執行 mysqladmin會出現如下訊息 Cant connect to local MYSQL Server through Socket varlibmysqlmysqlsock或是

Cant connect to local MYSQL Server through Socket tmpmysqldsock

Ans 可能有下列幾個原因

1這個 mysqldsock 不見了被某人刪除了或是被一些系統自動執行程式給刪

了例如有些 cron任務便會設定定期刪除 tmp 裡的東西所以呢您只能修改

cron 裡的設定讓它不要清除 mysqldsock 2在啟動時也可以改變 mysqldsock的位置您在啟動 MySQL的時候可以加入此參數usrlocalmysqlbinsafe_mysqld --user=mysql --socket=其他路

徑socket amp 同時得去設定環境變數 MYSQL_UNIX_PORT的值以指定新的

73

路徑 3若是您沒改 MYSQL_UNIX_PORT的值那麼您可以在執行指令的時候才打

例如mysqladmin --socket=其他路徑socket version Q7How to get the last insert id Ans CREATE TABLE product ( id INT(4) NOT NULL AUTO_INCREMENT PRIMARY KEY description VARCHAR(50) ) 1利用 SQL的話 mysqlgt insert into product(description) values(123) Query OK 1 row affected (000 sec) mysqlgt select last_insert_id() +------------------+ | last_insert_id() | +------------------+ +------------------+ 1 row in set (000 sec) ======================================== 2如果是 PHP的話 你可以用mysql_insert_id()取得該 id PHP example $result=MYSQL_QUERY(INSERT INTO product (description) VALUES ($description)) $id= mysql_insert_id() print This file has the following Database ID $id Q8如何將文字檔匯入資料庫 Ans $addr=homehttpdhtmlphpschool001txt $sql_select = load data infile $addr into table test fields terminated by t 解說 $sql_select = load data infile 文字檔名 into table 表格名 fields terminated by

74

t

(欄位分隔以 TAB鍵) 該文字檔須與資料表欄位格式相符 例如欄位有三個 則文字檔為每行一筆資料如下 欄 1資料ltTABgt欄 2資料ltTABgt欄 3資料 欄 1資料ltTABgt欄 2資料ltTABgt欄 3資料 欄 1資料ltTABgt欄 2資料ltTABgt欄 3資料 欄 1資料ltTABgtltTABgt欄 3資料

Q9如何撰寫 MySQL C API Ans Step 1利用文字編輯器撰寫以下程式碼 mysqlcc

include ltstdiohgt

include ltmysqlmysqlhgt

int main (int argc char argv[])

MYSQL mysql

MYSQL_RES res

MYSQL_ROW row

if (argc = 2)

fputs (Usage myc ltdatabasegt stderr)

return 1

if ((mysql_connect(ampmysqllocalhostrootYour_Password)))

fputs (Error connecting stderr)

abort()

75

if (mysql_select_db(ampmysqlargv[1]))

fputs (Error selecting database stderr)

abort()

if (mysql_query(ampmysqlSELECT FROM test_table))

fputs (Error processing query stderr)

abort()

if ((res = mysql_store_result(ampmysql)))

fputs (Error storing results stderr)

abort()

while((row = mysql_fetch_row(res)))

uint i = 0

for (i=0 i lt mysql_num_fields(res) i++)

printf(s row[i])

printf(n)

return 0

Step 2 Compile

gcc -Iusrlocalmysqlinclude -Lusrlocalmysqllibmysql mysqlcc ndashlm -lmysqlclient

(其中 include path與 library path取決於你的 MySQL安裝路徑)

76

如果執行時發生如下 error Run problemerror in loading shared libraries libmysqlclientsoX 將你的 MySQL library path(for exampleusrlocalmysqllibmysql) 加入etcldsoconf and run sbinldconfig -v Q9ASP + MySQL 範例程式 Ans Dim myconn As New ADODBConnection Dim myrs As New Recordset Dim mySQL As String Dim myrows As Long myconnOpen DSN=MyODBCsample mySQL = SELECT from user myrsSource = mySQL Set myrsActiveConnection = myconn myrsCursorLocation = adUseClient myrsOpen myrows = myrsRecordCount myrsClose myconnClose 可參考 httpwwwdwamnetmysqlasp_myodbcasp 有詳細的資料 Q10如何將 MySQL中的資料庫匯出成txt檔 Ans select from TableName into outfile textxls all result fields will seperate by tab

77

第八章 參考資料

英文部份 網址 1 httpwwwmysqlcom MySQL 網站有第一手有關 MySQL的資料 2 httpwwwmysqlcomdocenReplicationhtml 有關 MySQL Replication 的文件 3 httpwwwgeocitiescomsqlhomefaqstore_blobhtml 如何在 MySQL 存放 BLOB的資料 4httpwwwsapdborg 有關 SAP跟 MySQL相關合作的網站 書藉 1 Cooking with MySQL

Paul DuBois has selected sample recipes from the hundreds youll find in his book MySQL

Cookbook In this third and final series of excerpts showcasing these recipes learn how to

compute team standings how to calculate the differences between successive Dec 26

2002 2 Tips for Building Web Database Applications with PHP and MySQL by Hugh E Williams co-author of Web Database Applications with PHP amp MySQL 04042002

3 Managing and Using MySQL 2nd Edition By Tim King George Reese Randy Jay Yarger

4 MySQL Cookbook By Paul DuBoisPublisher OReillyPub Date October 2002

中文部份

78

1 httplinuxtncedutwtechdocmysqlmysql_docmanual_tochtml MySQL 中文手冊 2 httpchenshloxaedutwphpZ_1php PHP+MySQ程式研習設計網站 3 httplinuxtncedutwtechdocbanicdownhtml PHP 4 手冊 4 httpwwwtncedutwadmin_zonephp台南縣教育網網路中心有很多 Linux相關文件 5 httpdobtncedutw網站建置百寶箱有很多 PHP MySQL 相關範例程式 5 httpwwwdbworldcomtw資料庫專家電子雜誌介紹資料庫的重要觀念及名詞

79

附錄一 SQL Command 介紹

SQL (讀音ess-que-el) 是一種結構查詢語法SQL 使用於資料庫交流

傳遞相容於 ANSI (American National Standards Institute) 是一套標準的關聯

式資料庫語言 SQL 語言是執行更新或從資料系統獲取資料一般常見的關聯

資料庫系統都有提供 SQL 如 Oracle Sybase Microsoft SQL Server Access Ingres 等雖然大部份的資料庫都有提供 SQL 但也多提供了自已獨特的語

法造成了不相容的情形但標準基本的語法是相通的如Select Insert Update Delete Create and Drop 每一個系統都有支援

Table相關 Command

Create Table

關聯式資料庫包含有很多元件稱為資料表(tables) 把資料或訊息放在資

料表中 資料表是以不同的名稱做分別資料表由欄列所構成的二維陣列

欄包含欄位名資料型態 及其他可判斷的資訊列是由全部欄位構成一筆一

筆的紀錄 create table 語法用在建立一個新的資料表語法格式如下

create table tablename (column1 data type column2 data type column3 data type)

Format of create table if you were to use optional constraints

create table tablename (column1 data type [constraint] column2 data type [constraint] column3 data type [constraint]) [ ] = optional

Note You may have as many columns as youd like and the constraints are optional

80

Example

create table employee (first varchar(15) last varchar(20) age number(3) address varchar(30) city varchar(20) state varchar(20))

注意建立資料表格式要以括號把前後框住而最後以(分號)做結尾

欄位名不要超過 30個字元長而且不要使用 sql 的關鍵字(如 where select等)而在後面接是型態的宣告(如字串數字日期格式等)

資料型態是來描述欄位的方式如一個欄位Last_Name 是一個姓氏可以使用varchar (可變動長度字串) 資料型態

以下是幾個常見的資料庫型態 char(size) 固定長度字串最長為 255 位元 varchar(size) 變動長度字串最大字元數以 size 來指定 number(size) 數值格式可以是整數也可以是小數最大數字以 size 位數判

斷未指定小數位數由系統內定 date 日期格式 number(sized) 數值格式最大數字以 size 位數判斷d 為小數位數整數位

數為 size-d 位

有何限制當資料表被建立通常有一或數個欄位是要使用來做關聯的功

能 例如unique 限制(唯一值)兩筆記錄不可以相同的值 not null (非空值)該欄位一定要輸入資料不可是空的primary key (主鍵)是每一筆記錄識別的主要方式

Drop a table drop table 刪除資料表(其中的資料也會一併刪除)

drop table tablename

Example

81

drop table 和刪除全部資料是不同的刪除全部資料欄位名稱資訊等還會

存在但刪除資料表會把這一些也一併移除掉

如何查詢資料

Select 基本用法

select 語法是關連式資料庫最常用的部份可以取得你想要的資料這是一個

簡單的範例 select column1[column2etc] from tablename [where condition] [] = optional 在 select 之後所列欄位名則是要顯示的資料部份你可以一一列出各欄位

名或是以 (星號)來代表選擇全部的欄位 from 之後放資料表名稱 where 子句 (選項) 指定要過濾的條件符合者才會顯現 where 可使用的條件運算元 = 等於 gt 大於 lt 小於 gt= 大或等於 lt= 小或等於 ltgt 大相等 LIKE 相似 For example select first last city

82

from empinfo where first LIKE Er 以Er 為開頭的字串就符合要以單引號框住 Or you can specify select first last from empinfo where last LIKE s 最後一字為 S 就符合 select from empinfo where first = Eric 則表示 first name 一定要是 Eric 才可以 範例資料表empinfo 統計函數

MIN 傳回指定欄位最小值

MAX 傳回指定欄位最大值

SUM 傳回指定欄位總和

AVG 傳回指定欄位平均值

COUNT 傳回指定欄位的筆數

COUNT() 傳回資料庫中的總筆數

統計函數使用於資料表中的數值欄位配合 SELECT 語法使用 只用於總結特定單一欄位可以配合 GROUP BY 做篩選但也可以不使用 GROUP BY 語句For example

SELECT AVG(salary) FROM employee

83

傳回全部 salary 平均值

Another example

SELECT AVG(salary) FROM employee WHERE title = Programmer

傳回 salary 平均值條件為 employees 資料表中當 title 等於 Programmer

Example

SELECT Count() FROM employees

傳回 employees 資料表中紀錄總筆數

GROUP BY 語法 SELECT column1 SUM(column2) FROM list-of-tables GROUP BY column-list The GROUP BY 語句可以先以所列的欄位為條件分組排序在一起(可以多欄

位) example 要列出每一個 dept 中最高 salary 值 SELECT max(salary) dept FROM employee GROUP BY dept HAVING 語法

SELECT column1 SUM(column2) FROM list-of-tables GROUP BY column-list HAVING condition

HAVING 子句是 GROUP BY 的一部份用來過濾在 GROUP BY 所選出的資料功能如同 select 命令中 where 條件式一樣只是 HAVING 必需配合 GROUP BY 使用

我們以例子來說明我們要取得每一公司名及每一公司的薪水平均值輸入如下

84

SELECT dept avg(salary) FROM employee GROUP BY dept

但如果我們只列出薪資平均值超過 20000元的公司資料

SELECT dept avg(salary) FROM employee GROUP BY dept HAVING avg(salary) gt 20000

ORDER BY子句語法

SELECT column1 SUM(column2) FROM list-of-tables ORDER BY column-list [ASC | DESC]

[ ] =選項

ORDER BY是一個選項子句當你以排序方式來顯示資料(正向由小到大反向由大到小)以指定的欄位資料做排序

ASC = 正向- 預設值 DESC = 反向排序

For example

SELECT employee_id dept name age salary FROM employee_info WHERE dept = Sales ORDER BY salary

以上列出公司代號公司名銷售員人名年紀及薪資而條件是公司名為 Sales 顯示順序以薪資多少排序(由小到大為預設值)

如果要以多個欄位做排序要以逗號做分隔如下

SELECT employee_id dept name age salary FROM employee_info WHERE dept = Sales ORDER BY salary age DESC

85

結合條件及布林運算 SELECT column1 SUM(column2) FROM list-of-tables WHERE condition1 AND condition2 AND運算可以結兩個或以上的條件放在 WHERE子句中 兩者都要為真才

會顯示該筆記錄 OR 運算可以結兩個或以上敘述放在 WHERE子句中只要其中一個為直就

會顯示該筆記錄 For example SELECT employeeid firstname lastname title salary FROM employee_info WHERE salary gt= 5000000 AND title = Programmer 必需要薪資大於等於 50000而且職稱為 Programmer同時符合才會顯示該筆資料 以下以括號括住雖然不是必需的但如此比較容易讀 SELECT employeeid firstname lastname title salary FROM employee_info WHERE (salary gt= 5000000) AND (title = Programmer) 另外範例 SELECT firstname lastname title salary FROM employee_info WHERE (title = Sales) OR (title = Programmer) 條件為只要是 Sales 或 Programmer 職稱的就會被列出 IN and BETWEEN 子句

SELECT column1 SUM(column2) FROM list-of-tables WHERE column3 IN (list-of-values) SELECT column1 SUM(column2) FROM list-of-tables WHERE column3 BETWEEN value1 AND value2 IN 子句使用在列舉項目的使用上也就是分別測試是否符合所列的值 For example

86

SELECT employeeid lastname salary FROM employee_info WHERE lastname IN (Hernandez Jones Roberts Ruiz) 條件為姓氏(astname)要符合 Hernandez Jones Roberts or Ruiz 其中一個才會被傳回 IN運算元也可以使用 OR 的語法來取代如下結果相同 SELECT employeeid lastname salary FROM employee_info WHERE lastname = Hernandez OR lastname = Jones OR lastname = Roberts OR lastname = Ruiz 但使用 IN 句子比較短也比較易懂 你也可以使用 NOT IN 來去掉不要的記錄 BETWEEN 運算元使用在判斷是否存在兩個數值之間 For example SELECT employeeid age lastname salary FROM employee_info WHERE age BETWEEN 30 AND 40 傳回年紀 30歲到 40歲之間的資料(含 30及 40歲者) 相同的也可以使用以下語法來達到相同的結果 SELECT employeeid age lastname salary FROM employee_info WHERE age gt= 30 AND age lt= 40 你也可使用 NOT BETWEEN 來濾掉中間值的資料 數學運算 標準 ANSI SQL-92 提供以下運算

87

+ 加

- 減

餘數

餘數為除法後剩整數這不在標準的 ANSI SQL 中但大部份的資料庫都會支

援這運算元以下列出有用的函數雖不在 ANSI SQL-92 提供但一般資料庫

也會支援他們

ABS(x) 傳回 x 絕對值

SIGN(x) returns the sign of input x as -1 0 or 1 (negative zero or positive respectively)

MOD(xy) 餘數 - returns the integer remainder of x divided by y (同 xy)

FLOOR(x) 傳回小或等於 x 的最大整數值

CEILING(x) or CEIL(x)

傳回大或等於 x 的最小整數值

POWER(xy) x的 y 次方

ROUND(x) 把 x 四捨五入為整數

ROUND(xd) 四捨五入取到小數 d 位

SQRT(x) x 開平方

For example SELECT round(salary) firstname FROM employee_info 傳回薪資取到整數位

如何新增資料

insert 加入一筆新紀錄到資料表中 insert into tablename (first_columnlast_column) values (first_valuelast_value) [] = optional Example insert into employee

88

(first last age address city state) values (Luke Duke 45 2130 Boars Nest Hazard Co Georgia) Note 字串要以單引號住如string 數字框住也無妨 insert into 後面接資料表名稱再接以括號括住的欄位名在 values 後括號分別對映各欄位的值 以上的例子新增了一筆名(first) 為 Luke而住所(state) 為 Georgia 的資料

如何刪除資料

delete 可以刪除單筆或多筆紀錄 delete from tablename where columnname OPERATOR value [and|or column OPERATOR value] [ ] = optional Examples delete from employee Note 如果你沒有指定 where 子句那麼全部的紀錄都會被刪除 delete from employee where lastname = May delete from employee where firstname = Mike or firstname = Eric delete from 接著資料表名 再接著是條件式判斷沒有條件式則全部紀錄會

被刪除

如何更新資料

update 用來更新你所指定的記錄要和 WHERE 配合小心使用 語法 update tablename set columnname = newvalue[nextcolumn = newvalue2] where columnname OPERATOR value [and|or column OPERATOR value] [] = optional Examples

89

update phone_book set area_code = 623 where prefix = 979 update phone_book set last_name = Smith prefix=555 suffix=9292 where last_name = Jones update employee set age = age+1 where first_name=Mary and last_name=Williams

90

附錄二Replication

測試環境

RedHat 90 + MySQL 32358 MySQL資料庫路徑 varlibmysql MySQL設定檔 etcmycnf Master IP 1921680100 Slave IP 1921680200 請至下列網址下載最新MySQL 32358套件並利用rpm ndashUvh 更新 httpupdatesredhatcom9enosi386

圖 最新 MySQL 套件

測試架構圖

91

1921680100

1921680200Master Server

erveSlave S r

圖 測試架構圖

測試步驟

Master server 部份 Step1 確認 MasterSlave機器上所裝的 MySQL版本能進行

replication( 32329 or higher ) Step2 在 Master MySQL上開放一個帳號給 Slave mysql ndashu root ndashp mysqlgtGRANT FILE ON TO repl1921680200 IDENTIFIED BY lsquoabc123rsquo mysqlgtq 上面是 Master開放一個帳號 repl密碼 abc123給 IP1921680200有檔案處理

的權限 Step3 shutdown MySQL on the Master mysqladmin ndashu root ndashp shutdown Step4 備份 Master所有資料庫 tar ndashcvf tmpmysql-snapshottar varlibmysql 注意tar的時候MySQL是要在 stop情況下 在mysql (wwwmysqlcom) 網站的FAQ有不用shutdown的方法

92

Step5 在 master機器上修改etcmycnf 在[mysqld]區段內加入參數 log-bin server-id=這邊設定 server-id=1 sql-bin-update-same binlog-do-db=CRM只針對 CRM資料庫做紀錄 Step6 Restart MySQL on the master service mysqld start 此時因為有加入 log-bin 參數因此開始有 index產生了在varlibmysql目錄下

有index檔案紀錄資料庫的異動 log Slave server 部份 Step1 在 slave設定etcmycnf 在[mysqld]區段加入 master-host= master-user= master-password= master-port= server-id= 這邊設定 master-host=1921680100 master-user=repl master-password=abc123 master-port=3306 server-id=2 master-connect-retry=60預設重試間隔 60秒 replicate-do-db=CRM告訴 slave只做 CRM資料庫的更新 log-slave-updates Step2 將 master上的 mysql-snapshottar copy到 slave上 用 ftp傳到 slave的tmp Step3 解壓縮 Master資料庫至 Slave Server上 cd varlib tar xvf tmpmysql-snapshottar chown ndashR mysqlmysql mysql

93

chmod ndashR 770 mysql (視情況) Step4 Restart MySQL on the slave server 這時在varlibmysql目錄會出現 masterinfo此檔案紀錄了 Master MySQL server的資訊

狀況測試

One-way replication

1921680100

1921680200Master Server

erveSlave S r

圖 One-way replication架構圖 Step1 Master跟 Slave網路及服務都正常情況下由 Master端異動資料後 到 Slave端瀏覽資料檢視是否有進行 replication Step2 模擬 Slave Server 當機 可用在於 slave真的當機或是 Slave 不一定需要一直跟 master connect將Slave MySQL server shutdown由 Master端異動資料到 slave端瀏覽此時Slave應該沒有被 replication 更新然後再將 Slave端 MySQL server start起來

預設 60秒後 Slave會嘗試跟 Master要求進行 replication再去 Slave端檢視是否有更新資料

94

Step3 模擬 Master當機因為是設定 One-way replication一旦 Master Server Slave端沒有 Master的 source可以 download Two-way replication 基於 Master當機狀況於是發展雙向 Replication即 1921680100 ( Host A ) 1921680200 ( Host B )都分別擔任 MasterSlave身分

1921680100

1921680200er

Server B MasterSlave Server

Server A MasterSlave Serv

圖 Two-way replication架構圖 以下是針對兩台 MySQL伺服器進行雙向 Replication Step1觀念同單向 replication只是改成 Master也有 Slave身分 Slave也有Master的身分先分別在 Server AServer B 都去 grant一個進行 replication的身分 [A]mysqlgtGRANT FILE ON TO repl1921680200 IDENTIFIED BY lsquoabc123rsquo [B]mysqlgt GRANT FILE ON TO repl1921680100 IDENTIFIED BY lsquoabc123rsquo Step2做完單向 replication後stop Server Aserver B MySQL service此時 AB資料是一樣的

95

修改etcmycnf設定 範例 Server A [mysqld] datadir=varlibmysql socket=varlibmysqlmysqlsock server-id=1 log-bin sql-bin-update-same binlog-do-db=CRM master-host=1921680200 master-user=repl master-password=abc123 log-slave-updates master-connect-retry=60 replicate-do-db=CRM Server B [mysqld] datadir=varlibmysql socket=varlibmysqlmysqlsock server-id=2 log-bin sql-bin-update-same binlog-do-db=CRM master-host=1921680100 master-user=repl master-password=abc123 log-slave-updates master-connect-retry=60 replicate-do-db=CRM 分別 start Server AServer B MySQL後此時雙方都是 MasterSlave身分一旦哪一方資料異動就會通知對方來 replication-若 replication失效則必須將Server AServer B的masterinfo及index00x 都砍掉然後分別 restart MySQL server進行測試檢視成果 實務上通常如果需要做Two-way replication通常會搭配Virtual Server使用

96

在前端架設一台Virtual Server不過此部份不在此份SOP討論範圍內有興趣

的讀者可參考 httpwwwlinuxvirtualserverorg 網站

1921680100 1921680200

Host A MasterSlave Server

Host B MasterSlave Server

Virtual Host

圖 Virtual Server + Two-way replication 架構圖

97

圖 High Availability Linux Virtual Server架構圖

98

  • COSA-SOP-03-006
  • 第一章 簡介
    • 11適用對象 (Audience)
    • 12 MySQL本身
    • 13 MySQL 40版跟50版重大的改進功能
    • 14 各家資料庫軟體比較
      • 第二章 前置需求
      • 第三章 安裝
        • 31 MySQL安裝
        • 32 phpMyAdmin安裝
        • 33 升級及注意事項
          • 第四章 MySQL管理
            • 41 Webmin 管理介面
            • 42 phpMyAdmin 的操作介面
            • 43管理指令介紹
              • 431 利用mysqladmin設定root的密碼
                  • 第五章 實用範例
                    • 51 任務一Web Base客戶通訊錄
                    • 52 任務二Web Base群組軟體 ( twig )
                      • 第六章 維護及更新程序
                        • 61 日常維護
                        • 62 更新程序
                        • 63 備份重要檔案
                        • 64 離線備份與還原
                        • 65 線上備份與還原
                          • 第七章 問題與解答
                          • 第八章 參考資料
                          • 附錄一 SQL Command 介紹
                          • 附錄二Replication
Page 17: DataBase Server Standard Operation Procedureebooks.lib.ntu.edu.tw/1_file/oss/63/93doc4-5.pdf · 業務的公司帶來了不少壓力,譬如微軟,甲骨文 ... 外的錢用在第三方的資料庫產品上,譬如就可以不用再購買甲骨文公司

32 phpMyAdmin安裝

本書除了會介紹利用當今 Linux上最紅的整合管理工具Webmin 來管理

MySQL外還會為各位介紹專門管理 MySQL的工具 phpMyAdmin phpMyAdmin是免費的 PHP原始程式碼的Web網站可用來管理整個

MySQL伺服器這是一套Web介面的 MySQL管理程式支援中文的使用者介

面 phpMyAdmin只需透過瀏覽器就可管理 MySQL伺服器換句話說不論

MySQL是安裝在 Linux或是Windows 作業系統都可以使用相同步驟在

MySQL上建立資料庫(Database)資料表(Table)和編輯紀錄(Record) Step 1 下載phpMyAdmin ( httpwwwphpmyadminnet )選擇最櫎新穩定的版

本 253

圖 3-10 httpwwwphpmyadminnet

17

圖 3-11 下載 phpMyAdmin-253-phptarbz2

Step 2 將 phpMyAdmin-253-phptarbz2收至 tmp 並執行下列指令將其解壓

縮至varwww tar jxvf phpMyAdmin-253-phptarbz ndashC varwwwhtml

圖 3-12 解壓縮安裝 phpMyadmin-253

Step 3 為了操作方便起見建立 Soft link ln ndashs phpMyAdmin-253 phpMyAdmin

圖 3-13 修改 phpMyadmin 設定檔 configincphp

18

Step 4 修改 phpMyadmin 設定檔 configincphp gedit varwwwhtmlphpMyAdminconfigincphp

圖 3-14 configincphp設定檔

Step 5 設定顯示行號以方便修改 configincphp 設定檔

19

圖 3-15 顯示行號

Step 6 修改下列設定 第 39 行 設定 phpMyAdmin的 URL 第 69 行 MySQL Server 的 ip 第 80 行 利用何帳號存取 MySQL 第 81 行 如果 root有設定 password此處即填入 root的 password

30 In most cases you can leave this variable empty as the correct value

31 will be detected automatically However we recommend that you do

32 test to see that the auto-detection code works in your system A good

33 test is to browse a table then edit a row and save it There will be

34 an error message if phpMyAdmin cannot auto-detect the correct value

35

36 If the auto-detection code does work properly you can set to TRUE the

37 $cfg[PmaAbsoluteUri_DisableWarning] variable below

38

39 $cfg[PmaAbsoluteUri] = httpossccosaorgtwphpMyAdmin

hellip

20

hellip

69 $cfg[Servers][$i][host] = localhost MySQL hostname or IP address hellip 80 $cfg[Servers][$i][user] = root MySQL user

81 $cfg[Servers][$i][password] = 1234 MySQL password (only needed

圖 3-16 修改 configincphp

21

圖 3-17 修改 configincphp

圖 3-18 修改 configincphp p

Step 7 設定語系

22

圖 3-19 設定語系

圖 3-20 執行 phpMyAdmin

23

33 升級及注意事項

RedHat 90附的 MySQL版本為 323 MySQL所釋出最新穩定版本為

40若是您不想用系統預附的 323請先利用下列移除之前 323的版本

rpm ndashe mysql-devel rpm ndashe mysql-server rpm ndashe mysql --nodeps 然後到下列網址下載您所想要的版本進行安裝在這裏我們用 4014版為例 Step 1 下載相關套件( httpwwwmysqlcomdownloadsmysql-40html )

圖 3-21 Download MySQL 4014 相關 RPM Step 2 利用 rpm 指令安裝

24

圖 3-22 Install MySQL 4014 相關 RPM

圖 3-23 Install MySQL 4014 相關 RPM

Step 3 啟動 MySQL

25

圖 3-24 啟動 MySQL 4014 並修改密碼

26

第四章 MySQL管理

本章將我們介紹利用WebminphpAdminCommand的方式建立一個名為

CONTACT的資料庫內有一個 address的 Table作為我們客戶通訊錄程式使

用的資料庫

41 Webmin 管理介面

412建立資料庫

Step 1 登入Webmin

圖 4-1 登入WebMin

Step 2 點選伺服器

27

圖 4-2 伺服器畫面

Step 3 點選 MySQL資料庫伺服器

圖 4-3 MySQL資料庫伺服器

28

Step 4 建立一個新的資料庫

圖 4-4 建立 MySQL資料庫

Step 5 建立名為 CONTACT的資料庫

29

圖 4-5 指定資料庫名稱

412 建立資料表

假設我們要建立一個名為 address的 Table其結構如下 欄位名稱 資料型態 長度 說明 id INT (自動編號) 連絡人編號 name varchar文字 20 連絡人姓名 tel Varchar文字 15 連絡人電話 Step 1 選擇 CONTACT資料庫

30

圖 4-6 選擇資料庫

Step 2 指定欄位數目

31

圖 4-7 設定欄位數目

Step 3設定表格欄位屬性

圖 3-8 設定表格欄位屬性

Step 4建立表格資料

32

圖 4-9 建立表格資料

圖 4-10 檢視資料

33

圖 4-11 新增資料

圖 4-12

34

圖 4-13

413 使用者管理

接下來我們要利用Webmin 來建立資料庫使用者並給予某些權限 Step1建立使用者

35

圖 4-14 選擇使用者權限

圖 4-15

36

Step2 賦予權限

圖 4-16

Step3 權限列表

37

圖 4-17

38

42 phpMyAdmin 的操作介面

421建立資料庫

Step 填入資料庫名稱並按「建立」

圖 4-18建立資料庫

422 建立資料表

Step1 填入資料表名稱並指定欄位數量 執行

39

圖 4-19填入資料表名稱並指定欄位數量

Step2 設定欄位屬性

圖 4-20設定欄位屬性

40

Step3 phpMyAdmin會產生相關的 SQL Command

圖 4-21 資料表結構及相關 SQL Command

Step4新增 Record

41

圖 4-22

圖 4-23

42

圖 4-24

圖 4-25

43

423使用者管理

Step1建立使用者

圖 4-26

44

圖 4-27

Step2 給予權限

圖 4-28

Step3權限列表

45

圖 4-29

43管理指令介紹

431 利用 mysqladmin設定 root的密碼

當您在Windows 或 Linux 中安裝好 MySQL後系統會自動幫您建立兩個

帳分別是 root 和 匿名者MySQL的 root 跟 Linux 最高權限使用者 root無關MySQL的 root使用者相當於 MS SQL 中的 sa 帳號擁有最高的 Database管理權限但系統預設 MySQL的 root 是不需要密碼所以通常我們一安裝

MySQL後首要任務便是修改 root的密碼 我們可以利用 mysqladmin工具或是直接修改 MySQL內部資料庫的使用者資

料 mysqladmin ndashu root ndashh cosaexamplecom password lsquo1234rsquo

46

-u 表示使用者帳號root 為 MySQL預設的管理帳號

-h 表示 MySQL主機的主機名稱也可使用 IP Address password 表示使用者的密碼因為字串請使用單引號將密碼括起來 密碼設定完成之後還是可以利用 mysqladmin修改密碼但是你必須提供目前的密碼

432 連線 MySQL

mysql -uroot -p密碼 (-p和密碼之間不能有空白) 或 mysql -uroot -p (此方式會在進入後要求密碼) [rootossc phpMyAdmin] mysql -u root -p1234

Welcome to the MySQL monitor Commands end with or g

Your MySQL connection id is 25 to server version 32354

Type help or h for help Type c to clear the buffer

mysqlgt show databases

+----------+

| Database |

+----------+

| mysql |

| test |

+----------+

2 rows in set (000 sec)

mysqlgt exit

Bye

[rootossc phpMyAdmin]

433 建立資料庫

可利用 mysqladmin指令建立 CONTACT資料庫 mysqladmin -u root -p1234 create CONTACT

47

或是利用 mysql指令 [rootossc bluepage] mysql -u root -p1234 Welcome to the MySQL monitor Commands end with or g Your MySQL connection id is 1057 to server version 32354 Type help or h for help Type c to clear the buffer mysqlgt create database CONTACT Query OK 1 row affected (000 sec) mysqlgt show databases +----------+ | Database | +----------+ | CONTACT | | address | | hello | | mysql | | nuke | | test | +----------+ 6 rows in set (000 sec) mysqlgt exit

434 建立資料表

編寫 adresssql內容如下 -- Table structure for table address CREATE TABLE address ( id int(11) NOT NULL auto_increment name varchar(20) NOT NULL default tel varchar(15) NOT NULL default PRIMARY KEY (id) ) TYPE=MyISAM

48

-- Dumping data for table address INSERT INTO address VALUES (1林小明0800016888) INSERT INTO address VALUES (2黃大雄0800016888) INSERT INTO address VALUES (3劉小芬0800024365) 然後執行此 sql script mysql -u root -p1234 CONTACT lt addresssql 或是利 mysql command [rootossc bluepage] mysql -u root -p1234 Welcome to the MySQL monitor Commands end with or g Your MySQL connection id is 1090 to server version 32354 Type help or h for help Type c to clear the buffer mysqlgt use CONTACT Database changed Database changed mysqlgt CREATE TABLE address ( -gt id int(11) NOT NULL auto_increment -gt name varchar(20) NOT NULL default -gt tel varchar(15) NOT NULL default -gt PRIMARY KEY (id) -gt ) TYPE=MyISAM Query OK 0 rows affected (000 sec) mysqlgt INSERT INTO address VALUES (1林小明0800016888) Query OK 1 row affected (000 sec) mysqlgt INSERT INTO address VALUES (2黃大雄0800016888) Query OK 1 row affected (000 sec) mysqlgt INSERT INTO address VALUES (3劉小芬0800024365) Query OK 1 row affected (000 sec) mysqlgt exit Bye

49

第五章 實用範例

51 任務一Web Base客戶通訊錄

任職於開放科技公司的林小明前些日子在最符合成本效益的條件下快

速地完成公司網站的建置老闆因此對小明讚譽有加最近因為公司存放客戶資

料的 SQL Server主機屢遭病毒攻擊加上作業系統本身的問題當機次數頻繁

老闆希望能儘快把公司的客戶通訊錄程式移轉到較穩定的環境上因為此客戶通

訊錄程式最主要給內部人員使用所以介面美觀並不特別要求只求穩定且能快

速得到查詢結果老闆希望在短時間先看到程式的雛型並鍵入資料對其效率

及穩定性進行測試因為上次小明表現突出所以這次不可能的任務自然又落到

小明身上 小明想來想去既然要快速又穩定他而且又不希望所有人都得安裝 Client

程式於是小明決定)捨棄他的舊愛「Delphi+MS SQL」投向新歡「Apache + MySQL + PHP」利用此架構來設計一個簡單實用的Web Base客戶通訊錄程式

511 Web Base客戶通訊錄架構

此程式需要建立 CONTACT的資料庫並建立 adress Tables其結構如下表建立步驟請參考第三章 欄位名稱 資料型態 長度 說明 id INT (自動編號) 連絡人編號 name varchar文字 20 連絡人姓名 tel Varchar文字 15 連絡人電話 Web Base通訊錄共有下列幾個檔案功能如下表

檔案名稱 說明 Indexhtml Web Base通訊錄首頁 addphp 新增連絡人的 php程式 searchphp 尋找連絡人的 php程式 editphp 具有更新及刪除功能的 php程式

50

我們將這些檔案放至varwwwhtmlbluepage (預設無 bluepage目錄)

512 Web Base通訊錄測試

httpwwwopencombluepage 新增資料

圖 5-1 新增連絡人

圖 5-2 填入資料

51

圖 5-3 新增成功

搜尋及異動資料

圖 5-4 搜尋通訊錄

52

圖 5-5 編輯資料

圖 5-6 更新資料

513 程式內容及說明

lt-- 程式範例indexhtml--gt lthtmlgt ltheadgtlttitlegt通訊錄lttitlegtltheadgt ltbodygt ltcentergt

53

lth2gt通訊錄lth2gtlthrgt lta href=indexhtmlgt通訊錄ltagt | lta href=addphpgt新增連絡人ltagt | lta href=searchphpgt搜尋通訊錄ltagt ltcentergt ltbodygt lthtmlgt lt-- 程式範例addphp --gt lthtmlgt ltheadgtlttitlegt新增連絡人lttitlegtltheadgt ltbodygt ltcentergtlth2gt新增連絡人lth2gtltcentergtlthrgt lt 取得欄位資料 if (isset($_POST[Name]) ampamp isset($_POST[Tel]) ) $name = $_POST[Name] $tel = $_POST[Tel] 檢查是否有輸入欄位資料 if ($name = ampamp $tel = ) 建立 SQL字串 $sql = INSERT INTO address (name tel) values( $sql= $name $tel) 建立 MySQL 連結 $link = mysql_connect(localhostroot1234) 選擇資料庫 mysql_select_db(CONTACT) 執行 SQL指令 mysql_query($sql) mysql_close($link) echo ltfont color=redgt新增連絡人成功ltfontgtltbrgt gt ltform action=addphp method=postgt lttable border=0 width=300gt lttrgtlttdgt姓名 lttdgt

54

lttdgtltinput type=text name=Name size=20 maxlength=10gtlttdgtlttrgt lttrgtlttdgt電話 lttdgt lttdgtltinput type=text name=Tel size=20 maxlength=20gtlttdgtlttrgt lttrgtlttd colspan=2 align=centergt ltinput type=submit value=新增連絡人gtlttdgtlttrgt lttablegt ltformgt ltbrgtlta href=indexhtmlgt通訊錄ltagt | lta href=addphpgt新增連絡人ltagt | lta href=searchphpgt搜尋通訊錄ltagt ltbodygt lthtmlgt

lt-- 程式範例searchphp --gt lthtmlgt ltheadgtlttitlegt搜尋通訊錄lttitlegtltheadgt ltbodygt ltcentergtlth2gt搜尋通訊錄lth2gtlthrgt lt if (isset($_POST[Search])) 建立資料庫連結並選定資料庫 $link = mysql_connect(localhostroot1234) mysql_select_db(CONTACT) 建立基本的 SQL字串 $sql = SELECT FROM address 檢查是否輸入姓名 if (chop($_POST[Name]) = ) $name = name LIKE $_POST[Name] else $name = 檢查是否輸入電話號碼 if (chop($_POST[Tel]) = ) $tel = tel LIKE $_POST[Tel] else $tel =

55

if條件組合 SQL字串 if (chop($name) = ampamp chop($tel) = ) $sql= WHERE $name AND $tel elseif (chop($name) = ) 只有姓名 $sql = WHERE $name elseif (chop($tel) = ) 只有電話號碼 $sql = WHERE $tel $sql= ORDER BY name 最後加上排序 $result = mysql_query($sql) 取得欄位數 $total_fields = mysql_num_fields($result) echo lttable border=1gt echo lttrgtlttdgt編號lttdgtlttdgt姓名lttdgtlttdgt電話lttdgtlttd colspan=2gt功能選項lttdgtlttrgt 表格顯示查詢結果 while ($rows = mysql_fetch_array($result MYSQL_NUM)) echo lttrgt for ($i = 0 $i lt $total_fields $i++) echo lttdgt$rows[$i]lttdgt echo lttdgtlta href=editphpaction=editampid= echo $rows[0]gtltbgt編輯ltbgtlttdgt echo lttdgtlta href=editphpaction=delampid= echo $rows[0]gtltbgt刪除ltbgtlttdgt echo lttrgt echo lttablegtlthrgt mysql_free_result($result) mysql_close($link) gt ltcentergt ltform action=searchphp method=postgt lttable border=0 width=450gt lttrgtlttdgt搜尋姓名 lttdgt lttdgtltinput type=text name=Name size=10 maxlength=20gtlttdgtlttrgt lttrgtlttdgt搜尋電話 lttdgt lttdgtltinput type=text name=Tel

56

size=20 maxlength=20gtlttdgtlttrgt lttrgtlttd colspan=2 align=centergt ltinput type=submit name=Search value=搜尋gtlttdgtlttrgt lttablegt ltformgt ltbrgtlta href=indexhtmlgt通訊錄ltagt | lta href=addphpgt新增連絡人ltagt | lta href=searchphpgt搜尋通訊錄ltagt ltbodygt lthtmlgt

lt ob_start() gt lt-- 程式範例editphp --gt lthtmlgt ltheadgtlttitlegt編輯通訊錄lttitlegtltheadgt ltbodygt lt 取得 URL 參數 $id = $_GET[id] $action = $_GET[action] 建立資料庫連結 $link = mysql_connect(localhostroot1234) mysql_select_db(CONTACT) 選擇資料庫 執行的操作 switch ($action) case update 更新 取得欄位資料 $name = $_POST[Name] $tel = $_POST[Tel] $sql = UPDATE address SET name=$name tel=$tel WHERE id=$id mysql_query($sql) 執行 SQL指令 mysql_close($link) header(Location searchphp) 轉向到 serachphp break case del 刪除 $sql = DELETE FROM address WHERE id=$id

57

mysql_query($sql) 執行 SQL指令 mysql_close($link) header(Location searchphp) 轉向到 serachphp break case edit 編輯 $sql = SELECT FROM address WHERE id=$id $result = mysql_query($sql) 執行 SQL指令 $row = mysql_fetch_row($result) 取回記錄 $name = $row[1] 取得欄位 name $tel = $row[2] 取得欄位 tel mysql_close($link) 顯示編輯表單 gt ltcentergtlth2gt更新通訊錄lth2gtltcentergtlthrgt ltform action=editphpaction=updateampid=lt echo $id gt method=postgt lttable border=0 width=300gt lttrgtlttdgt姓名 lttdgt lttdgtltinput type=text name=Name size=20 maxlength=10 value=lt echo $name gtgtlttdgtlttrgt lttrgtlttdgt電話 lttdgt lttdgtltinput type=text name=Tel size=20 maxlength=20 value=lt echo $tel gtgtlttdgtlttrgt lttrgtlttd colspan=2 align=centergt ltinput type=submit value=更新連絡人gtlttdgtlttrgt lttablegt ltformgt ltbrgtlta href=indexhtmlgt通訊錄ltagt | lta href=addphpgt新增連絡人ltagt | lta href=searchphpgt搜尋通訊錄ltagt lt break gt ltbodygt lthtmlgt

58

52 任務二Web Base群組軟體 ( twig )

順利完成Web Base客戶通訊錄程式測試一段時間後「Apache + MySQL + PHP」架構的穩定與快速巳深得老闆與公司所有同事的認同隨著公司業績蒸

蒸日上人員組織編罝愈來愈龐大跨部門的會議愈來愈多業務員每日排滿拜

訪客戶的行程跟客戶的 Email的往來也愈來愈頻繁 愈來愈多部門的同事希望公司能建置一套群組軟體提供 web mail可讓業

務人員方便收發 mail還有連絡人議事日程待辦工作書簽等功能讓整個

公司運作及個人時間管理更有效率

老闆問小明對這些需求有什麼看法小明認為如果這些功能完全由程式部

門開發必定曠日費時而且耗費公司資源小明在網路尋找是否有提供這些功能

的Free Software皇天不負苦心人小明發現了TWIG (The Web Information Gateway) httptwigscrewdrivernet這個群組軟體它在 Web 上整合郵件新聞聯絡人議事日程工作序書簽等功能非常符合公司的需求 Step 1 下載 twig-277targz 下載網址 httptwigscrewdrivernetdownloadphp3

Step 2 解開 twig-277targz tar -xzvf twig-277targz

59

Step 3 執行安裝動作安裝到 varwwwhtmltwig 目錄 cd twig-277 twig-install varwwwhtmltwig

Step 4 建立 MySQL 資料庫(twig)及各資料表

cd setup mysql -u root -p1234 mysqlgt create database twig Query OK 1 row affected (001 sec) mysqlgt quit mysql -u root ndashp1234 twiglt twigtablemysql

Step 5 修改 configincphp3 參數設定 vi varwwwhtmltwigconfigconfigincphp3 $config[fromdomain] = opencom 網域 $config[language] = chinesebig5 中文訊息 $config[imap_port] = 143notls

60

Step 6 修改連結 MySQL 的帳號密碼 vi varwwwhtmltwigconfigdbconfigincphp3 $dbconfig[sqlusername] = root username $dbconfig[sqlpassword] = 1234 password

Step 7 其他設定檔

vi etchttpdconfhttpdconf 加入 AddType applicationx-httpd-php php3 在 DirectoryIndex最後加入 indexphp3 DirectoryIndex indexhtml indexhtmlvar indexphp3 在 AddDefaultCharset ISO-8859-1加上 AddDefaultCharset ISO-8859-1

vi etcphpini register_globals = On service httpd restart Step 8 sendmail 設定 vi etcmailsendmailcf在 264 行前面加上並重新啟動 sendmail「service snedmail restart」 262 SMTP daemon options 263 264 O DaemonPortOptions=Port=smtpAddr=127001 Name=MTA 265 266 SMTP client options 267 O ClientPortOptions=Family=inet Address=00

61

Step 9 檢查設定有無錯誤 http主機名稱twigtestphp3

62

Step 10 登入 twig ( http主機名稱twig)

63

第六章 維護及更新程序

61 日常維護

系統管理員最好定期以 root 身份登入看看信件在 RedHat Linux 中有一支 logwatch 程式會定時去分析 log file如果發現異常便會發信給 root除此之外筆者建議讀者平時就檢查 MySQL log file ( varlogmysqldlog)是否有異常情形

62 更新程序

讀者可至httprpmfindnet 尋找MySQL相關套件至於升級的相關步驟請參

考Linux OS SOP 第 54節

63 備份重要檔案

預設 MySQL 的 DB 檔案是存在 varlibmysql 內以 DB名稱為目錄目錄

內就是該 DB 的所有資料通常得定期備份還有 MySQL的設定檔 etcmycnf也別忘了一起備份

64 離線備份與還原

641 離線備份

預設 MySQL 的 DB 檔案是存在 varlibmysql 內以 DB 名稱為目錄目錄內

就是該 DB 的所有資料像 CRM 這個 DB就是存在 varlibmysqlCRM 內在備份前因為怕資料尚未完全寫入磁碟而且 MySQL 會 Lock 在使用的 DB 檔案所以應該是要先把 MySQL 先 Shutdown 一下整個備份的程序可以下像下面的指令去完成 cd varlibmysql

64

service mysqld stop tar cvfz CRM_db_20030905tgz CRM service mysqld start 對這樣就可以了 不過要注意的是怕 DB 內每個 Tables 間的資料有關關

聯性所以最好是把整個 DB 一次備起來單獨只備哪個 Tables 的檔案以後回存時怕會有資料關聯不一致的問題

642 離線還原

DB 發生錯誤而要回存時其實也不難先找出最近一次完整正常的備份先把現在錯誤的網頁或 DB 先更名或 tar 起來再把好的備份給解開回原來目錄位

置就行了需要注意的是 MySQL 服務最好也是要先停止回存完成後再啟動服務回存 DB 的整個程序可能像下面 cd varlibmysql service mysqldstop mv CRM CRM_OLD tar xvfz CRM_db_20030905tg service mysqld start

65 線上備份與還原

651 線上備份

使用像上面的檔案方式備份是個不錯的方法它最少可以保持該主機某個時間點的完整檔案備份但還是有一些問題需要考慮到有些主機就不只建立一個 DB 而已總不能為了備份某個 DB 而把整個 MySQL 服務停止備份檔案的方式回存在原主機上一定適用但假如 MySQL 版本升級或是在那天該網頁空間需遷機移機到別的主機時那就沒人敢保證備出來的資料檔可以用所以我們可以考慮另一種備份的方式是使用 MySQL 本身提供的功能 MySQL Data Dump指令是 mysqldump

65

使用 MySQL 的 Dump 功能可以把 DB 的結構資料或結構加資料 Dump 成文字檔 mysqldump 指令提供的彈性很大你可以選擇把整個 DB Dump 成一個檔或是每個 Table 為一個檔甚至是把結構檔和資料分開儲存都

可以 mysqladmin -uroot -p flush-logs mysqldump CRM -uroot -p --opt gt CRM_20030905sql (CRM 是 DB 名稱 opt 是一個使用完整 Dump 參數) 假如只是要單獨 Dump 某個 Table 時只要在上面的指令後轉出符號 gt 前加個 Table 名稱就可以如只要 phpbb2_users 這個 Table 的 Dump 時只要下 mysqldump CRM -uroot -p --opt CUSTOMER gt CRM_CUSTOMER_20030905sql

652 線上還原

若要回存整個資料庫只需將壓縮的備份檔還原成 Dump 的檔案再用下面的指令回存 mysql CRM -uroot -p lt CRM_20030905sql 這邊需注意的是若建立備份時是以--opt或--add-drop-table為參數時回存的 動作是先將舊的 Table 先刪除重建 Table 的結構後再把 Data 匯入所以回存後所有的資料會回到你當時備份那個時間點因此在回存資料時可以考慮把現有錯誤或不完整的 DB 先備份一份下來以備不時之需或是拿來比對錯誤的地

方在那裡當然你也可以把資料回存到另一個測試用的 DB 內只要把上面指令

的 DB 名稱改成你的測試用 DB 名稱即可 使用這種回存方式 MySQL 服務不需停止也不會動到其他正在使用的 DB 在一些提供 MySQL 服務的虛擬主機可用這種方式作你自己的 DB 備份及回存

66

另外假如你是系統重建或是移機時切需在新的 MySQL 內新建一個空白 DB 後才行作回存的工作你可以用下面的指令建立 mysql -uroot -p -e CREATE DATABASE CRM (上面的 CRM是你要新建的 DB 名稱) 另一種作法先用 mysql 指令進入 mysql client console 然後再用 CREATE DATABASE CRM 這樣就行了記得尾端要加個 符號該行指令才會執行

67

第七章 問題與解答

Q1RedHat 90預附的 MySQL到底有無支援 Transcation機制 Ans MySQL自 32334a之後的 MySQL-Max版本加入 InnoDB的資料庫類型透過

InnoDBMySQL同樣可以進行 COMMIT與 ROLLRACK的動作RedHat 90預附的 MySQL為 32354a-11巳支援 InnoDB的資料庫類型不過必須做以

下設定 1cp usrsharedocmysql-server-32354amy-mediumcnf to etcmycnf 2 vi etcmycnf 將以下設定前的拿掉 innodb_data_home_dir = varlibmysql innodb_data_file_path = ibdata110Mautoextend innodb_log_group_home_dir = varlibmysql innodb_log_arch_dir = varlibmysql 3service mysqld restart 如此一來各位在建立Table時便可指定Table Type為 innodb ( ex create table with type=innodb ) Q2如何解決 php+mysql 許功蓋等字變亂的問題 Ans 方法一 【確定 MySQL 預設的字元集】 1 打開 WinMySQLadmin 管理畫面(在視窗右下角狀態列紅綠燈圖示中按滑鼠

右鍵點選 Show me 選項) 2 點選管理畫面中 [Variables] 標籤選項其中 character_set變數就是您預設

字元集的變數其預設是 latin1 字元集(我們要將他改回 big5)而 chatacters_set 變數則是 MySQL 可以支援哪些字元集 【修改預設字元集變數 character_set 】 1 請點選管理畫面中 [myini Setup] 標籤選項設定 myini 2 按一下 [Pick-up and Edit myini values] 按鈕以便編輯目前的 myini 設定 3 在 [mysqld] 設定區塊底下新增一行 default-character-set = big5 變數設

68

定 4 新增一個 [client] 設定區塊並加入第三步驟的變數設定(游標往下移到空白處新增兩行 [client] 和 default-character-set=big5) 5 按一下畫面左下方 [Save Modification] 按鈕儲存設定 6 重新啟動 MySQL 或 Windows 方法二 Server端注意事項 phpini 中有關的設定為(預設值) Magic quotes for incoming GETPOSTCookie data magic_quotes_gpc = On Use Sybase-style magic quotes (escape with instead of ) magic_quotes_sybase = Off Client端注意事項 1中文資料送進 mysql 前請用 addslashes($str) 處理 2處理後送進 mysql 時請用 括起來並在參數後留一個空白如 $sql = UPDATE ezf_table set tablename=$tname tableend=$endtime table inguser=$tguser tableingid=$tguserid tableallnumber=$tnumber tableloca l=$tablelocal tableanyone=$tableopen tabletext=$ttext WHERE tableid=$t ableid tablename=$tname c 取出時請用 stripslashes($str) Q3MySQL root 密碼忘了該怎麼辦 Ans 1先停掉 mysql etcrcdinitdmysql stop 2以--skip-grant-table 的參數啟動 mysql safe_mysql --skip-grant-tableamp 3 更改 root 密碼 mysql mysql mysqlgt UPDATE user SET password=password(newpassword)

69

WHERE user=root mysqlgt FLUSH PRIVILEGES mysqlgt exit 4停掉 mysql再重跑 mysqladmin -uroot -p shutdown Enter password 輸入新設定的密碼 etcrcdinitdmysql start

Q4NULL值問題

Ans

NULL值的概念是造成 SQL的新手的混淆的普遍原因他們經常認為 NULL是和一個空字符串的一樣的東西不是這樣的例如下列語句是完全不同的

mysqlgt INSERT INTO my_table (phone) VALUES (NULL)

mysqlgt INSERT INTO my_table (phone) VALUES ()

兩個語句把值插入到 phone 列但是第一個插入一個 NULL值而第二個插入一個空字符串第一個的含義可以認為是ldquo電話號碼不知道而第二個則可意味

著ldquo她沒有電話

在 SQL中NULL值在于任何其他值甚至 NULL值比較時總是假的(FALSE)包含 NULL的一個表達式總是產生一個 NULL值除非在包含在表達式中的運算符和函數的文檔中指出在下列例子所有的列返回 NULL

mysqlgt SELECT NULL1+NULLCONCAT(InvisibleNULL)

如果你想要尋找值是 NULL的列你不能使用=NULL測試下列語句不返回任

何行因為對任何表達式expr = NULL是假的

mysqlgt SELECT FROM my_table WHERE phone = NULL

要想尋找 NULL值你必須使用 IS NULL測試下例顯示如何找出 NULL電話號碼和空的電話號碼

70

mysqlgt SELECT FROM my_table WHERE phone IS NULL mysqlgt SELECT FROM my_table WHERE phone =

在 MySQL中就像很多其他的 SQL服務器一樣你不能索引可以有 NULL值的列你必須聲明這樣的列為 NOT NULL而且你不能插入 NULL到索引的

列中

當用 LOAD DATA INFILE 讀取數據時空列用更新如果你想要在一個列中有

NULL值你應該在文本文件中使用N字面上的詞NULL也可以在某些情形下使用

當使用 ORDER BY時首先呈現 NULL值如果你用 DESC以降序排序NULL值最後顯示當使用 GROUP BY時所有的 NULL值被認為是相等的

為了有助于NULL的處理你能使用 IS NULL和 IS NOT NULL運算符和 IFNULL()函數

對某些列類型NULL值被特殊地處理如果你將 NULL插入表的第一個TIMESTAMP 列則插入當前的日期和時間如果你將 NULL插入一個AUTO_INCREMENT 列則插入順序中的下一個數字

Q5如何將圖片存放於 MySQL中

Ans

Step 1建立資料庫 test

Step 2 建立表格 binary_data

CREATE TABLE binary_data (

id INT(4) NOT NULL AUTO_INCREMENT PRIMARY KEY

description CHAR(50)

bin_data LONGBLOB

filename CHAR(50)

filesize CHAR(50)

filetype CHAR(50)

71

)

Step 3 利用 storephp 寫入圖片

storephp 程式碼

ltHTMLgt ltHEADgtltTITLEgtStore binary data into SQL DatabaseltTITLEgtltHEADgt ltBODYgt lt code that will be executed if the form has been submitted

if ($submit) mysql_connect(localhostrootYOUR_PASSWORD) mysql_select_db(test) $data=Base64_Encode(fread(fopen($form_data r) filesize($form_data))) $result=MYSQL_QUERY(INSERT INTO binary_data (descriptionbin_datafilenamefilesizefiletype) VALUES ($form_description$data$form_data_name$form_data_size$form_data_type)) $id= mysql_insert_id() print ltpgtThis file has the following Database ID ltbgt$idltbgt MYSQL_CLOSE() else else show the form to submit new data

gt

ltform method=post action=ltphp echo $PHP_SELF gt enctype=multipartform-datagt File Descriptionltbrgt ltinput type=text name=form_description size=40gt ltINPUT TYPE=hidden name=MAX_FILE_SIZE value=4000000gt ltbrgtFile to uploadstore in databaseltbrgt ltinput type=file name=form_data size=40gt ltpgtltinput type=submit name=submit value=submitgt ltformgt lt

72

gt ltBODYgt ltHTMLgt

Step 3 利用 storephp 取出圖片

getdataphp 程式碼

lt Syntax getdataphp3id=ltidgt if($id) you may have to modify login information for your database server MYSQL_CONNECT(localhostrootYOUR_PASSWORD) mysql_select_db(test) $query = select bin_datafiletype from binary_data where id=$id $result = MYSQL_QUERY($query) $data = Base64_Decode(MYSQL_RESULT($result0bin_data)) $type = MYSQL_RESULT($result0filetype) Header( Content-type $type) echo $data gt

Q6MySQL裝好之後啟動時或是執行 mysqladmin會出現如下訊息 Cant connect to local MYSQL Server through Socket varlibmysqlmysqlsock或是

Cant connect to local MYSQL Server through Socket tmpmysqldsock

Ans 可能有下列幾個原因

1這個 mysqldsock 不見了被某人刪除了或是被一些系統自動執行程式給刪

了例如有些 cron任務便會設定定期刪除 tmp 裡的東西所以呢您只能修改

cron 裡的設定讓它不要清除 mysqldsock 2在啟動時也可以改變 mysqldsock的位置您在啟動 MySQL的時候可以加入此參數usrlocalmysqlbinsafe_mysqld --user=mysql --socket=其他路

徑socket amp 同時得去設定環境變數 MYSQL_UNIX_PORT的值以指定新的

73

路徑 3若是您沒改 MYSQL_UNIX_PORT的值那麼您可以在執行指令的時候才打

例如mysqladmin --socket=其他路徑socket version Q7How to get the last insert id Ans CREATE TABLE product ( id INT(4) NOT NULL AUTO_INCREMENT PRIMARY KEY description VARCHAR(50) ) 1利用 SQL的話 mysqlgt insert into product(description) values(123) Query OK 1 row affected (000 sec) mysqlgt select last_insert_id() +------------------+ | last_insert_id() | +------------------+ +------------------+ 1 row in set (000 sec) ======================================== 2如果是 PHP的話 你可以用mysql_insert_id()取得該 id PHP example $result=MYSQL_QUERY(INSERT INTO product (description) VALUES ($description)) $id= mysql_insert_id() print This file has the following Database ID $id Q8如何將文字檔匯入資料庫 Ans $addr=homehttpdhtmlphpschool001txt $sql_select = load data infile $addr into table test fields terminated by t 解說 $sql_select = load data infile 文字檔名 into table 表格名 fields terminated by

74

t

(欄位分隔以 TAB鍵) 該文字檔須與資料表欄位格式相符 例如欄位有三個 則文字檔為每行一筆資料如下 欄 1資料ltTABgt欄 2資料ltTABgt欄 3資料 欄 1資料ltTABgt欄 2資料ltTABgt欄 3資料 欄 1資料ltTABgt欄 2資料ltTABgt欄 3資料 欄 1資料ltTABgtltTABgt欄 3資料

Q9如何撰寫 MySQL C API Ans Step 1利用文字編輯器撰寫以下程式碼 mysqlcc

include ltstdiohgt

include ltmysqlmysqlhgt

int main (int argc char argv[])

MYSQL mysql

MYSQL_RES res

MYSQL_ROW row

if (argc = 2)

fputs (Usage myc ltdatabasegt stderr)

return 1

if ((mysql_connect(ampmysqllocalhostrootYour_Password)))

fputs (Error connecting stderr)

abort()

75

if (mysql_select_db(ampmysqlargv[1]))

fputs (Error selecting database stderr)

abort()

if (mysql_query(ampmysqlSELECT FROM test_table))

fputs (Error processing query stderr)

abort()

if ((res = mysql_store_result(ampmysql)))

fputs (Error storing results stderr)

abort()

while((row = mysql_fetch_row(res)))

uint i = 0

for (i=0 i lt mysql_num_fields(res) i++)

printf(s row[i])

printf(n)

return 0

Step 2 Compile

gcc -Iusrlocalmysqlinclude -Lusrlocalmysqllibmysql mysqlcc ndashlm -lmysqlclient

(其中 include path與 library path取決於你的 MySQL安裝路徑)

76

如果執行時發生如下 error Run problemerror in loading shared libraries libmysqlclientsoX 將你的 MySQL library path(for exampleusrlocalmysqllibmysql) 加入etcldsoconf and run sbinldconfig -v Q9ASP + MySQL 範例程式 Ans Dim myconn As New ADODBConnection Dim myrs As New Recordset Dim mySQL As String Dim myrows As Long myconnOpen DSN=MyODBCsample mySQL = SELECT from user myrsSource = mySQL Set myrsActiveConnection = myconn myrsCursorLocation = adUseClient myrsOpen myrows = myrsRecordCount myrsClose myconnClose 可參考 httpwwwdwamnetmysqlasp_myodbcasp 有詳細的資料 Q10如何將 MySQL中的資料庫匯出成txt檔 Ans select from TableName into outfile textxls all result fields will seperate by tab

77

第八章 參考資料

英文部份 網址 1 httpwwwmysqlcom MySQL 網站有第一手有關 MySQL的資料 2 httpwwwmysqlcomdocenReplicationhtml 有關 MySQL Replication 的文件 3 httpwwwgeocitiescomsqlhomefaqstore_blobhtml 如何在 MySQL 存放 BLOB的資料 4httpwwwsapdborg 有關 SAP跟 MySQL相關合作的網站 書藉 1 Cooking with MySQL

Paul DuBois has selected sample recipes from the hundreds youll find in his book MySQL

Cookbook In this third and final series of excerpts showcasing these recipes learn how to

compute team standings how to calculate the differences between successive Dec 26

2002 2 Tips for Building Web Database Applications with PHP and MySQL by Hugh E Williams co-author of Web Database Applications with PHP amp MySQL 04042002

3 Managing and Using MySQL 2nd Edition By Tim King George Reese Randy Jay Yarger

4 MySQL Cookbook By Paul DuBoisPublisher OReillyPub Date October 2002

中文部份

78

1 httplinuxtncedutwtechdocmysqlmysql_docmanual_tochtml MySQL 中文手冊 2 httpchenshloxaedutwphpZ_1php PHP+MySQ程式研習設計網站 3 httplinuxtncedutwtechdocbanicdownhtml PHP 4 手冊 4 httpwwwtncedutwadmin_zonephp台南縣教育網網路中心有很多 Linux相關文件 5 httpdobtncedutw網站建置百寶箱有很多 PHP MySQL 相關範例程式 5 httpwwwdbworldcomtw資料庫專家電子雜誌介紹資料庫的重要觀念及名詞

79

附錄一 SQL Command 介紹

SQL (讀音ess-que-el) 是一種結構查詢語法SQL 使用於資料庫交流

傳遞相容於 ANSI (American National Standards Institute) 是一套標準的關聯

式資料庫語言 SQL 語言是執行更新或從資料系統獲取資料一般常見的關聯

資料庫系統都有提供 SQL 如 Oracle Sybase Microsoft SQL Server Access Ingres 等雖然大部份的資料庫都有提供 SQL 但也多提供了自已獨特的語

法造成了不相容的情形但標準基本的語法是相通的如Select Insert Update Delete Create and Drop 每一個系統都有支援

Table相關 Command

Create Table

關聯式資料庫包含有很多元件稱為資料表(tables) 把資料或訊息放在資

料表中 資料表是以不同的名稱做分別資料表由欄列所構成的二維陣列

欄包含欄位名資料型態 及其他可判斷的資訊列是由全部欄位構成一筆一

筆的紀錄 create table 語法用在建立一個新的資料表語法格式如下

create table tablename (column1 data type column2 data type column3 data type)

Format of create table if you were to use optional constraints

create table tablename (column1 data type [constraint] column2 data type [constraint] column3 data type [constraint]) [ ] = optional

Note You may have as many columns as youd like and the constraints are optional

80

Example

create table employee (first varchar(15) last varchar(20) age number(3) address varchar(30) city varchar(20) state varchar(20))

注意建立資料表格式要以括號把前後框住而最後以(分號)做結尾

欄位名不要超過 30個字元長而且不要使用 sql 的關鍵字(如 where select等)而在後面接是型態的宣告(如字串數字日期格式等)

資料型態是來描述欄位的方式如一個欄位Last_Name 是一個姓氏可以使用varchar (可變動長度字串) 資料型態

以下是幾個常見的資料庫型態 char(size) 固定長度字串最長為 255 位元 varchar(size) 變動長度字串最大字元數以 size 來指定 number(size) 數值格式可以是整數也可以是小數最大數字以 size 位數判

斷未指定小數位數由系統內定 date 日期格式 number(sized) 數值格式最大數字以 size 位數判斷d 為小數位數整數位

數為 size-d 位

有何限制當資料表被建立通常有一或數個欄位是要使用來做關聯的功

能 例如unique 限制(唯一值)兩筆記錄不可以相同的值 not null (非空值)該欄位一定要輸入資料不可是空的primary key (主鍵)是每一筆記錄識別的主要方式

Drop a table drop table 刪除資料表(其中的資料也會一併刪除)

drop table tablename

Example

81

drop table 和刪除全部資料是不同的刪除全部資料欄位名稱資訊等還會

存在但刪除資料表會把這一些也一併移除掉

如何查詢資料

Select 基本用法

select 語法是關連式資料庫最常用的部份可以取得你想要的資料這是一個

簡單的範例 select column1[column2etc] from tablename [where condition] [] = optional 在 select 之後所列欄位名則是要顯示的資料部份你可以一一列出各欄位

名或是以 (星號)來代表選擇全部的欄位 from 之後放資料表名稱 where 子句 (選項) 指定要過濾的條件符合者才會顯現 where 可使用的條件運算元 = 等於 gt 大於 lt 小於 gt= 大或等於 lt= 小或等於 ltgt 大相等 LIKE 相似 For example select first last city

82

from empinfo where first LIKE Er 以Er 為開頭的字串就符合要以單引號框住 Or you can specify select first last from empinfo where last LIKE s 最後一字為 S 就符合 select from empinfo where first = Eric 則表示 first name 一定要是 Eric 才可以 範例資料表empinfo 統計函數

MIN 傳回指定欄位最小值

MAX 傳回指定欄位最大值

SUM 傳回指定欄位總和

AVG 傳回指定欄位平均值

COUNT 傳回指定欄位的筆數

COUNT() 傳回資料庫中的總筆數

統計函數使用於資料表中的數值欄位配合 SELECT 語法使用 只用於總結特定單一欄位可以配合 GROUP BY 做篩選但也可以不使用 GROUP BY 語句For example

SELECT AVG(salary) FROM employee

83

傳回全部 salary 平均值

Another example

SELECT AVG(salary) FROM employee WHERE title = Programmer

傳回 salary 平均值條件為 employees 資料表中當 title 等於 Programmer

Example

SELECT Count() FROM employees

傳回 employees 資料表中紀錄總筆數

GROUP BY 語法 SELECT column1 SUM(column2) FROM list-of-tables GROUP BY column-list The GROUP BY 語句可以先以所列的欄位為條件分組排序在一起(可以多欄

位) example 要列出每一個 dept 中最高 salary 值 SELECT max(salary) dept FROM employee GROUP BY dept HAVING 語法

SELECT column1 SUM(column2) FROM list-of-tables GROUP BY column-list HAVING condition

HAVING 子句是 GROUP BY 的一部份用來過濾在 GROUP BY 所選出的資料功能如同 select 命令中 where 條件式一樣只是 HAVING 必需配合 GROUP BY 使用

我們以例子來說明我們要取得每一公司名及每一公司的薪水平均值輸入如下

84

SELECT dept avg(salary) FROM employee GROUP BY dept

但如果我們只列出薪資平均值超過 20000元的公司資料

SELECT dept avg(salary) FROM employee GROUP BY dept HAVING avg(salary) gt 20000

ORDER BY子句語法

SELECT column1 SUM(column2) FROM list-of-tables ORDER BY column-list [ASC | DESC]

[ ] =選項

ORDER BY是一個選項子句當你以排序方式來顯示資料(正向由小到大反向由大到小)以指定的欄位資料做排序

ASC = 正向- 預設值 DESC = 反向排序

For example

SELECT employee_id dept name age salary FROM employee_info WHERE dept = Sales ORDER BY salary

以上列出公司代號公司名銷售員人名年紀及薪資而條件是公司名為 Sales 顯示順序以薪資多少排序(由小到大為預設值)

如果要以多個欄位做排序要以逗號做分隔如下

SELECT employee_id dept name age salary FROM employee_info WHERE dept = Sales ORDER BY salary age DESC

85

結合條件及布林運算 SELECT column1 SUM(column2) FROM list-of-tables WHERE condition1 AND condition2 AND運算可以結兩個或以上的條件放在 WHERE子句中 兩者都要為真才

會顯示該筆記錄 OR 運算可以結兩個或以上敘述放在 WHERE子句中只要其中一個為直就

會顯示該筆記錄 For example SELECT employeeid firstname lastname title salary FROM employee_info WHERE salary gt= 5000000 AND title = Programmer 必需要薪資大於等於 50000而且職稱為 Programmer同時符合才會顯示該筆資料 以下以括號括住雖然不是必需的但如此比較容易讀 SELECT employeeid firstname lastname title salary FROM employee_info WHERE (salary gt= 5000000) AND (title = Programmer) 另外範例 SELECT firstname lastname title salary FROM employee_info WHERE (title = Sales) OR (title = Programmer) 條件為只要是 Sales 或 Programmer 職稱的就會被列出 IN and BETWEEN 子句

SELECT column1 SUM(column2) FROM list-of-tables WHERE column3 IN (list-of-values) SELECT column1 SUM(column2) FROM list-of-tables WHERE column3 BETWEEN value1 AND value2 IN 子句使用在列舉項目的使用上也就是分別測試是否符合所列的值 For example

86

SELECT employeeid lastname salary FROM employee_info WHERE lastname IN (Hernandez Jones Roberts Ruiz) 條件為姓氏(astname)要符合 Hernandez Jones Roberts or Ruiz 其中一個才會被傳回 IN運算元也可以使用 OR 的語法來取代如下結果相同 SELECT employeeid lastname salary FROM employee_info WHERE lastname = Hernandez OR lastname = Jones OR lastname = Roberts OR lastname = Ruiz 但使用 IN 句子比較短也比較易懂 你也可以使用 NOT IN 來去掉不要的記錄 BETWEEN 運算元使用在判斷是否存在兩個數值之間 For example SELECT employeeid age lastname salary FROM employee_info WHERE age BETWEEN 30 AND 40 傳回年紀 30歲到 40歲之間的資料(含 30及 40歲者) 相同的也可以使用以下語法來達到相同的結果 SELECT employeeid age lastname salary FROM employee_info WHERE age gt= 30 AND age lt= 40 你也可使用 NOT BETWEEN 來濾掉中間值的資料 數學運算 標準 ANSI SQL-92 提供以下運算

87

+ 加

- 減

餘數

餘數為除法後剩整數這不在標準的 ANSI SQL 中但大部份的資料庫都會支

援這運算元以下列出有用的函數雖不在 ANSI SQL-92 提供但一般資料庫

也會支援他們

ABS(x) 傳回 x 絕對值

SIGN(x) returns the sign of input x as -1 0 or 1 (negative zero or positive respectively)

MOD(xy) 餘數 - returns the integer remainder of x divided by y (同 xy)

FLOOR(x) 傳回小或等於 x 的最大整數值

CEILING(x) or CEIL(x)

傳回大或等於 x 的最小整數值

POWER(xy) x的 y 次方

ROUND(x) 把 x 四捨五入為整數

ROUND(xd) 四捨五入取到小數 d 位

SQRT(x) x 開平方

For example SELECT round(salary) firstname FROM employee_info 傳回薪資取到整數位

如何新增資料

insert 加入一筆新紀錄到資料表中 insert into tablename (first_columnlast_column) values (first_valuelast_value) [] = optional Example insert into employee

88

(first last age address city state) values (Luke Duke 45 2130 Boars Nest Hazard Co Georgia) Note 字串要以單引號住如string 數字框住也無妨 insert into 後面接資料表名稱再接以括號括住的欄位名在 values 後括號分別對映各欄位的值 以上的例子新增了一筆名(first) 為 Luke而住所(state) 為 Georgia 的資料

如何刪除資料

delete 可以刪除單筆或多筆紀錄 delete from tablename where columnname OPERATOR value [and|or column OPERATOR value] [ ] = optional Examples delete from employee Note 如果你沒有指定 where 子句那麼全部的紀錄都會被刪除 delete from employee where lastname = May delete from employee where firstname = Mike or firstname = Eric delete from 接著資料表名 再接著是條件式判斷沒有條件式則全部紀錄會

被刪除

如何更新資料

update 用來更新你所指定的記錄要和 WHERE 配合小心使用 語法 update tablename set columnname = newvalue[nextcolumn = newvalue2] where columnname OPERATOR value [and|or column OPERATOR value] [] = optional Examples

89

update phone_book set area_code = 623 where prefix = 979 update phone_book set last_name = Smith prefix=555 suffix=9292 where last_name = Jones update employee set age = age+1 where first_name=Mary and last_name=Williams

90

附錄二Replication

測試環境

RedHat 90 + MySQL 32358 MySQL資料庫路徑 varlibmysql MySQL設定檔 etcmycnf Master IP 1921680100 Slave IP 1921680200 請至下列網址下載最新MySQL 32358套件並利用rpm ndashUvh 更新 httpupdatesredhatcom9enosi386

圖 最新 MySQL 套件

測試架構圖

91

1921680100

1921680200Master Server

erveSlave S r

圖 測試架構圖

測試步驟

Master server 部份 Step1 確認 MasterSlave機器上所裝的 MySQL版本能進行

replication( 32329 or higher ) Step2 在 Master MySQL上開放一個帳號給 Slave mysql ndashu root ndashp mysqlgtGRANT FILE ON TO repl1921680200 IDENTIFIED BY lsquoabc123rsquo mysqlgtq 上面是 Master開放一個帳號 repl密碼 abc123給 IP1921680200有檔案處理

的權限 Step3 shutdown MySQL on the Master mysqladmin ndashu root ndashp shutdown Step4 備份 Master所有資料庫 tar ndashcvf tmpmysql-snapshottar varlibmysql 注意tar的時候MySQL是要在 stop情況下 在mysql (wwwmysqlcom) 網站的FAQ有不用shutdown的方法

92

Step5 在 master機器上修改etcmycnf 在[mysqld]區段內加入參數 log-bin server-id=這邊設定 server-id=1 sql-bin-update-same binlog-do-db=CRM只針對 CRM資料庫做紀錄 Step6 Restart MySQL on the master service mysqld start 此時因為有加入 log-bin 參數因此開始有 index產生了在varlibmysql目錄下

有index檔案紀錄資料庫的異動 log Slave server 部份 Step1 在 slave設定etcmycnf 在[mysqld]區段加入 master-host= master-user= master-password= master-port= server-id= 這邊設定 master-host=1921680100 master-user=repl master-password=abc123 master-port=3306 server-id=2 master-connect-retry=60預設重試間隔 60秒 replicate-do-db=CRM告訴 slave只做 CRM資料庫的更新 log-slave-updates Step2 將 master上的 mysql-snapshottar copy到 slave上 用 ftp傳到 slave的tmp Step3 解壓縮 Master資料庫至 Slave Server上 cd varlib tar xvf tmpmysql-snapshottar chown ndashR mysqlmysql mysql

93

chmod ndashR 770 mysql (視情況) Step4 Restart MySQL on the slave server 這時在varlibmysql目錄會出現 masterinfo此檔案紀錄了 Master MySQL server的資訊

狀況測試

One-way replication

1921680100

1921680200Master Server

erveSlave S r

圖 One-way replication架構圖 Step1 Master跟 Slave網路及服務都正常情況下由 Master端異動資料後 到 Slave端瀏覽資料檢視是否有進行 replication Step2 模擬 Slave Server 當機 可用在於 slave真的當機或是 Slave 不一定需要一直跟 master connect將Slave MySQL server shutdown由 Master端異動資料到 slave端瀏覽此時Slave應該沒有被 replication 更新然後再將 Slave端 MySQL server start起來

預設 60秒後 Slave會嘗試跟 Master要求進行 replication再去 Slave端檢視是否有更新資料

94

Step3 模擬 Master當機因為是設定 One-way replication一旦 Master Server Slave端沒有 Master的 source可以 download Two-way replication 基於 Master當機狀況於是發展雙向 Replication即 1921680100 ( Host A ) 1921680200 ( Host B )都分別擔任 MasterSlave身分

1921680100

1921680200er

Server B MasterSlave Server

Server A MasterSlave Serv

圖 Two-way replication架構圖 以下是針對兩台 MySQL伺服器進行雙向 Replication Step1觀念同單向 replication只是改成 Master也有 Slave身分 Slave也有Master的身分先分別在 Server AServer B 都去 grant一個進行 replication的身分 [A]mysqlgtGRANT FILE ON TO repl1921680200 IDENTIFIED BY lsquoabc123rsquo [B]mysqlgt GRANT FILE ON TO repl1921680100 IDENTIFIED BY lsquoabc123rsquo Step2做完單向 replication後stop Server Aserver B MySQL service此時 AB資料是一樣的

95

修改etcmycnf設定 範例 Server A [mysqld] datadir=varlibmysql socket=varlibmysqlmysqlsock server-id=1 log-bin sql-bin-update-same binlog-do-db=CRM master-host=1921680200 master-user=repl master-password=abc123 log-slave-updates master-connect-retry=60 replicate-do-db=CRM Server B [mysqld] datadir=varlibmysql socket=varlibmysqlmysqlsock server-id=2 log-bin sql-bin-update-same binlog-do-db=CRM master-host=1921680100 master-user=repl master-password=abc123 log-slave-updates master-connect-retry=60 replicate-do-db=CRM 分別 start Server AServer B MySQL後此時雙方都是 MasterSlave身分一旦哪一方資料異動就會通知對方來 replication-若 replication失效則必須將Server AServer B的masterinfo及index00x 都砍掉然後分別 restart MySQL server進行測試檢視成果 實務上通常如果需要做Two-way replication通常會搭配Virtual Server使用

96

在前端架設一台Virtual Server不過此部份不在此份SOP討論範圍內有興趣

的讀者可參考 httpwwwlinuxvirtualserverorg 網站

1921680100 1921680200

Host A MasterSlave Server

Host B MasterSlave Server

Virtual Host

圖 Virtual Server + Two-way replication 架構圖

97

圖 High Availability Linux Virtual Server架構圖

98

  • COSA-SOP-03-006
  • 第一章 簡介
    • 11適用對象 (Audience)
    • 12 MySQL本身
    • 13 MySQL 40版跟50版重大的改進功能
    • 14 各家資料庫軟體比較
      • 第二章 前置需求
      • 第三章 安裝
        • 31 MySQL安裝
        • 32 phpMyAdmin安裝
        • 33 升級及注意事項
          • 第四章 MySQL管理
            • 41 Webmin 管理介面
            • 42 phpMyAdmin 的操作介面
            • 43管理指令介紹
              • 431 利用mysqladmin設定root的密碼
                  • 第五章 實用範例
                    • 51 任務一Web Base客戶通訊錄
                    • 52 任務二Web Base群組軟體 ( twig )
                      • 第六章 維護及更新程序
                        • 61 日常維護
                        • 62 更新程序
                        • 63 備份重要檔案
                        • 64 離線備份與還原
                        • 65 線上備份與還原
                          • 第七章 問題與解答
                          • 第八章 參考資料
                          • 附錄一 SQL Command 介紹
                          • 附錄二Replication
Page 18: DataBase Server Standard Operation Procedureebooks.lib.ntu.edu.tw/1_file/oss/63/93doc4-5.pdf · 業務的公司帶來了不少壓力,譬如微軟,甲骨文 ... 外的錢用在第三方的資料庫產品上,譬如就可以不用再購買甲骨文公司

圖 3-11 下載 phpMyAdmin-253-phptarbz2

Step 2 將 phpMyAdmin-253-phptarbz2收至 tmp 並執行下列指令將其解壓

縮至varwww tar jxvf phpMyAdmin-253-phptarbz ndashC varwwwhtml

圖 3-12 解壓縮安裝 phpMyadmin-253

Step 3 為了操作方便起見建立 Soft link ln ndashs phpMyAdmin-253 phpMyAdmin

圖 3-13 修改 phpMyadmin 設定檔 configincphp

18

Step 4 修改 phpMyadmin 設定檔 configincphp gedit varwwwhtmlphpMyAdminconfigincphp

圖 3-14 configincphp設定檔

Step 5 設定顯示行號以方便修改 configincphp 設定檔

19

圖 3-15 顯示行號

Step 6 修改下列設定 第 39 行 設定 phpMyAdmin的 URL 第 69 行 MySQL Server 的 ip 第 80 行 利用何帳號存取 MySQL 第 81 行 如果 root有設定 password此處即填入 root的 password

30 In most cases you can leave this variable empty as the correct value

31 will be detected automatically However we recommend that you do

32 test to see that the auto-detection code works in your system A good

33 test is to browse a table then edit a row and save it There will be

34 an error message if phpMyAdmin cannot auto-detect the correct value

35

36 If the auto-detection code does work properly you can set to TRUE the

37 $cfg[PmaAbsoluteUri_DisableWarning] variable below

38

39 $cfg[PmaAbsoluteUri] = httpossccosaorgtwphpMyAdmin

hellip

20

hellip

69 $cfg[Servers][$i][host] = localhost MySQL hostname or IP address hellip 80 $cfg[Servers][$i][user] = root MySQL user

81 $cfg[Servers][$i][password] = 1234 MySQL password (only needed

圖 3-16 修改 configincphp

21

圖 3-17 修改 configincphp

圖 3-18 修改 configincphp p

Step 7 設定語系

22

圖 3-19 設定語系

圖 3-20 執行 phpMyAdmin

23

33 升級及注意事項

RedHat 90附的 MySQL版本為 323 MySQL所釋出最新穩定版本為

40若是您不想用系統預附的 323請先利用下列移除之前 323的版本

rpm ndashe mysql-devel rpm ndashe mysql-server rpm ndashe mysql --nodeps 然後到下列網址下載您所想要的版本進行安裝在這裏我們用 4014版為例 Step 1 下載相關套件( httpwwwmysqlcomdownloadsmysql-40html )

圖 3-21 Download MySQL 4014 相關 RPM Step 2 利用 rpm 指令安裝

24

圖 3-22 Install MySQL 4014 相關 RPM

圖 3-23 Install MySQL 4014 相關 RPM

Step 3 啟動 MySQL

25

圖 3-24 啟動 MySQL 4014 並修改密碼

26

第四章 MySQL管理

本章將我們介紹利用WebminphpAdminCommand的方式建立一個名為

CONTACT的資料庫內有一個 address的 Table作為我們客戶通訊錄程式使

用的資料庫

41 Webmin 管理介面

412建立資料庫

Step 1 登入Webmin

圖 4-1 登入WebMin

Step 2 點選伺服器

27

圖 4-2 伺服器畫面

Step 3 點選 MySQL資料庫伺服器

圖 4-3 MySQL資料庫伺服器

28

Step 4 建立一個新的資料庫

圖 4-4 建立 MySQL資料庫

Step 5 建立名為 CONTACT的資料庫

29

圖 4-5 指定資料庫名稱

412 建立資料表

假設我們要建立一個名為 address的 Table其結構如下 欄位名稱 資料型態 長度 說明 id INT (自動編號) 連絡人編號 name varchar文字 20 連絡人姓名 tel Varchar文字 15 連絡人電話 Step 1 選擇 CONTACT資料庫

30

圖 4-6 選擇資料庫

Step 2 指定欄位數目

31

圖 4-7 設定欄位數目

Step 3設定表格欄位屬性

圖 3-8 設定表格欄位屬性

Step 4建立表格資料

32

圖 4-9 建立表格資料

圖 4-10 檢視資料

33

圖 4-11 新增資料

圖 4-12

34

圖 4-13

413 使用者管理

接下來我們要利用Webmin 來建立資料庫使用者並給予某些權限 Step1建立使用者

35

圖 4-14 選擇使用者權限

圖 4-15

36

Step2 賦予權限

圖 4-16

Step3 權限列表

37

圖 4-17

38

42 phpMyAdmin 的操作介面

421建立資料庫

Step 填入資料庫名稱並按「建立」

圖 4-18建立資料庫

422 建立資料表

Step1 填入資料表名稱並指定欄位數量 執行

39

圖 4-19填入資料表名稱並指定欄位數量

Step2 設定欄位屬性

圖 4-20設定欄位屬性

40

Step3 phpMyAdmin會產生相關的 SQL Command

圖 4-21 資料表結構及相關 SQL Command

Step4新增 Record

41

圖 4-22

圖 4-23

42

圖 4-24

圖 4-25

43

423使用者管理

Step1建立使用者

圖 4-26

44

圖 4-27

Step2 給予權限

圖 4-28

Step3權限列表

45

圖 4-29

43管理指令介紹

431 利用 mysqladmin設定 root的密碼

當您在Windows 或 Linux 中安裝好 MySQL後系統會自動幫您建立兩個

帳分別是 root 和 匿名者MySQL的 root 跟 Linux 最高權限使用者 root無關MySQL的 root使用者相當於 MS SQL 中的 sa 帳號擁有最高的 Database管理權限但系統預設 MySQL的 root 是不需要密碼所以通常我們一安裝

MySQL後首要任務便是修改 root的密碼 我們可以利用 mysqladmin工具或是直接修改 MySQL內部資料庫的使用者資

料 mysqladmin ndashu root ndashh cosaexamplecom password lsquo1234rsquo

46

-u 表示使用者帳號root 為 MySQL預設的管理帳號

-h 表示 MySQL主機的主機名稱也可使用 IP Address password 表示使用者的密碼因為字串請使用單引號將密碼括起來 密碼設定完成之後還是可以利用 mysqladmin修改密碼但是你必須提供目前的密碼

432 連線 MySQL

mysql -uroot -p密碼 (-p和密碼之間不能有空白) 或 mysql -uroot -p (此方式會在進入後要求密碼) [rootossc phpMyAdmin] mysql -u root -p1234

Welcome to the MySQL monitor Commands end with or g

Your MySQL connection id is 25 to server version 32354

Type help or h for help Type c to clear the buffer

mysqlgt show databases

+----------+

| Database |

+----------+

| mysql |

| test |

+----------+

2 rows in set (000 sec)

mysqlgt exit

Bye

[rootossc phpMyAdmin]

433 建立資料庫

可利用 mysqladmin指令建立 CONTACT資料庫 mysqladmin -u root -p1234 create CONTACT

47

或是利用 mysql指令 [rootossc bluepage] mysql -u root -p1234 Welcome to the MySQL monitor Commands end with or g Your MySQL connection id is 1057 to server version 32354 Type help or h for help Type c to clear the buffer mysqlgt create database CONTACT Query OK 1 row affected (000 sec) mysqlgt show databases +----------+ | Database | +----------+ | CONTACT | | address | | hello | | mysql | | nuke | | test | +----------+ 6 rows in set (000 sec) mysqlgt exit

434 建立資料表

編寫 adresssql內容如下 -- Table structure for table address CREATE TABLE address ( id int(11) NOT NULL auto_increment name varchar(20) NOT NULL default tel varchar(15) NOT NULL default PRIMARY KEY (id) ) TYPE=MyISAM

48

-- Dumping data for table address INSERT INTO address VALUES (1林小明0800016888) INSERT INTO address VALUES (2黃大雄0800016888) INSERT INTO address VALUES (3劉小芬0800024365) 然後執行此 sql script mysql -u root -p1234 CONTACT lt addresssql 或是利 mysql command [rootossc bluepage] mysql -u root -p1234 Welcome to the MySQL monitor Commands end with or g Your MySQL connection id is 1090 to server version 32354 Type help or h for help Type c to clear the buffer mysqlgt use CONTACT Database changed Database changed mysqlgt CREATE TABLE address ( -gt id int(11) NOT NULL auto_increment -gt name varchar(20) NOT NULL default -gt tel varchar(15) NOT NULL default -gt PRIMARY KEY (id) -gt ) TYPE=MyISAM Query OK 0 rows affected (000 sec) mysqlgt INSERT INTO address VALUES (1林小明0800016888) Query OK 1 row affected (000 sec) mysqlgt INSERT INTO address VALUES (2黃大雄0800016888) Query OK 1 row affected (000 sec) mysqlgt INSERT INTO address VALUES (3劉小芬0800024365) Query OK 1 row affected (000 sec) mysqlgt exit Bye

49

第五章 實用範例

51 任務一Web Base客戶通訊錄

任職於開放科技公司的林小明前些日子在最符合成本效益的條件下快

速地完成公司網站的建置老闆因此對小明讚譽有加最近因為公司存放客戶資

料的 SQL Server主機屢遭病毒攻擊加上作業系統本身的問題當機次數頻繁

老闆希望能儘快把公司的客戶通訊錄程式移轉到較穩定的環境上因為此客戶通

訊錄程式最主要給內部人員使用所以介面美觀並不特別要求只求穩定且能快

速得到查詢結果老闆希望在短時間先看到程式的雛型並鍵入資料對其效率

及穩定性進行測試因為上次小明表現突出所以這次不可能的任務自然又落到

小明身上 小明想來想去既然要快速又穩定他而且又不希望所有人都得安裝 Client

程式於是小明決定)捨棄他的舊愛「Delphi+MS SQL」投向新歡「Apache + MySQL + PHP」利用此架構來設計一個簡單實用的Web Base客戶通訊錄程式

511 Web Base客戶通訊錄架構

此程式需要建立 CONTACT的資料庫並建立 adress Tables其結構如下表建立步驟請參考第三章 欄位名稱 資料型態 長度 說明 id INT (自動編號) 連絡人編號 name varchar文字 20 連絡人姓名 tel Varchar文字 15 連絡人電話 Web Base通訊錄共有下列幾個檔案功能如下表

檔案名稱 說明 Indexhtml Web Base通訊錄首頁 addphp 新增連絡人的 php程式 searchphp 尋找連絡人的 php程式 editphp 具有更新及刪除功能的 php程式

50

我們將這些檔案放至varwwwhtmlbluepage (預設無 bluepage目錄)

512 Web Base通訊錄測試

httpwwwopencombluepage 新增資料

圖 5-1 新增連絡人

圖 5-2 填入資料

51

圖 5-3 新增成功

搜尋及異動資料

圖 5-4 搜尋通訊錄

52

圖 5-5 編輯資料

圖 5-6 更新資料

513 程式內容及說明

lt-- 程式範例indexhtml--gt lthtmlgt ltheadgtlttitlegt通訊錄lttitlegtltheadgt ltbodygt ltcentergt

53

lth2gt通訊錄lth2gtlthrgt lta href=indexhtmlgt通訊錄ltagt | lta href=addphpgt新增連絡人ltagt | lta href=searchphpgt搜尋通訊錄ltagt ltcentergt ltbodygt lthtmlgt lt-- 程式範例addphp --gt lthtmlgt ltheadgtlttitlegt新增連絡人lttitlegtltheadgt ltbodygt ltcentergtlth2gt新增連絡人lth2gtltcentergtlthrgt lt 取得欄位資料 if (isset($_POST[Name]) ampamp isset($_POST[Tel]) ) $name = $_POST[Name] $tel = $_POST[Tel] 檢查是否有輸入欄位資料 if ($name = ampamp $tel = ) 建立 SQL字串 $sql = INSERT INTO address (name tel) values( $sql= $name $tel) 建立 MySQL 連結 $link = mysql_connect(localhostroot1234) 選擇資料庫 mysql_select_db(CONTACT) 執行 SQL指令 mysql_query($sql) mysql_close($link) echo ltfont color=redgt新增連絡人成功ltfontgtltbrgt gt ltform action=addphp method=postgt lttable border=0 width=300gt lttrgtlttdgt姓名 lttdgt

54

lttdgtltinput type=text name=Name size=20 maxlength=10gtlttdgtlttrgt lttrgtlttdgt電話 lttdgt lttdgtltinput type=text name=Tel size=20 maxlength=20gtlttdgtlttrgt lttrgtlttd colspan=2 align=centergt ltinput type=submit value=新增連絡人gtlttdgtlttrgt lttablegt ltformgt ltbrgtlta href=indexhtmlgt通訊錄ltagt | lta href=addphpgt新增連絡人ltagt | lta href=searchphpgt搜尋通訊錄ltagt ltbodygt lthtmlgt

lt-- 程式範例searchphp --gt lthtmlgt ltheadgtlttitlegt搜尋通訊錄lttitlegtltheadgt ltbodygt ltcentergtlth2gt搜尋通訊錄lth2gtlthrgt lt if (isset($_POST[Search])) 建立資料庫連結並選定資料庫 $link = mysql_connect(localhostroot1234) mysql_select_db(CONTACT) 建立基本的 SQL字串 $sql = SELECT FROM address 檢查是否輸入姓名 if (chop($_POST[Name]) = ) $name = name LIKE $_POST[Name] else $name = 檢查是否輸入電話號碼 if (chop($_POST[Tel]) = ) $tel = tel LIKE $_POST[Tel] else $tel =

55

if條件組合 SQL字串 if (chop($name) = ampamp chop($tel) = ) $sql= WHERE $name AND $tel elseif (chop($name) = ) 只有姓名 $sql = WHERE $name elseif (chop($tel) = ) 只有電話號碼 $sql = WHERE $tel $sql= ORDER BY name 最後加上排序 $result = mysql_query($sql) 取得欄位數 $total_fields = mysql_num_fields($result) echo lttable border=1gt echo lttrgtlttdgt編號lttdgtlttdgt姓名lttdgtlttdgt電話lttdgtlttd colspan=2gt功能選項lttdgtlttrgt 表格顯示查詢結果 while ($rows = mysql_fetch_array($result MYSQL_NUM)) echo lttrgt for ($i = 0 $i lt $total_fields $i++) echo lttdgt$rows[$i]lttdgt echo lttdgtlta href=editphpaction=editampid= echo $rows[0]gtltbgt編輯ltbgtlttdgt echo lttdgtlta href=editphpaction=delampid= echo $rows[0]gtltbgt刪除ltbgtlttdgt echo lttrgt echo lttablegtlthrgt mysql_free_result($result) mysql_close($link) gt ltcentergt ltform action=searchphp method=postgt lttable border=0 width=450gt lttrgtlttdgt搜尋姓名 lttdgt lttdgtltinput type=text name=Name size=10 maxlength=20gtlttdgtlttrgt lttrgtlttdgt搜尋電話 lttdgt lttdgtltinput type=text name=Tel

56

size=20 maxlength=20gtlttdgtlttrgt lttrgtlttd colspan=2 align=centergt ltinput type=submit name=Search value=搜尋gtlttdgtlttrgt lttablegt ltformgt ltbrgtlta href=indexhtmlgt通訊錄ltagt | lta href=addphpgt新增連絡人ltagt | lta href=searchphpgt搜尋通訊錄ltagt ltbodygt lthtmlgt

lt ob_start() gt lt-- 程式範例editphp --gt lthtmlgt ltheadgtlttitlegt編輯通訊錄lttitlegtltheadgt ltbodygt lt 取得 URL 參數 $id = $_GET[id] $action = $_GET[action] 建立資料庫連結 $link = mysql_connect(localhostroot1234) mysql_select_db(CONTACT) 選擇資料庫 執行的操作 switch ($action) case update 更新 取得欄位資料 $name = $_POST[Name] $tel = $_POST[Tel] $sql = UPDATE address SET name=$name tel=$tel WHERE id=$id mysql_query($sql) 執行 SQL指令 mysql_close($link) header(Location searchphp) 轉向到 serachphp break case del 刪除 $sql = DELETE FROM address WHERE id=$id

57

mysql_query($sql) 執行 SQL指令 mysql_close($link) header(Location searchphp) 轉向到 serachphp break case edit 編輯 $sql = SELECT FROM address WHERE id=$id $result = mysql_query($sql) 執行 SQL指令 $row = mysql_fetch_row($result) 取回記錄 $name = $row[1] 取得欄位 name $tel = $row[2] 取得欄位 tel mysql_close($link) 顯示編輯表單 gt ltcentergtlth2gt更新通訊錄lth2gtltcentergtlthrgt ltform action=editphpaction=updateampid=lt echo $id gt method=postgt lttable border=0 width=300gt lttrgtlttdgt姓名 lttdgt lttdgtltinput type=text name=Name size=20 maxlength=10 value=lt echo $name gtgtlttdgtlttrgt lttrgtlttdgt電話 lttdgt lttdgtltinput type=text name=Tel size=20 maxlength=20 value=lt echo $tel gtgtlttdgtlttrgt lttrgtlttd colspan=2 align=centergt ltinput type=submit value=更新連絡人gtlttdgtlttrgt lttablegt ltformgt ltbrgtlta href=indexhtmlgt通訊錄ltagt | lta href=addphpgt新增連絡人ltagt | lta href=searchphpgt搜尋通訊錄ltagt lt break gt ltbodygt lthtmlgt

58

52 任務二Web Base群組軟體 ( twig )

順利完成Web Base客戶通訊錄程式測試一段時間後「Apache + MySQL + PHP」架構的穩定與快速巳深得老闆與公司所有同事的認同隨著公司業績蒸

蒸日上人員組織編罝愈來愈龐大跨部門的會議愈來愈多業務員每日排滿拜

訪客戶的行程跟客戶的 Email的往來也愈來愈頻繁 愈來愈多部門的同事希望公司能建置一套群組軟體提供 web mail可讓業

務人員方便收發 mail還有連絡人議事日程待辦工作書簽等功能讓整個

公司運作及個人時間管理更有效率

老闆問小明對這些需求有什麼看法小明認為如果這些功能完全由程式部

門開發必定曠日費時而且耗費公司資源小明在網路尋找是否有提供這些功能

的Free Software皇天不負苦心人小明發現了TWIG (The Web Information Gateway) httptwigscrewdrivernet這個群組軟體它在 Web 上整合郵件新聞聯絡人議事日程工作序書簽等功能非常符合公司的需求 Step 1 下載 twig-277targz 下載網址 httptwigscrewdrivernetdownloadphp3

Step 2 解開 twig-277targz tar -xzvf twig-277targz

59

Step 3 執行安裝動作安裝到 varwwwhtmltwig 目錄 cd twig-277 twig-install varwwwhtmltwig

Step 4 建立 MySQL 資料庫(twig)及各資料表

cd setup mysql -u root -p1234 mysqlgt create database twig Query OK 1 row affected (001 sec) mysqlgt quit mysql -u root ndashp1234 twiglt twigtablemysql

Step 5 修改 configincphp3 參數設定 vi varwwwhtmltwigconfigconfigincphp3 $config[fromdomain] = opencom 網域 $config[language] = chinesebig5 中文訊息 $config[imap_port] = 143notls

60

Step 6 修改連結 MySQL 的帳號密碼 vi varwwwhtmltwigconfigdbconfigincphp3 $dbconfig[sqlusername] = root username $dbconfig[sqlpassword] = 1234 password

Step 7 其他設定檔

vi etchttpdconfhttpdconf 加入 AddType applicationx-httpd-php php3 在 DirectoryIndex最後加入 indexphp3 DirectoryIndex indexhtml indexhtmlvar indexphp3 在 AddDefaultCharset ISO-8859-1加上 AddDefaultCharset ISO-8859-1

vi etcphpini register_globals = On service httpd restart Step 8 sendmail 設定 vi etcmailsendmailcf在 264 行前面加上並重新啟動 sendmail「service snedmail restart」 262 SMTP daemon options 263 264 O DaemonPortOptions=Port=smtpAddr=127001 Name=MTA 265 266 SMTP client options 267 O ClientPortOptions=Family=inet Address=00

61

Step 9 檢查設定有無錯誤 http主機名稱twigtestphp3

62

Step 10 登入 twig ( http主機名稱twig)

63

第六章 維護及更新程序

61 日常維護

系統管理員最好定期以 root 身份登入看看信件在 RedHat Linux 中有一支 logwatch 程式會定時去分析 log file如果發現異常便會發信給 root除此之外筆者建議讀者平時就檢查 MySQL log file ( varlogmysqldlog)是否有異常情形

62 更新程序

讀者可至httprpmfindnet 尋找MySQL相關套件至於升級的相關步驟請參

考Linux OS SOP 第 54節

63 備份重要檔案

預設 MySQL 的 DB 檔案是存在 varlibmysql 內以 DB名稱為目錄目錄

內就是該 DB 的所有資料通常得定期備份還有 MySQL的設定檔 etcmycnf也別忘了一起備份

64 離線備份與還原

641 離線備份

預設 MySQL 的 DB 檔案是存在 varlibmysql 內以 DB 名稱為目錄目錄內

就是該 DB 的所有資料像 CRM 這個 DB就是存在 varlibmysqlCRM 內在備份前因為怕資料尚未完全寫入磁碟而且 MySQL 會 Lock 在使用的 DB 檔案所以應該是要先把 MySQL 先 Shutdown 一下整個備份的程序可以下像下面的指令去完成 cd varlibmysql

64

service mysqld stop tar cvfz CRM_db_20030905tgz CRM service mysqld start 對這樣就可以了 不過要注意的是怕 DB 內每個 Tables 間的資料有關關

聯性所以最好是把整個 DB 一次備起來單獨只備哪個 Tables 的檔案以後回存時怕會有資料關聯不一致的問題

642 離線還原

DB 發生錯誤而要回存時其實也不難先找出最近一次完整正常的備份先把現在錯誤的網頁或 DB 先更名或 tar 起來再把好的備份給解開回原來目錄位

置就行了需要注意的是 MySQL 服務最好也是要先停止回存完成後再啟動服務回存 DB 的整個程序可能像下面 cd varlibmysql service mysqldstop mv CRM CRM_OLD tar xvfz CRM_db_20030905tg service mysqld start

65 線上備份與還原

651 線上備份

使用像上面的檔案方式備份是個不錯的方法它最少可以保持該主機某個時間點的完整檔案備份但還是有一些問題需要考慮到有些主機就不只建立一個 DB 而已總不能為了備份某個 DB 而把整個 MySQL 服務停止備份檔案的方式回存在原主機上一定適用但假如 MySQL 版本升級或是在那天該網頁空間需遷機移機到別的主機時那就沒人敢保證備出來的資料檔可以用所以我們可以考慮另一種備份的方式是使用 MySQL 本身提供的功能 MySQL Data Dump指令是 mysqldump

65

使用 MySQL 的 Dump 功能可以把 DB 的結構資料或結構加資料 Dump 成文字檔 mysqldump 指令提供的彈性很大你可以選擇把整個 DB Dump 成一個檔或是每個 Table 為一個檔甚至是把結構檔和資料分開儲存都

可以 mysqladmin -uroot -p flush-logs mysqldump CRM -uroot -p --opt gt CRM_20030905sql (CRM 是 DB 名稱 opt 是一個使用完整 Dump 參數) 假如只是要單獨 Dump 某個 Table 時只要在上面的指令後轉出符號 gt 前加個 Table 名稱就可以如只要 phpbb2_users 這個 Table 的 Dump 時只要下 mysqldump CRM -uroot -p --opt CUSTOMER gt CRM_CUSTOMER_20030905sql

652 線上還原

若要回存整個資料庫只需將壓縮的備份檔還原成 Dump 的檔案再用下面的指令回存 mysql CRM -uroot -p lt CRM_20030905sql 這邊需注意的是若建立備份時是以--opt或--add-drop-table為參數時回存的 動作是先將舊的 Table 先刪除重建 Table 的結構後再把 Data 匯入所以回存後所有的資料會回到你當時備份那個時間點因此在回存資料時可以考慮把現有錯誤或不完整的 DB 先備份一份下來以備不時之需或是拿來比對錯誤的地

方在那裡當然你也可以把資料回存到另一個測試用的 DB 內只要把上面指令

的 DB 名稱改成你的測試用 DB 名稱即可 使用這種回存方式 MySQL 服務不需停止也不會動到其他正在使用的 DB 在一些提供 MySQL 服務的虛擬主機可用這種方式作你自己的 DB 備份及回存

66

另外假如你是系統重建或是移機時切需在新的 MySQL 內新建一個空白 DB 後才行作回存的工作你可以用下面的指令建立 mysql -uroot -p -e CREATE DATABASE CRM (上面的 CRM是你要新建的 DB 名稱) 另一種作法先用 mysql 指令進入 mysql client console 然後再用 CREATE DATABASE CRM 這樣就行了記得尾端要加個 符號該行指令才會執行

67

第七章 問題與解答

Q1RedHat 90預附的 MySQL到底有無支援 Transcation機制 Ans MySQL自 32334a之後的 MySQL-Max版本加入 InnoDB的資料庫類型透過

InnoDBMySQL同樣可以進行 COMMIT與 ROLLRACK的動作RedHat 90預附的 MySQL為 32354a-11巳支援 InnoDB的資料庫類型不過必須做以

下設定 1cp usrsharedocmysql-server-32354amy-mediumcnf to etcmycnf 2 vi etcmycnf 將以下設定前的拿掉 innodb_data_home_dir = varlibmysql innodb_data_file_path = ibdata110Mautoextend innodb_log_group_home_dir = varlibmysql innodb_log_arch_dir = varlibmysql 3service mysqld restart 如此一來各位在建立Table時便可指定Table Type為 innodb ( ex create table with type=innodb ) Q2如何解決 php+mysql 許功蓋等字變亂的問題 Ans 方法一 【確定 MySQL 預設的字元集】 1 打開 WinMySQLadmin 管理畫面(在視窗右下角狀態列紅綠燈圖示中按滑鼠

右鍵點選 Show me 選項) 2 點選管理畫面中 [Variables] 標籤選項其中 character_set變數就是您預設

字元集的變數其預設是 latin1 字元集(我們要將他改回 big5)而 chatacters_set 變數則是 MySQL 可以支援哪些字元集 【修改預設字元集變數 character_set 】 1 請點選管理畫面中 [myini Setup] 標籤選項設定 myini 2 按一下 [Pick-up and Edit myini values] 按鈕以便編輯目前的 myini 設定 3 在 [mysqld] 設定區塊底下新增一行 default-character-set = big5 變數設

68

定 4 新增一個 [client] 設定區塊並加入第三步驟的變數設定(游標往下移到空白處新增兩行 [client] 和 default-character-set=big5) 5 按一下畫面左下方 [Save Modification] 按鈕儲存設定 6 重新啟動 MySQL 或 Windows 方法二 Server端注意事項 phpini 中有關的設定為(預設值) Magic quotes for incoming GETPOSTCookie data magic_quotes_gpc = On Use Sybase-style magic quotes (escape with instead of ) magic_quotes_sybase = Off Client端注意事項 1中文資料送進 mysql 前請用 addslashes($str) 處理 2處理後送進 mysql 時請用 括起來並在參數後留一個空白如 $sql = UPDATE ezf_table set tablename=$tname tableend=$endtime table inguser=$tguser tableingid=$tguserid tableallnumber=$tnumber tableloca l=$tablelocal tableanyone=$tableopen tabletext=$ttext WHERE tableid=$t ableid tablename=$tname c 取出時請用 stripslashes($str) Q3MySQL root 密碼忘了該怎麼辦 Ans 1先停掉 mysql etcrcdinitdmysql stop 2以--skip-grant-table 的參數啟動 mysql safe_mysql --skip-grant-tableamp 3 更改 root 密碼 mysql mysql mysqlgt UPDATE user SET password=password(newpassword)

69

WHERE user=root mysqlgt FLUSH PRIVILEGES mysqlgt exit 4停掉 mysql再重跑 mysqladmin -uroot -p shutdown Enter password 輸入新設定的密碼 etcrcdinitdmysql start

Q4NULL值問題

Ans

NULL值的概念是造成 SQL的新手的混淆的普遍原因他們經常認為 NULL是和一個空字符串的一樣的東西不是這樣的例如下列語句是完全不同的

mysqlgt INSERT INTO my_table (phone) VALUES (NULL)

mysqlgt INSERT INTO my_table (phone) VALUES ()

兩個語句把值插入到 phone 列但是第一個插入一個 NULL值而第二個插入一個空字符串第一個的含義可以認為是ldquo電話號碼不知道而第二個則可意味

著ldquo她沒有電話

在 SQL中NULL值在于任何其他值甚至 NULL值比較時總是假的(FALSE)包含 NULL的一個表達式總是產生一個 NULL值除非在包含在表達式中的運算符和函數的文檔中指出在下列例子所有的列返回 NULL

mysqlgt SELECT NULL1+NULLCONCAT(InvisibleNULL)

如果你想要尋找值是 NULL的列你不能使用=NULL測試下列語句不返回任

何行因為對任何表達式expr = NULL是假的

mysqlgt SELECT FROM my_table WHERE phone = NULL

要想尋找 NULL值你必須使用 IS NULL測試下例顯示如何找出 NULL電話號碼和空的電話號碼

70

mysqlgt SELECT FROM my_table WHERE phone IS NULL mysqlgt SELECT FROM my_table WHERE phone =

在 MySQL中就像很多其他的 SQL服務器一樣你不能索引可以有 NULL值的列你必須聲明這樣的列為 NOT NULL而且你不能插入 NULL到索引的

列中

當用 LOAD DATA INFILE 讀取數據時空列用更新如果你想要在一個列中有

NULL值你應該在文本文件中使用N字面上的詞NULL也可以在某些情形下使用

當使用 ORDER BY時首先呈現 NULL值如果你用 DESC以降序排序NULL值最後顯示當使用 GROUP BY時所有的 NULL值被認為是相等的

為了有助于NULL的處理你能使用 IS NULL和 IS NOT NULL運算符和 IFNULL()函數

對某些列類型NULL值被特殊地處理如果你將 NULL插入表的第一個TIMESTAMP 列則插入當前的日期和時間如果你將 NULL插入一個AUTO_INCREMENT 列則插入順序中的下一個數字

Q5如何將圖片存放於 MySQL中

Ans

Step 1建立資料庫 test

Step 2 建立表格 binary_data

CREATE TABLE binary_data (

id INT(4) NOT NULL AUTO_INCREMENT PRIMARY KEY

description CHAR(50)

bin_data LONGBLOB

filename CHAR(50)

filesize CHAR(50)

filetype CHAR(50)

71

)

Step 3 利用 storephp 寫入圖片

storephp 程式碼

ltHTMLgt ltHEADgtltTITLEgtStore binary data into SQL DatabaseltTITLEgtltHEADgt ltBODYgt lt code that will be executed if the form has been submitted

if ($submit) mysql_connect(localhostrootYOUR_PASSWORD) mysql_select_db(test) $data=Base64_Encode(fread(fopen($form_data r) filesize($form_data))) $result=MYSQL_QUERY(INSERT INTO binary_data (descriptionbin_datafilenamefilesizefiletype) VALUES ($form_description$data$form_data_name$form_data_size$form_data_type)) $id= mysql_insert_id() print ltpgtThis file has the following Database ID ltbgt$idltbgt MYSQL_CLOSE() else else show the form to submit new data

gt

ltform method=post action=ltphp echo $PHP_SELF gt enctype=multipartform-datagt File Descriptionltbrgt ltinput type=text name=form_description size=40gt ltINPUT TYPE=hidden name=MAX_FILE_SIZE value=4000000gt ltbrgtFile to uploadstore in databaseltbrgt ltinput type=file name=form_data size=40gt ltpgtltinput type=submit name=submit value=submitgt ltformgt lt

72

gt ltBODYgt ltHTMLgt

Step 3 利用 storephp 取出圖片

getdataphp 程式碼

lt Syntax getdataphp3id=ltidgt if($id) you may have to modify login information for your database server MYSQL_CONNECT(localhostrootYOUR_PASSWORD) mysql_select_db(test) $query = select bin_datafiletype from binary_data where id=$id $result = MYSQL_QUERY($query) $data = Base64_Decode(MYSQL_RESULT($result0bin_data)) $type = MYSQL_RESULT($result0filetype) Header( Content-type $type) echo $data gt

Q6MySQL裝好之後啟動時或是執行 mysqladmin會出現如下訊息 Cant connect to local MYSQL Server through Socket varlibmysqlmysqlsock或是

Cant connect to local MYSQL Server through Socket tmpmysqldsock

Ans 可能有下列幾個原因

1這個 mysqldsock 不見了被某人刪除了或是被一些系統自動執行程式給刪

了例如有些 cron任務便會設定定期刪除 tmp 裡的東西所以呢您只能修改

cron 裡的設定讓它不要清除 mysqldsock 2在啟動時也可以改變 mysqldsock的位置您在啟動 MySQL的時候可以加入此參數usrlocalmysqlbinsafe_mysqld --user=mysql --socket=其他路

徑socket amp 同時得去設定環境變數 MYSQL_UNIX_PORT的值以指定新的

73

路徑 3若是您沒改 MYSQL_UNIX_PORT的值那麼您可以在執行指令的時候才打

例如mysqladmin --socket=其他路徑socket version Q7How to get the last insert id Ans CREATE TABLE product ( id INT(4) NOT NULL AUTO_INCREMENT PRIMARY KEY description VARCHAR(50) ) 1利用 SQL的話 mysqlgt insert into product(description) values(123) Query OK 1 row affected (000 sec) mysqlgt select last_insert_id() +------------------+ | last_insert_id() | +------------------+ +------------------+ 1 row in set (000 sec) ======================================== 2如果是 PHP的話 你可以用mysql_insert_id()取得該 id PHP example $result=MYSQL_QUERY(INSERT INTO product (description) VALUES ($description)) $id= mysql_insert_id() print This file has the following Database ID $id Q8如何將文字檔匯入資料庫 Ans $addr=homehttpdhtmlphpschool001txt $sql_select = load data infile $addr into table test fields terminated by t 解說 $sql_select = load data infile 文字檔名 into table 表格名 fields terminated by

74

t

(欄位分隔以 TAB鍵) 該文字檔須與資料表欄位格式相符 例如欄位有三個 則文字檔為每行一筆資料如下 欄 1資料ltTABgt欄 2資料ltTABgt欄 3資料 欄 1資料ltTABgt欄 2資料ltTABgt欄 3資料 欄 1資料ltTABgt欄 2資料ltTABgt欄 3資料 欄 1資料ltTABgtltTABgt欄 3資料

Q9如何撰寫 MySQL C API Ans Step 1利用文字編輯器撰寫以下程式碼 mysqlcc

include ltstdiohgt

include ltmysqlmysqlhgt

int main (int argc char argv[])

MYSQL mysql

MYSQL_RES res

MYSQL_ROW row

if (argc = 2)

fputs (Usage myc ltdatabasegt stderr)

return 1

if ((mysql_connect(ampmysqllocalhostrootYour_Password)))

fputs (Error connecting stderr)

abort()

75

if (mysql_select_db(ampmysqlargv[1]))

fputs (Error selecting database stderr)

abort()

if (mysql_query(ampmysqlSELECT FROM test_table))

fputs (Error processing query stderr)

abort()

if ((res = mysql_store_result(ampmysql)))

fputs (Error storing results stderr)

abort()

while((row = mysql_fetch_row(res)))

uint i = 0

for (i=0 i lt mysql_num_fields(res) i++)

printf(s row[i])

printf(n)

return 0

Step 2 Compile

gcc -Iusrlocalmysqlinclude -Lusrlocalmysqllibmysql mysqlcc ndashlm -lmysqlclient

(其中 include path與 library path取決於你的 MySQL安裝路徑)

76

如果執行時發生如下 error Run problemerror in loading shared libraries libmysqlclientsoX 將你的 MySQL library path(for exampleusrlocalmysqllibmysql) 加入etcldsoconf and run sbinldconfig -v Q9ASP + MySQL 範例程式 Ans Dim myconn As New ADODBConnection Dim myrs As New Recordset Dim mySQL As String Dim myrows As Long myconnOpen DSN=MyODBCsample mySQL = SELECT from user myrsSource = mySQL Set myrsActiveConnection = myconn myrsCursorLocation = adUseClient myrsOpen myrows = myrsRecordCount myrsClose myconnClose 可參考 httpwwwdwamnetmysqlasp_myodbcasp 有詳細的資料 Q10如何將 MySQL中的資料庫匯出成txt檔 Ans select from TableName into outfile textxls all result fields will seperate by tab

77

第八章 參考資料

英文部份 網址 1 httpwwwmysqlcom MySQL 網站有第一手有關 MySQL的資料 2 httpwwwmysqlcomdocenReplicationhtml 有關 MySQL Replication 的文件 3 httpwwwgeocitiescomsqlhomefaqstore_blobhtml 如何在 MySQL 存放 BLOB的資料 4httpwwwsapdborg 有關 SAP跟 MySQL相關合作的網站 書藉 1 Cooking with MySQL

Paul DuBois has selected sample recipes from the hundreds youll find in his book MySQL

Cookbook In this third and final series of excerpts showcasing these recipes learn how to

compute team standings how to calculate the differences between successive Dec 26

2002 2 Tips for Building Web Database Applications with PHP and MySQL by Hugh E Williams co-author of Web Database Applications with PHP amp MySQL 04042002

3 Managing and Using MySQL 2nd Edition By Tim King George Reese Randy Jay Yarger

4 MySQL Cookbook By Paul DuBoisPublisher OReillyPub Date October 2002

中文部份

78

1 httplinuxtncedutwtechdocmysqlmysql_docmanual_tochtml MySQL 中文手冊 2 httpchenshloxaedutwphpZ_1php PHP+MySQ程式研習設計網站 3 httplinuxtncedutwtechdocbanicdownhtml PHP 4 手冊 4 httpwwwtncedutwadmin_zonephp台南縣教育網網路中心有很多 Linux相關文件 5 httpdobtncedutw網站建置百寶箱有很多 PHP MySQL 相關範例程式 5 httpwwwdbworldcomtw資料庫專家電子雜誌介紹資料庫的重要觀念及名詞

79

附錄一 SQL Command 介紹

SQL (讀音ess-que-el) 是一種結構查詢語法SQL 使用於資料庫交流

傳遞相容於 ANSI (American National Standards Institute) 是一套標準的關聯

式資料庫語言 SQL 語言是執行更新或從資料系統獲取資料一般常見的關聯

資料庫系統都有提供 SQL 如 Oracle Sybase Microsoft SQL Server Access Ingres 等雖然大部份的資料庫都有提供 SQL 但也多提供了自已獨特的語

法造成了不相容的情形但標準基本的語法是相通的如Select Insert Update Delete Create and Drop 每一個系統都有支援

Table相關 Command

Create Table

關聯式資料庫包含有很多元件稱為資料表(tables) 把資料或訊息放在資

料表中 資料表是以不同的名稱做分別資料表由欄列所構成的二維陣列

欄包含欄位名資料型態 及其他可判斷的資訊列是由全部欄位構成一筆一

筆的紀錄 create table 語法用在建立一個新的資料表語法格式如下

create table tablename (column1 data type column2 data type column3 data type)

Format of create table if you were to use optional constraints

create table tablename (column1 data type [constraint] column2 data type [constraint] column3 data type [constraint]) [ ] = optional

Note You may have as many columns as youd like and the constraints are optional

80

Example

create table employee (first varchar(15) last varchar(20) age number(3) address varchar(30) city varchar(20) state varchar(20))

注意建立資料表格式要以括號把前後框住而最後以(分號)做結尾

欄位名不要超過 30個字元長而且不要使用 sql 的關鍵字(如 where select等)而在後面接是型態的宣告(如字串數字日期格式等)

資料型態是來描述欄位的方式如一個欄位Last_Name 是一個姓氏可以使用varchar (可變動長度字串) 資料型態

以下是幾個常見的資料庫型態 char(size) 固定長度字串最長為 255 位元 varchar(size) 變動長度字串最大字元數以 size 來指定 number(size) 數值格式可以是整數也可以是小數最大數字以 size 位數判

斷未指定小數位數由系統內定 date 日期格式 number(sized) 數值格式最大數字以 size 位數判斷d 為小數位數整數位

數為 size-d 位

有何限制當資料表被建立通常有一或數個欄位是要使用來做關聯的功

能 例如unique 限制(唯一值)兩筆記錄不可以相同的值 not null (非空值)該欄位一定要輸入資料不可是空的primary key (主鍵)是每一筆記錄識別的主要方式

Drop a table drop table 刪除資料表(其中的資料也會一併刪除)

drop table tablename

Example

81

drop table 和刪除全部資料是不同的刪除全部資料欄位名稱資訊等還會

存在但刪除資料表會把這一些也一併移除掉

如何查詢資料

Select 基本用法

select 語法是關連式資料庫最常用的部份可以取得你想要的資料這是一個

簡單的範例 select column1[column2etc] from tablename [where condition] [] = optional 在 select 之後所列欄位名則是要顯示的資料部份你可以一一列出各欄位

名或是以 (星號)來代表選擇全部的欄位 from 之後放資料表名稱 where 子句 (選項) 指定要過濾的條件符合者才會顯現 where 可使用的條件運算元 = 等於 gt 大於 lt 小於 gt= 大或等於 lt= 小或等於 ltgt 大相等 LIKE 相似 For example select first last city

82

from empinfo where first LIKE Er 以Er 為開頭的字串就符合要以單引號框住 Or you can specify select first last from empinfo where last LIKE s 最後一字為 S 就符合 select from empinfo where first = Eric 則表示 first name 一定要是 Eric 才可以 範例資料表empinfo 統計函數

MIN 傳回指定欄位最小值

MAX 傳回指定欄位最大值

SUM 傳回指定欄位總和

AVG 傳回指定欄位平均值

COUNT 傳回指定欄位的筆數

COUNT() 傳回資料庫中的總筆數

統計函數使用於資料表中的數值欄位配合 SELECT 語法使用 只用於總結特定單一欄位可以配合 GROUP BY 做篩選但也可以不使用 GROUP BY 語句For example

SELECT AVG(salary) FROM employee

83

傳回全部 salary 平均值

Another example

SELECT AVG(salary) FROM employee WHERE title = Programmer

傳回 salary 平均值條件為 employees 資料表中當 title 等於 Programmer

Example

SELECT Count() FROM employees

傳回 employees 資料表中紀錄總筆數

GROUP BY 語法 SELECT column1 SUM(column2) FROM list-of-tables GROUP BY column-list The GROUP BY 語句可以先以所列的欄位為條件分組排序在一起(可以多欄

位) example 要列出每一個 dept 中最高 salary 值 SELECT max(salary) dept FROM employee GROUP BY dept HAVING 語法

SELECT column1 SUM(column2) FROM list-of-tables GROUP BY column-list HAVING condition

HAVING 子句是 GROUP BY 的一部份用來過濾在 GROUP BY 所選出的資料功能如同 select 命令中 where 條件式一樣只是 HAVING 必需配合 GROUP BY 使用

我們以例子來說明我們要取得每一公司名及每一公司的薪水平均值輸入如下

84

SELECT dept avg(salary) FROM employee GROUP BY dept

但如果我們只列出薪資平均值超過 20000元的公司資料

SELECT dept avg(salary) FROM employee GROUP BY dept HAVING avg(salary) gt 20000

ORDER BY子句語法

SELECT column1 SUM(column2) FROM list-of-tables ORDER BY column-list [ASC | DESC]

[ ] =選項

ORDER BY是一個選項子句當你以排序方式來顯示資料(正向由小到大反向由大到小)以指定的欄位資料做排序

ASC = 正向- 預設值 DESC = 反向排序

For example

SELECT employee_id dept name age salary FROM employee_info WHERE dept = Sales ORDER BY salary

以上列出公司代號公司名銷售員人名年紀及薪資而條件是公司名為 Sales 顯示順序以薪資多少排序(由小到大為預設值)

如果要以多個欄位做排序要以逗號做分隔如下

SELECT employee_id dept name age salary FROM employee_info WHERE dept = Sales ORDER BY salary age DESC

85

結合條件及布林運算 SELECT column1 SUM(column2) FROM list-of-tables WHERE condition1 AND condition2 AND運算可以結兩個或以上的條件放在 WHERE子句中 兩者都要為真才

會顯示該筆記錄 OR 運算可以結兩個或以上敘述放在 WHERE子句中只要其中一個為直就

會顯示該筆記錄 For example SELECT employeeid firstname lastname title salary FROM employee_info WHERE salary gt= 5000000 AND title = Programmer 必需要薪資大於等於 50000而且職稱為 Programmer同時符合才會顯示該筆資料 以下以括號括住雖然不是必需的但如此比較容易讀 SELECT employeeid firstname lastname title salary FROM employee_info WHERE (salary gt= 5000000) AND (title = Programmer) 另外範例 SELECT firstname lastname title salary FROM employee_info WHERE (title = Sales) OR (title = Programmer) 條件為只要是 Sales 或 Programmer 職稱的就會被列出 IN and BETWEEN 子句

SELECT column1 SUM(column2) FROM list-of-tables WHERE column3 IN (list-of-values) SELECT column1 SUM(column2) FROM list-of-tables WHERE column3 BETWEEN value1 AND value2 IN 子句使用在列舉項目的使用上也就是分別測試是否符合所列的值 For example

86

SELECT employeeid lastname salary FROM employee_info WHERE lastname IN (Hernandez Jones Roberts Ruiz) 條件為姓氏(astname)要符合 Hernandez Jones Roberts or Ruiz 其中一個才會被傳回 IN運算元也可以使用 OR 的語法來取代如下結果相同 SELECT employeeid lastname salary FROM employee_info WHERE lastname = Hernandez OR lastname = Jones OR lastname = Roberts OR lastname = Ruiz 但使用 IN 句子比較短也比較易懂 你也可以使用 NOT IN 來去掉不要的記錄 BETWEEN 運算元使用在判斷是否存在兩個數值之間 For example SELECT employeeid age lastname salary FROM employee_info WHERE age BETWEEN 30 AND 40 傳回年紀 30歲到 40歲之間的資料(含 30及 40歲者) 相同的也可以使用以下語法來達到相同的結果 SELECT employeeid age lastname salary FROM employee_info WHERE age gt= 30 AND age lt= 40 你也可使用 NOT BETWEEN 來濾掉中間值的資料 數學運算 標準 ANSI SQL-92 提供以下運算

87

+ 加

- 減

餘數

餘數為除法後剩整數這不在標準的 ANSI SQL 中但大部份的資料庫都會支

援這運算元以下列出有用的函數雖不在 ANSI SQL-92 提供但一般資料庫

也會支援他們

ABS(x) 傳回 x 絕對值

SIGN(x) returns the sign of input x as -1 0 or 1 (negative zero or positive respectively)

MOD(xy) 餘數 - returns the integer remainder of x divided by y (同 xy)

FLOOR(x) 傳回小或等於 x 的最大整數值

CEILING(x) or CEIL(x)

傳回大或等於 x 的最小整數值

POWER(xy) x的 y 次方

ROUND(x) 把 x 四捨五入為整數

ROUND(xd) 四捨五入取到小數 d 位

SQRT(x) x 開平方

For example SELECT round(salary) firstname FROM employee_info 傳回薪資取到整數位

如何新增資料

insert 加入一筆新紀錄到資料表中 insert into tablename (first_columnlast_column) values (first_valuelast_value) [] = optional Example insert into employee

88

(first last age address city state) values (Luke Duke 45 2130 Boars Nest Hazard Co Georgia) Note 字串要以單引號住如string 數字框住也無妨 insert into 後面接資料表名稱再接以括號括住的欄位名在 values 後括號分別對映各欄位的值 以上的例子新增了一筆名(first) 為 Luke而住所(state) 為 Georgia 的資料

如何刪除資料

delete 可以刪除單筆或多筆紀錄 delete from tablename where columnname OPERATOR value [and|or column OPERATOR value] [ ] = optional Examples delete from employee Note 如果你沒有指定 where 子句那麼全部的紀錄都會被刪除 delete from employee where lastname = May delete from employee where firstname = Mike or firstname = Eric delete from 接著資料表名 再接著是條件式判斷沒有條件式則全部紀錄會

被刪除

如何更新資料

update 用來更新你所指定的記錄要和 WHERE 配合小心使用 語法 update tablename set columnname = newvalue[nextcolumn = newvalue2] where columnname OPERATOR value [and|or column OPERATOR value] [] = optional Examples

89

update phone_book set area_code = 623 where prefix = 979 update phone_book set last_name = Smith prefix=555 suffix=9292 where last_name = Jones update employee set age = age+1 where first_name=Mary and last_name=Williams

90

附錄二Replication

測試環境

RedHat 90 + MySQL 32358 MySQL資料庫路徑 varlibmysql MySQL設定檔 etcmycnf Master IP 1921680100 Slave IP 1921680200 請至下列網址下載最新MySQL 32358套件並利用rpm ndashUvh 更新 httpupdatesredhatcom9enosi386

圖 最新 MySQL 套件

測試架構圖

91

1921680100

1921680200Master Server

erveSlave S r

圖 測試架構圖

測試步驟

Master server 部份 Step1 確認 MasterSlave機器上所裝的 MySQL版本能進行

replication( 32329 or higher ) Step2 在 Master MySQL上開放一個帳號給 Slave mysql ndashu root ndashp mysqlgtGRANT FILE ON TO repl1921680200 IDENTIFIED BY lsquoabc123rsquo mysqlgtq 上面是 Master開放一個帳號 repl密碼 abc123給 IP1921680200有檔案處理

的權限 Step3 shutdown MySQL on the Master mysqladmin ndashu root ndashp shutdown Step4 備份 Master所有資料庫 tar ndashcvf tmpmysql-snapshottar varlibmysql 注意tar的時候MySQL是要在 stop情況下 在mysql (wwwmysqlcom) 網站的FAQ有不用shutdown的方法

92

Step5 在 master機器上修改etcmycnf 在[mysqld]區段內加入參數 log-bin server-id=這邊設定 server-id=1 sql-bin-update-same binlog-do-db=CRM只針對 CRM資料庫做紀錄 Step6 Restart MySQL on the master service mysqld start 此時因為有加入 log-bin 參數因此開始有 index產生了在varlibmysql目錄下

有index檔案紀錄資料庫的異動 log Slave server 部份 Step1 在 slave設定etcmycnf 在[mysqld]區段加入 master-host= master-user= master-password= master-port= server-id= 這邊設定 master-host=1921680100 master-user=repl master-password=abc123 master-port=3306 server-id=2 master-connect-retry=60預設重試間隔 60秒 replicate-do-db=CRM告訴 slave只做 CRM資料庫的更新 log-slave-updates Step2 將 master上的 mysql-snapshottar copy到 slave上 用 ftp傳到 slave的tmp Step3 解壓縮 Master資料庫至 Slave Server上 cd varlib tar xvf tmpmysql-snapshottar chown ndashR mysqlmysql mysql

93

chmod ndashR 770 mysql (視情況) Step4 Restart MySQL on the slave server 這時在varlibmysql目錄會出現 masterinfo此檔案紀錄了 Master MySQL server的資訊

狀況測試

One-way replication

1921680100

1921680200Master Server

erveSlave S r

圖 One-way replication架構圖 Step1 Master跟 Slave網路及服務都正常情況下由 Master端異動資料後 到 Slave端瀏覽資料檢視是否有進行 replication Step2 模擬 Slave Server 當機 可用在於 slave真的當機或是 Slave 不一定需要一直跟 master connect將Slave MySQL server shutdown由 Master端異動資料到 slave端瀏覽此時Slave應該沒有被 replication 更新然後再將 Slave端 MySQL server start起來

預設 60秒後 Slave會嘗試跟 Master要求進行 replication再去 Slave端檢視是否有更新資料

94

Step3 模擬 Master當機因為是設定 One-way replication一旦 Master Server Slave端沒有 Master的 source可以 download Two-way replication 基於 Master當機狀況於是發展雙向 Replication即 1921680100 ( Host A ) 1921680200 ( Host B )都分別擔任 MasterSlave身分

1921680100

1921680200er

Server B MasterSlave Server

Server A MasterSlave Serv

圖 Two-way replication架構圖 以下是針對兩台 MySQL伺服器進行雙向 Replication Step1觀念同單向 replication只是改成 Master也有 Slave身分 Slave也有Master的身分先分別在 Server AServer B 都去 grant一個進行 replication的身分 [A]mysqlgtGRANT FILE ON TO repl1921680200 IDENTIFIED BY lsquoabc123rsquo [B]mysqlgt GRANT FILE ON TO repl1921680100 IDENTIFIED BY lsquoabc123rsquo Step2做完單向 replication後stop Server Aserver B MySQL service此時 AB資料是一樣的

95

修改etcmycnf設定 範例 Server A [mysqld] datadir=varlibmysql socket=varlibmysqlmysqlsock server-id=1 log-bin sql-bin-update-same binlog-do-db=CRM master-host=1921680200 master-user=repl master-password=abc123 log-slave-updates master-connect-retry=60 replicate-do-db=CRM Server B [mysqld] datadir=varlibmysql socket=varlibmysqlmysqlsock server-id=2 log-bin sql-bin-update-same binlog-do-db=CRM master-host=1921680100 master-user=repl master-password=abc123 log-slave-updates master-connect-retry=60 replicate-do-db=CRM 分別 start Server AServer B MySQL後此時雙方都是 MasterSlave身分一旦哪一方資料異動就會通知對方來 replication-若 replication失效則必須將Server AServer B的masterinfo及index00x 都砍掉然後分別 restart MySQL server進行測試檢視成果 實務上通常如果需要做Two-way replication通常會搭配Virtual Server使用

96

在前端架設一台Virtual Server不過此部份不在此份SOP討論範圍內有興趣

的讀者可參考 httpwwwlinuxvirtualserverorg 網站

1921680100 1921680200

Host A MasterSlave Server

Host B MasterSlave Server

Virtual Host

圖 Virtual Server + Two-way replication 架構圖

97

圖 High Availability Linux Virtual Server架構圖

98

  • COSA-SOP-03-006
  • 第一章 簡介
    • 11適用對象 (Audience)
    • 12 MySQL本身
    • 13 MySQL 40版跟50版重大的改進功能
    • 14 各家資料庫軟體比較
      • 第二章 前置需求
      • 第三章 安裝
        • 31 MySQL安裝
        • 32 phpMyAdmin安裝
        • 33 升級及注意事項
          • 第四章 MySQL管理
            • 41 Webmin 管理介面
            • 42 phpMyAdmin 的操作介面
            • 43管理指令介紹
              • 431 利用mysqladmin設定root的密碼
                  • 第五章 實用範例
                    • 51 任務一Web Base客戶通訊錄
                    • 52 任務二Web Base群組軟體 ( twig )
                      • 第六章 維護及更新程序
                        • 61 日常維護
                        • 62 更新程序
                        • 63 備份重要檔案
                        • 64 離線備份與還原
                        • 65 線上備份與還原
                          • 第七章 問題與解答
                          • 第八章 參考資料
                          • 附錄一 SQL Command 介紹
                          • 附錄二Replication
Page 19: DataBase Server Standard Operation Procedureebooks.lib.ntu.edu.tw/1_file/oss/63/93doc4-5.pdf · 業務的公司帶來了不少壓力,譬如微軟,甲骨文 ... 外的錢用在第三方的資料庫產品上,譬如就可以不用再購買甲骨文公司

Step 4 修改 phpMyadmin 設定檔 configincphp gedit varwwwhtmlphpMyAdminconfigincphp

圖 3-14 configincphp設定檔

Step 5 設定顯示行號以方便修改 configincphp 設定檔

19

圖 3-15 顯示行號

Step 6 修改下列設定 第 39 行 設定 phpMyAdmin的 URL 第 69 行 MySQL Server 的 ip 第 80 行 利用何帳號存取 MySQL 第 81 行 如果 root有設定 password此處即填入 root的 password

30 In most cases you can leave this variable empty as the correct value

31 will be detected automatically However we recommend that you do

32 test to see that the auto-detection code works in your system A good

33 test is to browse a table then edit a row and save it There will be

34 an error message if phpMyAdmin cannot auto-detect the correct value

35

36 If the auto-detection code does work properly you can set to TRUE the

37 $cfg[PmaAbsoluteUri_DisableWarning] variable below

38

39 $cfg[PmaAbsoluteUri] = httpossccosaorgtwphpMyAdmin

hellip

20

hellip

69 $cfg[Servers][$i][host] = localhost MySQL hostname or IP address hellip 80 $cfg[Servers][$i][user] = root MySQL user

81 $cfg[Servers][$i][password] = 1234 MySQL password (only needed

圖 3-16 修改 configincphp

21

圖 3-17 修改 configincphp

圖 3-18 修改 configincphp p

Step 7 設定語系

22

圖 3-19 設定語系

圖 3-20 執行 phpMyAdmin

23

33 升級及注意事項

RedHat 90附的 MySQL版本為 323 MySQL所釋出最新穩定版本為

40若是您不想用系統預附的 323請先利用下列移除之前 323的版本

rpm ndashe mysql-devel rpm ndashe mysql-server rpm ndashe mysql --nodeps 然後到下列網址下載您所想要的版本進行安裝在這裏我們用 4014版為例 Step 1 下載相關套件( httpwwwmysqlcomdownloadsmysql-40html )

圖 3-21 Download MySQL 4014 相關 RPM Step 2 利用 rpm 指令安裝

24

圖 3-22 Install MySQL 4014 相關 RPM

圖 3-23 Install MySQL 4014 相關 RPM

Step 3 啟動 MySQL

25

圖 3-24 啟動 MySQL 4014 並修改密碼

26

第四章 MySQL管理

本章將我們介紹利用WebminphpAdminCommand的方式建立一個名為

CONTACT的資料庫內有一個 address的 Table作為我們客戶通訊錄程式使

用的資料庫

41 Webmin 管理介面

412建立資料庫

Step 1 登入Webmin

圖 4-1 登入WebMin

Step 2 點選伺服器

27

圖 4-2 伺服器畫面

Step 3 點選 MySQL資料庫伺服器

圖 4-3 MySQL資料庫伺服器

28

Step 4 建立一個新的資料庫

圖 4-4 建立 MySQL資料庫

Step 5 建立名為 CONTACT的資料庫

29

圖 4-5 指定資料庫名稱

412 建立資料表

假設我們要建立一個名為 address的 Table其結構如下 欄位名稱 資料型態 長度 說明 id INT (自動編號) 連絡人編號 name varchar文字 20 連絡人姓名 tel Varchar文字 15 連絡人電話 Step 1 選擇 CONTACT資料庫

30

圖 4-6 選擇資料庫

Step 2 指定欄位數目

31

圖 4-7 設定欄位數目

Step 3設定表格欄位屬性

圖 3-8 設定表格欄位屬性

Step 4建立表格資料

32

圖 4-9 建立表格資料

圖 4-10 檢視資料

33

圖 4-11 新增資料

圖 4-12

34

圖 4-13

413 使用者管理

接下來我們要利用Webmin 來建立資料庫使用者並給予某些權限 Step1建立使用者

35

圖 4-14 選擇使用者權限

圖 4-15

36

Step2 賦予權限

圖 4-16

Step3 權限列表

37

圖 4-17

38

42 phpMyAdmin 的操作介面

421建立資料庫

Step 填入資料庫名稱並按「建立」

圖 4-18建立資料庫

422 建立資料表

Step1 填入資料表名稱並指定欄位數量 執行

39

圖 4-19填入資料表名稱並指定欄位數量

Step2 設定欄位屬性

圖 4-20設定欄位屬性

40

Step3 phpMyAdmin會產生相關的 SQL Command

圖 4-21 資料表結構及相關 SQL Command

Step4新增 Record

41

圖 4-22

圖 4-23

42

圖 4-24

圖 4-25

43

423使用者管理

Step1建立使用者

圖 4-26

44

圖 4-27

Step2 給予權限

圖 4-28

Step3權限列表

45

圖 4-29

43管理指令介紹

431 利用 mysqladmin設定 root的密碼

當您在Windows 或 Linux 中安裝好 MySQL後系統會自動幫您建立兩個

帳分別是 root 和 匿名者MySQL的 root 跟 Linux 最高權限使用者 root無關MySQL的 root使用者相當於 MS SQL 中的 sa 帳號擁有最高的 Database管理權限但系統預設 MySQL的 root 是不需要密碼所以通常我們一安裝

MySQL後首要任務便是修改 root的密碼 我們可以利用 mysqladmin工具或是直接修改 MySQL內部資料庫的使用者資

料 mysqladmin ndashu root ndashh cosaexamplecom password lsquo1234rsquo

46

-u 表示使用者帳號root 為 MySQL預設的管理帳號

-h 表示 MySQL主機的主機名稱也可使用 IP Address password 表示使用者的密碼因為字串請使用單引號將密碼括起來 密碼設定完成之後還是可以利用 mysqladmin修改密碼但是你必須提供目前的密碼

432 連線 MySQL

mysql -uroot -p密碼 (-p和密碼之間不能有空白) 或 mysql -uroot -p (此方式會在進入後要求密碼) [rootossc phpMyAdmin] mysql -u root -p1234

Welcome to the MySQL monitor Commands end with or g

Your MySQL connection id is 25 to server version 32354

Type help or h for help Type c to clear the buffer

mysqlgt show databases

+----------+

| Database |

+----------+

| mysql |

| test |

+----------+

2 rows in set (000 sec)

mysqlgt exit

Bye

[rootossc phpMyAdmin]

433 建立資料庫

可利用 mysqladmin指令建立 CONTACT資料庫 mysqladmin -u root -p1234 create CONTACT

47

或是利用 mysql指令 [rootossc bluepage] mysql -u root -p1234 Welcome to the MySQL monitor Commands end with or g Your MySQL connection id is 1057 to server version 32354 Type help or h for help Type c to clear the buffer mysqlgt create database CONTACT Query OK 1 row affected (000 sec) mysqlgt show databases +----------+ | Database | +----------+ | CONTACT | | address | | hello | | mysql | | nuke | | test | +----------+ 6 rows in set (000 sec) mysqlgt exit

434 建立資料表

編寫 adresssql內容如下 -- Table structure for table address CREATE TABLE address ( id int(11) NOT NULL auto_increment name varchar(20) NOT NULL default tel varchar(15) NOT NULL default PRIMARY KEY (id) ) TYPE=MyISAM

48

-- Dumping data for table address INSERT INTO address VALUES (1林小明0800016888) INSERT INTO address VALUES (2黃大雄0800016888) INSERT INTO address VALUES (3劉小芬0800024365) 然後執行此 sql script mysql -u root -p1234 CONTACT lt addresssql 或是利 mysql command [rootossc bluepage] mysql -u root -p1234 Welcome to the MySQL monitor Commands end with or g Your MySQL connection id is 1090 to server version 32354 Type help or h for help Type c to clear the buffer mysqlgt use CONTACT Database changed Database changed mysqlgt CREATE TABLE address ( -gt id int(11) NOT NULL auto_increment -gt name varchar(20) NOT NULL default -gt tel varchar(15) NOT NULL default -gt PRIMARY KEY (id) -gt ) TYPE=MyISAM Query OK 0 rows affected (000 sec) mysqlgt INSERT INTO address VALUES (1林小明0800016888) Query OK 1 row affected (000 sec) mysqlgt INSERT INTO address VALUES (2黃大雄0800016888) Query OK 1 row affected (000 sec) mysqlgt INSERT INTO address VALUES (3劉小芬0800024365) Query OK 1 row affected (000 sec) mysqlgt exit Bye

49

第五章 實用範例

51 任務一Web Base客戶通訊錄

任職於開放科技公司的林小明前些日子在最符合成本效益的條件下快

速地完成公司網站的建置老闆因此對小明讚譽有加最近因為公司存放客戶資

料的 SQL Server主機屢遭病毒攻擊加上作業系統本身的問題當機次數頻繁

老闆希望能儘快把公司的客戶通訊錄程式移轉到較穩定的環境上因為此客戶通

訊錄程式最主要給內部人員使用所以介面美觀並不特別要求只求穩定且能快

速得到查詢結果老闆希望在短時間先看到程式的雛型並鍵入資料對其效率

及穩定性進行測試因為上次小明表現突出所以這次不可能的任務自然又落到

小明身上 小明想來想去既然要快速又穩定他而且又不希望所有人都得安裝 Client

程式於是小明決定)捨棄他的舊愛「Delphi+MS SQL」投向新歡「Apache + MySQL + PHP」利用此架構來設計一個簡單實用的Web Base客戶通訊錄程式

511 Web Base客戶通訊錄架構

此程式需要建立 CONTACT的資料庫並建立 adress Tables其結構如下表建立步驟請參考第三章 欄位名稱 資料型態 長度 說明 id INT (自動編號) 連絡人編號 name varchar文字 20 連絡人姓名 tel Varchar文字 15 連絡人電話 Web Base通訊錄共有下列幾個檔案功能如下表

檔案名稱 說明 Indexhtml Web Base通訊錄首頁 addphp 新增連絡人的 php程式 searchphp 尋找連絡人的 php程式 editphp 具有更新及刪除功能的 php程式

50

我們將這些檔案放至varwwwhtmlbluepage (預設無 bluepage目錄)

512 Web Base通訊錄測試

httpwwwopencombluepage 新增資料

圖 5-1 新增連絡人

圖 5-2 填入資料

51

圖 5-3 新增成功

搜尋及異動資料

圖 5-4 搜尋通訊錄

52

圖 5-5 編輯資料

圖 5-6 更新資料

513 程式內容及說明

lt-- 程式範例indexhtml--gt lthtmlgt ltheadgtlttitlegt通訊錄lttitlegtltheadgt ltbodygt ltcentergt

53

lth2gt通訊錄lth2gtlthrgt lta href=indexhtmlgt通訊錄ltagt | lta href=addphpgt新增連絡人ltagt | lta href=searchphpgt搜尋通訊錄ltagt ltcentergt ltbodygt lthtmlgt lt-- 程式範例addphp --gt lthtmlgt ltheadgtlttitlegt新增連絡人lttitlegtltheadgt ltbodygt ltcentergtlth2gt新增連絡人lth2gtltcentergtlthrgt lt 取得欄位資料 if (isset($_POST[Name]) ampamp isset($_POST[Tel]) ) $name = $_POST[Name] $tel = $_POST[Tel] 檢查是否有輸入欄位資料 if ($name = ampamp $tel = ) 建立 SQL字串 $sql = INSERT INTO address (name tel) values( $sql= $name $tel) 建立 MySQL 連結 $link = mysql_connect(localhostroot1234) 選擇資料庫 mysql_select_db(CONTACT) 執行 SQL指令 mysql_query($sql) mysql_close($link) echo ltfont color=redgt新增連絡人成功ltfontgtltbrgt gt ltform action=addphp method=postgt lttable border=0 width=300gt lttrgtlttdgt姓名 lttdgt

54

lttdgtltinput type=text name=Name size=20 maxlength=10gtlttdgtlttrgt lttrgtlttdgt電話 lttdgt lttdgtltinput type=text name=Tel size=20 maxlength=20gtlttdgtlttrgt lttrgtlttd colspan=2 align=centergt ltinput type=submit value=新增連絡人gtlttdgtlttrgt lttablegt ltformgt ltbrgtlta href=indexhtmlgt通訊錄ltagt | lta href=addphpgt新增連絡人ltagt | lta href=searchphpgt搜尋通訊錄ltagt ltbodygt lthtmlgt

lt-- 程式範例searchphp --gt lthtmlgt ltheadgtlttitlegt搜尋通訊錄lttitlegtltheadgt ltbodygt ltcentergtlth2gt搜尋通訊錄lth2gtlthrgt lt if (isset($_POST[Search])) 建立資料庫連結並選定資料庫 $link = mysql_connect(localhostroot1234) mysql_select_db(CONTACT) 建立基本的 SQL字串 $sql = SELECT FROM address 檢查是否輸入姓名 if (chop($_POST[Name]) = ) $name = name LIKE $_POST[Name] else $name = 檢查是否輸入電話號碼 if (chop($_POST[Tel]) = ) $tel = tel LIKE $_POST[Tel] else $tel =

55

if條件組合 SQL字串 if (chop($name) = ampamp chop($tel) = ) $sql= WHERE $name AND $tel elseif (chop($name) = ) 只有姓名 $sql = WHERE $name elseif (chop($tel) = ) 只有電話號碼 $sql = WHERE $tel $sql= ORDER BY name 最後加上排序 $result = mysql_query($sql) 取得欄位數 $total_fields = mysql_num_fields($result) echo lttable border=1gt echo lttrgtlttdgt編號lttdgtlttdgt姓名lttdgtlttdgt電話lttdgtlttd colspan=2gt功能選項lttdgtlttrgt 表格顯示查詢結果 while ($rows = mysql_fetch_array($result MYSQL_NUM)) echo lttrgt for ($i = 0 $i lt $total_fields $i++) echo lttdgt$rows[$i]lttdgt echo lttdgtlta href=editphpaction=editampid= echo $rows[0]gtltbgt編輯ltbgtlttdgt echo lttdgtlta href=editphpaction=delampid= echo $rows[0]gtltbgt刪除ltbgtlttdgt echo lttrgt echo lttablegtlthrgt mysql_free_result($result) mysql_close($link) gt ltcentergt ltform action=searchphp method=postgt lttable border=0 width=450gt lttrgtlttdgt搜尋姓名 lttdgt lttdgtltinput type=text name=Name size=10 maxlength=20gtlttdgtlttrgt lttrgtlttdgt搜尋電話 lttdgt lttdgtltinput type=text name=Tel

56

size=20 maxlength=20gtlttdgtlttrgt lttrgtlttd colspan=2 align=centergt ltinput type=submit name=Search value=搜尋gtlttdgtlttrgt lttablegt ltformgt ltbrgtlta href=indexhtmlgt通訊錄ltagt | lta href=addphpgt新增連絡人ltagt | lta href=searchphpgt搜尋通訊錄ltagt ltbodygt lthtmlgt

lt ob_start() gt lt-- 程式範例editphp --gt lthtmlgt ltheadgtlttitlegt編輯通訊錄lttitlegtltheadgt ltbodygt lt 取得 URL 參數 $id = $_GET[id] $action = $_GET[action] 建立資料庫連結 $link = mysql_connect(localhostroot1234) mysql_select_db(CONTACT) 選擇資料庫 執行的操作 switch ($action) case update 更新 取得欄位資料 $name = $_POST[Name] $tel = $_POST[Tel] $sql = UPDATE address SET name=$name tel=$tel WHERE id=$id mysql_query($sql) 執行 SQL指令 mysql_close($link) header(Location searchphp) 轉向到 serachphp break case del 刪除 $sql = DELETE FROM address WHERE id=$id

57

mysql_query($sql) 執行 SQL指令 mysql_close($link) header(Location searchphp) 轉向到 serachphp break case edit 編輯 $sql = SELECT FROM address WHERE id=$id $result = mysql_query($sql) 執行 SQL指令 $row = mysql_fetch_row($result) 取回記錄 $name = $row[1] 取得欄位 name $tel = $row[2] 取得欄位 tel mysql_close($link) 顯示編輯表單 gt ltcentergtlth2gt更新通訊錄lth2gtltcentergtlthrgt ltform action=editphpaction=updateampid=lt echo $id gt method=postgt lttable border=0 width=300gt lttrgtlttdgt姓名 lttdgt lttdgtltinput type=text name=Name size=20 maxlength=10 value=lt echo $name gtgtlttdgtlttrgt lttrgtlttdgt電話 lttdgt lttdgtltinput type=text name=Tel size=20 maxlength=20 value=lt echo $tel gtgtlttdgtlttrgt lttrgtlttd colspan=2 align=centergt ltinput type=submit value=更新連絡人gtlttdgtlttrgt lttablegt ltformgt ltbrgtlta href=indexhtmlgt通訊錄ltagt | lta href=addphpgt新增連絡人ltagt | lta href=searchphpgt搜尋通訊錄ltagt lt break gt ltbodygt lthtmlgt

58

52 任務二Web Base群組軟體 ( twig )

順利完成Web Base客戶通訊錄程式測試一段時間後「Apache + MySQL + PHP」架構的穩定與快速巳深得老闆與公司所有同事的認同隨著公司業績蒸

蒸日上人員組織編罝愈來愈龐大跨部門的會議愈來愈多業務員每日排滿拜

訪客戶的行程跟客戶的 Email的往來也愈來愈頻繁 愈來愈多部門的同事希望公司能建置一套群組軟體提供 web mail可讓業

務人員方便收發 mail還有連絡人議事日程待辦工作書簽等功能讓整個

公司運作及個人時間管理更有效率

老闆問小明對這些需求有什麼看法小明認為如果這些功能完全由程式部

門開發必定曠日費時而且耗費公司資源小明在網路尋找是否有提供這些功能

的Free Software皇天不負苦心人小明發現了TWIG (The Web Information Gateway) httptwigscrewdrivernet這個群組軟體它在 Web 上整合郵件新聞聯絡人議事日程工作序書簽等功能非常符合公司的需求 Step 1 下載 twig-277targz 下載網址 httptwigscrewdrivernetdownloadphp3

Step 2 解開 twig-277targz tar -xzvf twig-277targz

59

Step 3 執行安裝動作安裝到 varwwwhtmltwig 目錄 cd twig-277 twig-install varwwwhtmltwig

Step 4 建立 MySQL 資料庫(twig)及各資料表

cd setup mysql -u root -p1234 mysqlgt create database twig Query OK 1 row affected (001 sec) mysqlgt quit mysql -u root ndashp1234 twiglt twigtablemysql

Step 5 修改 configincphp3 參數設定 vi varwwwhtmltwigconfigconfigincphp3 $config[fromdomain] = opencom 網域 $config[language] = chinesebig5 中文訊息 $config[imap_port] = 143notls

60

Step 6 修改連結 MySQL 的帳號密碼 vi varwwwhtmltwigconfigdbconfigincphp3 $dbconfig[sqlusername] = root username $dbconfig[sqlpassword] = 1234 password

Step 7 其他設定檔

vi etchttpdconfhttpdconf 加入 AddType applicationx-httpd-php php3 在 DirectoryIndex最後加入 indexphp3 DirectoryIndex indexhtml indexhtmlvar indexphp3 在 AddDefaultCharset ISO-8859-1加上 AddDefaultCharset ISO-8859-1

vi etcphpini register_globals = On service httpd restart Step 8 sendmail 設定 vi etcmailsendmailcf在 264 行前面加上並重新啟動 sendmail「service snedmail restart」 262 SMTP daemon options 263 264 O DaemonPortOptions=Port=smtpAddr=127001 Name=MTA 265 266 SMTP client options 267 O ClientPortOptions=Family=inet Address=00

61

Step 9 檢查設定有無錯誤 http主機名稱twigtestphp3

62

Step 10 登入 twig ( http主機名稱twig)

63

第六章 維護及更新程序

61 日常維護

系統管理員最好定期以 root 身份登入看看信件在 RedHat Linux 中有一支 logwatch 程式會定時去分析 log file如果發現異常便會發信給 root除此之外筆者建議讀者平時就檢查 MySQL log file ( varlogmysqldlog)是否有異常情形

62 更新程序

讀者可至httprpmfindnet 尋找MySQL相關套件至於升級的相關步驟請參

考Linux OS SOP 第 54節

63 備份重要檔案

預設 MySQL 的 DB 檔案是存在 varlibmysql 內以 DB名稱為目錄目錄

內就是該 DB 的所有資料通常得定期備份還有 MySQL的設定檔 etcmycnf也別忘了一起備份

64 離線備份與還原

641 離線備份

預設 MySQL 的 DB 檔案是存在 varlibmysql 內以 DB 名稱為目錄目錄內

就是該 DB 的所有資料像 CRM 這個 DB就是存在 varlibmysqlCRM 內在備份前因為怕資料尚未完全寫入磁碟而且 MySQL 會 Lock 在使用的 DB 檔案所以應該是要先把 MySQL 先 Shutdown 一下整個備份的程序可以下像下面的指令去完成 cd varlibmysql

64

service mysqld stop tar cvfz CRM_db_20030905tgz CRM service mysqld start 對這樣就可以了 不過要注意的是怕 DB 內每個 Tables 間的資料有關關

聯性所以最好是把整個 DB 一次備起來單獨只備哪個 Tables 的檔案以後回存時怕會有資料關聯不一致的問題

642 離線還原

DB 發生錯誤而要回存時其實也不難先找出最近一次完整正常的備份先把現在錯誤的網頁或 DB 先更名或 tar 起來再把好的備份給解開回原來目錄位

置就行了需要注意的是 MySQL 服務最好也是要先停止回存完成後再啟動服務回存 DB 的整個程序可能像下面 cd varlibmysql service mysqldstop mv CRM CRM_OLD tar xvfz CRM_db_20030905tg service mysqld start

65 線上備份與還原

651 線上備份

使用像上面的檔案方式備份是個不錯的方法它最少可以保持該主機某個時間點的完整檔案備份但還是有一些問題需要考慮到有些主機就不只建立一個 DB 而已總不能為了備份某個 DB 而把整個 MySQL 服務停止備份檔案的方式回存在原主機上一定適用但假如 MySQL 版本升級或是在那天該網頁空間需遷機移機到別的主機時那就沒人敢保證備出來的資料檔可以用所以我們可以考慮另一種備份的方式是使用 MySQL 本身提供的功能 MySQL Data Dump指令是 mysqldump

65

使用 MySQL 的 Dump 功能可以把 DB 的結構資料或結構加資料 Dump 成文字檔 mysqldump 指令提供的彈性很大你可以選擇把整個 DB Dump 成一個檔或是每個 Table 為一個檔甚至是把結構檔和資料分開儲存都

可以 mysqladmin -uroot -p flush-logs mysqldump CRM -uroot -p --opt gt CRM_20030905sql (CRM 是 DB 名稱 opt 是一個使用完整 Dump 參數) 假如只是要單獨 Dump 某個 Table 時只要在上面的指令後轉出符號 gt 前加個 Table 名稱就可以如只要 phpbb2_users 這個 Table 的 Dump 時只要下 mysqldump CRM -uroot -p --opt CUSTOMER gt CRM_CUSTOMER_20030905sql

652 線上還原

若要回存整個資料庫只需將壓縮的備份檔還原成 Dump 的檔案再用下面的指令回存 mysql CRM -uroot -p lt CRM_20030905sql 這邊需注意的是若建立備份時是以--opt或--add-drop-table為參數時回存的 動作是先將舊的 Table 先刪除重建 Table 的結構後再把 Data 匯入所以回存後所有的資料會回到你當時備份那個時間點因此在回存資料時可以考慮把現有錯誤或不完整的 DB 先備份一份下來以備不時之需或是拿來比對錯誤的地

方在那裡當然你也可以把資料回存到另一個測試用的 DB 內只要把上面指令

的 DB 名稱改成你的測試用 DB 名稱即可 使用這種回存方式 MySQL 服務不需停止也不會動到其他正在使用的 DB 在一些提供 MySQL 服務的虛擬主機可用這種方式作你自己的 DB 備份及回存

66

另外假如你是系統重建或是移機時切需在新的 MySQL 內新建一個空白 DB 後才行作回存的工作你可以用下面的指令建立 mysql -uroot -p -e CREATE DATABASE CRM (上面的 CRM是你要新建的 DB 名稱) 另一種作法先用 mysql 指令進入 mysql client console 然後再用 CREATE DATABASE CRM 這樣就行了記得尾端要加個 符號該行指令才會執行

67

第七章 問題與解答

Q1RedHat 90預附的 MySQL到底有無支援 Transcation機制 Ans MySQL自 32334a之後的 MySQL-Max版本加入 InnoDB的資料庫類型透過

InnoDBMySQL同樣可以進行 COMMIT與 ROLLRACK的動作RedHat 90預附的 MySQL為 32354a-11巳支援 InnoDB的資料庫類型不過必須做以

下設定 1cp usrsharedocmysql-server-32354amy-mediumcnf to etcmycnf 2 vi etcmycnf 將以下設定前的拿掉 innodb_data_home_dir = varlibmysql innodb_data_file_path = ibdata110Mautoextend innodb_log_group_home_dir = varlibmysql innodb_log_arch_dir = varlibmysql 3service mysqld restart 如此一來各位在建立Table時便可指定Table Type為 innodb ( ex create table with type=innodb ) Q2如何解決 php+mysql 許功蓋等字變亂的問題 Ans 方法一 【確定 MySQL 預設的字元集】 1 打開 WinMySQLadmin 管理畫面(在視窗右下角狀態列紅綠燈圖示中按滑鼠

右鍵點選 Show me 選項) 2 點選管理畫面中 [Variables] 標籤選項其中 character_set變數就是您預設

字元集的變數其預設是 latin1 字元集(我們要將他改回 big5)而 chatacters_set 變數則是 MySQL 可以支援哪些字元集 【修改預設字元集變數 character_set 】 1 請點選管理畫面中 [myini Setup] 標籤選項設定 myini 2 按一下 [Pick-up and Edit myini values] 按鈕以便編輯目前的 myini 設定 3 在 [mysqld] 設定區塊底下新增一行 default-character-set = big5 變數設

68

定 4 新增一個 [client] 設定區塊並加入第三步驟的變數設定(游標往下移到空白處新增兩行 [client] 和 default-character-set=big5) 5 按一下畫面左下方 [Save Modification] 按鈕儲存設定 6 重新啟動 MySQL 或 Windows 方法二 Server端注意事項 phpini 中有關的設定為(預設值) Magic quotes for incoming GETPOSTCookie data magic_quotes_gpc = On Use Sybase-style magic quotes (escape with instead of ) magic_quotes_sybase = Off Client端注意事項 1中文資料送進 mysql 前請用 addslashes($str) 處理 2處理後送進 mysql 時請用 括起來並在參數後留一個空白如 $sql = UPDATE ezf_table set tablename=$tname tableend=$endtime table inguser=$tguser tableingid=$tguserid tableallnumber=$tnumber tableloca l=$tablelocal tableanyone=$tableopen tabletext=$ttext WHERE tableid=$t ableid tablename=$tname c 取出時請用 stripslashes($str) Q3MySQL root 密碼忘了該怎麼辦 Ans 1先停掉 mysql etcrcdinitdmysql stop 2以--skip-grant-table 的參數啟動 mysql safe_mysql --skip-grant-tableamp 3 更改 root 密碼 mysql mysql mysqlgt UPDATE user SET password=password(newpassword)

69

WHERE user=root mysqlgt FLUSH PRIVILEGES mysqlgt exit 4停掉 mysql再重跑 mysqladmin -uroot -p shutdown Enter password 輸入新設定的密碼 etcrcdinitdmysql start

Q4NULL值問題

Ans

NULL值的概念是造成 SQL的新手的混淆的普遍原因他們經常認為 NULL是和一個空字符串的一樣的東西不是這樣的例如下列語句是完全不同的

mysqlgt INSERT INTO my_table (phone) VALUES (NULL)

mysqlgt INSERT INTO my_table (phone) VALUES ()

兩個語句把值插入到 phone 列但是第一個插入一個 NULL值而第二個插入一個空字符串第一個的含義可以認為是ldquo電話號碼不知道而第二個則可意味

著ldquo她沒有電話

在 SQL中NULL值在于任何其他值甚至 NULL值比較時總是假的(FALSE)包含 NULL的一個表達式總是產生一個 NULL值除非在包含在表達式中的運算符和函數的文檔中指出在下列例子所有的列返回 NULL

mysqlgt SELECT NULL1+NULLCONCAT(InvisibleNULL)

如果你想要尋找值是 NULL的列你不能使用=NULL測試下列語句不返回任

何行因為對任何表達式expr = NULL是假的

mysqlgt SELECT FROM my_table WHERE phone = NULL

要想尋找 NULL值你必須使用 IS NULL測試下例顯示如何找出 NULL電話號碼和空的電話號碼

70

mysqlgt SELECT FROM my_table WHERE phone IS NULL mysqlgt SELECT FROM my_table WHERE phone =

在 MySQL中就像很多其他的 SQL服務器一樣你不能索引可以有 NULL值的列你必須聲明這樣的列為 NOT NULL而且你不能插入 NULL到索引的

列中

當用 LOAD DATA INFILE 讀取數據時空列用更新如果你想要在一個列中有

NULL值你應該在文本文件中使用N字面上的詞NULL也可以在某些情形下使用

當使用 ORDER BY時首先呈現 NULL值如果你用 DESC以降序排序NULL值最後顯示當使用 GROUP BY時所有的 NULL值被認為是相等的

為了有助于NULL的處理你能使用 IS NULL和 IS NOT NULL運算符和 IFNULL()函數

對某些列類型NULL值被特殊地處理如果你將 NULL插入表的第一個TIMESTAMP 列則插入當前的日期和時間如果你將 NULL插入一個AUTO_INCREMENT 列則插入順序中的下一個數字

Q5如何將圖片存放於 MySQL中

Ans

Step 1建立資料庫 test

Step 2 建立表格 binary_data

CREATE TABLE binary_data (

id INT(4) NOT NULL AUTO_INCREMENT PRIMARY KEY

description CHAR(50)

bin_data LONGBLOB

filename CHAR(50)

filesize CHAR(50)

filetype CHAR(50)

71

)

Step 3 利用 storephp 寫入圖片

storephp 程式碼

ltHTMLgt ltHEADgtltTITLEgtStore binary data into SQL DatabaseltTITLEgtltHEADgt ltBODYgt lt code that will be executed if the form has been submitted

if ($submit) mysql_connect(localhostrootYOUR_PASSWORD) mysql_select_db(test) $data=Base64_Encode(fread(fopen($form_data r) filesize($form_data))) $result=MYSQL_QUERY(INSERT INTO binary_data (descriptionbin_datafilenamefilesizefiletype) VALUES ($form_description$data$form_data_name$form_data_size$form_data_type)) $id= mysql_insert_id() print ltpgtThis file has the following Database ID ltbgt$idltbgt MYSQL_CLOSE() else else show the form to submit new data

gt

ltform method=post action=ltphp echo $PHP_SELF gt enctype=multipartform-datagt File Descriptionltbrgt ltinput type=text name=form_description size=40gt ltINPUT TYPE=hidden name=MAX_FILE_SIZE value=4000000gt ltbrgtFile to uploadstore in databaseltbrgt ltinput type=file name=form_data size=40gt ltpgtltinput type=submit name=submit value=submitgt ltformgt lt

72

gt ltBODYgt ltHTMLgt

Step 3 利用 storephp 取出圖片

getdataphp 程式碼

lt Syntax getdataphp3id=ltidgt if($id) you may have to modify login information for your database server MYSQL_CONNECT(localhostrootYOUR_PASSWORD) mysql_select_db(test) $query = select bin_datafiletype from binary_data where id=$id $result = MYSQL_QUERY($query) $data = Base64_Decode(MYSQL_RESULT($result0bin_data)) $type = MYSQL_RESULT($result0filetype) Header( Content-type $type) echo $data gt

Q6MySQL裝好之後啟動時或是執行 mysqladmin會出現如下訊息 Cant connect to local MYSQL Server through Socket varlibmysqlmysqlsock或是

Cant connect to local MYSQL Server through Socket tmpmysqldsock

Ans 可能有下列幾個原因

1這個 mysqldsock 不見了被某人刪除了或是被一些系統自動執行程式給刪

了例如有些 cron任務便會設定定期刪除 tmp 裡的東西所以呢您只能修改

cron 裡的設定讓它不要清除 mysqldsock 2在啟動時也可以改變 mysqldsock的位置您在啟動 MySQL的時候可以加入此參數usrlocalmysqlbinsafe_mysqld --user=mysql --socket=其他路

徑socket amp 同時得去設定環境變數 MYSQL_UNIX_PORT的值以指定新的

73

路徑 3若是您沒改 MYSQL_UNIX_PORT的值那麼您可以在執行指令的時候才打

例如mysqladmin --socket=其他路徑socket version Q7How to get the last insert id Ans CREATE TABLE product ( id INT(4) NOT NULL AUTO_INCREMENT PRIMARY KEY description VARCHAR(50) ) 1利用 SQL的話 mysqlgt insert into product(description) values(123) Query OK 1 row affected (000 sec) mysqlgt select last_insert_id() +------------------+ | last_insert_id() | +------------------+ +------------------+ 1 row in set (000 sec) ======================================== 2如果是 PHP的話 你可以用mysql_insert_id()取得該 id PHP example $result=MYSQL_QUERY(INSERT INTO product (description) VALUES ($description)) $id= mysql_insert_id() print This file has the following Database ID $id Q8如何將文字檔匯入資料庫 Ans $addr=homehttpdhtmlphpschool001txt $sql_select = load data infile $addr into table test fields terminated by t 解說 $sql_select = load data infile 文字檔名 into table 表格名 fields terminated by

74

t

(欄位分隔以 TAB鍵) 該文字檔須與資料表欄位格式相符 例如欄位有三個 則文字檔為每行一筆資料如下 欄 1資料ltTABgt欄 2資料ltTABgt欄 3資料 欄 1資料ltTABgt欄 2資料ltTABgt欄 3資料 欄 1資料ltTABgt欄 2資料ltTABgt欄 3資料 欄 1資料ltTABgtltTABgt欄 3資料

Q9如何撰寫 MySQL C API Ans Step 1利用文字編輯器撰寫以下程式碼 mysqlcc

include ltstdiohgt

include ltmysqlmysqlhgt

int main (int argc char argv[])

MYSQL mysql

MYSQL_RES res

MYSQL_ROW row

if (argc = 2)

fputs (Usage myc ltdatabasegt stderr)

return 1

if ((mysql_connect(ampmysqllocalhostrootYour_Password)))

fputs (Error connecting stderr)

abort()

75

if (mysql_select_db(ampmysqlargv[1]))

fputs (Error selecting database stderr)

abort()

if (mysql_query(ampmysqlSELECT FROM test_table))

fputs (Error processing query stderr)

abort()

if ((res = mysql_store_result(ampmysql)))

fputs (Error storing results stderr)

abort()

while((row = mysql_fetch_row(res)))

uint i = 0

for (i=0 i lt mysql_num_fields(res) i++)

printf(s row[i])

printf(n)

return 0

Step 2 Compile

gcc -Iusrlocalmysqlinclude -Lusrlocalmysqllibmysql mysqlcc ndashlm -lmysqlclient

(其中 include path與 library path取決於你的 MySQL安裝路徑)

76

如果執行時發生如下 error Run problemerror in loading shared libraries libmysqlclientsoX 將你的 MySQL library path(for exampleusrlocalmysqllibmysql) 加入etcldsoconf and run sbinldconfig -v Q9ASP + MySQL 範例程式 Ans Dim myconn As New ADODBConnection Dim myrs As New Recordset Dim mySQL As String Dim myrows As Long myconnOpen DSN=MyODBCsample mySQL = SELECT from user myrsSource = mySQL Set myrsActiveConnection = myconn myrsCursorLocation = adUseClient myrsOpen myrows = myrsRecordCount myrsClose myconnClose 可參考 httpwwwdwamnetmysqlasp_myodbcasp 有詳細的資料 Q10如何將 MySQL中的資料庫匯出成txt檔 Ans select from TableName into outfile textxls all result fields will seperate by tab

77

第八章 參考資料

英文部份 網址 1 httpwwwmysqlcom MySQL 網站有第一手有關 MySQL的資料 2 httpwwwmysqlcomdocenReplicationhtml 有關 MySQL Replication 的文件 3 httpwwwgeocitiescomsqlhomefaqstore_blobhtml 如何在 MySQL 存放 BLOB的資料 4httpwwwsapdborg 有關 SAP跟 MySQL相關合作的網站 書藉 1 Cooking with MySQL

Paul DuBois has selected sample recipes from the hundreds youll find in his book MySQL

Cookbook In this third and final series of excerpts showcasing these recipes learn how to

compute team standings how to calculate the differences between successive Dec 26

2002 2 Tips for Building Web Database Applications with PHP and MySQL by Hugh E Williams co-author of Web Database Applications with PHP amp MySQL 04042002

3 Managing and Using MySQL 2nd Edition By Tim King George Reese Randy Jay Yarger

4 MySQL Cookbook By Paul DuBoisPublisher OReillyPub Date October 2002

中文部份

78

1 httplinuxtncedutwtechdocmysqlmysql_docmanual_tochtml MySQL 中文手冊 2 httpchenshloxaedutwphpZ_1php PHP+MySQ程式研習設計網站 3 httplinuxtncedutwtechdocbanicdownhtml PHP 4 手冊 4 httpwwwtncedutwadmin_zonephp台南縣教育網網路中心有很多 Linux相關文件 5 httpdobtncedutw網站建置百寶箱有很多 PHP MySQL 相關範例程式 5 httpwwwdbworldcomtw資料庫專家電子雜誌介紹資料庫的重要觀念及名詞

79

附錄一 SQL Command 介紹

SQL (讀音ess-que-el) 是一種結構查詢語法SQL 使用於資料庫交流

傳遞相容於 ANSI (American National Standards Institute) 是一套標準的關聯

式資料庫語言 SQL 語言是執行更新或從資料系統獲取資料一般常見的關聯

資料庫系統都有提供 SQL 如 Oracle Sybase Microsoft SQL Server Access Ingres 等雖然大部份的資料庫都有提供 SQL 但也多提供了自已獨特的語

法造成了不相容的情形但標準基本的語法是相通的如Select Insert Update Delete Create and Drop 每一個系統都有支援

Table相關 Command

Create Table

關聯式資料庫包含有很多元件稱為資料表(tables) 把資料或訊息放在資

料表中 資料表是以不同的名稱做分別資料表由欄列所構成的二維陣列

欄包含欄位名資料型態 及其他可判斷的資訊列是由全部欄位構成一筆一

筆的紀錄 create table 語法用在建立一個新的資料表語法格式如下

create table tablename (column1 data type column2 data type column3 data type)

Format of create table if you were to use optional constraints

create table tablename (column1 data type [constraint] column2 data type [constraint] column3 data type [constraint]) [ ] = optional

Note You may have as many columns as youd like and the constraints are optional

80

Example

create table employee (first varchar(15) last varchar(20) age number(3) address varchar(30) city varchar(20) state varchar(20))

注意建立資料表格式要以括號把前後框住而最後以(分號)做結尾

欄位名不要超過 30個字元長而且不要使用 sql 的關鍵字(如 where select等)而在後面接是型態的宣告(如字串數字日期格式等)

資料型態是來描述欄位的方式如一個欄位Last_Name 是一個姓氏可以使用varchar (可變動長度字串) 資料型態

以下是幾個常見的資料庫型態 char(size) 固定長度字串最長為 255 位元 varchar(size) 變動長度字串最大字元數以 size 來指定 number(size) 數值格式可以是整數也可以是小數最大數字以 size 位數判

斷未指定小數位數由系統內定 date 日期格式 number(sized) 數值格式最大數字以 size 位數判斷d 為小數位數整數位

數為 size-d 位

有何限制當資料表被建立通常有一或數個欄位是要使用來做關聯的功

能 例如unique 限制(唯一值)兩筆記錄不可以相同的值 not null (非空值)該欄位一定要輸入資料不可是空的primary key (主鍵)是每一筆記錄識別的主要方式

Drop a table drop table 刪除資料表(其中的資料也會一併刪除)

drop table tablename

Example

81

drop table 和刪除全部資料是不同的刪除全部資料欄位名稱資訊等還會

存在但刪除資料表會把這一些也一併移除掉

如何查詢資料

Select 基本用法

select 語法是關連式資料庫最常用的部份可以取得你想要的資料這是一個

簡單的範例 select column1[column2etc] from tablename [where condition] [] = optional 在 select 之後所列欄位名則是要顯示的資料部份你可以一一列出各欄位

名或是以 (星號)來代表選擇全部的欄位 from 之後放資料表名稱 where 子句 (選項) 指定要過濾的條件符合者才會顯現 where 可使用的條件運算元 = 等於 gt 大於 lt 小於 gt= 大或等於 lt= 小或等於 ltgt 大相等 LIKE 相似 For example select first last city

82

from empinfo where first LIKE Er 以Er 為開頭的字串就符合要以單引號框住 Or you can specify select first last from empinfo where last LIKE s 最後一字為 S 就符合 select from empinfo where first = Eric 則表示 first name 一定要是 Eric 才可以 範例資料表empinfo 統計函數

MIN 傳回指定欄位最小值

MAX 傳回指定欄位最大值

SUM 傳回指定欄位總和

AVG 傳回指定欄位平均值

COUNT 傳回指定欄位的筆數

COUNT() 傳回資料庫中的總筆數

統計函數使用於資料表中的數值欄位配合 SELECT 語法使用 只用於總結特定單一欄位可以配合 GROUP BY 做篩選但也可以不使用 GROUP BY 語句For example

SELECT AVG(salary) FROM employee

83

傳回全部 salary 平均值

Another example

SELECT AVG(salary) FROM employee WHERE title = Programmer

傳回 salary 平均值條件為 employees 資料表中當 title 等於 Programmer

Example

SELECT Count() FROM employees

傳回 employees 資料表中紀錄總筆數

GROUP BY 語法 SELECT column1 SUM(column2) FROM list-of-tables GROUP BY column-list The GROUP BY 語句可以先以所列的欄位為條件分組排序在一起(可以多欄

位) example 要列出每一個 dept 中最高 salary 值 SELECT max(salary) dept FROM employee GROUP BY dept HAVING 語法

SELECT column1 SUM(column2) FROM list-of-tables GROUP BY column-list HAVING condition

HAVING 子句是 GROUP BY 的一部份用來過濾在 GROUP BY 所選出的資料功能如同 select 命令中 where 條件式一樣只是 HAVING 必需配合 GROUP BY 使用

我們以例子來說明我們要取得每一公司名及每一公司的薪水平均值輸入如下

84

SELECT dept avg(salary) FROM employee GROUP BY dept

但如果我們只列出薪資平均值超過 20000元的公司資料

SELECT dept avg(salary) FROM employee GROUP BY dept HAVING avg(salary) gt 20000

ORDER BY子句語法

SELECT column1 SUM(column2) FROM list-of-tables ORDER BY column-list [ASC | DESC]

[ ] =選項

ORDER BY是一個選項子句當你以排序方式來顯示資料(正向由小到大反向由大到小)以指定的欄位資料做排序

ASC = 正向- 預設值 DESC = 反向排序

For example

SELECT employee_id dept name age salary FROM employee_info WHERE dept = Sales ORDER BY salary

以上列出公司代號公司名銷售員人名年紀及薪資而條件是公司名為 Sales 顯示順序以薪資多少排序(由小到大為預設值)

如果要以多個欄位做排序要以逗號做分隔如下

SELECT employee_id dept name age salary FROM employee_info WHERE dept = Sales ORDER BY salary age DESC

85

結合條件及布林運算 SELECT column1 SUM(column2) FROM list-of-tables WHERE condition1 AND condition2 AND運算可以結兩個或以上的條件放在 WHERE子句中 兩者都要為真才

會顯示該筆記錄 OR 運算可以結兩個或以上敘述放在 WHERE子句中只要其中一個為直就

會顯示該筆記錄 For example SELECT employeeid firstname lastname title salary FROM employee_info WHERE salary gt= 5000000 AND title = Programmer 必需要薪資大於等於 50000而且職稱為 Programmer同時符合才會顯示該筆資料 以下以括號括住雖然不是必需的但如此比較容易讀 SELECT employeeid firstname lastname title salary FROM employee_info WHERE (salary gt= 5000000) AND (title = Programmer) 另外範例 SELECT firstname lastname title salary FROM employee_info WHERE (title = Sales) OR (title = Programmer) 條件為只要是 Sales 或 Programmer 職稱的就會被列出 IN and BETWEEN 子句

SELECT column1 SUM(column2) FROM list-of-tables WHERE column3 IN (list-of-values) SELECT column1 SUM(column2) FROM list-of-tables WHERE column3 BETWEEN value1 AND value2 IN 子句使用在列舉項目的使用上也就是分別測試是否符合所列的值 For example

86

SELECT employeeid lastname salary FROM employee_info WHERE lastname IN (Hernandez Jones Roberts Ruiz) 條件為姓氏(astname)要符合 Hernandez Jones Roberts or Ruiz 其中一個才會被傳回 IN運算元也可以使用 OR 的語法來取代如下結果相同 SELECT employeeid lastname salary FROM employee_info WHERE lastname = Hernandez OR lastname = Jones OR lastname = Roberts OR lastname = Ruiz 但使用 IN 句子比較短也比較易懂 你也可以使用 NOT IN 來去掉不要的記錄 BETWEEN 運算元使用在判斷是否存在兩個數值之間 For example SELECT employeeid age lastname salary FROM employee_info WHERE age BETWEEN 30 AND 40 傳回年紀 30歲到 40歲之間的資料(含 30及 40歲者) 相同的也可以使用以下語法來達到相同的結果 SELECT employeeid age lastname salary FROM employee_info WHERE age gt= 30 AND age lt= 40 你也可使用 NOT BETWEEN 來濾掉中間值的資料 數學運算 標準 ANSI SQL-92 提供以下運算

87

+ 加

- 減

餘數

餘數為除法後剩整數這不在標準的 ANSI SQL 中但大部份的資料庫都會支

援這運算元以下列出有用的函數雖不在 ANSI SQL-92 提供但一般資料庫

也會支援他們

ABS(x) 傳回 x 絕對值

SIGN(x) returns the sign of input x as -1 0 or 1 (negative zero or positive respectively)

MOD(xy) 餘數 - returns the integer remainder of x divided by y (同 xy)

FLOOR(x) 傳回小或等於 x 的最大整數值

CEILING(x) or CEIL(x)

傳回大或等於 x 的最小整數值

POWER(xy) x的 y 次方

ROUND(x) 把 x 四捨五入為整數

ROUND(xd) 四捨五入取到小數 d 位

SQRT(x) x 開平方

For example SELECT round(salary) firstname FROM employee_info 傳回薪資取到整數位

如何新增資料

insert 加入一筆新紀錄到資料表中 insert into tablename (first_columnlast_column) values (first_valuelast_value) [] = optional Example insert into employee

88

(first last age address city state) values (Luke Duke 45 2130 Boars Nest Hazard Co Georgia) Note 字串要以單引號住如string 數字框住也無妨 insert into 後面接資料表名稱再接以括號括住的欄位名在 values 後括號分別對映各欄位的值 以上的例子新增了一筆名(first) 為 Luke而住所(state) 為 Georgia 的資料

如何刪除資料

delete 可以刪除單筆或多筆紀錄 delete from tablename where columnname OPERATOR value [and|or column OPERATOR value] [ ] = optional Examples delete from employee Note 如果你沒有指定 where 子句那麼全部的紀錄都會被刪除 delete from employee where lastname = May delete from employee where firstname = Mike or firstname = Eric delete from 接著資料表名 再接著是條件式判斷沒有條件式則全部紀錄會

被刪除

如何更新資料

update 用來更新你所指定的記錄要和 WHERE 配合小心使用 語法 update tablename set columnname = newvalue[nextcolumn = newvalue2] where columnname OPERATOR value [and|or column OPERATOR value] [] = optional Examples

89

update phone_book set area_code = 623 where prefix = 979 update phone_book set last_name = Smith prefix=555 suffix=9292 where last_name = Jones update employee set age = age+1 where first_name=Mary and last_name=Williams

90

附錄二Replication

測試環境

RedHat 90 + MySQL 32358 MySQL資料庫路徑 varlibmysql MySQL設定檔 etcmycnf Master IP 1921680100 Slave IP 1921680200 請至下列網址下載最新MySQL 32358套件並利用rpm ndashUvh 更新 httpupdatesredhatcom9enosi386

圖 最新 MySQL 套件

測試架構圖

91

1921680100

1921680200Master Server

erveSlave S r

圖 測試架構圖

測試步驟

Master server 部份 Step1 確認 MasterSlave機器上所裝的 MySQL版本能進行

replication( 32329 or higher ) Step2 在 Master MySQL上開放一個帳號給 Slave mysql ndashu root ndashp mysqlgtGRANT FILE ON TO repl1921680200 IDENTIFIED BY lsquoabc123rsquo mysqlgtq 上面是 Master開放一個帳號 repl密碼 abc123給 IP1921680200有檔案處理

的權限 Step3 shutdown MySQL on the Master mysqladmin ndashu root ndashp shutdown Step4 備份 Master所有資料庫 tar ndashcvf tmpmysql-snapshottar varlibmysql 注意tar的時候MySQL是要在 stop情況下 在mysql (wwwmysqlcom) 網站的FAQ有不用shutdown的方法

92

Step5 在 master機器上修改etcmycnf 在[mysqld]區段內加入參數 log-bin server-id=這邊設定 server-id=1 sql-bin-update-same binlog-do-db=CRM只針對 CRM資料庫做紀錄 Step6 Restart MySQL on the master service mysqld start 此時因為有加入 log-bin 參數因此開始有 index產生了在varlibmysql目錄下

有index檔案紀錄資料庫的異動 log Slave server 部份 Step1 在 slave設定etcmycnf 在[mysqld]區段加入 master-host= master-user= master-password= master-port= server-id= 這邊設定 master-host=1921680100 master-user=repl master-password=abc123 master-port=3306 server-id=2 master-connect-retry=60預設重試間隔 60秒 replicate-do-db=CRM告訴 slave只做 CRM資料庫的更新 log-slave-updates Step2 將 master上的 mysql-snapshottar copy到 slave上 用 ftp傳到 slave的tmp Step3 解壓縮 Master資料庫至 Slave Server上 cd varlib tar xvf tmpmysql-snapshottar chown ndashR mysqlmysql mysql

93

chmod ndashR 770 mysql (視情況) Step4 Restart MySQL on the slave server 這時在varlibmysql目錄會出現 masterinfo此檔案紀錄了 Master MySQL server的資訊

狀況測試

One-way replication

1921680100

1921680200Master Server

erveSlave S r

圖 One-way replication架構圖 Step1 Master跟 Slave網路及服務都正常情況下由 Master端異動資料後 到 Slave端瀏覽資料檢視是否有進行 replication Step2 模擬 Slave Server 當機 可用在於 slave真的當機或是 Slave 不一定需要一直跟 master connect將Slave MySQL server shutdown由 Master端異動資料到 slave端瀏覽此時Slave應該沒有被 replication 更新然後再將 Slave端 MySQL server start起來

預設 60秒後 Slave會嘗試跟 Master要求進行 replication再去 Slave端檢視是否有更新資料

94

Step3 模擬 Master當機因為是設定 One-way replication一旦 Master Server Slave端沒有 Master的 source可以 download Two-way replication 基於 Master當機狀況於是發展雙向 Replication即 1921680100 ( Host A ) 1921680200 ( Host B )都分別擔任 MasterSlave身分

1921680100

1921680200er

Server B MasterSlave Server

Server A MasterSlave Serv

圖 Two-way replication架構圖 以下是針對兩台 MySQL伺服器進行雙向 Replication Step1觀念同單向 replication只是改成 Master也有 Slave身分 Slave也有Master的身分先分別在 Server AServer B 都去 grant一個進行 replication的身分 [A]mysqlgtGRANT FILE ON TO repl1921680200 IDENTIFIED BY lsquoabc123rsquo [B]mysqlgt GRANT FILE ON TO repl1921680100 IDENTIFIED BY lsquoabc123rsquo Step2做完單向 replication後stop Server Aserver B MySQL service此時 AB資料是一樣的

95

修改etcmycnf設定 範例 Server A [mysqld] datadir=varlibmysql socket=varlibmysqlmysqlsock server-id=1 log-bin sql-bin-update-same binlog-do-db=CRM master-host=1921680200 master-user=repl master-password=abc123 log-slave-updates master-connect-retry=60 replicate-do-db=CRM Server B [mysqld] datadir=varlibmysql socket=varlibmysqlmysqlsock server-id=2 log-bin sql-bin-update-same binlog-do-db=CRM master-host=1921680100 master-user=repl master-password=abc123 log-slave-updates master-connect-retry=60 replicate-do-db=CRM 分別 start Server AServer B MySQL後此時雙方都是 MasterSlave身分一旦哪一方資料異動就會通知對方來 replication-若 replication失效則必須將Server AServer B的masterinfo及index00x 都砍掉然後分別 restart MySQL server進行測試檢視成果 實務上通常如果需要做Two-way replication通常會搭配Virtual Server使用

96

在前端架設一台Virtual Server不過此部份不在此份SOP討論範圍內有興趣

的讀者可參考 httpwwwlinuxvirtualserverorg 網站

1921680100 1921680200

Host A MasterSlave Server

Host B MasterSlave Server

Virtual Host

圖 Virtual Server + Two-way replication 架構圖

97

圖 High Availability Linux Virtual Server架構圖

98

  • COSA-SOP-03-006
  • 第一章 簡介
    • 11適用對象 (Audience)
    • 12 MySQL本身
    • 13 MySQL 40版跟50版重大的改進功能
    • 14 各家資料庫軟體比較
      • 第二章 前置需求
      • 第三章 安裝
        • 31 MySQL安裝
        • 32 phpMyAdmin安裝
        • 33 升級及注意事項
          • 第四章 MySQL管理
            • 41 Webmin 管理介面
            • 42 phpMyAdmin 的操作介面
            • 43管理指令介紹
              • 431 利用mysqladmin設定root的密碼
                  • 第五章 實用範例
                    • 51 任務一Web Base客戶通訊錄
                    • 52 任務二Web Base群組軟體 ( twig )
                      • 第六章 維護及更新程序
                        • 61 日常維護
                        • 62 更新程序
                        • 63 備份重要檔案
                        • 64 離線備份與還原
                        • 65 線上備份與還原
                          • 第七章 問題與解答
                          • 第八章 參考資料
                          • 附錄一 SQL Command 介紹
                          • 附錄二Replication
Page 20: DataBase Server Standard Operation Procedureebooks.lib.ntu.edu.tw/1_file/oss/63/93doc4-5.pdf · 業務的公司帶來了不少壓力,譬如微軟,甲骨文 ... 外的錢用在第三方的資料庫產品上,譬如就可以不用再購買甲骨文公司

圖 3-15 顯示行號

Step 6 修改下列設定 第 39 行 設定 phpMyAdmin的 URL 第 69 行 MySQL Server 的 ip 第 80 行 利用何帳號存取 MySQL 第 81 行 如果 root有設定 password此處即填入 root的 password

30 In most cases you can leave this variable empty as the correct value

31 will be detected automatically However we recommend that you do

32 test to see that the auto-detection code works in your system A good

33 test is to browse a table then edit a row and save it There will be

34 an error message if phpMyAdmin cannot auto-detect the correct value

35

36 If the auto-detection code does work properly you can set to TRUE the

37 $cfg[PmaAbsoluteUri_DisableWarning] variable below

38

39 $cfg[PmaAbsoluteUri] = httpossccosaorgtwphpMyAdmin

hellip

20

hellip

69 $cfg[Servers][$i][host] = localhost MySQL hostname or IP address hellip 80 $cfg[Servers][$i][user] = root MySQL user

81 $cfg[Servers][$i][password] = 1234 MySQL password (only needed

圖 3-16 修改 configincphp

21

圖 3-17 修改 configincphp

圖 3-18 修改 configincphp p

Step 7 設定語系

22

圖 3-19 設定語系

圖 3-20 執行 phpMyAdmin

23

33 升級及注意事項

RedHat 90附的 MySQL版本為 323 MySQL所釋出最新穩定版本為

40若是您不想用系統預附的 323請先利用下列移除之前 323的版本

rpm ndashe mysql-devel rpm ndashe mysql-server rpm ndashe mysql --nodeps 然後到下列網址下載您所想要的版本進行安裝在這裏我們用 4014版為例 Step 1 下載相關套件( httpwwwmysqlcomdownloadsmysql-40html )

圖 3-21 Download MySQL 4014 相關 RPM Step 2 利用 rpm 指令安裝

24

圖 3-22 Install MySQL 4014 相關 RPM

圖 3-23 Install MySQL 4014 相關 RPM

Step 3 啟動 MySQL

25

圖 3-24 啟動 MySQL 4014 並修改密碼

26

第四章 MySQL管理

本章將我們介紹利用WebminphpAdminCommand的方式建立一個名為

CONTACT的資料庫內有一個 address的 Table作為我們客戶通訊錄程式使

用的資料庫

41 Webmin 管理介面

412建立資料庫

Step 1 登入Webmin

圖 4-1 登入WebMin

Step 2 點選伺服器

27

圖 4-2 伺服器畫面

Step 3 點選 MySQL資料庫伺服器

圖 4-3 MySQL資料庫伺服器

28

Step 4 建立一個新的資料庫

圖 4-4 建立 MySQL資料庫

Step 5 建立名為 CONTACT的資料庫

29

圖 4-5 指定資料庫名稱

412 建立資料表

假設我們要建立一個名為 address的 Table其結構如下 欄位名稱 資料型態 長度 說明 id INT (自動編號) 連絡人編號 name varchar文字 20 連絡人姓名 tel Varchar文字 15 連絡人電話 Step 1 選擇 CONTACT資料庫

30

圖 4-6 選擇資料庫

Step 2 指定欄位數目

31

圖 4-7 設定欄位數目

Step 3設定表格欄位屬性

圖 3-8 設定表格欄位屬性

Step 4建立表格資料

32

圖 4-9 建立表格資料

圖 4-10 檢視資料

33

圖 4-11 新增資料

圖 4-12

34

圖 4-13

413 使用者管理

接下來我們要利用Webmin 來建立資料庫使用者並給予某些權限 Step1建立使用者

35

圖 4-14 選擇使用者權限

圖 4-15

36

Step2 賦予權限

圖 4-16

Step3 權限列表

37

圖 4-17

38

42 phpMyAdmin 的操作介面

421建立資料庫

Step 填入資料庫名稱並按「建立」

圖 4-18建立資料庫

422 建立資料表

Step1 填入資料表名稱並指定欄位數量 執行

39

圖 4-19填入資料表名稱並指定欄位數量

Step2 設定欄位屬性

圖 4-20設定欄位屬性

40

Step3 phpMyAdmin會產生相關的 SQL Command

圖 4-21 資料表結構及相關 SQL Command

Step4新增 Record

41

圖 4-22

圖 4-23

42

圖 4-24

圖 4-25

43

423使用者管理

Step1建立使用者

圖 4-26

44

圖 4-27

Step2 給予權限

圖 4-28

Step3權限列表

45

圖 4-29

43管理指令介紹

431 利用 mysqladmin設定 root的密碼

當您在Windows 或 Linux 中安裝好 MySQL後系統會自動幫您建立兩個

帳分別是 root 和 匿名者MySQL的 root 跟 Linux 最高權限使用者 root無關MySQL的 root使用者相當於 MS SQL 中的 sa 帳號擁有最高的 Database管理權限但系統預設 MySQL的 root 是不需要密碼所以通常我們一安裝

MySQL後首要任務便是修改 root的密碼 我們可以利用 mysqladmin工具或是直接修改 MySQL內部資料庫的使用者資

料 mysqladmin ndashu root ndashh cosaexamplecom password lsquo1234rsquo

46

-u 表示使用者帳號root 為 MySQL預設的管理帳號

-h 表示 MySQL主機的主機名稱也可使用 IP Address password 表示使用者的密碼因為字串請使用單引號將密碼括起來 密碼設定完成之後還是可以利用 mysqladmin修改密碼但是你必須提供目前的密碼

432 連線 MySQL

mysql -uroot -p密碼 (-p和密碼之間不能有空白) 或 mysql -uroot -p (此方式會在進入後要求密碼) [rootossc phpMyAdmin] mysql -u root -p1234

Welcome to the MySQL monitor Commands end with or g

Your MySQL connection id is 25 to server version 32354

Type help or h for help Type c to clear the buffer

mysqlgt show databases

+----------+

| Database |

+----------+

| mysql |

| test |

+----------+

2 rows in set (000 sec)

mysqlgt exit

Bye

[rootossc phpMyAdmin]

433 建立資料庫

可利用 mysqladmin指令建立 CONTACT資料庫 mysqladmin -u root -p1234 create CONTACT

47

或是利用 mysql指令 [rootossc bluepage] mysql -u root -p1234 Welcome to the MySQL monitor Commands end with or g Your MySQL connection id is 1057 to server version 32354 Type help or h for help Type c to clear the buffer mysqlgt create database CONTACT Query OK 1 row affected (000 sec) mysqlgt show databases +----------+ | Database | +----------+ | CONTACT | | address | | hello | | mysql | | nuke | | test | +----------+ 6 rows in set (000 sec) mysqlgt exit

434 建立資料表

編寫 adresssql內容如下 -- Table structure for table address CREATE TABLE address ( id int(11) NOT NULL auto_increment name varchar(20) NOT NULL default tel varchar(15) NOT NULL default PRIMARY KEY (id) ) TYPE=MyISAM

48

-- Dumping data for table address INSERT INTO address VALUES (1林小明0800016888) INSERT INTO address VALUES (2黃大雄0800016888) INSERT INTO address VALUES (3劉小芬0800024365) 然後執行此 sql script mysql -u root -p1234 CONTACT lt addresssql 或是利 mysql command [rootossc bluepage] mysql -u root -p1234 Welcome to the MySQL monitor Commands end with or g Your MySQL connection id is 1090 to server version 32354 Type help or h for help Type c to clear the buffer mysqlgt use CONTACT Database changed Database changed mysqlgt CREATE TABLE address ( -gt id int(11) NOT NULL auto_increment -gt name varchar(20) NOT NULL default -gt tel varchar(15) NOT NULL default -gt PRIMARY KEY (id) -gt ) TYPE=MyISAM Query OK 0 rows affected (000 sec) mysqlgt INSERT INTO address VALUES (1林小明0800016888) Query OK 1 row affected (000 sec) mysqlgt INSERT INTO address VALUES (2黃大雄0800016888) Query OK 1 row affected (000 sec) mysqlgt INSERT INTO address VALUES (3劉小芬0800024365) Query OK 1 row affected (000 sec) mysqlgt exit Bye

49

第五章 實用範例

51 任務一Web Base客戶通訊錄

任職於開放科技公司的林小明前些日子在最符合成本效益的條件下快

速地完成公司網站的建置老闆因此對小明讚譽有加最近因為公司存放客戶資

料的 SQL Server主機屢遭病毒攻擊加上作業系統本身的問題當機次數頻繁

老闆希望能儘快把公司的客戶通訊錄程式移轉到較穩定的環境上因為此客戶通

訊錄程式最主要給內部人員使用所以介面美觀並不特別要求只求穩定且能快

速得到查詢結果老闆希望在短時間先看到程式的雛型並鍵入資料對其效率

及穩定性進行測試因為上次小明表現突出所以這次不可能的任務自然又落到

小明身上 小明想來想去既然要快速又穩定他而且又不希望所有人都得安裝 Client

程式於是小明決定)捨棄他的舊愛「Delphi+MS SQL」投向新歡「Apache + MySQL + PHP」利用此架構來設計一個簡單實用的Web Base客戶通訊錄程式

511 Web Base客戶通訊錄架構

此程式需要建立 CONTACT的資料庫並建立 adress Tables其結構如下表建立步驟請參考第三章 欄位名稱 資料型態 長度 說明 id INT (自動編號) 連絡人編號 name varchar文字 20 連絡人姓名 tel Varchar文字 15 連絡人電話 Web Base通訊錄共有下列幾個檔案功能如下表

檔案名稱 說明 Indexhtml Web Base通訊錄首頁 addphp 新增連絡人的 php程式 searchphp 尋找連絡人的 php程式 editphp 具有更新及刪除功能的 php程式

50

我們將這些檔案放至varwwwhtmlbluepage (預設無 bluepage目錄)

512 Web Base通訊錄測試

httpwwwopencombluepage 新增資料

圖 5-1 新增連絡人

圖 5-2 填入資料

51

圖 5-3 新增成功

搜尋及異動資料

圖 5-4 搜尋通訊錄

52

圖 5-5 編輯資料

圖 5-6 更新資料

513 程式內容及說明

lt-- 程式範例indexhtml--gt lthtmlgt ltheadgtlttitlegt通訊錄lttitlegtltheadgt ltbodygt ltcentergt

53

lth2gt通訊錄lth2gtlthrgt lta href=indexhtmlgt通訊錄ltagt | lta href=addphpgt新增連絡人ltagt | lta href=searchphpgt搜尋通訊錄ltagt ltcentergt ltbodygt lthtmlgt lt-- 程式範例addphp --gt lthtmlgt ltheadgtlttitlegt新增連絡人lttitlegtltheadgt ltbodygt ltcentergtlth2gt新增連絡人lth2gtltcentergtlthrgt lt 取得欄位資料 if (isset($_POST[Name]) ampamp isset($_POST[Tel]) ) $name = $_POST[Name] $tel = $_POST[Tel] 檢查是否有輸入欄位資料 if ($name = ampamp $tel = ) 建立 SQL字串 $sql = INSERT INTO address (name tel) values( $sql= $name $tel) 建立 MySQL 連結 $link = mysql_connect(localhostroot1234) 選擇資料庫 mysql_select_db(CONTACT) 執行 SQL指令 mysql_query($sql) mysql_close($link) echo ltfont color=redgt新增連絡人成功ltfontgtltbrgt gt ltform action=addphp method=postgt lttable border=0 width=300gt lttrgtlttdgt姓名 lttdgt

54

lttdgtltinput type=text name=Name size=20 maxlength=10gtlttdgtlttrgt lttrgtlttdgt電話 lttdgt lttdgtltinput type=text name=Tel size=20 maxlength=20gtlttdgtlttrgt lttrgtlttd colspan=2 align=centergt ltinput type=submit value=新增連絡人gtlttdgtlttrgt lttablegt ltformgt ltbrgtlta href=indexhtmlgt通訊錄ltagt | lta href=addphpgt新增連絡人ltagt | lta href=searchphpgt搜尋通訊錄ltagt ltbodygt lthtmlgt

lt-- 程式範例searchphp --gt lthtmlgt ltheadgtlttitlegt搜尋通訊錄lttitlegtltheadgt ltbodygt ltcentergtlth2gt搜尋通訊錄lth2gtlthrgt lt if (isset($_POST[Search])) 建立資料庫連結並選定資料庫 $link = mysql_connect(localhostroot1234) mysql_select_db(CONTACT) 建立基本的 SQL字串 $sql = SELECT FROM address 檢查是否輸入姓名 if (chop($_POST[Name]) = ) $name = name LIKE $_POST[Name] else $name = 檢查是否輸入電話號碼 if (chop($_POST[Tel]) = ) $tel = tel LIKE $_POST[Tel] else $tel =

55

if條件組合 SQL字串 if (chop($name) = ampamp chop($tel) = ) $sql= WHERE $name AND $tel elseif (chop($name) = ) 只有姓名 $sql = WHERE $name elseif (chop($tel) = ) 只有電話號碼 $sql = WHERE $tel $sql= ORDER BY name 最後加上排序 $result = mysql_query($sql) 取得欄位數 $total_fields = mysql_num_fields($result) echo lttable border=1gt echo lttrgtlttdgt編號lttdgtlttdgt姓名lttdgtlttdgt電話lttdgtlttd colspan=2gt功能選項lttdgtlttrgt 表格顯示查詢結果 while ($rows = mysql_fetch_array($result MYSQL_NUM)) echo lttrgt for ($i = 0 $i lt $total_fields $i++) echo lttdgt$rows[$i]lttdgt echo lttdgtlta href=editphpaction=editampid= echo $rows[0]gtltbgt編輯ltbgtlttdgt echo lttdgtlta href=editphpaction=delampid= echo $rows[0]gtltbgt刪除ltbgtlttdgt echo lttrgt echo lttablegtlthrgt mysql_free_result($result) mysql_close($link) gt ltcentergt ltform action=searchphp method=postgt lttable border=0 width=450gt lttrgtlttdgt搜尋姓名 lttdgt lttdgtltinput type=text name=Name size=10 maxlength=20gtlttdgtlttrgt lttrgtlttdgt搜尋電話 lttdgt lttdgtltinput type=text name=Tel

56

size=20 maxlength=20gtlttdgtlttrgt lttrgtlttd colspan=2 align=centergt ltinput type=submit name=Search value=搜尋gtlttdgtlttrgt lttablegt ltformgt ltbrgtlta href=indexhtmlgt通訊錄ltagt | lta href=addphpgt新增連絡人ltagt | lta href=searchphpgt搜尋通訊錄ltagt ltbodygt lthtmlgt

lt ob_start() gt lt-- 程式範例editphp --gt lthtmlgt ltheadgtlttitlegt編輯通訊錄lttitlegtltheadgt ltbodygt lt 取得 URL 參數 $id = $_GET[id] $action = $_GET[action] 建立資料庫連結 $link = mysql_connect(localhostroot1234) mysql_select_db(CONTACT) 選擇資料庫 執行的操作 switch ($action) case update 更新 取得欄位資料 $name = $_POST[Name] $tel = $_POST[Tel] $sql = UPDATE address SET name=$name tel=$tel WHERE id=$id mysql_query($sql) 執行 SQL指令 mysql_close($link) header(Location searchphp) 轉向到 serachphp break case del 刪除 $sql = DELETE FROM address WHERE id=$id

57

mysql_query($sql) 執行 SQL指令 mysql_close($link) header(Location searchphp) 轉向到 serachphp break case edit 編輯 $sql = SELECT FROM address WHERE id=$id $result = mysql_query($sql) 執行 SQL指令 $row = mysql_fetch_row($result) 取回記錄 $name = $row[1] 取得欄位 name $tel = $row[2] 取得欄位 tel mysql_close($link) 顯示編輯表單 gt ltcentergtlth2gt更新通訊錄lth2gtltcentergtlthrgt ltform action=editphpaction=updateampid=lt echo $id gt method=postgt lttable border=0 width=300gt lttrgtlttdgt姓名 lttdgt lttdgtltinput type=text name=Name size=20 maxlength=10 value=lt echo $name gtgtlttdgtlttrgt lttrgtlttdgt電話 lttdgt lttdgtltinput type=text name=Tel size=20 maxlength=20 value=lt echo $tel gtgtlttdgtlttrgt lttrgtlttd colspan=2 align=centergt ltinput type=submit value=更新連絡人gtlttdgtlttrgt lttablegt ltformgt ltbrgtlta href=indexhtmlgt通訊錄ltagt | lta href=addphpgt新增連絡人ltagt | lta href=searchphpgt搜尋通訊錄ltagt lt break gt ltbodygt lthtmlgt

58

52 任務二Web Base群組軟體 ( twig )

順利完成Web Base客戶通訊錄程式測試一段時間後「Apache + MySQL + PHP」架構的穩定與快速巳深得老闆與公司所有同事的認同隨著公司業績蒸

蒸日上人員組織編罝愈來愈龐大跨部門的會議愈來愈多業務員每日排滿拜

訪客戶的行程跟客戶的 Email的往來也愈來愈頻繁 愈來愈多部門的同事希望公司能建置一套群組軟體提供 web mail可讓業

務人員方便收發 mail還有連絡人議事日程待辦工作書簽等功能讓整個

公司運作及個人時間管理更有效率

老闆問小明對這些需求有什麼看法小明認為如果這些功能完全由程式部

門開發必定曠日費時而且耗費公司資源小明在網路尋找是否有提供這些功能

的Free Software皇天不負苦心人小明發現了TWIG (The Web Information Gateway) httptwigscrewdrivernet這個群組軟體它在 Web 上整合郵件新聞聯絡人議事日程工作序書簽等功能非常符合公司的需求 Step 1 下載 twig-277targz 下載網址 httptwigscrewdrivernetdownloadphp3

Step 2 解開 twig-277targz tar -xzvf twig-277targz

59

Step 3 執行安裝動作安裝到 varwwwhtmltwig 目錄 cd twig-277 twig-install varwwwhtmltwig

Step 4 建立 MySQL 資料庫(twig)及各資料表

cd setup mysql -u root -p1234 mysqlgt create database twig Query OK 1 row affected (001 sec) mysqlgt quit mysql -u root ndashp1234 twiglt twigtablemysql

Step 5 修改 configincphp3 參數設定 vi varwwwhtmltwigconfigconfigincphp3 $config[fromdomain] = opencom 網域 $config[language] = chinesebig5 中文訊息 $config[imap_port] = 143notls

60

Step 6 修改連結 MySQL 的帳號密碼 vi varwwwhtmltwigconfigdbconfigincphp3 $dbconfig[sqlusername] = root username $dbconfig[sqlpassword] = 1234 password

Step 7 其他設定檔

vi etchttpdconfhttpdconf 加入 AddType applicationx-httpd-php php3 在 DirectoryIndex最後加入 indexphp3 DirectoryIndex indexhtml indexhtmlvar indexphp3 在 AddDefaultCharset ISO-8859-1加上 AddDefaultCharset ISO-8859-1

vi etcphpini register_globals = On service httpd restart Step 8 sendmail 設定 vi etcmailsendmailcf在 264 行前面加上並重新啟動 sendmail「service snedmail restart」 262 SMTP daemon options 263 264 O DaemonPortOptions=Port=smtpAddr=127001 Name=MTA 265 266 SMTP client options 267 O ClientPortOptions=Family=inet Address=00

61

Step 9 檢查設定有無錯誤 http主機名稱twigtestphp3

62

Step 10 登入 twig ( http主機名稱twig)

63

第六章 維護及更新程序

61 日常維護

系統管理員最好定期以 root 身份登入看看信件在 RedHat Linux 中有一支 logwatch 程式會定時去分析 log file如果發現異常便會發信給 root除此之外筆者建議讀者平時就檢查 MySQL log file ( varlogmysqldlog)是否有異常情形

62 更新程序

讀者可至httprpmfindnet 尋找MySQL相關套件至於升級的相關步驟請參

考Linux OS SOP 第 54節

63 備份重要檔案

預設 MySQL 的 DB 檔案是存在 varlibmysql 內以 DB名稱為目錄目錄

內就是該 DB 的所有資料通常得定期備份還有 MySQL的設定檔 etcmycnf也別忘了一起備份

64 離線備份與還原

641 離線備份

預設 MySQL 的 DB 檔案是存在 varlibmysql 內以 DB 名稱為目錄目錄內

就是該 DB 的所有資料像 CRM 這個 DB就是存在 varlibmysqlCRM 內在備份前因為怕資料尚未完全寫入磁碟而且 MySQL 會 Lock 在使用的 DB 檔案所以應該是要先把 MySQL 先 Shutdown 一下整個備份的程序可以下像下面的指令去完成 cd varlibmysql

64

service mysqld stop tar cvfz CRM_db_20030905tgz CRM service mysqld start 對這樣就可以了 不過要注意的是怕 DB 內每個 Tables 間的資料有關關

聯性所以最好是把整個 DB 一次備起來單獨只備哪個 Tables 的檔案以後回存時怕會有資料關聯不一致的問題

642 離線還原

DB 發生錯誤而要回存時其實也不難先找出最近一次完整正常的備份先把現在錯誤的網頁或 DB 先更名或 tar 起來再把好的備份給解開回原來目錄位

置就行了需要注意的是 MySQL 服務最好也是要先停止回存完成後再啟動服務回存 DB 的整個程序可能像下面 cd varlibmysql service mysqldstop mv CRM CRM_OLD tar xvfz CRM_db_20030905tg service mysqld start

65 線上備份與還原

651 線上備份

使用像上面的檔案方式備份是個不錯的方法它最少可以保持該主機某個時間點的完整檔案備份但還是有一些問題需要考慮到有些主機就不只建立一個 DB 而已總不能為了備份某個 DB 而把整個 MySQL 服務停止備份檔案的方式回存在原主機上一定適用但假如 MySQL 版本升級或是在那天該網頁空間需遷機移機到別的主機時那就沒人敢保證備出來的資料檔可以用所以我們可以考慮另一種備份的方式是使用 MySQL 本身提供的功能 MySQL Data Dump指令是 mysqldump

65

使用 MySQL 的 Dump 功能可以把 DB 的結構資料或結構加資料 Dump 成文字檔 mysqldump 指令提供的彈性很大你可以選擇把整個 DB Dump 成一個檔或是每個 Table 為一個檔甚至是把結構檔和資料分開儲存都

可以 mysqladmin -uroot -p flush-logs mysqldump CRM -uroot -p --opt gt CRM_20030905sql (CRM 是 DB 名稱 opt 是一個使用完整 Dump 參數) 假如只是要單獨 Dump 某個 Table 時只要在上面的指令後轉出符號 gt 前加個 Table 名稱就可以如只要 phpbb2_users 這個 Table 的 Dump 時只要下 mysqldump CRM -uroot -p --opt CUSTOMER gt CRM_CUSTOMER_20030905sql

652 線上還原

若要回存整個資料庫只需將壓縮的備份檔還原成 Dump 的檔案再用下面的指令回存 mysql CRM -uroot -p lt CRM_20030905sql 這邊需注意的是若建立備份時是以--opt或--add-drop-table為參數時回存的 動作是先將舊的 Table 先刪除重建 Table 的結構後再把 Data 匯入所以回存後所有的資料會回到你當時備份那個時間點因此在回存資料時可以考慮把現有錯誤或不完整的 DB 先備份一份下來以備不時之需或是拿來比對錯誤的地

方在那裡當然你也可以把資料回存到另一個測試用的 DB 內只要把上面指令

的 DB 名稱改成你的測試用 DB 名稱即可 使用這種回存方式 MySQL 服務不需停止也不會動到其他正在使用的 DB 在一些提供 MySQL 服務的虛擬主機可用這種方式作你自己的 DB 備份及回存

66

另外假如你是系統重建或是移機時切需在新的 MySQL 內新建一個空白 DB 後才行作回存的工作你可以用下面的指令建立 mysql -uroot -p -e CREATE DATABASE CRM (上面的 CRM是你要新建的 DB 名稱) 另一種作法先用 mysql 指令進入 mysql client console 然後再用 CREATE DATABASE CRM 這樣就行了記得尾端要加個 符號該行指令才會執行

67

第七章 問題與解答

Q1RedHat 90預附的 MySQL到底有無支援 Transcation機制 Ans MySQL自 32334a之後的 MySQL-Max版本加入 InnoDB的資料庫類型透過

InnoDBMySQL同樣可以進行 COMMIT與 ROLLRACK的動作RedHat 90預附的 MySQL為 32354a-11巳支援 InnoDB的資料庫類型不過必須做以

下設定 1cp usrsharedocmysql-server-32354amy-mediumcnf to etcmycnf 2 vi etcmycnf 將以下設定前的拿掉 innodb_data_home_dir = varlibmysql innodb_data_file_path = ibdata110Mautoextend innodb_log_group_home_dir = varlibmysql innodb_log_arch_dir = varlibmysql 3service mysqld restart 如此一來各位在建立Table時便可指定Table Type為 innodb ( ex create table with type=innodb ) Q2如何解決 php+mysql 許功蓋等字變亂的問題 Ans 方法一 【確定 MySQL 預設的字元集】 1 打開 WinMySQLadmin 管理畫面(在視窗右下角狀態列紅綠燈圖示中按滑鼠

右鍵點選 Show me 選項) 2 點選管理畫面中 [Variables] 標籤選項其中 character_set變數就是您預設

字元集的變數其預設是 latin1 字元集(我們要將他改回 big5)而 chatacters_set 變數則是 MySQL 可以支援哪些字元集 【修改預設字元集變數 character_set 】 1 請點選管理畫面中 [myini Setup] 標籤選項設定 myini 2 按一下 [Pick-up and Edit myini values] 按鈕以便編輯目前的 myini 設定 3 在 [mysqld] 設定區塊底下新增一行 default-character-set = big5 變數設

68

定 4 新增一個 [client] 設定區塊並加入第三步驟的變數設定(游標往下移到空白處新增兩行 [client] 和 default-character-set=big5) 5 按一下畫面左下方 [Save Modification] 按鈕儲存設定 6 重新啟動 MySQL 或 Windows 方法二 Server端注意事項 phpini 中有關的設定為(預設值) Magic quotes for incoming GETPOSTCookie data magic_quotes_gpc = On Use Sybase-style magic quotes (escape with instead of ) magic_quotes_sybase = Off Client端注意事項 1中文資料送進 mysql 前請用 addslashes($str) 處理 2處理後送進 mysql 時請用 括起來並在參數後留一個空白如 $sql = UPDATE ezf_table set tablename=$tname tableend=$endtime table inguser=$tguser tableingid=$tguserid tableallnumber=$tnumber tableloca l=$tablelocal tableanyone=$tableopen tabletext=$ttext WHERE tableid=$t ableid tablename=$tname c 取出時請用 stripslashes($str) Q3MySQL root 密碼忘了該怎麼辦 Ans 1先停掉 mysql etcrcdinitdmysql stop 2以--skip-grant-table 的參數啟動 mysql safe_mysql --skip-grant-tableamp 3 更改 root 密碼 mysql mysql mysqlgt UPDATE user SET password=password(newpassword)

69

WHERE user=root mysqlgt FLUSH PRIVILEGES mysqlgt exit 4停掉 mysql再重跑 mysqladmin -uroot -p shutdown Enter password 輸入新設定的密碼 etcrcdinitdmysql start

Q4NULL值問題

Ans

NULL值的概念是造成 SQL的新手的混淆的普遍原因他們經常認為 NULL是和一個空字符串的一樣的東西不是這樣的例如下列語句是完全不同的

mysqlgt INSERT INTO my_table (phone) VALUES (NULL)

mysqlgt INSERT INTO my_table (phone) VALUES ()

兩個語句把值插入到 phone 列但是第一個插入一個 NULL值而第二個插入一個空字符串第一個的含義可以認為是ldquo電話號碼不知道而第二個則可意味

著ldquo她沒有電話

在 SQL中NULL值在于任何其他值甚至 NULL值比較時總是假的(FALSE)包含 NULL的一個表達式總是產生一個 NULL值除非在包含在表達式中的運算符和函數的文檔中指出在下列例子所有的列返回 NULL

mysqlgt SELECT NULL1+NULLCONCAT(InvisibleNULL)

如果你想要尋找值是 NULL的列你不能使用=NULL測試下列語句不返回任

何行因為對任何表達式expr = NULL是假的

mysqlgt SELECT FROM my_table WHERE phone = NULL

要想尋找 NULL值你必須使用 IS NULL測試下例顯示如何找出 NULL電話號碼和空的電話號碼

70

mysqlgt SELECT FROM my_table WHERE phone IS NULL mysqlgt SELECT FROM my_table WHERE phone =

在 MySQL中就像很多其他的 SQL服務器一樣你不能索引可以有 NULL值的列你必須聲明這樣的列為 NOT NULL而且你不能插入 NULL到索引的

列中

當用 LOAD DATA INFILE 讀取數據時空列用更新如果你想要在一個列中有

NULL值你應該在文本文件中使用N字面上的詞NULL也可以在某些情形下使用

當使用 ORDER BY時首先呈現 NULL值如果你用 DESC以降序排序NULL值最後顯示當使用 GROUP BY時所有的 NULL值被認為是相等的

為了有助于NULL的處理你能使用 IS NULL和 IS NOT NULL運算符和 IFNULL()函數

對某些列類型NULL值被特殊地處理如果你將 NULL插入表的第一個TIMESTAMP 列則插入當前的日期和時間如果你將 NULL插入一個AUTO_INCREMENT 列則插入順序中的下一個數字

Q5如何將圖片存放於 MySQL中

Ans

Step 1建立資料庫 test

Step 2 建立表格 binary_data

CREATE TABLE binary_data (

id INT(4) NOT NULL AUTO_INCREMENT PRIMARY KEY

description CHAR(50)

bin_data LONGBLOB

filename CHAR(50)

filesize CHAR(50)

filetype CHAR(50)

71

)

Step 3 利用 storephp 寫入圖片

storephp 程式碼

ltHTMLgt ltHEADgtltTITLEgtStore binary data into SQL DatabaseltTITLEgtltHEADgt ltBODYgt lt code that will be executed if the form has been submitted

if ($submit) mysql_connect(localhostrootYOUR_PASSWORD) mysql_select_db(test) $data=Base64_Encode(fread(fopen($form_data r) filesize($form_data))) $result=MYSQL_QUERY(INSERT INTO binary_data (descriptionbin_datafilenamefilesizefiletype) VALUES ($form_description$data$form_data_name$form_data_size$form_data_type)) $id= mysql_insert_id() print ltpgtThis file has the following Database ID ltbgt$idltbgt MYSQL_CLOSE() else else show the form to submit new data

gt

ltform method=post action=ltphp echo $PHP_SELF gt enctype=multipartform-datagt File Descriptionltbrgt ltinput type=text name=form_description size=40gt ltINPUT TYPE=hidden name=MAX_FILE_SIZE value=4000000gt ltbrgtFile to uploadstore in databaseltbrgt ltinput type=file name=form_data size=40gt ltpgtltinput type=submit name=submit value=submitgt ltformgt lt

72

gt ltBODYgt ltHTMLgt

Step 3 利用 storephp 取出圖片

getdataphp 程式碼

lt Syntax getdataphp3id=ltidgt if($id) you may have to modify login information for your database server MYSQL_CONNECT(localhostrootYOUR_PASSWORD) mysql_select_db(test) $query = select bin_datafiletype from binary_data where id=$id $result = MYSQL_QUERY($query) $data = Base64_Decode(MYSQL_RESULT($result0bin_data)) $type = MYSQL_RESULT($result0filetype) Header( Content-type $type) echo $data gt

Q6MySQL裝好之後啟動時或是執行 mysqladmin會出現如下訊息 Cant connect to local MYSQL Server through Socket varlibmysqlmysqlsock或是

Cant connect to local MYSQL Server through Socket tmpmysqldsock

Ans 可能有下列幾個原因

1這個 mysqldsock 不見了被某人刪除了或是被一些系統自動執行程式給刪

了例如有些 cron任務便會設定定期刪除 tmp 裡的東西所以呢您只能修改

cron 裡的設定讓它不要清除 mysqldsock 2在啟動時也可以改變 mysqldsock的位置您在啟動 MySQL的時候可以加入此參數usrlocalmysqlbinsafe_mysqld --user=mysql --socket=其他路

徑socket amp 同時得去設定環境變數 MYSQL_UNIX_PORT的值以指定新的

73

路徑 3若是您沒改 MYSQL_UNIX_PORT的值那麼您可以在執行指令的時候才打

例如mysqladmin --socket=其他路徑socket version Q7How to get the last insert id Ans CREATE TABLE product ( id INT(4) NOT NULL AUTO_INCREMENT PRIMARY KEY description VARCHAR(50) ) 1利用 SQL的話 mysqlgt insert into product(description) values(123) Query OK 1 row affected (000 sec) mysqlgt select last_insert_id() +------------------+ | last_insert_id() | +------------------+ +------------------+ 1 row in set (000 sec) ======================================== 2如果是 PHP的話 你可以用mysql_insert_id()取得該 id PHP example $result=MYSQL_QUERY(INSERT INTO product (description) VALUES ($description)) $id= mysql_insert_id() print This file has the following Database ID $id Q8如何將文字檔匯入資料庫 Ans $addr=homehttpdhtmlphpschool001txt $sql_select = load data infile $addr into table test fields terminated by t 解說 $sql_select = load data infile 文字檔名 into table 表格名 fields terminated by

74

t

(欄位分隔以 TAB鍵) 該文字檔須與資料表欄位格式相符 例如欄位有三個 則文字檔為每行一筆資料如下 欄 1資料ltTABgt欄 2資料ltTABgt欄 3資料 欄 1資料ltTABgt欄 2資料ltTABgt欄 3資料 欄 1資料ltTABgt欄 2資料ltTABgt欄 3資料 欄 1資料ltTABgtltTABgt欄 3資料

Q9如何撰寫 MySQL C API Ans Step 1利用文字編輯器撰寫以下程式碼 mysqlcc

include ltstdiohgt

include ltmysqlmysqlhgt

int main (int argc char argv[])

MYSQL mysql

MYSQL_RES res

MYSQL_ROW row

if (argc = 2)

fputs (Usage myc ltdatabasegt stderr)

return 1

if ((mysql_connect(ampmysqllocalhostrootYour_Password)))

fputs (Error connecting stderr)

abort()

75

if (mysql_select_db(ampmysqlargv[1]))

fputs (Error selecting database stderr)

abort()

if (mysql_query(ampmysqlSELECT FROM test_table))

fputs (Error processing query stderr)

abort()

if ((res = mysql_store_result(ampmysql)))

fputs (Error storing results stderr)

abort()

while((row = mysql_fetch_row(res)))

uint i = 0

for (i=0 i lt mysql_num_fields(res) i++)

printf(s row[i])

printf(n)

return 0

Step 2 Compile

gcc -Iusrlocalmysqlinclude -Lusrlocalmysqllibmysql mysqlcc ndashlm -lmysqlclient

(其中 include path與 library path取決於你的 MySQL安裝路徑)

76

如果執行時發生如下 error Run problemerror in loading shared libraries libmysqlclientsoX 將你的 MySQL library path(for exampleusrlocalmysqllibmysql) 加入etcldsoconf and run sbinldconfig -v Q9ASP + MySQL 範例程式 Ans Dim myconn As New ADODBConnection Dim myrs As New Recordset Dim mySQL As String Dim myrows As Long myconnOpen DSN=MyODBCsample mySQL = SELECT from user myrsSource = mySQL Set myrsActiveConnection = myconn myrsCursorLocation = adUseClient myrsOpen myrows = myrsRecordCount myrsClose myconnClose 可參考 httpwwwdwamnetmysqlasp_myodbcasp 有詳細的資料 Q10如何將 MySQL中的資料庫匯出成txt檔 Ans select from TableName into outfile textxls all result fields will seperate by tab

77

第八章 參考資料

英文部份 網址 1 httpwwwmysqlcom MySQL 網站有第一手有關 MySQL的資料 2 httpwwwmysqlcomdocenReplicationhtml 有關 MySQL Replication 的文件 3 httpwwwgeocitiescomsqlhomefaqstore_blobhtml 如何在 MySQL 存放 BLOB的資料 4httpwwwsapdborg 有關 SAP跟 MySQL相關合作的網站 書藉 1 Cooking with MySQL

Paul DuBois has selected sample recipes from the hundreds youll find in his book MySQL

Cookbook In this third and final series of excerpts showcasing these recipes learn how to

compute team standings how to calculate the differences between successive Dec 26

2002 2 Tips for Building Web Database Applications with PHP and MySQL by Hugh E Williams co-author of Web Database Applications with PHP amp MySQL 04042002

3 Managing and Using MySQL 2nd Edition By Tim King George Reese Randy Jay Yarger

4 MySQL Cookbook By Paul DuBoisPublisher OReillyPub Date October 2002

中文部份

78

1 httplinuxtncedutwtechdocmysqlmysql_docmanual_tochtml MySQL 中文手冊 2 httpchenshloxaedutwphpZ_1php PHP+MySQ程式研習設計網站 3 httplinuxtncedutwtechdocbanicdownhtml PHP 4 手冊 4 httpwwwtncedutwadmin_zonephp台南縣教育網網路中心有很多 Linux相關文件 5 httpdobtncedutw網站建置百寶箱有很多 PHP MySQL 相關範例程式 5 httpwwwdbworldcomtw資料庫專家電子雜誌介紹資料庫的重要觀念及名詞

79

附錄一 SQL Command 介紹

SQL (讀音ess-que-el) 是一種結構查詢語法SQL 使用於資料庫交流

傳遞相容於 ANSI (American National Standards Institute) 是一套標準的關聯

式資料庫語言 SQL 語言是執行更新或從資料系統獲取資料一般常見的關聯

資料庫系統都有提供 SQL 如 Oracle Sybase Microsoft SQL Server Access Ingres 等雖然大部份的資料庫都有提供 SQL 但也多提供了自已獨特的語

法造成了不相容的情形但標準基本的語法是相通的如Select Insert Update Delete Create and Drop 每一個系統都有支援

Table相關 Command

Create Table

關聯式資料庫包含有很多元件稱為資料表(tables) 把資料或訊息放在資

料表中 資料表是以不同的名稱做分別資料表由欄列所構成的二維陣列

欄包含欄位名資料型態 及其他可判斷的資訊列是由全部欄位構成一筆一

筆的紀錄 create table 語法用在建立一個新的資料表語法格式如下

create table tablename (column1 data type column2 data type column3 data type)

Format of create table if you were to use optional constraints

create table tablename (column1 data type [constraint] column2 data type [constraint] column3 data type [constraint]) [ ] = optional

Note You may have as many columns as youd like and the constraints are optional

80

Example

create table employee (first varchar(15) last varchar(20) age number(3) address varchar(30) city varchar(20) state varchar(20))

注意建立資料表格式要以括號把前後框住而最後以(分號)做結尾

欄位名不要超過 30個字元長而且不要使用 sql 的關鍵字(如 where select等)而在後面接是型態的宣告(如字串數字日期格式等)

資料型態是來描述欄位的方式如一個欄位Last_Name 是一個姓氏可以使用varchar (可變動長度字串) 資料型態

以下是幾個常見的資料庫型態 char(size) 固定長度字串最長為 255 位元 varchar(size) 變動長度字串最大字元數以 size 來指定 number(size) 數值格式可以是整數也可以是小數最大數字以 size 位數判

斷未指定小數位數由系統內定 date 日期格式 number(sized) 數值格式最大數字以 size 位數判斷d 為小數位數整數位

數為 size-d 位

有何限制當資料表被建立通常有一或數個欄位是要使用來做關聯的功

能 例如unique 限制(唯一值)兩筆記錄不可以相同的值 not null (非空值)該欄位一定要輸入資料不可是空的primary key (主鍵)是每一筆記錄識別的主要方式

Drop a table drop table 刪除資料表(其中的資料也會一併刪除)

drop table tablename

Example

81

drop table 和刪除全部資料是不同的刪除全部資料欄位名稱資訊等還會

存在但刪除資料表會把這一些也一併移除掉

如何查詢資料

Select 基本用法

select 語法是關連式資料庫最常用的部份可以取得你想要的資料這是一個

簡單的範例 select column1[column2etc] from tablename [where condition] [] = optional 在 select 之後所列欄位名則是要顯示的資料部份你可以一一列出各欄位

名或是以 (星號)來代表選擇全部的欄位 from 之後放資料表名稱 where 子句 (選項) 指定要過濾的條件符合者才會顯現 where 可使用的條件運算元 = 等於 gt 大於 lt 小於 gt= 大或等於 lt= 小或等於 ltgt 大相等 LIKE 相似 For example select first last city

82

from empinfo where first LIKE Er 以Er 為開頭的字串就符合要以單引號框住 Or you can specify select first last from empinfo where last LIKE s 最後一字為 S 就符合 select from empinfo where first = Eric 則表示 first name 一定要是 Eric 才可以 範例資料表empinfo 統計函數

MIN 傳回指定欄位最小值

MAX 傳回指定欄位最大值

SUM 傳回指定欄位總和

AVG 傳回指定欄位平均值

COUNT 傳回指定欄位的筆數

COUNT() 傳回資料庫中的總筆數

統計函數使用於資料表中的數值欄位配合 SELECT 語法使用 只用於總結特定單一欄位可以配合 GROUP BY 做篩選但也可以不使用 GROUP BY 語句For example

SELECT AVG(salary) FROM employee

83

傳回全部 salary 平均值

Another example

SELECT AVG(salary) FROM employee WHERE title = Programmer

傳回 salary 平均值條件為 employees 資料表中當 title 等於 Programmer

Example

SELECT Count() FROM employees

傳回 employees 資料表中紀錄總筆數

GROUP BY 語法 SELECT column1 SUM(column2) FROM list-of-tables GROUP BY column-list The GROUP BY 語句可以先以所列的欄位為條件分組排序在一起(可以多欄

位) example 要列出每一個 dept 中最高 salary 值 SELECT max(salary) dept FROM employee GROUP BY dept HAVING 語法

SELECT column1 SUM(column2) FROM list-of-tables GROUP BY column-list HAVING condition

HAVING 子句是 GROUP BY 的一部份用來過濾在 GROUP BY 所選出的資料功能如同 select 命令中 where 條件式一樣只是 HAVING 必需配合 GROUP BY 使用

我們以例子來說明我們要取得每一公司名及每一公司的薪水平均值輸入如下

84

SELECT dept avg(salary) FROM employee GROUP BY dept

但如果我們只列出薪資平均值超過 20000元的公司資料

SELECT dept avg(salary) FROM employee GROUP BY dept HAVING avg(salary) gt 20000

ORDER BY子句語法

SELECT column1 SUM(column2) FROM list-of-tables ORDER BY column-list [ASC | DESC]

[ ] =選項

ORDER BY是一個選項子句當你以排序方式來顯示資料(正向由小到大反向由大到小)以指定的欄位資料做排序

ASC = 正向- 預設值 DESC = 反向排序

For example

SELECT employee_id dept name age salary FROM employee_info WHERE dept = Sales ORDER BY salary

以上列出公司代號公司名銷售員人名年紀及薪資而條件是公司名為 Sales 顯示順序以薪資多少排序(由小到大為預設值)

如果要以多個欄位做排序要以逗號做分隔如下

SELECT employee_id dept name age salary FROM employee_info WHERE dept = Sales ORDER BY salary age DESC

85

結合條件及布林運算 SELECT column1 SUM(column2) FROM list-of-tables WHERE condition1 AND condition2 AND運算可以結兩個或以上的條件放在 WHERE子句中 兩者都要為真才

會顯示該筆記錄 OR 運算可以結兩個或以上敘述放在 WHERE子句中只要其中一個為直就

會顯示該筆記錄 For example SELECT employeeid firstname lastname title salary FROM employee_info WHERE salary gt= 5000000 AND title = Programmer 必需要薪資大於等於 50000而且職稱為 Programmer同時符合才會顯示該筆資料 以下以括號括住雖然不是必需的但如此比較容易讀 SELECT employeeid firstname lastname title salary FROM employee_info WHERE (salary gt= 5000000) AND (title = Programmer) 另外範例 SELECT firstname lastname title salary FROM employee_info WHERE (title = Sales) OR (title = Programmer) 條件為只要是 Sales 或 Programmer 職稱的就會被列出 IN and BETWEEN 子句

SELECT column1 SUM(column2) FROM list-of-tables WHERE column3 IN (list-of-values) SELECT column1 SUM(column2) FROM list-of-tables WHERE column3 BETWEEN value1 AND value2 IN 子句使用在列舉項目的使用上也就是分別測試是否符合所列的值 For example

86

SELECT employeeid lastname salary FROM employee_info WHERE lastname IN (Hernandez Jones Roberts Ruiz) 條件為姓氏(astname)要符合 Hernandez Jones Roberts or Ruiz 其中一個才會被傳回 IN運算元也可以使用 OR 的語法來取代如下結果相同 SELECT employeeid lastname salary FROM employee_info WHERE lastname = Hernandez OR lastname = Jones OR lastname = Roberts OR lastname = Ruiz 但使用 IN 句子比較短也比較易懂 你也可以使用 NOT IN 來去掉不要的記錄 BETWEEN 運算元使用在判斷是否存在兩個數值之間 For example SELECT employeeid age lastname salary FROM employee_info WHERE age BETWEEN 30 AND 40 傳回年紀 30歲到 40歲之間的資料(含 30及 40歲者) 相同的也可以使用以下語法來達到相同的結果 SELECT employeeid age lastname salary FROM employee_info WHERE age gt= 30 AND age lt= 40 你也可使用 NOT BETWEEN 來濾掉中間值的資料 數學運算 標準 ANSI SQL-92 提供以下運算

87

+ 加

- 減

餘數

餘數為除法後剩整數這不在標準的 ANSI SQL 中但大部份的資料庫都會支

援這運算元以下列出有用的函數雖不在 ANSI SQL-92 提供但一般資料庫

也會支援他們

ABS(x) 傳回 x 絕對值

SIGN(x) returns the sign of input x as -1 0 or 1 (negative zero or positive respectively)

MOD(xy) 餘數 - returns the integer remainder of x divided by y (同 xy)

FLOOR(x) 傳回小或等於 x 的最大整數值

CEILING(x) or CEIL(x)

傳回大或等於 x 的最小整數值

POWER(xy) x的 y 次方

ROUND(x) 把 x 四捨五入為整數

ROUND(xd) 四捨五入取到小數 d 位

SQRT(x) x 開平方

For example SELECT round(salary) firstname FROM employee_info 傳回薪資取到整數位

如何新增資料

insert 加入一筆新紀錄到資料表中 insert into tablename (first_columnlast_column) values (first_valuelast_value) [] = optional Example insert into employee

88

(first last age address city state) values (Luke Duke 45 2130 Boars Nest Hazard Co Georgia) Note 字串要以單引號住如string 數字框住也無妨 insert into 後面接資料表名稱再接以括號括住的欄位名在 values 後括號分別對映各欄位的值 以上的例子新增了一筆名(first) 為 Luke而住所(state) 為 Georgia 的資料

如何刪除資料

delete 可以刪除單筆或多筆紀錄 delete from tablename where columnname OPERATOR value [and|or column OPERATOR value] [ ] = optional Examples delete from employee Note 如果你沒有指定 where 子句那麼全部的紀錄都會被刪除 delete from employee where lastname = May delete from employee where firstname = Mike or firstname = Eric delete from 接著資料表名 再接著是條件式判斷沒有條件式則全部紀錄會

被刪除

如何更新資料

update 用來更新你所指定的記錄要和 WHERE 配合小心使用 語法 update tablename set columnname = newvalue[nextcolumn = newvalue2] where columnname OPERATOR value [and|or column OPERATOR value] [] = optional Examples

89

update phone_book set area_code = 623 where prefix = 979 update phone_book set last_name = Smith prefix=555 suffix=9292 where last_name = Jones update employee set age = age+1 where first_name=Mary and last_name=Williams

90

附錄二Replication

測試環境

RedHat 90 + MySQL 32358 MySQL資料庫路徑 varlibmysql MySQL設定檔 etcmycnf Master IP 1921680100 Slave IP 1921680200 請至下列網址下載最新MySQL 32358套件並利用rpm ndashUvh 更新 httpupdatesredhatcom9enosi386

圖 最新 MySQL 套件

測試架構圖

91

1921680100

1921680200Master Server

erveSlave S r

圖 測試架構圖

測試步驟

Master server 部份 Step1 確認 MasterSlave機器上所裝的 MySQL版本能進行

replication( 32329 or higher ) Step2 在 Master MySQL上開放一個帳號給 Slave mysql ndashu root ndashp mysqlgtGRANT FILE ON TO repl1921680200 IDENTIFIED BY lsquoabc123rsquo mysqlgtq 上面是 Master開放一個帳號 repl密碼 abc123給 IP1921680200有檔案處理

的權限 Step3 shutdown MySQL on the Master mysqladmin ndashu root ndashp shutdown Step4 備份 Master所有資料庫 tar ndashcvf tmpmysql-snapshottar varlibmysql 注意tar的時候MySQL是要在 stop情況下 在mysql (wwwmysqlcom) 網站的FAQ有不用shutdown的方法

92

Step5 在 master機器上修改etcmycnf 在[mysqld]區段內加入參數 log-bin server-id=這邊設定 server-id=1 sql-bin-update-same binlog-do-db=CRM只針對 CRM資料庫做紀錄 Step6 Restart MySQL on the master service mysqld start 此時因為有加入 log-bin 參數因此開始有 index產生了在varlibmysql目錄下

有index檔案紀錄資料庫的異動 log Slave server 部份 Step1 在 slave設定etcmycnf 在[mysqld]區段加入 master-host= master-user= master-password= master-port= server-id= 這邊設定 master-host=1921680100 master-user=repl master-password=abc123 master-port=3306 server-id=2 master-connect-retry=60預設重試間隔 60秒 replicate-do-db=CRM告訴 slave只做 CRM資料庫的更新 log-slave-updates Step2 將 master上的 mysql-snapshottar copy到 slave上 用 ftp傳到 slave的tmp Step3 解壓縮 Master資料庫至 Slave Server上 cd varlib tar xvf tmpmysql-snapshottar chown ndashR mysqlmysql mysql

93

chmod ndashR 770 mysql (視情況) Step4 Restart MySQL on the slave server 這時在varlibmysql目錄會出現 masterinfo此檔案紀錄了 Master MySQL server的資訊

狀況測試

One-way replication

1921680100

1921680200Master Server

erveSlave S r

圖 One-way replication架構圖 Step1 Master跟 Slave網路及服務都正常情況下由 Master端異動資料後 到 Slave端瀏覽資料檢視是否有進行 replication Step2 模擬 Slave Server 當機 可用在於 slave真的當機或是 Slave 不一定需要一直跟 master connect將Slave MySQL server shutdown由 Master端異動資料到 slave端瀏覽此時Slave應該沒有被 replication 更新然後再將 Slave端 MySQL server start起來

預設 60秒後 Slave會嘗試跟 Master要求進行 replication再去 Slave端檢視是否有更新資料

94

Step3 模擬 Master當機因為是設定 One-way replication一旦 Master Server Slave端沒有 Master的 source可以 download Two-way replication 基於 Master當機狀況於是發展雙向 Replication即 1921680100 ( Host A ) 1921680200 ( Host B )都分別擔任 MasterSlave身分

1921680100

1921680200er

Server B MasterSlave Server

Server A MasterSlave Serv

圖 Two-way replication架構圖 以下是針對兩台 MySQL伺服器進行雙向 Replication Step1觀念同單向 replication只是改成 Master也有 Slave身分 Slave也有Master的身分先分別在 Server AServer B 都去 grant一個進行 replication的身分 [A]mysqlgtGRANT FILE ON TO repl1921680200 IDENTIFIED BY lsquoabc123rsquo [B]mysqlgt GRANT FILE ON TO repl1921680100 IDENTIFIED BY lsquoabc123rsquo Step2做完單向 replication後stop Server Aserver B MySQL service此時 AB資料是一樣的

95

修改etcmycnf設定 範例 Server A [mysqld] datadir=varlibmysql socket=varlibmysqlmysqlsock server-id=1 log-bin sql-bin-update-same binlog-do-db=CRM master-host=1921680200 master-user=repl master-password=abc123 log-slave-updates master-connect-retry=60 replicate-do-db=CRM Server B [mysqld] datadir=varlibmysql socket=varlibmysqlmysqlsock server-id=2 log-bin sql-bin-update-same binlog-do-db=CRM master-host=1921680100 master-user=repl master-password=abc123 log-slave-updates master-connect-retry=60 replicate-do-db=CRM 分別 start Server AServer B MySQL後此時雙方都是 MasterSlave身分一旦哪一方資料異動就會通知對方來 replication-若 replication失效則必須將Server AServer B的masterinfo及index00x 都砍掉然後分別 restart MySQL server進行測試檢視成果 實務上通常如果需要做Two-way replication通常會搭配Virtual Server使用

96

在前端架設一台Virtual Server不過此部份不在此份SOP討論範圍內有興趣

的讀者可參考 httpwwwlinuxvirtualserverorg 網站

1921680100 1921680200

Host A MasterSlave Server

Host B MasterSlave Server

Virtual Host

圖 Virtual Server + Two-way replication 架構圖

97

圖 High Availability Linux Virtual Server架構圖

98

  • COSA-SOP-03-006
  • 第一章 簡介
    • 11適用對象 (Audience)
    • 12 MySQL本身
    • 13 MySQL 40版跟50版重大的改進功能
    • 14 各家資料庫軟體比較
      • 第二章 前置需求
      • 第三章 安裝
        • 31 MySQL安裝
        • 32 phpMyAdmin安裝
        • 33 升級及注意事項
          • 第四章 MySQL管理
            • 41 Webmin 管理介面
            • 42 phpMyAdmin 的操作介面
            • 43管理指令介紹
              • 431 利用mysqladmin設定root的密碼
                  • 第五章 實用範例
                    • 51 任務一Web Base客戶通訊錄
                    • 52 任務二Web Base群組軟體 ( twig )
                      • 第六章 維護及更新程序
                        • 61 日常維護
                        • 62 更新程序
                        • 63 備份重要檔案
                        • 64 離線備份與還原
                        • 65 線上備份與還原
                          • 第七章 問題與解答
                          • 第八章 參考資料
                          • 附錄一 SQL Command 介紹
                          • 附錄二Replication
Page 21: DataBase Server Standard Operation Procedureebooks.lib.ntu.edu.tw/1_file/oss/63/93doc4-5.pdf · 業務的公司帶來了不少壓力,譬如微軟,甲骨文 ... 外的錢用在第三方的資料庫產品上,譬如就可以不用再購買甲骨文公司

hellip

69 $cfg[Servers][$i][host] = localhost MySQL hostname or IP address hellip 80 $cfg[Servers][$i][user] = root MySQL user

81 $cfg[Servers][$i][password] = 1234 MySQL password (only needed

圖 3-16 修改 configincphp

21

圖 3-17 修改 configincphp

圖 3-18 修改 configincphp p

Step 7 設定語系

22

圖 3-19 設定語系

圖 3-20 執行 phpMyAdmin

23

33 升級及注意事項

RedHat 90附的 MySQL版本為 323 MySQL所釋出最新穩定版本為

40若是您不想用系統預附的 323請先利用下列移除之前 323的版本

rpm ndashe mysql-devel rpm ndashe mysql-server rpm ndashe mysql --nodeps 然後到下列網址下載您所想要的版本進行安裝在這裏我們用 4014版為例 Step 1 下載相關套件( httpwwwmysqlcomdownloadsmysql-40html )

圖 3-21 Download MySQL 4014 相關 RPM Step 2 利用 rpm 指令安裝

24

圖 3-22 Install MySQL 4014 相關 RPM

圖 3-23 Install MySQL 4014 相關 RPM

Step 3 啟動 MySQL

25

圖 3-24 啟動 MySQL 4014 並修改密碼

26

第四章 MySQL管理

本章將我們介紹利用WebminphpAdminCommand的方式建立一個名為

CONTACT的資料庫內有一個 address的 Table作為我們客戶通訊錄程式使

用的資料庫

41 Webmin 管理介面

412建立資料庫

Step 1 登入Webmin

圖 4-1 登入WebMin

Step 2 點選伺服器

27

圖 4-2 伺服器畫面

Step 3 點選 MySQL資料庫伺服器

圖 4-3 MySQL資料庫伺服器

28

Step 4 建立一個新的資料庫

圖 4-4 建立 MySQL資料庫

Step 5 建立名為 CONTACT的資料庫

29

圖 4-5 指定資料庫名稱

412 建立資料表

假設我們要建立一個名為 address的 Table其結構如下 欄位名稱 資料型態 長度 說明 id INT (自動編號) 連絡人編號 name varchar文字 20 連絡人姓名 tel Varchar文字 15 連絡人電話 Step 1 選擇 CONTACT資料庫

30

圖 4-6 選擇資料庫

Step 2 指定欄位數目

31

圖 4-7 設定欄位數目

Step 3設定表格欄位屬性

圖 3-8 設定表格欄位屬性

Step 4建立表格資料

32

圖 4-9 建立表格資料

圖 4-10 檢視資料

33

圖 4-11 新增資料

圖 4-12

34

圖 4-13

413 使用者管理

接下來我們要利用Webmin 來建立資料庫使用者並給予某些權限 Step1建立使用者

35

圖 4-14 選擇使用者權限

圖 4-15

36

Step2 賦予權限

圖 4-16

Step3 權限列表

37

圖 4-17

38

42 phpMyAdmin 的操作介面

421建立資料庫

Step 填入資料庫名稱並按「建立」

圖 4-18建立資料庫

422 建立資料表

Step1 填入資料表名稱並指定欄位數量 執行

39

圖 4-19填入資料表名稱並指定欄位數量

Step2 設定欄位屬性

圖 4-20設定欄位屬性

40

Step3 phpMyAdmin會產生相關的 SQL Command

圖 4-21 資料表結構及相關 SQL Command

Step4新增 Record

41

圖 4-22

圖 4-23

42

圖 4-24

圖 4-25

43

423使用者管理

Step1建立使用者

圖 4-26

44

圖 4-27

Step2 給予權限

圖 4-28

Step3權限列表

45

圖 4-29

43管理指令介紹

431 利用 mysqladmin設定 root的密碼

當您在Windows 或 Linux 中安裝好 MySQL後系統會自動幫您建立兩個

帳分別是 root 和 匿名者MySQL的 root 跟 Linux 最高權限使用者 root無關MySQL的 root使用者相當於 MS SQL 中的 sa 帳號擁有最高的 Database管理權限但系統預設 MySQL的 root 是不需要密碼所以通常我們一安裝

MySQL後首要任務便是修改 root的密碼 我們可以利用 mysqladmin工具或是直接修改 MySQL內部資料庫的使用者資

料 mysqladmin ndashu root ndashh cosaexamplecom password lsquo1234rsquo

46

-u 表示使用者帳號root 為 MySQL預設的管理帳號

-h 表示 MySQL主機的主機名稱也可使用 IP Address password 表示使用者的密碼因為字串請使用單引號將密碼括起來 密碼設定完成之後還是可以利用 mysqladmin修改密碼但是你必須提供目前的密碼

432 連線 MySQL

mysql -uroot -p密碼 (-p和密碼之間不能有空白) 或 mysql -uroot -p (此方式會在進入後要求密碼) [rootossc phpMyAdmin] mysql -u root -p1234

Welcome to the MySQL monitor Commands end with or g

Your MySQL connection id is 25 to server version 32354

Type help or h for help Type c to clear the buffer

mysqlgt show databases

+----------+

| Database |

+----------+

| mysql |

| test |

+----------+

2 rows in set (000 sec)

mysqlgt exit

Bye

[rootossc phpMyAdmin]

433 建立資料庫

可利用 mysqladmin指令建立 CONTACT資料庫 mysqladmin -u root -p1234 create CONTACT

47

或是利用 mysql指令 [rootossc bluepage] mysql -u root -p1234 Welcome to the MySQL monitor Commands end with or g Your MySQL connection id is 1057 to server version 32354 Type help or h for help Type c to clear the buffer mysqlgt create database CONTACT Query OK 1 row affected (000 sec) mysqlgt show databases +----------+ | Database | +----------+ | CONTACT | | address | | hello | | mysql | | nuke | | test | +----------+ 6 rows in set (000 sec) mysqlgt exit

434 建立資料表

編寫 adresssql內容如下 -- Table structure for table address CREATE TABLE address ( id int(11) NOT NULL auto_increment name varchar(20) NOT NULL default tel varchar(15) NOT NULL default PRIMARY KEY (id) ) TYPE=MyISAM

48

-- Dumping data for table address INSERT INTO address VALUES (1林小明0800016888) INSERT INTO address VALUES (2黃大雄0800016888) INSERT INTO address VALUES (3劉小芬0800024365) 然後執行此 sql script mysql -u root -p1234 CONTACT lt addresssql 或是利 mysql command [rootossc bluepage] mysql -u root -p1234 Welcome to the MySQL monitor Commands end with or g Your MySQL connection id is 1090 to server version 32354 Type help or h for help Type c to clear the buffer mysqlgt use CONTACT Database changed Database changed mysqlgt CREATE TABLE address ( -gt id int(11) NOT NULL auto_increment -gt name varchar(20) NOT NULL default -gt tel varchar(15) NOT NULL default -gt PRIMARY KEY (id) -gt ) TYPE=MyISAM Query OK 0 rows affected (000 sec) mysqlgt INSERT INTO address VALUES (1林小明0800016888) Query OK 1 row affected (000 sec) mysqlgt INSERT INTO address VALUES (2黃大雄0800016888) Query OK 1 row affected (000 sec) mysqlgt INSERT INTO address VALUES (3劉小芬0800024365) Query OK 1 row affected (000 sec) mysqlgt exit Bye

49

第五章 實用範例

51 任務一Web Base客戶通訊錄

任職於開放科技公司的林小明前些日子在最符合成本效益的條件下快

速地完成公司網站的建置老闆因此對小明讚譽有加最近因為公司存放客戶資

料的 SQL Server主機屢遭病毒攻擊加上作業系統本身的問題當機次數頻繁

老闆希望能儘快把公司的客戶通訊錄程式移轉到較穩定的環境上因為此客戶通

訊錄程式最主要給內部人員使用所以介面美觀並不特別要求只求穩定且能快

速得到查詢結果老闆希望在短時間先看到程式的雛型並鍵入資料對其效率

及穩定性進行測試因為上次小明表現突出所以這次不可能的任務自然又落到

小明身上 小明想來想去既然要快速又穩定他而且又不希望所有人都得安裝 Client

程式於是小明決定)捨棄他的舊愛「Delphi+MS SQL」投向新歡「Apache + MySQL + PHP」利用此架構來設計一個簡單實用的Web Base客戶通訊錄程式

511 Web Base客戶通訊錄架構

此程式需要建立 CONTACT的資料庫並建立 adress Tables其結構如下表建立步驟請參考第三章 欄位名稱 資料型態 長度 說明 id INT (自動編號) 連絡人編號 name varchar文字 20 連絡人姓名 tel Varchar文字 15 連絡人電話 Web Base通訊錄共有下列幾個檔案功能如下表

檔案名稱 說明 Indexhtml Web Base通訊錄首頁 addphp 新增連絡人的 php程式 searchphp 尋找連絡人的 php程式 editphp 具有更新及刪除功能的 php程式

50

我們將這些檔案放至varwwwhtmlbluepage (預設無 bluepage目錄)

512 Web Base通訊錄測試

httpwwwopencombluepage 新增資料

圖 5-1 新增連絡人

圖 5-2 填入資料

51

圖 5-3 新增成功

搜尋及異動資料

圖 5-4 搜尋通訊錄

52

圖 5-5 編輯資料

圖 5-6 更新資料

513 程式內容及說明

lt-- 程式範例indexhtml--gt lthtmlgt ltheadgtlttitlegt通訊錄lttitlegtltheadgt ltbodygt ltcentergt

53

lth2gt通訊錄lth2gtlthrgt lta href=indexhtmlgt通訊錄ltagt | lta href=addphpgt新增連絡人ltagt | lta href=searchphpgt搜尋通訊錄ltagt ltcentergt ltbodygt lthtmlgt lt-- 程式範例addphp --gt lthtmlgt ltheadgtlttitlegt新增連絡人lttitlegtltheadgt ltbodygt ltcentergtlth2gt新增連絡人lth2gtltcentergtlthrgt lt 取得欄位資料 if (isset($_POST[Name]) ampamp isset($_POST[Tel]) ) $name = $_POST[Name] $tel = $_POST[Tel] 檢查是否有輸入欄位資料 if ($name = ampamp $tel = ) 建立 SQL字串 $sql = INSERT INTO address (name tel) values( $sql= $name $tel) 建立 MySQL 連結 $link = mysql_connect(localhostroot1234) 選擇資料庫 mysql_select_db(CONTACT) 執行 SQL指令 mysql_query($sql) mysql_close($link) echo ltfont color=redgt新增連絡人成功ltfontgtltbrgt gt ltform action=addphp method=postgt lttable border=0 width=300gt lttrgtlttdgt姓名 lttdgt

54

lttdgtltinput type=text name=Name size=20 maxlength=10gtlttdgtlttrgt lttrgtlttdgt電話 lttdgt lttdgtltinput type=text name=Tel size=20 maxlength=20gtlttdgtlttrgt lttrgtlttd colspan=2 align=centergt ltinput type=submit value=新增連絡人gtlttdgtlttrgt lttablegt ltformgt ltbrgtlta href=indexhtmlgt通訊錄ltagt | lta href=addphpgt新增連絡人ltagt | lta href=searchphpgt搜尋通訊錄ltagt ltbodygt lthtmlgt

lt-- 程式範例searchphp --gt lthtmlgt ltheadgtlttitlegt搜尋通訊錄lttitlegtltheadgt ltbodygt ltcentergtlth2gt搜尋通訊錄lth2gtlthrgt lt if (isset($_POST[Search])) 建立資料庫連結並選定資料庫 $link = mysql_connect(localhostroot1234) mysql_select_db(CONTACT) 建立基本的 SQL字串 $sql = SELECT FROM address 檢查是否輸入姓名 if (chop($_POST[Name]) = ) $name = name LIKE $_POST[Name] else $name = 檢查是否輸入電話號碼 if (chop($_POST[Tel]) = ) $tel = tel LIKE $_POST[Tel] else $tel =

55

if條件組合 SQL字串 if (chop($name) = ampamp chop($tel) = ) $sql= WHERE $name AND $tel elseif (chop($name) = ) 只有姓名 $sql = WHERE $name elseif (chop($tel) = ) 只有電話號碼 $sql = WHERE $tel $sql= ORDER BY name 最後加上排序 $result = mysql_query($sql) 取得欄位數 $total_fields = mysql_num_fields($result) echo lttable border=1gt echo lttrgtlttdgt編號lttdgtlttdgt姓名lttdgtlttdgt電話lttdgtlttd colspan=2gt功能選項lttdgtlttrgt 表格顯示查詢結果 while ($rows = mysql_fetch_array($result MYSQL_NUM)) echo lttrgt for ($i = 0 $i lt $total_fields $i++) echo lttdgt$rows[$i]lttdgt echo lttdgtlta href=editphpaction=editampid= echo $rows[0]gtltbgt編輯ltbgtlttdgt echo lttdgtlta href=editphpaction=delampid= echo $rows[0]gtltbgt刪除ltbgtlttdgt echo lttrgt echo lttablegtlthrgt mysql_free_result($result) mysql_close($link) gt ltcentergt ltform action=searchphp method=postgt lttable border=0 width=450gt lttrgtlttdgt搜尋姓名 lttdgt lttdgtltinput type=text name=Name size=10 maxlength=20gtlttdgtlttrgt lttrgtlttdgt搜尋電話 lttdgt lttdgtltinput type=text name=Tel

56

size=20 maxlength=20gtlttdgtlttrgt lttrgtlttd colspan=2 align=centergt ltinput type=submit name=Search value=搜尋gtlttdgtlttrgt lttablegt ltformgt ltbrgtlta href=indexhtmlgt通訊錄ltagt | lta href=addphpgt新增連絡人ltagt | lta href=searchphpgt搜尋通訊錄ltagt ltbodygt lthtmlgt

lt ob_start() gt lt-- 程式範例editphp --gt lthtmlgt ltheadgtlttitlegt編輯通訊錄lttitlegtltheadgt ltbodygt lt 取得 URL 參數 $id = $_GET[id] $action = $_GET[action] 建立資料庫連結 $link = mysql_connect(localhostroot1234) mysql_select_db(CONTACT) 選擇資料庫 執行的操作 switch ($action) case update 更新 取得欄位資料 $name = $_POST[Name] $tel = $_POST[Tel] $sql = UPDATE address SET name=$name tel=$tel WHERE id=$id mysql_query($sql) 執行 SQL指令 mysql_close($link) header(Location searchphp) 轉向到 serachphp break case del 刪除 $sql = DELETE FROM address WHERE id=$id

57

mysql_query($sql) 執行 SQL指令 mysql_close($link) header(Location searchphp) 轉向到 serachphp break case edit 編輯 $sql = SELECT FROM address WHERE id=$id $result = mysql_query($sql) 執行 SQL指令 $row = mysql_fetch_row($result) 取回記錄 $name = $row[1] 取得欄位 name $tel = $row[2] 取得欄位 tel mysql_close($link) 顯示編輯表單 gt ltcentergtlth2gt更新通訊錄lth2gtltcentergtlthrgt ltform action=editphpaction=updateampid=lt echo $id gt method=postgt lttable border=0 width=300gt lttrgtlttdgt姓名 lttdgt lttdgtltinput type=text name=Name size=20 maxlength=10 value=lt echo $name gtgtlttdgtlttrgt lttrgtlttdgt電話 lttdgt lttdgtltinput type=text name=Tel size=20 maxlength=20 value=lt echo $tel gtgtlttdgtlttrgt lttrgtlttd colspan=2 align=centergt ltinput type=submit value=更新連絡人gtlttdgtlttrgt lttablegt ltformgt ltbrgtlta href=indexhtmlgt通訊錄ltagt | lta href=addphpgt新增連絡人ltagt | lta href=searchphpgt搜尋通訊錄ltagt lt break gt ltbodygt lthtmlgt

58

52 任務二Web Base群組軟體 ( twig )

順利完成Web Base客戶通訊錄程式測試一段時間後「Apache + MySQL + PHP」架構的穩定與快速巳深得老闆與公司所有同事的認同隨著公司業績蒸

蒸日上人員組織編罝愈來愈龐大跨部門的會議愈來愈多業務員每日排滿拜

訪客戶的行程跟客戶的 Email的往來也愈來愈頻繁 愈來愈多部門的同事希望公司能建置一套群組軟體提供 web mail可讓業

務人員方便收發 mail還有連絡人議事日程待辦工作書簽等功能讓整個

公司運作及個人時間管理更有效率

老闆問小明對這些需求有什麼看法小明認為如果這些功能完全由程式部

門開發必定曠日費時而且耗費公司資源小明在網路尋找是否有提供這些功能

的Free Software皇天不負苦心人小明發現了TWIG (The Web Information Gateway) httptwigscrewdrivernet這個群組軟體它在 Web 上整合郵件新聞聯絡人議事日程工作序書簽等功能非常符合公司的需求 Step 1 下載 twig-277targz 下載網址 httptwigscrewdrivernetdownloadphp3

Step 2 解開 twig-277targz tar -xzvf twig-277targz

59

Step 3 執行安裝動作安裝到 varwwwhtmltwig 目錄 cd twig-277 twig-install varwwwhtmltwig

Step 4 建立 MySQL 資料庫(twig)及各資料表

cd setup mysql -u root -p1234 mysqlgt create database twig Query OK 1 row affected (001 sec) mysqlgt quit mysql -u root ndashp1234 twiglt twigtablemysql

Step 5 修改 configincphp3 參數設定 vi varwwwhtmltwigconfigconfigincphp3 $config[fromdomain] = opencom 網域 $config[language] = chinesebig5 中文訊息 $config[imap_port] = 143notls

60

Step 6 修改連結 MySQL 的帳號密碼 vi varwwwhtmltwigconfigdbconfigincphp3 $dbconfig[sqlusername] = root username $dbconfig[sqlpassword] = 1234 password

Step 7 其他設定檔

vi etchttpdconfhttpdconf 加入 AddType applicationx-httpd-php php3 在 DirectoryIndex最後加入 indexphp3 DirectoryIndex indexhtml indexhtmlvar indexphp3 在 AddDefaultCharset ISO-8859-1加上 AddDefaultCharset ISO-8859-1

vi etcphpini register_globals = On service httpd restart Step 8 sendmail 設定 vi etcmailsendmailcf在 264 行前面加上並重新啟動 sendmail「service snedmail restart」 262 SMTP daemon options 263 264 O DaemonPortOptions=Port=smtpAddr=127001 Name=MTA 265 266 SMTP client options 267 O ClientPortOptions=Family=inet Address=00

61

Step 9 檢查設定有無錯誤 http主機名稱twigtestphp3

62

Step 10 登入 twig ( http主機名稱twig)

63

第六章 維護及更新程序

61 日常維護

系統管理員最好定期以 root 身份登入看看信件在 RedHat Linux 中有一支 logwatch 程式會定時去分析 log file如果發現異常便會發信給 root除此之外筆者建議讀者平時就檢查 MySQL log file ( varlogmysqldlog)是否有異常情形

62 更新程序

讀者可至httprpmfindnet 尋找MySQL相關套件至於升級的相關步驟請參

考Linux OS SOP 第 54節

63 備份重要檔案

預設 MySQL 的 DB 檔案是存在 varlibmysql 內以 DB名稱為目錄目錄

內就是該 DB 的所有資料通常得定期備份還有 MySQL的設定檔 etcmycnf也別忘了一起備份

64 離線備份與還原

641 離線備份

預設 MySQL 的 DB 檔案是存在 varlibmysql 內以 DB 名稱為目錄目錄內

就是該 DB 的所有資料像 CRM 這個 DB就是存在 varlibmysqlCRM 內在備份前因為怕資料尚未完全寫入磁碟而且 MySQL 會 Lock 在使用的 DB 檔案所以應該是要先把 MySQL 先 Shutdown 一下整個備份的程序可以下像下面的指令去完成 cd varlibmysql

64

service mysqld stop tar cvfz CRM_db_20030905tgz CRM service mysqld start 對這樣就可以了 不過要注意的是怕 DB 內每個 Tables 間的資料有關關

聯性所以最好是把整個 DB 一次備起來單獨只備哪個 Tables 的檔案以後回存時怕會有資料關聯不一致的問題

642 離線還原

DB 發生錯誤而要回存時其實也不難先找出最近一次完整正常的備份先把現在錯誤的網頁或 DB 先更名或 tar 起來再把好的備份給解開回原來目錄位

置就行了需要注意的是 MySQL 服務最好也是要先停止回存完成後再啟動服務回存 DB 的整個程序可能像下面 cd varlibmysql service mysqldstop mv CRM CRM_OLD tar xvfz CRM_db_20030905tg service mysqld start

65 線上備份與還原

651 線上備份

使用像上面的檔案方式備份是個不錯的方法它最少可以保持該主機某個時間點的完整檔案備份但還是有一些問題需要考慮到有些主機就不只建立一個 DB 而已總不能為了備份某個 DB 而把整個 MySQL 服務停止備份檔案的方式回存在原主機上一定適用但假如 MySQL 版本升級或是在那天該網頁空間需遷機移機到別的主機時那就沒人敢保證備出來的資料檔可以用所以我們可以考慮另一種備份的方式是使用 MySQL 本身提供的功能 MySQL Data Dump指令是 mysqldump

65

使用 MySQL 的 Dump 功能可以把 DB 的結構資料或結構加資料 Dump 成文字檔 mysqldump 指令提供的彈性很大你可以選擇把整個 DB Dump 成一個檔或是每個 Table 為一個檔甚至是把結構檔和資料分開儲存都

可以 mysqladmin -uroot -p flush-logs mysqldump CRM -uroot -p --opt gt CRM_20030905sql (CRM 是 DB 名稱 opt 是一個使用完整 Dump 參數) 假如只是要單獨 Dump 某個 Table 時只要在上面的指令後轉出符號 gt 前加個 Table 名稱就可以如只要 phpbb2_users 這個 Table 的 Dump 時只要下 mysqldump CRM -uroot -p --opt CUSTOMER gt CRM_CUSTOMER_20030905sql

652 線上還原

若要回存整個資料庫只需將壓縮的備份檔還原成 Dump 的檔案再用下面的指令回存 mysql CRM -uroot -p lt CRM_20030905sql 這邊需注意的是若建立備份時是以--opt或--add-drop-table為參數時回存的 動作是先將舊的 Table 先刪除重建 Table 的結構後再把 Data 匯入所以回存後所有的資料會回到你當時備份那個時間點因此在回存資料時可以考慮把現有錯誤或不完整的 DB 先備份一份下來以備不時之需或是拿來比對錯誤的地

方在那裡當然你也可以把資料回存到另一個測試用的 DB 內只要把上面指令

的 DB 名稱改成你的測試用 DB 名稱即可 使用這種回存方式 MySQL 服務不需停止也不會動到其他正在使用的 DB 在一些提供 MySQL 服務的虛擬主機可用這種方式作你自己的 DB 備份及回存

66

另外假如你是系統重建或是移機時切需在新的 MySQL 內新建一個空白 DB 後才行作回存的工作你可以用下面的指令建立 mysql -uroot -p -e CREATE DATABASE CRM (上面的 CRM是你要新建的 DB 名稱) 另一種作法先用 mysql 指令進入 mysql client console 然後再用 CREATE DATABASE CRM 這樣就行了記得尾端要加個 符號該行指令才會執行

67

第七章 問題與解答

Q1RedHat 90預附的 MySQL到底有無支援 Transcation機制 Ans MySQL自 32334a之後的 MySQL-Max版本加入 InnoDB的資料庫類型透過

InnoDBMySQL同樣可以進行 COMMIT與 ROLLRACK的動作RedHat 90預附的 MySQL為 32354a-11巳支援 InnoDB的資料庫類型不過必須做以

下設定 1cp usrsharedocmysql-server-32354amy-mediumcnf to etcmycnf 2 vi etcmycnf 將以下設定前的拿掉 innodb_data_home_dir = varlibmysql innodb_data_file_path = ibdata110Mautoextend innodb_log_group_home_dir = varlibmysql innodb_log_arch_dir = varlibmysql 3service mysqld restart 如此一來各位在建立Table時便可指定Table Type為 innodb ( ex create table with type=innodb ) Q2如何解決 php+mysql 許功蓋等字變亂的問題 Ans 方法一 【確定 MySQL 預設的字元集】 1 打開 WinMySQLadmin 管理畫面(在視窗右下角狀態列紅綠燈圖示中按滑鼠

右鍵點選 Show me 選項) 2 點選管理畫面中 [Variables] 標籤選項其中 character_set變數就是您預設

字元集的變數其預設是 latin1 字元集(我們要將他改回 big5)而 chatacters_set 變數則是 MySQL 可以支援哪些字元集 【修改預設字元集變數 character_set 】 1 請點選管理畫面中 [myini Setup] 標籤選項設定 myini 2 按一下 [Pick-up and Edit myini values] 按鈕以便編輯目前的 myini 設定 3 在 [mysqld] 設定區塊底下新增一行 default-character-set = big5 變數設

68

定 4 新增一個 [client] 設定區塊並加入第三步驟的變數設定(游標往下移到空白處新增兩行 [client] 和 default-character-set=big5) 5 按一下畫面左下方 [Save Modification] 按鈕儲存設定 6 重新啟動 MySQL 或 Windows 方法二 Server端注意事項 phpini 中有關的設定為(預設值) Magic quotes for incoming GETPOSTCookie data magic_quotes_gpc = On Use Sybase-style magic quotes (escape with instead of ) magic_quotes_sybase = Off Client端注意事項 1中文資料送進 mysql 前請用 addslashes($str) 處理 2處理後送進 mysql 時請用 括起來並在參數後留一個空白如 $sql = UPDATE ezf_table set tablename=$tname tableend=$endtime table inguser=$tguser tableingid=$tguserid tableallnumber=$tnumber tableloca l=$tablelocal tableanyone=$tableopen tabletext=$ttext WHERE tableid=$t ableid tablename=$tname c 取出時請用 stripslashes($str) Q3MySQL root 密碼忘了該怎麼辦 Ans 1先停掉 mysql etcrcdinitdmysql stop 2以--skip-grant-table 的參數啟動 mysql safe_mysql --skip-grant-tableamp 3 更改 root 密碼 mysql mysql mysqlgt UPDATE user SET password=password(newpassword)

69

WHERE user=root mysqlgt FLUSH PRIVILEGES mysqlgt exit 4停掉 mysql再重跑 mysqladmin -uroot -p shutdown Enter password 輸入新設定的密碼 etcrcdinitdmysql start

Q4NULL值問題

Ans

NULL值的概念是造成 SQL的新手的混淆的普遍原因他們經常認為 NULL是和一個空字符串的一樣的東西不是這樣的例如下列語句是完全不同的

mysqlgt INSERT INTO my_table (phone) VALUES (NULL)

mysqlgt INSERT INTO my_table (phone) VALUES ()

兩個語句把值插入到 phone 列但是第一個插入一個 NULL值而第二個插入一個空字符串第一個的含義可以認為是ldquo電話號碼不知道而第二個則可意味

著ldquo她沒有電話

在 SQL中NULL值在于任何其他值甚至 NULL值比較時總是假的(FALSE)包含 NULL的一個表達式總是產生一個 NULL值除非在包含在表達式中的運算符和函數的文檔中指出在下列例子所有的列返回 NULL

mysqlgt SELECT NULL1+NULLCONCAT(InvisibleNULL)

如果你想要尋找值是 NULL的列你不能使用=NULL測試下列語句不返回任

何行因為對任何表達式expr = NULL是假的

mysqlgt SELECT FROM my_table WHERE phone = NULL

要想尋找 NULL值你必須使用 IS NULL測試下例顯示如何找出 NULL電話號碼和空的電話號碼

70

mysqlgt SELECT FROM my_table WHERE phone IS NULL mysqlgt SELECT FROM my_table WHERE phone =

在 MySQL中就像很多其他的 SQL服務器一樣你不能索引可以有 NULL值的列你必須聲明這樣的列為 NOT NULL而且你不能插入 NULL到索引的

列中

當用 LOAD DATA INFILE 讀取數據時空列用更新如果你想要在一個列中有

NULL值你應該在文本文件中使用N字面上的詞NULL也可以在某些情形下使用

當使用 ORDER BY時首先呈現 NULL值如果你用 DESC以降序排序NULL值最後顯示當使用 GROUP BY時所有的 NULL值被認為是相等的

為了有助于NULL的處理你能使用 IS NULL和 IS NOT NULL運算符和 IFNULL()函數

對某些列類型NULL值被特殊地處理如果你將 NULL插入表的第一個TIMESTAMP 列則插入當前的日期和時間如果你將 NULL插入一個AUTO_INCREMENT 列則插入順序中的下一個數字

Q5如何將圖片存放於 MySQL中

Ans

Step 1建立資料庫 test

Step 2 建立表格 binary_data

CREATE TABLE binary_data (

id INT(4) NOT NULL AUTO_INCREMENT PRIMARY KEY

description CHAR(50)

bin_data LONGBLOB

filename CHAR(50)

filesize CHAR(50)

filetype CHAR(50)

71

)

Step 3 利用 storephp 寫入圖片

storephp 程式碼

ltHTMLgt ltHEADgtltTITLEgtStore binary data into SQL DatabaseltTITLEgtltHEADgt ltBODYgt lt code that will be executed if the form has been submitted

if ($submit) mysql_connect(localhostrootYOUR_PASSWORD) mysql_select_db(test) $data=Base64_Encode(fread(fopen($form_data r) filesize($form_data))) $result=MYSQL_QUERY(INSERT INTO binary_data (descriptionbin_datafilenamefilesizefiletype) VALUES ($form_description$data$form_data_name$form_data_size$form_data_type)) $id= mysql_insert_id() print ltpgtThis file has the following Database ID ltbgt$idltbgt MYSQL_CLOSE() else else show the form to submit new data

gt

ltform method=post action=ltphp echo $PHP_SELF gt enctype=multipartform-datagt File Descriptionltbrgt ltinput type=text name=form_description size=40gt ltINPUT TYPE=hidden name=MAX_FILE_SIZE value=4000000gt ltbrgtFile to uploadstore in databaseltbrgt ltinput type=file name=form_data size=40gt ltpgtltinput type=submit name=submit value=submitgt ltformgt lt

72

gt ltBODYgt ltHTMLgt

Step 3 利用 storephp 取出圖片

getdataphp 程式碼

lt Syntax getdataphp3id=ltidgt if($id) you may have to modify login information for your database server MYSQL_CONNECT(localhostrootYOUR_PASSWORD) mysql_select_db(test) $query = select bin_datafiletype from binary_data where id=$id $result = MYSQL_QUERY($query) $data = Base64_Decode(MYSQL_RESULT($result0bin_data)) $type = MYSQL_RESULT($result0filetype) Header( Content-type $type) echo $data gt

Q6MySQL裝好之後啟動時或是執行 mysqladmin會出現如下訊息 Cant connect to local MYSQL Server through Socket varlibmysqlmysqlsock或是

Cant connect to local MYSQL Server through Socket tmpmysqldsock

Ans 可能有下列幾個原因

1這個 mysqldsock 不見了被某人刪除了或是被一些系統自動執行程式給刪

了例如有些 cron任務便會設定定期刪除 tmp 裡的東西所以呢您只能修改

cron 裡的設定讓它不要清除 mysqldsock 2在啟動時也可以改變 mysqldsock的位置您在啟動 MySQL的時候可以加入此參數usrlocalmysqlbinsafe_mysqld --user=mysql --socket=其他路

徑socket amp 同時得去設定環境變數 MYSQL_UNIX_PORT的值以指定新的

73

路徑 3若是您沒改 MYSQL_UNIX_PORT的值那麼您可以在執行指令的時候才打

例如mysqladmin --socket=其他路徑socket version Q7How to get the last insert id Ans CREATE TABLE product ( id INT(4) NOT NULL AUTO_INCREMENT PRIMARY KEY description VARCHAR(50) ) 1利用 SQL的話 mysqlgt insert into product(description) values(123) Query OK 1 row affected (000 sec) mysqlgt select last_insert_id() +------------------+ | last_insert_id() | +------------------+ +------------------+ 1 row in set (000 sec) ======================================== 2如果是 PHP的話 你可以用mysql_insert_id()取得該 id PHP example $result=MYSQL_QUERY(INSERT INTO product (description) VALUES ($description)) $id= mysql_insert_id() print This file has the following Database ID $id Q8如何將文字檔匯入資料庫 Ans $addr=homehttpdhtmlphpschool001txt $sql_select = load data infile $addr into table test fields terminated by t 解說 $sql_select = load data infile 文字檔名 into table 表格名 fields terminated by

74

t

(欄位分隔以 TAB鍵) 該文字檔須與資料表欄位格式相符 例如欄位有三個 則文字檔為每行一筆資料如下 欄 1資料ltTABgt欄 2資料ltTABgt欄 3資料 欄 1資料ltTABgt欄 2資料ltTABgt欄 3資料 欄 1資料ltTABgt欄 2資料ltTABgt欄 3資料 欄 1資料ltTABgtltTABgt欄 3資料

Q9如何撰寫 MySQL C API Ans Step 1利用文字編輯器撰寫以下程式碼 mysqlcc

include ltstdiohgt

include ltmysqlmysqlhgt

int main (int argc char argv[])

MYSQL mysql

MYSQL_RES res

MYSQL_ROW row

if (argc = 2)

fputs (Usage myc ltdatabasegt stderr)

return 1

if ((mysql_connect(ampmysqllocalhostrootYour_Password)))

fputs (Error connecting stderr)

abort()

75

if (mysql_select_db(ampmysqlargv[1]))

fputs (Error selecting database stderr)

abort()

if (mysql_query(ampmysqlSELECT FROM test_table))

fputs (Error processing query stderr)

abort()

if ((res = mysql_store_result(ampmysql)))

fputs (Error storing results stderr)

abort()

while((row = mysql_fetch_row(res)))

uint i = 0

for (i=0 i lt mysql_num_fields(res) i++)

printf(s row[i])

printf(n)

return 0

Step 2 Compile

gcc -Iusrlocalmysqlinclude -Lusrlocalmysqllibmysql mysqlcc ndashlm -lmysqlclient

(其中 include path與 library path取決於你的 MySQL安裝路徑)

76

如果執行時發生如下 error Run problemerror in loading shared libraries libmysqlclientsoX 將你的 MySQL library path(for exampleusrlocalmysqllibmysql) 加入etcldsoconf and run sbinldconfig -v Q9ASP + MySQL 範例程式 Ans Dim myconn As New ADODBConnection Dim myrs As New Recordset Dim mySQL As String Dim myrows As Long myconnOpen DSN=MyODBCsample mySQL = SELECT from user myrsSource = mySQL Set myrsActiveConnection = myconn myrsCursorLocation = adUseClient myrsOpen myrows = myrsRecordCount myrsClose myconnClose 可參考 httpwwwdwamnetmysqlasp_myodbcasp 有詳細的資料 Q10如何將 MySQL中的資料庫匯出成txt檔 Ans select from TableName into outfile textxls all result fields will seperate by tab

77

第八章 參考資料

英文部份 網址 1 httpwwwmysqlcom MySQL 網站有第一手有關 MySQL的資料 2 httpwwwmysqlcomdocenReplicationhtml 有關 MySQL Replication 的文件 3 httpwwwgeocitiescomsqlhomefaqstore_blobhtml 如何在 MySQL 存放 BLOB的資料 4httpwwwsapdborg 有關 SAP跟 MySQL相關合作的網站 書藉 1 Cooking with MySQL

Paul DuBois has selected sample recipes from the hundreds youll find in his book MySQL

Cookbook In this third and final series of excerpts showcasing these recipes learn how to

compute team standings how to calculate the differences between successive Dec 26

2002 2 Tips for Building Web Database Applications with PHP and MySQL by Hugh E Williams co-author of Web Database Applications with PHP amp MySQL 04042002

3 Managing and Using MySQL 2nd Edition By Tim King George Reese Randy Jay Yarger

4 MySQL Cookbook By Paul DuBoisPublisher OReillyPub Date October 2002

中文部份

78

1 httplinuxtncedutwtechdocmysqlmysql_docmanual_tochtml MySQL 中文手冊 2 httpchenshloxaedutwphpZ_1php PHP+MySQ程式研習設計網站 3 httplinuxtncedutwtechdocbanicdownhtml PHP 4 手冊 4 httpwwwtncedutwadmin_zonephp台南縣教育網網路中心有很多 Linux相關文件 5 httpdobtncedutw網站建置百寶箱有很多 PHP MySQL 相關範例程式 5 httpwwwdbworldcomtw資料庫專家電子雜誌介紹資料庫的重要觀念及名詞

79

附錄一 SQL Command 介紹

SQL (讀音ess-que-el) 是一種結構查詢語法SQL 使用於資料庫交流

傳遞相容於 ANSI (American National Standards Institute) 是一套標準的關聯

式資料庫語言 SQL 語言是執行更新或從資料系統獲取資料一般常見的關聯

資料庫系統都有提供 SQL 如 Oracle Sybase Microsoft SQL Server Access Ingres 等雖然大部份的資料庫都有提供 SQL 但也多提供了自已獨特的語

法造成了不相容的情形但標準基本的語法是相通的如Select Insert Update Delete Create and Drop 每一個系統都有支援

Table相關 Command

Create Table

關聯式資料庫包含有很多元件稱為資料表(tables) 把資料或訊息放在資

料表中 資料表是以不同的名稱做分別資料表由欄列所構成的二維陣列

欄包含欄位名資料型態 及其他可判斷的資訊列是由全部欄位構成一筆一

筆的紀錄 create table 語法用在建立一個新的資料表語法格式如下

create table tablename (column1 data type column2 data type column3 data type)

Format of create table if you were to use optional constraints

create table tablename (column1 data type [constraint] column2 data type [constraint] column3 data type [constraint]) [ ] = optional

Note You may have as many columns as youd like and the constraints are optional

80

Example

create table employee (first varchar(15) last varchar(20) age number(3) address varchar(30) city varchar(20) state varchar(20))

注意建立資料表格式要以括號把前後框住而最後以(分號)做結尾

欄位名不要超過 30個字元長而且不要使用 sql 的關鍵字(如 where select等)而在後面接是型態的宣告(如字串數字日期格式等)

資料型態是來描述欄位的方式如一個欄位Last_Name 是一個姓氏可以使用varchar (可變動長度字串) 資料型態

以下是幾個常見的資料庫型態 char(size) 固定長度字串最長為 255 位元 varchar(size) 變動長度字串最大字元數以 size 來指定 number(size) 數值格式可以是整數也可以是小數最大數字以 size 位數判

斷未指定小數位數由系統內定 date 日期格式 number(sized) 數值格式最大數字以 size 位數判斷d 為小數位數整數位

數為 size-d 位

有何限制當資料表被建立通常有一或數個欄位是要使用來做關聯的功

能 例如unique 限制(唯一值)兩筆記錄不可以相同的值 not null (非空值)該欄位一定要輸入資料不可是空的primary key (主鍵)是每一筆記錄識別的主要方式

Drop a table drop table 刪除資料表(其中的資料也會一併刪除)

drop table tablename

Example

81

drop table 和刪除全部資料是不同的刪除全部資料欄位名稱資訊等還會

存在但刪除資料表會把這一些也一併移除掉

如何查詢資料

Select 基本用法

select 語法是關連式資料庫最常用的部份可以取得你想要的資料這是一個

簡單的範例 select column1[column2etc] from tablename [where condition] [] = optional 在 select 之後所列欄位名則是要顯示的資料部份你可以一一列出各欄位

名或是以 (星號)來代表選擇全部的欄位 from 之後放資料表名稱 where 子句 (選項) 指定要過濾的條件符合者才會顯現 where 可使用的條件運算元 = 等於 gt 大於 lt 小於 gt= 大或等於 lt= 小或等於 ltgt 大相等 LIKE 相似 For example select first last city

82

from empinfo where first LIKE Er 以Er 為開頭的字串就符合要以單引號框住 Or you can specify select first last from empinfo where last LIKE s 最後一字為 S 就符合 select from empinfo where first = Eric 則表示 first name 一定要是 Eric 才可以 範例資料表empinfo 統計函數

MIN 傳回指定欄位最小值

MAX 傳回指定欄位最大值

SUM 傳回指定欄位總和

AVG 傳回指定欄位平均值

COUNT 傳回指定欄位的筆數

COUNT() 傳回資料庫中的總筆數

統計函數使用於資料表中的數值欄位配合 SELECT 語法使用 只用於總結特定單一欄位可以配合 GROUP BY 做篩選但也可以不使用 GROUP BY 語句For example

SELECT AVG(salary) FROM employee

83

傳回全部 salary 平均值

Another example

SELECT AVG(salary) FROM employee WHERE title = Programmer

傳回 salary 平均值條件為 employees 資料表中當 title 等於 Programmer

Example

SELECT Count() FROM employees

傳回 employees 資料表中紀錄總筆數

GROUP BY 語法 SELECT column1 SUM(column2) FROM list-of-tables GROUP BY column-list The GROUP BY 語句可以先以所列的欄位為條件分組排序在一起(可以多欄

位) example 要列出每一個 dept 中最高 salary 值 SELECT max(salary) dept FROM employee GROUP BY dept HAVING 語法

SELECT column1 SUM(column2) FROM list-of-tables GROUP BY column-list HAVING condition

HAVING 子句是 GROUP BY 的一部份用來過濾在 GROUP BY 所選出的資料功能如同 select 命令中 where 條件式一樣只是 HAVING 必需配合 GROUP BY 使用

我們以例子來說明我們要取得每一公司名及每一公司的薪水平均值輸入如下

84

SELECT dept avg(salary) FROM employee GROUP BY dept

但如果我們只列出薪資平均值超過 20000元的公司資料

SELECT dept avg(salary) FROM employee GROUP BY dept HAVING avg(salary) gt 20000

ORDER BY子句語法

SELECT column1 SUM(column2) FROM list-of-tables ORDER BY column-list [ASC | DESC]

[ ] =選項

ORDER BY是一個選項子句當你以排序方式來顯示資料(正向由小到大反向由大到小)以指定的欄位資料做排序

ASC = 正向- 預設值 DESC = 反向排序

For example

SELECT employee_id dept name age salary FROM employee_info WHERE dept = Sales ORDER BY salary

以上列出公司代號公司名銷售員人名年紀及薪資而條件是公司名為 Sales 顯示順序以薪資多少排序(由小到大為預設值)

如果要以多個欄位做排序要以逗號做分隔如下

SELECT employee_id dept name age salary FROM employee_info WHERE dept = Sales ORDER BY salary age DESC

85

結合條件及布林運算 SELECT column1 SUM(column2) FROM list-of-tables WHERE condition1 AND condition2 AND運算可以結兩個或以上的條件放在 WHERE子句中 兩者都要為真才

會顯示該筆記錄 OR 運算可以結兩個或以上敘述放在 WHERE子句中只要其中一個為直就

會顯示該筆記錄 For example SELECT employeeid firstname lastname title salary FROM employee_info WHERE salary gt= 5000000 AND title = Programmer 必需要薪資大於等於 50000而且職稱為 Programmer同時符合才會顯示該筆資料 以下以括號括住雖然不是必需的但如此比較容易讀 SELECT employeeid firstname lastname title salary FROM employee_info WHERE (salary gt= 5000000) AND (title = Programmer) 另外範例 SELECT firstname lastname title salary FROM employee_info WHERE (title = Sales) OR (title = Programmer) 條件為只要是 Sales 或 Programmer 職稱的就會被列出 IN and BETWEEN 子句

SELECT column1 SUM(column2) FROM list-of-tables WHERE column3 IN (list-of-values) SELECT column1 SUM(column2) FROM list-of-tables WHERE column3 BETWEEN value1 AND value2 IN 子句使用在列舉項目的使用上也就是分別測試是否符合所列的值 For example

86

SELECT employeeid lastname salary FROM employee_info WHERE lastname IN (Hernandez Jones Roberts Ruiz) 條件為姓氏(astname)要符合 Hernandez Jones Roberts or Ruiz 其中一個才會被傳回 IN運算元也可以使用 OR 的語法來取代如下結果相同 SELECT employeeid lastname salary FROM employee_info WHERE lastname = Hernandez OR lastname = Jones OR lastname = Roberts OR lastname = Ruiz 但使用 IN 句子比較短也比較易懂 你也可以使用 NOT IN 來去掉不要的記錄 BETWEEN 運算元使用在判斷是否存在兩個數值之間 For example SELECT employeeid age lastname salary FROM employee_info WHERE age BETWEEN 30 AND 40 傳回年紀 30歲到 40歲之間的資料(含 30及 40歲者) 相同的也可以使用以下語法來達到相同的結果 SELECT employeeid age lastname salary FROM employee_info WHERE age gt= 30 AND age lt= 40 你也可使用 NOT BETWEEN 來濾掉中間值的資料 數學運算 標準 ANSI SQL-92 提供以下運算

87

+ 加

- 減

餘數

餘數為除法後剩整數這不在標準的 ANSI SQL 中但大部份的資料庫都會支

援這運算元以下列出有用的函數雖不在 ANSI SQL-92 提供但一般資料庫

也會支援他們

ABS(x) 傳回 x 絕對值

SIGN(x) returns the sign of input x as -1 0 or 1 (negative zero or positive respectively)

MOD(xy) 餘數 - returns the integer remainder of x divided by y (同 xy)

FLOOR(x) 傳回小或等於 x 的最大整數值

CEILING(x) or CEIL(x)

傳回大或等於 x 的最小整數值

POWER(xy) x的 y 次方

ROUND(x) 把 x 四捨五入為整數

ROUND(xd) 四捨五入取到小數 d 位

SQRT(x) x 開平方

For example SELECT round(salary) firstname FROM employee_info 傳回薪資取到整數位

如何新增資料

insert 加入一筆新紀錄到資料表中 insert into tablename (first_columnlast_column) values (first_valuelast_value) [] = optional Example insert into employee

88

(first last age address city state) values (Luke Duke 45 2130 Boars Nest Hazard Co Georgia) Note 字串要以單引號住如string 數字框住也無妨 insert into 後面接資料表名稱再接以括號括住的欄位名在 values 後括號分別對映各欄位的值 以上的例子新增了一筆名(first) 為 Luke而住所(state) 為 Georgia 的資料

如何刪除資料

delete 可以刪除單筆或多筆紀錄 delete from tablename where columnname OPERATOR value [and|or column OPERATOR value] [ ] = optional Examples delete from employee Note 如果你沒有指定 where 子句那麼全部的紀錄都會被刪除 delete from employee where lastname = May delete from employee where firstname = Mike or firstname = Eric delete from 接著資料表名 再接著是條件式判斷沒有條件式則全部紀錄會

被刪除

如何更新資料

update 用來更新你所指定的記錄要和 WHERE 配合小心使用 語法 update tablename set columnname = newvalue[nextcolumn = newvalue2] where columnname OPERATOR value [and|or column OPERATOR value] [] = optional Examples

89

update phone_book set area_code = 623 where prefix = 979 update phone_book set last_name = Smith prefix=555 suffix=9292 where last_name = Jones update employee set age = age+1 where first_name=Mary and last_name=Williams

90

附錄二Replication

測試環境

RedHat 90 + MySQL 32358 MySQL資料庫路徑 varlibmysql MySQL設定檔 etcmycnf Master IP 1921680100 Slave IP 1921680200 請至下列網址下載最新MySQL 32358套件並利用rpm ndashUvh 更新 httpupdatesredhatcom9enosi386

圖 最新 MySQL 套件

測試架構圖

91

1921680100

1921680200Master Server

erveSlave S r

圖 測試架構圖

測試步驟

Master server 部份 Step1 確認 MasterSlave機器上所裝的 MySQL版本能進行

replication( 32329 or higher ) Step2 在 Master MySQL上開放一個帳號給 Slave mysql ndashu root ndashp mysqlgtGRANT FILE ON TO repl1921680200 IDENTIFIED BY lsquoabc123rsquo mysqlgtq 上面是 Master開放一個帳號 repl密碼 abc123給 IP1921680200有檔案處理

的權限 Step3 shutdown MySQL on the Master mysqladmin ndashu root ndashp shutdown Step4 備份 Master所有資料庫 tar ndashcvf tmpmysql-snapshottar varlibmysql 注意tar的時候MySQL是要在 stop情況下 在mysql (wwwmysqlcom) 網站的FAQ有不用shutdown的方法

92

Step5 在 master機器上修改etcmycnf 在[mysqld]區段內加入參數 log-bin server-id=這邊設定 server-id=1 sql-bin-update-same binlog-do-db=CRM只針對 CRM資料庫做紀錄 Step6 Restart MySQL on the master service mysqld start 此時因為有加入 log-bin 參數因此開始有 index產生了在varlibmysql目錄下

有index檔案紀錄資料庫的異動 log Slave server 部份 Step1 在 slave設定etcmycnf 在[mysqld]區段加入 master-host= master-user= master-password= master-port= server-id= 這邊設定 master-host=1921680100 master-user=repl master-password=abc123 master-port=3306 server-id=2 master-connect-retry=60預設重試間隔 60秒 replicate-do-db=CRM告訴 slave只做 CRM資料庫的更新 log-slave-updates Step2 將 master上的 mysql-snapshottar copy到 slave上 用 ftp傳到 slave的tmp Step3 解壓縮 Master資料庫至 Slave Server上 cd varlib tar xvf tmpmysql-snapshottar chown ndashR mysqlmysql mysql

93

chmod ndashR 770 mysql (視情況) Step4 Restart MySQL on the slave server 這時在varlibmysql目錄會出現 masterinfo此檔案紀錄了 Master MySQL server的資訊

狀況測試

One-way replication

1921680100

1921680200Master Server

erveSlave S r

圖 One-way replication架構圖 Step1 Master跟 Slave網路及服務都正常情況下由 Master端異動資料後 到 Slave端瀏覽資料檢視是否有進行 replication Step2 模擬 Slave Server 當機 可用在於 slave真的當機或是 Slave 不一定需要一直跟 master connect將Slave MySQL server shutdown由 Master端異動資料到 slave端瀏覽此時Slave應該沒有被 replication 更新然後再將 Slave端 MySQL server start起來

預設 60秒後 Slave會嘗試跟 Master要求進行 replication再去 Slave端檢視是否有更新資料

94

Step3 模擬 Master當機因為是設定 One-way replication一旦 Master Server Slave端沒有 Master的 source可以 download Two-way replication 基於 Master當機狀況於是發展雙向 Replication即 1921680100 ( Host A ) 1921680200 ( Host B )都分別擔任 MasterSlave身分

1921680100

1921680200er

Server B MasterSlave Server

Server A MasterSlave Serv

圖 Two-way replication架構圖 以下是針對兩台 MySQL伺服器進行雙向 Replication Step1觀念同單向 replication只是改成 Master也有 Slave身分 Slave也有Master的身分先分別在 Server AServer B 都去 grant一個進行 replication的身分 [A]mysqlgtGRANT FILE ON TO repl1921680200 IDENTIFIED BY lsquoabc123rsquo [B]mysqlgt GRANT FILE ON TO repl1921680100 IDENTIFIED BY lsquoabc123rsquo Step2做完單向 replication後stop Server Aserver B MySQL service此時 AB資料是一樣的

95

修改etcmycnf設定 範例 Server A [mysqld] datadir=varlibmysql socket=varlibmysqlmysqlsock server-id=1 log-bin sql-bin-update-same binlog-do-db=CRM master-host=1921680200 master-user=repl master-password=abc123 log-slave-updates master-connect-retry=60 replicate-do-db=CRM Server B [mysqld] datadir=varlibmysql socket=varlibmysqlmysqlsock server-id=2 log-bin sql-bin-update-same binlog-do-db=CRM master-host=1921680100 master-user=repl master-password=abc123 log-slave-updates master-connect-retry=60 replicate-do-db=CRM 分別 start Server AServer B MySQL後此時雙方都是 MasterSlave身分一旦哪一方資料異動就會通知對方來 replication-若 replication失效則必須將Server AServer B的masterinfo及index00x 都砍掉然後分別 restart MySQL server進行測試檢視成果 實務上通常如果需要做Two-way replication通常會搭配Virtual Server使用

96

在前端架設一台Virtual Server不過此部份不在此份SOP討論範圍內有興趣

的讀者可參考 httpwwwlinuxvirtualserverorg 網站

1921680100 1921680200

Host A MasterSlave Server

Host B MasterSlave Server

Virtual Host

圖 Virtual Server + Two-way replication 架構圖

97

圖 High Availability Linux Virtual Server架構圖

98

  • COSA-SOP-03-006
  • 第一章 簡介
    • 11適用對象 (Audience)
    • 12 MySQL本身
    • 13 MySQL 40版跟50版重大的改進功能
    • 14 各家資料庫軟體比較
      • 第二章 前置需求
      • 第三章 安裝
        • 31 MySQL安裝
        • 32 phpMyAdmin安裝
        • 33 升級及注意事項
          • 第四章 MySQL管理
            • 41 Webmin 管理介面
            • 42 phpMyAdmin 的操作介面
            • 43管理指令介紹
              • 431 利用mysqladmin設定root的密碼
                  • 第五章 實用範例
                    • 51 任務一Web Base客戶通訊錄
                    • 52 任務二Web Base群組軟體 ( twig )
                      • 第六章 維護及更新程序
                        • 61 日常維護
                        • 62 更新程序
                        • 63 備份重要檔案
                        • 64 離線備份與還原
                        • 65 線上備份與還原
                          • 第七章 問題與解答
                          • 第八章 參考資料
                          • 附錄一 SQL Command 介紹
                          • 附錄二Replication
Page 22: DataBase Server Standard Operation Procedureebooks.lib.ntu.edu.tw/1_file/oss/63/93doc4-5.pdf · 業務的公司帶來了不少壓力,譬如微軟,甲骨文 ... 外的錢用在第三方的資料庫產品上,譬如就可以不用再購買甲骨文公司

圖 3-17 修改 configincphp

圖 3-18 修改 configincphp p

Step 7 設定語系

22

圖 3-19 設定語系

圖 3-20 執行 phpMyAdmin

23

33 升級及注意事項

RedHat 90附的 MySQL版本為 323 MySQL所釋出最新穩定版本為

40若是您不想用系統預附的 323請先利用下列移除之前 323的版本

rpm ndashe mysql-devel rpm ndashe mysql-server rpm ndashe mysql --nodeps 然後到下列網址下載您所想要的版本進行安裝在這裏我們用 4014版為例 Step 1 下載相關套件( httpwwwmysqlcomdownloadsmysql-40html )

圖 3-21 Download MySQL 4014 相關 RPM Step 2 利用 rpm 指令安裝

24

圖 3-22 Install MySQL 4014 相關 RPM

圖 3-23 Install MySQL 4014 相關 RPM

Step 3 啟動 MySQL

25

圖 3-24 啟動 MySQL 4014 並修改密碼

26

第四章 MySQL管理

本章將我們介紹利用WebminphpAdminCommand的方式建立一個名為

CONTACT的資料庫內有一個 address的 Table作為我們客戶通訊錄程式使

用的資料庫

41 Webmin 管理介面

412建立資料庫

Step 1 登入Webmin

圖 4-1 登入WebMin

Step 2 點選伺服器

27

圖 4-2 伺服器畫面

Step 3 點選 MySQL資料庫伺服器

圖 4-3 MySQL資料庫伺服器

28

Step 4 建立一個新的資料庫

圖 4-4 建立 MySQL資料庫

Step 5 建立名為 CONTACT的資料庫

29

圖 4-5 指定資料庫名稱

412 建立資料表

假設我們要建立一個名為 address的 Table其結構如下 欄位名稱 資料型態 長度 說明 id INT (自動編號) 連絡人編號 name varchar文字 20 連絡人姓名 tel Varchar文字 15 連絡人電話 Step 1 選擇 CONTACT資料庫

30

圖 4-6 選擇資料庫

Step 2 指定欄位數目

31

圖 4-7 設定欄位數目

Step 3設定表格欄位屬性

圖 3-8 設定表格欄位屬性

Step 4建立表格資料

32

圖 4-9 建立表格資料

圖 4-10 檢視資料

33

圖 4-11 新增資料

圖 4-12

34

圖 4-13

413 使用者管理

接下來我們要利用Webmin 來建立資料庫使用者並給予某些權限 Step1建立使用者

35

圖 4-14 選擇使用者權限

圖 4-15

36

Step2 賦予權限

圖 4-16

Step3 權限列表

37

圖 4-17

38

42 phpMyAdmin 的操作介面

421建立資料庫

Step 填入資料庫名稱並按「建立」

圖 4-18建立資料庫

422 建立資料表

Step1 填入資料表名稱並指定欄位數量 執行

39

圖 4-19填入資料表名稱並指定欄位數量

Step2 設定欄位屬性

圖 4-20設定欄位屬性

40

Step3 phpMyAdmin會產生相關的 SQL Command

圖 4-21 資料表結構及相關 SQL Command

Step4新增 Record

41

圖 4-22

圖 4-23

42

圖 4-24

圖 4-25

43

423使用者管理

Step1建立使用者

圖 4-26

44

圖 4-27

Step2 給予權限

圖 4-28

Step3權限列表

45

圖 4-29

43管理指令介紹

431 利用 mysqladmin設定 root的密碼

當您在Windows 或 Linux 中安裝好 MySQL後系統會自動幫您建立兩個

帳分別是 root 和 匿名者MySQL的 root 跟 Linux 最高權限使用者 root無關MySQL的 root使用者相當於 MS SQL 中的 sa 帳號擁有最高的 Database管理權限但系統預設 MySQL的 root 是不需要密碼所以通常我們一安裝

MySQL後首要任務便是修改 root的密碼 我們可以利用 mysqladmin工具或是直接修改 MySQL內部資料庫的使用者資

料 mysqladmin ndashu root ndashh cosaexamplecom password lsquo1234rsquo

46

-u 表示使用者帳號root 為 MySQL預設的管理帳號

-h 表示 MySQL主機的主機名稱也可使用 IP Address password 表示使用者的密碼因為字串請使用單引號將密碼括起來 密碼設定完成之後還是可以利用 mysqladmin修改密碼但是你必須提供目前的密碼

432 連線 MySQL

mysql -uroot -p密碼 (-p和密碼之間不能有空白) 或 mysql -uroot -p (此方式會在進入後要求密碼) [rootossc phpMyAdmin] mysql -u root -p1234

Welcome to the MySQL monitor Commands end with or g

Your MySQL connection id is 25 to server version 32354

Type help or h for help Type c to clear the buffer

mysqlgt show databases

+----------+

| Database |

+----------+

| mysql |

| test |

+----------+

2 rows in set (000 sec)

mysqlgt exit

Bye

[rootossc phpMyAdmin]

433 建立資料庫

可利用 mysqladmin指令建立 CONTACT資料庫 mysqladmin -u root -p1234 create CONTACT

47

或是利用 mysql指令 [rootossc bluepage] mysql -u root -p1234 Welcome to the MySQL monitor Commands end with or g Your MySQL connection id is 1057 to server version 32354 Type help or h for help Type c to clear the buffer mysqlgt create database CONTACT Query OK 1 row affected (000 sec) mysqlgt show databases +----------+ | Database | +----------+ | CONTACT | | address | | hello | | mysql | | nuke | | test | +----------+ 6 rows in set (000 sec) mysqlgt exit

434 建立資料表

編寫 adresssql內容如下 -- Table structure for table address CREATE TABLE address ( id int(11) NOT NULL auto_increment name varchar(20) NOT NULL default tel varchar(15) NOT NULL default PRIMARY KEY (id) ) TYPE=MyISAM

48

-- Dumping data for table address INSERT INTO address VALUES (1林小明0800016888) INSERT INTO address VALUES (2黃大雄0800016888) INSERT INTO address VALUES (3劉小芬0800024365) 然後執行此 sql script mysql -u root -p1234 CONTACT lt addresssql 或是利 mysql command [rootossc bluepage] mysql -u root -p1234 Welcome to the MySQL monitor Commands end with or g Your MySQL connection id is 1090 to server version 32354 Type help or h for help Type c to clear the buffer mysqlgt use CONTACT Database changed Database changed mysqlgt CREATE TABLE address ( -gt id int(11) NOT NULL auto_increment -gt name varchar(20) NOT NULL default -gt tel varchar(15) NOT NULL default -gt PRIMARY KEY (id) -gt ) TYPE=MyISAM Query OK 0 rows affected (000 sec) mysqlgt INSERT INTO address VALUES (1林小明0800016888) Query OK 1 row affected (000 sec) mysqlgt INSERT INTO address VALUES (2黃大雄0800016888) Query OK 1 row affected (000 sec) mysqlgt INSERT INTO address VALUES (3劉小芬0800024365) Query OK 1 row affected (000 sec) mysqlgt exit Bye

49

第五章 實用範例

51 任務一Web Base客戶通訊錄

任職於開放科技公司的林小明前些日子在最符合成本效益的條件下快

速地完成公司網站的建置老闆因此對小明讚譽有加最近因為公司存放客戶資

料的 SQL Server主機屢遭病毒攻擊加上作業系統本身的問題當機次數頻繁

老闆希望能儘快把公司的客戶通訊錄程式移轉到較穩定的環境上因為此客戶通

訊錄程式最主要給內部人員使用所以介面美觀並不特別要求只求穩定且能快

速得到查詢結果老闆希望在短時間先看到程式的雛型並鍵入資料對其效率

及穩定性進行測試因為上次小明表現突出所以這次不可能的任務自然又落到

小明身上 小明想來想去既然要快速又穩定他而且又不希望所有人都得安裝 Client

程式於是小明決定)捨棄他的舊愛「Delphi+MS SQL」投向新歡「Apache + MySQL + PHP」利用此架構來設計一個簡單實用的Web Base客戶通訊錄程式

511 Web Base客戶通訊錄架構

此程式需要建立 CONTACT的資料庫並建立 adress Tables其結構如下表建立步驟請參考第三章 欄位名稱 資料型態 長度 說明 id INT (自動編號) 連絡人編號 name varchar文字 20 連絡人姓名 tel Varchar文字 15 連絡人電話 Web Base通訊錄共有下列幾個檔案功能如下表

檔案名稱 說明 Indexhtml Web Base通訊錄首頁 addphp 新增連絡人的 php程式 searchphp 尋找連絡人的 php程式 editphp 具有更新及刪除功能的 php程式

50

我們將這些檔案放至varwwwhtmlbluepage (預設無 bluepage目錄)

512 Web Base通訊錄測試

httpwwwopencombluepage 新增資料

圖 5-1 新增連絡人

圖 5-2 填入資料

51

圖 5-3 新增成功

搜尋及異動資料

圖 5-4 搜尋通訊錄

52

圖 5-5 編輯資料

圖 5-6 更新資料

513 程式內容及說明

lt-- 程式範例indexhtml--gt lthtmlgt ltheadgtlttitlegt通訊錄lttitlegtltheadgt ltbodygt ltcentergt

53

lth2gt通訊錄lth2gtlthrgt lta href=indexhtmlgt通訊錄ltagt | lta href=addphpgt新增連絡人ltagt | lta href=searchphpgt搜尋通訊錄ltagt ltcentergt ltbodygt lthtmlgt lt-- 程式範例addphp --gt lthtmlgt ltheadgtlttitlegt新增連絡人lttitlegtltheadgt ltbodygt ltcentergtlth2gt新增連絡人lth2gtltcentergtlthrgt lt 取得欄位資料 if (isset($_POST[Name]) ampamp isset($_POST[Tel]) ) $name = $_POST[Name] $tel = $_POST[Tel] 檢查是否有輸入欄位資料 if ($name = ampamp $tel = ) 建立 SQL字串 $sql = INSERT INTO address (name tel) values( $sql= $name $tel) 建立 MySQL 連結 $link = mysql_connect(localhostroot1234) 選擇資料庫 mysql_select_db(CONTACT) 執行 SQL指令 mysql_query($sql) mysql_close($link) echo ltfont color=redgt新增連絡人成功ltfontgtltbrgt gt ltform action=addphp method=postgt lttable border=0 width=300gt lttrgtlttdgt姓名 lttdgt

54

lttdgtltinput type=text name=Name size=20 maxlength=10gtlttdgtlttrgt lttrgtlttdgt電話 lttdgt lttdgtltinput type=text name=Tel size=20 maxlength=20gtlttdgtlttrgt lttrgtlttd colspan=2 align=centergt ltinput type=submit value=新增連絡人gtlttdgtlttrgt lttablegt ltformgt ltbrgtlta href=indexhtmlgt通訊錄ltagt | lta href=addphpgt新增連絡人ltagt | lta href=searchphpgt搜尋通訊錄ltagt ltbodygt lthtmlgt

lt-- 程式範例searchphp --gt lthtmlgt ltheadgtlttitlegt搜尋通訊錄lttitlegtltheadgt ltbodygt ltcentergtlth2gt搜尋通訊錄lth2gtlthrgt lt if (isset($_POST[Search])) 建立資料庫連結並選定資料庫 $link = mysql_connect(localhostroot1234) mysql_select_db(CONTACT) 建立基本的 SQL字串 $sql = SELECT FROM address 檢查是否輸入姓名 if (chop($_POST[Name]) = ) $name = name LIKE $_POST[Name] else $name = 檢查是否輸入電話號碼 if (chop($_POST[Tel]) = ) $tel = tel LIKE $_POST[Tel] else $tel =

55

if條件組合 SQL字串 if (chop($name) = ampamp chop($tel) = ) $sql= WHERE $name AND $tel elseif (chop($name) = ) 只有姓名 $sql = WHERE $name elseif (chop($tel) = ) 只有電話號碼 $sql = WHERE $tel $sql= ORDER BY name 最後加上排序 $result = mysql_query($sql) 取得欄位數 $total_fields = mysql_num_fields($result) echo lttable border=1gt echo lttrgtlttdgt編號lttdgtlttdgt姓名lttdgtlttdgt電話lttdgtlttd colspan=2gt功能選項lttdgtlttrgt 表格顯示查詢結果 while ($rows = mysql_fetch_array($result MYSQL_NUM)) echo lttrgt for ($i = 0 $i lt $total_fields $i++) echo lttdgt$rows[$i]lttdgt echo lttdgtlta href=editphpaction=editampid= echo $rows[0]gtltbgt編輯ltbgtlttdgt echo lttdgtlta href=editphpaction=delampid= echo $rows[0]gtltbgt刪除ltbgtlttdgt echo lttrgt echo lttablegtlthrgt mysql_free_result($result) mysql_close($link) gt ltcentergt ltform action=searchphp method=postgt lttable border=0 width=450gt lttrgtlttdgt搜尋姓名 lttdgt lttdgtltinput type=text name=Name size=10 maxlength=20gtlttdgtlttrgt lttrgtlttdgt搜尋電話 lttdgt lttdgtltinput type=text name=Tel

56

size=20 maxlength=20gtlttdgtlttrgt lttrgtlttd colspan=2 align=centergt ltinput type=submit name=Search value=搜尋gtlttdgtlttrgt lttablegt ltformgt ltbrgtlta href=indexhtmlgt通訊錄ltagt | lta href=addphpgt新增連絡人ltagt | lta href=searchphpgt搜尋通訊錄ltagt ltbodygt lthtmlgt

lt ob_start() gt lt-- 程式範例editphp --gt lthtmlgt ltheadgtlttitlegt編輯通訊錄lttitlegtltheadgt ltbodygt lt 取得 URL 參數 $id = $_GET[id] $action = $_GET[action] 建立資料庫連結 $link = mysql_connect(localhostroot1234) mysql_select_db(CONTACT) 選擇資料庫 執行的操作 switch ($action) case update 更新 取得欄位資料 $name = $_POST[Name] $tel = $_POST[Tel] $sql = UPDATE address SET name=$name tel=$tel WHERE id=$id mysql_query($sql) 執行 SQL指令 mysql_close($link) header(Location searchphp) 轉向到 serachphp break case del 刪除 $sql = DELETE FROM address WHERE id=$id

57

mysql_query($sql) 執行 SQL指令 mysql_close($link) header(Location searchphp) 轉向到 serachphp break case edit 編輯 $sql = SELECT FROM address WHERE id=$id $result = mysql_query($sql) 執行 SQL指令 $row = mysql_fetch_row($result) 取回記錄 $name = $row[1] 取得欄位 name $tel = $row[2] 取得欄位 tel mysql_close($link) 顯示編輯表單 gt ltcentergtlth2gt更新通訊錄lth2gtltcentergtlthrgt ltform action=editphpaction=updateampid=lt echo $id gt method=postgt lttable border=0 width=300gt lttrgtlttdgt姓名 lttdgt lttdgtltinput type=text name=Name size=20 maxlength=10 value=lt echo $name gtgtlttdgtlttrgt lttrgtlttdgt電話 lttdgt lttdgtltinput type=text name=Tel size=20 maxlength=20 value=lt echo $tel gtgtlttdgtlttrgt lttrgtlttd colspan=2 align=centergt ltinput type=submit value=更新連絡人gtlttdgtlttrgt lttablegt ltformgt ltbrgtlta href=indexhtmlgt通訊錄ltagt | lta href=addphpgt新增連絡人ltagt | lta href=searchphpgt搜尋通訊錄ltagt lt break gt ltbodygt lthtmlgt

58

52 任務二Web Base群組軟體 ( twig )

順利完成Web Base客戶通訊錄程式測試一段時間後「Apache + MySQL + PHP」架構的穩定與快速巳深得老闆與公司所有同事的認同隨著公司業績蒸

蒸日上人員組織編罝愈來愈龐大跨部門的會議愈來愈多業務員每日排滿拜

訪客戶的行程跟客戶的 Email的往來也愈來愈頻繁 愈來愈多部門的同事希望公司能建置一套群組軟體提供 web mail可讓業

務人員方便收發 mail還有連絡人議事日程待辦工作書簽等功能讓整個

公司運作及個人時間管理更有效率

老闆問小明對這些需求有什麼看法小明認為如果這些功能完全由程式部

門開發必定曠日費時而且耗費公司資源小明在網路尋找是否有提供這些功能

的Free Software皇天不負苦心人小明發現了TWIG (The Web Information Gateway) httptwigscrewdrivernet這個群組軟體它在 Web 上整合郵件新聞聯絡人議事日程工作序書簽等功能非常符合公司的需求 Step 1 下載 twig-277targz 下載網址 httptwigscrewdrivernetdownloadphp3

Step 2 解開 twig-277targz tar -xzvf twig-277targz

59

Step 3 執行安裝動作安裝到 varwwwhtmltwig 目錄 cd twig-277 twig-install varwwwhtmltwig

Step 4 建立 MySQL 資料庫(twig)及各資料表

cd setup mysql -u root -p1234 mysqlgt create database twig Query OK 1 row affected (001 sec) mysqlgt quit mysql -u root ndashp1234 twiglt twigtablemysql

Step 5 修改 configincphp3 參數設定 vi varwwwhtmltwigconfigconfigincphp3 $config[fromdomain] = opencom 網域 $config[language] = chinesebig5 中文訊息 $config[imap_port] = 143notls

60

Step 6 修改連結 MySQL 的帳號密碼 vi varwwwhtmltwigconfigdbconfigincphp3 $dbconfig[sqlusername] = root username $dbconfig[sqlpassword] = 1234 password

Step 7 其他設定檔

vi etchttpdconfhttpdconf 加入 AddType applicationx-httpd-php php3 在 DirectoryIndex最後加入 indexphp3 DirectoryIndex indexhtml indexhtmlvar indexphp3 在 AddDefaultCharset ISO-8859-1加上 AddDefaultCharset ISO-8859-1

vi etcphpini register_globals = On service httpd restart Step 8 sendmail 設定 vi etcmailsendmailcf在 264 行前面加上並重新啟動 sendmail「service snedmail restart」 262 SMTP daemon options 263 264 O DaemonPortOptions=Port=smtpAddr=127001 Name=MTA 265 266 SMTP client options 267 O ClientPortOptions=Family=inet Address=00

61

Step 9 檢查設定有無錯誤 http主機名稱twigtestphp3

62

Step 10 登入 twig ( http主機名稱twig)

63

第六章 維護及更新程序

61 日常維護

系統管理員最好定期以 root 身份登入看看信件在 RedHat Linux 中有一支 logwatch 程式會定時去分析 log file如果發現異常便會發信給 root除此之外筆者建議讀者平時就檢查 MySQL log file ( varlogmysqldlog)是否有異常情形

62 更新程序

讀者可至httprpmfindnet 尋找MySQL相關套件至於升級的相關步驟請參

考Linux OS SOP 第 54節

63 備份重要檔案

預設 MySQL 的 DB 檔案是存在 varlibmysql 內以 DB名稱為目錄目錄

內就是該 DB 的所有資料通常得定期備份還有 MySQL的設定檔 etcmycnf也別忘了一起備份

64 離線備份與還原

641 離線備份

預設 MySQL 的 DB 檔案是存在 varlibmysql 內以 DB 名稱為目錄目錄內

就是該 DB 的所有資料像 CRM 這個 DB就是存在 varlibmysqlCRM 內在備份前因為怕資料尚未完全寫入磁碟而且 MySQL 會 Lock 在使用的 DB 檔案所以應該是要先把 MySQL 先 Shutdown 一下整個備份的程序可以下像下面的指令去完成 cd varlibmysql

64

service mysqld stop tar cvfz CRM_db_20030905tgz CRM service mysqld start 對這樣就可以了 不過要注意的是怕 DB 內每個 Tables 間的資料有關關

聯性所以最好是把整個 DB 一次備起來單獨只備哪個 Tables 的檔案以後回存時怕會有資料關聯不一致的問題

642 離線還原

DB 發生錯誤而要回存時其實也不難先找出最近一次完整正常的備份先把現在錯誤的網頁或 DB 先更名或 tar 起來再把好的備份給解開回原來目錄位

置就行了需要注意的是 MySQL 服務最好也是要先停止回存完成後再啟動服務回存 DB 的整個程序可能像下面 cd varlibmysql service mysqldstop mv CRM CRM_OLD tar xvfz CRM_db_20030905tg service mysqld start

65 線上備份與還原

651 線上備份

使用像上面的檔案方式備份是個不錯的方法它最少可以保持該主機某個時間點的完整檔案備份但還是有一些問題需要考慮到有些主機就不只建立一個 DB 而已總不能為了備份某個 DB 而把整個 MySQL 服務停止備份檔案的方式回存在原主機上一定適用但假如 MySQL 版本升級或是在那天該網頁空間需遷機移機到別的主機時那就沒人敢保證備出來的資料檔可以用所以我們可以考慮另一種備份的方式是使用 MySQL 本身提供的功能 MySQL Data Dump指令是 mysqldump

65

使用 MySQL 的 Dump 功能可以把 DB 的結構資料或結構加資料 Dump 成文字檔 mysqldump 指令提供的彈性很大你可以選擇把整個 DB Dump 成一個檔或是每個 Table 為一個檔甚至是把結構檔和資料分開儲存都

可以 mysqladmin -uroot -p flush-logs mysqldump CRM -uroot -p --opt gt CRM_20030905sql (CRM 是 DB 名稱 opt 是一個使用完整 Dump 參數) 假如只是要單獨 Dump 某個 Table 時只要在上面的指令後轉出符號 gt 前加個 Table 名稱就可以如只要 phpbb2_users 這個 Table 的 Dump 時只要下 mysqldump CRM -uroot -p --opt CUSTOMER gt CRM_CUSTOMER_20030905sql

652 線上還原

若要回存整個資料庫只需將壓縮的備份檔還原成 Dump 的檔案再用下面的指令回存 mysql CRM -uroot -p lt CRM_20030905sql 這邊需注意的是若建立備份時是以--opt或--add-drop-table為參數時回存的 動作是先將舊的 Table 先刪除重建 Table 的結構後再把 Data 匯入所以回存後所有的資料會回到你當時備份那個時間點因此在回存資料時可以考慮把現有錯誤或不完整的 DB 先備份一份下來以備不時之需或是拿來比對錯誤的地

方在那裡當然你也可以把資料回存到另一個測試用的 DB 內只要把上面指令

的 DB 名稱改成你的測試用 DB 名稱即可 使用這種回存方式 MySQL 服務不需停止也不會動到其他正在使用的 DB 在一些提供 MySQL 服務的虛擬主機可用這種方式作你自己的 DB 備份及回存

66

另外假如你是系統重建或是移機時切需在新的 MySQL 內新建一個空白 DB 後才行作回存的工作你可以用下面的指令建立 mysql -uroot -p -e CREATE DATABASE CRM (上面的 CRM是你要新建的 DB 名稱) 另一種作法先用 mysql 指令進入 mysql client console 然後再用 CREATE DATABASE CRM 這樣就行了記得尾端要加個 符號該行指令才會執行

67

第七章 問題與解答

Q1RedHat 90預附的 MySQL到底有無支援 Transcation機制 Ans MySQL自 32334a之後的 MySQL-Max版本加入 InnoDB的資料庫類型透過

InnoDBMySQL同樣可以進行 COMMIT與 ROLLRACK的動作RedHat 90預附的 MySQL為 32354a-11巳支援 InnoDB的資料庫類型不過必須做以

下設定 1cp usrsharedocmysql-server-32354amy-mediumcnf to etcmycnf 2 vi etcmycnf 將以下設定前的拿掉 innodb_data_home_dir = varlibmysql innodb_data_file_path = ibdata110Mautoextend innodb_log_group_home_dir = varlibmysql innodb_log_arch_dir = varlibmysql 3service mysqld restart 如此一來各位在建立Table時便可指定Table Type為 innodb ( ex create table with type=innodb ) Q2如何解決 php+mysql 許功蓋等字變亂的問題 Ans 方法一 【確定 MySQL 預設的字元集】 1 打開 WinMySQLadmin 管理畫面(在視窗右下角狀態列紅綠燈圖示中按滑鼠

右鍵點選 Show me 選項) 2 點選管理畫面中 [Variables] 標籤選項其中 character_set變數就是您預設

字元集的變數其預設是 latin1 字元集(我們要將他改回 big5)而 chatacters_set 變數則是 MySQL 可以支援哪些字元集 【修改預設字元集變數 character_set 】 1 請點選管理畫面中 [myini Setup] 標籤選項設定 myini 2 按一下 [Pick-up and Edit myini values] 按鈕以便編輯目前的 myini 設定 3 在 [mysqld] 設定區塊底下新增一行 default-character-set = big5 變數設

68

定 4 新增一個 [client] 設定區塊並加入第三步驟的變數設定(游標往下移到空白處新增兩行 [client] 和 default-character-set=big5) 5 按一下畫面左下方 [Save Modification] 按鈕儲存設定 6 重新啟動 MySQL 或 Windows 方法二 Server端注意事項 phpini 中有關的設定為(預設值) Magic quotes for incoming GETPOSTCookie data magic_quotes_gpc = On Use Sybase-style magic quotes (escape with instead of ) magic_quotes_sybase = Off Client端注意事項 1中文資料送進 mysql 前請用 addslashes($str) 處理 2處理後送進 mysql 時請用 括起來並在參數後留一個空白如 $sql = UPDATE ezf_table set tablename=$tname tableend=$endtime table inguser=$tguser tableingid=$tguserid tableallnumber=$tnumber tableloca l=$tablelocal tableanyone=$tableopen tabletext=$ttext WHERE tableid=$t ableid tablename=$tname c 取出時請用 stripslashes($str) Q3MySQL root 密碼忘了該怎麼辦 Ans 1先停掉 mysql etcrcdinitdmysql stop 2以--skip-grant-table 的參數啟動 mysql safe_mysql --skip-grant-tableamp 3 更改 root 密碼 mysql mysql mysqlgt UPDATE user SET password=password(newpassword)

69

WHERE user=root mysqlgt FLUSH PRIVILEGES mysqlgt exit 4停掉 mysql再重跑 mysqladmin -uroot -p shutdown Enter password 輸入新設定的密碼 etcrcdinitdmysql start

Q4NULL值問題

Ans

NULL值的概念是造成 SQL的新手的混淆的普遍原因他們經常認為 NULL是和一個空字符串的一樣的東西不是這樣的例如下列語句是完全不同的

mysqlgt INSERT INTO my_table (phone) VALUES (NULL)

mysqlgt INSERT INTO my_table (phone) VALUES ()

兩個語句把值插入到 phone 列但是第一個插入一個 NULL值而第二個插入一個空字符串第一個的含義可以認為是ldquo電話號碼不知道而第二個則可意味

著ldquo她沒有電話

在 SQL中NULL值在于任何其他值甚至 NULL值比較時總是假的(FALSE)包含 NULL的一個表達式總是產生一個 NULL值除非在包含在表達式中的運算符和函數的文檔中指出在下列例子所有的列返回 NULL

mysqlgt SELECT NULL1+NULLCONCAT(InvisibleNULL)

如果你想要尋找值是 NULL的列你不能使用=NULL測試下列語句不返回任

何行因為對任何表達式expr = NULL是假的

mysqlgt SELECT FROM my_table WHERE phone = NULL

要想尋找 NULL值你必須使用 IS NULL測試下例顯示如何找出 NULL電話號碼和空的電話號碼

70

mysqlgt SELECT FROM my_table WHERE phone IS NULL mysqlgt SELECT FROM my_table WHERE phone =

在 MySQL中就像很多其他的 SQL服務器一樣你不能索引可以有 NULL值的列你必須聲明這樣的列為 NOT NULL而且你不能插入 NULL到索引的

列中

當用 LOAD DATA INFILE 讀取數據時空列用更新如果你想要在一個列中有

NULL值你應該在文本文件中使用N字面上的詞NULL也可以在某些情形下使用

當使用 ORDER BY時首先呈現 NULL值如果你用 DESC以降序排序NULL值最後顯示當使用 GROUP BY時所有的 NULL值被認為是相等的

為了有助于NULL的處理你能使用 IS NULL和 IS NOT NULL運算符和 IFNULL()函數

對某些列類型NULL值被特殊地處理如果你將 NULL插入表的第一個TIMESTAMP 列則插入當前的日期和時間如果你將 NULL插入一個AUTO_INCREMENT 列則插入順序中的下一個數字

Q5如何將圖片存放於 MySQL中

Ans

Step 1建立資料庫 test

Step 2 建立表格 binary_data

CREATE TABLE binary_data (

id INT(4) NOT NULL AUTO_INCREMENT PRIMARY KEY

description CHAR(50)

bin_data LONGBLOB

filename CHAR(50)

filesize CHAR(50)

filetype CHAR(50)

71

)

Step 3 利用 storephp 寫入圖片

storephp 程式碼

ltHTMLgt ltHEADgtltTITLEgtStore binary data into SQL DatabaseltTITLEgtltHEADgt ltBODYgt lt code that will be executed if the form has been submitted

if ($submit) mysql_connect(localhostrootYOUR_PASSWORD) mysql_select_db(test) $data=Base64_Encode(fread(fopen($form_data r) filesize($form_data))) $result=MYSQL_QUERY(INSERT INTO binary_data (descriptionbin_datafilenamefilesizefiletype) VALUES ($form_description$data$form_data_name$form_data_size$form_data_type)) $id= mysql_insert_id() print ltpgtThis file has the following Database ID ltbgt$idltbgt MYSQL_CLOSE() else else show the form to submit new data

gt

ltform method=post action=ltphp echo $PHP_SELF gt enctype=multipartform-datagt File Descriptionltbrgt ltinput type=text name=form_description size=40gt ltINPUT TYPE=hidden name=MAX_FILE_SIZE value=4000000gt ltbrgtFile to uploadstore in databaseltbrgt ltinput type=file name=form_data size=40gt ltpgtltinput type=submit name=submit value=submitgt ltformgt lt

72

gt ltBODYgt ltHTMLgt

Step 3 利用 storephp 取出圖片

getdataphp 程式碼

lt Syntax getdataphp3id=ltidgt if($id) you may have to modify login information for your database server MYSQL_CONNECT(localhostrootYOUR_PASSWORD) mysql_select_db(test) $query = select bin_datafiletype from binary_data where id=$id $result = MYSQL_QUERY($query) $data = Base64_Decode(MYSQL_RESULT($result0bin_data)) $type = MYSQL_RESULT($result0filetype) Header( Content-type $type) echo $data gt

Q6MySQL裝好之後啟動時或是執行 mysqladmin會出現如下訊息 Cant connect to local MYSQL Server through Socket varlibmysqlmysqlsock或是

Cant connect to local MYSQL Server through Socket tmpmysqldsock

Ans 可能有下列幾個原因

1這個 mysqldsock 不見了被某人刪除了或是被一些系統自動執行程式給刪

了例如有些 cron任務便會設定定期刪除 tmp 裡的東西所以呢您只能修改

cron 裡的設定讓它不要清除 mysqldsock 2在啟動時也可以改變 mysqldsock的位置您在啟動 MySQL的時候可以加入此參數usrlocalmysqlbinsafe_mysqld --user=mysql --socket=其他路

徑socket amp 同時得去設定環境變數 MYSQL_UNIX_PORT的值以指定新的

73

路徑 3若是您沒改 MYSQL_UNIX_PORT的值那麼您可以在執行指令的時候才打

例如mysqladmin --socket=其他路徑socket version Q7How to get the last insert id Ans CREATE TABLE product ( id INT(4) NOT NULL AUTO_INCREMENT PRIMARY KEY description VARCHAR(50) ) 1利用 SQL的話 mysqlgt insert into product(description) values(123) Query OK 1 row affected (000 sec) mysqlgt select last_insert_id() +------------------+ | last_insert_id() | +------------------+ +------------------+ 1 row in set (000 sec) ======================================== 2如果是 PHP的話 你可以用mysql_insert_id()取得該 id PHP example $result=MYSQL_QUERY(INSERT INTO product (description) VALUES ($description)) $id= mysql_insert_id() print This file has the following Database ID $id Q8如何將文字檔匯入資料庫 Ans $addr=homehttpdhtmlphpschool001txt $sql_select = load data infile $addr into table test fields terminated by t 解說 $sql_select = load data infile 文字檔名 into table 表格名 fields terminated by

74

t

(欄位分隔以 TAB鍵) 該文字檔須與資料表欄位格式相符 例如欄位有三個 則文字檔為每行一筆資料如下 欄 1資料ltTABgt欄 2資料ltTABgt欄 3資料 欄 1資料ltTABgt欄 2資料ltTABgt欄 3資料 欄 1資料ltTABgt欄 2資料ltTABgt欄 3資料 欄 1資料ltTABgtltTABgt欄 3資料

Q9如何撰寫 MySQL C API Ans Step 1利用文字編輯器撰寫以下程式碼 mysqlcc

include ltstdiohgt

include ltmysqlmysqlhgt

int main (int argc char argv[])

MYSQL mysql

MYSQL_RES res

MYSQL_ROW row

if (argc = 2)

fputs (Usage myc ltdatabasegt stderr)

return 1

if ((mysql_connect(ampmysqllocalhostrootYour_Password)))

fputs (Error connecting stderr)

abort()

75

if (mysql_select_db(ampmysqlargv[1]))

fputs (Error selecting database stderr)

abort()

if (mysql_query(ampmysqlSELECT FROM test_table))

fputs (Error processing query stderr)

abort()

if ((res = mysql_store_result(ampmysql)))

fputs (Error storing results stderr)

abort()

while((row = mysql_fetch_row(res)))

uint i = 0

for (i=0 i lt mysql_num_fields(res) i++)

printf(s row[i])

printf(n)

return 0

Step 2 Compile

gcc -Iusrlocalmysqlinclude -Lusrlocalmysqllibmysql mysqlcc ndashlm -lmysqlclient

(其中 include path與 library path取決於你的 MySQL安裝路徑)

76

如果執行時發生如下 error Run problemerror in loading shared libraries libmysqlclientsoX 將你的 MySQL library path(for exampleusrlocalmysqllibmysql) 加入etcldsoconf and run sbinldconfig -v Q9ASP + MySQL 範例程式 Ans Dim myconn As New ADODBConnection Dim myrs As New Recordset Dim mySQL As String Dim myrows As Long myconnOpen DSN=MyODBCsample mySQL = SELECT from user myrsSource = mySQL Set myrsActiveConnection = myconn myrsCursorLocation = adUseClient myrsOpen myrows = myrsRecordCount myrsClose myconnClose 可參考 httpwwwdwamnetmysqlasp_myodbcasp 有詳細的資料 Q10如何將 MySQL中的資料庫匯出成txt檔 Ans select from TableName into outfile textxls all result fields will seperate by tab

77

第八章 參考資料

英文部份 網址 1 httpwwwmysqlcom MySQL 網站有第一手有關 MySQL的資料 2 httpwwwmysqlcomdocenReplicationhtml 有關 MySQL Replication 的文件 3 httpwwwgeocitiescomsqlhomefaqstore_blobhtml 如何在 MySQL 存放 BLOB的資料 4httpwwwsapdborg 有關 SAP跟 MySQL相關合作的網站 書藉 1 Cooking with MySQL

Paul DuBois has selected sample recipes from the hundreds youll find in his book MySQL

Cookbook In this third and final series of excerpts showcasing these recipes learn how to

compute team standings how to calculate the differences between successive Dec 26

2002 2 Tips for Building Web Database Applications with PHP and MySQL by Hugh E Williams co-author of Web Database Applications with PHP amp MySQL 04042002

3 Managing and Using MySQL 2nd Edition By Tim King George Reese Randy Jay Yarger

4 MySQL Cookbook By Paul DuBoisPublisher OReillyPub Date October 2002

中文部份

78

1 httplinuxtncedutwtechdocmysqlmysql_docmanual_tochtml MySQL 中文手冊 2 httpchenshloxaedutwphpZ_1php PHP+MySQ程式研習設計網站 3 httplinuxtncedutwtechdocbanicdownhtml PHP 4 手冊 4 httpwwwtncedutwadmin_zonephp台南縣教育網網路中心有很多 Linux相關文件 5 httpdobtncedutw網站建置百寶箱有很多 PHP MySQL 相關範例程式 5 httpwwwdbworldcomtw資料庫專家電子雜誌介紹資料庫的重要觀念及名詞

79

附錄一 SQL Command 介紹

SQL (讀音ess-que-el) 是一種結構查詢語法SQL 使用於資料庫交流

傳遞相容於 ANSI (American National Standards Institute) 是一套標準的關聯

式資料庫語言 SQL 語言是執行更新或從資料系統獲取資料一般常見的關聯

資料庫系統都有提供 SQL 如 Oracle Sybase Microsoft SQL Server Access Ingres 等雖然大部份的資料庫都有提供 SQL 但也多提供了自已獨特的語

法造成了不相容的情形但標準基本的語法是相通的如Select Insert Update Delete Create and Drop 每一個系統都有支援

Table相關 Command

Create Table

關聯式資料庫包含有很多元件稱為資料表(tables) 把資料或訊息放在資

料表中 資料表是以不同的名稱做分別資料表由欄列所構成的二維陣列

欄包含欄位名資料型態 及其他可判斷的資訊列是由全部欄位構成一筆一

筆的紀錄 create table 語法用在建立一個新的資料表語法格式如下

create table tablename (column1 data type column2 data type column3 data type)

Format of create table if you were to use optional constraints

create table tablename (column1 data type [constraint] column2 data type [constraint] column3 data type [constraint]) [ ] = optional

Note You may have as many columns as youd like and the constraints are optional

80

Example

create table employee (first varchar(15) last varchar(20) age number(3) address varchar(30) city varchar(20) state varchar(20))

注意建立資料表格式要以括號把前後框住而最後以(分號)做結尾

欄位名不要超過 30個字元長而且不要使用 sql 的關鍵字(如 where select等)而在後面接是型態的宣告(如字串數字日期格式等)

資料型態是來描述欄位的方式如一個欄位Last_Name 是一個姓氏可以使用varchar (可變動長度字串) 資料型態

以下是幾個常見的資料庫型態 char(size) 固定長度字串最長為 255 位元 varchar(size) 變動長度字串最大字元數以 size 來指定 number(size) 數值格式可以是整數也可以是小數最大數字以 size 位數判

斷未指定小數位數由系統內定 date 日期格式 number(sized) 數值格式最大數字以 size 位數判斷d 為小數位數整數位

數為 size-d 位

有何限制當資料表被建立通常有一或數個欄位是要使用來做關聯的功

能 例如unique 限制(唯一值)兩筆記錄不可以相同的值 not null (非空值)該欄位一定要輸入資料不可是空的primary key (主鍵)是每一筆記錄識別的主要方式

Drop a table drop table 刪除資料表(其中的資料也會一併刪除)

drop table tablename

Example

81

drop table 和刪除全部資料是不同的刪除全部資料欄位名稱資訊等還會

存在但刪除資料表會把這一些也一併移除掉

如何查詢資料

Select 基本用法

select 語法是關連式資料庫最常用的部份可以取得你想要的資料這是一個

簡單的範例 select column1[column2etc] from tablename [where condition] [] = optional 在 select 之後所列欄位名則是要顯示的資料部份你可以一一列出各欄位

名或是以 (星號)來代表選擇全部的欄位 from 之後放資料表名稱 where 子句 (選項) 指定要過濾的條件符合者才會顯現 where 可使用的條件運算元 = 等於 gt 大於 lt 小於 gt= 大或等於 lt= 小或等於 ltgt 大相等 LIKE 相似 For example select first last city

82

from empinfo where first LIKE Er 以Er 為開頭的字串就符合要以單引號框住 Or you can specify select first last from empinfo where last LIKE s 最後一字為 S 就符合 select from empinfo where first = Eric 則表示 first name 一定要是 Eric 才可以 範例資料表empinfo 統計函數

MIN 傳回指定欄位最小值

MAX 傳回指定欄位最大值

SUM 傳回指定欄位總和

AVG 傳回指定欄位平均值

COUNT 傳回指定欄位的筆數

COUNT() 傳回資料庫中的總筆數

統計函數使用於資料表中的數值欄位配合 SELECT 語法使用 只用於總結特定單一欄位可以配合 GROUP BY 做篩選但也可以不使用 GROUP BY 語句For example

SELECT AVG(salary) FROM employee

83

傳回全部 salary 平均值

Another example

SELECT AVG(salary) FROM employee WHERE title = Programmer

傳回 salary 平均值條件為 employees 資料表中當 title 等於 Programmer

Example

SELECT Count() FROM employees

傳回 employees 資料表中紀錄總筆數

GROUP BY 語法 SELECT column1 SUM(column2) FROM list-of-tables GROUP BY column-list The GROUP BY 語句可以先以所列的欄位為條件分組排序在一起(可以多欄

位) example 要列出每一個 dept 中最高 salary 值 SELECT max(salary) dept FROM employee GROUP BY dept HAVING 語法

SELECT column1 SUM(column2) FROM list-of-tables GROUP BY column-list HAVING condition

HAVING 子句是 GROUP BY 的一部份用來過濾在 GROUP BY 所選出的資料功能如同 select 命令中 where 條件式一樣只是 HAVING 必需配合 GROUP BY 使用

我們以例子來說明我們要取得每一公司名及每一公司的薪水平均值輸入如下

84

SELECT dept avg(salary) FROM employee GROUP BY dept

但如果我們只列出薪資平均值超過 20000元的公司資料

SELECT dept avg(salary) FROM employee GROUP BY dept HAVING avg(salary) gt 20000

ORDER BY子句語法

SELECT column1 SUM(column2) FROM list-of-tables ORDER BY column-list [ASC | DESC]

[ ] =選項

ORDER BY是一個選項子句當你以排序方式來顯示資料(正向由小到大反向由大到小)以指定的欄位資料做排序

ASC = 正向- 預設值 DESC = 反向排序

For example

SELECT employee_id dept name age salary FROM employee_info WHERE dept = Sales ORDER BY salary

以上列出公司代號公司名銷售員人名年紀及薪資而條件是公司名為 Sales 顯示順序以薪資多少排序(由小到大為預設值)

如果要以多個欄位做排序要以逗號做分隔如下

SELECT employee_id dept name age salary FROM employee_info WHERE dept = Sales ORDER BY salary age DESC

85

結合條件及布林運算 SELECT column1 SUM(column2) FROM list-of-tables WHERE condition1 AND condition2 AND運算可以結兩個或以上的條件放在 WHERE子句中 兩者都要為真才

會顯示該筆記錄 OR 運算可以結兩個或以上敘述放在 WHERE子句中只要其中一個為直就

會顯示該筆記錄 For example SELECT employeeid firstname lastname title salary FROM employee_info WHERE salary gt= 5000000 AND title = Programmer 必需要薪資大於等於 50000而且職稱為 Programmer同時符合才會顯示該筆資料 以下以括號括住雖然不是必需的但如此比較容易讀 SELECT employeeid firstname lastname title salary FROM employee_info WHERE (salary gt= 5000000) AND (title = Programmer) 另外範例 SELECT firstname lastname title salary FROM employee_info WHERE (title = Sales) OR (title = Programmer) 條件為只要是 Sales 或 Programmer 職稱的就會被列出 IN and BETWEEN 子句

SELECT column1 SUM(column2) FROM list-of-tables WHERE column3 IN (list-of-values) SELECT column1 SUM(column2) FROM list-of-tables WHERE column3 BETWEEN value1 AND value2 IN 子句使用在列舉項目的使用上也就是分別測試是否符合所列的值 For example

86

SELECT employeeid lastname salary FROM employee_info WHERE lastname IN (Hernandez Jones Roberts Ruiz) 條件為姓氏(astname)要符合 Hernandez Jones Roberts or Ruiz 其中一個才會被傳回 IN運算元也可以使用 OR 的語法來取代如下結果相同 SELECT employeeid lastname salary FROM employee_info WHERE lastname = Hernandez OR lastname = Jones OR lastname = Roberts OR lastname = Ruiz 但使用 IN 句子比較短也比較易懂 你也可以使用 NOT IN 來去掉不要的記錄 BETWEEN 運算元使用在判斷是否存在兩個數值之間 For example SELECT employeeid age lastname salary FROM employee_info WHERE age BETWEEN 30 AND 40 傳回年紀 30歲到 40歲之間的資料(含 30及 40歲者) 相同的也可以使用以下語法來達到相同的結果 SELECT employeeid age lastname salary FROM employee_info WHERE age gt= 30 AND age lt= 40 你也可使用 NOT BETWEEN 來濾掉中間值的資料 數學運算 標準 ANSI SQL-92 提供以下運算

87

+ 加

- 減

餘數

餘數為除法後剩整數這不在標準的 ANSI SQL 中但大部份的資料庫都會支

援這運算元以下列出有用的函數雖不在 ANSI SQL-92 提供但一般資料庫

也會支援他們

ABS(x) 傳回 x 絕對值

SIGN(x) returns the sign of input x as -1 0 or 1 (negative zero or positive respectively)

MOD(xy) 餘數 - returns the integer remainder of x divided by y (同 xy)

FLOOR(x) 傳回小或等於 x 的最大整數值

CEILING(x) or CEIL(x)

傳回大或等於 x 的最小整數值

POWER(xy) x的 y 次方

ROUND(x) 把 x 四捨五入為整數

ROUND(xd) 四捨五入取到小數 d 位

SQRT(x) x 開平方

For example SELECT round(salary) firstname FROM employee_info 傳回薪資取到整數位

如何新增資料

insert 加入一筆新紀錄到資料表中 insert into tablename (first_columnlast_column) values (first_valuelast_value) [] = optional Example insert into employee

88

(first last age address city state) values (Luke Duke 45 2130 Boars Nest Hazard Co Georgia) Note 字串要以單引號住如string 數字框住也無妨 insert into 後面接資料表名稱再接以括號括住的欄位名在 values 後括號分別對映各欄位的值 以上的例子新增了一筆名(first) 為 Luke而住所(state) 為 Georgia 的資料

如何刪除資料

delete 可以刪除單筆或多筆紀錄 delete from tablename where columnname OPERATOR value [and|or column OPERATOR value] [ ] = optional Examples delete from employee Note 如果你沒有指定 where 子句那麼全部的紀錄都會被刪除 delete from employee where lastname = May delete from employee where firstname = Mike or firstname = Eric delete from 接著資料表名 再接著是條件式判斷沒有條件式則全部紀錄會

被刪除

如何更新資料

update 用來更新你所指定的記錄要和 WHERE 配合小心使用 語法 update tablename set columnname = newvalue[nextcolumn = newvalue2] where columnname OPERATOR value [and|or column OPERATOR value] [] = optional Examples

89

update phone_book set area_code = 623 where prefix = 979 update phone_book set last_name = Smith prefix=555 suffix=9292 where last_name = Jones update employee set age = age+1 where first_name=Mary and last_name=Williams

90

附錄二Replication

測試環境

RedHat 90 + MySQL 32358 MySQL資料庫路徑 varlibmysql MySQL設定檔 etcmycnf Master IP 1921680100 Slave IP 1921680200 請至下列網址下載最新MySQL 32358套件並利用rpm ndashUvh 更新 httpupdatesredhatcom9enosi386

圖 最新 MySQL 套件

測試架構圖

91

1921680100

1921680200Master Server

erveSlave S r

圖 測試架構圖

測試步驟

Master server 部份 Step1 確認 MasterSlave機器上所裝的 MySQL版本能進行

replication( 32329 or higher ) Step2 在 Master MySQL上開放一個帳號給 Slave mysql ndashu root ndashp mysqlgtGRANT FILE ON TO repl1921680200 IDENTIFIED BY lsquoabc123rsquo mysqlgtq 上面是 Master開放一個帳號 repl密碼 abc123給 IP1921680200有檔案處理

的權限 Step3 shutdown MySQL on the Master mysqladmin ndashu root ndashp shutdown Step4 備份 Master所有資料庫 tar ndashcvf tmpmysql-snapshottar varlibmysql 注意tar的時候MySQL是要在 stop情況下 在mysql (wwwmysqlcom) 網站的FAQ有不用shutdown的方法

92

Step5 在 master機器上修改etcmycnf 在[mysqld]區段內加入參數 log-bin server-id=這邊設定 server-id=1 sql-bin-update-same binlog-do-db=CRM只針對 CRM資料庫做紀錄 Step6 Restart MySQL on the master service mysqld start 此時因為有加入 log-bin 參數因此開始有 index產生了在varlibmysql目錄下

有index檔案紀錄資料庫的異動 log Slave server 部份 Step1 在 slave設定etcmycnf 在[mysqld]區段加入 master-host= master-user= master-password= master-port= server-id= 這邊設定 master-host=1921680100 master-user=repl master-password=abc123 master-port=3306 server-id=2 master-connect-retry=60預設重試間隔 60秒 replicate-do-db=CRM告訴 slave只做 CRM資料庫的更新 log-slave-updates Step2 將 master上的 mysql-snapshottar copy到 slave上 用 ftp傳到 slave的tmp Step3 解壓縮 Master資料庫至 Slave Server上 cd varlib tar xvf tmpmysql-snapshottar chown ndashR mysqlmysql mysql

93

chmod ndashR 770 mysql (視情況) Step4 Restart MySQL on the slave server 這時在varlibmysql目錄會出現 masterinfo此檔案紀錄了 Master MySQL server的資訊

狀況測試

One-way replication

1921680100

1921680200Master Server

erveSlave S r

圖 One-way replication架構圖 Step1 Master跟 Slave網路及服務都正常情況下由 Master端異動資料後 到 Slave端瀏覽資料檢視是否有進行 replication Step2 模擬 Slave Server 當機 可用在於 slave真的當機或是 Slave 不一定需要一直跟 master connect將Slave MySQL server shutdown由 Master端異動資料到 slave端瀏覽此時Slave應該沒有被 replication 更新然後再將 Slave端 MySQL server start起來

預設 60秒後 Slave會嘗試跟 Master要求進行 replication再去 Slave端檢視是否有更新資料

94

Step3 模擬 Master當機因為是設定 One-way replication一旦 Master Server Slave端沒有 Master的 source可以 download Two-way replication 基於 Master當機狀況於是發展雙向 Replication即 1921680100 ( Host A ) 1921680200 ( Host B )都分別擔任 MasterSlave身分

1921680100

1921680200er

Server B MasterSlave Server

Server A MasterSlave Serv

圖 Two-way replication架構圖 以下是針對兩台 MySQL伺服器進行雙向 Replication Step1觀念同單向 replication只是改成 Master也有 Slave身分 Slave也有Master的身分先分別在 Server AServer B 都去 grant一個進行 replication的身分 [A]mysqlgtGRANT FILE ON TO repl1921680200 IDENTIFIED BY lsquoabc123rsquo [B]mysqlgt GRANT FILE ON TO repl1921680100 IDENTIFIED BY lsquoabc123rsquo Step2做完單向 replication後stop Server Aserver B MySQL service此時 AB資料是一樣的

95

修改etcmycnf設定 範例 Server A [mysqld] datadir=varlibmysql socket=varlibmysqlmysqlsock server-id=1 log-bin sql-bin-update-same binlog-do-db=CRM master-host=1921680200 master-user=repl master-password=abc123 log-slave-updates master-connect-retry=60 replicate-do-db=CRM Server B [mysqld] datadir=varlibmysql socket=varlibmysqlmysqlsock server-id=2 log-bin sql-bin-update-same binlog-do-db=CRM master-host=1921680100 master-user=repl master-password=abc123 log-slave-updates master-connect-retry=60 replicate-do-db=CRM 分別 start Server AServer B MySQL後此時雙方都是 MasterSlave身分一旦哪一方資料異動就會通知對方來 replication-若 replication失效則必須將Server AServer B的masterinfo及index00x 都砍掉然後分別 restart MySQL server進行測試檢視成果 實務上通常如果需要做Two-way replication通常會搭配Virtual Server使用

96

在前端架設一台Virtual Server不過此部份不在此份SOP討論範圍內有興趣

的讀者可參考 httpwwwlinuxvirtualserverorg 網站

1921680100 1921680200

Host A MasterSlave Server

Host B MasterSlave Server

Virtual Host

圖 Virtual Server + Two-way replication 架構圖

97

圖 High Availability Linux Virtual Server架構圖

98

  • COSA-SOP-03-006
  • 第一章 簡介
    • 11適用對象 (Audience)
    • 12 MySQL本身
    • 13 MySQL 40版跟50版重大的改進功能
    • 14 各家資料庫軟體比較
      • 第二章 前置需求
      • 第三章 安裝
        • 31 MySQL安裝
        • 32 phpMyAdmin安裝
        • 33 升級及注意事項
          • 第四章 MySQL管理
            • 41 Webmin 管理介面
            • 42 phpMyAdmin 的操作介面
            • 43管理指令介紹
              • 431 利用mysqladmin設定root的密碼
                  • 第五章 實用範例
                    • 51 任務一Web Base客戶通訊錄
                    • 52 任務二Web Base群組軟體 ( twig )
                      • 第六章 維護及更新程序
                        • 61 日常維護
                        • 62 更新程序
                        • 63 備份重要檔案
                        • 64 離線備份與還原
                        • 65 線上備份與還原
                          • 第七章 問題與解答
                          • 第八章 參考資料
                          • 附錄一 SQL Command 介紹
                          • 附錄二Replication
Page 23: DataBase Server Standard Operation Procedureebooks.lib.ntu.edu.tw/1_file/oss/63/93doc4-5.pdf · 業務的公司帶來了不少壓力,譬如微軟,甲骨文 ... 外的錢用在第三方的資料庫產品上,譬如就可以不用再購買甲骨文公司

圖 3-19 設定語系

圖 3-20 執行 phpMyAdmin

23

33 升級及注意事項

RedHat 90附的 MySQL版本為 323 MySQL所釋出最新穩定版本為

40若是您不想用系統預附的 323請先利用下列移除之前 323的版本

rpm ndashe mysql-devel rpm ndashe mysql-server rpm ndashe mysql --nodeps 然後到下列網址下載您所想要的版本進行安裝在這裏我們用 4014版為例 Step 1 下載相關套件( httpwwwmysqlcomdownloadsmysql-40html )

圖 3-21 Download MySQL 4014 相關 RPM Step 2 利用 rpm 指令安裝

24

圖 3-22 Install MySQL 4014 相關 RPM

圖 3-23 Install MySQL 4014 相關 RPM

Step 3 啟動 MySQL

25

圖 3-24 啟動 MySQL 4014 並修改密碼

26

第四章 MySQL管理

本章將我們介紹利用WebminphpAdminCommand的方式建立一個名為

CONTACT的資料庫內有一個 address的 Table作為我們客戶通訊錄程式使

用的資料庫

41 Webmin 管理介面

412建立資料庫

Step 1 登入Webmin

圖 4-1 登入WebMin

Step 2 點選伺服器

27

圖 4-2 伺服器畫面

Step 3 點選 MySQL資料庫伺服器

圖 4-3 MySQL資料庫伺服器

28

Step 4 建立一個新的資料庫

圖 4-4 建立 MySQL資料庫

Step 5 建立名為 CONTACT的資料庫

29

圖 4-5 指定資料庫名稱

412 建立資料表

假設我們要建立一個名為 address的 Table其結構如下 欄位名稱 資料型態 長度 說明 id INT (自動編號) 連絡人編號 name varchar文字 20 連絡人姓名 tel Varchar文字 15 連絡人電話 Step 1 選擇 CONTACT資料庫

30

圖 4-6 選擇資料庫

Step 2 指定欄位數目

31

圖 4-7 設定欄位數目

Step 3設定表格欄位屬性

圖 3-8 設定表格欄位屬性

Step 4建立表格資料

32

圖 4-9 建立表格資料

圖 4-10 檢視資料

33

圖 4-11 新增資料

圖 4-12

34

圖 4-13

413 使用者管理

接下來我們要利用Webmin 來建立資料庫使用者並給予某些權限 Step1建立使用者

35

圖 4-14 選擇使用者權限

圖 4-15

36

Step2 賦予權限

圖 4-16

Step3 權限列表

37

圖 4-17

38

42 phpMyAdmin 的操作介面

421建立資料庫

Step 填入資料庫名稱並按「建立」

圖 4-18建立資料庫

422 建立資料表

Step1 填入資料表名稱並指定欄位數量 執行

39

圖 4-19填入資料表名稱並指定欄位數量

Step2 設定欄位屬性

圖 4-20設定欄位屬性

40

Step3 phpMyAdmin會產生相關的 SQL Command

圖 4-21 資料表結構及相關 SQL Command

Step4新增 Record

41

圖 4-22

圖 4-23

42

圖 4-24

圖 4-25

43

423使用者管理

Step1建立使用者

圖 4-26

44

圖 4-27

Step2 給予權限

圖 4-28

Step3權限列表

45

圖 4-29

43管理指令介紹

431 利用 mysqladmin設定 root的密碼

當您在Windows 或 Linux 中安裝好 MySQL後系統會自動幫您建立兩個

帳分別是 root 和 匿名者MySQL的 root 跟 Linux 最高權限使用者 root無關MySQL的 root使用者相當於 MS SQL 中的 sa 帳號擁有最高的 Database管理權限但系統預設 MySQL的 root 是不需要密碼所以通常我們一安裝

MySQL後首要任務便是修改 root的密碼 我們可以利用 mysqladmin工具或是直接修改 MySQL內部資料庫的使用者資

料 mysqladmin ndashu root ndashh cosaexamplecom password lsquo1234rsquo

46

-u 表示使用者帳號root 為 MySQL預設的管理帳號

-h 表示 MySQL主機的主機名稱也可使用 IP Address password 表示使用者的密碼因為字串請使用單引號將密碼括起來 密碼設定完成之後還是可以利用 mysqladmin修改密碼但是你必須提供目前的密碼

432 連線 MySQL

mysql -uroot -p密碼 (-p和密碼之間不能有空白) 或 mysql -uroot -p (此方式會在進入後要求密碼) [rootossc phpMyAdmin] mysql -u root -p1234

Welcome to the MySQL monitor Commands end with or g

Your MySQL connection id is 25 to server version 32354

Type help or h for help Type c to clear the buffer

mysqlgt show databases

+----------+

| Database |

+----------+

| mysql |

| test |

+----------+

2 rows in set (000 sec)

mysqlgt exit

Bye

[rootossc phpMyAdmin]

433 建立資料庫

可利用 mysqladmin指令建立 CONTACT資料庫 mysqladmin -u root -p1234 create CONTACT

47

或是利用 mysql指令 [rootossc bluepage] mysql -u root -p1234 Welcome to the MySQL monitor Commands end with or g Your MySQL connection id is 1057 to server version 32354 Type help or h for help Type c to clear the buffer mysqlgt create database CONTACT Query OK 1 row affected (000 sec) mysqlgt show databases +----------+ | Database | +----------+ | CONTACT | | address | | hello | | mysql | | nuke | | test | +----------+ 6 rows in set (000 sec) mysqlgt exit

434 建立資料表

編寫 adresssql內容如下 -- Table structure for table address CREATE TABLE address ( id int(11) NOT NULL auto_increment name varchar(20) NOT NULL default tel varchar(15) NOT NULL default PRIMARY KEY (id) ) TYPE=MyISAM

48

-- Dumping data for table address INSERT INTO address VALUES (1林小明0800016888) INSERT INTO address VALUES (2黃大雄0800016888) INSERT INTO address VALUES (3劉小芬0800024365) 然後執行此 sql script mysql -u root -p1234 CONTACT lt addresssql 或是利 mysql command [rootossc bluepage] mysql -u root -p1234 Welcome to the MySQL monitor Commands end with or g Your MySQL connection id is 1090 to server version 32354 Type help or h for help Type c to clear the buffer mysqlgt use CONTACT Database changed Database changed mysqlgt CREATE TABLE address ( -gt id int(11) NOT NULL auto_increment -gt name varchar(20) NOT NULL default -gt tel varchar(15) NOT NULL default -gt PRIMARY KEY (id) -gt ) TYPE=MyISAM Query OK 0 rows affected (000 sec) mysqlgt INSERT INTO address VALUES (1林小明0800016888) Query OK 1 row affected (000 sec) mysqlgt INSERT INTO address VALUES (2黃大雄0800016888) Query OK 1 row affected (000 sec) mysqlgt INSERT INTO address VALUES (3劉小芬0800024365) Query OK 1 row affected (000 sec) mysqlgt exit Bye

49

第五章 實用範例

51 任務一Web Base客戶通訊錄

任職於開放科技公司的林小明前些日子在最符合成本效益的條件下快

速地完成公司網站的建置老闆因此對小明讚譽有加最近因為公司存放客戶資

料的 SQL Server主機屢遭病毒攻擊加上作業系統本身的問題當機次數頻繁

老闆希望能儘快把公司的客戶通訊錄程式移轉到較穩定的環境上因為此客戶通

訊錄程式最主要給內部人員使用所以介面美觀並不特別要求只求穩定且能快

速得到查詢結果老闆希望在短時間先看到程式的雛型並鍵入資料對其效率

及穩定性進行測試因為上次小明表現突出所以這次不可能的任務自然又落到

小明身上 小明想來想去既然要快速又穩定他而且又不希望所有人都得安裝 Client

程式於是小明決定)捨棄他的舊愛「Delphi+MS SQL」投向新歡「Apache + MySQL + PHP」利用此架構來設計一個簡單實用的Web Base客戶通訊錄程式

511 Web Base客戶通訊錄架構

此程式需要建立 CONTACT的資料庫並建立 adress Tables其結構如下表建立步驟請參考第三章 欄位名稱 資料型態 長度 說明 id INT (自動編號) 連絡人編號 name varchar文字 20 連絡人姓名 tel Varchar文字 15 連絡人電話 Web Base通訊錄共有下列幾個檔案功能如下表

檔案名稱 說明 Indexhtml Web Base通訊錄首頁 addphp 新增連絡人的 php程式 searchphp 尋找連絡人的 php程式 editphp 具有更新及刪除功能的 php程式

50

我們將這些檔案放至varwwwhtmlbluepage (預設無 bluepage目錄)

512 Web Base通訊錄測試

httpwwwopencombluepage 新增資料

圖 5-1 新增連絡人

圖 5-2 填入資料

51

圖 5-3 新增成功

搜尋及異動資料

圖 5-4 搜尋通訊錄

52

圖 5-5 編輯資料

圖 5-6 更新資料

513 程式內容及說明

lt-- 程式範例indexhtml--gt lthtmlgt ltheadgtlttitlegt通訊錄lttitlegtltheadgt ltbodygt ltcentergt

53

lth2gt通訊錄lth2gtlthrgt lta href=indexhtmlgt通訊錄ltagt | lta href=addphpgt新增連絡人ltagt | lta href=searchphpgt搜尋通訊錄ltagt ltcentergt ltbodygt lthtmlgt lt-- 程式範例addphp --gt lthtmlgt ltheadgtlttitlegt新增連絡人lttitlegtltheadgt ltbodygt ltcentergtlth2gt新增連絡人lth2gtltcentergtlthrgt lt 取得欄位資料 if (isset($_POST[Name]) ampamp isset($_POST[Tel]) ) $name = $_POST[Name] $tel = $_POST[Tel] 檢查是否有輸入欄位資料 if ($name = ampamp $tel = ) 建立 SQL字串 $sql = INSERT INTO address (name tel) values( $sql= $name $tel) 建立 MySQL 連結 $link = mysql_connect(localhostroot1234) 選擇資料庫 mysql_select_db(CONTACT) 執行 SQL指令 mysql_query($sql) mysql_close($link) echo ltfont color=redgt新增連絡人成功ltfontgtltbrgt gt ltform action=addphp method=postgt lttable border=0 width=300gt lttrgtlttdgt姓名 lttdgt

54

lttdgtltinput type=text name=Name size=20 maxlength=10gtlttdgtlttrgt lttrgtlttdgt電話 lttdgt lttdgtltinput type=text name=Tel size=20 maxlength=20gtlttdgtlttrgt lttrgtlttd colspan=2 align=centergt ltinput type=submit value=新增連絡人gtlttdgtlttrgt lttablegt ltformgt ltbrgtlta href=indexhtmlgt通訊錄ltagt | lta href=addphpgt新增連絡人ltagt | lta href=searchphpgt搜尋通訊錄ltagt ltbodygt lthtmlgt

lt-- 程式範例searchphp --gt lthtmlgt ltheadgtlttitlegt搜尋通訊錄lttitlegtltheadgt ltbodygt ltcentergtlth2gt搜尋通訊錄lth2gtlthrgt lt if (isset($_POST[Search])) 建立資料庫連結並選定資料庫 $link = mysql_connect(localhostroot1234) mysql_select_db(CONTACT) 建立基本的 SQL字串 $sql = SELECT FROM address 檢查是否輸入姓名 if (chop($_POST[Name]) = ) $name = name LIKE $_POST[Name] else $name = 檢查是否輸入電話號碼 if (chop($_POST[Tel]) = ) $tel = tel LIKE $_POST[Tel] else $tel =

55

if條件組合 SQL字串 if (chop($name) = ampamp chop($tel) = ) $sql= WHERE $name AND $tel elseif (chop($name) = ) 只有姓名 $sql = WHERE $name elseif (chop($tel) = ) 只有電話號碼 $sql = WHERE $tel $sql= ORDER BY name 最後加上排序 $result = mysql_query($sql) 取得欄位數 $total_fields = mysql_num_fields($result) echo lttable border=1gt echo lttrgtlttdgt編號lttdgtlttdgt姓名lttdgtlttdgt電話lttdgtlttd colspan=2gt功能選項lttdgtlttrgt 表格顯示查詢結果 while ($rows = mysql_fetch_array($result MYSQL_NUM)) echo lttrgt for ($i = 0 $i lt $total_fields $i++) echo lttdgt$rows[$i]lttdgt echo lttdgtlta href=editphpaction=editampid= echo $rows[0]gtltbgt編輯ltbgtlttdgt echo lttdgtlta href=editphpaction=delampid= echo $rows[0]gtltbgt刪除ltbgtlttdgt echo lttrgt echo lttablegtlthrgt mysql_free_result($result) mysql_close($link) gt ltcentergt ltform action=searchphp method=postgt lttable border=0 width=450gt lttrgtlttdgt搜尋姓名 lttdgt lttdgtltinput type=text name=Name size=10 maxlength=20gtlttdgtlttrgt lttrgtlttdgt搜尋電話 lttdgt lttdgtltinput type=text name=Tel

56

size=20 maxlength=20gtlttdgtlttrgt lttrgtlttd colspan=2 align=centergt ltinput type=submit name=Search value=搜尋gtlttdgtlttrgt lttablegt ltformgt ltbrgtlta href=indexhtmlgt通訊錄ltagt | lta href=addphpgt新增連絡人ltagt | lta href=searchphpgt搜尋通訊錄ltagt ltbodygt lthtmlgt

lt ob_start() gt lt-- 程式範例editphp --gt lthtmlgt ltheadgtlttitlegt編輯通訊錄lttitlegtltheadgt ltbodygt lt 取得 URL 參數 $id = $_GET[id] $action = $_GET[action] 建立資料庫連結 $link = mysql_connect(localhostroot1234) mysql_select_db(CONTACT) 選擇資料庫 執行的操作 switch ($action) case update 更新 取得欄位資料 $name = $_POST[Name] $tel = $_POST[Tel] $sql = UPDATE address SET name=$name tel=$tel WHERE id=$id mysql_query($sql) 執行 SQL指令 mysql_close($link) header(Location searchphp) 轉向到 serachphp break case del 刪除 $sql = DELETE FROM address WHERE id=$id

57

mysql_query($sql) 執行 SQL指令 mysql_close($link) header(Location searchphp) 轉向到 serachphp break case edit 編輯 $sql = SELECT FROM address WHERE id=$id $result = mysql_query($sql) 執行 SQL指令 $row = mysql_fetch_row($result) 取回記錄 $name = $row[1] 取得欄位 name $tel = $row[2] 取得欄位 tel mysql_close($link) 顯示編輯表單 gt ltcentergtlth2gt更新通訊錄lth2gtltcentergtlthrgt ltform action=editphpaction=updateampid=lt echo $id gt method=postgt lttable border=0 width=300gt lttrgtlttdgt姓名 lttdgt lttdgtltinput type=text name=Name size=20 maxlength=10 value=lt echo $name gtgtlttdgtlttrgt lttrgtlttdgt電話 lttdgt lttdgtltinput type=text name=Tel size=20 maxlength=20 value=lt echo $tel gtgtlttdgtlttrgt lttrgtlttd colspan=2 align=centergt ltinput type=submit value=更新連絡人gtlttdgtlttrgt lttablegt ltformgt ltbrgtlta href=indexhtmlgt通訊錄ltagt | lta href=addphpgt新增連絡人ltagt | lta href=searchphpgt搜尋通訊錄ltagt lt break gt ltbodygt lthtmlgt

58

52 任務二Web Base群組軟體 ( twig )

順利完成Web Base客戶通訊錄程式測試一段時間後「Apache + MySQL + PHP」架構的穩定與快速巳深得老闆與公司所有同事的認同隨著公司業績蒸

蒸日上人員組織編罝愈來愈龐大跨部門的會議愈來愈多業務員每日排滿拜

訪客戶的行程跟客戶的 Email的往來也愈來愈頻繁 愈來愈多部門的同事希望公司能建置一套群組軟體提供 web mail可讓業

務人員方便收發 mail還有連絡人議事日程待辦工作書簽等功能讓整個

公司運作及個人時間管理更有效率

老闆問小明對這些需求有什麼看法小明認為如果這些功能完全由程式部

門開發必定曠日費時而且耗費公司資源小明在網路尋找是否有提供這些功能

的Free Software皇天不負苦心人小明發現了TWIG (The Web Information Gateway) httptwigscrewdrivernet這個群組軟體它在 Web 上整合郵件新聞聯絡人議事日程工作序書簽等功能非常符合公司的需求 Step 1 下載 twig-277targz 下載網址 httptwigscrewdrivernetdownloadphp3

Step 2 解開 twig-277targz tar -xzvf twig-277targz

59

Step 3 執行安裝動作安裝到 varwwwhtmltwig 目錄 cd twig-277 twig-install varwwwhtmltwig

Step 4 建立 MySQL 資料庫(twig)及各資料表

cd setup mysql -u root -p1234 mysqlgt create database twig Query OK 1 row affected (001 sec) mysqlgt quit mysql -u root ndashp1234 twiglt twigtablemysql

Step 5 修改 configincphp3 參數設定 vi varwwwhtmltwigconfigconfigincphp3 $config[fromdomain] = opencom 網域 $config[language] = chinesebig5 中文訊息 $config[imap_port] = 143notls

60

Step 6 修改連結 MySQL 的帳號密碼 vi varwwwhtmltwigconfigdbconfigincphp3 $dbconfig[sqlusername] = root username $dbconfig[sqlpassword] = 1234 password

Step 7 其他設定檔

vi etchttpdconfhttpdconf 加入 AddType applicationx-httpd-php php3 在 DirectoryIndex最後加入 indexphp3 DirectoryIndex indexhtml indexhtmlvar indexphp3 在 AddDefaultCharset ISO-8859-1加上 AddDefaultCharset ISO-8859-1

vi etcphpini register_globals = On service httpd restart Step 8 sendmail 設定 vi etcmailsendmailcf在 264 行前面加上並重新啟動 sendmail「service snedmail restart」 262 SMTP daemon options 263 264 O DaemonPortOptions=Port=smtpAddr=127001 Name=MTA 265 266 SMTP client options 267 O ClientPortOptions=Family=inet Address=00

61

Step 9 檢查設定有無錯誤 http主機名稱twigtestphp3

62

Step 10 登入 twig ( http主機名稱twig)

63

第六章 維護及更新程序

61 日常維護

系統管理員最好定期以 root 身份登入看看信件在 RedHat Linux 中有一支 logwatch 程式會定時去分析 log file如果發現異常便會發信給 root除此之外筆者建議讀者平時就檢查 MySQL log file ( varlogmysqldlog)是否有異常情形

62 更新程序

讀者可至httprpmfindnet 尋找MySQL相關套件至於升級的相關步驟請參

考Linux OS SOP 第 54節

63 備份重要檔案

預設 MySQL 的 DB 檔案是存在 varlibmysql 內以 DB名稱為目錄目錄

內就是該 DB 的所有資料通常得定期備份還有 MySQL的設定檔 etcmycnf也別忘了一起備份

64 離線備份與還原

641 離線備份

預設 MySQL 的 DB 檔案是存在 varlibmysql 內以 DB 名稱為目錄目錄內

就是該 DB 的所有資料像 CRM 這個 DB就是存在 varlibmysqlCRM 內在備份前因為怕資料尚未完全寫入磁碟而且 MySQL 會 Lock 在使用的 DB 檔案所以應該是要先把 MySQL 先 Shutdown 一下整個備份的程序可以下像下面的指令去完成 cd varlibmysql

64

service mysqld stop tar cvfz CRM_db_20030905tgz CRM service mysqld start 對這樣就可以了 不過要注意的是怕 DB 內每個 Tables 間的資料有關關

聯性所以最好是把整個 DB 一次備起來單獨只備哪個 Tables 的檔案以後回存時怕會有資料關聯不一致的問題

642 離線還原

DB 發生錯誤而要回存時其實也不難先找出最近一次完整正常的備份先把現在錯誤的網頁或 DB 先更名或 tar 起來再把好的備份給解開回原來目錄位

置就行了需要注意的是 MySQL 服務最好也是要先停止回存完成後再啟動服務回存 DB 的整個程序可能像下面 cd varlibmysql service mysqldstop mv CRM CRM_OLD tar xvfz CRM_db_20030905tg service mysqld start

65 線上備份與還原

651 線上備份

使用像上面的檔案方式備份是個不錯的方法它最少可以保持該主機某個時間點的完整檔案備份但還是有一些問題需要考慮到有些主機就不只建立一個 DB 而已總不能為了備份某個 DB 而把整個 MySQL 服務停止備份檔案的方式回存在原主機上一定適用但假如 MySQL 版本升級或是在那天該網頁空間需遷機移機到別的主機時那就沒人敢保證備出來的資料檔可以用所以我們可以考慮另一種備份的方式是使用 MySQL 本身提供的功能 MySQL Data Dump指令是 mysqldump

65

使用 MySQL 的 Dump 功能可以把 DB 的結構資料或結構加資料 Dump 成文字檔 mysqldump 指令提供的彈性很大你可以選擇把整個 DB Dump 成一個檔或是每個 Table 為一個檔甚至是把結構檔和資料分開儲存都

可以 mysqladmin -uroot -p flush-logs mysqldump CRM -uroot -p --opt gt CRM_20030905sql (CRM 是 DB 名稱 opt 是一個使用完整 Dump 參數) 假如只是要單獨 Dump 某個 Table 時只要在上面的指令後轉出符號 gt 前加個 Table 名稱就可以如只要 phpbb2_users 這個 Table 的 Dump 時只要下 mysqldump CRM -uroot -p --opt CUSTOMER gt CRM_CUSTOMER_20030905sql

652 線上還原

若要回存整個資料庫只需將壓縮的備份檔還原成 Dump 的檔案再用下面的指令回存 mysql CRM -uroot -p lt CRM_20030905sql 這邊需注意的是若建立備份時是以--opt或--add-drop-table為參數時回存的 動作是先將舊的 Table 先刪除重建 Table 的結構後再把 Data 匯入所以回存後所有的資料會回到你當時備份那個時間點因此在回存資料時可以考慮把現有錯誤或不完整的 DB 先備份一份下來以備不時之需或是拿來比對錯誤的地

方在那裡當然你也可以把資料回存到另一個測試用的 DB 內只要把上面指令

的 DB 名稱改成你的測試用 DB 名稱即可 使用這種回存方式 MySQL 服務不需停止也不會動到其他正在使用的 DB 在一些提供 MySQL 服務的虛擬主機可用這種方式作你自己的 DB 備份及回存

66

另外假如你是系統重建或是移機時切需在新的 MySQL 內新建一個空白 DB 後才行作回存的工作你可以用下面的指令建立 mysql -uroot -p -e CREATE DATABASE CRM (上面的 CRM是你要新建的 DB 名稱) 另一種作法先用 mysql 指令進入 mysql client console 然後再用 CREATE DATABASE CRM 這樣就行了記得尾端要加個 符號該行指令才會執行

67

第七章 問題與解答

Q1RedHat 90預附的 MySQL到底有無支援 Transcation機制 Ans MySQL自 32334a之後的 MySQL-Max版本加入 InnoDB的資料庫類型透過

InnoDBMySQL同樣可以進行 COMMIT與 ROLLRACK的動作RedHat 90預附的 MySQL為 32354a-11巳支援 InnoDB的資料庫類型不過必須做以

下設定 1cp usrsharedocmysql-server-32354amy-mediumcnf to etcmycnf 2 vi etcmycnf 將以下設定前的拿掉 innodb_data_home_dir = varlibmysql innodb_data_file_path = ibdata110Mautoextend innodb_log_group_home_dir = varlibmysql innodb_log_arch_dir = varlibmysql 3service mysqld restart 如此一來各位在建立Table時便可指定Table Type為 innodb ( ex create table with type=innodb ) Q2如何解決 php+mysql 許功蓋等字變亂的問題 Ans 方法一 【確定 MySQL 預設的字元集】 1 打開 WinMySQLadmin 管理畫面(在視窗右下角狀態列紅綠燈圖示中按滑鼠

右鍵點選 Show me 選項) 2 點選管理畫面中 [Variables] 標籤選項其中 character_set變數就是您預設

字元集的變數其預設是 latin1 字元集(我們要將他改回 big5)而 chatacters_set 變數則是 MySQL 可以支援哪些字元集 【修改預設字元集變數 character_set 】 1 請點選管理畫面中 [myini Setup] 標籤選項設定 myini 2 按一下 [Pick-up and Edit myini values] 按鈕以便編輯目前的 myini 設定 3 在 [mysqld] 設定區塊底下新增一行 default-character-set = big5 變數設

68

定 4 新增一個 [client] 設定區塊並加入第三步驟的變數設定(游標往下移到空白處新增兩行 [client] 和 default-character-set=big5) 5 按一下畫面左下方 [Save Modification] 按鈕儲存設定 6 重新啟動 MySQL 或 Windows 方法二 Server端注意事項 phpini 中有關的設定為(預設值) Magic quotes for incoming GETPOSTCookie data magic_quotes_gpc = On Use Sybase-style magic quotes (escape with instead of ) magic_quotes_sybase = Off Client端注意事項 1中文資料送進 mysql 前請用 addslashes($str) 處理 2處理後送進 mysql 時請用 括起來並在參數後留一個空白如 $sql = UPDATE ezf_table set tablename=$tname tableend=$endtime table inguser=$tguser tableingid=$tguserid tableallnumber=$tnumber tableloca l=$tablelocal tableanyone=$tableopen tabletext=$ttext WHERE tableid=$t ableid tablename=$tname c 取出時請用 stripslashes($str) Q3MySQL root 密碼忘了該怎麼辦 Ans 1先停掉 mysql etcrcdinitdmysql stop 2以--skip-grant-table 的參數啟動 mysql safe_mysql --skip-grant-tableamp 3 更改 root 密碼 mysql mysql mysqlgt UPDATE user SET password=password(newpassword)

69

WHERE user=root mysqlgt FLUSH PRIVILEGES mysqlgt exit 4停掉 mysql再重跑 mysqladmin -uroot -p shutdown Enter password 輸入新設定的密碼 etcrcdinitdmysql start

Q4NULL值問題

Ans

NULL值的概念是造成 SQL的新手的混淆的普遍原因他們經常認為 NULL是和一個空字符串的一樣的東西不是這樣的例如下列語句是完全不同的

mysqlgt INSERT INTO my_table (phone) VALUES (NULL)

mysqlgt INSERT INTO my_table (phone) VALUES ()

兩個語句把值插入到 phone 列但是第一個插入一個 NULL值而第二個插入一個空字符串第一個的含義可以認為是ldquo電話號碼不知道而第二個則可意味

著ldquo她沒有電話

在 SQL中NULL值在于任何其他值甚至 NULL值比較時總是假的(FALSE)包含 NULL的一個表達式總是產生一個 NULL值除非在包含在表達式中的運算符和函數的文檔中指出在下列例子所有的列返回 NULL

mysqlgt SELECT NULL1+NULLCONCAT(InvisibleNULL)

如果你想要尋找值是 NULL的列你不能使用=NULL測試下列語句不返回任

何行因為對任何表達式expr = NULL是假的

mysqlgt SELECT FROM my_table WHERE phone = NULL

要想尋找 NULL值你必須使用 IS NULL測試下例顯示如何找出 NULL電話號碼和空的電話號碼

70

mysqlgt SELECT FROM my_table WHERE phone IS NULL mysqlgt SELECT FROM my_table WHERE phone =

在 MySQL中就像很多其他的 SQL服務器一樣你不能索引可以有 NULL值的列你必須聲明這樣的列為 NOT NULL而且你不能插入 NULL到索引的

列中

當用 LOAD DATA INFILE 讀取數據時空列用更新如果你想要在一個列中有

NULL值你應該在文本文件中使用N字面上的詞NULL也可以在某些情形下使用

當使用 ORDER BY時首先呈現 NULL值如果你用 DESC以降序排序NULL值最後顯示當使用 GROUP BY時所有的 NULL值被認為是相等的

為了有助于NULL的處理你能使用 IS NULL和 IS NOT NULL運算符和 IFNULL()函數

對某些列類型NULL值被特殊地處理如果你將 NULL插入表的第一個TIMESTAMP 列則插入當前的日期和時間如果你將 NULL插入一個AUTO_INCREMENT 列則插入順序中的下一個數字

Q5如何將圖片存放於 MySQL中

Ans

Step 1建立資料庫 test

Step 2 建立表格 binary_data

CREATE TABLE binary_data (

id INT(4) NOT NULL AUTO_INCREMENT PRIMARY KEY

description CHAR(50)

bin_data LONGBLOB

filename CHAR(50)

filesize CHAR(50)

filetype CHAR(50)

71

)

Step 3 利用 storephp 寫入圖片

storephp 程式碼

ltHTMLgt ltHEADgtltTITLEgtStore binary data into SQL DatabaseltTITLEgtltHEADgt ltBODYgt lt code that will be executed if the form has been submitted

if ($submit) mysql_connect(localhostrootYOUR_PASSWORD) mysql_select_db(test) $data=Base64_Encode(fread(fopen($form_data r) filesize($form_data))) $result=MYSQL_QUERY(INSERT INTO binary_data (descriptionbin_datafilenamefilesizefiletype) VALUES ($form_description$data$form_data_name$form_data_size$form_data_type)) $id= mysql_insert_id() print ltpgtThis file has the following Database ID ltbgt$idltbgt MYSQL_CLOSE() else else show the form to submit new data

gt

ltform method=post action=ltphp echo $PHP_SELF gt enctype=multipartform-datagt File Descriptionltbrgt ltinput type=text name=form_description size=40gt ltINPUT TYPE=hidden name=MAX_FILE_SIZE value=4000000gt ltbrgtFile to uploadstore in databaseltbrgt ltinput type=file name=form_data size=40gt ltpgtltinput type=submit name=submit value=submitgt ltformgt lt

72

gt ltBODYgt ltHTMLgt

Step 3 利用 storephp 取出圖片

getdataphp 程式碼

lt Syntax getdataphp3id=ltidgt if($id) you may have to modify login information for your database server MYSQL_CONNECT(localhostrootYOUR_PASSWORD) mysql_select_db(test) $query = select bin_datafiletype from binary_data where id=$id $result = MYSQL_QUERY($query) $data = Base64_Decode(MYSQL_RESULT($result0bin_data)) $type = MYSQL_RESULT($result0filetype) Header( Content-type $type) echo $data gt

Q6MySQL裝好之後啟動時或是執行 mysqladmin會出現如下訊息 Cant connect to local MYSQL Server through Socket varlibmysqlmysqlsock或是

Cant connect to local MYSQL Server through Socket tmpmysqldsock

Ans 可能有下列幾個原因

1這個 mysqldsock 不見了被某人刪除了或是被一些系統自動執行程式給刪

了例如有些 cron任務便會設定定期刪除 tmp 裡的東西所以呢您只能修改

cron 裡的設定讓它不要清除 mysqldsock 2在啟動時也可以改變 mysqldsock的位置您在啟動 MySQL的時候可以加入此參數usrlocalmysqlbinsafe_mysqld --user=mysql --socket=其他路

徑socket amp 同時得去設定環境變數 MYSQL_UNIX_PORT的值以指定新的

73

路徑 3若是您沒改 MYSQL_UNIX_PORT的值那麼您可以在執行指令的時候才打

例如mysqladmin --socket=其他路徑socket version Q7How to get the last insert id Ans CREATE TABLE product ( id INT(4) NOT NULL AUTO_INCREMENT PRIMARY KEY description VARCHAR(50) ) 1利用 SQL的話 mysqlgt insert into product(description) values(123) Query OK 1 row affected (000 sec) mysqlgt select last_insert_id() +------------------+ | last_insert_id() | +------------------+ +------------------+ 1 row in set (000 sec) ======================================== 2如果是 PHP的話 你可以用mysql_insert_id()取得該 id PHP example $result=MYSQL_QUERY(INSERT INTO product (description) VALUES ($description)) $id= mysql_insert_id() print This file has the following Database ID $id Q8如何將文字檔匯入資料庫 Ans $addr=homehttpdhtmlphpschool001txt $sql_select = load data infile $addr into table test fields terminated by t 解說 $sql_select = load data infile 文字檔名 into table 表格名 fields terminated by

74

t

(欄位分隔以 TAB鍵) 該文字檔須與資料表欄位格式相符 例如欄位有三個 則文字檔為每行一筆資料如下 欄 1資料ltTABgt欄 2資料ltTABgt欄 3資料 欄 1資料ltTABgt欄 2資料ltTABgt欄 3資料 欄 1資料ltTABgt欄 2資料ltTABgt欄 3資料 欄 1資料ltTABgtltTABgt欄 3資料

Q9如何撰寫 MySQL C API Ans Step 1利用文字編輯器撰寫以下程式碼 mysqlcc

include ltstdiohgt

include ltmysqlmysqlhgt

int main (int argc char argv[])

MYSQL mysql

MYSQL_RES res

MYSQL_ROW row

if (argc = 2)

fputs (Usage myc ltdatabasegt stderr)

return 1

if ((mysql_connect(ampmysqllocalhostrootYour_Password)))

fputs (Error connecting stderr)

abort()

75

if (mysql_select_db(ampmysqlargv[1]))

fputs (Error selecting database stderr)

abort()

if (mysql_query(ampmysqlSELECT FROM test_table))

fputs (Error processing query stderr)

abort()

if ((res = mysql_store_result(ampmysql)))

fputs (Error storing results stderr)

abort()

while((row = mysql_fetch_row(res)))

uint i = 0

for (i=0 i lt mysql_num_fields(res) i++)

printf(s row[i])

printf(n)

return 0

Step 2 Compile

gcc -Iusrlocalmysqlinclude -Lusrlocalmysqllibmysql mysqlcc ndashlm -lmysqlclient

(其中 include path與 library path取決於你的 MySQL安裝路徑)

76

如果執行時發生如下 error Run problemerror in loading shared libraries libmysqlclientsoX 將你的 MySQL library path(for exampleusrlocalmysqllibmysql) 加入etcldsoconf and run sbinldconfig -v Q9ASP + MySQL 範例程式 Ans Dim myconn As New ADODBConnection Dim myrs As New Recordset Dim mySQL As String Dim myrows As Long myconnOpen DSN=MyODBCsample mySQL = SELECT from user myrsSource = mySQL Set myrsActiveConnection = myconn myrsCursorLocation = adUseClient myrsOpen myrows = myrsRecordCount myrsClose myconnClose 可參考 httpwwwdwamnetmysqlasp_myodbcasp 有詳細的資料 Q10如何將 MySQL中的資料庫匯出成txt檔 Ans select from TableName into outfile textxls all result fields will seperate by tab

77

第八章 參考資料

英文部份 網址 1 httpwwwmysqlcom MySQL 網站有第一手有關 MySQL的資料 2 httpwwwmysqlcomdocenReplicationhtml 有關 MySQL Replication 的文件 3 httpwwwgeocitiescomsqlhomefaqstore_blobhtml 如何在 MySQL 存放 BLOB的資料 4httpwwwsapdborg 有關 SAP跟 MySQL相關合作的網站 書藉 1 Cooking with MySQL

Paul DuBois has selected sample recipes from the hundreds youll find in his book MySQL

Cookbook In this third and final series of excerpts showcasing these recipes learn how to

compute team standings how to calculate the differences between successive Dec 26

2002 2 Tips for Building Web Database Applications with PHP and MySQL by Hugh E Williams co-author of Web Database Applications with PHP amp MySQL 04042002

3 Managing and Using MySQL 2nd Edition By Tim King George Reese Randy Jay Yarger

4 MySQL Cookbook By Paul DuBoisPublisher OReillyPub Date October 2002

中文部份

78

1 httplinuxtncedutwtechdocmysqlmysql_docmanual_tochtml MySQL 中文手冊 2 httpchenshloxaedutwphpZ_1php PHP+MySQ程式研習設計網站 3 httplinuxtncedutwtechdocbanicdownhtml PHP 4 手冊 4 httpwwwtncedutwadmin_zonephp台南縣教育網網路中心有很多 Linux相關文件 5 httpdobtncedutw網站建置百寶箱有很多 PHP MySQL 相關範例程式 5 httpwwwdbworldcomtw資料庫專家電子雜誌介紹資料庫的重要觀念及名詞

79

附錄一 SQL Command 介紹

SQL (讀音ess-que-el) 是一種結構查詢語法SQL 使用於資料庫交流

傳遞相容於 ANSI (American National Standards Institute) 是一套標準的關聯

式資料庫語言 SQL 語言是執行更新或從資料系統獲取資料一般常見的關聯

資料庫系統都有提供 SQL 如 Oracle Sybase Microsoft SQL Server Access Ingres 等雖然大部份的資料庫都有提供 SQL 但也多提供了自已獨特的語

法造成了不相容的情形但標準基本的語法是相通的如Select Insert Update Delete Create and Drop 每一個系統都有支援

Table相關 Command

Create Table

關聯式資料庫包含有很多元件稱為資料表(tables) 把資料或訊息放在資

料表中 資料表是以不同的名稱做分別資料表由欄列所構成的二維陣列

欄包含欄位名資料型態 及其他可判斷的資訊列是由全部欄位構成一筆一

筆的紀錄 create table 語法用在建立一個新的資料表語法格式如下

create table tablename (column1 data type column2 data type column3 data type)

Format of create table if you were to use optional constraints

create table tablename (column1 data type [constraint] column2 data type [constraint] column3 data type [constraint]) [ ] = optional

Note You may have as many columns as youd like and the constraints are optional

80

Example

create table employee (first varchar(15) last varchar(20) age number(3) address varchar(30) city varchar(20) state varchar(20))

注意建立資料表格式要以括號把前後框住而最後以(分號)做結尾

欄位名不要超過 30個字元長而且不要使用 sql 的關鍵字(如 where select等)而在後面接是型態的宣告(如字串數字日期格式等)

資料型態是來描述欄位的方式如一個欄位Last_Name 是一個姓氏可以使用varchar (可變動長度字串) 資料型態

以下是幾個常見的資料庫型態 char(size) 固定長度字串最長為 255 位元 varchar(size) 變動長度字串最大字元數以 size 來指定 number(size) 數值格式可以是整數也可以是小數最大數字以 size 位數判

斷未指定小數位數由系統內定 date 日期格式 number(sized) 數值格式最大數字以 size 位數判斷d 為小數位數整數位

數為 size-d 位

有何限制當資料表被建立通常有一或數個欄位是要使用來做關聯的功

能 例如unique 限制(唯一值)兩筆記錄不可以相同的值 not null (非空值)該欄位一定要輸入資料不可是空的primary key (主鍵)是每一筆記錄識別的主要方式

Drop a table drop table 刪除資料表(其中的資料也會一併刪除)

drop table tablename

Example

81

drop table 和刪除全部資料是不同的刪除全部資料欄位名稱資訊等還會

存在但刪除資料表會把這一些也一併移除掉

如何查詢資料

Select 基本用法

select 語法是關連式資料庫最常用的部份可以取得你想要的資料這是一個

簡單的範例 select column1[column2etc] from tablename [where condition] [] = optional 在 select 之後所列欄位名則是要顯示的資料部份你可以一一列出各欄位

名或是以 (星號)來代表選擇全部的欄位 from 之後放資料表名稱 where 子句 (選項) 指定要過濾的條件符合者才會顯現 where 可使用的條件運算元 = 等於 gt 大於 lt 小於 gt= 大或等於 lt= 小或等於 ltgt 大相等 LIKE 相似 For example select first last city

82

from empinfo where first LIKE Er 以Er 為開頭的字串就符合要以單引號框住 Or you can specify select first last from empinfo where last LIKE s 最後一字為 S 就符合 select from empinfo where first = Eric 則表示 first name 一定要是 Eric 才可以 範例資料表empinfo 統計函數

MIN 傳回指定欄位最小值

MAX 傳回指定欄位最大值

SUM 傳回指定欄位總和

AVG 傳回指定欄位平均值

COUNT 傳回指定欄位的筆數

COUNT() 傳回資料庫中的總筆數

統計函數使用於資料表中的數值欄位配合 SELECT 語法使用 只用於總結特定單一欄位可以配合 GROUP BY 做篩選但也可以不使用 GROUP BY 語句For example

SELECT AVG(salary) FROM employee

83

傳回全部 salary 平均值

Another example

SELECT AVG(salary) FROM employee WHERE title = Programmer

傳回 salary 平均值條件為 employees 資料表中當 title 等於 Programmer

Example

SELECT Count() FROM employees

傳回 employees 資料表中紀錄總筆數

GROUP BY 語法 SELECT column1 SUM(column2) FROM list-of-tables GROUP BY column-list The GROUP BY 語句可以先以所列的欄位為條件分組排序在一起(可以多欄

位) example 要列出每一個 dept 中最高 salary 值 SELECT max(salary) dept FROM employee GROUP BY dept HAVING 語法

SELECT column1 SUM(column2) FROM list-of-tables GROUP BY column-list HAVING condition

HAVING 子句是 GROUP BY 的一部份用來過濾在 GROUP BY 所選出的資料功能如同 select 命令中 where 條件式一樣只是 HAVING 必需配合 GROUP BY 使用

我們以例子來說明我們要取得每一公司名及每一公司的薪水平均值輸入如下

84

SELECT dept avg(salary) FROM employee GROUP BY dept

但如果我們只列出薪資平均值超過 20000元的公司資料

SELECT dept avg(salary) FROM employee GROUP BY dept HAVING avg(salary) gt 20000

ORDER BY子句語法

SELECT column1 SUM(column2) FROM list-of-tables ORDER BY column-list [ASC | DESC]

[ ] =選項

ORDER BY是一個選項子句當你以排序方式來顯示資料(正向由小到大反向由大到小)以指定的欄位資料做排序

ASC = 正向- 預設值 DESC = 反向排序

For example

SELECT employee_id dept name age salary FROM employee_info WHERE dept = Sales ORDER BY salary

以上列出公司代號公司名銷售員人名年紀及薪資而條件是公司名為 Sales 顯示順序以薪資多少排序(由小到大為預設值)

如果要以多個欄位做排序要以逗號做分隔如下

SELECT employee_id dept name age salary FROM employee_info WHERE dept = Sales ORDER BY salary age DESC

85

結合條件及布林運算 SELECT column1 SUM(column2) FROM list-of-tables WHERE condition1 AND condition2 AND運算可以結兩個或以上的條件放在 WHERE子句中 兩者都要為真才

會顯示該筆記錄 OR 運算可以結兩個或以上敘述放在 WHERE子句中只要其中一個為直就

會顯示該筆記錄 For example SELECT employeeid firstname lastname title salary FROM employee_info WHERE salary gt= 5000000 AND title = Programmer 必需要薪資大於等於 50000而且職稱為 Programmer同時符合才會顯示該筆資料 以下以括號括住雖然不是必需的但如此比較容易讀 SELECT employeeid firstname lastname title salary FROM employee_info WHERE (salary gt= 5000000) AND (title = Programmer) 另外範例 SELECT firstname lastname title salary FROM employee_info WHERE (title = Sales) OR (title = Programmer) 條件為只要是 Sales 或 Programmer 職稱的就會被列出 IN and BETWEEN 子句

SELECT column1 SUM(column2) FROM list-of-tables WHERE column3 IN (list-of-values) SELECT column1 SUM(column2) FROM list-of-tables WHERE column3 BETWEEN value1 AND value2 IN 子句使用在列舉項目的使用上也就是分別測試是否符合所列的值 For example

86

SELECT employeeid lastname salary FROM employee_info WHERE lastname IN (Hernandez Jones Roberts Ruiz) 條件為姓氏(astname)要符合 Hernandez Jones Roberts or Ruiz 其中一個才會被傳回 IN運算元也可以使用 OR 的語法來取代如下結果相同 SELECT employeeid lastname salary FROM employee_info WHERE lastname = Hernandez OR lastname = Jones OR lastname = Roberts OR lastname = Ruiz 但使用 IN 句子比較短也比較易懂 你也可以使用 NOT IN 來去掉不要的記錄 BETWEEN 運算元使用在判斷是否存在兩個數值之間 For example SELECT employeeid age lastname salary FROM employee_info WHERE age BETWEEN 30 AND 40 傳回年紀 30歲到 40歲之間的資料(含 30及 40歲者) 相同的也可以使用以下語法來達到相同的結果 SELECT employeeid age lastname salary FROM employee_info WHERE age gt= 30 AND age lt= 40 你也可使用 NOT BETWEEN 來濾掉中間值的資料 數學運算 標準 ANSI SQL-92 提供以下運算

87

+ 加

- 減

餘數

餘數為除法後剩整數這不在標準的 ANSI SQL 中但大部份的資料庫都會支

援這運算元以下列出有用的函數雖不在 ANSI SQL-92 提供但一般資料庫

也會支援他們

ABS(x) 傳回 x 絕對值

SIGN(x) returns the sign of input x as -1 0 or 1 (negative zero or positive respectively)

MOD(xy) 餘數 - returns the integer remainder of x divided by y (同 xy)

FLOOR(x) 傳回小或等於 x 的最大整數值

CEILING(x) or CEIL(x)

傳回大或等於 x 的最小整數值

POWER(xy) x的 y 次方

ROUND(x) 把 x 四捨五入為整數

ROUND(xd) 四捨五入取到小數 d 位

SQRT(x) x 開平方

For example SELECT round(salary) firstname FROM employee_info 傳回薪資取到整數位

如何新增資料

insert 加入一筆新紀錄到資料表中 insert into tablename (first_columnlast_column) values (first_valuelast_value) [] = optional Example insert into employee

88

(first last age address city state) values (Luke Duke 45 2130 Boars Nest Hazard Co Georgia) Note 字串要以單引號住如string 數字框住也無妨 insert into 後面接資料表名稱再接以括號括住的欄位名在 values 後括號分別對映各欄位的值 以上的例子新增了一筆名(first) 為 Luke而住所(state) 為 Georgia 的資料

如何刪除資料

delete 可以刪除單筆或多筆紀錄 delete from tablename where columnname OPERATOR value [and|or column OPERATOR value] [ ] = optional Examples delete from employee Note 如果你沒有指定 where 子句那麼全部的紀錄都會被刪除 delete from employee where lastname = May delete from employee where firstname = Mike or firstname = Eric delete from 接著資料表名 再接著是條件式判斷沒有條件式則全部紀錄會

被刪除

如何更新資料

update 用來更新你所指定的記錄要和 WHERE 配合小心使用 語法 update tablename set columnname = newvalue[nextcolumn = newvalue2] where columnname OPERATOR value [and|or column OPERATOR value] [] = optional Examples

89

update phone_book set area_code = 623 where prefix = 979 update phone_book set last_name = Smith prefix=555 suffix=9292 where last_name = Jones update employee set age = age+1 where first_name=Mary and last_name=Williams

90

附錄二Replication

測試環境

RedHat 90 + MySQL 32358 MySQL資料庫路徑 varlibmysql MySQL設定檔 etcmycnf Master IP 1921680100 Slave IP 1921680200 請至下列網址下載最新MySQL 32358套件並利用rpm ndashUvh 更新 httpupdatesredhatcom9enosi386

圖 最新 MySQL 套件

測試架構圖

91

1921680100

1921680200Master Server

erveSlave S r

圖 測試架構圖

測試步驟

Master server 部份 Step1 確認 MasterSlave機器上所裝的 MySQL版本能進行

replication( 32329 or higher ) Step2 在 Master MySQL上開放一個帳號給 Slave mysql ndashu root ndashp mysqlgtGRANT FILE ON TO repl1921680200 IDENTIFIED BY lsquoabc123rsquo mysqlgtq 上面是 Master開放一個帳號 repl密碼 abc123給 IP1921680200有檔案處理

的權限 Step3 shutdown MySQL on the Master mysqladmin ndashu root ndashp shutdown Step4 備份 Master所有資料庫 tar ndashcvf tmpmysql-snapshottar varlibmysql 注意tar的時候MySQL是要在 stop情況下 在mysql (wwwmysqlcom) 網站的FAQ有不用shutdown的方法

92

Step5 在 master機器上修改etcmycnf 在[mysqld]區段內加入參數 log-bin server-id=這邊設定 server-id=1 sql-bin-update-same binlog-do-db=CRM只針對 CRM資料庫做紀錄 Step6 Restart MySQL on the master service mysqld start 此時因為有加入 log-bin 參數因此開始有 index產生了在varlibmysql目錄下

有index檔案紀錄資料庫的異動 log Slave server 部份 Step1 在 slave設定etcmycnf 在[mysqld]區段加入 master-host= master-user= master-password= master-port= server-id= 這邊設定 master-host=1921680100 master-user=repl master-password=abc123 master-port=3306 server-id=2 master-connect-retry=60預設重試間隔 60秒 replicate-do-db=CRM告訴 slave只做 CRM資料庫的更新 log-slave-updates Step2 將 master上的 mysql-snapshottar copy到 slave上 用 ftp傳到 slave的tmp Step3 解壓縮 Master資料庫至 Slave Server上 cd varlib tar xvf tmpmysql-snapshottar chown ndashR mysqlmysql mysql

93

chmod ndashR 770 mysql (視情況) Step4 Restart MySQL on the slave server 這時在varlibmysql目錄會出現 masterinfo此檔案紀錄了 Master MySQL server的資訊

狀況測試

One-way replication

1921680100

1921680200Master Server

erveSlave S r

圖 One-way replication架構圖 Step1 Master跟 Slave網路及服務都正常情況下由 Master端異動資料後 到 Slave端瀏覽資料檢視是否有進行 replication Step2 模擬 Slave Server 當機 可用在於 slave真的當機或是 Slave 不一定需要一直跟 master connect將Slave MySQL server shutdown由 Master端異動資料到 slave端瀏覽此時Slave應該沒有被 replication 更新然後再將 Slave端 MySQL server start起來

預設 60秒後 Slave會嘗試跟 Master要求進行 replication再去 Slave端檢視是否有更新資料

94

Step3 模擬 Master當機因為是設定 One-way replication一旦 Master Server Slave端沒有 Master的 source可以 download Two-way replication 基於 Master當機狀況於是發展雙向 Replication即 1921680100 ( Host A ) 1921680200 ( Host B )都分別擔任 MasterSlave身分

1921680100

1921680200er

Server B MasterSlave Server

Server A MasterSlave Serv

圖 Two-way replication架構圖 以下是針對兩台 MySQL伺服器進行雙向 Replication Step1觀念同單向 replication只是改成 Master也有 Slave身分 Slave也有Master的身分先分別在 Server AServer B 都去 grant一個進行 replication的身分 [A]mysqlgtGRANT FILE ON TO repl1921680200 IDENTIFIED BY lsquoabc123rsquo [B]mysqlgt GRANT FILE ON TO repl1921680100 IDENTIFIED BY lsquoabc123rsquo Step2做完單向 replication後stop Server Aserver B MySQL service此時 AB資料是一樣的

95

修改etcmycnf設定 範例 Server A [mysqld] datadir=varlibmysql socket=varlibmysqlmysqlsock server-id=1 log-bin sql-bin-update-same binlog-do-db=CRM master-host=1921680200 master-user=repl master-password=abc123 log-slave-updates master-connect-retry=60 replicate-do-db=CRM Server B [mysqld] datadir=varlibmysql socket=varlibmysqlmysqlsock server-id=2 log-bin sql-bin-update-same binlog-do-db=CRM master-host=1921680100 master-user=repl master-password=abc123 log-slave-updates master-connect-retry=60 replicate-do-db=CRM 分別 start Server AServer B MySQL後此時雙方都是 MasterSlave身分一旦哪一方資料異動就會通知對方來 replication-若 replication失效則必須將Server AServer B的masterinfo及index00x 都砍掉然後分別 restart MySQL server進行測試檢視成果 實務上通常如果需要做Two-way replication通常會搭配Virtual Server使用

96

在前端架設一台Virtual Server不過此部份不在此份SOP討論範圍內有興趣

的讀者可參考 httpwwwlinuxvirtualserverorg 網站

1921680100 1921680200

Host A MasterSlave Server

Host B MasterSlave Server

Virtual Host

圖 Virtual Server + Two-way replication 架構圖

97

圖 High Availability Linux Virtual Server架構圖

98

  • COSA-SOP-03-006
  • 第一章 簡介
    • 11適用對象 (Audience)
    • 12 MySQL本身
    • 13 MySQL 40版跟50版重大的改進功能
    • 14 各家資料庫軟體比較
      • 第二章 前置需求
      • 第三章 安裝
        • 31 MySQL安裝
        • 32 phpMyAdmin安裝
        • 33 升級及注意事項
          • 第四章 MySQL管理
            • 41 Webmin 管理介面
            • 42 phpMyAdmin 的操作介面
            • 43管理指令介紹
              • 431 利用mysqladmin設定root的密碼
                  • 第五章 實用範例
                    • 51 任務一Web Base客戶通訊錄
                    • 52 任務二Web Base群組軟體 ( twig )
                      • 第六章 維護及更新程序
                        • 61 日常維護
                        • 62 更新程序
                        • 63 備份重要檔案
                        • 64 離線備份與還原
                        • 65 線上備份與還原
                          • 第七章 問題與解答
                          • 第八章 參考資料
                          • 附錄一 SQL Command 介紹
                          • 附錄二Replication
Page 24: DataBase Server Standard Operation Procedureebooks.lib.ntu.edu.tw/1_file/oss/63/93doc4-5.pdf · 業務的公司帶來了不少壓力,譬如微軟,甲骨文 ... 外的錢用在第三方的資料庫產品上,譬如就可以不用再購買甲骨文公司

33 升級及注意事項

RedHat 90附的 MySQL版本為 323 MySQL所釋出最新穩定版本為

40若是您不想用系統預附的 323請先利用下列移除之前 323的版本

rpm ndashe mysql-devel rpm ndashe mysql-server rpm ndashe mysql --nodeps 然後到下列網址下載您所想要的版本進行安裝在這裏我們用 4014版為例 Step 1 下載相關套件( httpwwwmysqlcomdownloadsmysql-40html )

圖 3-21 Download MySQL 4014 相關 RPM Step 2 利用 rpm 指令安裝

24

圖 3-22 Install MySQL 4014 相關 RPM

圖 3-23 Install MySQL 4014 相關 RPM

Step 3 啟動 MySQL

25

圖 3-24 啟動 MySQL 4014 並修改密碼

26

第四章 MySQL管理

本章將我們介紹利用WebminphpAdminCommand的方式建立一個名為

CONTACT的資料庫內有一個 address的 Table作為我們客戶通訊錄程式使

用的資料庫

41 Webmin 管理介面

412建立資料庫

Step 1 登入Webmin

圖 4-1 登入WebMin

Step 2 點選伺服器

27

圖 4-2 伺服器畫面

Step 3 點選 MySQL資料庫伺服器

圖 4-3 MySQL資料庫伺服器

28

Step 4 建立一個新的資料庫

圖 4-4 建立 MySQL資料庫

Step 5 建立名為 CONTACT的資料庫

29

圖 4-5 指定資料庫名稱

412 建立資料表

假設我們要建立一個名為 address的 Table其結構如下 欄位名稱 資料型態 長度 說明 id INT (自動編號) 連絡人編號 name varchar文字 20 連絡人姓名 tel Varchar文字 15 連絡人電話 Step 1 選擇 CONTACT資料庫

30

圖 4-6 選擇資料庫

Step 2 指定欄位數目

31

圖 4-7 設定欄位數目

Step 3設定表格欄位屬性

圖 3-8 設定表格欄位屬性

Step 4建立表格資料

32

圖 4-9 建立表格資料

圖 4-10 檢視資料

33

圖 4-11 新增資料

圖 4-12

34

圖 4-13

413 使用者管理

接下來我們要利用Webmin 來建立資料庫使用者並給予某些權限 Step1建立使用者

35

圖 4-14 選擇使用者權限

圖 4-15

36

Step2 賦予權限

圖 4-16

Step3 權限列表

37

圖 4-17

38

42 phpMyAdmin 的操作介面

421建立資料庫

Step 填入資料庫名稱並按「建立」

圖 4-18建立資料庫

422 建立資料表

Step1 填入資料表名稱並指定欄位數量 執行

39

圖 4-19填入資料表名稱並指定欄位數量

Step2 設定欄位屬性

圖 4-20設定欄位屬性

40

Step3 phpMyAdmin會產生相關的 SQL Command

圖 4-21 資料表結構及相關 SQL Command

Step4新增 Record

41

圖 4-22

圖 4-23

42

圖 4-24

圖 4-25

43

423使用者管理

Step1建立使用者

圖 4-26

44

圖 4-27

Step2 給予權限

圖 4-28

Step3權限列表

45

圖 4-29

43管理指令介紹

431 利用 mysqladmin設定 root的密碼

當您在Windows 或 Linux 中安裝好 MySQL後系統會自動幫您建立兩個

帳分別是 root 和 匿名者MySQL的 root 跟 Linux 最高權限使用者 root無關MySQL的 root使用者相當於 MS SQL 中的 sa 帳號擁有最高的 Database管理權限但系統預設 MySQL的 root 是不需要密碼所以通常我們一安裝

MySQL後首要任務便是修改 root的密碼 我們可以利用 mysqladmin工具或是直接修改 MySQL內部資料庫的使用者資

料 mysqladmin ndashu root ndashh cosaexamplecom password lsquo1234rsquo

46

-u 表示使用者帳號root 為 MySQL預設的管理帳號

-h 表示 MySQL主機的主機名稱也可使用 IP Address password 表示使用者的密碼因為字串請使用單引號將密碼括起來 密碼設定完成之後還是可以利用 mysqladmin修改密碼但是你必須提供目前的密碼

432 連線 MySQL

mysql -uroot -p密碼 (-p和密碼之間不能有空白) 或 mysql -uroot -p (此方式會在進入後要求密碼) [rootossc phpMyAdmin] mysql -u root -p1234

Welcome to the MySQL monitor Commands end with or g

Your MySQL connection id is 25 to server version 32354

Type help or h for help Type c to clear the buffer

mysqlgt show databases

+----------+

| Database |

+----------+

| mysql |

| test |

+----------+

2 rows in set (000 sec)

mysqlgt exit

Bye

[rootossc phpMyAdmin]

433 建立資料庫

可利用 mysqladmin指令建立 CONTACT資料庫 mysqladmin -u root -p1234 create CONTACT

47

或是利用 mysql指令 [rootossc bluepage] mysql -u root -p1234 Welcome to the MySQL monitor Commands end with or g Your MySQL connection id is 1057 to server version 32354 Type help or h for help Type c to clear the buffer mysqlgt create database CONTACT Query OK 1 row affected (000 sec) mysqlgt show databases +----------+ | Database | +----------+ | CONTACT | | address | | hello | | mysql | | nuke | | test | +----------+ 6 rows in set (000 sec) mysqlgt exit

434 建立資料表

編寫 adresssql內容如下 -- Table structure for table address CREATE TABLE address ( id int(11) NOT NULL auto_increment name varchar(20) NOT NULL default tel varchar(15) NOT NULL default PRIMARY KEY (id) ) TYPE=MyISAM

48

-- Dumping data for table address INSERT INTO address VALUES (1林小明0800016888) INSERT INTO address VALUES (2黃大雄0800016888) INSERT INTO address VALUES (3劉小芬0800024365) 然後執行此 sql script mysql -u root -p1234 CONTACT lt addresssql 或是利 mysql command [rootossc bluepage] mysql -u root -p1234 Welcome to the MySQL monitor Commands end with or g Your MySQL connection id is 1090 to server version 32354 Type help or h for help Type c to clear the buffer mysqlgt use CONTACT Database changed Database changed mysqlgt CREATE TABLE address ( -gt id int(11) NOT NULL auto_increment -gt name varchar(20) NOT NULL default -gt tel varchar(15) NOT NULL default -gt PRIMARY KEY (id) -gt ) TYPE=MyISAM Query OK 0 rows affected (000 sec) mysqlgt INSERT INTO address VALUES (1林小明0800016888) Query OK 1 row affected (000 sec) mysqlgt INSERT INTO address VALUES (2黃大雄0800016888) Query OK 1 row affected (000 sec) mysqlgt INSERT INTO address VALUES (3劉小芬0800024365) Query OK 1 row affected (000 sec) mysqlgt exit Bye

49

第五章 實用範例

51 任務一Web Base客戶通訊錄

任職於開放科技公司的林小明前些日子在最符合成本效益的條件下快

速地完成公司網站的建置老闆因此對小明讚譽有加最近因為公司存放客戶資

料的 SQL Server主機屢遭病毒攻擊加上作業系統本身的問題當機次數頻繁

老闆希望能儘快把公司的客戶通訊錄程式移轉到較穩定的環境上因為此客戶通

訊錄程式最主要給內部人員使用所以介面美觀並不特別要求只求穩定且能快

速得到查詢結果老闆希望在短時間先看到程式的雛型並鍵入資料對其效率

及穩定性進行測試因為上次小明表現突出所以這次不可能的任務自然又落到

小明身上 小明想來想去既然要快速又穩定他而且又不希望所有人都得安裝 Client

程式於是小明決定)捨棄他的舊愛「Delphi+MS SQL」投向新歡「Apache + MySQL + PHP」利用此架構來設計一個簡單實用的Web Base客戶通訊錄程式

511 Web Base客戶通訊錄架構

此程式需要建立 CONTACT的資料庫並建立 adress Tables其結構如下表建立步驟請參考第三章 欄位名稱 資料型態 長度 說明 id INT (自動編號) 連絡人編號 name varchar文字 20 連絡人姓名 tel Varchar文字 15 連絡人電話 Web Base通訊錄共有下列幾個檔案功能如下表

檔案名稱 說明 Indexhtml Web Base通訊錄首頁 addphp 新增連絡人的 php程式 searchphp 尋找連絡人的 php程式 editphp 具有更新及刪除功能的 php程式

50

我們將這些檔案放至varwwwhtmlbluepage (預設無 bluepage目錄)

512 Web Base通訊錄測試

httpwwwopencombluepage 新增資料

圖 5-1 新增連絡人

圖 5-2 填入資料

51

圖 5-3 新增成功

搜尋及異動資料

圖 5-4 搜尋通訊錄

52

圖 5-5 編輯資料

圖 5-6 更新資料

513 程式內容及說明

lt-- 程式範例indexhtml--gt lthtmlgt ltheadgtlttitlegt通訊錄lttitlegtltheadgt ltbodygt ltcentergt

53

lth2gt通訊錄lth2gtlthrgt lta href=indexhtmlgt通訊錄ltagt | lta href=addphpgt新增連絡人ltagt | lta href=searchphpgt搜尋通訊錄ltagt ltcentergt ltbodygt lthtmlgt lt-- 程式範例addphp --gt lthtmlgt ltheadgtlttitlegt新增連絡人lttitlegtltheadgt ltbodygt ltcentergtlth2gt新增連絡人lth2gtltcentergtlthrgt lt 取得欄位資料 if (isset($_POST[Name]) ampamp isset($_POST[Tel]) ) $name = $_POST[Name] $tel = $_POST[Tel] 檢查是否有輸入欄位資料 if ($name = ampamp $tel = ) 建立 SQL字串 $sql = INSERT INTO address (name tel) values( $sql= $name $tel) 建立 MySQL 連結 $link = mysql_connect(localhostroot1234) 選擇資料庫 mysql_select_db(CONTACT) 執行 SQL指令 mysql_query($sql) mysql_close($link) echo ltfont color=redgt新增連絡人成功ltfontgtltbrgt gt ltform action=addphp method=postgt lttable border=0 width=300gt lttrgtlttdgt姓名 lttdgt

54

lttdgtltinput type=text name=Name size=20 maxlength=10gtlttdgtlttrgt lttrgtlttdgt電話 lttdgt lttdgtltinput type=text name=Tel size=20 maxlength=20gtlttdgtlttrgt lttrgtlttd colspan=2 align=centergt ltinput type=submit value=新增連絡人gtlttdgtlttrgt lttablegt ltformgt ltbrgtlta href=indexhtmlgt通訊錄ltagt | lta href=addphpgt新增連絡人ltagt | lta href=searchphpgt搜尋通訊錄ltagt ltbodygt lthtmlgt

lt-- 程式範例searchphp --gt lthtmlgt ltheadgtlttitlegt搜尋通訊錄lttitlegtltheadgt ltbodygt ltcentergtlth2gt搜尋通訊錄lth2gtlthrgt lt if (isset($_POST[Search])) 建立資料庫連結並選定資料庫 $link = mysql_connect(localhostroot1234) mysql_select_db(CONTACT) 建立基本的 SQL字串 $sql = SELECT FROM address 檢查是否輸入姓名 if (chop($_POST[Name]) = ) $name = name LIKE $_POST[Name] else $name = 檢查是否輸入電話號碼 if (chop($_POST[Tel]) = ) $tel = tel LIKE $_POST[Tel] else $tel =

55

if條件組合 SQL字串 if (chop($name) = ampamp chop($tel) = ) $sql= WHERE $name AND $tel elseif (chop($name) = ) 只有姓名 $sql = WHERE $name elseif (chop($tel) = ) 只有電話號碼 $sql = WHERE $tel $sql= ORDER BY name 最後加上排序 $result = mysql_query($sql) 取得欄位數 $total_fields = mysql_num_fields($result) echo lttable border=1gt echo lttrgtlttdgt編號lttdgtlttdgt姓名lttdgtlttdgt電話lttdgtlttd colspan=2gt功能選項lttdgtlttrgt 表格顯示查詢結果 while ($rows = mysql_fetch_array($result MYSQL_NUM)) echo lttrgt for ($i = 0 $i lt $total_fields $i++) echo lttdgt$rows[$i]lttdgt echo lttdgtlta href=editphpaction=editampid= echo $rows[0]gtltbgt編輯ltbgtlttdgt echo lttdgtlta href=editphpaction=delampid= echo $rows[0]gtltbgt刪除ltbgtlttdgt echo lttrgt echo lttablegtlthrgt mysql_free_result($result) mysql_close($link) gt ltcentergt ltform action=searchphp method=postgt lttable border=0 width=450gt lttrgtlttdgt搜尋姓名 lttdgt lttdgtltinput type=text name=Name size=10 maxlength=20gtlttdgtlttrgt lttrgtlttdgt搜尋電話 lttdgt lttdgtltinput type=text name=Tel

56

size=20 maxlength=20gtlttdgtlttrgt lttrgtlttd colspan=2 align=centergt ltinput type=submit name=Search value=搜尋gtlttdgtlttrgt lttablegt ltformgt ltbrgtlta href=indexhtmlgt通訊錄ltagt | lta href=addphpgt新增連絡人ltagt | lta href=searchphpgt搜尋通訊錄ltagt ltbodygt lthtmlgt

lt ob_start() gt lt-- 程式範例editphp --gt lthtmlgt ltheadgtlttitlegt編輯通訊錄lttitlegtltheadgt ltbodygt lt 取得 URL 參數 $id = $_GET[id] $action = $_GET[action] 建立資料庫連結 $link = mysql_connect(localhostroot1234) mysql_select_db(CONTACT) 選擇資料庫 執行的操作 switch ($action) case update 更新 取得欄位資料 $name = $_POST[Name] $tel = $_POST[Tel] $sql = UPDATE address SET name=$name tel=$tel WHERE id=$id mysql_query($sql) 執行 SQL指令 mysql_close($link) header(Location searchphp) 轉向到 serachphp break case del 刪除 $sql = DELETE FROM address WHERE id=$id

57

mysql_query($sql) 執行 SQL指令 mysql_close($link) header(Location searchphp) 轉向到 serachphp break case edit 編輯 $sql = SELECT FROM address WHERE id=$id $result = mysql_query($sql) 執行 SQL指令 $row = mysql_fetch_row($result) 取回記錄 $name = $row[1] 取得欄位 name $tel = $row[2] 取得欄位 tel mysql_close($link) 顯示編輯表單 gt ltcentergtlth2gt更新通訊錄lth2gtltcentergtlthrgt ltform action=editphpaction=updateampid=lt echo $id gt method=postgt lttable border=0 width=300gt lttrgtlttdgt姓名 lttdgt lttdgtltinput type=text name=Name size=20 maxlength=10 value=lt echo $name gtgtlttdgtlttrgt lttrgtlttdgt電話 lttdgt lttdgtltinput type=text name=Tel size=20 maxlength=20 value=lt echo $tel gtgtlttdgtlttrgt lttrgtlttd colspan=2 align=centergt ltinput type=submit value=更新連絡人gtlttdgtlttrgt lttablegt ltformgt ltbrgtlta href=indexhtmlgt通訊錄ltagt | lta href=addphpgt新增連絡人ltagt | lta href=searchphpgt搜尋通訊錄ltagt lt break gt ltbodygt lthtmlgt

58

52 任務二Web Base群組軟體 ( twig )

順利完成Web Base客戶通訊錄程式測試一段時間後「Apache + MySQL + PHP」架構的穩定與快速巳深得老闆與公司所有同事的認同隨著公司業績蒸

蒸日上人員組織編罝愈來愈龐大跨部門的會議愈來愈多業務員每日排滿拜

訪客戶的行程跟客戶的 Email的往來也愈來愈頻繁 愈來愈多部門的同事希望公司能建置一套群組軟體提供 web mail可讓業

務人員方便收發 mail還有連絡人議事日程待辦工作書簽等功能讓整個

公司運作及個人時間管理更有效率

老闆問小明對這些需求有什麼看法小明認為如果這些功能完全由程式部

門開發必定曠日費時而且耗費公司資源小明在網路尋找是否有提供這些功能

的Free Software皇天不負苦心人小明發現了TWIG (The Web Information Gateway) httptwigscrewdrivernet這個群組軟體它在 Web 上整合郵件新聞聯絡人議事日程工作序書簽等功能非常符合公司的需求 Step 1 下載 twig-277targz 下載網址 httptwigscrewdrivernetdownloadphp3

Step 2 解開 twig-277targz tar -xzvf twig-277targz

59

Step 3 執行安裝動作安裝到 varwwwhtmltwig 目錄 cd twig-277 twig-install varwwwhtmltwig

Step 4 建立 MySQL 資料庫(twig)及各資料表

cd setup mysql -u root -p1234 mysqlgt create database twig Query OK 1 row affected (001 sec) mysqlgt quit mysql -u root ndashp1234 twiglt twigtablemysql

Step 5 修改 configincphp3 參數設定 vi varwwwhtmltwigconfigconfigincphp3 $config[fromdomain] = opencom 網域 $config[language] = chinesebig5 中文訊息 $config[imap_port] = 143notls

60

Step 6 修改連結 MySQL 的帳號密碼 vi varwwwhtmltwigconfigdbconfigincphp3 $dbconfig[sqlusername] = root username $dbconfig[sqlpassword] = 1234 password

Step 7 其他設定檔

vi etchttpdconfhttpdconf 加入 AddType applicationx-httpd-php php3 在 DirectoryIndex最後加入 indexphp3 DirectoryIndex indexhtml indexhtmlvar indexphp3 在 AddDefaultCharset ISO-8859-1加上 AddDefaultCharset ISO-8859-1

vi etcphpini register_globals = On service httpd restart Step 8 sendmail 設定 vi etcmailsendmailcf在 264 行前面加上並重新啟動 sendmail「service snedmail restart」 262 SMTP daemon options 263 264 O DaemonPortOptions=Port=smtpAddr=127001 Name=MTA 265 266 SMTP client options 267 O ClientPortOptions=Family=inet Address=00

61

Step 9 檢查設定有無錯誤 http主機名稱twigtestphp3

62

Step 10 登入 twig ( http主機名稱twig)

63

第六章 維護及更新程序

61 日常維護

系統管理員最好定期以 root 身份登入看看信件在 RedHat Linux 中有一支 logwatch 程式會定時去分析 log file如果發現異常便會發信給 root除此之外筆者建議讀者平時就檢查 MySQL log file ( varlogmysqldlog)是否有異常情形

62 更新程序

讀者可至httprpmfindnet 尋找MySQL相關套件至於升級的相關步驟請參

考Linux OS SOP 第 54節

63 備份重要檔案

預設 MySQL 的 DB 檔案是存在 varlibmysql 內以 DB名稱為目錄目錄

內就是該 DB 的所有資料通常得定期備份還有 MySQL的設定檔 etcmycnf也別忘了一起備份

64 離線備份與還原

641 離線備份

預設 MySQL 的 DB 檔案是存在 varlibmysql 內以 DB 名稱為目錄目錄內

就是該 DB 的所有資料像 CRM 這個 DB就是存在 varlibmysqlCRM 內在備份前因為怕資料尚未完全寫入磁碟而且 MySQL 會 Lock 在使用的 DB 檔案所以應該是要先把 MySQL 先 Shutdown 一下整個備份的程序可以下像下面的指令去完成 cd varlibmysql

64

service mysqld stop tar cvfz CRM_db_20030905tgz CRM service mysqld start 對這樣就可以了 不過要注意的是怕 DB 內每個 Tables 間的資料有關關

聯性所以最好是把整個 DB 一次備起來單獨只備哪個 Tables 的檔案以後回存時怕會有資料關聯不一致的問題

642 離線還原

DB 發生錯誤而要回存時其實也不難先找出最近一次完整正常的備份先把現在錯誤的網頁或 DB 先更名或 tar 起來再把好的備份給解開回原來目錄位

置就行了需要注意的是 MySQL 服務最好也是要先停止回存完成後再啟動服務回存 DB 的整個程序可能像下面 cd varlibmysql service mysqldstop mv CRM CRM_OLD tar xvfz CRM_db_20030905tg service mysqld start

65 線上備份與還原

651 線上備份

使用像上面的檔案方式備份是個不錯的方法它最少可以保持該主機某個時間點的完整檔案備份但還是有一些問題需要考慮到有些主機就不只建立一個 DB 而已總不能為了備份某個 DB 而把整個 MySQL 服務停止備份檔案的方式回存在原主機上一定適用但假如 MySQL 版本升級或是在那天該網頁空間需遷機移機到別的主機時那就沒人敢保證備出來的資料檔可以用所以我們可以考慮另一種備份的方式是使用 MySQL 本身提供的功能 MySQL Data Dump指令是 mysqldump

65

使用 MySQL 的 Dump 功能可以把 DB 的結構資料或結構加資料 Dump 成文字檔 mysqldump 指令提供的彈性很大你可以選擇把整個 DB Dump 成一個檔或是每個 Table 為一個檔甚至是把結構檔和資料分開儲存都

可以 mysqladmin -uroot -p flush-logs mysqldump CRM -uroot -p --opt gt CRM_20030905sql (CRM 是 DB 名稱 opt 是一個使用完整 Dump 參數) 假如只是要單獨 Dump 某個 Table 時只要在上面的指令後轉出符號 gt 前加個 Table 名稱就可以如只要 phpbb2_users 這個 Table 的 Dump 時只要下 mysqldump CRM -uroot -p --opt CUSTOMER gt CRM_CUSTOMER_20030905sql

652 線上還原

若要回存整個資料庫只需將壓縮的備份檔還原成 Dump 的檔案再用下面的指令回存 mysql CRM -uroot -p lt CRM_20030905sql 這邊需注意的是若建立備份時是以--opt或--add-drop-table為參數時回存的 動作是先將舊的 Table 先刪除重建 Table 的結構後再把 Data 匯入所以回存後所有的資料會回到你當時備份那個時間點因此在回存資料時可以考慮把現有錯誤或不完整的 DB 先備份一份下來以備不時之需或是拿來比對錯誤的地

方在那裡當然你也可以把資料回存到另一個測試用的 DB 內只要把上面指令

的 DB 名稱改成你的測試用 DB 名稱即可 使用這種回存方式 MySQL 服務不需停止也不會動到其他正在使用的 DB 在一些提供 MySQL 服務的虛擬主機可用這種方式作你自己的 DB 備份及回存

66

另外假如你是系統重建或是移機時切需在新的 MySQL 內新建一個空白 DB 後才行作回存的工作你可以用下面的指令建立 mysql -uroot -p -e CREATE DATABASE CRM (上面的 CRM是你要新建的 DB 名稱) 另一種作法先用 mysql 指令進入 mysql client console 然後再用 CREATE DATABASE CRM 這樣就行了記得尾端要加個 符號該行指令才會執行

67

第七章 問題與解答

Q1RedHat 90預附的 MySQL到底有無支援 Transcation機制 Ans MySQL自 32334a之後的 MySQL-Max版本加入 InnoDB的資料庫類型透過

InnoDBMySQL同樣可以進行 COMMIT與 ROLLRACK的動作RedHat 90預附的 MySQL為 32354a-11巳支援 InnoDB的資料庫類型不過必須做以

下設定 1cp usrsharedocmysql-server-32354amy-mediumcnf to etcmycnf 2 vi etcmycnf 將以下設定前的拿掉 innodb_data_home_dir = varlibmysql innodb_data_file_path = ibdata110Mautoextend innodb_log_group_home_dir = varlibmysql innodb_log_arch_dir = varlibmysql 3service mysqld restart 如此一來各位在建立Table時便可指定Table Type為 innodb ( ex create table with type=innodb ) Q2如何解決 php+mysql 許功蓋等字變亂的問題 Ans 方法一 【確定 MySQL 預設的字元集】 1 打開 WinMySQLadmin 管理畫面(在視窗右下角狀態列紅綠燈圖示中按滑鼠

右鍵點選 Show me 選項) 2 點選管理畫面中 [Variables] 標籤選項其中 character_set變數就是您預設

字元集的變數其預設是 latin1 字元集(我們要將他改回 big5)而 chatacters_set 變數則是 MySQL 可以支援哪些字元集 【修改預設字元集變數 character_set 】 1 請點選管理畫面中 [myini Setup] 標籤選項設定 myini 2 按一下 [Pick-up and Edit myini values] 按鈕以便編輯目前的 myini 設定 3 在 [mysqld] 設定區塊底下新增一行 default-character-set = big5 變數設

68

定 4 新增一個 [client] 設定區塊並加入第三步驟的變數設定(游標往下移到空白處新增兩行 [client] 和 default-character-set=big5) 5 按一下畫面左下方 [Save Modification] 按鈕儲存設定 6 重新啟動 MySQL 或 Windows 方法二 Server端注意事項 phpini 中有關的設定為(預設值) Magic quotes for incoming GETPOSTCookie data magic_quotes_gpc = On Use Sybase-style magic quotes (escape with instead of ) magic_quotes_sybase = Off Client端注意事項 1中文資料送進 mysql 前請用 addslashes($str) 處理 2處理後送進 mysql 時請用 括起來並在參數後留一個空白如 $sql = UPDATE ezf_table set tablename=$tname tableend=$endtime table inguser=$tguser tableingid=$tguserid tableallnumber=$tnumber tableloca l=$tablelocal tableanyone=$tableopen tabletext=$ttext WHERE tableid=$t ableid tablename=$tname c 取出時請用 stripslashes($str) Q3MySQL root 密碼忘了該怎麼辦 Ans 1先停掉 mysql etcrcdinitdmysql stop 2以--skip-grant-table 的參數啟動 mysql safe_mysql --skip-grant-tableamp 3 更改 root 密碼 mysql mysql mysqlgt UPDATE user SET password=password(newpassword)

69

WHERE user=root mysqlgt FLUSH PRIVILEGES mysqlgt exit 4停掉 mysql再重跑 mysqladmin -uroot -p shutdown Enter password 輸入新設定的密碼 etcrcdinitdmysql start

Q4NULL值問題

Ans

NULL值的概念是造成 SQL的新手的混淆的普遍原因他們經常認為 NULL是和一個空字符串的一樣的東西不是這樣的例如下列語句是完全不同的

mysqlgt INSERT INTO my_table (phone) VALUES (NULL)

mysqlgt INSERT INTO my_table (phone) VALUES ()

兩個語句把值插入到 phone 列但是第一個插入一個 NULL值而第二個插入一個空字符串第一個的含義可以認為是ldquo電話號碼不知道而第二個則可意味

著ldquo她沒有電話

在 SQL中NULL值在于任何其他值甚至 NULL值比較時總是假的(FALSE)包含 NULL的一個表達式總是產生一個 NULL值除非在包含在表達式中的運算符和函數的文檔中指出在下列例子所有的列返回 NULL

mysqlgt SELECT NULL1+NULLCONCAT(InvisibleNULL)

如果你想要尋找值是 NULL的列你不能使用=NULL測試下列語句不返回任

何行因為對任何表達式expr = NULL是假的

mysqlgt SELECT FROM my_table WHERE phone = NULL

要想尋找 NULL值你必須使用 IS NULL測試下例顯示如何找出 NULL電話號碼和空的電話號碼

70

mysqlgt SELECT FROM my_table WHERE phone IS NULL mysqlgt SELECT FROM my_table WHERE phone =

在 MySQL中就像很多其他的 SQL服務器一樣你不能索引可以有 NULL值的列你必須聲明這樣的列為 NOT NULL而且你不能插入 NULL到索引的

列中

當用 LOAD DATA INFILE 讀取數據時空列用更新如果你想要在一個列中有

NULL值你應該在文本文件中使用N字面上的詞NULL也可以在某些情形下使用

當使用 ORDER BY時首先呈現 NULL值如果你用 DESC以降序排序NULL值最後顯示當使用 GROUP BY時所有的 NULL值被認為是相等的

為了有助于NULL的處理你能使用 IS NULL和 IS NOT NULL運算符和 IFNULL()函數

對某些列類型NULL值被特殊地處理如果你將 NULL插入表的第一個TIMESTAMP 列則插入當前的日期和時間如果你將 NULL插入一個AUTO_INCREMENT 列則插入順序中的下一個數字

Q5如何將圖片存放於 MySQL中

Ans

Step 1建立資料庫 test

Step 2 建立表格 binary_data

CREATE TABLE binary_data (

id INT(4) NOT NULL AUTO_INCREMENT PRIMARY KEY

description CHAR(50)

bin_data LONGBLOB

filename CHAR(50)

filesize CHAR(50)

filetype CHAR(50)

71

)

Step 3 利用 storephp 寫入圖片

storephp 程式碼

ltHTMLgt ltHEADgtltTITLEgtStore binary data into SQL DatabaseltTITLEgtltHEADgt ltBODYgt lt code that will be executed if the form has been submitted

if ($submit) mysql_connect(localhostrootYOUR_PASSWORD) mysql_select_db(test) $data=Base64_Encode(fread(fopen($form_data r) filesize($form_data))) $result=MYSQL_QUERY(INSERT INTO binary_data (descriptionbin_datafilenamefilesizefiletype) VALUES ($form_description$data$form_data_name$form_data_size$form_data_type)) $id= mysql_insert_id() print ltpgtThis file has the following Database ID ltbgt$idltbgt MYSQL_CLOSE() else else show the form to submit new data

gt

ltform method=post action=ltphp echo $PHP_SELF gt enctype=multipartform-datagt File Descriptionltbrgt ltinput type=text name=form_description size=40gt ltINPUT TYPE=hidden name=MAX_FILE_SIZE value=4000000gt ltbrgtFile to uploadstore in databaseltbrgt ltinput type=file name=form_data size=40gt ltpgtltinput type=submit name=submit value=submitgt ltformgt lt

72

gt ltBODYgt ltHTMLgt

Step 3 利用 storephp 取出圖片

getdataphp 程式碼

lt Syntax getdataphp3id=ltidgt if($id) you may have to modify login information for your database server MYSQL_CONNECT(localhostrootYOUR_PASSWORD) mysql_select_db(test) $query = select bin_datafiletype from binary_data where id=$id $result = MYSQL_QUERY($query) $data = Base64_Decode(MYSQL_RESULT($result0bin_data)) $type = MYSQL_RESULT($result0filetype) Header( Content-type $type) echo $data gt

Q6MySQL裝好之後啟動時或是執行 mysqladmin會出現如下訊息 Cant connect to local MYSQL Server through Socket varlibmysqlmysqlsock或是

Cant connect to local MYSQL Server through Socket tmpmysqldsock

Ans 可能有下列幾個原因

1這個 mysqldsock 不見了被某人刪除了或是被一些系統自動執行程式給刪

了例如有些 cron任務便會設定定期刪除 tmp 裡的東西所以呢您只能修改

cron 裡的設定讓它不要清除 mysqldsock 2在啟動時也可以改變 mysqldsock的位置您在啟動 MySQL的時候可以加入此參數usrlocalmysqlbinsafe_mysqld --user=mysql --socket=其他路

徑socket amp 同時得去設定環境變數 MYSQL_UNIX_PORT的值以指定新的

73

路徑 3若是您沒改 MYSQL_UNIX_PORT的值那麼您可以在執行指令的時候才打

例如mysqladmin --socket=其他路徑socket version Q7How to get the last insert id Ans CREATE TABLE product ( id INT(4) NOT NULL AUTO_INCREMENT PRIMARY KEY description VARCHAR(50) ) 1利用 SQL的話 mysqlgt insert into product(description) values(123) Query OK 1 row affected (000 sec) mysqlgt select last_insert_id() +------------------+ | last_insert_id() | +------------------+ +------------------+ 1 row in set (000 sec) ======================================== 2如果是 PHP的話 你可以用mysql_insert_id()取得該 id PHP example $result=MYSQL_QUERY(INSERT INTO product (description) VALUES ($description)) $id= mysql_insert_id() print This file has the following Database ID $id Q8如何將文字檔匯入資料庫 Ans $addr=homehttpdhtmlphpschool001txt $sql_select = load data infile $addr into table test fields terminated by t 解說 $sql_select = load data infile 文字檔名 into table 表格名 fields terminated by

74

t

(欄位分隔以 TAB鍵) 該文字檔須與資料表欄位格式相符 例如欄位有三個 則文字檔為每行一筆資料如下 欄 1資料ltTABgt欄 2資料ltTABgt欄 3資料 欄 1資料ltTABgt欄 2資料ltTABgt欄 3資料 欄 1資料ltTABgt欄 2資料ltTABgt欄 3資料 欄 1資料ltTABgtltTABgt欄 3資料

Q9如何撰寫 MySQL C API Ans Step 1利用文字編輯器撰寫以下程式碼 mysqlcc

include ltstdiohgt

include ltmysqlmysqlhgt

int main (int argc char argv[])

MYSQL mysql

MYSQL_RES res

MYSQL_ROW row

if (argc = 2)

fputs (Usage myc ltdatabasegt stderr)

return 1

if ((mysql_connect(ampmysqllocalhostrootYour_Password)))

fputs (Error connecting stderr)

abort()

75

if (mysql_select_db(ampmysqlargv[1]))

fputs (Error selecting database stderr)

abort()

if (mysql_query(ampmysqlSELECT FROM test_table))

fputs (Error processing query stderr)

abort()

if ((res = mysql_store_result(ampmysql)))

fputs (Error storing results stderr)

abort()

while((row = mysql_fetch_row(res)))

uint i = 0

for (i=0 i lt mysql_num_fields(res) i++)

printf(s row[i])

printf(n)

return 0

Step 2 Compile

gcc -Iusrlocalmysqlinclude -Lusrlocalmysqllibmysql mysqlcc ndashlm -lmysqlclient

(其中 include path與 library path取決於你的 MySQL安裝路徑)

76

如果執行時發生如下 error Run problemerror in loading shared libraries libmysqlclientsoX 將你的 MySQL library path(for exampleusrlocalmysqllibmysql) 加入etcldsoconf and run sbinldconfig -v Q9ASP + MySQL 範例程式 Ans Dim myconn As New ADODBConnection Dim myrs As New Recordset Dim mySQL As String Dim myrows As Long myconnOpen DSN=MyODBCsample mySQL = SELECT from user myrsSource = mySQL Set myrsActiveConnection = myconn myrsCursorLocation = adUseClient myrsOpen myrows = myrsRecordCount myrsClose myconnClose 可參考 httpwwwdwamnetmysqlasp_myodbcasp 有詳細的資料 Q10如何將 MySQL中的資料庫匯出成txt檔 Ans select from TableName into outfile textxls all result fields will seperate by tab

77

第八章 參考資料

英文部份 網址 1 httpwwwmysqlcom MySQL 網站有第一手有關 MySQL的資料 2 httpwwwmysqlcomdocenReplicationhtml 有關 MySQL Replication 的文件 3 httpwwwgeocitiescomsqlhomefaqstore_blobhtml 如何在 MySQL 存放 BLOB的資料 4httpwwwsapdborg 有關 SAP跟 MySQL相關合作的網站 書藉 1 Cooking with MySQL

Paul DuBois has selected sample recipes from the hundreds youll find in his book MySQL

Cookbook In this third and final series of excerpts showcasing these recipes learn how to

compute team standings how to calculate the differences between successive Dec 26

2002 2 Tips for Building Web Database Applications with PHP and MySQL by Hugh E Williams co-author of Web Database Applications with PHP amp MySQL 04042002

3 Managing and Using MySQL 2nd Edition By Tim King George Reese Randy Jay Yarger

4 MySQL Cookbook By Paul DuBoisPublisher OReillyPub Date October 2002

中文部份

78

1 httplinuxtncedutwtechdocmysqlmysql_docmanual_tochtml MySQL 中文手冊 2 httpchenshloxaedutwphpZ_1php PHP+MySQ程式研習設計網站 3 httplinuxtncedutwtechdocbanicdownhtml PHP 4 手冊 4 httpwwwtncedutwadmin_zonephp台南縣教育網網路中心有很多 Linux相關文件 5 httpdobtncedutw網站建置百寶箱有很多 PHP MySQL 相關範例程式 5 httpwwwdbworldcomtw資料庫專家電子雜誌介紹資料庫的重要觀念及名詞

79

附錄一 SQL Command 介紹

SQL (讀音ess-que-el) 是一種結構查詢語法SQL 使用於資料庫交流

傳遞相容於 ANSI (American National Standards Institute) 是一套標準的關聯

式資料庫語言 SQL 語言是執行更新或從資料系統獲取資料一般常見的關聯

資料庫系統都有提供 SQL 如 Oracle Sybase Microsoft SQL Server Access Ingres 等雖然大部份的資料庫都有提供 SQL 但也多提供了自已獨特的語

法造成了不相容的情形但標準基本的語法是相通的如Select Insert Update Delete Create and Drop 每一個系統都有支援

Table相關 Command

Create Table

關聯式資料庫包含有很多元件稱為資料表(tables) 把資料或訊息放在資

料表中 資料表是以不同的名稱做分別資料表由欄列所構成的二維陣列

欄包含欄位名資料型態 及其他可判斷的資訊列是由全部欄位構成一筆一

筆的紀錄 create table 語法用在建立一個新的資料表語法格式如下

create table tablename (column1 data type column2 data type column3 data type)

Format of create table if you were to use optional constraints

create table tablename (column1 data type [constraint] column2 data type [constraint] column3 data type [constraint]) [ ] = optional

Note You may have as many columns as youd like and the constraints are optional

80

Example

create table employee (first varchar(15) last varchar(20) age number(3) address varchar(30) city varchar(20) state varchar(20))

注意建立資料表格式要以括號把前後框住而最後以(分號)做結尾

欄位名不要超過 30個字元長而且不要使用 sql 的關鍵字(如 where select等)而在後面接是型態的宣告(如字串數字日期格式等)

資料型態是來描述欄位的方式如一個欄位Last_Name 是一個姓氏可以使用varchar (可變動長度字串) 資料型態

以下是幾個常見的資料庫型態 char(size) 固定長度字串最長為 255 位元 varchar(size) 變動長度字串最大字元數以 size 來指定 number(size) 數值格式可以是整數也可以是小數最大數字以 size 位數判

斷未指定小數位數由系統內定 date 日期格式 number(sized) 數值格式最大數字以 size 位數判斷d 為小數位數整數位

數為 size-d 位

有何限制當資料表被建立通常有一或數個欄位是要使用來做關聯的功

能 例如unique 限制(唯一值)兩筆記錄不可以相同的值 not null (非空值)該欄位一定要輸入資料不可是空的primary key (主鍵)是每一筆記錄識別的主要方式

Drop a table drop table 刪除資料表(其中的資料也會一併刪除)

drop table tablename

Example

81

drop table 和刪除全部資料是不同的刪除全部資料欄位名稱資訊等還會

存在但刪除資料表會把這一些也一併移除掉

如何查詢資料

Select 基本用法

select 語法是關連式資料庫最常用的部份可以取得你想要的資料這是一個

簡單的範例 select column1[column2etc] from tablename [where condition] [] = optional 在 select 之後所列欄位名則是要顯示的資料部份你可以一一列出各欄位

名或是以 (星號)來代表選擇全部的欄位 from 之後放資料表名稱 where 子句 (選項) 指定要過濾的條件符合者才會顯現 where 可使用的條件運算元 = 等於 gt 大於 lt 小於 gt= 大或等於 lt= 小或等於 ltgt 大相等 LIKE 相似 For example select first last city

82

from empinfo where first LIKE Er 以Er 為開頭的字串就符合要以單引號框住 Or you can specify select first last from empinfo where last LIKE s 最後一字為 S 就符合 select from empinfo where first = Eric 則表示 first name 一定要是 Eric 才可以 範例資料表empinfo 統計函數

MIN 傳回指定欄位最小值

MAX 傳回指定欄位最大值

SUM 傳回指定欄位總和

AVG 傳回指定欄位平均值

COUNT 傳回指定欄位的筆數

COUNT() 傳回資料庫中的總筆數

統計函數使用於資料表中的數值欄位配合 SELECT 語法使用 只用於總結特定單一欄位可以配合 GROUP BY 做篩選但也可以不使用 GROUP BY 語句For example

SELECT AVG(salary) FROM employee

83

傳回全部 salary 平均值

Another example

SELECT AVG(salary) FROM employee WHERE title = Programmer

傳回 salary 平均值條件為 employees 資料表中當 title 等於 Programmer

Example

SELECT Count() FROM employees

傳回 employees 資料表中紀錄總筆數

GROUP BY 語法 SELECT column1 SUM(column2) FROM list-of-tables GROUP BY column-list The GROUP BY 語句可以先以所列的欄位為條件分組排序在一起(可以多欄

位) example 要列出每一個 dept 中最高 salary 值 SELECT max(salary) dept FROM employee GROUP BY dept HAVING 語法

SELECT column1 SUM(column2) FROM list-of-tables GROUP BY column-list HAVING condition

HAVING 子句是 GROUP BY 的一部份用來過濾在 GROUP BY 所選出的資料功能如同 select 命令中 where 條件式一樣只是 HAVING 必需配合 GROUP BY 使用

我們以例子來說明我們要取得每一公司名及每一公司的薪水平均值輸入如下

84

SELECT dept avg(salary) FROM employee GROUP BY dept

但如果我們只列出薪資平均值超過 20000元的公司資料

SELECT dept avg(salary) FROM employee GROUP BY dept HAVING avg(salary) gt 20000

ORDER BY子句語法

SELECT column1 SUM(column2) FROM list-of-tables ORDER BY column-list [ASC | DESC]

[ ] =選項

ORDER BY是一個選項子句當你以排序方式來顯示資料(正向由小到大反向由大到小)以指定的欄位資料做排序

ASC = 正向- 預設值 DESC = 反向排序

For example

SELECT employee_id dept name age salary FROM employee_info WHERE dept = Sales ORDER BY salary

以上列出公司代號公司名銷售員人名年紀及薪資而條件是公司名為 Sales 顯示順序以薪資多少排序(由小到大為預設值)

如果要以多個欄位做排序要以逗號做分隔如下

SELECT employee_id dept name age salary FROM employee_info WHERE dept = Sales ORDER BY salary age DESC

85

結合條件及布林運算 SELECT column1 SUM(column2) FROM list-of-tables WHERE condition1 AND condition2 AND運算可以結兩個或以上的條件放在 WHERE子句中 兩者都要為真才

會顯示該筆記錄 OR 運算可以結兩個或以上敘述放在 WHERE子句中只要其中一個為直就

會顯示該筆記錄 For example SELECT employeeid firstname lastname title salary FROM employee_info WHERE salary gt= 5000000 AND title = Programmer 必需要薪資大於等於 50000而且職稱為 Programmer同時符合才會顯示該筆資料 以下以括號括住雖然不是必需的但如此比較容易讀 SELECT employeeid firstname lastname title salary FROM employee_info WHERE (salary gt= 5000000) AND (title = Programmer) 另外範例 SELECT firstname lastname title salary FROM employee_info WHERE (title = Sales) OR (title = Programmer) 條件為只要是 Sales 或 Programmer 職稱的就會被列出 IN and BETWEEN 子句

SELECT column1 SUM(column2) FROM list-of-tables WHERE column3 IN (list-of-values) SELECT column1 SUM(column2) FROM list-of-tables WHERE column3 BETWEEN value1 AND value2 IN 子句使用在列舉項目的使用上也就是分別測試是否符合所列的值 For example

86

SELECT employeeid lastname salary FROM employee_info WHERE lastname IN (Hernandez Jones Roberts Ruiz) 條件為姓氏(astname)要符合 Hernandez Jones Roberts or Ruiz 其中一個才會被傳回 IN運算元也可以使用 OR 的語法來取代如下結果相同 SELECT employeeid lastname salary FROM employee_info WHERE lastname = Hernandez OR lastname = Jones OR lastname = Roberts OR lastname = Ruiz 但使用 IN 句子比較短也比較易懂 你也可以使用 NOT IN 來去掉不要的記錄 BETWEEN 運算元使用在判斷是否存在兩個數值之間 For example SELECT employeeid age lastname salary FROM employee_info WHERE age BETWEEN 30 AND 40 傳回年紀 30歲到 40歲之間的資料(含 30及 40歲者) 相同的也可以使用以下語法來達到相同的結果 SELECT employeeid age lastname salary FROM employee_info WHERE age gt= 30 AND age lt= 40 你也可使用 NOT BETWEEN 來濾掉中間值的資料 數學運算 標準 ANSI SQL-92 提供以下運算

87

+ 加

- 減

餘數

餘數為除法後剩整數這不在標準的 ANSI SQL 中但大部份的資料庫都會支

援這運算元以下列出有用的函數雖不在 ANSI SQL-92 提供但一般資料庫

也會支援他們

ABS(x) 傳回 x 絕對值

SIGN(x) returns the sign of input x as -1 0 or 1 (negative zero or positive respectively)

MOD(xy) 餘數 - returns the integer remainder of x divided by y (同 xy)

FLOOR(x) 傳回小或等於 x 的最大整數值

CEILING(x) or CEIL(x)

傳回大或等於 x 的最小整數值

POWER(xy) x的 y 次方

ROUND(x) 把 x 四捨五入為整數

ROUND(xd) 四捨五入取到小數 d 位

SQRT(x) x 開平方

For example SELECT round(salary) firstname FROM employee_info 傳回薪資取到整數位

如何新增資料

insert 加入一筆新紀錄到資料表中 insert into tablename (first_columnlast_column) values (first_valuelast_value) [] = optional Example insert into employee

88

(first last age address city state) values (Luke Duke 45 2130 Boars Nest Hazard Co Georgia) Note 字串要以單引號住如string 數字框住也無妨 insert into 後面接資料表名稱再接以括號括住的欄位名在 values 後括號分別對映各欄位的值 以上的例子新增了一筆名(first) 為 Luke而住所(state) 為 Georgia 的資料

如何刪除資料

delete 可以刪除單筆或多筆紀錄 delete from tablename where columnname OPERATOR value [and|or column OPERATOR value] [ ] = optional Examples delete from employee Note 如果你沒有指定 where 子句那麼全部的紀錄都會被刪除 delete from employee where lastname = May delete from employee where firstname = Mike or firstname = Eric delete from 接著資料表名 再接著是條件式判斷沒有條件式則全部紀錄會

被刪除

如何更新資料

update 用來更新你所指定的記錄要和 WHERE 配合小心使用 語法 update tablename set columnname = newvalue[nextcolumn = newvalue2] where columnname OPERATOR value [and|or column OPERATOR value] [] = optional Examples

89

update phone_book set area_code = 623 where prefix = 979 update phone_book set last_name = Smith prefix=555 suffix=9292 where last_name = Jones update employee set age = age+1 where first_name=Mary and last_name=Williams

90

附錄二Replication

測試環境

RedHat 90 + MySQL 32358 MySQL資料庫路徑 varlibmysql MySQL設定檔 etcmycnf Master IP 1921680100 Slave IP 1921680200 請至下列網址下載最新MySQL 32358套件並利用rpm ndashUvh 更新 httpupdatesredhatcom9enosi386

圖 最新 MySQL 套件

測試架構圖

91

1921680100

1921680200Master Server

erveSlave S r

圖 測試架構圖

測試步驟

Master server 部份 Step1 確認 MasterSlave機器上所裝的 MySQL版本能進行

replication( 32329 or higher ) Step2 在 Master MySQL上開放一個帳號給 Slave mysql ndashu root ndashp mysqlgtGRANT FILE ON TO repl1921680200 IDENTIFIED BY lsquoabc123rsquo mysqlgtq 上面是 Master開放一個帳號 repl密碼 abc123給 IP1921680200有檔案處理

的權限 Step3 shutdown MySQL on the Master mysqladmin ndashu root ndashp shutdown Step4 備份 Master所有資料庫 tar ndashcvf tmpmysql-snapshottar varlibmysql 注意tar的時候MySQL是要在 stop情況下 在mysql (wwwmysqlcom) 網站的FAQ有不用shutdown的方法

92

Step5 在 master機器上修改etcmycnf 在[mysqld]區段內加入參數 log-bin server-id=這邊設定 server-id=1 sql-bin-update-same binlog-do-db=CRM只針對 CRM資料庫做紀錄 Step6 Restart MySQL on the master service mysqld start 此時因為有加入 log-bin 參數因此開始有 index產生了在varlibmysql目錄下

有index檔案紀錄資料庫的異動 log Slave server 部份 Step1 在 slave設定etcmycnf 在[mysqld]區段加入 master-host= master-user= master-password= master-port= server-id= 這邊設定 master-host=1921680100 master-user=repl master-password=abc123 master-port=3306 server-id=2 master-connect-retry=60預設重試間隔 60秒 replicate-do-db=CRM告訴 slave只做 CRM資料庫的更新 log-slave-updates Step2 將 master上的 mysql-snapshottar copy到 slave上 用 ftp傳到 slave的tmp Step3 解壓縮 Master資料庫至 Slave Server上 cd varlib tar xvf tmpmysql-snapshottar chown ndashR mysqlmysql mysql

93

chmod ndashR 770 mysql (視情況) Step4 Restart MySQL on the slave server 這時在varlibmysql目錄會出現 masterinfo此檔案紀錄了 Master MySQL server的資訊

狀況測試

One-way replication

1921680100

1921680200Master Server

erveSlave S r

圖 One-way replication架構圖 Step1 Master跟 Slave網路及服務都正常情況下由 Master端異動資料後 到 Slave端瀏覽資料檢視是否有進行 replication Step2 模擬 Slave Server 當機 可用在於 slave真的當機或是 Slave 不一定需要一直跟 master connect將Slave MySQL server shutdown由 Master端異動資料到 slave端瀏覽此時Slave應該沒有被 replication 更新然後再將 Slave端 MySQL server start起來

預設 60秒後 Slave會嘗試跟 Master要求進行 replication再去 Slave端檢視是否有更新資料

94

Step3 模擬 Master當機因為是設定 One-way replication一旦 Master Server Slave端沒有 Master的 source可以 download Two-way replication 基於 Master當機狀況於是發展雙向 Replication即 1921680100 ( Host A ) 1921680200 ( Host B )都分別擔任 MasterSlave身分

1921680100

1921680200er

Server B MasterSlave Server

Server A MasterSlave Serv

圖 Two-way replication架構圖 以下是針對兩台 MySQL伺服器進行雙向 Replication Step1觀念同單向 replication只是改成 Master也有 Slave身分 Slave也有Master的身分先分別在 Server AServer B 都去 grant一個進行 replication的身分 [A]mysqlgtGRANT FILE ON TO repl1921680200 IDENTIFIED BY lsquoabc123rsquo [B]mysqlgt GRANT FILE ON TO repl1921680100 IDENTIFIED BY lsquoabc123rsquo Step2做完單向 replication後stop Server Aserver B MySQL service此時 AB資料是一樣的

95

修改etcmycnf設定 範例 Server A [mysqld] datadir=varlibmysql socket=varlibmysqlmysqlsock server-id=1 log-bin sql-bin-update-same binlog-do-db=CRM master-host=1921680200 master-user=repl master-password=abc123 log-slave-updates master-connect-retry=60 replicate-do-db=CRM Server B [mysqld] datadir=varlibmysql socket=varlibmysqlmysqlsock server-id=2 log-bin sql-bin-update-same binlog-do-db=CRM master-host=1921680100 master-user=repl master-password=abc123 log-slave-updates master-connect-retry=60 replicate-do-db=CRM 分別 start Server AServer B MySQL後此時雙方都是 MasterSlave身分一旦哪一方資料異動就會通知對方來 replication-若 replication失效則必須將Server AServer B的masterinfo及index00x 都砍掉然後分別 restart MySQL server進行測試檢視成果 實務上通常如果需要做Two-way replication通常會搭配Virtual Server使用

96

在前端架設一台Virtual Server不過此部份不在此份SOP討論範圍內有興趣

的讀者可參考 httpwwwlinuxvirtualserverorg 網站

1921680100 1921680200

Host A MasterSlave Server

Host B MasterSlave Server

Virtual Host

圖 Virtual Server + Two-way replication 架構圖

97

圖 High Availability Linux Virtual Server架構圖

98

  • COSA-SOP-03-006
  • 第一章 簡介
    • 11適用對象 (Audience)
    • 12 MySQL本身
    • 13 MySQL 40版跟50版重大的改進功能
    • 14 各家資料庫軟體比較
      • 第二章 前置需求
      • 第三章 安裝
        • 31 MySQL安裝
        • 32 phpMyAdmin安裝
        • 33 升級及注意事項
          • 第四章 MySQL管理
            • 41 Webmin 管理介面
            • 42 phpMyAdmin 的操作介面
            • 43管理指令介紹
              • 431 利用mysqladmin設定root的密碼
                  • 第五章 實用範例
                    • 51 任務一Web Base客戶通訊錄
                    • 52 任務二Web Base群組軟體 ( twig )
                      • 第六章 維護及更新程序
                        • 61 日常維護
                        • 62 更新程序
                        • 63 備份重要檔案
                        • 64 離線備份與還原
                        • 65 線上備份與還原
                          • 第七章 問題與解答
                          • 第八章 參考資料
                          • 附錄一 SQL Command 介紹
                          • 附錄二Replication
Page 25: DataBase Server Standard Operation Procedureebooks.lib.ntu.edu.tw/1_file/oss/63/93doc4-5.pdf · 業務的公司帶來了不少壓力,譬如微軟,甲骨文 ... 外的錢用在第三方的資料庫產品上,譬如就可以不用再購買甲骨文公司

圖 3-22 Install MySQL 4014 相關 RPM

圖 3-23 Install MySQL 4014 相關 RPM

Step 3 啟動 MySQL

25

圖 3-24 啟動 MySQL 4014 並修改密碼

26

第四章 MySQL管理

本章將我們介紹利用WebminphpAdminCommand的方式建立一個名為

CONTACT的資料庫內有一個 address的 Table作為我們客戶通訊錄程式使

用的資料庫

41 Webmin 管理介面

412建立資料庫

Step 1 登入Webmin

圖 4-1 登入WebMin

Step 2 點選伺服器

27

圖 4-2 伺服器畫面

Step 3 點選 MySQL資料庫伺服器

圖 4-3 MySQL資料庫伺服器

28

Step 4 建立一個新的資料庫

圖 4-4 建立 MySQL資料庫

Step 5 建立名為 CONTACT的資料庫

29

圖 4-5 指定資料庫名稱

412 建立資料表

假設我們要建立一個名為 address的 Table其結構如下 欄位名稱 資料型態 長度 說明 id INT (自動編號) 連絡人編號 name varchar文字 20 連絡人姓名 tel Varchar文字 15 連絡人電話 Step 1 選擇 CONTACT資料庫

30

圖 4-6 選擇資料庫

Step 2 指定欄位數目

31

圖 4-7 設定欄位數目

Step 3設定表格欄位屬性

圖 3-8 設定表格欄位屬性

Step 4建立表格資料

32

圖 4-9 建立表格資料

圖 4-10 檢視資料

33

圖 4-11 新增資料

圖 4-12

34

圖 4-13

413 使用者管理

接下來我們要利用Webmin 來建立資料庫使用者並給予某些權限 Step1建立使用者

35

圖 4-14 選擇使用者權限

圖 4-15

36

Step2 賦予權限

圖 4-16

Step3 權限列表

37

圖 4-17

38

42 phpMyAdmin 的操作介面

421建立資料庫

Step 填入資料庫名稱並按「建立」

圖 4-18建立資料庫

422 建立資料表

Step1 填入資料表名稱並指定欄位數量 執行

39

圖 4-19填入資料表名稱並指定欄位數量

Step2 設定欄位屬性

圖 4-20設定欄位屬性

40

Step3 phpMyAdmin會產生相關的 SQL Command

圖 4-21 資料表結構及相關 SQL Command

Step4新增 Record

41

圖 4-22

圖 4-23

42

圖 4-24

圖 4-25

43

423使用者管理

Step1建立使用者

圖 4-26

44

圖 4-27

Step2 給予權限

圖 4-28

Step3權限列表

45

圖 4-29

43管理指令介紹

431 利用 mysqladmin設定 root的密碼

當您在Windows 或 Linux 中安裝好 MySQL後系統會自動幫您建立兩個

帳分別是 root 和 匿名者MySQL的 root 跟 Linux 最高權限使用者 root無關MySQL的 root使用者相當於 MS SQL 中的 sa 帳號擁有最高的 Database管理權限但系統預設 MySQL的 root 是不需要密碼所以通常我們一安裝

MySQL後首要任務便是修改 root的密碼 我們可以利用 mysqladmin工具或是直接修改 MySQL內部資料庫的使用者資

料 mysqladmin ndashu root ndashh cosaexamplecom password lsquo1234rsquo

46

-u 表示使用者帳號root 為 MySQL預設的管理帳號

-h 表示 MySQL主機的主機名稱也可使用 IP Address password 表示使用者的密碼因為字串請使用單引號將密碼括起來 密碼設定完成之後還是可以利用 mysqladmin修改密碼但是你必須提供目前的密碼

432 連線 MySQL

mysql -uroot -p密碼 (-p和密碼之間不能有空白) 或 mysql -uroot -p (此方式會在進入後要求密碼) [rootossc phpMyAdmin] mysql -u root -p1234

Welcome to the MySQL monitor Commands end with or g

Your MySQL connection id is 25 to server version 32354

Type help or h for help Type c to clear the buffer

mysqlgt show databases

+----------+

| Database |

+----------+

| mysql |

| test |

+----------+

2 rows in set (000 sec)

mysqlgt exit

Bye

[rootossc phpMyAdmin]

433 建立資料庫

可利用 mysqladmin指令建立 CONTACT資料庫 mysqladmin -u root -p1234 create CONTACT

47

或是利用 mysql指令 [rootossc bluepage] mysql -u root -p1234 Welcome to the MySQL monitor Commands end with or g Your MySQL connection id is 1057 to server version 32354 Type help or h for help Type c to clear the buffer mysqlgt create database CONTACT Query OK 1 row affected (000 sec) mysqlgt show databases +----------+ | Database | +----------+ | CONTACT | | address | | hello | | mysql | | nuke | | test | +----------+ 6 rows in set (000 sec) mysqlgt exit

434 建立資料表

編寫 adresssql內容如下 -- Table structure for table address CREATE TABLE address ( id int(11) NOT NULL auto_increment name varchar(20) NOT NULL default tel varchar(15) NOT NULL default PRIMARY KEY (id) ) TYPE=MyISAM

48

-- Dumping data for table address INSERT INTO address VALUES (1林小明0800016888) INSERT INTO address VALUES (2黃大雄0800016888) INSERT INTO address VALUES (3劉小芬0800024365) 然後執行此 sql script mysql -u root -p1234 CONTACT lt addresssql 或是利 mysql command [rootossc bluepage] mysql -u root -p1234 Welcome to the MySQL monitor Commands end with or g Your MySQL connection id is 1090 to server version 32354 Type help or h for help Type c to clear the buffer mysqlgt use CONTACT Database changed Database changed mysqlgt CREATE TABLE address ( -gt id int(11) NOT NULL auto_increment -gt name varchar(20) NOT NULL default -gt tel varchar(15) NOT NULL default -gt PRIMARY KEY (id) -gt ) TYPE=MyISAM Query OK 0 rows affected (000 sec) mysqlgt INSERT INTO address VALUES (1林小明0800016888) Query OK 1 row affected (000 sec) mysqlgt INSERT INTO address VALUES (2黃大雄0800016888) Query OK 1 row affected (000 sec) mysqlgt INSERT INTO address VALUES (3劉小芬0800024365) Query OK 1 row affected (000 sec) mysqlgt exit Bye

49

第五章 實用範例

51 任務一Web Base客戶通訊錄

任職於開放科技公司的林小明前些日子在最符合成本效益的條件下快

速地完成公司網站的建置老闆因此對小明讚譽有加最近因為公司存放客戶資

料的 SQL Server主機屢遭病毒攻擊加上作業系統本身的問題當機次數頻繁

老闆希望能儘快把公司的客戶通訊錄程式移轉到較穩定的環境上因為此客戶通

訊錄程式最主要給內部人員使用所以介面美觀並不特別要求只求穩定且能快

速得到查詢結果老闆希望在短時間先看到程式的雛型並鍵入資料對其效率

及穩定性進行測試因為上次小明表現突出所以這次不可能的任務自然又落到

小明身上 小明想來想去既然要快速又穩定他而且又不希望所有人都得安裝 Client

程式於是小明決定)捨棄他的舊愛「Delphi+MS SQL」投向新歡「Apache + MySQL + PHP」利用此架構來設計一個簡單實用的Web Base客戶通訊錄程式

511 Web Base客戶通訊錄架構

此程式需要建立 CONTACT的資料庫並建立 adress Tables其結構如下表建立步驟請參考第三章 欄位名稱 資料型態 長度 說明 id INT (自動編號) 連絡人編號 name varchar文字 20 連絡人姓名 tel Varchar文字 15 連絡人電話 Web Base通訊錄共有下列幾個檔案功能如下表

檔案名稱 說明 Indexhtml Web Base通訊錄首頁 addphp 新增連絡人的 php程式 searchphp 尋找連絡人的 php程式 editphp 具有更新及刪除功能的 php程式

50

我們將這些檔案放至varwwwhtmlbluepage (預設無 bluepage目錄)

512 Web Base通訊錄測試

httpwwwopencombluepage 新增資料

圖 5-1 新增連絡人

圖 5-2 填入資料

51

圖 5-3 新增成功

搜尋及異動資料

圖 5-4 搜尋通訊錄

52

圖 5-5 編輯資料

圖 5-6 更新資料

513 程式內容及說明

lt-- 程式範例indexhtml--gt lthtmlgt ltheadgtlttitlegt通訊錄lttitlegtltheadgt ltbodygt ltcentergt

53

lth2gt通訊錄lth2gtlthrgt lta href=indexhtmlgt通訊錄ltagt | lta href=addphpgt新增連絡人ltagt | lta href=searchphpgt搜尋通訊錄ltagt ltcentergt ltbodygt lthtmlgt lt-- 程式範例addphp --gt lthtmlgt ltheadgtlttitlegt新增連絡人lttitlegtltheadgt ltbodygt ltcentergtlth2gt新增連絡人lth2gtltcentergtlthrgt lt 取得欄位資料 if (isset($_POST[Name]) ampamp isset($_POST[Tel]) ) $name = $_POST[Name] $tel = $_POST[Tel] 檢查是否有輸入欄位資料 if ($name = ampamp $tel = ) 建立 SQL字串 $sql = INSERT INTO address (name tel) values( $sql= $name $tel) 建立 MySQL 連結 $link = mysql_connect(localhostroot1234) 選擇資料庫 mysql_select_db(CONTACT) 執行 SQL指令 mysql_query($sql) mysql_close($link) echo ltfont color=redgt新增連絡人成功ltfontgtltbrgt gt ltform action=addphp method=postgt lttable border=0 width=300gt lttrgtlttdgt姓名 lttdgt

54

lttdgtltinput type=text name=Name size=20 maxlength=10gtlttdgtlttrgt lttrgtlttdgt電話 lttdgt lttdgtltinput type=text name=Tel size=20 maxlength=20gtlttdgtlttrgt lttrgtlttd colspan=2 align=centergt ltinput type=submit value=新增連絡人gtlttdgtlttrgt lttablegt ltformgt ltbrgtlta href=indexhtmlgt通訊錄ltagt | lta href=addphpgt新增連絡人ltagt | lta href=searchphpgt搜尋通訊錄ltagt ltbodygt lthtmlgt

lt-- 程式範例searchphp --gt lthtmlgt ltheadgtlttitlegt搜尋通訊錄lttitlegtltheadgt ltbodygt ltcentergtlth2gt搜尋通訊錄lth2gtlthrgt lt if (isset($_POST[Search])) 建立資料庫連結並選定資料庫 $link = mysql_connect(localhostroot1234) mysql_select_db(CONTACT) 建立基本的 SQL字串 $sql = SELECT FROM address 檢查是否輸入姓名 if (chop($_POST[Name]) = ) $name = name LIKE $_POST[Name] else $name = 檢查是否輸入電話號碼 if (chop($_POST[Tel]) = ) $tel = tel LIKE $_POST[Tel] else $tel =

55

if條件組合 SQL字串 if (chop($name) = ampamp chop($tel) = ) $sql= WHERE $name AND $tel elseif (chop($name) = ) 只有姓名 $sql = WHERE $name elseif (chop($tel) = ) 只有電話號碼 $sql = WHERE $tel $sql= ORDER BY name 最後加上排序 $result = mysql_query($sql) 取得欄位數 $total_fields = mysql_num_fields($result) echo lttable border=1gt echo lttrgtlttdgt編號lttdgtlttdgt姓名lttdgtlttdgt電話lttdgtlttd colspan=2gt功能選項lttdgtlttrgt 表格顯示查詢結果 while ($rows = mysql_fetch_array($result MYSQL_NUM)) echo lttrgt for ($i = 0 $i lt $total_fields $i++) echo lttdgt$rows[$i]lttdgt echo lttdgtlta href=editphpaction=editampid= echo $rows[0]gtltbgt編輯ltbgtlttdgt echo lttdgtlta href=editphpaction=delampid= echo $rows[0]gtltbgt刪除ltbgtlttdgt echo lttrgt echo lttablegtlthrgt mysql_free_result($result) mysql_close($link) gt ltcentergt ltform action=searchphp method=postgt lttable border=0 width=450gt lttrgtlttdgt搜尋姓名 lttdgt lttdgtltinput type=text name=Name size=10 maxlength=20gtlttdgtlttrgt lttrgtlttdgt搜尋電話 lttdgt lttdgtltinput type=text name=Tel

56

size=20 maxlength=20gtlttdgtlttrgt lttrgtlttd colspan=2 align=centergt ltinput type=submit name=Search value=搜尋gtlttdgtlttrgt lttablegt ltformgt ltbrgtlta href=indexhtmlgt通訊錄ltagt | lta href=addphpgt新增連絡人ltagt | lta href=searchphpgt搜尋通訊錄ltagt ltbodygt lthtmlgt

lt ob_start() gt lt-- 程式範例editphp --gt lthtmlgt ltheadgtlttitlegt編輯通訊錄lttitlegtltheadgt ltbodygt lt 取得 URL 參數 $id = $_GET[id] $action = $_GET[action] 建立資料庫連結 $link = mysql_connect(localhostroot1234) mysql_select_db(CONTACT) 選擇資料庫 執行的操作 switch ($action) case update 更新 取得欄位資料 $name = $_POST[Name] $tel = $_POST[Tel] $sql = UPDATE address SET name=$name tel=$tel WHERE id=$id mysql_query($sql) 執行 SQL指令 mysql_close($link) header(Location searchphp) 轉向到 serachphp break case del 刪除 $sql = DELETE FROM address WHERE id=$id

57

mysql_query($sql) 執行 SQL指令 mysql_close($link) header(Location searchphp) 轉向到 serachphp break case edit 編輯 $sql = SELECT FROM address WHERE id=$id $result = mysql_query($sql) 執行 SQL指令 $row = mysql_fetch_row($result) 取回記錄 $name = $row[1] 取得欄位 name $tel = $row[2] 取得欄位 tel mysql_close($link) 顯示編輯表單 gt ltcentergtlth2gt更新通訊錄lth2gtltcentergtlthrgt ltform action=editphpaction=updateampid=lt echo $id gt method=postgt lttable border=0 width=300gt lttrgtlttdgt姓名 lttdgt lttdgtltinput type=text name=Name size=20 maxlength=10 value=lt echo $name gtgtlttdgtlttrgt lttrgtlttdgt電話 lttdgt lttdgtltinput type=text name=Tel size=20 maxlength=20 value=lt echo $tel gtgtlttdgtlttrgt lttrgtlttd colspan=2 align=centergt ltinput type=submit value=更新連絡人gtlttdgtlttrgt lttablegt ltformgt ltbrgtlta href=indexhtmlgt通訊錄ltagt | lta href=addphpgt新增連絡人ltagt | lta href=searchphpgt搜尋通訊錄ltagt lt break gt ltbodygt lthtmlgt

58

52 任務二Web Base群組軟體 ( twig )

順利完成Web Base客戶通訊錄程式測試一段時間後「Apache + MySQL + PHP」架構的穩定與快速巳深得老闆與公司所有同事的認同隨著公司業績蒸

蒸日上人員組織編罝愈來愈龐大跨部門的會議愈來愈多業務員每日排滿拜

訪客戶的行程跟客戶的 Email的往來也愈來愈頻繁 愈來愈多部門的同事希望公司能建置一套群組軟體提供 web mail可讓業

務人員方便收發 mail還有連絡人議事日程待辦工作書簽等功能讓整個

公司運作及個人時間管理更有效率

老闆問小明對這些需求有什麼看法小明認為如果這些功能完全由程式部

門開發必定曠日費時而且耗費公司資源小明在網路尋找是否有提供這些功能

的Free Software皇天不負苦心人小明發現了TWIG (The Web Information Gateway) httptwigscrewdrivernet這個群組軟體它在 Web 上整合郵件新聞聯絡人議事日程工作序書簽等功能非常符合公司的需求 Step 1 下載 twig-277targz 下載網址 httptwigscrewdrivernetdownloadphp3

Step 2 解開 twig-277targz tar -xzvf twig-277targz

59

Step 3 執行安裝動作安裝到 varwwwhtmltwig 目錄 cd twig-277 twig-install varwwwhtmltwig

Step 4 建立 MySQL 資料庫(twig)及各資料表

cd setup mysql -u root -p1234 mysqlgt create database twig Query OK 1 row affected (001 sec) mysqlgt quit mysql -u root ndashp1234 twiglt twigtablemysql

Step 5 修改 configincphp3 參數設定 vi varwwwhtmltwigconfigconfigincphp3 $config[fromdomain] = opencom 網域 $config[language] = chinesebig5 中文訊息 $config[imap_port] = 143notls

60

Step 6 修改連結 MySQL 的帳號密碼 vi varwwwhtmltwigconfigdbconfigincphp3 $dbconfig[sqlusername] = root username $dbconfig[sqlpassword] = 1234 password

Step 7 其他設定檔

vi etchttpdconfhttpdconf 加入 AddType applicationx-httpd-php php3 在 DirectoryIndex最後加入 indexphp3 DirectoryIndex indexhtml indexhtmlvar indexphp3 在 AddDefaultCharset ISO-8859-1加上 AddDefaultCharset ISO-8859-1

vi etcphpini register_globals = On service httpd restart Step 8 sendmail 設定 vi etcmailsendmailcf在 264 行前面加上並重新啟動 sendmail「service snedmail restart」 262 SMTP daemon options 263 264 O DaemonPortOptions=Port=smtpAddr=127001 Name=MTA 265 266 SMTP client options 267 O ClientPortOptions=Family=inet Address=00

61

Step 9 檢查設定有無錯誤 http主機名稱twigtestphp3

62

Step 10 登入 twig ( http主機名稱twig)

63

第六章 維護及更新程序

61 日常維護

系統管理員最好定期以 root 身份登入看看信件在 RedHat Linux 中有一支 logwatch 程式會定時去分析 log file如果發現異常便會發信給 root除此之外筆者建議讀者平時就檢查 MySQL log file ( varlogmysqldlog)是否有異常情形

62 更新程序

讀者可至httprpmfindnet 尋找MySQL相關套件至於升級的相關步驟請參

考Linux OS SOP 第 54節

63 備份重要檔案

預設 MySQL 的 DB 檔案是存在 varlibmysql 內以 DB名稱為目錄目錄

內就是該 DB 的所有資料通常得定期備份還有 MySQL的設定檔 etcmycnf也別忘了一起備份

64 離線備份與還原

641 離線備份

預設 MySQL 的 DB 檔案是存在 varlibmysql 內以 DB 名稱為目錄目錄內

就是該 DB 的所有資料像 CRM 這個 DB就是存在 varlibmysqlCRM 內在備份前因為怕資料尚未完全寫入磁碟而且 MySQL 會 Lock 在使用的 DB 檔案所以應該是要先把 MySQL 先 Shutdown 一下整個備份的程序可以下像下面的指令去完成 cd varlibmysql

64

service mysqld stop tar cvfz CRM_db_20030905tgz CRM service mysqld start 對這樣就可以了 不過要注意的是怕 DB 內每個 Tables 間的資料有關關

聯性所以最好是把整個 DB 一次備起來單獨只備哪個 Tables 的檔案以後回存時怕會有資料關聯不一致的問題

642 離線還原

DB 發生錯誤而要回存時其實也不難先找出最近一次完整正常的備份先把現在錯誤的網頁或 DB 先更名或 tar 起來再把好的備份給解開回原來目錄位

置就行了需要注意的是 MySQL 服務最好也是要先停止回存完成後再啟動服務回存 DB 的整個程序可能像下面 cd varlibmysql service mysqldstop mv CRM CRM_OLD tar xvfz CRM_db_20030905tg service mysqld start

65 線上備份與還原

651 線上備份

使用像上面的檔案方式備份是個不錯的方法它最少可以保持該主機某個時間點的完整檔案備份但還是有一些問題需要考慮到有些主機就不只建立一個 DB 而已總不能為了備份某個 DB 而把整個 MySQL 服務停止備份檔案的方式回存在原主機上一定適用但假如 MySQL 版本升級或是在那天該網頁空間需遷機移機到別的主機時那就沒人敢保證備出來的資料檔可以用所以我們可以考慮另一種備份的方式是使用 MySQL 本身提供的功能 MySQL Data Dump指令是 mysqldump

65

使用 MySQL 的 Dump 功能可以把 DB 的結構資料或結構加資料 Dump 成文字檔 mysqldump 指令提供的彈性很大你可以選擇把整個 DB Dump 成一個檔或是每個 Table 為一個檔甚至是把結構檔和資料分開儲存都

可以 mysqladmin -uroot -p flush-logs mysqldump CRM -uroot -p --opt gt CRM_20030905sql (CRM 是 DB 名稱 opt 是一個使用完整 Dump 參數) 假如只是要單獨 Dump 某個 Table 時只要在上面的指令後轉出符號 gt 前加個 Table 名稱就可以如只要 phpbb2_users 這個 Table 的 Dump 時只要下 mysqldump CRM -uroot -p --opt CUSTOMER gt CRM_CUSTOMER_20030905sql

652 線上還原

若要回存整個資料庫只需將壓縮的備份檔還原成 Dump 的檔案再用下面的指令回存 mysql CRM -uroot -p lt CRM_20030905sql 這邊需注意的是若建立備份時是以--opt或--add-drop-table為參數時回存的 動作是先將舊的 Table 先刪除重建 Table 的結構後再把 Data 匯入所以回存後所有的資料會回到你當時備份那個時間點因此在回存資料時可以考慮把現有錯誤或不完整的 DB 先備份一份下來以備不時之需或是拿來比對錯誤的地

方在那裡當然你也可以把資料回存到另一個測試用的 DB 內只要把上面指令

的 DB 名稱改成你的測試用 DB 名稱即可 使用這種回存方式 MySQL 服務不需停止也不會動到其他正在使用的 DB 在一些提供 MySQL 服務的虛擬主機可用這種方式作你自己的 DB 備份及回存

66

另外假如你是系統重建或是移機時切需在新的 MySQL 內新建一個空白 DB 後才行作回存的工作你可以用下面的指令建立 mysql -uroot -p -e CREATE DATABASE CRM (上面的 CRM是你要新建的 DB 名稱) 另一種作法先用 mysql 指令進入 mysql client console 然後再用 CREATE DATABASE CRM 這樣就行了記得尾端要加個 符號該行指令才會執行

67

第七章 問題與解答

Q1RedHat 90預附的 MySQL到底有無支援 Transcation機制 Ans MySQL自 32334a之後的 MySQL-Max版本加入 InnoDB的資料庫類型透過

InnoDBMySQL同樣可以進行 COMMIT與 ROLLRACK的動作RedHat 90預附的 MySQL為 32354a-11巳支援 InnoDB的資料庫類型不過必須做以

下設定 1cp usrsharedocmysql-server-32354amy-mediumcnf to etcmycnf 2 vi etcmycnf 將以下設定前的拿掉 innodb_data_home_dir = varlibmysql innodb_data_file_path = ibdata110Mautoextend innodb_log_group_home_dir = varlibmysql innodb_log_arch_dir = varlibmysql 3service mysqld restart 如此一來各位在建立Table時便可指定Table Type為 innodb ( ex create table with type=innodb ) Q2如何解決 php+mysql 許功蓋等字變亂的問題 Ans 方法一 【確定 MySQL 預設的字元集】 1 打開 WinMySQLadmin 管理畫面(在視窗右下角狀態列紅綠燈圖示中按滑鼠

右鍵點選 Show me 選項) 2 點選管理畫面中 [Variables] 標籤選項其中 character_set變數就是您預設

字元集的變數其預設是 latin1 字元集(我們要將他改回 big5)而 chatacters_set 變數則是 MySQL 可以支援哪些字元集 【修改預設字元集變數 character_set 】 1 請點選管理畫面中 [myini Setup] 標籤選項設定 myini 2 按一下 [Pick-up and Edit myini values] 按鈕以便編輯目前的 myini 設定 3 在 [mysqld] 設定區塊底下新增一行 default-character-set = big5 變數設

68

定 4 新增一個 [client] 設定區塊並加入第三步驟的變數設定(游標往下移到空白處新增兩行 [client] 和 default-character-set=big5) 5 按一下畫面左下方 [Save Modification] 按鈕儲存設定 6 重新啟動 MySQL 或 Windows 方法二 Server端注意事項 phpini 中有關的設定為(預設值) Magic quotes for incoming GETPOSTCookie data magic_quotes_gpc = On Use Sybase-style magic quotes (escape with instead of ) magic_quotes_sybase = Off Client端注意事項 1中文資料送進 mysql 前請用 addslashes($str) 處理 2處理後送進 mysql 時請用 括起來並在參數後留一個空白如 $sql = UPDATE ezf_table set tablename=$tname tableend=$endtime table inguser=$tguser tableingid=$tguserid tableallnumber=$tnumber tableloca l=$tablelocal tableanyone=$tableopen tabletext=$ttext WHERE tableid=$t ableid tablename=$tname c 取出時請用 stripslashes($str) Q3MySQL root 密碼忘了該怎麼辦 Ans 1先停掉 mysql etcrcdinitdmysql stop 2以--skip-grant-table 的參數啟動 mysql safe_mysql --skip-grant-tableamp 3 更改 root 密碼 mysql mysql mysqlgt UPDATE user SET password=password(newpassword)

69

WHERE user=root mysqlgt FLUSH PRIVILEGES mysqlgt exit 4停掉 mysql再重跑 mysqladmin -uroot -p shutdown Enter password 輸入新設定的密碼 etcrcdinitdmysql start

Q4NULL值問題

Ans

NULL值的概念是造成 SQL的新手的混淆的普遍原因他們經常認為 NULL是和一個空字符串的一樣的東西不是這樣的例如下列語句是完全不同的

mysqlgt INSERT INTO my_table (phone) VALUES (NULL)

mysqlgt INSERT INTO my_table (phone) VALUES ()

兩個語句把值插入到 phone 列但是第一個插入一個 NULL值而第二個插入一個空字符串第一個的含義可以認為是ldquo電話號碼不知道而第二個則可意味

著ldquo她沒有電話

在 SQL中NULL值在于任何其他值甚至 NULL值比較時總是假的(FALSE)包含 NULL的一個表達式總是產生一個 NULL值除非在包含在表達式中的運算符和函數的文檔中指出在下列例子所有的列返回 NULL

mysqlgt SELECT NULL1+NULLCONCAT(InvisibleNULL)

如果你想要尋找值是 NULL的列你不能使用=NULL測試下列語句不返回任

何行因為對任何表達式expr = NULL是假的

mysqlgt SELECT FROM my_table WHERE phone = NULL

要想尋找 NULL值你必須使用 IS NULL測試下例顯示如何找出 NULL電話號碼和空的電話號碼

70

mysqlgt SELECT FROM my_table WHERE phone IS NULL mysqlgt SELECT FROM my_table WHERE phone =

在 MySQL中就像很多其他的 SQL服務器一樣你不能索引可以有 NULL值的列你必須聲明這樣的列為 NOT NULL而且你不能插入 NULL到索引的

列中

當用 LOAD DATA INFILE 讀取數據時空列用更新如果你想要在一個列中有

NULL值你應該在文本文件中使用N字面上的詞NULL也可以在某些情形下使用

當使用 ORDER BY時首先呈現 NULL值如果你用 DESC以降序排序NULL值最後顯示當使用 GROUP BY時所有的 NULL值被認為是相等的

為了有助于NULL的處理你能使用 IS NULL和 IS NOT NULL運算符和 IFNULL()函數

對某些列類型NULL值被特殊地處理如果你將 NULL插入表的第一個TIMESTAMP 列則插入當前的日期和時間如果你將 NULL插入一個AUTO_INCREMENT 列則插入順序中的下一個數字

Q5如何將圖片存放於 MySQL中

Ans

Step 1建立資料庫 test

Step 2 建立表格 binary_data

CREATE TABLE binary_data (

id INT(4) NOT NULL AUTO_INCREMENT PRIMARY KEY

description CHAR(50)

bin_data LONGBLOB

filename CHAR(50)

filesize CHAR(50)

filetype CHAR(50)

71

)

Step 3 利用 storephp 寫入圖片

storephp 程式碼

ltHTMLgt ltHEADgtltTITLEgtStore binary data into SQL DatabaseltTITLEgtltHEADgt ltBODYgt lt code that will be executed if the form has been submitted

if ($submit) mysql_connect(localhostrootYOUR_PASSWORD) mysql_select_db(test) $data=Base64_Encode(fread(fopen($form_data r) filesize($form_data))) $result=MYSQL_QUERY(INSERT INTO binary_data (descriptionbin_datafilenamefilesizefiletype) VALUES ($form_description$data$form_data_name$form_data_size$form_data_type)) $id= mysql_insert_id() print ltpgtThis file has the following Database ID ltbgt$idltbgt MYSQL_CLOSE() else else show the form to submit new data

gt

ltform method=post action=ltphp echo $PHP_SELF gt enctype=multipartform-datagt File Descriptionltbrgt ltinput type=text name=form_description size=40gt ltINPUT TYPE=hidden name=MAX_FILE_SIZE value=4000000gt ltbrgtFile to uploadstore in databaseltbrgt ltinput type=file name=form_data size=40gt ltpgtltinput type=submit name=submit value=submitgt ltformgt lt

72

gt ltBODYgt ltHTMLgt

Step 3 利用 storephp 取出圖片

getdataphp 程式碼

lt Syntax getdataphp3id=ltidgt if($id) you may have to modify login information for your database server MYSQL_CONNECT(localhostrootYOUR_PASSWORD) mysql_select_db(test) $query = select bin_datafiletype from binary_data where id=$id $result = MYSQL_QUERY($query) $data = Base64_Decode(MYSQL_RESULT($result0bin_data)) $type = MYSQL_RESULT($result0filetype) Header( Content-type $type) echo $data gt

Q6MySQL裝好之後啟動時或是執行 mysqladmin會出現如下訊息 Cant connect to local MYSQL Server through Socket varlibmysqlmysqlsock或是

Cant connect to local MYSQL Server through Socket tmpmysqldsock

Ans 可能有下列幾個原因

1這個 mysqldsock 不見了被某人刪除了或是被一些系統自動執行程式給刪

了例如有些 cron任務便會設定定期刪除 tmp 裡的東西所以呢您只能修改

cron 裡的設定讓它不要清除 mysqldsock 2在啟動時也可以改變 mysqldsock的位置您在啟動 MySQL的時候可以加入此參數usrlocalmysqlbinsafe_mysqld --user=mysql --socket=其他路

徑socket amp 同時得去設定環境變數 MYSQL_UNIX_PORT的值以指定新的

73

路徑 3若是您沒改 MYSQL_UNIX_PORT的值那麼您可以在執行指令的時候才打

例如mysqladmin --socket=其他路徑socket version Q7How to get the last insert id Ans CREATE TABLE product ( id INT(4) NOT NULL AUTO_INCREMENT PRIMARY KEY description VARCHAR(50) ) 1利用 SQL的話 mysqlgt insert into product(description) values(123) Query OK 1 row affected (000 sec) mysqlgt select last_insert_id() +------------------+ | last_insert_id() | +------------------+ +------------------+ 1 row in set (000 sec) ======================================== 2如果是 PHP的話 你可以用mysql_insert_id()取得該 id PHP example $result=MYSQL_QUERY(INSERT INTO product (description) VALUES ($description)) $id= mysql_insert_id() print This file has the following Database ID $id Q8如何將文字檔匯入資料庫 Ans $addr=homehttpdhtmlphpschool001txt $sql_select = load data infile $addr into table test fields terminated by t 解說 $sql_select = load data infile 文字檔名 into table 表格名 fields terminated by

74

t

(欄位分隔以 TAB鍵) 該文字檔須與資料表欄位格式相符 例如欄位有三個 則文字檔為每行一筆資料如下 欄 1資料ltTABgt欄 2資料ltTABgt欄 3資料 欄 1資料ltTABgt欄 2資料ltTABgt欄 3資料 欄 1資料ltTABgt欄 2資料ltTABgt欄 3資料 欄 1資料ltTABgtltTABgt欄 3資料

Q9如何撰寫 MySQL C API Ans Step 1利用文字編輯器撰寫以下程式碼 mysqlcc

include ltstdiohgt

include ltmysqlmysqlhgt

int main (int argc char argv[])

MYSQL mysql

MYSQL_RES res

MYSQL_ROW row

if (argc = 2)

fputs (Usage myc ltdatabasegt stderr)

return 1

if ((mysql_connect(ampmysqllocalhostrootYour_Password)))

fputs (Error connecting stderr)

abort()

75

if (mysql_select_db(ampmysqlargv[1]))

fputs (Error selecting database stderr)

abort()

if (mysql_query(ampmysqlSELECT FROM test_table))

fputs (Error processing query stderr)

abort()

if ((res = mysql_store_result(ampmysql)))

fputs (Error storing results stderr)

abort()

while((row = mysql_fetch_row(res)))

uint i = 0

for (i=0 i lt mysql_num_fields(res) i++)

printf(s row[i])

printf(n)

return 0

Step 2 Compile

gcc -Iusrlocalmysqlinclude -Lusrlocalmysqllibmysql mysqlcc ndashlm -lmysqlclient

(其中 include path與 library path取決於你的 MySQL安裝路徑)

76

如果執行時發生如下 error Run problemerror in loading shared libraries libmysqlclientsoX 將你的 MySQL library path(for exampleusrlocalmysqllibmysql) 加入etcldsoconf and run sbinldconfig -v Q9ASP + MySQL 範例程式 Ans Dim myconn As New ADODBConnection Dim myrs As New Recordset Dim mySQL As String Dim myrows As Long myconnOpen DSN=MyODBCsample mySQL = SELECT from user myrsSource = mySQL Set myrsActiveConnection = myconn myrsCursorLocation = adUseClient myrsOpen myrows = myrsRecordCount myrsClose myconnClose 可參考 httpwwwdwamnetmysqlasp_myodbcasp 有詳細的資料 Q10如何將 MySQL中的資料庫匯出成txt檔 Ans select from TableName into outfile textxls all result fields will seperate by tab

77

第八章 參考資料

英文部份 網址 1 httpwwwmysqlcom MySQL 網站有第一手有關 MySQL的資料 2 httpwwwmysqlcomdocenReplicationhtml 有關 MySQL Replication 的文件 3 httpwwwgeocitiescomsqlhomefaqstore_blobhtml 如何在 MySQL 存放 BLOB的資料 4httpwwwsapdborg 有關 SAP跟 MySQL相關合作的網站 書藉 1 Cooking with MySQL

Paul DuBois has selected sample recipes from the hundreds youll find in his book MySQL

Cookbook In this third and final series of excerpts showcasing these recipes learn how to

compute team standings how to calculate the differences between successive Dec 26

2002 2 Tips for Building Web Database Applications with PHP and MySQL by Hugh E Williams co-author of Web Database Applications with PHP amp MySQL 04042002

3 Managing and Using MySQL 2nd Edition By Tim King George Reese Randy Jay Yarger

4 MySQL Cookbook By Paul DuBoisPublisher OReillyPub Date October 2002

中文部份

78

1 httplinuxtncedutwtechdocmysqlmysql_docmanual_tochtml MySQL 中文手冊 2 httpchenshloxaedutwphpZ_1php PHP+MySQ程式研習設計網站 3 httplinuxtncedutwtechdocbanicdownhtml PHP 4 手冊 4 httpwwwtncedutwadmin_zonephp台南縣教育網網路中心有很多 Linux相關文件 5 httpdobtncedutw網站建置百寶箱有很多 PHP MySQL 相關範例程式 5 httpwwwdbworldcomtw資料庫專家電子雜誌介紹資料庫的重要觀念及名詞

79

附錄一 SQL Command 介紹

SQL (讀音ess-que-el) 是一種結構查詢語法SQL 使用於資料庫交流

傳遞相容於 ANSI (American National Standards Institute) 是一套標準的關聯

式資料庫語言 SQL 語言是執行更新或從資料系統獲取資料一般常見的關聯

資料庫系統都有提供 SQL 如 Oracle Sybase Microsoft SQL Server Access Ingres 等雖然大部份的資料庫都有提供 SQL 但也多提供了自已獨特的語

法造成了不相容的情形但標準基本的語法是相通的如Select Insert Update Delete Create and Drop 每一個系統都有支援

Table相關 Command

Create Table

關聯式資料庫包含有很多元件稱為資料表(tables) 把資料或訊息放在資

料表中 資料表是以不同的名稱做分別資料表由欄列所構成的二維陣列

欄包含欄位名資料型態 及其他可判斷的資訊列是由全部欄位構成一筆一

筆的紀錄 create table 語法用在建立一個新的資料表語法格式如下

create table tablename (column1 data type column2 data type column3 data type)

Format of create table if you were to use optional constraints

create table tablename (column1 data type [constraint] column2 data type [constraint] column3 data type [constraint]) [ ] = optional

Note You may have as many columns as youd like and the constraints are optional

80

Example

create table employee (first varchar(15) last varchar(20) age number(3) address varchar(30) city varchar(20) state varchar(20))

注意建立資料表格式要以括號把前後框住而最後以(分號)做結尾

欄位名不要超過 30個字元長而且不要使用 sql 的關鍵字(如 where select等)而在後面接是型態的宣告(如字串數字日期格式等)

資料型態是來描述欄位的方式如一個欄位Last_Name 是一個姓氏可以使用varchar (可變動長度字串) 資料型態

以下是幾個常見的資料庫型態 char(size) 固定長度字串最長為 255 位元 varchar(size) 變動長度字串最大字元數以 size 來指定 number(size) 數值格式可以是整數也可以是小數最大數字以 size 位數判

斷未指定小數位數由系統內定 date 日期格式 number(sized) 數值格式最大數字以 size 位數判斷d 為小數位數整數位

數為 size-d 位

有何限制當資料表被建立通常有一或數個欄位是要使用來做關聯的功

能 例如unique 限制(唯一值)兩筆記錄不可以相同的值 not null (非空值)該欄位一定要輸入資料不可是空的primary key (主鍵)是每一筆記錄識別的主要方式

Drop a table drop table 刪除資料表(其中的資料也會一併刪除)

drop table tablename

Example

81

drop table 和刪除全部資料是不同的刪除全部資料欄位名稱資訊等還會

存在但刪除資料表會把這一些也一併移除掉

如何查詢資料

Select 基本用法

select 語法是關連式資料庫最常用的部份可以取得你想要的資料這是一個

簡單的範例 select column1[column2etc] from tablename [where condition] [] = optional 在 select 之後所列欄位名則是要顯示的資料部份你可以一一列出各欄位

名或是以 (星號)來代表選擇全部的欄位 from 之後放資料表名稱 where 子句 (選項) 指定要過濾的條件符合者才會顯現 where 可使用的條件運算元 = 等於 gt 大於 lt 小於 gt= 大或等於 lt= 小或等於 ltgt 大相等 LIKE 相似 For example select first last city

82

from empinfo where first LIKE Er 以Er 為開頭的字串就符合要以單引號框住 Or you can specify select first last from empinfo where last LIKE s 最後一字為 S 就符合 select from empinfo where first = Eric 則表示 first name 一定要是 Eric 才可以 範例資料表empinfo 統計函數

MIN 傳回指定欄位最小值

MAX 傳回指定欄位最大值

SUM 傳回指定欄位總和

AVG 傳回指定欄位平均值

COUNT 傳回指定欄位的筆數

COUNT() 傳回資料庫中的總筆數

統計函數使用於資料表中的數值欄位配合 SELECT 語法使用 只用於總結特定單一欄位可以配合 GROUP BY 做篩選但也可以不使用 GROUP BY 語句For example

SELECT AVG(salary) FROM employee

83

傳回全部 salary 平均值

Another example

SELECT AVG(salary) FROM employee WHERE title = Programmer

傳回 salary 平均值條件為 employees 資料表中當 title 等於 Programmer

Example

SELECT Count() FROM employees

傳回 employees 資料表中紀錄總筆數

GROUP BY 語法 SELECT column1 SUM(column2) FROM list-of-tables GROUP BY column-list The GROUP BY 語句可以先以所列的欄位為條件分組排序在一起(可以多欄

位) example 要列出每一個 dept 中最高 salary 值 SELECT max(salary) dept FROM employee GROUP BY dept HAVING 語法

SELECT column1 SUM(column2) FROM list-of-tables GROUP BY column-list HAVING condition

HAVING 子句是 GROUP BY 的一部份用來過濾在 GROUP BY 所選出的資料功能如同 select 命令中 where 條件式一樣只是 HAVING 必需配合 GROUP BY 使用

我們以例子來說明我們要取得每一公司名及每一公司的薪水平均值輸入如下

84

SELECT dept avg(salary) FROM employee GROUP BY dept

但如果我們只列出薪資平均值超過 20000元的公司資料

SELECT dept avg(salary) FROM employee GROUP BY dept HAVING avg(salary) gt 20000

ORDER BY子句語法

SELECT column1 SUM(column2) FROM list-of-tables ORDER BY column-list [ASC | DESC]

[ ] =選項

ORDER BY是一個選項子句當你以排序方式來顯示資料(正向由小到大反向由大到小)以指定的欄位資料做排序

ASC = 正向- 預設值 DESC = 反向排序

For example

SELECT employee_id dept name age salary FROM employee_info WHERE dept = Sales ORDER BY salary

以上列出公司代號公司名銷售員人名年紀及薪資而條件是公司名為 Sales 顯示順序以薪資多少排序(由小到大為預設值)

如果要以多個欄位做排序要以逗號做分隔如下

SELECT employee_id dept name age salary FROM employee_info WHERE dept = Sales ORDER BY salary age DESC

85

結合條件及布林運算 SELECT column1 SUM(column2) FROM list-of-tables WHERE condition1 AND condition2 AND運算可以結兩個或以上的條件放在 WHERE子句中 兩者都要為真才

會顯示該筆記錄 OR 運算可以結兩個或以上敘述放在 WHERE子句中只要其中一個為直就

會顯示該筆記錄 For example SELECT employeeid firstname lastname title salary FROM employee_info WHERE salary gt= 5000000 AND title = Programmer 必需要薪資大於等於 50000而且職稱為 Programmer同時符合才會顯示該筆資料 以下以括號括住雖然不是必需的但如此比較容易讀 SELECT employeeid firstname lastname title salary FROM employee_info WHERE (salary gt= 5000000) AND (title = Programmer) 另外範例 SELECT firstname lastname title salary FROM employee_info WHERE (title = Sales) OR (title = Programmer) 條件為只要是 Sales 或 Programmer 職稱的就會被列出 IN and BETWEEN 子句

SELECT column1 SUM(column2) FROM list-of-tables WHERE column3 IN (list-of-values) SELECT column1 SUM(column2) FROM list-of-tables WHERE column3 BETWEEN value1 AND value2 IN 子句使用在列舉項目的使用上也就是分別測試是否符合所列的值 For example

86

SELECT employeeid lastname salary FROM employee_info WHERE lastname IN (Hernandez Jones Roberts Ruiz) 條件為姓氏(astname)要符合 Hernandez Jones Roberts or Ruiz 其中一個才會被傳回 IN運算元也可以使用 OR 的語法來取代如下結果相同 SELECT employeeid lastname salary FROM employee_info WHERE lastname = Hernandez OR lastname = Jones OR lastname = Roberts OR lastname = Ruiz 但使用 IN 句子比較短也比較易懂 你也可以使用 NOT IN 來去掉不要的記錄 BETWEEN 運算元使用在判斷是否存在兩個數值之間 For example SELECT employeeid age lastname salary FROM employee_info WHERE age BETWEEN 30 AND 40 傳回年紀 30歲到 40歲之間的資料(含 30及 40歲者) 相同的也可以使用以下語法來達到相同的結果 SELECT employeeid age lastname salary FROM employee_info WHERE age gt= 30 AND age lt= 40 你也可使用 NOT BETWEEN 來濾掉中間值的資料 數學運算 標準 ANSI SQL-92 提供以下運算

87

+ 加

- 減

餘數

餘數為除法後剩整數這不在標準的 ANSI SQL 中但大部份的資料庫都會支

援這運算元以下列出有用的函數雖不在 ANSI SQL-92 提供但一般資料庫

也會支援他們

ABS(x) 傳回 x 絕對值

SIGN(x) returns the sign of input x as -1 0 or 1 (negative zero or positive respectively)

MOD(xy) 餘數 - returns the integer remainder of x divided by y (同 xy)

FLOOR(x) 傳回小或等於 x 的最大整數值

CEILING(x) or CEIL(x)

傳回大或等於 x 的最小整數值

POWER(xy) x的 y 次方

ROUND(x) 把 x 四捨五入為整數

ROUND(xd) 四捨五入取到小數 d 位

SQRT(x) x 開平方

For example SELECT round(salary) firstname FROM employee_info 傳回薪資取到整數位

如何新增資料

insert 加入一筆新紀錄到資料表中 insert into tablename (first_columnlast_column) values (first_valuelast_value) [] = optional Example insert into employee

88

(first last age address city state) values (Luke Duke 45 2130 Boars Nest Hazard Co Georgia) Note 字串要以單引號住如string 數字框住也無妨 insert into 後面接資料表名稱再接以括號括住的欄位名在 values 後括號分別對映各欄位的值 以上的例子新增了一筆名(first) 為 Luke而住所(state) 為 Georgia 的資料

如何刪除資料

delete 可以刪除單筆或多筆紀錄 delete from tablename where columnname OPERATOR value [and|or column OPERATOR value] [ ] = optional Examples delete from employee Note 如果你沒有指定 where 子句那麼全部的紀錄都會被刪除 delete from employee where lastname = May delete from employee where firstname = Mike or firstname = Eric delete from 接著資料表名 再接著是條件式判斷沒有條件式則全部紀錄會

被刪除

如何更新資料

update 用來更新你所指定的記錄要和 WHERE 配合小心使用 語法 update tablename set columnname = newvalue[nextcolumn = newvalue2] where columnname OPERATOR value [and|or column OPERATOR value] [] = optional Examples

89

update phone_book set area_code = 623 where prefix = 979 update phone_book set last_name = Smith prefix=555 suffix=9292 where last_name = Jones update employee set age = age+1 where first_name=Mary and last_name=Williams

90

附錄二Replication

測試環境

RedHat 90 + MySQL 32358 MySQL資料庫路徑 varlibmysql MySQL設定檔 etcmycnf Master IP 1921680100 Slave IP 1921680200 請至下列網址下載最新MySQL 32358套件並利用rpm ndashUvh 更新 httpupdatesredhatcom9enosi386

圖 最新 MySQL 套件

測試架構圖

91

1921680100

1921680200Master Server

erveSlave S r

圖 測試架構圖

測試步驟

Master server 部份 Step1 確認 MasterSlave機器上所裝的 MySQL版本能進行

replication( 32329 or higher ) Step2 在 Master MySQL上開放一個帳號給 Slave mysql ndashu root ndashp mysqlgtGRANT FILE ON TO repl1921680200 IDENTIFIED BY lsquoabc123rsquo mysqlgtq 上面是 Master開放一個帳號 repl密碼 abc123給 IP1921680200有檔案處理

的權限 Step3 shutdown MySQL on the Master mysqladmin ndashu root ndashp shutdown Step4 備份 Master所有資料庫 tar ndashcvf tmpmysql-snapshottar varlibmysql 注意tar的時候MySQL是要在 stop情況下 在mysql (wwwmysqlcom) 網站的FAQ有不用shutdown的方法

92

Step5 在 master機器上修改etcmycnf 在[mysqld]區段內加入參數 log-bin server-id=這邊設定 server-id=1 sql-bin-update-same binlog-do-db=CRM只針對 CRM資料庫做紀錄 Step6 Restart MySQL on the master service mysqld start 此時因為有加入 log-bin 參數因此開始有 index產生了在varlibmysql目錄下

有index檔案紀錄資料庫的異動 log Slave server 部份 Step1 在 slave設定etcmycnf 在[mysqld]區段加入 master-host= master-user= master-password= master-port= server-id= 這邊設定 master-host=1921680100 master-user=repl master-password=abc123 master-port=3306 server-id=2 master-connect-retry=60預設重試間隔 60秒 replicate-do-db=CRM告訴 slave只做 CRM資料庫的更新 log-slave-updates Step2 將 master上的 mysql-snapshottar copy到 slave上 用 ftp傳到 slave的tmp Step3 解壓縮 Master資料庫至 Slave Server上 cd varlib tar xvf tmpmysql-snapshottar chown ndashR mysqlmysql mysql

93

chmod ndashR 770 mysql (視情況) Step4 Restart MySQL on the slave server 這時在varlibmysql目錄會出現 masterinfo此檔案紀錄了 Master MySQL server的資訊

狀況測試

One-way replication

1921680100

1921680200Master Server

erveSlave S r

圖 One-way replication架構圖 Step1 Master跟 Slave網路及服務都正常情況下由 Master端異動資料後 到 Slave端瀏覽資料檢視是否有進行 replication Step2 模擬 Slave Server 當機 可用在於 slave真的當機或是 Slave 不一定需要一直跟 master connect將Slave MySQL server shutdown由 Master端異動資料到 slave端瀏覽此時Slave應該沒有被 replication 更新然後再將 Slave端 MySQL server start起來

預設 60秒後 Slave會嘗試跟 Master要求進行 replication再去 Slave端檢視是否有更新資料

94

Step3 模擬 Master當機因為是設定 One-way replication一旦 Master Server Slave端沒有 Master的 source可以 download Two-way replication 基於 Master當機狀況於是發展雙向 Replication即 1921680100 ( Host A ) 1921680200 ( Host B )都分別擔任 MasterSlave身分

1921680100

1921680200er

Server B MasterSlave Server

Server A MasterSlave Serv

圖 Two-way replication架構圖 以下是針對兩台 MySQL伺服器進行雙向 Replication Step1觀念同單向 replication只是改成 Master也有 Slave身分 Slave也有Master的身分先分別在 Server AServer B 都去 grant一個進行 replication的身分 [A]mysqlgtGRANT FILE ON TO repl1921680200 IDENTIFIED BY lsquoabc123rsquo [B]mysqlgt GRANT FILE ON TO repl1921680100 IDENTIFIED BY lsquoabc123rsquo Step2做完單向 replication後stop Server Aserver B MySQL service此時 AB資料是一樣的

95

修改etcmycnf設定 範例 Server A [mysqld] datadir=varlibmysql socket=varlibmysqlmysqlsock server-id=1 log-bin sql-bin-update-same binlog-do-db=CRM master-host=1921680200 master-user=repl master-password=abc123 log-slave-updates master-connect-retry=60 replicate-do-db=CRM Server B [mysqld] datadir=varlibmysql socket=varlibmysqlmysqlsock server-id=2 log-bin sql-bin-update-same binlog-do-db=CRM master-host=1921680100 master-user=repl master-password=abc123 log-slave-updates master-connect-retry=60 replicate-do-db=CRM 分別 start Server AServer B MySQL後此時雙方都是 MasterSlave身分一旦哪一方資料異動就會通知對方來 replication-若 replication失效則必須將Server AServer B的masterinfo及index00x 都砍掉然後分別 restart MySQL server進行測試檢視成果 實務上通常如果需要做Two-way replication通常會搭配Virtual Server使用

96

在前端架設一台Virtual Server不過此部份不在此份SOP討論範圍內有興趣

的讀者可參考 httpwwwlinuxvirtualserverorg 網站

1921680100 1921680200

Host A MasterSlave Server

Host B MasterSlave Server

Virtual Host

圖 Virtual Server + Two-way replication 架構圖

97

圖 High Availability Linux Virtual Server架構圖

98

  • COSA-SOP-03-006
  • 第一章 簡介
    • 11適用對象 (Audience)
    • 12 MySQL本身
    • 13 MySQL 40版跟50版重大的改進功能
    • 14 各家資料庫軟體比較
      • 第二章 前置需求
      • 第三章 安裝
        • 31 MySQL安裝
        • 32 phpMyAdmin安裝
        • 33 升級及注意事項
          • 第四章 MySQL管理
            • 41 Webmin 管理介面
            • 42 phpMyAdmin 的操作介面
            • 43管理指令介紹
              • 431 利用mysqladmin設定root的密碼
                  • 第五章 實用範例
                    • 51 任務一Web Base客戶通訊錄
                    • 52 任務二Web Base群組軟體 ( twig )
                      • 第六章 維護及更新程序
                        • 61 日常維護
                        • 62 更新程序
                        • 63 備份重要檔案
                        • 64 離線備份與還原
                        • 65 線上備份與還原
                          • 第七章 問題與解答
                          • 第八章 參考資料
                          • 附錄一 SQL Command 介紹
                          • 附錄二Replication
Page 26: DataBase Server Standard Operation Procedureebooks.lib.ntu.edu.tw/1_file/oss/63/93doc4-5.pdf · 業務的公司帶來了不少壓力,譬如微軟,甲骨文 ... 外的錢用在第三方的資料庫產品上,譬如就可以不用再購買甲骨文公司

圖 3-24 啟動 MySQL 4014 並修改密碼

26

第四章 MySQL管理

本章將我們介紹利用WebminphpAdminCommand的方式建立一個名為

CONTACT的資料庫內有一個 address的 Table作為我們客戶通訊錄程式使

用的資料庫

41 Webmin 管理介面

412建立資料庫

Step 1 登入Webmin

圖 4-1 登入WebMin

Step 2 點選伺服器

27

圖 4-2 伺服器畫面

Step 3 點選 MySQL資料庫伺服器

圖 4-3 MySQL資料庫伺服器

28

Step 4 建立一個新的資料庫

圖 4-4 建立 MySQL資料庫

Step 5 建立名為 CONTACT的資料庫

29

圖 4-5 指定資料庫名稱

412 建立資料表

假設我們要建立一個名為 address的 Table其結構如下 欄位名稱 資料型態 長度 說明 id INT (自動編號) 連絡人編號 name varchar文字 20 連絡人姓名 tel Varchar文字 15 連絡人電話 Step 1 選擇 CONTACT資料庫

30

圖 4-6 選擇資料庫

Step 2 指定欄位數目

31

圖 4-7 設定欄位數目

Step 3設定表格欄位屬性

圖 3-8 設定表格欄位屬性

Step 4建立表格資料

32

圖 4-9 建立表格資料

圖 4-10 檢視資料

33

圖 4-11 新增資料

圖 4-12

34

圖 4-13

413 使用者管理

接下來我們要利用Webmin 來建立資料庫使用者並給予某些權限 Step1建立使用者

35

圖 4-14 選擇使用者權限

圖 4-15

36

Step2 賦予權限

圖 4-16

Step3 權限列表

37

圖 4-17

38

42 phpMyAdmin 的操作介面

421建立資料庫

Step 填入資料庫名稱並按「建立」

圖 4-18建立資料庫

422 建立資料表

Step1 填入資料表名稱並指定欄位數量 執行

39

圖 4-19填入資料表名稱並指定欄位數量

Step2 設定欄位屬性

圖 4-20設定欄位屬性

40

Step3 phpMyAdmin會產生相關的 SQL Command

圖 4-21 資料表結構及相關 SQL Command

Step4新增 Record

41

圖 4-22

圖 4-23

42

圖 4-24

圖 4-25

43

423使用者管理

Step1建立使用者

圖 4-26

44

圖 4-27

Step2 給予權限

圖 4-28

Step3權限列表

45

圖 4-29

43管理指令介紹

431 利用 mysqladmin設定 root的密碼

當您在Windows 或 Linux 中安裝好 MySQL後系統會自動幫您建立兩個

帳分別是 root 和 匿名者MySQL的 root 跟 Linux 最高權限使用者 root無關MySQL的 root使用者相當於 MS SQL 中的 sa 帳號擁有最高的 Database管理權限但系統預設 MySQL的 root 是不需要密碼所以通常我們一安裝

MySQL後首要任務便是修改 root的密碼 我們可以利用 mysqladmin工具或是直接修改 MySQL內部資料庫的使用者資

料 mysqladmin ndashu root ndashh cosaexamplecom password lsquo1234rsquo

46

-u 表示使用者帳號root 為 MySQL預設的管理帳號

-h 表示 MySQL主機的主機名稱也可使用 IP Address password 表示使用者的密碼因為字串請使用單引號將密碼括起來 密碼設定完成之後還是可以利用 mysqladmin修改密碼但是你必須提供目前的密碼

432 連線 MySQL

mysql -uroot -p密碼 (-p和密碼之間不能有空白) 或 mysql -uroot -p (此方式會在進入後要求密碼) [rootossc phpMyAdmin] mysql -u root -p1234

Welcome to the MySQL monitor Commands end with or g

Your MySQL connection id is 25 to server version 32354

Type help or h for help Type c to clear the buffer

mysqlgt show databases

+----------+

| Database |

+----------+

| mysql |

| test |

+----------+

2 rows in set (000 sec)

mysqlgt exit

Bye

[rootossc phpMyAdmin]

433 建立資料庫

可利用 mysqladmin指令建立 CONTACT資料庫 mysqladmin -u root -p1234 create CONTACT

47

或是利用 mysql指令 [rootossc bluepage] mysql -u root -p1234 Welcome to the MySQL monitor Commands end with or g Your MySQL connection id is 1057 to server version 32354 Type help or h for help Type c to clear the buffer mysqlgt create database CONTACT Query OK 1 row affected (000 sec) mysqlgt show databases +----------+ | Database | +----------+ | CONTACT | | address | | hello | | mysql | | nuke | | test | +----------+ 6 rows in set (000 sec) mysqlgt exit

434 建立資料表

編寫 adresssql內容如下 -- Table structure for table address CREATE TABLE address ( id int(11) NOT NULL auto_increment name varchar(20) NOT NULL default tel varchar(15) NOT NULL default PRIMARY KEY (id) ) TYPE=MyISAM

48

-- Dumping data for table address INSERT INTO address VALUES (1林小明0800016888) INSERT INTO address VALUES (2黃大雄0800016888) INSERT INTO address VALUES (3劉小芬0800024365) 然後執行此 sql script mysql -u root -p1234 CONTACT lt addresssql 或是利 mysql command [rootossc bluepage] mysql -u root -p1234 Welcome to the MySQL monitor Commands end with or g Your MySQL connection id is 1090 to server version 32354 Type help or h for help Type c to clear the buffer mysqlgt use CONTACT Database changed Database changed mysqlgt CREATE TABLE address ( -gt id int(11) NOT NULL auto_increment -gt name varchar(20) NOT NULL default -gt tel varchar(15) NOT NULL default -gt PRIMARY KEY (id) -gt ) TYPE=MyISAM Query OK 0 rows affected (000 sec) mysqlgt INSERT INTO address VALUES (1林小明0800016888) Query OK 1 row affected (000 sec) mysqlgt INSERT INTO address VALUES (2黃大雄0800016888) Query OK 1 row affected (000 sec) mysqlgt INSERT INTO address VALUES (3劉小芬0800024365) Query OK 1 row affected (000 sec) mysqlgt exit Bye

49

第五章 實用範例

51 任務一Web Base客戶通訊錄

任職於開放科技公司的林小明前些日子在最符合成本效益的條件下快

速地完成公司網站的建置老闆因此對小明讚譽有加最近因為公司存放客戶資

料的 SQL Server主機屢遭病毒攻擊加上作業系統本身的問題當機次數頻繁

老闆希望能儘快把公司的客戶通訊錄程式移轉到較穩定的環境上因為此客戶通

訊錄程式最主要給內部人員使用所以介面美觀並不特別要求只求穩定且能快

速得到查詢結果老闆希望在短時間先看到程式的雛型並鍵入資料對其效率

及穩定性進行測試因為上次小明表現突出所以這次不可能的任務自然又落到

小明身上 小明想來想去既然要快速又穩定他而且又不希望所有人都得安裝 Client

程式於是小明決定)捨棄他的舊愛「Delphi+MS SQL」投向新歡「Apache + MySQL + PHP」利用此架構來設計一個簡單實用的Web Base客戶通訊錄程式

511 Web Base客戶通訊錄架構

此程式需要建立 CONTACT的資料庫並建立 adress Tables其結構如下表建立步驟請參考第三章 欄位名稱 資料型態 長度 說明 id INT (自動編號) 連絡人編號 name varchar文字 20 連絡人姓名 tel Varchar文字 15 連絡人電話 Web Base通訊錄共有下列幾個檔案功能如下表

檔案名稱 說明 Indexhtml Web Base通訊錄首頁 addphp 新增連絡人的 php程式 searchphp 尋找連絡人的 php程式 editphp 具有更新及刪除功能的 php程式

50

我們將這些檔案放至varwwwhtmlbluepage (預設無 bluepage目錄)

512 Web Base通訊錄測試

httpwwwopencombluepage 新增資料

圖 5-1 新增連絡人

圖 5-2 填入資料

51

圖 5-3 新增成功

搜尋及異動資料

圖 5-4 搜尋通訊錄

52

圖 5-5 編輯資料

圖 5-6 更新資料

513 程式內容及說明

lt-- 程式範例indexhtml--gt lthtmlgt ltheadgtlttitlegt通訊錄lttitlegtltheadgt ltbodygt ltcentergt

53

lth2gt通訊錄lth2gtlthrgt lta href=indexhtmlgt通訊錄ltagt | lta href=addphpgt新增連絡人ltagt | lta href=searchphpgt搜尋通訊錄ltagt ltcentergt ltbodygt lthtmlgt lt-- 程式範例addphp --gt lthtmlgt ltheadgtlttitlegt新增連絡人lttitlegtltheadgt ltbodygt ltcentergtlth2gt新增連絡人lth2gtltcentergtlthrgt lt 取得欄位資料 if (isset($_POST[Name]) ampamp isset($_POST[Tel]) ) $name = $_POST[Name] $tel = $_POST[Tel] 檢查是否有輸入欄位資料 if ($name = ampamp $tel = ) 建立 SQL字串 $sql = INSERT INTO address (name tel) values( $sql= $name $tel) 建立 MySQL 連結 $link = mysql_connect(localhostroot1234) 選擇資料庫 mysql_select_db(CONTACT) 執行 SQL指令 mysql_query($sql) mysql_close($link) echo ltfont color=redgt新增連絡人成功ltfontgtltbrgt gt ltform action=addphp method=postgt lttable border=0 width=300gt lttrgtlttdgt姓名 lttdgt

54

lttdgtltinput type=text name=Name size=20 maxlength=10gtlttdgtlttrgt lttrgtlttdgt電話 lttdgt lttdgtltinput type=text name=Tel size=20 maxlength=20gtlttdgtlttrgt lttrgtlttd colspan=2 align=centergt ltinput type=submit value=新增連絡人gtlttdgtlttrgt lttablegt ltformgt ltbrgtlta href=indexhtmlgt通訊錄ltagt | lta href=addphpgt新增連絡人ltagt | lta href=searchphpgt搜尋通訊錄ltagt ltbodygt lthtmlgt

lt-- 程式範例searchphp --gt lthtmlgt ltheadgtlttitlegt搜尋通訊錄lttitlegtltheadgt ltbodygt ltcentergtlth2gt搜尋通訊錄lth2gtlthrgt lt if (isset($_POST[Search])) 建立資料庫連結並選定資料庫 $link = mysql_connect(localhostroot1234) mysql_select_db(CONTACT) 建立基本的 SQL字串 $sql = SELECT FROM address 檢查是否輸入姓名 if (chop($_POST[Name]) = ) $name = name LIKE $_POST[Name] else $name = 檢查是否輸入電話號碼 if (chop($_POST[Tel]) = ) $tel = tel LIKE $_POST[Tel] else $tel =

55

if條件組合 SQL字串 if (chop($name) = ampamp chop($tel) = ) $sql= WHERE $name AND $tel elseif (chop($name) = ) 只有姓名 $sql = WHERE $name elseif (chop($tel) = ) 只有電話號碼 $sql = WHERE $tel $sql= ORDER BY name 最後加上排序 $result = mysql_query($sql) 取得欄位數 $total_fields = mysql_num_fields($result) echo lttable border=1gt echo lttrgtlttdgt編號lttdgtlttdgt姓名lttdgtlttdgt電話lttdgtlttd colspan=2gt功能選項lttdgtlttrgt 表格顯示查詢結果 while ($rows = mysql_fetch_array($result MYSQL_NUM)) echo lttrgt for ($i = 0 $i lt $total_fields $i++) echo lttdgt$rows[$i]lttdgt echo lttdgtlta href=editphpaction=editampid= echo $rows[0]gtltbgt編輯ltbgtlttdgt echo lttdgtlta href=editphpaction=delampid= echo $rows[0]gtltbgt刪除ltbgtlttdgt echo lttrgt echo lttablegtlthrgt mysql_free_result($result) mysql_close($link) gt ltcentergt ltform action=searchphp method=postgt lttable border=0 width=450gt lttrgtlttdgt搜尋姓名 lttdgt lttdgtltinput type=text name=Name size=10 maxlength=20gtlttdgtlttrgt lttrgtlttdgt搜尋電話 lttdgt lttdgtltinput type=text name=Tel

56

size=20 maxlength=20gtlttdgtlttrgt lttrgtlttd colspan=2 align=centergt ltinput type=submit name=Search value=搜尋gtlttdgtlttrgt lttablegt ltformgt ltbrgtlta href=indexhtmlgt通訊錄ltagt | lta href=addphpgt新增連絡人ltagt | lta href=searchphpgt搜尋通訊錄ltagt ltbodygt lthtmlgt

lt ob_start() gt lt-- 程式範例editphp --gt lthtmlgt ltheadgtlttitlegt編輯通訊錄lttitlegtltheadgt ltbodygt lt 取得 URL 參數 $id = $_GET[id] $action = $_GET[action] 建立資料庫連結 $link = mysql_connect(localhostroot1234) mysql_select_db(CONTACT) 選擇資料庫 執行的操作 switch ($action) case update 更新 取得欄位資料 $name = $_POST[Name] $tel = $_POST[Tel] $sql = UPDATE address SET name=$name tel=$tel WHERE id=$id mysql_query($sql) 執行 SQL指令 mysql_close($link) header(Location searchphp) 轉向到 serachphp break case del 刪除 $sql = DELETE FROM address WHERE id=$id

57

mysql_query($sql) 執行 SQL指令 mysql_close($link) header(Location searchphp) 轉向到 serachphp break case edit 編輯 $sql = SELECT FROM address WHERE id=$id $result = mysql_query($sql) 執行 SQL指令 $row = mysql_fetch_row($result) 取回記錄 $name = $row[1] 取得欄位 name $tel = $row[2] 取得欄位 tel mysql_close($link) 顯示編輯表單 gt ltcentergtlth2gt更新通訊錄lth2gtltcentergtlthrgt ltform action=editphpaction=updateampid=lt echo $id gt method=postgt lttable border=0 width=300gt lttrgtlttdgt姓名 lttdgt lttdgtltinput type=text name=Name size=20 maxlength=10 value=lt echo $name gtgtlttdgtlttrgt lttrgtlttdgt電話 lttdgt lttdgtltinput type=text name=Tel size=20 maxlength=20 value=lt echo $tel gtgtlttdgtlttrgt lttrgtlttd colspan=2 align=centergt ltinput type=submit value=更新連絡人gtlttdgtlttrgt lttablegt ltformgt ltbrgtlta href=indexhtmlgt通訊錄ltagt | lta href=addphpgt新增連絡人ltagt | lta href=searchphpgt搜尋通訊錄ltagt lt break gt ltbodygt lthtmlgt

58

52 任務二Web Base群組軟體 ( twig )

順利完成Web Base客戶通訊錄程式測試一段時間後「Apache + MySQL + PHP」架構的穩定與快速巳深得老闆與公司所有同事的認同隨著公司業績蒸

蒸日上人員組織編罝愈來愈龐大跨部門的會議愈來愈多業務員每日排滿拜

訪客戶的行程跟客戶的 Email的往來也愈來愈頻繁 愈來愈多部門的同事希望公司能建置一套群組軟體提供 web mail可讓業

務人員方便收發 mail還有連絡人議事日程待辦工作書簽等功能讓整個

公司運作及個人時間管理更有效率

老闆問小明對這些需求有什麼看法小明認為如果這些功能完全由程式部

門開發必定曠日費時而且耗費公司資源小明在網路尋找是否有提供這些功能

的Free Software皇天不負苦心人小明發現了TWIG (The Web Information Gateway) httptwigscrewdrivernet這個群組軟體它在 Web 上整合郵件新聞聯絡人議事日程工作序書簽等功能非常符合公司的需求 Step 1 下載 twig-277targz 下載網址 httptwigscrewdrivernetdownloadphp3

Step 2 解開 twig-277targz tar -xzvf twig-277targz

59

Step 3 執行安裝動作安裝到 varwwwhtmltwig 目錄 cd twig-277 twig-install varwwwhtmltwig

Step 4 建立 MySQL 資料庫(twig)及各資料表

cd setup mysql -u root -p1234 mysqlgt create database twig Query OK 1 row affected (001 sec) mysqlgt quit mysql -u root ndashp1234 twiglt twigtablemysql

Step 5 修改 configincphp3 參數設定 vi varwwwhtmltwigconfigconfigincphp3 $config[fromdomain] = opencom 網域 $config[language] = chinesebig5 中文訊息 $config[imap_port] = 143notls

60

Step 6 修改連結 MySQL 的帳號密碼 vi varwwwhtmltwigconfigdbconfigincphp3 $dbconfig[sqlusername] = root username $dbconfig[sqlpassword] = 1234 password

Step 7 其他設定檔

vi etchttpdconfhttpdconf 加入 AddType applicationx-httpd-php php3 在 DirectoryIndex最後加入 indexphp3 DirectoryIndex indexhtml indexhtmlvar indexphp3 在 AddDefaultCharset ISO-8859-1加上 AddDefaultCharset ISO-8859-1

vi etcphpini register_globals = On service httpd restart Step 8 sendmail 設定 vi etcmailsendmailcf在 264 行前面加上並重新啟動 sendmail「service snedmail restart」 262 SMTP daemon options 263 264 O DaemonPortOptions=Port=smtpAddr=127001 Name=MTA 265 266 SMTP client options 267 O ClientPortOptions=Family=inet Address=00

61

Step 9 檢查設定有無錯誤 http主機名稱twigtestphp3

62

Step 10 登入 twig ( http主機名稱twig)

63

第六章 維護及更新程序

61 日常維護

系統管理員最好定期以 root 身份登入看看信件在 RedHat Linux 中有一支 logwatch 程式會定時去分析 log file如果發現異常便會發信給 root除此之外筆者建議讀者平時就檢查 MySQL log file ( varlogmysqldlog)是否有異常情形

62 更新程序

讀者可至httprpmfindnet 尋找MySQL相關套件至於升級的相關步驟請參

考Linux OS SOP 第 54節

63 備份重要檔案

預設 MySQL 的 DB 檔案是存在 varlibmysql 內以 DB名稱為目錄目錄

內就是該 DB 的所有資料通常得定期備份還有 MySQL的設定檔 etcmycnf也別忘了一起備份

64 離線備份與還原

641 離線備份

預設 MySQL 的 DB 檔案是存在 varlibmysql 內以 DB 名稱為目錄目錄內

就是該 DB 的所有資料像 CRM 這個 DB就是存在 varlibmysqlCRM 內在備份前因為怕資料尚未完全寫入磁碟而且 MySQL 會 Lock 在使用的 DB 檔案所以應該是要先把 MySQL 先 Shutdown 一下整個備份的程序可以下像下面的指令去完成 cd varlibmysql

64

service mysqld stop tar cvfz CRM_db_20030905tgz CRM service mysqld start 對這樣就可以了 不過要注意的是怕 DB 內每個 Tables 間的資料有關關

聯性所以最好是把整個 DB 一次備起來單獨只備哪個 Tables 的檔案以後回存時怕會有資料關聯不一致的問題

642 離線還原

DB 發生錯誤而要回存時其實也不難先找出最近一次完整正常的備份先把現在錯誤的網頁或 DB 先更名或 tar 起來再把好的備份給解開回原來目錄位

置就行了需要注意的是 MySQL 服務最好也是要先停止回存完成後再啟動服務回存 DB 的整個程序可能像下面 cd varlibmysql service mysqldstop mv CRM CRM_OLD tar xvfz CRM_db_20030905tg service mysqld start

65 線上備份與還原

651 線上備份

使用像上面的檔案方式備份是個不錯的方法它最少可以保持該主機某個時間點的完整檔案備份但還是有一些問題需要考慮到有些主機就不只建立一個 DB 而已總不能為了備份某個 DB 而把整個 MySQL 服務停止備份檔案的方式回存在原主機上一定適用但假如 MySQL 版本升級或是在那天該網頁空間需遷機移機到別的主機時那就沒人敢保證備出來的資料檔可以用所以我們可以考慮另一種備份的方式是使用 MySQL 本身提供的功能 MySQL Data Dump指令是 mysqldump

65

使用 MySQL 的 Dump 功能可以把 DB 的結構資料或結構加資料 Dump 成文字檔 mysqldump 指令提供的彈性很大你可以選擇把整個 DB Dump 成一個檔或是每個 Table 為一個檔甚至是把結構檔和資料分開儲存都

可以 mysqladmin -uroot -p flush-logs mysqldump CRM -uroot -p --opt gt CRM_20030905sql (CRM 是 DB 名稱 opt 是一個使用完整 Dump 參數) 假如只是要單獨 Dump 某個 Table 時只要在上面的指令後轉出符號 gt 前加個 Table 名稱就可以如只要 phpbb2_users 這個 Table 的 Dump 時只要下 mysqldump CRM -uroot -p --opt CUSTOMER gt CRM_CUSTOMER_20030905sql

652 線上還原

若要回存整個資料庫只需將壓縮的備份檔還原成 Dump 的檔案再用下面的指令回存 mysql CRM -uroot -p lt CRM_20030905sql 這邊需注意的是若建立備份時是以--opt或--add-drop-table為參數時回存的 動作是先將舊的 Table 先刪除重建 Table 的結構後再把 Data 匯入所以回存後所有的資料會回到你當時備份那個時間點因此在回存資料時可以考慮把現有錯誤或不完整的 DB 先備份一份下來以備不時之需或是拿來比對錯誤的地

方在那裡當然你也可以把資料回存到另一個測試用的 DB 內只要把上面指令

的 DB 名稱改成你的測試用 DB 名稱即可 使用這種回存方式 MySQL 服務不需停止也不會動到其他正在使用的 DB 在一些提供 MySQL 服務的虛擬主機可用這種方式作你自己的 DB 備份及回存

66

另外假如你是系統重建或是移機時切需在新的 MySQL 內新建一個空白 DB 後才行作回存的工作你可以用下面的指令建立 mysql -uroot -p -e CREATE DATABASE CRM (上面的 CRM是你要新建的 DB 名稱) 另一種作法先用 mysql 指令進入 mysql client console 然後再用 CREATE DATABASE CRM 這樣就行了記得尾端要加個 符號該行指令才會執行

67

第七章 問題與解答

Q1RedHat 90預附的 MySQL到底有無支援 Transcation機制 Ans MySQL自 32334a之後的 MySQL-Max版本加入 InnoDB的資料庫類型透過

InnoDBMySQL同樣可以進行 COMMIT與 ROLLRACK的動作RedHat 90預附的 MySQL為 32354a-11巳支援 InnoDB的資料庫類型不過必須做以

下設定 1cp usrsharedocmysql-server-32354amy-mediumcnf to etcmycnf 2 vi etcmycnf 將以下設定前的拿掉 innodb_data_home_dir = varlibmysql innodb_data_file_path = ibdata110Mautoextend innodb_log_group_home_dir = varlibmysql innodb_log_arch_dir = varlibmysql 3service mysqld restart 如此一來各位在建立Table時便可指定Table Type為 innodb ( ex create table with type=innodb ) Q2如何解決 php+mysql 許功蓋等字變亂的問題 Ans 方法一 【確定 MySQL 預設的字元集】 1 打開 WinMySQLadmin 管理畫面(在視窗右下角狀態列紅綠燈圖示中按滑鼠

右鍵點選 Show me 選項) 2 點選管理畫面中 [Variables] 標籤選項其中 character_set變數就是您預設

字元集的變數其預設是 latin1 字元集(我們要將他改回 big5)而 chatacters_set 變數則是 MySQL 可以支援哪些字元集 【修改預設字元集變數 character_set 】 1 請點選管理畫面中 [myini Setup] 標籤選項設定 myini 2 按一下 [Pick-up and Edit myini values] 按鈕以便編輯目前的 myini 設定 3 在 [mysqld] 設定區塊底下新增一行 default-character-set = big5 變數設

68

定 4 新增一個 [client] 設定區塊並加入第三步驟的變數設定(游標往下移到空白處新增兩行 [client] 和 default-character-set=big5) 5 按一下畫面左下方 [Save Modification] 按鈕儲存設定 6 重新啟動 MySQL 或 Windows 方法二 Server端注意事項 phpini 中有關的設定為(預設值) Magic quotes for incoming GETPOSTCookie data magic_quotes_gpc = On Use Sybase-style magic quotes (escape with instead of ) magic_quotes_sybase = Off Client端注意事項 1中文資料送進 mysql 前請用 addslashes($str) 處理 2處理後送進 mysql 時請用 括起來並在參數後留一個空白如 $sql = UPDATE ezf_table set tablename=$tname tableend=$endtime table inguser=$tguser tableingid=$tguserid tableallnumber=$tnumber tableloca l=$tablelocal tableanyone=$tableopen tabletext=$ttext WHERE tableid=$t ableid tablename=$tname c 取出時請用 stripslashes($str) Q3MySQL root 密碼忘了該怎麼辦 Ans 1先停掉 mysql etcrcdinitdmysql stop 2以--skip-grant-table 的參數啟動 mysql safe_mysql --skip-grant-tableamp 3 更改 root 密碼 mysql mysql mysqlgt UPDATE user SET password=password(newpassword)

69

WHERE user=root mysqlgt FLUSH PRIVILEGES mysqlgt exit 4停掉 mysql再重跑 mysqladmin -uroot -p shutdown Enter password 輸入新設定的密碼 etcrcdinitdmysql start

Q4NULL值問題

Ans

NULL值的概念是造成 SQL的新手的混淆的普遍原因他們經常認為 NULL是和一個空字符串的一樣的東西不是這樣的例如下列語句是完全不同的

mysqlgt INSERT INTO my_table (phone) VALUES (NULL)

mysqlgt INSERT INTO my_table (phone) VALUES ()

兩個語句把值插入到 phone 列但是第一個插入一個 NULL值而第二個插入一個空字符串第一個的含義可以認為是ldquo電話號碼不知道而第二個則可意味

著ldquo她沒有電話

在 SQL中NULL值在于任何其他值甚至 NULL值比較時總是假的(FALSE)包含 NULL的一個表達式總是產生一個 NULL值除非在包含在表達式中的運算符和函數的文檔中指出在下列例子所有的列返回 NULL

mysqlgt SELECT NULL1+NULLCONCAT(InvisibleNULL)

如果你想要尋找值是 NULL的列你不能使用=NULL測試下列語句不返回任

何行因為對任何表達式expr = NULL是假的

mysqlgt SELECT FROM my_table WHERE phone = NULL

要想尋找 NULL值你必須使用 IS NULL測試下例顯示如何找出 NULL電話號碼和空的電話號碼

70

mysqlgt SELECT FROM my_table WHERE phone IS NULL mysqlgt SELECT FROM my_table WHERE phone =

在 MySQL中就像很多其他的 SQL服務器一樣你不能索引可以有 NULL值的列你必須聲明這樣的列為 NOT NULL而且你不能插入 NULL到索引的

列中

當用 LOAD DATA INFILE 讀取數據時空列用更新如果你想要在一個列中有

NULL值你應該在文本文件中使用N字面上的詞NULL也可以在某些情形下使用

當使用 ORDER BY時首先呈現 NULL值如果你用 DESC以降序排序NULL值最後顯示當使用 GROUP BY時所有的 NULL值被認為是相等的

為了有助于NULL的處理你能使用 IS NULL和 IS NOT NULL運算符和 IFNULL()函數

對某些列類型NULL值被特殊地處理如果你將 NULL插入表的第一個TIMESTAMP 列則插入當前的日期和時間如果你將 NULL插入一個AUTO_INCREMENT 列則插入順序中的下一個數字

Q5如何將圖片存放於 MySQL中

Ans

Step 1建立資料庫 test

Step 2 建立表格 binary_data

CREATE TABLE binary_data (

id INT(4) NOT NULL AUTO_INCREMENT PRIMARY KEY

description CHAR(50)

bin_data LONGBLOB

filename CHAR(50)

filesize CHAR(50)

filetype CHAR(50)

71

)

Step 3 利用 storephp 寫入圖片

storephp 程式碼

ltHTMLgt ltHEADgtltTITLEgtStore binary data into SQL DatabaseltTITLEgtltHEADgt ltBODYgt lt code that will be executed if the form has been submitted

if ($submit) mysql_connect(localhostrootYOUR_PASSWORD) mysql_select_db(test) $data=Base64_Encode(fread(fopen($form_data r) filesize($form_data))) $result=MYSQL_QUERY(INSERT INTO binary_data (descriptionbin_datafilenamefilesizefiletype) VALUES ($form_description$data$form_data_name$form_data_size$form_data_type)) $id= mysql_insert_id() print ltpgtThis file has the following Database ID ltbgt$idltbgt MYSQL_CLOSE() else else show the form to submit new data

gt

ltform method=post action=ltphp echo $PHP_SELF gt enctype=multipartform-datagt File Descriptionltbrgt ltinput type=text name=form_description size=40gt ltINPUT TYPE=hidden name=MAX_FILE_SIZE value=4000000gt ltbrgtFile to uploadstore in databaseltbrgt ltinput type=file name=form_data size=40gt ltpgtltinput type=submit name=submit value=submitgt ltformgt lt

72

gt ltBODYgt ltHTMLgt

Step 3 利用 storephp 取出圖片

getdataphp 程式碼

lt Syntax getdataphp3id=ltidgt if($id) you may have to modify login information for your database server MYSQL_CONNECT(localhostrootYOUR_PASSWORD) mysql_select_db(test) $query = select bin_datafiletype from binary_data where id=$id $result = MYSQL_QUERY($query) $data = Base64_Decode(MYSQL_RESULT($result0bin_data)) $type = MYSQL_RESULT($result0filetype) Header( Content-type $type) echo $data gt

Q6MySQL裝好之後啟動時或是執行 mysqladmin會出現如下訊息 Cant connect to local MYSQL Server through Socket varlibmysqlmysqlsock或是

Cant connect to local MYSQL Server through Socket tmpmysqldsock

Ans 可能有下列幾個原因

1這個 mysqldsock 不見了被某人刪除了或是被一些系統自動執行程式給刪

了例如有些 cron任務便會設定定期刪除 tmp 裡的東西所以呢您只能修改

cron 裡的設定讓它不要清除 mysqldsock 2在啟動時也可以改變 mysqldsock的位置您在啟動 MySQL的時候可以加入此參數usrlocalmysqlbinsafe_mysqld --user=mysql --socket=其他路

徑socket amp 同時得去設定環境變數 MYSQL_UNIX_PORT的值以指定新的

73

路徑 3若是您沒改 MYSQL_UNIX_PORT的值那麼您可以在執行指令的時候才打

例如mysqladmin --socket=其他路徑socket version Q7How to get the last insert id Ans CREATE TABLE product ( id INT(4) NOT NULL AUTO_INCREMENT PRIMARY KEY description VARCHAR(50) ) 1利用 SQL的話 mysqlgt insert into product(description) values(123) Query OK 1 row affected (000 sec) mysqlgt select last_insert_id() +------------------+ | last_insert_id() | +------------------+ +------------------+ 1 row in set (000 sec) ======================================== 2如果是 PHP的話 你可以用mysql_insert_id()取得該 id PHP example $result=MYSQL_QUERY(INSERT INTO product (description) VALUES ($description)) $id= mysql_insert_id() print This file has the following Database ID $id Q8如何將文字檔匯入資料庫 Ans $addr=homehttpdhtmlphpschool001txt $sql_select = load data infile $addr into table test fields terminated by t 解說 $sql_select = load data infile 文字檔名 into table 表格名 fields terminated by

74

t

(欄位分隔以 TAB鍵) 該文字檔須與資料表欄位格式相符 例如欄位有三個 則文字檔為每行一筆資料如下 欄 1資料ltTABgt欄 2資料ltTABgt欄 3資料 欄 1資料ltTABgt欄 2資料ltTABgt欄 3資料 欄 1資料ltTABgt欄 2資料ltTABgt欄 3資料 欄 1資料ltTABgtltTABgt欄 3資料

Q9如何撰寫 MySQL C API Ans Step 1利用文字編輯器撰寫以下程式碼 mysqlcc

include ltstdiohgt

include ltmysqlmysqlhgt

int main (int argc char argv[])

MYSQL mysql

MYSQL_RES res

MYSQL_ROW row

if (argc = 2)

fputs (Usage myc ltdatabasegt stderr)

return 1

if ((mysql_connect(ampmysqllocalhostrootYour_Password)))

fputs (Error connecting stderr)

abort()

75

if (mysql_select_db(ampmysqlargv[1]))

fputs (Error selecting database stderr)

abort()

if (mysql_query(ampmysqlSELECT FROM test_table))

fputs (Error processing query stderr)

abort()

if ((res = mysql_store_result(ampmysql)))

fputs (Error storing results stderr)

abort()

while((row = mysql_fetch_row(res)))

uint i = 0

for (i=0 i lt mysql_num_fields(res) i++)

printf(s row[i])

printf(n)

return 0

Step 2 Compile

gcc -Iusrlocalmysqlinclude -Lusrlocalmysqllibmysql mysqlcc ndashlm -lmysqlclient

(其中 include path與 library path取決於你的 MySQL安裝路徑)

76

如果執行時發生如下 error Run problemerror in loading shared libraries libmysqlclientsoX 將你的 MySQL library path(for exampleusrlocalmysqllibmysql) 加入etcldsoconf and run sbinldconfig -v Q9ASP + MySQL 範例程式 Ans Dim myconn As New ADODBConnection Dim myrs As New Recordset Dim mySQL As String Dim myrows As Long myconnOpen DSN=MyODBCsample mySQL = SELECT from user myrsSource = mySQL Set myrsActiveConnection = myconn myrsCursorLocation = adUseClient myrsOpen myrows = myrsRecordCount myrsClose myconnClose 可參考 httpwwwdwamnetmysqlasp_myodbcasp 有詳細的資料 Q10如何將 MySQL中的資料庫匯出成txt檔 Ans select from TableName into outfile textxls all result fields will seperate by tab

77

第八章 參考資料

英文部份 網址 1 httpwwwmysqlcom MySQL 網站有第一手有關 MySQL的資料 2 httpwwwmysqlcomdocenReplicationhtml 有關 MySQL Replication 的文件 3 httpwwwgeocitiescomsqlhomefaqstore_blobhtml 如何在 MySQL 存放 BLOB的資料 4httpwwwsapdborg 有關 SAP跟 MySQL相關合作的網站 書藉 1 Cooking with MySQL

Paul DuBois has selected sample recipes from the hundreds youll find in his book MySQL

Cookbook In this third and final series of excerpts showcasing these recipes learn how to

compute team standings how to calculate the differences between successive Dec 26

2002 2 Tips for Building Web Database Applications with PHP and MySQL by Hugh E Williams co-author of Web Database Applications with PHP amp MySQL 04042002

3 Managing and Using MySQL 2nd Edition By Tim King George Reese Randy Jay Yarger

4 MySQL Cookbook By Paul DuBoisPublisher OReillyPub Date October 2002

中文部份

78

1 httplinuxtncedutwtechdocmysqlmysql_docmanual_tochtml MySQL 中文手冊 2 httpchenshloxaedutwphpZ_1php PHP+MySQ程式研習設計網站 3 httplinuxtncedutwtechdocbanicdownhtml PHP 4 手冊 4 httpwwwtncedutwadmin_zonephp台南縣教育網網路中心有很多 Linux相關文件 5 httpdobtncedutw網站建置百寶箱有很多 PHP MySQL 相關範例程式 5 httpwwwdbworldcomtw資料庫專家電子雜誌介紹資料庫的重要觀念及名詞

79

附錄一 SQL Command 介紹

SQL (讀音ess-que-el) 是一種結構查詢語法SQL 使用於資料庫交流

傳遞相容於 ANSI (American National Standards Institute) 是一套標準的關聯

式資料庫語言 SQL 語言是執行更新或從資料系統獲取資料一般常見的關聯

資料庫系統都有提供 SQL 如 Oracle Sybase Microsoft SQL Server Access Ingres 等雖然大部份的資料庫都有提供 SQL 但也多提供了自已獨特的語

法造成了不相容的情形但標準基本的語法是相通的如Select Insert Update Delete Create and Drop 每一個系統都有支援

Table相關 Command

Create Table

關聯式資料庫包含有很多元件稱為資料表(tables) 把資料或訊息放在資

料表中 資料表是以不同的名稱做分別資料表由欄列所構成的二維陣列

欄包含欄位名資料型態 及其他可判斷的資訊列是由全部欄位構成一筆一

筆的紀錄 create table 語法用在建立一個新的資料表語法格式如下

create table tablename (column1 data type column2 data type column3 data type)

Format of create table if you were to use optional constraints

create table tablename (column1 data type [constraint] column2 data type [constraint] column3 data type [constraint]) [ ] = optional

Note You may have as many columns as youd like and the constraints are optional

80

Example

create table employee (first varchar(15) last varchar(20) age number(3) address varchar(30) city varchar(20) state varchar(20))

注意建立資料表格式要以括號把前後框住而最後以(分號)做結尾

欄位名不要超過 30個字元長而且不要使用 sql 的關鍵字(如 where select等)而在後面接是型態的宣告(如字串數字日期格式等)

資料型態是來描述欄位的方式如一個欄位Last_Name 是一個姓氏可以使用varchar (可變動長度字串) 資料型態

以下是幾個常見的資料庫型態 char(size) 固定長度字串最長為 255 位元 varchar(size) 變動長度字串最大字元數以 size 來指定 number(size) 數值格式可以是整數也可以是小數最大數字以 size 位數判

斷未指定小數位數由系統內定 date 日期格式 number(sized) 數值格式最大數字以 size 位數判斷d 為小數位數整數位

數為 size-d 位

有何限制當資料表被建立通常有一或數個欄位是要使用來做關聯的功

能 例如unique 限制(唯一值)兩筆記錄不可以相同的值 not null (非空值)該欄位一定要輸入資料不可是空的primary key (主鍵)是每一筆記錄識別的主要方式

Drop a table drop table 刪除資料表(其中的資料也會一併刪除)

drop table tablename

Example

81

drop table 和刪除全部資料是不同的刪除全部資料欄位名稱資訊等還會

存在但刪除資料表會把這一些也一併移除掉

如何查詢資料

Select 基本用法

select 語法是關連式資料庫最常用的部份可以取得你想要的資料這是一個

簡單的範例 select column1[column2etc] from tablename [where condition] [] = optional 在 select 之後所列欄位名則是要顯示的資料部份你可以一一列出各欄位

名或是以 (星號)來代表選擇全部的欄位 from 之後放資料表名稱 where 子句 (選項) 指定要過濾的條件符合者才會顯現 where 可使用的條件運算元 = 等於 gt 大於 lt 小於 gt= 大或等於 lt= 小或等於 ltgt 大相等 LIKE 相似 For example select first last city

82

from empinfo where first LIKE Er 以Er 為開頭的字串就符合要以單引號框住 Or you can specify select first last from empinfo where last LIKE s 最後一字為 S 就符合 select from empinfo where first = Eric 則表示 first name 一定要是 Eric 才可以 範例資料表empinfo 統計函數

MIN 傳回指定欄位最小值

MAX 傳回指定欄位最大值

SUM 傳回指定欄位總和

AVG 傳回指定欄位平均值

COUNT 傳回指定欄位的筆數

COUNT() 傳回資料庫中的總筆數

統計函數使用於資料表中的數值欄位配合 SELECT 語法使用 只用於總結特定單一欄位可以配合 GROUP BY 做篩選但也可以不使用 GROUP BY 語句For example

SELECT AVG(salary) FROM employee

83

傳回全部 salary 平均值

Another example

SELECT AVG(salary) FROM employee WHERE title = Programmer

傳回 salary 平均值條件為 employees 資料表中當 title 等於 Programmer

Example

SELECT Count() FROM employees

傳回 employees 資料表中紀錄總筆數

GROUP BY 語法 SELECT column1 SUM(column2) FROM list-of-tables GROUP BY column-list The GROUP BY 語句可以先以所列的欄位為條件分組排序在一起(可以多欄

位) example 要列出每一個 dept 中最高 salary 值 SELECT max(salary) dept FROM employee GROUP BY dept HAVING 語法

SELECT column1 SUM(column2) FROM list-of-tables GROUP BY column-list HAVING condition

HAVING 子句是 GROUP BY 的一部份用來過濾在 GROUP BY 所選出的資料功能如同 select 命令中 where 條件式一樣只是 HAVING 必需配合 GROUP BY 使用

我們以例子來說明我們要取得每一公司名及每一公司的薪水平均值輸入如下

84

SELECT dept avg(salary) FROM employee GROUP BY dept

但如果我們只列出薪資平均值超過 20000元的公司資料

SELECT dept avg(salary) FROM employee GROUP BY dept HAVING avg(salary) gt 20000

ORDER BY子句語法

SELECT column1 SUM(column2) FROM list-of-tables ORDER BY column-list [ASC | DESC]

[ ] =選項

ORDER BY是一個選項子句當你以排序方式來顯示資料(正向由小到大反向由大到小)以指定的欄位資料做排序

ASC = 正向- 預設值 DESC = 反向排序

For example

SELECT employee_id dept name age salary FROM employee_info WHERE dept = Sales ORDER BY salary

以上列出公司代號公司名銷售員人名年紀及薪資而條件是公司名為 Sales 顯示順序以薪資多少排序(由小到大為預設值)

如果要以多個欄位做排序要以逗號做分隔如下

SELECT employee_id dept name age salary FROM employee_info WHERE dept = Sales ORDER BY salary age DESC

85

結合條件及布林運算 SELECT column1 SUM(column2) FROM list-of-tables WHERE condition1 AND condition2 AND運算可以結兩個或以上的條件放在 WHERE子句中 兩者都要為真才

會顯示該筆記錄 OR 運算可以結兩個或以上敘述放在 WHERE子句中只要其中一個為直就

會顯示該筆記錄 For example SELECT employeeid firstname lastname title salary FROM employee_info WHERE salary gt= 5000000 AND title = Programmer 必需要薪資大於等於 50000而且職稱為 Programmer同時符合才會顯示該筆資料 以下以括號括住雖然不是必需的但如此比較容易讀 SELECT employeeid firstname lastname title salary FROM employee_info WHERE (salary gt= 5000000) AND (title = Programmer) 另外範例 SELECT firstname lastname title salary FROM employee_info WHERE (title = Sales) OR (title = Programmer) 條件為只要是 Sales 或 Programmer 職稱的就會被列出 IN and BETWEEN 子句

SELECT column1 SUM(column2) FROM list-of-tables WHERE column3 IN (list-of-values) SELECT column1 SUM(column2) FROM list-of-tables WHERE column3 BETWEEN value1 AND value2 IN 子句使用在列舉項目的使用上也就是分別測試是否符合所列的值 For example

86

SELECT employeeid lastname salary FROM employee_info WHERE lastname IN (Hernandez Jones Roberts Ruiz) 條件為姓氏(astname)要符合 Hernandez Jones Roberts or Ruiz 其中一個才會被傳回 IN運算元也可以使用 OR 的語法來取代如下結果相同 SELECT employeeid lastname salary FROM employee_info WHERE lastname = Hernandez OR lastname = Jones OR lastname = Roberts OR lastname = Ruiz 但使用 IN 句子比較短也比較易懂 你也可以使用 NOT IN 來去掉不要的記錄 BETWEEN 運算元使用在判斷是否存在兩個數值之間 For example SELECT employeeid age lastname salary FROM employee_info WHERE age BETWEEN 30 AND 40 傳回年紀 30歲到 40歲之間的資料(含 30及 40歲者) 相同的也可以使用以下語法來達到相同的結果 SELECT employeeid age lastname salary FROM employee_info WHERE age gt= 30 AND age lt= 40 你也可使用 NOT BETWEEN 來濾掉中間值的資料 數學運算 標準 ANSI SQL-92 提供以下運算

87

+ 加

- 減

餘數

餘數為除法後剩整數這不在標準的 ANSI SQL 中但大部份的資料庫都會支

援這運算元以下列出有用的函數雖不在 ANSI SQL-92 提供但一般資料庫

也會支援他們

ABS(x) 傳回 x 絕對值

SIGN(x) returns the sign of input x as -1 0 or 1 (negative zero or positive respectively)

MOD(xy) 餘數 - returns the integer remainder of x divided by y (同 xy)

FLOOR(x) 傳回小或等於 x 的最大整數值

CEILING(x) or CEIL(x)

傳回大或等於 x 的最小整數值

POWER(xy) x的 y 次方

ROUND(x) 把 x 四捨五入為整數

ROUND(xd) 四捨五入取到小數 d 位

SQRT(x) x 開平方

For example SELECT round(salary) firstname FROM employee_info 傳回薪資取到整數位

如何新增資料

insert 加入一筆新紀錄到資料表中 insert into tablename (first_columnlast_column) values (first_valuelast_value) [] = optional Example insert into employee

88

(first last age address city state) values (Luke Duke 45 2130 Boars Nest Hazard Co Georgia) Note 字串要以單引號住如string 數字框住也無妨 insert into 後面接資料表名稱再接以括號括住的欄位名在 values 後括號分別對映各欄位的值 以上的例子新增了一筆名(first) 為 Luke而住所(state) 為 Georgia 的資料

如何刪除資料

delete 可以刪除單筆或多筆紀錄 delete from tablename where columnname OPERATOR value [and|or column OPERATOR value] [ ] = optional Examples delete from employee Note 如果你沒有指定 where 子句那麼全部的紀錄都會被刪除 delete from employee where lastname = May delete from employee where firstname = Mike or firstname = Eric delete from 接著資料表名 再接著是條件式判斷沒有條件式則全部紀錄會

被刪除

如何更新資料

update 用來更新你所指定的記錄要和 WHERE 配合小心使用 語法 update tablename set columnname = newvalue[nextcolumn = newvalue2] where columnname OPERATOR value [and|or column OPERATOR value] [] = optional Examples

89

update phone_book set area_code = 623 where prefix = 979 update phone_book set last_name = Smith prefix=555 suffix=9292 where last_name = Jones update employee set age = age+1 where first_name=Mary and last_name=Williams

90

附錄二Replication

測試環境

RedHat 90 + MySQL 32358 MySQL資料庫路徑 varlibmysql MySQL設定檔 etcmycnf Master IP 1921680100 Slave IP 1921680200 請至下列網址下載最新MySQL 32358套件並利用rpm ndashUvh 更新 httpupdatesredhatcom9enosi386

圖 最新 MySQL 套件

測試架構圖

91

1921680100

1921680200Master Server

erveSlave S r

圖 測試架構圖

測試步驟

Master server 部份 Step1 確認 MasterSlave機器上所裝的 MySQL版本能進行

replication( 32329 or higher ) Step2 在 Master MySQL上開放一個帳號給 Slave mysql ndashu root ndashp mysqlgtGRANT FILE ON TO repl1921680200 IDENTIFIED BY lsquoabc123rsquo mysqlgtq 上面是 Master開放一個帳號 repl密碼 abc123給 IP1921680200有檔案處理

的權限 Step3 shutdown MySQL on the Master mysqladmin ndashu root ndashp shutdown Step4 備份 Master所有資料庫 tar ndashcvf tmpmysql-snapshottar varlibmysql 注意tar的時候MySQL是要在 stop情況下 在mysql (wwwmysqlcom) 網站的FAQ有不用shutdown的方法

92

Step5 在 master機器上修改etcmycnf 在[mysqld]區段內加入參數 log-bin server-id=這邊設定 server-id=1 sql-bin-update-same binlog-do-db=CRM只針對 CRM資料庫做紀錄 Step6 Restart MySQL on the master service mysqld start 此時因為有加入 log-bin 參數因此開始有 index產生了在varlibmysql目錄下

有index檔案紀錄資料庫的異動 log Slave server 部份 Step1 在 slave設定etcmycnf 在[mysqld]區段加入 master-host= master-user= master-password= master-port= server-id= 這邊設定 master-host=1921680100 master-user=repl master-password=abc123 master-port=3306 server-id=2 master-connect-retry=60預設重試間隔 60秒 replicate-do-db=CRM告訴 slave只做 CRM資料庫的更新 log-slave-updates Step2 將 master上的 mysql-snapshottar copy到 slave上 用 ftp傳到 slave的tmp Step3 解壓縮 Master資料庫至 Slave Server上 cd varlib tar xvf tmpmysql-snapshottar chown ndashR mysqlmysql mysql

93

chmod ndashR 770 mysql (視情況) Step4 Restart MySQL on the slave server 這時在varlibmysql目錄會出現 masterinfo此檔案紀錄了 Master MySQL server的資訊

狀況測試

One-way replication

1921680100

1921680200Master Server

erveSlave S r

圖 One-way replication架構圖 Step1 Master跟 Slave網路及服務都正常情況下由 Master端異動資料後 到 Slave端瀏覽資料檢視是否有進行 replication Step2 模擬 Slave Server 當機 可用在於 slave真的當機或是 Slave 不一定需要一直跟 master connect將Slave MySQL server shutdown由 Master端異動資料到 slave端瀏覽此時Slave應該沒有被 replication 更新然後再將 Slave端 MySQL server start起來

預設 60秒後 Slave會嘗試跟 Master要求進行 replication再去 Slave端檢視是否有更新資料

94

Step3 模擬 Master當機因為是設定 One-way replication一旦 Master Server Slave端沒有 Master的 source可以 download Two-way replication 基於 Master當機狀況於是發展雙向 Replication即 1921680100 ( Host A ) 1921680200 ( Host B )都分別擔任 MasterSlave身分

1921680100

1921680200er

Server B MasterSlave Server

Server A MasterSlave Serv

圖 Two-way replication架構圖 以下是針對兩台 MySQL伺服器進行雙向 Replication Step1觀念同單向 replication只是改成 Master也有 Slave身分 Slave也有Master的身分先分別在 Server AServer B 都去 grant一個進行 replication的身分 [A]mysqlgtGRANT FILE ON TO repl1921680200 IDENTIFIED BY lsquoabc123rsquo [B]mysqlgt GRANT FILE ON TO repl1921680100 IDENTIFIED BY lsquoabc123rsquo Step2做完單向 replication後stop Server Aserver B MySQL service此時 AB資料是一樣的

95

修改etcmycnf設定 範例 Server A [mysqld] datadir=varlibmysql socket=varlibmysqlmysqlsock server-id=1 log-bin sql-bin-update-same binlog-do-db=CRM master-host=1921680200 master-user=repl master-password=abc123 log-slave-updates master-connect-retry=60 replicate-do-db=CRM Server B [mysqld] datadir=varlibmysql socket=varlibmysqlmysqlsock server-id=2 log-bin sql-bin-update-same binlog-do-db=CRM master-host=1921680100 master-user=repl master-password=abc123 log-slave-updates master-connect-retry=60 replicate-do-db=CRM 分別 start Server AServer B MySQL後此時雙方都是 MasterSlave身分一旦哪一方資料異動就會通知對方來 replication-若 replication失效則必須將Server AServer B的masterinfo及index00x 都砍掉然後分別 restart MySQL server進行測試檢視成果 實務上通常如果需要做Two-way replication通常會搭配Virtual Server使用

96

在前端架設一台Virtual Server不過此部份不在此份SOP討論範圍內有興趣

的讀者可參考 httpwwwlinuxvirtualserverorg 網站

1921680100 1921680200

Host A MasterSlave Server

Host B MasterSlave Server

Virtual Host

圖 Virtual Server + Two-way replication 架構圖

97

圖 High Availability Linux Virtual Server架構圖

98

  • COSA-SOP-03-006
  • 第一章 簡介
    • 11適用對象 (Audience)
    • 12 MySQL本身
    • 13 MySQL 40版跟50版重大的改進功能
    • 14 各家資料庫軟體比較
      • 第二章 前置需求
      • 第三章 安裝
        • 31 MySQL安裝
        • 32 phpMyAdmin安裝
        • 33 升級及注意事項
          • 第四章 MySQL管理
            • 41 Webmin 管理介面
            • 42 phpMyAdmin 的操作介面
            • 43管理指令介紹
              • 431 利用mysqladmin設定root的密碼
                  • 第五章 實用範例
                    • 51 任務一Web Base客戶通訊錄
                    • 52 任務二Web Base群組軟體 ( twig )
                      • 第六章 維護及更新程序
                        • 61 日常維護
                        • 62 更新程序
                        • 63 備份重要檔案
                        • 64 離線備份與還原
                        • 65 線上備份與還原
                          • 第七章 問題與解答
                          • 第八章 參考資料
                          • 附錄一 SQL Command 介紹
                          • 附錄二Replication
Page 27: DataBase Server Standard Operation Procedureebooks.lib.ntu.edu.tw/1_file/oss/63/93doc4-5.pdf · 業務的公司帶來了不少壓力,譬如微軟,甲骨文 ... 外的錢用在第三方的資料庫產品上,譬如就可以不用再購買甲骨文公司

第四章 MySQL管理

本章將我們介紹利用WebminphpAdminCommand的方式建立一個名為

CONTACT的資料庫內有一個 address的 Table作為我們客戶通訊錄程式使

用的資料庫

41 Webmin 管理介面

412建立資料庫

Step 1 登入Webmin

圖 4-1 登入WebMin

Step 2 點選伺服器

27

圖 4-2 伺服器畫面

Step 3 點選 MySQL資料庫伺服器

圖 4-3 MySQL資料庫伺服器

28

Step 4 建立一個新的資料庫

圖 4-4 建立 MySQL資料庫

Step 5 建立名為 CONTACT的資料庫

29

圖 4-5 指定資料庫名稱

412 建立資料表

假設我們要建立一個名為 address的 Table其結構如下 欄位名稱 資料型態 長度 說明 id INT (自動編號) 連絡人編號 name varchar文字 20 連絡人姓名 tel Varchar文字 15 連絡人電話 Step 1 選擇 CONTACT資料庫

30

圖 4-6 選擇資料庫

Step 2 指定欄位數目

31

圖 4-7 設定欄位數目

Step 3設定表格欄位屬性

圖 3-8 設定表格欄位屬性

Step 4建立表格資料

32

圖 4-9 建立表格資料

圖 4-10 檢視資料

33

圖 4-11 新增資料

圖 4-12

34

圖 4-13

413 使用者管理

接下來我們要利用Webmin 來建立資料庫使用者並給予某些權限 Step1建立使用者

35

圖 4-14 選擇使用者權限

圖 4-15

36

Step2 賦予權限

圖 4-16

Step3 權限列表

37

圖 4-17

38

42 phpMyAdmin 的操作介面

421建立資料庫

Step 填入資料庫名稱並按「建立」

圖 4-18建立資料庫

422 建立資料表

Step1 填入資料表名稱並指定欄位數量 執行

39

圖 4-19填入資料表名稱並指定欄位數量

Step2 設定欄位屬性

圖 4-20設定欄位屬性

40

Step3 phpMyAdmin會產生相關的 SQL Command

圖 4-21 資料表結構及相關 SQL Command

Step4新增 Record

41

圖 4-22

圖 4-23

42

圖 4-24

圖 4-25

43

423使用者管理

Step1建立使用者

圖 4-26

44

圖 4-27

Step2 給予權限

圖 4-28

Step3權限列表

45

圖 4-29

43管理指令介紹

431 利用 mysqladmin設定 root的密碼

當您在Windows 或 Linux 中安裝好 MySQL後系統會自動幫您建立兩個

帳分別是 root 和 匿名者MySQL的 root 跟 Linux 最高權限使用者 root無關MySQL的 root使用者相當於 MS SQL 中的 sa 帳號擁有最高的 Database管理權限但系統預設 MySQL的 root 是不需要密碼所以通常我們一安裝

MySQL後首要任務便是修改 root的密碼 我們可以利用 mysqladmin工具或是直接修改 MySQL內部資料庫的使用者資

料 mysqladmin ndashu root ndashh cosaexamplecom password lsquo1234rsquo

46

-u 表示使用者帳號root 為 MySQL預設的管理帳號

-h 表示 MySQL主機的主機名稱也可使用 IP Address password 表示使用者的密碼因為字串請使用單引號將密碼括起來 密碼設定完成之後還是可以利用 mysqladmin修改密碼但是你必須提供目前的密碼

432 連線 MySQL

mysql -uroot -p密碼 (-p和密碼之間不能有空白) 或 mysql -uroot -p (此方式會在進入後要求密碼) [rootossc phpMyAdmin] mysql -u root -p1234

Welcome to the MySQL monitor Commands end with or g

Your MySQL connection id is 25 to server version 32354

Type help or h for help Type c to clear the buffer

mysqlgt show databases

+----------+

| Database |

+----------+

| mysql |

| test |

+----------+

2 rows in set (000 sec)

mysqlgt exit

Bye

[rootossc phpMyAdmin]

433 建立資料庫

可利用 mysqladmin指令建立 CONTACT資料庫 mysqladmin -u root -p1234 create CONTACT

47

或是利用 mysql指令 [rootossc bluepage] mysql -u root -p1234 Welcome to the MySQL monitor Commands end with or g Your MySQL connection id is 1057 to server version 32354 Type help or h for help Type c to clear the buffer mysqlgt create database CONTACT Query OK 1 row affected (000 sec) mysqlgt show databases +----------+ | Database | +----------+ | CONTACT | | address | | hello | | mysql | | nuke | | test | +----------+ 6 rows in set (000 sec) mysqlgt exit

434 建立資料表

編寫 adresssql內容如下 -- Table structure for table address CREATE TABLE address ( id int(11) NOT NULL auto_increment name varchar(20) NOT NULL default tel varchar(15) NOT NULL default PRIMARY KEY (id) ) TYPE=MyISAM

48

-- Dumping data for table address INSERT INTO address VALUES (1林小明0800016888) INSERT INTO address VALUES (2黃大雄0800016888) INSERT INTO address VALUES (3劉小芬0800024365) 然後執行此 sql script mysql -u root -p1234 CONTACT lt addresssql 或是利 mysql command [rootossc bluepage] mysql -u root -p1234 Welcome to the MySQL monitor Commands end with or g Your MySQL connection id is 1090 to server version 32354 Type help or h for help Type c to clear the buffer mysqlgt use CONTACT Database changed Database changed mysqlgt CREATE TABLE address ( -gt id int(11) NOT NULL auto_increment -gt name varchar(20) NOT NULL default -gt tel varchar(15) NOT NULL default -gt PRIMARY KEY (id) -gt ) TYPE=MyISAM Query OK 0 rows affected (000 sec) mysqlgt INSERT INTO address VALUES (1林小明0800016888) Query OK 1 row affected (000 sec) mysqlgt INSERT INTO address VALUES (2黃大雄0800016888) Query OK 1 row affected (000 sec) mysqlgt INSERT INTO address VALUES (3劉小芬0800024365) Query OK 1 row affected (000 sec) mysqlgt exit Bye

49

第五章 實用範例

51 任務一Web Base客戶通訊錄

任職於開放科技公司的林小明前些日子在最符合成本效益的條件下快

速地完成公司網站的建置老闆因此對小明讚譽有加最近因為公司存放客戶資

料的 SQL Server主機屢遭病毒攻擊加上作業系統本身的問題當機次數頻繁

老闆希望能儘快把公司的客戶通訊錄程式移轉到較穩定的環境上因為此客戶通

訊錄程式最主要給內部人員使用所以介面美觀並不特別要求只求穩定且能快

速得到查詢結果老闆希望在短時間先看到程式的雛型並鍵入資料對其效率

及穩定性進行測試因為上次小明表現突出所以這次不可能的任務自然又落到

小明身上 小明想來想去既然要快速又穩定他而且又不希望所有人都得安裝 Client

程式於是小明決定)捨棄他的舊愛「Delphi+MS SQL」投向新歡「Apache + MySQL + PHP」利用此架構來設計一個簡單實用的Web Base客戶通訊錄程式

511 Web Base客戶通訊錄架構

此程式需要建立 CONTACT的資料庫並建立 adress Tables其結構如下表建立步驟請參考第三章 欄位名稱 資料型態 長度 說明 id INT (自動編號) 連絡人編號 name varchar文字 20 連絡人姓名 tel Varchar文字 15 連絡人電話 Web Base通訊錄共有下列幾個檔案功能如下表

檔案名稱 說明 Indexhtml Web Base通訊錄首頁 addphp 新增連絡人的 php程式 searchphp 尋找連絡人的 php程式 editphp 具有更新及刪除功能的 php程式

50

我們將這些檔案放至varwwwhtmlbluepage (預設無 bluepage目錄)

512 Web Base通訊錄測試

httpwwwopencombluepage 新增資料

圖 5-1 新增連絡人

圖 5-2 填入資料

51

圖 5-3 新增成功

搜尋及異動資料

圖 5-4 搜尋通訊錄

52

圖 5-5 編輯資料

圖 5-6 更新資料

513 程式內容及說明

lt-- 程式範例indexhtml--gt lthtmlgt ltheadgtlttitlegt通訊錄lttitlegtltheadgt ltbodygt ltcentergt

53

lth2gt通訊錄lth2gtlthrgt lta href=indexhtmlgt通訊錄ltagt | lta href=addphpgt新增連絡人ltagt | lta href=searchphpgt搜尋通訊錄ltagt ltcentergt ltbodygt lthtmlgt lt-- 程式範例addphp --gt lthtmlgt ltheadgtlttitlegt新增連絡人lttitlegtltheadgt ltbodygt ltcentergtlth2gt新增連絡人lth2gtltcentergtlthrgt lt 取得欄位資料 if (isset($_POST[Name]) ampamp isset($_POST[Tel]) ) $name = $_POST[Name] $tel = $_POST[Tel] 檢查是否有輸入欄位資料 if ($name = ampamp $tel = ) 建立 SQL字串 $sql = INSERT INTO address (name tel) values( $sql= $name $tel) 建立 MySQL 連結 $link = mysql_connect(localhostroot1234) 選擇資料庫 mysql_select_db(CONTACT) 執行 SQL指令 mysql_query($sql) mysql_close($link) echo ltfont color=redgt新增連絡人成功ltfontgtltbrgt gt ltform action=addphp method=postgt lttable border=0 width=300gt lttrgtlttdgt姓名 lttdgt

54

lttdgtltinput type=text name=Name size=20 maxlength=10gtlttdgtlttrgt lttrgtlttdgt電話 lttdgt lttdgtltinput type=text name=Tel size=20 maxlength=20gtlttdgtlttrgt lttrgtlttd colspan=2 align=centergt ltinput type=submit value=新增連絡人gtlttdgtlttrgt lttablegt ltformgt ltbrgtlta href=indexhtmlgt通訊錄ltagt | lta href=addphpgt新增連絡人ltagt | lta href=searchphpgt搜尋通訊錄ltagt ltbodygt lthtmlgt

lt-- 程式範例searchphp --gt lthtmlgt ltheadgtlttitlegt搜尋通訊錄lttitlegtltheadgt ltbodygt ltcentergtlth2gt搜尋通訊錄lth2gtlthrgt lt if (isset($_POST[Search])) 建立資料庫連結並選定資料庫 $link = mysql_connect(localhostroot1234) mysql_select_db(CONTACT) 建立基本的 SQL字串 $sql = SELECT FROM address 檢查是否輸入姓名 if (chop($_POST[Name]) = ) $name = name LIKE $_POST[Name] else $name = 檢查是否輸入電話號碼 if (chop($_POST[Tel]) = ) $tel = tel LIKE $_POST[Tel] else $tel =

55

if條件組合 SQL字串 if (chop($name) = ampamp chop($tel) = ) $sql= WHERE $name AND $tel elseif (chop($name) = ) 只有姓名 $sql = WHERE $name elseif (chop($tel) = ) 只有電話號碼 $sql = WHERE $tel $sql= ORDER BY name 最後加上排序 $result = mysql_query($sql) 取得欄位數 $total_fields = mysql_num_fields($result) echo lttable border=1gt echo lttrgtlttdgt編號lttdgtlttdgt姓名lttdgtlttdgt電話lttdgtlttd colspan=2gt功能選項lttdgtlttrgt 表格顯示查詢結果 while ($rows = mysql_fetch_array($result MYSQL_NUM)) echo lttrgt for ($i = 0 $i lt $total_fields $i++) echo lttdgt$rows[$i]lttdgt echo lttdgtlta href=editphpaction=editampid= echo $rows[0]gtltbgt編輯ltbgtlttdgt echo lttdgtlta href=editphpaction=delampid= echo $rows[0]gtltbgt刪除ltbgtlttdgt echo lttrgt echo lttablegtlthrgt mysql_free_result($result) mysql_close($link) gt ltcentergt ltform action=searchphp method=postgt lttable border=0 width=450gt lttrgtlttdgt搜尋姓名 lttdgt lttdgtltinput type=text name=Name size=10 maxlength=20gtlttdgtlttrgt lttrgtlttdgt搜尋電話 lttdgt lttdgtltinput type=text name=Tel

56

size=20 maxlength=20gtlttdgtlttrgt lttrgtlttd colspan=2 align=centergt ltinput type=submit name=Search value=搜尋gtlttdgtlttrgt lttablegt ltformgt ltbrgtlta href=indexhtmlgt通訊錄ltagt | lta href=addphpgt新增連絡人ltagt | lta href=searchphpgt搜尋通訊錄ltagt ltbodygt lthtmlgt

lt ob_start() gt lt-- 程式範例editphp --gt lthtmlgt ltheadgtlttitlegt編輯通訊錄lttitlegtltheadgt ltbodygt lt 取得 URL 參數 $id = $_GET[id] $action = $_GET[action] 建立資料庫連結 $link = mysql_connect(localhostroot1234) mysql_select_db(CONTACT) 選擇資料庫 執行的操作 switch ($action) case update 更新 取得欄位資料 $name = $_POST[Name] $tel = $_POST[Tel] $sql = UPDATE address SET name=$name tel=$tel WHERE id=$id mysql_query($sql) 執行 SQL指令 mysql_close($link) header(Location searchphp) 轉向到 serachphp break case del 刪除 $sql = DELETE FROM address WHERE id=$id

57

mysql_query($sql) 執行 SQL指令 mysql_close($link) header(Location searchphp) 轉向到 serachphp break case edit 編輯 $sql = SELECT FROM address WHERE id=$id $result = mysql_query($sql) 執行 SQL指令 $row = mysql_fetch_row($result) 取回記錄 $name = $row[1] 取得欄位 name $tel = $row[2] 取得欄位 tel mysql_close($link) 顯示編輯表單 gt ltcentergtlth2gt更新通訊錄lth2gtltcentergtlthrgt ltform action=editphpaction=updateampid=lt echo $id gt method=postgt lttable border=0 width=300gt lttrgtlttdgt姓名 lttdgt lttdgtltinput type=text name=Name size=20 maxlength=10 value=lt echo $name gtgtlttdgtlttrgt lttrgtlttdgt電話 lttdgt lttdgtltinput type=text name=Tel size=20 maxlength=20 value=lt echo $tel gtgtlttdgtlttrgt lttrgtlttd colspan=2 align=centergt ltinput type=submit value=更新連絡人gtlttdgtlttrgt lttablegt ltformgt ltbrgtlta href=indexhtmlgt通訊錄ltagt | lta href=addphpgt新增連絡人ltagt | lta href=searchphpgt搜尋通訊錄ltagt lt break gt ltbodygt lthtmlgt

58

52 任務二Web Base群組軟體 ( twig )

順利完成Web Base客戶通訊錄程式測試一段時間後「Apache + MySQL + PHP」架構的穩定與快速巳深得老闆與公司所有同事的認同隨著公司業績蒸

蒸日上人員組織編罝愈來愈龐大跨部門的會議愈來愈多業務員每日排滿拜

訪客戶的行程跟客戶的 Email的往來也愈來愈頻繁 愈來愈多部門的同事希望公司能建置一套群組軟體提供 web mail可讓業

務人員方便收發 mail還有連絡人議事日程待辦工作書簽等功能讓整個

公司運作及個人時間管理更有效率

老闆問小明對這些需求有什麼看法小明認為如果這些功能完全由程式部

門開發必定曠日費時而且耗費公司資源小明在網路尋找是否有提供這些功能

的Free Software皇天不負苦心人小明發現了TWIG (The Web Information Gateway) httptwigscrewdrivernet這個群組軟體它在 Web 上整合郵件新聞聯絡人議事日程工作序書簽等功能非常符合公司的需求 Step 1 下載 twig-277targz 下載網址 httptwigscrewdrivernetdownloadphp3

Step 2 解開 twig-277targz tar -xzvf twig-277targz

59

Step 3 執行安裝動作安裝到 varwwwhtmltwig 目錄 cd twig-277 twig-install varwwwhtmltwig

Step 4 建立 MySQL 資料庫(twig)及各資料表

cd setup mysql -u root -p1234 mysqlgt create database twig Query OK 1 row affected (001 sec) mysqlgt quit mysql -u root ndashp1234 twiglt twigtablemysql

Step 5 修改 configincphp3 參數設定 vi varwwwhtmltwigconfigconfigincphp3 $config[fromdomain] = opencom 網域 $config[language] = chinesebig5 中文訊息 $config[imap_port] = 143notls

60

Step 6 修改連結 MySQL 的帳號密碼 vi varwwwhtmltwigconfigdbconfigincphp3 $dbconfig[sqlusername] = root username $dbconfig[sqlpassword] = 1234 password

Step 7 其他設定檔

vi etchttpdconfhttpdconf 加入 AddType applicationx-httpd-php php3 在 DirectoryIndex最後加入 indexphp3 DirectoryIndex indexhtml indexhtmlvar indexphp3 在 AddDefaultCharset ISO-8859-1加上 AddDefaultCharset ISO-8859-1

vi etcphpini register_globals = On service httpd restart Step 8 sendmail 設定 vi etcmailsendmailcf在 264 行前面加上並重新啟動 sendmail「service snedmail restart」 262 SMTP daemon options 263 264 O DaemonPortOptions=Port=smtpAddr=127001 Name=MTA 265 266 SMTP client options 267 O ClientPortOptions=Family=inet Address=00

61

Step 9 檢查設定有無錯誤 http主機名稱twigtestphp3

62

Step 10 登入 twig ( http主機名稱twig)

63

第六章 維護及更新程序

61 日常維護

系統管理員最好定期以 root 身份登入看看信件在 RedHat Linux 中有一支 logwatch 程式會定時去分析 log file如果發現異常便會發信給 root除此之外筆者建議讀者平時就檢查 MySQL log file ( varlogmysqldlog)是否有異常情形

62 更新程序

讀者可至httprpmfindnet 尋找MySQL相關套件至於升級的相關步驟請參

考Linux OS SOP 第 54節

63 備份重要檔案

預設 MySQL 的 DB 檔案是存在 varlibmysql 內以 DB名稱為目錄目錄

內就是該 DB 的所有資料通常得定期備份還有 MySQL的設定檔 etcmycnf也別忘了一起備份

64 離線備份與還原

641 離線備份

預設 MySQL 的 DB 檔案是存在 varlibmysql 內以 DB 名稱為目錄目錄內

就是該 DB 的所有資料像 CRM 這個 DB就是存在 varlibmysqlCRM 內在備份前因為怕資料尚未完全寫入磁碟而且 MySQL 會 Lock 在使用的 DB 檔案所以應該是要先把 MySQL 先 Shutdown 一下整個備份的程序可以下像下面的指令去完成 cd varlibmysql

64

service mysqld stop tar cvfz CRM_db_20030905tgz CRM service mysqld start 對這樣就可以了 不過要注意的是怕 DB 內每個 Tables 間的資料有關關

聯性所以最好是把整個 DB 一次備起來單獨只備哪個 Tables 的檔案以後回存時怕會有資料關聯不一致的問題

642 離線還原

DB 發生錯誤而要回存時其實也不難先找出最近一次完整正常的備份先把現在錯誤的網頁或 DB 先更名或 tar 起來再把好的備份給解開回原來目錄位

置就行了需要注意的是 MySQL 服務最好也是要先停止回存完成後再啟動服務回存 DB 的整個程序可能像下面 cd varlibmysql service mysqldstop mv CRM CRM_OLD tar xvfz CRM_db_20030905tg service mysqld start

65 線上備份與還原

651 線上備份

使用像上面的檔案方式備份是個不錯的方法它最少可以保持該主機某個時間點的完整檔案備份但還是有一些問題需要考慮到有些主機就不只建立一個 DB 而已總不能為了備份某個 DB 而把整個 MySQL 服務停止備份檔案的方式回存在原主機上一定適用但假如 MySQL 版本升級或是在那天該網頁空間需遷機移機到別的主機時那就沒人敢保證備出來的資料檔可以用所以我們可以考慮另一種備份的方式是使用 MySQL 本身提供的功能 MySQL Data Dump指令是 mysqldump

65

使用 MySQL 的 Dump 功能可以把 DB 的結構資料或結構加資料 Dump 成文字檔 mysqldump 指令提供的彈性很大你可以選擇把整個 DB Dump 成一個檔或是每個 Table 為一個檔甚至是把結構檔和資料分開儲存都

可以 mysqladmin -uroot -p flush-logs mysqldump CRM -uroot -p --opt gt CRM_20030905sql (CRM 是 DB 名稱 opt 是一個使用完整 Dump 參數) 假如只是要單獨 Dump 某個 Table 時只要在上面的指令後轉出符號 gt 前加個 Table 名稱就可以如只要 phpbb2_users 這個 Table 的 Dump 時只要下 mysqldump CRM -uroot -p --opt CUSTOMER gt CRM_CUSTOMER_20030905sql

652 線上還原

若要回存整個資料庫只需將壓縮的備份檔還原成 Dump 的檔案再用下面的指令回存 mysql CRM -uroot -p lt CRM_20030905sql 這邊需注意的是若建立備份時是以--opt或--add-drop-table為參數時回存的 動作是先將舊的 Table 先刪除重建 Table 的結構後再把 Data 匯入所以回存後所有的資料會回到你當時備份那個時間點因此在回存資料時可以考慮把現有錯誤或不完整的 DB 先備份一份下來以備不時之需或是拿來比對錯誤的地

方在那裡當然你也可以把資料回存到另一個測試用的 DB 內只要把上面指令

的 DB 名稱改成你的測試用 DB 名稱即可 使用這種回存方式 MySQL 服務不需停止也不會動到其他正在使用的 DB 在一些提供 MySQL 服務的虛擬主機可用這種方式作你自己的 DB 備份及回存

66

另外假如你是系統重建或是移機時切需在新的 MySQL 內新建一個空白 DB 後才行作回存的工作你可以用下面的指令建立 mysql -uroot -p -e CREATE DATABASE CRM (上面的 CRM是你要新建的 DB 名稱) 另一種作法先用 mysql 指令進入 mysql client console 然後再用 CREATE DATABASE CRM 這樣就行了記得尾端要加個 符號該行指令才會執行

67

第七章 問題與解答

Q1RedHat 90預附的 MySQL到底有無支援 Transcation機制 Ans MySQL自 32334a之後的 MySQL-Max版本加入 InnoDB的資料庫類型透過

InnoDBMySQL同樣可以進行 COMMIT與 ROLLRACK的動作RedHat 90預附的 MySQL為 32354a-11巳支援 InnoDB的資料庫類型不過必須做以

下設定 1cp usrsharedocmysql-server-32354amy-mediumcnf to etcmycnf 2 vi etcmycnf 將以下設定前的拿掉 innodb_data_home_dir = varlibmysql innodb_data_file_path = ibdata110Mautoextend innodb_log_group_home_dir = varlibmysql innodb_log_arch_dir = varlibmysql 3service mysqld restart 如此一來各位在建立Table時便可指定Table Type為 innodb ( ex create table with type=innodb ) Q2如何解決 php+mysql 許功蓋等字變亂的問題 Ans 方法一 【確定 MySQL 預設的字元集】 1 打開 WinMySQLadmin 管理畫面(在視窗右下角狀態列紅綠燈圖示中按滑鼠

右鍵點選 Show me 選項) 2 點選管理畫面中 [Variables] 標籤選項其中 character_set變數就是您預設

字元集的變數其預設是 latin1 字元集(我們要將他改回 big5)而 chatacters_set 變數則是 MySQL 可以支援哪些字元集 【修改預設字元集變數 character_set 】 1 請點選管理畫面中 [myini Setup] 標籤選項設定 myini 2 按一下 [Pick-up and Edit myini values] 按鈕以便編輯目前的 myini 設定 3 在 [mysqld] 設定區塊底下新增一行 default-character-set = big5 變數設

68

定 4 新增一個 [client] 設定區塊並加入第三步驟的變數設定(游標往下移到空白處新增兩行 [client] 和 default-character-set=big5) 5 按一下畫面左下方 [Save Modification] 按鈕儲存設定 6 重新啟動 MySQL 或 Windows 方法二 Server端注意事項 phpini 中有關的設定為(預設值) Magic quotes for incoming GETPOSTCookie data magic_quotes_gpc = On Use Sybase-style magic quotes (escape with instead of ) magic_quotes_sybase = Off Client端注意事項 1中文資料送進 mysql 前請用 addslashes($str) 處理 2處理後送進 mysql 時請用 括起來並在參數後留一個空白如 $sql = UPDATE ezf_table set tablename=$tname tableend=$endtime table inguser=$tguser tableingid=$tguserid tableallnumber=$tnumber tableloca l=$tablelocal tableanyone=$tableopen tabletext=$ttext WHERE tableid=$t ableid tablename=$tname c 取出時請用 stripslashes($str) Q3MySQL root 密碼忘了該怎麼辦 Ans 1先停掉 mysql etcrcdinitdmysql stop 2以--skip-grant-table 的參數啟動 mysql safe_mysql --skip-grant-tableamp 3 更改 root 密碼 mysql mysql mysqlgt UPDATE user SET password=password(newpassword)

69

WHERE user=root mysqlgt FLUSH PRIVILEGES mysqlgt exit 4停掉 mysql再重跑 mysqladmin -uroot -p shutdown Enter password 輸入新設定的密碼 etcrcdinitdmysql start

Q4NULL值問題

Ans

NULL值的概念是造成 SQL的新手的混淆的普遍原因他們經常認為 NULL是和一個空字符串的一樣的東西不是這樣的例如下列語句是完全不同的

mysqlgt INSERT INTO my_table (phone) VALUES (NULL)

mysqlgt INSERT INTO my_table (phone) VALUES ()

兩個語句把值插入到 phone 列但是第一個插入一個 NULL值而第二個插入一個空字符串第一個的含義可以認為是ldquo電話號碼不知道而第二個則可意味

著ldquo她沒有電話

在 SQL中NULL值在于任何其他值甚至 NULL值比較時總是假的(FALSE)包含 NULL的一個表達式總是產生一個 NULL值除非在包含在表達式中的運算符和函數的文檔中指出在下列例子所有的列返回 NULL

mysqlgt SELECT NULL1+NULLCONCAT(InvisibleNULL)

如果你想要尋找值是 NULL的列你不能使用=NULL測試下列語句不返回任

何行因為對任何表達式expr = NULL是假的

mysqlgt SELECT FROM my_table WHERE phone = NULL

要想尋找 NULL值你必須使用 IS NULL測試下例顯示如何找出 NULL電話號碼和空的電話號碼

70

mysqlgt SELECT FROM my_table WHERE phone IS NULL mysqlgt SELECT FROM my_table WHERE phone =

在 MySQL中就像很多其他的 SQL服務器一樣你不能索引可以有 NULL值的列你必須聲明這樣的列為 NOT NULL而且你不能插入 NULL到索引的

列中

當用 LOAD DATA INFILE 讀取數據時空列用更新如果你想要在一個列中有

NULL值你應該在文本文件中使用N字面上的詞NULL也可以在某些情形下使用

當使用 ORDER BY時首先呈現 NULL值如果你用 DESC以降序排序NULL值最後顯示當使用 GROUP BY時所有的 NULL值被認為是相等的

為了有助于NULL的處理你能使用 IS NULL和 IS NOT NULL運算符和 IFNULL()函數

對某些列類型NULL值被特殊地處理如果你將 NULL插入表的第一個TIMESTAMP 列則插入當前的日期和時間如果你將 NULL插入一個AUTO_INCREMENT 列則插入順序中的下一個數字

Q5如何將圖片存放於 MySQL中

Ans

Step 1建立資料庫 test

Step 2 建立表格 binary_data

CREATE TABLE binary_data (

id INT(4) NOT NULL AUTO_INCREMENT PRIMARY KEY

description CHAR(50)

bin_data LONGBLOB

filename CHAR(50)

filesize CHAR(50)

filetype CHAR(50)

71

)

Step 3 利用 storephp 寫入圖片

storephp 程式碼

ltHTMLgt ltHEADgtltTITLEgtStore binary data into SQL DatabaseltTITLEgtltHEADgt ltBODYgt lt code that will be executed if the form has been submitted

if ($submit) mysql_connect(localhostrootYOUR_PASSWORD) mysql_select_db(test) $data=Base64_Encode(fread(fopen($form_data r) filesize($form_data))) $result=MYSQL_QUERY(INSERT INTO binary_data (descriptionbin_datafilenamefilesizefiletype) VALUES ($form_description$data$form_data_name$form_data_size$form_data_type)) $id= mysql_insert_id() print ltpgtThis file has the following Database ID ltbgt$idltbgt MYSQL_CLOSE() else else show the form to submit new data

gt

ltform method=post action=ltphp echo $PHP_SELF gt enctype=multipartform-datagt File Descriptionltbrgt ltinput type=text name=form_description size=40gt ltINPUT TYPE=hidden name=MAX_FILE_SIZE value=4000000gt ltbrgtFile to uploadstore in databaseltbrgt ltinput type=file name=form_data size=40gt ltpgtltinput type=submit name=submit value=submitgt ltformgt lt

72

gt ltBODYgt ltHTMLgt

Step 3 利用 storephp 取出圖片

getdataphp 程式碼

lt Syntax getdataphp3id=ltidgt if($id) you may have to modify login information for your database server MYSQL_CONNECT(localhostrootYOUR_PASSWORD) mysql_select_db(test) $query = select bin_datafiletype from binary_data where id=$id $result = MYSQL_QUERY($query) $data = Base64_Decode(MYSQL_RESULT($result0bin_data)) $type = MYSQL_RESULT($result0filetype) Header( Content-type $type) echo $data gt

Q6MySQL裝好之後啟動時或是執行 mysqladmin會出現如下訊息 Cant connect to local MYSQL Server through Socket varlibmysqlmysqlsock或是

Cant connect to local MYSQL Server through Socket tmpmysqldsock

Ans 可能有下列幾個原因

1這個 mysqldsock 不見了被某人刪除了或是被一些系統自動執行程式給刪

了例如有些 cron任務便會設定定期刪除 tmp 裡的東西所以呢您只能修改

cron 裡的設定讓它不要清除 mysqldsock 2在啟動時也可以改變 mysqldsock的位置您在啟動 MySQL的時候可以加入此參數usrlocalmysqlbinsafe_mysqld --user=mysql --socket=其他路

徑socket amp 同時得去設定環境變數 MYSQL_UNIX_PORT的值以指定新的

73

路徑 3若是您沒改 MYSQL_UNIX_PORT的值那麼您可以在執行指令的時候才打

例如mysqladmin --socket=其他路徑socket version Q7How to get the last insert id Ans CREATE TABLE product ( id INT(4) NOT NULL AUTO_INCREMENT PRIMARY KEY description VARCHAR(50) ) 1利用 SQL的話 mysqlgt insert into product(description) values(123) Query OK 1 row affected (000 sec) mysqlgt select last_insert_id() +------------------+ | last_insert_id() | +------------------+ +------------------+ 1 row in set (000 sec) ======================================== 2如果是 PHP的話 你可以用mysql_insert_id()取得該 id PHP example $result=MYSQL_QUERY(INSERT INTO product (description) VALUES ($description)) $id= mysql_insert_id() print This file has the following Database ID $id Q8如何將文字檔匯入資料庫 Ans $addr=homehttpdhtmlphpschool001txt $sql_select = load data infile $addr into table test fields terminated by t 解說 $sql_select = load data infile 文字檔名 into table 表格名 fields terminated by

74

t

(欄位分隔以 TAB鍵) 該文字檔須與資料表欄位格式相符 例如欄位有三個 則文字檔為每行一筆資料如下 欄 1資料ltTABgt欄 2資料ltTABgt欄 3資料 欄 1資料ltTABgt欄 2資料ltTABgt欄 3資料 欄 1資料ltTABgt欄 2資料ltTABgt欄 3資料 欄 1資料ltTABgtltTABgt欄 3資料

Q9如何撰寫 MySQL C API Ans Step 1利用文字編輯器撰寫以下程式碼 mysqlcc

include ltstdiohgt

include ltmysqlmysqlhgt

int main (int argc char argv[])

MYSQL mysql

MYSQL_RES res

MYSQL_ROW row

if (argc = 2)

fputs (Usage myc ltdatabasegt stderr)

return 1

if ((mysql_connect(ampmysqllocalhostrootYour_Password)))

fputs (Error connecting stderr)

abort()

75

if (mysql_select_db(ampmysqlargv[1]))

fputs (Error selecting database stderr)

abort()

if (mysql_query(ampmysqlSELECT FROM test_table))

fputs (Error processing query stderr)

abort()

if ((res = mysql_store_result(ampmysql)))

fputs (Error storing results stderr)

abort()

while((row = mysql_fetch_row(res)))

uint i = 0

for (i=0 i lt mysql_num_fields(res) i++)

printf(s row[i])

printf(n)

return 0

Step 2 Compile

gcc -Iusrlocalmysqlinclude -Lusrlocalmysqllibmysql mysqlcc ndashlm -lmysqlclient

(其中 include path與 library path取決於你的 MySQL安裝路徑)

76

如果執行時發生如下 error Run problemerror in loading shared libraries libmysqlclientsoX 將你的 MySQL library path(for exampleusrlocalmysqllibmysql) 加入etcldsoconf and run sbinldconfig -v Q9ASP + MySQL 範例程式 Ans Dim myconn As New ADODBConnection Dim myrs As New Recordset Dim mySQL As String Dim myrows As Long myconnOpen DSN=MyODBCsample mySQL = SELECT from user myrsSource = mySQL Set myrsActiveConnection = myconn myrsCursorLocation = adUseClient myrsOpen myrows = myrsRecordCount myrsClose myconnClose 可參考 httpwwwdwamnetmysqlasp_myodbcasp 有詳細的資料 Q10如何將 MySQL中的資料庫匯出成txt檔 Ans select from TableName into outfile textxls all result fields will seperate by tab

77

第八章 參考資料

英文部份 網址 1 httpwwwmysqlcom MySQL 網站有第一手有關 MySQL的資料 2 httpwwwmysqlcomdocenReplicationhtml 有關 MySQL Replication 的文件 3 httpwwwgeocitiescomsqlhomefaqstore_blobhtml 如何在 MySQL 存放 BLOB的資料 4httpwwwsapdborg 有關 SAP跟 MySQL相關合作的網站 書藉 1 Cooking with MySQL

Paul DuBois has selected sample recipes from the hundreds youll find in his book MySQL

Cookbook In this third and final series of excerpts showcasing these recipes learn how to

compute team standings how to calculate the differences between successive Dec 26

2002 2 Tips for Building Web Database Applications with PHP and MySQL by Hugh E Williams co-author of Web Database Applications with PHP amp MySQL 04042002

3 Managing and Using MySQL 2nd Edition By Tim King George Reese Randy Jay Yarger

4 MySQL Cookbook By Paul DuBoisPublisher OReillyPub Date October 2002

中文部份

78

1 httplinuxtncedutwtechdocmysqlmysql_docmanual_tochtml MySQL 中文手冊 2 httpchenshloxaedutwphpZ_1php PHP+MySQ程式研習設計網站 3 httplinuxtncedutwtechdocbanicdownhtml PHP 4 手冊 4 httpwwwtncedutwadmin_zonephp台南縣教育網網路中心有很多 Linux相關文件 5 httpdobtncedutw網站建置百寶箱有很多 PHP MySQL 相關範例程式 5 httpwwwdbworldcomtw資料庫專家電子雜誌介紹資料庫的重要觀念及名詞

79

附錄一 SQL Command 介紹

SQL (讀音ess-que-el) 是一種結構查詢語法SQL 使用於資料庫交流

傳遞相容於 ANSI (American National Standards Institute) 是一套標準的關聯

式資料庫語言 SQL 語言是執行更新或從資料系統獲取資料一般常見的關聯

資料庫系統都有提供 SQL 如 Oracle Sybase Microsoft SQL Server Access Ingres 等雖然大部份的資料庫都有提供 SQL 但也多提供了自已獨特的語

法造成了不相容的情形但標準基本的語法是相通的如Select Insert Update Delete Create and Drop 每一個系統都有支援

Table相關 Command

Create Table

關聯式資料庫包含有很多元件稱為資料表(tables) 把資料或訊息放在資

料表中 資料表是以不同的名稱做分別資料表由欄列所構成的二維陣列

欄包含欄位名資料型態 及其他可判斷的資訊列是由全部欄位構成一筆一

筆的紀錄 create table 語法用在建立一個新的資料表語法格式如下

create table tablename (column1 data type column2 data type column3 data type)

Format of create table if you were to use optional constraints

create table tablename (column1 data type [constraint] column2 data type [constraint] column3 data type [constraint]) [ ] = optional

Note You may have as many columns as youd like and the constraints are optional

80

Example

create table employee (first varchar(15) last varchar(20) age number(3) address varchar(30) city varchar(20) state varchar(20))

注意建立資料表格式要以括號把前後框住而最後以(分號)做結尾

欄位名不要超過 30個字元長而且不要使用 sql 的關鍵字(如 where select等)而在後面接是型態的宣告(如字串數字日期格式等)

資料型態是來描述欄位的方式如一個欄位Last_Name 是一個姓氏可以使用varchar (可變動長度字串) 資料型態

以下是幾個常見的資料庫型態 char(size) 固定長度字串最長為 255 位元 varchar(size) 變動長度字串最大字元數以 size 來指定 number(size) 數值格式可以是整數也可以是小數最大數字以 size 位數判

斷未指定小數位數由系統內定 date 日期格式 number(sized) 數值格式最大數字以 size 位數判斷d 為小數位數整數位

數為 size-d 位

有何限制當資料表被建立通常有一或數個欄位是要使用來做關聯的功

能 例如unique 限制(唯一值)兩筆記錄不可以相同的值 not null (非空值)該欄位一定要輸入資料不可是空的primary key (主鍵)是每一筆記錄識別的主要方式

Drop a table drop table 刪除資料表(其中的資料也會一併刪除)

drop table tablename

Example

81

drop table 和刪除全部資料是不同的刪除全部資料欄位名稱資訊等還會

存在但刪除資料表會把這一些也一併移除掉

如何查詢資料

Select 基本用法

select 語法是關連式資料庫最常用的部份可以取得你想要的資料這是一個

簡單的範例 select column1[column2etc] from tablename [where condition] [] = optional 在 select 之後所列欄位名則是要顯示的資料部份你可以一一列出各欄位

名或是以 (星號)來代表選擇全部的欄位 from 之後放資料表名稱 where 子句 (選項) 指定要過濾的條件符合者才會顯現 where 可使用的條件運算元 = 等於 gt 大於 lt 小於 gt= 大或等於 lt= 小或等於 ltgt 大相等 LIKE 相似 For example select first last city

82

from empinfo where first LIKE Er 以Er 為開頭的字串就符合要以單引號框住 Or you can specify select first last from empinfo where last LIKE s 最後一字為 S 就符合 select from empinfo where first = Eric 則表示 first name 一定要是 Eric 才可以 範例資料表empinfo 統計函數

MIN 傳回指定欄位最小值

MAX 傳回指定欄位最大值

SUM 傳回指定欄位總和

AVG 傳回指定欄位平均值

COUNT 傳回指定欄位的筆數

COUNT() 傳回資料庫中的總筆數

統計函數使用於資料表中的數值欄位配合 SELECT 語法使用 只用於總結特定單一欄位可以配合 GROUP BY 做篩選但也可以不使用 GROUP BY 語句For example

SELECT AVG(salary) FROM employee

83

傳回全部 salary 平均值

Another example

SELECT AVG(salary) FROM employee WHERE title = Programmer

傳回 salary 平均值條件為 employees 資料表中當 title 等於 Programmer

Example

SELECT Count() FROM employees

傳回 employees 資料表中紀錄總筆數

GROUP BY 語法 SELECT column1 SUM(column2) FROM list-of-tables GROUP BY column-list The GROUP BY 語句可以先以所列的欄位為條件分組排序在一起(可以多欄

位) example 要列出每一個 dept 中最高 salary 值 SELECT max(salary) dept FROM employee GROUP BY dept HAVING 語法

SELECT column1 SUM(column2) FROM list-of-tables GROUP BY column-list HAVING condition

HAVING 子句是 GROUP BY 的一部份用來過濾在 GROUP BY 所選出的資料功能如同 select 命令中 where 條件式一樣只是 HAVING 必需配合 GROUP BY 使用

我們以例子來說明我們要取得每一公司名及每一公司的薪水平均值輸入如下

84

SELECT dept avg(salary) FROM employee GROUP BY dept

但如果我們只列出薪資平均值超過 20000元的公司資料

SELECT dept avg(salary) FROM employee GROUP BY dept HAVING avg(salary) gt 20000

ORDER BY子句語法

SELECT column1 SUM(column2) FROM list-of-tables ORDER BY column-list [ASC | DESC]

[ ] =選項

ORDER BY是一個選項子句當你以排序方式來顯示資料(正向由小到大反向由大到小)以指定的欄位資料做排序

ASC = 正向- 預設值 DESC = 反向排序

For example

SELECT employee_id dept name age salary FROM employee_info WHERE dept = Sales ORDER BY salary

以上列出公司代號公司名銷售員人名年紀及薪資而條件是公司名為 Sales 顯示順序以薪資多少排序(由小到大為預設值)

如果要以多個欄位做排序要以逗號做分隔如下

SELECT employee_id dept name age salary FROM employee_info WHERE dept = Sales ORDER BY salary age DESC

85

結合條件及布林運算 SELECT column1 SUM(column2) FROM list-of-tables WHERE condition1 AND condition2 AND運算可以結兩個或以上的條件放在 WHERE子句中 兩者都要為真才

會顯示該筆記錄 OR 運算可以結兩個或以上敘述放在 WHERE子句中只要其中一個為直就

會顯示該筆記錄 For example SELECT employeeid firstname lastname title salary FROM employee_info WHERE salary gt= 5000000 AND title = Programmer 必需要薪資大於等於 50000而且職稱為 Programmer同時符合才會顯示該筆資料 以下以括號括住雖然不是必需的但如此比較容易讀 SELECT employeeid firstname lastname title salary FROM employee_info WHERE (salary gt= 5000000) AND (title = Programmer) 另外範例 SELECT firstname lastname title salary FROM employee_info WHERE (title = Sales) OR (title = Programmer) 條件為只要是 Sales 或 Programmer 職稱的就會被列出 IN and BETWEEN 子句

SELECT column1 SUM(column2) FROM list-of-tables WHERE column3 IN (list-of-values) SELECT column1 SUM(column2) FROM list-of-tables WHERE column3 BETWEEN value1 AND value2 IN 子句使用在列舉項目的使用上也就是分別測試是否符合所列的值 For example

86

SELECT employeeid lastname salary FROM employee_info WHERE lastname IN (Hernandez Jones Roberts Ruiz) 條件為姓氏(astname)要符合 Hernandez Jones Roberts or Ruiz 其中一個才會被傳回 IN運算元也可以使用 OR 的語法來取代如下結果相同 SELECT employeeid lastname salary FROM employee_info WHERE lastname = Hernandez OR lastname = Jones OR lastname = Roberts OR lastname = Ruiz 但使用 IN 句子比較短也比較易懂 你也可以使用 NOT IN 來去掉不要的記錄 BETWEEN 運算元使用在判斷是否存在兩個數值之間 For example SELECT employeeid age lastname salary FROM employee_info WHERE age BETWEEN 30 AND 40 傳回年紀 30歲到 40歲之間的資料(含 30及 40歲者) 相同的也可以使用以下語法來達到相同的結果 SELECT employeeid age lastname salary FROM employee_info WHERE age gt= 30 AND age lt= 40 你也可使用 NOT BETWEEN 來濾掉中間值的資料 數學運算 標準 ANSI SQL-92 提供以下運算

87

+ 加

- 減

餘數

餘數為除法後剩整數這不在標準的 ANSI SQL 中但大部份的資料庫都會支

援這運算元以下列出有用的函數雖不在 ANSI SQL-92 提供但一般資料庫

也會支援他們

ABS(x) 傳回 x 絕對值

SIGN(x) returns the sign of input x as -1 0 or 1 (negative zero or positive respectively)

MOD(xy) 餘數 - returns the integer remainder of x divided by y (同 xy)

FLOOR(x) 傳回小或等於 x 的最大整數值

CEILING(x) or CEIL(x)

傳回大或等於 x 的最小整數值

POWER(xy) x的 y 次方

ROUND(x) 把 x 四捨五入為整數

ROUND(xd) 四捨五入取到小數 d 位

SQRT(x) x 開平方

For example SELECT round(salary) firstname FROM employee_info 傳回薪資取到整數位

如何新增資料

insert 加入一筆新紀錄到資料表中 insert into tablename (first_columnlast_column) values (first_valuelast_value) [] = optional Example insert into employee

88

(first last age address city state) values (Luke Duke 45 2130 Boars Nest Hazard Co Georgia) Note 字串要以單引號住如string 數字框住也無妨 insert into 後面接資料表名稱再接以括號括住的欄位名在 values 後括號分別對映各欄位的值 以上的例子新增了一筆名(first) 為 Luke而住所(state) 為 Georgia 的資料

如何刪除資料

delete 可以刪除單筆或多筆紀錄 delete from tablename where columnname OPERATOR value [and|or column OPERATOR value] [ ] = optional Examples delete from employee Note 如果你沒有指定 where 子句那麼全部的紀錄都會被刪除 delete from employee where lastname = May delete from employee where firstname = Mike or firstname = Eric delete from 接著資料表名 再接著是條件式判斷沒有條件式則全部紀錄會

被刪除

如何更新資料

update 用來更新你所指定的記錄要和 WHERE 配合小心使用 語法 update tablename set columnname = newvalue[nextcolumn = newvalue2] where columnname OPERATOR value [and|or column OPERATOR value] [] = optional Examples

89

update phone_book set area_code = 623 where prefix = 979 update phone_book set last_name = Smith prefix=555 suffix=9292 where last_name = Jones update employee set age = age+1 where first_name=Mary and last_name=Williams

90

附錄二Replication

測試環境

RedHat 90 + MySQL 32358 MySQL資料庫路徑 varlibmysql MySQL設定檔 etcmycnf Master IP 1921680100 Slave IP 1921680200 請至下列網址下載最新MySQL 32358套件並利用rpm ndashUvh 更新 httpupdatesredhatcom9enosi386

圖 最新 MySQL 套件

測試架構圖

91

1921680100

1921680200Master Server

erveSlave S r

圖 測試架構圖

測試步驟

Master server 部份 Step1 確認 MasterSlave機器上所裝的 MySQL版本能進行

replication( 32329 or higher ) Step2 在 Master MySQL上開放一個帳號給 Slave mysql ndashu root ndashp mysqlgtGRANT FILE ON TO repl1921680200 IDENTIFIED BY lsquoabc123rsquo mysqlgtq 上面是 Master開放一個帳號 repl密碼 abc123給 IP1921680200有檔案處理

的權限 Step3 shutdown MySQL on the Master mysqladmin ndashu root ndashp shutdown Step4 備份 Master所有資料庫 tar ndashcvf tmpmysql-snapshottar varlibmysql 注意tar的時候MySQL是要在 stop情況下 在mysql (wwwmysqlcom) 網站的FAQ有不用shutdown的方法

92

Step5 在 master機器上修改etcmycnf 在[mysqld]區段內加入參數 log-bin server-id=這邊設定 server-id=1 sql-bin-update-same binlog-do-db=CRM只針對 CRM資料庫做紀錄 Step6 Restart MySQL on the master service mysqld start 此時因為有加入 log-bin 參數因此開始有 index產生了在varlibmysql目錄下

有index檔案紀錄資料庫的異動 log Slave server 部份 Step1 在 slave設定etcmycnf 在[mysqld]區段加入 master-host= master-user= master-password= master-port= server-id= 這邊設定 master-host=1921680100 master-user=repl master-password=abc123 master-port=3306 server-id=2 master-connect-retry=60預設重試間隔 60秒 replicate-do-db=CRM告訴 slave只做 CRM資料庫的更新 log-slave-updates Step2 將 master上的 mysql-snapshottar copy到 slave上 用 ftp傳到 slave的tmp Step3 解壓縮 Master資料庫至 Slave Server上 cd varlib tar xvf tmpmysql-snapshottar chown ndashR mysqlmysql mysql

93

chmod ndashR 770 mysql (視情況) Step4 Restart MySQL on the slave server 這時在varlibmysql目錄會出現 masterinfo此檔案紀錄了 Master MySQL server的資訊

狀況測試

One-way replication

1921680100

1921680200Master Server

erveSlave S r

圖 One-way replication架構圖 Step1 Master跟 Slave網路及服務都正常情況下由 Master端異動資料後 到 Slave端瀏覽資料檢視是否有進行 replication Step2 模擬 Slave Server 當機 可用在於 slave真的當機或是 Slave 不一定需要一直跟 master connect將Slave MySQL server shutdown由 Master端異動資料到 slave端瀏覽此時Slave應該沒有被 replication 更新然後再將 Slave端 MySQL server start起來

預設 60秒後 Slave會嘗試跟 Master要求進行 replication再去 Slave端檢視是否有更新資料

94

Step3 模擬 Master當機因為是設定 One-way replication一旦 Master Server Slave端沒有 Master的 source可以 download Two-way replication 基於 Master當機狀況於是發展雙向 Replication即 1921680100 ( Host A ) 1921680200 ( Host B )都分別擔任 MasterSlave身分

1921680100

1921680200er

Server B MasterSlave Server

Server A MasterSlave Serv

圖 Two-way replication架構圖 以下是針對兩台 MySQL伺服器進行雙向 Replication Step1觀念同單向 replication只是改成 Master也有 Slave身分 Slave也有Master的身分先分別在 Server AServer B 都去 grant一個進行 replication的身分 [A]mysqlgtGRANT FILE ON TO repl1921680200 IDENTIFIED BY lsquoabc123rsquo [B]mysqlgt GRANT FILE ON TO repl1921680100 IDENTIFIED BY lsquoabc123rsquo Step2做完單向 replication後stop Server Aserver B MySQL service此時 AB資料是一樣的

95

修改etcmycnf設定 範例 Server A [mysqld] datadir=varlibmysql socket=varlibmysqlmysqlsock server-id=1 log-bin sql-bin-update-same binlog-do-db=CRM master-host=1921680200 master-user=repl master-password=abc123 log-slave-updates master-connect-retry=60 replicate-do-db=CRM Server B [mysqld] datadir=varlibmysql socket=varlibmysqlmysqlsock server-id=2 log-bin sql-bin-update-same binlog-do-db=CRM master-host=1921680100 master-user=repl master-password=abc123 log-slave-updates master-connect-retry=60 replicate-do-db=CRM 分別 start Server AServer B MySQL後此時雙方都是 MasterSlave身分一旦哪一方資料異動就會通知對方來 replication-若 replication失效則必須將Server AServer B的masterinfo及index00x 都砍掉然後分別 restart MySQL server進行測試檢視成果 實務上通常如果需要做Two-way replication通常會搭配Virtual Server使用

96

在前端架設一台Virtual Server不過此部份不在此份SOP討論範圍內有興趣

的讀者可參考 httpwwwlinuxvirtualserverorg 網站

1921680100 1921680200

Host A MasterSlave Server

Host B MasterSlave Server

Virtual Host

圖 Virtual Server + Two-way replication 架構圖

97

圖 High Availability Linux Virtual Server架構圖

98

  • COSA-SOP-03-006
  • 第一章 簡介
    • 11適用對象 (Audience)
    • 12 MySQL本身
    • 13 MySQL 40版跟50版重大的改進功能
    • 14 各家資料庫軟體比較
      • 第二章 前置需求
      • 第三章 安裝
        • 31 MySQL安裝
        • 32 phpMyAdmin安裝
        • 33 升級及注意事項
          • 第四章 MySQL管理
            • 41 Webmin 管理介面
            • 42 phpMyAdmin 的操作介面
            • 43管理指令介紹
              • 431 利用mysqladmin設定root的密碼
                  • 第五章 實用範例
                    • 51 任務一Web Base客戶通訊錄
                    • 52 任務二Web Base群組軟體 ( twig )
                      • 第六章 維護及更新程序
                        • 61 日常維護
                        • 62 更新程序
                        • 63 備份重要檔案
                        • 64 離線備份與還原
                        • 65 線上備份與還原
                          • 第七章 問題與解答
                          • 第八章 參考資料
                          • 附錄一 SQL Command 介紹
                          • 附錄二Replication
Page 28: DataBase Server Standard Operation Procedureebooks.lib.ntu.edu.tw/1_file/oss/63/93doc4-5.pdf · 業務的公司帶來了不少壓力,譬如微軟,甲骨文 ... 外的錢用在第三方的資料庫產品上,譬如就可以不用再購買甲骨文公司

圖 4-2 伺服器畫面

Step 3 點選 MySQL資料庫伺服器

圖 4-3 MySQL資料庫伺服器

28

Step 4 建立一個新的資料庫

圖 4-4 建立 MySQL資料庫

Step 5 建立名為 CONTACT的資料庫

29

圖 4-5 指定資料庫名稱

412 建立資料表

假設我們要建立一個名為 address的 Table其結構如下 欄位名稱 資料型態 長度 說明 id INT (自動編號) 連絡人編號 name varchar文字 20 連絡人姓名 tel Varchar文字 15 連絡人電話 Step 1 選擇 CONTACT資料庫

30

圖 4-6 選擇資料庫

Step 2 指定欄位數目

31

圖 4-7 設定欄位數目

Step 3設定表格欄位屬性

圖 3-8 設定表格欄位屬性

Step 4建立表格資料

32

圖 4-9 建立表格資料

圖 4-10 檢視資料

33

圖 4-11 新增資料

圖 4-12

34

圖 4-13

413 使用者管理

接下來我們要利用Webmin 來建立資料庫使用者並給予某些權限 Step1建立使用者

35

圖 4-14 選擇使用者權限

圖 4-15

36

Step2 賦予權限

圖 4-16

Step3 權限列表

37

圖 4-17

38

42 phpMyAdmin 的操作介面

421建立資料庫

Step 填入資料庫名稱並按「建立」

圖 4-18建立資料庫

422 建立資料表

Step1 填入資料表名稱並指定欄位數量 執行

39

圖 4-19填入資料表名稱並指定欄位數量

Step2 設定欄位屬性

圖 4-20設定欄位屬性

40

Step3 phpMyAdmin會產生相關的 SQL Command

圖 4-21 資料表結構及相關 SQL Command

Step4新增 Record

41

圖 4-22

圖 4-23

42

圖 4-24

圖 4-25

43

423使用者管理

Step1建立使用者

圖 4-26

44

圖 4-27

Step2 給予權限

圖 4-28

Step3權限列表

45

圖 4-29

43管理指令介紹

431 利用 mysqladmin設定 root的密碼

當您在Windows 或 Linux 中安裝好 MySQL後系統會自動幫您建立兩個

帳分別是 root 和 匿名者MySQL的 root 跟 Linux 最高權限使用者 root無關MySQL的 root使用者相當於 MS SQL 中的 sa 帳號擁有最高的 Database管理權限但系統預設 MySQL的 root 是不需要密碼所以通常我們一安裝

MySQL後首要任務便是修改 root的密碼 我們可以利用 mysqladmin工具或是直接修改 MySQL內部資料庫的使用者資

料 mysqladmin ndashu root ndashh cosaexamplecom password lsquo1234rsquo

46

-u 表示使用者帳號root 為 MySQL預設的管理帳號

-h 表示 MySQL主機的主機名稱也可使用 IP Address password 表示使用者的密碼因為字串請使用單引號將密碼括起來 密碼設定完成之後還是可以利用 mysqladmin修改密碼但是你必須提供目前的密碼

432 連線 MySQL

mysql -uroot -p密碼 (-p和密碼之間不能有空白) 或 mysql -uroot -p (此方式會在進入後要求密碼) [rootossc phpMyAdmin] mysql -u root -p1234

Welcome to the MySQL monitor Commands end with or g

Your MySQL connection id is 25 to server version 32354

Type help or h for help Type c to clear the buffer

mysqlgt show databases

+----------+

| Database |

+----------+

| mysql |

| test |

+----------+

2 rows in set (000 sec)

mysqlgt exit

Bye

[rootossc phpMyAdmin]

433 建立資料庫

可利用 mysqladmin指令建立 CONTACT資料庫 mysqladmin -u root -p1234 create CONTACT

47

或是利用 mysql指令 [rootossc bluepage] mysql -u root -p1234 Welcome to the MySQL monitor Commands end with or g Your MySQL connection id is 1057 to server version 32354 Type help or h for help Type c to clear the buffer mysqlgt create database CONTACT Query OK 1 row affected (000 sec) mysqlgt show databases +----------+ | Database | +----------+ | CONTACT | | address | | hello | | mysql | | nuke | | test | +----------+ 6 rows in set (000 sec) mysqlgt exit

434 建立資料表

編寫 adresssql內容如下 -- Table structure for table address CREATE TABLE address ( id int(11) NOT NULL auto_increment name varchar(20) NOT NULL default tel varchar(15) NOT NULL default PRIMARY KEY (id) ) TYPE=MyISAM

48

-- Dumping data for table address INSERT INTO address VALUES (1林小明0800016888) INSERT INTO address VALUES (2黃大雄0800016888) INSERT INTO address VALUES (3劉小芬0800024365) 然後執行此 sql script mysql -u root -p1234 CONTACT lt addresssql 或是利 mysql command [rootossc bluepage] mysql -u root -p1234 Welcome to the MySQL monitor Commands end with or g Your MySQL connection id is 1090 to server version 32354 Type help or h for help Type c to clear the buffer mysqlgt use CONTACT Database changed Database changed mysqlgt CREATE TABLE address ( -gt id int(11) NOT NULL auto_increment -gt name varchar(20) NOT NULL default -gt tel varchar(15) NOT NULL default -gt PRIMARY KEY (id) -gt ) TYPE=MyISAM Query OK 0 rows affected (000 sec) mysqlgt INSERT INTO address VALUES (1林小明0800016888) Query OK 1 row affected (000 sec) mysqlgt INSERT INTO address VALUES (2黃大雄0800016888) Query OK 1 row affected (000 sec) mysqlgt INSERT INTO address VALUES (3劉小芬0800024365) Query OK 1 row affected (000 sec) mysqlgt exit Bye

49

第五章 實用範例

51 任務一Web Base客戶通訊錄

任職於開放科技公司的林小明前些日子在最符合成本效益的條件下快

速地完成公司網站的建置老闆因此對小明讚譽有加最近因為公司存放客戶資

料的 SQL Server主機屢遭病毒攻擊加上作業系統本身的問題當機次數頻繁

老闆希望能儘快把公司的客戶通訊錄程式移轉到較穩定的環境上因為此客戶通

訊錄程式最主要給內部人員使用所以介面美觀並不特別要求只求穩定且能快

速得到查詢結果老闆希望在短時間先看到程式的雛型並鍵入資料對其效率

及穩定性進行測試因為上次小明表現突出所以這次不可能的任務自然又落到

小明身上 小明想來想去既然要快速又穩定他而且又不希望所有人都得安裝 Client

程式於是小明決定)捨棄他的舊愛「Delphi+MS SQL」投向新歡「Apache + MySQL + PHP」利用此架構來設計一個簡單實用的Web Base客戶通訊錄程式

511 Web Base客戶通訊錄架構

此程式需要建立 CONTACT的資料庫並建立 adress Tables其結構如下表建立步驟請參考第三章 欄位名稱 資料型態 長度 說明 id INT (自動編號) 連絡人編號 name varchar文字 20 連絡人姓名 tel Varchar文字 15 連絡人電話 Web Base通訊錄共有下列幾個檔案功能如下表

檔案名稱 說明 Indexhtml Web Base通訊錄首頁 addphp 新增連絡人的 php程式 searchphp 尋找連絡人的 php程式 editphp 具有更新及刪除功能的 php程式

50

我們將這些檔案放至varwwwhtmlbluepage (預設無 bluepage目錄)

512 Web Base通訊錄測試

httpwwwopencombluepage 新增資料

圖 5-1 新增連絡人

圖 5-2 填入資料

51

圖 5-3 新增成功

搜尋及異動資料

圖 5-4 搜尋通訊錄

52

圖 5-5 編輯資料

圖 5-6 更新資料

513 程式內容及說明

lt-- 程式範例indexhtml--gt lthtmlgt ltheadgtlttitlegt通訊錄lttitlegtltheadgt ltbodygt ltcentergt

53

lth2gt通訊錄lth2gtlthrgt lta href=indexhtmlgt通訊錄ltagt | lta href=addphpgt新增連絡人ltagt | lta href=searchphpgt搜尋通訊錄ltagt ltcentergt ltbodygt lthtmlgt lt-- 程式範例addphp --gt lthtmlgt ltheadgtlttitlegt新增連絡人lttitlegtltheadgt ltbodygt ltcentergtlth2gt新增連絡人lth2gtltcentergtlthrgt lt 取得欄位資料 if (isset($_POST[Name]) ampamp isset($_POST[Tel]) ) $name = $_POST[Name] $tel = $_POST[Tel] 檢查是否有輸入欄位資料 if ($name = ampamp $tel = ) 建立 SQL字串 $sql = INSERT INTO address (name tel) values( $sql= $name $tel) 建立 MySQL 連結 $link = mysql_connect(localhostroot1234) 選擇資料庫 mysql_select_db(CONTACT) 執行 SQL指令 mysql_query($sql) mysql_close($link) echo ltfont color=redgt新增連絡人成功ltfontgtltbrgt gt ltform action=addphp method=postgt lttable border=0 width=300gt lttrgtlttdgt姓名 lttdgt

54

lttdgtltinput type=text name=Name size=20 maxlength=10gtlttdgtlttrgt lttrgtlttdgt電話 lttdgt lttdgtltinput type=text name=Tel size=20 maxlength=20gtlttdgtlttrgt lttrgtlttd colspan=2 align=centergt ltinput type=submit value=新增連絡人gtlttdgtlttrgt lttablegt ltformgt ltbrgtlta href=indexhtmlgt通訊錄ltagt | lta href=addphpgt新增連絡人ltagt | lta href=searchphpgt搜尋通訊錄ltagt ltbodygt lthtmlgt

lt-- 程式範例searchphp --gt lthtmlgt ltheadgtlttitlegt搜尋通訊錄lttitlegtltheadgt ltbodygt ltcentergtlth2gt搜尋通訊錄lth2gtlthrgt lt if (isset($_POST[Search])) 建立資料庫連結並選定資料庫 $link = mysql_connect(localhostroot1234) mysql_select_db(CONTACT) 建立基本的 SQL字串 $sql = SELECT FROM address 檢查是否輸入姓名 if (chop($_POST[Name]) = ) $name = name LIKE $_POST[Name] else $name = 檢查是否輸入電話號碼 if (chop($_POST[Tel]) = ) $tel = tel LIKE $_POST[Tel] else $tel =

55

if條件組合 SQL字串 if (chop($name) = ampamp chop($tel) = ) $sql= WHERE $name AND $tel elseif (chop($name) = ) 只有姓名 $sql = WHERE $name elseif (chop($tel) = ) 只有電話號碼 $sql = WHERE $tel $sql= ORDER BY name 最後加上排序 $result = mysql_query($sql) 取得欄位數 $total_fields = mysql_num_fields($result) echo lttable border=1gt echo lttrgtlttdgt編號lttdgtlttdgt姓名lttdgtlttdgt電話lttdgtlttd colspan=2gt功能選項lttdgtlttrgt 表格顯示查詢結果 while ($rows = mysql_fetch_array($result MYSQL_NUM)) echo lttrgt for ($i = 0 $i lt $total_fields $i++) echo lttdgt$rows[$i]lttdgt echo lttdgtlta href=editphpaction=editampid= echo $rows[0]gtltbgt編輯ltbgtlttdgt echo lttdgtlta href=editphpaction=delampid= echo $rows[0]gtltbgt刪除ltbgtlttdgt echo lttrgt echo lttablegtlthrgt mysql_free_result($result) mysql_close($link) gt ltcentergt ltform action=searchphp method=postgt lttable border=0 width=450gt lttrgtlttdgt搜尋姓名 lttdgt lttdgtltinput type=text name=Name size=10 maxlength=20gtlttdgtlttrgt lttrgtlttdgt搜尋電話 lttdgt lttdgtltinput type=text name=Tel

56

size=20 maxlength=20gtlttdgtlttrgt lttrgtlttd colspan=2 align=centergt ltinput type=submit name=Search value=搜尋gtlttdgtlttrgt lttablegt ltformgt ltbrgtlta href=indexhtmlgt通訊錄ltagt | lta href=addphpgt新增連絡人ltagt | lta href=searchphpgt搜尋通訊錄ltagt ltbodygt lthtmlgt

lt ob_start() gt lt-- 程式範例editphp --gt lthtmlgt ltheadgtlttitlegt編輯通訊錄lttitlegtltheadgt ltbodygt lt 取得 URL 參數 $id = $_GET[id] $action = $_GET[action] 建立資料庫連結 $link = mysql_connect(localhostroot1234) mysql_select_db(CONTACT) 選擇資料庫 執行的操作 switch ($action) case update 更新 取得欄位資料 $name = $_POST[Name] $tel = $_POST[Tel] $sql = UPDATE address SET name=$name tel=$tel WHERE id=$id mysql_query($sql) 執行 SQL指令 mysql_close($link) header(Location searchphp) 轉向到 serachphp break case del 刪除 $sql = DELETE FROM address WHERE id=$id

57

mysql_query($sql) 執行 SQL指令 mysql_close($link) header(Location searchphp) 轉向到 serachphp break case edit 編輯 $sql = SELECT FROM address WHERE id=$id $result = mysql_query($sql) 執行 SQL指令 $row = mysql_fetch_row($result) 取回記錄 $name = $row[1] 取得欄位 name $tel = $row[2] 取得欄位 tel mysql_close($link) 顯示編輯表單 gt ltcentergtlth2gt更新通訊錄lth2gtltcentergtlthrgt ltform action=editphpaction=updateampid=lt echo $id gt method=postgt lttable border=0 width=300gt lttrgtlttdgt姓名 lttdgt lttdgtltinput type=text name=Name size=20 maxlength=10 value=lt echo $name gtgtlttdgtlttrgt lttrgtlttdgt電話 lttdgt lttdgtltinput type=text name=Tel size=20 maxlength=20 value=lt echo $tel gtgtlttdgtlttrgt lttrgtlttd colspan=2 align=centergt ltinput type=submit value=更新連絡人gtlttdgtlttrgt lttablegt ltformgt ltbrgtlta href=indexhtmlgt通訊錄ltagt | lta href=addphpgt新增連絡人ltagt | lta href=searchphpgt搜尋通訊錄ltagt lt break gt ltbodygt lthtmlgt

58

52 任務二Web Base群組軟體 ( twig )

順利完成Web Base客戶通訊錄程式測試一段時間後「Apache + MySQL + PHP」架構的穩定與快速巳深得老闆與公司所有同事的認同隨著公司業績蒸

蒸日上人員組織編罝愈來愈龐大跨部門的會議愈來愈多業務員每日排滿拜

訪客戶的行程跟客戶的 Email的往來也愈來愈頻繁 愈來愈多部門的同事希望公司能建置一套群組軟體提供 web mail可讓業

務人員方便收發 mail還有連絡人議事日程待辦工作書簽等功能讓整個

公司運作及個人時間管理更有效率

老闆問小明對這些需求有什麼看法小明認為如果這些功能完全由程式部

門開發必定曠日費時而且耗費公司資源小明在網路尋找是否有提供這些功能

的Free Software皇天不負苦心人小明發現了TWIG (The Web Information Gateway) httptwigscrewdrivernet這個群組軟體它在 Web 上整合郵件新聞聯絡人議事日程工作序書簽等功能非常符合公司的需求 Step 1 下載 twig-277targz 下載網址 httptwigscrewdrivernetdownloadphp3

Step 2 解開 twig-277targz tar -xzvf twig-277targz

59

Step 3 執行安裝動作安裝到 varwwwhtmltwig 目錄 cd twig-277 twig-install varwwwhtmltwig

Step 4 建立 MySQL 資料庫(twig)及各資料表

cd setup mysql -u root -p1234 mysqlgt create database twig Query OK 1 row affected (001 sec) mysqlgt quit mysql -u root ndashp1234 twiglt twigtablemysql

Step 5 修改 configincphp3 參數設定 vi varwwwhtmltwigconfigconfigincphp3 $config[fromdomain] = opencom 網域 $config[language] = chinesebig5 中文訊息 $config[imap_port] = 143notls

60

Step 6 修改連結 MySQL 的帳號密碼 vi varwwwhtmltwigconfigdbconfigincphp3 $dbconfig[sqlusername] = root username $dbconfig[sqlpassword] = 1234 password

Step 7 其他設定檔

vi etchttpdconfhttpdconf 加入 AddType applicationx-httpd-php php3 在 DirectoryIndex最後加入 indexphp3 DirectoryIndex indexhtml indexhtmlvar indexphp3 在 AddDefaultCharset ISO-8859-1加上 AddDefaultCharset ISO-8859-1

vi etcphpini register_globals = On service httpd restart Step 8 sendmail 設定 vi etcmailsendmailcf在 264 行前面加上並重新啟動 sendmail「service snedmail restart」 262 SMTP daemon options 263 264 O DaemonPortOptions=Port=smtpAddr=127001 Name=MTA 265 266 SMTP client options 267 O ClientPortOptions=Family=inet Address=00

61

Step 9 檢查設定有無錯誤 http主機名稱twigtestphp3

62

Step 10 登入 twig ( http主機名稱twig)

63

第六章 維護及更新程序

61 日常維護

系統管理員最好定期以 root 身份登入看看信件在 RedHat Linux 中有一支 logwatch 程式會定時去分析 log file如果發現異常便會發信給 root除此之外筆者建議讀者平時就檢查 MySQL log file ( varlogmysqldlog)是否有異常情形

62 更新程序

讀者可至httprpmfindnet 尋找MySQL相關套件至於升級的相關步驟請參

考Linux OS SOP 第 54節

63 備份重要檔案

預設 MySQL 的 DB 檔案是存在 varlibmysql 內以 DB名稱為目錄目錄

內就是該 DB 的所有資料通常得定期備份還有 MySQL的設定檔 etcmycnf也別忘了一起備份

64 離線備份與還原

641 離線備份

預設 MySQL 的 DB 檔案是存在 varlibmysql 內以 DB 名稱為目錄目錄內

就是該 DB 的所有資料像 CRM 這個 DB就是存在 varlibmysqlCRM 內在備份前因為怕資料尚未完全寫入磁碟而且 MySQL 會 Lock 在使用的 DB 檔案所以應該是要先把 MySQL 先 Shutdown 一下整個備份的程序可以下像下面的指令去完成 cd varlibmysql

64

service mysqld stop tar cvfz CRM_db_20030905tgz CRM service mysqld start 對這樣就可以了 不過要注意的是怕 DB 內每個 Tables 間的資料有關關

聯性所以最好是把整個 DB 一次備起來單獨只備哪個 Tables 的檔案以後回存時怕會有資料關聯不一致的問題

642 離線還原

DB 發生錯誤而要回存時其實也不難先找出最近一次完整正常的備份先把現在錯誤的網頁或 DB 先更名或 tar 起來再把好的備份給解開回原來目錄位

置就行了需要注意的是 MySQL 服務最好也是要先停止回存完成後再啟動服務回存 DB 的整個程序可能像下面 cd varlibmysql service mysqldstop mv CRM CRM_OLD tar xvfz CRM_db_20030905tg service mysqld start

65 線上備份與還原

651 線上備份

使用像上面的檔案方式備份是個不錯的方法它最少可以保持該主機某個時間點的完整檔案備份但還是有一些問題需要考慮到有些主機就不只建立一個 DB 而已總不能為了備份某個 DB 而把整個 MySQL 服務停止備份檔案的方式回存在原主機上一定適用但假如 MySQL 版本升級或是在那天該網頁空間需遷機移機到別的主機時那就沒人敢保證備出來的資料檔可以用所以我們可以考慮另一種備份的方式是使用 MySQL 本身提供的功能 MySQL Data Dump指令是 mysqldump

65

使用 MySQL 的 Dump 功能可以把 DB 的結構資料或結構加資料 Dump 成文字檔 mysqldump 指令提供的彈性很大你可以選擇把整個 DB Dump 成一個檔或是每個 Table 為一個檔甚至是把結構檔和資料分開儲存都

可以 mysqladmin -uroot -p flush-logs mysqldump CRM -uroot -p --opt gt CRM_20030905sql (CRM 是 DB 名稱 opt 是一個使用完整 Dump 參數) 假如只是要單獨 Dump 某個 Table 時只要在上面的指令後轉出符號 gt 前加個 Table 名稱就可以如只要 phpbb2_users 這個 Table 的 Dump 時只要下 mysqldump CRM -uroot -p --opt CUSTOMER gt CRM_CUSTOMER_20030905sql

652 線上還原

若要回存整個資料庫只需將壓縮的備份檔還原成 Dump 的檔案再用下面的指令回存 mysql CRM -uroot -p lt CRM_20030905sql 這邊需注意的是若建立備份時是以--opt或--add-drop-table為參數時回存的 動作是先將舊的 Table 先刪除重建 Table 的結構後再把 Data 匯入所以回存後所有的資料會回到你當時備份那個時間點因此在回存資料時可以考慮把現有錯誤或不完整的 DB 先備份一份下來以備不時之需或是拿來比對錯誤的地

方在那裡當然你也可以把資料回存到另一個測試用的 DB 內只要把上面指令

的 DB 名稱改成你的測試用 DB 名稱即可 使用這種回存方式 MySQL 服務不需停止也不會動到其他正在使用的 DB 在一些提供 MySQL 服務的虛擬主機可用這種方式作你自己的 DB 備份及回存

66

另外假如你是系統重建或是移機時切需在新的 MySQL 內新建一個空白 DB 後才行作回存的工作你可以用下面的指令建立 mysql -uroot -p -e CREATE DATABASE CRM (上面的 CRM是你要新建的 DB 名稱) 另一種作法先用 mysql 指令進入 mysql client console 然後再用 CREATE DATABASE CRM 這樣就行了記得尾端要加個 符號該行指令才會執行

67

第七章 問題與解答

Q1RedHat 90預附的 MySQL到底有無支援 Transcation機制 Ans MySQL自 32334a之後的 MySQL-Max版本加入 InnoDB的資料庫類型透過

InnoDBMySQL同樣可以進行 COMMIT與 ROLLRACK的動作RedHat 90預附的 MySQL為 32354a-11巳支援 InnoDB的資料庫類型不過必須做以

下設定 1cp usrsharedocmysql-server-32354amy-mediumcnf to etcmycnf 2 vi etcmycnf 將以下設定前的拿掉 innodb_data_home_dir = varlibmysql innodb_data_file_path = ibdata110Mautoextend innodb_log_group_home_dir = varlibmysql innodb_log_arch_dir = varlibmysql 3service mysqld restart 如此一來各位在建立Table時便可指定Table Type為 innodb ( ex create table with type=innodb ) Q2如何解決 php+mysql 許功蓋等字變亂的問題 Ans 方法一 【確定 MySQL 預設的字元集】 1 打開 WinMySQLadmin 管理畫面(在視窗右下角狀態列紅綠燈圖示中按滑鼠

右鍵點選 Show me 選項) 2 點選管理畫面中 [Variables] 標籤選項其中 character_set變數就是您預設

字元集的變數其預設是 latin1 字元集(我們要將他改回 big5)而 chatacters_set 變數則是 MySQL 可以支援哪些字元集 【修改預設字元集變數 character_set 】 1 請點選管理畫面中 [myini Setup] 標籤選項設定 myini 2 按一下 [Pick-up and Edit myini values] 按鈕以便編輯目前的 myini 設定 3 在 [mysqld] 設定區塊底下新增一行 default-character-set = big5 變數設

68

定 4 新增一個 [client] 設定區塊並加入第三步驟的變數設定(游標往下移到空白處新增兩行 [client] 和 default-character-set=big5) 5 按一下畫面左下方 [Save Modification] 按鈕儲存設定 6 重新啟動 MySQL 或 Windows 方法二 Server端注意事項 phpini 中有關的設定為(預設值) Magic quotes for incoming GETPOSTCookie data magic_quotes_gpc = On Use Sybase-style magic quotes (escape with instead of ) magic_quotes_sybase = Off Client端注意事項 1中文資料送進 mysql 前請用 addslashes($str) 處理 2處理後送進 mysql 時請用 括起來並在參數後留一個空白如 $sql = UPDATE ezf_table set tablename=$tname tableend=$endtime table inguser=$tguser tableingid=$tguserid tableallnumber=$tnumber tableloca l=$tablelocal tableanyone=$tableopen tabletext=$ttext WHERE tableid=$t ableid tablename=$tname c 取出時請用 stripslashes($str) Q3MySQL root 密碼忘了該怎麼辦 Ans 1先停掉 mysql etcrcdinitdmysql stop 2以--skip-grant-table 的參數啟動 mysql safe_mysql --skip-grant-tableamp 3 更改 root 密碼 mysql mysql mysqlgt UPDATE user SET password=password(newpassword)

69

WHERE user=root mysqlgt FLUSH PRIVILEGES mysqlgt exit 4停掉 mysql再重跑 mysqladmin -uroot -p shutdown Enter password 輸入新設定的密碼 etcrcdinitdmysql start

Q4NULL值問題

Ans

NULL值的概念是造成 SQL的新手的混淆的普遍原因他們經常認為 NULL是和一個空字符串的一樣的東西不是這樣的例如下列語句是完全不同的

mysqlgt INSERT INTO my_table (phone) VALUES (NULL)

mysqlgt INSERT INTO my_table (phone) VALUES ()

兩個語句把值插入到 phone 列但是第一個插入一個 NULL值而第二個插入一個空字符串第一個的含義可以認為是ldquo電話號碼不知道而第二個則可意味

著ldquo她沒有電話

在 SQL中NULL值在于任何其他值甚至 NULL值比較時總是假的(FALSE)包含 NULL的一個表達式總是產生一個 NULL值除非在包含在表達式中的運算符和函數的文檔中指出在下列例子所有的列返回 NULL

mysqlgt SELECT NULL1+NULLCONCAT(InvisibleNULL)

如果你想要尋找值是 NULL的列你不能使用=NULL測試下列語句不返回任

何行因為對任何表達式expr = NULL是假的

mysqlgt SELECT FROM my_table WHERE phone = NULL

要想尋找 NULL值你必須使用 IS NULL測試下例顯示如何找出 NULL電話號碼和空的電話號碼

70

mysqlgt SELECT FROM my_table WHERE phone IS NULL mysqlgt SELECT FROM my_table WHERE phone =

在 MySQL中就像很多其他的 SQL服務器一樣你不能索引可以有 NULL值的列你必須聲明這樣的列為 NOT NULL而且你不能插入 NULL到索引的

列中

當用 LOAD DATA INFILE 讀取數據時空列用更新如果你想要在一個列中有

NULL值你應該在文本文件中使用N字面上的詞NULL也可以在某些情形下使用

當使用 ORDER BY時首先呈現 NULL值如果你用 DESC以降序排序NULL值最後顯示當使用 GROUP BY時所有的 NULL值被認為是相等的

為了有助于NULL的處理你能使用 IS NULL和 IS NOT NULL運算符和 IFNULL()函數

對某些列類型NULL值被特殊地處理如果你將 NULL插入表的第一個TIMESTAMP 列則插入當前的日期和時間如果你將 NULL插入一個AUTO_INCREMENT 列則插入順序中的下一個數字

Q5如何將圖片存放於 MySQL中

Ans

Step 1建立資料庫 test

Step 2 建立表格 binary_data

CREATE TABLE binary_data (

id INT(4) NOT NULL AUTO_INCREMENT PRIMARY KEY

description CHAR(50)

bin_data LONGBLOB

filename CHAR(50)

filesize CHAR(50)

filetype CHAR(50)

71

)

Step 3 利用 storephp 寫入圖片

storephp 程式碼

ltHTMLgt ltHEADgtltTITLEgtStore binary data into SQL DatabaseltTITLEgtltHEADgt ltBODYgt lt code that will be executed if the form has been submitted

if ($submit) mysql_connect(localhostrootYOUR_PASSWORD) mysql_select_db(test) $data=Base64_Encode(fread(fopen($form_data r) filesize($form_data))) $result=MYSQL_QUERY(INSERT INTO binary_data (descriptionbin_datafilenamefilesizefiletype) VALUES ($form_description$data$form_data_name$form_data_size$form_data_type)) $id= mysql_insert_id() print ltpgtThis file has the following Database ID ltbgt$idltbgt MYSQL_CLOSE() else else show the form to submit new data

gt

ltform method=post action=ltphp echo $PHP_SELF gt enctype=multipartform-datagt File Descriptionltbrgt ltinput type=text name=form_description size=40gt ltINPUT TYPE=hidden name=MAX_FILE_SIZE value=4000000gt ltbrgtFile to uploadstore in databaseltbrgt ltinput type=file name=form_data size=40gt ltpgtltinput type=submit name=submit value=submitgt ltformgt lt

72

gt ltBODYgt ltHTMLgt

Step 3 利用 storephp 取出圖片

getdataphp 程式碼

lt Syntax getdataphp3id=ltidgt if($id) you may have to modify login information for your database server MYSQL_CONNECT(localhostrootYOUR_PASSWORD) mysql_select_db(test) $query = select bin_datafiletype from binary_data where id=$id $result = MYSQL_QUERY($query) $data = Base64_Decode(MYSQL_RESULT($result0bin_data)) $type = MYSQL_RESULT($result0filetype) Header( Content-type $type) echo $data gt

Q6MySQL裝好之後啟動時或是執行 mysqladmin會出現如下訊息 Cant connect to local MYSQL Server through Socket varlibmysqlmysqlsock或是

Cant connect to local MYSQL Server through Socket tmpmysqldsock

Ans 可能有下列幾個原因

1這個 mysqldsock 不見了被某人刪除了或是被一些系統自動執行程式給刪

了例如有些 cron任務便會設定定期刪除 tmp 裡的東西所以呢您只能修改

cron 裡的設定讓它不要清除 mysqldsock 2在啟動時也可以改變 mysqldsock的位置您在啟動 MySQL的時候可以加入此參數usrlocalmysqlbinsafe_mysqld --user=mysql --socket=其他路

徑socket amp 同時得去設定環境變數 MYSQL_UNIX_PORT的值以指定新的

73

路徑 3若是您沒改 MYSQL_UNIX_PORT的值那麼您可以在執行指令的時候才打

例如mysqladmin --socket=其他路徑socket version Q7How to get the last insert id Ans CREATE TABLE product ( id INT(4) NOT NULL AUTO_INCREMENT PRIMARY KEY description VARCHAR(50) ) 1利用 SQL的話 mysqlgt insert into product(description) values(123) Query OK 1 row affected (000 sec) mysqlgt select last_insert_id() +------------------+ | last_insert_id() | +------------------+ +------------------+ 1 row in set (000 sec) ======================================== 2如果是 PHP的話 你可以用mysql_insert_id()取得該 id PHP example $result=MYSQL_QUERY(INSERT INTO product (description) VALUES ($description)) $id= mysql_insert_id() print This file has the following Database ID $id Q8如何將文字檔匯入資料庫 Ans $addr=homehttpdhtmlphpschool001txt $sql_select = load data infile $addr into table test fields terminated by t 解說 $sql_select = load data infile 文字檔名 into table 表格名 fields terminated by

74

t

(欄位分隔以 TAB鍵) 該文字檔須與資料表欄位格式相符 例如欄位有三個 則文字檔為每行一筆資料如下 欄 1資料ltTABgt欄 2資料ltTABgt欄 3資料 欄 1資料ltTABgt欄 2資料ltTABgt欄 3資料 欄 1資料ltTABgt欄 2資料ltTABgt欄 3資料 欄 1資料ltTABgtltTABgt欄 3資料

Q9如何撰寫 MySQL C API Ans Step 1利用文字編輯器撰寫以下程式碼 mysqlcc

include ltstdiohgt

include ltmysqlmysqlhgt

int main (int argc char argv[])

MYSQL mysql

MYSQL_RES res

MYSQL_ROW row

if (argc = 2)

fputs (Usage myc ltdatabasegt stderr)

return 1

if ((mysql_connect(ampmysqllocalhostrootYour_Password)))

fputs (Error connecting stderr)

abort()

75

if (mysql_select_db(ampmysqlargv[1]))

fputs (Error selecting database stderr)

abort()

if (mysql_query(ampmysqlSELECT FROM test_table))

fputs (Error processing query stderr)

abort()

if ((res = mysql_store_result(ampmysql)))

fputs (Error storing results stderr)

abort()

while((row = mysql_fetch_row(res)))

uint i = 0

for (i=0 i lt mysql_num_fields(res) i++)

printf(s row[i])

printf(n)

return 0

Step 2 Compile

gcc -Iusrlocalmysqlinclude -Lusrlocalmysqllibmysql mysqlcc ndashlm -lmysqlclient

(其中 include path與 library path取決於你的 MySQL安裝路徑)

76

如果執行時發生如下 error Run problemerror in loading shared libraries libmysqlclientsoX 將你的 MySQL library path(for exampleusrlocalmysqllibmysql) 加入etcldsoconf and run sbinldconfig -v Q9ASP + MySQL 範例程式 Ans Dim myconn As New ADODBConnection Dim myrs As New Recordset Dim mySQL As String Dim myrows As Long myconnOpen DSN=MyODBCsample mySQL = SELECT from user myrsSource = mySQL Set myrsActiveConnection = myconn myrsCursorLocation = adUseClient myrsOpen myrows = myrsRecordCount myrsClose myconnClose 可參考 httpwwwdwamnetmysqlasp_myodbcasp 有詳細的資料 Q10如何將 MySQL中的資料庫匯出成txt檔 Ans select from TableName into outfile textxls all result fields will seperate by tab

77

第八章 參考資料

英文部份 網址 1 httpwwwmysqlcom MySQL 網站有第一手有關 MySQL的資料 2 httpwwwmysqlcomdocenReplicationhtml 有關 MySQL Replication 的文件 3 httpwwwgeocitiescomsqlhomefaqstore_blobhtml 如何在 MySQL 存放 BLOB的資料 4httpwwwsapdborg 有關 SAP跟 MySQL相關合作的網站 書藉 1 Cooking with MySQL

Paul DuBois has selected sample recipes from the hundreds youll find in his book MySQL

Cookbook In this third and final series of excerpts showcasing these recipes learn how to

compute team standings how to calculate the differences between successive Dec 26

2002 2 Tips for Building Web Database Applications with PHP and MySQL by Hugh E Williams co-author of Web Database Applications with PHP amp MySQL 04042002

3 Managing and Using MySQL 2nd Edition By Tim King George Reese Randy Jay Yarger

4 MySQL Cookbook By Paul DuBoisPublisher OReillyPub Date October 2002

中文部份

78

1 httplinuxtncedutwtechdocmysqlmysql_docmanual_tochtml MySQL 中文手冊 2 httpchenshloxaedutwphpZ_1php PHP+MySQ程式研習設計網站 3 httplinuxtncedutwtechdocbanicdownhtml PHP 4 手冊 4 httpwwwtncedutwadmin_zonephp台南縣教育網網路中心有很多 Linux相關文件 5 httpdobtncedutw網站建置百寶箱有很多 PHP MySQL 相關範例程式 5 httpwwwdbworldcomtw資料庫專家電子雜誌介紹資料庫的重要觀念及名詞

79

附錄一 SQL Command 介紹

SQL (讀音ess-que-el) 是一種結構查詢語法SQL 使用於資料庫交流

傳遞相容於 ANSI (American National Standards Institute) 是一套標準的關聯

式資料庫語言 SQL 語言是執行更新或從資料系統獲取資料一般常見的關聯

資料庫系統都有提供 SQL 如 Oracle Sybase Microsoft SQL Server Access Ingres 等雖然大部份的資料庫都有提供 SQL 但也多提供了自已獨特的語

法造成了不相容的情形但標準基本的語法是相通的如Select Insert Update Delete Create and Drop 每一個系統都有支援

Table相關 Command

Create Table

關聯式資料庫包含有很多元件稱為資料表(tables) 把資料或訊息放在資

料表中 資料表是以不同的名稱做分別資料表由欄列所構成的二維陣列

欄包含欄位名資料型態 及其他可判斷的資訊列是由全部欄位構成一筆一

筆的紀錄 create table 語法用在建立一個新的資料表語法格式如下

create table tablename (column1 data type column2 data type column3 data type)

Format of create table if you were to use optional constraints

create table tablename (column1 data type [constraint] column2 data type [constraint] column3 data type [constraint]) [ ] = optional

Note You may have as many columns as youd like and the constraints are optional

80

Example

create table employee (first varchar(15) last varchar(20) age number(3) address varchar(30) city varchar(20) state varchar(20))

注意建立資料表格式要以括號把前後框住而最後以(分號)做結尾

欄位名不要超過 30個字元長而且不要使用 sql 的關鍵字(如 where select等)而在後面接是型態的宣告(如字串數字日期格式等)

資料型態是來描述欄位的方式如一個欄位Last_Name 是一個姓氏可以使用varchar (可變動長度字串) 資料型態

以下是幾個常見的資料庫型態 char(size) 固定長度字串最長為 255 位元 varchar(size) 變動長度字串最大字元數以 size 來指定 number(size) 數值格式可以是整數也可以是小數最大數字以 size 位數判

斷未指定小數位數由系統內定 date 日期格式 number(sized) 數值格式最大數字以 size 位數判斷d 為小數位數整數位

數為 size-d 位

有何限制當資料表被建立通常有一或數個欄位是要使用來做關聯的功

能 例如unique 限制(唯一值)兩筆記錄不可以相同的值 not null (非空值)該欄位一定要輸入資料不可是空的primary key (主鍵)是每一筆記錄識別的主要方式

Drop a table drop table 刪除資料表(其中的資料也會一併刪除)

drop table tablename

Example

81

drop table 和刪除全部資料是不同的刪除全部資料欄位名稱資訊等還會

存在但刪除資料表會把這一些也一併移除掉

如何查詢資料

Select 基本用法

select 語法是關連式資料庫最常用的部份可以取得你想要的資料這是一個

簡單的範例 select column1[column2etc] from tablename [where condition] [] = optional 在 select 之後所列欄位名則是要顯示的資料部份你可以一一列出各欄位

名或是以 (星號)來代表選擇全部的欄位 from 之後放資料表名稱 where 子句 (選項) 指定要過濾的條件符合者才會顯現 where 可使用的條件運算元 = 等於 gt 大於 lt 小於 gt= 大或等於 lt= 小或等於 ltgt 大相等 LIKE 相似 For example select first last city

82

from empinfo where first LIKE Er 以Er 為開頭的字串就符合要以單引號框住 Or you can specify select first last from empinfo where last LIKE s 最後一字為 S 就符合 select from empinfo where first = Eric 則表示 first name 一定要是 Eric 才可以 範例資料表empinfo 統計函數

MIN 傳回指定欄位最小值

MAX 傳回指定欄位最大值

SUM 傳回指定欄位總和

AVG 傳回指定欄位平均值

COUNT 傳回指定欄位的筆數

COUNT() 傳回資料庫中的總筆數

統計函數使用於資料表中的數值欄位配合 SELECT 語法使用 只用於總結特定單一欄位可以配合 GROUP BY 做篩選但也可以不使用 GROUP BY 語句For example

SELECT AVG(salary) FROM employee

83

傳回全部 salary 平均值

Another example

SELECT AVG(salary) FROM employee WHERE title = Programmer

傳回 salary 平均值條件為 employees 資料表中當 title 等於 Programmer

Example

SELECT Count() FROM employees

傳回 employees 資料表中紀錄總筆數

GROUP BY 語法 SELECT column1 SUM(column2) FROM list-of-tables GROUP BY column-list The GROUP BY 語句可以先以所列的欄位為條件分組排序在一起(可以多欄

位) example 要列出每一個 dept 中最高 salary 值 SELECT max(salary) dept FROM employee GROUP BY dept HAVING 語法

SELECT column1 SUM(column2) FROM list-of-tables GROUP BY column-list HAVING condition

HAVING 子句是 GROUP BY 的一部份用來過濾在 GROUP BY 所選出的資料功能如同 select 命令中 where 條件式一樣只是 HAVING 必需配合 GROUP BY 使用

我們以例子來說明我們要取得每一公司名及每一公司的薪水平均值輸入如下

84

SELECT dept avg(salary) FROM employee GROUP BY dept

但如果我們只列出薪資平均值超過 20000元的公司資料

SELECT dept avg(salary) FROM employee GROUP BY dept HAVING avg(salary) gt 20000

ORDER BY子句語法

SELECT column1 SUM(column2) FROM list-of-tables ORDER BY column-list [ASC | DESC]

[ ] =選項

ORDER BY是一個選項子句當你以排序方式來顯示資料(正向由小到大反向由大到小)以指定的欄位資料做排序

ASC = 正向- 預設值 DESC = 反向排序

For example

SELECT employee_id dept name age salary FROM employee_info WHERE dept = Sales ORDER BY salary

以上列出公司代號公司名銷售員人名年紀及薪資而條件是公司名為 Sales 顯示順序以薪資多少排序(由小到大為預設值)

如果要以多個欄位做排序要以逗號做分隔如下

SELECT employee_id dept name age salary FROM employee_info WHERE dept = Sales ORDER BY salary age DESC

85

結合條件及布林運算 SELECT column1 SUM(column2) FROM list-of-tables WHERE condition1 AND condition2 AND運算可以結兩個或以上的條件放在 WHERE子句中 兩者都要為真才

會顯示該筆記錄 OR 運算可以結兩個或以上敘述放在 WHERE子句中只要其中一個為直就

會顯示該筆記錄 For example SELECT employeeid firstname lastname title salary FROM employee_info WHERE salary gt= 5000000 AND title = Programmer 必需要薪資大於等於 50000而且職稱為 Programmer同時符合才會顯示該筆資料 以下以括號括住雖然不是必需的但如此比較容易讀 SELECT employeeid firstname lastname title salary FROM employee_info WHERE (salary gt= 5000000) AND (title = Programmer) 另外範例 SELECT firstname lastname title salary FROM employee_info WHERE (title = Sales) OR (title = Programmer) 條件為只要是 Sales 或 Programmer 職稱的就會被列出 IN and BETWEEN 子句

SELECT column1 SUM(column2) FROM list-of-tables WHERE column3 IN (list-of-values) SELECT column1 SUM(column2) FROM list-of-tables WHERE column3 BETWEEN value1 AND value2 IN 子句使用在列舉項目的使用上也就是分別測試是否符合所列的值 For example

86

SELECT employeeid lastname salary FROM employee_info WHERE lastname IN (Hernandez Jones Roberts Ruiz) 條件為姓氏(astname)要符合 Hernandez Jones Roberts or Ruiz 其中一個才會被傳回 IN運算元也可以使用 OR 的語法來取代如下結果相同 SELECT employeeid lastname salary FROM employee_info WHERE lastname = Hernandez OR lastname = Jones OR lastname = Roberts OR lastname = Ruiz 但使用 IN 句子比較短也比較易懂 你也可以使用 NOT IN 來去掉不要的記錄 BETWEEN 運算元使用在判斷是否存在兩個數值之間 For example SELECT employeeid age lastname salary FROM employee_info WHERE age BETWEEN 30 AND 40 傳回年紀 30歲到 40歲之間的資料(含 30及 40歲者) 相同的也可以使用以下語法來達到相同的結果 SELECT employeeid age lastname salary FROM employee_info WHERE age gt= 30 AND age lt= 40 你也可使用 NOT BETWEEN 來濾掉中間值的資料 數學運算 標準 ANSI SQL-92 提供以下運算

87

+ 加

- 減

餘數

餘數為除法後剩整數這不在標準的 ANSI SQL 中但大部份的資料庫都會支

援這運算元以下列出有用的函數雖不在 ANSI SQL-92 提供但一般資料庫

也會支援他們

ABS(x) 傳回 x 絕對值

SIGN(x) returns the sign of input x as -1 0 or 1 (negative zero or positive respectively)

MOD(xy) 餘數 - returns the integer remainder of x divided by y (同 xy)

FLOOR(x) 傳回小或等於 x 的最大整數值

CEILING(x) or CEIL(x)

傳回大或等於 x 的最小整數值

POWER(xy) x的 y 次方

ROUND(x) 把 x 四捨五入為整數

ROUND(xd) 四捨五入取到小數 d 位

SQRT(x) x 開平方

For example SELECT round(salary) firstname FROM employee_info 傳回薪資取到整數位

如何新增資料

insert 加入一筆新紀錄到資料表中 insert into tablename (first_columnlast_column) values (first_valuelast_value) [] = optional Example insert into employee

88

(first last age address city state) values (Luke Duke 45 2130 Boars Nest Hazard Co Georgia) Note 字串要以單引號住如string 數字框住也無妨 insert into 後面接資料表名稱再接以括號括住的欄位名在 values 後括號分別對映各欄位的值 以上的例子新增了一筆名(first) 為 Luke而住所(state) 為 Georgia 的資料

如何刪除資料

delete 可以刪除單筆或多筆紀錄 delete from tablename where columnname OPERATOR value [and|or column OPERATOR value] [ ] = optional Examples delete from employee Note 如果你沒有指定 where 子句那麼全部的紀錄都會被刪除 delete from employee where lastname = May delete from employee where firstname = Mike or firstname = Eric delete from 接著資料表名 再接著是條件式判斷沒有條件式則全部紀錄會

被刪除

如何更新資料

update 用來更新你所指定的記錄要和 WHERE 配合小心使用 語法 update tablename set columnname = newvalue[nextcolumn = newvalue2] where columnname OPERATOR value [and|or column OPERATOR value] [] = optional Examples

89

update phone_book set area_code = 623 where prefix = 979 update phone_book set last_name = Smith prefix=555 suffix=9292 where last_name = Jones update employee set age = age+1 where first_name=Mary and last_name=Williams

90

附錄二Replication

測試環境

RedHat 90 + MySQL 32358 MySQL資料庫路徑 varlibmysql MySQL設定檔 etcmycnf Master IP 1921680100 Slave IP 1921680200 請至下列網址下載最新MySQL 32358套件並利用rpm ndashUvh 更新 httpupdatesredhatcom9enosi386

圖 最新 MySQL 套件

測試架構圖

91

1921680100

1921680200Master Server

erveSlave S r

圖 測試架構圖

測試步驟

Master server 部份 Step1 確認 MasterSlave機器上所裝的 MySQL版本能進行

replication( 32329 or higher ) Step2 在 Master MySQL上開放一個帳號給 Slave mysql ndashu root ndashp mysqlgtGRANT FILE ON TO repl1921680200 IDENTIFIED BY lsquoabc123rsquo mysqlgtq 上面是 Master開放一個帳號 repl密碼 abc123給 IP1921680200有檔案處理

的權限 Step3 shutdown MySQL on the Master mysqladmin ndashu root ndashp shutdown Step4 備份 Master所有資料庫 tar ndashcvf tmpmysql-snapshottar varlibmysql 注意tar的時候MySQL是要在 stop情況下 在mysql (wwwmysqlcom) 網站的FAQ有不用shutdown的方法

92

Step5 在 master機器上修改etcmycnf 在[mysqld]區段內加入參數 log-bin server-id=這邊設定 server-id=1 sql-bin-update-same binlog-do-db=CRM只針對 CRM資料庫做紀錄 Step6 Restart MySQL on the master service mysqld start 此時因為有加入 log-bin 參數因此開始有 index產生了在varlibmysql目錄下

有index檔案紀錄資料庫的異動 log Slave server 部份 Step1 在 slave設定etcmycnf 在[mysqld]區段加入 master-host= master-user= master-password= master-port= server-id= 這邊設定 master-host=1921680100 master-user=repl master-password=abc123 master-port=3306 server-id=2 master-connect-retry=60預設重試間隔 60秒 replicate-do-db=CRM告訴 slave只做 CRM資料庫的更新 log-slave-updates Step2 將 master上的 mysql-snapshottar copy到 slave上 用 ftp傳到 slave的tmp Step3 解壓縮 Master資料庫至 Slave Server上 cd varlib tar xvf tmpmysql-snapshottar chown ndashR mysqlmysql mysql

93

chmod ndashR 770 mysql (視情況) Step4 Restart MySQL on the slave server 這時在varlibmysql目錄會出現 masterinfo此檔案紀錄了 Master MySQL server的資訊

狀況測試

One-way replication

1921680100

1921680200Master Server

erveSlave S r

圖 One-way replication架構圖 Step1 Master跟 Slave網路及服務都正常情況下由 Master端異動資料後 到 Slave端瀏覽資料檢視是否有進行 replication Step2 模擬 Slave Server 當機 可用在於 slave真的當機或是 Slave 不一定需要一直跟 master connect將Slave MySQL server shutdown由 Master端異動資料到 slave端瀏覽此時Slave應該沒有被 replication 更新然後再將 Slave端 MySQL server start起來

預設 60秒後 Slave會嘗試跟 Master要求進行 replication再去 Slave端檢視是否有更新資料

94

Step3 模擬 Master當機因為是設定 One-way replication一旦 Master Server Slave端沒有 Master的 source可以 download Two-way replication 基於 Master當機狀況於是發展雙向 Replication即 1921680100 ( Host A ) 1921680200 ( Host B )都分別擔任 MasterSlave身分

1921680100

1921680200er

Server B MasterSlave Server

Server A MasterSlave Serv

圖 Two-way replication架構圖 以下是針對兩台 MySQL伺服器進行雙向 Replication Step1觀念同單向 replication只是改成 Master也有 Slave身分 Slave也有Master的身分先分別在 Server AServer B 都去 grant一個進行 replication的身分 [A]mysqlgtGRANT FILE ON TO repl1921680200 IDENTIFIED BY lsquoabc123rsquo [B]mysqlgt GRANT FILE ON TO repl1921680100 IDENTIFIED BY lsquoabc123rsquo Step2做完單向 replication後stop Server Aserver B MySQL service此時 AB資料是一樣的

95

修改etcmycnf設定 範例 Server A [mysqld] datadir=varlibmysql socket=varlibmysqlmysqlsock server-id=1 log-bin sql-bin-update-same binlog-do-db=CRM master-host=1921680200 master-user=repl master-password=abc123 log-slave-updates master-connect-retry=60 replicate-do-db=CRM Server B [mysqld] datadir=varlibmysql socket=varlibmysqlmysqlsock server-id=2 log-bin sql-bin-update-same binlog-do-db=CRM master-host=1921680100 master-user=repl master-password=abc123 log-slave-updates master-connect-retry=60 replicate-do-db=CRM 分別 start Server AServer B MySQL後此時雙方都是 MasterSlave身分一旦哪一方資料異動就會通知對方來 replication-若 replication失效則必須將Server AServer B的masterinfo及index00x 都砍掉然後分別 restart MySQL server進行測試檢視成果 實務上通常如果需要做Two-way replication通常會搭配Virtual Server使用

96

在前端架設一台Virtual Server不過此部份不在此份SOP討論範圍內有興趣

的讀者可參考 httpwwwlinuxvirtualserverorg 網站

1921680100 1921680200

Host A MasterSlave Server

Host B MasterSlave Server

Virtual Host

圖 Virtual Server + Two-way replication 架構圖

97

圖 High Availability Linux Virtual Server架構圖

98

  • COSA-SOP-03-006
  • 第一章 簡介
    • 11適用對象 (Audience)
    • 12 MySQL本身
    • 13 MySQL 40版跟50版重大的改進功能
    • 14 各家資料庫軟體比較
      • 第二章 前置需求
      • 第三章 安裝
        • 31 MySQL安裝
        • 32 phpMyAdmin安裝
        • 33 升級及注意事項
          • 第四章 MySQL管理
            • 41 Webmin 管理介面
            • 42 phpMyAdmin 的操作介面
            • 43管理指令介紹
              • 431 利用mysqladmin設定root的密碼
                  • 第五章 實用範例
                    • 51 任務一Web Base客戶通訊錄
                    • 52 任務二Web Base群組軟體 ( twig )
                      • 第六章 維護及更新程序
                        • 61 日常維護
                        • 62 更新程序
                        • 63 備份重要檔案
                        • 64 離線備份與還原
                        • 65 線上備份與還原
                          • 第七章 問題與解答
                          • 第八章 參考資料
                          • 附錄一 SQL Command 介紹
                          • 附錄二Replication
Page 29: DataBase Server Standard Operation Procedureebooks.lib.ntu.edu.tw/1_file/oss/63/93doc4-5.pdf · 業務的公司帶來了不少壓力,譬如微軟,甲骨文 ... 外的錢用在第三方的資料庫產品上,譬如就可以不用再購買甲骨文公司

Step 4 建立一個新的資料庫

圖 4-4 建立 MySQL資料庫

Step 5 建立名為 CONTACT的資料庫

29

圖 4-5 指定資料庫名稱

412 建立資料表

假設我們要建立一個名為 address的 Table其結構如下 欄位名稱 資料型態 長度 說明 id INT (自動編號) 連絡人編號 name varchar文字 20 連絡人姓名 tel Varchar文字 15 連絡人電話 Step 1 選擇 CONTACT資料庫

30

圖 4-6 選擇資料庫

Step 2 指定欄位數目

31

圖 4-7 設定欄位數目

Step 3設定表格欄位屬性

圖 3-8 設定表格欄位屬性

Step 4建立表格資料

32

圖 4-9 建立表格資料

圖 4-10 檢視資料

33

圖 4-11 新增資料

圖 4-12

34

圖 4-13

413 使用者管理

接下來我們要利用Webmin 來建立資料庫使用者並給予某些權限 Step1建立使用者

35

圖 4-14 選擇使用者權限

圖 4-15

36

Step2 賦予權限

圖 4-16

Step3 權限列表

37

圖 4-17

38

42 phpMyAdmin 的操作介面

421建立資料庫

Step 填入資料庫名稱並按「建立」

圖 4-18建立資料庫

422 建立資料表

Step1 填入資料表名稱並指定欄位數量 執行

39

圖 4-19填入資料表名稱並指定欄位數量

Step2 設定欄位屬性

圖 4-20設定欄位屬性

40

Step3 phpMyAdmin會產生相關的 SQL Command

圖 4-21 資料表結構及相關 SQL Command

Step4新增 Record

41

圖 4-22

圖 4-23

42

圖 4-24

圖 4-25

43

423使用者管理

Step1建立使用者

圖 4-26

44

圖 4-27

Step2 給予權限

圖 4-28

Step3權限列表

45

圖 4-29

43管理指令介紹

431 利用 mysqladmin設定 root的密碼

當您在Windows 或 Linux 中安裝好 MySQL後系統會自動幫您建立兩個

帳分別是 root 和 匿名者MySQL的 root 跟 Linux 最高權限使用者 root無關MySQL的 root使用者相當於 MS SQL 中的 sa 帳號擁有最高的 Database管理權限但系統預設 MySQL的 root 是不需要密碼所以通常我們一安裝

MySQL後首要任務便是修改 root的密碼 我們可以利用 mysqladmin工具或是直接修改 MySQL內部資料庫的使用者資

料 mysqladmin ndashu root ndashh cosaexamplecom password lsquo1234rsquo

46

-u 表示使用者帳號root 為 MySQL預設的管理帳號

-h 表示 MySQL主機的主機名稱也可使用 IP Address password 表示使用者的密碼因為字串請使用單引號將密碼括起來 密碼設定完成之後還是可以利用 mysqladmin修改密碼但是你必須提供目前的密碼

432 連線 MySQL

mysql -uroot -p密碼 (-p和密碼之間不能有空白) 或 mysql -uroot -p (此方式會在進入後要求密碼) [rootossc phpMyAdmin] mysql -u root -p1234

Welcome to the MySQL monitor Commands end with or g

Your MySQL connection id is 25 to server version 32354

Type help or h for help Type c to clear the buffer

mysqlgt show databases

+----------+

| Database |

+----------+

| mysql |

| test |

+----------+

2 rows in set (000 sec)

mysqlgt exit

Bye

[rootossc phpMyAdmin]

433 建立資料庫

可利用 mysqladmin指令建立 CONTACT資料庫 mysqladmin -u root -p1234 create CONTACT

47

或是利用 mysql指令 [rootossc bluepage] mysql -u root -p1234 Welcome to the MySQL monitor Commands end with or g Your MySQL connection id is 1057 to server version 32354 Type help or h for help Type c to clear the buffer mysqlgt create database CONTACT Query OK 1 row affected (000 sec) mysqlgt show databases +----------+ | Database | +----------+ | CONTACT | | address | | hello | | mysql | | nuke | | test | +----------+ 6 rows in set (000 sec) mysqlgt exit

434 建立資料表

編寫 adresssql內容如下 -- Table structure for table address CREATE TABLE address ( id int(11) NOT NULL auto_increment name varchar(20) NOT NULL default tel varchar(15) NOT NULL default PRIMARY KEY (id) ) TYPE=MyISAM

48

-- Dumping data for table address INSERT INTO address VALUES (1林小明0800016888) INSERT INTO address VALUES (2黃大雄0800016888) INSERT INTO address VALUES (3劉小芬0800024365) 然後執行此 sql script mysql -u root -p1234 CONTACT lt addresssql 或是利 mysql command [rootossc bluepage] mysql -u root -p1234 Welcome to the MySQL monitor Commands end with or g Your MySQL connection id is 1090 to server version 32354 Type help or h for help Type c to clear the buffer mysqlgt use CONTACT Database changed Database changed mysqlgt CREATE TABLE address ( -gt id int(11) NOT NULL auto_increment -gt name varchar(20) NOT NULL default -gt tel varchar(15) NOT NULL default -gt PRIMARY KEY (id) -gt ) TYPE=MyISAM Query OK 0 rows affected (000 sec) mysqlgt INSERT INTO address VALUES (1林小明0800016888) Query OK 1 row affected (000 sec) mysqlgt INSERT INTO address VALUES (2黃大雄0800016888) Query OK 1 row affected (000 sec) mysqlgt INSERT INTO address VALUES (3劉小芬0800024365) Query OK 1 row affected (000 sec) mysqlgt exit Bye

49

第五章 實用範例

51 任務一Web Base客戶通訊錄

任職於開放科技公司的林小明前些日子在最符合成本效益的條件下快

速地完成公司網站的建置老闆因此對小明讚譽有加最近因為公司存放客戶資

料的 SQL Server主機屢遭病毒攻擊加上作業系統本身的問題當機次數頻繁

老闆希望能儘快把公司的客戶通訊錄程式移轉到較穩定的環境上因為此客戶通

訊錄程式最主要給內部人員使用所以介面美觀並不特別要求只求穩定且能快

速得到查詢結果老闆希望在短時間先看到程式的雛型並鍵入資料對其效率

及穩定性進行測試因為上次小明表現突出所以這次不可能的任務自然又落到

小明身上 小明想來想去既然要快速又穩定他而且又不希望所有人都得安裝 Client

程式於是小明決定)捨棄他的舊愛「Delphi+MS SQL」投向新歡「Apache + MySQL + PHP」利用此架構來設計一個簡單實用的Web Base客戶通訊錄程式

511 Web Base客戶通訊錄架構

此程式需要建立 CONTACT的資料庫並建立 adress Tables其結構如下表建立步驟請參考第三章 欄位名稱 資料型態 長度 說明 id INT (自動編號) 連絡人編號 name varchar文字 20 連絡人姓名 tel Varchar文字 15 連絡人電話 Web Base通訊錄共有下列幾個檔案功能如下表

檔案名稱 說明 Indexhtml Web Base通訊錄首頁 addphp 新增連絡人的 php程式 searchphp 尋找連絡人的 php程式 editphp 具有更新及刪除功能的 php程式

50

我們將這些檔案放至varwwwhtmlbluepage (預設無 bluepage目錄)

512 Web Base通訊錄測試

httpwwwopencombluepage 新增資料

圖 5-1 新增連絡人

圖 5-2 填入資料

51

圖 5-3 新增成功

搜尋及異動資料

圖 5-4 搜尋通訊錄

52

圖 5-5 編輯資料

圖 5-6 更新資料

513 程式內容及說明

lt-- 程式範例indexhtml--gt lthtmlgt ltheadgtlttitlegt通訊錄lttitlegtltheadgt ltbodygt ltcentergt

53

lth2gt通訊錄lth2gtlthrgt lta href=indexhtmlgt通訊錄ltagt | lta href=addphpgt新增連絡人ltagt | lta href=searchphpgt搜尋通訊錄ltagt ltcentergt ltbodygt lthtmlgt lt-- 程式範例addphp --gt lthtmlgt ltheadgtlttitlegt新增連絡人lttitlegtltheadgt ltbodygt ltcentergtlth2gt新增連絡人lth2gtltcentergtlthrgt lt 取得欄位資料 if (isset($_POST[Name]) ampamp isset($_POST[Tel]) ) $name = $_POST[Name] $tel = $_POST[Tel] 檢查是否有輸入欄位資料 if ($name = ampamp $tel = ) 建立 SQL字串 $sql = INSERT INTO address (name tel) values( $sql= $name $tel) 建立 MySQL 連結 $link = mysql_connect(localhostroot1234) 選擇資料庫 mysql_select_db(CONTACT) 執行 SQL指令 mysql_query($sql) mysql_close($link) echo ltfont color=redgt新增連絡人成功ltfontgtltbrgt gt ltform action=addphp method=postgt lttable border=0 width=300gt lttrgtlttdgt姓名 lttdgt

54

lttdgtltinput type=text name=Name size=20 maxlength=10gtlttdgtlttrgt lttrgtlttdgt電話 lttdgt lttdgtltinput type=text name=Tel size=20 maxlength=20gtlttdgtlttrgt lttrgtlttd colspan=2 align=centergt ltinput type=submit value=新增連絡人gtlttdgtlttrgt lttablegt ltformgt ltbrgtlta href=indexhtmlgt通訊錄ltagt | lta href=addphpgt新增連絡人ltagt | lta href=searchphpgt搜尋通訊錄ltagt ltbodygt lthtmlgt

lt-- 程式範例searchphp --gt lthtmlgt ltheadgtlttitlegt搜尋通訊錄lttitlegtltheadgt ltbodygt ltcentergtlth2gt搜尋通訊錄lth2gtlthrgt lt if (isset($_POST[Search])) 建立資料庫連結並選定資料庫 $link = mysql_connect(localhostroot1234) mysql_select_db(CONTACT) 建立基本的 SQL字串 $sql = SELECT FROM address 檢查是否輸入姓名 if (chop($_POST[Name]) = ) $name = name LIKE $_POST[Name] else $name = 檢查是否輸入電話號碼 if (chop($_POST[Tel]) = ) $tel = tel LIKE $_POST[Tel] else $tel =

55

if條件組合 SQL字串 if (chop($name) = ampamp chop($tel) = ) $sql= WHERE $name AND $tel elseif (chop($name) = ) 只有姓名 $sql = WHERE $name elseif (chop($tel) = ) 只有電話號碼 $sql = WHERE $tel $sql= ORDER BY name 最後加上排序 $result = mysql_query($sql) 取得欄位數 $total_fields = mysql_num_fields($result) echo lttable border=1gt echo lttrgtlttdgt編號lttdgtlttdgt姓名lttdgtlttdgt電話lttdgtlttd colspan=2gt功能選項lttdgtlttrgt 表格顯示查詢結果 while ($rows = mysql_fetch_array($result MYSQL_NUM)) echo lttrgt for ($i = 0 $i lt $total_fields $i++) echo lttdgt$rows[$i]lttdgt echo lttdgtlta href=editphpaction=editampid= echo $rows[0]gtltbgt編輯ltbgtlttdgt echo lttdgtlta href=editphpaction=delampid= echo $rows[0]gtltbgt刪除ltbgtlttdgt echo lttrgt echo lttablegtlthrgt mysql_free_result($result) mysql_close($link) gt ltcentergt ltform action=searchphp method=postgt lttable border=0 width=450gt lttrgtlttdgt搜尋姓名 lttdgt lttdgtltinput type=text name=Name size=10 maxlength=20gtlttdgtlttrgt lttrgtlttdgt搜尋電話 lttdgt lttdgtltinput type=text name=Tel

56

size=20 maxlength=20gtlttdgtlttrgt lttrgtlttd colspan=2 align=centergt ltinput type=submit name=Search value=搜尋gtlttdgtlttrgt lttablegt ltformgt ltbrgtlta href=indexhtmlgt通訊錄ltagt | lta href=addphpgt新增連絡人ltagt | lta href=searchphpgt搜尋通訊錄ltagt ltbodygt lthtmlgt

lt ob_start() gt lt-- 程式範例editphp --gt lthtmlgt ltheadgtlttitlegt編輯通訊錄lttitlegtltheadgt ltbodygt lt 取得 URL 參數 $id = $_GET[id] $action = $_GET[action] 建立資料庫連結 $link = mysql_connect(localhostroot1234) mysql_select_db(CONTACT) 選擇資料庫 執行的操作 switch ($action) case update 更新 取得欄位資料 $name = $_POST[Name] $tel = $_POST[Tel] $sql = UPDATE address SET name=$name tel=$tel WHERE id=$id mysql_query($sql) 執行 SQL指令 mysql_close($link) header(Location searchphp) 轉向到 serachphp break case del 刪除 $sql = DELETE FROM address WHERE id=$id

57

mysql_query($sql) 執行 SQL指令 mysql_close($link) header(Location searchphp) 轉向到 serachphp break case edit 編輯 $sql = SELECT FROM address WHERE id=$id $result = mysql_query($sql) 執行 SQL指令 $row = mysql_fetch_row($result) 取回記錄 $name = $row[1] 取得欄位 name $tel = $row[2] 取得欄位 tel mysql_close($link) 顯示編輯表單 gt ltcentergtlth2gt更新通訊錄lth2gtltcentergtlthrgt ltform action=editphpaction=updateampid=lt echo $id gt method=postgt lttable border=0 width=300gt lttrgtlttdgt姓名 lttdgt lttdgtltinput type=text name=Name size=20 maxlength=10 value=lt echo $name gtgtlttdgtlttrgt lttrgtlttdgt電話 lttdgt lttdgtltinput type=text name=Tel size=20 maxlength=20 value=lt echo $tel gtgtlttdgtlttrgt lttrgtlttd colspan=2 align=centergt ltinput type=submit value=更新連絡人gtlttdgtlttrgt lttablegt ltformgt ltbrgtlta href=indexhtmlgt通訊錄ltagt | lta href=addphpgt新增連絡人ltagt | lta href=searchphpgt搜尋通訊錄ltagt lt break gt ltbodygt lthtmlgt

58

52 任務二Web Base群組軟體 ( twig )

順利完成Web Base客戶通訊錄程式測試一段時間後「Apache + MySQL + PHP」架構的穩定與快速巳深得老闆與公司所有同事的認同隨著公司業績蒸

蒸日上人員組織編罝愈來愈龐大跨部門的會議愈來愈多業務員每日排滿拜

訪客戶的行程跟客戶的 Email的往來也愈來愈頻繁 愈來愈多部門的同事希望公司能建置一套群組軟體提供 web mail可讓業

務人員方便收發 mail還有連絡人議事日程待辦工作書簽等功能讓整個

公司運作及個人時間管理更有效率

老闆問小明對這些需求有什麼看法小明認為如果這些功能完全由程式部

門開發必定曠日費時而且耗費公司資源小明在網路尋找是否有提供這些功能

的Free Software皇天不負苦心人小明發現了TWIG (The Web Information Gateway) httptwigscrewdrivernet這個群組軟體它在 Web 上整合郵件新聞聯絡人議事日程工作序書簽等功能非常符合公司的需求 Step 1 下載 twig-277targz 下載網址 httptwigscrewdrivernetdownloadphp3

Step 2 解開 twig-277targz tar -xzvf twig-277targz

59

Step 3 執行安裝動作安裝到 varwwwhtmltwig 目錄 cd twig-277 twig-install varwwwhtmltwig

Step 4 建立 MySQL 資料庫(twig)及各資料表

cd setup mysql -u root -p1234 mysqlgt create database twig Query OK 1 row affected (001 sec) mysqlgt quit mysql -u root ndashp1234 twiglt twigtablemysql

Step 5 修改 configincphp3 參數設定 vi varwwwhtmltwigconfigconfigincphp3 $config[fromdomain] = opencom 網域 $config[language] = chinesebig5 中文訊息 $config[imap_port] = 143notls

60

Step 6 修改連結 MySQL 的帳號密碼 vi varwwwhtmltwigconfigdbconfigincphp3 $dbconfig[sqlusername] = root username $dbconfig[sqlpassword] = 1234 password

Step 7 其他設定檔

vi etchttpdconfhttpdconf 加入 AddType applicationx-httpd-php php3 在 DirectoryIndex最後加入 indexphp3 DirectoryIndex indexhtml indexhtmlvar indexphp3 在 AddDefaultCharset ISO-8859-1加上 AddDefaultCharset ISO-8859-1

vi etcphpini register_globals = On service httpd restart Step 8 sendmail 設定 vi etcmailsendmailcf在 264 行前面加上並重新啟動 sendmail「service snedmail restart」 262 SMTP daemon options 263 264 O DaemonPortOptions=Port=smtpAddr=127001 Name=MTA 265 266 SMTP client options 267 O ClientPortOptions=Family=inet Address=00

61

Step 9 檢查設定有無錯誤 http主機名稱twigtestphp3

62

Step 10 登入 twig ( http主機名稱twig)

63

第六章 維護及更新程序

61 日常維護

系統管理員最好定期以 root 身份登入看看信件在 RedHat Linux 中有一支 logwatch 程式會定時去分析 log file如果發現異常便會發信給 root除此之外筆者建議讀者平時就檢查 MySQL log file ( varlogmysqldlog)是否有異常情形

62 更新程序

讀者可至httprpmfindnet 尋找MySQL相關套件至於升級的相關步驟請參

考Linux OS SOP 第 54節

63 備份重要檔案

預設 MySQL 的 DB 檔案是存在 varlibmysql 內以 DB名稱為目錄目錄

內就是該 DB 的所有資料通常得定期備份還有 MySQL的設定檔 etcmycnf也別忘了一起備份

64 離線備份與還原

641 離線備份

預設 MySQL 的 DB 檔案是存在 varlibmysql 內以 DB 名稱為目錄目錄內

就是該 DB 的所有資料像 CRM 這個 DB就是存在 varlibmysqlCRM 內在備份前因為怕資料尚未完全寫入磁碟而且 MySQL 會 Lock 在使用的 DB 檔案所以應該是要先把 MySQL 先 Shutdown 一下整個備份的程序可以下像下面的指令去完成 cd varlibmysql

64

service mysqld stop tar cvfz CRM_db_20030905tgz CRM service mysqld start 對這樣就可以了 不過要注意的是怕 DB 內每個 Tables 間的資料有關關

聯性所以最好是把整個 DB 一次備起來單獨只備哪個 Tables 的檔案以後回存時怕會有資料關聯不一致的問題

642 離線還原

DB 發生錯誤而要回存時其實也不難先找出最近一次完整正常的備份先把現在錯誤的網頁或 DB 先更名或 tar 起來再把好的備份給解開回原來目錄位

置就行了需要注意的是 MySQL 服務最好也是要先停止回存完成後再啟動服務回存 DB 的整個程序可能像下面 cd varlibmysql service mysqldstop mv CRM CRM_OLD tar xvfz CRM_db_20030905tg service mysqld start

65 線上備份與還原

651 線上備份

使用像上面的檔案方式備份是個不錯的方法它最少可以保持該主機某個時間點的完整檔案備份但還是有一些問題需要考慮到有些主機就不只建立一個 DB 而已總不能為了備份某個 DB 而把整個 MySQL 服務停止備份檔案的方式回存在原主機上一定適用但假如 MySQL 版本升級或是在那天該網頁空間需遷機移機到別的主機時那就沒人敢保證備出來的資料檔可以用所以我們可以考慮另一種備份的方式是使用 MySQL 本身提供的功能 MySQL Data Dump指令是 mysqldump

65

使用 MySQL 的 Dump 功能可以把 DB 的結構資料或結構加資料 Dump 成文字檔 mysqldump 指令提供的彈性很大你可以選擇把整個 DB Dump 成一個檔或是每個 Table 為一個檔甚至是把結構檔和資料分開儲存都

可以 mysqladmin -uroot -p flush-logs mysqldump CRM -uroot -p --opt gt CRM_20030905sql (CRM 是 DB 名稱 opt 是一個使用完整 Dump 參數) 假如只是要單獨 Dump 某個 Table 時只要在上面的指令後轉出符號 gt 前加個 Table 名稱就可以如只要 phpbb2_users 這個 Table 的 Dump 時只要下 mysqldump CRM -uroot -p --opt CUSTOMER gt CRM_CUSTOMER_20030905sql

652 線上還原

若要回存整個資料庫只需將壓縮的備份檔還原成 Dump 的檔案再用下面的指令回存 mysql CRM -uroot -p lt CRM_20030905sql 這邊需注意的是若建立備份時是以--opt或--add-drop-table為參數時回存的 動作是先將舊的 Table 先刪除重建 Table 的結構後再把 Data 匯入所以回存後所有的資料會回到你當時備份那個時間點因此在回存資料時可以考慮把現有錯誤或不完整的 DB 先備份一份下來以備不時之需或是拿來比對錯誤的地

方在那裡當然你也可以把資料回存到另一個測試用的 DB 內只要把上面指令

的 DB 名稱改成你的測試用 DB 名稱即可 使用這種回存方式 MySQL 服務不需停止也不會動到其他正在使用的 DB 在一些提供 MySQL 服務的虛擬主機可用這種方式作你自己的 DB 備份及回存

66

另外假如你是系統重建或是移機時切需在新的 MySQL 內新建一個空白 DB 後才行作回存的工作你可以用下面的指令建立 mysql -uroot -p -e CREATE DATABASE CRM (上面的 CRM是你要新建的 DB 名稱) 另一種作法先用 mysql 指令進入 mysql client console 然後再用 CREATE DATABASE CRM 這樣就行了記得尾端要加個 符號該行指令才會執行

67

第七章 問題與解答

Q1RedHat 90預附的 MySQL到底有無支援 Transcation機制 Ans MySQL自 32334a之後的 MySQL-Max版本加入 InnoDB的資料庫類型透過

InnoDBMySQL同樣可以進行 COMMIT與 ROLLRACK的動作RedHat 90預附的 MySQL為 32354a-11巳支援 InnoDB的資料庫類型不過必須做以

下設定 1cp usrsharedocmysql-server-32354amy-mediumcnf to etcmycnf 2 vi etcmycnf 將以下設定前的拿掉 innodb_data_home_dir = varlibmysql innodb_data_file_path = ibdata110Mautoextend innodb_log_group_home_dir = varlibmysql innodb_log_arch_dir = varlibmysql 3service mysqld restart 如此一來各位在建立Table時便可指定Table Type為 innodb ( ex create table with type=innodb ) Q2如何解決 php+mysql 許功蓋等字變亂的問題 Ans 方法一 【確定 MySQL 預設的字元集】 1 打開 WinMySQLadmin 管理畫面(在視窗右下角狀態列紅綠燈圖示中按滑鼠

右鍵點選 Show me 選項) 2 點選管理畫面中 [Variables] 標籤選項其中 character_set變數就是您預設

字元集的變數其預設是 latin1 字元集(我們要將他改回 big5)而 chatacters_set 變數則是 MySQL 可以支援哪些字元集 【修改預設字元集變數 character_set 】 1 請點選管理畫面中 [myini Setup] 標籤選項設定 myini 2 按一下 [Pick-up and Edit myini values] 按鈕以便編輯目前的 myini 設定 3 在 [mysqld] 設定區塊底下新增一行 default-character-set = big5 變數設

68

定 4 新增一個 [client] 設定區塊並加入第三步驟的變數設定(游標往下移到空白處新增兩行 [client] 和 default-character-set=big5) 5 按一下畫面左下方 [Save Modification] 按鈕儲存設定 6 重新啟動 MySQL 或 Windows 方法二 Server端注意事項 phpini 中有關的設定為(預設值) Magic quotes for incoming GETPOSTCookie data magic_quotes_gpc = On Use Sybase-style magic quotes (escape with instead of ) magic_quotes_sybase = Off Client端注意事項 1中文資料送進 mysql 前請用 addslashes($str) 處理 2處理後送進 mysql 時請用 括起來並在參數後留一個空白如 $sql = UPDATE ezf_table set tablename=$tname tableend=$endtime table inguser=$tguser tableingid=$tguserid tableallnumber=$tnumber tableloca l=$tablelocal tableanyone=$tableopen tabletext=$ttext WHERE tableid=$t ableid tablename=$tname c 取出時請用 stripslashes($str) Q3MySQL root 密碼忘了該怎麼辦 Ans 1先停掉 mysql etcrcdinitdmysql stop 2以--skip-grant-table 的參數啟動 mysql safe_mysql --skip-grant-tableamp 3 更改 root 密碼 mysql mysql mysqlgt UPDATE user SET password=password(newpassword)

69

WHERE user=root mysqlgt FLUSH PRIVILEGES mysqlgt exit 4停掉 mysql再重跑 mysqladmin -uroot -p shutdown Enter password 輸入新設定的密碼 etcrcdinitdmysql start

Q4NULL值問題

Ans

NULL值的概念是造成 SQL的新手的混淆的普遍原因他們經常認為 NULL是和一個空字符串的一樣的東西不是這樣的例如下列語句是完全不同的

mysqlgt INSERT INTO my_table (phone) VALUES (NULL)

mysqlgt INSERT INTO my_table (phone) VALUES ()

兩個語句把值插入到 phone 列但是第一個插入一個 NULL值而第二個插入一個空字符串第一個的含義可以認為是ldquo電話號碼不知道而第二個則可意味

著ldquo她沒有電話

在 SQL中NULL值在于任何其他值甚至 NULL值比較時總是假的(FALSE)包含 NULL的一個表達式總是產生一個 NULL值除非在包含在表達式中的運算符和函數的文檔中指出在下列例子所有的列返回 NULL

mysqlgt SELECT NULL1+NULLCONCAT(InvisibleNULL)

如果你想要尋找值是 NULL的列你不能使用=NULL測試下列語句不返回任

何行因為對任何表達式expr = NULL是假的

mysqlgt SELECT FROM my_table WHERE phone = NULL

要想尋找 NULL值你必須使用 IS NULL測試下例顯示如何找出 NULL電話號碼和空的電話號碼

70

mysqlgt SELECT FROM my_table WHERE phone IS NULL mysqlgt SELECT FROM my_table WHERE phone =

在 MySQL中就像很多其他的 SQL服務器一樣你不能索引可以有 NULL值的列你必須聲明這樣的列為 NOT NULL而且你不能插入 NULL到索引的

列中

當用 LOAD DATA INFILE 讀取數據時空列用更新如果你想要在一個列中有

NULL值你應該在文本文件中使用N字面上的詞NULL也可以在某些情形下使用

當使用 ORDER BY時首先呈現 NULL值如果你用 DESC以降序排序NULL值最後顯示當使用 GROUP BY時所有的 NULL值被認為是相等的

為了有助于NULL的處理你能使用 IS NULL和 IS NOT NULL運算符和 IFNULL()函數

對某些列類型NULL值被特殊地處理如果你將 NULL插入表的第一個TIMESTAMP 列則插入當前的日期和時間如果你將 NULL插入一個AUTO_INCREMENT 列則插入順序中的下一個數字

Q5如何將圖片存放於 MySQL中

Ans

Step 1建立資料庫 test

Step 2 建立表格 binary_data

CREATE TABLE binary_data (

id INT(4) NOT NULL AUTO_INCREMENT PRIMARY KEY

description CHAR(50)

bin_data LONGBLOB

filename CHAR(50)

filesize CHAR(50)

filetype CHAR(50)

71

)

Step 3 利用 storephp 寫入圖片

storephp 程式碼

ltHTMLgt ltHEADgtltTITLEgtStore binary data into SQL DatabaseltTITLEgtltHEADgt ltBODYgt lt code that will be executed if the form has been submitted

if ($submit) mysql_connect(localhostrootYOUR_PASSWORD) mysql_select_db(test) $data=Base64_Encode(fread(fopen($form_data r) filesize($form_data))) $result=MYSQL_QUERY(INSERT INTO binary_data (descriptionbin_datafilenamefilesizefiletype) VALUES ($form_description$data$form_data_name$form_data_size$form_data_type)) $id= mysql_insert_id() print ltpgtThis file has the following Database ID ltbgt$idltbgt MYSQL_CLOSE() else else show the form to submit new data

gt

ltform method=post action=ltphp echo $PHP_SELF gt enctype=multipartform-datagt File Descriptionltbrgt ltinput type=text name=form_description size=40gt ltINPUT TYPE=hidden name=MAX_FILE_SIZE value=4000000gt ltbrgtFile to uploadstore in databaseltbrgt ltinput type=file name=form_data size=40gt ltpgtltinput type=submit name=submit value=submitgt ltformgt lt

72

gt ltBODYgt ltHTMLgt

Step 3 利用 storephp 取出圖片

getdataphp 程式碼

lt Syntax getdataphp3id=ltidgt if($id) you may have to modify login information for your database server MYSQL_CONNECT(localhostrootYOUR_PASSWORD) mysql_select_db(test) $query = select bin_datafiletype from binary_data where id=$id $result = MYSQL_QUERY($query) $data = Base64_Decode(MYSQL_RESULT($result0bin_data)) $type = MYSQL_RESULT($result0filetype) Header( Content-type $type) echo $data gt

Q6MySQL裝好之後啟動時或是執行 mysqladmin會出現如下訊息 Cant connect to local MYSQL Server through Socket varlibmysqlmysqlsock或是

Cant connect to local MYSQL Server through Socket tmpmysqldsock

Ans 可能有下列幾個原因

1這個 mysqldsock 不見了被某人刪除了或是被一些系統自動執行程式給刪

了例如有些 cron任務便會設定定期刪除 tmp 裡的東西所以呢您只能修改

cron 裡的設定讓它不要清除 mysqldsock 2在啟動時也可以改變 mysqldsock的位置您在啟動 MySQL的時候可以加入此參數usrlocalmysqlbinsafe_mysqld --user=mysql --socket=其他路

徑socket amp 同時得去設定環境變數 MYSQL_UNIX_PORT的值以指定新的

73

路徑 3若是您沒改 MYSQL_UNIX_PORT的值那麼您可以在執行指令的時候才打

例如mysqladmin --socket=其他路徑socket version Q7How to get the last insert id Ans CREATE TABLE product ( id INT(4) NOT NULL AUTO_INCREMENT PRIMARY KEY description VARCHAR(50) ) 1利用 SQL的話 mysqlgt insert into product(description) values(123) Query OK 1 row affected (000 sec) mysqlgt select last_insert_id() +------------------+ | last_insert_id() | +------------------+ +------------------+ 1 row in set (000 sec) ======================================== 2如果是 PHP的話 你可以用mysql_insert_id()取得該 id PHP example $result=MYSQL_QUERY(INSERT INTO product (description) VALUES ($description)) $id= mysql_insert_id() print This file has the following Database ID $id Q8如何將文字檔匯入資料庫 Ans $addr=homehttpdhtmlphpschool001txt $sql_select = load data infile $addr into table test fields terminated by t 解說 $sql_select = load data infile 文字檔名 into table 表格名 fields terminated by

74

t

(欄位分隔以 TAB鍵) 該文字檔須與資料表欄位格式相符 例如欄位有三個 則文字檔為每行一筆資料如下 欄 1資料ltTABgt欄 2資料ltTABgt欄 3資料 欄 1資料ltTABgt欄 2資料ltTABgt欄 3資料 欄 1資料ltTABgt欄 2資料ltTABgt欄 3資料 欄 1資料ltTABgtltTABgt欄 3資料

Q9如何撰寫 MySQL C API Ans Step 1利用文字編輯器撰寫以下程式碼 mysqlcc

include ltstdiohgt

include ltmysqlmysqlhgt

int main (int argc char argv[])

MYSQL mysql

MYSQL_RES res

MYSQL_ROW row

if (argc = 2)

fputs (Usage myc ltdatabasegt stderr)

return 1

if ((mysql_connect(ampmysqllocalhostrootYour_Password)))

fputs (Error connecting stderr)

abort()

75

if (mysql_select_db(ampmysqlargv[1]))

fputs (Error selecting database stderr)

abort()

if (mysql_query(ampmysqlSELECT FROM test_table))

fputs (Error processing query stderr)

abort()

if ((res = mysql_store_result(ampmysql)))

fputs (Error storing results stderr)

abort()

while((row = mysql_fetch_row(res)))

uint i = 0

for (i=0 i lt mysql_num_fields(res) i++)

printf(s row[i])

printf(n)

return 0

Step 2 Compile

gcc -Iusrlocalmysqlinclude -Lusrlocalmysqllibmysql mysqlcc ndashlm -lmysqlclient

(其中 include path與 library path取決於你的 MySQL安裝路徑)

76

如果執行時發生如下 error Run problemerror in loading shared libraries libmysqlclientsoX 將你的 MySQL library path(for exampleusrlocalmysqllibmysql) 加入etcldsoconf and run sbinldconfig -v Q9ASP + MySQL 範例程式 Ans Dim myconn As New ADODBConnection Dim myrs As New Recordset Dim mySQL As String Dim myrows As Long myconnOpen DSN=MyODBCsample mySQL = SELECT from user myrsSource = mySQL Set myrsActiveConnection = myconn myrsCursorLocation = adUseClient myrsOpen myrows = myrsRecordCount myrsClose myconnClose 可參考 httpwwwdwamnetmysqlasp_myodbcasp 有詳細的資料 Q10如何將 MySQL中的資料庫匯出成txt檔 Ans select from TableName into outfile textxls all result fields will seperate by tab

77

第八章 參考資料

英文部份 網址 1 httpwwwmysqlcom MySQL 網站有第一手有關 MySQL的資料 2 httpwwwmysqlcomdocenReplicationhtml 有關 MySQL Replication 的文件 3 httpwwwgeocitiescomsqlhomefaqstore_blobhtml 如何在 MySQL 存放 BLOB的資料 4httpwwwsapdborg 有關 SAP跟 MySQL相關合作的網站 書藉 1 Cooking with MySQL

Paul DuBois has selected sample recipes from the hundreds youll find in his book MySQL

Cookbook In this third and final series of excerpts showcasing these recipes learn how to

compute team standings how to calculate the differences between successive Dec 26

2002 2 Tips for Building Web Database Applications with PHP and MySQL by Hugh E Williams co-author of Web Database Applications with PHP amp MySQL 04042002

3 Managing and Using MySQL 2nd Edition By Tim King George Reese Randy Jay Yarger

4 MySQL Cookbook By Paul DuBoisPublisher OReillyPub Date October 2002

中文部份

78

1 httplinuxtncedutwtechdocmysqlmysql_docmanual_tochtml MySQL 中文手冊 2 httpchenshloxaedutwphpZ_1php PHP+MySQ程式研習設計網站 3 httplinuxtncedutwtechdocbanicdownhtml PHP 4 手冊 4 httpwwwtncedutwadmin_zonephp台南縣教育網網路中心有很多 Linux相關文件 5 httpdobtncedutw網站建置百寶箱有很多 PHP MySQL 相關範例程式 5 httpwwwdbworldcomtw資料庫專家電子雜誌介紹資料庫的重要觀念及名詞

79

附錄一 SQL Command 介紹

SQL (讀音ess-que-el) 是一種結構查詢語法SQL 使用於資料庫交流

傳遞相容於 ANSI (American National Standards Institute) 是一套標準的關聯

式資料庫語言 SQL 語言是執行更新或從資料系統獲取資料一般常見的關聯

資料庫系統都有提供 SQL 如 Oracle Sybase Microsoft SQL Server Access Ingres 等雖然大部份的資料庫都有提供 SQL 但也多提供了自已獨特的語

法造成了不相容的情形但標準基本的語法是相通的如Select Insert Update Delete Create and Drop 每一個系統都有支援

Table相關 Command

Create Table

關聯式資料庫包含有很多元件稱為資料表(tables) 把資料或訊息放在資

料表中 資料表是以不同的名稱做分別資料表由欄列所構成的二維陣列

欄包含欄位名資料型態 及其他可判斷的資訊列是由全部欄位構成一筆一

筆的紀錄 create table 語法用在建立一個新的資料表語法格式如下

create table tablename (column1 data type column2 data type column3 data type)

Format of create table if you were to use optional constraints

create table tablename (column1 data type [constraint] column2 data type [constraint] column3 data type [constraint]) [ ] = optional

Note You may have as many columns as youd like and the constraints are optional

80

Example

create table employee (first varchar(15) last varchar(20) age number(3) address varchar(30) city varchar(20) state varchar(20))

注意建立資料表格式要以括號把前後框住而最後以(分號)做結尾

欄位名不要超過 30個字元長而且不要使用 sql 的關鍵字(如 where select等)而在後面接是型態的宣告(如字串數字日期格式等)

資料型態是來描述欄位的方式如一個欄位Last_Name 是一個姓氏可以使用varchar (可變動長度字串) 資料型態

以下是幾個常見的資料庫型態 char(size) 固定長度字串最長為 255 位元 varchar(size) 變動長度字串最大字元數以 size 來指定 number(size) 數值格式可以是整數也可以是小數最大數字以 size 位數判

斷未指定小數位數由系統內定 date 日期格式 number(sized) 數值格式最大數字以 size 位數判斷d 為小數位數整數位

數為 size-d 位

有何限制當資料表被建立通常有一或數個欄位是要使用來做關聯的功

能 例如unique 限制(唯一值)兩筆記錄不可以相同的值 not null (非空值)該欄位一定要輸入資料不可是空的primary key (主鍵)是每一筆記錄識別的主要方式

Drop a table drop table 刪除資料表(其中的資料也會一併刪除)

drop table tablename

Example

81

drop table 和刪除全部資料是不同的刪除全部資料欄位名稱資訊等還會

存在但刪除資料表會把這一些也一併移除掉

如何查詢資料

Select 基本用法

select 語法是關連式資料庫最常用的部份可以取得你想要的資料這是一個

簡單的範例 select column1[column2etc] from tablename [where condition] [] = optional 在 select 之後所列欄位名則是要顯示的資料部份你可以一一列出各欄位

名或是以 (星號)來代表選擇全部的欄位 from 之後放資料表名稱 where 子句 (選項) 指定要過濾的條件符合者才會顯現 where 可使用的條件運算元 = 等於 gt 大於 lt 小於 gt= 大或等於 lt= 小或等於 ltgt 大相等 LIKE 相似 For example select first last city

82

from empinfo where first LIKE Er 以Er 為開頭的字串就符合要以單引號框住 Or you can specify select first last from empinfo where last LIKE s 最後一字為 S 就符合 select from empinfo where first = Eric 則表示 first name 一定要是 Eric 才可以 範例資料表empinfo 統計函數

MIN 傳回指定欄位最小值

MAX 傳回指定欄位最大值

SUM 傳回指定欄位總和

AVG 傳回指定欄位平均值

COUNT 傳回指定欄位的筆數

COUNT() 傳回資料庫中的總筆數

統計函數使用於資料表中的數值欄位配合 SELECT 語法使用 只用於總結特定單一欄位可以配合 GROUP BY 做篩選但也可以不使用 GROUP BY 語句For example

SELECT AVG(salary) FROM employee

83

傳回全部 salary 平均值

Another example

SELECT AVG(salary) FROM employee WHERE title = Programmer

傳回 salary 平均值條件為 employees 資料表中當 title 等於 Programmer

Example

SELECT Count() FROM employees

傳回 employees 資料表中紀錄總筆數

GROUP BY 語法 SELECT column1 SUM(column2) FROM list-of-tables GROUP BY column-list The GROUP BY 語句可以先以所列的欄位為條件分組排序在一起(可以多欄

位) example 要列出每一個 dept 中最高 salary 值 SELECT max(salary) dept FROM employee GROUP BY dept HAVING 語法

SELECT column1 SUM(column2) FROM list-of-tables GROUP BY column-list HAVING condition

HAVING 子句是 GROUP BY 的一部份用來過濾在 GROUP BY 所選出的資料功能如同 select 命令中 where 條件式一樣只是 HAVING 必需配合 GROUP BY 使用

我們以例子來說明我們要取得每一公司名及每一公司的薪水平均值輸入如下

84

SELECT dept avg(salary) FROM employee GROUP BY dept

但如果我們只列出薪資平均值超過 20000元的公司資料

SELECT dept avg(salary) FROM employee GROUP BY dept HAVING avg(salary) gt 20000

ORDER BY子句語法

SELECT column1 SUM(column2) FROM list-of-tables ORDER BY column-list [ASC | DESC]

[ ] =選項

ORDER BY是一個選項子句當你以排序方式來顯示資料(正向由小到大反向由大到小)以指定的欄位資料做排序

ASC = 正向- 預設值 DESC = 反向排序

For example

SELECT employee_id dept name age salary FROM employee_info WHERE dept = Sales ORDER BY salary

以上列出公司代號公司名銷售員人名年紀及薪資而條件是公司名為 Sales 顯示順序以薪資多少排序(由小到大為預設值)

如果要以多個欄位做排序要以逗號做分隔如下

SELECT employee_id dept name age salary FROM employee_info WHERE dept = Sales ORDER BY salary age DESC

85

結合條件及布林運算 SELECT column1 SUM(column2) FROM list-of-tables WHERE condition1 AND condition2 AND運算可以結兩個或以上的條件放在 WHERE子句中 兩者都要為真才

會顯示該筆記錄 OR 運算可以結兩個或以上敘述放在 WHERE子句中只要其中一個為直就

會顯示該筆記錄 For example SELECT employeeid firstname lastname title salary FROM employee_info WHERE salary gt= 5000000 AND title = Programmer 必需要薪資大於等於 50000而且職稱為 Programmer同時符合才會顯示該筆資料 以下以括號括住雖然不是必需的但如此比較容易讀 SELECT employeeid firstname lastname title salary FROM employee_info WHERE (salary gt= 5000000) AND (title = Programmer) 另外範例 SELECT firstname lastname title salary FROM employee_info WHERE (title = Sales) OR (title = Programmer) 條件為只要是 Sales 或 Programmer 職稱的就會被列出 IN and BETWEEN 子句

SELECT column1 SUM(column2) FROM list-of-tables WHERE column3 IN (list-of-values) SELECT column1 SUM(column2) FROM list-of-tables WHERE column3 BETWEEN value1 AND value2 IN 子句使用在列舉項目的使用上也就是分別測試是否符合所列的值 For example

86

SELECT employeeid lastname salary FROM employee_info WHERE lastname IN (Hernandez Jones Roberts Ruiz) 條件為姓氏(astname)要符合 Hernandez Jones Roberts or Ruiz 其中一個才會被傳回 IN運算元也可以使用 OR 的語法來取代如下結果相同 SELECT employeeid lastname salary FROM employee_info WHERE lastname = Hernandez OR lastname = Jones OR lastname = Roberts OR lastname = Ruiz 但使用 IN 句子比較短也比較易懂 你也可以使用 NOT IN 來去掉不要的記錄 BETWEEN 運算元使用在判斷是否存在兩個數值之間 For example SELECT employeeid age lastname salary FROM employee_info WHERE age BETWEEN 30 AND 40 傳回年紀 30歲到 40歲之間的資料(含 30及 40歲者) 相同的也可以使用以下語法來達到相同的結果 SELECT employeeid age lastname salary FROM employee_info WHERE age gt= 30 AND age lt= 40 你也可使用 NOT BETWEEN 來濾掉中間值的資料 數學運算 標準 ANSI SQL-92 提供以下運算

87

+ 加

- 減

餘數

餘數為除法後剩整數這不在標準的 ANSI SQL 中但大部份的資料庫都會支

援這運算元以下列出有用的函數雖不在 ANSI SQL-92 提供但一般資料庫

也會支援他們

ABS(x) 傳回 x 絕對值

SIGN(x) returns the sign of input x as -1 0 or 1 (negative zero or positive respectively)

MOD(xy) 餘數 - returns the integer remainder of x divided by y (同 xy)

FLOOR(x) 傳回小或等於 x 的最大整數值

CEILING(x) or CEIL(x)

傳回大或等於 x 的最小整數值

POWER(xy) x的 y 次方

ROUND(x) 把 x 四捨五入為整數

ROUND(xd) 四捨五入取到小數 d 位

SQRT(x) x 開平方

For example SELECT round(salary) firstname FROM employee_info 傳回薪資取到整數位

如何新增資料

insert 加入一筆新紀錄到資料表中 insert into tablename (first_columnlast_column) values (first_valuelast_value) [] = optional Example insert into employee

88

(first last age address city state) values (Luke Duke 45 2130 Boars Nest Hazard Co Georgia) Note 字串要以單引號住如string 數字框住也無妨 insert into 後面接資料表名稱再接以括號括住的欄位名在 values 後括號分別對映各欄位的值 以上的例子新增了一筆名(first) 為 Luke而住所(state) 為 Georgia 的資料

如何刪除資料

delete 可以刪除單筆或多筆紀錄 delete from tablename where columnname OPERATOR value [and|or column OPERATOR value] [ ] = optional Examples delete from employee Note 如果你沒有指定 where 子句那麼全部的紀錄都會被刪除 delete from employee where lastname = May delete from employee where firstname = Mike or firstname = Eric delete from 接著資料表名 再接著是條件式判斷沒有條件式則全部紀錄會

被刪除

如何更新資料

update 用來更新你所指定的記錄要和 WHERE 配合小心使用 語法 update tablename set columnname = newvalue[nextcolumn = newvalue2] where columnname OPERATOR value [and|or column OPERATOR value] [] = optional Examples

89

update phone_book set area_code = 623 where prefix = 979 update phone_book set last_name = Smith prefix=555 suffix=9292 where last_name = Jones update employee set age = age+1 where first_name=Mary and last_name=Williams

90

附錄二Replication

測試環境

RedHat 90 + MySQL 32358 MySQL資料庫路徑 varlibmysql MySQL設定檔 etcmycnf Master IP 1921680100 Slave IP 1921680200 請至下列網址下載最新MySQL 32358套件並利用rpm ndashUvh 更新 httpupdatesredhatcom9enosi386

圖 最新 MySQL 套件

測試架構圖

91

1921680100

1921680200Master Server

erveSlave S r

圖 測試架構圖

測試步驟

Master server 部份 Step1 確認 MasterSlave機器上所裝的 MySQL版本能進行

replication( 32329 or higher ) Step2 在 Master MySQL上開放一個帳號給 Slave mysql ndashu root ndashp mysqlgtGRANT FILE ON TO repl1921680200 IDENTIFIED BY lsquoabc123rsquo mysqlgtq 上面是 Master開放一個帳號 repl密碼 abc123給 IP1921680200有檔案處理

的權限 Step3 shutdown MySQL on the Master mysqladmin ndashu root ndashp shutdown Step4 備份 Master所有資料庫 tar ndashcvf tmpmysql-snapshottar varlibmysql 注意tar的時候MySQL是要在 stop情況下 在mysql (wwwmysqlcom) 網站的FAQ有不用shutdown的方法

92

Step5 在 master機器上修改etcmycnf 在[mysqld]區段內加入參數 log-bin server-id=這邊設定 server-id=1 sql-bin-update-same binlog-do-db=CRM只針對 CRM資料庫做紀錄 Step6 Restart MySQL on the master service mysqld start 此時因為有加入 log-bin 參數因此開始有 index產生了在varlibmysql目錄下

有index檔案紀錄資料庫的異動 log Slave server 部份 Step1 在 slave設定etcmycnf 在[mysqld]區段加入 master-host= master-user= master-password= master-port= server-id= 這邊設定 master-host=1921680100 master-user=repl master-password=abc123 master-port=3306 server-id=2 master-connect-retry=60預設重試間隔 60秒 replicate-do-db=CRM告訴 slave只做 CRM資料庫的更新 log-slave-updates Step2 將 master上的 mysql-snapshottar copy到 slave上 用 ftp傳到 slave的tmp Step3 解壓縮 Master資料庫至 Slave Server上 cd varlib tar xvf tmpmysql-snapshottar chown ndashR mysqlmysql mysql

93

chmod ndashR 770 mysql (視情況) Step4 Restart MySQL on the slave server 這時在varlibmysql目錄會出現 masterinfo此檔案紀錄了 Master MySQL server的資訊

狀況測試

One-way replication

1921680100

1921680200Master Server

erveSlave S r

圖 One-way replication架構圖 Step1 Master跟 Slave網路及服務都正常情況下由 Master端異動資料後 到 Slave端瀏覽資料檢視是否有進行 replication Step2 模擬 Slave Server 當機 可用在於 slave真的當機或是 Slave 不一定需要一直跟 master connect將Slave MySQL server shutdown由 Master端異動資料到 slave端瀏覽此時Slave應該沒有被 replication 更新然後再將 Slave端 MySQL server start起來

預設 60秒後 Slave會嘗試跟 Master要求進行 replication再去 Slave端檢視是否有更新資料

94

Step3 模擬 Master當機因為是設定 One-way replication一旦 Master Server Slave端沒有 Master的 source可以 download Two-way replication 基於 Master當機狀況於是發展雙向 Replication即 1921680100 ( Host A ) 1921680200 ( Host B )都分別擔任 MasterSlave身分

1921680100

1921680200er

Server B MasterSlave Server

Server A MasterSlave Serv

圖 Two-way replication架構圖 以下是針對兩台 MySQL伺服器進行雙向 Replication Step1觀念同單向 replication只是改成 Master也有 Slave身分 Slave也有Master的身分先分別在 Server AServer B 都去 grant一個進行 replication的身分 [A]mysqlgtGRANT FILE ON TO repl1921680200 IDENTIFIED BY lsquoabc123rsquo [B]mysqlgt GRANT FILE ON TO repl1921680100 IDENTIFIED BY lsquoabc123rsquo Step2做完單向 replication後stop Server Aserver B MySQL service此時 AB資料是一樣的

95

修改etcmycnf設定 範例 Server A [mysqld] datadir=varlibmysql socket=varlibmysqlmysqlsock server-id=1 log-bin sql-bin-update-same binlog-do-db=CRM master-host=1921680200 master-user=repl master-password=abc123 log-slave-updates master-connect-retry=60 replicate-do-db=CRM Server B [mysqld] datadir=varlibmysql socket=varlibmysqlmysqlsock server-id=2 log-bin sql-bin-update-same binlog-do-db=CRM master-host=1921680100 master-user=repl master-password=abc123 log-slave-updates master-connect-retry=60 replicate-do-db=CRM 分別 start Server AServer B MySQL後此時雙方都是 MasterSlave身分一旦哪一方資料異動就會通知對方來 replication-若 replication失效則必須將Server AServer B的masterinfo及index00x 都砍掉然後分別 restart MySQL server進行測試檢視成果 實務上通常如果需要做Two-way replication通常會搭配Virtual Server使用

96

在前端架設一台Virtual Server不過此部份不在此份SOP討論範圍內有興趣

的讀者可參考 httpwwwlinuxvirtualserverorg 網站

1921680100 1921680200

Host A MasterSlave Server

Host B MasterSlave Server

Virtual Host

圖 Virtual Server + Two-way replication 架構圖

97

圖 High Availability Linux Virtual Server架構圖

98

  • COSA-SOP-03-006
  • 第一章 簡介
    • 11適用對象 (Audience)
    • 12 MySQL本身
    • 13 MySQL 40版跟50版重大的改進功能
    • 14 各家資料庫軟體比較
      • 第二章 前置需求
      • 第三章 安裝
        • 31 MySQL安裝
        • 32 phpMyAdmin安裝
        • 33 升級及注意事項
          • 第四章 MySQL管理
            • 41 Webmin 管理介面
            • 42 phpMyAdmin 的操作介面
            • 43管理指令介紹
              • 431 利用mysqladmin設定root的密碼
                  • 第五章 實用範例
                    • 51 任務一Web Base客戶通訊錄
                    • 52 任務二Web Base群組軟體 ( twig )
                      • 第六章 維護及更新程序
                        • 61 日常維護
                        • 62 更新程序
                        • 63 備份重要檔案
                        • 64 離線備份與還原
                        • 65 線上備份與還原
                          • 第七章 問題與解答
                          • 第八章 參考資料
                          • 附錄一 SQL Command 介紹
                          • 附錄二Replication
Page 30: DataBase Server Standard Operation Procedureebooks.lib.ntu.edu.tw/1_file/oss/63/93doc4-5.pdf · 業務的公司帶來了不少壓力,譬如微軟,甲骨文 ... 外的錢用在第三方的資料庫產品上,譬如就可以不用再購買甲骨文公司

圖 4-5 指定資料庫名稱

412 建立資料表

假設我們要建立一個名為 address的 Table其結構如下 欄位名稱 資料型態 長度 說明 id INT (自動編號) 連絡人編號 name varchar文字 20 連絡人姓名 tel Varchar文字 15 連絡人電話 Step 1 選擇 CONTACT資料庫

30

圖 4-6 選擇資料庫

Step 2 指定欄位數目

31

圖 4-7 設定欄位數目

Step 3設定表格欄位屬性

圖 3-8 設定表格欄位屬性

Step 4建立表格資料

32

圖 4-9 建立表格資料

圖 4-10 檢視資料

33

圖 4-11 新增資料

圖 4-12

34

圖 4-13

413 使用者管理

接下來我們要利用Webmin 來建立資料庫使用者並給予某些權限 Step1建立使用者

35

圖 4-14 選擇使用者權限

圖 4-15

36

Step2 賦予權限

圖 4-16

Step3 權限列表

37

圖 4-17

38

42 phpMyAdmin 的操作介面

421建立資料庫

Step 填入資料庫名稱並按「建立」

圖 4-18建立資料庫

422 建立資料表

Step1 填入資料表名稱並指定欄位數量 執行

39

圖 4-19填入資料表名稱並指定欄位數量

Step2 設定欄位屬性

圖 4-20設定欄位屬性

40

Step3 phpMyAdmin會產生相關的 SQL Command

圖 4-21 資料表結構及相關 SQL Command

Step4新增 Record

41

圖 4-22

圖 4-23

42

圖 4-24

圖 4-25

43

423使用者管理

Step1建立使用者

圖 4-26

44

圖 4-27

Step2 給予權限

圖 4-28

Step3權限列表

45

圖 4-29

43管理指令介紹

431 利用 mysqladmin設定 root的密碼

當您在Windows 或 Linux 中安裝好 MySQL後系統會自動幫您建立兩個

帳分別是 root 和 匿名者MySQL的 root 跟 Linux 最高權限使用者 root無關MySQL的 root使用者相當於 MS SQL 中的 sa 帳號擁有最高的 Database管理權限但系統預設 MySQL的 root 是不需要密碼所以通常我們一安裝

MySQL後首要任務便是修改 root的密碼 我們可以利用 mysqladmin工具或是直接修改 MySQL內部資料庫的使用者資

料 mysqladmin ndashu root ndashh cosaexamplecom password lsquo1234rsquo

46

-u 表示使用者帳號root 為 MySQL預設的管理帳號

-h 表示 MySQL主機的主機名稱也可使用 IP Address password 表示使用者的密碼因為字串請使用單引號將密碼括起來 密碼設定完成之後還是可以利用 mysqladmin修改密碼但是你必須提供目前的密碼

432 連線 MySQL

mysql -uroot -p密碼 (-p和密碼之間不能有空白) 或 mysql -uroot -p (此方式會在進入後要求密碼) [rootossc phpMyAdmin] mysql -u root -p1234

Welcome to the MySQL monitor Commands end with or g

Your MySQL connection id is 25 to server version 32354

Type help or h for help Type c to clear the buffer

mysqlgt show databases

+----------+

| Database |

+----------+

| mysql |

| test |

+----------+

2 rows in set (000 sec)

mysqlgt exit

Bye

[rootossc phpMyAdmin]

433 建立資料庫

可利用 mysqladmin指令建立 CONTACT資料庫 mysqladmin -u root -p1234 create CONTACT

47

或是利用 mysql指令 [rootossc bluepage] mysql -u root -p1234 Welcome to the MySQL monitor Commands end with or g Your MySQL connection id is 1057 to server version 32354 Type help or h for help Type c to clear the buffer mysqlgt create database CONTACT Query OK 1 row affected (000 sec) mysqlgt show databases +----------+ | Database | +----------+ | CONTACT | | address | | hello | | mysql | | nuke | | test | +----------+ 6 rows in set (000 sec) mysqlgt exit

434 建立資料表

編寫 adresssql內容如下 -- Table structure for table address CREATE TABLE address ( id int(11) NOT NULL auto_increment name varchar(20) NOT NULL default tel varchar(15) NOT NULL default PRIMARY KEY (id) ) TYPE=MyISAM

48

-- Dumping data for table address INSERT INTO address VALUES (1林小明0800016888) INSERT INTO address VALUES (2黃大雄0800016888) INSERT INTO address VALUES (3劉小芬0800024365) 然後執行此 sql script mysql -u root -p1234 CONTACT lt addresssql 或是利 mysql command [rootossc bluepage] mysql -u root -p1234 Welcome to the MySQL monitor Commands end with or g Your MySQL connection id is 1090 to server version 32354 Type help or h for help Type c to clear the buffer mysqlgt use CONTACT Database changed Database changed mysqlgt CREATE TABLE address ( -gt id int(11) NOT NULL auto_increment -gt name varchar(20) NOT NULL default -gt tel varchar(15) NOT NULL default -gt PRIMARY KEY (id) -gt ) TYPE=MyISAM Query OK 0 rows affected (000 sec) mysqlgt INSERT INTO address VALUES (1林小明0800016888) Query OK 1 row affected (000 sec) mysqlgt INSERT INTO address VALUES (2黃大雄0800016888) Query OK 1 row affected (000 sec) mysqlgt INSERT INTO address VALUES (3劉小芬0800024365) Query OK 1 row affected (000 sec) mysqlgt exit Bye

49

第五章 實用範例

51 任務一Web Base客戶通訊錄

任職於開放科技公司的林小明前些日子在最符合成本效益的條件下快

速地完成公司網站的建置老闆因此對小明讚譽有加最近因為公司存放客戶資

料的 SQL Server主機屢遭病毒攻擊加上作業系統本身的問題當機次數頻繁

老闆希望能儘快把公司的客戶通訊錄程式移轉到較穩定的環境上因為此客戶通

訊錄程式最主要給內部人員使用所以介面美觀並不特別要求只求穩定且能快

速得到查詢結果老闆希望在短時間先看到程式的雛型並鍵入資料對其效率

及穩定性進行測試因為上次小明表現突出所以這次不可能的任務自然又落到

小明身上 小明想來想去既然要快速又穩定他而且又不希望所有人都得安裝 Client

程式於是小明決定)捨棄他的舊愛「Delphi+MS SQL」投向新歡「Apache + MySQL + PHP」利用此架構來設計一個簡單實用的Web Base客戶通訊錄程式

511 Web Base客戶通訊錄架構

此程式需要建立 CONTACT的資料庫並建立 adress Tables其結構如下表建立步驟請參考第三章 欄位名稱 資料型態 長度 說明 id INT (自動編號) 連絡人編號 name varchar文字 20 連絡人姓名 tel Varchar文字 15 連絡人電話 Web Base通訊錄共有下列幾個檔案功能如下表

檔案名稱 說明 Indexhtml Web Base通訊錄首頁 addphp 新增連絡人的 php程式 searchphp 尋找連絡人的 php程式 editphp 具有更新及刪除功能的 php程式

50

我們將這些檔案放至varwwwhtmlbluepage (預設無 bluepage目錄)

512 Web Base通訊錄測試

httpwwwopencombluepage 新增資料

圖 5-1 新增連絡人

圖 5-2 填入資料

51

圖 5-3 新增成功

搜尋及異動資料

圖 5-4 搜尋通訊錄

52

圖 5-5 編輯資料

圖 5-6 更新資料

513 程式內容及說明

lt-- 程式範例indexhtml--gt lthtmlgt ltheadgtlttitlegt通訊錄lttitlegtltheadgt ltbodygt ltcentergt

53

lth2gt通訊錄lth2gtlthrgt lta href=indexhtmlgt通訊錄ltagt | lta href=addphpgt新增連絡人ltagt | lta href=searchphpgt搜尋通訊錄ltagt ltcentergt ltbodygt lthtmlgt lt-- 程式範例addphp --gt lthtmlgt ltheadgtlttitlegt新增連絡人lttitlegtltheadgt ltbodygt ltcentergtlth2gt新增連絡人lth2gtltcentergtlthrgt lt 取得欄位資料 if (isset($_POST[Name]) ampamp isset($_POST[Tel]) ) $name = $_POST[Name] $tel = $_POST[Tel] 檢查是否有輸入欄位資料 if ($name = ampamp $tel = ) 建立 SQL字串 $sql = INSERT INTO address (name tel) values( $sql= $name $tel) 建立 MySQL 連結 $link = mysql_connect(localhostroot1234) 選擇資料庫 mysql_select_db(CONTACT) 執行 SQL指令 mysql_query($sql) mysql_close($link) echo ltfont color=redgt新增連絡人成功ltfontgtltbrgt gt ltform action=addphp method=postgt lttable border=0 width=300gt lttrgtlttdgt姓名 lttdgt

54

lttdgtltinput type=text name=Name size=20 maxlength=10gtlttdgtlttrgt lttrgtlttdgt電話 lttdgt lttdgtltinput type=text name=Tel size=20 maxlength=20gtlttdgtlttrgt lttrgtlttd colspan=2 align=centergt ltinput type=submit value=新增連絡人gtlttdgtlttrgt lttablegt ltformgt ltbrgtlta href=indexhtmlgt通訊錄ltagt | lta href=addphpgt新增連絡人ltagt | lta href=searchphpgt搜尋通訊錄ltagt ltbodygt lthtmlgt

lt-- 程式範例searchphp --gt lthtmlgt ltheadgtlttitlegt搜尋通訊錄lttitlegtltheadgt ltbodygt ltcentergtlth2gt搜尋通訊錄lth2gtlthrgt lt if (isset($_POST[Search])) 建立資料庫連結並選定資料庫 $link = mysql_connect(localhostroot1234) mysql_select_db(CONTACT) 建立基本的 SQL字串 $sql = SELECT FROM address 檢查是否輸入姓名 if (chop($_POST[Name]) = ) $name = name LIKE $_POST[Name] else $name = 檢查是否輸入電話號碼 if (chop($_POST[Tel]) = ) $tel = tel LIKE $_POST[Tel] else $tel =

55

if條件組合 SQL字串 if (chop($name) = ampamp chop($tel) = ) $sql= WHERE $name AND $tel elseif (chop($name) = ) 只有姓名 $sql = WHERE $name elseif (chop($tel) = ) 只有電話號碼 $sql = WHERE $tel $sql= ORDER BY name 最後加上排序 $result = mysql_query($sql) 取得欄位數 $total_fields = mysql_num_fields($result) echo lttable border=1gt echo lttrgtlttdgt編號lttdgtlttdgt姓名lttdgtlttdgt電話lttdgtlttd colspan=2gt功能選項lttdgtlttrgt 表格顯示查詢結果 while ($rows = mysql_fetch_array($result MYSQL_NUM)) echo lttrgt for ($i = 0 $i lt $total_fields $i++) echo lttdgt$rows[$i]lttdgt echo lttdgtlta href=editphpaction=editampid= echo $rows[0]gtltbgt編輯ltbgtlttdgt echo lttdgtlta href=editphpaction=delampid= echo $rows[0]gtltbgt刪除ltbgtlttdgt echo lttrgt echo lttablegtlthrgt mysql_free_result($result) mysql_close($link) gt ltcentergt ltform action=searchphp method=postgt lttable border=0 width=450gt lttrgtlttdgt搜尋姓名 lttdgt lttdgtltinput type=text name=Name size=10 maxlength=20gtlttdgtlttrgt lttrgtlttdgt搜尋電話 lttdgt lttdgtltinput type=text name=Tel

56

size=20 maxlength=20gtlttdgtlttrgt lttrgtlttd colspan=2 align=centergt ltinput type=submit name=Search value=搜尋gtlttdgtlttrgt lttablegt ltformgt ltbrgtlta href=indexhtmlgt通訊錄ltagt | lta href=addphpgt新增連絡人ltagt | lta href=searchphpgt搜尋通訊錄ltagt ltbodygt lthtmlgt

lt ob_start() gt lt-- 程式範例editphp --gt lthtmlgt ltheadgtlttitlegt編輯通訊錄lttitlegtltheadgt ltbodygt lt 取得 URL 參數 $id = $_GET[id] $action = $_GET[action] 建立資料庫連結 $link = mysql_connect(localhostroot1234) mysql_select_db(CONTACT) 選擇資料庫 執行的操作 switch ($action) case update 更新 取得欄位資料 $name = $_POST[Name] $tel = $_POST[Tel] $sql = UPDATE address SET name=$name tel=$tel WHERE id=$id mysql_query($sql) 執行 SQL指令 mysql_close($link) header(Location searchphp) 轉向到 serachphp break case del 刪除 $sql = DELETE FROM address WHERE id=$id

57

mysql_query($sql) 執行 SQL指令 mysql_close($link) header(Location searchphp) 轉向到 serachphp break case edit 編輯 $sql = SELECT FROM address WHERE id=$id $result = mysql_query($sql) 執行 SQL指令 $row = mysql_fetch_row($result) 取回記錄 $name = $row[1] 取得欄位 name $tel = $row[2] 取得欄位 tel mysql_close($link) 顯示編輯表單 gt ltcentergtlth2gt更新通訊錄lth2gtltcentergtlthrgt ltform action=editphpaction=updateampid=lt echo $id gt method=postgt lttable border=0 width=300gt lttrgtlttdgt姓名 lttdgt lttdgtltinput type=text name=Name size=20 maxlength=10 value=lt echo $name gtgtlttdgtlttrgt lttrgtlttdgt電話 lttdgt lttdgtltinput type=text name=Tel size=20 maxlength=20 value=lt echo $tel gtgtlttdgtlttrgt lttrgtlttd colspan=2 align=centergt ltinput type=submit value=更新連絡人gtlttdgtlttrgt lttablegt ltformgt ltbrgtlta href=indexhtmlgt通訊錄ltagt | lta href=addphpgt新增連絡人ltagt | lta href=searchphpgt搜尋通訊錄ltagt lt break gt ltbodygt lthtmlgt

58

52 任務二Web Base群組軟體 ( twig )

順利完成Web Base客戶通訊錄程式測試一段時間後「Apache + MySQL + PHP」架構的穩定與快速巳深得老闆與公司所有同事的認同隨著公司業績蒸

蒸日上人員組織編罝愈來愈龐大跨部門的會議愈來愈多業務員每日排滿拜

訪客戶的行程跟客戶的 Email的往來也愈來愈頻繁 愈來愈多部門的同事希望公司能建置一套群組軟體提供 web mail可讓業

務人員方便收發 mail還有連絡人議事日程待辦工作書簽等功能讓整個

公司運作及個人時間管理更有效率

老闆問小明對這些需求有什麼看法小明認為如果這些功能完全由程式部

門開發必定曠日費時而且耗費公司資源小明在網路尋找是否有提供這些功能

的Free Software皇天不負苦心人小明發現了TWIG (The Web Information Gateway) httptwigscrewdrivernet這個群組軟體它在 Web 上整合郵件新聞聯絡人議事日程工作序書簽等功能非常符合公司的需求 Step 1 下載 twig-277targz 下載網址 httptwigscrewdrivernetdownloadphp3

Step 2 解開 twig-277targz tar -xzvf twig-277targz

59

Step 3 執行安裝動作安裝到 varwwwhtmltwig 目錄 cd twig-277 twig-install varwwwhtmltwig

Step 4 建立 MySQL 資料庫(twig)及各資料表

cd setup mysql -u root -p1234 mysqlgt create database twig Query OK 1 row affected (001 sec) mysqlgt quit mysql -u root ndashp1234 twiglt twigtablemysql

Step 5 修改 configincphp3 參數設定 vi varwwwhtmltwigconfigconfigincphp3 $config[fromdomain] = opencom 網域 $config[language] = chinesebig5 中文訊息 $config[imap_port] = 143notls

60

Step 6 修改連結 MySQL 的帳號密碼 vi varwwwhtmltwigconfigdbconfigincphp3 $dbconfig[sqlusername] = root username $dbconfig[sqlpassword] = 1234 password

Step 7 其他設定檔

vi etchttpdconfhttpdconf 加入 AddType applicationx-httpd-php php3 在 DirectoryIndex最後加入 indexphp3 DirectoryIndex indexhtml indexhtmlvar indexphp3 在 AddDefaultCharset ISO-8859-1加上 AddDefaultCharset ISO-8859-1

vi etcphpini register_globals = On service httpd restart Step 8 sendmail 設定 vi etcmailsendmailcf在 264 行前面加上並重新啟動 sendmail「service snedmail restart」 262 SMTP daemon options 263 264 O DaemonPortOptions=Port=smtpAddr=127001 Name=MTA 265 266 SMTP client options 267 O ClientPortOptions=Family=inet Address=00

61

Step 9 檢查設定有無錯誤 http主機名稱twigtestphp3

62

Step 10 登入 twig ( http主機名稱twig)

63

第六章 維護及更新程序

61 日常維護

系統管理員最好定期以 root 身份登入看看信件在 RedHat Linux 中有一支 logwatch 程式會定時去分析 log file如果發現異常便會發信給 root除此之外筆者建議讀者平時就檢查 MySQL log file ( varlogmysqldlog)是否有異常情形

62 更新程序

讀者可至httprpmfindnet 尋找MySQL相關套件至於升級的相關步驟請參

考Linux OS SOP 第 54節

63 備份重要檔案

預設 MySQL 的 DB 檔案是存在 varlibmysql 內以 DB名稱為目錄目錄

內就是該 DB 的所有資料通常得定期備份還有 MySQL的設定檔 etcmycnf也別忘了一起備份

64 離線備份與還原

641 離線備份

預設 MySQL 的 DB 檔案是存在 varlibmysql 內以 DB 名稱為目錄目錄內

就是該 DB 的所有資料像 CRM 這個 DB就是存在 varlibmysqlCRM 內在備份前因為怕資料尚未完全寫入磁碟而且 MySQL 會 Lock 在使用的 DB 檔案所以應該是要先把 MySQL 先 Shutdown 一下整個備份的程序可以下像下面的指令去完成 cd varlibmysql

64

service mysqld stop tar cvfz CRM_db_20030905tgz CRM service mysqld start 對這樣就可以了 不過要注意的是怕 DB 內每個 Tables 間的資料有關關

聯性所以最好是把整個 DB 一次備起來單獨只備哪個 Tables 的檔案以後回存時怕會有資料關聯不一致的問題

642 離線還原

DB 發生錯誤而要回存時其實也不難先找出最近一次完整正常的備份先把現在錯誤的網頁或 DB 先更名或 tar 起來再把好的備份給解開回原來目錄位

置就行了需要注意的是 MySQL 服務最好也是要先停止回存完成後再啟動服務回存 DB 的整個程序可能像下面 cd varlibmysql service mysqldstop mv CRM CRM_OLD tar xvfz CRM_db_20030905tg service mysqld start

65 線上備份與還原

651 線上備份

使用像上面的檔案方式備份是個不錯的方法它最少可以保持該主機某個時間點的完整檔案備份但還是有一些問題需要考慮到有些主機就不只建立一個 DB 而已總不能為了備份某個 DB 而把整個 MySQL 服務停止備份檔案的方式回存在原主機上一定適用但假如 MySQL 版本升級或是在那天該網頁空間需遷機移機到別的主機時那就沒人敢保證備出來的資料檔可以用所以我們可以考慮另一種備份的方式是使用 MySQL 本身提供的功能 MySQL Data Dump指令是 mysqldump

65

使用 MySQL 的 Dump 功能可以把 DB 的結構資料或結構加資料 Dump 成文字檔 mysqldump 指令提供的彈性很大你可以選擇把整個 DB Dump 成一個檔或是每個 Table 為一個檔甚至是把結構檔和資料分開儲存都

可以 mysqladmin -uroot -p flush-logs mysqldump CRM -uroot -p --opt gt CRM_20030905sql (CRM 是 DB 名稱 opt 是一個使用完整 Dump 參數) 假如只是要單獨 Dump 某個 Table 時只要在上面的指令後轉出符號 gt 前加個 Table 名稱就可以如只要 phpbb2_users 這個 Table 的 Dump 時只要下 mysqldump CRM -uroot -p --opt CUSTOMER gt CRM_CUSTOMER_20030905sql

652 線上還原

若要回存整個資料庫只需將壓縮的備份檔還原成 Dump 的檔案再用下面的指令回存 mysql CRM -uroot -p lt CRM_20030905sql 這邊需注意的是若建立備份時是以--opt或--add-drop-table為參數時回存的 動作是先將舊的 Table 先刪除重建 Table 的結構後再把 Data 匯入所以回存後所有的資料會回到你當時備份那個時間點因此在回存資料時可以考慮把現有錯誤或不完整的 DB 先備份一份下來以備不時之需或是拿來比對錯誤的地

方在那裡當然你也可以把資料回存到另一個測試用的 DB 內只要把上面指令

的 DB 名稱改成你的測試用 DB 名稱即可 使用這種回存方式 MySQL 服務不需停止也不會動到其他正在使用的 DB 在一些提供 MySQL 服務的虛擬主機可用這種方式作你自己的 DB 備份及回存

66

另外假如你是系統重建或是移機時切需在新的 MySQL 內新建一個空白 DB 後才行作回存的工作你可以用下面的指令建立 mysql -uroot -p -e CREATE DATABASE CRM (上面的 CRM是你要新建的 DB 名稱) 另一種作法先用 mysql 指令進入 mysql client console 然後再用 CREATE DATABASE CRM 這樣就行了記得尾端要加個 符號該行指令才會執行

67

第七章 問題與解答

Q1RedHat 90預附的 MySQL到底有無支援 Transcation機制 Ans MySQL自 32334a之後的 MySQL-Max版本加入 InnoDB的資料庫類型透過

InnoDBMySQL同樣可以進行 COMMIT與 ROLLRACK的動作RedHat 90預附的 MySQL為 32354a-11巳支援 InnoDB的資料庫類型不過必須做以

下設定 1cp usrsharedocmysql-server-32354amy-mediumcnf to etcmycnf 2 vi etcmycnf 將以下設定前的拿掉 innodb_data_home_dir = varlibmysql innodb_data_file_path = ibdata110Mautoextend innodb_log_group_home_dir = varlibmysql innodb_log_arch_dir = varlibmysql 3service mysqld restart 如此一來各位在建立Table時便可指定Table Type為 innodb ( ex create table with type=innodb ) Q2如何解決 php+mysql 許功蓋等字變亂的問題 Ans 方法一 【確定 MySQL 預設的字元集】 1 打開 WinMySQLadmin 管理畫面(在視窗右下角狀態列紅綠燈圖示中按滑鼠

右鍵點選 Show me 選項) 2 點選管理畫面中 [Variables] 標籤選項其中 character_set變數就是您預設

字元集的變數其預設是 latin1 字元集(我們要將他改回 big5)而 chatacters_set 變數則是 MySQL 可以支援哪些字元集 【修改預設字元集變數 character_set 】 1 請點選管理畫面中 [myini Setup] 標籤選項設定 myini 2 按一下 [Pick-up and Edit myini values] 按鈕以便編輯目前的 myini 設定 3 在 [mysqld] 設定區塊底下新增一行 default-character-set = big5 變數設

68

定 4 新增一個 [client] 設定區塊並加入第三步驟的變數設定(游標往下移到空白處新增兩行 [client] 和 default-character-set=big5) 5 按一下畫面左下方 [Save Modification] 按鈕儲存設定 6 重新啟動 MySQL 或 Windows 方法二 Server端注意事項 phpini 中有關的設定為(預設值) Magic quotes for incoming GETPOSTCookie data magic_quotes_gpc = On Use Sybase-style magic quotes (escape with instead of ) magic_quotes_sybase = Off Client端注意事項 1中文資料送進 mysql 前請用 addslashes($str) 處理 2處理後送進 mysql 時請用 括起來並在參數後留一個空白如 $sql = UPDATE ezf_table set tablename=$tname tableend=$endtime table inguser=$tguser tableingid=$tguserid tableallnumber=$tnumber tableloca l=$tablelocal tableanyone=$tableopen tabletext=$ttext WHERE tableid=$t ableid tablename=$tname c 取出時請用 stripslashes($str) Q3MySQL root 密碼忘了該怎麼辦 Ans 1先停掉 mysql etcrcdinitdmysql stop 2以--skip-grant-table 的參數啟動 mysql safe_mysql --skip-grant-tableamp 3 更改 root 密碼 mysql mysql mysqlgt UPDATE user SET password=password(newpassword)

69

WHERE user=root mysqlgt FLUSH PRIVILEGES mysqlgt exit 4停掉 mysql再重跑 mysqladmin -uroot -p shutdown Enter password 輸入新設定的密碼 etcrcdinitdmysql start

Q4NULL值問題

Ans

NULL值的概念是造成 SQL的新手的混淆的普遍原因他們經常認為 NULL是和一個空字符串的一樣的東西不是這樣的例如下列語句是完全不同的

mysqlgt INSERT INTO my_table (phone) VALUES (NULL)

mysqlgt INSERT INTO my_table (phone) VALUES ()

兩個語句把值插入到 phone 列但是第一個插入一個 NULL值而第二個插入一個空字符串第一個的含義可以認為是ldquo電話號碼不知道而第二個則可意味

著ldquo她沒有電話

在 SQL中NULL值在于任何其他值甚至 NULL值比較時總是假的(FALSE)包含 NULL的一個表達式總是產生一個 NULL值除非在包含在表達式中的運算符和函數的文檔中指出在下列例子所有的列返回 NULL

mysqlgt SELECT NULL1+NULLCONCAT(InvisibleNULL)

如果你想要尋找值是 NULL的列你不能使用=NULL測試下列語句不返回任

何行因為對任何表達式expr = NULL是假的

mysqlgt SELECT FROM my_table WHERE phone = NULL

要想尋找 NULL值你必須使用 IS NULL測試下例顯示如何找出 NULL電話號碼和空的電話號碼

70

mysqlgt SELECT FROM my_table WHERE phone IS NULL mysqlgt SELECT FROM my_table WHERE phone =

在 MySQL中就像很多其他的 SQL服務器一樣你不能索引可以有 NULL值的列你必須聲明這樣的列為 NOT NULL而且你不能插入 NULL到索引的

列中

當用 LOAD DATA INFILE 讀取數據時空列用更新如果你想要在一個列中有

NULL值你應該在文本文件中使用N字面上的詞NULL也可以在某些情形下使用

當使用 ORDER BY時首先呈現 NULL值如果你用 DESC以降序排序NULL值最後顯示當使用 GROUP BY時所有的 NULL值被認為是相等的

為了有助于NULL的處理你能使用 IS NULL和 IS NOT NULL運算符和 IFNULL()函數

對某些列類型NULL值被特殊地處理如果你將 NULL插入表的第一個TIMESTAMP 列則插入當前的日期和時間如果你將 NULL插入一個AUTO_INCREMENT 列則插入順序中的下一個數字

Q5如何將圖片存放於 MySQL中

Ans

Step 1建立資料庫 test

Step 2 建立表格 binary_data

CREATE TABLE binary_data (

id INT(4) NOT NULL AUTO_INCREMENT PRIMARY KEY

description CHAR(50)

bin_data LONGBLOB

filename CHAR(50)

filesize CHAR(50)

filetype CHAR(50)

71

)

Step 3 利用 storephp 寫入圖片

storephp 程式碼

ltHTMLgt ltHEADgtltTITLEgtStore binary data into SQL DatabaseltTITLEgtltHEADgt ltBODYgt lt code that will be executed if the form has been submitted

if ($submit) mysql_connect(localhostrootYOUR_PASSWORD) mysql_select_db(test) $data=Base64_Encode(fread(fopen($form_data r) filesize($form_data))) $result=MYSQL_QUERY(INSERT INTO binary_data (descriptionbin_datafilenamefilesizefiletype) VALUES ($form_description$data$form_data_name$form_data_size$form_data_type)) $id= mysql_insert_id() print ltpgtThis file has the following Database ID ltbgt$idltbgt MYSQL_CLOSE() else else show the form to submit new data

gt

ltform method=post action=ltphp echo $PHP_SELF gt enctype=multipartform-datagt File Descriptionltbrgt ltinput type=text name=form_description size=40gt ltINPUT TYPE=hidden name=MAX_FILE_SIZE value=4000000gt ltbrgtFile to uploadstore in databaseltbrgt ltinput type=file name=form_data size=40gt ltpgtltinput type=submit name=submit value=submitgt ltformgt lt

72

gt ltBODYgt ltHTMLgt

Step 3 利用 storephp 取出圖片

getdataphp 程式碼

lt Syntax getdataphp3id=ltidgt if($id) you may have to modify login information for your database server MYSQL_CONNECT(localhostrootYOUR_PASSWORD) mysql_select_db(test) $query = select bin_datafiletype from binary_data where id=$id $result = MYSQL_QUERY($query) $data = Base64_Decode(MYSQL_RESULT($result0bin_data)) $type = MYSQL_RESULT($result0filetype) Header( Content-type $type) echo $data gt

Q6MySQL裝好之後啟動時或是執行 mysqladmin會出現如下訊息 Cant connect to local MYSQL Server through Socket varlibmysqlmysqlsock或是

Cant connect to local MYSQL Server through Socket tmpmysqldsock

Ans 可能有下列幾個原因

1這個 mysqldsock 不見了被某人刪除了或是被一些系統自動執行程式給刪

了例如有些 cron任務便會設定定期刪除 tmp 裡的東西所以呢您只能修改

cron 裡的設定讓它不要清除 mysqldsock 2在啟動時也可以改變 mysqldsock的位置您在啟動 MySQL的時候可以加入此參數usrlocalmysqlbinsafe_mysqld --user=mysql --socket=其他路

徑socket amp 同時得去設定環境變數 MYSQL_UNIX_PORT的值以指定新的

73

路徑 3若是您沒改 MYSQL_UNIX_PORT的值那麼您可以在執行指令的時候才打

例如mysqladmin --socket=其他路徑socket version Q7How to get the last insert id Ans CREATE TABLE product ( id INT(4) NOT NULL AUTO_INCREMENT PRIMARY KEY description VARCHAR(50) ) 1利用 SQL的話 mysqlgt insert into product(description) values(123) Query OK 1 row affected (000 sec) mysqlgt select last_insert_id() +------------------+ | last_insert_id() | +------------------+ +------------------+ 1 row in set (000 sec) ======================================== 2如果是 PHP的話 你可以用mysql_insert_id()取得該 id PHP example $result=MYSQL_QUERY(INSERT INTO product (description) VALUES ($description)) $id= mysql_insert_id() print This file has the following Database ID $id Q8如何將文字檔匯入資料庫 Ans $addr=homehttpdhtmlphpschool001txt $sql_select = load data infile $addr into table test fields terminated by t 解說 $sql_select = load data infile 文字檔名 into table 表格名 fields terminated by

74

t

(欄位分隔以 TAB鍵) 該文字檔須與資料表欄位格式相符 例如欄位有三個 則文字檔為每行一筆資料如下 欄 1資料ltTABgt欄 2資料ltTABgt欄 3資料 欄 1資料ltTABgt欄 2資料ltTABgt欄 3資料 欄 1資料ltTABgt欄 2資料ltTABgt欄 3資料 欄 1資料ltTABgtltTABgt欄 3資料

Q9如何撰寫 MySQL C API Ans Step 1利用文字編輯器撰寫以下程式碼 mysqlcc

include ltstdiohgt

include ltmysqlmysqlhgt

int main (int argc char argv[])

MYSQL mysql

MYSQL_RES res

MYSQL_ROW row

if (argc = 2)

fputs (Usage myc ltdatabasegt stderr)

return 1

if ((mysql_connect(ampmysqllocalhostrootYour_Password)))

fputs (Error connecting stderr)

abort()

75

if (mysql_select_db(ampmysqlargv[1]))

fputs (Error selecting database stderr)

abort()

if (mysql_query(ampmysqlSELECT FROM test_table))

fputs (Error processing query stderr)

abort()

if ((res = mysql_store_result(ampmysql)))

fputs (Error storing results stderr)

abort()

while((row = mysql_fetch_row(res)))

uint i = 0

for (i=0 i lt mysql_num_fields(res) i++)

printf(s row[i])

printf(n)

return 0

Step 2 Compile

gcc -Iusrlocalmysqlinclude -Lusrlocalmysqllibmysql mysqlcc ndashlm -lmysqlclient

(其中 include path與 library path取決於你的 MySQL安裝路徑)

76

如果執行時發生如下 error Run problemerror in loading shared libraries libmysqlclientsoX 將你的 MySQL library path(for exampleusrlocalmysqllibmysql) 加入etcldsoconf and run sbinldconfig -v Q9ASP + MySQL 範例程式 Ans Dim myconn As New ADODBConnection Dim myrs As New Recordset Dim mySQL As String Dim myrows As Long myconnOpen DSN=MyODBCsample mySQL = SELECT from user myrsSource = mySQL Set myrsActiveConnection = myconn myrsCursorLocation = adUseClient myrsOpen myrows = myrsRecordCount myrsClose myconnClose 可參考 httpwwwdwamnetmysqlasp_myodbcasp 有詳細的資料 Q10如何將 MySQL中的資料庫匯出成txt檔 Ans select from TableName into outfile textxls all result fields will seperate by tab

77

第八章 參考資料

英文部份 網址 1 httpwwwmysqlcom MySQL 網站有第一手有關 MySQL的資料 2 httpwwwmysqlcomdocenReplicationhtml 有關 MySQL Replication 的文件 3 httpwwwgeocitiescomsqlhomefaqstore_blobhtml 如何在 MySQL 存放 BLOB的資料 4httpwwwsapdborg 有關 SAP跟 MySQL相關合作的網站 書藉 1 Cooking with MySQL

Paul DuBois has selected sample recipes from the hundreds youll find in his book MySQL

Cookbook In this third and final series of excerpts showcasing these recipes learn how to

compute team standings how to calculate the differences between successive Dec 26

2002 2 Tips for Building Web Database Applications with PHP and MySQL by Hugh E Williams co-author of Web Database Applications with PHP amp MySQL 04042002

3 Managing and Using MySQL 2nd Edition By Tim King George Reese Randy Jay Yarger

4 MySQL Cookbook By Paul DuBoisPublisher OReillyPub Date October 2002

中文部份

78

1 httplinuxtncedutwtechdocmysqlmysql_docmanual_tochtml MySQL 中文手冊 2 httpchenshloxaedutwphpZ_1php PHP+MySQ程式研習設計網站 3 httplinuxtncedutwtechdocbanicdownhtml PHP 4 手冊 4 httpwwwtncedutwadmin_zonephp台南縣教育網網路中心有很多 Linux相關文件 5 httpdobtncedutw網站建置百寶箱有很多 PHP MySQL 相關範例程式 5 httpwwwdbworldcomtw資料庫專家電子雜誌介紹資料庫的重要觀念及名詞

79

附錄一 SQL Command 介紹

SQL (讀音ess-que-el) 是一種結構查詢語法SQL 使用於資料庫交流

傳遞相容於 ANSI (American National Standards Institute) 是一套標準的關聯

式資料庫語言 SQL 語言是執行更新或從資料系統獲取資料一般常見的關聯

資料庫系統都有提供 SQL 如 Oracle Sybase Microsoft SQL Server Access Ingres 等雖然大部份的資料庫都有提供 SQL 但也多提供了自已獨特的語

法造成了不相容的情形但標準基本的語法是相通的如Select Insert Update Delete Create and Drop 每一個系統都有支援

Table相關 Command

Create Table

關聯式資料庫包含有很多元件稱為資料表(tables) 把資料或訊息放在資

料表中 資料表是以不同的名稱做分別資料表由欄列所構成的二維陣列

欄包含欄位名資料型態 及其他可判斷的資訊列是由全部欄位構成一筆一

筆的紀錄 create table 語法用在建立一個新的資料表語法格式如下

create table tablename (column1 data type column2 data type column3 data type)

Format of create table if you were to use optional constraints

create table tablename (column1 data type [constraint] column2 data type [constraint] column3 data type [constraint]) [ ] = optional

Note You may have as many columns as youd like and the constraints are optional

80

Example

create table employee (first varchar(15) last varchar(20) age number(3) address varchar(30) city varchar(20) state varchar(20))

注意建立資料表格式要以括號把前後框住而最後以(分號)做結尾

欄位名不要超過 30個字元長而且不要使用 sql 的關鍵字(如 where select等)而在後面接是型態的宣告(如字串數字日期格式等)

資料型態是來描述欄位的方式如一個欄位Last_Name 是一個姓氏可以使用varchar (可變動長度字串) 資料型態

以下是幾個常見的資料庫型態 char(size) 固定長度字串最長為 255 位元 varchar(size) 變動長度字串最大字元數以 size 來指定 number(size) 數值格式可以是整數也可以是小數最大數字以 size 位數判

斷未指定小數位數由系統內定 date 日期格式 number(sized) 數值格式最大數字以 size 位數判斷d 為小數位數整數位

數為 size-d 位

有何限制當資料表被建立通常有一或數個欄位是要使用來做關聯的功

能 例如unique 限制(唯一值)兩筆記錄不可以相同的值 not null (非空值)該欄位一定要輸入資料不可是空的primary key (主鍵)是每一筆記錄識別的主要方式

Drop a table drop table 刪除資料表(其中的資料也會一併刪除)

drop table tablename

Example

81

drop table 和刪除全部資料是不同的刪除全部資料欄位名稱資訊等還會

存在但刪除資料表會把這一些也一併移除掉

如何查詢資料

Select 基本用法

select 語法是關連式資料庫最常用的部份可以取得你想要的資料這是一個

簡單的範例 select column1[column2etc] from tablename [where condition] [] = optional 在 select 之後所列欄位名則是要顯示的資料部份你可以一一列出各欄位

名或是以 (星號)來代表選擇全部的欄位 from 之後放資料表名稱 where 子句 (選項) 指定要過濾的條件符合者才會顯現 where 可使用的條件運算元 = 等於 gt 大於 lt 小於 gt= 大或等於 lt= 小或等於 ltgt 大相等 LIKE 相似 For example select first last city

82

from empinfo where first LIKE Er 以Er 為開頭的字串就符合要以單引號框住 Or you can specify select first last from empinfo where last LIKE s 最後一字為 S 就符合 select from empinfo where first = Eric 則表示 first name 一定要是 Eric 才可以 範例資料表empinfo 統計函數

MIN 傳回指定欄位最小值

MAX 傳回指定欄位最大值

SUM 傳回指定欄位總和

AVG 傳回指定欄位平均值

COUNT 傳回指定欄位的筆數

COUNT() 傳回資料庫中的總筆數

統計函數使用於資料表中的數值欄位配合 SELECT 語法使用 只用於總結特定單一欄位可以配合 GROUP BY 做篩選但也可以不使用 GROUP BY 語句For example

SELECT AVG(salary) FROM employee

83

傳回全部 salary 平均值

Another example

SELECT AVG(salary) FROM employee WHERE title = Programmer

傳回 salary 平均值條件為 employees 資料表中當 title 等於 Programmer

Example

SELECT Count() FROM employees

傳回 employees 資料表中紀錄總筆數

GROUP BY 語法 SELECT column1 SUM(column2) FROM list-of-tables GROUP BY column-list The GROUP BY 語句可以先以所列的欄位為條件分組排序在一起(可以多欄

位) example 要列出每一個 dept 中最高 salary 值 SELECT max(salary) dept FROM employee GROUP BY dept HAVING 語法

SELECT column1 SUM(column2) FROM list-of-tables GROUP BY column-list HAVING condition

HAVING 子句是 GROUP BY 的一部份用來過濾在 GROUP BY 所選出的資料功能如同 select 命令中 where 條件式一樣只是 HAVING 必需配合 GROUP BY 使用

我們以例子來說明我們要取得每一公司名及每一公司的薪水平均值輸入如下

84

SELECT dept avg(salary) FROM employee GROUP BY dept

但如果我們只列出薪資平均值超過 20000元的公司資料

SELECT dept avg(salary) FROM employee GROUP BY dept HAVING avg(salary) gt 20000

ORDER BY子句語法

SELECT column1 SUM(column2) FROM list-of-tables ORDER BY column-list [ASC | DESC]

[ ] =選項

ORDER BY是一個選項子句當你以排序方式來顯示資料(正向由小到大反向由大到小)以指定的欄位資料做排序

ASC = 正向- 預設值 DESC = 反向排序

For example

SELECT employee_id dept name age salary FROM employee_info WHERE dept = Sales ORDER BY salary

以上列出公司代號公司名銷售員人名年紀及薪資而條件是公司名為 Sales 顯示順序以薪資多少排序(由小到大為預設值)

如果要以多個欄位做排序要以逗號做分隔如下

SELECT employee_id dept name age salary FROM employee_info WHERE dept = Sales ORDER BY salary age DESC

85

結合條件及布林運算 SELECT column1 SUM(column2) FROM list-of-tables WHERE condition1 AND condition2 AND運算可以結兩個或以上的條件放在 WHERE子句中 兩者都要為真才

會顯示該筆記錄 OR 運算可以結兩個或以上敘述放在 WHERE子句中只要其中一個為直就

會顯示該筆記錄 For example SELECT employeeid firstname lastname title salary FROM employee_info WHERE salary gt= 5000000 AND title = Programmer 必需要薪資大於等於 50000而且職稱為 Programmer同時符合才會顯示該筆資料 以下以括號括住雖然不是必需的但如此比較容易讀 SELECT employeeid firstname lastname title salary FROM employee_info WHERE (salary gt= 5000000) AND (title = Programmer) 另外範例 SELECT firstname lastname title salary FROM employee_info WHERE (title = Sales) OR (title = Programmer) 條件為只要是 Sales 或 Programmer 職稱的就會被列出 IN and BETWEEN 子句

SELECT column1 SUM(column2) FROM list-of-tables WHERE column3 IN (list-of-values) SELECT column1 SUM(column2) FROM list-of-tables WHERE column3 BETWEEN value1 AND value2 IN 子句使用在列舉項目的使用上也就是分別測試是否符合所列的值 For example

86

SELECT employeeid lastname salary FROM employee_info WHERE lastname IN (Hernandez Jones Roberts Ruiz) 條件為姓氏(astname)要符合 Hernandez Jones Roberts or Ruiz 其中一個才會被傳回 IN運算元也可以使用 OR 的語法來取代如下結果相同 SELECT employeeid lastname salary FROM employee_info WHERE lastname = Hernandez OR lastname = Jones OR lastname = Roberts OR lastname = Ruiz 但使用 IN 句子比較短也比較易懂 你也可以使用 NOT IN 來去掉不要的記錄 BETWEEN 運算元使用在判斷是否存在兩個數值之間 For example SELECT employeeid age lastname salary FROM employee_info WHERE age BETWEEN 30 AND 40 傳回年紀 30歲到 40歲之間的資料(含 30及 40歲者) 相同的也可以使用以下語法來達到相同的結果 SELECT employeeid age lastname salary FROM employee_info WHERE age gt= 30 AND age lt= 40 你也可使用 NOT BETWEEN 來濾掉中間值的資料 數學運算 標準 ANSI SQL-92 提供以下運算

87

+ 加

- 減

餘數

餘數為除法後剩整數這不在標準的 ANSI SQL 中但大部份的資料庫都會支

援這運算元以下列出有用的函數雖不在 ANSI SQL-92 提供但一般資料庫

也會支援他們

ABS(x) 傳回 x 絕對值

SIGN(x) returns the sign of input x as -1 0 or 1 (negative zero or positive respectively)

MOD(xy) 餘數 - returns the integer remainder of x divided by y (同 xy)

FLOOR(x) 傳回小或等於 x 的最大整數值

CEILING(x) or CEIL(x)

傳回大或等於 x 的最小整數值

POWER(xy) x的 y 次方

ROUND(x) 把 x 四捨五入為整數

ROUND(xd) 四捨五入取到小數 d 位

SQRT(x) x 開平方

For example SELECT round(salary) firstname FROM employee_info 傳回薪資取到整數位

如何新增資料

insert 加入一筆新紀錄到資料表中 insert into tablename (first_columnlast_column) values (first_valuelast_value) [] = optional Example insert into employee

88

(first last age address city state) values (Luke Duke 45 2130 Boars Nest Hazard Co Georgia) Note 字串要以單引號住如string 數字框住也無妨 insert into 後面接資料表名稱再接以括號括住的欄位名在 values 後括號分別對映各欄位的值 以上的例子新增了一筆名(first) 為 Luke而住所(state) 為 Georgia 的資料

如何刪除資料

delete 可以刪除單筆或多筆紀錄 delete from tablename where columnname OPERATOR value [and|or column OPERATOR value] [ ] = optional Examples delete from employee Note 如果你沒有指定 where 子句那麼全部的紀錄都會被刪除 delete from employee where lastname = May delete from employee where firstname = Mike or firstname = Eric delete from 接著資料表名 再接著是條件式判斷沒有條件式則全部紀錄會

被刪除

如何更新資料

update 用來更新你所指定的記錄要和 WHERE 配合小心使用 語法 update tablename set columnname = newvalue[nextcolumn = newvalue2] where columnname OPERATOR value [and|or column OPERATOR value] [] = optional Examples

89

update phone_book set area_code = 623 where prefix = 979 update phone_book set last_name = Smith prefix=555 suffix=9292 where last_name = Jones update employee set age = age+1 where first_name=Mary and last_name=Williams

90

附錄二Replication

測試環境

RedHat 90 + MySQL 32358 MySQL資料庫路徑 varlibmysql MySQL設定檔 etcmycnf Master IP 1921680100 Slave IP 1921680200 請至下列網址下載最新MySQL 32358套件並利用rpm ndashUvh 更新 httpupdatesredhatcom9enosi386

圖 最新 MySQL 套件

測試架構圖

91

1921680100

1921680200Master Server

erveSlave S r

圖 測試架構圖

測試步驟

Master server 部份 Step1 確認 MasterSlave機器上所裝的 MySQL版本能進行

replication( 32329 or higher ) Step2 在 Master MySQL上開放一個帳號給 Slave mysql ndashu root ndashp mysqlgtGRANT FILE ON TO repl1921680200 IDENTIFIED BY lsquoabc123rsquo mysqlgtq 上面是 Master開放一個帳號 repl密碼 abc123給 IP1921680200有檔案處理

的權限 Step3 shutdown MySQL on the Master mysqladmin ndashu root ndashp shutdown Step4 備份 Master所有資料庫 tar ndashcvf tmpmysql-snapshottar varlibmysql 注意tar的時候MySQL是要在 stop情況下 在mysql (wwwmysqlcom) 網站的FAQ有不用shutdown的方法

92

Step5 在 master機器上修改etcmycnf 在[mysqld]區段內加入參數 log-bin server-id=這邊設定 server-id=1 sql-bin-update-same binlog-do-db=CRM只針對 CRM資料庫做紀錄 Step6 Restart MySQL on the master service mysqld start 此時因為有加入 log-bin 參數因此開始有 index產生了在varlibmysql目錄下

有index檔案紀錄資料庫的異動 log Slave server 部份 Step1 在 slave設定etcmycnf 在[mysqld]區段加入 master-host= master-user= master-password= master-port= server-id= 這邊設定 master-host=1921680100 master-user=repl master-password=abc123 master-port=3306 server-id=2 master-connect-retry=60預設重試間隔 60秒 replicate-do-db=CRM告訴 slave只做 CRM資料庫的更新 log-slave-updates Step2 將 master上的 mysql-snapshottar copy到 slave上 用 ftp傳到 slave的tmp Step3 解壓縮 Master資料庫至 Slave Server上 cd varlib tar xvf tmpmysql-snapshottar chown ndashR mysqlmysql mysql

93

chmod ndashR 770 mysql (視情況) Step4 Restart MySQL on the slave server 這時在varlibmysql目錄會出現 masterinfo此檔案紀錄了 Master MySQL server的資訊

狀況測試

One-way replication

1921680100

1921680200Master Server

erveSlave S r

圖 One-way replication架構圖 Step1 Master跟 Slave網路及服務都正常情況下由 Master端異動資料後 到 Slave端瀏覽資料檢視是否有進行 replication Step2 模擬 Slave Server 當機 可用在於 slave真的當機或是 Slave 不一定需要一直跟 master connect將Slave MySQL server shutdown由 Master端異動資料到 slave端瀏覽此時Slave應該沒有被 replication 更新然後再將 Slave端 MySQL server start起來

預設 60秒後 Slave會嘗試跟 Master要求進行 replication再去 Slave端檢視是否有更新資料

94

Step3 模擬 Master當機因為是設定 One-way replication一旦 Master Server Slave端沒有 Master的 source可以 download Two-way replication 基於 Master當機狀況於是發展雙向 Replication即 1921680100 ( Host A ) 1921680200 ( Host B )都分別擔任 MasterSlave身分

1921680100

1921680200er

Server B MasterSlave Server

Server A MasterSlave Serv

圖 Two-way replication架構圖 以下是針對兩台 MySQL伺服器進行雙向 Replication Step1觀念同單向 replication只是改成 Master也有 Slave身分 Slave也有Master的身分先分別在 Server AServer B 都去 grant一個進行 replication的身分 [A]mysqlgtGRANT FILE ON TO repl1921680200 IDENTIFIED BY lsquoabc123rsquo [B]mysqlgt GRANT FILE ON TO repl1921680100 IDENTIFIED BY lsquoabc123rsquo Step2做完單向 replication後stop Server Aserver B MySQL service此時 AB資料是一樣的

95

修改etcmycnf設定 範例 Server A [mysqld] datadir=varlibmysql socket=varlibmysqlmysqlsock server-id=1 log-bin sql-bin-update-same binlog-do-db=CRM master-host=1921680200 master-user=repl master-password=abc123 log-slave-updates master-connect-retry=60 replicate-do-db=CRM Server B [mysqld] datadir=varlibmysql socket=varlibmysqlmysqlsock server-id=2 log-bin sql-bin-update-same binlog-do-db=CRM master-host=1921680100 master-user=repl master-password=abc123 log-slave-updates master-connect-retry=60 replicate-do-db=CRM 分別 start Server AServer B MySQL後此時雙方都是 MasterSlave身分一旦哪一方資料異動就會通知對方來 replication-若 replication失效則必須將Server AServer B的masterinfo及index00x 都砍掉然後分別 restart MySQL server進行測試檢視成果 實務上通常如果需要做Two-way replication通常會搭配Virtual Server使用

96

在前端架設一台Virtual Server不過此部份不在此份SOP討論範圍內有興趣

的讀者可參考 httpwwwlinuxvirtualserverorg 網站

1921680100 1921680200

Host A MasterSlave Server

Host B MasterSlave Server

Virtual Host

圖 Virtual Server + Two-way replication 架構圖

97

圖 High Availability Linux Virtual Server架構圖

98

  • COSA-SOP-03-006
  • 第一章 簡介
    • 11適用對象 (Audience)
    • 12 MySQL本身
    • 13 MySQL 40版跟50版重大的改進功能
    • 14 各家資料庫軟體比較
      • 第二章 前置需求
      • 第三章 安裝
        • 31 MySQL安裝
        • 32 phpMyAdmin安裝
        • 33 升級及注意事項
          • 第四章 MySQL管理
            • 41 Webmin 管理介面
            • 42 phpMyAdmin 的操作介面
            • 43管理指令介紹
              • 431 利用mysqladmin設定root的密碼
                  • 第五章 實用範例
                    • 51 任務一Web Base客戶通訊錄
                    • 52 任務二Web Base群組軟體 ( twig )
                      • 第六章 維護及更新程序
                        • 61 日常維護
                        • 62 更新程序
                        • 63 備份重要檔案
                        • 64 離線備份與還原
                        • 65 線上備份與還原
                          • 第七章 問題與解答
                          • 第八章 參考資料
                          • 附錄一 SQL Command 介紹
                          • 附錄二Replication
Page 31: DataBase Server Standard Operation Procedureebooks.lib.ntu.edu.tw/1_file/oss/63/93doc4-5.pdf · 業務的公司帶來了不少壓力,譬如微軟,甲骨文 ... 外的錢用在第三方的資料庫產品上,譬如就可以不用再購買甲骨文公司

圖 4-6 選擇資料庫

Step 2 指定欄位數目

31

圖 4-7 設定欄位數目

Step 3設定表格欄位屬性

圖 3-8 設定表格欄位屬性

Step 4建立表格資料

32

圖 4-9 建立表格資料

圖 4-10 檢視資料

33

圖 4-11 新增資料

圖 4-12

34

圖 4-13

413 使用者管理

接下來我們要利用Webmin 來建立資料庫使用者並給予某些權限 Step1建立使用者

35

圖 4-14 選擇使用者權限

圖 4-15

36

Step2 賦予權限

圖 4-16

Step3 權限列表

37

圖 4-17

38

42 phpMyAdmin 的操作介面

421建立資料庫

Step 填入資料庫名稱並按「建立」

圖 4-18建立資料庫

422 建立資料表

Step1 填入資料表名稱並指定欄位數量 執行

39

圖 4-19填入資料表名稱並指定欄位數量

Step2 設定欄位屬性

圖 4-20設定欄位屬性

40

Step3 phpMyAdmin會產生相關的 SQL Command

圖 4-21 資料表結構及相關 SQL Command

Step4新增 Record

41

圖 4-22

圖 4-23

42

圖 4-24

圖 4-25

43

423使用者管理

Step1建立使用者

圖 4-26

44

圖 4-27

Step2 給予權限

圖 4-28

Step3權限列表

45

圖 4-29

43管理指令介紹

431 利用 mysqladmin設定 root的密碼

當您在Windows 或 Linux 中安裝好 MySQL後系統會自動幫您建立兩個

帳分別是 root 和 匿名者MySQL的 root 跟 Linux 最高權限使用者 root無關MySQL的 root使用者相當於 MS SQL 中的 sa 帳號擁有最高的 Database管理權限但系統預設 MySQL的 root 是不需要密碼所以通常我們一安裝

MySQL後首要任務便是修改 root的密碼 我們可以利用 mysqladmin工具或是直接修改 MySQL內部資料庫的使用者資

料 mysqladmin ndashu root ndashh cosaexamplecom password lsquo1234rsquo

46

-u 表示使用者帳號root 為 MySQL預設的管理帳號

-h 表示 MySQL主機的主機名稱也可使用 IP Address password 表示使用者的密碼因為字串請使用單引號將密碼括起來 密碼設定完成之後還是可以利用 mysqladmin修改密碼但是你必須提供目前的密碼

432 連線 MySQL

mysql -uroot -p密碼 (-p和密碼之間不能有空白) 或 mysql -uroot -p (此方式會在進入後要求密碼) [rootossc phpMyAdmin] mysql -u root -p1234

Welcome to the MySQL monitor Commands end with or g

Your MySQL connection id is 25 to server version 32354

Type help or h for help Type c to clear the buffer

mysqlgt show databases

+----------+

| Database |

+----------+

| mysql |

| test |

+----------+

2 rows in set (000 sec)

mysqlgt exit

Bye

[rootossc phpMyAdmin]

433 建立資料庫

可利用 mysqladmin指令建立 CONTACT資料庫 mysqladmin -u root -p1234 create CONTACT

47

或是利用 mysql指令 [rootossc bluepage] mysql -u root -p1234 Welcome to the MySQL monitor Commands end with or g Your MySQL connection id is 1057 to server version 32354 Type help or h for help Type c to clear the buffer mysqlgt create database CONTACT Query OK 1 row affected (000 sec) mysqlgt show databases +----------+ | Database | +----------+ | CONTACT | | address | | hello | | mysql | | nuke | | test | +----------+ 6 rows in set (000 sec) mysqlgt exit

434 建立資料表

編寫 adresssql內容如下 -- Table structure for table address CREATE TABLE address ( id int(11) NOT NULL auto_increment name varchar(20) NOT NULL default tel varchar(15) NOT NULL default PRIMARY KEY (id) ) TYPE=MyISAM

48

-- Dumping data for table address INSERT INTO address VALUES (1林小明0800016888) INSERT INTO address VALUES (2黃大雄0800016888) INSERT INTO address VALUES (3劉小芬0800024365) 然後執行此 sql script mysql -u root -p1234 CONTACT lt addresssql 或是利 mysql command [rootossc bluepage] mysql -u root -p1234 Welcome to the MySQL monitor Commands end with or g Your MySQL connection id is 1090 to server version 32354 Type help or h for help Type c to clear the buffer mysqlgt use CONTACT Database changed Database changed mysqlgt CREATE TABLE address ( -gt id int(11) NOT NULL auto_increment -gt name varchar(20) NOT NULL default -gt tel varchar(15) NOT NULL default -gt PRIMARY KEY (id) -gt ) TYPE=MyISAM Query OK 0 rows affected (000 sec) mysqlgt INSERT INTO address VALUES (1林小明0800016888) Query OK 1 row affected (000 sec) mysqlgt INSERT INTO address VALUES (2黃大雄0800016888) Query OK 1 row affected (000 sec) mysqlgt INSERT INTO address VALUES (3劉小芬0800024365) Query OK 1 row affected (000 sec) mysqlgt exit Bye

49

第五章 實用範例

51 任務一Web Base客戶通訊錄

任職於開放科技公司的林小明前些日子在最符合成本效益的條件下快

速地完成公司網站的建置老闆因此對小明讚譽有加最近因為公司存放客戶資

料的 SQL Server主機屢遭病毒攻擊加上作業系統本身的問題當機次數頻繁

老闆希望能儘快把公司的客戶通訊錄程式移轉到較穩定的環境上因為此客戶通

訊錄程式最主要給內部人員使用所以介面美觀並不特別要求只求穩定且能快

速得到查詢結果老闆希望在短時間先看到程式的雛型並鍵入資料對其效率

及穩定性進行測試因為上次小明表現突出所以這次不可能的任務自然又落到

小明身上 小明想來想去既然要快速又穩定他而且又不希望所有人都得安裝 Client

程式於是小明決定)捨棄他的舊愛「Delphi+MS SQL」投向新歡「Apache + MySQL + PHP」利用此架構來設計一個簡單實用的Web Base客戶通訊錄程式

511 Web Base客戶通訊錄架構

此程式需要建立 CONTACT的資料庫並建立 adress Tables其結構如下表建立步驟請參考第三章 欄位名稱 資料型態 長度 說明 id INT (自動編號) 連絡人編號 name varchar文字 20 連絡人姓名 tel Varchar文字 15 連絡人電話 Web Base通訊錄共有下列幾個檔案功能如下表

檔案名稱 說明 Indexhtml Web Base通訊錄首頁 addphp 新增連絡人的 php程式 searchphp 尋找連絡人的 php程式 editphp 具有更新及刪除功能的 php程式

50

我們將這些檔案放至varwwwhtmlbluepage (預設無 bluepage目錄)

512 Web Base通訊錄測試

httpwwwopencombluepage 新增資料

圖 5-1 新增連絡人

圖 5-2 填入資料

51

圖 5-3 新增成功

搜尋及異動資料

圖 5-4 搜尋通訊錄

52

圖 5-5 編輯資料

圖 5-6 更新資料

513 程式內容及說明

lt-- 程式範例indexhtml--gt lthtmlgt ltheadgtlttitlegt通訊錄lttitlegtltheadgt ltbodygt ltcentergt

53

lth2gt通訊錄lth2gtlthrgt lta href=indexhtmlgt通訊錄ltagt | lta href=addphpgt新增連絡人ltagt | lta href=searchphpgt搜尋通訊錄ltagt ltcentergt ltbodygt lthtmlgt lt-- 程式範例addphp --gt lthtmlgt ltheadgtlttitlegt新增連絡人lttitlegtltheadgt ltbodygt ltcentergtlth2gt新增連絡人lth2gtltcentergtlthrgt lt 取得欄位資料 if (isset($_POST[Name]) ampamp isset($_POST[Tel]) ) $name = $_POST[Name] $tel = $_POST[Tel] 檢查是否有輸入欄位資料 if ($name = ampamp $tel = ) 建立 SQL字串 $sql = INSERT INTO address (name tel) values( $sql= $name $tel) 建立 MySQL 連結 $link = mysql_connect(localhostroot1234) 選擇資料庫 mysql_select_db(CONTACT) 執行 SQL指令 mysql_query($sql) mysql_close($link) echo ltfont color=redgt新增連絡人成功ltfontgtltbrgt gt ltform action=addphp method=postgt lttable border=0 width=300gt lttrgtlttdgt姓名 lttdgt

54

lttdgtltinput type=text name=Name size=20 maxlength=10gtlttdgtlttrgt lttrgtlttdgt電話 lttdgt lttdgtltinput type=text name=Tel size=20 maxlength=20gtlttdgtlttrgt lttrgtlttd colspan=2 align=centergt ltinput type=submit value=新增連絡人gtlttdgtlttrgt lttablegt ltformgt ltbrgtlta href=indexhtmlgt通訊錄ltagt | lta href=addphpgt新增連絡人ltagt | lta href=searchphpgt搜尋通訊錄ltagt ltbodygt lthtmlgt

lt-- 程式範例searchphp --gt lthtmlgt ltheadgtlttitlegt搜尋通訊錄lttitlegtltheadgt ltbodygt ltcentergtlth2gt搜尋通訊錄lth2gtlthrgt lt if (isset($_POST[Search])) 建立資料庫連結並選定資料庫 $link = mysql_connect(localhostroot1234) mysql_select_db(CONTACT) 建立基本的 SQL字串 $sql = SELECT FROM address 檢查是否輸入姓名 if (chop($_POST[Name]) = ) $name = name LIKE $_POST[Name] else $name = 檢查是否輸入電話號碼 if (chop($_POST[Tel]) = ) $tel = tel LIKE $_POST[Tel] else $tel =

55

if條件組合 SQL字串 if (chop($name) = ampamp chop($tel) = ) $sql= WHERE $name AND $tel elseif (chop($name) = ) 只有姓名 $sql = WHERE $name elseif (chop($tel) = ) 只有電話號碼 $sql = WHERE $tel $sql= ORDER BY name 最後加上排序 $result = mysql_query($sql) 取得欄位數 $total_fields = mysql_num_fields($result) echo lttable border=1gt echo lttrgtlttdgt編號lttdgtlttdgt姓名lttdgtlttdgt電話lttdgtlttd colspan=2gt功能選項lttdgtlttrgt 表格顯示查詢結果 while ($rows = mysql_fetch_array($result MYSQL_NUM)) echo lttrgt for ($i = 0 $i lt $total_fields $i++) echo lttdgt$rows[$i]lttdgt echo lttdgtlta href=editphpaction=editampid= echo $rows[0]gtltbgt編輯ltbgtlttdgt echo lttdgtlta href=editphpaction=delampid= echo $rows[0]gtltbgt刪除ltbgtlttdgt echo lttrgt echo lttablegtlthrgt mysql_free_result($result) mysql_close($link) gt ltcentergt ltform action=searchphp method=postgt lttable border=0 width=450gt lttrgtlttdgt搜尋姓名 lttdgt lttdgtltinput type=text name=Name size=10 maxlength=20gtlttdgtlttrgt lttrgtlttdgt搜尋電話 lttdgt lttdgtltinput type=text name=Tel

56

size=20 maxlength=20gtlttdgtlttrgt lttrgtlttd colspan=2 align=centergt ltinput type=submit name=Search value=搜尋gtlttdgtlttrgt lttablegt ltformgt ltbrgtlta href=indexhtmlgt通訊錄ltagt | lta href=addphpgt新增連絡人ltagt | lta href=searchphpgt搜尋通訊錄ltagt ltbodygt lthtmlgt

lt ob_start() gt lt-- 程式範例editphp --gt lthtmlgt ltheadgtlttitlegt編輯通訊錄lttitlegtltheadgt ltbodygt lt 取得 URL 參數 $id = $_GET[id] $action = $_GET[action] 建立資料庫連結 $link = mysql_connect(localhostroot1234) mysql_select_db(CONTACT) 選擇資料庫 執行的操作 switch ($action) case update 更新 取得欄位資料 $name = $_POST[Name] $tel = $_POST[Tel] $sql = UPDATE address SET name=$name tel=$tel WHERE id=$id mysql_query($sql) 執行 SQL指令 mysql_close($link) header(Location searchphp) 轉向到 serachphp break case del 刪除 $sql = DELETE FROM address WHERE id=$id

57

mysql_query($sql) 執行 SQL指令 mysql_close($link) header(Location searchphp) 轉向到 serachphp break case edit 編輯 $sql = SELECT FROM address WHERE id=$id $result = mysql_query($sql) 執行 SQL指令 $row = mysql_fetch_row($result) 取回記錄 $name = $row[1] 取得欄位 name $tel = $row[2] 取得欄位 tel mysql_close($link) 顯示編輯表單 gt ltcentergtlth2gt更新通訊錄lth2gtltcentergtlthrgt ltform action=editphpaction=updateampid=lt echo $id gt method=postgt lttable border=0 width=300gt lttrgtlttdgt姓名 lttdgt lttdgtltinput type=text name=Name size=20 maxlength=10 value=lt echo $name gtgtlttdgtlttrgt lttrgtlttdgt電話 lttdgt lttdgtltinput type=text name=Tel size=20 maxlength=20 value=lt echo $tel gtgtlttdgtlttrgt lttrgtlttd colspan=2 align=centergt ltinput type=submit value=更新連絡人gtlttdgtlttrgt lttablegt ltformgt ltbrgtlta href=indexhtmlgt通訊錄ltagt | lta href=addphpgt新增連絡人ltagt | lta href=searchphpgt搜尋通訊錄ltagt lt break gt ltbodygt lthtmlgt

58

52 任務二Web Base群組軟體 ( twig )

順利完成Web Base客戶通訊錄程式測試一段時間後「Apache + MySQL + PHP」架構的穩定與快速巳深得老闆與公司所有同事的認同隨著公司業績蒸

蒸日上人員組織編罝愈來愈龐大跨部門的會議愈來愈多業務員每日排滿拜

訪客戶的行程跟客戶的 Email的往來也愈來愈頻繁 愈來愈多部門的同事希望公司能建置一套群組軟體提供 web mail可讓業

務人員方便收發 mail還有連絡人議事日程待辦工作書簽等功能讓整個

公司運作及個人時間管理更有效率

老闆問小明對這些需求有什麼看法小明認為如果這些功能完全由程式部

門開發必定曠日費時而且耗費公司資源小明在網路尋找是否有提供這些功能

的Free Software皇天不負苦心人小明發現了TWIG (The Web Information Gateway) httptwigscrewdrivernet這個群組軟體它在 Web 上整合郵件新聞聯絡人議事日程工作序書簽等功能非常符合公司的需求 Step 1 下載 twig-277targz 下載網址 httptwigscrewdrivernetdownloadphp3

Step 2 解開 twig-277targz tar -xzvf twig-277targz

59

Step 3 執行安裝動作安裝到 varwwwhtmltwig 目錄 cd twig-277 twig-install varwwwhtmltwig

Step 4 建立 MySQL 資料庫(twig)及各資料表

cd setup mysql -u root -p1234 mysqlgt create database twig Query OK 1 row affected (001 sec) mysqlgt quit mysql -u root ndashp1234 twiglt twigtablemysql

Step 5 修改 configincphp3 參數設定 vi varwwwhtmltwigconfigconfigincphp3 $config[fromdomain] = opencom 網域 $config[language] = chinesebig5 中文訊息 $config[imap_port] = 143notls

60

Step 6 修改連結 MySQL 的帳號密碼 vi varwwwhtmltwigconfigdbconfigincphp3 $dbconfig[sqlusername] = root username $dbconfig[sqlpassword] = 1234 password

Step 7 其他設定檔

vi etchttpdconfhttpdconf 加入 AddType applicationx-httpd-php php3 在 DirectoryIndex最後加入 indexphp3 DirectoryIndex indexhtml indexhtmlvar indexphp3 在 AddDefaultCharset ISO-8859-1加上 AddDefaultCharset ISO-8859-1

vi etcphpini register_globals = On service httpd restart Step 8 sendmail 設定 vi etcmailsendmailcf在 264 行前面加上並重新啟動 sendmail「service snedmail restart」 262 SMTP daemon options 263 264 O DaemonPortOptions=Port=smtpAddr=127001 Name=MTA 265 266 SMTP client options 267 O ClientPortOptions=Family=inet Address=00

61

Step 9 檢查設定有無錯誤 http主機名稱twigtestphp3

62

Step 10 登入 twig ( http主機名稱twig)

63

第六章 維護及更新程序

61 日常維護

系統管理員最好定期以 root 身份登入看看信件在 RedHat Linux 中有一支 logwatch 程式會定時去分析 log file如果發現異常便會發信給 root除此之外筆者建議讀者平時就檢查 MySQL log file ( varlogmysqldlog)是否有異常情形

62 更新程序

讀者可至httprpmfindnet 尋找MySQL相關套件至於升級的相關步驟請參

考Linux OS SOP 第 54節

63 備份重要檔案

預設 MySQL 的 DB 檔案是存在 varlibmysql 內以 DB名稱為目錄目錄

內就是該 DB 的所有資料通常得定期備份還有 MySQL的設定檔 etcmycnf也別忘了一起備份

64 離線備份與還原

641 離線備份

預設 MySQL 的 DB 檔案是存在 varlibmysql 內以 DB 名稱為目錄目錄內

就是該 DB 的所有資料像 CRM 這個 DB就是存在 varlibmysqlCRM 內在備份前因為怕資料尚未完全寫入磁碟而且 MySQL 會 Lock 在使用的 DB 檔案所以應該是要先把 MySQL 先 Shutdown 一下整個備份的程序可以下像下面的指令去完成 cd varlibmysql

64

service mysqld stop tar cvfz CRM_db_20030905tgz CRM service mysqld start 對這樣就可以了 不過要注意的是怕 DB 內每個 Tables 間的資料有關關

聯性所以最好是把整個 DB 一次備起來單獨只備哪個 Tables 的檔案以後回存時怕會有資料關聯不一致的問題

642 離線還原

DB 發生錯誤而要回存時其實也不難先找出最近一次完整正常的備份先把現在錯誤的網頁或 DB 先更名或 tar 起來再把好的備份給解開回原來目錄位

置就行了需要注意的是 MySQL 服務最好也是要先停止回存完成後再啟動服務回存 DB 的整個程序可能像下面 cd varlibmysql service mysqldstop mv CRM CRM_OLD tar xvfz CRM_db_20030905tg service mysqld start

65 線上備份與還原

651 線上備份

使用像上面的檔案方式備份是個不錯的方法它最少可以保持該主機某個時間點的完整檔案備份但還是有一些問題需要考慮到有些主機就不只建立一個 DB 而已總不能為了備份某個 DB 而把整個 MySQL 服務停止備份檔案的方式回存在原主機上一定適用但假如 MySQL 版本升級或是在那天該網頁空間需遷機移機到別的主機時那就沒人敢保證備出來的資料檔可以用所以我們可以考慮另一種備份的方式是使用 MySQL 本身提供的功能 MySQL Data Dump指令是 mysqldump

65

使用 MySQL 的 Dump 功能可以把 DB 的結構資料或結構加資料 Dump 成文字檔 mysqldump 指令提供的彈性很大你可以選擇把整個 DB Dump 成一個檔或是每個 Table 為一個檔甚至是把結構檔和資料分開儲存都

可以 mysqladmin -uroot -p flush-logs mysqldump CRM -uroot -p --opt gt CRM_20030905sql (CRM 是 DB 名稱 opt 是一個使用完整 Dump 參數) 假如只是要單獨 Dump 某個 Table 時只要在上面的指令後轉出符號 gt 前加個 Table 名稱就可以如只要 phpbb2_users 這個 Table 的 Dump 時只要下 mysqldump CRM -uroot -p --opt CUSTOMER gt CRM_CUSTOMER_20030905sql

652 線上還原

若要回存整個資料庫只需將壓縮的備份檔還原成 Dump 的檔案再用下面的指令回存 mysql CRM -uroot -p lt CRM_20030905sql 這邊需注意的是若建立備份時是以--opt或--add-drop-table為參數時回存的 動作是先將舊的 Table 先刪除重建 Table 的結構後再把 Data 匯入所以回存後所有的資料會回到你當時備份那個時間點因此在回存資料時可以考慮把現有錯誤或不完整的 DB 先備份一份下來以備不時之需或是拿來比對錯誤的地

方在那裡當然你也可以把資料回存到另一個測試用的 DB 內只要把上面指令

的 DB 名稱改成你的測試用 DB 名稱即可 使用這種回存方式 MySQL 服務不需停止也不會動到其他正在使用的 DB 在一些提供 MySQL 服務的虛擬主機可用這種方式作你自己的 DB 備份及回存

66

另外假如你是系統重建或是移機時切需在新的 MySQL 內新建一個空白 DB 後才行作回存的工作你可以用下面的指令建立 mysql -uroot -p -e CREATE DATABASE CRM (上面的 CRM是你要新建的 DB 名稱) 另一種作法先用 mysql 指令進入 mysql client console 然後再用 CREATE DATABASE CRM 這樣就行了記得尾端要加個 符號該行指令才會執行

67

第七章 問題與解答

Q1RedHat 90預附的 MySQL到底有無支援 Transcation機制 Ans MySQL自 32334a之後的 MySQL-Max版本加入 InnoDB的資料庫類型透過

InnoDBMySQL同樣可以進行 COMMIT與 ROLLRACK的動作RedHat 90預附的 MySQL為 32354a-11巳支援 InnoDB的資料庫類型不過必須做以

下設定 1cp usrsharedocmysql-server-32354amy-mediumcnf to etcmycnf 2 vi etcmycnf 將以下設定前的拿掉 innodb_data_home_dir = varlibmysql innodb_data_file_path = ibdata110Mautoextend innodb_log_group_home_dir = varlibmysql innodb_log_arch_dir = varlibmysql 3service mysqld restart 如此一來各位在建立Table時便可指定Table Type為 innodb ( ex create table with type=innodb ) Q2如何解決 php+mysql 許功蓋等字變亂的問題 Ans 方法一 【確定 MySQL 預設的字元集】 1 打開 WinMySQLadmin 管理畫面(在視窗右下角狀態列紅綠燈圖示中按滑鼠

右鍵點選 Show me 選項) 2 點選管理畫面中 [Variables] 標籤選項其中 character_set變數就是您預設

字元集的變數其預設是 latin1 字元集(我們要將他改回 big5)而 chatacters_set 變數則是 MySQL 可以支援哪些字元集 【修改預設字元集變數 character_set 】 1 請點選管理畫面中 [myini Setup] 標籤選項設定 myini 2 按一下 [Pick-up and Edit myini values] 按鈕以便編輯目前的 myini 設定 3 在 [mysqld] 設定區塊底下新增一行 default-character-set = big5 變數設

68

定 4 新增一個 [client] 設定區塊並加入第三步驟的變數設定(游標往下移到空白處新增兩行 [client] 和 default-character-set=big5) 5 按一下畫面左下方 [Save Modification] 按鈕儲存設定 6 重新啟動 MySQL 或 Windows 方法二 Server端注意事項 phpini 中有關的設定為(預設值) Magic quotes for incoming GETPOSTCookie data magic_quotes_gpc = On Use Sybase-style magic quotes (escape with instead of ) magic_quotes_sybase = Off Client端注意事項 1中文資料送進 mysql 前請用 addslashes($str) 處理 2處理後送進 mysql 時請用 括起來並在參數後留一個空白如 $sql = UPDATE ezf_table set tablename=$tname tableend=$endtime table inguser=$tguser tableingid=$tguserid tableallnumber=$tnumber tableloca l=$tablelocal tableanyone=$tableopen tabletext=$ttext WHERE tableid=$t ableid tablename=$tname c 取出時請用 stripslashes($str) Q3MySQL root 密碼忘了該怎麼辦 Ans 1先停掉 mysql etcrcdinitdmysql stop 2以--skip-grant-table 的參數啟動 mysql safe_mysql --skip-grant-tableamp 3 更改 root 密碼 mysql mysql mysqlgt UPDATE user SET password=password(newpassword)

69

WHERE user=root mysqlgt FLUSH PRIVILEGES mysqlgt exit 4停掉 mysql再重跑 mysqladmin -uroot -p shutdown Enter password 輸入新設定的密碼 etcrcdinitdmysql start

Q4NULL值問題

Ans

NULL值的概念是造成 SQL的新手的混淆的普遍原因他們經常認為 NULL是和一個空字符串的一樣的東西不是這樣的例如下列語句是完全不同的

mysqlgt INSERT INTO my_table (phone) VALUES (NULL)

mysqlgt INSERT INTO my_table (phone) VALUES ()

兩個語句把值插入到 phone 列但是第一個插入一個 NULL值而第二個插入一個空字符串第一個的含義可以認為是ldquo電話號碼不知道而第二個則可意味

著ldquo她沒有電話

在 SQL中NULL值在于任何其他值甚至 NULL值比較時總是假的(FALSE)包含 NULL的一個表達式總是產生一個 NULL值除非在包含在表達式中的運算符和函數的文檔中指出在下列例子所有的列返回 NULL

mysqlgt SELECT NULL1+NULLCONCAT(InvisibleNULL)

如果你想要尋找值是 NULL的列你不能使用=NULL測試下列語句不返回任

何行因為對任何表達式expr = NULL是假的

mysqlgt SELECT FROM my_table WHERE phone = NULL

要想尋找 NULL值你必須使用 IS NULL測試下例顯示如何找出 NULL電話號碼和空的電話號碼

70

mysqlgt SELECT FROM my_table WHERE phone IS NULL mysqlgt SELECT FROM my_table WHERE phone =

在 MySQL中就像很多其他的 SQL服務器一樣你不能索引可以有 NULL值的列你必須聲明這樣的列為 NOT NULL而且你不能插入 NULL到索引的

列中

當用 LOAD DATA INFILE 讀取數據時空列用更新如果你想要在一個列中有

NULL值你應該在文本文件中使用N字面上的詞NULL也可以在某些情形下使用

當使用 ORDER BY時首先呈現 NULL值如果你用 DESC以降序排序NULL值最後顯示當使用 GROUP BY時所有的 NULL值被認為是相等的

為了有助于NULL的處理你能使用 IS NULL和 IS NOT NULL運算符和 IFNULL()函數

對某些列類型NULL值被特殊地處理如果你將 NULL插入表的第一個TIMESTAMP 列則插入當前的日期和時間如果你將 NULL插入一個AUTO_INCREMENT 列則插入順序中的下一個數字

Q5如何將圖片存放於 MySQL中

Ans

Step 1建立資料庫 test

Step 2 建立表格 binary_data

CREATE TABLE binary_data (

id INT(4) NOT NULL AUTO_INCREMENT PRIMARY KEY

description CHAR(50)

bin_data LONGBLOB

filename CHAR(50)

filesize CHAR(50)

filetype CHAR(50)

71

)

Step 3 利用 storephp 寫入圖片

storephp 程式碼

ltHTMLgt ltHEADgtltTITLEgtStore binary data into SQL DatabaseltTITLEgtltHEADgt ltBODYgt lt code that will be executed if the form has been submitted

if ($submit) mysql_connect(localhostrootYOUR_PASSWORD) mysql_select_db(test) $data=Base64_Encode(fread(fopen($form_data r) filesize($form_data))) $result=MYSQL_QUERY(INSERT INTO binary_data (descriptionbin_datafilenamefilesizefiletype) VALUES ($form_description$data$form_data_name$form_data_size$form_data_type)) $id= mysql_insert_id() print ltpgtThis file has the following Database ID ltbgt$idltbgt MYSQL_CLOSE() else else show the form to submit new data

gt

ltform method=post action=ltphp echo $PHP_SELF gt enctype=multipartform-datagt File Descriptionltbrgt ltinput type=text name=form_description size=40gt ltINPUT TYPE=hidden name=MAX_FILE_SIZE value=4000000gt ltbrgtFile to uploadstore in databaseltbrgt ltinput type=file name=form_data size=40gt ltpgtltinput type=submit name=submit value=submitgt ltformgt lt

72

gt ltBODYgt ltHTMLgt

Step 3 利用 storephp 取出圖片

getdataphp 程式碼

lt Syntax getdataphp3id=ltidgt if($id) you may have to modify login information for your database server MYSQL_CONNECT(localhostrootYOUR_PASSWORD) mysql_select_db(test) $query = select bin_datafiletype from binary_data where id=$id $result = MYSQL_QUERY($query) $data = Base64_Decode(MYSQL_RESULT($result0bin_data)) $type = MYSQL_RESULT($result0filetype) Header( Content-type $type) echo $data gt

Q6MySQL裝好之後啟動時或是執行 mysqladmin會出現如下訊息 Cant connect to local MYSQL Server through Socket varlibmysqlmysqlsock或是

Cant connect to local MYSQL Server through Socket tmpmysqldsock

Ans 可能有下列幾個原因

1這個 mysqldsock 不見了被某人刪除了或是被一些系統自動執行程式給刪

了例如有些 cron任務便會設定定期刪除 tmp 裡的東西所以呢您只能修改

cron 裡的設定讓它不要清除 mysqldsock 2在啟動時也可以改變 mysqldsock的位置您在啟動 MySQL的時候可以加入此參數usrlocalmysqlbinsafe_mysqld --user=mysql --socket=其他路

徑socket amp 同時得去設定環境變數 MYSQL_UNIX_PORT的值以指定新的

73

路徑 3若是您沒改 MYSQL_UNIX_PORT的值那麼您可以在執行指令的時候才打

例如mysqladmin --socket=其他路徑socket version Q7How to get the last insert id Ans CREATE TABLE product ( id INT(4) NOT NULL AUTO_INCREMENT PRIMARY KEY description VARCHAR(50) ) 1利用 SQL的話 mysqlgt insert into product(description) values(123) Query OK 1 row affected (000 sec) mysqlgt select last_insert_id() +------------------+ | last_insert_id() | +------------------+ +------------------+ 1 row in set (000 sec) ======================================== 2如果是 PHP的話 你可以用mysql_insert_id()取得該 id PHP example $result=MYSQL_QUERY(INSERT INTO product (description) VALUES ($description)) $id= mysql_insert_id() print This file has the following Database ID $id Q8如何將文字檔匯入資料庫 Ans $addr=homehttpdhtmlphpschool001txt $sql_select = load data infile $addr into table test fields terminated by t 解說 $sql_select = load data infile 文字檔名 into table 表格名 fields terminated by

74

t

(欄位分隔以 TAB鍵) 該文字檔須與資料表欄位格式相符 例如欄位有三個 則文字檔為每行一筆資料如下 欄 1資料ltTABgt欄 2資料ltTABgt欄 3資料 欄 1資料ltTABgt欄 2資料ltTABgt欄 3資料 欄 1資料ltTABgt欄 2資料ltTABgt欄 3資料 欄 1資料ltTABgtltTABgt欄 3資料

Q9如何撰寫 MySQL C API Ans Step 1利用文字編輯器撰寫以下程式碼 mysqlcc

include ltstdiohgt

include ltmysqlmysqlhgt

int main (int argc char argv[])

MYSQL mysql

MYSQL_RES res

MYSQL_ROW row

if (argc = 2)

fputs (Usage myc ltdatabasegt stderr)

return 1

if ((mysql_connect(ampmysqllocalhostrootYour_Password)))

fputs (Error connecting stderr)

abort()

75

if (mysql_select_db(ampmysqlargv[1]))

fputs (Error selecting database stderr)

abort()

if (mysql_query(ampmysqlSELECT FROM test_table))

fputs (Error processing query stderr)

abort()

if ((res = mysql_store_result(ampmysql)))

fputs (Error storing results stderr)

abort()

while((row = mysql_fetch_row(res)))

uint i = 0

for (i=0 i lt mysql_num_fields(res) i++)

printf(s row[i])

printf(n)

return 0

Step 2 Compile

gcc -Iusrlocalmysqlinclude -Lusrlocalmysqllibmysql mysqlcc ndashlm -lmysqlclient

(其中 include path與 library path取決於你的 MySQL安裝路徑)

76

如果執行時發生如下 error Run problemerror in loading shared libraries libmysqlclientsoX 將你的 MySQL library path(for exampleusrlocalmysqllibmysql) 加入etcldsoconf and run sbinldconfig -v Q9ASP + MySQL 範例程式 Ans Dim myconn As New ADODBConnection Dim myrs As New Recordset Dim mySQL As String Dim myrows As Long myconnOpen DSN=MyODBCsample mySQL = SELECT from user myrsSource = mySQL Set myrsActiveConnection = myconn myrsCursorLocation = adUseClient myrsOpen myrows = myrsRecordCount myrsClose myconnClose 可參考 httpwwwdwamnetmysqlasp_myodbcasp 有詳細的資料 Q10如何將 MySQL中的資料庫匯出成txt檔 Ans select from TableName into outfile textxls all result fields will seperate by tab

77

第八章 參考資料

英文部份 網址 1 httpwwwmysqlcom MySQL 網站有第一手有關 MySQL的資料 2 httpwwwmysqlcomdocenReplicationhtml 有關 MySQL Replication 的文件 3 httpwwwgeocitiescomsqlhomefaqstore_blobhtml 如何在 MySQL 存放 BLOB的資料 4httpwwwsapdborg 有關 SAP跟 MySQL相關合作的網站 書藉 1 Cooking with MySQL

Paul DuBois has selected sample recipes from the hundreds youll find in his book MySQL

Cookbook In this third and final series of excerpts showcasing these recipes learn how to

compute team standings how to calculate the differences between successive Dec 26

2002 2 Tips for Building Web Database Applications with PHP and MySQL by Hugh E Williams co-author of Web Database Applications with PHP amp MySQL 04042002

3 Managing and Using MySQL 2nd Edition By Tim King George Reese Randy Jay Yarger

4 MySQL Cookbook By Paul DuBoisPublisher OReillyPub Date October 2002

中文部份

78

1 httplinuxtncedutwtechdocmysqlmysql_docmanual_tochtml MySQL 中文手冊 2 httpchenshloxaedutwphpZ_1php PHP+MySQ程式研習設計網站 3 httplinuxtncedutwtechdocbanicdownhtml PHP 4 手冊 4 httpwwwtncedutwadmin_zonephp台南縣教育網網路中心有很多 Linux相關文件 5 httpdobtncedutw網站建置百寶箱有很多 PHP MySQL 相關範例程式 5 httpwwwdbworldcomtw資料庫專家電子雜誌介紹資料庫的重要觀念及名詞

79

附錄一 SQL Command 介紹

SQL (讀音ess-que-el) 是一種結構查詢語法SQL 使用於資料庫交流

傳遞相容於 ANSI (American National Standards Institute) 是一套標準的關聯

式資料庫語言 SQL 語言是執行更新或從資料系統獲取資料一般常見的關聯

資料庫系統都有提供 SQL 如 Oracle Sybase Microsoft SQL Server Access Ingres 等雖然大部份的資料庫都有提供 SQL 但也多提供了自已獨特的語

法造成了不相容的情形但標準基本的語法是相通的如Select Insert Update Delete Create and Drop 每一個系統都有支援

Table相關 Command

Create Table

關聯式資料庫包含有很多元件稱為資料表(tables) 把資料或訊息放在資

料表中 資料表是以不同的名稱做分別資料表由欄列所構成的二維陣列

欄包含欄位名資料型態 及其他可判斷的資訊列是由全部欄位構成一筆一

筆的紀錄 create table 語法用在建立一個新的資料表語法格式如下

create table tablename (column1 data type column2 data type column3 data type)

Format of create table if you were to use optional constraints

create table tablename (column1 data type [constraint] column2 data type [constraint] column3 data type [constraint]) [ ] = optional

Note You may have as many columns as youd like and the constraints are optional

80

Example

create table employee (first varchar(15) last varchar(20) age number(3) address varchar(30) city varchar(20) state varchar(20))

注意建立資料表格式要以括號把前後框住而最後以(分號)做結尾

欄位名不要超過 30個字元長而且不要使用 sql 的關鍵字(如 where select等)而在後面接是型態的宣告(如字串數字日期格式等)

資料型態是來描述欄位的方式如一個欄位Last_Name 是一個姓氏可以使用varchar (可變動長度字串) 資料型態

以下是幾個常見的資料庫型態 char(size) 固定長度字串最長為 255 位元 varchar(size) 變動長度字串最大字元數以 size 來指定 number(size) 數值格式可以是整數也可以是小數最大數字以 size 位數判

斷未指定小數位數由系統內定 date 日期格式 number(sized) 數值格式最大數字以 size 位數判斷d 為小數位數整數位

數為 size-d 位

有何限制當資料表被建立通常有一或數個欄位是要使用來做關聯的功

能 例如unique 限制(唯一值)兩筆記錄不可以相同的值 not null (非空值)該欄位一定要輸入資料不可是空的primary key (主鍵)是每一筆記錄識別的主要方式

Drop a table drop table 刪除資料表(其中的資料也會一併刪除)

drop table tablename

Example

81

drop table 和刪除全部資料是不同的刪除全部資料欄位名稱資訊等還會

存在但刪除資料表會把這一些也一併移除掉

如何查詢資料

Select 基本用法

select 語法是關連式資料庫最常用的部份可以取得你想要的資料這是一個

簡單的範例 select column1[column2etc] from tablename [where condition] [] = optional 在 select 之後所列欄位名則是要顯示的資料部份你可以一一列出各欄位

名或是以 (星號)來代表選擇全部的欄位 from 之後放資料表名稱 where 子句 (選項) 指定要過濾的條件符合者才會顯現 where 可使用的條件運算元 = 等於 gt 大於 lt 小於 gt= 大或等於 lt= 小或等於 ltgt 大相等 LIKE 相似 For example select first last city

82

from empinfo where first LIKE Er 以Er 為開頭的字串就符合要以單引號框住 Or you can specify select first last from empinfo where last LIKE s 最後一字為 S 就符合 select from empinfo where first = Eric 則表示 first name 一定要是 Eric 才可以 範例資料表empinfo 統計函數

MIN 傳回指定欄位最小值

MAX 傳回指定欄位最大值

SUM 傳回指定欄位總和

AVG 傳回指定欄位平均值

COUNT 傳回指定欄位的筆數

COUNT() 傳回資料庫中的總筆數

統計函數使用於資料表中的數值欄位配合 SELECT 語法使用 只用於總結特定單一欄位可以配合 GROUP BY 做篩選但也可以不使用 GROUP BY 語句For example

SELECT AVG(salary) FROM employee

83

傳回全部 salary 平均值

Another example

SELECT AVG(salary) FROM employee WHERE title = Programmer

傳回 salary 平均值條件為 employees 資料表中當 title 等於 Programmer

Example

SELECT Count() FROM employees

傳回 employees 資料表中紀錄總筆數

GROUP BY 語法 SELECT column1 SUM(column2) FROM list-of-tables GROUP BY column-list The GROUP BY 語句可以先以所列的欄位為條件分組排序在一起(可以多欄

位) example 要列出每一個 dept 中最高 salary 值 SELECT max(salary) dept FROM employee GROUP BY dept HAVING 語法

SELECT column1 SUM(column2) FROM list-of-tables GROUP BY column-list HAVING condition

HAVING 子句是 GROUP BY 的一部份用來過濾在 GROUP BY 所選出的資料功能如同 select 命令中 where 條件式一樣只是 HAVING 必需配合 GROUP BY 使用

我們以例子來說明我們要取得每一公司名及每一公司的薪水平均值輸入如下

84

SELECT dept avg(salary) FROM employee GROUP BY dept

但如果我們只列出薪資平均值超過 20000元的公司資料

SELECT dept avg(salary) FROM employee GROUP BY dept HAVING avg(salary) gt 20000

ORDER BY子句語法

SELECT column1 SUM(column2) FROM list-of-tables ORDER BY column-list [ASC | DESC]

[ ] =選項

ORDER BY是一個選項子句當你以排序方式來顯示資料(正向由小到大反向由大到小)以指定的欄位資料做排序

ASC = 正向- 預設值 DESC = 反向排序

For example

SELECT employee_id dept name age salary FROM employee_info WHERE dept = Sales ORDER BY salary

以上列出公司代號公司名銷售員人名年紀及薪資而條件是公司名為 Sales 顯示順序以薪資多少排序(由小到大為預設值)

如果要以多個欄位做排序要以逗號做分隔如下

SELECT employee_id dept name age salary FROM employee_info WHERE dept = Sales ORDER BY salary age DESC

85

結合條件及布林運算 SELECT column1 SUM(column2) FROM list-of-tables WHERE condition1 AND condition2 AND運算可以結兩個或以上的條件放在 WHERE子句中 兩者都要為真才

會顯示該筆記錄 OR 運算可以結兩個或以上敘述放在 WHERE子句中只要其中一個為直就

會顯示該筆記錄 For example SELECT employeeid firstname lastname title salary FROM employee_info WHERE salary gt= 5000000 AND title = Programmer 必需要薪資大於等於 50000而且職稱為 Programmer同時符合才會顯示該筆資料 以下以括號括住雖然不是必需的但如此比較容易讀 SELECT employeeid firstname lastname title salary FROM employee_info WHERE (salary gt= 5000000) AND (title = Programmer) 另外範例 SELECT firstname lastname title salary FROM employee_info WHERE (title = Sales) OR (title = Programmer) 條件為只要是 Sales 或 Programmer 職稱的就會被列出 IN and BETWEEN 子句

SELECT column1 SUM(column2) FROM list-of-tables WHERE column3 IN (list-of-values) SELECT column1 SUM(column2) FROM list-of-tables WHERE column3 BETWEEN value1 AND value2 IN 子句使用在列舉項目的使用上也就是分別測試是否符合所列的值 For example

86

SELECT employeeid lastname salary FROM employee_info WHERE lastname IN (Hernandez Jones Roberts Ruiz) 條件為姓氏(astname)要符合 Hernandez Jones Roberts or Ruiz 其中一個才會被傳回 IN運算元也可以使用 OR 的語法來取代如下結果相同 SELECT employeeid lastname salary FROM employee_info WHERE lastname = Hernandez OR lastname = Jones OR lastname = Roberts OR lastname = Ruiz 但使用 IN 句子比較短也比較易懂 你也可以使用 NOT IN 來去掉不要的記錄 BETWEEN 運算元使用在判斷是否存在兩個數值之間 For example SELECT employeeid age lastname salary FROM employee_info WHERE age BETWEEN 30 AND 40 傳回年紀 30歲到 40歲之間的資料(含 30及 40歲者) 相同的也可以使用以下語法來達到相同的結果 SELECT employeeid age lastname salary FROM employee_info WHERE age gt= 30 AND age lt= 40 你也可使用 NOT BETWEEN 來濾掉中間值的資料 數學運算 標準 ANSI SQL-92 提供以下運算

87

+ 加

- 減

餘數

餘數為除法後剩整數這不在標準的 ANSI SQL 中但大部份的資料庫都會支

援這運算元以下列出有用的函數雖不在 ANSI SQL-92 提供但一般資料庫

也會支援他們

ABS(x) 傳回 x 絕對值

SIGN(x) returns the sign of input x as -1 0 or 1 (negative zero or positive respectively)

MOD(xy) 餘數 - returns the integer remainder of x divided by y (同 xy)

FLOOR(x) 傳回小或等於 x 的最大整數值

CEILING(x) or CEIL(x)

傳回大或等於 x 的最小整數值

POWER(xy) x的 y 次方

ROUND(x) 把 x 四捨五入為整數

ROUND(xd) 四捨五入取到小數 d 位

SQRT(x) x 開平方

For example SELECT round(salary) firstname FROM employee_info 傳回薪資取到整數位

如何新增資料

insert 加入一筆新紀錄到資料表中 insert into tablename (first_columnlast_column) values (first_valuelast_value) [] = optional Example insert into employee

88

(first last age address city state) values (Luke Duke 45 2130 Boars Nest Hazard Co Georgia) Note 字串要以單引號住如string 數字框住也無妨 insert into 後面接資料表名稱再接以括號括住的欄位名在 values 後括號分別對映各欄位的值 以上的例子新增了一筆名(first) 為 Luke而住所(state) 為 Georgia 的資料

如何刪除資料

delete 可以刪除單筆或多筆紀錄 delete from tablename where columnname OPERATOR value [and|or column OPERATOR value] [ ] = optional Examples delete from employee Note 如果你沒有指定 where 子句那麼全部的紀錄都會被刪除 delete from employee where lastname = May delete from employee where firstname = Mike or firstname = Eric delete from 接著資料表名 再接著是條件式判斷沒有條件式則全部紀錄會

被刪除

如何更新資料

update 用來更新你所指定的記錄要和 WHERE 配合小心使用 語法 update tablename set columnname = newvalue[nextcolumn = newvalue2] where columnname OPERATOR value [and|or column OPERATOR value] [] = optional Examples

89

update phone_book set area_code = 623 where prefix = 979 update phone_book set last_name = Smith prefix=555 suffix=9292 where last_name = Jones update employee set age = age+1 where first_name=Mary and last_name=Williams

90

附錄二Replication

測試環境

RedHat 90 + MySQL 32358 MySQL資料庫路徑 varlibmysql MySQL設定檔 etcmycnf Master IP 1921680100 Slave IP 1921680200 請至下列網址下載最新MySQL 32358套件並利用rpm ndashUvh 更新 httpupdatesredhatcom9enosi386

圖 最新 MySQL 套件

測試架構圖

91

1921680100

1921680200Master Server

erveSlave S r

圖 測試架構圖

測試步驟

Master server 部份 Step1 確認 MasterSlave機器上所裝的 MySQL版本能進行

replication( 32329 or higher ) Step2 在 Master MySQL上開放一個帳號給 Slave mysql ndashu root ndashp mysqlgtGRANT FILE ON TO repl1921680200 IDENTIFIED BY lsquoabc123rsquo mysqlgtq 上面是 Master開放一個帳號 repl密碼 abc123給 IP1921680200有檔案處理

的權限 Step3 shutdown MySQL on the Master mysqladmin ndashu root ndashp shutdown Step4 備份 Master所有資料庫 tar ndashcvf tmpmysql-snapshottar varlibmysql 注意tar的時候MySQL是要在 stop情況下 在mysql (wwwmysqlcom) 網站的FAQ有不用shutdown的方法

92

Step5 在 master機器上修改etcmycnf 在[mysqld]區段內加入參數 log-bin server-id=這邊設定 server-id=1 sql-bin-update-same binlog-do-db=CRM只針對 CRM資料庫做紀錄 Step6 Restart MySQL on the master service mysqld start 此時因為有加入 log-bin 參數因此開始有 index產生了在varlibmysql目錄下

有index檔案紀錄資料庫的異動 log Slave server 部份 Step1 在 slave設定etcmycnf 在[mysqld]區段加入 master-host= master-user= master-password= master-port= server-id= 這邊設定 master-host=1921680100 master-user=repl master-password=abc123 master-port=3306 server-id=2 master-connect-retry=60預設重試間隔 60秒 replicate-do-db=CRM告訴 slave只做 CRM資料庫的更新 log-slave-updates Step2 將 master上的 mysql-snapshottar copy到 slave上 用 ftp傳到 slave的tmp Step3 解壓縮 Master資料庫至 Slave Server上 cd varlib tar xvf tmpmysql-snapshottar chown ndashR mysqlmysql mysql

93

chmod ndashR 770 mysql (視情況) Step4 Restart MySQL on the slave server 這時在varlibmysql目錄會出現 masterinfo此檔案紀錄了 Master MySQL server的資訊

狀況測試

One-way replication

1921680100

1921680200Master Server

erveSlave S r

圖 One-way replication架構圖 Step1 Master跟 Slave網路及服務都正常情況下由 Master端異動資料後 到 Slave端瀏覽資料檢視是否有進行 replication Step2 模擬 Slave Server 當機 可用在於 slave真的當機或是 Slave 不一定需要一直跟 master connect將Slave MySQL server shutdown由 Master端異動資料到 slave端瀏覽此時Slave應該沒有被 replication 更新然後再將 Slave端 MySQL server start起來

預設 60秒後 Slave會嘗試跟 Master要求進行 replication再去 Slave端檢視是否有更新資料

94

Step3 模擬 Master當機因為是設定 One-way replication一旦 Master Server Slave端沒有 Master的 source可以 download Two-way replication 基於 Master當機狀況於是發展雙向 Replication即 1921680100 ( Host A ) 1921680200 ( Host B )都分別擔任 MasterSlave身分

1921680100

1921680200er

Server B MasterSlave Server

Server A MasterSlave Serv

圖 Two-way replication架構圖 以下是針對兩台 MySQL伺服器進行雙向 Replication Step1觀念同單向 replication只是改成 Master也有 Slave身分 Slave也有Master的身分先分別在 Server AServer B 都去 grant一個進行 replication的身分 [A]mysqlgtGRANT FILE ON TO repl1921680200 IDENTIFIED BY lsquoabc123rsquo [B]mysqlgt GRANT FILE ON TO repl1921680100 IDENTIFIED BY lsquoabc123rsquo Step2做完單向 replication後stop Server Aserver B MySQL service此時 AB資料是一樣的

95

修改etcmycnf設定 範例 Server A [mysqld] datadir=varlibmysql socket=varlibmysqlmysqlsock server-id=1 log-bin sql-bin-update-same binlog-do-db=CRM master-host=1921680200 master-user=repl master-password=abc123 log-slave-updates master-connect-retry=60 replicate-do-db=CRM Server B [mysqld] datadir=varlibmysql socket=varlibmysqlmysqlsock server-id=2 log-bin sql-bin-update-same binlog-do-db=CRM master-host=1921680100 master-user=repl master-password=abc123 log-slave-updates master-connect-retry=60 replicate-do-db=CRM 分別 start Server AServer B MySQL後此時雙方都是 MasterSlave身分一旦哪一方資料異動就會通知對方來 replication-若 replication失效則必須將Server AServer B的masterinfo及index00x 都砍掉然後分別 restart MySQL server進行測試檢視成果 實務上通常如果需要做Two-way replication通常會搭配Virtual Server使用

96

在前端架設一台Virtual Server不過此部份不在此份SOP討論範圍內有興趣

的讀者可參考 httpwwwlinuxvirtualserverorg 網站

1921680100 1921680200

Host A MasterSlave Server

Host B MasterSlave Server

Virtual Host

圖 Virtual Server + Two-way replication 架構圖

97

圖 High Availability Linux Virtual Server架構圖

98

  • COSA-SOP-03-006
  • 第一章 簡介
    • 11適用對象 (Audience)
    • 12 MySQL本身
    • 13 MySQL 40版跟50版重大的改進功能
    • 14 各家資料庫軟體比較
      • 第二章 前置需求
      • 第三章 安裝
        • 31 MySQL安裝
        • 32 phpMyAdmin安裝
        • 33 升級及注意事項
          • 第四章 MySQL管理
            • 41 Webmin 管理介面
            • 42 phpMyAdmin 的操作介面
            • 43管理指令介紹
              • 431 利用mysqladmin設定root的密碼
                  • 第五章 實用範例
                    • 51 任務一Web Base客戶通訊錄
                    • 52 任務二Web Base群組軟體 ( twig )
                      • 第六章 維護及更新程序
                        • 61 日常維護
                        • 62 更新程序
                        • 63 備份重要檔案
                        • 64 離線備份與還原
                        • 65 線上備份與還原
                          • 第七章 問題與解答
                          • 第八章 參考資料
                          • 附錄一 SQL Command 介紹
                          • 附錄二Replication
Page 32: DataBase Server Standard Operation Procedureebooks.lib.ntu.edu.tw/1_file/oss/63/93doc4-5.pdf · 業務的公司帶來了不少壓力,譬如微軟,甲骨文 ... 外的錢用在第三方的資料庫產品上,譬如就可以不用再購買甲骨文公司

圖 4-7 設定欄位數目

Step 3設定表格欄位屬性

圖 3-8 設定表格欄位屬性

Step 4建立表格資料

32

圖 4-9 建立表格資料

圖 4-10 檢視資料

33

圖 4-11 新增資料

圖 4-12

34

圖 4-13

413 使用者管理

接下來我們要利用Webmin 來建立資料庫使用者並給予某些權限 Step1建立使用者

35

圖 4-14 選擇使用者權限

圖 4-15

36

Step2 賦予權限

圖 4-16

Step3 權限列表

37

圖 4-17

38

42 phpMyAdmin 的操作介面

421建立資料庫

Step 填入資料庫名稱並按「建立」

圖 4-18建立資料庫

422 建立資料表

Step1 填入資料表名稱並指定欄位數量 執行

39

圖 4-19填入資料表名稱並指定欄位數量

Step2 設定欄位屬性

圖 4-20設定欄位屬性

40

Step3 phpMyAdmin會產生相關的 SQL Command

圖 4-21 資料表結構及相關 SQL Command

Step4新增 Record

41

圖 4-22

圖 4-23

42

圖 4-24

圖 4-25

43

423使用者管理

Step1建立使用者

圖 4-26

44

圖 4-27

Step2 給予權限

圖 4-28

Step3權限列表

45

圖 4-29

43管理指令介紹

431 利用 mysqladmin設定 root的密碼

當您在Windows 或 Linux 中安裝好 MySQL後系統會自動幫您建立兩個

帳分別是 root 和 匿名者MySQL的 root 跟 Linux 最高權限使用者 root無關MySQL的 root使用者相當於 MS SQL 中的 sa 帳號擁有最高的 Database管理權限但系統預設 MySQL的 root 是不需要密碼所以通常我們一安裝

MySQL後首要任務便是修改 root的密碼 我們可以利用 mysqladmin工具或是直接修改 MySQL內部資料庫的使用者資

料 mysqladmin ndashu root ndashh cosaexamplecom password lsquo1234rsquo

46

-u 表示使用者帳號root 為 MySQL預設的管理帳號

-h 表示 MySQL主機的主機名稱也可使用 IP Address password 表示使用者的密碼因為字串請使用單引號將密碼括起來 密碼設定完成之後還是可以利用 mysqladmin修改密碼但是你必須提供目前的密碼

432 連線 MySQL

mysql -uroot -p密碼 (-p和密碼之間不能有空白) 或 mysql -uroot -p (此方式會在進入後要求密碼) [rootossc phpMyAdmin] mysql -u root -p1234

Welcome to the MySQL monitor Commands end with or g

Your MySQL connection id is 25 to server version 32354

Type help or h for help Type c to clear the buffer

mysqlgt show databases

+----------+

| Database |

+----------+

| mysql |

| test |

+----------+

2 rows in set (000 sec)

mysqlgt exit

Bye

[rootossc phpMyAdmin]

433 建立資料庫

可利用 mysqladmin指令建立 CONTACT資料庫 mysqladmin -u root -p1234 create CONTACT

47

或是利用 mysql指令 [rootossc bluepage] mysql -u root -p1234 Welcome to the MySQL monitor Commands end with or g Your MySQL connection id is 1057 to server version 32354 Type help or h for help Type c to clear the buffer mysqlgt create database CONTACT Query OK 1 row affected (000 sec) mysqlgt show databases +----------+ | Database | +----------+ | CONTACT | | address | | hello | | mysql | | nuke | | test | +----------+ 6 rows in set (000 sec) mysqlgt exit

434 建立資料表

編寫 adresssql內容如下 -- Table structure for table address CREATE TABLE address ( id int(11) NOT NULL auto_increment name varchar(20) NOT NULL default tel varchar(15) NOT NULL default PRIMARY KEY (id) ) TYPE=MyISAM

48

-- Dumping data for table address INSERT INTO address VALUES (1林小明0800016888) INSERT INTO address VALUES (2黃大雄0800016888) INSERT INTO address VALUES (3劉小芬0800024365) 然後執行此 sql script mysql -u root -p1234 CONTACT lt addresssql 或是利 mysql command [rootossc bluepage] mysql -u root -p1234 Welcome to the MySQL monitor Commands end with or g Your MySQL connection id is 1090 to server version 32354 Type help or h for help Type c to clear the buffer mysqlgt use CONTACT Database changed Database changed mysqlgt CREATE TABLE address ( -gt id int(11) NOT NULL auto_increment -gt name varchar(20) NOT NULL default -gt tel varchar(15) NOT NULL default -gt PRIMARY KEY (id) -gt ) TYPE=MyISAM Query OK 0 rows affected (000 sec) mysqlgt INSERT INTO address VALUES (1林小明0800016888) Query OK 1 row affected (000 sec) mysqlgt INSERT INTO address VALUES (2黃大雄0800016888) Query OK 1 row affected (000 sec) mysqlgt INSERT INTO address VALUES (3劉小芬0800024365) Query OK 1 row affected (000 sec) mysqlgt exit Bye

49

第五章 實用範例

51 任務一Web Base客戶通訊錄

任職於開放科技公司的林小明前些日子在最符合成本效益的條件下快

速地完成公司網站的建置老闆因此對小明讚譽有加最近因為公司存放客戶資

料的 SQL Server主機屢遭病毒攻擊加上作業系統本身的問題當機次數頻繁

老闆希望能儘快把公司的客戶通訊錄程式移轉到較穩定的環境上因為此客戶通

訊錄程式最主要給內部人員使用所以介面美觀並不特別要求只求穩定且能快

速得到查詢結果老闆希望在短時間先看到程式的雛型並鍵入資料對其效率

及穩定性進行測試因為上次小明表現突出所以這次不可能的任務自然又落到

小明身上 小明想來想去既然要快速又穩定他而且又不希望所有人都得安裝 Client

程式於是小明決定)捨棄他的舊愛「Delphi+MS SQL」投向新歡「Apache + MySQL + PHP」利用此架構來設計一個簡單實用的Web Base客戶通訊錄程式

511 Web Base客戶通訊錄架構

此程式需要建立 CONTACT的資料庫並建立 adress Tables其結構如下表建立步驟請參考第三章 欄位名稱 資料型態 長度 說明 id INT (自動編號) 連絡人編號 name varchar文字 20 連絡人姓名 tel Varchar文字 15 連絡人電話 Web Base通訊錄共有下列幾個檔案功能如下表

檔案名稱 說明 Indexhtml Web Base通訊錄首頁 addphp 新增連絡人的 php程式 searchphp 尋找連絡人的 php程式 editphp 具有更新及刪除功能的 php程式

50

我們將這些檔案放至varwwwhtmlbluepage (預設無 bluepage目錄)

512 Web Base通訊錄測試

httpwwwopencombluepage 新增資料

圖 5-1 新增連絡人

圖 5-2 填入資料

51

圖 5-3 新增成功

搜尋及異動資料

圖 5-4 搜尋通訊錄

52

圖 5-5 編輯資料

圖 5-6 更新資料

513 程式內容及說明

lt-- 程式範例indexhtml--gt lthtmlgt ltheadgtlttitlegt通訊錄lttitlegtltheadgt ltbodygt ltcentergt

53

lth2gt通訊錄lth2gtlthrgt lta href=indexhtmlgt通訊錄ltagt | lta href=addphpgt新增連絡人ltagt | lta href=searchphpgt搜尋通訊錄ltagt ltcentergt ltbodygt lthtmlgt lt-- 程式範例addphp --gt lthtmlgt ltheadgtlttitlegt新增連絡人lttitlegtltheadgt ltbodygt ltcentergtlth2gt新增連絡人lth2gtltcentergtlthrgt lt 取得欄位資料 if (isset($_POST[Name]) ampamp isset($_POST[Tel]) ) $name = $_POST[Name] $tel = $_POST[Tel] 檢查是否有輸入欄位資料 if ($name = ampamp $tel = ) 建立 SQL字串 $sql = INSERT INTO address (name tel) values( $sql= $name $tel) 建立 MySQL 連結 $link = mysql_connect(localhostroot1234) 選擇資料庫 mysql_select_db(CONTACT) 執行 SQL指令 mysql_query($sql) mysql_close($link) echo ltfont color=redgt新增連絡人成功ltfontgtltbrgt gt ltform action=addphp method=postgt lttable border=0 width=300gt lttrgtlttdgt姓名 lttdgt

54

lttdgtltinput type=text name=Name size=20 maxlength=10gtlttdgtlttrgt lttrgtlttdgt電話 lttdgt lttdgtltinput type=text name=Tel size=20 maxlength=20gtlttdgtlttrgt lttrgtlttd colspan=2 align=centergt ltinput type=submit value=新增連絡人gtlttdgtlttrgt lttablegt ltformgt ltbrgtlta href=indexhtmlgt通訊錄ltagt | lta href=addphpgt新增連絡人ltagt | lta href=searchphpgt搜尋通訊錄ltagt ltbodygt lthtmlgt

lt-- 程式範例searchphp --gt lthtmlgt ltheadgtlttitlegt搜尋通訊錄lttitlegtltheadgt ltbodygt ltcentergtlth2gt搜尋通訊錄lth2gtlthrgt lt if (isset($_POST[Search])) 建立資料庫連結並選定資料庫 $link = mysql_connect(localhostroot1234) mysql_select_db(CONTACT) 建立基本的 SQL字串 $sql = SELECT FROM address 檢查是否輸入姓名 if (chop($_POST[Name]) = ) $name = name LIKE $_POST[Name] else $name = 檢查是否輸入電話號碼 if (chop($_POST[Tel]) = ) $tel = tel LIKE $_POST[Tel] else $tel =

55

if條件組合 SQL字串 if (chop($name) = ampamp chop($tel) = ) $sql= WHERE $name AND $tel elseif (chop($name) = ) 只有姓名 $sql = WHERE $name elseif (chop($tel) = ) 只有電話號碼 $sql = WHERE $tel $sql= ORDER BY name 最後加上排序 $result = mysql_query($sql) 取得欄位數 $total_fields = mysql_num_fields($result) echo lttable border=1gt echo lttrgtlttdgt編號lttdgtlttdgt姓名lttdgtlttdgt電話lttdgtlttd colspan=2gt功能選項lttdgtlttrgt 表格顯示查詢結果 while ($rows = mysql_fetch_array($result MYSQL_NUM)) echo lttrgt for ($i = 0 $i lt $total_fields $i++) echo lttdgt$rows[$i]lttdgt echo lttdgtlta href=editphpaction=editampid= echo $rows[0]gtltbgt編輯ltbgtlttdgt echo lttdgtlta href=editphpaction=delampid= echo $rows[0]gtltbgt刪除ltbgtlttdgt echo lttrgt echo lttablegtlthrgt mysql_free_result($result) mysql_close($link) gt ltcentergt ltform action=searchphp method=postgt lttable border=0 width=450gt lttrgtlttdgt搜尋姓名 lttdgt lttdgtltinput type=text name=Name size=10 maxlength=20gtlttdgtlttrgt lttrgtlttdgt搜尋電話 lttdgt lttdgtltinput type=text name=Tel

56

size=20 maxlength=20gtlttdgtlttrgt lttrgtlttd colspan=2 align=centergt ltinput type=submit name=Search value=搜尋gtlttdgtlttrgt lttablegt ltformgt ltbrgtlta href=indexhtmlgt通訊錄ltagt | lta href=addphpgt新增連絡人ltagt | lta href=searchphpgt搜尋通訊錄ltagt ltbodygt lthtmlgt

lt ob_start() gt lt-- 程式範例editphp --gt lthtmlgt ltheadgtlttitlegt編輯通訊錄lttitlegtltheadgt ltbodygt lt 取得 URL 參數 $id = $_GET[id] $action = $_GET[action] 建立資料庫連結 $link = mysql_connect(localhostroot1234) mysql_select_db(CONTACT) 選擇資料庫 執行的操作 switch ($action) case update 更新 取得欄位資料 $name = $_POST[Name] $tel = $_POST[Tel] $sql = UPDATE address SET name=$name tel=$tel WHERE id=$id mysql_query($sql) 執行 SQL指令 mysql_close($link) header(Location searchphp) 轉向到 serachphp break case del 刪除 $sql = DELETE FROM address WHERE id=$id

57

mysql_query($sql) 執行 SQL指令 mysql_close($link) header(Location searchphp) 轉向到 serachphp break case edit 編輯 $sql = SELECT FROM address WHERE id=$id $result = mysql_query($sql) 執行 SQL指令 $row = mysql_fetch_row($result) 取回記錄 $name = $row[1] 取得欄位 name $tel = $row[2] 取得欄位 tel mysql_close($link) 顯示編輯表單 gt ltcentergtlth2gt更新通訊錄lth2gtltcentergtlthrgt ltform action=editphpaction=updateampid=lt echo $id gt method=postgt lttable border=0 width=300gt lttrgtlttdgt姓名 lttdgt lttdgtltinput type=text name=Name size=20 maxlength=10 value=lt echo $name gtgtlttdgtlttrgt lttrgtlttdgt電話 lttdgt lttdgtltinput type=text name=Tel size=20 maxlength=20 value=lt echo $tel gtgtlttdgtlttrgt lttrgtlttd colspan=2 align=centergt ltinput type=submit value=更新連絡人gtlttdgtlttrgt lttablegt ltformgt ltbrgtlta href=indexhtmlgt通訊錄ltagt | lta href=addphpgt新增連絡人ltagt | lta href=searchphpgt搜尋通訊錄ltagt lt break gt ltbodygt lthtmlgt

58

52 任務二Web Base群組軟體 ( twig )

順利完成Web Base客戶通訊錄程式測試一段時間後「Apache + MySQL + PHP」架構的穩定與快速巳深得老闆與公司所有同事的認同隨著公司業績蒸

蒸日上人員組織編罝愈來愈龐大跨部門的會議愈來愈多業務員每日排滿拜

訪客戶的行程跟客戶的 Email的往來也愈來愈頻繁 愈來愈多部門的同事希望公司能建置一套群組軟體提供 web mail可讓業

務人員方便收發 mail還有連絡人議事日程待辦工作書簽等功能讓整個

公司運作及個人時間管理更有效率

老闆問小明對這些需求有什麼看法小明認為如果這些功能完全由程式部

門開發必定曠日費時而且耗費公司資源小明在網路尋找是否有提供這些功能

的Free Software皇天不負苦心人小明發現了TWIG (The Web Information Gateway) httptwigscrewdrivernet這個群組軟體它在 Web 上整合郵件新聞聯絡人議事日程工作序書簽等功能非常符合公司的需求 Step 1 下載 twig-277targz 下載網址 httptwigscrewdrivernetdownloadphp3

Step 2 解開 twig-277targz tar -xzvf twig-277targz

59

Step 3 執行安裝動作安裝到 varwwwhtmltwig 目錄 cd twig-277 twig-install varwwwhtmltwig

Step 4 建立 MySQL 資料庫(twig)及各資料表

cd setup mysql -u root -p1234 mysqlgt create database twig Query OK 1 row affected (001 sec) mysqlgt quit mysql -u root ndashp1234 twiglt twigtablemysql

Step 5 修改 configincphp3 參數設定 vi varwwwhtmltwigconfigconfigincphp3 $config[fromdomain] = opencom 網域 $config[language] = chinesebig5 中文訊息 $config[imap_port] = 143notls

60

Step 6 修改連結 MySQL 的帳號密碼 vi varwwwhtmltwigconfigdbconfigincphp3 $dbconfig[sqlusername] = root username $dbconfig[sqlpassword] = 1234 password

Step 7 其他設定檔

vi etchttpdconfhttpdconf 加入 AddType applicationx-httpd-php php3 在 DirectoryIndex最後加入 indexphp3 DirectoryIndex indexhtml indexhtmlvar indexphp3 在 AddDefaultCharset ISO-8859-1加上 AddDefaultCharset ISO-8859-1

vi etcphpini register_globals = On service httpd restart Step 8 sendmail 設定 vi etcmailsendmailcf在 264 行前面加上並重新啟動 sendmail「service snedmail restart」 262 SMTP daemon options 263 264 O DaemonPortOptions=Port=smtpAddr=127001 Name=MTA 265 266 SMTP client options 267 O ClientPortOptions=Family=inet Address=00

61

Step 9 檢查設定有無錯誤 http主機名稱twigtestphp3

62

Step 10 登入 twig ( http主機名稱twig)

63

第六章 維護及更新程序

61 日常維護

系統管理員最好定期以 root 身份登入看看信件在 RedHat Linux 中有一支 logwatch 程式會定時去分析 log file如果發現異常便會發信給 root除此之外筆者建議讀者平時就檢查 MySQL log file ( varlogmysqldlog)是否有異常情形

62 更新程序

讀者可至httprpmfindnet 尋找MySQL相關套件至於升級的相關步驟請參

考Linux OS SOP 第 54節

63 備份重要檔案

預設 MySQL 的 DB 檔案是存在 varlibmysql 內以 DB名稱為目錄目錄

內就是該 DB 的所有資料通常得定期備份還有 MySQL的設定檔 etcmycnf也別忘了一起備份

64 離線備份與還原

641 離線備份

預設 MySQL 的 DB 檔案是存在 varlibmysql 內以 DB 名稱為目錄目錄內

就是該 DB 的所有資料像 CRM 這個 DB就是存在 varlibmysqlCRM 內在備份前因為怕資料尚未完全寫入磁碟而且 MySQL 會 Lock 在使用的 DB 檔案所以應該是要先把 MySQL 先 Shutdown 一下整個備份的程序可以下像下面的指令去完成 cd varlibmysql

64

service mysqld stop tar cvfz CRM_db_20030905tgz CRM service mysqld start 對這樣就可以了 不過要注意的是怕 DB 內每個 Tables 間的資料有關關

聯性所以最好是把整個 DB 一次備起來單獨只備哪個 Tables 的檔案以後回存時怕會有資料關聯不一致的問題

642 離線還原

DB 發生錯誤而要回存時其實也不難先找出最近一次完整正常的備份先把現在錯誤的網頁或 DB 先更名或 tar 起來再把好的備份給解開回原來目錄位

置就行了需要注意的是 MySQL 服務最好也是要先停止回存完成後再啟動服務回存 DB 的整個程序可能像下面 cd varlibmysql service mysqldstop mv CRM CRM_OLD tar xvfz CRM_db_20030905tg service mysqld start

65 線上備份與還原

651 線上備份

使用像上面的檔案方式備份是個不錯的方法它最少可以保持該主機某個時間點的完整檔案備份但還是有一些問題需要考慮到有些主機就不只建立一個 DB 而已總不能為了備份某個 DB 而把整個 MySQL 服務停止備份檔案的方式回存在原主機上一定適用但假如 MySQL 版本升級或是在那天該網頁空間需遷機移機到別的主機時那就沒人敢保證備出來的資料檔可以用所以我們可以考慮另一種備份的方式是使用 MySQL 本身提供的功能 MySQL Data Dump指令是 mysqldump

65

使用 MySQL 的 Dump 功能可以把 DB 的結構資料或結構加資料 Dump 成文字檔 mysqldump 指令提供的彈性很大你可以選擇把整個 DB Dump 成一個檔或是每個 Table 為一個檔甚至是把結構檔和資料分開儲存都

可以 mysqladmin -uroot -p flush-logs mysqldump CRM -uroot -p --opt gt CRM_20030905sql (CRM 是 DB 名稱 opt 是一個使用完整 Dump 參數) 假如只是要單獨 Dump 某個 Table 時只要在上面的指令後轉出符號 gt 前加個 Table 名稱就可以如只要 phpbb2_users 這個 Table 的 Dump 時只要下 mysqldump CRM -uroot -p --opt CUSTOMER gt CRM_CUSTOMER_20030905sql

652 線上還原

若要回存整個資料庫只需將壓縮的備份檔還原成 Dump 的檔案再用下面的指令回存 mysql CRM -uroot -p lt CRM_20030905sql 這邊需注意的是若建立備份時是以--opt或--add-drop-table為參數時回存的 動作是先將舊的 Table 先刪除重建 Table 的結構後再把 Data 匯入所以回存後所有的資料會回到你當時備份那個時間點因此在回存資料時可以考慮把現有錯誤或不完整的 DB 先備份一份下來以備不時之需或是拿來比對錯誤的地

方在那裡當然你也可以把資料回存到另一個測試用的 DB 內只要把上面指令

的 DB 名稱改成你的測試用 DB 名稱即可 使用這種回存方式 MySQL 服務不需停止也不會動到其他正在使用的 DB 在一些提供 MySQL 服務的虛擬主機可用這種方式作你自己的 DB 備份及回存

66

另外假如你是系統重建或是移機時切需在新的 MySQL 內新建一個空白 DB 後才行作回存的工作你可以用下面的指令建立 mysql -uroot -p -e CREATE DATABASE CRM (上面的 CRM是你要新建的 DB 名稱) 另一種作法先用 mysql 指令進入 mysql client console 然後再用 CREATE DATABASE CRM 這樣就行了記得尾端要加個 符號該行指令才會執行

67

第七章 問題與解答

Q1RedHat 90預附的 MySQL到底有無支援 Transcation機制 Ans MySQL自 32334a之後的 MySQL-Max版本加入 InnoDB的資料庫類型透過

InnoDBMySQL同樣可以進行 COMMIT與 ROLLRACK的動作RedHat 90預附的 MySQL為 32354a-11巳支援 InnoDB的資料庫類型不過必須做以

下設定 1cp usrsharedocmysql-server-32354amy-mediumcnf to etcmycnf 2 vi etcmycnf 將以下設定前的拿掉 innodb_data_home_dir = varlibmysql innodb_data_file_path = ibdata110Mautoextend innodb_log_group_home_dir = varlibmysql innodb_log_arch_dir = varlibmysql 3service mysqld restart 如此一來各位在建立Table時便可指定Table Type為 innodb ( ex create table with type=innodb ) Q2如何解決 php+mysql 許功蓋等字變亂的問題 Ans 方法一 【確定 MySQL 預設的字元集】 1 打開 WinMySQLadmin 管理畫面(在視窗右下角狀態列紅綠燈圖示中按滑鼠

右鍵點選 Show me 選項) 2 點選管理畫面中 [Variables] 標籤選項其中 character_set變數就是您預設

字元集的變數其預設是 latin1 字元集(我們要將他改回 big5)而 chatacters_set 變數則是 MySQL 可以支援哪些字元集 【修改預設字元集變數 character_set 】 1 請點選管理畫面中 [myini Setup] 標籤選項設定 myini 2 按一下 [Pick-up and Edit myini values] 按鈕以便編輯目前的 myini 設定 3 在 [mysqld] 設定區塊底下新增一行 default-character-set = big5 變數設

68

定 4 新增一個 [client] 設定區塊並加入第三步驟的變數設定(游標往下移到空白處新增兩行 [client] 和 default-character-set=big5) 5 按一下畫面左下方 [Save Modification] 按鈕儲存設定 6 重新啟動 MySQL 或 Windows 方法二 Server端注意事項 phpini 中有關的設定為(預設值) Magic quotes for incoming GETPOSTCookie data magic_quotes_gpc = On Use Sybase-style magic quotes (escape with instead of ) magic_quotes_sybase = Off Client端注意事項 1中文資料送進 mysql 前請用 addslashes($str) 處理 2處理後送進 mysql 時請用 括起來並在參數後留一個空白如 $sql = UPDATE ezf_table set tablename=$tname tableend=$endtime table inguser=$tguser tableingid=$tguserid tableallnumber=$tnumber tableloca l=$tablelocal tableanyone=$tableopen tabletext=$ttext WHERE tableid=$t ableid tablename=$tname c 取出時請用 stripslashes($str) Q3MySQL root 密碼忘了該怎麼辦 Ans 1先停掉 mysql etcrcdinitdmysql stop 2以--skip-grant-table 的參數啟動 mysql safe_mysql --skip-grant-tableamp 3 更改 root 密碼 mysql mysql mysqlgt UPDATE user SET password=password(newpassword)

69

WHERE user=root mysqlgt FLUSH PRIVILEGES mysqlgt exit 4停掉 mysql再重跑 mysqladmin -uroot -p shutdown Enter password 輸入新設定的密碼 etcrcdinitdmysql start

Q4NULL值問題

Ans

NULL值的概念是造成 SQL的新手的混淆的普遍原因他們經常認為 NULL是和一個空字符串的一樣的東西不是這樣的例如下列語句是完全不同的

mysqlgt INSERT INTO my_table (phone) VALUES (NULL)

mysqlgt INSERT INTO my_table (phone) VALUES ()

兩個語句把值插入到 phone 列但是第一個插入一個 NULL值而第二個插入一個空字符串第一個的含義可以認為是ldquo電話號碼不知道而第二個則可意味

著ldquo她沒有電話

在 SQL中NULL值在于任何其他值甚至 NULL值比較時總是假的(FALSE)包含 NULL的一個表達式總是產生一個 NULL值除非在包含在表達式中的運算符和函數的文檔中指出在下列例子所有的列返回 NULL

mysqlgt SELECT NULL1+NULLCONCAT(InvisibleNULL)

如果你想要尋找值是 NULL的列你不能使用=NULL測試下列語句不返回任

何行因為對任何表達式expr = NULL是假的

mysqlgt SELECT FROM my_table WHERE phone = NULL

要想尋找 NULL值你必須使用 IS NULL測試下例顯示如何找出 NULL電話號碼和空的電話號碼

70

mysqlgt SELECT FROM my_table WHERE phone IS NULL mysqlgt SELECT FROM my_table WHERE phone =

在 MySQL中就像很多其他的 SQL服務器一樣你不能索引可以有 NULL值的列你必須聲明這樣的列為 NOT NULL而且你不能插入 NULL到索引的

列中

當用 LOAD DATA INFILE 讀取數據時空列用更新如果你想要在一個列中有

NULL值你應該在文本文件中使用N字面上的詞NULL也可以在某些情形下使用

當使用 ORDER BY時首先呈現 NULL值如果你用 DESC以降序排序NULL值最後顯示當使用 GROUP BY時所有的 NULL值被認為是相等的

為了有助于NULL的處理你能使用 IS NULL和 IS NOT NULL運算符和 IFNULL()函數

對某些列類型NULL值被特殊地處理如果你將 NULL插入表的第一個TIMESTAMP 列則插入當前的日期和時間如果你將 NULL插入一個AUTO_INCREMENT 列則插入順序中的下一個數字

Q5如何將圖片存放於 MySQL中

Ans

Step 1建立資料庫 test

Step 2 建立表格 binary_data

CREATE TABLE binary_data (

id INT(4) NOT NULL AUTO_INCREMENT PRIMARY KEY

description CHAR(50)

bin_data LONGBLOB

filename CHAR(50)

filesize CHAR(50)

filetype CHAR(50)

71

)

Step 3 利用 storephp 寫入圖片

storephp 程式碼

ltHTMLgt ltHEADgtltTITLEgtStore binary data into SQL DatabaseltTITLEgtltHEADgt ltBODYgt lt code that will be executed if the form has been submitted

if ($submit) mysql_connect(localhostrootYOUR_PASSWORD) mysql_select_db(test) $data=Base64_Encode(fread(fopen($form_data r) filesize($form_data))) $result=MYSQL_QUERY(INSERT INTO binary_data (descriptionbin_datafilenamefilesizefiletype) VALUES ($form_description$data$form_data_name$form_data_size$form_data_type)) $id= mysql_insert_id() print ltpgtThis file has the following Database ID ltbgt$idltbgt MYSQL_CLOSE() else else show the form to submit new data

gt

ltform method=post action=ltphp echo $PHP_SELF gt enctype=multipartform-datagt File Descriptionltbrgt ltinput type=text name=form_description size=40gt ltINPUT TYPE=hidden name=MAX_FILE_SIZE value=4000000gt ltbrgtFile to uploadstore in databaseltbrgt ltinput type=file name=form_data size=40gt ltpgtltinput type=submit name=submit value=submitgt ltformgt lt

72

gt ltBODYgt ltHTMLgt

Step 3 利用 storephp 取出圖片

getdataphp 程式碼

lt Syntax getdataphp3id=ltidgt if($id) you may have to modify login information for your database server MYSQL_CONNECT(localhostrootYOUR_PASSWORD) mysql_select_db(test) $query = select bin_datafiletype from binary_data where id=$id $result = MYSQL_QUERY($query) $data = Base64_Decode(MYSQL_RESULT($result0bin_data)) $type = MYSQL_RESULT($result0filetype) Header( Content-type $type) echo $data gt

Q6MySQL裝好之後啟動時或是執行 mysqladmin會出現如下訊息 Cant connect to local MYSQL Server through Socket varlibmysqlmysqlsock或是

Cant connect to local MYSQL Server through Socket tmpmysqldsock

Ans 可能有下列幾個原因

1這個 mysqldsock 不見了被某人刪除了或是被一些系統自動執行程式給刪

了例如有些 cron任務便會設定定期刪除 tmp 裡的東西所以呢您只能修改

cron 裡的設定讓它不要清除 mysqldsock 2在啟動時也可以改變 mysqldsock的位置您在啟動 MySQL的時候可以加入此參數usrlocalmysqlbinsafe_mysqld --user=mysql --socket=其他路

徑socket amp 同時得去設定環境變數 MYSQL_UNIX_PORT的值以指定新的

73

路徑 3若是您沒改 MYSQL_UNIX_PORT的值那麼您可以在執行指令的時候才打

例如mysqladmin --socket=其他路徑socket version Q7How to get the last insert id Ans CREATE TABLE product ( id INT(4) NOT NULL AUTO_INCREMENT PRIMARY KEY description VARCHAR(50) ) 1利用 SQL的話 mysqlgt insert into product(description) values(123) Query OK 1 row affected (000 sec) mysqlgt select last_insert_id() +------------------+ | last_insert_id() | +------------------+ +------------------+ 1 row in set (000 sec) ======================================== 2如果是 PHP的話 你可以用mysql_insert_id()取得該 id PHP example $result=MYSQL_QUERY(INSERT INTO product (description) VALUES ($description)) $id= mysql_insert_id() print This file has the following Database ID $id Q8如何將文字檔匯入資料庫 Ans $addr=homehttpdhtmlphpschool001txt $sql_select = load data infile $addr into table test fields terminated by t 解說 $sql_select = load data infile 文字檔名 into table 表格名 fields terminated by

74

t

(欄位分隔以 TAB鍵) 該文字檔須與資料表欄位格式相符 例如欄位有三個 則文字檔為每行一筆資料如下 欄 1資料ltTABgt欄 2資料ltTABgt欄 3資料 欄 1資料ltTABgt欄 2資料ltTABgt欄 3資料 欄 1資料ltTABgt欄 2資料ltTABgt欄 3資料 欄 1資料ltTABgtltTABgt欄 3資料

Q9如何撰寫 MySQL C API Ans Step 1利用文字編輯器撰寫以下程式碼 mysqlcc

include ltstdiohgt

include ltmysqlmysqlhgt

int main (int argc char argv[])

MYSQL mysql

MYSQL_RES res

MYSQL_ROW row

if (argc = 2)

fputs (Usage myc ltdatabasegt stderr)

return 1

if ((mysql_connect(ampmysqllocalhostrootYour_Password)))

fputs (Error connecting stderr)

abort()

75

if (mysql_select_db(ampmysqlargv[1]))

fputs (Error selecting database stderr)

abort()

if (mysql_query(ampmysqlSELECT FROM test_table))

fputs (Error processing query stderr)

abort()

if ((res = mysql_store_result(ampmysql)))

fputs (Error storing results stderr)

abort()

while((row = mysql_fetch_row(res)))

uint i = 0

for (i=0 i lt mysql_num_fields(res) i++)

printf(s row[i])

printf(n)

return 0

Step 2 Compile

gcc -Iusrlocalmysqlinclude -Lusrlocalmysqllibmysql mysqlcc ndashlm -lmysqlclient

(其中 include path與 library path取決於你的 MySQL安裝路徑)

76

如果執行時發生如下 error Run problemerror in loading shared libraries libmysqlclientsoX 將你的 MySQL library path(for exampleusrlocalmysqllibmysql) 加入etcldsoconf and run sbinldconfig -v Q9ASP + MySQL 範例程式 Ans Dim myconn As New ADODBConnection Dim myrs As New Recordset Dim mySQL As String Dim myrows As Long myconnOpen DSN=MyODBCsample mySQL = SELECT from user myrsSource = mySQL Set myrsActiveConnection = myconn myrsCursorLocation = adUseClient myrsOpen myrows = myrsRecordCount myrsClose myconnClose 可參考 httpwwwdwamnetmysqlasp_myodbcasp 有詳細的資料 Q10如何將 MySQL中的資料庫匯出成txt檔 Ans select from TableName into outfile textxls all result fields will seperate by tab

77

第八章 參考資料

英文部份 網址 1 httpwwwmysqlcom MySQL 網站有第一手有關 MySQL的資料 2 httpwwwmysqlcomdocenReplicationhtml 有關 MySQL Replication 的文件 3 httpwwwgeocitiescomsqlhomefaqstore_blobhtml 如何在 MySQL 存放 BLOB的資料 4httpwwwsapdborg 有關 SAP跟 MySQL相關合作的網站 書藉 1 Cooking with MySQL

Paul DuBois has selected sample recipes from the hundreds youll find in his book MySQL

Cookbook In this third and final series of excerpts showcasing these recipes learn how to

compute team standings how to calculate the differences between successive Dec 26

2002 2 Tips for Building Web Database Applications with PHP and MySQL by Hugh E Williams co-author of Web Database Applications with PHP amp MySQL 04042002

3 Managing and Using MySQL 2nd Edition By Tim King George Reese Randy Jay Yarger

4 MySQL Cookbook By Paul DuBoisPublisher OReillyPub Date October 2002

中文部份

78

1 httplinuxtncedutwtechdocmysqlmysql_docmanual_tochtml MySQL 中文手冊 2 httpchenshloxaedutwphpZ_1php PHP+MySQ程式研習設計網站 3 httplinuxtncedutwtechdocbanicdownhtml PHP 4 手冊 4 httpwwwtncedutwadmin_zonephp台南縣教育網網路中心有很多 Linux相關文件 5 httpdobtncedutw網站建置百寶箱有很多 PHP MySQL 相關範例程式 5 httpwwwdbworldcomtw資料庫專家電子雜誌介紹資料庫的重要觀念及名詞

79

附錄一 SQL Command 介紹

SQL (讀音ess-que-el) 是一種結構查詢語法SQL 使用於資料庫交流

傳遞相容於 ANSI (American National Standards Institute) 是一套標準的關聯

式資料庫語言 SQL 語言是執行更新或從資料系統獲取資料一般常見的關聯

資料庫系統都有提供 SQL 如 Oracle Sybase Microsoft SQL Server Access Ingres 等雖然大部份的資料庫都有提供 SQL 但也多提供了自已獨特的語

法造成了不相容的情形但標準基本的語法是相通的如Select Insert Update Delete Create and Drop 每一個系統都有支援

Table相關 Command

Create Table

關聯式資料庫包含有很多元件稱為資料表(tables) 把資料或訊息放在資

料表中 資料表是以不同的名稱做分別資料表由欄列所構成的二維陣列

欄包含欄位名資料型態 及其他可判斷的資訊列是由全部欄位構成一筆一

筆的紀錄 create table 語法用在建立一個新的資料表語法格式如下

create table tablename (column1 data type column2 data type column3 data type)

Format of create table if you were to use optional constraints

create table tablename (column1 data type [constraint] column2 data type [constraint] column3 data type [constraint]) [ ] = optional

Note You may have as many columns as youd like and the constraints are optional

80

Example

create table employee (first varchar(15) last varchar(20) age number(3) address varchar(30) city varchar(20) state varchar(20))

注意建立資料表格式要以括號把前後框住而最後以(分號)做結尾

欄位名不要超過 30個字元長而且不要使用 sql 的關鍵字(如 where select等)而在後面接是型態的宣告(如字串數字日期格式等)

資料型態是來描述欄位的方式如一個欄位Last_Name 是一個姓氏可以使用varchar (可變動長度字串) 資料型態

以下是幾個常見的資料庫型態 char(size) 固定長度字串最長為 255 位元 varchar(size) 變動長度字串最大字元數以 size 來指定 number(size) 數值格式可以是整數也可以是小數最大數字以 size 位數判

斷未指定小數位數由系統內定 date 日期格式 number(sized) 數值格式最大數字以 size 位數判斷d 為小數位數整數位

數為 size-d 位

有何限制當資料表被建立通常有一或數個欄位是要使用來做關聯的功

能 例如unique 限制(唯一值)兩筆記錄不可以相同的值 not null (非空值)該欄位一定要輸入資料不可是空的primary key (主鍵)是每一筆記錄識別的主要方式

Drop a table drop table 刪除資料表(其中的資料也會一併刪除)

drop table tablename

Example

81

drop table 和刪除全部資料是不同的刪除全部資料欄位名稱資訊等還會

存在但刪除資料表會把這一些也一併移除掉

如何查詢資料

Select 基本用法

select 語法是關連式資料庫最常用的部份可以取得你想要的資料這是一個

簡單的範例 select column1[column2etc] from tablename [where condition] [] = optional 在 select 之後所列欄位名則是要顯示的資料部份你可以一一列出各欄位

名或是以 (星號)來代表選擇全部的欄位 from 之後放資料表名稱 where 子句 (選項) 指定要過濾的條件符合者才會顯現 where 可使用的條件運算元 = 等於 gt 大於 lt 小於 gt= 大或等於 lt= 小或等於 ltgt 大相等 LIKE 相似 For example select first last city

82

from empinfo where first LIKE Er 以Er 為開頭的字串就符合要以單引號框住 Or you can specify select first last from empinfo where last LIKE s 最後一字為 S 就符合 select from empinfo where first = Eric 則表示 first name 一定要是 Eric 才可以 範例資料表empinfo 統計函數

MIN 傳回指定欄位最小值

MAX 傳回指定欄位最大值

SUM 傳回指定欄位總和

AVG 傳回指定欄位平均值

COUNT 傳回指定欄位的筆數

COUNT() 傳回資料庫中的總筆數

統計函數使用於資料表中的數值欄位配合 SELECT 語法使用 只用於總結特定單一欄位可以配合 GROUP BY 做篩選但也可以不使用 GROUP BY 語句For example

SELECT AVG(salary) FROM employee

83

傳回全部 salary 平均值

Another example

SELECT AVG(salary) FROM employee WHERE title = Programmer

傳回 salary 平均值條件為 employees 資料表中當 title 等於 Programmer

Example

SELECT Count() FROM employees

傳回 employees 資料表中紀錄總筆數

GROUP BY 語法 SELECT column1 SUM(column2) FROM list-of-tables GROUP BY column-list The GROUP BY 語句可以先以所列的欄位為條件分組排序在一起(可以多欄

位) example 要列出每一個 dept 中最高 salary 值 SELECT max(salary) dept FROM employee GROUP BY dept HAVING 語法

SELECT column1 SUM(column2) FROM list-of-tables GROUP BY column-list HAVING condition

HAVING 子句是 GROUP BY 的一部份用來過濾在 GROUP BY 所選出的資料功能如同 select 命令中 where 條件式一樣只是 HAVING 必需配合 GROUP BY 使用

我們以例子來說明我們要取得每一公司名及每一公司的薪水平均值輸入如下

84

SELECT dept avg(salary) FROM employee GROUP BY dept

但如果我們只列出薪資平均值超過 20000元的公司資料

SELECT dept avg(salary) FROM employee GROUP BY dept HAVING avg(salary) gt 20000

ORDER BY子句語法

SELECT column1 SUM(column2) FROM list-of-tables ORDER BY column-list [ASC | DESC]

[ ] =選項

ORDER BY是一個選項子句當你以排序方式來顯示資料(正向由小到大反向由大到小)以指定的欄位資料做排序

ASC = 正向- 預設值 DESC = 反向排序

For example

SELECT employee_id dept name age salary FROM employee_info WHERE dept = Sales ORDER BY salary

以上列出公司代號公司名銷售員人名年紀及薪資而條件是公司名為 Sales 顯示順序以薪資多少排序(由小到大為預設值)

如果要以多個欄位做排序要以逗號做分隔如下

SELECT employee_id dept name age salary FROM employee_info WHERE dept = Sales ORDER BY salary age DESC

85

結合條件及布林運算 SELECT column1 SUM(column2) FROM list-of-tables WHERE condition1 AND condition2 AND運算可以結兩個或以上的條件放在 WHERE子句中 兩者都要為真才

會顯示該筆記錄 OR 運算可以結兩個或以上敘述放在 WHERE子句中只要其中一個為直就

會顯示該筆記錄 For example SELECT employeeid firstname lastname title salary FROM employee_info WHERE salary gt= 5000000 AND title = Programmer 必需要薪資大於等於 50000而且職稱為 Programmer同時符合才會顯示該筆資料 以下以括號括住雖然不是必需的但如此比較容易讀 SELECT employeeid firstname lastname title salary FROM employee_info WHERE (salary gt= 5000000) AND (title = Programmer) 另外範例 SELECT firstname lastname title salary FROM employee_info WHERE (title = Sales) OR (title = Programmer) 條件為只要是 Sales 或 Programmer 職稱的就會被列出 IN and BETWEEN 子句

SELECT column1 SUM(column2) FROM list-of-tables WHERE column3 IN (list-of-values) SELECT column1 SUM(column2) FROM list-of-tables WHERE column3 BETWEEN value1 AND value2 IN 子句使用在列舉項目的使用上也就是分別測試是否符合所列的值 For example

86

SELECT employeeid lastname salary FROM employee_info WHERE lastname IN (Hernandez Jones Roberts Ruiz) 條件為姓氏(astname)要符合 Hernandez Jones Roberts or Ruiz 其中一個才會被傳回 IN運算元也可以使用 OR 的語法來取代如下結果相同 SELECT employeeid lastname salary FROM employee_info WHERE lastname = Hernandez OR lastname = Jones OR lastname = Roberts OR lastname = Ruiz 但使用 IN 句子比較短也比較易懂 你也可以使用 NOT IN 來去掉不要的記錄 BETWEEN 運算元使用在判斷是否存在兩個數值之間 For example SELECT employeeid age lastname salary FROM employee_info WHERE age BETWEEN 30 AND 40 傳回年紀 30歲到 40歲之間的資料(含 30及 40歲者) 相同的也可以使用以下語法來達到相同的結果 SELECT employeeid age lastname salary FROM employee_info WHERE age gt= 30 AND age lt= 40 你也可使用 NOT BETWEEN 來濾掉中間值的資料 數學運算 標準 ANSI SQL-92 提供以下運算

87

+ 加

- 減

餘數

餘數為除法後剩整數這不在標準的 ANSI SQL 中但大部份的資料庫都會支

援這運算元以下列出有用的函數雖不在 ANSI SQL-92 提供但一般資料庫

也會支援他們

ABS(x) 傳回 x 絕對值

SIGN(x) returns the sign of input x as -1 0 or 1 (negative zero or positive respectively)

MOD(xy) 餘數 - returns the integer remainder of x divided by y (同 xy)

FLOOR(x) 傳回小或等於 x 的最大整數值

CEILING(x) or CEIL(x)

傳回大或等於 x 的最小整數值

POWER(xy) x的 y 次方

ROUND(x) 把 x 四捨五入為整數

ROUND(xd) 四捨五入取到小數 d 位

SQRT(x) x 開平方

For example SELECT round(salary) firstname FROM employee_info 傳回薪資取到整數位

如何新增資料

insert 加入一筆新紀錄到資料表中 insert into tablename (first_columnlast_column) values (first_valuelast_value) [] = optional Example insert into employee

88

(first last age address city state) values (Luke Duke 45 2130 Boars Nest Hazard Co Georgia) Note 字串要以單引號住如string 數字框住也無妨 insert into 後面接資料表名稱再接以括號括住的欄位名在 values 後括號分別對映各欄位的值 以上的例子新增了一筆名(first) 為 Luke而住所(state) 為 Georgia 的資料

如何刪除資料

delete 可以刪除單筆或多筆紀錄 delete from tablename where columnname OPERATOR value [and|or column OPERATOR value] [ ] = optional Examples delete from employee Note 如果你沒有指定 where 子句那麼全部的紀錄都會被刪除 delete from employee where lastname = May delete from employee where firstname = Mike or firstname = Eric delete from 接著資料表名 再接著是條件式判斷沒有條件式則全部紀錄會

被刪除

如何更新資料

update 用來更新你所指定的記錄要和 WHERE 配合小心使用 語法 update tablename set columnname = newvalue[nextcolumn = newvalue2] where columnname OPERATOR value [and|or column OPERATOR value] [] = optional Examples

89

update phone_book set area_code = 623 where prefix = 979 update phone_book set last_name = Smith prefix=555 suffix=9292 where last_name = Jones update employee set age = age+1 where first_name=Mary and last_name=Williams

90

附錄二Replication

測試環境

RedHat 90 + MySQL 32358 MySQL資料庫路徑 varlibmysql MySQL設定檔 etcmycnf Master IP 1921680100 Slave IP 1921680200 請至下列網址下載最新MySQL 32358套件並利用rpm ndashUvh 更新 httpupdatesredhatcom9enosi386

圖 最新 MySQL 套件

測試架構圖

91

1921680100

1921680200Master Server

erveSlave S r

圖 測試架構圖

測試步驟

Master server 部份 Step1 確認 MasterSlave機器上所裝的 MySQL版本能進行

replication( 32329 or higher ) Step2 在 Master MySQL上開放一個帳號給 Slave mysql ndashu root ndashp mysqlgtGRANT FILE ON TO repl1921680200 IDENTIFIED BY lsquoabc123rsquo mysqlgtq 上面是 Master開放一個帳號 repl密碼 abc123給 IP1921680200有檔案處理

的權限 Step3 shutdown MySQL on the Master mysqladmin ndashu root ndashp shutdown Step4 備份 Master所有資料庫 tar ndashcvf tmpmysql-snapshottar varlibmysql 注意tar的時候MySQL是要在 stop情況下 在mysql (wwwmysqlcom) 網站的FAQ有不用shutdown的方法

92

Step5 在 master機器上修改etcmycnf 在[mysqld]區段內加入參數 log-bin server-id=這邊設定 server-id=1 sql-bin-update-same binlog-do-db=CRM只針對 CRM資料庫做紀錄 Step6 Restart MySQL on the master service mysqld start 此時因為有加入 log-bin 參數因此開始有 index產生了在varlibmysql目錄下

有index檔案紀錄資料庫的異動 log Slave server 部份 Step1 在 slave設定etcmycnf 在[mysqld]區段加入 master-host= master-user= master-password= master-port= server-id= 這邊設定 master-host=1921680100 master-user=repl master-password=abc123 master-port=3306 server-id=2 master-connect-retry=60預設重試間隔 60秒 replicate-do-db=CRM告訴 slave只做 CRM資料庫的更新 log-slave-updates Step2 將 master上的 mysql-snapshottar copy到 slave上 用 ftp傳到 slave的tmp Step3 解壓縮 Master資料庫至 Slave Server上 cd varlib tar xvf tmpmysql-snapshottar chown ndashR mysqlmysql mysql

93

chmod ndashR 770 mysql (視情況) Step4 Restart MySQL on the slave server 這時在varlibmysql目錄會出現 masterinfo此檔案紀錄了 Master MySQL server的資訊

狀況測試

One-way replication

1921680100

1921680200Master Server

erveSlave S r

圖 One-way replication架構圖 Step1 Master跟 Slave網路及服務都正常情況下由 Master端異動資料後 到 Slave端瀏覽資料檢視是否有進行 replication Step2 模擬 Slave Server 當機 可用在於 slave真的當機或是 Slave 不一定需要一直跟 master connect將Slave MySQL server shutdown由 Master端異動資料到 slave端瀏覽此時Slave應該沒有被 replication 更新然後再將 Slave端 MySQL server start起來

預設 60秒後 Slave會嘗試跟 Master要求進行 replication再去 Slave端檢視是否有更新資料

94

Step3 模擬 Master當機因為是設定 One-way replication一旦 Master Server Slave端沒有 Master的 source可以 download Two-way replication 基於 Master當機狀況於是發展雙向 Replication即 1921680100 ( Host A ) 1921680200 ( Host B )都分別擔任 MasterSlave身分

1921680100

1921680200er

Server B MasterSlave Server

Server A MasterSlave Serv

圖 Two-way replication架構圖 以下是針對兩台 MySQL伺服器進行雙向 Replication Step1觀念同單向 replication只是改成 Master也有 Slave身分 Slave也有Master的身分先分別在 Server AServer B 都去 grant一個進行 replication的身分 [A]mysqlgtGRANT FILE ON TO repl1921680200 IDENTIFIED BY lsquoabc123rsquo [B]mysqlgt GRANT FILE ON TO repl1921680100 IDENTIFIED BY lsquoabc123rsquo Step2做完單向 replication後stop Server Aserver B MySQL service此時 AB資料是一樣的

95

修改etcmycnf設定 範例 Server A [mysqld] datadir=varlibmysql socket=varlibmysqlmysqlsock server-id=1 log-bin sql-bin-update-same binlog-do-db=CRM master-host=1921680200 master-user=repl master-password=abc123 log-slave-updates master-connect-retry=60 replicate-do-db=CRM Server B [mysqld] datadir=varlibmysql socket=varlibmysqlmysqlsock server-id=2 log-bin sql-bin-update-same binlog-do-db=CRM master-host=1921680100 master-user=repl master-password=abc123 log-slave-updates master-connect-retry=60 replicate-do-db=CRM 分別 start Server AServer B MySQL後此時雙方都是 MasterSlave身分一旦哪一方資料異動就會通知對方來 replication-若 replication失效則必須將Server AServer B的masterinfo及index00x 都砍掉然後分別 restart MySQL server進行測試檢視成果 實務上通常如果需要做Two-way replication通常會搭配Virtual Server使用

96

在前端架設一台Virtual Server不過此部份不在此份SOP討論範圍內有興趣

的讀者可參考 httpwwwlinuxvirtualserverorg 網站

1921680100 1921680200

Host A MasterSlave Server

Host B MasterSlave Server

Virtual Host

圖 Virtual Server + Two-way replication 架構圖

97

圖 High Availability Linux Virtual Server架構圖

98

  • COSA-SOP-03-006
  • 第一章 簡介
    • 11適用對象 (Audience)
    • 12 MySQL本身
    • 13 MySQL 40版跟50版重大的改進功能
    • 14 各家資料庫軟體比較
      • 第二章 前置需求
      • 第三章 安裝
        • 31 MySQL安裝
        • 32 phpMyAdmin安裝
        • 33 升級及注意事項
          • 第四章 MySQL管理
            • 41 Webmin 管理介面
            • 42 phpMyAdmin 的操作介面
            • 43管理指令介紹
              • 431 利用mysqladmin設定root的密碼
                  • 第五章 實用範例
                    • 51 任務一Web Base客戶通訊錄
                    • 52 任務二Web Base群組軟體 ( twig )
                      • 第六章 維護及更新程序
                        • 61 日常維護
                        • 62 更新程序
                        • 63 備份重要檔案
                        • 64 離線備份與還原
                        • 65 線上備份與還原
                          • 第七章 問題與解答
                          • 第八章 參考資料
                          • 附錄一 SQL Command 介紹
                          • 附錄二Replication
Page 33: DataBase Server Standard Operation Procedureebooks.lib.ntu.edu.tw/1_file/oss/63/93doc4-5.pdf · 業務的公司帶來了不少壓力,譬如微軟,甲骨文 ... 外的錢用在第三方的資料庫產品上,譬如就可以不用再購買甲骨文公司

圖 4-9 建立表格資料

圖 4-10 檢視資料

33

圖 4-11 新增資料

圖 4-12

34

圖 4-13

413 使用者管理

接下來我們要利用Webmin 來建立資料庫使用者並給予某些權限 Step1建立使用者

35

圖 4-14 選擇使用者權限

圖 4-15

36

Step2 賦予權限

圖 4-16

Step3 權限列表

37

圖 4-17

38

42 phpMyAdmin 的操作介面

421建立資料庫

Step 填入資料庫名稱並按「建立」

圖 4-18建立資料庫

422 建立資料表

Step1 填入資料表名稱並指定欄位數量 執行

39

圖 4-19填入資料表名稱並指定欄位數量

Step2 設定欄位屬性

圖 4-20設定欄位屬性

40

Step3 phpMyAdmin會產生相關的 SQL Command

圖 4-21 資料表結構及相關 SQL Command

Step4新增 Record

41

圖 4-22

圖 4-23

42

圖 4-24

圖 4-25

43

423使用者管理

Step1建立使用者

圖 4-26

44

圖 4-27

Step2 給予權限

圖 4-28

Step3權限列表

45

圖 4-29

43管理指令介紹

431 利用 mysqladmin設定 root的密碼

當您在Windows 或 Linux 中安裝好 MySQL後系統會自動幫您建立兩個

帳分別是 root 和 匿名者MySQL的 root 跟 Linux 最高權限使用者 root無關MySQL的 root使用者相當於 MS SQL 中的 sa 帳號擁有最高的 Database管理權限但系統預設 MySQL的 root 是不需要密碼所以通常我們一安裝

MySQL後首要任務便是修改 root的密碼 我們可以利用 mysqladmin工具或是直接修改 MySQL內部資料庫的使用者資

料 mysqladmin ndashu root ndashh cosaexamplecom password lsquo1234rsquo

46

-u 表示使用者帳號root 為 MySQL預設的管理帳號

-h 表示 MySQL主機的主機名稱也可使用 IP Address password 表示使用者的密碼因為字串請使用單引號將密碼括起來 密碼設定完成之後還是可以利用 mysqladmin修改密碼但是你必須提供目前的密碼

432 連線 MySQL

mysql -uroot -p密碼 (-p和密碼之間不能有空白) 或 mysql -uroot -p (此方式會在進入後要求密碼) [rootossc phpMyAdmin] mysql -u root -p1234

Welcome to the MySQL monitor Commands end with or g

Your MySQL connection id is 25 to server version 32354

Type help or h for help Type c to clear the buffer

mysqlgt show databases

+----------+

| Database |

+----------+

| mysql |

| test |

+----------+

2 rows in set (000 sec)

mysqlgt exit

Bye

[rootossc phpMyAdmin]

433 建立資料庫

可利用 mysqladmin指令建立 CONTACT資料庫 mysqladmin -u root -p1234 create CONTACT

47

或是利用 mysql指令 [rootossc bluepage] mysql -u root -p1234 Welcome to the MySQL monitor Commands end with or g Your MySQL connection id is 1057 to server version 32354 Type help or h for help Type c to clear the buffer mysqlgt create database CONTACT Query OK 1 row affected (000 sec) mysqlgt show databases +----------+ | Database | +----------+ | CONTACT | | address | | hello | | mysql | | nuke | | test | +----------+ 6 rows in set (000 sec) mysqlgt exit

434 建立資料表

編寫 adresssql內容如下 -- Table structure for table address CREATE TABLE address ( id int(11) NOT NULL auto_increment name varchar(20) NOT NULL default tel varchar(15) NOT NULL default PRIMARY KEY (id) ) TYPE=MyISAM

48

-- Dumping data for table address INSERT INTO address VALUES (1林小明0800016888) INSERT INTO address VALUES (2黃大雄0800016888) INSERT INTO address VALUES (3劉小芬0800024365) 然後執行此 sql script mysql -u root -p1234 CONTACT lt addresssql 或是利 mysql command [rootossc bluepage] mysql -u root -p1234 Welcome to the MySQL monitor Commands end with or g Your MySQL connection id is 1090 to server version 32354 Type help or h for help Type c to clear the buffer mysqlgt use CONTACT Database changed Database changed mysqlgt CREATE TABLE address ( -gt id int(11) NOT NULL auto_increment -gt name varchar(20) NOT NULL default -gt tel varchar(15) NOT NULL default -gt PRIMARY KEY (id) -gt ) TYPE=MyISAM Query OK 0 rows affected (000 sec) mysqlgt INSERT INTO address VALUES (1林小明0800016888) Query OK 1 row affected (000 sec) mysqlgt INSERT INTO address VALUES (2黃大雄0800016888) Query OK 1 row affected (000 sec) mysqlgt INSERT INTO address VALUES (3劉小芬0800024365) Query OK 1 row affected (000 sec) mysqlgt exit Bye

49

第五章 實用範例

51 任務一Web Base客戶通訊錄

任職於開放科技公司的林小明前些日子在最符合成本效益的條件下快

速地完成公司網站的建置老闆因此對小明讚譽有加最近因為公司存放客戶資

料的 SQL Server主機屢遭病毒攻擊加上作業系統本身的問題當機次數頻繁

老闆希望能儘快把公司的客戶通訊錄程式移轉到較穩定的環境上因為此客戶通

訊錄程式最主要給內部人員使用所以介面美觀並不特別要求只求穩定且能快

速得到查詢結果老闆希望在短時間先看到程式的雛型並鍵入資料對其效率

及穩定性進行測試因為上次小明表現突出所以這次不可能的任務自然又落到

小明身上 小明想來想去既然要快速又穩定他而且又不希望所有人都得安裝 Client

程式於是小明決定)捨棄他的舊愛「Delphi+MS SQL」投向新歡「Apache + MySQL + PHP」利用此架構來設計一個簡單實用的Web Base客戶通訊錄程式

511 Web Base客戶通訊錄架構

此程式需要建立 CONTACT的資料庫並建立 adress Tables其結構如下表建立步驟請參考第三章 欄位名稱 資料型態 長度 說明 id INT (自動編號) 連絡人編號 name varchar文字 20 連絡人姓名 tel Varchar文字 15 連絡人電話 Web Base通訊錄共有下列幾個檔案功能如下表

檔案名稱 說明 Indexhtml Web Base通訊錄首頁 addphp 新增連絡人的 php程式 searchphp 尋找連絡人的 php程式 editphp 具有更新及刪除功能的 php程式

50

我們將這些檔案放至varwwwhtmlbluepage (預設無 bluepage目錄)

512 Web Base通訊錄測試

httpwwwopencombluepage 新增資料

圖 5-1 新增連絡人

圖 5-2 填入資料

51

圖 5-3 新增成功

搜尋及異動資料

圖 5-4 搜尋通訊錄

52

圖 5-5 編輯資料

圖 5-6 更新資料

513 程式內容及說明

lt-- 程式範例indexhtml--gt lthtmlgt ltheadgtlttitlegt通訊錄lttitlegtltheadgt ltbodygt ltcentergt

53

lth2gt通訊錄lth2gtlthrgt lta href=indexhtmlgt通訊錄ltagt | lta href=addphpgt新增連絡人ltagt | lta href=searchphpgt搜尋通訊錄ltagt ltcentergt ltbodygt lthtmlgt lt-- 程式範例addphp --gt lthtmlgt ltheadgtlttitlegt新增連絡人lttitlegtltheadgt ltbodygt ltcentergtlth2gt新增連絡人lth2gtltcentergtlthrgt lt 取得欄位資料 if (isset($_POST[Name]) ampamp isset($_POST[Tel]) ) $name = $_POST[Name] $tel = $_POST[Tel] 檢查是否有輸入欄位資料 if ($name = ampamp $tel = ) 建立 SQL字串 $sql = INSERT INTO address (name tel) values( $sql= $name $tel) 建立 MySQL 連結 $link = mysql_connect(localhostroot1234) 選擇資料庫 mysql_select_db(CONTACT) 執行 SQL指令 mysql_query($sql) mysql_close($link) echo ltfont color=redgt新增連絡人成功ltfontgtltbrgt gt ltform action=addphp method=postgt lttable border=0 width=300gt lttrgtlttdgt姓名 lttdgt

54

lttdgtltinput type=text name=Name size=20 maxlength=10gtlttdgtlttrgt lttrgtlttdgt電話 lttdgt lttdgtltinput type=text name=Tel size=20 maxlength=20gtlttdgtlttrgt lttrgtlttd colspan=2 align=centergt ltinput type=submit value=新增連絡人gtlttdgtlttrgt lttablegt ltformgt ltbrgtlta href=indexhtmlgt通訊錄ltagt | lta href=addphpgt新增連絡人ltagt | lta href=searchphpgt搜尋通訊錄ltagt ltbodygt lthtmlgt

lt-- 程式範例searchphp --gt lthtmlgt ltheadgtlttitlegt搜尋通訊錄lttitlegtltheadgt ltbodygt ltcentergtlth2gt搜尋通訊錄lth2gtlthrgt lt if (isset($_POST[Search])) 建立資料庫連結並選定資料庫 $link = mysql_connect(localhostroot1234) mysql_select_db(CONTACT) 建立基本的 SQL字串 $sql = SELECT FROM address 檢查是否輸入姓名 if (chop($_POST[Name]) = ) $name = name LIKE $_POST[Name] else $name = 檢查是否輸入電話號碼 if (chop($_POST[Tel]) = ) $tel = tel LIKE $_POST[Tel] else $tel =

55

if條件組合 SQL字串 if (chop($name) = ampamp chop($tel) = ) $sql= WHERE $name AND $tel elseif (chop($name) = ) 只有姓名 $sql = WHERE $name elseif (chop($tel) = ) 只有電話號碼 $sql = WHERE $tel $sql= ORDER BY name 最後加上排序 $result = mysql_query($sql) 取得欄位數 $total_fields = mysql_num_fields($result) echo lttable border=1gt echo lttrgtlttdgt編號lttdgtlttdgt姓名lttdgtlttdgt電話lttdgtlttd colspan=2gt功能選項lttdgtlttrgt 表格顯示查詢結果 while ($rows = mysql_fetch_array($result MYSQL_NUM)) echo lttrgt for ($i = 0 $i lt $total_fields $i++) echo lttdgt$rows[$i]lttdgt echo lttdgtlta href=editphpaction=editampid= echo $rows[0]gtltbgt編輯ltbgtlttdgt echo lttdgtlta href=editphpaction=delampid= echo $rows[0]gtltbgt刪除ltbgtlttdgt echo lttrgt echo lttablegtlthrgt mysql_free_result($result) mysql_close($link) gt ltcentergt ltform action=searchphp method=postgt lttable border=0 width=450gt lttrgtlttdgt搜尋姓名 lttdgt lttdgtltinput type=text name=Name size=10 maxlength=20gtlttdgtlttrgt lttrgtlttdgt搜尋電話 lttdgt lttdgtltinput type=text name=Tel

56

size=20 maxlength=20gtlttdgtlttrgt lttrgtlttd colspan=2 align=centergt ltinput type=submit name=Search value=搜尋gtlttdgtlttrgt lttablegt ltformgt ltbrgtlta href=indexhtmlgt通訊錄ltagt | lta href=addphpgt新增連絡人ltagt | lta href=searchphpgt搜尋通訊錄ltagt ltbodygt lthtmlgt

lt ob_start() gt lt-- 程式範例editphp --gt lthtmlgt ltheadgtlttitlegt編輯通訊錄lttitlegtltheadgt ltbodygt lt 取得 URL 參數 $id = $_GET[id] $action = $_GET[action] 建立資料庫連結 $link = mysql_connect(localhostroot1234) mysql_select_db(CONTACT) 選擇資料庫 執行的操作 switch ($action) case update 更新 取得欄位資料 $name = $_POST[Name] $tel = $_POST[Tel] $sql = UPDATE address SET name=$name tel=$tel WHERE id=$id mysql_query($sql) 執行 SQL指令 mysql_close($link) header(Location searchphp) 轉向到 serachphp break case del 刪除 $sql = DELETE FROM address WHERE id=$id

57

mysql_query($sql) 執行 SQL指令 mysql_close($link) header(Location searchphp) 轉向到 serachphp break case edit 編輯 $sql = SELECT FROM address WHERE id=$id $result = mysql_query($sql) 執行 SQL指令 $row = mysql_fetch_row($result) 取回記錄 $name = $row[1] 取得欄位 name $tel = $row[2] 取得欄位 tel mysql_close($link) 顯示編輯表單 gt ltcentergtlth2gt更新通訊錄lth2gtltcentergtlthrgt ltform action=editphpaction=updateampid=lt echo $id gt method=postgt lttable border=0 width=300gt lttrgtlttdgt姓名 lttdgt lttdgtltinput type=text name=Name size=20 maxlength=10 value=lt echo $name gtgtlttdgtlttrgt lttrgtlttdgt電話 lttdgt lttdgtltinput type=text name=Tel size=20 maxlength=20 value=lt echo $tel gtgtlttdgtlttrgt lttrgtlttd colspan=2 align=centergt ltinput type=submit value=更新連絡人gtlttdgtlttrgt lttablegt ltformgt ltbrgtlta href=indexhtmlgt通訊錄ltagt | lta href=addphpgt新增連絡人ltagt | lta href=searchphpgt搜尋通訊錄ltagt lt break gt ltbodygt lthtmlgt

58

52 任務二Web Base群組軟體 ( twig )

順利完成Web Base客戶通訊錄程式測試一段時間後「Apache + MySQL + PHP」架構的穩定與快速巳深得老闆與公司所有同事的認同隨著公司業績蒸

蒸日上人員組織編罝愈來愈龐大跨部門的會議愈來愈多業務員每日排滿拜

訪客戶的行程跟客戶的 Email的往來也愈來愈頻繁 愈來愈多部門的同事希望公司能建置一套群組軟體提供 web mail可讓業

務人員方便收發 mail還有連絡人議事日程待辦工作書簽等功能讓整個

公司運作及個人時間管理更有效率

老闆問小明對這些需求有什麼看法小明認為如果這些功能完全由程式部

門開發必定曠日費時而且耗費公司資源小明在網路尋找是否有提供這些功能

的Free Software皇天不負苦心人小明發現了TWIG (The Web Information Gateway) httptwigscrewdrivernet這個群組軟體它在 Web 上整合郵件新聞聯絡人議事日程工作序書簽等功能非常符合公司的需求 Step 1 下載 twig-277targz 下載網址 httptwigscrewdrivernetdownloadphp3

Step 2 解開 twig-277targz tar -xzvf twig-277targz

59

Step 3 執行安裝動作安裝到 varwwwhtmltwig 目錄 cd twig-277 twig-install varwwwhtmltwig

Step 4 建立 MySQL 資料庫(twig)及各資料表

cd setup mysql -u root -p1234 mysqlgt create database twig Query OK 1 row affected (001 sec) mysqlgt quit mysql -u root ndashp1234 twiglt twigtablemysql

Step 5 修改 configincphp3 參數設定 vi varwwwhtmltwigconfigconfigincphp3 $config[fromdomain] = opencom 網域 $config[language] = chinesebig5 中文訊息 $config[imap_port] = 143notls

60

Step 6 修改連結 MySQL 的帳號密碼 vi varwwwhtmltwigconfigdbconfigincphp3 $dbconfig[sqlusername] = root username $dbconfig[sqlpassword] = 1234 password

Step 7 其他設定檔

vi etchttpdconfhttpdconf 加入 AddType applicationx-httpd-php php3 在 DirectoryIndex最後加入 indexphp3 DirectoryIndex indexhtml indexhtmlvar indexphp3 在 AddDefaultCharset ISO-8859-1加上 AddDefaultCharset ISO-8859-1

vi etcphpini register_globals = On service httpd restart Step 8 sendmail 設定 vi etcmailsendmailcf在 264 行前面加上並重新啟動 sendmail「service snedmail restart」 262 SMTP daemon options 263 264 O DaemonPortOptions=Port=smtpAddr=127001 Name=MTA 265 266 SMTP client options 267 O ClientPortOptions=Family=inet Address=00

61

Step 9 檢查設定有無錯誤 http主機名稱twigtestphp3

62

Step 10 登入 twig ( http主機名稱twig)

63

第六章 維護及更新程序

61 日常維護

系統管理員最好定期以 root 身份登入看看信件在 RedHat Linux 中有一支 logwatch 程式會定時去分析 log file如果發現異常便會發信給 root除此之外筆者建議讀者平時就檢查 MySQL log file ( varlogmysqldlog)是否有異常情形

62 更新程序

讀者可至httprpmfindnet 尋找MySQL相關套件至於升級的相關步驟請參

考Linux OS SOP 第 54節

63 備份重要檔案

預設 MySQL 的 DB 檔案是存在 varlibmysql 內以 DB名稱為目錄目錄

內就是該 DB 的所有資料通常得定期備份還有 MySQL的設定檔 etcmycnf也別忘了一起備份

64 離線備份與還原

641 離線備份

預設 MySQL 的 DB 檔案是存在 varlibmysql 內以 DB 名稱為目錄目錄內

就是該 DB 的所有資料像 CRM 這個 DB就是存在 varlibmysqlCRM 內在備份前因為怕資料尚未完全寫入磁碟而且 MySQL 會 Lock 在使用的 DB 檔案所以應該是要先把 MySQL 先 Shutdown 一下整個備份的程序可以下像下面的指令去完成 cd varlibmysql

64

service mysqld stop tar cvfz CRM_db_20030905tgz CRM service mysqld start 對這樣就可以了 不過要注意的是怕 DB 內每個 Tables 間的資料有關關

聯性所以最好是把整個 DB 一次備起來單獨只備哪個 Tables 的檔案以後回存時怕會有資料關聯不一致的問題

642 離線還原

DB 發生錯誤而要回存時其實也不難先找出最近一次完整正常的備份先把現在錯誤的網頁或 DB 先更名或 tar 起來再把好的備份給解開回原來目錄位

置就行了需要注意的是 MySQL 服務最好也是要先停止回存完成後再啟動服務回存 DB 的整個程序可能像下面 cd varlibmysql service mysqldstop mv CRM CRM_OLD tar xvfz CRM_db_20030905tg service mysqld start

65 線上備份與還原

651 線上備份

使用像上面的檔案方式備份是個不錯的方法它最少可以保持該主機某個時間點的完整檔案備份但還是有一些問題需要考慮到有些主機就不只建立一個 DB 而已總不能為了備份某個 DB 而把整個 MySQL 服務停止備份檔案的方式回存在原主機上一定適用但假如 MySQL 版本升級或是在那天該網頁空間需遷機移機到別的主機時那就沒人敢保證備出來的資料檔可以用所以我們可以考慮另一種備份的方式是使用 MySQL 本身提供的功能 MySQL Data Dump指令是 mysqldump

65

使用 MySQL 的 Dump 功能可以把 DB 的結構資料或結構加資料 Dump 成文字檔 mysqldump 指令提供的彈性很大你可以選擇把整個 DB Dump 成一個檔或是每個 Table 為一個檔甚至是把結構檔和資料分開儲存都

可以 mysqladmin -uroot -p flush-logs mysqldump CRM -uroot -p --opt gt CRM_20030905sql (CRM 是 DB 名稱 opt 是一個使用完整 Dump 參數) 假如只是要單獨 Dump 某個 Table 時只要在上面的指令後轉出符號 gt 前加個 Table 名稱就可以如只要 phpbb2_users 這個 Table 的 Dump 時只要下 mysqldump CRM -uroot -p --opt CUSTOMER gt CRM_CUSTOMER_20030905sql

652 線上還原

若要回存整個資料庫只需將壓縮的備份檔還原成 Dump 的檔案再用下面的指令回存 mysql CRM -uroot -p lt CRM_20030905sql 這邊需注意的是若建立備份時是以--opt或--add-drop-table為參數時回存的 動作是先將舊的 Table 先刪除重建 Table 的結構後再把 Data 匯入所以回存後所有的資料會回到你當時備份那個時間點因此在回存資料時可以考慮把現有錯誤或不完整的 DB 先備份一份下來以備不時之需或是拿來比對錯誤的地

方在那裡當然你也可以把資料回存到另一個測試用的 DB 內只要把上面指令

的 DB 名稱改成你的測試用 DB 名稱即可 使用這種回存方式 MySQL 服務不需停止也不會動到其他正在使用的 DB 在一些提供 MySQL 服務的虛擬主機可用這種方式作你自己的 DB 備份及回存

66

另外假如你是系統重建或是移機時切需在新的 MySQL 內新建一個空白 DB 後才行作回存的工作你可以用下面的指令建立 mysql -uroot -p -e CREATE DATABASE CRM (上面的 CRM是你要新建的 DB 名稱) 另一種作法先用 mysql 指令進入 mysql client console 然後再用 CREATE DATABASE CRM 這樣就行了記得尾端要加個 符號該行指令才會執行

67

第七章 問題與解答

Q1RedHat 90預附的 MySQL到底有無支援 Transcation機制 Ans MySQL自 32334a之後的 MySQL-Max版本加入 InnoDB的資料庫類型透過

InnoDBMySQL同樣可以進行 COMMIT與 ROLLRACK的動作RedHat 90預附的 MySQL為 32354a-11巳支援 InnoDB的資料庫類型不過必須做以

下設定 1cp usrsharedocmysql-server-32354amy-mediumcnf to etcmycnf 2 vi etcmycnf 將以下設定前的拿掉 innodb_data_home_dir = varlibmysql innodb_data_file_path = ibdata110Mautoextend innodb_log_group_home_dir = varlibmysql innodb_log_arch_dir = varlibmysql 3service mysqld restart 如此一來各位在建立Table時便可指定Table Type為 innodb ( ex create table with type=innodb ) Q2如何解決 php+mysql 許功蓋等字變亂的問題 Ans 方法一 【確定 MySQL 預設的字元集】 1 打開 WinMySQLadmin 管理畫面(在視窗右下角狀態列紅綠燈圖示中按滑鼠

右鍵點選 Show me 選項) 2 點選管理畫面中 [Variables] 標籤選項其中 character_set變數就是您預設

字元集的變數其預設是 latin1 字元集(我們要將他改回 big5)而 chatacters_set 變數則是 MySQL 可以支援哪些字元集 【修改預設字元集變數 character_set 】 1 請點選管理畫面中 [myini Setup] 標籤選項設定 myini 2 按一下 [Pick-up and Edit myini values] 按鈕以便編輯目前的 myini 設定 3 在 [mysqld] 設定區塊底下新增一行 default-character-set = big5 變數設

68

定 4 新增一個 [client] 設定區塊並加入第三步驟的變數設定(游標往下移到空白處新增兩行 [client] 和 default-character-set=big5) 5 按一下畫面左下方 [Save Modification] 按鈕儲存設定 6 重新啟動 MySQL 或 Windows 方法二 Server端注意事項 phpini 中有關的設定為(預設值) Magic quotes for incoming GETPOSTCookie data magic_quotes_gpc = On Use Sybase-style magic quotes (escape with instead of ) magic_quotes_sybase = Off Client端注意事項 1中文資料送進 mysql 前請用 addslashes($str) 處理 2處理後送進 mysql 時請用 括起來並在參數後留一個空白如 $sql = UPDATE ezf_table set tablename=$tname tableend=$endtime table inguser=$tguser tableingid=$tguserid tableallnumber=$tnumber tableloca l=$tablelocal tableanyone=$tableopen tabletext=$ttext WHERE tableid=$t ableid tablename=$tname c 取出時請用 stripslashes($str) Q3MySQL root 密碼忘了該怎麼辦 Ans 1先停掉 mysql etcrcdinitdmysql stop 2以--skip-grant-table 的參數啟動 mysql safe_mysql --skip-grant-tableamp 3 更改 root 密碼 mysql mysql mysqlgt UPDATE user SET password=password(newpassword)

69

WHERE user=root mysqlgt FLUSH PRIVILEGES mysqlgt exit 4停掉 mysql再重跑 mysqladmin -uroot -p shutdown Enter password 輸入新設定的密碼 etcrcdinitdmysql start

Q4NULL值問題

Ans

NULL值的概念是造成 SQL的新手的混淆的普遍原因他們經常認為 NULL是和一個空字符串的一樣的東西不是這樣的例如下列語句是完全不同的

mysqlgt INSERT INTO my_table (phone) VALUES (NULL)

mysqlgt INSERT INTO my_table (phone) VALUES ()

兩個語句把值插入到 phone 列但是第一個插入一個 NULL值而第二個插入一個空字符串第一個的含義可以認為是ldquo電話號碼不知道而第二個則可意味

著ldquo她沒有電話

在 SQL中NULL值在于任何其他值甚至 NULL值比較時總是假的(FALSE)包含 NULL的一個表達式總是產生一個 NULL值除非在包含在表達式中的運算符和函數的文檔中指出在下列例子所有的列返回 NULL

mysqlgt SELECT NULL1+NULLCONCAT(InvisibleNULL)

如果你想要尋找值是 NULL的列你不能使用=NULL測試下列語句不返回任

何行因為對任何表達式expr = NULL是假的

mysqlgt SELECT FROM my_table WHERE phone = NULL

要想尋找 NULL值你必須使用 IS NULL測試下例顯示如何找出 NULL電話號碼和空的電話號碼

70

mysqlgt SELECT FROM my_table WHERE phone IS NULL mysqlgt SELECT FROM my_table WHERE phone =

在 MySQL中就像很多其他的 SQL服務器一樣你不能索引可以有 NULL值的列你必須聲明這樣的列為 NOT NULL而且你不能插入 NULL到索引的

列中

當用 LOAD DATA INFILE 讀取數據時空列用更新如果你想要在一個列中有

NULL值你應該在文本文件中使用N字面上的詞NULL也可以在某些情形下使用

當使用 ORDER BY時首先呈現 NULL值如果你用 DESC以降序排序NULL值最後顯示當使用 GROUP BY時所有的 NULL值被認為是相等的

為了有助于NULL的處理你能使用 IS NULL和 IS NOT NULL運算符和 IFNULL()函數

對某些列類型NULL值被特殊地處理如果你將 NULL插入表的第一個TIMESTAMP 列則插入當前的日期和時間如果你將 NULL插入一個AUTO_INCREMENT 列則插入順序中的下一個數字

Q5如何將圖片存放於 MySQL中

Ans

Step 1建立資料庫 test

Step 2 建立表格 binary_data

CREATE TABLE binary_data (

id INT(4) NOT NULL AUTO_INCREMENT PRIMARY KEY

description CHAR(50)

bin_data LONGBLOB

filename CHAR(50)

filesize CHAR(50)

filetype CHAR(50)

71

)

Step 3 利用 storephp 寫入圖片

storephp 程式碼

ltHTMLgt ltHEADgtltTITLEgtStore binary data into SQL DatabaseltTITLEgtltHEADgt ltBODYgt lt code that will be executed if the form has been submitted

if ($submit) mysql_connect(localhostrootYOUR_PASSWORD) mysql_select_db(test) $data=Base64_Encode(fread(fopen($form_data r) filesize($form_data))) $result=MYSQL_QUERY(INSERT INTO binary_data (descriptionbin_datafilenamefilesizefiletype) VALUES ($form_description$data$form_data_name$form_data_size$form_data_type)) $id= mysql_insert_id() print ltpgtThis file has the following Database ID ltbgt$idltbgt MYSQL_CLOSE() else else show the form to submit new data

gt

ltform method=post action=ltphp echo $PHP_SELF gt enctype=multipartform-datagt File Descriptionltbrgt ltinput type=text name=form_description size=40gt ltINPUT TYPE=hidden name=MAX_FILE_SIZE value=4000000gt ltbrgtFile to uploadstore in databaseltbrgt ltinput type=file name=form_data size=40gt ltpgtltinput type=submit name=submit value=submitgt ltformgt lt

72

gt ltBODYgt ltHTMLgt

Step 3 利用 storephp 取出圖片

getdataphp 程式碼

lt Syntax getdataphp3id=ltidgt if($id) you may have to modify login information for your database server MYSQL_CONNECT(localhostrootYOUR_PASSWORD) mysql_select_db(test) $query = select bin_datafiletype from binary_data where id=$id $result = MYSQL_QUERY($query) $data = Base64_Decode(MYSQL_RESULT($result0bin_data)) $type = MYSQL_RESULT($result0filetype) Header( Content-type $type) echo $data gt

Q6MySQL裝好之後啟動時或是執行 mysqladmin會出現如下訊息 Cant connect to local MYSQL Server through Socket varlibmysqlmysqlsock或是

Cant connect to local MYSQL Server through Socket tmpmysqldsock

Ans 可能有下列幾個原因

1這個 mysqldsock 不見了被某人刪除了或是被一些系統自動執行程式給刪

了例如有些 cron任務便會設定定期刪除 tmp 裡的東西所以呢您只能修改

cron 裡的設定讓它不要清除 mysqldsock 2在啟動時也可以改變 mysqldsock的位置您在啟動 MySQL的時候可以加入此參數usrlocalmysqlbinsafe_mysqld --user=mysql --socket=其他路

徑socket amp 同時得去設定環境變數 MYSQL_UNIX_PORT的值以指定新的

73

路徑 3若是您沒改 MYSQL_UNIX_PORT的值那麼您可以在執行指令的時候才打

例如mysqladmin --socket=其他路徑socket version Q7How to get the last insert id Ans CREATE TABLE product ( id INT(4) NOT NULL AUTO_INCREMENT PRIMARY KEY description VARCHAR(50) ) 1利用 SQL的話 mysqlgt insert into product(description) values(123) Query OK 1 row affected (000 sec) mysqlgt select last_insert_id() +------------------+ | last_insert_id() | +------------------+ +------------------+ 1 row in set (000 sec) ======================================== 2如果是 PHP的話 你可以用mysql_insert_id()取得該 id PHP example $result=MYSQL_QUERY(INSERT INTO product (description) VALUES ($description)) $id= mysql_insert_id() print This file has the following Database ID $id Q8如何將文字檔匯入資料庫 Ans $addr=homehttpdhtmlphpschool001txt $sql_select = load data infile $addr into table test fields terminated by t 解說 $sql_select = load data infile 文字檔名 into table 表格名 fields terminated by

74

t

(欄位分隔以 TAB鍵) 該文字檔須與資料表欄位格式相符 例如欄位有三個 則文字檔為每行一筆資料如下 欄 1資料ltTABgt欄 2資料ltTABgt欄 3資料 欄 1資料ltTABgt欄 2資料ltTABgt欄 3資料 欄 1資料ltTABgt欄 2資料ltTABgt欄 3資料 欄 1資料ltTABgtltTABgt欄 3資料

Q9如何撰寫 MySQL C API Ans Step 1利用文字編輯器撰寫以下程式碼 mysqlcc

include ltstdiohgt

include ltmysqlmysqlhgt

int main (int argc char argv[])

MYSQL mysql

MYSQL_RES res

MYSQL_ROW row

if (argc = 2)

fputs (Usage myc ltdatabasegt stderr)

return 1

if ((mysql_connect(ampmysqllocalhostrootYour_Password)))

fputs (Error connecting stderr)

abort()

75

if (mysql_select_db(ampmysqlargv[1]))

fputs (Error selecting database stderr)

abort()

if (mysql_query(ampmysqlSELECT FROM test_table))

fputs (Error processing query stderr)

abort()

if ((res = mysql_store_result(ampmysql)))

fputs (Error storing results stderr)

abort()

while((row = mysql_fetch_row(res)))

uint i = 0

for (i=0 i lt mysql_num_fields(res) i++)

printf(s row[i])

printf(n)

return 0

Step 2 Compile

gcc -Iusrlocalmysqlinclude -Lusrlocalmysqllibmysql mysqlcc ndashlm -lmysqlclient

(其中 include path與 library path取決於你的 MySQL安裝路徑)

76

如果執行時發生如下 error Run problemerror in loading shared libraries libmysqlclientsoX 將你的 MySQL library path(for exampleusrlocalmysqllibmysql) 加入etcldsoconf and run sbinldconfig -v Q9ASP + MySQL 範例程式 Ans Dim myconn As New ADODBConnection Dim myrs As New Recordset Dim mySQL As String Dim myrows As Long myconnOpen DSN=MyODBCsample mySQL = SELECT from user myrsSource = mySQL Set myrsActiveConnection = myconn myrsCursorLocation = adUseClient myrsOpen myrows = myrsRecordCount myrsClose myconnClose 可參考 httpwwwdwamnetmysqlasp_myodbcasp 有詳細的資料 Q10如何將 MySQL中的資料庫匯出成txt檔 Ans select from TableName into outfile textxls all result fields will seperate by tab

77

第八章 參考資料

英文部份 網址 1 httpwwwmysqlcom MySQL 網站有第一手有關 MySQL的資料 2 httpwwwmysqlcomdocenReplicationhtml 有關 MySQL Replication 的文件 3 httpwwwgeocitiescomsqlhomefaqstore_blobhtml 如何在 MySQL 存放 BLOB的資料 4httpwwwsapdborg 有關 SAP跟 MySQL相關合作的網站 書藉 1 Cooking with MySQL

Paul DuBois has selected sample recipes from the hundreds youll find in his book MySQL

Cookbook In this third and final series of excerpts showcasing these recipes learn how to

compute team standings how to calculate the differences between successive Dec 26

2002 2 Tips for Building Web Database Applications with PHP and MySQL by Hugh E Williams co-author of Web Database Applications with PHP amp MySQL 04042002

3 Managing and Using MySQL 2nd Edition By Tim King George Reese Randy Jay Yarger

4 MySQL Cookbook By Paul DuBoisPublisher OReillyPub Date October 2002

中文部份

78

1 httplinuxtncedutwtechdocmysqlmysql_docmanual_tochtml MySQL 中文手冊 2 httpchenshloxaedutwphpZ_1php PHP+MySQ程式研習設計網站 3 httplinuxtncedutwtechdocbanicdownhtml PHP 4 手冊 4 httpwwwtncedutwadmin_zonephp台南縣教育網網路中心有很多 Linux相關文件 5 httpdobtncedutw網站建置百寶箱有很多 PHP MySQL 相關範例程式 5 httpwwwdbworldcomtw資料庫專家電子雜誌介紹資料庫的重要觀念及名詞

79

附錄一 SQL Command 介紹

SQL (讀音ess-que-el) 是一種結構查詢語法SQL 使用於資料庫交流

傳遞相容於 ANSI (American National Standards Institute) 是一套標準的關聯

式資料庫語言 SQL 語言是執行更新或從資料系統獲取資料一般常見的關聯

資料庫系統都有提供 SQL 如 Oracle Sybase Microsoft SQL Server Access Ingres 等雖然大部份的資料庫都有提供 SQL 但也多提供了自已獨特的語

法造成了不相容的情形但標準基本的語法是相通的如Select Insert Update Delete Create and Drop 每一個系統都有支援

Table相關 Command

Create Table

關聯式資料庫包含有很多元件稱為資料表(tables) 把資料或訊息放在資

料表中 資料表是以不同的名稱做分別資料表由欄列所構成的二維陣列

欄包含欄位名資料型態 及其他可判斷的資訊列是由全部欄位構成一筆一

筆的紀錄 create table 語法用在建立一個新的資料表語法格式如下

create table tablename (column1 data type column2 data type column3 data type)

Format of create table if you were to use optional constraints

create table tablename (column1 data type [constraint] column2 data type [constraint] column3 data type [constraint]) [ ] = optional

Note You may have as many columns as youd like and the constraints are optional

80

Example

create table employee (first varchar(15) last varchar(20) age number(3) address varchar(30) city varchar(20) state varchar(20))

注意建立資料表格式要以括號把前後框住而最後以(分號)做結尾

欄位名不要超過 30個字元長而且不要使用 sql 的關鍵字(如 where select等)而在後面接是型態的宣告(如字串數字日期格式等)

資料型態是來描述欄位的方式如一個欄位Last_Name 是一個姓氏可以使用varchar (可變動長度字串) 資料型態

以下是幾個常見的資料庫型態 char(size) 固定長度字串最長為 255 位元 varchar(size) 變動長度字串最大字元數以 size 來指定 number(size) 數值格式可以是整數也可以是小數最大數字以 size 位數判

斷未指定小數位數由系統內定 date 日期格式 number(sized) 數值格式最大數字以 size 位數判斷d 為小數位數整數位

數為 size-d 位

有何限制當資料表被建立通常有一或數個欄位是要使用來做關聯的功

能 例如unique 限制(唯一值)兩筆記錄不可以相同的值 not null (非空值)該欄位一定要輸入資料不可是空的primary key (主鍵)是每一筆記錄識別的主要方式

Drop a table drop table 刪除資料表(其中的資料也會一併刪除)

drop table tablename

Example

81

drop table 和刪除全部資料是不同的刪除全部資料欄位名稱資訊等還會

存在但刪除資料表會把這一些也一併移除掉

如何查詢資料

Select 基本用法

select 語法是關連式資料庫最常用的部份可以取得你想要的資料這是一個

簡單的範例 select column1[column2etc] from tablename [where condition] [] = optional 在 select 之後所列欄位名則是要顯示的資料部份你可以一一列出各欄位

名或是以 (星號)來代表選擇全部的欄位 from 之後放資料表名稱 where 子句 (選項) 指定要過濾的條件符合者才會顯現 where 可使用的條件運算元 = 等於 gt 大於 lt 小於 gt= 大或等於 lt= 小或等於 ltgt 大相等 LIKE 相似 For example select first last city

82

from empinfo where first LIKE Er 以Er 為開頭的字串就符合要以單引號框住 Or you can specify select first last from empinfo where last LIKE s 最後一字為 S 就符合 select from empinfo where first = Eric 則表示 first name 一定要是 Eric 才可以 範例資料表empinfo 統計函數

MIN 傳回指定欄位最小值

MAX 傳回指定欄位最大值

SUM 傳回指定欄位總和

AVG 傳回指定欄位平均值

COUNT 傳回指定欄位的筆數

COUNT() 傳回資料庫中的總筆數

統計函數使用於資料表中的數值欄位配合 SELECT 語法使用 只用於總結特定單一欄位可以配合 GROUP BY 做篩選但也可以不使用 GROUP BY 語句For example

SELECT AVG(salary) FROM employee

83

傳回全部 salary 平均值

Another example

SELECT AVG(salary) FROM employee WHERE title = Programmer

傳回 salary 平均值條件為 employees 資料表中當 title 等於 Programmer

Example

SELECT Count() FROM employees

傳回 employees 資料表中紀錄總筆數

GROUP BY 語法 SELECT column1 SUM(column2) FROM list-of-tables GROUP BY column-list The GROUP BY 語句可以先以所列的欄位為條件分組排序在一起(可以多欄

位) example 要列出每一個 dept 中最高 salary 值 SELECT max(salary) dept FROM employee GROUP BY dept HAVING 語法

SELECT column1 SUM(column2) FROM list-of-tables GROUP BY column-list HAVING condition

HAVING 子句是 GROUP BY 的一部份用來過濾在 GROUP BY 所選出的資料功能如同 select 命令中 where 條件式一樣只是 HAVING 必需配合 GROUP BY 使用

我們以例子來說明我們要取得每一公司名及每一公司的薪水平均值輸入如下

84

SELECT dept avg(salary) FROM employee GROUP BY dept

但如果我們只列出薪資平均值超過 20000元的公司資料

SELECT dept avg(salary) FROM employee GROUP BY dept HAVING avg(salary) gt 20000

ORDER BY子句語法

SELECT column1 SUM(column2) FROM list-of-tables ORDER BY column-list [ASC | DESC]

[ ] =選項

ORDER BY是一個選項子句當你以排序方式來顯示資料(正向由小到大反向由大到小)以指定的欄位資料做排序

ASC = 正向- 預設值 DESC = 反向排序

For example

SELECT employee_id dept name age salary FROM employee_info WHERE dept = Sales ORDER BY salary

以上列出公司代號公司名銷售員人名年紀及薪資而條件是公司名為 Sales 顯示順序以薪資多少排序(由小到大為預設值)

如果要以多個欄位做排序要以逗號做分隔如下

SELECT employee_id dept name age salary FROM employee_info WHERE dept = Sales ORDER BY salary age DESC

85

結合條件及布林運算 SELECT column1 SUM(column2) FROM list-of-tables WHERE condition1 AND condition2 AND運算可以結兩個或以上的條件放在 WHERE子句中 兩者都要為真才

會顯示該筆記錄 OR 運算可以結兩個或以上敘述放在 WHERE子句中只要其中一個為直就

會顯示該筆記錄 For example SELECT employeeid firstname lastname title salary FROM employee_info WHERE salary gt= 5000000 AND title = Programmer 必需要薪資大於等於 50000而且職稱為 Programmer同時符合才會顯示該筆資料 以下以括號括住雖然不是必需的但如此比較容易讀 SELECT employeeid firstname lastname title salary FROM employee_info WHERE (salary gt= 5000000) AND (title = Programmer) 另外範例 SELECT firstname lastname title salary FROM employee_info WHERE (title = Sales) OR (title = Programmer) 條件為只要是 Sales 或 Programmer 職稱的就會被列出 IN and BETWEEN 子句

SELECT column1 SUM(column2) FROM list-of-tables WHERE column3 IN (list-of-values) SELECT column1 SUM(column2) FROM list-of-tables WHERE column3 BETWEEN value1 AND value2 IN 子句使用在列舉項目的使用上也就是分別測試是否符合所列的值 For example

86

SELECT employeeid lastname salary FROM employee_info WHERE lastname IN (Hernandez Jones Roberts Ruiz) 條件為姓氏(astname)要符合 Hernandez Jones Roberts or Ruiz 其中一個才會被傳回 IN運算元也可以使用 OR 的語法來取代如下結果相同 SELECT employeeid lastname salary FROM employee_info WHERE lastname = Hernandez OR lastname = Jones OR lastname = Roberts OR lastname = Ruiz 但使用 IN 句子比較短也比較易懂 你也可以使用 NOT IN 來去掉不要的記錄 BETWEEN 運算元使用在判斷是否存在兩個數值之間 For example SELECT employeeid age lastname salary FROM employee_info WHERE age BETWEEN 30 AND 40 傳回年紀 30歲到 40歲之間的資料(含 30及 40歲者) 相同的也可以使用以下語法來達到相同的結果 SELECT employeeid age lastname salary FROM employee_info WHERE age gt= 30 AND age lt= 40 你也可使用 NOT BETWEEN 來濾掉中間值的資料 數學運算 標準 ANSI SQL-92 提供以下運算

87

+ 加

- 減

餘數

餘數為除法後剩整數這不在標準的 ANSI SQL 中但大部份的資料庫都會支

援這運算元以下列出有用的函數雖不在 ANSI SQL-92 提供但一般資料庫

也會支援他們

ABS(x) 傳回 x 絕對值

SIGN(x) returns the sign of input x as -1 0 or 1 (negative zero or positive respectively)

MOD(xy) 餘數 - returns the integer remainder of x divided by y (同 xy)

FLOOR(x) 傳回小或等於 x 的最大整數值

CEILING(x) or CEIL(x)

傳回大或等於 x 的最小整數值

POWER(xy) x的 y 次方

ROUND(x) 把 x 四捨五入為整數

ROUND(xd) 四捨五入取到小數 d 位

SQRT(x) x 開平方

For example SELECT round(salary) firstname FROM employee_info 傳回薪資取到整數位

如何新增資料

insert 加入一筆新紀錄到資料表中 insert into tablename (first_columnlast_column) values (first_valuelast_value) [] = optional Example insert into employee

88

(first last age address city state) values (Luke Duke 45 2130 Boars Nest Hazard Co Georgia) Note 字串要以單引號住如string 數字框住也無妨 insert into 後面接資料表名稱再接以括號括住的欄位名在 values 後括號分別對映各欄位的值 以上的例子新增了一筆名(first) 為 Luke而住所(state) 為 Georgia 的資料

如何刪除資料

delete 可以刪除單筆或多筆紀錄 delete from tablename where columnname OPERATOR value [and|or column OPERATOR value] [ ] = optional Examples delete from employee Note 如果你沒有指定 where 子句那麼全部的紀錄都會被刪除 delete from employee where lastname = May delete from employee where firstname = Mike or firstname = Eric delete from 接著資料表名 再接著是條件式判斷沒有條件式則全部紀錄會

被刪除

如何更新資料

update 用來更新你所指定的記錄要和 WHERE 配合小心使用 語法 update tablename set columnname = newvalue[nextcolumn = newvalue2] where columnname OPERATOR value [and|or column OPERATOR value] [] = optional Examples

89

update phone_book set area_code = 623 where prefix = 979 update phone_book set last_name = Smith prefix=555 suffix=9292 where last_name = Jones update employee set age = age+1 where first_name=Mary and last_name=Williams

90

附錄二Replication

測試環境

RedHat 90 + MySQL 32358 MySQL資料庫路徑 varlibmysql MySQL設定檔 etcmycnf Master IP 1921680100 Slave IP 1921680200 請至下列網址下載最新MySQL 32358套件並利用rpm ndashUvh 更新 httpupdatesredhatcom9enosi386

圖 最新 MySQL 套件

測試架構圖

91

1921680100

1921680200Master Server

erveSlave S r

圖 測試架構圖

測試步驟

Master server 部份 Step1 確認 MasterSlave機器上所裝的 MySQL版本能進行

replication( 32329 or higher ) Step2 在 Master MySQL上開放一個帳號給 Slave mysql ndashu root ndashp mysqlgtGRANT FILE ON TO repl1921680200 IDENTIFIED BY lsquoabc123rsquo mysqlgtq 上面是 Master開放一個帳號 repl密碼 abc123給 IP1921680200有檔案處理

的權限 Step3 shutdown MySQL on the Master mysqladmin ndashu root ndashp shutdown Step4 備份 Master所有資料庫 tar ndashcvf tmpmysql-snapshottar varlibmysql 注意tar的時候MySQL是要在 stop情況下 在mysql (wwwmysqlcom) 網站的FAQ有不用shutdown的方法

92

Step5 在 master機器上修改etcmycnf 在[mysqld]區段內加入參數 log-bin server-id=這邊設定 server-id=1 sql-bin-update-same binlog-do-db=CRM只針對 CRM資料庫做紀錄 Step6 Restart MySQL on the master service mysqld start 此時因為有加入 log-bin 參數因此開始有 index產生了在varlibmysql目錄下

有index檔案紀錄資料庫的異動 log Slave server 部份 Step1 在 slave設定etcmycnf 在[mysqld]區段加入 master-host= master-user= master-password= master-port= server-id= 這邊設定 master-host=1921680100 master-user=repl master-password=abc123 master-port=3306 server-id=2 master-connect-retry=60預設重試間隔 60秒 replicate-do-db=CRM告訴 slave只做 CRM資料庫的更新 log-slave-updates Step2 將 master上的 mysql-snapshottar copy到 slave上 用 ftp傳到 slave的tmp Step3 解壓縮 Master資料庫至 Slave Server上 cd varlib tar xvf tmpmysql-snapshottar chown ndashR mysqlmysql mysql

93

chmod ndashR 770 mysql (視情況) Step4 Restart MySQL on the slave server 這時在varlibmysql目錄會出現 masterinfo此檔案紀錄了 Master MySQL server的資訊

狀況測試

One-way replication

1921680100

1921680200Master Server

erveSlave S r

圖 One-way replication架構圖 Step1 Master跟 Slave網路及服務都正常情況下由 Master端異動資料後 到 Slave端瀏覽資料檢視是否有進行 replication Step2 模擬 Slave Server 當機 可用在於 slave真的當機或是 Slave 不一定需要一直跟 master connect將Slave MySQL server shutdown由 Master端異動資料到 slave端瀏覽此時Slave應該沒有被 replication 更新然後再將 Slave端 MySQL server start起來

預設 60秒後 Slave會嘗試跟 Master要求進行 replication再去 Slave端檢視是否有更新資料

94

Step3 模擬 Master當機因為是設定 One-way replication一旦 Master Server Slave端沒有 Master的 source可以 download Two-way replication 基於 Master當機狀況於是發展雙向 Replication即 1921680100 ( Host A ) 1921680200 ( Host B )都分別擔任 MasterSlave身分

1921680100

1921680200er

Server B MasterSlave Server

Server A MasterSlave Serv

圖 Two-way replication架構圖 以下是針對兩台 MySQL伺服器進行雙向 Replication Step1觀念同單向 replication只是改成 Master也有 Slave身分 Slave也有Master的身分先分別在 Server AServer B 都去 grant一個進行 replication的身分 [A]mysqlgtGRANT FILE ON TO repl1921680200 IDENTIFIED BY lsquoabc123rsquo [B]mysqlgt GRANT FILE ON TO repl1921680100 IDENTIFIED BY lsquoabc123rsquo Step2做完單向 replication後stop Server Aserver B MySQL service此時 AB資料是一樣的

95

修改etcmycnf設定 範例 Server A [mysqld] datadir=varlibmysql socket=varlibmysqlmysqlsock server-id=1 log-bin sql-bin-update-same binlog-do-db=CRM master-host=1921680200 master-user=repl master-password=abc123 log-slave-updates master-connect-retry=60 replicate-do-db=CRM Server B [mysqld] datadir=varlibmysql socket=varlibmysqlmysqlsock server-id=2 log-bin sql-bin-update-same binlog-do-db=CRM master-host=1921680100 master-user=repl master-password=abc123 log-slave-updates master-connect-retry=60 replicate-do-db=CRM 分別 start Server AServer B MySQL後此時雙方都是 MasterSlave身分一旦哪一方資料異動就會通知對方來 replication-若 replication失效則必須將Server AServer B的masterinfo及index00x 都砍掉然後分別 restart MySQL server進行測試檢視成果 實務上通常如果需要做Two-way replication通常會搭配Virtual Server使用

96

在前端架設一台Virtual Server不過此部份不在此份SOP討論範圍內有興趣

的讀者可參考 httpwwwlinuxvirtualserverorg 網站

1921680100 1921680200

Host A MasterSlave Server

Host B MasterSlave Server

Virtual Host

圖 Virtual Server + Two-way replication 架構圖

97

圖 High Availability Linux Virtual Server架構圖

98

  • COSA-SOP-03-006
  • 第一章 簡介
    • 11適用對象 (Audience)
    • 12 MySQL本身
    • 13 MySQL 40版跟50版重大的改進功能
    • 14 各家資料庫軟體比較
      • 第二章 前置需求
      • 第三章 安裝
        • 31 MySQL安裝
        • 32 phpMyAdmin安裝
        • 33 升級及注意事項
          • 第四章 MySQL管理
            • 41 Webmin 管理介面
            • 42 phpMyAdmin 的操作介面
            • 43管理指令介紹
              • 431 利用mysqladmin設定root的密碼
                  • 第五章 實用範例
                    • 51 任務一Web Base客戶通訊錄
                    • 52 任務二Web Base群組軟體 ( twig )
                      • 第六章 維護及更新程序
                        • 61 日常維護
                        • 62 更新程序
                        • 63 備份重要檔案
                        • 64 離線備份與還原
                        • 65 線上備份與還原
                          • 第七章 問題與解答
                          • 第八章 參考資料
                          • 附錄一 SQL Command 介紹
                          • 附錄二Replication
Page 34: DataBase Server Standard Operation Procedureebooks.lib.ntu.edu.tw/1_file/oss/63/93doc4-5.pdf · 業務的公司帶來了不少壓力,譬如微軟,甲骨文 ... 外的錢用在第三方的資料庫產品上,譬如就可以不用再購買甲骨文公司

圖 4-11 新增資料

圖 4-12

34

圖 4-13

413 使用者管理

接下來我們要利用Webmin 來建立資料庫使用者並給予某些權限 Step1建立使用者

35

圖 4-14 選擇使用者權限

圖 4-15

36

Step2 賦予權限

圖 4-16

Step3 權限列表

37

圖 4-17

38

42 phpMyAdmin 的操作介面

421建立資料庫

Step 填入資料庫名稱並按「建立」

圖 4-18建立資料庫

422 建立資料表

Step1 填入資料表名稱並指定欄位數量 執行

39

圖 4-19填入資料表名稱並指定欄位數量

Step2 設定欄位屬性

圖 4-20設定欄位屬性

40

Step3 phpMyAdmin會產生相關的 SQL Command

圖 4-21 資料表結構及相關 SQL Command

Step4新增 Record

41

圖 4-22

圖 4-23

42

圖 4-24

圖 4-25

43

423使用者管理

Step1建立使用者

圖 4-26

44

圖 4-27

Step2 給予權限

圖 4-28

Step3權限列表

45

圖 4-29

43管理指令介紹

431 利用 mysqladmin設定 root的密碼

當您在Windows 或 Linux 中安裝好 MySQL後系統會自動幫您建立兩個

帳分別是 root 和 匿名者MySQL的 root 跟 Linux 最高權限使用者 root無關MySQL的 root使用者相當於 MS SQL 中的 sa 帳號擁有最高的 Database管理權限但系統預設 MySQL的 root 是不需要密碼所以通常我們一安裝

MySQL後首要任務便是修改 root的密碼 我們可以利用 mysqladmin工具或是直接修改 MySQL內部資料庫的使用者資

料 mysqladmin ndashu root ndashh cosaexamplecom password lsquo1234rsquo

46

-u 表示使用者帳號root 為 MySQL預設的管理帳號

-h 表示 MySQL主機的主機名稱也可使用 IP Address password 表示使用者的密碼因為字串請使用單引號將密碼括起來 密碼設定完成之後還是可以利用 mysqladmin修改密碼但是你必須提供目前的密碼

432 連線 MySQL

mysql -uroot -p密碼 (-p和密碼之間不能有空白) 或 mysql -uroot -p (此方式會在進入後要求密碼) [rootossc phpMyAdmin] mysql -u root -p1234

Welcome to the MySQL monitor Commands end with or g

Your MySQL connection id is 25 to server version 32354

Type help or h for help Type c to clear the buffer

mysqlgt show databases

+----------+

| Database |

+----------+

| mysql |

| test |

+----------+

2 rows in set (000 sec)

mysqlgt exit

Bye

[rootossc phpMyAdmin]

433 建立資料庫

可利用 mysqladmin指令建立 CONTACT資料庫 mysqladmin -u root -p1234 create CONTACT

47

或是利用 mysql指令 [rootossc bluepage] mysql -u root -p1234 Welcome to the MySQL monitor Commands end with or g Your MySQL connection id is 1057 to server version 32354 Type help or h for help Type c to clear the buffer mysqlgt create database CONTACT Query OK 1 row affected (000 sec) mysqlgt show databases +----------+ | Database | +----------+ | CONTACT | | address | | hello | | mysql | | nuke | | test | +----------+ 6 rows in set (000 sec) mysqlgt exit

434 建立資料表

編寫 adresssql內容如下 -- Table structure for table address CREATE TABLE address ( id int(11) NOT NULL auto_increment name varchar(20) NOT NULL default tel varchar(15) NOT NULL default PRIMARY KEY (id) ) TYPE=MyISAM

48

-- Dumping data for table address INSERT INTO address VALUES (1林小明0800016888) INSERT INTO address VALUES (2黃大雄0800016888) INSERT INTO address VALUES (3劉小芬0800024365) 然後執行此 sql script mysql -u root -p1234 CONTACT lt addresssql 或是利 mysql command [rootossc bluepage] mysql -u root -p1234 Welcome to the MySQL monitor Commands end with or g Your MySQL connection id is 1090 to server version 32354 Type help or h for help Type c to clear the buffer mysqlgt use CONTACT Database changed Database changed mysqlgt CREATE TABLE address ( -gt id int(11) NOT NULL auto_increment -gt name varchar(20) NOT NULL default -gt tel varchar(15) NOT NULL default -gt PRIMARY KEY (id) -gt ) TYPE=MyISAM Query OK 0 rows affected (000 sec) mysqlgt INSERT INTO address VALUES (1林小明0800016888) Query OK 1 row affected (000 sec) mysqlgt INSERT INTO address VALUES (2黃大雄0800016888) Query OK 1 row affected (000 sec) mysqlgt INSERT INTO address VALUES (3劉小芬0800024365) Query OK 1 row affected (000 sec) mysqlgt exit Bye

49

第五章 實用範例

51 任務一Web Base客戶通訊錄

任職於開放科技公司的林小明前些日子在最符合成本效益的條件下快

速地完成公司網站的建置老闆因此對小明讚譽有加最近因為公司存放客戶資

料的 SQL Server主機屢遭病毒攻擊加上作業系統本身的問題當機次數頻繁

老闆希望能儘快把公司的客戶通訊錄程式移轉到較穩定的環境上因為此客戶通

訊錄程式最主要給內部人員使用所以介面美觀並不特別要求只求穩定且能快

速得到查詢結果老闆希望在短時間先看到程式的雛型並鍵入資料對其效率

及穩定性進行測試因為上次小明表現突出所以這次不可能的任務自然又落到

小明身上 小明想來想去既然要快速又穩定他而且又不希望所有人都得安裝 Client

程式於是小明決定)捨棄他的舊愛「Delphi+MS SQL」投向新歡「Apache + MySQL + PHP」利用此架構來設計一個簡單實用的Web Base客戶通訊錄程式

511 Web Base客戶通訊錄架構

此程式需要建立 CONTACT的資料庫並建立 adress Tables其結構如下表建立步驟請參考第三章 欄位名稱 資料型態 長度 說明 id INT (自動編號) 連絡人編號 name varchar文字 20 連絡人姓名 tel Varchar文字 15 連絡人電話 Web Base通訊錄共有下列幾個檔案功能如下表

檔案名稱 說明 Indexhtml Web Base通訊錄首頁 addphp 新增連絡人的 php程式 searchphp 尋找連絡人的 php程式 editphp 具有更新及刪除功能的 php程式

50

我們將這些檔案放至varwwwhtmlbluepage (預設無 bluepage目錄)

512 Web Base通訊錄測試

httpwwwopencombluepage 新增資料

圖 5-1 新增連絡人

圖 5-2 填入資料

51

圖 5-3 新增成功

搜尋及異動資料

圖 5-4 搜尋通訊錄

52

圖 5-5 編輯資料

圖 5-6 更新資料

513 程式內容及說明

lt-- 程式範例indexhtml--gt lthtmlgt ltheadgtlttitlegt通訊錄lttitlegtltheadgt ltbodygt ltcentergt

53

lth2gt通訊錄lth2gtlthrgt lta href=indexhtmlgt通訊錄ltagt | lta href=addphpgt新增連絡人ltagt | lta href=searchphpgt搜尋通訊錄ltagt ltcentergt ltbodygt lthtmlgt lt-- 程式範例addphp --gt lthtmlgt ltheadgtlttitlegt新增連絡人lttitlegtltheadgt ltbodygt ltcentergtlth2gt新增連絡人lth2gtltcentergtlthrgt lt 取得欄位資料 if (isset($_POST[Name]) ampamp isset($_POST[Tel]) ) $name = $_POST[Name] $tel = $_POST[Tel] 檢查是否有輸入欄位資料 if ($name = ampamp $tel = ) 建立 SQL字串 $sql = INSERT INTO address (name tel) values( $sql= $name $tel) 建立 MySQL 連結 $link = mysql_connect(localhostroot1234) 選擇資料庫 mysql_select_db(CONTACT) 執行 SQL指令 mysql_query($sql) mysql_close($link) echo ltfont color=redgt新增連絡人成功ltfontgtltbrgt gt ltform action=addphp method=postgt lttable border=0 width=300gt lttrgtlttdgt姓名 lttdgt

54

lttdgtltinput type=text name=Name size=20 maxlength=10gtlttdgtlttrgt lttrgtlttdgt電話 lttdgt lttdgtltinput type=text name=Tel size=20 maxlength=20gtlttdgtlttrgt lttrgtlttd colspan=2 align=centergt ltinput type=submit value=新增連絡人gtlttdgtlttrgt lttablegt ltformgt ltbrgtlta href=indexhtmlgt通訊錄ltagt | lta href=addphpgt新增連絡人ltagt | lta href=searchphpgt搜尋通訊錄ltagt ltbodygt lthtmlgt

lt-- 程式範例searchphp --gt lthtmlgt ltheadgtlttitlegt搜尋通訊錄lttitlegtltheadgt ltbodygt ltcentergtlth2gt搜尋通訊錄lth2gtlthrgt lt if (isset($_POST[Search])) 建立資料庫連結並選定資料庫 $link = mysql_connect(localhostroot1234) mysql_select_db(CONTACT) 建立基本的 SQL字串 $sql = SELECT FROM address 檢查是否輸入姓名 if (chop($_POST[Name]) = ) $name = name LIKE $_POST[Name] else $name = 檢查是否輸入電話號碼 if (chop($_POST[Tel]) = ) $tel = tel LIKE $_POST[Tel] else $tel =

55

if條件組合 SQL字串 if (chop($name) = ampamp chop($tel) = ) $sql= WHERE $name AND $tel elseif (chop($name) = ) 只有姓名 $sql = WHERE $name elseif (chop($tel) = ) 只有電話號碼 $sql = WHERE $tel $sql= ORDER BY name 最後加上排序 $result = mysql_query($sql) 取得欄位數 $total_fields = mysql_num_fields($result) echo lttable border=1gt echo lttrgtlttdgt編號lttdgtlttdgt姓名lttdgtlttdgt電話lttdgtlttd colspan=2gt功能選項lttdgtlttrgt 表格顯示查詢結果 while ($rows = mysql_fetch_array($result MYSQL_NUM)) echo lttrgt for ($i = 0 $i lt $total_fields $i++) echo lttdgt$rows[$i]lttdgt echo lttdgtlta href=editphpaction=editampid= echo $rows[0]gtltbgt編輯ltbgtlttdgt echo lttdgtlta href=editphpaction=delampid= echo $rows[0]gtltbgt刪除ltbgtlttdgt echo lttrgt echo lttablegtlthrgt mysql_free_result($result) mysql_close($link) gt ltcentergt ltform action=searchphp method=postgt lttable border=0 width=450gt lttrgtlttdgt搜尋姓名 lttdgt lttdgtltinput type=text name=Name size=10 maxlength=20gtlttdgtlttrgt lttrgtlttdgt搜尋電話 lttdgt lttdgtltinput type=text name=Tel

56

size=20 maxlength=20gtlttdgtlttrgt lttrgtlttd colspan=2 align=centergt ltinput type=submit name=Search value=搜尋gtlttdgtlttrgt lttablegt ltformgt ltbrgtlta href=indexhtmlgt通訊錄ltagt | lta href=addphpgt新增連絡人ltagt | lta href=searchphpgt搜尋通訊錄ltagt ltbodygt lthtmlgt

lt ob_start() gt lt-- 程式範例editphp --gt lthtmlgt ltheadgtlttitlegt編輯通訊錄lttitlegtltheadgt ltbodygt lt 取得 URL 參數 $id = $_GET[id] $action = $_GET[action] 建立資料庫連結 $link = mysql_connect(localhostroot1234) mysql_select_db(CONTACT) 選擇資料庫 執行的操作 switch ($action) case update 更新 取得欄位資料 $name = $_POST[Name] $tel = $_POST[Tel] $sql = UPDATE address SET name=$name tel=$tel WHERE id=$id mysql_query($sql) 執行 SQL指令 mysql_close($link) header(Location searchphp) 轉向到 serachphp break case del 刪除 $sql = DELETE FROM address WHERE id=$id

57

mysql_query($sql) 執行 SQL指令 mysql_close($link) header(Location searchphp) 轉向到 serachphp break case edit 編輯 $sql = SELECT FROM address WHERE id=$id $result = mysql_query($sql) 執行 SQL指令 $row = mysql_fetch_row($result) 取回記錄 $name = $row[1] 取得欄位 name $tel = $row[2] 取得欄位 tel mysql_close($link) 顯示編輯表單 gt ltcentergtlth2gt更新通訊錄lth2gtltcentergtlthrgt ltform action=editphpaction=updateampid=lt echo $id gt method=postgt lttable border=0 width=300gt lttrgtlttdgt姓名 lttdgt lttdgtltinput type=text name=Name size=20 maxlength=10 value=lt echo $name gtgtlttdgtlttrgt lttrgtlttdgt電話 lttdgt lttdgtltinput type=text name=Tel size=20 maxlength=20 value=lt echo $tel gtgtlttdgtlttrgt lttrgtlttd colspan=2 align=centergt ltinput type=submit value=更新連絡人gtlttdgtlttrgt lttablegt ltformgt ltbrgtlta href=indexhtmlgt通訊錄ltagt | lta href=addphpgt新增連絡人ltagt | lta href=searchphpgt搜尋通訊錄ltagt lt break gt ltbodygt lthtmlgt

58

52 任務二Web Base群組軟體 ( twig )

順利完成Web Base客戶通訊錄程式測試一段時間後「Apache + MySQL + PHP」架構的穩定與快速巳深得老闆與公司所有同事的認同隨著公司業績蒸

蒸日上人員組織編罝愈來愈龐大跨部門的會議愈來愈多業務員每日排滿拜

訪客戶的行程跟客戶的 Email的往來也愈來愈頻繁 愈來愈多部門的同事希望公司能建置一套群組軟體提供 web mail可讓業

務人員方便收發 mail還有連絡人議事日程待辦工作書簽等功能讓整個

公司運作及個人時間管理更有效率

老闆問小明對這些需求有什麼看法小明認為如果這些功能完全由程式部

門開發必定曠日費時而且耗費公司資源小明在網路尋找是否有提供這些功能

的Free Software皇天不負苦心人小明發現了TWIG (The Web Information Gateway) httptwigscrewdrivernet這個群組軟體它在 Web 上整合郵件新聞聯絡人議事日程工作序書簽等功能非常符合公司的需求 Step 1 下載 twig-277targz 下載網址 httptwigscrewdrivernetdownloadphp3

Step 2 解開 twig-277targz tar -xzvf twig-277targz

59

Step 3 執行安裝動作安裝到 varwwwhtmltwig 目錄 cd twig-277 twig-install varwwwhtmltwig

Step 4 建立 MySQL 資料庫(twig)及各資料表

cd setup mysql -u root -p1234 mysqlgt create database twig Query OK 1 row affected (001 sec) mysqlgt quit mysql -u root ndashp1234 twiglt twigtablemysql

Step 5 修改 configincphp3 參數設定 vi varwwwhtmltwigconfigconfigincphp3 $config[fromdomain] = opencom 網域 $config[language] = chinesebig5 中文訊息 $config[imap_port] = 143notls

60

Step 6 修改連結 MySQL 的帳號密碼 vi varwwwhtmltwigconfigdbconfigincphp3 $dbconfig[sqlusername] = root username $dbconfig[sqlpassword] = 1234 password

Step 7 其他設定檔

vi etchttpdconfhttpdconf 加入 AddType applicationx-httpd-php php3 在 DirectoryIndex最後加入 indexphp3 DirectoryIndex indexhtml indexhtmlvar indexphp3 在 AddDefaultCharset ISO-8859-1加上 AddDefaultCharset ISO-8859-1

vi etcphpini register_globals = On service httpd restart Step 8 sendmail 設定 vi etcmailsendmailcf在 264 行前面加上並重新啟動 sendmail「service snedmail restart」 262 SMTP daemon options 263 264 O DaemonPortOptions=Port=smtpAddr=127001 Name=MTA 265 266 SMTP client options 267 O ClientPortOptions=Family=inet Address=00

61

Step 9 檢查設定有無錯誤 http主機名稱twigtestphp3

62

Step 10 登入 twig ( http主機名稱twig)

63

第六章 維護及更新程序

61 日常維護

系統管理員最好定期以 root 身份登入看看信件在 RedHat Linux 中有一支 logwatch 程式會定時去分析 log file如果發現異常便會發信給 root除此之外筆者建議讀者平時就檢查 MySQL log file ( varlogmysqldlog)是否有異常情形

62 更新程序

讀者可至httprpmfindnet 尋找MySQL相關套件至於升級的相關步驟請參

考Linux OS SOP 第 54節

63 備份重要檔案

預設 MySQL 的 DB 檔案是存在 varlibmysql 內以 DB名稱為目錄目錄

內就是該 DB 的所有資料通常得定期備份還有 MySQL的設定檔 etcmycnf也別忘了一起備份

64 離線備份與還原

641 離線備份

預設 MySQL 的 DB 檔案是存在 varlibmysql 內以 DB 名稱為目錄目錄內

就是該 DB 的所有資料像 CRM 這個 DB就是存在 varlibmysqlCRM 內在備份前因為怕資料尚未完全寫入磁碟而且 MySQL 會 Lock 在使用的 DB 檔案所以應該是要先把 MySQL 先 Shutdown 一下整個備份的程序可以下像下面的指令去完成 cd varlibmysql

64

service mysqld stop tar cvfz CRM_db_20030905tgz CRM service mysqld start 對這樣就可以了 不過要注意的是怕 DB 內每個 Tables 間的資料有關關

聯性所以最好是把整個 DB 一次備起來單獨只備哪個 Tables 的檔案以後回存時怕會有資料關聯不一致的問題

642 離線還原

DB 發生錯誤而要回存時其實也不難先找出最近一次完整正常的備份先把現在錯誤的網頁或 DB 先更名或 tar 起來再把好的備份給解開回原來目錄位

置就行了需要注意的是 MySQL 服務最好也是要先停止回存完成後再啟動服務回存 DB 的整個程序可能像下面 cd varlibmysql service mysqldstop mv CRM CRM_OLD tar xvfz CRM_db_20030905tg service mysqld start

65 線上備份與還原

651 線上備份

使用像上面的檔案方式備份是個不錯的方法它最少可以保持該主機某個時間點的完整檔案備份但還是有一些問題需要考慮到有些主機就不只建立一個 DB 而已總不能為了備份某個 DB 而把整個 MySQL 服務停止備份檔案的方式回存在原主機上一定適用但假如 MySQL 版本升級或是在那天該網頁空間需遷機移機到別的主機時那就沒人敢保證備出來的資料檔可以用所以我們可以考慮另一種備份的方式是使用 MySQL 本身提供的功能 MySQL Data Dump指令是 mysqldump

65

使用 MySQL 的 Dump 功能可以把 DB 的結構資料或結構加資料 Dump 成文字檔 mysqldump 指令提供的彈性很大你可以選擇把整個 DB Dump 成一個檔或是每個 Table 為一個檔甚至是把結構檔和資料分開儲存都

可以 mysqladmin -uroot -p flush-logs mysqldump CRM -uroot -p --opt gt CRM_20030905sql (CRM 是 DB 名稱 opt 是一個使用完整 Dump 參數) 假如只是要單獨 Dump 某個 Table 時只要在上面的指令後轉出符號 gt 前加個 Table 名稱就可以如只要 phpbb2_users 這個 Table 的 Dump 時只要下 mysqldump CRM -uroot -p --opt CUSTOMER gt CRM_CUSTOMER_20030905sql

652 線上還原

若要回存整個資料庫只需將壓縮的備份檔還原成 Dump 的檔案再用下面的指令回存 mysql CRM -uroot -p lt CRM_20030905sql 這邊需注意的是若建立備份時是以--opt或--add-drop-table為參數時回存的 動作是先將舊的 Table 先刪除重建 Table 的結構後再把 Data 匯入所以回存後所有的資料會回到你當時備份那個時間點因此在回存資料時可以考慮把現有錯誤或不完整的 DB 先備份一份下來以備不時之需或是拿來比對錯誤的地

方在那裡當然你也可以把資料回存到另一個測試用的 DB 內只要把上面指令

的 DB 名稱改成你的測試用 DB 名稱即可 使用這種回存方式 MySQL 服務不需停止也不會動到其他正在使用的 DB 在一些提供 MySQL 服務的虛擬主機可用這種方式作你自己的 DB 備份及回存

66

另外假如你是系統重建或是移機時切需在新的 MySQL 內新建一個空白 DB 後才行作回存的工作你可以用下面的指令建立 mysql -uroot -p -e CREATE DATABASE CRM (上面的 CRM是你要新建的 DB 名稱) 另一種作法先用 mysql 指令進入 mysql client console 然後再用 CREATE DATABASE CRM 這樣就行了記得尾端要加個 符號該行指令才會執行

67

第七章 問題與解答

Q1RedHat 90預附的 MySQL到底有無支援 Transcation機制 Ans MySQL自 32334a之後的 MySQL-Max版本加入 InnoDB的資料庫類型透過

InnoDBMySQL同樣可以進行 COMMIT與 ROLLRACK的動作RedHat 90預附的 MySQL為 32354a-11巳支援 InnoDB的資料庫類型不過必須做以

下設定 1cp usrsharedocmysql-server-32354amy-mediumcnf to etcmycnf 2 vi etcmycnf 將以下設定前的拿掉 innodb_data_home_dir = varlibmysql innodb_data_file_path = ibdata110Mautoextend innodb_log_group_home_dir = varlibmysql innodb_log_arch_dir = varlibmysql 3service mysqld restart 如此一來各位在建立Table時便可指定Table Type為 innodb ( ex create table with type=innodb ) Q2如何解決 php+mysql 許功蓋等字變亂的問題 Ans 方法一 【確定 MySQL 預設的字元集】 1 打開 WinMySQLadmin 管理畫面(在視窗右下角狀態列紅綠燈圖示中按滑鼠

右鍵點選 Show me 選項) 2 點選管理畫面中 [Variables] 標籤選項其中 character_set變數就是您預設

字元集的變數其預設是 latin1 字元集(我們要將他改回 big5)而 chatacters_set 變數則是 MySQL 可以支援哪些字元集 【修改預設字元集變數 character_set 】 1 請點選管理畫面中 [myini Setup] 標籤選項設定 myini 2 按一下 [Pick-up and Edit myini values] 按鈕以便編輯目前的 myini 設定 3 在 [mysqld] 設定區塊底下新增一行 default-character-set = big5 變數設

68

定 4 新增一個 [client] 設定區塊並加入第三步驟的變數設定(游標往下移到空白處新增兩行 [client] 和 default-character-set=big5) 5 按一下畫面左下方 [Save Modification] 按鈕儲存設定 6 重新啟動 MySQL 或 Windows 方法二 Server端注意事項 phpini 中有關的設定為(預設值) Magic quotes for incoming GETPOSTCookie data magic_quotes_gpc = On Use Sybase-style magic quotes (escape with instead of ) magic_quotes_sybase = Off Client端注意事項 1中文資料送進 mysql 前請用 addslashes($str) 處理 2處理後送進 mysql 時請用 括起來並在參數後留一個空白如 $sql = UPDATE ezf_table set tablename=$tname tableend=$endtime table inguser=$tguser tableingid=$tguserid tableallnumber=$tnumber tableloca l=$tablelocal tableanyone=$tableopen tabletext=$ttext WHERE tableid=$t ableid tablename=$tname c 取出時請用 stripslashes($str) Q3MySQL root 密碼忘了該怎麼辦 Ans 1先停掉 mysql etcrcdinitdmysql stop 2以--skip-grant-table 的參數啟動 mysql safe_mysql --skip-grant-tableamp 3 更改 root 密碼 mysql mysql mysqlgt UPDATE user SET password=password(newpassword)

69

WHERE user=root mysqlgt FLUSH PRIVILEGES mysqlgt exit 4停掉 mysql再重跑 mysqladmin -uroot -p shutdown Enter password 輸入新設定的密碼 etcrcdinitdmysql start

Q4NULL值問題

Ans

NULL值的概念是造成 SQL的新手的混淆的普遍原因他們經常認為 NULL是和一個空字符串的一樣的東西不是這樣的例如下列語句是完全不同的

mysqlgt INSERT INTO my_table (phone) VALUES (NULL)

mysqlgt INSERT INTO my_table (phone) VALUES ()

兩個語句把值插入到 phone 列但是第一個插入一個 NULL值而第二個插入一個空字符串第一個的含義可以認為是ldquo電話號碼不知道而第二個則可意味

著ldquo她沒有電話

在 SQL中NULL值在于任何其他值甚至 NULL值比較時總是假的(FALSE)包含 NULL的一個表達式總是產生一個 NULL值除非在包含在表達式中的運算符和函數的文檔中指出在下列例子所有的列返回 NULL

mysqlgt SELECT NULL1+NULLCONCAT(InvisibleNULL)

如果你想要尋找值是 NULL的列你不能使用=NULL測試下列語句不返回任

何行因為對任何表達式expr = NULL是假的

mysqlgt SELECT FROM my_table WHERE phone = NULL

要想尋找 NULL值你必須使用 IS NULL測試下例顯示如何找出 NULL電話號碼和空的電話號碼

70

mysqlgt SELECT FROM my_table WHERE phone IS NULL mysqlgt SELECT FROM my_table WHERE phone =

在 MySQL中就像很多其他的 SQL服務器一樣你不能索引可以有 NULL值的列你必須聲明這樣的列為 NOT NULL而且你不能插入 NULL到索引的

列中

當用 LOAD DATA INFILE 讀取數據時空列用更新如果你想要在一個列中有

NULL值你應該在文本文件中使用N字面上的詞NULL也可以在某些情形下使用

當使用 ORDER BY時首先呈現 NULL值如果你用 DESC以降序排序NULL值最後顯示當使用 GROUP BY時所有的 NULL值被認為是相等的

為了有助于NULL的處理你能使用 IS NULL和 IS NOT NULL運算符和 IFNULL()函數

對某些列類型NULL值被特殊地處理如果你將 NULL插入表的第一個TIMESTAMP 列則插入當前的日期和時間如果你將 NULL插入一個AUTO_INCREMENT 列則插入順序中的下一個數字

Q5如何將圖片存放於 MySQL中

Ans

Step 1建立資料庫 test

Step 2 建立表格 binary_data

CREATE TABLE binary_data (

id INT(4) NOT NULL AUTO_INCREMENT PRIMARY KEY

description CHAR(50)

bin_data LONGBLOB

filename CHAR(50)

filesize CHAR(50)

filetype CHAR(50)

71

)

Step 3 利用 storephp 寫入圖片

storephp 程式碼

ltHTMLgt ltHEADgtltTITLEgtStore binary data into SQL DatabaseltTITLEgtltHEADgt ltBODYgt lt code that will be executed if the form has been submitted

if ($submit) mysql_connect(localhostrootYOUR_PASSWORD) mysql_select_db(test) $data=Base64_Encode(fread(fopen($form_data r) filesize($form_data))) $result=MYSQL_QUERY(INSERT INTO binary_data (descriptionbin_datafilenamefilesizefiletype) VALUES ($form_description$data$form_data_name$form_data_size$form_data_type)) $id= mysql_insert_id() print ltpgtThis file has the following Database ID ltbgt$idltbgt MYSQL_CLOSE() else else show the form to submit new data

gt

ltform method=post action=ltphp echo $PHP_SELF gt enctype=multipartform-datagt File Descriptionltbrgt ltinput type=text name=form_description size=40gt ltINPUT TYPE=hidden name=MAX_FILE_SIZE value=4000000gt ltbrgtFile to uploadstore in databaseltbrgt ltinput type=file name=form_data size=40gt ltpgtltinput type=submit name=submit value=submitgt ltformgt lt

72

gt ltBODYgt ltHTMLgt

Step 3 利用 storephp 取出圖片

getdataphp 程式碼

lt Syntax getdataphp3id=ltidgt if($id) you may have to modify login information for your database server MYSQL_CONNECT(localhostrootYOUR_PASSWORD) mysql_select_db(test) $query = select bin_datafiletype from binary_data where id=$id $result = MYSQL_QUERY($query) $data = Base64_Decode(MYSQL_RESULT($result0bin_data)) $type = MYSQL_RESULT($result0filetype) Header( Content-type $type) echo $data gt

Q6MySQL裝好之後啟動時或是執行 mysqladmin會出現如下訊息 Cant connect to local MYSQL Server through Socket varlibmysqlmysqlsock或是

Cant connect to local MYSQL Server through Socket tmpmysqldsock

Ans 可能有下列幾個原因

1這個 mysqldsock 不見了被某人刪除了或是被一些系統自動執行程式給刪

了例如有些 cron任務便會設定定期刪除 tmp 裡的東西所以呢您只能修改

cron 裡的設定讓它不要清除 mysqldsock 2在啟動時也可以改變 mysqldsock的位置您在啟動 MySQL的時候可以加入此參數usrlocalmysqlbinsafe_mysqld --user=mysql --socket=其他路

徑socket amp 同時得去設定環境變數 MYSQL_UNIX_PORT的值以指定新的

73

路徑 3若是您沒改 MYSQL_UNIX_PORT的值那麼您可以在執行指令的時候才打

例如mysqladmin --socket=其他路徑socket version Q7How to get the last insert id Ans CREATE TABLE product ( id INT(4) NOT NULL AUTO_INCREMENT PRIMARY KEY description VARCHAR(50) ) 1利用 SQL的話 mysqlgt insert into product(description) values(123) Query OK 1 row affected (000 sec) mysqlgt select last_insert_id() +------------------+ | last_insert_id() | +------------------+ +------------------+ 1 row in set (000 sec) ======================================== 2如果是 PHP的話 你可以用mysql_insert_id()取得該 id PHP example $result=MYSQL_QUERY(INSERT INTO product (description) VALUES ($description)) $id= mysql_insert_id() print This file has the following Database ID $id Q8如何將文字檔匯入資料庫 Ans $addr=homehttpdhtmlphpschool001txt $sql_select = load data infile $addr into table test fields terminated by t 解說 $sql_select = load data infile 文字檔名 into table 表格名 fields terminated by

74

t

(欄位分隔以 TAB鍵) 該文字檔須與資料表欄位格式相符 例如欄位有三個 則文字檔為每行一筆資料如下 欄 1資料ltTABgt欄 2資料ltTABgt欄 3資料 欄 1資料ltTABgt欄 2資料ltTABgt欄 3資料 欄 1資料ltTABgt欄 2資料ltTABgt欄 3資料 欄 1資料ltTABgtltTABgt欄 3資料

Q9如何撰寫 MySQL C API Ans Step 1利用文字編輯器撰寫以下程式碼 mysqlcc

include ltstdiohgt

include ltmysqlmysqlhgt

int main (int argc char argv[])

MYSQL mysql

MYSQL_RES res

MYSQL_ROW row

if (argc = 2)

fputs (Usage myc ltdatabasegt stderr)

return 1

if ((mysql_connect(ampmysqllocalhostrootYour_Password)))

fputs (Error connecting stderr)

abort()

75

if (mysql_select_db(ampmysqlargv[1]))

fputs (Error selecting database stderr)

abort()

if (mysql_query(ampmysqlSELECT FROM test_table))

fputs (Error processing query stderr)

abort()

if ((res = mysql_store_result(ampmysql)))

fputs (Error storing results stderr)

abort()

while((row = mysql_fetch_row(res)))

uint i = 0

for (i=0 i lt mysql_num_fields(res) i++)

printf(s row[i])

printf(n)

return 0

Step 2 Compile

gcc -Iusrlocalmysqlinclude -Lusrlocalmysqllibmysql mysqlcc ndashlm -lmysqlclient

(其中 include path與 library path取決於你的 MySQL安裝路徑)

76

如果執行時發生如下 error Run problemerror in loading shared libraries libmysqlclientsoX 將你的 MySQL library path(for exampleusrlocalmysqllibmysql) 加入etcldsoconf and run sbinldconfig -v Q9ASP + MySQL 範例程式 Ans Dim myconn As New ADODBConnection Dim myrs As New Recordset Dim mySQL As String Dim myrows As Long myconnOpen DSN=MyODBCsample mySQL = SELECT from user myrsSource = mySQL Set myrsActiveConnection = myconn myrsCursorLocation = adUseClient myrsOpen myrows = myrsRecordCount myrsClose myconnClose 可參考 httpwwwdwamnetmysqlasp_myodbcasp 有詳細的資料 Q10如何將 MySQL中的資料庫匯出成txt檔 Ans select from TableName into outfile textxls all result fields will seperate by tab

77

第八章 參考資料

英文部份 網址 1 httpwwwmysqlcom MySQL 網站有第一手有關 MySQL的資料 2 httpwwwmysqlcomdocenReplicationhtml 有關 MySQL Replication 的文件 3 httpwwwgeocitiescomsqlhomefaqstore_blobhtml 如何在 MySQL 存放 BLOB的資料 4httpwwwsapdborg 有關 SAP跟 MySQL相關合作的網站 書藉 1 Cooking with MySQL

Paul DuBois has selected sample recipes from the hundreds youll find in his book MySQL

Cookbook In this third and final series of excerpts showcasing these recipes learn how to

compute team standings how to calculate the differences between successive Dec 26

2002 2 Tips for Building Web Database Applications with PHP and MySQL by Hugh E Williams co-author of Web Database Applications with PHP amp MySQL 04042002

3 Managing and Using MySQL 2nd Edition By Tim King George Reese Randy Jay Yarger

4 MySQL Cookbook By Paul DuBoisPublisher OReillyPub Date October 2002

中文部份

78

1 httplinuxtncedutwtechdocmysqlmysql_docmanual_tochtml MySQL 中文手冊 2 httpchenshloxaedutwphpZ_1php PHP+MySQ程式研習設計網站 3 httplinuxtncedutwtechdocbanicdownhtml PHP 4 手冊 4 httpwwwtncedutwadmin_zonephp台南縣教育網網路中心有很多 Linux相關文件 5 httpdobtncedutw網站建置百寶箱有很多 PHP MySQL 相關範例程式 5 httpwwwdbworldcomtw資料庫專家電子雜誌介紹資料庫的重要觀念及名詞

79

附錄一 SQL Command 介紹

SQL (讀音ess-que-el) 是一種結構查詢語法SQL 使用於資料庫交流

傳遞相容於 ANSI (American National Standards Institute) 是一套標準的關聯

式資料庫語言 SQL 語言是執行更新或從資料系統獲取資料一般常見的關聯

資料庫系統都有提供 SQL 如 Oracle Sybase Microsoft SQL Server Access Ingres 等雖然大部份的資料庫都有提供 SQL 但也多提供了自已獨特的語

法造成了不相容的情形但標準基本的語法是相通的如Select Insert Update Delete Create and Drop 每一個系統都有支援

Table相關 Command

Create Table

關聯式資料庫包含有很多元件稱為資料表(tables) 把資料或訊息放在資

料表中 資料表是以不同的名稱做分別資料表由欄列所構成的二維陣列

欄包含欄位名資料型態 及其他可判斷的資訊列是由全部欄位構成一筆一

筆的紀錄 create table 語法用在建立一個新的資料表語法格式如下

create table tablename (column1 data type column2 data type column3 data type)

Format of create table if you were to use optional constraints

create table tablename (column1 data type [constraint] column2 data type [constraint] column3 data type [constraint]) [ ] = optional

Note You may have as many columns as youd like and the constraints are optional

80

Example

create table employee (first varchar(15) last varchar(20) age number(3) address varchar(30) city varchar(20) state varchar(20))

注意建立資料表格式要以括號把前後框住而最後以(分號)做結尾

欄位名不要超過 30個字元長而且不要使用 sql 的關鍵字(如 where select等)而在後面接是型態的宣告(如字串數字日期格式等)

資料型態是來描述欄位的方式如一個欄位Last_Name 是一個姓氏可以使用varchar (可變動長度字串) 資料型態

以下是幾個常見的資料庫型態 char(size) 固定長度字串最長為 255 位元 varchar(size) 變動長度字串最大字元數以 size 來指定 number(size) 數值格式可以是整數也可以是小數最大數字以 size 位數判

斷未指定小數位數由系統內定 date 日期格式 number(sized) 數值格式最大數字以 size 位數判斷d 為小數位數整數位

數為 size-d 位

有何限制當資料表被建立通常有一或數個欄位是要使用來做關聯的功

能 例如unique 限制(唯一值)兩筆記錄不可以相同的值 not null (非空值)該欄位一定要輸入資料不可是空的primary key (主鍵)是每一筆記錄識別的主要方式

Drop a table drop table 刪除資料表(其中的資料也會一併刪除)

drop table tablename

Example

81

drop table 和刪除全部資料是不同的刪除全部資料欄位名稱資訊等還會

存在但刪除資料表會把這一些也一併移除掉

如何查詢資料

Select 基本用法

select 語法是關連式資料庫最常用的部份可以取得你想要的資料這是一個

簡單的範例 select column1[column2etc] from tablename [where condition] [] = optional 在 select 之後所列欄位名則是要顯示的資料部份你可以一一列出各欄位

名或是以 (星號)來代表選擇全部的欄位 from 之後放資料表名稱 where 子句 (選項) 指定要過濾的條件符合者才會顯現 where 可使用的條件運算元 = 等於 gt 大於 lt 小於 gt= 大或等於 lt= 小或等於 ltgt 大相等 LIKE 相似 For example select first last city

82

from empinfo where first LIKE Er 以Er 為開頭的字串就符合要以單引號框住 Or you can specify select first last from empinfo where last LIKE s 最後一字為 S 就符合 select from empinfo where first = Eric 則表示 first name 一定要是 Eric 才可以 範例資料表empinfo 統計函數

MIN 傳回指定欄位最小值

MAX 傳回指定欄位最大值

SUM 傳回指定欄位總和

AVG 傳回指定欄位平均值

COUNT 傳回指定欄位的筆數

COUNT() 傳回資料庫中的總筆數

統計函數使用於資料表中的數值欄位配合 SELECT 語法使用 只用於總結特定單一欄位可以配合 GROUP BY 做篩選但也可以不使用 GROUP BY 語句For example

SELECT AVG(salary) FROM employee

83

傳回全部 salary 平均值

Another example

SELECT AVG(salary) FROM employee WHERE title = Programmer

傳回 salary 平均值條件為 employees 資料表中當 title 等於 Programmer

Example

SELECT Count() FROM employees

傳回 employees 資料表中紀錄總筆數

GROUP BY 語法 SELECT column1 SUM(column2) FROM list-of-tables GROUP BY column-list The GROUP BY 語句可以先以所列的欄位為條件分組排序在一起(可以多欄

位) example 要列出每一個 dept 中最高 salary 值 SELECT max(salary) dept FROM employee GROUP BY dept HAVING 語法

SELECT column1 SUM(column2) FROM list-of-tables GROUP BY column-list HAVING condition

HAVING 子句是 GROUP BY 的一部份用來過濾在 GROUP BY 所選出的資料功能如同 select 命令中 where 條件式一樣只是 HAVING 必需配合 GROUP BY 使用

我們以例子來說明我們要取得每一公司名及每一公司的薪水平均值輸入如下

84

SELECT dept avg(salary) FROM employee GROUP BY dept

但如果我們只列出薪資平均值超過 20000元的公司資料

SELECT dept avg(salary) FROM employee GROUP BY dept HAVING avg(salary) gt 20000

ORDER BY子句語法

SELECT column1 SUM(column2) FROM list-of-tables ORDER BY column-list [ASC | DESC]

[ ] =選項

ORDER BY是一個選項子句當你以排序方式來顯示資料(正向由小到大反向由大到小)以指定的欄位資料做排序

ASC = 正向- 預設值 DESC = 反向排序

For example

SELECT employee_id dept name age salary FROM employee_info WHERE dept = Sales ORDER BY salary

以上列出公司代號公司名銷售員人名年紀及薪資而條件是公司名為 Sales 顯示順序以薪資多少排序(由小到大為預設值)

如果要以多個欄位做排序要以逗號做分隔如下

SELECT employee_id dept name age salary FROM employee_info WHERE dept = Sales ORDER BY salary age DESC

85

結合條件及布林運算 SELECT column1 SUM(column2) FROM list-of-tables WHERE condition1 AND condition2 AND運算可以結兩個或以上的條件放在 WHERE子句中 兩者都要為真才

會顯示該筆記錄 OR 運算可以結兩個或以上敘述放在 WHERE子句中只要其中一個為直就

會顯示該筆記錄 For example SELECT employeeid firstname lastname title salary FROM employee_info WHERE salary gt= 5000000 AND title = Programmer 必需要薪資大於等於 50000而且職稱為 Programmer同時符合才會顯示該筆資料 以下以括號括住雖然不是必需的但如此比較容易讀 SELECT employeeid firstname lastname title salary FROM employee_info WHERE (salary gt= 5000000) AND (title = Programmer) 另外範例 SELECT firstname lastname title salary FROM employee_info WHERE (title = Sales) OR (title = Programmer) 條件為只要是 Sales 或 Programmer 職稱的就會被列出 IN and BETWEEN 子句

SELECT column1 SUM(column2) FROM list-of-tables WHERE column3 IN (list-of-values) SELECT column1 SUM(column2) FROM list-of-tables WHERE column3 BETWEEN value1 AND value2 IN 子句使用在列舉項目的使用上也就是分別測試是否符合所列的值 For example

86

SELECT employeeid lastname salary FROM employee_info WHERE lastname IN (Hernandez Jones Roberts Ruiz) 條件為姓氏(astname)要符合 Hernandez Jones Roberts or Ruiz 其中一個才會被傳回 IN運算元也可以使用 OR 的語法來取代如下結果相同 SELECT employeeid lastname salary FROM employee_info WHERE lastname = Hernandez OR lastname = Jones OR lastname = Roberts OR lastname = Ruiz 但使用 IN 句子比較短也比較易懂 你也可以使用 NOT IN 來去掉不要的記錄 BETWEEN 運算元使用在判斷是否存在兩個數值之間 For example SELECT employeeid age lastname salary FROM employee_info WHERE age BETWEEN 30 AND 40 傳回年紀 30歲到 40歲之間的資料(含 30及 40歲者) 相同的也可以使用以下語法來達到相同的結果 SELECT employeeid age lastname salary FROM employee_info WHERE age gt= 30 AND age lt= 40 你也可使用 NOT BETWEEN 來濾掉中間值的資料 數學運算 標準 ANSI SQL-92 提供以下運算

87

+ 加

- 減

餘數

餘數為除法後剩整數這不在標準的 ANSI SQL 中但大部份的資料庫都會支

援這運算元以下列出有用的函數雖不在 ANSI SQL-92 提供但一般資料庫

也會支援他們

ABS(x) 傳回 x 絕對值

SIGN(x) returns the sign of input x as -1 0 or 1 (negative zero or positive respectively)

MOD(xy) 餘數 - returns the integer remainder of x divided by y (同 xy)

FLOOR(x) 傳回小或等於 x 的最大整數值

CEILING(x) or CEIL(x)

傳回大或等於 x 的最小整數值

POWER(xy) x的 y 次方

ROUND(x) 把 x 四捨五入為整數

ROUND(xd) 四捨五入取到小數 d 位

SQRT(x) x 開平方

For example SELECT round(salary) firstname FROM employee_info 傳回薪資取到整數位

如何新增資料

insert 加入一筆新紀錄到資料表中 insert into tablename (first_columnlast_column) values (first_valuelast_value) [] = optional Example insert into employee

88

(first last age address city state) values (Luke Duke 45 2130 Boars Nest Hazard Co Georgia) Note 字串要以單引號住如string 數字框住也無妨 insert into 後面接資料表名稱再接以括號括住的欄位名在 values 後括號分別對映各欄位的值 以上的例子新增了一筆名(first) 為 Luke而住所(state) 為 Georgia 的資料

如何刪除資料

delete 可以刪除單筆或多筆紀錄 delete from tablename where columnname OPERATOR value [and|or column OPERATOR value] [ ] = optional Examples delete from employee Note 如果你沒有指定 where 子句那麼全部的紀錄都會被刪除 delete from employee where lastname = May delete from employee where firstname = Mike or firstname = Eric delete from 接著資料表名 再接著是條件式判斷沒有條件式則全部紀錄會

被刪除

如何更新資料

update 用來更新你所指定的記錄要和 WHERE 配合小心使用 語法 update tablename set columnname = newvalue[nextcolumn = newvalue2] where columnname OPERATOR value [and|or column OPERATOR value] [] = optional Examples

89

update phone_book set area_code = 623 where prefix = 979 update phone_book set last_name = Smith prefix=555 suffix=9292 where last_name = Jones update employee set age = age+1 where first_name=Mary and last_name=Williams

90

附錄二Replication

測試環境

RedHat 90 + MySQL 32358 MySQL資料庫路徑 varlibmysql MySQL設定檔 etcmycnf Master IP 1921680100 Slave IP 1921680200 請至下列網址下載最新MySQL 32358套件並利用rpm ndashUvh 更新 httpupdatesredhatcom9enosi386

圖 最新 MySQL 套件

測試架構圖

91

1921680100

1921680200Master Server

erveSlave S r

圖 測試架構圖

測試步驟

Master server 部份 Step1 確認 MasterSlave機器上所裝的 MySQL版本能進行

replication( 32329 or higher ) Step2 在 Master MySQL上開放一個帳號給 Slave mysql ndashu root ndashp mysqlgtGRANT FILE ON TO repl1921680200 IDENTIFIED BY lsquoabc123rsquo mysqlgtq 上面是 Master開放一個帳號 repl密碼 abc123給 IP1921680200有檔案處理

的權限 Step3 shutdown MySQL on the Master mysqladmin ndashu root ndashp shutdown Step4 備份 Master所有資料庫 tar ndashcvf tmpmysql-snapshottar varlibmysql 注意tar的時候MySQL是要在 stop情況下 在mysql (wwwmysqlcom) 網站的FAQ有不用shutdown的方法

92

Step5 在 master機器上修改etcmycnf 在[mysqld]區段內加入參數 log-bin server-id=這邊設定 server-id=1 sql-bin-update-same binlog-do-db=CRM只針對 CRM資料庫做紀錄 Step6 Restart MySQL on the master service mysqld start 此時因為有加入 log-bin 參數因此開始有 index產生了在varlibmysql目錄下

有index檔案紀錄資料庫的異動 log Slave server 部份 Step1 在 slave設定etcmycnf 在[mysqld]區段加入 master-host= master-user= master-password= master-port= server-id= 這邊設定 master-host=1921680100 master-user=repl master-password=abc123 master-port=3306 server-id=2 master-connect-retry=60預設重試間隔 60秒 replicate-do-db=CRM告訴 slave只做 CRM資料庫的更新 log-slave-updates Step2 將 master上的 mysql-snapshottar copy到 slave上 用 ftp傳到 slave的tmp Step3 解壓縮 Master資料庫至 Slave Server上 cd varlib tar xvf tmpmysql-snapshottar chown ndashR mysqlmysql mysql

93

chmod ndashR 770 mysql (視情況) Step4 Restart MySQL on the slave server 這時在varlibmysql目錄會出現 masterinfo此檔案紀錄了 Master MySQL server的資訊

狀況測試

One-way replication

1921680100

1921680200Master Server

erveSlave S r

圖 One-way replication架構圖 Step1 Master跟 Slave網路及服務都正常情況下由 Master端異動資料後 到 Slave端瀏覽資料檢視是否有進行 replication Step2 模擬 Slave Server 當機 可用在於 slave真的當機或是 Slave 不一定需要一直跟 master connect將Slave MySQL server shutdown由 Master端異動資料到 slave端瀏覽此時Slave應該沒有被 replication 更新然後再將 Slave端 MySQL server start起來

預設 60秒後 Slave會嘗試跟 Master要求進行 replication再去 Slave端檢視是否有更新資料

94

Step3 模擬 Master當機因為是設定 One-way replication一旦 Master Server Slave端沒有 Master的 source可以 download Two-way replication 基於 Master當機狀況於是發展雙向 Replication即 1921680100 ( Host A ) 1921680200 ( Host B )都分別擔任 MasterSlave身分

1921680100

1921680200er

Server B MasterSlave Server

Server A MasterSlave Serv

圖 Two-way replication架構圖 以下是針對兩台 MySQL伺服器進行雙向 Replication Step1觀念同單向 replication只是改成 Master也有 Slave身分 Slave也有Master的身分先分別在 Server AServer B 都去 grant一個進行 replication的身分 [A]mysqlgtGRANT FILE ON TO repl1921680200 IDENTIFIED BY lsquoabc123rsquo [B]mysqlgt GRANT FILE ON TO repl1921680100 IDENTIFIED BY lsquoabc123rsquo Step2做完單向 replication後stop Server Aserver B MySQL service此時 AB資料是一樣的

95

修改etcmycnf設定 範例 Server A [mysqld] datadir=varlibmysql socket=varlibmysqlmysqlsock server-id=1 log-bin sql-bin-update-same binlog-do-db=CRM master-host=1921680200 master-user=repl master-password=abc123 log-slave-updates master-connect-retry=60 replicate-do-db=CRM Server B [mysqld] datadir=varlibmysql socket=varlibmysqlmysqlsock server-id=2 log-bin sql-bin-update-same binlog-do-db=CRM master-host=1921680100 master-user=repl master-password=abc123 log-slave-updates master-connect-retry=60 replicate-do-db=CRM 分別 start Server AServer B MySQL後此時雙方都是 MasterSlave身分一旦哪一方資料異動就會通知對方來 replication-若 replication失效則必須將Server AServer B的masterinfo及index00x 都砍掉然後分別 restart MySQL server進行測試檢視成果 實務上通常如果需要做Two-way replication通常會搭配Virtual Server使用

96

在前端架設一台Virtual Server不過此部份不在此份SOP討論範圍內有興趣

的讀者可參考 httpwwwlinuxvirtualserverorg 網站

1921680100 1921680200

Host A MasterSlave Server

Host B MasterSlave Server

Virtual Host

圖 Virtual Server + Two-way replication 架構圖

97

圖 High Availability Linux Virtual Server架構圖

98

  • COSA-SOP-03-006
  • 第一章 簡介
    • 11適用對象 (Audience)
    • 12 MySQL本身
    • 13 MySQL 40版跟50版重大的改進功能
    • 14 各家資料庫軟體比較
      • 第二章 前置需求
      • 第三章 安裝
        • 31 MySQL安裝
        • 32 phpMyAdmin安裝
        • 33 升級及注意事項
          • 第四章 MySQL管理
            • 41 Webmin 管理介面
            • 42 phpMyAdmin 的操作介面
            • 43管理指令介紹
              • 431 利用mysqladmin設定root的密碼
                  • 第五章 實用範例
                    • 51 任務一Web Base客戶通訊錄
                    • 52 任務二Web Base群組軟體 ( twig )
                      • 第六章 維護及更新程序
                        • 61 日常維護
                        • 62 更新程序
                        • 63 備份重要檔案
                        • 64 離線備份與還原
                        • 65 線上備份與還原
                          • 第七章 問題與解答
                          • 第八章 參考資料
                          • 附錄一 SQL Command 介紹
                          • 附錄二Replication
Page 35: DataBase Server Standard Operation Procedureebooks.lib.ntu.edu.tw/1_file/oss/63/93doc4-5.pdf · 業務的公司帶來了不少壓力,譬如微軟,甲骨文 ... 外的錢用在第三方的資料庫產品上,譬如就可以不用再購買甲骨文公司

圖 4-13

413 使用者管理

接下來我們要利用Webmin 來建立資料庫使用者並給予某些權限 Step1建立使用者

35

圖 4-14 選擇使用者權限

圖 4-15

36

Step2 賦予權限

圖 4-16

Step3 權限列表

37

圖 4-17

38

42 phpMyAdmin 的操作介面

421建立資料庫

Step 填入資料庫名稱並按「建立」

圖 4-18建立資料庫

422 建立資料表

Step1 填入資料表名稱並指定欄位數量 執行

39

圖 4-19填入資料表名稱並指定欄位數量

Step2 設定欄位屬性

圖 4-20設定欄位屬性

40

Step3 phpMyAdmin會產生相關的 SQL Command

圖 4-21 資料表結構及相關 SQL Command

Step4新增 Record

41

圖 4-22

圖 4-23

42

圖 4-24

圖 4-25

43

423使用者管理

Step1建立使用者

圖 4-26

44

圖 4-27

Step2 給予權限

圖 4-28

Step3權限列表

45

圖 4-29

43管理指令介紹

431 利用 mysqladmin設定 root的密碼

當您在Windows 或 Linux 中安裝好 MySQL後系統會自動幫您建立兩個

帳分別是 root 和 匿名者MySQL的 root 跟 Linux 最高權限使用者 root無關MySQL的 root使用者相當於 MS SQL 中的 sa 帳號擁有最高的 Database管理權限但系統預設 MySQL的 root 是不需要密碼所以通常我們一安裝

MySQL後首要任務便是修改 root的密碼 我們可以利用 mysqladmin工具或是直接修改 MySQL內部資料庫的使用者資

料 mysqladmin ndashu root ndashh cosaexamplecom password lsquo1234rsquo

46

-u 表示使用者帳號root 為 MySQL預設的管理帳號

-h 表示 MySQL主機的主機名稱也可使用 IP Address password 表示使用者的密碼因為字串請使用單引號將密碼括起來 密碼設定完成之後還是可以利用 mysqladmin修改密碼但是你必須提供目前的密碼

432 連線 MySQL

mysql -uroot -p密碼 (-p和密碼之間不能有空白) 或 mysql -uroot -p (此方式會在進入後要求密碼) [rootossc phpMyAdmin] mysql -u root -p1234

Welcome to the MySQL monitor Commands end with or g

Your MySQL connection id is 25 to server version 32354

Type help or h for help Type c to clear the buffer

mysqlgt show databases

+----------+

| Database |

+----------+

| mysql |

| test |

+----------+

2 rows in set (000 sec)

mysqlgt exit

Bye

[rootossc phpMyAdmin]

433 建立資料庫

可利用 mysqladmin指令建立 CONTACT資料庫 mysqladmin -u root -p1234 create CONTACT

47

或是利用 mysql指令 [rootossc bluepage] mysql -u root -p1234 Welcome to the MySQL monitor Commands end with or g Your MySQL connection id is 1057 to server version 32354 Type help or h for help Type c to clear the buffer mysqlgt create database CONTACT Query OK 1 row affected (000 sec) mysqlgt show databases +----------+ | Database | +----------+ | CONTACT | | address | | hello | | mysql | | nuke | | test | +----------+ 6 rows in set (000 sec) mysqlgt exit

434 建立資料表

編寫 adresssql內容如下 -- Table structure for table address CREATE TABLE address ( id int(11) NOT NULL auto_increment name varchar(20) NOT NULL default tel varchar(15) NOT NULL default PRIMARY KEY (id) ) TYPE=MyISAM

48

-- Dumping data for table address INSERT INTO address VALUES (1林小明0800016888) INSERT INTO address VALUES (2黃大雄0800016888) INSERT INTO address VALUES (3劉小芬0800024365) 然後執行此 sql script mysql -u root -p1234 CONTACT lt addresssql 或是利 mysql command [rootossc bluepage] mysql -u root -p1234 Welcome to the MySQL monitor Commands end with or g Your MySQL connection id is 1090 to server version 32354 Type help or h for help Type c to clear the buffer mysqlgt use CONTACT Database changed Database changed mysqlgt CREATE TABLE address ( -gt id int(11) NOT NULL auto_increment -gt name varchar(20) NOT NULL default -gt tel varchar(15) NOT NULL default -gt PRIMARY KEY (id) -gt ) TYPE=MyISAM Query OK 0 rows affected (000 sec) mysqlgt INSERT INTO address VALUES (1林小明0800016888) Query OK 1 row affected (000 sec) mysqlgt INSERT INTO address VALUES (2黃大雄0800016888) Query OK 1 row affected (000 sec) mysqlgt INSERT INTO address VALUES (3劉小芬0800024365) Query OK 1 row affected (000 sec) mysqlgt exit Bye

49

第五章 實用範例

51 任務一Web Base客戶通訊錄

任職於開放科技公司的林小明前些日子在最符合成本效益的條件下快

速地完成公司網站的建置老闆因此對小明讚譽有加最近因為公司存放客戶資

料的 SQL Server主機屢遭病毒攻擊加上作業系統本身的問題當機次數頻繁

老闆希望能儘快把公司的客戶通訊錄程式移轉到較穩定的環境上因為此客戶通

訊錄程式最主要給內部人員使用所以介面美觀並不特別要求只求穩定且能快

速得到查詢結果老闆希望在短時間先看到程式的雛型並鍵入資料對其效率

及穩定性進行測試因為上次小明表現突出所以這次不可能的任務自然又落到

小明身上 小明想來想去既然要快速又穩定他而且又不希望所有人都得安裝 Client

程式於是小明決定)捨棄他的舊愛「Delphi+MS SQL」投向新歡「Apache + MySQL + PHP」利用此架構來設計一個簡單實用的Web Base客戶通訊錄程式

511 Web Base客戶通訊錄架構

此程式需要建立 CONTACT的資料庫並建立 adress Tables其結構如下表建立步驟請參考第三章 欄位名稱 資料型態 長度 說明 id INT (自動編號) 連絡人編號 name varchar文字 20 連絡人姓名 tel Varchar文字 15 連絡人電話 Web Base通訊錄共有下列幾個檔案功能如下表

檔案名稱 說明 Indexhtml Web Base通訊錄首頁 addphp 新增連絡人的 php程式 searchphp 尋找連絡人的 php程式 editphp 具有更新及刪除功能的 php程式

50

我們將這些檔案放至varwwwhtmlbluepage (預設無 bluepage目錄)

512 Web Base通訊錄測試

httpwwwopencombluepage 新增資料

圖 5-1 新增連絡人

圖 5-2 填入資料

51

圖 5-3 新增成功

搜尋及異動資料

圖 5-4 搜尋通訊錄

52

圖 5-5 編輯資料

圖 5-6 更新資料

513 程式內容及說明

lt-- 程式範例indexhtml--gt lthtmlgt ltheadgtlttitlegt通訊錄lttitlegtltheadgt ltbodygt ltcentergt

53

lth2gt通訊錄lth2gtlthrgt lta href=indexhtmlgt通訊錄ltagt | lta href=addphpgt新增連絡人ltagt | lta href=searchphpgt搜尋通訊錄ltagt ltcentergt ltbodygt lthtmlgt lt-- 程式範例addphp --gt lthtmlgt ltheadgtlttitlegt新增連絡人lttitlegtltheadgt ltbodygt ltcentergtlth2gt新增連絡人lth2gtltcentergtlthrgt lt 取得欄位資料 if (isset($_POST[Name]) ampamp isset($_POST[Tel]) ) $name = $_POST[Name] $tel = $_POST[Tel] 檢查是否有輸入欄位資料 if ($name = ampamp $tel = ) 建立 SQL字串 $sql = INSERT INTO address (name tel) values( $sql= $name $tel) 建立 MySQL 連結 $link = mysql_connect(localhostroot1234) 選擇資料庫 mysql_select_db(CONTACT) 執行 SQL指令 mysql_query($sql) mysql_close($link) echo ltfont color=redgt新增連絡人成功ltfontgtltbrgt gt ltform action=addphp method=postgt lttable border=0 width=300gt lttrgtlttdgt姓名 lttdgt

54

lttdgtltinput type=text name=Name size=20 maxlength=10gtlttdgtlttrgt lttrgtlttdgt電話 lttdgt lttdgtltinput type=text name=Tel size=20 maxlength=20gtlttdgtlttrgt lttrgtlttd colspan=2 align=centergt ltinput type=submit value=新增連絡人gtlttdgtlttrgt lttablegt ltformgt ltbrgtlta href=indexhtmlgt通訊錄ltagt | lta href=addphpgt新增連絡人ltagt | lta href=searchphpgt搜尋通訊錄ltagt ltbodygt lthtmlgt

lt-- 程式範例searchphp --gt lthtmlgt ltheadgtlttitlegt搜尋通訊錄lttitlegtltheadgt ltbodygt ltcentergtlth2gt搜尋通訊錄lth2gtlthrgt lt if (isset($_POST[Search])) 建立資料庫連結並選定資料庫 $link = mysql_connect(localhostroot1234) mysql_select_db(CONTACT) 建立基本的 SQL字串 $sql = SELECT FROM address 檢查是否輸入姓名 if (chop($_POST[Name]) = ) $name = name LIKE $_POST[Name] else $name = 檢查是否輸入電話號碼 if (chop($_POST[Tel]) = ) $tel = tel LIKE $_POST[Tel] else $tel =

55

if條件組合 SQL字串 if (chop($name) = ampamp chop($tel) = ) $sql= WHERE $name AND $tel elseif (chop($name) = ) 只有姓名 $sql = WHERE $name elseif (chop($tel) = ) 只有電話號碼 $sql = WHERE $tel $sql= ORDER BY name 最後加上排序 $result = mysql_query($sql) 取得欄位數 $total_fields = mysql_num_fields($result) echo lttable border=1gt echo lttrgtlttdgt編號lttdgtlttdgt姓名lttdgtlttdgt電話lttdgtlttd colspan=2gt功能選項lttdgtlttrgt 表格顯示查詢結果 while ($rows = mysql_fetch_array($result MYSQL_NUM)) echo lttrgt for ($i = 0 $i lt $total_fields $i++) echo lttdgt$rows[$i]lttdgt echo lttdgtlta href=editphpaction=editampid= echo $rows[0]gtltbgt編輯ltbgtlttdgt echo lttdgtlta href=editphpaction=delampid= echo $rows[0]gtltbgt刪除ltbgtlttdgt echo lttrgt echo lttablegtlthrgt mysql_free_result($result) mysql_close($link) gt ltcentergt ltform action=searchphp method=postgt lttable border=0 width=450gt lttrgtlttdgt搜尋姓名 lttdgt lttdgtltinput type=text name=Name size=10 maxlength=20gtlttdgtlttrgt lttrgtlttdgt搜尋電話 lttdgt lttdgtltinput type=text name=Tel

56

size=20 maxlength=20gtlttdgtlttrgt lttrgtlttd colspan=2 align=centergt ltinput type=submit name=Search value=搜尋gtlttdgtlttrgt lttablegt ltformgt ltbrgtlta href=indexhtmlgt通訊錄ltagt | lta href=addphpgt新增連絡人ltagt | lta href=searchphpgt搜尋通訊錄ltagt ltbodygt lthtmlgt

lt ob_start() gt lt-- 程式範例editphp --gt lthtmlgt ltheadgtlttitlegt編輯通訊錄lttitlegtltheadgt ltbodygt lt 取得 URL 參數 $id = $_GET[id] $action = $_GET[action] 建立資料庫連結 $link = mysql_connect(localhostroot1234) mysql_select_db(CONTACT) 選擇資料庫 執行的操作 switch ($action) case update 更新 取得欄位資料 $name = $_POST[Name] $tel = $_POST[Tel] $sql = UPDATE address SET name=$name tel=$tel WHERE id=$id mysql_query($sql) 執行 SQL指令 mysql_close($link) header(Location searchphp) 轉向到 serachphp break case del 刪除 $sql = DELETE FROM address WHERE id=$id

57

mysql_query($sql) 執行 SQL指令 mysql_close($link) header(Location searchphp) 轉向到 serachphp break case edit 編輯 $sql = SELECT FROM address WHERE id=$id $result = mysql_query($sql) 執行 SQL指令 $row = mysql_fetch_row($result) 取回記錄 $name = $row[1] 取得欄位 name $tel = $row[2] 取得欄位 tel mysql_close($link) 顯示編輯表單 gt ltcentergtlth2gt更新通訊錄lth2gtltcentergtlthrgt ltform action=editphpaction=updateampid=lt echo $id gt method=postgt lttable border=0 width=300gt lttrgtlttdgt姓名 lttdgt lttdgtltinput type=text name=Name size=20 maxlength=10 value=lt echo $name gtgtlttdgtlttrgt lttrgtlttdgt電話 lttdgt lttdgtltinput type=text name=Tel size=20 maxlength=20 value=lt echo $tel gtgtlttdgtlttrgt lttrgtlttd colspan=2 align=centergt ltinput type=submit value=更新連絡人gtlttdgtlttrgt lttablegt ltformgt ltbrgtlta href=indexhtmlgt通訊錄ltagt | lta href=addphpgt新增連絡人ltagt | lta href=searchphpgt搜尋通訊錄ltagt lt break gt ltbodygt lthtmlgt

58

52 任務二Web Base群組軟體 ( twig )

順利完成Web Base客戶通訊錄程式測試一段時間後「Apache + MySQL + PHP」架構的穩定與快速巳深得老闆與公司所有同事的認同隨著公司業績蒸

蒸日上人員組織編罝愈來愈龐大跨部門的會議愈來愈多業務員每日排滿拜

訪客戶的行程跟客戶的 Email的往來也愈來愈頻繁 愈來愈多部門的同事希望公司能建置一套群組軟體提供 web mail可讓業

務人員方便收發 mail還有連絡人議事日程待辦工作書簽等功能讓整個

公司運作及個人時間管理更有效率

老闆問小明對這些需求有什麼看法小明認為如果這些功能完全由程式部

門開發必定曠日費時而且耗費公司資源小明在網路尋找是否有提供這些功能

的Free Software皇天不負苦心人小明發現了TWIG (The Web Information Gateway) httptwigscrewdrivernet這個群組軟體它在 Web 上整合郵件新聞聯絡人議事日程工作序書簽等功能非常符合公司的需求 Step 1 下載 twig-277targz 下載網址 httptwigscrewdrivernetdownloadphp3

Step 2 解開 twig-277targz tar -xzvf twig-277targz

59

Step 3 執行安裝動作安裝到 varwwwhtmltwig 目錄 cd twig-277 twig-install varwwwhtmltwig

Step 4 建立 MySQL 資料庫(twig)及各資料表

cd setup mysql -u root -p1234 mysqlgt create database twig Query OK 1 row affected (001 sec) mysqlgt quit mysql -u root ndashp1234 twiglt twigtablemysql

Step 5 修改 configincphp3 參數設定 vi varwwwhtmltwigconfigconfigincphp3 $config[fromdomain] = opencom 網域 $config[language] = chinesebig5 中文訊息 $config[imap_port] = 143notls

60

Step 6 修改連結 MySQL 的帳號密碼 vi varwwwhtmltwigconfigdbconfigincphp3 $dbconfig[sqlusername] = root username $dbconfig[sqlpassword] = 1234 password

Step 7 其他設定檔

vi etchttpdconfhttpdconf 加入 AddType applicationx-httpd-php php3 在 DirectoryIndex最後加入 indexphp3 DirectoryIndex indexhtml indexhtmlvar indexphp3 在 AddDefaultCharset ISO-8859-1加上 AddDefaultCharset ISO-8859-1

vi etcphpini register_globals = On service httpd restart Step 8 sendmail 設定 vi etcmailsendmailcf在 264 行前面加上並重新啟動 sendmail「service snedmail restart」 262 SMTP daemon options 263 264 O DaemonPortOptions=Port=smtpAddr=127001 Name=MTA 265 266 SMTP client options 267 O ClientPortOptions=Family=inet Address=00

61

Step 9 檢查設定有無錯誤 http主機名稱twigtestphp3

62

Step 10 登入 twig ( http主機名稱twig)

63

第六章 維護及更新程序

61 日常維護

系統管理員最好定期以 root 身份登入看看信件在 RedHat Linux 中有一支 logwatch 程式會定時去分析 log file如果發現異常便會發信給 root除此之外筆者建議讀者平時就檢查 MySQL log file ( varlogmysqldlog)是否有異常情形

62 更新程序

讀者可至httprpmfindnet 尋找MySQL相關套件至於升級的相關步驟請參

考Linux OS SOP 第 54節

63 備份重要檔案

預設 MySQL 的 DB 檔案是存在 varlibmysql 內以 DB名稱為目錄目錄

內就是該 DB 的所有資料通常得定期備份還有 MySQL的設定檔 etcmycnf也別忘了一起備份

64 離線備份與還原

641 離線備份

預設 MySQL 的 DB 檔案是存在 varlibmysql 內以 DB 名稱為目錄目錄內

就是該 DB 的所有資料像 CRM 這個 DB就是存在 varlibmysqlCRM 內在備份前因為怕資料尚未完全寫入磁碟而且 MySQL 會 Lock 在使用的 DB 檔案所以應該是要先把 MySQL 先 Shutdown 一下整個備份的程序可以下像下面的指令去完成 cd varlibmysql

64

service mysqld stop tar cvfz CRM_db_20030905tgz CRM service mysqld start 對這樣就可以了 不過要注意的是怕 DB 內每個 Tables 間的資料有關關

聯性所以最好是把整個 DB 一次備起來單獨只備哪個 Tables 的檔案以後回存時怕會有資料關聯不一致的問題

642 離線還原

DB 發生錯誤而要回存時其實也不難先找出最近一次完整正常的備份先把現在錯誤的網頁或 DB 先更名或 tar 起來再把好的備份給解開回原來目錄位

置就行了需要注意的是 MySQL 服務最好也是要先停止回存完成後再啟動服務回存 DB 的整個程序可能像下面 cd varlibmysql service mysqldstop mv CRM CRM_OLD tar xvfz CRM_db_20030905tg service mysqld start

65 線上備份與還原

651 線上備份

使用像上面的檔案方式備份是個不錯的方法它最少可以保持該主機某個時間點的完整檔案備份但還是有一些問題需要考慮到有些主機就不只建立一個 DB 而已總不能為了備份某個 DB 而把整個 MySQL 服務停止備份檔案的方式回存在原主機上一定適用但假如 MySQL 版本升級或是在那天該網頁空間需遷機移機到別的主機時那就沒人敢保證備出來的資料檔可以用所以我們可以考慮另一種備份的方式是使用 MySQL 本身提供的功能 MySQL Data Dump指令是 mysqldump

65

使用 MySQL 的 Dump 功能可以把 DB 的結構資料或結構加資料 Dump 成文字檔 mysqldump 指令提供的彈性很大你可以選擇把整個 DB Dump 成一個檔或是每個 Table 為一個檔甚至是把結構檔和資料分開儲存都

可以 mysqladmin -uroot -p flush-logs mysqldump CRM -uroot -p --opt gt CRM_20030905sql (CRM 是 DB 名稱 opt 是一個使用完整 Dump 參數) 假如只是要單獨 Dump 某個 Table 時只要在上面的指令後轉出符號 gt 前加個 Table 名稱就可以如只要 phpbb2_users 這個 Table 的 Dump 時只要下 mysqldump CRM -uroot -p --opt CUSTOMER gt CRM_CUSTOMER_20030905sql

652 線上還原

若要回存整個資料庫只需將壓縮的備份檔還原成 Dump 的檔案再用下面的指令回存 mysql CRM -uroot -p lt CRM_20030905sql 這邊需注意的是若建立備份時是以--opt或--add-drop-table為參數時回存的 動作是先將舊的 Table 先刪除重建 Table 的結構後再把 Data 匯入所以回存後所有的資料會回到你當時備份那個時間點因此在回存資料時可以考慮把現有錯誤或不完整的 DB 先備份一份下來以備不時之需或是拿來比對錯誤的地

方在那裡當然你也可以把資料回存到另一個測試用的 DB 內只要把上面指令

的 DB 名稱改成你的測試用 DB 名稱即可 使用這種回存方式 MySQL 服務不需停止也不會動到其他正在使用的 DB 在一些提供 MySQL 服務的虛擬主機可用這種方式作你自己的 DB 備份及回存

66

另外假如你是系統重建或是移機時切需在新的 MySQL 內新建一個空白 DB 後才行作回存的工作你可以用下面的指令建立 mysql -uroot -p -e CREATE DATABASE CRM (上面的 CRM是你要新建的 DB 名稱) 另一種作法先用 mysql 指令進入 mysql client console 然後再用 CREATE DATABASE CRM 這樣就行了記得尾端要加個 符號該行指令才會執行

67

第七章 問題與解答

Q1RedHat 90預附的 MySQL到底有無支援 Transcation機制 Ans MySQL自 32334a之後的 MySQL-Max版本加入 InnoDB的資料庫類型透過

InnoDBMySQL同樣可以進行 COMMIT與 ROLLRACK的動作RedHat 90預附的 MySQL為 32354a-11巳支援 InnoDB的資料庫類型不過必須做以

下設定 1cp usrsharedocmysql-server-32354amy-mediumcnf to etcmycnf 2 vi etcmycnf 將以下設定前的拿掉 innodb_data_home_dir = varlibmysql innodb_data_file_path = ibdata110Mautoextend innodb_log_group_home_dir = varlibmysql innodb_log_arch_dir = varlibmysql 3service mysqld restart 如此一來各位在建立Table時便可指定Table Type為 innodb ( ex create table with type=innodb ) Q2如何解決 php+mysql 許功蓋等字變亂的問題 Ans 方法一 【確定 MySQL 預設的字元集】 1 打開 WinMySQLadmin 管理畫面(在視窗右下角狀態列紅綠燈圖示中按滑鼠

右鍵點選 Show me 選項) 2 點選管理畫面中 [Variables] 標籤選項其中 character_set變數就是您預設

字元集的變數其預設是 latin1 字元集(我們要將他改回 big5)而 chatacters_set 變數則是 MySQL 可以支援哪些字元集 【修改預設字元集變數 character_set 】 1 請點選管理畫面中 [myini Setup] 標籤選項設定 myini 2 按一下 [Pick-up and Edit myini values] 按鈕以便編輯目前的 myini 設定 3 在 [mysqld] 設定區塊底下新增一行 default-character-set = big5 變數設

68

定 4 新增一個 [client] 設定區塊並加入第三步驟的變數設定(游標往下移到空白處新增兩行 [client] 和 default-character-set=big5) 5 按一下畫面左下方 [Save Modification] 按鈕儲存設定 6 重新啟動 MySQL 或 Windows 方法二 Server端注意事項 phpini 中有關的設定為(預設值) Magic quotes for incoming GETPOSTCookie data magic_quotes_gpc = On Use Sybase-style magic quotes (escape with instead of ) magic_quotes_sybase = Off Client端注意事項 1中文資料送進 mysql 前請用 addslashes($str) 處理 2處理後送進 mysql 時請用 括起來並在參數後留一個空白如 $sql = UPDATE ezf_table set tablename=$tname tableend=$endtime table inguser=$tguser tableingid=$tguserid tableallnumber=$tnumber tableloca l=$tablelocal tableanyone=$tableopen tabletext=$ttext WHERE tableid=$t ableid tablename=$tname c 取出時請用 stripslashes($str) Q3MySQL root 密碼忘了該怎麼辦 Ans 1先停掉 mysql etcrcdinitdmysql stop 2以--skip-grant-table 的參數啟動 mysql safe_mysql --skip-grant-tableamp 3 更改 root 密碼 mysql mysql mysqlgt UPDATE user SET password=password(newpassword)

69

WHERE user=root mysqlgt FLUSH PRIVILEGES mysqlgt exit 4停掉 mysql再重跑 mysqladmin -uroot -p shutdown Enter password 輸入新設定的密碼 etcrcdinitdmysql start

Q4NULL值問題

Ans

NULL值的概念是造成 SQL的新手的混淆的普遍原因他們經常認為 NULL是和一個空字符串的一樣的東西不是這樣的例如下列語句是完全不同的

mysqlgt INSERT INTO my_table (phone) VALUES (NULL)

mysqlgt INSERT INTO my_table (phone) VALUES ()

兩個語句把值插入到 phone 列但是第一個插入一個 NULL值而第二個插入一個空字符串第一個的含義可以認為是ldquo電話號碼不知道而第二個則可意味

著ldquo她沒有電話

在 SQL中NULL值在于任何其他值甚至 NULL值比較時總是假的(FALSE)包含 NULL的一個表達式總是產生一個 NULL值除非在包含在表達式中的運算符和函數的文檔中指出在下列例子所有的列返回 NULL

mysqlgt SELECT NULL1+NULLCONCAT(InvisibleNULL)

如果你想要尋找值是 NULL的列你不能使用=NULL測試下列語句不返回任

何行因為對任何表達式expr = NULL是假的

mysqlgt SELECT FROM my_table WHERE phone = NULL

要想尋找 NULL值你必須使用 IS NULL測試下例顯示如何找出 NULL電話號碼和空的電話號碼

70

mysqlgt SELECT FROM my_table WHERE phone IS NULL mysqlgt SELECT FROM my_table WHERE phone =

在 MySQL中就像很多其他的 SQL服務器一樣你不能索引可以有 NULL值的列你必須聲明這樣的列為 NOT NULL而且你不能插入 NULL到索引的

列中

當用 LOAD DATA INFILE 讀取數據時空列用更新如果你想要在一個列中有

NULL值你應該在文本文件中使用N字面上的詞NULL也可以在某些情形下使用

當使用 ORDER BY時首先呈現 NULL值如果你用 DESC以降序排序NULL值最後顯示當使用 GROUP BY時所有的 NULL值被認為是相等的

為了有助于NULL的處理你能使用 IS NULL和 IS NOT NULL運算符和 IFNULL()函數

對某些列類型NULL值被特殊地處理如果你將 NULL插入表的第一個TIMESTAMP 列則插入當前的日期和時間如果你將 NULL插入一個AUTO_INCREMENT 列則插入順序中的下一個數字

Q5如何將圖片存放於 MySQL中

Ans

Step 1建立資料庫 test

Step 2 建立表格 binary_data

CREATE TABLE binary_data (

id INT(4) NOT NULL AUTO_INCREMENT PRIMARY KEY

description CHAR(50)

bin_data LONGBLOB

filename CHAR(50)

filesize CHAR(50)

filetype CHAR(50)

71

)

Step 3 利用 storephp 寫入圖片

storephp 程式碼

ltHTMLgt ltHEADgtltTITLEgtStore binary data into SQL DatabaseltTITLEgtltHEADgt ltBODYgt lt code that will be executed if the form has been submitted

if ($submit) mysql_connect(localhostrootYOUR_PASSWORD) mysql_select_db(test) $data=Base64_Encode(fread(fopen($form_data r) filesize($form_data))) $result=MYSQL_QUERY(INSERT INTO binary_data (descriptionbin_datafilenamefilesizefiletype) VALUES ($form_description$data$form_data_name$form_data_size$form_data_type)) $id= mysql_insert_id() print ltpgtThis file has the following Database ID ltbgt$idltbgt MYSQL_CLOSE() else else show the form to submit new data

gt

ltform method=post action=ltphp echo $PHP_SELF gt enctype=multipartform-datagt File Descriptionltbrgt ltinput type=text name=form_description size=40gt ltINPUT TYPE=hidden name=MAX_FILE_SIZE value=4000000gt ltbrgtFile to uploadstore in databaseltbrgt ltinput type=file name=form_data size=40gt ltpgtltinput type=submit name=submit value=submitgt ltformgt lt

72

gt ltBODYgt ltHTMLgt

Step 3 利用 storephp 取出圖片

getdataphp 程式碼

lt Syntax getdataphp3id=ltidgt if($id) you may have to modify login information for your database server MYSQL_CONNECT(localhostrootYOUR_PASSWORD) mysql_select_db(test) $query = select bin_datafiletype from binary_data where id=$id $result = MYSQL_QUERY($query) $data = Base64_Decode(MYSQL_RESULT($result0bin_data)) $type = MYSQL_RESULT($result0filetype) Header( Content-type $type) echo $data gt

Q6MySQL裝好之後啟動時或是執行 mysqladmin會出現如下訊息 Cant connect to local MYSQL Server through Socket varlibmysqlmysqlsock或是

Cant connect to local MYSQL Server through Socket tmpmysqldsock

Ans 可能有下列幾個原因

1這個 mysqldsock 不見了被某人刪除了或是被一些系統自動執行程式給刪

了例如有些 cron任務便會設定定期刪除 tmp 裡的東西所以呢您只能修改

cron 裡的設定讓它不要清除 mysqldsock 2在啟動時也可以改變 mysqldsock的位置您在啟動 MySQL的時候可以加入此參數usrlocalmysqlbinsafe_mysqld --user=mysql --socket=其他路

徑socket amp 同時得去設定環境變數 MYSQL_UNIX_PORT的值以指定新的

73

路徑 3若是您沒改 MYSQL_UNIX_PORT的值那麼您可以在執行指令的時候才打

例如mysqladmin --socket=其他路徑socket version Q7How to get the last insert id Ans CREATE TABLE product ( id INT(4) NOT NULL AUTO_INCREMENT PRIMARY KEY description VARCHAR(50) ) 1利用 SQL的話 mysqlgt insert into product(description) values(123) Query OK 1 row affected (000 sec) mysqlgt select last_insert_id() +------------------+ | last_insert_id() | +------------------+ +------------------+ 1 row in set (000 sec) ======================================== 2如果是 PHP的話 你可以用mysql_insert_id()取得該 id PHP example $result=MYSQL_QUERY(INSERT INTO product (description) VALUES ($description)) $id= mysql_insert_id() print This file has the following Database ID $id Q8如何將文字檔匯入資料庫 Ans $addr=homehttpdhtmlphpschool001txt $sql_select = load data infile $addr into table test fields terminated by t 解說 $sql_select = load data infile 文字檔名 into table 表格名 fields terminated by

74

t

(欄位分隔以 TAB鍵) 該文字檔須與資料表欄位格式相符 例如欄位有三個 則文字檔為每行一筆資料如下 欄 1資料ltTABgt欄 2資料ltTABgt欄 3資料 欄 1資料ltTABgt欄 2資料ltTABgt欄 3資料 欄 1資料ltTABgt欄 2資料ltTABgt欄 3資料 欄 1資料ltTABgtltTABgt欄 3資料

Q9如何撰寫 MySQL C API Ans Step 1利用文字編輯器撰寫以下程式碼 mysqlcc

include ltstdiohgt

include ltmysqlmysqlhgt

int main (int argc char argv[])

MYSQL mysql

MYSQL_RES res

MYSQL_ROW row

if (argc = 2)

fputs (Usage myc ltdatabasegt stderr)

return 1

if ((mysql_connect(ampmysqllocalhostrootYour_Password)))

fputs (Error connecting stderr)

abort()

75

if (mysql_select_db(ampmysqlargv[1]))

fputs (Error selecting database stderr)

abort()

if (mysql_query(ampmysqlSELECT FROM test_table))

fputs (Error processing query stderr)

abort()

if ((res = mysql_store_result(ampmysql)))

fputs (Error storing results stderr)

abort()

while((row = mysql_fetch_row(res)))

uint i = 0

for (i=0 i lt mysql_num_fields(res) i++)

printf(s row[i])

printf(n)

return 0

Step 2 Compile

gcc -Iusrlocalmysqlinclude -Lusrlocalmysqllibmysql mysqlcc ndashlm -lmysqlclient

(其中 include path與 library path取決於你的 MySQL安裝路徑)

76

如果執行時發生如下 error Run problemerror in loading shared libraries libmysqlclientsoX 將你的 MySQL library path(for exampleusrlocalmysqllibmysql) 加入etcldsoconf and run sbinldconfig -v Q9ASP + MySQL 範例程式 Ans Dim myconn As New ADODBConnection Dim myrs As New Recordset Dim mySQL As String Dim myrows As Long myconnOpen DSN=MyODBCsample mySQL = SELECT from user myrsSource = mySQL Set myrsActiveConnection = myconn myrsCursorLocation = adUseClient myrsOpen myrows = myrsRecordCount myrsClose myconnClose 可參考 httpwwwdwamnetmysqlasp_myodbcasp 有詳細的資料 Q10如何將 MySQL中的資料庫匯出成txt檔 Ans select from TableName into outfile textxls all result fields will seperate by tab

77

第八章 參考資料

英文部份 網址 1 httpwwwmysqlcom MySQL 網站有第一手有關 MySQL的資料 2 httpwwwmysqlcomdocenReplicationhtml 有關 MySQL Replication 的文件 3 httpwwwgeocitiescomsqlhomefaqstore_blobhtml 如何在 MySQL 存放 BLOB的資料 4httpwwwsapdborg 有關 SAP跟 MySQL相關合作的網站 書藉 1 Cooking with MySQL

Paul DuBois has selected sample recipes from the hundreds youll find in his book MySQL

Cookbook In this third and final series of excerpts showcasing these recipes learn how to

compute team standings how to calculate the differences between successive Dec 26

2002 2 Tips for Building Web Database Applications with PHP and MySQL by Hugh E Williams co-author of Web Database Applications with PHP amp MySQL 04042002

3 Managing and Using MySQL 2nd Edition By Tim King George Reese Randy Jay Yarger

4 MySQL Cookbook By Paul DuBoisPublisher OReillyPub Date October 2002

中文部份

78

1 httplinuxtncedutwtechdocmysqlmysql_docmanual_tochtml MySQL 中文手冊 2 httpchenshloxaedutwphpZ_1php PHP+MySQ程式研習設計網站 3 httplinuxtncedutwtechdocbanicdownhtml PHP 4 手冊 4 httpwwwtncedutwadmin_zonephp台南縣教育網網路中心有很多 Linux相關文件 5 httpdobtncedutw網站建置百寶箱有很多 PHP MySQL 相關範例程式 5 httpwwwdbworldcomtw資料庫專家電子雜誌介紹資料庫的重要觀念及名詞

79

附錄一 SQL Command 介紹

SQL (讀音ess-que-el) 是一種結構查詢語法SQL 使用於資料庫交流

傳遞相容於 ANSI (American National Standards Institute) 是一套標準的關聯

式資料庫語言 SQL 語言是執行更新或從資料系統獲取資料一般常見的關聯

資料庫系統都有提供 SQL 如 Oracle Sybase Microsoft SQL Server Access Ingres 等雖然大部份的資料庫都有提供 SQL 但也多提供了自已獨特的語

法造成了不相容的情形但標準基本的語法是相通的如Select Insert Update Delete Create and Drop 每一個系統都有支援

Table相關 Command

Create Table

關聯式資料庫包含有很多元件稱為資料表(tables) 把資料或訊息放在資

料表中 資料表是以不同的名稱做分別資料表由欄列所構成的二維陣列

欄包含欄位名資料型態 及其他可判斷的資訊列是由全部欄位構成一筆一

筆的紀錄 create table 語法用在建立一個新的資料表語法格式如下

create table tablename (column1 data type column2 data type column3 data type)

Format of create table if you were to use optional constraints

create table tablename (column1 data type [constraint] column2 data type [constraint] column3 data type [constraint]) [ ] = optional

Note You may have as many columns as youd like and the constraints are optional

80

Example

create table employee (first varchar(15) last varchar(20) age number(3) address varchar(30) city varchar(20) state varchar(20))

注意建立資料表格式要以括號把前後框住而最後以(分號)做結尾

欄位名不要超過 30個字元長而且不要使用 sql 的關鍵字(如 where select等)而在後面接是型態的宣告(如字串數字日期格式等)

資料型態是來描述欄位的方式如一個欄位Last_Name 是一個姓氏可以使用varchar (可變動長度字串) 資料型態

以下是幾個常見的資料庫型態 char(size) 固定長度字串最長為 255 位元 varchar(size) 變動長度字串最大字元數以 size 來指定 number(size) 數值格式可以是整數也可以是小數最大數字以 size 位數判

斷未指定小數位數由系統內定 date 日期格式 number(sized) 數值格式最大數字以 size 位數判斷d 為小數位數整數位

數為 size-d 位

有何限制當資料表被建立通常有一或數個欄位是要使用來做關聯的功

能 例如unique 限制(唯一值)兩筆記錄不可以相同的值 not null (非空值)該欄位一定要輸入資料不可是空的primary key (主鍵)是每一筆記錄識別的主要方式

Drop a table drop table 刪除資料表(其中的資料也會一併刪除)

drop table tablename

Example

81

drop table 和刪除全部資料是不同的刪除全部資料欄位名稱資訊等還會

存在但刪除資料表會把這一些也一併移除掉

如何查詢資料

Select 基本用法

select 語法是關連式資料庫最常用的部份可以取得你想要的資料這是一個

簡單的範例 select column1[column2etc] from tablename [where condition] [] = optional 在 select 之後所列欄位名則是要顯示的資料部份你可以一一列出各欄位

名或是以 (星號)來代表選擇全部的欄位 from 之後放資料表名稱 where 子句 (選項) 指定要過濾的條件符合者才會顯現 where 可使用的條件運算元 = 等於 gt 大於 lt 小於 gt= 大或等於 lt= 小或等於 ltgt 大相等 LIKE 相似 For example select first last city

82

from empinfo where first LIKE Er 以Er 為開頭的字串就符合要以單引號框住 Or you can specify select first last from empinfo where last LIKE s 最後一字為 S 就符合 select from empinfo where first = Eric 則表示 first name 一定要是 Eric 才可以 範例資料表empinfo 統計函數

MIN 傳回指定欄位最小值

MAX 傳回指定欄位最大值

SUM 傳回指定欄位總和

AVG 傳回指定欄位平均值

COUNT 傳回指定欄位的筆數

COUNT() 傳回資料庫中的總筆數

統計函數使用於資料表中的數值欄位配合 SELECT 語法使用 只用於總結特定單一欄位可以配合 GROUP BY 做篩選但也可以不使用 GROUP BY 語句For example

SELECT AVG(salary) FROM employee

83

傳回全部 salary 平均值

Another example

SELECT AVG(salary) FROM employee WHERE title = Programmer

傳回 salary 平均值條件為 employees 資料表中當 title 等於 Programmer

Example

SELECT Count() FROM employees

傳回 employees 資料表中紀錄總筆數

GROUP BY 語法 SELECT column1 SUM(column2) FROM list-of-tables GROUP BY column-list The GROUP BY 語句可以先以所列的欄位為條件分組排序在一起(可以多欄

位) example 要列出每一個 dept 中最高 salary 值 SELECT max(salary) dept FROM employee GROUP BY dept HAVING 語法

SELECT column1 SUM(column2) FROM list-of-tables GROUP BY column-list HAVING condition

HAVING 子句是 GROUP BY 的一部份用來過濾在 GROUP BY 所選出的資料功能如同 select 命令中 where 條件式一樣只是 HAVING 必需配合 GROUP BY 使用

我們以例子來說明我們要取得每一公司名及每一公司的薪水平均值輸入如下

84

SELECT dept avg(salary) FROM employee GROUP BY dept

但如果我們只列出薪資平均值超過 20000元的公司資料

SELECT dept avg(salary) FROM employee GROUP BY dept HAVING avg(salary) gt 20000

ORDER BY子句語法

SELECT column1 SUM(column2) FROM list-of-tables ORDER BY column-list [ASC | DESC]

[ ] =選項

ORDER BY是一個選項子句當你以排序方式來顯示資料(正向由小到大反向由大到小)以指定的欄位資料做排序

ASC = 正向- 預設值 DESC = 反向排序

For example

SELECT employee_id dept name age salary FROM employee_info WHERE dept = Sales ORDER BY salary

以上列出公司代號公司名銷售員人名年紀及薪資而條件是公司名為 Sales 顯示順序以薪資多少排序(由小到大為預設值)

如果要以多個欄位做排序要以逗號做分隔如下

SELECT employee_id dept name age salary FROM employee_info WHERE dept = Sales ORDER BY salary age DESC

85

結合條件及布林運算 SELECT column1 SUM(column2) FROM list-of-tables WHERE condition1 AND condition2 AND運算可以結兩個或以上的條件放在 WHERE子句中 兩者都要為真才

會顯示該筆記錄 OR 運算可以結兩個或以上敘述放在 WHERE子句中只要其中一個為直就

會顯示該筆記錄 For example SELECT employeeid firstname lastname title salary FROM employee_info WHERE salary gt= 5000000 AND title = Programmer 必需要薪資大於等於 50000而且職稱為 Programmer同時符合才會顯示該筆資料 以下以括號括住雖然不是必需的但如此比較容易讀 SELECT employeeid firstname lastname title salary FROM employee_info WHERE (salary gt= 5000000) AND (title = Programmer) 另外範例 SELECT firstname lastname title salary FROM employee_info WHERE (title = Sales) OR (title = Programmer) 條件為只要是 Sales 或 Programmer 職稱的就會被列出 IN and BETWEEN 子句

SELECT column1 SUM(column2) FROM list-of-tables WHERE column3 IN (list-of-values) SELECT column1 SUM(column2) FROM list-of-tables WHERE column3 BETWEEN value1 AND value2 IN 子句使用在列舉項目的使用上也就是分別測試是否符合所列的值 For example

86

SELECT employeeid lastname salary FROM employee_info WHERE lastname IN (Hernandez Jones Roberts Ruiz) 條件為姓氏(astname)要符合 Hernandez Jones Roberts or Ruiz 其中一個才會被傳回 IN運算元也可以使用 OR 的語法來取代如下結果相同 SELECT employeeid lastname salary FROM employee_info WHERE lastname = Hernandez OR lastname = Jones OR lastname = Roberts OR lastname = Ruiz 但使用 IN 句子比較短也比較易懂 你也可以使用 NOT IN 來去掉不要的記錄 BETWEEN 運算元使用在判斷是否存在兩個數值之間 For example SELECT employeeid age lastname salary FROM employee_info WHERE age BETWEEN 30 AND 40 傳回年紀 30歲到 40歲之間的資料(含 30及 40歲者) 相同的也可以使用以下語法來達到相同的結果 SELECT employeeid age lastname salary FROM employee_info WHERE age gt= 30 AND age lt= 40 你也可使用 NOT BETWEEN 來濾掉中間值的資料 數學運算 標準 ANSI SQL-92 提供以下運算

87

+ 加

- 減

餘數

餘數為除法後剩整數這不在標準的 ANSI SQL 中但大部份的資料庫都會支

援這運算元以下列出有用的函數雖不在 ANSI SQL-92 提供但一般資料庫

也會支援他們

ABS(x) 傳回 x 絕對值

SIGN(x) returns the sign of input x as -1 0 or 1 (negative zero or positive respectively)

MOD(xy) 餘數 - returns the integer remainder of x divided by y (同 xy)

FLOOR(x) 傳回小或等於 x 的最大整數值

CEILING(x) or CEIL(x)

傳回大或等於 x 的最小整數值

POWER(xy) x的 y 次方

ROUND(x) 把 x 四捨五入為整數

ROUND(xd) 四捨五入取到小數 d 位

SQRT(x) x 開平方

For example SELECT round(salary) firstname FROM employee_info 傳回薪資取到整數位

如何新增資料

insert 加入一筆新紀錄到資料表中 insert into tablename (first_columnlast_column) values (first_valuelast_value) [] = optional Example insert into employee

88

(first last age address city state) values (Luke Duke 45 2130 Boars Nest Hazard Co Georgia) Note 字串要以單引號住如string 數字框住也無妨 insert into 後面接資料表名稱再接以括號括住的欄位名在 values 後括號分別對映各欄位的值 以上的例子新增了一筆名(first) 為 Luke而住所(state) 為 Georgia 的資料

如何刪除資料

delete 可以刪除單筆或多筆紀錄 delete from tablename where columnname OPERATOR value [and|or column OPERATOR value] [ ] = optional Examples delete from employee Note 如果你沒有指定 where 子句那麼全部的紀錄都會被刪除 delete from employee where lastname = May delete from employee where firstname = Mike or firstname = Eric delete from 接著資料表名 再接著是條件式判斷沒有條件式則全部紀錄會

被刪除

如何更新資料

update 用來更新你所指定的記錄要和 WHERE 配合小心使用 語法 update tablename set columnname = newvalue[nextcolumn = newvalue2] where columnname OPERATOR value [and|or column OPERATOR value] [] = optional Examples

89

update phone_book set area_code = 623 where prefix = 979 update phone_book set last_name = Smith prefix=555 suffix=9292 where last_name = Jones update employee set age = age+1 where first_name=Mary and last_name=Williams

90

附錄二Replication

測試環境

RedHat 90 + MySQL 32358 MySQL資料庫路徑 varlibmysql MySQL設定檔 etcmycnf Master IP 1921680100 Slave IP 1921680200 請至下列網址下載最新MySQL 32358套件並利用rpm ndashUvh 更新 httpupdatesredhatcom9enosi386

圖 最新 MySQL 套件

測試架構圖

91

1921680100

1921680200Master Server

erveSlave S r

圖 測試架構圖

測試步驟

Master server 部份 Step1 確認 MasterSlave機器上所裝的 MySQL版本能進行

replication( 32329 or higher ) Step2 在 Master MySQL上開放一個帳號給 Slave mysql ndashu root ndashp mysqlgtGRANT FILE ON TO repl1921680200 IDENTIFIED BY lsquoabc123rsquo mysqlgtq 上面是 Master開放一個帳號 repl密碼 abc123給 IP1921680200有檔案處理

的權限 Step3 shutdown MySQL on the Master mysqladmin ndashu root ndashp shutdown Step4 備份 Master所有資料庫 tar ndashcvf tmpmysql-snapshottar varlibmysql 注意tar的時候MySQL是要在 stop情況下 在mysql (wwwmysqlcom) 網站的FAQ有不用shutdown的方法

92

Step5 在 master機器上修改etcmycnf 在[mysqld]區段內加入參數 log-bin server-id=這邊設定 server-id=1 sql-bin-update-same binlog-do-db=CRM只針對 CRM資料庫做紀錄 Step6 Restart MySQL on the master service mysqld start 此時因為有加入 log-bin 參數因此開始有 index產生了在varlibmysql目錄下

有index檔案紀錄資料庫的異動 log Slave server 部份 Step1 在 slave設定etcmycnf 在[mysqld]區段加入 master-host= master-user= master-password= master-port= server-id= 這邊設定 master-host=1921680100 master-user=repl master-password=abc123 master-port=3306 server-id=2 master-connect-retry=60預設重試間隔 60秒 replicate-do-db=CRM告訴 slave只做 CRM資料庫的更新 log-slave-updates Step2 將 master上的 mysql-snapshottar copy到 slave上 用 ftp傳到 slave的tmp Step3 解壓縮 Master資料庫至 Slave Server上 cd varlib tar xvf tmpmysql-snapshottar chown ndashR mysqlmysql mysql

93

chmod ndashR 770 mysql (視情況) Step4 Restart MySQL on the slave server 這時在varlibmysql目錄會出現 masterinfo此檔案紀錄了 Master MySQL server的資訊

狀況測試

One-way replication

1921680100

1921680200Master Server

erveSlave S r

圖 One-way replication架構圖 Step1 Master跟 Slave網路及服務都正常情況下由 Master端異動資料後 到 Slave端瀏覽資料檢視是否有進行 replication Step2 模擬 Slave Server 當機 可用在於 slave真的當機或是 Slave 不一定需要一直跟 master connect將Slave MySQL server shutdown由 Master端異動資料到 slave端瀏覽此時Slave應該沒有被 replication 更新然後再將 Slave端 MySQL server start起來

預設 60秒後 Slave會嘗試跟 Master要求進行 replication再去 Slave端檢視是否有更新資料

94

Step3 模擬 Master當機因為是設定 One-way replication一旦 Master Server Slave端沒有 Master的 source可以 download Two-way replication 基於 Master當機狀況於是發展雙向 Replication即 1921680100 ( Host A ) 1921680200 ( Host B )都分別擔任 MasterSlave身分

1921680100

1921680200er

Server B MasterSlave Server

Server A MasterSlave Serv

圖 Two-way replication架構圖 以下是針對兩台 MySQL伺服器進行雙向 Replication Step1觀念同單向 replication只是改成 Master也有 Slave身分 Slave也有Master的身分先分別在 Server AServer B 都去 grant一個進行 replication的身分 [A]mysqlgtGRANT FILE ON TO repl1921680200 IDENTIFIED BY lsquoabc123rsquo [B]mysqlgt GRANT FILE ON TO repl1921680100 IDENTIFIED BY lsquoabc123rsquo Step2做完單向 replication後stop Server Aserver B MySQL service此時 AB資料是一樣的

95

修改etcmycnf設定 範例 Server A [mysqld] datadir=varlibmysql socket=varlibmysqlmysqlsock server-id=1 log-bin sql-bin-update-same binlog-do-db=CRM master-host=1921680200 master-user=repl master-password=abc123 log-slave-updates master-connect-retry=60 replicate-do-db=CRM Server B [mysqld] datadir=varlibmysql socket=varlibmysqlmysqlsock server-id=2 log-bin sql-bin-update-same binlog-do-db=CRM master-host=1921680100 master-user=repl master-password=abc123 log-slave-updates master-connect-retry=60 replicate-do-db=CRM 分別 start Server AServer B MySQL後此時雙方都是 MasterSlave身分一旦哪一方資料異動就會通知對方來 replication-若 replication失效則必須將Server AServer B的masterinfo及index00x 都砍掉然後分別 restart MySQL server進行測試檢視成果 實務上通常如果需要做Two-way replication通常會搭配Virtual Server使用

96

在前端架設一台Virtual Server不過此部份不在此份SOP討論範圍內有興趣

的讀者可參考 httpwwwlinuxvirtualserverorg 網站

1921680100 1921680200

Host A MasterSlave Server

Host B MasterSlave Server

Virtual Host

圖 Virtual Server + Two-way replication 架構圖

97

圖 High Availability Linux Virtual Server架構圖

98

  • COSA-SOP-03-006
  • 第一章 簡介
    • 11適用對象 (Audience)
    • 12 MySQL本身
    • 13 MySQL 40版跟50版重大的改進功能
    • 14 各家資料庫軟體比較
      • 第二章 前置需求
      • 第三章 安裝
        • 31 MySQL安裝
        • 32 phpMyAdmin安裝
        • 33 升級及注意事項
          • 第四章 MySQL管理
            • 41 Webmin 管理介面
            • 42 phpMyAdmin 的操作介面
            • 43管理指令介紹
              • 431 利用mysqladmin設定root的密碼
                  • 第五章 實用範例
                    • 51 任務一Web Base客戶通訊錄
                    • 52 任務二Web Base群組軟體 ( twig )
                      • 第六章 維護及更新程序
                        • 61 日常維護
                        • 62 更新程序
                        • 63 備份重要檔案
                        • 64 離線備份與還原
                        • 65 線上備份與還原
                          • 第七章 問題與解答
                          • 第八章 參考資料
                          • 附錄一 SQL Command 介紹
                          • 附錄二Replication
Page 36: DataBase Server Standard Operation Procedureebooks.lib.ntu.edu.tw/1_file/oss/63/93doc4-5.pdf · 業務的公司帶來了不少壓力,譬如微軟,甲骨文 ... 外的錢用在第三方的資料庫產品上,譬如就可以不用再購買甲骨文公司

圖 4-14 選擇使用者權限

圖 4-15

36

Step2 賦予權限

圖 4-16

Step3 權限列表

37

圖 4-17

38

42 phpMyAdmin 的操作介面

421建立資料庫

Step 填入資料庫名稱並按「建立」

圖 4-18建立資料庫

422 建立資料表

Step1 填入資料表名稱並指定欄位數量 執行

39

圖 4-19填入資料表名稱並指定欄位數量

Step2 設定欄位屬性

圖 4-20設定欄位屬性

40

Step3 phpMyAdmin會產生相關的 SQL Command

圖 4-21 資料表結構及相關 SQL Command

Step4新增 Record

41

圖 4-22

圖 4-23

42

圖 4-24

圖 4-25

43

423使用者管理

Step1建立使用者

圖 4-26

44

圖 4-27

Step2 給予權限

圖 4-28

Step3權限列表

45

圖 4-29

43管理指令介紹

431 利用 mysqladmin設定 root的密碼

當您在Windows 或 Linux 中安裝好 MySQL後系統會自動幫您建立兩個

帳分別是 root 和 匿名者MySQL的 root 跟 Linux 最高權限使用者 root無關MySQL的 root使用者相當於 MS SQL 中的 sa 帳號擁有最高的 Database管理權限但系統預設 MySQL的 root 是不需要密碼所以通常我們一安裝

MySQL後首要任務便是修改 root的密碼 我們可以利用 mysqladmin工具或是直接修改 MySQL內部資料庫的使用者資

料 mysqladmin ndashu root ndashh cosaexamplecom password lsquo1234rsquo

46

-u 表示使用者帳號root 為 MySQL預設的管理帳號

-h 表示 MySQL主機的主機名稱也可使用 IP Address password 表示使用者的密碼因為字串請使用單引號將密碼括起來 密碼設定完成之後還是可以利用 mysqladmin修改密碼但是你必須提供目前的密碼

432 連線 MySQL

mysql -uroot -p密碼 (-p和密碼之間不能有空白) 或 mysql -uroot -p (此方式會在進入後要求密碼) [rootossc phpMyAdmin] mysql -u root -p1234

Welcome to the MySQL monitor Commands end with or g

Your MySQL connection id is 25 to server version 32354

Type help or h for help Type c to clear the buffer

mysqlgt show databases

+----------+

| Database |

+----------+

| mysql |

| test |

+----------+

2 rows in set (000 sec)

mysqlgt exit

Bye

[rootossc phpMyAdmin]

433 建立資料庫

可利用 mysqladmin指令建立 CONTACT資料庫 mysqladmin -u root -p1234 create CONTACT

47

或是利用 mysql指令 [rootossc bluepage] mysql -u root -p1234 Welcome to the MySQL monitor Commands end with or g Your MySQL connection id is 1057 to server version 32354 Type help or h for help Type c to clear the buffer mysqlgt create database CONTACT Query OK 1 row affected (000 sec) mysqlgt show databases +----------+ | Database | +----------+ | CONTACT | | address | | hello | | mysql | | nuke | | test | +----------+ 6 rows in set (000 sec) mysqlgt exit

434 建立資料表

編寫 adresssql內容如下 -- Table structure for table address CREATE TABLE address ( id int(11) NOT NULL auto_increment name varchar(20) NOT NULL default tel varchar(15) NOT NULL default PRIMARY KEY (id) ) TYPE=MyISAM

48

-- Dumping data for table address INSERT INTO address VALUES (1林小明0800016888) INSERT INTO address VALUES (2黃大雄0800016888) INSERT INTO address VALUES (3劉小芬0800024365) 然後執行此 sql script mysql -u root -p1234 CONTACT lt addresssql 或是利 mysql command [rootossc bluepage] mysql -u root -p1234 Welcome to the MySQL monitor Commands end with or g Your MySQL connection id is 1090 to server version 32354 Type help or h for help Type c to clear the buffer mysqlgt use CONTACT Database changed Database changed mysqlgt CREATE TABLE address ( -gt id int(11) NOT NULL auto_increment -gt name varchar(20) NOT NULL default -gt tel varchar(15) NOT NULL default -gt PRIMARY KEY (id) -gt ) TYPE=MyISAM Query OK 0 rows affected (000 sec) mysqlgt INSERT INTO address VALUES (1林小明0800016888) Query OK 1 row affected (000 sec) mysqlgt INSERT INTO address VALUES (2黃大雄0800016888) Query OK 1 row affected (000 sec) mysqlgt INSERT INTO address VALUES (3劉小芬0800024365) Query OK 1 row affected (000 sec) mysqlgt exit Bye

49

第五章 實用範例

51 任務一Web Base客戶通訊錄

任職於開放科技公司的林小明前些日子在最符合成本效益的條件下快

速地完成公司網站的建置老闆因此對小明讚譽有加最近因為公司存放客戶資

料的 SQL Server主機屢遭病毒攻擊加上作業系統本身的問題當機次數頻繁

老闆希望能儘快把公司的客戶通訊錄程式移轉到較穩定的環境上因為此客戶通

訊錄程式最主要給內部人員使用所以介面美觀並不特別要求只求穩定且能快

速得到查詢結果老闆希望在短時間先看到程式的雛型並鍵入資料對其效率

及穩定性進行測試因為上次小明表現突出所以這次不可能的任務自然又落到

小明身上 小明想來想去既然要快速又穩定他而且又不希望所有人都得安裝 Client

程式於是小明決定)捨棄他的舊愛「Delphi+MS SQL」投向新歡「Apache + MySQL + PHP」利用此架構來設計一個簡單實用的Web Base客戶通訊錄程式

511 Web Base客戶通訊錄架構

此程式需要建立 CONTACT的資料庫並建立 adress Tables其結構如下表建立步驟請參考第三章 欄位名稱 資料型態 長度 說明 id INT (自動編號) 連絡人編號 name varchar文字 20 連絡人姓名 tel Varchar文字 15 連絡人電話 Web Base通訊錄共有下列幾個檔案功能如下表

檔案名稱 說明 Indexhtml Web Base通訊錄首頁 addphp 新增連絡人的 php程式 searchphp 尋找連絡人的 php程式 editphp 具有更新及刪除功能的 php程式

50

我們將這些檔案放至varwwwhtmlbluepage (預設無 bluepage目錄)

512 Web Base通訊錄測試

httpwwwopencombluepage 新增資料

圖 5-1 新增連絡人

圖 5-2 填入資料

51

圖 5-3 新增成功

搜尋及異動資料

圖 5-4 搜尋通訊錄

52

圖 5-5 編輯資料

圖 5-6 更新資料

513 程式內容及說明

lt-- 程式範例indexhtml--gt lthtmlgt ltheadgtlttitlegt通訊錄lttitlegtltheadgt ltbodygt ltcentergt

53

lth2gt通訊錄lth2gtlthrgt lta href=indexhtmlgt通訊錄ltagt | lta href=addphpgt新增連絡人ltagt | lta href=searchphpgt搜尋通訊錄ltagt ltcentergt ltbodygt lthtmlgt lt-- 程式範例addphp --gt lthtmlgt ltheadgtlttitlegt新增連絡人lttitlegtltheadgt ltbodygt ltcentergtlth2gt新增連絡人lth2gtltcentergtlthrgt lt 取得欄位資料 if (isset($_POST[Name]) ampamp isset($_POST[Tel]) ) $name = $_POST[Name] $tel = $_POST[Tel] 檢查是否有輸入欄位資料 if ($name = ampamp $tel = ) 建立 SQL字串 $sql = INSERT INTO address (name tel) values( $sql= $name $tel) 建立 MySQL 連結 $link = mysql_connect(localhostroot1234) 選擇資料庫 mysql_select_db(CONTACT) 執行 SQL指令 mysql_query($sql) mysql_close($link) echo ltfont color=redgt新增連絡人成功ltfontgtltbrgt gt ltform action=addphp method=postgt lttable border=0 width=300gt lttrgtlttdgt姓名 lttdgt

54

lttdgtltinput type=text name=Name size=20 maxlength=10gtlttdgtlttrgt lttrgtlttdgt電話 lttdgt lttdgtltinput type=text name=Tel size=20 maxlength=20gtlttdgtlttrgt lttrgtlttd colspan=2 align=centergt ltinput type=submit value=新增連絡人gtlttdgtlttrgt lttablegt ltformgt ltbrgtlta href=indexhtmlgt通訊錄ltagt | lta href=addphpgt新增連絡人ltagt | lta href=searchphpgt搜尋通訊錄ltagt ltbodygt lthtmlgt

lt-- 程式範例searchphp --gt lthtmlgt ltheadgtlttitlegt搜尋通訊錄lttitlegtltheadgt ltbodygt ltcentergtlth2gt搜尋通訊錄lth2gtlthrgt lt if (isset($_POST[Search])) 建立資料庫連結並選定資料庫 $link = mysql_connect(localhostroot1234) mysql_select_db(CONTACT) 建立基本的 SQL字串 $sql = SELECT FROM address 檢查是否輸入姓名 if (chop($_POST[Name]) = ) $name = name LIKE $_POST[Name] else $name = 檢查是否輸入電話號碼 if (chop($_POST[Tel]) = ) $tel = tel LIKE $_POST[Tel] else $tel =

55

if條件組合 SQL字串 if (chop($name) = ampamp chop($tel) = ) $sql= WHERE $name AND $tel elseif (chop($name) = ) 只有姓名 $sql = WHERE $name elseif (chop($tel) = ) 只有電話號碼 $sql = WHERE $tel $sql= ORDER BY name 最後加上排序 $result = mysql_query($sql) 取得欄位數 $total_fields = mysql_num_fields($result) echo lttable border=1gt echo lttrgtlttdgt編號lttdgtlttdgt姓名lttdgtlttdgt電話lttdgtlttd colspan=2gt功能選項lttdgtlttrgt 表格顯示查詢結果 while ($rows = mysql_fetch_array($result MYSQL_NUM)) echo lttrgt for ($i = 0 $i lt $total_fields $i++) echo lttdgt$rows[$i]lttdgt echo lttdgtlta href=editphpaction=editampid= echo $rows[0]gtltbgt編輯ltbgtlttdgt echo lttdgtlta href=editphpaction=delampid= echo $rows[0]gtltbgt刪除ltbgtlttdgt echo lttrgt echo lttablegtlthrgt mysql_free_result($result) mysql_close($link) gt ltcentergt ltform action=searchphp method=postgt lttable border=0 width=450gt lttrgtlttdgt搜尋姓名 lttdgt lttdgtltinput type=text name=Name size=10 maxlength=20gtlttdgtlttrgt lttrgtlttdgt搜尋電話 lttdgt lttdgtltinput type=text name=Tel

56

size=20 maxlength=20gtlttdgtlttrgt lttrgtlttd colspan=2 align=centergt ltinput type=submit name=Search value=搜尋gtlttdgtlttrgt lttablegt ltformgt ltbrgtlta href=indexhtmlgt通訊錄ltagt | lta href=addphpgt新增連絡人ltagt | lta href=searchphpgt搜尋通訊錄ltagt ltbodygt lthtmlgt

lt ob_start() gt lt-- 程式範例editphp --gt lthtmlgt ltheadgtlttitlegt編輯通訊錄lttitlegtltheadgt ltbodygt lt 取得 URL 參數 $id = $_GET[id] $action = $_GET[action] 建立資料庫連結 $link = mysql_connect(localhostroot1234) mysql_select_db(CONTACT) 選擇資料庫 執行的操作 switch ($action) case update 更新 取得欄位資料 $name = $_POST[Name] $tel = $_POST[Tel] $sql = UPDATE address SET name=$name tel=$tel WHERE id=$id mysql_query($sql) 執行 SQL指令 mysql_close($link) header(Location searchphp) 轉向到 serachphp break case del 刪除 $sql = DELETE FROM address WHERE id=$id

57

mysql_query($sql) 執行 SQL指令 mysql_close($link) header(Location searchphp) 轉向到 serachphp break case edit 編輯 $sql = SELECT FROM address WHERE id=$id $result = mysql_query($sql) 執行 SQL指令 $row = mysql_fetch_row($result) 取回記錄 $name = $row[1] 取得欄位 name $tel = $row[2] 取得欄位 tel mysql_close($link) 顯示編輯表單 gt ltcentergtlth2gt更新通訊錄lth2gtltcentergtlthrgt ltform action=editphpaction=updateampid=lt echo $id gt method=postgt lttable border=0 width=300gt lttrgtlttdgt姓名 lttdgt lttdgtltinput type=text name=Name size=20 maxlength=10 value=lt echo $name gtgtlttdgtlttrgt lttrgtlttdgt電話 lttdgt lttdgtltinput type=text name=Tel size=20 maxlength=20 value=lt echo $tel gtgtlttdgtlttrgt lttrgtlttd colspan=2 align=centergt ltinput type=submit value=更新連絡人gtlttdgtlttrgt lttablegt ltformgt ltbrgtlta href=indexhtmlgt通訊錄ltagt | lta href=addphpgt新增連絡人ltagt | lta href=searchphpgt搜尋通訊錄ltagt lt break gt ltbodygt lthtmlgt

58

52 任務二Web Base群組軟體 ( twig )

順利完成Web Base客戶通訊錄程式測試一段時間後「Apache + MySQL + PHP」架構的穩定與快速巳深得老闆與公司所有同事的認同隨著公司業績蒸

蒸日上人員組織編罝愈來愈龐大跨部門的會議愈來愈多業務員每日排滿拜

訪客戶的行程跟客戶的 Email的往來也愈來愈頻繁 愈來愈多部門的同事希望公司能建置一套群組軟體提供 web mail可讓業

務人員方便收發 mail還有連絡人議事日程待辦工作書簽等功能讓整個

公司運作及個人時間管理更有效率

老闆問小明對這些需求有什麼看法小明認為如果這些功能完全由程式部

門開發必定曠日費時而且耗費公司資源小明在網路尋找是否有提供這些功能

的Free Software皇天不負苦心人小明發現了TWIG (The Web Information Gateway) httptwigscrewdrivernet這個群組軟體它在 Web 上整合郵件新聞聯絡人議事日程工作序書簽等功能非常符合公司的需求 Step 1 下載 twig-277targz 下載網址 httptwigscrewdrivernetdownloadphp3

Step 2 解開 twig-277targz tar -xzvf twig-277targz

59

Step 3 執行安裝動作安裝到 varwwwhtmltwig 目錄 cd twig-277 twig-install varwwwhtmltwig

Step 4 建立 MySQL 資料庫(twig)及各資料表

cd setup mysql -u root -p1234 mysqlgt create database twig Query OK 1 row affected (001 sec) mysqlgt quit mysql -u root ndashp1234 twiglt twigtablemysql

Step 5 修改 configincphp3 參數設定 vi varwwwhtmltwigconfigconfigincphp3 $config[fromdomain] = opencom 網域 $config[language] = chinesebig5 中文訊息 $config[imap_port] = 143notls

60

Step 6 修改連結 MySQL 的帳號密碼 vi varwwwhtmltwigconfigdbconfigincphp3 $dbconfig[sqlusername] = root username $dbconfig[sqlpassword] = 1234 password

Step 7 其他設定檔

vi etchttpdconfhttpdconf 加入 AddType applicationx-httpd-php php3 在 DirectoryIndex最後加入 indexphp3 DirectoryIndex indexhtml indexhtmlvar indexphp3 在 AddDefaultCharset ISO-8859-1加上 AddDefaultCharset ISO-8859-1

vi etcphpini register_globals = On service httpd restart Step 8 sendmail 設定 vi etcmailsendmailcf在 264 行前面加上並重新啟動 sendmail「service snedmail restart」 262 SMTP daemon options 263 264 O DaemonPortOptions=Port=smtpAddr=127001 Name=MTA 265 266 SMTP client options 267 O ClientPortOptions=Family=inet Address=00

61

Step 9 檢查設定有無錯誤 http主機名稱twigtestphp3

62

Step 10 登入 twig ( http主機名稱twig)

63

第六章 維護及更新程序

61 日常維護

系統管理員最好定期以 root 身份登入看看信件在 RedHat Linux 中有一支 logwatch 程式會定時去分析 log file如果發現異常便會發信給 root除此之外筆者建議讀者平時就檢查 MySQL log file ( varlogmysqldlog)是否有異常情形

62 更新程序

讀者可至httprpmfindnet 尋找MySQL相關套件至於升級的相關步驟請參

考Linux OS SOP 第 54節

63 備份重要檔案

預設 MySQL 的 DB 檔案是存在 varlibmysql 內以 DB名稱為目錄目錄

內就是該 DB 的所有資料通常得定期備份還有 MySQL的設定檔 etcmycnf也別忘了一起備份

64 離線備份與還原

641 離線備份

預設 MySQL 的 DB 檔案是存在 varlibmysql 內以 DB 名稱為目錄目錄內

就是該 DB 的所有資料像 CRM 這個 DB就是存在 varlibmysqlCRM 內在備份前因為怕資料尚未完全寫入磁碟而且 MySQL 會 Lock 在使用的 DB 檔案所以應該是要先把 MySQL 先 Shutdown 一下整個備份的程序可以下像下面的指令去完成 cd varlibmysql

64

service mysqld stop tar cvfz CRM_db_20030905tgz CRM service mysqld start 對這樣就可以了 不過要注意的是怕 DB 內每個 Tables 間的資料有關關

聯性所以最好是把整個 DB 一次備起來單獨只備哪個 Tables 的檔案以後回存時怕會有資料關聯不一致的問題

642 離線還原

DB 發生錯誤而要回存時其實也不難先找出最近一次完整正常的備份先把現在錯誤的網頁或 DB 先更名或 tar 起來再把好的備份給解開回原來目錄位

置就行了需要注意的是 MySQL 服務最好也是要先停止回存完成後再啟動服務回存 DB 的整個程序可能像下面 cd varlibmysql service mysqldstop mv CRM CRM_OLD tar xvfz CRM_db_20030905tg service mysqld start

65 線上備份與還原

651 線上備份

使用像上面的檔案方式備份是個不錯的方法它最少可以保持該主機某個時間點的完整檔案備份但還是有一些問題需要考慮到有些主機就不只建立一個 DB 而已總不能為了備份某個 DB 而把整個 MySQL 服務停止備份檔案的方式回存在原主機上一定適用但假如 MySQL 版本升級或是在那天該網頁空間需遷機移機到別的主機時那就沒人敢保證備出來的資料檔可以用所以我們可以考慮另一種備份的方式是使用 MySQL 本身提供的功能 MySQL Data Dump指令是 mysqldump

65

使用 MySQL 的 Dump 功能可以把 DB 的結構資料或結構加資料 Dump 成文字檔 mysqldump 指令提供的彈性很大你可以選擇把整個 DB Dump 成一個檔或是每個 Table 為一個檔甚至是把結構檔和資料分開儲存都

可以 mysqladmin -uroot -p flush-logs mysqldump CRM -uroot -p --opt gt CRM_20030905sql (CRM 是 DB 名稱 opt 是一個使用完整 Dump 參數) 假如只是要單獨 Dump 某個 Table 時只要在上面的指令後轉出符號 gt 前加個 Table 名稱就可以如只要 phpbb2_users 這個 Table 的 Dump 時只要下 mysqldump CRM -uroot -p --opt CUSTOMER gt CRM_CUSTOMER_20030905sql

652 線上還原

若要回存整個資料庫只需將壓縮的備份檔還原成 Dump 的檔案再用下面的指令回存 mysql CRM -uroot -p lt CRM_20030905sql 這邊需注意的是若建立備份時是以--opt或--add-drop-table為參數時回存的 動作是先將舊的 Table 先刪除重建 Table 的結構後再把 Data 匯入所以回存後所有的資料會回到你當時備份那個時間點因此在回存資料時可以考慮把現有錯誤或不完整的 DB 先備份一份下來以備不時之需或是拿來比對錯誤的地

方在那裡當然你也可以把資料回存到另一個測試用的 DB 內只要把上面指令

的 DB 名稱改成你的測試用 DB 名稱即可 使用這種回存方式 MySQL 服務不需停止也不會動到其他正在使用的 DB 在一些提供 MySQL 服務的虛擬主機可用這種方式作你自己的 DB 備份及回存

66

另外假如你是系統重建或是移機時切需在新的 MySQL 內新建一個空白 DB 後才行作回存的工作你可以用下面的指令建立 mysql -uroot -p -e CREATE DATABASE CRM (上面的 CRM是你要新建的 DB 名稱) 另一種作法先用 mysql 指令進入 mysql client console 然後再用 CREATE DATABASE CRM 這樣就行了記得尾端要加個 符號該行指令才會執行

67

第七章 問題與解答

Q1RedHat 90預附的 MySQL到底有無支援 Transcation機制 Ans MySQL自 32334a之後的 MySQL-Max版本加入 InnoDB的資料庫類型透過

InnoDBMySQL同樣可以進行 COMMIT與 ROLLRACK的動作RedHat 90預附的 MySQL為 32354a-11巳支援 InnoDB的資料庫類型不過必須做以

下設定 1cp usrsharedocmysql-server-32354amy-mediumcnf to etcmycnf 2 vi etcmycnf 將以下設定前的拿掉 innodb_data_home_dir = varlibmysql innodb_data_file_path = ibdata110Mautoextend innodb_log_group_home_dir = varlibmysql innodb_log_arch_dir = varlibmysql 3service mysqld restart 如此一來各位在建立Table時便可指定Table Type為 innodb ( ex create table with type=innodb ) Q2如何解決 php+mysql 許功蓋等字變亂的問題 Ans 方法一 【確定 MySQL 預設的字元集】 1 打開 WinMySQLadmin 管理畫面(在視窗右下角狀態列紅綠燈圖示中按滑鼠

右鍵點選 Show me 選項) 2 點選管理畫面中 [Variables] 標籤選項其中 character_set變數就是您預設

字元集的變數其預設是 latin1 字元集(我們要將他改回 big5)而 chatacters_set 變數則是 MySQL 可以支援哪些字元集 【修改預設字元集變數 character_set 】 1 請點選管理畫面中 [myini Setup] 標籤選項設定 myini 2 按一下 [Pick-up and Edit myini values] 按鈕以便編輯目前的 myini 設定 3 在 [mysqld] 設定區塊底下新增一行 default-character-set = big5 變數設

68

定 4 新增一個 [client] 設定區塊並加入第三步驟的變數設定(游標往下移到空白處新增兩行 [client] 和 default-character-set=big5) 5 按一下畫面左下方 [Save Modification] 按鈕儲存設定 6 重新啟動 MySQL 或 Windows 方法二 Server端注意事項 phpini 中有關的設定為(預設值) Magic quotes for incoming GETPOSTCookie data magic_quotes_gpc = On Use Sybase-style magic quotes (escape with instead of ) magic_quotes_sybase = Off Client端注意事項 1中文資料送進 mysql 前請用 addslashes($str) 處理 2處理後送進 mysql 時請用 括起來並在參數後留一個空白如 $sql = UPDATE ezf_table set tablename=$tname tableend=$endtime table inguser=$tguser tableingid=$tguserid tableallnumber=$tnumber tableloca l=$tablelocal tableanyone=$tableopen tabletext=$ttext WHERE tableid=$t ableid tablename=$tname c 取出時請用 stripslashes($str) Q3MySQL root 密碼忘了該怎麼辦 Ans 1先停掉 mysql etcrcdinitdmysql stop 2以--skip-grant-table 的參數啟動 mysql safe_mysql --skip-grant-tableamp 3 更改 root 密碼 mysql mysql mysqlgt UPDATE user SET password=password(newpassword)

69

WHERE user=root mysqlgt FLUSH PRIVILEGES mysqlgt exit 4停掉 mysql再重跑 mysqladmin -uroot -p shutdown Enter password 輸入新設定的密碼 etcrcdinitdmysql start

Q4NULL值問題

Ans

NULL值的概念是造成 SQL的新手的混淆的普遍原因他們經常認為 NULL是和一個空字符串的一樣的東西不是這樣的例如下列語句是完全不同的

mysqlgt INSERT INTO my_table (phone) VALUES (NULL)

mysqlgt INSERT INTO my_table (phone) VALUES ()

兩個語句把值插入到 phone 列但是第一個插入一個 NULL值而第二個插入一個空字符串第一個的含義可以認為是ldquo電話號碼不知道而第二個則可意味

著ldquo她沒有電話

在 SQL中NULL值在于任何其他值甚至 NULL值比較時總是假的(FALSE)包含 NULL的一個表達式總是產生一個 NULL值除非在包含在表達式中的運算符和函數的文檔中指出在下列例子所有的列返回 NULL

mysqlgt SELECT NULL1+NULLCONCAT(InvisibleNULL)

如果你想要尋找值是 NULL的列你不能使用=NULL測試下列語句不返回任

何行因為對任何表達式expr = NULL是假的

mysqlgt SELECT FROM my_table WHERE phone = NULL

要想尋找 NULL值你必須使用 IS NULL測試下例顯示如何找出 NULL電話號碼和空的電話號碼

70

mysqlgt SELECT FROM my_table WHERE phone IS NULL mysqlgt SELECT FROM my_table WHERE phone =

在 MySQL中就像很多其他的 SQL服務器一樣你不能索引可以有 NULL值的列你必須聲明這樣的列為 NOT NULL而且你不能插入 NULL到索引的

列中

當用 LOAD DATA INFILE 讀取數據時空列用更新如果你想要在一個列中有

NULL值你應該在文本文件中使用N字面上的詞NULL也可以在某些情形下使用

當使用 ORDER BY時首先呈現 NULL值如果你用 DESC以降序排序NULL值最後顯示當使用 GROUP BY時所有的 NULL值被認為是相等的

為了有助于NULL的處理你能使用 IS NULL和 IS NOT NULL運算符和 IFNULL()函數

對某些列類型NULL值被特殊地處理如果你將 NULL插入表的第一個TIMESTAMP 列則插入當前的日期和時間如果你將 NULL插入一個AUTO_INCREMENT 列則插入順序中的下一個數字

Q5如何將圖片存放於 MySQL中

Ans

Step 1建立資料庫 test

Step 2 建立表格 binary_data

CREATE TABLE binary_data (

id INT(4) NOT NULL AUTO_INCREMENT PRIMARY KEY

description CHAR(50)

bin_data LONGBLOB

filename CHAR(50)

filesize CHAR(50)

filetype CHAR(50)

71

)

Step 3 利用 storephp 寫入圖片

storephp 程式碼

ltHTMLgt ltHEADgtltTITLEgtStore binary data into SQL DatabaseltTITLEgtltHEADgt ltBODYgt lt code that will be executed if the form has been submitted

if ($submit) mysql_connect(localhostrootYOUR_PASSWORD) mysql_select_db(test) $data=Base64_Encode(fread(fopen($form_data r) filesize($form_data))) $result=MYSQL_QUERY(INSERT INTO binary_data (descriptionbin_datafilenamefilesizefiletype) VALUES ($form_description$data$form_data_name$form_data_size$form_data_type)) $id= mysql_insert_id() print ltpgtThis file has the following Database ID ltbgt$idltbgt MYSQL_CLOSE() else else show the form to submit new data

gt

ltform method=post action=ltphp echo $PHP_SELF gt enctype=multipartform-datagt File Descriptionltbrgt ltinput type=text name=form_description size=40gt ltINPUT TYPE=hidden name=MAX_FILE_SIZE value=4000000gt ltbrgtFile to uploadstore in databaseltbrgt ltinput type=file name=form_data size=40gt ltpgtltinput type=submit name=submit value=submitgt ltformgt lt

72

gt ltBODYgt ltHTMLgt

Step 3 利用 storephp 取出圖片

getdataphp 程式碼

lt Syntax getdataphp3id=ltidgt if($id) you may have to modify login information for your database server MYSQL_CONNECT(localhostrootYOUR_PASSWORD) mysql_select_db(test) $query = select bin_datafiletype from binary_data where id=$id $result = MYSQL_QUERY($query) $data = Base64_Decode(MYSQL_RESULT($result0bin_data)) $type = MYSQL_RESULT($result0filetype) Header( Content-type $type) echo $data gt

Q6MySQL裝好之後啟動時或是執行 mysqladmin會出現如下訊息 Cant connect to local MYSQL Server through Socket varlibmysqlmysqlsock或是

Cant connect to local MYSQL Server through Socket tmpmysqldsock

Ans 可能有下列幾個原因

1這個 mysqldsock 不見了被某人刪除了或是被一些系統自動執行程式給刪

了例如有些 cron任務便會設定定期刪除 tmp 裡的東西所以呢您只能修改

cron 裡的設定讓它不要清除 mysqldsock 2在啟動時也可以改變 mysqldsock的位置您在啟動 MySQL的時候可以加入此參數usrlocalmysqlbinsafe_mysqld --user=mysql --socket=其他路

徑socket amp 同時得去設定環境變數 MYSQL_UNIX_PORT的值以指定新的

73

路徑 3若是您沒改 MYSQL_UNIX_PORT的值那麼您可以在執行指令的時候才打

例如mysqladmin --socket=其他路徑socket version Q7How to get the last insert id Ans CREATE TABLE product ( id INT(4) NOT NULL AUTO_INCREMENT PRIMARY KEY description VARCHAR(50) ) 1利用 SQL的話 mysqlgt insert into product(description) values(123) Query OK 1 row affected (000 sec) mysqlgt select last_insert_id() +------------------+ | last_insert_id() | +------------------+ +------------------+ 1 row in set (000 sec) ======================================== 2如果是 PHP的話 你可以用mysql_insert_id()取得該 id PHP example $result=MYSQL_QUERY(INSERT INTO product (description) VALUES ($description)) $id= mysql_insert_id() print This file has the following Database ID $id Q8如何將文字檔匯入資料庫 Ans $addr=homehttpdhtmlphpschool001txt $sql_select = load data infile $addr into table test fields terminated by t 解說 $sql_select = load data infile 文字檔名 into table 表格名 fields terminated by

74

t

(欄位分隔以 TAB鍵) 該文字檔須與資料表欄位格式相符 例如欄位有三個 則文字檔為每行一筆資料如下 欄 1資料ltTABgt欄 2資料ltTABgt欄 3資料 欄 1資料ltTABgt欄 2資料ltTABgt欄 3資料 欄 1資料ltTABgt欄 2資料ltTABgt欄 3資料 欄 1資料ltTABgtltTABgt欄 3資料

Q9如何撰寫 MySQL C API Ans Step 1利用文字編輯器撰寫以下程式碼 mysqlcc

include ltstdiohgt

include ltmysqlmysqlhgt

int main (int argc char argv[])

MYSQL mysql

MYSQL_RES res

MYSQL_ROW row

if (argc = 2)

fputs (Usage myc ltdatabasegt stderr)

return 1

if ((mysql_connect(ampmysqllocalhostrootYour_Password)))

fputs (Error connecting stderr)

abort()

75

if (mysql_select_db(ampmysqlargv[1]))

fputs (Error selecting database stderr)

abort()

if (mysql_query(ampmysqlSELECT FROM test_table))

fputs (Error processing query stderr)

abort()

if ((res = mysql_store_result(ampmysql)))

fputs (Error storing results stderr)

abort()

while((row = mysql_fetch_row(res)))

uint i = 0

for (i=0 i lt mysql_num_fields(res) i++)

printf(s row[i])

printf(n)

return 0

Step 2 Compile

gcc -Iusrlocalmysqlinclude -Lusrlocalmysqllibmysql mysqlcc ndashlm -lmysqlclient

(其中 include path與 library path取決於你的 MySQL安裝路徑)

76

如果執行時發生如下 error Run problemerror in loading shared libraries libmysqlclientsoX 將你的 MySQL library path(for exampleusrlocalmysqllibmysql) 加入etcldsoconf and run sbinldconfig -v Q9ASP + MySQL 範例程式 Ans Dim myconn As New ADODBConnection Dim myrs As New Recordset Dim mySQL As String Dim myrows As Long myconnOpen DSN=MyODBCsample mySQL = SELECT from user myrsSource = mySQL Set myrsActiveConnection = myconn myrsCursorLocation = adUseClient myrsOpen myrows = myrsRecordCount myrsClose myconnClose 可參考 httpwwwdwamnetmysqlasp_myodbcasp 有詳細的資料 Q10如何將 MySQL中的資料庫匯出成txt檔 Ans select from TableName into outfile textxls all result fields will seperate by tab

77

第八章 參考資料

英文部份 網址 1 httpwwwmysqlcom MySQL 網站有第一手有關 MySQL的資料 2 httpwwwmysqlcomdocenReplicationhtml 有關 MySQL Replication 的文件 3 httpwwwgeocitiescomsqlhomefaqstore_blobhtml 如何在 MySQL 存放 BLOB的資料 4httpwwwsapdborg 有關 SAP跟 MySQL相關合作的網站 書藉 1 Cooking with MySQL

Paul DuBois has selected sample recipes from the hundreds youll find in his book MySQL

Cookbook In this third and final series of excerpts showcasing these recipes learn how to

compute team standings how to calculate the differences between successive Dec 26

2002 2 Tips for Building Web Database Applications with PHP and MySQL by Hugh E Williams co-author of Web Database Applications with PHP amp MySQL 04042002

3 Managing and Using MySQL 2nd Edition By Tim King George Reese Randy Jay Yarger

4 MySQL Cookbook By Paul DuBoisPublisher OReillyPub Date October 2002

中文部份

78

1 httplinuxtncedutwtechdocmysqlmysql_docmanual_tochtml MySQL 中文手冊 2 httpchenshloxaedutwphpZ_1php PHP+MySQ程式研習設計網站 3 httplinuxtncedutwtechdocbanicdownhtml PHP 4 手冊 4 httpwwwtncedutwadmin_zonephp台南縣教育網網路中心有很多 Linux相關文件 5 httpdobtncedutw網站建置百寶箱有很多 PHP MySQL 相關範例程式 5 httpwwwdbworldcomtw資料庫專家電子雜誌介紹資料庫的重要觀念及名詞

79

附錄一 SQL Command 介紹

SQL (讀音ess-que-el) 是一種結構查詢語法SQL 使用於資料庫交流

傳遞相容於 ANSI (American National Standards Institute) 是一套標準的關聯

式資料庫語言 SQL 語言是執行更新或從資料系統獲取資料一般常見的關聯

資料庫系統都有提供 SQL 如 Oracle Sybase Microsoft SQL Server Access Ingres 等雖然大部份的資料庫都有提供 SQL 但也多提供了自已獨特的語

法造成了不相容的情形但標準基本的語法是相通的如Select Insert Update Delete Create and Drop 每一個系統都有支援

Table相關 Command

Create Table

關聯式資料庫包含有很多元件稱為資料表(tables) 把資料或訊息放在資

料表中 資料表是以不同的名稱做分別資料表由欄列所構成的二維陣列

欄包含欄位名資料型態 及其他可判斷的資訊列是由全部欄位構成一筆一

筆的紀錄 create table 語法用在建立一個新的資料表語法格式如下

create table tablename (column1 data type column2 data type column3 data type)

Format of create table if you were to use optional constraints

create table tablename (column1 data type [constraint] column2 data type [constraint] column3 data type [constraint]) [ ] = optional

Note You may have as many columns as youd like and the constraints are optional

80

Example

create table employee (first varchar(15) last varchar(20) age number(3) address varchar(30) city varchar(20) state varchar(20))

注意建立資料表格式要以括號把前後框住而最後以(分號)做結尾

欄位名不要超過 30個字元長而且不要使用 sql 的關鍵字(如 where select等)而在後面接是型態的宣告(如字串數字日期格式等)

資料型態是來描述欄位的方式如一個欄位Last_Name 是一個姓氏可以使用varchar (可變動長度字串) 資料型態

以下是幾個常見的資料庫型態 char(size) 固定長度字串最長為 255 位元 varchar(size) 變動長度字串最大字元數以 size 來指定 number(size) 數值格式可以是整數也可以是小數最大數字以 size 位數判

斷未指定小數位數由系統內定 date 日期格式 number(sized) 數值格式最大數字以 size 位數判斷d 為小數位數整數位

數為 size-d 位

有何限制當資料表被建立通常有一或數個欄位是要使用來做關聯的功

能 例如unique 限制(唯一值)兩筆記錄不可以相同的值 not null (非空值)該欄位一定要輸入資料不可是空的primary key (主鍵)是每一筆記錄識別的主要方式

Drop a table drop table 刪除資料表(其中的資料也會一併刪除)

drop table tablename

Example

81

drop table 和刪除全部資料是不同的刪除全部資料欄位名稱資訊等還會

存在但刪除資料表會把這一些也一併移除掉

如何查詢資料

Select 基本用法

select 語法是關連式資料庫最常用的部份可以取得你想要的資料這是一個

簡單的範例 select column1[column2etc] from tablename [where condition] [] = optional 在 select 之後所列欄位名則是要顯示的資料部份你可以一一列出各欄位

名或是以 (星號)來代表選擇全部的欄位 from 之後放資料表名稱 where 子句 (選項) 指定要過濾的條件符合者才會顯現 where 可使用的條件運算元 = 等於 gt 大於 lt 小於 gt= 大或等於 lt= 小或等於 ltgt 大相等 LIKE 相似 For example select first last city

82

from empinfo where first LIKE Er 以Er 為開頭的字串就符合要以單引號框住 Or you can specify select first last from empinfo where last LIKE s 最後一字為 S 就符合 select from empinfo where first = Eric 則表示 first name 一定要是 Eric 才可以 範例資料表empinfo 統計函數

MIN 傳回指定欄位最小值

MAX 傳回指定欄位最大值

SUM 傳回指定欄位總和

AVG 傳回指定欄位平均值

COUNT 傳回指定欄位的筆數

COUNT() 傳回資料庫中的總筆數

統計函數使用於資料表中的數值欄位配合 SELECT 語法使用 只用於總結特定單一欄位可以配合 GROUP BY 做篩選但也可以不使用 GROUP BY 語句For example

SELECT AVG(salary) FROM employee

83

傳回全部 salary 平均值

Another example

SELECT AVG(salary) FROM employee WHERE title = Programmer

傳回 salary 平均值條件為 employees 資料表中當 title 等於 Programmer

Example

SELECT Count() FROM employees

傳回 employees 資料表中紀錄總筆數

GROUP BY 語法 SELECT column1 SUM(column2) FROM list-of-tables GROUP BY column-list The GROUP BY 語句可以先以所列的欄位為條件分組排序在一起(可以多欄

位) example 要列出每一個 dept 中最高 salary 值 SELECT max(salary) dept FROM employee GROUP BY dept HAVING 語法

SELECT column1 SUM(column2) FROM list-of-tables GROUP BY column-list HAVING condition

HAVING 子句是 GROUP BY 的一部份用來過濾在 GROUP BY 所選出的資料功能如同 select 命令中 where 條件式一樣只是 HAVING 必需配合 GROUP BY 使用

我們以例子來說明我們要取得每一公司名及每一公司的薪水平均值輸入如下

84

SELECT dept avg(salary) FROM employee GROUP BY dept

但如果我們只列出薪資平均值超過 20000元的公司資料

SELECT dept avg(salary) FROM employee GROUP BY dept HAVING avg(salary) gt 20000

ORDER BY子句語法

SELECT column1 SUM(column2) FROM list-of-tables ORDER BY column-list [ASC | DESC]

[ ] =選項

ORDER BY是一個選項子句當你以排序方式來顯示資料(正向由小到大反向由大到小)以指定的欄位資料做排序

ASC = 正向- 預設值 DESC = 反向排序

For example

SELECT employee_id dept name age salary FROM employee_info WHERE dept = Sales ORDER BY salary

以上列出公司代號公司名銷售員人名年紀及薪資而條件是公司名為 Sales 顯示順序以薪資多少排序(由小到大為預設值)

如果要以多個欄位做排序要以逗號做分隔如下

SELECT employee_id dept name age salary FROM employee_info WHERE dept = Sales ORDER BY salary age DESC

85

結合條件及布林運算 SELECT column1 SUM(column2) FROM list-of-tables WHERE condition1 AND condition2 AND運算可以結兩個或以上的條件放在 WHERE子句中 兩者都要為真才

會顯示該筆記錄 OR 運算可以結兩個或以上敘述放在 WHERE子句中只要其中一個為直就

會顯示該筆記錄 For example SELECT employeeid firstname lastname title salary FROM employee_info WHERE salary gt= 5000000 AND title = Programmer 必需要薪資大於等於 50000而且職稱為 Programmer同時符合才會顯示該筆資料 以下以括號括住雖然不是必需的但如此比較容易讀 SELECT employeeid firstname lastname title salary FROM employee_info WHERE (salary gt= 5000000) AND (title = Programmer) 另外範例 SELECT firstname lastname title salary FROM employee_info WHERE (title = Sales) OR (title = Programmer) 條件為只要是 Sales 或 Programmer 職稱的就會被列出 IN and BETWEEN 子句

SELECT column1 SUM(column2) FROM list-of-tables WHERE column3 IN (list-of-values) SELECT column1 SUM(column2) FROM list-of-tables WHERE column3 BETWEEN value1 AND value2 IN 子句使用在列舉項目的使用上也就是分別測試是否符合所列的值 For example

86

SELECT employeeid lastname salary FROM employee_info WHERE lastname IN (Hernandez Jones Roberts Ruiz) 條件為姓氏(astname)要符合 Hernandez Jones Roberts or Ruiz 其中一個才會被傳回 IN運算元也可以使用 OR 的語法來取代如下結果相同 SELECT employeeid lastname salary FROM employee_info WHERE lastname = Hernandez OR lastname = Jones OR lastname = Roberts OR lastname = Ruiz 但使用 IN 句子比較短也比較易懂 你也可以使用 NOT IN 來去掉不要的記錄 BETWEEN 運算元使用在判斷是否存在兩個數值之間 For example SELECT employeeid age lastname salary FROM employee_info WHERE age BETWEEN 30 AND 40 傳回年紀 30歲到 40歲之間的資料(含 30及 40歲者) 相同的也可以使用以下語法來達到相同的結果 SELECT employeeid age lastname salary FROM employee_info WHERE age gt= 30 AND age lt= 40 你也可使用 NOT BETWEEN 來濾掉中間值的資料 數學運算 標準 ANSI SQL-92 提供以下運算

87

+ 加

- 減

餘數

餘數為除法後剩整數這不在標準的 ANSI SQL 中但大部份的資料庫都會支

援這運算元以下列出有用的函數雖不在 ANSI SQL-92 提供但一般資料庫

也會支援他們

ABS(x) 傳回 x 絕對值

SIGN(x) returns the sign of input x as -1 0 or 1 (negative zero or positive respectively)

MOD(xy) 餘數 - returns the integer remainder of x divided by y (同 xy)

FLOOR(x) 傳回小或等於 x 的最大整數值

CEILING(x) or CEIL(x)

傳回大或等於 x 的最小整數值

POWER(xy) x的 y 次方

ROUND(x) 把 x 四捨五入為整數

ROUND(xd) 四捨五入取到小數 d 位

SQRT(x) x 開平方

For example SELECT round(salary) firstname FROM employee_info 傳回薪資取到整數位

如何新增資料

insert 加入一筆新紀錄到資料表中 insert into tablename (first_columnlast_column) values (first_valuelast_value) [] = optional Example insert into employee

88

(first last age address city state) values (Luke Duke 45 2130 Boars Nest Hazard Co Georgia) Note 字串要以單引號住如string 數字框住也無妨 insert into 後面接資料表名稱再接以括號括住的欄位名在 values 後括號分別對映各欄位的值 以上的例子新增了一筆名(first) 為 Luke而住所(state) 為 Georgia 的資料

如何刪除資料

delete 可以刪除單筆或多筆紀錄 delete from tablename where columnname OPERATOR value [and|or column OPERATOR value] [ ] = optional Examples delete from employee Note 如果你沒有指定 where 子句那麼全部的紀錄都會被刪除 delete from employee where lastname = May delete from employee where firstname = Mike or firstname = Eric delete from 接著資料表名 再接著是條件式判斷沒有條件式則全部紀錄會

被刪除

如何更新資料

update 用來更新你所指定的記錄要和 WHERE 配合小心使用 語法 update tablename set columnname = newvalue[nextcolumn = newvalue2] where columnname OPERATOR value [and|or column OPERATOR value] [] = optional Examples

89

update phone_book set area_code = 623 where prefix = 979 update phone_book set last_name = Smith prefix=555 suffix=9292 where last_name = Jones update employee set age = age+1 where first_name=Mary and last_name=Williams

90

附錄二Replication

測試環境

RedHat 90 + MySQL 32358 MySQL資料庫路徑 varlibmysql MySQL設定檔 etcmycnf Master IP 1921680100 Slave IP 1921680200 請至下列網址下載最新MySQL 32358套件並利用rpm ndashUvh 更新 httpupdatesredhatcom9enosi386

圖 最新 MySQL 套件

測試架構圖

91

1921680100

1921680200Master Server

erveSlave S r

圖 測試架構圖

測試步驟

Master server 部份 Step1 確認 MasterSlave機器上所裝的 MySQL版本能進行

replication( 32329 or higher ) Step2 在 Master MySQL上開放一個帳號給 Slave mysql ndashu root ndashp mysqlgtGRANT FILE ON TO repl1921680200 IDENTIFIED BY lsquoabc123rsquo mysqlgtq 上面是 Master開放一個帳號 repl密碼 abc123給 IP1921680200有檔案處理

的權限 Step3 shutdown MySQL on the Master mysqladmin ndashu root ndashp shutdown Step4 備份 Master所有資料庫 tar ndashcvf tmpmysql-snapshottar varlibmysql 注意tar的時候MySQL是要在 stop情況下 在mysql (wwwmysqlcom) 網站的FAQ有不用shutdown的方法

92

Step5 在 master機器上修改etcmycnf 在[mysqld]區段內加入參數 log-bin server-id=這邊設定 server-id=1 sql-bin-update-same binlog-do-db=CRM只針對 CRM資料庫做紀錄 Step6 Restart MySQL on the master service mysqld start 此時因為有加入 log-bin 參數因此開始有 index產生了在varlibmysql目錄下

有index檔案紀錄資料庫的異動 log Slave server 部份 Step1 在 slave設定etcmycnf 在[mysqld]區段加入 master-host= master-user= master-password= master-port= server-id= 這邊設定 master-host=1921680100 master-user=repl master-password=abc123 master-port=3306 server-id=2 master-connect-retry=60預設重試間隔 60秒 replicate-do-db=CRM告訴 slave只做 CRM資料庫的更新 log-slave-updates Step2 將 master上的 mysql-snapshottar copy到 slave上 用 ftp傳到 slave的tmp Step3 解壓縮 Master資料庫至 Slave Server上 cd varlib tar xvf tmpmysql-snapshottar chown ndashR mysqlmysql mysql

93

chmod ndashR 770 mysql (視情況) Step4 Restart MySQL on the slave server 這時在varlibmysql目錄會出現 masterinfo此檔案紀錄了 Master MySQL server的資訊

狀況測試

One-way replication

1921680100

1921680200Master Server

erveSlave S r

圖 One-way replication架構圖 Step1 Master跟 Slave網路及服務都正常情況下由 Master端異動資料後 到 Slave端瀏覽資料檢視是否有進行 replication Step2 模擬 Slave Server 當機 可用在於 slave真的當機或是 Slave 不一定需要一直跟 master connect將Slave MySQL server shutdown由 Master端異動資料到 slave端瀏覽此時Slave應該沒有被 replication 更新然後再將 Slave端 MySQL server start起來

預設 60秒後 Slave會嘗試跟 Master要求進行 replication再去 Slave端檢視是否有更新資料

94

Step3 模擬 Master當機因為是設定 One-way replication一旦 Master Server Slave端沒有 Master的 source可以 download Two-way replication 基於 Master當機狀況於是發展雙向 Replication即 1921680100 ( Host A ) 1921680200 ( Host B )都分別擔任 MasterSlave身分

1921680100

1921680200er

Server B MasterSlave Server

Server A MasterSlave Serv

圖 Two-way replication架構圖 以下是針對兩台 MySQL伺服器進行雙向 Replication Step1觀念同單向 replication只是改成 Master也有 Slave身分 Slave也有Master的身分先分別在 Server AServer B 都去 grant一個進行 replication的身分 [A]mysqlgtGRANT FILE ON TO repl1921680200 IDENTIFIED BY lsquoabc123rsquo [B]mysqlgt GRANT FILE ON TO repl1921680100 IDENTIFIED BY lsquoabc123rsquo Step2做完單向 replication後stop Server Aserver B MySQL service此時 AB資料是一樣的

95

修改etcmycnf設定 範例 Server A [mysqld] datadir=varlibmysql socket=varlibmysqlmysqlsock server-id=1 log-bin sql-bin-update-same binlog-do-db=CRM master-host=1921680200 master-user=repl master-password=abc123 log-slave-updates master-connect-retry=60 replicate-do-db=CRM Server B [mysqld] datadir=varlibmysql socket=varlibmysqlmysqlsock server-id=2 log-bin sql-bin-update-same binlog-do-db=CRM master-host=1921680100 master-user=repl master-password=abc123 log-slave-updates master-connect-retry=60 replicate-do-db=CRM 分別 start Server AServer B MySQL後此時雙方都是 MasterSlave身分一旦哪一方資料異動就會通知對方來 replication-若 replication失效則必須將Server AServer B的masterinfo及index00x 都砍掉然後分別 restart MySQL server進行測試檢視成果 實務上通常如果需要做Two-way replication通常會搭配Virtual Server使用

96

在前端架設一台Virtual Server不過此部份不在此份SOP討論範圍內有興趣

的讀者可參考 httpwwwlinuxvirtualserverorg 網站

1921680100 1921680200

Host A MasterSlave Server

Host B MasterSlave Server

Virtual Host

圖 Virtual Server + Two-way replication 架構圖

97

圖 High Availability Linux Virtual Server架構圖

98

  • COSA-SOP-03-006
  • 第一章 簡介
    • 11適用對象 (Audience)
    • 12 MySQL本身
    • 13 MySQL 40版跟50版重大的改進功能
    • 14 各家資料庫軟體比較
      • 第二章 前置需求
      • 第三章 安裝
        • 31 MySQL安裝
        • 32 phpMyAdmin安裝
        • 33 升級及注意事項
          • 第四章 MySQL管理
            • 41 Webmin 管理介面
            • 42 phpMyAdmin 的操作介面
            • 43管理指令介紹
              • 431 利用mysqladmin設定root的密碼
                  • 第五章 實用範例
                    • 51 任務一Web Base客戶通訊錄
                    • 52 任務二Web Base群組軟體 ( twig )
                      • 第六章 維護及更新程序
                        • 61 日常維護
                        • 62 更新程序
                        • 63 備份重要檔案
                        • 64 離線備份與還原
                        • 65 線上備份與還原
                          • 第七章 問題與解答
                          • 第八章 參考資料
                          • 附錄一 SQL Command 介紹
                          • 附錄二Replication
Page 37: DataBase Server Standard Operation Procedureebooks.lib.ntu.edu.tw/1_file/oss/63/93doc4-5.pdf · 業務的公司帶來了不少壓力,譬如微軟,甲骨文 ... 外的錢用在第三方的資料庫產品上,譬如就可以不用再購買甲骨文公司

Step2 賦予權限

圖 4-16

Step3 權限列表

37

圖 4-17

38

42 phpMyAdmin 的操作介面

421建立資料庫

Step 填入資料庫名稱並按「建立」

圖 4-18建立資料庫

422 建立資料表

Step1 填入資料表名稱並指定欄位數量 執行

39

圖 4-19填入資料表名稱並指定欄位數量

Step2 設定欄位屬性

圖 4-20設定欄位屬性

40

Step3 phpMyAdmin會產生相關的 SQL Command

圖 4-21 資料表結構及相關 SQL Command

Step4新增 Record

41

圖 4-22

圖 4-23

42

圖 4-24

圖 4-25

43

423使用者管理

Step1建立使用者

圖 4-26

44

圖 4-27

Step2 給予權限

圖 4-28

Step3權限列表

45

圖 4-29

43管理指令介紹

431 利用 mysqladmin設定 root的密碼

當您在Windows 或 Linux 中安裝好 MySQL後系統會自動幫您建立兩個

帳分別是 root 和 匿名者MySQL的 root 跟 Linux 最高權限使用者 root無關MySQL的 root使用者相當於 MS SQL 中的 sa 帳號擁有最高的 Database管理權限但系統預設 MySQL的 root 是不需要密碼所以通常我們一安裝

MySQL後首要任務便是修改 root的密碼 我們可以利用 mysqladmin工具或是直接修改 MySQL內部資料庫的使用者資

料 mysqladmin ndashu root ndashh cosaexamplecom password lsquo1234rsquo

46

-u 表示使用者帳號root 為 MySQL預設的管理帳號

-h 表示 MySQL主機的主機名稱也可使用 IP Address password 表示使用者的密碼因為字串請使用單引號將密碼括起來 密碼設定完成之後還是可以利用 mysqladmin修改密碼但是你必須提供目前的密碼

432 連線 MySQL

mysql -uroot -p密碼 (-p和密碼之間不能有空白) 或 mysql -uroot -p (此方式會在進入後要求密碼) [rootossc phpMyAdmin] mysql -u root -p1234

Welcome to the MySQL monitor Commands end with or g

Your MySQL connection id is 25 to server version 32354

Type help or h for help Type c to clear the buffer

mysqlgt show databases

+----------+

| Database |

+----------+

| mysql |

| test |

+----------+

2 rows in set (000 sec)

mysqlgt exit

Bye

[rootossc phpMyAdmin]

433 建立資料庫

可利用 mysqladmin指令建立 CONTACT資料庫 mysqladmin -u root -p1234 create CONTACT

47

或是利用 mysql指令 [rootossc bluepage] mysql -u root -p1234 Welcome to the MySQL monitor Commands end with or g Your MySQL connection id is 1057 to server version 32354 Type help or h for help Type c to clear the buffer mysqlgt create database CONTACT Query OK 1 row affected (000 sec) mysqlgt show databases +----------+ | Database | +----------+ | CONTACT | | address | | hello | | mysql | | nuke | | test | +----------+ 6 rows in set (000 sec) mysqlgt exit

434 建立資料表

編寫 adresssql內容如下 -- Table structure for table address CREATE TABLE address ( id int(11) NOT NULL auto_increment name varchar(20) NOT NULL default tel varchar(15) NOT NULL default PRIMARY KEY (id) ) TYPE=MyISAM

48

-- Dumping data for table address INSERT INTO address VALUES (1林小明0800016888) INSERT INTO address VALUES (2黃大雄0800016888) INSERT INTO address VALUES (3劉小芬0800024365) 然後執行此 sql script mysql -u root -p1234 CONTACT lt addresssql 或是利 mysql command [rootossc bluepage] mysql -u root -p1234 Welcome to the MySQL monitor Commands end with or g Your MySQL connection id is 1090 to server version 32354 Type help or h for help Type c to clear the buffer mysqlgt use CONTACT Database changed Database changed mysqlgt CREATE TABLE address ( -gt id int(11) NOT NULL auto_increment -gt name varchar(20) NOT NULL default -gt tel varchar(15) NOT NULL default -gt PRIMARY KEY (id) -gt ) TYPE=MyISAM Query OK 0 rows affected (000 sec) mysqlgt INSERT INTO address VALUES (1林小明0800016888) Query OK 1 row affected (000 sec) mysqlgt INSERT INTO address VALUES (2黃大雄0800016888) Query OK 1 row affected (000 sec) mysqlgt INSERT INTO address VALUES (3劉小芬0800024365) Query OK 1 row affected (000 sec) mysqlgt exit Bye

49

第五章 實用範例

51 任務一Web Base客戶通訊錄

任職於開放科技公司的林小明前些日子在最符合成本效益的條件下快

速地完成公司網站的建置老闆因此對小明讚譽有加最近因為公司存放客戶資

料的 SQL Server主機屢遭病毒攻擊加上作業系統本身的問題當機次數頻繁

老闆希望能儘快把公司的客戶通訊錄程式移轉到較穩定的環境上因為此客戶通

訊錄程式最主要給內部人員使用所以介面美觀並不特別要求只求穩定且能快

速得到查詢結果老闆希望在短時間先看到程式的雛型並鍵入資料對其效率

及穩定性進行測試因為上次小明表現突出所以這次不可能的任務自然又落到

小明身上 小明想來想去既然要快速又穩定他而且又不希望所有人都得安裝 Client

程式於是小明決定)捨棄他的舊愛「Delphi+MS SQL」投向新歡「Apache + MySQL + PHP」利用此架構來設計一個簡單實用的Web Base客戶通訊錄程式

511 Web Base客戶通訊錄架構

此程式需要建立 CONTACT的資料庫並建立 adress Tables其結構如下表建立步驟請參考第三章 欄位名稱 資料型態 長度 說明 id INT (自動編號) 連絡人編號 name varchar文字 20 連絡人姓名 tel Varchar文字 15 連絡人電話 Web Base通訊錄共有下列幾個檔案功能如下表

檔案名稱 說明 Indexhtml Web Base通訊錄首頁 addphp 新增連絡人的 php程式 searchphp 尋找連絡人的 php程式 editphp 具有更新及刪除功能的 php程式

50

我們將這些檔案放至varwwwhtmlbluepage (預設無 bluepage目錄)

512 Web Base通訊錄測試

httpwwwopencombluepage 新增資料

圖 5-1 新增連絡人

圖 5-2 填入資料

51

圖 5-3 新增成功

搜尋及異動資料

圖 5-4 搜尋通訊錄

52

圖 5-5 編輯資料

圖 5-6 更新資料

513 程式內容及說明

lt-- 程式範例indexhtml--gt lthtmlgt ltheadgtlttitlegt通訊錄lttitlegtltheadgt ltbodygt ltcentergt

53

lth2gt通訊錄lth2gtlthrgt lta href=indexhtmlgt通訊錄ltagt | lta href=addphpgt新增連絡人ltagt | lta href=searchphpgt搜尋通訊錄ltagt ltcentergt ltbodygt lthtmlgt lt-- 程式範例addphp --gt lthtmlgt ltheadgtlttitlegt新增連絡人lttitlegtltheadgt ltbodygt ltcentergtlth2gt新增連絡人lth2gtltcentergtlthrgt lt 取得欄位資料 if (isset($_POST[Name]) ampamp isset($_POST[Tel]) ) $name = $_POST[Name] $tel = $_POST[Tel] 檢查是否有輸入欄位資料 if ($name = ampamp $tel = ) 建立 SQL字串 $sql = INSERT INTO address (name tel) values( $sql= $name $tel) 建立 MySQL 連結 $link = mysql_connect(localhostroot1234) 選擇資料庫 mysql_select_db(CONTACT) 執行 SQL指令 mysql_query($sql) mysql_close($link) echo ltfont color=redgt新增連絡人成功ltfontgtltbrgt gt ltform action=addphp method=postgt lttable border=0 width=300gt lttrgtlttdgt姓名 lttdgt

54

lttdgtltinput type=text name=Name size=20 maxlength=10gtlttdgtlttrgt lttrgtlttdgt電話 lttdgt lttdgtltinput type=text name=Tel size=20 maxlength=20gtlttdgtlttrgt lttrgtlttd colspan=2 align=centergt ltinput type=submit value=新增連絡人gtlttdgtlttrgt lttablegt ltformgt ltbrgtlta href=indexhtmlgt通訊錄ltagt | lta href=addphpgt新增連絡人ltagt | lta href=searchphpgt搜尋通訊錄ltagt ltbodygt lthtmlgt

lt-- 程式範例searchphp --gt lthtmlgt ltheadgtlttitlegt搜尋通訊錄lttitlegtltheadgt ltbodygt ltcentergtlth2gt搜尋通訊錄lth2gtlthrgt lt if (isset($_POST[Search])) 建立資料庫連結並選定資料庫 $link = mysql_connect(localhostroot1234) mysql_select_db(CONTACT) 建立基本的 SQL字串 $sql = SELECT FROM address 檢查是否輸入姓名 if (chop($_POST[Name]) = ) $name = name LIKE $_POST[Name] else $name = 檢查是否輸入電話號碼 if (chop($_POST[Tel]) = ) $tel = tel LIKE $_POST[Tel] else $tel =

55

if條件組合 SQL字串 if (chop($name) = ampamp chop($tel) = ) $sql= WHERE $name AND $tel elseif (chop($name) = ) 只有姓名 $sql = WHERE $name elseif (chop($tel) = ) 只有電話號碼 $sql = WHERE $tel $sql= ORDER BY name 最後加上排序 $result = mysql_query($sql) 取得欄位數 $total_fields = mysql_num_fields($result) echo lttable border=1gt echo lttrgtlttdgt編號lttdgtlttdgt姓名lttdgtlttdgt電話lttdgtlttd colspan=2gt功能選項lttdgtlttrgt 表格顯示查詢結果 while ($rows = mysql_fetch_array($result MYSQL_NUM)) echo lttrgt for ($i = 0 $i lt $total_fields $i++) echo lttdgt$rows[$i]lttdgt echo lttdgtlta href=editphpaction=editampid= echo $rows[0]gtltbgt編輯ltbgtlttdgt echo lttdgtlta href=editphpaction=delampid= echo $rows[0]gtltbgt刪除ltbgtlttdgt echo lttrgt echo lttablegtlthrgt mysql_free_result($result) mysql_close($link) gt ltcentergt ltform action=searchphp method=postgt lttable border=0 width=450gt lttrgtlttdgt搜尋姓名 lttdgt lttdgtltinput type=text name=Name size=10 maxlength=20gtlttdgtlttrgt lttrgtlttdgt搜尋電話 lttdgt lttdgtltinput type=text name=Tel

56

size=20 maxlength=20gtlttdgtlttrgt lttrgtlttd colspan=2 align=centergt ltinput type=submit name=Search value=搜尋gtlttdgtlttrgt lttablegt ltformgt ltbrgtlta href=indexhtmlgt通訊錄ltagt | lta href=addphpgt新增連絡人ltagt | lta href=searchphpgt搜尋通訊錄ltagt ltbodygt lthtmlgt

lt ob_start() gt lt-- 程式範例editphp --gt lthtmlgt ltheadgtlttitlegt編輯通訊錄lttitlegtltheadgt ltbodygt lt 取得 URL 參數 $id = $_GET[id] $action = $_GET[action] 建立資料庫連結 $link = mysql_connect(localhostroot1234) mysql_select_db(CONTACT) 選擇資料庫 執行的操作 switch ($action) case update 更新 取得欄位資料 $name = $_POST[Name] $tel = $_POST[Tel] $sql = UPDATE address SET name=$name tel=$tel WHERE id=$id mysql_query($sql) 執行 SQL指令 mysql_close($link) header(Location searchphp) 轉向到 serachphp break case del 刪除 $sql = DELETE FROM address WHERE id=$id

57

mysql_query($sql) 執行 SQL指令 mysql_close($link) header(Location searchphp) 轉向到 serachphp break case edit 編輯 $sql = SELECT FROM address WHERE id=$id $result = mysql_query($sql) 執行 SQL指令 $row = mysql_fetch_row($result) 取回記錄 $name = $row[1] 取得欄位 name $tel = $row[2] 取得欄位 tel mysql_close($link) 顯示編輯表單 gt ltcentergtlth2gt更新通訊錄lth2gtltcentergtlthrgt ltform action=editphpaction=updateampid=lt echo $id gt method=postgt lttable border=0 width=300gt lttrgtlttdgt姓名 lttdgt lttdgtltinput type=text name=Name size=20 maxlength=10 value=lt echo $name gtgtlttdgtlttrgt lttrgtlttdgt電話 lttdgt lttdgtltinput type=text name=Tel size=20 maxlength=20 value=lt echo $tel gtgtlttdgtlttrgt lttrgtlttd colspan=2 align=centergt ltinput type=submit value=更新連絡人gtlttdgtlttrgt lttablegt ltformgt ltbrgtlta href=indexhtmlgt通訊錄ltagt | lta href=addphpgt新增連絡人ltagt | lta href=searchphpgt搜尋通訊錄ltagt lt break gt ltbodygt lthtmlgt

58

52 任務二Web Base群組軟體 ( twig )

順利完成Web Base客戶通訊錄程式測試一段時間後「Apache + MySQL + PHP」架構的穩定與快速巳深得老闆與公司所有同事的認同隨著公司業績蒸

蒸日上人員組織編罝愈來愈龐大跨部門的會議愈來愈多業務員每日排滿拜

訪客戶的行程跟客戶的 Email的往來也愈來愈頻繁 愈來愈多部門的同事希望公司能建置一套群組軟體提供 web mail可讓業

務人員方便收發 mail還有連絡人議事日程待辦工作書簽等功能讓整個

公司運作及個人時間管理更有效率

老闆問小明對這些需求有什麼看法小明認為如果這些功能完全由程式部

門開發必定曠日費時而且耗費公司資源小明在網路尋找是否有提供這些功能

的Free Software皇天不負苦心人小明發現了TWIG (The Web Information Gateway) httptwigscrewdrivernet這個群組軟體它在 Web 上整合郵件新聞聯絡人議事日程工作序書簽等功能非常符合公司的需求 Step 1 下載 twig-277targz 下載網址 httptwigscrewdrivernetdownloadphp3

Step 2 解開 twig-277targz tar -xzvf twig-277targz

59

Step 3 執行安裝動作安裝到 varwwwhtmltwig 目錄 cd twig-277 twig-install varwwwhtmltwig

Step 4 建立 MySQL 資料庫(twig)及各資料表

cd setup mysql -u root -p1234 mysqlgt create database twig Query OK 1 row affected (001 sec) mysqlgt quit mysql -u root ndashp1234 twiglt twigtablemysql

Step 5 修改 configincphp3 參數設定 vi varwwwhtmltwigconfigconfigincphp3 $config[fromdomain] = opencom 網域 $config[language] = chinesebig5 中文訊息 $config[imap_port] = 143notls

60

Step 6 修改連結 MySQL 的帳號密碼 vi varwwwhtmltwigconfigdbconfigincphp3 $dbconfig[sqlusername] = root username $dbconfig[sqlpassword] = 1234 password

Step 7 其他設定檔

vi etchttpdconfhttpdconf 加入 AddType applicationx-httpd-php php3 在 DirectoryIndex最後加入 indexphp3 DirectoryIndex indexhtml indexhtmlvar indexphp3 在 AddDefaultCharset ISO-8859-1加上 AddDefaultCharset ISO-8859-1

vi etcphpini register_globals = On service httpd restart Step 8 sendmail 設定 vi etcmailsendmailcf在 264 行前面加上並重新啟動 sendmail「service snedmail restart」 262 SMTP daemon options 263 264 O DaemonPortOptions=Port=smtpAddr=127001 Name=MTA 265 266 SMTP client options 267 O ClientPortOptions=Family=inet Address=00

61

Step 9 檢查設定有無錯誤 http主機名稱twigtestphp3

62

Step 10 登入 twig ( http主機名稱twig)

63

第六章 維護及更新程序

61 日常維護

系統管理員最好定期以 root 身份登入看看信件在 RedHat Linux 中有一支 logwatch 程式會定時去分析 log file如果發現異常便會發信給 root除此之外筆者建議讀者平時就檢查 MySQL log file ( varlogmysqldlog)是否有異常情形

62 更新程序

讀者可至httprpmfindnet 尋找MySQL相關套件至於升級的相關步驟請參

考Linux OS SOP 第 54節

63 備份重要檔案

預設 MySQL 的 DB 檔案是存在 varlibmysql 內以 DB名稱為目錄目錄

內就是該 DB 的所有資料通常得定期備份還有 MySQL的設定檔 etcmycnf也別忘了一起備份

64 離線備份與還原

641 離線備份

預設 MySQL 的 DB 檔案是存在 varlibmysql 內以 DB 名稱為目錄目錄內

就是該 DB 的所有資料像 CRM 這個 DB就是存在 varlibmysqlCRM 內在備份前因為怕資料尚未完全寫入磁碟而且 MySQL 會 Lock 在使用的 DB 檔案所以應該是要先把 MySQL 先 Shutdown 一下整個備份的程序可以下像下面的指令去完成 cd varlibmysql

64

service mysqld stop tar cvfz CRM_db_20030905tgz CRM service mysqld start 對這樣就可以了 不過要注意的是怕 DB 內每個 Tables 間的資料有關關

聯性所以最好是把整個 DB 一次備起來單獨只備哪個 Tables 的檔案以後回存時怕會有資料關聯不一致的問題

642 離線還原

DB 發生錯誤而要回存時其實也不難先找出最近一次完整正常的備份先把現在錯誤的網頁或 DB 先更名或 tar 起來再把好的備份給解開回原來目錄位

置就行了需要注意的是 MySQL 服務最好也是要先停止回存完成後再啟動服務回存 DB 的整個程序可能像下面 cd varlibmysql service mysqldstop mv CRM CRM_OLD tar xvfz CRM_db_20030905tg service mysqld start

65 線上備份與還原

651 線上備份

使用像上面的檔案方式備份是個不錯的方法它最少可以保持該主機某個時間點的完整檔案備份但還是有一些問題需要考慮到有些主機就不只建立一個 DB 而已總不能為了備份某個 DB 而把整個 MySQL 服務停止備份檔案的方式回存在原主機上一定適用但假如 MySQL 版本升級或是在那天該網頁空間需遷機移機到別的主機時那就沒人敢保證備出來的資料檔可以用所以我們可以考慮另一種備份的方式是使用 MySQL 本身提供的功能 MySQL Data Dump指令是 mysqldump

65

使用 MySQL 的 Dump 功能可以把 DB 的結構資料或結構加資料 Dump 成文字檔 mysqldump 指令提供的彈性很大你可以選擇把整個 DB Dump 成一個檔或是每個 Table 為一個檔甚至是把結構檔和資料分開儲存都

可以 mysqladmin -uroot -p flush-logs mysqldump CRM -uroot -p --opt gt CRM_20030905sql (CRM 是 DB 名稱 opt 是一個使用完整 Dump 參數) 假如只是要單獨 Dump 某個 Table 時只要在上面的指令後轉出符號 gt 前加個 Table 名稱就可以如只要 phpbb2_users 這個 Table 的 Dump 時只要下 mysqldump CRM -uroot -p --opt CUSTOMER gt CRM_CUSTOMER_20030905sql

652 線上還原

若要回存整個資料庫只需將壓縮的備份檔還原成 Dump 的檔案再用下面的指令回存 mysql CRM -uroot -p lt CRM_20030905sql 這邊需注意的是若建立備份時是以--opt或--add-drop-table為參數時回存的 動作是先將舊的 Table 先刪除重建 Table 的結構後再把 Data 匯入所以回存後所有的資料會回到你當時備份那個時間點因此在回存資料時可以考慮把現有錯誤或不完整的 DB 先備份一份下來以備不時之需或是拿來比對錯誤的地

方在那裡當然你也可以把資料回存到另一個測試用的 DB 內只要把上面指令

的 DB 名稱改成你的測試用 DB 名稱即可 使用這種回存方式 MySQL 服務不需停止也不會動到其他正在使用的 DB 在一些提供 MySQL 服務的虛擬主機可用這種方式作你自己的 DB 備份及回存

66

另外假如你是系統重建或是移機時切需在新的 MySQL 內新建一個空白 DB 後才行作回存的工作你可以用下面的指令建立 mysql -uroot -p -e CREATE DATABASE CRM (上面的 CRM是你要新建的 DB 名稱) 另一種作法先用 mysql 指令進入 mysql client console 然後再用 CREATE DATABASE CRM 這樣就行了記得尾端要加個 符號該行指令才會執行

67

第七章 問題與解答

Q1RedHat 90預附的 MySQL到底有無支援 Transcation機制 Ans MySQL自 32334a之後的 MySQL-Max版本加入 InnoDB的資料庫類型透過

InnoDBMySQL同樣可以進行 COMMIT與 ROLLRACK的動作RedHat 90預附的 MySQL為 32354a-11巳支援 InnoDB的資料庫類型不過必須做以

下設定 1cp usrsharedocmysql-server-32354amy-mediumcnf to etcmycnf 2 vi etcmycnf 將以下設定前的拿掉 innodb_data_home_dir = varlibmysql innodb_data_file_path = ibdata110Mautoextend innodb_log_group_home_dir = varlibmysql innodb_log_arch_dir = varlibmysql 3service mysqld restart 如此一來各位在建立Table時便可指定Table Type為 innodb ( ex create table with type=innodb ) Q2如何解決 php+mysql 許功蓋等字變亂的問題 Ans 方法一 【確定 MySQL 預設的字元集】 1 打開 WinMySQLadmin 管理畫面(在視窗右下角狀態列紅綠燈圖示中按滑鼠

右鍵點選 Show me 選項) 2 點選管理畫面中 [Variables] 標籤選項其中 character_set變數就是您預設

字元集的變數其預設是 latin1 字元集(我們要將他改回 big5)而 chatacters_set 變數則是 MySQL 可以支援哪些字元集 【修改預設字元集變數 character_set 】 1 請點選管理畫面中 [myini Setup] 標籤選項設定 myini 2 按一下 [Pick-up and Edit myini values] 按鈕以便編輯目前的 myini 設定 3 在 [mysqld] 設定區塊底下新增一行 default-character-set = big5 變數設

68

定 4 新增一個 [client] 設定區塊並加入第三步驟的變數設定(游標往下移到空白處新增兩行 [client] 和 default-character-set=big5) 5 按一下畫面左下方 [Save Modification] 按鈕儲存設定 6 重新啟動 MySQL 或 Windows 方法二 Server端注意事項 phpini 中有關的設定為(預設值) Magic quotes for incoming GETPOSTCookie data magic_quotes_gpc = On Use Sybase-style magic quotes (escape with instead of ) magic_quotes_sybase = Off Client端注意事項 1中文資料送進 mysql 前請用 addslashes($str) 處理 2處理後送進 mysql 時請用 括起來並在參數後留一個空白如 $sql = UPDATE ezf_table set tablename=$tname tableend=$endtime table inguser=$tguser tableingid=$tguserid tableallnumber=$tnumber tableloca l=$tablelocal tableanyone=$tableopen tabletext=$ttext WHERE tableid=$t ableid tablename=$tname c 取出時請用 stripslashes($str) Q3MySQL root 密碼忘了該怎麼辦 Ans 1先停掉 mysql etcrcdinitdmysql stop 2以--skip-grant-table 的參數啟動 mysql safe_mysql --skip-grant-tableamp 3 更改 root 密碼 mysql mysql mysqlgt UPDATE user SET password=password(newpassword)

69

WHERE user=root mysqlgt FLUSH PRIVILEGES mysqlgt exit 4停掉 mysql再重跑 mysqladmin -uroot -p shutdown Enter password 輸入新設定的密碼 etcrcdinitdmysql start

Q4NULL值問題

Ans

NULL值的概念是造成 SQL的新手的混淆的普遍原因他們經常認為 NULL是和一個空字符串的一樣的東西不是這樣的例如下列語句是完全不同的

mysqlgt INSERT INTO my_table (phone) VALUES (NULL)

mysqlgt INSERT INTO my_table (phone) VALUES ()

兩個語句把值插入到 phone 列但是第一個插入一個 NULL值而第二個插入一個空字符串第一個的含義可以認為是ldquo電話號碼不知道而第二個則可意味

著ldquo她沒有電話

在 SQL中NULL值在于任何其他值甚至 NULL值比較時總是假的(FALSE)包含 NULL的一個表達式總是產生一個 NULL值除非在包含在表達式中的運算符和函數的文檔中指出在下列例子所有的列返回 NULL

mysqlgt SELECT NULL1+NULLCONCAT(InvisibleNULL)

如果你想要尋找值是 NULL的列你不能使用=NULL測試下列語句不返回任

何行因為對任何表達式expr = NULL是假的

mysqlgt SELECT FROM my_table WHERE phone = NULL

要想尋找 NULL值你必須使用 IS NULL測試下例顯示如何找出 NULL電話號碼和空的電話號碼

70

mysqlgt SELECT FROM my_table WHERE phone IS NULL mysqlgt SELECT FROM my_table WHERE phone =

在 MySQL中就像很多其他的 SQL服務器一樣你不能索引可以有 NULL值的列你必須聲明這樣的列為 NOT NULL而且你不能插入 NULL到索引的

列中

當用 LOAD DATA INFILE 讀取數據時空列用更新如果你想要在一個列中有

NULL值你應該在文本文件中使用N字面上的詞NULL也可以在某些情形下使用

當使用 ORDER BY時首先呈現 NULL值如果你用 DESC以降序排序NULL值最後顯示當使用 GROUP BY時所有的 NULL值被認為是相等的

為了有助于NULL的處理你能使用 IS NULL和 IS NOT NULL運算符和 IFNULL()函數

對某些列類型NULL值被特殊地處理如果你將 NULL插入表的第一個TIMESTAMP 列則插入當前的日期和時間如果你將 NULL插入一個AUTO_INCREMENT 列則插入順序中的下一個數字

Q5如何將圖片存放於 MySQL中

Ans

Step 1建立資料庫 test

Step 2 建立表格 binary_data

CREATE TABLE binary_data (

id INT(4) NOT NULL AUTO_INCREMENT PRIMARY KEY

description CHAR(50)

bin_data LONGBLOB

filename CHAR(50)

filesize CHAR(50)

filetype CHAR(50)

71

)

Step 3 利用 storephp 寫入圖片

storephp 程式碼

ltHTMLgt ltHEADgtltTITLEgtStore binary data into SQL DatabaseltTITLEgtltHEADgt ltBODYgt lt code that will be executed if the form has been submitted

if ($submit) mysql_connect(localhostrootYOUR_PASSWORD) mysql_select_db(test) $data=Base64_Encode(fread(fopen($form_data r) filesize($form_data))) $result=MYSQL_QUERY(INSERT INTO binary_data (descriptionbin_datafilenamefilesizefiletype) VALUES ($form_description$data$form_data_name$form_data_size$form_data_type)) $id= mysql_insert_id() print ltpgtThis file has the following Database ID ltbgt$idltbgt MYSQL_CLOSE() else else show the form to submit new data

gt

ltform method=post action=ltphp echo $PHP_SELF gt enctype=multipartform-datagt File Descriptionltbrgt ltinput type=text name=form_description size=40gt ltINPUT TYPE=hidden name=MAX_FILE_SIZE value=4000000gt ltbrgtFile to uploadstore in databaseltbrgt ltinput type=file name=form_data size=40gt ltpgtltinput type=submit name=submit value=submitgt ltformgt lt

72

gt ltBODYgt ltHTMLgt

Step 3 利用 storephp 取出圖片

getdataphp 程式碼

lt Syntax getdataphp3id=ltidgt if($id) you may have to modify login information for your database server MYSQL_CONNECT(localhostrootYOUR_PASSWORD) mysql_select_db(test) $query = select bin_datafiletype from binary_data where id=$id $result = MYSQL_QUERY($query) $data = Base64_Decode(MYSQL_RESULT($result0bin_data)) $type = MYSQL_RESULT($result0filetype) Header( Content-type $type) echo $data gt

Q6MySQL裝好之後啟動時或是執行 mysqladmin會出現如下訊息 Cant connect to local MYSQL Server through Socket varlibmysqlmysqlsock或是

Cant connect to local MYSQL Server through Socket tmpmysqldsock

Ans 可能有下列幾個原因

1這個 mysqldsock 不見了被某人刪除了或是被一些系統自動執行程式給刪

了例如有些 cron任務便會設定定期刪除 tmp 裡的東西所以呢您只能修改

cron 裡的設定讓它不要清除 mysqldsock 2在啟動時也可以改變 mysqldsock的位置您在啟動 MySQL的時候可以加入此參數usrlocalmysqlbinsafe_mysqld --user=mysql --socket=其他路

徑socket amp 同時得去設定環境變數 MYSQL_UNIX_PORT的值以指定新的

73

路徑 3若是您沒改 MYSQL_UNIX_PORT的值那麼您可以在執行指令的時候才打

例如mysqladmin --socket=其他路徑socket version Q7How to get the last insert id Ans CREATE TABLE product ( id INT(4) NOT NULL AUTO_INCREMENT PRIMARY KEY description VARCHAR(50) ) 1利用 SQL的話 mysqlgt insert into product(description) values(123) Query OK 1 row affected (000 sec) mysqlgt select last_insert_id() +------------------+ | last_insert_id() | +------------------+ +------------------+ 1 row in set (000 sec) ======================================== 2如果是 PHP的話 你可以用mysql_insert_id()取得該 id PHP example $result=MYSQL_QUERY(INSERT INTO product (description) VALUES ($description)) $id= mysql_insert_id() print This file has the following Database ID $id Q8如何將文字檔匯入資料庫 Ans $addr=homehttpdhtmlphpschool001txt $sql_select = load data infile $addr into table test fields terminated by t 解說 $sql_select = load data infile 文字檔名 into table 表格名 fields terminated by

74

t

(欄位分隔以 TAB鍵) 該文字檔須與資料表欄位格式相符 例如欄位有三個 則文字檔為每行一筆資料如下 欄 1資料ltTABgt欄 2資料ltTABgt欄 3資料 欄 1資料ltTABgt欄 2資料ltTABgt欄 3資料 欄 1資料ltTABgt欄 2資料ltTABgt欄 3資料 欄 1資料ltTABgtltTABgt欄 3資料

Q9如何撰寫 MySQL C API Ans Step 1利用文字編輯器撰寫以下程式碼 mysqlcc

include ltstdiohgt

include ltmysqlmysqlhgt

int main (int argc char argv[])

MYSQL mysql

MYSQL_RES res

MYSQL_ROW row

if (argc = 2)

fputs (Usage myc ltdatabasegt stderr)

return 1

if ((mysql_connect(ampmysqllocalhostrootYour_Password)))

fputs (Error connecting stderr)

abort()

75

if (mysql_select_db(ampmysqlargv[1]))

fputs (Error selecting database stderr)

abort()

if (mysql_query(ampmysqlSELECT FROM test_table))

fputs (Error processing query stderr)

abort()

if ((res = mysql_store_result(ampmysql)))

fputs (Error storing results stderr)

abort()

while((row = mysql_fetch_row(res)))

uint i = 0

for (i=0 i lt mysql_num_fields(res) i++)

printf(s row[i])

printf(n)

return 0

Step 2 Compile

gcc -Iusrlocalmysqlinclude -Lusrlocalmysqllibmysql mysqlcc ndashlm -lmysqlclient

(其中 include path與 library path取決於你的 MySQL安裝路徑)

76

如果執行時發生如下 error Run problemerror in loading shared libraries libmysqlclientsoX 將你的 MySQL library path(for exampleusrlocalmysqllibmysql) 加入etcldsoconf and run sbinldconfig -v Q9ASP + MySQL 範例程式 Ans Dim myconn As New ADODBConnection Dim myrs As New Recordset Dim mySQL As String Dim myrows As Long myconnOpen DSN=MyODBCsample mySQL = SELECT from user myrsSource = mySQL Set myrsActiveConnection = myconn myrsCursorLocation = adUseClient myrsOpen myrows = myrsRecordCount myrsClose myconnClose 可參考 httpwwwdwamnetmysqlasp_myodbcasp 有詳細的資料 Q10如何將 MySQL中的資料庫匯出成txt檔 Ans select from TableName into outfile textxls all result fields will seperate by tab

77

第八章 參考資料

英文部份 網址 1 httpwwwmysqlcom MySQL 網站有第一手有關 MySQL的資料 2 httpwwwmysqlcomdocenReplicationhtml 有關 MySQL Replication 的文件 3 httpwwwgeocitiescomsqlhomefaqstore_blobhtml 如何在 MySQL 存放 BLOB的資料 4httpwwwsapdborg 有關 SAP跟 MySQL相關合作的網站 書藉 1 Cooking with MySQL

Paul DuBois has selected sample recipes from the hundreds youll find in his book MySQL

Cookbook In this third and final series of excerpts showcasing these recipes learn how to

compute team standings how to calculate the differences between successive Dec 26

2002 2 Tips for Building Web Database Applications with PHP and MySQL by Hugh E Williams co-author of Web Database Applications with PHP amp MySQL 04042002

3 Managing and Using MySQL 2nd Edition By Tim King George Reese Randy Jay Yarger

4 MySQL Cookbook By Paul DuBoisPublisher OReillyPub Date October 2002

中文部份

78

1 httplinuxtncedutwtechdocmysqlmysql_docmanual_tochtml MySQL 中文手冊 2 httpchenshloxaedutwphpZ_1php PHP+MySQ程式研習設計網站 3 httplinuxtncedutwtechdocbanicdownhtml PHP 4 手冊 4 httpwwwtncedutwadmin_zonephp台南縣教育網網路中心有很多 Linux相關文件 5 httpdobtncedutw網站建置百寶箱有很多 PHP MySQL 相關範例程式 5 httpwwwdbworldcomtw資料庫專家電子雜誌介紹資料庫的重要觀念及名詞

79

附錄一 SQL Command 介紹

SQL (讀音ess-que-el) 是一種結構查詢語法SQL 使用於資料庫交流

傳遞相容於 ANSI (American National Standards Institute) 是一套標準的關聯

式資料庫語言 SQL 語言是執行更新或從資料系統獲取資料一般常見的關聯

資料庫系統都有提供 SQL 如 Oracle Sybase Microsoft SQL Server Access Ingres 等雖然大部份的資料庫都有提供 SQL 但也多提供了自已獨特的語

法造成了不相容的情形但標準基本的語法是相通的如Select Insert Update Delete Create and Drop 每一個系統都有支援

Table相關 Command

Create Table

關聯式資料庫包含有很多元件稱為資料表(tables) 把資料或訊息放在資

料表中 資料表是以不同的名稱做分別資料表由欄列所構成的二維陣列

欄包含欄位名資料型態 及其他可判斷的資訊列是由全部欄位構成一筆一

筆的紀錄 create table 語法用在建立一個新的資料表語法格式如下

create table tablename (column1 data type column2 data type column3 data type)

Format of create table if you were to use optional constraints

create table tablename (column1 data type [constraint] column2 data type [constraint] column3 data type [constraint]) [ ] = optional

Note You may have as many columns as youd like and the constraints are optional

80

Example

create table employee (first varchar(15) last varchar(20) age number(3) address varchar(30) city varchar(20) state varchar(20))

注意建立資料表格式要以括號把前後框住而最後以(分號)做結尾

欄位名不要超過 30個字元長而且不要使用 sql 的關鍵字(如 where select等)而在後面接是型態的宣告(如字串數字日期格式等)

資料型態是來描述欄位的方式如一個欄位Last_Name 是一個姓氏可以使用varchar (可變動長度字串) 資料型態

以下是幾個常見的資料庫型態 char(size) 固定長度字串最長為 255 位元 varchar(size) 變動長度字串最大字元數以 size 來指定 number(size) 數值格式可以是整數也可以是小數最大數字以 size 位數判

斷未指定小數位數由系統內定 date 日期格式 number(sized) 數值格式最大數字以 size 位數判斷d 為小數位數整數位

數為 size-d 位

有何限制當資料表被建立通常有一或數個欄位是要使用來做關聯的功

能 例如unique 限制(唯一值)兩筆記錄不可以相同的值 not null (非空值)該欄位一定要輸入資料不可是空的primary key (主鍵)是每一筆記錄識別的主要方式

Drop a table drop table 刪除資料表(其中的資料也會一併刪除)

drop table tablename

Example

81

drop table 和刪除全部資料是不同的刪除全部資料欄位名稱資訊等還會

存在但刪除資料表會把這一些也一併移除掉

如何查詢資料

Select 基本用法

select 語法是關連式資料庫最常用的部份可以取得你想要的資料這是一個

簡單的範例 select column1[column2etc] from tablename [where condition] [] = optional 在 select 之後所列欄位名則是要顯示的資料部份你可以一一列出各欄位

名或是以 (星號)來代表選擇全部的欄位 from 之後放資料表名稱 where 子句 (選項) 指定要過濾的條件符合者才會顯現 where 可使用的條件運算元 = 等於 gt 大於 lt 小於 gt= 大或等於 lt= 小或等於 ltgt 大相等 LIKE 相似 For example select first last city

82

from empinfo where first LIKE Er 以Er 為開頭的字串就符合要以單引號框住 Or you can specify select first last from empinfo where last LIKE s 最後一字為 S 就符合 select from empinfo where first = Eric 則表示 first name 一定要是 Eric 才可以 範例資料表empinfo 統計函數

MIN 傳回指定欄位最小值

MAX 傳回指定欄位最大值

SUM 傳回指定欄位總和

AVG 傳回指定欄位平均值

COUNT 傳回指定欄位的筆數

COUNT() 傳回資料庫中的總筆數

統計函數使用於資料表中的數值欄位配合 SELECT 語法使用 只用於總結特定單一欄位可以配合 GROUP BY 做篩選但也可以不使用 GROUP BY 語句For example

SELECT AVG(salary) FROM employee

83

傳回全部 salary 平均值

Another example

SELECT AVG(salary) FROM employee WHERE title = Programmer

傳回 salary 平均值條件為 employees 資料表中當 title 等於 Programmer

Example

SELECT Count() FROM employees

傳回 employees 資料表中紀錄總筆數

GROUP BY 語法 SELECT column1 SUM(column2) FROM list-of-tables GROUP BY column-list The GROUP BY 語句可以先以所列的欄位為條件分組排序在一起(可以多欄

位) example 要列出每一個 dept 中最高 salary 值 SELECT max(salary) dept FROM employee GROUP BY dept HAVING 語法

SELECT column1 SUM(column2) FROM list-of-tables GROUP BY column-list HAVING condition

HAVING 子句是 GROUP BY 的一部份用來過濾在 GROUP BY 所選出的資料功能如同 select 命令中 where 條件式一樣只是 HAVING 必需配合 GROUP BY 使用

我們以例子來說明我們要取得每一公司名及每一公司的薪水平均值輸入如下

84

SELECT dept avg(salary) FROM employee GROUP BY dept

但如果我們只列出薪資平均值超過 20000元的公司資料

SELECT dept avg(salary) FROM employee GROUP BY dept HAVING avg(salary) gt 20000

ORDER BY子句語法

SELECT column1 SUM(column2) FROM list-of-tables ORDER BY column-list [ASC | DESC]

[ ] =選項

ORDER BY是一個選項子句當你以排序方式來顯示資料(正向由小到大反向由大到小)以指定的欄位資料做排序

ASC = 正向- 預設值 DESC = 反向排序

For example

SELECT employee_id dept name age salary FROM employee_info WHERE dept = Sales ORDER BY salary

以上列出公司代號公司名銷售員人名年紀及薪資而條件是公司名為 Sales 顯示順序以薪資多少排序(由小到大為預設值)

如果要以多個欄位做排序要以逗號做分隔如下

SELECT employee_id dept name age salary FROM employee_info WHERE dept = Sales ORDER BY salary age DESC

85

結合條件及布林運算 SELECT column1 SUM(column2) FROM list-of-tables WHERE condition1 AND condition2 AND運算可以結兩個或以上的條件放在 WHERE子句中 兩者都要為真才

會顯示該筆記錄 OR 運算可以結兩個或以上敘述放在 WHERE子句中只要其中一個為直就

會顯示該筆記錄 For example SELECT employeeid firstname lastname title salary FROM employee_info WHERE salary gt= 5000000 AND title = Programmer 必需要薪資大於等於 50000而且職稱為 Programmer同時符合才會顯示該筆資料 以下以括號括住雖然不是必需的但如此比較容易讀 SELECT employeeid firstname lastname title salary FROM employee_info WHERE (salary gt= 5000000) AND (title = Programmer) 另外範例 SELECT firstname lastname title salary FROM employee_info WHERE (title = Sales) OR (title = Programmer) 條件為只要是 Sales 或 Programmer 職稱的就會被列出 IN and BETWEEN 子句

SELECT column1 SUM(column2) FROM list-of-tables WHERE column3 IN (list-of-values) SELECT column1 SUM(column2) FROM list-of-tables WHERE column3 BETWEEN value1 AND value2 IN 子句使用在列舉項目的使用上也就是分別測試是否符合所列的值 For example

86

SELECT employeeid lastname salary FROM employee_info WHERE lastname IN (Hernandez Jones Roberts Ruiz) 條件為姓氏(astname)要符合 Hernandez Jones Roberts or Ruiz 其中一個才會被傳回 IN運算元也可以使用 OR 的語法來取代如下結果相同 SELECT employeeid lastname salary FROM employee_info WHERE lastname = Hernandez OR lastname = Jones OR lastname = Roberts OR lastname = Ruiz 但使用 IN 句子比較短也比較易懂 你也可以使用 NOT IN 來去掉不要的記錄 BETWEEN 運算元使用在判斷是否存在兩個數值之間 For example SELECT employeeid age lastname salary FROM employee_info WHERE age BETWEEN 30 AND 40 傳回年紀 30歲到 40歲之間的資料(含 30及 40歲者) 相同的也可以使用以下語法來達到相同的結果 SELECT employeeid age lastname salary FROM employee_info WHERE age gt= 30 AND age lt= 40 你也可使用 NOT BETWEEN 來濾掉中間值的資料 數學運算 標準 ANSI SQL-92 提供以下運算

87

+ 加

- 減

餘數

餘數為除法後剩整數這不在標準的 ANSI SQL 中但大部份的資料庫都會支

援這運算元以下列出有用的函數雖不在 ANSI SQL-92 提供但一般資料庫

也會支援他們

ABS(x) 傳回 x 絕對值

SIGN(x) returns the sign of input x as -1 0 or 1 (negative zero or positive respectively)

MOD(xy) 餘數 - returns the integer remainder of x divided by y (同 xy)

FLOOR(x) 傳回小或等於 x 的最大整數值

CEILING(x) or CEIL(x)

傳回大或等於 x 的最小整數值

POWER(xy) x的 y 次方

ROUND(x) 把 x 四捨五入為整數

ROUND(xd) 四捨五入取到小數 d 位

SQRT(x) x 開平方

For example SELECT round(salary) firstname FROM employee_info 傳回薪資取到整數位

如何新增資料

insert 加入一筆新紀錄到資料表中 insert into tablename (first_columnlast_column) values (first_valuelast_value) [] = optional Example insert into employee

88

(first last age address city state) values (Luke Duke 45 2130 Boars Nest Hazard Co Georgia) Note 字串要以單引號住如string 數字框住也無妨 insert into 後面接資料表名稱再接以括號括住的欄位名在 values 後括號分別對映各欄位的值 以上的例子新增了一筆名(first) 為 Luke而住所(state) 為 Georgia 的資料

如何刪除資料

delete 可以刪除單筆或多筆紀錄 delete from tablename where columnname OPERATOR value [and|or column OPERATOR value] [ ] = optional Examples delete from employee Note 如果你沒有指定 where 子句那麼全部的紀錄都會被刪除 delete from employee where lastname = May delete from employee where firstname = Mike or firstname = Eric delete from 接著資料表名 再接著是條件式判斷沒有條件式則全部紀錄會

被刪除

如何更新資料

update 用來更新你所指定的記錄要和 WHERE 配合小心使用 語法 update tablename set columnname = newvalue[nextcolumn = newvalue2] where columnname OPERATOR value [and|or column OPERATOR value] [] = optional Examples

89

update phone_book set area_code = 623 where prefix = 979 update phone_book set last_name = Smith prefix=555 suffix=9292 where last_name = Jones update employee set age = age+1 where first_name=Mary and last_name=Williams

90

附錄二Replication

測試環境

RedHat 90 + MySQL 32358 MySQL資料庫路徑 varlibmysql MySQL設定檔 etcmycnf Master IP 1921680100 Slave IP 1921680200 請至下列網址下載最新MySQL 32358套件並利用rpm ndashUvh 更新 httpupdatesredhatcom9enosi386

圖 最新 MySQL 套件

測試架構圖

91

1921680100

1921680200Master Server

erveSlave S r

圖 測試架構圖

測試步驟

Master server 部份 Step1 確認 MasterSlave機器上所裝的 MySQL版本能進行

replication( 32329 or higher ) Step2 在 Master MySQL上開放一個帳號給 Slave mysql ndashu root ndashp mysqlgtGRANT FILE ON TO repl1921680200 IDENTIFIED BY lsquoabc123rsquo mysqlgtq 上面是 Master開放一個帳號 repl密碼 abc123給 IP1921680200有檔案處理

的權限 Step3 shutdown MySQL on the Master mysqladmin ndashu root ndashp shutdown Step4 備份 Master所有資料庫 tar ndashcvf tmpmysql-snapshottar varlibmysql 注意tar的時候MySQL是要在 stop情況下 在mysql (wwwmysqlcom) 網站的FAQ有不用shutdown的方法

92

Step5 在 master機器上修改etcmycnf 在[mysqld]區段內加入參數 log-bin server-id=這邊設定 server-id=1 sql-bin-update-same binlog-do-db=CRM只針對 CRM資料庫做紀錄 Step6 Restart MySQL on the master service mysqld start 此時因為有加入 log-bin 參數因此開始有 index產生了在varlibmysql目錄下

有index檔案紀錄資料庫的異動 log Slave server 部份 Step1 在 slave設定etcmycnf 在[mysqld]區段加入 master-host= master-user= master-password= master-port= server-id= 這邊設定 master-host=1921680100 master-user=repl master-password=abc123 master-port=3306 server-id=2 master-connect-retry=60預設重試間隔 60秒 replicate-do-db=CRM告訴 slave只做 CRM資料庫的更新 log-slave-updates Step2 將 master上的 mysql-snapshottar copy到 slave上 用 ftp傳到 slave的tmp Step3 解壓縮 Master資料庫至 Slave Server上 cd varlib tar xvf tmpmysql-snapshottar chown ndashR mysqlmysql mysql

93

chmod ndashR 770 mysql (視情況) Step4 Restart MySQL on the slave server 這時在varlibmysql目錄會出現 masterinfo此檔案紀錄了 Master MySQL server的資訊

狀況測試

One-way replication

1921680100

1921680200Master Server

erveSlave S r

圖 One-way replication架構圖 Step1 Master跟 Slave網路及服務都正常情況下由 Master端異動資料後 到 Slave端瀏覽資料檢視是否有進行 replication Step2 模擬 Slave Server 當機 可用在於 slave真的當機或是 Slave 不一定需要一直跟 master connect將Slave MySQL server shutdown由 Master端異動資料到 slave端瀏覽此時Slave應該沒有被 replication 更新然後再將 Slave端 MySQL server start起來

預設 60秒後 Slave會嘗試跟 Master要求進行 replication再去 Slave端檢視是否有更新資料

94

Step3 模擬 Master當機因為是設定 One-way replication一旦 Master Server Slave端沒有 Master的 source可以 download Two-way replication 基於 Master當機狀況於是發展雙向 Replication即 1921680100 ( Host A ) 1921680200 ( Host B )都分別擔任 MasterSlave身分

1921680100

1921680200er

Server B MasterSlave Server

Server A MasterSlave Serv

圖 Two-way replication架構圖 以下是針對兩台 MySQL伺服器進行雙向 Replication Step1觀念同單向 replication只是改成 Master也有 Slave身分 Slave也有Master的身分先分別在 Server AServer B 都去 grant一個進行 replication的身分 [A]mysqlgtGRANT FILE ON TO repl1921680200 IDENTIFIED BY lsquoabc123rsquo [B]mysqlgt GRANT FILE ON TO repl1921680100 IDENTIFIED BY lsquoabc123rsquo Step2做完單向 replication後stop Server Aserver B MySQL service此時 AB資料是一樣的

95

修改etcmycnf設定 範例 Server A [mysqld] datadir=varlibmysql socket=varlibmysqlmysqlsock server-id=1 log-bin sql-bin-update-same binlog-do-db=CRM master-host=1921680200 master-user=repl master-password=abc123 log-slave-updates master-connect-retry=60 replicate-do-db=CRM Server B [mysqld] datadir=varlibmysql socket=varlibmysqlmysqlsock server-id=2 log-bin sql-bin-update-same binlog-do-db=CRM master-host=1921680100 master-user=repl master-password=abc123 log-slave-updates master-connect-retry=60 replicate-do-db=CRM 分別 start Server AServer B MySQL後此時雙方都是 MasterSlave身分一旦哪一方資料異動就會通知對方來 replication-若 replication失效則必須將Server AServer B的masterinfo及index00x 都砍掉然後分別 restart MySQL server進行測試檢視成果 實務上通常如果需要做Two-way replication通常會搭配Virtual Server使用

96

在前端架設一台Virtual Server不過此部份不在此份SOP討論範圍內有興趣

的讀者可參考 httpwwwlinuxvirtualserverorg 網站

1921680100 1921680200

Host A MasterSlave Server

Host B MasterSlave Server

Virtual Host

圖 Virtual Server + Two-way replication 架構圖

97

圖 High Availability Linux Virtual Server架構圖

98

  • COSA-SOP-03-006
  • 第一章 簡介
    • 11適用對象 (Audience)
    • 12 MySQL本身
    • 13 MySQL 40版跟50版重大的改進功能
    • 14 各家資料庫軟體比較
      • 第二章 前置需求
      • 第三章 安裝
        • 31 MySQL安裝
        • 32 phpMyAdmin安裝
        • 33 升級及注意事項
          • 第四章 MySQL管理
            • 41 Webmin 管理介面
            • 42 phpMyAdmin 的操作介面
            • 43管理指令介紹
              • 431 利用mysqladmin設定root的密碼
                  • 第五章 實用範例
                    • 51 任務一Web Base客戶通訊錄
                    • 52 任務二Web Base群組軟體 ( twig )
                      • 第六章 維護及更新程序
                        • 61 日常維護
                        • 62 更新程序
                        • 63 備份重要檔案
                        • 64 離線備份與還原
                        • 65 線上備份與還原
                          • 第七章 問題與解答
                          • 第八章 參考資料
                          • 附錄一 SQL Command 介紹
                          • 附錄二Replication
Page 38: DataBase Server Standard Operation Procedureebooks.lib.ntu.edu.tw/1_file/oss/63/93doc4-5.pdf · 業務的公司帶來了不少壓力,譬如微軟,甲骨文 ... 外的錢用在第三方的資料庫產品上,譬如就可以不用再購買甲骨文公司

圖 4-17

38

42 phpMyAdmin 的操作介面

421建立資料庫

Step 填入資料庫名稱並按「建立」

圖 4-18建立資料庫

422 建立資料表

Step1 填入資料表名稱並指定欄位數量 執行

39

圖 4-19填入資料表名稱並指定欄位數量

Step2 設定欄位屬性

圖 4-20設定欄位屬性

40

Step3 phpMyAdmin會產生相關的 SQL Command

圖 4-21 資料表結構及相關 SQL Command

Step4新增 Record

41

圖 4-22

圖 4-23

42

圖 4-24

圖 4-25

43

423使用者管理

Step1建立使用者

圖 4-26

44

圖 4-27

Step2 給予權限

圖 4-28

Step3權限列表

45

圖 4-29

43管理指令介紹

431 利用 mysqladmin設定 root的密碼

當您在Windows 或 Linux 中安裝好 MySQL後系統會自動幫您建立兩個

帳分別是 root 和 匿名者MySQL的 root 跟 Linux 最高權限使用者 root無關MySQL的 root使用者相當於 MS SQL 中的 sa 帳號擁有最高的 Database管理權限但系統預設 MySQL的 root 是不需要密碼所以通常我們一安裝

MySQL後首要任務便是修改 root的密碼 我們可以利用 mysqladmin工具或是直接修改 MySQL內部資料庫的使用者資

料 mysqladmin ndashu root ndashh cosaexamplecom password lsquo1234rsquo

46

-u 表示使用者帳號root 為 MySQL預設的管理帳號

-h 表示 MySQL主機的主機名稱也可使用 IP Address password 表示使用者的密碼因為字串請使用單引號將密碼括起來 密碼設定完成之後還是可以利用 mysqladmin修改密碼但是你必須提供目前的密碼

432 連線 MySQL

mysql -uroot -p密碼 (-p和密碼之間不能有空白) 或 mysql -uroot -p (此方式會在進入後要求密碼) [rootossc phpMyAdmin] mysql -u root -p1234

Welcome to the MySQL monitor Commands end with or g

Your MySQL connection id is 25 to server version 32354

Type help or h for help Type c to clear the buffer

mysqlgt show databases

+----------+

| Database |

+----------+

| mysql |

| test |

+----------+

2 rows in set (000 sec)

mysqlgt exit

Bye

[rootossc phpMyAdmin]

433 建立資料庫

可利用 mysqladmin指令建立 CONTACT資料庫 mysqladmin -u root -p1234 create CONTACT

47

或是利用 mysql指令 [rootossc bluepage] mysql -u root -p1234 Welcome to the MySQL monitor Commands end with or g Your MySQL connection id is 1057 to server version 32354 Type help or h for help Type c to clear the buffer mysqlgt create database CONTACT Query OK 1 row affected (000 sec) mysqlgt show databases +----------+ | Database | +----------+ | CONTACT | | address | | hello | | mysql | | nuke | | test | +----------+ 6 rows in set (000 sec) mysqlgt exit

434 建立資料表

編寫 adresssql內容如下 -- Table structure for table address CREATE TABLE address ( id int(11) NOT NULL auto_increment name varchar(20) NOT NULL default tel varchar(15) NOT NULL default PRIMARY KEY (id) ) TYPE=MyISAM

48

-- Dumping data for table address INSERT INTO address VALUES (1林小明0800016888) INSERT INTO address VALUES (2黃大雄0800016888) INSERT INTO address VALUES (3劉小芬0800024365) 然後執行此 sql script mysql -u root -p1234 CONTACT lt addresssql 或是利 mysql command [rootossc bluepage] mysql -u root -p1234 Welcome to the MySQL monitor Commands end with or g Your MySQL connection id is 1090 to server version 32354 Type help or h for help Type c to clear the buffer mysqlgt use CONTACT Database changed Database changed mysqlgt CREATE TABLE address ( -gt id int(11) NOT NULL auto_increment -gt name varchar(20) NOT NULL default -gt tel varchar(15) NOT NULL default -gt PRIMARY KEY (id) -gt ) TYPE=MyISAM Query OK 0 rows affected (000 sec) mysqlgt INSERT INTO address VALUES (1林小明0800016888) Query OK 1 row affected (000 sec) mysqlgt INSERT INTO address VALUES (2黃大雄0800016888) Query OK 1 row affected (000 sec) mysqlgt INSERT INTO address VALUES (3劉小芬0800024365) Query OK 1 row affected (000 sec) mysqlgt exit Bye

49

第五章 實用範例

51 任務一Web Base客戶通訊錄

任職於開放科技公司的林小明前些日子在最符合成本效益的條件下快

速地完成公司網站的建置老闆因此對小明讚譽有加最近因為公司存放客戶資

料的 SQL Server主機屢遭病毒攻擊加上作業系統本身的問題當機次數頻繁

老闆希望能儘快把公司的客戶通訊錄程式移轉到較穩定的環境上因為此客戶通

訊錄程式最主要給內部人員使用所以介面美觀並不特別要求只求穩定且能快

速得到查詢結果老闆希望在短時間先看到程式的雛型並鍵入資料對其效率

及穩定性進行測試因為上次小明表現突出所以這次不可能的任務自然又落到

小明身上 小明想來想去既然要快速又穩定他而且又不希望所有人都得安裝 Client

程式於是小明決定)捨棄他的舊愛「Delphi+MS SQL」投向新歡「Apache + MySQL + PHP」利用此架構來設計一個簡單實用的Web Base客戶通訊錄程式

511 Web Base客戶通訊錄架構

此程式需要建立 CONTACT的資料庫並建立 adress Tables其結構如下表建立步驟請參考第三章 欄位名稱 資料型態 長度 說明 id INT (自動編號) 連絡人編號 name varchar文字 20 連絡人姓名 tel Varchar文字 15 連絡人電話 Web Base通訊錄共有下列幾個檔案功能如下表

檔案名稱 說明 Indexhtml Web Base通訊錄首頁 addphp 新增連絡人的 php程式 searchphp 尋找連絡人的 php程式 editphp 具有更新及刪除功能的 php程式

50

我們將這些檔案放至varwwwhtmlbluepage (預設無 bluepage目錄)

512 Web Base通訊錄測試

httpwwwopencombluepage 新增資料

圖 5-1 新增連絡人

圖 5-2 填入資料

51

圖 5-3 新增成功

搜尋及異動資料

圖 5-4 搜尋通訊錄

52

圖 5-5 編輯資料

圖 5-6 更新資料

513 程式內容及說明

lt-- 程式範例indexhtml--gt lthtmlgt ltheadgtlttitlegt通訊錄lttitlegtltheadgt ltbodygt ltcentergt

53

lth2gt通訊錄lth2gtlthrgt lta href=indexhtmlgt通訊錄ltagt | lta href=addphpgt新增連絡人ltagt | lta href=searchphpgt搜尋通訊錄ltagt ltcentergt ltbodygt lthtmlgt lt-- 程式範例addphp --gt lthtmlgt ltheadgtlttitlegt新增連絡人lttitlegtltheadgt ltbodygt ltcentergtlth2gt新增連絡人lth2gtltcentergtlthrgt lt 取得欄位資料 if (isset($_POST[Name]) ampamp isset($_POST[Tel]) ) $name = $_POST[Name] $tel = $_POST[Tel] 檢查是否有輸入欄位資料 if ($name = ampamp $tel = ) 建立 SQL字串 $sql = INSERT INTO address (name tel) values( $sql= $name $tel) 建立 MySQL 連結 $link = mysql_connect(localhostroot1234) 選擇資料庫 mysql_select_db(CONTACT) 執行 SQL指令 mysql_query($sql) mysql_close($link) echo ltfont color=redgt新增連絡人成功ltfontgtltbrgt gt ltform action=addphp method=postgt lttable border=0 width=300gt lttrgtlttdgt姓名 lttdgt

54

lttdgtltinput type=text name=Name size=20 maxlength=10gtlttdgtlttrgt lttrgtlttdgt電話 lttdgt lttdgtltinput type=text name=Tel size=20 maxlength=20gtlttdgtlttrgt lttrgtlttd colspan=2 align=centergt ltinput type=submit value=新增連絡人gtlttdgtlttrgt lttablegt ltformgt ltbrgtlta href=indexhtmlgt通訊錄ltagt | lta href=addphpgt新增連絡人ltagt | lta href=searchphpgt搜尋通訊錄ltagt ltbodygt lthtmlgt

lt-- 程式範例searchphp --gt lthtmlgt ltheadgtlttitlegt搜尋通訊錄lttitlegtltheadgt ltbodygt ltcentergtlth2gt搜尋通訊錄lth2gtlthrgt lt if (isset($_POST[Search])) 建立資料庫連結並選定資料庫 $link = mysql_connect(localhostroot1234) mysql_select_db(CONTACT) 建立基本的 SQL字串 $sql = SELECT FROM address 檢查是否輸入姓名 if (chop($_POST[Name]) = ) $name = name LIKE $_POST[Name] else $name = 檢查是否輸入電話號碼 if (chop($_POST[Tel]) = ) $tel = tel LIKE $_POST[Tel] else $tel =

55

if條件組合 SQL字串 if (chop($name) = ampamp chop($tel) = ) $sql= WHERE $name AND $tel elseif (chop($name) = ) 只有姓名 $sql = WHERE $name elseif (chop($tel) = ) 只有電話號碼 $sql = WHERE $tel $sql= ORDER BY name 最後加上排序 $result = mysql_query($sql) 取得欄位數 $total_fields = mysql_num_fields($result) echo lttable border=1gt echo lttrgtlttdgt編號lttdgtlttdgt姓名lttdgtlttdgt電話lttdgtlttd colspan=2gt功能選項lttdgtlttrgt 表格顯示查詢結果 while ($rows = mysql_fetch_array($result MYSQL_NUM)) echo lttrgt for ($i = 0 $i lt $total_fields $i++) echo lttdgt$rows[$i]lttdgt echo lttdgtlta href=editphpaction=editampid= echo $rows[0]gtltbgt編輯ltbgtlttdgt echo lttdgtlta href=editphpaction=delampid= echo $rows[0]gtltbgt刪除ltbgtlttdgt echo lttrgt echo lttablegtlthrgt mysql_free_result($result) mysql_close($link) gt ltcentergt ltform action=searchphp method=postgt lttable border=0 width=450gt lttrgtlttdgt搜尋姓名 lttdgt lttdgtltinput type=text name=Name size=10 maxlength=20gtlttdgtlttrgt lttrgtlttdgt搜尋電話 lttdgt lttdgtltinput type=text name=Tel

56

size=20 maxlength=20gtlttdgtlttrgt lttrgtlttd colspan=2 align=centergt ltinput type=submit name=Search value=搜尋gtlttdgtlttrgt lttablegt ltformgt ltbrgtlta href=indexhtmlgt通訊錄ltagt | lta href=addphpgt新增連絡人ltagt | lta href=searchphpgt搜尋通訊錄ltagt ltbodygt lthtmlgt

lt ob_start() gt lt-- 程式範例editphp --gt lthtmlgt ltheadgtlttitlegt編輯通訊錄lttitlegtltheadgt ltbodygt lt 取得 URL 參數 $id = $_GET[id] $action = $_GET[action] 建立資料庫連結 $link = mysql_connect(localhostroot1234) mysql_select_db(CONTACT) 選擇資料庫 執行的操作 switch ($action) case update 更新 取得欄位資料 $name = $_POST[Name] $tel = $_POST[Tel] $sql = UPDATE address SET name=$name tel=$tel WHERE id=$id mysql_query($sql) 執行 SQL指令 mysql_close($link) header(Location searchphp) 轉向到 serachphp break case del 刪除 $sql = DELETE FROM address WHERE id=$id

57

mysql_query($sql) 執行 SQL指令 mysql_close($link) header(Location searchphp) 轉向到 serachphp break case edit 編輯 $sql = SELECT FROM address WHERE id=$id $result = mysql_query($sql) 執行 SQL指令 $row = mysql_fetch_row($result) 取回記錄 $name = $row[1] 取得欄位 name $tel = $row[2] 取得欄位 tel mysql_close($link) 顯示編輯表單 gt ltcentergtlth2gt更新通訊錄lth2gtltcentergtlthrgt ltform action=editphpaction=updateampid=lt echo $id gt method=postgt lttable border=0 width=300gt lttrgtlttdgt姓名 lttdgt lttdgtltinput type=text name=Name size=20 maxlength=10 value=lt echo $name gtgtlttdgtlttrgt lttrgtlttdgt電話 lttdgt lttdgtltinput type=text name=Tel size=20 maxlength=20 value=lt echo $tel gtgtlttdgtlttrgt lttrgtlttd colspan=2 align=centergt ltinput type=submit value=更新連絡人gtlttdgtlttrgt lttablegt ltformgt ltbrgtlta href=indexhtmlgt通訊錄ltagt | lta href=addphpgt新增連絡人ltagt | lta href=searchphpgt搜尋通訊錄ltagt lt break gt ltbodygt lthtmlgt

58

52 任務二Web Base群組軟體 ( twig )

順利完成Web Base客戶通訊錄程式測試一段時間後「Apache + MySQL + PHP」架構的穩定與快速巳深得老闆與公司所有同事的認同隨著公司業績蒸

蒸日上人員組織編罝愈來愈龐大跨部門的會議愈來愈多業務員每日排滿拜

訪客戶的行程跟客戶的 Email的往來也愈來愈頻繁 愈來愈多部門的同事希望公司能建置一套群組軟體提供 web mail可讓業

務人員方便收發 mail還有連絡人議事日程待辦工作書簽等功能讓整個

公司運作及個人時間管理更有效率

老闆問小明對這些需求有什麼看法小明認為如果這些功能完全由程式部

門開發必定曠日費時而且耗費公司資源小明在網路尋找是否有提供這些功能

的Free Software皇天不負苦心人小明發現了TWIG (The Web Information Gateway) httptwigscrewdrivernet這個群組軟體它在 Web 上整合郵件新聞聯絡人議事日程工作序書簽等功能非常符合公司的需求 Step 1 下載 twig-277targz 下載網址 httptwigscrewdrivernetdownloadphp3

Step 2 解開 twig-277targz tar -xzvf twig-277targz

59

Step 3 執行安裝動作安裝到 varwwwhtmltwig 目錄 cd twig-277 twig-install varwwwhtmltwig

Step 4 建立 MySQL 資料庫(twig)及各資料表

cd setup mysql -u root -p1234 mysqlgt create database twig Query OK 1 row affected (001 sec) mysqlgt quit mysql -u root ndashp1234 twiglt twigtablemysql

Step 5 修改 configincphp3 參數設定 vi varwwwhtmltwigconfigconfigincphp3 $config[fromdomain] = opencom 網域 $config[language] = chinesebig5 中文訊息 $config[imap_port] = 143notls

60

Step 6 修改連結 MySQL 的帳號密碼 vi varwwwhtmltwigconfigdbconfigincphp3 $dbconfig[sqlusername] = root username $dbconfig[sqlpassword] = 1234 password

Step 7 其他設定檔

vi etchttpdconfhttpdconf 加入 AddType applicationx-httpd-php php3 在 DirectoryIndex最後加入 indexphp3 DirectoryIndex indexhtml indexhtmlvar indexphp3 在 AddDefaultCharset ISO-8859-1加上 AddDefaultCharset ISO-8859-1

vi etcphpini register_globals = On service httpd restart Step 8 sendmail 設定 vi etcmailsendmailcf在 264 行前面加上並重新啟動 sendmail「service snedmail restart」 262 SMTP daemon options 263 264 O DaemonPortOptions=Port=smtpAddr=127001 Name=MTA 265 266 SMTP client options 267 O ClientPortOptions=Family=inet Address=00

61

Step 9 檢查設定有無錯誤 http主機名稱twigtestphp3

62

Step 10 登入 twig ( http主機名稱twig)

63

第六章 維護及更新程序

61 日常維護

系統管理員最好定期以 root 身份登入看看信件在 RedHat Linux 中有一支 logwatch 程式會定時去分析 log file如果發現異常便會發信給 root除此之外筆者建議讀者平時就檢查 MySQL log file ( varlogmysqldlog)是否有異常情形

62 更新程序

讀者可至httprpmfindnet 尋找MySQL相關套件至於升級的相關步驟請參

考Linux OS SOP 第 54節

63 備份重要檔案

預設 MySQL 的 DB 檔案是存在 varlibmysql 內以 DB名稱為目錄目錄

內就是該 DB 的所有資料通常得定期備份還有 MySQL的設定檔 etcmycnf也別忘了一起備份

64 離線備份與還原

641 離線備份

預設 MySQL 的 DB 檔案是存在 varlibmysql 內以 DB 名稱為目錄目錄內

就是該 DB 的所有資料像 CRM 這個 DB就是存在 varlibmysqlCRM 內在備份前因為怕資料尚未完全寫入磁碟而且 MySQL 會 Lock 在使用的 DB 檔案所以應該是要先把 MySQL 先 Shutdown 一下整個備份的程序可以下像下面的指令去完成 cd varlibmysql

64

service mysqld stop tar cvfz CRM_db_20030905tgz CRM service mysqld start 對這樣就可以了 不過要注意的是怕 DB 內每個 Tables 間的資料有關關

聯性所以最好是把整個 DB 一次備起來單獨只備哪個 Tables 的檔案以後回存時怕會有資料關聯不一致的問題

642 離線還原

DB 發生錯誤而要回存時其實也不難先找出最近一次完整正常的備份先把現在錯誤的網頁或 DB 先更名或 tar 起來再把好的備份給解開回原來目錄位

置就行了需要注意的是 MySQL 服務最好也是要先停止回存完成後再啟動服務回存 DB 的整個程序可能像下面 cd varlibmysql service mysqldstop mv CRM CRM_OLD tar xvfz CRM_db_20030905tg service mysqld start

65 線上備份與還原

651 線上備份

使用像上面的檔案方式備份是個不錯的方法它最少可以保持該主機某個時間點的完整檔案備份但還是有一些問題需要考慮到有些主機就不只建立一個 DB 而已總不能為了備份某個 DB 而把整個 MySQL 服務停止備份檔案的方式回存在原主機上一定適用但假如 MySQL 版本升級或是在那天該網頁空間需遷機移機到別的主機時那就沒人敢保證備出來的資料檔可以用所以我們可以考慮另一種備份的方式是使用 MySQL 本身提供的功能 MySQL Data Dump指令是 mysqldump

65

使用 MySQL 的 Dump 功能可以把 DB 的結構資料或結構加資料 Dump 成文字檔 mysqldump 指令提供的彈性很大你可以選擇把整個 DB Dump 成一個檔或是每個 Table 為一個檔甚至是把結構檔和資料分開儲存都

可以 mysqladmin -uroot -p flush-logs mysqldump CRM -uroot -p --opt gt CRM_20030905sql (CRM 是 DB 名稱 opt 是一個使用完整 Dump 參數) 假如只是要單獨 Dump 某個 Table 時只要在上面的指令後轉出符號 gt 前加個 Table 名稱就可以如只要 phpbb2_users 這個 Table 的 Dump 時只要下 mysqldump CRM -uroot -p --opt CUSTOMER gt CRM_CUSTOMER_20030905sql

652 線上還原

若要回存整個資料庫只需將壓縮的備份檔還原成 Dump 的檔案再用下面的指令回存 mysql CRM -uroot -p lt CRM_20030905sql 這邊需注意的是若建立備份時是以--opt或--add-drop-table為參數時回存的 動作是先將舊的 Table 先刪除重建 Table 的結構後再把 Data 匯入所以回存後所有的資料會回到你當時備份那個時間點因此在回存資料時可以考慮把現有錯誤或不完整的 DB 先備份一份下來以備不時之需或是拿來比對錯誤的地

方在那裡當然你也可以把資料回存到另一個測試用的 DB 內只要把上面指令

的 DB 名稱改成你的測試用 DB 名稱即可 使用這種回存方式 MySQL 服務不需停止也不會動到其他正在使用的 DB 在一些提供 MySQL 服務的虛擬主機可用這種方式作你自己的 DB 備份及回存

66

另外假如你是系統重建或是移機時切需在新的 MySQL 內新建一個空白 DB 後才行作回存的工作你可以用下面的指令建立 mysql -uroot -p -e CREATE DATABASE CRM (上面的 CRM是你要新建的 DB 名稱) 另一種作法先用 mysql 指令進入 mysql client console 然後再用 CREATE DATABASE CRM 這樣就行了記得尾端要加個 符號該行指令才會執行

67

第七章 問題與解答

Q1RedHat 90預附的 MySQL到底有無支援 Transcation機制 Ans MySQL自 32334a之後的 MySQL-Max版本加入 InnoDB的資料庫類型透過

InnoDBMySQL同樣可以進行 COMMIT與 ROLLRACK的動作RedHat 90預附的 MySQL為 32354a-11巳支援 InnoDB的資料庫類型不過必須做以

下設定 1cp usrsharedocmysql-server-32354amy-mediumcnf to etcmycnf 2 vi etcmycnf 將以下設定前的拿掉 innodb_data_home_dir = varlibmysql innodb_data_file_path = ibdata110Mautoextend innodb_log_group_home_dir = varlibmysql innodb_log_arch_dir = varlibmysql 3service mysqld restart 如此一來各位在建立Table時便可指定Table Type為 innodb ( ex create table with type=innodb ) Q2如何解決 php+mysql 許功蓋等字變亂的問題 Ans 方法一 【確定 MySQL 預設的字元集】 1 打開 WinMySQLadmin 管理畫面(在視窗右下角狀態列紅綠燈圖示中按滑鼠

右鍵點選 Show me 選項) 2 點選管理畫面中 [Variables] 標籤選項其中 character_set變數就是您預設

字元集的變數其預設是 latin1 字元集(我們要將他改回 big5)而 chatacters_set 變數則是 MySQL 可以支援哪些字元集 【修改預設字元集變數 character_set 】 1 請點選管理畫面中 [myini Setup] 標籤選項設定 myini 2 按一下 [Pick-up and Edit myini values] 按鈕以便編輯目前的 myini 設定 3 在 [mysqld] 設定區塊底下新增一行 default-character-set = big5 變數設

68

定 4 新增一個 [client] 設定區塊並加入第三步驟的變數設定(游標往下移到空白處新增兩行 [client] 和 default-character-set=big5) 5 按一下畫面左下方 [Save Modification] 按鈕儲存設定 6 重新啟動 MySQL 或 Windows 方法二 Server端注意事項 phpini 中有關的設定為(預設值) Magic quotes for incoming GETPOSTCookie data magic_quotes_gpc = On Use Sybase-style magic quotes (escape with instead of ) magic_quotes_sybase = Off Client端注意事項 1中文資料送進 mysql 前請用 addslashes($str) 處理 2處理後送進 mysql 時請用 括起來並在參數後留一個空白如 $sql = UPDATE ezf_table set tablename=$tname tableend=$endtime table inguser=$tguser tableingid=$tguserid tableallnumber=$tnumber tableloca l=$tablelocal tableanyone=$tableopen tabletext=$ttext WHERE tableid=$t ableid tablename=$tname c 取出時請用 stripslashes($str) Q3MySQL root 密碼忘了該怎麼辦 Ans 1先停掉 mysql etcrcdinitdmysql stop 2以--skip-grant-table 的參數啟動 mysql safe_mysql --skip-grant-tableamp 3 更改 root 密碼 mysql mysql mysqlgt UPDATE user SET password=password(newpassword)

69

WHERE user=root mysqlgt FLUSH PRIVILEGES mysqlgt exit 4停掉 mysql再重跑 mysqladmin -uroot -p shutdown Enter password 輸入新設定的密碼 etcrcdinitdmysql start

Q4NULL值問題

Ans

NULL值的概念是造成 SQL的新手的混淆的普遍原因他們經常認為 NULL是和一個空字符串的一樣的東西不是這樣的例如下列語句是完全不同的

mysqlgt INSERT INTO my_table (phone) VALUES (NULL)

mysqlgt INSERT INTO my_table (phone) VALUES ()

兩個語句把值插入到 phone 列但是第一個插入一個 NULL值而第二個插入一個空字符串第一個的含義可以認為是ldquo電話號碼不知道而第二個則可意味

著ldquo她沒有電話

在 SQL中NULL值在于任何其他值甚至 NULL值比較時總是假的(FALSE)包含 NULL的一個表達式總是產生一個 NULL值除非在包含在表達式中的運算符和函數的文檔中指出在下列例子所有的列返回 NULL

mysqlgt SELECT NULL1+NULLCONCAT(InvisibleNULL)

如果你想要尋找值是 NULL的列你不能使用=NULL測試下列語句不返回任

何行因為對任何表達式expr = NULL是假的

mysqlgt SELECT FROM my_table WHERE phone = NULL

要想尋找 NULL值你必須使用 IS NULL測試下例顯示如何找出 NULL電話號碼和空的電話號碼

70

mysqlgt SELECT FROM my_table WHERE phone IS NULL mysqlgt SELECT FROM my_table WHERE phone =

在 MySQL中就像很多其他的 SQL服務器一樣你不能索引可以有 NULL值的列你必須聲明這樣的列為 NOT NULL而且你不能插入 NULL到索引的

列中

當用 LOAD DATA INFILE 讀取數據時空列用更新如果你想要在一個列中有

NULL值你應該在文本文件中使用N字面上的詞NULL也可以在某些情形下使用

當使用 ORDER BY時首先呈現 NULL值如果你用 DESC以降序排序NULL值最後顯示當使用 GROUP BY時所有的 NULL值被認為是相等的

為了有助于NULL的處理你能使用 IS NULL和 IS NOT NULL運算符和 IFNULL()函數

對某些列類型NULL值被特殊地處理如果你將 NULL插入表的第一個TIMESTAMP 列則插入當前的日期和時間如果你將 NULL插入一個AUTO_INCREMENT 列則插入順序中的下一個數字

Q5如何將圖片存放於 MySQL中

Ans

Step 1建立資料庫 test

Step 2 建立表格 binary_data

CREATE TABLE binary_data (

id INT(4) NOT NULL AUTO_INCREMENT PRIMARY KEY

description CHAR(50)

bin_data LONGBLOB

filename CHAR(50)

filesize CHAR(50)

filetype CHAR(50)

71

)

Step 3 利用 storephp 寫入圖片

storephp 程式碼

ltHTMLgt ltHEADgtltTITLEgtStore binary data into SQL DatabaseltTITLEgtltHEADgt ltBODYgt lt code that will be executed if the form has been submitted

if ($submit) mysql_connect(localhostrootYOUR_PASSWORD) mysql_select_db(test) $data=Base64_Encode(fread(fopen($form_data r) filesize($form_data))) $result=MYSQL_QUERY(INSERT INTO binary_data (descriptionbin_datafilenamefilesizefiletype) VALUES ($form_description$data$form_data_name$form_data_size$form_data_type)) $id= mysql_insert_id() print ltpgtThis file has the following Database ID ltbgt$idltbgt MYSQL_CLOSE() else else show the form to submit new data

gt

ltform method=post action=ltphp echo $PHP_SELF gt enctype=multipartform-datagt File Descriptionltbrgt ltinput type=text name=form_description size=40gt ltINPUT TYPE=hidden name=MAX_FILE_SIZE value=4000000gt ltbrgtFile to uploadstore in databaseltbrgt ltinput type=file name=form_data size=40gt ltpgtltinput type=submit name=submit value=submitgt ltformgt lt

72

gt ltBODYgt ltHTMLgt

Step 3 利用 storephp 取出圖片

getdataphp 程式碼

lt Syntax getdataphp3id=ltidgt if($id) you may have to modify login information for your database server MYSQL_CONNECT(localhostrootYOUR_PASSWORD) mysql_select_db(test) $query = select bin_datafiletype from binary_data where id=$id $result = MYSQL_QUERY($query) $data = Base64_Decode(MYSQL_RESULT($result0bin_data)) $type = MYSQL_RESULT($result0filetype) Header( Content-type $type) echo $data gt

Q6MySQL裝好之後啟動時或是執行 mysqladmin會出現如下訊息 Cant connect to local MYSQL Server through Socket varlibmysqlmysqlsock或是

Cant connect to local MYSQL Server through Socket tmpmysqldsock

Ans 可能有下列幾個原因

1這個 mysqldsock 不見了被某人刪除了或是被一些系統自動執行程式給刪

了例如有些 cron任務便會設定定期刪除 tmp 裡的東西所以呢您只能修改

cron 裡的設定讓它不要清除 mysqldsock 2在啟動時也可以改變 mysqldsock的位置您在啟動 MySQL的時候可以加入此參數usrlocalmysqlbinsafe_mysqld --user=mysql --socket=其他路

徑socket amp 同時得去設定環境變數 MYSQL_UNIX_PORT的值以指定新的

73

路徑 3若是您沒改 MYSQL_UNIX_PORT的值那麼您可以在執行指令的時候才打

例如mysqladmin --socket=其他路徑socket version Q7How to get the last insert id Ans CREATE TABLE product ( id INT(4) NOT NULL AUTO_INCREMENT PRIMARY KEY description VARCHAR(50) ) 1利用 SQL的話 mysqlgt insert into product(description) values(123) Query OK 1 row affected (000 sec) mysqlgt select last_insert_id() +------------------+ | last_insert_id() | +------------------+ +------------------+ 1 row in set (000 sec) ======================================== 2如果是 PHP的話 你可以用mysql_insert_id()取得該 id PHP example $result=MYSQL_QUERY(INSERT INTO product (description) VALUES ($description)) $id= mysql_insert_id() print This file has the following Database ID $id Q8如何將文字檔匯入資料庫 Ans $addr=homehttpdhtmlphpschool001txt $sql_select = load data infile $addr into table test fields terminated by t 解說 $sql_select = load data infile 文字檔名 into table 表格名 fields terminated by

74

t

(欄位分隔以 TAB鍵) 該文字檔須與資料表欄位格式相符 例如欄位有三個 則文字檔為每行一筆資料如下 欄 1資料ltTABgt欄 2資料ltTABgt欄 3資料 欄 1資料ltTABgt欄 2資料ltTABgt欄 3資料 欄 1資料ltTABgt欄 2資料ltTABgt欄 3資料 欄 1資料ltTABgtltTABgt欄 3資料

Q9如何撰寫 MySQL C API Ans Step 1利用文字編輯器撰寫以下程式碼 mysqlcc

include ltstdiohgt

include ltmysqlmysqlhgt

int main (int argc char argv[])

MYSQL mysql

MYSQL_RES res

MYSQL_ROW row

if (argc = 2)

fputs (Usage myc ltdatabasegt stderr)

return 1

if ((mysql_connect(ampmysqllocalhostrootYour_Password)))

fputs (Error connecting stderr)

abort()

75

if (mysql_select_db(ampmysqlargv[1]))

fputs (Error selecting database stderr)

abort()

if (mysql_query(ampmysqlSELECT FROM test_table))

fputs (Error processing query stderr)

abort()

if ((res = mysql_store_result(ampmysql)))

fputs (Error storing results stderr)

abort()

while((row = mysql_fetch_row(res)))

uint i = 0

for (i=0 i lt mysql_num_fields(res) i++)

printf(s row[i])

printf(n)

return 0

Step 2 Compile

gcc -Iusrlocalmysqlinclude -Lusrlocalmysqllibmysql mysqlcc ndashlm -lmysqlclient

(其中 include path與 library path取決於你的 MySQL安裝路徑)

76

如果執行時發生如下 error Run problemerror in loading shared libraries libmysqlclientsoX 將你的 MySQL library path(for exampleusrlocalmysqllibmysql) 加入etcldsoconf and run sbinldconfig -v Q9ASP + MySQL 範例程式 Ans Dim myconn As New ADODBConnection Dim myrs As New Recordset Dim mySQL As String Dim myrows As Long myconnOpen DSN=MyODBCsample mySQL = SELECT from user myrsSource = mySQL Set myrsActiveConnection = myconn myrsCursorLocation = adUseClient myrsOpen myrows = myrsRecordCount myrsClose myconnClose 可參考 httpwwwdwamnetmysqlasp_myodbcasp 有詳細的資料 Q10如何將 MySQL中的資料庫匯出成txt檔 Ans select from TableName into outfile textxls all result fields will seperate by tab

77

第八章 參考資料

英文部份 網址 1 httpwwwmysqlcom MySQL 網站有第一手有關 MySQL的資料 2 httpwwwmysqlcomdocenReplicationhtml 有關 MySQL Replication 的文件 3 httpwwwgeocitiescomsqlhomefaqstore_blobhtml 如何在 MySQL 存放 BLOB的資料 4httpwwwsapdborg 有關 SAP跟 MySQL相關合作的網站 書藉 1 Cooking with MySQL

Paul DuBois has selected sample recipes from the hundreds youll find in his book MySQL

Cookbook In this third and final series of excerpts showcasing these recipes learn how to

compute team standings how to calculate the differences between successive Dec 26

2002 2 Tips for Building Web Database Applications with PHP and MySQL by Hugh E Williams co-author of Web Database Applications with PHP amp MySQL 04042002

3 Managing and Using MySQL 2nd Edition By Tim King George Reese Randy Jay Yarger

4 MySQL Cookbook By Paul DuBoisPublisher OReillyPub Date October 2002

中文部份

78

1 httplinuxtncedutwtechdocmysqlmysql_docmanual_tochtml MySQL 中文手冊 2 httpchenshloxaedutwphpZ_1php PHP+MySQ程式研習設計網站 3 httplinuxtncedutwtechdocbanicdownhtml PHP 4 手冊 4 httpwwwtncedutwadmin_zonephp台南縣教育網網路中心有很多 Linux相關文件 5 httpdobtncedutw網站建置百寶箱有很多 PHP MySQL 相關範例程式 5 httpwwwdbworldcomtw資料庫專家電子雜誌介紹資料庫的重要觀念及名詞

79

附錄一 SQL Command 介紹

SQL (讀音ess-que-el) 是一種結構查詢語法SQL 使用於資料庫交流

傳遞相容於 ANSI (American National Standards Institute) 是一套標準的關聯

式資料庫語言 SQL 語言是執行更新或從資料系統獲取資料一般常見的關聯

資料庫系統都有提供 SQL 如 Oracle Sybase Microsoft SQL Server Access Ingres 等雖然大部份的資料庫都有提供 SQL 但也多提供了自已獨特的語

法造成了不相容的情形但標準基本的語法是相通的如Select Insert Update Delete Create and Drop 每一個系統都有支援

Table相關 Command

Create Table

關聯式資料庫包含有很多元件稱為資料表(tables) 把資料或訊息放在資

料表中 資料表是以不同的名稱做分別資料表由欄列所構成的二維陣列

欄包含欄位名資料型態 及其他可判斷的資訊列是由全部欄位構成一筆一

筆的紀錄 create table 語法用在建立一個新的資料表語法格式如下

create table tablename (column1 data type column2 data type column3 data type)

Format of create table if you were to use optional constraints

create table tablename (column1 data type [constraint] column2 data type [constraint] column3 data type [constraint]) [ ] = optional

Note You may have as many columns as youd like and the constraints are optional

80

Example

create table employee (first varchar(15) last varchar(20) age number(3) address varchar(30) city varchar(20) state varchar(20))

注意建立資料表格式要以括號把前後框住而最後以(分號)做結尾

欄位名不要超過 30個字元長而且不要使用 sql 的關鍵字(如 where select等)而在後面接是型態的宣告(如字串數字日期格式等)

資料型態是來描述欄位的方式如一個欄位Last_Name 是一個姓氏可以使用varchar (可變動長度字串) 資料型態

以下是幾個常見的資料庫型態 char(size) 固定長度字串最長為 255 位元 varchar(size) 變動長度字串最大字元數以 size 來指定 number(size) 數值格式可以是整數也可以是小數最大數字以 size 位數判

斷未指定小數位數由系統內定 date 日期格式 number(sized) 數值格式最大數字以 size 位數判斷d 為小數位數整數位

數為 size-d 位

有何限制當資料表被建立通常有一或數個欄位是要使用來做關聯的功

能 例如unique 限制(唯一值)兩筆記錄不可以相同的值 not null (非空值)該欄位一定要輸入資料不可是空的primary key (主鍵)是每一筆記錄識別的主要方式

Drop a table drop table 刪除資料表(其中的資料也會一併刪除)

drop table tablename

Example

81

drop table 和刪除全部資料是不同的刪除全部資料欄位名稱資訊等還會

存在但刪除資料表會把這一些也一併移除掉

如何查詢資料

Select 基本用法

select 語法是關連式資料庫最常用的部份可以取得你想要的資料這是一個

簡單的範例 select column1[column2etc] from tablename [where condition] [] = optional 在 select 之後所列欄位名則是要顯示的資料部份你可以一一列出各欄位

名或是以 (星號)來代表選擇全部的欄位 from 之後放資料表名稱 where 子句 (選項) 指定要過濾的條件符合者才會顯現 where 可使用的條件運算元 = 等於 gt 大於 lt 小於 gt= 大或等於 lt= 小或等於 ltgt 大相等 LIKE 相似 For example select first last city

82

from empinfo where first LIKE Er 以Er 為開頭的字串就符合要以單引號框住 Or you can specify select first last from empinfo where last LIKE s 最後一字為 S 就符合 select from empinfo where first = Eric 則表示 first name 一定要是 Eric 才可以 範例資料表empinfo 統計函數

MIN 傳回指定欄位最小值

MAX 傳回指定欄位最大值

SUM 傳回指定欄位總和

AVG 傳回指定欄位平均值

COUNT 傳回指定欄位的筆數

COUNT() 傳回資料庫中的總筆數

統計函數使用於資料表中的數值欄位配合 SELECT 語法使用 只用於總結特定單一欄位可以配合 GROUP BY 做篩選但也可以不使用 GROUP BY 語句For example

SELECT AVG(salary) FROM employee

83

傳回全部 salary 平均值

Another example

SELECT AVG(salary) FROM employee WHERE title = Programmer

傳回 salary 平均值條件為 employees 資料表中當 title 等於 Programmer

Example

SELECT Count() FROM employees

傳回 employees 資料表中紀錄總筆數

GROUP BY 語法 SELECT column1 SUM(column2) FROM list-of-tables GROUP BY column-list The GROUP BY 語句可以先以所列的欄位為條件分組排序在一起(可以多欄

位) example 要列出每一個 dept 中最高 salary 值 SELECT max(salary) dept FROM employee GROUP BY dept HAVING 語法

SELECT column1 SUM(column2) FROM list-of-tables GROUP BY column-list HAVING condition

HAVING 子句是 GROUP BY 的一部份用來過濾在 GROUP BY 所選出的資料功能如同 select 命令中 where 條件式一樣只是 HAVING 必需配合 GROUP BY 使用

我們以例子來說明我們要取得每一公司名及每一公司的薪水平均值輸入如下

84

SELECT dept avg(salary) FROM employee GROUP BY dept

但如果我們只列出薪資平均值超過 20000元的公司資料

SELECT dept avg(salary) FROM employee GROUP BY dept HAVING avg(salary) gt 20000

ORDER BY子句語法

SELECT column1 SUM(column2) FROM list-of-tables ORDER BY column-list [ASC | DESC]

[ ] =選項

ORDER BY是一個選項子句當你以排序方式來顯示資料(正向由小到大反向由大到小)以指定的欄位資料做排序

ASC = 正向- 預設值 DESC = 反向排序

For example

SELECT employee_id dept name age salary FROM employee_info WHERE dept = Sales ORDER BY salary

以上列出公司代號公司名銷售員人名年紀及薪資而條件是公司名為 Sales 顯示順序以薪資多少排序(由小到大為預設值)

如果要以多個欄位做排序要以逗號做分隔如下

SELECT employee_id dept name age salary FROM employee_info WHERE dept = Sales ORDER BY salary age DESC

85

結合條件及布林運算 SELECT column1 SUM(column2) FROM list-of-tables WHERE condition1 AND condition2 AND運算可以結兩個或以上的條件放在 WHERE子句中 兩者都要為真才

會顯示該筆記錄 OR 運算可以結兩個或以上敘述放在 WHERE子句中只要其中一個為直就

會顯示該筆記錄 For example SELECT employeeid firstname lastname title salary FROM employee_info WHERE salary gt= 5000000 AND title = Programmer 必需要薪資大於等於 50000而且職稱為 Programmer同時符合才會顯示該筆資料 以下以括號括住雖然不是必需的但如此比較容易讀 SELECT employeeid firstname lastname title salary FROM employee_info WHERE (salary gt= 5000000) AND (title = Programmer) 另外範例 SELECT firstname lastname title salary FROM employee_info WHERE (title = Sales) OR (title = Programmer) 條件為只要是 Sales 或 Programmer 職稱的就會被列出 IN and BETWEEN 子句

SELECT column1 SUM(column2) FROM list-of-tables WHERE column3 IN (list-of-values) SELECT column1 SUM(column2) FROM list-of-tables WHERE column3 BETWEEN value1 AND value2 IN 子句使用在列舉項目的使用上也就是分別測試是否符合所列的值 For example

86

SELECT employeeid lastname salary FROM employee_info WHERE lastname IN (Hernandez Jones Roberts Ruiz) 條件為姓氏(astname)要符合 Hernandez Jones Roberts or Ruiz 其中一個才會被傳回 IN運算元也可以使用 OR 的語法來取代如下結果相同 SELECT employeeid lastname salary FROM employee_info WHERE lastname = Hernandez OR lastname = Jones OR lastname = Roberts OR lastname = Ruiz 但使用 IN 句子比較短也比較易懂 你也可以使用 NOT IN 來去掉不要的記錄 BETWEEN 運算元使用在判斷是否存在兩個數值之間 For example SELECT employeeid age lastname salary FROM employee_info WHERE age BETWEEN 30 AND 40 傳回年紀 30歲到 40歲之間的資料(含 30及 40歲者) 相同的也可以使用以下語法來達到相同的結果 SELECT employeeid age lastname salary FROM employee_info WHERE age gt= 30 AND age lt= 40 你也可使用 NOT BETWEEN 來濾掉中間值的資料 數學運算 標準 ANSI SQL-92 提供以下運算

87

+ 加

- 減

餘數

餘數為除法後剩整數這不在標準的 ANSI SQL 中但大部份的資料庫都會支

援這運算元以下列出有用的函數雖不在 ANSI SQL-92 提供但一般資料庫

也會支援他們

ABS(x) 傳回 x 絕對值

SIGN(x) returns the sign of input x as -1 0 or 1 (negative zero or positive respectively)

MOD(xy) 餘數 - returns the integer remainder of x divided by y (同 xy)

FLOOR(x) 傳回小或等於 x 的最大整數值

CEILING(x) or CEIL(x)

傳回大或等於 x 的最小整數值

POWER(xy) x的 y 次方

ROUND(x) 把 x 四捨五入為整數

ROUND(xd) 四捨五入取到小數 d 位

SQRT(x) x 開平方

For example SELECT round(salary) firstname FROM employee_info 傳回薪資取到整數位

如何新增資料

insert 加入一筆新紀錄到資料表中 insert into tablename (first_columnlast_column) values (first_valuelast_value) [] = optional Example insert into employee

88

(first last age address city state) values (Luke Duke 45 2130 Boars Nest Hazard Co Georgia) Note 字串要以單引號住如string 數字框住也無妨 insert into 後面接資料表名稱再接以括號括住的欄位名在 values 後括號分別對映各欄位的值 以上的例子新增了一筆名(first) 為 Luke而住所(state) 為 Georgia 的資料

如何刪除資料

delete 可以刪除單筆或多筆紀錄 delete from tablename where columnname OPERATOR value [and|or column OPERATOR value] [ ] = optional Examples delete from employee Note 如果你沒有指定 where 子句那麼全部的紀錄都會被刪除 delete from employee where lastname = May delete from employee where firstname = Mike or firstname = Eric delete from 接著資料表名 再接著是條件式判斷沒有條件式則全部紀錄會

被刪除

如何更新資料

update 用來更新你所指定的記錄要和 WHERE 配合小心使用 語法 update tablename set columnname = newvalue[nextcolumn = newvalue2] where columnname OPERATOR value [and|or column OPERATOR value] [] = optional Examples

89

update phone_book set area_code = 623 where prefix = 979 update phone_book set last_name = Smith prefix=555 suffix=9292 where last_name = Jones update employee set age = age+1 where first_name=Mary and last_name=Williams

90

附錄二Replication

測試環境

RedHat 90 + MySQL 32358 MySQL資料庫路徑 varlibmysql MySQL設定檔 etcmycnf Master IP 1921680100 Slave IP 1921680200 請至下列網址下載最新MySQL 32358套件並利用rpm ndashUvh 更新 httpupdatesredhatcom9enosi386

圖 最新 MySQL 套件

測試架構圖

91

1921680100

1921680200Master Server

erveSlave S r

圖 測試架構圖

測試步驟

Master server 部份 Step1 確認 MasterSlave機器上所裝的 MySQL版本能進行

replication( 32329 or higher ) Step2 在 Master MySQL上開放一個帳號給 Slave mysql ndashu root ndashp mysqlgtGRANT FILE ON TO repl1921680200 IDENTIFIED BY lsquoabc123rsquo mysqlgtq 上面是 Master開放一個帳號 repl密碼 abc123給 IP1921680200有檔案處理

的權限 Step3 shutdown MySQL on the Master mysqladmin ndashu root ndashp shutdown Step4 備份 Master所有資料庫 tar ndashcvf tmpmysql-snapshottar varlibmysql 注意tar的時候MySQL是要在 stop情況下 在mysql (wwwmysqlcom) 網站的FAQ有不用shutdown的方法

92

Step5 在 master機器上修改etcmycnf 在[mysqld]區段內加入參數 log-bin server-id=這邊設定 server-id=1 sql-bin-update-same binlog-do-db=CRM只針對 CRM資料庫做紀錄 Step6 Restart MySQL on the master service mysqld start 此時因為有加入 log-bin 參數因此開始有 index產生了在varlibmysql目錄下

有index檔案紀錄資料庫的異動 log Slave server 部份 Step1 在 slave設定etcmycnf 在[mysqld]區段加入 master-host= master-user= master-password= master-port= server-id= 這邊設定 master-host=1921680100 master-user=repl master-password=abc123 master-port=3306 server-id=2 master-connect-retry=60預設重試間隔 60秒 replicate-do-db=CRM告訴 slave只做 CRM資料庫的更新 log-slave-updates Step2 將 master上的 mysql-snapshottar copy到 slave上 用 ftp傳到 slave的tmp Step3 解壓縮 Master資料庫至 Slave Server上 cd varlib tar xvf tmpmysql-snapshottar chown ndashR mysqlmysql mysql

93

chmod ndashR 770 mysql (視情況) Step4 Restart MySQL on the slave server 這時在varlibmysql目錄會出現 masterinfo此檔案紀錄了 Master MySQL server的資訊

狀況測試

One-way replication

1921680100

1921680200Master Server

erveSlave S r

圖 One-way replication架構圖 Step1 Master跟 Slave網路及服務都正常情況下由 Master端異動資料後 到 Slave端瀏覽資料檢視是否有進行 replication Step2 模擬 Slave Server 當機 可用在於 slave真的當機或是 Slave 不一定需要一直跟 master connect將Slave MySQL server shutdown由 Master端異動資料到 slave端瀏覽此時Slave應該沒有被 replication 更新然後再將 Slave端 MySQL server start起來

預設 60秒後 Slave會嘗試跟 Master要求進行 replication再去 Slave端檢視是否有更新資料

94

Step3 模擬 Master當機因為是設定 One-way replication一旦 Master Server Slave端沒有 Master的 source可以 download Two-way replication 基於 Master當機狀況於是發展雙向 Replication即 1921680100 ( Host A ) 1921680200 ( Host B )都分別擔任 MasterSlave身分

1921680100

1921680200er

Server B MasterSlave Server

Server A MasterSlave Serv

圖 Two-way replication架構圖 以下是針對兩台 MySQL伺服器進行雙向 Replication Step1觀念同單向 replication只是改成 Master也有 Slave身分 Slave也有Master的身分先分別在 Server AServer B 都去 grant一個進行 replication的身分 [A]mysqlgtGRANT FILE ON TO repl1921680200 IDENTIFIED BY lsquoabc123rsquo [B]mysqlgt GRANT FILE ON TO repl1921680100 IDENTIFIED BY lsquoabc123rsquo Step2做完單向 replication後stop Server Aserver B MySQL service此時 AB資料是一樣的

95

修改etcmycnf設定 範例 Server A [mysqld] datadir=varlibmysql socket=varlibmysqlmysqlsock server-id=1 log-bin sql-bin-update-same binlog-do-db=CRM master-host=1921680200 master-user=repl master-password=abc123 log-slave-updates master-connect-retry=60 replicate-do-db=CRM Server B [mysqld] datadir=varlibmysql socket=varlibmysqlmysqlsock server-id=2 log-bin sql-bin-update-same binlog-do-db=CRM master-host=1921680100 master-user=repl master-password=abc123 log-slave-updates master-connect-retry=60 replicate-do-db=CRM 分別 start Server AServer B MySQL後此時雙方都是 MasterSlave身分一旦哪一方資料異動就會通知對方來 replication-若 replication失效則必須將Server AServer B的masterinfo及index00x 都砍掉然後分別 restart MySQL server進行測試檢視成果 實務上通常如果需要做Two-way replication通常會搭配Virtual Server使用

96

在前端架設一台Virtual Server不過此部份不在此份SOP討論範圍內有興趣

的讀者可參考 httpwwwlinuxvirtualserverorg 網站

1921680100 1921680200

Host A MasterSlave Server

Host B MasterSlave Server

Virtual Host

圖 Virtual Server + Two-way replication 架構圖

97

圖 High Availability Linux Virtual Server架構圖

98

  • COSA-SOP-03-006
  • 第一章 簡介
    • 11適用對象 (Audience)
    • 12 MySQL本身
    • 13 MySQL 40版跟50版重大的改進功能
    • 14 各家資料庫軟體比較
      • 第二章 前置需求
      • 第三章 安裝
        • 31 MySQL安裝
        • 32 phpMyAdmin安裝
        • 33 升級及注意事項
          • 第四章 MySQL管理
            • 41 Webmin 管理介面
            • 42 phpMyAdmin 的操作介面
            • 43管理指令介紹
              • 431 利用mysqladmin設定root的密碼
                  • 第五章 實用範例
                    • 51 任務一Web Base客戶通訊錄
                    • 52 任務二Web Base群組軟體 ( twig )
                      • 第六章 維護及更新程序
                        • 61 日常維護
                        • 62 更新程序
                        • 63 備份重要檔案
                        • 64 離線備份與還原
                        • 65 線上備份與還原
                          • 第七章 問題與解答
                          • 第八章 參考資料
                          • 附錄一 SQL Command 介紹
                          • 附錄二Replication
Page 39: DataBase Server Standard Operation Procedureebooks.lib.ntu.edu.tw/1_file/oss/63/93doc4-5.pdf · 業務的公司帶來了不少壓力,譬如微軟,甲骨文 ... 外的錢用在第三方的資料庫產品上,譬如就可以不用再購買甲骨文公司

42 phpMyAdmin 的操作介面

421建立資料庫

Step 填入資料庫名稱並按「建立」

圖 4-18建立資料庫

422 建立資料表

Step1 填入資料表名稱並指定欄位數量 執行

39

圖 4-19填入資料表名稱並指定欄位數量

Step2 設定欄位屬性

圖 4-20設定欄位屬性

40

Step3 phpMyAdmin會產生相關的 SQL Command

圖 4-21 資料表結構及相關 SQL Command

Step4新增 Record

41

圖 4-22

圖 4-23

42

圖 4-24

圖 4-25

43

423使用者管理

Step1建立使用者

圖 4-26

44

圖 4-27

Step2 給予權限

圖 4-28

Step3權限列表

45

圖 4-29

43管理指令介紹

431 利用 mysqladmin設定 root的密碼

當您在Windows 或 Linux 中安裝好 MySQL後系統會自動幫您建立兩個

帳分別是 root 和 匿名者MySQL的 root 跟 Linux 最高權限使用者 root無關MySQL的 root使用者相當於 MS SQL 中的 sa 帳號擁有最高的 Database管理權限但系統預設 MySQL的 root 是不需要密碼所以通常我們一安裝

MySQL後首要任務便是修改 root的密碼 我們可以利用 mysqladmin工具或是直接修改 MySQL內部資料庫的使用者資

料 mysqladmin ndashu root ndashh cosaexamplecom password lsquo1234rsquo

46

-u 表示使用者帳號root 為 MySQL預設的管理帳號

-h 表示 MySQL主機的主機名稱也可使用 IP Address password 表示使用者的密碼因為字串請使用單引號將密碼括起來 密碼設定完成之後還是可以利用 mysqladmin修改密碼但是你必須提供目前的密碼

432 連線 MySQL

mysql -uroot -p密碼 (-p和密碼之間不能有空白) 或 mysql -uroot -p (此方式會在進入後要求密碼) [rootossc phpMyAdmin] mysql -u root -p1234

Welcome to the MySQL monitor Commands end with or g

Your MySQL connection id is 25 to server version 32354

Type help or h for help Type c to clear the buffer

mysqlgt show databases

+----------+

| Database |

+----------+

| mysql |

| test |

+----------+

2 rows in set (000 sec)

mysqlgt exit

Bye

[rootossc phpMyAdmin]

433 建立資料庫

可利用 mysqladmin指令建立 CONTACT資料庫 mysqladmin -u root -p1234 create CONTACT

47

或是利用 mysql指令 [rootossc bluepage] mysql -u root -p1234 Welcome to the MySQL monitor Commands end with or g Your MySQL connection id is 1057 to server version 32354 Type help or h for help Type c to clear the buffer mysqlgt create database CONTACT Query OK 1 row affected (000 sec) mysqlgt show databases +----------+ | Database | +----------+ | CONTACT | | address | | hello | | mysql | | nuke | | test | +----------+ 6 rows in set (000 sec) mysqlgt exit

434 建立資料表

編寫 adresssql內容如下 -- Table structure for table address CREATE TABLE address ( id int(11) NOT NULL auto_increment name varchar(20) NOT NULL default tel varchar(15) NOT NULL default PRIMARY KEY (id) ) TYPE=MyISAM

48

-- Dumping data for table address INSERT INTO address VALUES (1林小明0800016888) INSERT INTO address VALUES (2黃大雄0800016888) INSERT INTO address VALUES (3劉小芬0800024365) 然後執行此 sql script mysql -u root -p1234 CONTACT lt addresssql 或是利 mysql command [rootossc bluepage] mysql -u root -p1234 Welcome to the MySQL monitor Commands end with or g Your MySQL connection id is 1090 to server version 32354 Type help or h for help Type c to clear the buffer mysqlgt use CONTACT Database changed Database changed mysqlgt CREATE TABLE address ( -gt id int(11) NOT NULL auto_increment -gt name varchar(20) NOT NULL default -gt tel varchar(15) NOT NULL default -gt PRIMARY KEY (id) -gt ) TYPE=MyISAM Query OK 0 rows affected (000 sec) mysqlgt INSERT INTO address VALUES (1林小明0800016888) Query OK 1 row affected (000 sec) mysqlgt INSERT INTO address VALUES (2黃大雄0800016888) Query OK 1 row affected (000 sec) mysqlgt INSERT INTO address VALUES (3劉小芬0800024365) Query OK 1 row affected (000 sec) mysqlgt exit Bye

49

第五章 實用範例

51 任務一Web Base客戶通訊錄

任職於開放科技公司的林小明前些日子在最符合成本效益的條件下快

速地完成公司網站的建置老闆因此對小明讚譽有加最近因為公司存放客戶資

料的 SQL Server主機屢遭病毒攻擊加上作業系統本身的問題當機次數頻繁

老闆希望能儘快把公司的客戶通訊錄程式移轉到較穩定的環境上因為此客戶通

訊錄程式最主要給內部人員使用所以介面美觀並不特別要求只求穩定且能快

速得到查詢結果老闆希望在短時間先看到程式的雛型並鍵入資料對其效率

及穩定性進行測試因為上次小明表現突出所以這次不可能的任務自然又落到

小明身上 小明想來想去既然要快速又穩定他而且又不希望所有人都得安裝 Client

程式於是小明決定)捨棄他的舊愛「Delphi+MS SQL」投向新歡「Apache + MySQL + PHP」利用此架構來設計一個簡單實用的Web Base客戶通訊錄程式

511 Web Base客戶通訊錄架構

此程式需要建立 CONTACT的資料庫並建立 adress Tables其結構如下表建立步驟請參考第三章 欄位名稱 資料型態 長度 說明 id INT (自動編號) 連絡人編號 name varchar文字 20 連絡人姓名 tel Varchar文字 15 連絡人電話 Web Base通訊錄共有下列幾個檔案功能如下表

檔案名稱 說明 Indexhtml Web Base通訊錄首頁 addphp 新增連絡人的 php程式 searchphp 尋找連絡人的 php程式 editphp 具有更新及刪除功能的 php程式

50

我們將這些檔案放至varwwwhtmlbluepage (預設無 bluepage目錄)

512 Web Base通訊錄測試

httpwwwopencombluepage 新增資料

圖 5-1 新增連絡人

圖 5-2 填入資料

51

圖 5-3 新增成功

搜尋及異動資料

圖 5-4 搜尋通訊錄

52

圖 5-5 編輯資料

圖 5-6 更新資料

513 程式內容及說明

lt-- 程式範例indexhtml--gt lthtmlgt ltheadgtlttitlegt通訊錄lttitlegtltheadgt ltbodygt ltcentergt

53

lth2gt通訊錄lth2gtlthrgt lta href=indexhtmlgt通訊錄ltagt | lta href=addphpgt新增連絡人ltagt | lta href=searchphpgt搜尋通訊錄ltagt ltcentergt ltbodygt lthtmlgt lt-- 程式範例addphp --gt lthtmlgt ltheadgtlttitlegt新增連絡人lttitlegtltheadgt ltbodygt ltcentergtlth2gt新增連絡人lth2gtltcentergtlthrgt lt 取得欄位資料 if (isset($_POST[Name]) ampamp isset($_POST[Tel]) ) $name = $_POST[Name] $tel = $_POST[Tel] 檢查是否有輸入欄位資料 if ($name = ampamp $tel = ) 建立 SQL字串 $sql = INSERT INTO address (name tel) values( $sql= $name $tel) 建立 MySQL 連結 $link = mysql_connect(localhostroot1234) 選擇資料庫 mysql_select_db(CONTACT) 執行 SQL指令 mysql_query($sql) mysql_close($link) echo ltfont color=redgt新增連絡人成功ltfontgtltbrgt gt ltform action=addphp method=postgt lttable border=0 width=300gt lttrgtlttdgt姓名 lttdgt

54

lttdgtltinput type=text name=Name size=20 maxlength=10gtlttdgtlttrgt lttrgtlttdgt電話 lttdgt lttdgtltinput type=text name=Tel size=20 maxlength=20gtlttdgtlttrgt lttrgtlttd colspan=2 align=centergt ltinput type=submit value=新增連絡人gtlttdgtlttrgt lttablegt ltformgt ltbrgtlta href=indexhtmlgt通訊錄ltagt | lta href=addphpgt新增連絡人ltagt | lta href=searchphpgt搜尋通訊錄ltagt ltbodygt lthtmlgt

lt-- 程式範例searchphp --gt lthtmlgt ltheadgtlttitlegt搜尋通訊錄lttitlegtltheadgt ltbodygt ltcentergtlth2gt搜尋通訊錄lth2gtlthrgt lt if (isset($_POST[Search])) 建立資料庫連結並選定資料庫 $link = mysql_connect(localhostroot1234) mysql_select_db(CONTACT) 建立基本的 SQL字串 $sql = SELECT FROM address 檢查是否輸入姓名 if (chop($_POST[Name]) = ) $name = name LIKE $_POST[Name] else $name = 檢查是否輸入電話號碼 if (chop($_POST[Tel]) = ) $tel = tel LIKE $_POST[Tel] else $tel =

55

if條件組合 SQL字串 if (chop($name) = ampamp chop($tel) = ) $sql= WHERE $name AND $tel elseif (chop($name) = ) 只有姓名 $sql = WHERE $name elseif (chop($tel) = ) 只有電話號碼 $sql = WHERE $tel $sql= ORDER BY name 最後加上排序 $result = mysql_query($sql) 取得欄位數 $total_fields = mysql_num_fields($result) echo lttable border=1gt echo lttrgtlttdgt編號lttdgtlttdgt姓名lttdgtlttdgt電話lttdgtlttd colspan=2gt功能選項lttdgtlttrgt 表格顯示查詢結果 while ($rows = mysql_fetch_array($result MYSQL_NUM)) echo lttrgt for ($i = 0 $i lt $total_fields $i++) echo lttdgt$rows[$i]lttdgt echo lttdgtlta href=editphpaction=editampid= echo $rows[0]gtltbgt編輯ltbgtlttdgt echo lttdgtlta href=editphpaction=delampid= echo $rows[0]gtltbgt刪除ltbgtlttdgt echo lttrgt echo lttablegtlthrgt mysql_free_result($result) mysql_close($link) gt ltcentergt ltform action=searchphp method=postgt lttable border=0 width=450gt lttrgtlttdgt搜尋姓名 lttdgt lttdgtltinput type=text name=Name size=10 maxlength=20gtlttdgtlttrgt lttrgtlttdgt搜尋電話 lttdgt lttdgtltinput type=text name=Tel

56

size=20 maxlength=20gtlttdgtlttrgt lttrgtlttd colspan=2 align=centergt ltinput type=submit name=Search value=搜尋gtlttdgtlttrgt lttablegt ltformgt ltbrgtlta href=indexhtmlgt通訊錄ltagt | lta href=addphpgt新增連絡人ltagt | lta href=searchphpgt搜尋通訊錄ltagt ltbodygt lthtmlgt

lt ob_start() gt lt-- 程式範例editphp --gt lthtmlgt ltheadgtlttitlegt編輯通訊錄lttitlegtltheadgt ltbodygt lt 取得 URL 參數 $id = $_GET[id] $action = $_GET[action] 建立資料庫連結 $link = mysql_connect(localhostroot1234) mysql_select_db(CONTACT) 選擇資料庫 執行的操作 switch ($action) case update 更新 取得欄位資料 $name = $_POST[Name] $tel = $_POST[Tel] $sql = UPDATE address SET name=$name tel=$tel WHERE id=$id mysql_query($sql) 執行 SQL指令 mysql_close($link) header(Location searchphp) 轉向到 serachphp break case del 刪除 $sql = DELETE FROM address WHERE id=$id

57

mysql_query($sql) 執行 SQL指令 mysql_close($link) header(Location searchphp) 轉向到 serachphp break case edit 編輯 $sql = SELECT FROM address WHERE id=$id $result = mysql_query($sql) 執行 SQL指令 $row = mysql_fetch_row($result) 取回記錄 $name = $row[1] 取得欄位 name $tel = $row[2] 取得欄位 tel mysql_close($link) 顯示編輯表單 gt ltcentergtlth2gt更新通訊錄lth2gtltcentergtlthrgt ltform action=editphpaction=updateampid=lt echo $id gt method=postgt lttable border=0 width=300gt lttrgtlttdgt姓名 lttdgt lttdgtltinput type=text name=Name size=20 maxlength=10 value=lt echo $name gtgtlttdgtlttrgt lttrgtlttdgt電話 lttdgt lttdgtltinput type=text name=Tel size=20 maxlength=20 value=lt echo $tel gtgtlttdgtlttrgt lttrgtlttd colspan=2 align=centergt ltinput type=submit value=更新連絡人gtlttdgtlttrgt lttablegt ltformgt ltbrgtlta href=indexhtmlgt通訊錄ltagt | lta href=addphpgt新增連絡人ltagt | lta href=searchphpgt搜尋通訊錄ltagt lt break gt ltbodygt lthtmlgt

58

52 任務二Web Base群組軟體 ( twig )

順利完成Web Base客戶通訊錄程式測試一段時間後「Apache + MySQL + PHP」架構的穩定與快速巳深得老闆與公司所有同事的認同隨著公司業績蒸

蒸日上人員組織編罝愈來愈龐大跨部門的會議愈來愈多業務員每日排滿拜

訪客戶的行程跟客戶的 Email的往來也愈來愈頻繁 愈來愈多部門的同事希望公司能建置一套群組軟體提供 web mail可讓業

務人員方便收發 mail還有連絡人議事日程待辦工作書簽等功能讓整個

公司運作及個人時間管理更有效率

老闆問小明對這些需求有什麼看法小明認為如果這些功能完全由程式部

門開發必定曠日費時而且耗費公司資源小明在網路尋找是否有提供這些功能

的Free Software皇天不負苦心人小明發現了TWIG (The Web Information Gateway) httptwigscrewdrivernet這個群組軟體它在 Web 上整合郵件新聞聯絡人議事日程工作序書簽等功能非常符合公司的需求 Step 1 下載 twig-277targz 下載網址 httptwigscrewdrivernetdownloadphp3

Step 2 解開 twig-277targz tar -xzvf twig-277targz

59

Step 3 執行安裝動作安裝到 varwwwhtmltwig 目錄 cd twig-277 twig-install varwwwhtmltwig

Step 4 建立 MySQL 資料庫(twig)及各資料表

cd setup mysql -u root -p1234 mysqlgt create database twig Query OK 1 row affected (001 sec) mysqlgt quit mysql -u root ndashp1234 twiglt twigtablemysql

Step 5 修改 configincphp3 參數設定 vi varwwwhtmltwigconfigconfigincphp3 $config[fromdomain] = opencom 網域 $config[language] = chinesebig5 中文訊息 $config[imap_port] = 143notls

60

Step 6 修改連結 MySQL 的帳號密碼 vi varwwwhtmltwigconfigdbconfigincphp3 $dbconfig[sqlusername] = root username $dbconfig[sqlpassword] = 1234 password

Step 7 其他設定檔

vi etchttpdconfhttpdconf 加入 AddType applicationx-httpd-php php3 在 DirectoryIndex最後加入 indexphp3 DirectoryIndex indexhtml indexhtmlvar indexphp3 在 AddDefaultCharset ISO-8859-1加上 AddDefaultCharset ISO-8859-1

vi etcphpini register_globals = On service httpd restart Step 8 sendmail 設定 vi etcmailsendmailcf在 264 行前面加上並重新啟動 sendmail「service snedmail restart」 262 SMTP daemon options 263 264 O DaemonPortOptions=Port=smtpAddr=127001 Name=MTA 265 266 SMTP client options 267 O ClientPortOptions=Family=inet Address=00

61

Step 9 檢查設定有無錯誤 http主機名稱twigtestphp3

62

Step 10 登入 twig ( http主機名稱twig)

63

第六章 維護及更新程序

61 日常維護

系統管理員最好定期以 root 身份登入看看信件在 RedHat Linux 中有一支 logwatch 程式會定時去分析 log file如果發現異常便會發信給 root除此之外筆者建議讀者平時就檢查 MySQL log file ( varlogmysqldlog)是否有異常情形

62 更新程序

讀者可至httprpmfindnet 尋找MySQL相關套件至於升級的相關步驟請參

考Linux OS SOP 第 54節

63 備份重要檔案

預設 MySQL 的 DB 檔案是存在 varlibmysql 內以 DB名稱為目錄目錄

內就是該 DB 的所有資料通常得定期備份還有 MySQL的設定檔 etcmycnf也別忘了一起備份

64 離線備份與還原

641 離線備份

預設 MySQL 的 DB 檔案是存在 varlibmysql 內以 DB 名稱為目錄目錄內

就是該 DB 的所有資料像 CRM 這個 DB就是存在 varlibmysqlCRM 內在備份前因為怕資料尚未完全寫入磁碟而且 MySQL 會 Lock 在使用的 DB 檔案所以應該是要先把 MySQL 先 Shutdown 一下整個備份的程序可以下像下面的指令去完成 cd varlibmysql

64

service mysqld stop tar cvfz CRM_db_20030905tgz CRM service mysqld start 對這樣就可以了 不過要注意的是怕 DB 內每個 Tables 間的資料有關關

聯性所以最好是把整個 DB 一次備起來單獨只備哪個 Tables 的檔案以後回存時怕會有資料關聯不一致的問題

642 離線還原

DB 發生錯誤而要回存時其實也不難先找出最近一次完整正常的備份先把現在錯誤的網頁或 DB 先更名或 tar 起來再把好的備份給解開回原來目錄位

置就行了需要注意的是 MySQL 服務最好也是要先停止回存完成後再啟動服務回存 DB 的整個程序可能像下面 cd varlibmysql service mysqldstop mv CRM CRM_OLD tar xvfz CRM_db_20030905tg service mysqld start

65 線上備份與還原

651 線上備份

使用像上面的檔案方式備份是個不錯的方法它最少可以保持該主機某個時間點的完整檔案備份但還是有一些問題需要考慮到有些主機就不只建立一個 DB 而已總不能為了備份某個 DB 而把整個 MySQL 服務停止備份檔案的方式回存在原主機上一定適用但假如 MySQL 版本升級或是在那天該網頁空間需遷機移機到別的主機時那就沒人敢保證備出來的資料檔可以用所以我們可以考慮另一種備份的方式是使用 MySQL 本身提供的功能 MySQL Data Dump指令是 mysqldump

65

使用 MySQL 的 Dump 功能可以把 DB 的結構資料或結構加資料 Dump 成文字檔 mysqldump 指令提供的彈性很大你可以選擇把整個 DB Dump 成一個檔或是每個 Table 為一個檔甚至是把結構檔和資料分開儲存都

可以 mysqladmin -uroot -p flush-logs mysqldump CRM -uroot -p --opt gt CRM_20030905sql (CRM 是 DB 名稱 opt 是一個使用完整 Dump 參數) 假如只是要單獨 Dump 某個 Table 時只要在上面的指令後轉出符號 gt 前加個 Table 名稱就可以如只要 phpbb2_users 這個 Table 的 Dump 時只要下 mysqldump CRM -uroot -p --opt CUSTOMER gt CRM_CUSTOMER_20030905sql

652 線上還原

若要回存整個資料庫只需將壓縮的備份檔還原成 Dump 的檔案再用下面的指令回存 mysql CRM -uroot -p lt CRM_20030905sql 這邊需注意的是若建立備份時是以--opt或--add-drop-table為參數時回存的 動作是先將舊的 Table 先刪除重建 Table 的結構後再把 Data 匯入所以回存後所有的資料會回到你當時備份那個時間點因此在回存資料時可以考慮把現有錯誤或不完整的 DB 先備份一份下來以備不時之需或是拿來比對錯誤的地

方在那裡當然你也可以把資料回存到另一個測試用的 DB 內只要把上面指令

的 DB 名稱改成你的測試用 DB 名稱即可 使用這種回存方式 MySQL 服務不需停止也不會動到其他正在使用的 DB 在一些提供 MySQL 服務的虛擬主機可用這種方式作你自己的 DB 備份及回存

66

另外假如你是系統重建或是移機時切需在新的 MySQL 內新建一個空白 DB 後才行作回存的工作你可以用下面的指令建立 mysql -uroot -p -e CREATE DATABASE CRM (上面的 CRM是你要新建的 DB 名稱) 另一種作法先用 mysql 指令進入 mysql client console 然後再用 CREATE DATABASE CRM 這樣就行了記得尾端要加個 符號該行指令才會執行

67

第七章 問題與解答

Q1RedHat 90預附的 MySQL到底有無支援 Transcation機制 Ans MySQL自 32334a之後的 MySQL-Max版本加入 InnoDB的資料庫類型透過

InnoDBMySQL同樣可以進行 COMMIT與 ROLLRACK的動作RedHat 90預附的 MySQL為 32354a-11巳支援 InnoDB的資料庫類型不過必須做以

下設定 1cp usrsharedocmysql-server-32354amy-mediumcnf to etcmycnf 2 vi etcmycnf 將以下設定前的拿掉 innodb_data_home_dir = varlibmysql innodb_data_file_path = ibdata110Mautoextend innodb_log_group_home_dir = varlibmysql innodb_log_arch_dir = varlibmysql 3service mysqld restart 如此一來各位在建立Table時便可指定Table Type為 innodb ( ex create table with type=innodb ) Q2如何解決 php+mysql 許功蓋等字變亂的問題 Ans 方法一 【確定 MySQL 預設的字元集】 1 打開 WinMySQLadmin 管理畫面(在視窗右下角狀態列紅綠燈圖示中按滑鼠

右鍵點選 Show me 選項) 2 點選管理畫面中 [Variables] 標籤選項其中 character_set變數就是您預設

字元集的變數其預設是 latin1 字元集(我們要將他改回 big5)而 chatacters_set 變數則是 MySQL 可以支援哪些字元集 【修改預設字元集變數 character_set 】 1 請點選管理畫面中 [myini Setup] 標籤選項設定 myini 2 按一下 [Pick-up and Edit myini values] 按鈕以便編輯目前的 myini 設定 3 在 [mysqld] 設定區塊底下新增一行 default-character-set = big5 變數設

68

定 4 新增一個 [client] 設定區塊並加入第三步驟的變數設定(游標往下移到空白處新增兩行 [client] 和 default-character-set=big5) 5 按一下畫面左下方 [Save Modification] 按鈕儲存設定 6 重新啟動 MySQL 或 Windows 方法二 Server端注意事項 phpini 中有關的設定為(預設值) Magic quotes for incoming GETPOSTCookie data magic_quotes_gpc = On Use Sybase-style magic quotes (escape with instead of ) magic_quotes_sybase = Off Client端注意事項 1中文資料送進 mysql 前請用 addslashes($str) 處理 2處理後送進 mysql 時請用 括起來並在參數後留一個空白如 $sql = UPDATE ezf_table set tablename=$tname tableend=$endtime table inguser=$tguser tableingid=$tguserid tableallnumber=$tnumber tableloca l=$tablelocal tableanyone=$tableopen tabletext=$ttext WHERE tableid=$t ableid tablename=$tname c 取出時請用 stripslashes($str) Q3MySQL root 密碼忘了該怎麼辦 Ans 1先停掉 mysql etcrcdinitdmysql stop 2以--skip-grant-table 的參數啟動 mysql safe_mysql --skip-grant-tableamp 3 更改 root 密碼 mysql mysql mysqlgt UPDATE user SET password=password(newpassword)

69

WHERE user=root mysqlgt FLUSH PRIVILEGES mysqlgt exit 4停掉 mysql再重跑 mysqladmin -uroot -p shutdown Enter password 輸入新設定的密碼 etcrcdinitdmysql start

Q4NULL值問題

Ans

NULL值的概念是造成 SQL的新手的混淆的普遍原因他們經常認為 NULL是和一個空字符串的一樣的東西不是這樣的例如下列語句是完全不同的

mysqlgt INSERT INTO my_table (phone) VALUES (NULL)

mysqlgt INSERT INTO my_table (phone) VALUES ()

兩個語句把值插入到 phone 列但是第一個插入一個 NULL值而第二個插入一個空字符串第一個的含義可以認為是ldquo電話號碼不知道而第二個則可意味

著ldquo她沒有電話

在 SQL中NULL值在于任何其他值甚至 NULL值比較時總是假的(FALSE)包含 NULL的一個表達式總是產生一個 NULL值除非在包含在表達式中的運算符和函數的文檔中指出在下列例子所有的列返回 NULL

mysqlgt SELECT NULL1+NULLCONCAT(InvisibleNULL)

如果你想要尋找值是 NULL的列你不能使用=NULL測試下列語句不返回任

何行因為對任何表達式expr = NULL是假的

mysqlgt SELECT FROM my_table WHERE phone = NULL

要想尋找 NULL值你必須使用 IS NULL測試下例顯示如何找出 NULL電話號碼和空的電話號碼

70

mysqlgt SELECT FROM my_table WHERE phone IS NULL mysqlgt SELECT FROM my_table WHERE phone =

在 MySQL中就像很多其他的 SQL服務器一樣你不能索引可以有 NULL值的列你必須聲明這樣的列為 NOT NULL而且你不能插入 NULL到索引的

列中

當用 LOAD DATA INFILE 讀取數據時空列用更新如果你想要在一個列中有

NULL值你應該在文本文件中使用N字面上的詞NULL也可以在某些情形下使用

當使用 ORDER BY時首先呈現 NULL值如果你用 DESC以降序排序NULL值最後顯示當使用 GROUP BY時所有的 NULL值被認為是相等的

為了有助于NULL的處理你能使用 IS NULL和 IS NOT NULL運算符和 IFNULL()函數

對某些列類型NULL值被特殊地處理如果你將 NULL插入表的第一個TIMESTAMP 列則插入當前的日期和時間如果你將 NULL插入一個AUTO_INCREMENT 列則插入順序中的下一個數字

Q5如何將圖片存放於 MySQL中

Ans

Step 1建立資料庫 test

Step 2 建立表格 binary_data

CREATE TABLE binary_data (

id INT(4) NOT NULL AUTO_INCREMENT PRIMARY KEY

description CHAR(50)

bin_data LONGBLOB

filename CHAR(50)

filesize CHAR(50)

filetype CHAR(50)

71

)

Step 3 利用 storephp 寫入圖片

storephp 程式碼

ltHTMLgt ltHEADgtltTITLEgtStore binary data into SQL DatabaseltTITLEgtltHEADgt ltBODYgt lt code that will be executed if the form has been submitted

if ($submit) mysql_connect(localhostrootYOUR_PASSWORD) mysql_select_db(test) $data=Base64_Encode(fread(fopen($form_data r) filesize($form_data))) $result=MYSQL_QUERY(INSERT INTO binary_data (descriptionbin_datafilenamefilesizefiletype) VALUES ($form_description$data$form_data_name$form_data_size$form_data_type)) $id= mysql_insert_id() print ltpgtThis file has the following Database ID ltbgt$idltbgt MYSQL_CLOSE() else else show the form to submit new data

gt

ltform method=post action=ltphp echo $PHP_SELF gt enctype=multipartform-datagt File Descriptionltbrgt ltinput type=text name=form_description size=40gt ltINPUT TYPE=hidden name=MAX_FILE_SIZE value=4000000gt ltbrgtFile to uploadstore in databaseltbrgt ltinput type=file name=form_data size=40gt ltpgtltinput type=submit name=submit value=submitgt ltformgt lt

72

gt ltBODYgt ltHTMLgt

Step 3 利用 storephp 取出圖片

getdataphp 程式碼

lt Syntax getdataphp3id=ltidgt if($id) you may have to modify login information for your database server MYSQL_CONNECT(localhostrootYOUR_PASSWORD) mysql_select_db(test) $query = select bin_datafiletype from binary_data where id=$id $result = MYSQL_QUERY($query) $data = Base64_Decode(MYSQL_RESULT($result0bin_data)) $type = MYSQL_RESULT($result0filetype) Header( Content-type $type) echo $data gt

Q6MySQL裝好之後啟動時或是執行 mysqladmin會出現如下訊息 Cant connect to local MYSQL Server through Socket varlibmysqlmysqlsock或是

Cant connect to local MYSQL Server through Socket tmpmysqldsock

Ans 可能有下列幾個原因

1這個 mysqldsock 不見了被某人刪除了或是被一些系統自動執行程式給刪

了例如有些 cron任務便會設定定期刪除 tmp 裡的東西所以呢您只能修改

cron 裡的設定讓它不要清除 mysqldsock 2在啟動時也可以改變 mysqldsock的位置您在啟動 MySQL的時候可以加入此參數usrlocalmysqlbinsafe_mysqld --user=mysql --socket=其他路

徑socket amp 同時得去設定環境變數 MYSQL_UNIX_PORT的值以指定新的

73

路徑 3若是您沒改 MYSQL_UNIX_PORT的值那麼您可以在執行指令的時候才打

例如mysqladmin --socket=其他路徑socket version Q7How to get the last insert id Ans CREATE TABLE product ( id INT(4) NOT NULL AUTO_INCREMENT PRIMARY KEY description VARCHAR(50) ) 1利用 SQL的話 mysqlgt insert into product(description) values(123) Query OK 1 row affected (000 sec) mysqlgt select last_insert_id() +------------------+ | last_insert_id() | +------------------+ +------------------+ 1 row in set (000 sec) ======================================== 2如果是 PHP的話 你可以用mysql_insert_id()取得該 id PHP example $result=MYSQL_QUERY(INSERT INTO product (description) VALUES ($description)) $id= mysql_insert_id() print This file has the following Database ID $id Q8如何將文字檔匯入資料庫 Ans $addr=homehttpdhtmlphpschool001txt $sql_select = load data infile $addr into table test fields terminated by t 解說 $sql_select = load data infile 文字檔名 into table 表格名 fields terminated by

74

t

(欄位分隔以 TAB鍵) 該文字檔須與資料表欄位格式相符 例如欄位有三個 則文字檔為每行一筆資料如下 欄 1資料ltTABgt欄 2資料ltTABgt欄 3資料 欄 1資料ltTABgt欄 2資料ltTABgt欄 3資料 欄 1資料ltTABgt欄 2資料ltTABgt欄 3資料 欄 1資料ltTABgtltTABgt欄 3資料

Q9如何撰寫 MySQL C API Ans Step 1利用文字編輯器撰寫以下程式碼 mysqlcc

include ltstdiohgt

include ltmysqlmysqlhgt

int main (int argc char argv[])

MYSQL mysql

MYSQL_RES res

MYSQL_ROW row

if (argc = 2)

fputs (Usage myc ltdatabasegt stderr)

return 1

if ((mysql_connect(ampmysqllocalhostrootYour_Password)))

fputs (Error connecting stderr)

abort()

75

if (mysql_select_db(ampmysqlargv[1]))

fputs (Error selecting database stderr)

abort()

if (mysql_query(ampmysqlSELECT FROM test_table))

fputs (Error processing query stderr)

abort()

if ((res = mysql_store_result(ampmysql)))

fputs (Error storing results stderr)

abort()

while((row = mysql_fetch_row(res)))

uint i = 0

for (i=0 i lt mysql_num_fields(res) i++)

printf(s row[i])

printf(n)

return 0

Step 2 Compile

gcc -Iusrlocalmysqlinclude -Lusrlocalmysqllibmysql mysqlcc ndashlm -lmysqlclient

(其中 include path與 library path取決於你的 MySQL安裝路徑)

76

如果執行時發生如下 error Run problemerror in loading shared libraries libmysqlclientsoX 將你的 MySQL library path(for exampleusrlocalmysqllibmysql) 加入etcldsoconf and run sbinldconfig -v Q9ASP + MySQL 範例程式 Ans Dim myconn As New ADODBConnection Dim myrs As New Recordset Dim mySQL As String Dim myrows As Long myconnOpen DSN=MyODBCsample mySQL = SELECT from user myrsSource = mySQL Set myrsActiveConnection = myconn myrsCursorLocation = adUseClient myrsOpen myrows = myrsRecordCount myrsClose myconnClose 可參考 httpwwwdwamnetmysqlasp_myodbcasp 有詳細的資料 Q10如何將 MySQL中的資料庫匯出成txt檔 Ans select from TableName into outfile textxls all result fields will seperate by tab

77

第八章 參考資料

英文部份 網址 1 httpwwwmysqlcom MySQL 網站有第一手有關 MySQL的資料 2 httpwwwmysqlcomdocenReplicationhtml 有關 MySQL Replication 的文件 3 httpwwwgeocitiescomsqlhomefaqstore_blobhtml 如何在 MySQL 存放 BLOB的資料 4httpwwwsapdborg 有關 SAP跟 MySQL相關合作的網站 書藉 1 Cooking with MySQL

Paul DuBois has selected sample recipes from the hundreds youll find in his book MySQL

Cookbook In this third and final series of excerpts showcasing these recipes learn how to

compute team standings how to calculate the differences between successive Dec 26

2002 2 Tips for Building Web Database Applications with PHP and MySQL by Hugh E Williams co-author of Web Database Applications with PHP amp MySQL 04042002

3 Managing and Using MySQL 2nd Edition By Tim King George Reese Randy Jay Yarger

4 MySQL Cookbook By Paul DuBoisPublisher OReillyPub Date October 2002

中文部份

78

1 httplinuxtncedutwtechdocmysqlmysql_docmanual_tochtml MySQL 中文手冊 2 httpchenshloxaedutwphpZ_1php PHP+MySQ程式研習設計網站 3 httplinuxtncedutwtechdocbanicdownhtml PHP 4 手冊 4 httpwwwtncedutwadmin_zonephp台南縣教育網網路中心有很多 Linux相關文件 5 httpdobtncedutw網站建置百寶箱有很多 PHP MySQL 相關範例程式 5 httpwwwdbworldcomtw資料庫專家電子雜誌介紹資料庫的重要觀念及名詞

79

附錄一 SQL Command 介紹

SQL (讀音ess-que-el) 是一種結構查詢語法SQL 使用於資料庫交流

傳遞相容於 ANSI (American National Standards Institute) 是一套標準的關聯

式資料庫語言 SQL 語言是執行更新或從資料系統獲取資料一般常見的關聯

資料庫系統都有提供 SQL 如 Oracle Sybase Microsoft SQL Server Access Ingres 等雖然大部份的資料庫都有提供 SQL 但也多提供了自已獨特的語

法造成了不相容的情形但標準基本的語法是相通的如Select Insert Update Delete Create and Drop 每一個系統都有支援

Table相關 Command

Create Table

關聯式資料庫包含有很多元件稱為資料表(tables) 把資料或訊息放在資

料表中 資料表是以不同的名稱做分別資料表由欄列所構成的二維陣列

欄包含欄位名資料型態 及其他可判斷的資訊列是由全部欄位構成一筆一

筆的紀錄 create table 語法用在建立一個新的資料表語法格式如下

create table tablename (column1 data type column2 data type column3 data type)

Format of create table if you were to use optional constraints

create table tablename (column1 data type [constraint] column2 data type [constraint] column3 data type [constraint]) [ ] = optional

Note You may have as many columns as youd like and the constraints are optional

80

Example

create table employee (first varchar(15) last varchar(20) age number(3) address varchar(30) city varchar(20) state varchar(20))

注意建立資料表格式要以括號把前後框住而最後以(分號)做結尾

欄位名不要超過 30個字元長而且不要使用 sql 的關鍵字(如 where select等)而在後面接是型態的宣告(如字串數字日期格式等)

資料型態是來描述欄位的方式如一個欄位Last_Name 是一個姓氏可以使用varchar (可變動長度字串) 資料型態

以下是幾個常見的資料庫型態 char(size) 固定長度字串最長為 255 位元 varchar(size) 變動長度字串最大字元數以 size 來指定 number(size) 數值格式可以是整數也可以是小數最大數字以 size 位數判

斷未指定小數位數由系統內定 date 日期格式 number(sized) 數值格式最大數字以 size 位數判斷d 為小數位數整數位

數為 size-d 位

有何限制當資料表被建立通常有一或數個欄位是要使用來做關聯的功

能 例如unique 限制(唯一值)兩筆記錄不可以相同的值 not null (非空值)該欄位一定要輸入資料不可是空的primary key (主鍵)是每一筆記錄識別的主要方式

Drop a table drop table 刪除資料表(其中的資料也會一併刪除)

drop table tablename

Example

81

drop table 和刪除全部資料是不同的刪除全部資料欄位名稱資訊等還會

存在但刪除資料表會把這一些也一併移除掉

如何查詢資料

Select 基本用法

select 語法是關連式資料庫最常用的部份可以取得你想要的資料這是一個

簡單的範例 select column1[column2etc] from tablename [where condition] [] = optional 在 select 之後所列欄位名則是要顯示的資料部份你可以一一列出各欄位

名或是以 (星號)來代表選擇全部的欄位 from 之後放資料表名稱 where 子句 (選項) 指定要過濾的條件符合者才會顯現 where 可使用的條件運算元 = 等於 gt 大於 lt 小於 gt= 大或等於 lt= 小或等於 ltgt 大相等 LIKE 相似 For example select first last city

82

from empinfo where first LIKE Er 以Er 為開頭的字串就符合要以單引號框住 Or you can specify select first last from empinfo where last LIKE s 最後一字為 S 就符合 select from empinfo where first = Eric 則表示 first name 一定要是 Eric 才可以 範例資料表empinfo 統計函數

MIN 傳回指定欄位最小值

MAX 傳回指定欄位最大值

SUM 傳回指定欄位總和

AVG 傳回指定欄位平均值

COUNT 傳回指定欄位的筆數

COUNT() 傳回資料庫中的總筆數

統計函數使用於資料表中的數值欄位配合 SELECT 語法使用 只用於總結特定單一欄位可以配合 GROUP BY 做篩選但也可以不使用 GROUP BY 語句For example

SELECT AVG(salary) FROM employee

83

傳回全部 salary 平均值

Another example

SELECT AVG(salary) FROM employee WHERE title = Programmer

傳回 salary 平均值條件為 employees 資料表中當 title 等於 Programmer

Example

SELECT Count() FROM employees

傳回 employees 資料表中紀錄總筆數

GROUP BY 語法 SELECT column1 SUM(column2) FROM list-of-tables GROUP BY column-list The GROUP BY 語句可以先以所列的欄位為條件分組排序在一起(可以多欄

位) example 要列出每一個 dept 中最高 salary 值 SELECT max(salary) dept FROM employee GROUP BY dept HAVING 語法

SELECT column1 SUM(column2) FROM list-of-tables GROUP BY column-list HAVING condition

HAVING 子句是 GROUP BY 的一部份用來過濾在 GROUP BY 所選出的資料功能如同 select 命令中 where 條件式一樣只是 HAVING 必需配合 GROUP BY 使用

我們以例子來說明我們要取得每一公司名及每一公司的薪水平均值輸入如下

84

SELECT dept avg(salary) FROM employee GROUP BY dept

但如果我們只列出薪資平均值超過 20000元的公司資料

SELECT dept avg(salary) FROM employee GROUP BY dept HAVING avg(salary) gt 20000

ORDER BY子句語法

SELECT column1 SUM(column2) FROM list-of-tables ORDER BY column-list [ASC | DESC]

[ ] =選項

ORDER BY是一個選項子句當你以排序方式來顯示資料(正向由小到大反向由大到小)以指定的欄位資料做排序

ASC = 正向- 預設值 DESC = 反向排序

For example

SELECT employee_id dept name age salary FROM employee_info WHERE dept = Sales ORDER BY salary

以上列出公司代號公司名銷售員人名年紀及薪資而條件是公司名為 Sales 顯示順序以薪資多少排序(由小到大為預設值)

如果要以多個欄位做排序要以逗號做分隔如下

SELECT employee_id dept name age salary FROM employee_info WHERE dept = Sales ORDER BY salary age DESC

85

結合條件及布林運算 SELECT column1 SUM(column2) FROM list-of-tables WHERE condition1 AND condition2 AND運算可以結兩個或以上的條件放在 WHERE子句中 兩者都要為真才

會顯示該筆記錄 OR 運算可以結兩個或以上敘述放在 WHERE子句中只要其中一個為直就

會顯示該筆記錄 For example SELECT employeeid firstname lastname title salary FROM employee_info WHERE salary gt= 5000000 AND title = Programmer 必需要薪資大於等於 50000而且職稱為 Programmer同時符合才會顯示該筆資料 以下以括號括住雖然不是必需的但如此比較容易讀 SELECT employeeid firstname lastname title salary FROM employee_info WHERE (salary gt= 5000000) AND (title = Programmer) 另外範例 SELECT firstname lastname title salary FROM employee_info WHERE (title = Sales) OR (title = Programmer) 條件為只要是 Sales 或 Programmer 職稱的就會被列出 IN and BETWEEN 子句

SELECT column1 SUM(column2) FROM list-of-tables WHERE column3 IN (list-of-values) SELECT column1 SUM(column2) FROM list-of-tables WHERE column3 BETWEEN value1 AND value2 IN 子句使用在列舉項目的使用上也就是分別測試是否符合所列的值 For example

86

SELECT employeeid lastname salary FROM employee_info WHERE lastname IN (Hernandez Jones Roberts Ruiz) 條件為姓氏(astname)要符合 Hernandez Jones Roberts or Ruiz 其中一個才會被傳回 IN運算元也可以使用 OR 的語法來取代如下結果相同 SELECT employeeid lastname salary FROM employee_info WHERE lastname = Hernandez OR lastname = Jones OR lastname = Roberts OR lastname = Ruiz 但使用 IN 句子比較短也比較易懂 你也可以使用 NOT IN 來去掉不要的記錄 BETWEEN 運算元使用在判斷是否存在兩個數值之間 For example SELECT employeeid age lastname salary FROM employee_info WHERE age BETWEEN 30 AND 40 傳回年紀 30歲到 40歲之間的資料(含 30及 40歲者) 相同的也可以使用以下語法來達到相同的結果 SELECT employeeid age lastname salary FROM employee_info WHERE age gt= 30 AND age lt= 40 你也可使用 NOT BETWEEN 來濾掉中間值的資料 數學運算 標準 ANSI SQL-92 提供以下運算

87

+ 加

- 減

餘數

餘數為除法後剩整數這不在標準的 ANSI SQL 中但大部份的資料庫都會支

援這運算元以下列出有用的函數雖不在 ANSI SQL-92 提供但一般資料庫

也會支援他們

ABS(x) 傳回 x 絕對值

SIGN(x) returns the sign of input x as -1 0 or 1 (negative zero or positive respectively)

MOD(xy) 餘數 - returns the integer remainder of x divided by y (同 xy)

FLOOR(x) 傳回小或等於 x 的最大整數值

CEILING(x) or CEIL(x)

傳回大或等於 x 的最小整數值

POWER(xy) x的 y 次方

ROUND(x) 把 x 四捨五入為整數

ROUND(xd) 四捨五入取到小數 d 位

SQRT(x) x 開平方

For example SELECT round(salary) firstname FROM employee_info 傳回薪資取到整數位

如何新增資料

insert 加入一筆新紀錄到資料表中 insert into tablename (first_columnlast_column) values (first_valuelast_value) [] = optional Example insert into employee

88

(first last age address city state) values (Luke Duke 45 2130 Boars Nest Hazard Co Georgia) Note 字串要以單引號住如string 數字框住也無妨 insert into 後面接資料表名稱再接以括號括住的欄位名在 values 後括號分別對映各欄位的值 以上的例子新增了一筆名(first) 為 Luke而住所(state) 為 Georgia 的資料

如何刪除資料

delete 可以刪除單筆或多筆紀錄 delete from tablename where columnname OPERATOR value [and|or column OPERATOR value] [ ] = optional Examples delete from employee Note 如果你沒有指定 where 子句那麼全部的紀錄都會被刪除 delete from employee where lastname = May delete from employee where firstname = Mike or firstname = Eric delete from 接著資料表名 再接著是條件式判斷沒有條件式則全部紀錄會

被刪除

如何更新資料

update 用來更新你所指定的記錄要和 WHERE 配合小心使用 語法 update tablename set columnname = newvalue[nextcolumn = newvalue2] where columnname OPERATOR value [and|or column OPERATOR value] [] = optional Examples

89

update phone_book set area_code = 623 where prefix = 979 update phone_book set last_name = Smith prefix=555 suffix=9292 where last_name = Jones update employee set age = age+1 where first_name=Mary and last_name=Williams

90

附錄二Replication

測試環境

RedHat 90 + MySQL 32358 MySQL資料庫路徑 varlibmysql MySQL設定檔 etcmycnf Master IP 1921680100 Slave IP 1921680200 請至下列網址下載最新MySQL 32358套件並利用rpm ndashUvh 更新 httpupdatesredhatcom9enosi386

圖 最新 MySQL 套件

測試架構圖

91

1921680100

1921680200Master Server

erveSlave S r

圖 測試架構圖

測試步驟

Master server 部份 Step1 確認 MasterSlave機器上所裝的 MySQL版本能進行

replication( 32329 or higher ) Step2 在 Master MySQL上開放一個帳號給 Slave mysql ndashu root ndashp mysqlgtGRANT FILE ON TO repl1921680200 IDENTIFIED BY lsquoabc123rsquo mysqlgtq 上面是 Master開放一個帳號 repl密碼 abc123給 IP1921680200有檔案處理

的權限 Step3 shutdown MySQL on the Master mysqladmin ndashu root ndashp shutdown Step4 備份 Master所有資料庫 tar ndashcvf tmpmysql-snapshottar varlibmysql 注意tar的時候MySQL是要在 stop情況下 在mysql (wwwmysqlcom) 網站的FAQ有不用shutdown的方法

92

Step5 在 master機器上修改etcmycnf 在[mysqld]區段內加入參數 log-bin server-id=這邊設定 server-id=1 sql-bin-update-same binlog-do-db=CRM只針對 CRM資料庫做紀錄 Step6 Restart MySQL on the master service mysqld start 此時因為有加入 log-bin 參數因此開始有 index產生了在varlibmysql目錄下

有index檔案紀錄資料庫的異動 log Slave server 部份 Step1 在 slave設定etcmycnf 在[mysqld]區段加入 master-host= master-user= master-password= master-port= server-id= 這邊設定 master-host=1921680100 master-user=repl master-password=abc123 master-port=3306 server-id=2 master-connect-retry=60預設重試間隔 60秒 replicate-do-db=CRM告訴 slave只做 CRM資料庫的更新 log-slave-updates Step2 將 master上的 mysql-snapshottar copy到 slave上 用 ftp傳到 slave的tmp Step3 解壓縮 Master資料庫至 Slave Server上 cd varlib tar xvf tmpmysql-snapshottar chown ndashR mysqlmysql mysql

93

chmod ndashR 770 mysql (視情況) Step4 Restart MySQL on the slave server 這時在varlibmysql目錄會出現 masterinfo此檔案紀錄了 Master MySQL server的資訊

狀況測試

One-way replication

1921680100

1921680200Master Server

erveSlave S r

圖 One-way replication架構圖 Step1 Master跟 Slave網路及服務都正常情況下由 Master端異動資料後 到 Slave端瀏覽資料檢視是否有進行 replication Step2 模擬 Slave Server 當機 可用在於 slave真的當機或是 Slave 不一定需要一直跟 master connect將Slave MySQL server shutdown由 Master端異動資料到 slave端瀏覽此時Slave應該沒有被 replication 更新然後再將 Slave端 MySQL server start起來

預設 60秒後 Slave會嘗試跟 Master要求進行 replication再去 Slave端檢視是否有更新資料

94

Step3 模擬 Master當機因為是設定 One-way replication一旦 Master Server Slave端沒有 Master的 source可以 download Two-way replication 基於 Master當機狀況於是發展雙向 Replication即 1921680100 ( Host A ) 1921680200 ( Host B )都分別擔任 MasterSlave身分

1921680100

1921680200er

Server B MasterSlave Server

Server A MasterSlave Serv

圖 Two-way replication架構圖 以下是針對兩台 MySQL伺服器進行雙向 Replication Step1觀念同單向 replication只是改成 Master也有 Slave身分 Slave也有Master的身分先分別在 Server AServer B 都去 grant一個進行 replication的身分 [A]mysqlgtGRANT FILE ON TO repl1921680200 IDENTIFIED BY lsquoabc123rsquo [B]mysqlgt GRANT FILE ON TO repl1921680100 IDENTIFIED BY lsquoabc123rsquo Step2做完單向 replication後stop Server Aserver B MySQL service此時 AB資料是一樣的

95

修改etcmycnf設定 範例 Server A [mysqld] datadir=varlibmysql socket=varlibmysqlmysqlsock server-id=1 log-bin sql-bin-update-same binlog-do-db=CRM master-host=1921680200 master-user=repl master-password=abc123 log-slave-updates master-connect-retry=60 replicate-do-db=CRM Server B [mysqld] datadir=varlibmysql socket=varlibmysqlmysqlsock server-id=2 log-bin sql-bin-update-same binlog-do-db=CRM master-host=1921680100 master-user=repl master-password=abc123 log-slave-updates master-connect-retry=60 replicate-do-db=CRM 分別 start Server AServer B MySQL後此時雙方都是 MasterSlave身分一旦哪一方資料異動就會通知對方來 replication-若 replication失效則必須將Server AServer B的masterinfo及index00x 都砍掉然後分別 restart MySQL server進行測試檢視成果 實務上通常如果需要做Two-way replication通常會搭配Virtual Server使用

96

在前端架設一台Virtual Server不過此部份不在此份SOP討論範圍內有興趣

的讀者可參考 httpwwwlinuxvirtualserverorg 網站

1921680100 1921680200

Host A MasterSlave Server

Host B MasterSlave Server

Virtual Host

圖 Virtual Server + Two-way replication 架構圖

97

圖 High Availability Linux Virtual Server架構圖

98

  • COSA-SOP-03-006
  • 第一章 簡介
    • 11適用對象 (Audience)
    • 12 MySQL本身
    • 13 MySQL 40版跟50版重大的改進功能
    • 14 各家資料庫軟體比較
      • 第二章 前置需求
      • 第三章 安裝
        • 31 MySQL安裝
        • 32 phpMyAdmin安裝
        • 33 升級及注意事項
          • 第四章 MySQL管理
            • 41 Webmin 管理介面
            • 42 phpMyAdmin 的操作介面
            • 43管理指令介紹
              • 431 利用mysqladmin設定root的密碼
                  • 第五章 實用範例
                    • 51 任務一Web Base客戶通訊錄
                    • 52 任務二Web Base群組軟體 ( twig )
                      • 第六章 維護及更新程序
                        • 61 日常維護
                        • 62 更新程序
                        • 63 備份重要檔案
                        • 64 離線備份與還原
                        • 65 線上備份與還原
                          • 第七章 問題與解答
                          • 第八章 參考資料
                          • 附錄一 SQL Command 介紹
                          • 附錄二Replication
Page 40: DataBase Server Standard Operation Procedureebooks.lib.ntu.edu.tw/1_file/oss/63/93doc4-5.pdf · 業務的公司帶來了不少壓力,譬如微軟,甲骨文 ... 外的錢用在第三方的資料庫產品上,譬如就可以不用再購買甲骨文公司

圖 4-19填入資料表名稱並指定欄位數量

Step2 設定欄位屬性

圖 4-20設定欄位屬性

40

Step3 phpMyAdmin會產生相關的 SQL Command

圖 4-21 資料表結構及相關 SQL Command

Step4新增 Record

41

圖 4-22

圖 4-23

42

圖 4-24

圖 4-25

43

423使用者管理

Step1建立使用者

圖 4-26

44

圖 4-27

Step2 給予權限

圖 4-28

Step3權限列表

45

圖 4-29

43管理指令介紹

431 利用 mysqladmin設定 root的密碼

當您在Windows 或 Linux 中安裝好 MySQL後系統會自動幫您建立兩個

帳分別是 root 和 匿名者MySQL的 root 跟 Linux 最高權限使用者 root無關MySQL的 root使用者相當於 MS SQL 中的 sa 帳號擁有最高的 Database管理權限但系統預設 MySQL的 root 是不需要密碼所以通常我們一安裝

MySQL後首要任務便是修改 root的密碼 我們可以利用 mysqladmin工具或是直接修改 MySQL內部資料庫的使用者資

料 mysqladmin ndashu root ndashh cosaexamplecom password lsquo1234rsquo

46

-u 表示使用者帳號root 為 MySQL預設的管理帳號

-h 表示 MySQL主機的主機名稱也可使用 IP Address password 表示使用者的密碼因為字串請使用單引號將密碼括起來 密碼設定完成之後還是可以利用 mysqladmin修改密碼但是你必須提供目前的密碼

432 連線 MySQL

mysql -uroot -p密碼 (-p和密碼之間不能有空白) 或 mysql -uroot -p (此方式會在進入後要求密碼) [rootossc phpMyAdmin] mysql -u root -p1234

Welcome to the MySQL monitor Commands end with or g

Your MySQL connection id is 25 to server version 32354

Type help or h for help Type c to clear the buffer

mysqlgt show databases

+----------+

| Database |

+----------+

| mysql |

| test |

+----------+

2 rows in set (000 sec)

mysqlgt exit

Bye

[rootossc phpMyAdmin]

433 建立資料庫

可利用 mysqladmin指令建立 CONTACT資料庫 mysqladmin -u root -p1234 create CONTACT

47

或是利用 mysql指令 [rootossc bluepage] mysql -u root -p1234 Welcome to the MySQL monitor Commands end with or g Your MySQL connection id is 1057 to server version 32354 Type help or h for help Type c to clear the buffer mysqlgt create database CONTACT Query OK 1 row affected (000 sec) mysqlgt show databases +----------+ | Database | +----------+ | CONTACT | | address | | hello | | mysql | | nuke | | test | +----------+ 6 rows in set (000 sec) mysqlgt exit

434 建立資料表

編寫 adresssql內容如下 -- Table structure for table address CREATE TABLE address ( id int(11) NOT NULL auto_increment name varchar(20) NOT NULL default tel varchar(15) NOT NULL default PRIMARY KEY (id) ) TYPE=MyISAM

48

-- Dumping data for table address INSERT INTO address VALUES (1林小明0800016888) INSERT INTO address VALUES (2黃大雄0800016888) INSERT INTO address VALUES (3劉小芬0800024365) 然後執行此 sql script mysql -u root -p1234 CONTACT lt addresssql 或是利 mysql command [rootossc bluepage] mysql -u root -p1234 Welcome to the MySQL monitor Commands end with or g Your MySQL connection id is 1090 to server version 32354 Type help or h for help Type c to clear the buffer mysqlgt use CONTACT Database changed Database changed mysqlgt CREATE TABLE address ( -gt id int(11) NOT NULL auto_increment -gt name varchar(20) NOT NULL default -gt tel varchar(15) NOT NULL default -gt PRIMARY KEY (id) -gt ) TYPE=MyISAM Query OK 0 rows affected (000 sec) mysqlgt INSERT INTO address VALUES (1林小明0800016888) Query OK 1 row affected (000 sec) mysqlgt INSERT INTO address VALUES (2黃大雄0800016888) Query OK 1 row affected (000 sec) mysqlgt INSERT INTO address VALUES (3劉小芬0800024365) Query OK 1 row affected (000 sec) mysqlgt exit Bye

49

第五章 實用範例

51 任務一Web Base客戶通訊錄

任職於開放科技公司的林小明前些日子在最符合成本效益的條件下快

速地完成公司網站的建置老闆因此對小明讚譽有加最近因為公司存放客戶資

料的 SQL Server主機屢遭病毒攻擊加上作業系統本身的問題當機次數頻繁

老闆希望能儘快把公司的客戶通訊錄程式移轉到較穩定的環境上因為此客戶通

訊錄程式最主要給內部人員使用所以介面美觀並不特別要求只求穩定且能快

速得到查詢結果老闆希望在短時間先看到程式的雛型並鍵入資料對其效率

及穩定性進行測試因為上次小明表現突出所以這次不可能的任務自然又落到

小明身上 小明想來想去既然要快速又穩定他而且又不希望所有人都得安裝 Client

程式於是小明決定)捨棄他的舊愛「Delphi+MS SQL」投向新歡「Apache + MySQL + PHP」利用此架構來設計一個簡單實用的Web Base客戶通訊錄程式

511 Web Base客戶通訊錄架構

此程式需要建立 CONTACT的資料庫並建立 adress Tables其結構如下表建立步驟請參考第三章 欄位名稱 資料型態 長度 說明 id INT (自動編號) 連絡人編號 name varchar文字 20 連絡人姓名 tel Varchar文字 15 連絡人電話 Web Base通訊錄共有下列幾個檔案功能如下表

檔案名稱 說明 Indexhtml Web Base通訊錄首頁 addphp 新增連絡人的 php程式 searchphp 尋找連絡人的 php程式 editphp 具有更新及刪除功能的 php程式

50

我們將這些檔案放至varwwwhtmlbluepage (預設無 bluepage目錄)

512 Web Base通訊錄測試

httpwwwopencombluepage 新增資料

圖 5-1 新增連絡人

圖 5-2 填入資料

51

圖 5-3 新增成功

搜尋及異動資料

圖 5-4 搜尋通訊錄

52

圖 5-5 編輯資料

圖 5-6 更新資料

513 程式內容及說明

lt-- 程式範例indexhtml--gt lthtmlgt ltheadgtlttitlegt通訊錄lttitlegtltheadgt ltbodygt ltcentergt

53

lth2gt通訊錄lth2gtlthrgt lta href=indexhtmlgt通訊錄ltagt | lta href=addphpgt新增連絡人ltagt | lta href=searchphpgt搜尋通訊錄ltagt ltcentergt ltbodygt lthtmlgt lt-- 程式範例addphp --gt lthtmlgt ltheadgtlttitlegt新增連絡人lttitlegtltheadgt ltbodygt ltcentergtlth2gt新增連絡人lth2gtltcentergtlthrgt lt 取得欄位資料 if (isset($_POST[Name]) ampamp isset($_POST[Tel]) ) $name = $_POST[Name] $tel = $_POST[Tel] 檢查是否有輸入欄位資料 if ($name = ampamp $tel = ) 建立 SQL字串 $sql = INSERT INTO address (name tel) values( $sql= $name $tel) 建立 MySQL 連結 $link = mysql_connect(localhostroot1234) 選擇資料庫 mysql_select_db(CONTACT) 執行 SQL指令 mysql_query($sql) mysql_close($link) echo ltfont color=redgt新增連絡人成功ltfontgtltbrgt gt ltform action=addphp method=postgt lttable border=0 width=300gt lttrgtlttdgt姓名 lttdgt

54

lttdgtltinput type=text name=Name size=20 maxlength=10gtlttdgtlttrgt lttrgtlttdgt電話 lttdgt lttdgtltinput type=text name=Tel size=20 maxlength=20gtlttdgtlttrgt lttrgtlttd colspan=2 align=centergt ltinput type=submit value=新增連絡人gtlttdgtlttrgt lttablegt ltformgt ltbrgtlta href=indexhtmlgt通訊錄ltagt | lta href=addphpgt新增連絡人ltagt | lta href=searchphpgt搜尋通訊錄ltagt ltbodygt lthtmlgt

lt-- 程式範例searchphp --gt lthtmlgt ltheadgtlttitlegt搜尋通訊錄lttitlegtltheadgt ltbodygt ltcentergtlth2gt搜尋通訊錄lth2gtlthrgt lt if (isset($_POST[Search])) 建立資料庫連結並選定資料庫 $link = mysql_connect(localhostroot1234) mysql_select_db(CONTACT) 建立基本的 SQL字串 $sql = SELECT FROM address 檢查是否輸入姓名 if (chop($_POST[Name]) = ) $name = name LIKE $_POST[Name] else $name = 檢查是否輸入電話號碼 if (chop($_POST[Tel]) = ) $tel = tel LIKE $_POST[Tel] else $tel =

55

if條件組合 SQL字串 if (chop($name) = ampamp chop($tel) = ) $sql= WHERE $name AND $tel elseif (chop($name) = ) 只有姓名 $sql = WHERE $name elseif (chop($tel) = ) 只有電話號碼 $sql = WHERE $tel $sql= ORDER BY name 最後加上排序 $result = mysql_query($sql) 取得欄位數 $total_fields = mysql_num_fields($result) echo lttable border=1gt echo lttrgtlttdgt編號lttdgtlttdgt姓名lttdgtlttdgt電話lttdgtlttd colspan=2gt功能選項lttdgtlttrgt 表格顯示查詢結果 while ($rows = mysql_fetch_array($result MYSQL_NUM)) echo lttrgt for ($i = 0 $i lt $total_fields $i++) echo lttdgt$rows[$i]lttdgt echo lttdgtlta href=editphpaction=editampid= echo $rows[0]gtltbgt編輯ltbgtlttdgt echo lttdgtlta href=editphpaction=delampid= echo $rows[0]gtltbgt刪除ltbgtlttdgt echo lttrgt echo lttablegtlthrgt mysql_free_result($result) mysql_close($link) gt ltcentergt ltform action=searchphp method=postgt lttable border=0 width=450gt lttrgtlttdgt搜尋姓名 lttdgt lttdgtltinput type=text name=Name size=10 maxlength=20gtlttdgtlttrgt lttrgtlttdgt搜尋電話 lttdgt lttdgtltinput type=text name=Tel

56

size=20 maxlength=20gtlttdgtlttrgt lttrgtlttd colspan=2 align=centergt ltinput type=submit name=Search value=搜尋gtlttdgtlttrgt lttablegt ltformgt ltbrgtlta href=indexhtmlgt通訊錄ltagt | lta href=addphpgt新增連絡人ltagt | lta href=searchphpgt搜尋通訊錄ltagt ltbodygt lthtmlgt

lt ob_start() gt lt-- 程式範例editphp --gt lthtmlgt ltheadgtlttitlegt編輯通訊錄lttitlegtltheadgt ltbodygt lt 取得 URL 參數 $id = $_GET[id] $action = $_GET[action] 建立資料庫連結 $link = mysql_connect(localhostroot1234) mysql_select_db(CONTACT) 選擇資料庫 執行的操作 switch ($action) case update 更新 取得欄位資料 $name = $_POST[Name] $tel = $_POST[Tel] $sql = UPDATE address SET name=$name tel=$tel WHERE id=$id mysql_query($sql) 執行 SQL指令 mysql_close($link) header(Location searchphp) 轉向到 serachphp break case del 刪除 $sql = DELETE FROM address WHERE id=$id

57

mysql_query($sql) 執行 SQL指令 mysql_close($link) header(Location searchphp) 轉向到 serachphp break case edit 編輯 $sql = SELECT FROM address WHERE id=$id $result = mysql_query($sql) 執行 SQL指令 $row = mysql_fetch_row($result) 取回記錄 $name = $row[1] 取得欄位 name $tel = $row[2] 取得欄位 tel mysql_close($link) 顯示編輯表單 gt ltcentergtlth2gt更新通訊錄lth2gtltcentergtlthrgt ltform action=editphpaction=updateampid=lt echo $id gt method=postgt lttable border=0 width=300gt lttrgtlttdgt姓名 lttdgt lttdgtltinput type=text name=Name size=20 maxlength=10 value=lt echo $name gtgtlttdgtlttrgt lttrgtlttdgt電話 lttdgt lttdgtltinput type=text name=Tel size=20 maxlength=20 value=lt echo $tel gtgtlttdgtlttrgt lttrgtlttd colspan=2 align=centergt ltinput type=submit value=更新連絡人gtlttdgtlttrgt lttablegt ltformgt ltbrgtlta href=indexhtmlgt通訊錄ltagt | lta href=addphpgt新增連絡人ltagt | lta href=searchphpgt搜尋通訊錄ltagt lt break gt ltbodygt lthtmlgt

58

52 任務二Web Base群組軟體 ( twig )

順利完成Web Base客戶通訊錄程式測試一段時間後「Apache + MySQL + PHP」架構的穩定與快速巳深得老闆與公司所有同事的認同隨著公司業績蒸

蒸日上人員組織編罝愈來愈龐大跨部門的會議愈來愈多業務員每日排滿拜

訪客戶的行程跟客戶的 Email的往來也愈來愈頻繁 愈來愈多部門的同事希望公司能建置一套群組軟體提供 web mail可讓業

務人員方便收發 mail還有連絡人議事日程待辦工作書簽等功能讓整個

公司運作及個人時間管理更有效率

老闆問小明對這些需求有什麼看法小明認為如果這些功能完全由程式部

門開發必定曠日費時而且耗費公司資源小明在網路尋找是否有提供這些功能

的Free Software皇天不負苦心人小明發現了TWIG (The Web Information Gateway) httptwigscrewdrivernet這個群組軟體它在 Web 上整合郵件新聞聯絡人議事日程工作序書簽等功能非常符合公司的需求 Step 1 下載 twig-277targz 下載網址 httptwigscrewdrivernetdownloadphp3

Step 2 解開 twig-277targz tar -xzvf twig-277targz

59

Step 3 執行安裝動作安裝到 varwwwhtmltwig 目錄 cd twig-277 twig-install varwwwhtmltwig

Step 4 建立 MySQL 資料庫(twig)及各資料表

cd setup mysql -u root -p1234 mysqlgt create database twig Query OK 1 row affected (001 sec) mysqlgt quit mysql -u root ndashp1234 twiglt twigtablemysql

Step 5 修改 configincphp3 參數設定 vi varwwwhtmltwigconfigconfigincphp3 $config[fromdomain] = opencom 網域 $config[language] = chinesebig5 中文訊息 $config[imap_port] = 143notls

60

Step 6 修改連結 MySQL 的帳號密碼 vi varwwwhtmltwigconfigdbconfigincphp3 $dbconfig[sqlusername] = root username $dbconfig[sqlpassword] = 1234 password

Step 7 其他設定檔

vi etchttpdconfhttpdconf 加入 AddType applicationx-httpd-php php3 在 DirectoryIndex最後加入 indexphp3 DirectoryIndex indexhtml indexhtmlvar indexphp3 在 AddDefaultCharset ISO-8859-1加上 AddDefaultCharset ISO-8859-1

vi etcphpini register_globals = On service httpd restart Step 8 sendmail 設定 vi etcmailsendmailcf在 264 行前面加上並重新啟動 sendmail「service snedmail restart」 262 SMTP daemon options 263 264 O DaemonPortOptions=Port=smtpAddr=127001 Name=MTA 265 266 SMTP client options 267 O ClientPortOptions=Family=inet Address=00

61

Step 9 檢查設定有無錯誤 http主機名稱twigtestphp3

62

Step 10 登入 twig ( http主機名稱twig)

63

第六章 維護及更新程序

61 日常維護

系統管理員最好定期以 root 身份登入看看信件在 RedHat Linux 中有一支 logwatch 程式會定時去分析 log file如果發現異常便會發信給 root除此之外筆者建議讀者平時就檢查 MySQL log file ( varlogmysqldlog)是否有異常情形

62 更新程序

讀者可至httprpmfindnet 尋找MySQL相關套件至於升級的相關步驟請參

考Linux OS SOP 第 54節

63 備份重要檔案

預設 MySQL 的 DB 檔案是存在 varlibmysql 內以 DB名稱為目錄目錄

內就是該 DB 的所有資料通常得定期備份還有 MySQL的設定檔 etcmycnf也別忘了一起備份

64 離線備份與還原

641 離線備份

預設 MySQL 的 DB 檔案是存在 varlibmysql 內以 DB 名稱為目錄目錄內

就是該 DB 的所有資料像 CRM 這個 DB就是存在 varlibmysqlCRM 內在備份前因為怕資料尚未完全寫入磁碟而且 MySQL 會 Lock 在使用的 DB 檔案所以應該是要先把 MySQL 先 Shutdown 一下整個備份的程序可以下像下面的指令去完成 cd varlibmysql

64

service mysqld stop tar cvfz CRM_db_20030905tgz CRM service mysqld start 對這樣就可以了 不過要注意的是怕 DB 內每個 Tables 間的資料有關關

聯性所以最好是把整個 DB 一次備起來單獨只備哪個 Tables 的檔案以後回存時怕會有資料關聯不一致的問題

642 離線還原

DB 發生錯誤而要回存時其實也不難先找出最近一次完整正常的備份先把現在錯誤的網頁或 DB 先更名或 tar 起來再把好的備份給解開回原來目錄位

置就行了需要注意的是 MySQL 服務最好也是要先停止回存完成後再啟動服務回存 DB 的整個程序可能像下面 cd varlibmysql service mysqldstop mv CRM CRM_OLD tar xvfz CRM_db_20030905tg service mysqld start

65 線上備份與還原

651 線上備份

使用像上面的檔案方式備份是個不錯的方法它最少可以保持該主機某個時間點的完整檔案備份但還是有一些問題需要考慮到有些主機就不只建立一個 DB 而已總不能為了備份某個 DB 而把整個 MySQL 服務停止備份檔案的方式回存在原主機上一定適用但假如 MySQL 版本升級或是在那天該網頁空間需遷機移機到別的主機時那就沒人敢保證備出來的資料檔可以用所以我們可以考慮另一種備份的方式是使用 MySQL 本身提供的功能 MySQL Data Dump指令是 mysqldump

65

使用 MySQL 的 Dump 功能可以把 DB 的結構資料或結構加資料 Dump 成文字檔 mysqldump 指令提供的彈性很大你可以選擇把整個 DB Dump 成一個檔或是每個 Table 為一個檔甚至是把結構檔和資料分開儲存都

可以 mysqladmin -uroot -p flush-logs mysqldump CRM -uroot -p --opt gt CRM_20030905sql (CRM 是 DB 名稱 opt 是一個使用完整 Dump 參數) 假如只是要單獨 Dump 某個 Table 時只要在上面的指令後轉出符號 gt 前加個 Table 名稱就可以如只要 phpbb2_users 這個 Table 的 Dump 時只要下 mysqldump CRM -uroot -p --opt CUSTOMER gt CRM_CUSTOMER_20030905sql

652 線上還原

若要回存整個資料庫只需將壓縮的備份檔還原成 Dump 的檔案再用下面的指令回存 mysql CRM -uroot -p lt CRM_20030905sql 這邊需注意的是若建立備份時是以--opt或--add-drop-table為參數時回存的 動作是先將舊的 Table 先刪除重建 Table 的結構後再把 Data 匯入所以回存後所有的資料會回到你當時備份那個時間點因此在回存資料時可以考慮把現有錯誤或不完整的 DB 先備份一份下來以備不時之需或是拿來比對錯誤的地

方在那裡當然你也可以把資料回存到另一個測試用的 DB 內只要把上面指令

的 DB 名稱改成你的測試用 DB 名稱即可 使用這種回存方式 MySQL 服務不需停止也不會動到其他正在使用的 DB 在一些提供 MySQL 服務的虛擬主機可用這種方式作你自己的 DB 備份及回存

66

另外假如你是系統重建或是移機時切需在新的 MySQL 內新建一個空白 DB 後才行作回存的工作你可以用下面的指令建立 mysql -uroot -p -e CREATE DATABASE CRM (上面的 CRM是你要新建的 DB 名稱) 另一種作法先用 mysql 指令進入 mysql client console 然後再用 CREATE DATABASE CRM 這樣就行了記得尾端要加個 符號該行指令才會執行

67

第七章 問題與解答

Q1RedHat 90預附的 MySQL到底有無支援 Transcation機制 Ans MySQL自 32334a之後的 MySQL-Max版本加入 InnoDB的資料庫類型透過

InnoDBMySQL同樣可以進行 COMMIT與 ROLLRACK的動作RedHat 90預附的 MySQL為 32354a-11巳支援 InnoDB的資料庫類型不過必須做以

下設定 1cp usrsharedocmysql-server-32354amy-mediumcnf to etcmycnf 2 vi etcmycnf 將以下設定前的拿掉 innodb_data_home_dir = varlibmysql innodb_data_file_path = ibdata110Mautoextend innodb_log_group_home_dir = varlibmysql innodb_log_arch_dir = varlibmysql 3service mysqld restart 如此一來各位在建立Table時便可指定Table Type為 innodb ( ex create table with type=innodb ) Q2如何解決 php+mysql 許功蓋等字變亂的問題 Ans 方法一 【確定 MySQL 預設的字元集】 1 打開 WinMySQLadmin 管理畫面(在視窗右下角狀態列紅綠燈圖示中按滑鼠

右鍵點選 Show me 選項) 2 點選管理畫面中 [Variables] 標籤選項其中 character_set變數就是您預設

字元集的變數其預設是 latin1 字元集(我們要將他改回 big5)而 chatacters_set 變數則是 MySQL 可以支援哪些字元集 【修改預設字元集變數 character_set 】 1 請點選管理畫面中 [myini Setup] 標籤選項設定 myini 2 按一下 [Pick-up and Edit myini values] 按鈕以便編輯目前的 myini 設定 3 在 [mysqld] 設定區塊底下新增一行 default-character-set = big5 變數設

68

定 4 新增一個 [client] 設定區塊並加入第三步驟的變數設定(游標往下移到空白處新增兩行 [client] 和 default-character-set=big5) 5 按一下畫面左下方 [Save Modification] 按鈕儲存設定 6 重新啟動 MySQL 或 Windows 方法二 Server端注意事項 phpini 中有關的設定為(預設值) Magic quotes for incoming GETPOSTCookie data magic_quotes_gpc = On Use Sybase-style magic quotes (escape with instead of ) magic_quotes_sybase = Off Client端注意事項 1中文資料送進 mysql 前請用 addslashes($str) 處理 2處理後送進 mysql 時請用 括起來並在參數後留一個空白如 $sql = UPDATE ezf_table set tablename=$tname tableend=$endtime table inguser=$tguser tableingid=$tguserid tableallnumber=$tnumber tableloca l=$tablelocal tableanyone=$tableopen tabletext=$ttext WHERE tableid=$t ableid tablename=$tname c 取出時請用 stripslashes($str) Q3MySQL root 密碼忘了該怎麼辦 Ans 1先停掉 mysql etcrcdinitdmysql stop 2以--skip-grant-table 的參數啟動 mysql safe_mysql --skip-grant-tableamp 3 更改 root 密碼 mysql mysql mysqlgt UPDATE user SET password=password(newpassword)

69

WHERE user=root mysqlgt FLUSH PRIVILEGES mysqlgt exit 4停掉 mysql再重跑 mysqladmin -uroot -p shutdown Enter password 輸入新設定的密碼 etcrcdinitdmysql start

Q4NULL值問題

Ans

NULL值的概念是造成 SQL的新手的混淆的普遍原因他們經常認為 NULL是和一個空字符串的一樣的東西不是這樣的例如下列語句是完全不同的

mysqlgt INSERT INTO my_table (phone) VALUES (NULL)

mysqlgt INSERT INTO my_table (phone) VALUES ()

兩個語句把值插入到 phone 列但是第一個插入一個 NULL值而第二個插入一個空字符串第一個的含義可以認為是ldquo電話號碼不知道而第二個則可意味

著ldquo她沒有電話

在 SQL中NULL值在于任何其他值甚至 NULL值比較時總是假的(FALSE)包含 NULL的一個表達式總是產生一個 NULL值除非在包含在表達式中的運算符和函數的文檔中指出在下列例子所有的列返回 NULL

mysqlgt SELECT NULL1+NULLCONCAT(InvisibleNULL)

如果你想要尋找值是 NULL的列你不能使用=NULL測試下列語句不返回任

何行因為對任何表達式expr = NULL是假的

mysqlgt SELECT FROM my_table WHERE phone = NULL

要想尋找 NULL值你必須使用 IS NULL測試下例顯示如何找出 NULL電話號碼和空的電話號碼

70

mysqlgt SELECT FROM my_table WHERE phone IS NULL mysqlgt SELECT FROM my_table WHERE phone =

在 MySQL中就像很多其他的 SQL服務器一樣你不能索引可以有 NULL值的列你必須聲明這樣的列為 NOT NULL而且你不能插入 NULL到索引的

列中

當用 LOAD DATA INFILE 讀取數據時空列用更新如果你想要在一個列中有

NULL值你應該在文本文件中使用N字面上的詞NULL也可以在某些情形下使用

當使用 ORDER BY時首先呈現 NULL值如果你用 DESC以降序排序NULL值最後顯示當使用 GROUP BY時所有的 NULL值被認為是相等的

為了有助于NULL的處理你能使用 IS NULL和 IS NOT NULL運算符和 IFNULL()函數

對某些列類型NULL值被特殊地處理如果你將 NULL插入表的第一個TIMESTAMP 列則插入當前的日期和時間如果你將 NULL插入一個AUTO_INCREMENT 列則插入順序中的下一個數字

Q5如何將圖片存放於 MySQL中

Ans

Step 1建立資料庫 test

Step 2 建立表格 binary_data

CREATE TABLE binary_data (

id INT(4) NOT NULL AUTO_INCREMENT PRIMARY KEY

description CHAR(50)

bin_data LONGBLOB

filename CHAR(50)

filesize CHAR(50)

filetype CHAR(50)

71

)

Step 3 利用 storephp 寫入圖片

storephp 程式碼

ltHTMLgt ltHEADgtltTITLEgtStore binary data into SQL DatabaseltTITLEgtltHEADgt ltBODYgt lt code that will be executed if the form has been submitted

if ($submit) mysql_connect(localhostrootYOUR_PASSWORD) mysql_select_db(test) $data=Base64_Encode(fread(fopen($form_data r) filesize($form_data))) $result=MYSQL_QUERY(INSERT INTO binary_data (descriptionbin_datafilenamefilesizefiletype) VALUES ($form_description$data$form_data_name$form_data_size$form_data_type)) $id= mysql_insert_id() print ltpgtThis file has the following Database ID ltbgt$idltbgt MYSQL_CLOSE() else else show the form to submit new data

gt

ltform method=post action=ltphp echo $PHP_SELF gt enctype=multipartform-datagt File Descriptionltbrgt ltinput type=text name=form_description size=40gt ltINPUT TYPE=hidden name=MAX_FILE_SIZE value=4000000gt ltbrgtFile to uploadstore in databaseltbrgt ltinput type=file name=form_data size=40gt ltpgtltinput type=submit name=submit value=submitgt ltformgt lt

72

gt ltBODYgt ltHTMLgt

Step 3 利用 storephp 取出圖片

getdataphp 程式碼

lt Syntax getdataphp3id=ltidgt if($id) you may have to modify login information for your database server MYSQL_CONNECT(localhostrootYOUR_PASSWORD) mysql_select_db(test) $query = select bin_datafiletype from binary_data where id=$id $result = MYSQL_QUERY($query) $data = Base64_Decode(MYSQL_RESULT($result0bin_data)) $type = MYSQL_RESULT($result0filetype) Header( Content-type $type) echo $data gt

Q6MySQL裝好之後啟動時或是執行 mysqladmin會出現如下訊息 Cant connect to local MYSQL Server through Socket varlibmysqlmysqlsock或是

Cant connect to local MYSQL Server through Socket tmpmysqldsock

Ans 可能有下列幾個原因

1這個 mysqldsock 不見了被某人刪除了或是被一些系統自動執行程式給刪

了例如有些 cron任務便會設定定期刪除 tmp 裡的東西所以呢您只能修改

cron 裡的設定讓它不要清除 mysqldsock 2在啟動時也可以改變 mysqldsock的位置您在啟動 MySQL的時候可以加入此參數usrlocalmysqlbinsafe_mysqld --user=mysql --socket=其他路

徑socket amp 同時得去設定環境變數 MYSQL_UNIX_PORT的值以指定新的

73

路徑 3若是您沒改 MYSQL_UNIX_PORT的值那麼您可以在執行指令的時候才打

例如mysqladmin --socket=其他路徑socket version Q7How to get the last insert id Ans CREATE TABLE product ( id INT(4) NOT NULL AUTO_INCREMENT PRIMARY KEY description VARCHAR(50) ) 1利用 SQL的話 mysqlgt insert into product(description) values(123) Query OK 1 row affected (000 sec) mysqlgt select last_insert_id() +------------------+ | last_insert_id() | +------------------+ +------------------+ 1 row in set (000 sec) ======================================== 2如果是 PHP的話 你可以用mysql_insert_id()取得該 id PHP example $result=MYSQL_QUERY(INSERT INTO product (description) VALUES ($description)) $id= mysql_insert_id() print This file has the following Database ID $id Q8如何將文字檔匯入資料庫 Ans $addr=homehttpdhtmlphpschool001txt $sql_select = load data infile $addr into table test fields terminated by t 解說 $sql_select = load data infile 文字檔名 into table 表格名 fields terminated by

74

t

(欄位分隔以 TAB鍵) 該文字檔須與資料表欄位格式相符 例如欄位有三個 則文字檔為每行一筆資料如下 欄 1資料ltTABgt欄 2資料ltTABgt欄 3資料 欄 1資料ltTABgt欄 2資料ltTABgt欄 3資料 欄 1資料ltTABgt欄 2資料ltTABgt欄 3資料 欄 1資料ltTABgtltTABgt欄 3資料

Q9如何撰寫 MySQL C API Ans Step 1利用文字編輯器撰寫以下程式碼 mysqlcc

include ltstdiohgt

include ltmysqlmysqlhgt

int main (int argc char argv[])

MYSQL mysql

MYSQL_RES res

MYSQL_ROW row

if (argc = 2)

fputs (Usage myc ltdatabasegt stderr)

return 1

if ((mysql_connect(ampmysqllocalhostrootYour_Password)))

fputs (Error connecting stderr)

abort()

75

if (mysql_select_db(ampmysqlargv[1]))

fputs (Error selecting database stderr)

abort()

if (mysql_query(ampmysqlSELECT FROM test_table))

fputs (Error processing query stderr)

abort()

if ((res = mysql_store_result(ampmysql)))

fputs (Error storing results stderr)

abort()

while((row = mysql_fetch_row(res)))

uint i = 0

for (i=0 i lt mysql_num_fields(res) i++)

printf(s row[i])

printf(n)

return 0

Step 2 Compile

gcc -Iusrlocalmysqlinclude -Lusrlocalmysqllibmysql mysqlcc ndashlm -lmysqlclient

(其中 include path與 library path取決於你的 MySQL安裝路徑)

76

如果執行時發生如下 error Run problemerror in loading shared libraries libmysqlclientsoX 將你的 MySQL library path(for exampleusrlocalmysqllibmysql) 加入etcldsoconf and run sbinldconfig -v Q9ASP + MySQL 範例程式 Ans Dim myconn As New ADODBConnection Dim myrs As New Recordset Dim mySQL As String Dim myrows As Long myconnOpen DSN=MyODBCsample mySQL = SELECT from user myrsSource = mySQL Set myrsActiveConnection = myconn myrsCursorLocation = adUseClient myrsOpen myrows = myrsRecordCount myrsClose myconnClose 可參考 httpwwwdwamnetmysqlasp_myodbcasp 有詳細的資料 Q10如何將 MySQL中的資料庫匯出成txt檔 Ans select from TableName into outfile textxls all result fields will seperate by tab

77

第八章 參考資料

英文部份 網址 1 httpwwwmysqlcom MySQL 網站有第一手有關 MySQL的資料 2 httpwwwmysqlcomdocenReplicationhtml 有關 MySQL Replication 的文件 3 httpwwwgeocitiescomsqlhomefaqstore_blobhtml 如何在 MySQL 存放 BLOB的資料 4httpwwwsapdborg 有關 SAP跟 MySQL相關合作的網站 書藉 1 Cooking with MySQL

Paul DuBois has selected sample recipes from the hundreds youll find in his book MySQL

Cookbook In this third and final series of excerpts showcasing these recipes learn how to

compute team standings how to calculate the differences between successive Dec 26

2002 2 Tips for Building Web Database Applications with PHP and MySQL by Hugh E Williams co-author of Web Database Applications with PHP amp MySQL 04042002

3 Managing and Using MySQL 2nd Edition By Tim King George Reese Randy Jay Yarger

4 MySQL Cookbook By Paul DuBoisPublisher OReillyPub Date October 2002

中文部份

78

1 httplinuxtncedutwtechdocmysqlmysql_docmanual_tochtml MySQL 中文手冊 2 httpchenshloxaedutwphpZ_1php PHP+MySQ程式研習設計網站 3 httplinuxtncedutwtechdocbanicdownhtml PHP 4 手冊 4 httpwwwtncedutwadmin_zonephp台南縣教育網網路中心有很多 Linux相關文件 5 httpdobtncedutw網站建置百寶箱有很多 PHP MySQL 相關範例程式 5 httpwwwdbworldcomtw資料庫專家電子雜誌介紹資料庫的重要觀念及名詞

79

附錄一 SQL Command 介紹

SQL (讀音ess-que-el) 是一種結構查詢語法SQL 使用於資料庫交流

傳遞相容於 ANSI (American National Standards Institute) 是一套標準的關聯

式資料庫語言 SQL 語言是執行更新或從資料系統獲取資料一般常見的關聯

資料庫系統都有提供 SQL 如 Oracle Sybase Microsoft SQL Server Access Ingres 等雖然大部份的資料庫都有提供 SQL 但也多提供了自已獨特的語

法造成了不相容的情形但標準基本的語法是相通的如Select Insert Update Delete Create and Drop 每一個系統都有支援

Table相關 Command

Create Table

關聯式資料庫包含有很多元件稱為資料表(tables) 把資料或訊息放在資

料表中 資料表是以不同的名稱做分別資料表由欄列所構成的二維陣列

欄包含欄位名資料型態 及其他可判斷的資訊列是由全部欄位構成一筆一

筆的紀錄 create table 語法用在建立一個新的資料表語法格式如下

create table tablename (column1 data type column2 data type column3 data type)

Format of create table if you were to use optional constraints

create table tablename (column1 data type [constraint] column2 data type [constraint] column3 data type [constraint]) [ ] = optional

Note You may have as many columns as youd like and the constraints are optional

80

Example

create table employee (first varchar(15) last varchar(20) age number(3) address varchar(30) city varchar(20) state varchar(20))

注意建立資料表格式要以括號把前後框住而最後以(分號)做結尾

欄位名不要超過 30個字元長而且不要使用 sql 的關鍵字(如 where select等)而在後面接是型態的宣告(如字串數字日期格式等)

資料型態是來描述欄位的方式如一個欄位Last_Name 是一個姓氏可以使用varchar (可變動長度字串) 資料型態

以下是幾個常見的資料庫型態 char(size) 固定長度字串最長為 255 位元 varchar(size) 變動長度字串最大字元數以 size 來指定 number(size) 數值格式可以是整數也可以是小數最大數字以 size 位數判

斷未指定小數位數由系統內定 date 日期格式 number(sized) 數值格式最大數字以 size 位數判斷d 為小數位數整數位

數為 size-d 位

有何限制當資料表被建立通常有一或數個欄位是要使用來做關聯的功

能 例如unique 限制(唯一值)兩筆記錄不可以相同的值 not null (非空值)該欄位一定要輸入資料不可是空的primary key (主鍵)是每一筆記錄識別的主要方式

Drop a table drop table 刪除資料表(其中的資料也會一併刪除)

drop table tablename

Example

81

drop table 和刪除全部資料是不同的刪除全部資料欄位名稱資訊等還會

存在但刪除資料表會把這一些也一併移除掉

如何查詢資料

Select 基本用法

select 語法是關連式資料庫最常用的部份可以取得你想要的資料這是一個

簡單的範例 select column1[column2etc] from tablename [where condition] [] = optional 在 select 之後所列欄位名則是要顯示的資料部份你可以一一列出各欄位

名或是以 (星號)來代表選擇全部的欄位 from 之後放資料表名稱 where 子句 (選項) 指定要過濾的條件符合者才會顯現 where 可使用的條件運算元 = 等於 gt 大於 lt 小於 gt= 大或等於 lt= 小或等於 ltgt 大相等 LIKE 相似 For example select first last city

82

from empinfo where first LIKE Er 以Er 為開頭的字串就符合要以單引號框住 Or you can specify select first last from empinfo where last LIKE s 最後一字為 S 就符合 select from empinfo where first = Eric 則表示 first name 一定要是 Eric 才可以 範例資料表empinfo 統計函數

MIN 傳回指定欄位最小值

MAX 傳回指定欄位最大值

SUM 傳回指定欄位總和

AVG 傳回指定欄位平均值

COUNT 傳回指定欄位的筆數

COUNT() 傳回資料庫中的總筆數

統計函數使用於資料表中的數值欄位配合 SELECT 語法使用 只用於總結特定單一欄位可以配合 GROUP BY 做篩選但也可以不使用 GROUP BY 語句For example

SELECT AVG(salary) FROM employee

83

傳回全部 salary 平均值

Another example

SELECT AVG(salary) FROM employee WHERE title = Programmer

傳回 salary 平均值條件為 employees 資料表中當 title 等於 Programmer

Example

SELECT Count() FROM employees

傳回 employees 資料表中紀錄總筆數

GROUP BY 語法 SELECT column1 SUM(column2) FROM list-of-tables GROUP BY column-list The GROUP BY 語句可以先以所列的欄位為條件分組排序在一起(可以多欄

位) example 要列出每一個 dept 中最高 salary 值 SELECT max(salary) dept FROM employee GROUP BY dept HAVING 語法

SELECT column1 SUM(column2) FROM list-of-tables GROUP BY column-list HAVING condition

HAVING 子句是 GROUP BY 的一部份用來過濾在 GROUP BY 所選出的資料功能如同 select 命令中 where 條件式一樣只是 HAVING 必需配合 GROUP BY 使用

我們以例子來說明我們要取得每一公司名及每一公司的薪水平均值輸入如下

84

SELECT dept avg(salary) FROM employee GROUP BY dept

但如果我們只列出薪資平均值超過 20000元的公司資料

SELECT dept avg(salary) FROM employee GROUP BY dept HAVING avg(salary) gt 20000

ORDER BY子句語法

SELECT column1 SUM(column2) FROM list-of-tables ORDER BY column-list [ASC | DESC]

[ ] =選項

ORDER BY是一個選項子句當你以排序方式來顯示資料(正向由小到大反向由大到小)以指定的欄位資料做排序

ASC = 正向- 預設值 DESC = 反向排序

For example

SELECT employee_id dept name age salary FROM employee_info WHERE dept = Sales ORDER BY salary

以上列出公司代號公司名銷售員人名年紀及薪資而條件是公司名為 Sales 顯示順序以薪資多少排序(由小到大為預設值)

如果要以多個欄位做排序要以逗號做分隔如下

SELECT employee_id dept name age salary FROM employee_info WHERE dept = Sales ORDER BY salary age DESC

85

結合條件及布林運算 SELECT column1 SUM(column2) FROM list-of-tables WHERE condition1 AND condition2 AND運算可以結兩個或以上的條件放在 WHERE子句中 兩者都要為真才

會顯示該筆記錄 OR 運算可以結兩個或以上敘述放在 WHERE子句中只要其中一個為直就

會顯示該筆記錄 For example SELECT employeeid firstname lastname title salary FROM employee_info WHERE salary gt= 5000000 AND title = Programmer 必需要薪資大於等於 50000而且職稱為 Programmer同時符合才會顯示該筆資料 以下以括號括住雖然不是必需的但如此比較容易讀 SELECT employeeid firstname lastname title salary FROM employee_info WHERE (salary gt= 5000000) AND (title = Programmer) 另外範例 SELECT firstname lastname title salary FROM employee_info WHERE (title = Sales) OR (title = Programmer) 條件為只要是 Sales 或 Programmer 職稱的就會被列出 IN and BETWEEN 子句

SELECT column1 SUM(column2) FROM list-of-tables WHERE column3 IN (list-of-values) SELECT column1 SUM(column2) FROM list-of-tables WHERE column3 BETWEEN value1 AND value2 IN 子句使用在列舉項目的使用上也就是分別測試是否符合所列的值 For example

86

SELECT employeeid lastname salary FROM employee_info WHERE lastname IN (Hernandez Jones Roberts Ruiz) 條件為姓氏(astname)要符合 Hernandez Jones Roberts or Ruiz 其中一個才會被傳回 IN運算元也可以使用 OR 的語法來取代如下結果相同 SELECT employeeid lastname salary FROM employee_info WHERE lastname = Hernandez OR lastname = Jones OR lastname = Roberts OR lastname = Ruiz 但使用 IN 句子比較短也比較易懂 你也可以使用 NOT IN 來去掉不要的記錄 BETWEEN 運算元使用在判斷是否存在兩個數值之間 For example SELECT employeeid age lastname salary FROM employee_info WHERE age BETWEEN 30 AND 40 傳回年紀 30歲到 40歲之間的資料(含 30及 40歲者) 相同的也可以使用以下語法來達到相同的結果 SELECT employeeid age lastname salary FROM employee_info WHERE age gt= 30 AND age lt= 40 你也可使用 NOT BETWEEN 來濾掉中間值的資料 數學運算 標準 ANSI SQL-92 提供以下運算

87

+ 加

- 減

餘數

餘數為除法後剩整數這不在標準的 ANSI SQL 中但大部份的資料庫都會支

援這運算元以下列出有用的函數雖不在 ANSI SQL-92 提供但一般資料庫

也會支援他們

ABS(x) 傳回 x 絕對值

SIGN(x) returns the sign of input x as -1 0 or 1 (negative zero or positive respectively)

MOD(xy) 餘數 - returns the integer remainder of x divided by y (同 xy)

FLOOR(x) 傳回小或等於 x 的最大整數值

CEILING(x) or CEIL(x)

傳回大或等於 x 的最小整數值

POWER(xy) x的 y 次方

ROUND(x) 把 x 四捨五入為整數

ROUND(xd) 四捨五入取到小數 d 位

SQRT(x) x 開平方

For example SELECT round(salary) firstname FROM employee_info 傳回薪資取到整數位

如何新增資料

insert 加入一筆新紀錄到資料表中 insert into tablename (first_columnlast_column) values (first_valuelast_value) [] = optional Example insert into employee

88

(first last age address city state) values (Luke Duke 45 2130 Boars Nest Hazard Co Georgia) Note 字串要以單引號住如string 數字框住也無妨 insert into 後面接資料表名稱再接以括號括住的欄位名在 values 後括號分別對映各欄位的值 以上的例子新增了一筆名(first) 為 Luke而住所(state) 為 Georgia 的資料

如何刪除資料

delete 可以刪除單筆或多筆紀錄 delete from tablename where columnname OPERATOR value [and|or column OPERATOR value] [ ] = optional Examples delete from employee Note 如果你沒有指定 where 子句那麼全部的紀錄都會被刪除 delete from employee where lastname = May delete from employee where firstname = Mike or firstname = Eric delete from 接著資料表名 再接著是條件式判斷沒有條件式則全部紀錄會

被刪除

如何更新資料

update 用來更新你所指定的記錄要和 WHERE 配合小心使用 語法 update tablename set columnname = newvalue[nextcolumn = newvalue2] where columnname OPERATOR value [and|or column OPERATOR value] [] = optional Examples

89

update phone_book set area_code = 623 where prefix = 979 update phone_book set last_name = Smith prefix=555 suffix=9292 where last_name = Jones update employee set age = age+1 where first_name=Mary and last_name=Williams

90

附錄二Replication

測試環境

RedHat 90 + MySQL 32358 MySQL資料庫路徑 varlibmysql MySQL設定檔 etcmycnf Master IP 1921680100 Slave IP 1921680200 請至下列網址下載最新MySQL 32358套件並利用rpm ndashUvh 更新 httpupdatesredhatcom9enosi386

圖 最新 MySQL 套件

測試架構圖

91

1921680100

1921680200Master Server

erveSlave S r

圖 測試架構圖

測試步驟

Master server 部份 Step1 確認 MasterSlave機器上所裝的 MySQL版本能進行

replication( 32329 or higher ) Step2 在 Master MySQL上開放一個帳號給 Slave mysql ndashu root ndashp mysqlgtGRANT FILE ON TO repl1921680200 IDENTIFIED BY lsquoabc123rsquo mysqlgtq 上面是 Master開放一個帳號 repl密碼 abc123給 IP1921680200有檔案處理

的權限 Step3 shutdown MySQL on the Master mysqladmin ndashu root ndashp shutdown Step4 備份 Master所有資料庫 tar ndashcvf tmpmysql-snapshottar varlibmysql 注意tar的時候MySQL是要在 stop情況下 在mysql (wwwmysqlcom) 網站的FAQ有不用shutdown的方法

92

Step5 在 master機器上修改etcmycnf 在[mysqld]區段內加入參數 log-bin server-id=這邊設定 server-id=1 sql-bin-update-same binlog-do-db=CRM只針對 CRM資料庫做紀錄 Step6 Restart MySQL on the master service mysqld start 此時因為有加入 log-bin 參數因此開始有 index產生了在varlibmysql目錄下

有index檔案紀錄資料庫的異動 log Slave server 部份 Step1 在 slave設定etcmycnf 在[mysqld]區段加入 master-host= master-user= master-password= master-port= server-id= 這邊設定 master-host=1921680100 master-user=repl master-password=abc123 master-port=3306 server-id=2 master-connect-retry=60預設重試間隔 60秒 replicate-do-db=CRM告訴 slave只做 CRM資料庫的更新 log-slave-updates Step2 將 master上的 mysql-snapshottar copy到 slave上 用 ftp傳到 slave的tmp Step3 解壓縮 Master資料庫至 Slave Server上 cd varlib tar xvf tmpmysql-snapshottar chown ndashR mysqlmysql mysql

93

chmod ndashR 770 mysql (視情況) Step4 Restart MySQL on the slave server 這時在varlibmysql目錄會出現 masterinfo此檔案紀錄了 Master MySQL server的資訊

狀況測試

One-way replication

1921680100

1921680200Master Server

erveSlave S r

圖 One-way replication架構圖 Step1 Master跟 Slave網路及服務都正常情況下由 Master端異動資料後 到 Slave端瀏覽資料檢視是否有進行 replication Step2 模擬 Slave Server 當機 可用在於 slave真的當機或是 Slave 不一定需要一直跟 master connect將Slave MySQL server shutdown由 Master端異動資料到 slave端瀏覽此時Slave應該沒有被 replication 更新然後再將 Slave端 MySQL server start起來

預設 60秒後 Slave會嘗試跟 Master要求進行 replication再去 Slave端檢視是否有更新資料

94

Step3 模擬 Master當機因為是設定 One-way replication一旦 Master Server Slave端沒有 Master的 source可以 download Two-way replication 基於 Master當機狀況於是發展雙向 Replication即 1921680100 ( Host A ) 1921680200 ( Host B )都分別擔任 MasterSlave身分

1921680100

1921680200er

Server B MasterSlave Server

Server A MasterSlave Serv

圖 Two-way replication架構圖 以下是針對兩台 MySQL伺服器進行雙向 Replication Step1觀念同單向 replication只是改成 Master也有 Slave身分 Slave也有Master的身分先分別在 Server AServer B 都去 grant一個進行 replication的身分 [A]mysqlgtGRANT FILE ON TO repl1921680200 IDENTIFIED BY lsquoabc123rsquo [B]mysqlgt GRANT FILE ON TO repl1921680100 IDENTIFIED BY lsquoabc123rsquo Step2做完單向 replication後stop Server Aserver B MySQL service此時 AB資料是一樣的

95

修改etcmycnf設定 範例 Server A [mysqld] datadir=varlibmysql socket=varlibmysqlmysqlsock server-id=1 log-bin sql-bin-update-same binlog-do-db=CRM master-host=1921680200 master-user=repl master-password=abc123 log-slave-updates master-connect-retry=60 replicate-do-db=CRM Server B [mysqld] datadir=varlibmysql socket=varlibmysqlmysqlsock server-id=2 log-bin sql-bin-update-same binlog-do-db=CRM master-host=1921680100 master-user=repl master-password=abc123 log-slave-updates master-connect-retry=60 replicate-do-db=CRM 分別 start Server AServer B MySQL後此時雙方都是 MasterSlave身分一旦哪一方資料異動就會通知對方來 replication-若 replication失效則必須將Server AServer B的masterinfo及index00x 都砍掉然後分別 restart MySQL server進行測試檢視成果 實務上通常如果需要做Two-way replication通常會搭配Virtual Server使用

96

在前端架設一台Virtual Server不過此部份不在此份SOP討論範圍內有興趣

的讀者可參考 httpwwwlinuxvirtualserverorg 網站

1921680100 1921680200

Host A MasterSlave Server

Host B MasterSlave Server

Virtual Host

圖 Virtual Server + Two-way replication 架構圖

97

圖 High Availability Linux Virtual Server架構圖

98

  • COSA-SOP-03-006
  • 第一章 簡介
    • 11適用對象 (Audience)
    • 12 MySQL本身
    • 13 MySQL 40版跟50版重大的改進功能
    • 14 各家資料庫軟體比較
      • 第二章 前置需求
      • 第三章 安裝
        • 31 MySQL安裝
        • 32 phpMyAdmin安裝
        • 33 升級及注意事項
          • 第四章 MySQL管理
            • 41 Webmin 管理介面
            • 42 phpMyAdmin 的操作介面
            • 43管理指令介紹
              • 431 利用mysqladmin設定root的密碼
                  • 第五章 實用範例
                    • 51 任務一Web Base客戶通訊錄
                    • 52 任務二Web Base群組軟體 ( twig )
                      • 第六章 維護及更新程序
                        • 61 日常維護
                        • 62 更新程序
                        • 63 備份重要檔案
                        • 64 離線備份與還原
                        • 65 線上備份與還原
                          • 第七章 問題與解答
                          • 第八章 參考資料
                          • 附錄一 SQL Command 介紹
                          • 附錄二Replication
Page 41: DataBase Server Standard Operation Procedureebooks.lib.ntu.edu.tw/1_file/oss/63/93doc4-5.pdf · 業務的公司帶來了不少壓力,譬如微軟,甲骨文 ... 外的錢用在第三方的資料庫產品上,譬如就可以不用再購買甲骨文公司

Step3 phpMyAdmin會產生相關的 SQL Command

圖 4-21 資料表結構及相關 SQL Command

Step4新增 Record

41

圖 4-22

圖 4-23

42

圖 4-24

圖 4-25

43

423使用者管理

Step1建立使用者

圖 4-26

44

圖 4-27

Step2 給予權限

圖 4-28

Step3權限列表

45

圖 4-29

43管理指令介紹

431 利用 mysqladmin設定 root的密碼

當您在Windows 或 Linux 中安裝好 MySQL後系統會自動幫您建立兩個

帳分別是 root 和 匿名者MySQL的 root 跟 Linux 最高權限使用者 root無關MySQL的 root使用者相當於 MS SQL 中的 sa 帳號擁有最高的 Database管理權限但系統預設 MySQL的 root 是不需要密碼所以通常我們一安裝

MySQL後首要任務便是修改 root的密碼 我們可以利用 mysqladmin工具或是直接修改 MySQL內部資料庫的使用者資

料 mysqladmin ndashu root ndashh cosaexamplecom password lsquo1234rsquo

46

-u 表示使用者帳號root 為 MySQL預設的管理帳號

-h 表示 MySQL主機的主機名稱也可使用 IP Address password 表示使用者的密碼因為字串請使用單引號將密碼括起來 密碼設定完成之後還是可以利用 mysqladmin修改密碼但是你必須提供目前的密碼

432 連線 MySQL

mysql -uroot -p密碼 (-p和密碼之間不能有空白) 或 mysql -uroot -p (此方式會在進入後要求密碼) [rootossc phpMyAdmin] mysql -u root -p1234

Welcome to the MySQL monitor Commands end with or g

Your MySQL connection id is 25 to server version 32354

Type help or h for help Type c to clear the buffer

mysqlgt show databases

+----------+

| Database |

+----------+

| mysql |

| test |

+----------+

2 rows in set (000 sec)

mysqlgt exit

Bye

[rootossc phpMyAdmin]

433 建立資料庫

可利用 mysqladmin指令建立 CONTACT資料庫 mysqladmin -u root -p1234 create CONTACT

47

或是利用 mysql指令 [rootossc bluepage] mysql -u root -p1234 Welcome to the MySQL monitor Commands end with or g Your MySQL connection id is 1057 to server version 32354 Type help or h for help Type c to clear the buffer mysqlgt create database CONTACT Query OK 1 row affected (000 sec) mysqlgt show databases +----------+ | Database | +----------+ | CONTACT | | address | | hello | | mysql | | nuke | | test | +----------+ 6 rows in set (000 sec) mysqlgt exit

434 建立資料表

編寫 adresssql內容如下 -- Table structure for table address CREATE TABLE address ( id int(11) NOT NULL auto_increment name varchar(20) NOT NULL default tel varchar(15) NOT NULL default PRIMARY KEY (id) ) TYPE=MyISAM

48

-- Dumping data for table address INSERT INTO address VALUES (1林小明0800016888) INSERT INTO address VALUES (2黃大雄0800016888) INSERT INTO address VALUES (3劉小芬0800024365) 然後執行此 sql script mysql -u root -p1234 CONTACT lt addresssql 或是利 mysql command [rootossc bluepage] mysql -u root -p1234 Welcome to the MySQL monitor Commands end with or g Your MySQL connection id is 1090 to server version 32354 Type help or h for help Type c to clear the buffer mysqlgt use CONTACT Database changed Database changed mysqlgt CREATE TABLE address ( -gt id int(11) NOT NULL auto_increment -gt name varchar(20) NOT NULL default -gt tel varchar(15) NOT NULL default -gt PRIMARY KEY (id) -gt ) TYPE=MyISAM Query OK 0 rows affected (000 sec) mysqlgt INSERT INTO address VALUES (1林小明0800016888) Query OK 1 row affected (000 sec) mysqlgt INSERT INTO address VALUES (2黃大雄0800016888) Query OK 1 row affected (000 sec) mysqlgt INSERT INTO address VALUES (3劉小芬0800024365) Query OK 1 row affected (000 sec) mysqlgt exit Bye

49

第五章 實用範例

51 任務一Web Base客戶通訊錄

任職於開放科技公司的林小明前些日子在最符合成本效益的條件下快

速地完成公司網站的建置老闆因此對小明讚譽有加最近因為公司存放客戶資

料的 SQL Server主機屢遭病毒攻擊加上作業系統本身的問題當機次數頻繁

老闆希望能儘快把公司的客戶通訊錄程式移轉到較穩定的環境上因為此客戶通

訊錄程式最主要給內部人員使用所以介面美觀並不特別要求只求穩定且能快

速得到查詢結果老闆希望在短時間先看到程式的雛型並鍵入資料對其效率

及穩定性進行測試因為上次小明表現突出所以這次不可能的任務自然又落到

小明身上 小明想來想去既然要快速又穩定他而且又不希望所有人都得安裝 Client

程式於是小明決定)捨棄他的舊愛「Delphi+MS SQL」投向新歡「Apache + MySQL + PHP」利用此架構來設計一個簡單實用的Web Base客戶通訊錄程式

511 Web Base客戶通訊錄架構

此程式需要建立 CONTACT的資料庫並建立 adress Tables其結構如下表建立步驟請參考第三章 欄位名稱 資料型態 長度 說明 id INT (自動編號) 連絡人編號 name varchar文字 20 連絡人姓名 tel Varchar文字 15 連絡人電話 Web Base通訊錄共有下列幾個檔案功能如下表

檔案名稱 說明 Indexhtml Web Base通訊錄首頁 addphp 新增連絡人的 php程式 searchphp 尋找連絡人的 php程式 editphp 具有更新及刪除功能的 php程式

50

我們將這些檔案放至varwwwhtmlbluepage (預設無 bluepage目錄)

512 Web Base通訊錄測試

httpwwwopencombluepage 新增資料

圖 5-1 新增連絡人

圖 5-2 填入資料

51

圖 5-3 新增成功

搜尋及異動資料

圖 5-4 搜尋通訊錄

52

圖 5-5 編輯資料

圖 5-6 更新資料

513 程式內容及說明

lt-- 程式範例indexhtml--gt lthtmlgt ltheadgtlttitlegt通訊錄lttitlegtltheadgt ltbodygt ltcentergt

53

lth2gt通訊錄lth2gtlthrgt lta href=indexhtmlgt通訊錄ltagt | lta href=addphpgt新增連絡人ltagt | lta href=searchphpgt搜尋通訊錄ltagt ltcentergt ltbodygt lthtmlgt lt-- 程式範例addphp --gt lthtmlgt ltheadgtlttitlegt新增連絡人lttitlegtltheadgt ltbodygt ltcentergtlth2gt新增連絡人lth2gtltcentergtlthrgt lt 取得欄位資料 if (isset($_POST[Name]) ampamp isset($_POST[Tel]) ) $name = $_POST[Name] $tel = $_POST[Tel] 檢查是否有輸入欄位資料 if ($name = ampamp $tel = ) 建立 SQL字串 $sql = INSERT INTO address (name tel) values( $sql= $name $tel) 建立 MySQL 連結 $link = mysql_connect(localhostroot1234) 選擇資料庫 mysql_select_db(CONTACT) 執行 SQL指令 mysql_query($sql) mysql_close($link) echo ltfont color=redgt新增連絡人成功ltfontgtltbrgt gt ltform action=addphp method=postgt lttable border=0 width=300gt lttrgtlttdgt姓名 lttdgt

54

lttdgtltinput type=text name=Name size=20 maxlength=10gtlttdgtlttrgt lttrgtlttdgt電話 lttdgt lttdgtltinput type=text name=Tel size=20 maxlength=20gtlttdgtlttrgt lttrgtlttd colspan=2 align=centergt ltinput type=submit value=新增連絡人gtlttdgtlttrgt lttablegt ltformgt ltbrgtlta href=indexhtmlgt通訊錄ltagt | lta href=addphpgt新增連絡人ltagt | lta href=searchphpgt搜尋通訊錄ltagt ltbodygt lthtmlgt

lt-- 程式範例searchphp --gt lthtmlgt ltheadgtlttitlegt搜尋通訊錄lttitlegtltheadgt ltbodygt ltcentergtlth2gt搜尋通訊錄lth2gtlthrgt lt if (isset($_POST[Search])) 建立資料庫連結並選定資料庫 $link = mysql_connect(localhostroot1234) mysql_select_db(CONTACT) 建立基本的 SQL字串 $sql = SELECT FROM address 檢查是否輸入姓名 if (chop($_POST[Name]) = ) $name = name LIKE $_POST[Name] else $name = 檢查是否輸入電話號碼 if (chop($_POST[Tel]) = ) $tel = tel LIKE $_POST[Tel] else $tel =

55

if條件組合 SQL字串 if (chop($name) = ampamp chop($tel) = ) $sql= WHERE $name AND $tel elseif (chop($name) = ) 只有姓名 $sql = WHERE $name elseif (chop($tel) = ) 只有電話號碼 $sql = WHERE $tel $sql= ORDER BY name 最後加上排序 $result = mysql_query($sql) 取得欄位數 $total_fields = mysql_num_fields($result) echo lttable border=1gt echo lttrgtlttdgt編號lttdgtlttdgt姓名lttdgtlttdgt電話lttdgtlttd colspan=2gt功能選項lttdgtlttrgt 表格顯示查詢結果 while ($rows = mysql_fetch_array($result MYSQL_NUM)) echo lttrgt for ($i = 0 $i lt $total_fields $i++) echo lttdgt$rows[$i]lttdgt echo lttdgtlta href=editphpaction=editampid= echo $rows[0]gtltbgt編輯ltbgtlttdgt echo lttdgtlta href=editphpaction=delampid= echo $rows[0]gtltbgt刪除ltbgtlttdgt echo lttrgt echo lttablegtlthrgt mysql_free_result($result) mysql_close($link) gt ltcentergt ltform action=searchphp method=postgt lttable border=0 width=450gt lttrgtlttdgt搜尋姓名 lttdgt lttdgtltinput type=text name=Name size=10 maxlength=20gtlttdgtlttrgt lttrgtlttdgt搜尋電話 lttdgt lttdgtltinput type=text name=Tel

56

size=20 maxlength=20gtlttdgtlttrgt lttrgtlttd colspan=2 align=centergt ltinput type=submit name=Search value=搜尋gtlttdgtlttrgt lttablegt ltformgt ltbrgtlta href=indexhtmlgt通訊錄ltagt | lta href=addphpgt新增連絡人ltagt | lta href=searchphpgt搜尋通訊錄ltagt ltbodygt lthtmlgt

lt ob_start() gt lt-- 程式範例editphp --gt lthtmlgt ltheadgtlttitlegt編輯通訊錄lttitlegtltheadgt ltbodygt lt 取得 URL 參數 $id = $_GET[id] $action = $_GET[action] 建立資料庫連結 $link = mysql_connect(localhostroot1234) mysql_select_db(CONTACT) 選擇資料庫 執行的操作 switch ($action) case update 更新 取得欄位資料 $name = $_POST[Name] $tel = $_POST[Tel] $sql = UPDATE address SET name=$name tel=$tel WHERE id=$id mysql_query($sql) 執行 SQL指令 mysql_close($link) header(Location searchphp) 轉向到 serachphp break case del 刪除 $sql = DELETE FROM address WHERE id=$id

57

mysql_query($sql) 執行 SQL指令 mysql_close($link) header(Location searchphp) 轉向到 serachphp break case edit 編輯 $sql = SELECT FROM address WHERE id=$id $result = mysql_query($sql) 執行 SQL指令 $row = mysql_fetch_row($result) 取回記錄 $name = $row[1] 取得欄位 name $tel = $row[2] 取得欄位 tel mysql_close($link) 顯示編輯表單 gt ltcentergtlth2gt更新通訊錄lth2gtltcentergtlthrgt ltform action=editphpaction=updateampid=lt echo $id gt method=postgt lttable border=0 width=300gt lttrgtlttdgt姓名 lttdgt lttdgtltinput type=text name=Name size=20 maxlength=10 value=lt echo $name gtgtlttdgtlttrgt lttrgtlttdgt電話 lttdgt lttdgtltinput type=text name=Tel size=20 maxlength=20 value=lt echo $tel gtgtlttdgtlttrgt lttrgtlttd colspan=2 align=centergt ltinput type=submit value=更新連絡人gtlttdgtlttrgt lttablegt ltformgt ltbrgtlta href=indexhtmlgt通訊錄ltagt | lta href=addphpgt新增連絡人ltagt | lta href=searchphpgt搜尋通訊錄ltagt lt break gt ltbodygt lthtmlgt

58

52 任務二Web Base群組軟體 ( twig )

順利完成Web Base客戶通訊錄程式測試一段時間後「Apache + MySQL + PHP」架構的穩定與快速巳深得老闆與公司所有同事的認同隨著公司業績蒸

蒸日上人員組織編罝愈來愈龐大跨部門的會議愈來愈多業務員每日排滿拜

訪客戶的行程跟客戶的 Email的往來也愈來愈頻繁 愈來愈多部門的同事希望公司能建置一套群組軟體提供 web mail可讓業

務人員方便收發 mail還有連絡人議事日程待辦工作書簽等功能讓整個

公司運作及個人時間管理更有效率

老闆問小明對這些需求有什麼看法小明認為如果這些功能完全由程式部

門開發必定曠日費時而且耗費公司資源小明在網路尋找是否有提供這些功能

的Free Software皇天不負苦心人小明發現了TWIG (The Web Information Gateway) httptwigscrewdrivernet這個群組軟體它在 Web 上整合郵件新聞聯絡人議事日程工作序書簽等功能非常符合公司的需求 Step 1 下載 twig-277targz 下載網址 httptwigscrewdrivernetdownloadphp3

Step 2 解開 twig-277targz tar -xzvf twig-277targz

59

Step 3 執行安裝動作安裝到 varwwwhtmltwig 目錄 cd twig-277 twig-install varwwwhtmltwig

Step 4 建立 MySQL 資料庫(twig)及各資料表

cd setup mysql -u root -p1234 mysqlgt create database twig Query OK 1 row affected (001 sec) mysqlgt quit mysql -u root ndashp1234 twiglt twigtablemysql

Step 5 修改 configincphp3 參數設定 vi varwwwhtmltwigconfigconfigincphp3 $config[fromdomain] = opencom 網域 $config[language] = chinesebig5 中文訊息 $config[imap_port] = 143notls

60

Step 6 修改連結 MySQL 的帳號密碼 vi varwwwhtmltwigconfigdbconfigincphp3 $dbconfig[sqlusername] = root username $dbconfig[sqlpassword] = 1234 password

Step 7 其他設定檔

vi etchttpdconfhttpdconf 加入 AddType applicationx-httpd-php php3 在 DirectoryIndex最後加入 indexphp3 DirectoryIndex indexhtml indexhtmlvar indexphp3 在 AddDefaultCharset ISO-8859-1加上 AddDefaultCharset ISO-8859-1

vi etcphpini register_globals = On service httpd restart Step 8 sendmail 設定 vi etcmailsendmailcf在 264 行前面加上並重新啟動 sendmail「service snedmail restart」 262 SMTP daemon options 263 264 O DaemonPortOptions=Port=smtpAddr=127001 Name=MTA 265 266 SMTP client options 267 O ClientPortOptions=Family=inet Address=00

61

Step 9 檢查設定有無錯誤 http主機名稱twigtestphp3

62

Step 10 登入 twig ( http主機名稱twig)

63

第六章 維護及更新程序

61 日常維護

系統管理員最好定期以 root 身份登入看看信件在 RedHat Linux 中有一支 logwatch 程式會定時去分析 log file如果發現異常便會發信給 root除此之外筆者建議讀者平時就檢查 MySQL log file ( varlogmysqldlog)是否有異常情形

62 更新程序

讀者可至httprpmfindnet 尋找MySQL相關套件至於升級的相關步驟請參

考Linux OS SOP 第 54節

63 備份重要檔案

預設 MySQL 的 DB 檔案是存在 varlibmysql 內以 DB名稱為目錄目錄

內就是該 DB 的所有資料通常得定期備份還有 MySQL的設定檔 etcmycnf也別忘了一起備份

64 離線備份與還原

641 離線備份

預設 MySQL 的 DB 檔案是存在 varlibmysql 內以 DB 名稱為目錄目錄內

就是該 DB 的所有資料像 CRM 這個 DB就是存在 varlibmysqlCRM 內在備份前因為怕資料尚未完全寫入磁碟而且 MySQL 會 Lock 在使用的 DB 檔案所以應該是要先把 MySQL 先 Shutdown 一下整個備份的程序可以下像下面的指令去完成 cd varlibmysql

64

service mysqld stop tar cvfz CRM_db_20030905tgz CRM service mysqld start 對這樣就可以了 不過要注意的是怕 DB 內每個 Tables 間的資料有關關

聯性所以最好是把整個 DB 一次備起來單獨只備哪個 Tables 的檔案以後回存時怕會有資料關聯不一致的問題

642 離線還原

DB 發生錯誤而要回存時其實也不難先找出最近一次完整正常的備份先把現在錯誤的網頁或 DB 先更名或 tar 起來再把好的備份給解開回原來目錄位

置就行了需要注意的是 MySQL 服務最好也是要先停止回存完成後再啟動服務回存 DB 的整個程序可能像下面 cd varlibmysql service mysqldstop mv CRM CRM_OLD tar xvfz CRM_db_20030905tg service mysqld start

65 線上備份與還原

651 線上備份

使用像上面的檔案方式備份是個不錯的方法它最少可以保持該主機某個時間點的完整檔案備份但還是有一些問題需要考慮到有些主機就不只建立一個 DB 而已總不能為了備份某個 DB 而把整個 MySQL 服務停止備份檔案的方式回存在原主機上一定適用但假如 MySQL 版本升級或是在那天該網頁空間需遷機移機到別的主機時那就沒人敢保證備出來的資料檔可以用所以我們可以考慮另一種備份的方式是使用 MySQL 本身提供的功能 MySQL Data Dump指令是 mysqldump

65

使用 MySQL 的 Dump 功能可以把 DB 的結構資料或結構加資料 Dump 成文字檔 mysqldump 指令提供的彈性很大你可以選擇把整個 DB Dump 成一個檔或是每個 Table 為一個檔甚至是把結構檔和資料分開儲存都

可以 mysqladmin -uroot -p flush-logs mysqldump CRM -uroot -p --opt gt CRM_20030905sql (CRM 是 DB 名稱 opt 是一個使用完整 Dump 參數) 假如只是要單獨 Dump 某個 Table 時只要在上面的指令後轉出符號 gt 前加個 Table 名稱就可以如只要 phpbb2_users 這個 Table 的 Dump 時只要下 mysqldump CRM -uroot -p --opt CUSTOMER gt CRM_CUSTOMER_20030905sql

652 線上還原

若要回存整個資料庫只需將壓縮的備份檔還原成 Dump 的檔案再用下面的指令回存 mysql CRM -uroot -p lt CRM_20030905sql 這邊需注意的是若建立備份時是以--opt或--add-drop-table為參數時回存的 動作是先將舊的 Table 先刪除重建 Table 的結構後再把 Data 匯入所以回存後所有的資料會回到你當時備份那個時間點因此在回存資料時可以考慮把現有錯誤或不完整的 DB 先備份一份下來以備不時之需或是拿來比對錯誤的地

方在那裡當然你也可以把資料回存到另一個測試用的 DB 內只要把上面指令

的 DB 名稱改成你的測試用 DB 名稱即可 使用這種回存方式 MySQL 服務不需停止也不會動到其他正在使用的 DB 在一些提供 MySQL 服務的虛擬主機可用這種方式作你自己的 DB 備份及回存

66

另外假如你是系統重建或是移機時切需在新的 MySQL 內新建一個空白 DB 後才行作回存的工作你可以用下面的指令建立 mysql -uroot -p -e CREATE DATABASE CRM (上面的 CRM是你要新建的 DB 名稱) 另一種作法先用 mysql 指令進入 mysql client console 然後再用 CREATE DATABASE CRM 這樣就行了記得尾端要加個 符號該行指令才會執行

67

第七章 問題與解答

Q1RedHat 90預附的 MySQL到底有無支援 Transcation機制 Ans MySQL自 32334a之後的 MySQL-Max版本加入 InnoDB的資料庫類型透過

InnoDBMySQL同樣可以進行 COMMIT與 ROLLRACK的動作RedHat 90預附的 MySQL為 32354a-11巳支援 InnoDB的資料庫類型不過必須做以

下設定 1cp usrsharedocmysql-server-32354amy-mediumcnf to etcmycnf 2 vi etcmycnf 將以下設定前的拿掉 innodb_data_home_dir = varlibmysql innodb_data_file_path = ibdata110Mautoextend innodb_log_group_home_dir = varlibmysql innodb_log_arch_dir = varlibmysql 3service mysqld restart 如此一來各位在建立Table時便可指定Table Type為 innodb ( ex create table with type=innodb ) Q2如何解決 php+mysql 許功蓋等字變亂的問題 Ans 方法一 【確定 MySQL 預設的字元集】 1 打開 WinMySQLadmin 管理畫面(在視窗右下角狀態列紅綠燈圖示中按滑鼠

右鍵點選 Show me 選項) 2 點選管理畫面中 [Variables] 標籤選項其中 character_set變數就是您預設

字元集的變數其預設是 latin1 字元集(我們要將他改回 big5)而 chatacters_set 變數則是 MySQL 可以支援哪些字元集 【修改預設字元集變數 character_set 】 1 請點選管理畫面中 [myini Setup] 標籤選項設定 myini 2 按一下 [Pick-up and Edit myini values] 按鈕以便編輯目前的 myini 設定 3 在 [mysqld] 設定區塊底下新增一行 default-character-set = big5 變數設

68

定 4 新增一個 [client] 設定區塊並加入第三步驟的變數設定(游標往下移到空白處新增兩行 [client] 和 default-character-set=big5) 5 按一下畫面左下方 [Save Modification] 按鈕儲存設定 6 重新啟動 MySQL 或 Windows 方法二 Server端注意事項 phpini 中有關的設定為(預設值) Magic quotes for incoming GETPOSTCookie data magic_quotes_gpc = On Use Sybase-style magic quotes (escape with instead of ) magic_quotes_sybase = Off Client端注意事項 1中文資料送進 mysql 前請用 addslashes($str) 處理 2處理後送進 mysql 時請用 括起來並在參數後留一個空白如 $sql = UPDATE ezf_table set tablename=$tname tableend=$endtime table inguser=$tguser tableingid=$tguserid tableallnumber=$tnumber tableloca l=$tablelocal tableanyone=$tableopen tabletext=$ttext WHERE tableid=$t ableid tablename=$tname c 取出時請用 stripslashes($str) Q3MySQL root 密碼忘了該怎麼辦 Ans 1先停掉 mysql etcrcdinitdmysql stop 2以--skip-grant-table 的參數啟動 mysql safe_mysql --skip-grant-tableamp 3 更改 root 密碼 mysql mysql mysqlgt UPDATE user SET password=password(newpassword)

69

WHERE user=root mysqlgt FLUSH PRIVILEGES mysqlgt exit 4停掉 mysql再重跑 mysqladmin -uroot -p shutdown Enter password 輸入新設定的密碼 etcrcdinitdmysql start

Q4NULL值問題

Ans

NULL值的概念是造成 SQL的新手的混淆的普遍原因他們經常認為 NULL是和一個空字符串的一樣的東西不是這樣的例如下列語句是完全不同的

mysqlgt INSERT INTO my_table (phone) VALUES (NULL)

mysqlgt INSERT INTO my_table (phone) VALUES ()

兩個語句把值插入到 phone 列但是第一個插入一個 NULL值而第二個插入一個空字符串第一個的含義可以認為是ldquo電話號碼不知道而第二個則可意味

著ldquo她沒有電話

在 SQL中NULL值在于任何其他值甚至 NULL值比較時總是假的(FALSE)包含 NULL的一個表達式總是產生一個 NULL值除非在包含在表達式中的運算符和函數的文檔中指出在下列例子所有的列返回 NULL

mysqlgt SELECT NULL1+NULLCONCAT(InvisibleNULL)

如果你想要尋找值是 NULL的列你不能使用=NULL測試下列語句不返回任

何行因為對任何表達式expr = NULL是假的

mysqlgt SELECT FROM my_table WHERE phone = NULL

要想尋找 NULL值你必須使用 IS NULL測試下例顯示如何找出 NULL電話號碼和空的電話號碼

70

mysqlgt SELECT FROM my_table WHERE phone IS NULL mysqlgt SELECT FROM my_table WHERE phone =

在 MySQL中就像很多其他的 SQL服務器一樣你不能索引可以有 NULL值的列你必須聲明這樣的列為 NOT NULL而且你不能插入 NULL到索引的

列中

當用 LOAD DATA INFILE 讀取數據時空列用更新如果你想要在一個列中有

NULL值你應該在文本文件中使用N字面上的詞NULL也可以在某些情形下使用

當使用 ORDER BY時首先呈現 NULL值如果你用 DESC以降序排序NULL值最後顯示當使用 GROUP BY時所有的 NULL值被認為是相等的

為了有助于NULL的處理你能使用 IS NULL和 IS NOT NULL運算符和 IFNULL()函數

對某些列類型NULL值被特殊地處理如果你將 NULL插入表的第一個TIMESTAMP 列則插入當前的日期和時間如果你將 NULL插入一個AUTO_INCREMENT 列則插入順序中的下一個數字

Q5如何將圖片存放於 MySQL中

Ans

Step 1建立資料庫 test

Step 2 建立表格 binary_data

CREATE TABLE binary_data (

id INT(4) NOT NULL AUTO_INCREMENT PRIMARY KEY

description CHAR(50)

bin_data LONGBLOB

filename CHAR(50)

filesize CHAR(50)

filetype CHAR(50)

71

)

Step 3 利用 storephp 寫入圖片

storephp 程式碼

ltHTMLgt ltHEADgtltTITLEgtStore binary data into SQL DatabaseltTITLEgtltHEADgt ltBODYgt lt code that will be executed if the form has been submitted

if ($submit) mysql_connect(localhostrootYOUR_PASSWORD) mysql_select_db(test) $data=Base64_Encode(fread(fopen($form_data r) filesize($form_data))) $result=MYSQL_QUERY(INSERT INTO binary_data (descriptionbin_datafilenamefilesizefiletype) VALUES ($form_description$data$form_data_name$form_data_size$form_data_type)) $id= mysql_insert_id() print ltpgtThis file has the following Database ID ltbgt$idltbgt MYSQL_CLOSE() else else show the form to submit new data

gt

ltform method=post action=ltphp echo $PHP_SELF gt enctype=multipartform-datagt File Descriptionltbrgt ltinput type=text name=form_description size=40gt ltINPUT TYPE=hidden name=MAX_FILE_SIZE value=4000000gt ltbrgtFile to uploadstore in databaseltbrgt ltinput type=file name=form_data size=40gt ltpgtltinput type=submit name=submit value=submitgt ltformgt lt

72

gt ltBODYgt ltHTMLgt

Step 3 利用 storephp 取出圖片

getdataphp 程式碼

lt Syntax getdataphp3id=ltidgt if($id) you may have to modify login information for your database server MYSQL_CONNECT(localhostrootYOUR_PASSWORD) mysql_select_db(test) $query = select bin_datafiletype from binary_data where id=$id $result = MYSQL_QUERY($query) $data = Base64_Decode(MYSQL_RESULT($result0bin_data)) $type = MYSQL_RESULT($result0filetype) Header( Content-type $type) echo $data gt

Q6MySQL裝好之後啟動時或是執行 mysqladmin會出現如下訊息 Cant connect to local MYSQL Server through Socket varlibmysqlmysqlsock或是

Cant connect to local MYSQL Server through Socket tmpmysqldsock

Ans 可能有下列幾個原因

1這個 mysqldsock 不見了被某人刪除了或是被一些系統自動執行程式給刪

了例如有些 cron任務便會設定定期刪除 tmp 裡的東西所以呢您只能修改

cron 裡的設定讓它不要清除 mysqldsock 2在啟動時也可以改變 mysqldsock的位置您在啟動 MySQL的時候可以加入此參數usrlocalmysqlbinsafe_mysqld --user=mysql --socket=其他路

徑socket amp 同時得去設定環境變數 MYSQL_UNIX_PORT的值以指定新的

73

路徑 3若是您沒改 MYSQL_UNIX_PORT的值那麼您可以在執行指令的時候才打

例如mysqladmin --socket=其他路徑socket version Q7How to get the last insert id Ans CREATE TABLE product ( id INT(4) NOT NULL AUTO_INCREMENT PRIMARY KEY description VARCHAR(50) ) 1利用 SQL的話 mysqlgt insert into product(description) values(123) Query OK 1 row affected (000 sec) mysqlgt select last_insert_id() +------------------+ | last_insert_id() | +------------------+ +------------------+ 1 row in set (000 sec) ======================================== 2如果是 PHP的話 你可以用mysql_insert_id()取得該 id PHP example $result=MYSQL_QUERY(INSERT INTO product (description) VALUES ($description)) $id= mysql_insert_id() print This file has the following Database ID $id Q8如何將文字檔匯入資料庫 Ans $addr=homehttpdhtmlphpschool001txt $sql_select = load data infile $addr into table test fields terminated by t 解說 $sql_select = load data infile 文字檔名 into table 表格名 fields terminated by

74

t

(欄位分隔以 TAB鍵) 該文字檔須與資料表欄位格式相符 例如欄位有三個 則文字檔為每行一筆資料如下 欄 1資料ltTABgt欄 2資料ltTABgt欄 3資料 欄 1資料ltTABgt欄 2資料ltTABgt欄 3資料 欄 1資料ltTABgt欄 2資料ltTABgt欄 3資料 欄 1資料ltTABgtltTABgt欄 3資料

Q9如何撰寫 MySQL C API Ans Step 1利用文字編輯器撰寫以下程式碼 mysqlcc

include ltstdiohgt

include ltmysqlmysqlhgt

int main (int argc char argv[])

MYSQL mysql

MYSQL_RES res

MYSQL_ROW row

if (argc = 2)

fputs (Usage myc ltdatabasegt stderr)

return 1

if ((mysql_connect(ampmysqllocalhostrootYour_Password)))

fputs (Error connecting stderr)

abort()

75

if (mysql_select_db(ampmysqlargv[1]))

fputs (Error selecting database stderr)

abort()

if (mysql_query(ampmysqlSELECT FROM test_table))

fputs (Error processing query stderr)

abort()

if ((res = mysql_store_result(ampmysql)))

fputs (Error storing results stderr)

abort()

while((row = mysql_fetch_row(res)))

uint i = 0

for (i=0 i lt mysql_num_fields(res) i++)

printf(s row[i])

printf(n)

return 0

Step 2 Compile

gcc -Iusrlocalmysqlinclude -Lusrlocalmysqllibmysql mysqlcc ndashlm -lmysqlclient

(其中 include path與 library path取決於你的 MySQL安裝路徑)

76

如果執行時發生如下 error Run problemerror in loading shared libraries libmysqlclientsoX 將你的 MySQL library path(for exampleusrlocalmysqllibmysql) 加入etcldsoconf and run sbinldconfig -v Q9ASP + MySQL 範例程式 Ans Dim myconn As New ADODBConnection Dim myrs As New Recordset Dim mySQL As String Dim myrows As Long myconnOpen DSN=MyODBCsample mySQL = SELECT from user myrsSource = mySQL Set myrsActiveConnection = myconn myrsCursorLocation = adUseClient myrsOpen myrows = myrsRecordCount myrsClose myconnClose 可參考 httpwwwdwamnetmysqlasp_myodbcasp 有詳細的資料 Q10如何將 MySQL中的資料庫匯出成txt檔 Ans select from TableName into outfile textxls all result fields will seperate by tab

77

第八章 參考資料

英文部份 網址 1 httpwwwmysqlcom MySQL 網站有第一手有關 MySQL的資料 2 httpwwwmysqlcomdocenReplicationhtml 有關 MySQL Replication 的文件 3 httpwwwgeocitiescomsqlhomefaqstore_blobhtml 如何在 MySQL 存放 BLOB的資料 4httpwwwsapdborg 有關 SAP跟 MySQL相關合作的網站 書藉 1 Cooking with MySQL

Paul DuBois has selected sample recipes from the hundreds youll find in his book MySQL

Cookbook In this third and final series of excerpts showcasing these recipes learn how to

compute team standings how to calculate the differences between successive Dec 26

2002 2 Tips for Building Web Database Applications with PHP and MySQL by Hugh E Williams co-author of Web Database Applications with PHP amp MySQL 04042002

3 Managing and Using MySQL 2nd Edition By Tim King George Reese Randy Jay Yarger

4 MySQL Cookbook By Paul DuBoisPublisher OReillyPub Date October 2002

中文部份

78

1 httplinuxtncedutwtechdocmysqlmysql_docmanual_tochtml MySQL 中文手冊 2 httpchenshloxaedutwphpZ_1php PHP+MySQ程式研習設計網站 3 httplinuxtncedutwtechdocbanicdownhtml PHP 4 手冊 4 httpwwwtncedutwadmin_zonephp台南縣教育網網路中心有很多 Linux相關文件 5 httpdobtncedutw網站建置百寶箱有很多 PHP MySQL 相關範例程式 5 httpwwwdbworldcomtw資料庫專家電子雜誌介紹資料庫的重要觀念及名詞

79

附錄一 SQL Command 介紹

SQL (讀音ess-que-el) 是一種結構查詢語法SQL 使用於資料庫交流

傳遞相容於 ANSI (American National Standards Institute) 是一套標準的關聯

式資料庫語言 SQL 語言是執行更新或從資料系統獲取資料一般常見的關聯

資料庫系統都有提供 SQL 如 Oracle Sybase Microsoft SQL Server Access Ingres 等雖然大部份的資料庫都有提供 SQL 但也多提供了自已獨特的語

法造成了不相容的情形但標準基本的語法是相通的如Select Insert Update Delete Create and Drop 每一個系統都有支援

Table相關 Command

Create Table

關聯式資料庫包含有很多元件稱為資料表(tables) 把資料或訊息放在資

料表中 資料表是以不同的名稱做分別資料表由欄列所構成的二維陣列

欄包含欄位名資料型態 及其他可判斷的資訊列是由全部欄位構成一筆一

筆的紀錄 create table 語法用在建立一個新的資料表語法格式如下

create table tablename (column1 data type column2 data type column3 data type)

Format of create table if you were to use optional constraints

create table tablename (column1 data type [constraint] column2 data type [constraint] column3 data type [constraint]) [ ] = optional

Note You may have as many columns as youd like and the constraints are optional

80

Example

create table employee (first varchar(15) last varchar(20) age number(3) address varchar(30) city varchar(20) state varchar(20))

注意建立資料表格式要以括號把前後框住而最後以(分號)做結尾

欄位名不要超過 30個字元長而且不要使用 sql 的關鍵字(如 where select等)而在後面接是型態的宣告(如字串數字日期格式等)

資料型態是來描述欄位的方式如一個欄位Last_Name 是一個姓氏可以使用varchar (可變動長度字串) 資料型態

以下是幾個常見的資料庫型態 char(size) 固定長度字串最長為 255 位元 varchar(size) 變動長度字串最大字元數以 size 來指定 number(size) 數值格式可以是整數也可以是小數最大數字以 size 位數判

斷未指定小數位數由系統內定 date 日期格式 number(sized) 數值格式最大數字以 size 位數判斷d 為小數位數整數位

數為 size-d 位

有何限制當資料表被建立通常有一或數個欄位是要使用來做關聯的功

能 例如unique 限制(唯一值)兩筆記錄不可以相同的值 not null (非空值)該欄位一定要輸入資料不可是空的primary key (主鍵)是每一筆記錄識別的主要方式

Drop a table drop table 刪除資料表(其中的資料也會一併刪除)

drop table tablename

Example

81

drop table 和刪除全部資料是不同的刪除全部資料欄位名稱資訊等還會

存在但刪除資料表會把這一些也一併移除掉

如何查詢資料

Select 基本用法

select 語法是關連式資料庫最常用的部份可以取得你想要的資料這是一個

簡單的範例 select column1[column2etc] from tablename [where condition] [] = optional 在 select 之後所列欄位名則是要顯示的資料部份你可以一一列出各欄位

名或是以 (星號)來代表選擇全部的欄位 from 之後放資料表名稱 where 子句 (選項) 指定要過濾的條件符合者才會顯現 where 可使用的條件運算元 = 等於 gt 大於 lt 小於 gt= 大或等於 lt= 小或等於 ltgt 大相等 LIKE 相似 For example select first last city

82

from empinfo where first LIKE Er 以Er 為開頭的字串就符合要以單引號框住 Or you can specify select first last from empinfo where last LIKE s 最後一字為 S 就符合 select from empinfo where first = Eric 則表示 first name 一定要是 Eric 才可以 範例資料表empinfo 統計函數

MIN 傳回指定欄位最小值

MAX 傳回指定欄位最大值

SUM 傳回指定欄位總和

AVG 傳回指定欄位平均值

COUNT 傳回指定欄位的筆數

COUNT() 傳回資料庫中的總筆數

統計函數使用於資料表中的數值欄位配合 SELECT 語法使用 只用於總結特定單一欄位可以配合 GROUP BY 做篩選但也可以不使用 GROUP BY 語句For example

SELECT AVG(salary) FROM employee

83

傳回全部 salary 平均值

Another example

SELECT AVG(salary) FROM employee WHERE title = Programmer

傳回 salary 平均值條件為 employees 資料表中當 title 等於 Programmer

Example

SELECT Count() FROM employees

傳回 employees 資料表中紀錄總筆數

GROUP BY 語法 SELECT column1 SUM(column2) FROM list-of-tables GROUP BY column-list The GROUP BY 語句可以先以所列的欄位為條件分組排序在一起(可以多欄

位) example 要列出每一個 dept 中最高 salary 值 SELECT max(salary) dept FROM employee GROUP BY dept HAVING 語法

SELECT column1 SUM(column2) FROM list-of-tables GROUP BY column-list HAVING condition

HAVING 子句是 GROUP BY 的一部份用來過濾在 GROUP BY 所選出的資料功能如同 select 命令中 where 條件式一樣只是 HAVING 必需配合 GROUP BY 使用

我們以例子來說明我們要取得每一公司名及每一公司的薪水平均值輸入如下

84

SELECT dept avg(salary) FROM employee GROUP BY dept

但如果我們只列出薪資平均值超過 20000元的公司資料

SELECT dept avg(salary) FROM employee GROUP BY dept HAVING avg(salary) gt 20000

ORDER BY子句語法

SELECT column1 SUM(column2) FROM list-of-tables ORDER BY column-list [ASC | DESC]

[ ] =選項

ORDER BY是一個選項子句當你以排序方式來顯示資料(正向由小到大反向由大到小)以指定的欄位資料做排序

ASC = 正向- 預設值 DESC = 反向排序

For example

SELECT employee_id dept name age salary FROM employee_info WHERE dept = Sales ORDER BY salary

以上列出公司代號公司名銷售員人名年紀及薪資而條件是公司名為 Sales 顯示順序以薪資多少排序(由小到大為預設值)

如果要以多個欄位做排序要以逗號做分隔如下

SELECT employee_id dept name age salary FROM employee_info WHERE dept = Sales ORDER BY salary age DESC

85

結合條件及布林運算 SELECT column1 SUM(column2) FROM list-of-tables WHERE condition1 AND condition2 AND運算可以結兩個或以上的條件放在 WHERE子句中 兩者都要為真才

會顯示該筆記錄 OR 運算可以結兩個或以上敘述放在 WHERE子句中只要其中一個為直就

會顯示該筆記錄 For example SELECT employeeid firstname lastname title salary FROM employee_info WHERE salary gt= 5000000 AND title = Programmer 必需要薪資大於等於 50000而且職稱為 Programmer同時符合才會顯示該筆資料 以下以括號括住雖然不是必需的但如此比較容易讀 SELECT employeeid firstname lastname title salary FROM employee_info WHERE (salary gt= 5000000) AND (title = Programmer) 另外範例 SELECT firstname lastname title salary FROM employee_info WHERE (title = Sales) OR (title = Programmer) 條件為只要是 Sales 或 Programmer 職稱的就會被列出 IN and BETWEEN 子句

SELECT column1 SUM(column2) FROM list-of-tables WHERE column3 IN (list-of-values) SELECT column1 SUM(column2) FROM list-of-tables WHERE column3 BETWEEN value1 AND value2 IN 子句使用在列舉項目的使用上也就是分別測試是否符合所列的值 For example

86

SELECT employeeid lastname salary FROM employee_info WHERE lastname IN (Hernandez Jones Roberts Ruiz) 條件為姓氏(astname)要符合 Hernandez Jones Roberts or Ruiz 其中一個才會被傳回 IN運算元也可以使用 OR 的語法來取代如下結果相同 SELECT employeeid lastname salary FROM employee_info WHERE lastname = Hernandez OR lastname = Jones OR lastname = Roberts OR lastname = Ruiz 但使用 IN 句子比較短也比較易懂 你也可以使用 NOT IN 來去掉不要的記錄 BETWEEN 運算元使用在判斷是否存在兩個數值之間 For example SELECT employeeid age lastname salary FROM employee_info WHERE age BETWEEN 30 AND 40 傳回年紀 30歲到 40歲之間的資料(含 30及 40歲者) 相同的也可以使用以下語法來達到相同的結果 SELECT employeeid age lastname salary FROM employee_info WHERE age gt= 30 AND age lt= 40 你也可使用 NOT BETWEEN 來濾掉中間值的資料 數學運算 標準 ANSI SQL-92 提供以下運算

87

+ 加

- 減

餘數

餘數為除法後剩整數這不在標準的 ANSI SQL 中但大部份的資料庫都會支

援這運算元以下列出有用的函數雖不在 ANSI SQL-92 提供但一般資料庫

也會支援他們

ABS(x) 傳回 x 絕對值

SIGN(x) returns the sign of input x as -1 0 or 1 (negative zero or positive respectively)

MOD(xy) 餘數 - returns the integer remainder of x divided by y (同 xy)

FLOOR(x) 傳回小或等於 x 的最大整數值

CEILING(x) or CEIL(x)

傳回大或等於 x 的最小整數值

POWER(xy) x的 y 次方

ROUND(x) 把 x 四捨五入為整數

ROUND(xd) 四捨五入取到小數 d 位

SQRT(x) x 開平方

For example SELECT round(salary) firstname FROM employee_info 傳回薪資取到整數位

如何新增資料

insert 加入一筆新紀錄到資料表中 insert into tablename (first_columnlast_column) values (first_valuelast_value) [] = optional Example insert into employee

88

(first last age address city state) values (Luke Duke 45 2130 Boars Nest Hazard Co Georgia) Note 字串要以單引號住如string 數字框住也無妨 insert into 後面接資料表名稱再接以括號括住的欄位名在 values 後括號分別對映各欄位的值 以上的例子新增了一筆名(first) 為 Luke而住所(state) 為 Georgia 的資料

如何刪除資料

delete 可以刪除單筆或多筆紀錄 delete from tablename where columnname OPERATOR value [and|or column OPERATOR value] [ ] = optional Examples delete from employee Note 如果你沒有指定 where 子句那麼全部的紀錄都會被刪除 delete from employee where lastname = May delete from employee where firstname = Mike or firstname = Eric delete from 接著資料表名 再接著是條件式判斷沒有條件式則全部紀錄會

被刪除

如何更新資料

update 用來更新你所指定的記錄要和 WHERE 配合小心使用 語法 update tablename set columnname = newvalue[nextcolumn = newvalue2] where columnname OPERATOR value [and|or column OPERATOR value] [] = optional Examples

89

update phone_book set area_code = 623 where prefix = 979 update phone_book set last_name = Smith prefix=555 suffix=9292 where last_name = Jones update employee set age = age+1 where first_name=Mary and last_name=Williams

90

附錄二Replication

測試環境

RedHat 90 + MySQL 32358 MySQL資料庫路徑 varlibmysql MySQL設定檔 etcmycnf Master IP 1921680100 Slave IP 1921680200 請至下列網址下載最新MySQL 32358套件並利用rpm ndashUvh 更新 httpupdatesredhatcom9enosi386

圖 最新 MySQL 套件

測試架構圖

91

1921680100

1921680200Master Server

erveSlave S r

圖 測試架構圖

測試步驟

Master server 部份 Step1 確認 MasterSlave機器上所裝的 MySQL版本能進行

replication( 32329 or higher ) Step2 在 Master MySQL上開放一個帳號給 Slave mysql ndashu root ndashp mysqlgtGRANT FILE ON TO repl1921680200 IDENTIFIED BY lsquoabc123rsquo mysqlgtq 上面是 Master開放一個帳號 repl密碼 abc123給 IP1921680200有檔案處理

的權限 Step3 shutdown MySQL on the Master mysqladmin ndashu root ndashp shutdown Step4 備份 Master所有資料庫 tar ndashcvf tmpmysql-snapshottar varlibmysql 注意tar的時候MySQL是要在 stop情況下 在mysql (wwwmysqlcom) 網站的FAQ有不用shutdown的方法

92

Step5 在 master機器上修改etcmycnf 在[mysqld]區段內加入參數 log-bin server-id=這邊設定 server-id=1 sql-bin-update-same binlog-do-db=CRM只針對 CRM資料庫做紀錄 Step6 Restart MySQL on the master service mysqld start 此時因為有加入 log-bin 參數因此開始有 index產生了在varlibmysql目錄下

有index檔案紀錄資料庫的異動 log Slave server 部份 Step1 在 slave設定etcmycnf 在[mysqld]區段加入 master-host= master-user= master-password= master-port= server-id= 這邊設定 master-host=1921680100 master-user=repl master-password=abc123 master-port=3306 server-id=2 master-connect-retry=60預設重試間隔 60秒 replicate-do-db=CRM告訴 slave只做 CRM資料庫的更新 log-slave-updates Step2 將 master上的 mysql-snapshottar copy到 slave上 用 ftp傳到 slave的tmp Step3 解壓縮 Master資料庫至 Slave Server上 cd varlib tar xvf tmpmysql-snapshottar chown ndashR mysqlmysql mysql

93

chmod ndashR 770 mysql (視情況) Step4 Restart MySQL on the slave server 這時在varlibmysql目錄會出現 masterinfo此檔案紀錄了 Master MySQL server的資訊

狀況測試

One-way replication

1921680100

1921680200Master Server

erveSlave S r

圖 One-way replication架構圖 Step1 Master跟 Slave網路及服務都正常情況下由 Master端異動資料後 到 Slave端瀏覽資料檢視是否有進行 replication Step2 模擬 Slave Server 當機 可用在於 slave真的當機或是 Slave 不一定需要一直跟 master connect將Slave MySQL server shutdown由 Master端異動資料到 slave端瀏覽此時Slave應該沒有被 replication 更新然後再將 Slave端 MySQL server start起來

預設 60秒後 Slave會嘗試跟 Master要求進行 replication再去 Slave端檢視是否有更新資料

94

Step3 模擬 Master當機因為是設定 One-way replication一旦 Master Server Slave端沒有 Master的 source可以 download Two-way replication 基於 Master當機狀況於是發展雙向 Replication即 1921680100 ( Host A ) 1921680200 ( Host B )都分別擔任 MasterSlave身分

1921680100

1921680200er

Server B MasterSlave Server

Server A MasterSlave Serv

圖 Two-way replication架構圖 以下是針對兩台 MySQL伺服器進行雙向 Replication Step1觀念同單向 replication只是改成 Master也有 Slave身分 Slave也有Master的身分先分別在 Server AServer B 都去 grant一個進行 replication的身分 [A]mysqlgtGRANT FILE ON TO repl1921680200 IDENTIFIED BY lsquoabc123rsquo [B]mysqlgt GRANT FILE ON TO repl1921680100 IDENTIFIED BY lsquoabc123rsquo Step2做完單向 replication後stop Server Aserver B MySQL service此時 AB資料是一樣的

95

修改etcmycnf設定 範例 Server A [mysqld] datadir=varlibmysql socket=varlibmysqlmysqlsock server-id=1 log-bin sql-bin-update-same binlog-do-db=CRM master-host=1921680200 master-user=repl master-password=abc123 log-slave-updates master-connect-retry=60 replicate-do-db=CRM Server B [mysqld] datadir=varlibmysql socket=varlibmysqlmysqlsock server-id=2 log-bin sql-bin-update-same binlog-do-db=CRM master-host=1921680100 master-user=repl master-password=abc123 log-slave-updates master-connect-retry=60 replicate-do-db=CRM 分別 start Server AServer B MySQL後此時雙方都是 MasterSlave身分一旦哪一方資料異動就會通知對方來 replication-若 replication失效則必須將Server AServer B的masterinfo及index00x 都砍掉然後分別 restart MySQL server進行測試檢視成果 實務上通常如果需要做Two-way replication通常會搭配Virtual Server使用

96

在前端架設一台Virtual Server不過此部份不在此份SOP討論範圍內有興趣

的讀者可參考 httpwwwlinuxvirtualserverorg 網站

1921680100 1921680200

Host A MasterSlave Server

Host B MasterSlave Server

Virtual Host

圖 Virtual Server + Two-way replication 架構圖

97

圖 High Availability Linux Virtual Server架構圖

98

  • COSA-SOP-03-006
  • 第一章 簡介
    • 11適用對象 (Audience)
    • 12 MySQL本身
    • 13 MySQL 40版跟50版重大的改進功能
    • 14 各家資料庫軟體比較
      • 第二章 前置需求
      • 第三章 安裝
        • 31 MySQL安裝
        • 32 phpMyAdmin安裝
        • 33 升級及注意事項
          • 第四章 MySQL管理
            • 41 Webmin 管理介面
            • 42 phpMyAdmin 的操作介面
            • 43管理指令介紹
              • 431 利用mysqladmin設定root的密碼
                  • 第五章 實用範例
                    • 51 任務一Web Base客戶通訊錄
                    • 52 任務二Web Base群組軟體 ( twig )
                      • 第六章 維護及更新程序
                        • 61 日常維護
                        • 62 更新程序
                        • 63 備份重要檔案
                        • 64 離線備份與還原
                        • 65 線上備份與還原
                          • 第七章 問題與解答
                          • 第八章 參考資料
                          • 附錄一 SQL Command 介紹
                          • 附錄二Replication
Page 42: DataBase Server Standard Operation Procedureebooks.lib.ntu.edu.tw/1_file/oss/63/93doc4-5.pdf · 業務的公司帶來了不少壓力,譬如微軟,甲骨文 ... 外的錢用在第三方的資料庫產品上,譬如就可以不用再購買甲骨文公司

圖 4-22

圖 4-23

42

圖 4-24

圖 4-25

43

423使用者管理

Step1建立使用者

圖 4-26

44

圖 4-27

Step2 給予權限

圖 4-28

Step3權限列表

45

圖 4-29

43管理指令介紹

431 利用 mysqladmin設定 root的密碼

當您在Windows 或 Linux 中安裝好 MySQL後系統會自動幫您建立兩個

帳分別是 root 和 匿名者MySQL的 root 跟 Linux 最高權限使用者 root無關MySQL的 root使用者相當於 MS SQL 中的 sa 帳號擁有最高的 Database管理權限但系統預設 MySQL的 root 是不需要密碼所以通常我們一安裝

MySQL後首要任務便是修改 root的密碼 我們可以利用 mysqladmin工具或是直接修改 MySQL內部資料庫的使用者資

料 mysqladmin ndashu root ndashh cosaexamplecom password lsquo1234rsquo

46

-u 表示使用者帳號root 為 MySQL預設的管理帳號

-h 表示 MySQL主機的主機名稱也可使用 IP Address password 表示使用者的密碼因為字串請使用單引號將密碼括起來 密碼設定完成之後還是可以利用 mysqladmin修改密碼但是你必須提供目前的密碼

432 連線 MySQL

mysql -uroot -p密碼 (-p和密碼之間不能有空白) 或 mysql -uroot -p (此方式會在進入後要求密碼) [rootossc phpMyAdmin] mysql -u root -p1234

Welcome to the MySQL monitor Commands end with or g

Your MySQL connection id is 25 to server version 32354

Type help or h for help Type c to clear the buffer

mysqlgt show databases

+----------+

| Database |

+----------+

| mysql |

| test |

+----------+

2 rows in set (000 sec)

mysqlgt exit

Bye

[rootossc phpMyAdmin]

433 建立資料庫

可利用 mysqladmin指令建立 CONTACT資料庫 mysqladmin -u root -p1234 create CONTACT

47

或是利用 mysql指令 [rootossc bluepage] mysql -u root -p1234 Welcome to the MySQL monitor Commands end with or g Your MySQL connection id is 1057 to server version 32354 Type help or h for help Type c to clear the buffer mysqlgt create database CONTACT Query OK 1 row affected (000 sec) mysqlgt show databases +----------+ | Database | +----------+ | CONTACT | | address | | hello | | mysql | | nuke | | test | +----------+ 6 rows in set (000 sec) mysqlgt exit

434 建立資料表

編寫 adresssql內容如下 -- Table structure for table address CREATE TABLE address ( id int(11) NOT NULL auto_increment name varchar(20) NOT NULL default tel varchar(15) NOT NULL default PRIMARY KEY (id) ) TYPE=MyISAM

48

-- Dumping data for table address INSERT INTO address VALUES (1林小明0800016888) INSERT INTO address VALUES (2黃大雄0800016888) INSERT INTO address VALUES (3劉小芬0800024365) 然後執行此 sql script mysql -u root -p1234 CONTACT lt addresssql 或是利 mysql command [rootossc bluepage] mysql -u root -p1234 Welcome to the MySQL monitor Commands end with or g Your MySQL connection id is 1090 to server version 32354 Type help or h for help Type c to clear the buffer mysqlgt use CONTACT Database changed Database changed mysqlgt CREATE TABLE address ( -gt id int(11) NOT NULL auto_increment -gt name varchar(20) NOT NULL default -gt tel varchar(15) NOT NULL default -gt PRIMARY KEY (id) -gt ) TYPE=MyISAM Query OK 0 rows affected (000 sec) mysqlgt INSERT INTO address VALUES (1林小明0800016888) Query OK 1 row affected (000 sec) mysqlgt INSERT INTO address VALUES (2黃大雄0800016888) Query OK 1 row affected (000 sec) mysqlgt INSERT INTO address VALUES (3劉小芬0800024365) Query OK 1 row affected (000 sec) mysqlgt exit Bye

49

第五章 實用範例

51 任務一Web Base客戶通訊錄

任職於開放科技公司的林小明前些日子在最符合成本效益的條件下快

速地完成公司網站的建置老闆因此對小明讚譽有加最近因為公司存放客戶資

料的 SQL Server主機屢遭病毒攻擊加上作業系統本身的問題當機次數頻繁

老闆希望能儘快把公司的客戶通訊錄程式移轉到較穩定的環境上因為此客戶通

訊錄程式最主要給內部人員使用所以介面美觀並不特別要求只求穩定且能快

速得到查詢結果老闆希望在短時間先看到程式的雛型並鍵入資料對其效率

及穩定性進行測試因為上次小明表現突出所以這次不可能的任務自然又落到

小明身上 小明想來想去既然要快速又穩定他而且又不希望所有人都得安裝 Client

程式於是小明決定)捨棄他的舊愛「Delphi+MS SQL」投向新歡「Apache + MySQL + PHP」利用此架構來設計一個簡單實用的Web Base客戶通訊錄程式

511 Web Base客戶通訊錄架構

此程式需要建立 CONTACT的資料庫並建立 adress Tables其結構如下表建立步驟請參考第三章 欄位名稱 資料型態 長度 說明 id INT (自動編號) 連絡人編號 name varchar文字 20 連絡人姓名 tel Varchar文字 15 連絡人電話 Web Base通訊錄共有下列幾個檔案功能如下表

檔案名稱 說明 Indexhtml Web Base通訊錄首頁 addphp 新增連絡人的 php程式 searchphp 尋找連絡人的 php程式 editphp 具有更新及刪除功能的 php程式

50

我們將這些檔案放至varwwwhtmlbluepage (預設無 bluepage目錄)

512 Web Base通訊錄測試

httpwwwopencombluepage 新增資料

圖 5-1 新增連絡人

圖 5-2 填入資料

51

圖 5-3 新增成功

搜尋及異動資料

圖 5-4 搜尋通訊錄

52

圖 5-5 編輯資料

圖 5-6 更新資料

513 程式內容及說明

lt-- 程式範例indexhtml--gt lthtmlgt ltheadgtlttitlegt通訊錄lttitlegtltheadgt ltbodygt ltcentergt

53

lth2gt通訊錄lth2gtlthrgt lta href=indexhtmlgt通訊錄ltagt | lta href=addphpgt新增連絡人ltagt | lta href=searchphpgt搜尋通訊錄ltagt ltcentergt ltbodygt lthtmlgt lt-- 程式範例addphp --gt lthtmlgt ltheadgtlttitlegt新增連絡人lttitlegtltheadgt ltbodygt ltcentergtlth2gt新增連絡人lth2gtltcentergtlthrgt lt 取得欄位資料 if (isset($_POST[Name]) ampamp isset($_POST[Tel]) ) $name = $_POST[Name] $tel = $_POST[Tel] 檢查是否有輸入欄位資料 if ($name = ampamp $tel = ) 建立 SQL字串 $sql = INSERT INTO address (name tel) values( $sql= $name $tel) 建立 MySQL 連結 $link = mysql_connect(localhostroot1234) 選擇資料庫 mysql_select_db(CONTACT) 執行 SQL指令 mysql_query($sql) mysql_close($link) echo ltfont color=redgt新增連絡人成功ltfontgtltbrgt gt ltform action=addphp method=postgt lttable border=0 width=300gt lttrgtlttdgt姓名 lttdgt

54

lttdgtltinput type=text name=Name size=20 maxlength=10gtlttdgtlttrgt lttrgtlttdgt電話 lttdgt lttdgtltinput type=text name=Tel size=20 maxlength=20gtlttdgtlttrgt lttrgtlttd colspan=2 align=centergt ltinput type=submit value=新增連絡人gtlttdgtlttrgt lttablegt ltformgt ltbrgtlta href=indexhtmlgt通訊錄ltagt | lta href=addphpgt新增連絡人ltagt | lta href=searchphpgt搜尋通訊錄ltagt ltbodygt lthtmlgt

lt-- 程式範例searchphp --gt lthtmlgt ltheadgtlttitlegt搜尋通訊錄lttitlegtltheadgt ltbodygt ltcentergtlth2gt搜尋通訊錄lth2gtlthrgt lt if (isset($_POST[Search])) 建立資料庫連結並選定資料庫 $link = mysql_connect(localhostroot1234) mysql_select_db(CONTACT) 建立基本的 SQL字串 $sql = SELECT FROM address 檢查是否輸入姓名 if (chop($_POST[Name]) = ) $name = name LIKE $_POST[Name] else $name = 檢查是否輸入電話號碼 if (chop($_POST[Tel]) = ) $tel = tel LIKE $_POST[Tel] else $tel =

55

if條件組合 SQL字串 if (chop($name) = ampamp chop($tel) = ) $sql= WHERE $name AND $tel elseif (chop($name) = ) 只有姓名 $sql = WHERE $name elseif (chop($tel) = ) 只有電話號碼 $sql = WHERE $tel $sql= ORDER BY name 最後加上排序 $result = mysql_query($sql) 取得欄位數 $total_fields = mysql_num_fields($result) echo lttable border=1gt echo lttrgtlttdgt編號lttdgtlttdgt姓名lttdgtlttdgt電話lttdgtlttd colspan=2gt功能選項lttdgtlttrgt 表格顯示查詢結果 while ($rows = mysql_fetch_array($result MYSQL_NUM)) echo lttrgt for ($i = 0 $i lt $total_fields $i++) echo lttdgt$rows[$i]lttdgt echo lttdgtlta href=editphpaction=editampid= echo $rows[0]gtltbgt編輯ltbgtlttdgt echo lttdgtlta href=editphpaction=delampid= echo $rows[0]gtltbgt刪除ltbgtlttdgt echo lttrgt echo lttablegtlthrgt mysql_free_result($result) mysql_close($link) gt ltcentergt ltform action=searchphp method=postgt lttable border=0 width=450gt lttrgtlttdgt搜尋姓名 lttdgt lttdgtltinput type=text name=Name size=10 maxlength=20gtlttdgtlttrgt lttrgtlttdgt搜尋電話 lttdgt lttdgtltinput type=text name=Tel

56

size=20 maxlength=20gtlttdgtlttrgt lttrgtlttd colspan=2 align=centergt ltinput type=submit name=Search value=搜尋gtlttdgtlttrgt lttablegt ltformgt ltbrgtlta href=indexhtmlgt通訊錄ltagt | lta href=addphpgt新增連絡人ltagt | lta href=searchphpgt搜尋通訊錄ltagt ltbodygt lthtmlgt

lt ob_start() gt lt-- 程式範例editphp --gt lthtmlgt ltheadgtlttitlegt編輯通訊錄lttitlegtltheadgt ltbodygt lt 取得 URL 參數 $id = $_GET[id] $action = $_GET[action] 建立資料庫連結 $link = mysql_connect(localhostroot1234) mysql_select_db(CONTACT) 選擇資料庫 執行的操作 switch ($action) case update 更新 取得欄位資料 $name = $_POST[Name] $tel = $_POST[Tel] $sql = UPDATE address SET name=$name tel=$tel WHERE id=$id mysql_query($sql) 執行 SQL指令 mysql_close($link) header(Location searchphp) 轉向到 serachphp break case del 刪除 $sql = DELETE FROM address WHERE id=$id

57

mysql_query($sql) 執行 SQL指令 mysql_close($link) header(Location searchphp) 轉向到 serachphp break case edit 編輯 $sql = SELECT FROM address WHERE id=$id $result = mysql_query($sql) 執行 SQL指令 $row = mysql_fetch_row($result) 取回記錄 $name = $row[1] 取得欄位 name $tel = $row[2] 取得欄位 tel mysql_close($link) 顯示編輯表單 gt ltcentergtlth2gt更新通訊錄lth2gtltcentergtlthrgt ltform action=editphpaction=updateampid=lt echo $id gt method=postgt lttable border=0 width=300gt lttrgtlttdgt姓名 lttdgt lttdgtltinput type=text name=Name size=20 maxlength=10 value=lt echo $name gtgtlttdgtlttrgt lttrgtlttdgt電話 lttdgt lttdgtltinput type=text name=Tel size=20 maxlength=20 value=lt echo $tel gtgtlttdgtlttrgt lttrgtlttd colspan=2 align=centergt ltinput type=submit value=更新連絡人gtlttdgtlttrgt lttablegt ltformgt ltbrgtlta href=indexhtmlgt通訊錄ltagt | lta href=addphpgt新增連絡人ltagt | lta href=searchphpgt搜尋通訊錄ltagt lt break gt ltbodygt lthtmlgt

58

52 任務二Web Base群組軟體 ( twig )

順利完成Web Base客戶通訊錄程式測試一段時間後「Apache + MySQL + PHP」架構的穩定與快速巳深得老闆與公司所有同事的認同隨著公司業績蒸

蒸日上人員組織編罝愈來愈龐大跨部門的會議愈來愈多業務員每日排滿拜

訪客戶的行程跟客戶的 Email的往來也愈來愈頻繁 愈來愈多部門的同事希望公司能建置一套群組軟體提供 web mail可讓業

務人員方便收發 mail還有連絡人議事日程待辦工作書簽等功能讓整個

公司運作及個人時間管理更有效率

老闆問小明對這些需求有什麼看法小明認為如果這些功能完全由程式部

門開發必定曠日費時而且耗費公司資源小明在網路尋找是否有提供這些功能

的Free Software皇天不負苦心人小明發現了TWIG (The Web Information Gateway) httptwigscrewdrivernet這個群組軟體它在 Web 上整合郵件新聞聯絡人議事日程工作序書簽等功能非常符合公司的需求 Step 1 下載 twig-277targz 下載網址 httptwigscrewdrivernetdownloadphp3

Step 2 解開 twig-277targz tar -xzvf twig-277targz

59

Step 3 執行安裝動作安裝到 varwwwhtmltwig 目錄 cd twig-277 twig-install varwwwhtmltwig

Step 4 建立 MySQL 資料庫(twig)及各資料表

cd setup mysql -u root -p1234 mysqlgt create database twig Query OK 1 row affected (001 sec) mysqlgt quit mysql -u root ndashp1234 twiglt twigtablemysql

Step 5 修改 configincphp3 參數設定 vi varwwwhtmltwigconfigconfigincphp3 $config[fromdomain] = opencom 網域 $config[language] = chinesebig5 中文訊息 $config[imap_port] = 143notls

60

Step 6 修改連結 MySQL 的帳號密碼 vi varwwwhtmltwigconfigdbconfigincphp3 $dbconfig[sqlusername] = root username $dbconfig[sqlpassword] = 1234 password

Step 7 其他設定檔

vi etchttpdconfhttpdconf 加入 AddType applicationx-httpd-php php3 在 DirectoryIndex最後加入 indexphp3 DirectoryIndex indexhtml indexhtmlvar indexphp3 在 AddDefaultCharset ISO-8859-1加上 AddDefaultCharset ISO-8859-1

vi etcphpini register_globals = On service httpd restart Step 8 sendmail 設定 vi etcmailsendmailcf在 264 行前面加上並重新啟動 sendmail「service snedmail restart」 262 SMTP daemon options 263 264 O DaemonPortOptions=Port=smtpAddr=127001 Name=MTA 265 266 SMTP client options 267 O ClientPortOptions=Family=inet Address=00

61

Step 9 檢查設定有無錯誤 http主機名稱twigtestphp3

62

Step 10 登入 twig ( http主機名稱twig)

63

第六章 維護及更新程序

61 日常維護

系統管理員最好定期以 root 身份登入看看信件在 RedHat Linux 中有一支 logwatch 程式會定時去分析 log file如果發現異常便會發信給 root除此之外筆者建議讀者平時就檢查 MySQL log file ( varlogmysqldlog)是否有異常情形

62 更新程序

讀者可至httprpmfindnet 尋找MySQL相關套件至於升級的相關步驟請參

考Linux OS SOP 第 54節

63 備份重要檔案

預設 MySQL 的 DB 檔案是存在 varlibmysql 內以 DB名稱為目錄目錄

內就是該 DB 的所有資料通常得定期備份還有 MySQL的設定檔 etcmycnf也別忘了一起備份

64 離線備份與還原

641 離線備份

預設 MySQL 的 DB 檔案是存在 varlibmysql 內以 DB 名稱為目錄目錄內

就是該 DB 的所有資料像 CRM 這個 DB就是存在 varlibmysqlCRM 內在備份前因為怕資料尚未完全寫入磁碟而且 MySQL 會 Lock 在使用的 DB 檔案所以應該是要先把 MySQL 先 Shutdown 一下整個備份的程序可以下像下面的指令去完成 cd varlibmysql

64

service mysqld stop tar cvfz CRM_db_20030905tgz CRM service mysqld start 對這樣就可以了 不過要注意的是怕 DB 內每個 Tables 間的資料有關關

聯性所以最好是把整個 DB 一次備起來單獨只備哪個 Tables 的檔案以後回存時怕會有資料關聯不一致的問題

642 離線還原

DB 發生錯誤而要回存時其實也不難先找出最近一次完整正常的備份先把現在錯誤的網頁或 DB 先更名或 tar 起來再把好的備份給解開回原來目錄位

置就行了需要注意的是 MySQL 服務最好也是要先停止回存完成後再啟動服務回存 DB 的整個程序可能像下面 cd varlibmysql service mysqldstop mv CRM CRM_OLD tar xvfz CRM_db_20030905tg service mysqld start

65 線上備份與還原

651 線上備份

使用像上面的檔案方式備份是個不錯的方法它最少可以保持該主機某個時間點的完整檔案備份但還是有一些問題需要考慮到有些主機就不只建立一個 DB 而已總不能為了備份某個 DB 而把整個 MySQL 服務停止備份檔案的方式回存在原主機上一定適用但假如 MySQL 版本升級或是在那天該網頁空間需遷機移機到別的主機時那就沒人敢保證備出來的資料檔可以用所以我們可以考慮另一種備份的方式是使用 MySQL 本身提供的功能 MySQL Data Dump指令是 mysqldump

65

使用 MySQL 的 Dump 功能可以把 DB 的結構資料或結構加資料 Dump 成文字檔 mysqldump 指令提供的彈性很大你可以選擇把整個 DB Dump 成一個檔或是每個 Table 為一個檔甚至是把結構檔和資料分開儲存都

可以 mysqladmin -uroot -p flush-logs mysqldump CRM -uroot -p --opt gt CRM_20030905sql (CRM 是 DB 名稱 opt 是一個使用完整 Dump 參數) 假如只是要單獨 Dump 某個 Table 時只要在上面的指令後轉出符號 gt 前加個 Table 名稱就可以如只要 phpbb2_users 這個 Table 的 Dump 時只要下 mysqldump CRM -uroot -p --opt CUSTOMER gt CRM_CUSTOMER_20030905sql

652 線上還原

若要回存整個資料庫只需將壓縮的備份檔還原成 Dump 的檔案再用下面的指令回存 mysql CRM -uroot -p lt CRM_20030905sql 這邊需注意的是若建立備份時是以--opt或--add-drop-table為參數時回存的 動作是先將舊的 Table 先刪除重建 Table 的結構後再把 Data 匯入所以回存後所有的資料會回到你當時備份那個時間點因此在回存資料時可以考慮把現有錯誤或不完整的 DB 先備份一份下來以備不時之需或是拿來比對錯誤的地

方在那裡當然你也可以把資料回存到另一個測試用的 DB 內只要把上面指令

的 DB 名稱改成你的測試用 DB 名稱即可 使用這種回存方式 MySQL 服務不需停止也不會動到其他正在使用的 DB 在一些提供 MySQL 服務的虛擬主機可用這種方式作你自己的 DB 備份及回存

66

另外假如你是系統重建或是移機時切需在新的 MySQL 內新建一個空白 DB 後才行作回存的工作你可以用下面的指令建立 mysql -uroot -p -e CREATE DATABASE CRM (上面的 CRM是你要新建的 DB 名稱) 另一種作法先用 mysql 指令進入 mysql client console 然後再用 CREATE DATABASE CRM 這樣就行了記得尾端要加個 符號該行指令才會執行

67

第七章 問題與解答

Q1RedHat 90預附的 MySQL到底有無支援 Transcation機制 Ans MySQL自 32334a之後的 MySQL-Max版本加入 InnoDB的資料庫類型透過

InnoDBMySQL同樣可以進行 COMMIT與 ROLLRACK的動作RedHat 90預附的 MySQL為 32354a-11巳支援 InnoDB的資料庫類型不過必須做以

下設定 1cp usrsharedocmysql-server-32354amy-mediumcnf to etcmycnf 2 vi etcmycnf 將以下設定前的拿掉 innodb_data_home_dir = varlibmysql innodb_data_file_path = ibdata110Mautoextend innodb_log_group_home_dir = varlibmysql innodb_log_arch_dir = varlibmysql 3service mysqld restart 如此一來各位在建立Table時便可指定Table Type為 innodb ( ex create table with type=innodb ) Q2如何解決 php+mysql 許功蓋等字變亂的問題 Ans 方法一 【確定 MySQL 預設的字元集】 1 打開 WinMySQLadmin 管理畫面(在視窗右下角狀態列紅綠燈圖示中按滑鼠

右鍵點選 Show me 選項) 2 點選管理畫面中 [Variables] 標籤選項其中 character_set變數就是您預設

字元集的變數其預設是 latin1 字元集(我們要將他改回 big5)而 chatacters_set 變數則是 MySQL 可以支援哪些字元集 【修改預設字元集變數 character_set 】 1 請點選管理畫面中 [myini Setup] 標籤選項設定 myini 2 按一下 [Pick-up and Edit myini values] 按鈕以便編輯目前的 myini 設定 3 在 [mysqld] 設定區塊底下新增一行 default-character-set = big5 變數設

68

定 4 新增一個 [client] 設定區塊並加入第三步驟的變數設定(游標往下移到空白處新增兩行 [client] 和 default-character-set=big5) 5 按一下畫面左下方 [Save Modification] 按鈕儲存設定 6 重新啟動 MySQL 或 Windows 方法二 Server端注意事項 phpini 中有關的設定為(預設值) Magic quotes for incoming GETPOSTCookie data magic_quotes_gpc = On Use Sybase-style magic quotes (escape with instead of ) magic_quotes_sybase = Off Client端注意事項 1中文資料送進 mysql 前請用 addslashes($str) 處理 2處理後送進 mysql 時請用 括起來並在參數後留一個空白如 $sql = UPDATE ezf_table set tablename=$tname tableend=$endtime table inguser=$tguser tableingid=$tguserid tableallnumber=$tnumber tableloca l=$tablelocal tableanyone=$tableopen tabletext=$ttext WHERE tableid=$t ableid tablename=$tname c 取出時請用 stripslashes($str) Q3MySQL root 密碼忘了該怎麼辦 Ans 1先停掉 mysql etcrcdinitdmysql stop 2以--skip-grant-table 的參數啟動 mysql safe_mysql --skip-grant-tableamp 3 更改 root 密碼 mysql mysql mysqlgt UPDATE user SET password=password(newpassword)

69

WHERE user=root mysqlgt FLUSH PRIVILEGES mysqlgt exit 4停掉 mysql再重跑 mysqladmin -uroot -p shutdown Enter password 輸入新設定的密碼 etcrcdinitdmysql start

Q4NULL值問題

Ans

NULL值的概念是造成 SQL的新手的混淆的普遍原因他們經常認為 NULL是和一個空字符串的一樣的東西不是這樣的例如下列語句是完全不同的

mysqlgt INSERT INTO my_table (phone) VALUES (NULL)

mysqlgt INSERT INTO my_table (phone) VALUES ()

兩個語句把值插入到 phone 列但是第一個插入一個 NULL值而第二個插入一個空字符串第一個的含義可以認為是ldquo電話號碼不知道而第二個則可意味

著ldquo她沒有電話

在 SQL中NULL值在于任何其他值甚至 NULL值比較時總是假的(FALSE)包含 NULL的一個表達式總是產生一個 NULL值除非在包含在表達式中的運算符和函數的文檔中指出在下列例子所有的列返回 NULL

mysqlgt SELECT NULL1+NULLCONCAT(InvisibleNULL)

如果你想要尋找值是 NULL的列你不能使用=NULL測試下列語句不返回任

何行因為對任何表達式expr = NULL是假的

mysqlgt SELECT FROM my_table WHERE phone = NULL

要想尋找 NULL值你必須使用 IS NULL測試下例顯示如何找出 NULL電話號碼和空的電話號碼

70

mysqlgt SELECT FROM my_table WHERE phone IS NULL mysqlgt SELECT FROM my_table WHERE phone =

在 MySQL中就像很多其他的 SQL服務器一樣你不能索引可以有 NULL值的列你必須聲明這樣的列為 NOT NULL而且你不能插入 NULL到索引的

列中

當用 LOAD DATA INFILE 讀取數據時空列用更新如果你想要在一個列中有

NULL值你應該在文本文件中使用N字面上的詞NULL也可以在某些情形下使用

當使用 ORDER BY時首先呈現 NULL值如果你用 DESC以降序排序NULL值最後顯示當使用 GROUP BY時所有的 NULL值被認為是相等的

為了有助于NULL的處理你能使用 IS NULL和 IS NOT NULL運算符和 IFNULL()函數

對某些列類型NULL值被特殊地處理如果你將 NULL插入表的第一個TIMESTAMP 列則插入當前的日期和時間如果你將 NULL插入一個AUTO_INCREMENT 列則插入順序中的下一個數字

Q5如何將圖片存放於 MySQL中

Ans

Step 1建立資料庫 test

Step 2 建立表格 binary_data

CREATE TABLE binary_data (

id INT(4) NOT NULL AUTO_INCREMENT PRIMARY KEY

description CHAR(50)

bin_data LONGBLOB

filename CHAR(50)

filesize CHAR(50)

filetype CHAR(50)

71

)

Step 3 利用 storephp 寫入圖片

storephp 程式碼

ltHTMLgt ltHEADgtltTITLEgtStore binary data into SQL DatabaseltTITLEgtltHEADgt ltBODYgt lt code that will be executed if the form has been submitted

if ($submit) mysql_connect(localhostrootYOUR_PASSWORD) mysql_select_db(test) $data=Base64_Encode(fread(fopen($form_data r) filesize($form_data))) $result=MYSQL_QUERY(INSERT INTO binary_data (descriptionbin_datafilenamefilesizefiletype) VALUES ($form_description$data$form_data_name$form_data_size$form_data_type)) $id= mysql_insert_id() print ltpgtThis file has the following Database ID ltbgt$idltbgt MYSQL_CLOSE() else else show the form to submit new data

gt

ltform method=post action=ltphp echo $PHP_SELF gt enctype=multipartform-datagt File Descriptionltbrgt ltinput type=text name=form_description size=40gt ltINPUT TYPE=hidden name=MAX_FILE_SIZE value=4000000gt ltbrgtFile to uploadstore in databaseltbrgt ltinput type=file name=form_data size=40gt ltpgtltinput type=submit name=submit value=submitgt ltformgt lt

72

gt ltBODYgt ltHTMLgt

Step 3 利用 storephp 取出圖片

getdataphp 程式碼

lt Syntax getdataphp3id=ltidgt if($id) you may have to modify login information for your database server MYSQL_CONNECT(localhostrootYOUR_PASSWORD) mysql_select_db(test) $query = select bin_datafiletype from binary_data where id=$id $result = MYSQL_QUERY($query) $data = Base64_Decode(MYSQL_RESULT($result0bin_data)) $type = MYSQL_RESULT($result0filetype) Header( Content-type $type) echo $data gt

Q6MySQL裝好之後啟動時或是執行 mysqladmin會出現如下訊息 Cant connect to local MYSQL Server through Socket varlibmysqlmysqlsock或是

Cant connect to local MYSQL Server through Socket tmpmysqldsock

Ans 可能有下列幾個原因

1這個 mysqldsock 不見了被某人刪除了或是被一些系統自動執行程式給刪

了例如有些 cron任務便會設定定期刪除 tmp 裡的東西所以呢您只能修改

cron 裡的設定讓它不要清除 mysqldsock 2在啟動時也可以改變 mysqldsock的位置您在啟動 MySQL的時候可以加入此參數usrlocalmysqlbinsafe_mysqld --user=mysql --socket=其他路

徑socket amp 同時得去設定環境變數 MYSQL_UNIX_PORT的值以指定新的

73

路徑 3若是您沒改 MYSQL_UNIX_PORT的值那麼您可以在執行指令的時候才打

例如mysqladmin --socket=其他路徑socket version Q7How to get the last insert id Ans CREATE TABLE product ( id INT(4) NOT NULL AUTO_INCREMENT PRIMARY KEY description VARCHAR(50) ) 1利用 SQL的話 mysqlgt insert into product(description) values(123) Query OK 1 row affected (000 sec) mysqlgt select last_insert_id() +------------------+ | last_insert_id() | +------------------+ +------------------+ 1 row in set (000 sec) ======================================== 2如果是 PHP的話 你可以用mysql_insert_id()取得該 id PHP example $result=MYSQL_QUERY(INSERT INTO product (description) VALUES ($description)) $id= mysql_insert_id() print This file has the following Database ID $id Q8如何將文字檔匯入資料庫 Ans $addr=homehttpdhtmlphpschool001txt $sql_select = load data infile $addr into table test fields terminated by t 解說 $sql_select = load data infile 文字檔名 into table 表格名 fields terminated by

74

t

(欄位分隔以 TAB鍵) 該文字檔須與資料表欄位格式相符 例如欄位有三個 則文字檔為每行一筆資料如下 欄 1資料ltTABgt欄 2資料ltTABgt欄 3資料 欄 1資料ltTABgt欄 2資料ltTABgt欄 3資料 欄 1資料ltTABgt欄 2資料ltTABgt欄 3資料 欄 1資料ltTABgtltTABgt欄 3資料

Q9如何撰寫 MySQL C API Ans Step 1利用文字編輯器撰寫以下程式碼 mysqlcc

include ltstdiohgt

include ltmysqlmysqlhgt

int main (int argc char argv[])

MYSQL mysql

MYSQL_RES res

MYSQL_ROW row

if (argc = 2)

fputs (Usage myc ltdatabasegt stderr)

return 1

if ((mysql_connect(ampmysqllocalhostrootYour_Password)))

fputs (Error connecting stderr)

abort()

75

if (mysql_select_db(ampmysqlargv[1]))

fputs (Error selecting database stderr)

abort()

if (mysql_query(ampmysqlSELECT FROM test_table))

fputs (Error processing query stderr)

abort()

if ((res = mysql_store_result(ampmysql)))

fputs (Error storing results stderr)

abort()

while((row = mysql_fetch_row(res)))

uint i = 0

for (i=0 i lt mysql_num_fields(res) i++)

printf(s row[i])

printf(n)

return 0

Step 2 Compile

gcc -Iusrlocalmysqlinclude -Lusrlocalmysqllibmysql mysqlcc ndashlm -lmysqlclient

(其中 include path與 library path取決於你的 MySQL安裝路徑)

76

如果執行時發生如下 error Run problemerror in loading shared libraries libmysqlclientsoX 將你的 MySQL library path(for exampleusrlocalmysqllibmysql) 加入etcldsoconf and run sbinldconfig -v Q9ASP + MySQL 範例程式 Ans Dim myconn As New ADODBConnection Dim myrs As New Recordset Dim mySQL As String Dim myrows As Long myconnOpen DSN=MyODBCsample mySQL = SELECT from user myrsSource = mySQL Set myrsActiveConnection = myconn myrsCursorLocation = adUseClient myrsOpen myrows = myrsRecordCount myrsClose myconnClose 可參考 httpwwwdwamnetmysqlasp_myodbcasp 有詳細的資料 Q10如何將 MySQL中的資料庫匯出成txt檔 Ans select from TableName into outfile textxls all result fields will seperate by tab

77

第八章 參考資料

英文部份 網址 1 httpwwwmysqlcom MySQL 網站有第一手有關 MySQL的資料 2 httpwwwmysqlcomdocenReplicationhtml 有關 MySQL Replication 的文件 3 httpwwwgeocitiescomsqlhomefaqstore_blobhtml 如何在 MySQL 存放 BLOB的資料 4httpwwwsapdborg 有關 SAP跟 MySQL相關合作的網站 書藉 1 Cooking with MySQL

Paul DuBois has selected sample recipes from the hundreds youll find in his book MySQL

Cookbook In this third and final series of excerpts showcasing these recipes learn how to

compute team standings how to calculate the differences between successive Dec 26

2002 2 Tips for Building Web Database Applications with PHP and MySQL by Hugh E Williams co-author of Web Database Applications with PHP amp MySQL 04042002

3 Managing and Using MySQL 2nd Edition By Tim King George Reese Randy Jay Yarger

4 MySQL Cookbook By Paul DuBoisPublisher OReillyPub Date October 2002

中文部份

78

1 httplinuxtncedutwtechdocmysqlmysql_docmanual_tochtml MySQL 中文手冊 2 httpchenshloxaedutwphpZ_1php PHP+MySQ程式研習設計網站 3 httplinuxtncedutwtechdocbanicdownhtml PHP 4 手冊 4 httpwwwtncedutwadmin_zonephp台南縣教育網網路中心有很多 Linux相關文件 5 httpdobtncedutw網站建置百寶箱有很多 PHP MySQL 相關範例程式 5 httpwwwdbworldcomtw資料庫專家電子雜誌介紹資料庫的重要觀念及名詞

79

附錄一 SQL Command 介紹

SQL (讀音ess-que-el) 是一種結構查詢語法SQL 使用於資料庫交流

傳遞相容於 ANSI (American National Standards Institute) 是一套標準的關聯

式資料庫語言 SQL 語言是執行更新或從資料系統獲取資料一般常見的關聯

資料庫系統都有提供 SQL 如 Oracle Sybase Microsoft SQL Server Access Ingres 等雖然大部份的資料庫都有提供 SQL 但也多提供了自已獨特的語

法造成了不相容的情形但標準基本的語法是相通的如Select Insert Update Delete Create and Drop 每一個系統都有支援

Table相關 Command

Create Table

關聯式資料庫包含有很多元件稱為資料表(tables) 把資料或訊息放在資

料表中 資料表是以不同的名稱做分別資料表由欄列所構成的二維陣列

欄包含欄位名資料型態 及其他可判斷的資訊列是由全部欄位構成一筆一

筆的紀錄 create table 語法用在建立一個新的資料表語法格式如下

create table tablename (column1 data type column2 data type column3 data type)

Format of create table if you were to use optional constraints

create table tablename (column1 data type [constraint] column2 data type [constraint] column3 data type [constraint]) [ ] = optional

Note You may have as many columns as youd like and the constraints are optional

80

Example

create table employee (first varchar(15) last varchar(20) age number(3) address varchar(30) city varchar(20) state varchar(20))

注意建立資料表格式要以括號把前後框住而最後以(分號)做結尾

欄位名不要超過 30個字元長而且不要使用 sql 的關鍵字(如 where select等)而在後面接是型態的宣告(如字串數字日期格式等)

資料型態是來描述欄位的方式如一個欄位Last_Name 是一個姓氏可以使用varchar (可變動長度字串) 資料型態

以下是幾個常見的資料庫型態 char(size) 固定長度字串最長為 255 位元 varchar(size) 變動長度字串最大字元數以 size 來指定 number(size) 數值格式可以是整數也可以是小數最大數字以 size 位數判

斷未指定小數位數由系統內定 date 日期格式 number(sized) 數值格式最大數字以 size 位數判斷d 為小數位數整數位

數為 size-d 位

有何限制當資料表被建立通常有一或數個欄位是要使用來做關聯的功

能 例如unique 限制(唯一值)兩筆記錄不可以相同的值 not null (非空值)該欄位一定要輸入資料不可是空的primary key (主鍵)是每一筆記錄識別的主要方式

Drop a table drop table 刪除資料表(其中的資料也會一併刪除)

drop table tablename

Example

81

drop table 和刪除全部資料是不同的刪除全部資料欄位名稱資訊等還會

存在但刪除資料表會把這一些也一併移除掉

如何查詢資料

Select 基本用法

select 語法是關連式資料庫最常用的部份可以取得你想要的資料這是一個

簡單的範例 select column1[column2etc] from tablename [where condition] [] = optional 在 select 之後所列欄位名則是要顯示的資料部份你可以一一列出各欄位

名或是以 (星號)來代表選擇全部的欄位 from 之後放資料表名稱 where 子句 (選項) 指定要過濾的條件符合者才會顯現 where 可使用的條件運算元 = 等於 gt 大於 lt 小於 gt= 大或等於 lt= 小或等於 ltgt 大相等 LIKE 相似 For example select first last city

82

from empinfo where first LIKE Er 以Er 為開頭的字串就符合要以單引號框住 Or you can specify select first last from empinfo where last LIKE s 最後一字為 S 就符合 select from empinfo where first = Eric 則表示 first name 一定要是 Eric 才可以 範例資料表empinfo 統計函數

MIN 傳回指定欄位最小值

MAX 傳回指定欄位最大值

SUM 傳回指定欄位總和

AVG 傳回指定欄位平均值

COUNT 傳回指定欄位的筆數

COUNT() 傳回資料庫中的總筆數

統計函數使用於資料表中的數值欄位配合 SELECT 語法使用 只用於總結特定單一欄位可以配合 GROUP BY 做篩選但也可以不使用 GROUP BY 語句For example

SELECT AVG(salary) FROM employee

83

傳回全部 salary 平均值

Another example

SELECT AVG(salary) FROM employee WHERE title = Programmer

傳回 salary 平均值條件為 employees 資料表中當 title 等於 Programmer

Example

SELECT Count() FROM employees

傳回 employees 資料表中紀錄總筆數

GROUP BY 語法 SELECT column1 SUM(column2) FROM list-of-tables GROUP BY column-list The GROUP BY 語句可以先以所列的欄位為條件分組排序在一起(可以多欄

位) example 要列出每一個 dept 中最高 salary 值 SELECT max(salary) dept FROM employee GROUP BY dept HAVING 語法

SELECT column1 SUM(column2) FROM list-of-tables GROUP BY column-list HAVING condition

HAVING 子句是 GROUP BY 的一部份用來過濾在 GROUP BY 所選出的資料功能如同 select 命令中 where 條件式一樣只是 HAVING 必需配合 GROUP BY 使用

我們以例子來說明我們要取得每一公司名及每一公司的薪水平均值輸入如下

84

SELECT dept avg(salary) FROM employee GROUP BY dept

但如果我們只列出薪資平均值超過 20000元的公司資料

SELECT dept avg(salary) FROM employee GROUP BY dept HAVING avg(salary) gt 20000

ORDER BY子句語法

SELECT column1 SUM(column2) FROM list-of-tables ORDER BY column-list [ASC | DESC]

[ ] =選項

ORDER BY是一個選項子句當你以排序方式來顯示資料(正向由小到大反向由大到小)以指定的欄位資料做排序

ASC = 正向- 預設值 DESC = 反向排序

For example

SELECT employee_id dept name age salary FROM employee_info WHERE dept = Sales ORDER BY salary

以上列出公司代號公司名銷售員人名年紀及薪資而條件是公司名為 Sales 顯示順序以薪資多少排序(由小到大為預設值)

如果要以多個欄位做排序要以逗號做分隔如下

SELECT employee_id dept name age salary FROM employee_info WHERE dept = Sales ORDER BY salary age DESC

85

結合條件及布林運算 SELECT column1 SUM(column2) FROM list-of-tables WHERE condition1 AND condition2 AND運算可以結兩個或以上的條件放在 WHERE子句中 兩者都要為真才

會顯示該筆記錄 OR 運算可以結兩個或以上敘述放在 WHERE子句中只要其中一個為直就

會顯示該筆記錄 For example SELECT employeeid firstname lastname title salary FROM employee_info WHERE salary gt= 5000000 AND title = Programmer 必需要薪資大於等於 50000而且職稱為 Programmer同時符合才會顯示該筆資料 以下以括號括住雖然不是必需的但如此比較容易讀 SELECT employeeid firstname lastname title salary FROM employee_info WHERE (salary gt= 5000000) AND (title = Programmer) 另外範例 SELECT firstname lastname title salary FROM employee_info WHERE (title = Sales) OR (title = Programmer) 條件為只要是 Sales 或 Programmer 職稱的就會被列出 IN and BETWEEN 子句

SELECT column1 SUM(column2) FROM list-of-tables WHERE column3 IN (list-of-values) SELECT column1 SUM(column2) FROM list-of-tables WHERE column3 BETWEEN value1 AND value2 IN 子句使用在列舉項目的使用上也就是分別測試是否符合所列的值 For example

86

SELECT employeeid lastname salary FROM employee_info WHERE lastname IN (Hernandez Jones Roberts Ruiz) 條件為姓氏(astname)要符合 Hernandez Jones Roberts or Ruiz 其中一個才會被傳回 IN運算元也可以使用 OR 的語法來取代如下結果相同 SELECT employeeid lastname salary FROM employee_info WHERE lastname = Hernandez OR lastname = Jones OR lastname = Roberts OR lastname = Ruiz 但使用 IN 句子比較短也比較易懂 你也可以使用 NOT IN 來去掉不要的記錄 BETWEEN 運算元使用在判斷是否存在兩個數值之間 For example SELECT employeeid age lastname salary FROM employee_info WHERE age BETWEEN 30 AND 40 傳回年紀 30歲到 40歲之間的資料(含 30及 40歲者) 相同的也可以使用以下語法來達到相同的結果 SELECT employeeid age lastname salary FROM employee_info WHERE age gt= 30 AND age lt= 40 你也可使用 NOT BETWEEN 來濾掉中間值的資料 數學運算 標準 ANSI SQL-92 提供以下運算

87

+ 加

- 減

餘數

餘數為除法後剩整數這不在標準的 ANSI SQL 中但大部份的資料庫都會支

援這運算元以下列出有用的函數雖不在 ANSI SQL-92 提供但一般資料庫

也會支援他們

ABS(x) 傳回 x 絕對值

SIGN(x) returns the sign of input x as -1 0 or 1 (negative zero or positive respectively)

MOD(xy) 餘數 - returns the integer remainder of x divided by y (同 xy)

FLOOR(x) 傳回小或等於 x 的最大整數值

CEILING(x) or CEIL(x)

傳回大或等於 x 的最小整數值

POWER(xy) x的 y 次方

ROUND(x) 把 x 四捨五入為整數

ROUND(xd) 四捨五入取到小數 d 位

SQRT(x) x 開平方

For example SELECT round(salary) firstname FROM employee_info 傳回薪資取到整數位

如何新增資料

insert 加入一筆新紀錄到資料表中 insert into tablename (first_columnlast_column) values (first_valuelast_value) [] = optional Example insert into employee

88

(first last age address city state) values (Luke Duke 45 2130 Boars Nest Hazard Co Georgia) Note 字串要以單引號住如string 數字框住也無妨 insert into 後面接資料表名稱再接以括號括住的欄位名在 values 後括號分別對映各欄位的值 以上的例子新增了一筆名(first) 為 Luke而住所(state) 為 Georgia 的資料

如何刪除資料

delete 可以刪除單筆或多筆紀錄 delete from tablename where columnname OPERATOR value [and|or column OPERATOR value] [ ] = optional Examples delete from employee Note 如果你沒有指定 where 子句那麼全部的紀錄都會被刪除 delete from employee where lastname = May delete from employee where firstname = Mike or firstname = Eric delete from 接著資料表名 再接著是條件式判斷沒有條件式則全部紀錄會

被刪除

如何更新資料

update 用來更新你所指定的記錄要和 WHERE 配合小心使用 語法 update tablename set columnname = newvalue[nextcolumn = newvalue2] where columnname OPERATOR value [and|or column OPERATOR value] [] = optional Examples

89

update phone_book set area_code = 623 where prefix = 979 update phone_book set last_name = Smith prefix=555 suffix=9292 where last_name = Jones update employee set age = age+1 where first_name=Mary and last_name=Williams

90

附錄二Replication

測試環境

RedHat 90 + MySQL 32358 MySQL資料庫路徑 varlibmysql MySQL設定檔 etcmycnf Master IP 1921680100 Slave IP 1921680200 請至下列網址下載最新MySQL 32358套件並利用rpm ndashUvh 更新 httpupdatesredhatcom9enosi386

圖 最新 MySQL 套件

測試架構圖

91

1921680100

1921680200Master Server

erveSlave S r

圖 測試架構圖

測試步驟

Master server 部份 Step1 確認 MasterSlave機器上所裝的 MySQL版本能進行

replication( 32329 or higher ) Step2 在 Master MySQL上開放一個帳號給 Slave mysql ndashu root ndashp mysqlgtGRANT FILE ON TO repl1921680200 IDENTIFIED BY lsquoabc123rsquo mysqlgtq 上面是 Master開放一個帳號 repl密碼 abc123給 IP1921680200有檔案處理

的權限 Step3 shutdown MySQL on the Master mysqladmin ndashu root ndashp shutdown Step4 備份 Master所有資料庫 tar ndashcvf tmpmysql-snapshottar varlibmysql 注意tar的時候MySQL是要在 stop情況下 在mysql (wwwmysqlcom) 網站的FAQ有不用shutdown的方法

92

Step5 在 master機器上修改etcmycnf 在[mysqld]區段內加入參數 log-bin server-id=這邊設定 server-id=1 sql-bin-update-same binlog-do-db=CRM只針對 CRM資料庫做紀錄 Step6 Restart MySQL on the master service mysqld start 此時因為有加入 log-bin 參數因此開始有 index產生了在varlibmysql目錄下

有index檔案紀錄資料庫的異動 log Slave server 部份 Step1 在 slave設定etcmycnf 在[mysqld]區段加入 master-host= master-user= master-password= master-port= server-id= 這邊設定 master-host=1921680100 master-user=repl master-password=abc123 master-port=3306 server-id=2 master-connect-retry=60預設重試間隔 60秒 replicate-do-db=CRM告訴 slave只做 CRM資料庫的更新 log-slave-updates Step2 將 master上的 mysql-snapshottar copy到 slave上 用 ftp傳到 slave的tmp Step3 解壓縮 Master資料庫至 Slave Server上 cd varlib tar xvf tmpmysql-snapshottar chown ndashR mysqlmysql mysql

93

chmod ndashR 770 mysql (視情況) Step4 Restart MySQL on the slave server 這時在varlibmysql目錄會出現 masterinfo此檔案紀錄了 Master MySQL server的資訊

狀況測試

One-way replication

1921680100

1921680200Master Server

erveSlave S r

圖 One-way replication架構圖 Step1 Master跟 Slave網路及服務都正常情況下由 Master端異動資料後 到 Slave端瀏覽資料檢視是否有進行 replication Step2 模擬 Slave Server 當機 可用在於 slave真的當機或是 Slave 不一定需要一直跟 master connect將Slave MySQL server shutdown由 Master端異動資料到 slave端瀏覽此時Slave應該沒有被 replication 更新然後再將 Slave端 MySQL server start起來

預設 60秒後 Slave會嘗試跟 Master要求進行 replication再去 Slave端檢視是否有更新資料

94

Step3 模擬 Master當機因為是設定 One-way replication一旦 Master Server Slave端沒有 Master的 source可以 download Two-way replication 基於 Master當機狀況於是發展雙向 Replication即 1921680100 ( Host A ) 1921680200 ( Host B )都分別擔任 MasterSlave身分

1921680100

1921680200er

Server B MasterSlave Server

Server A MasterSlave Serv

圖 Two-way replication架構圖 以下是針對兩台 MySQL伺服器進行雙向 Replication Step1觀念同單向 replication只是改成 Master也有 Slave身分 Slave也有Master的身分先分別在 Server AServer B 都去 grant一個進行 replication的身分 [A]mysqlgtGRANT FILE ON TO repl1921680200 IDENTIFIED BY lsquoabc123rsquo [B]mysqlgt GRANT FILE ON TO repl1921680100 IDENTIFIED BY lsquoabc123rsquo Step2做完單向 replication後stop Server Aserver B MySQL service此時 AB資料是一樣的

95

修改etcmycnf設定 範例 Server A [mysqld] datadir=varlibmysql socket=varlibmysqlmysqlsock server-id=1 log-bin sql-bin-update-same binlog-do-db=CRM master-host=1921680200 master-user=repl master-password=abc123 log-slave-updates master-connect-retry=60 replicate-do-db=CRM Server B [mysqld] datadir=varlibmysql socket=varlibmysqlmysqlsock server-id=2 log-bin sql-bin-update-same binlog-do-db=CRM master-host=1921680100 master-user=repl master-password=abc123 log-slave-updates master-connect-retry=60 replicate-do-db=CRM 分別 start Server AServer B MySQL後此時雙方都是 MasterSlave身分一旦哪一方資料異動就會通知對方來 replication-若 replication失效則必須將Server AServer B的masterinfo及index00x 都砍掉然後分別 restart MySQL server進行測試檢視成果 實務上通常如果需要做Two-way replication通常會搭配Virtual Server使用

96

在前端架設一台Virtual Server不過此部份不在此份SOP討論範圍內有興趣

的讀者可參考 httpwwwlinuxvirtualserverorg 網站

1921680100 1921680200

Host A MasterSlave Server

Host B MasterSlave Server

Virtual Host

圖 Virtual Server + Two-way replication 架構圖

97

圖 High Availability Linux Virtual Server架構圖

98

  • COSA-SOP-03-006
  • 第一章 簡介
    • 11適用對象 (Audience)
    • 12 MySQL本身
    • 13 MySQL 40版跟50版重大的改進功能
    • 14 各家資料庫軟體比較
      • 第二章 前置需求
      • 第三章 安裝
        • 31 MySQL安裝
        • 32 phpMyAdmin安裝
        • 33 升級及注意事項
          • 第四章 MySQL管理
            • 41 Webmin 管理介面
            • 42 phpMyAdmin 的操作介面
            • 43管理指令介紹
              • 431 利用mysqladmin設定root的密碼
                  • 第五章 實用範例
                    • 51 任務一Web Base客戶通訊錄
                    • 52 任務二Web Base群組軟體 ( twig )
                      • 第六章 維護及更新程序
                        • 61 日常維護
                        • 62 更新程序
                        • 63 備份重要檔案
                        • 64 離線備份與還原
                        • 65 線上備份與還原
                          • 第七章 問題與解答
                          • 第八章 參考資料
                          • 附錄一 SQL Command 介紹
                          • 附錄二Replication
Page 43: DataBase Server Standard Operation Procedureebooks.lib.ntu.edu.tw/1_file/oss/63/93doc4-5.pdf · 業務的公司帶來了不少壓力,譬如微軟,甲骨文 ... 外的錢用在第三方的資料庫產品上,譬如就可以不用再購買甲骨文公司

圖 4-24

圖 4-25

43

423使用者管理

Step1建立使用者

圖 4-26

44

圖 4-27

Step2 給予權限

圖 4-28

Step3權限列表

45

圖 4-29

43管理指令介紹

431 利用 mysqladmin設定 root的密碼

當您在Windows 或 Linux 中安裝好 MySQL後系統會自動幫您建立兩個

帳分別是 root 和 匿名者MySQL的 root 跟 Linux 最高權限使用者 root無關MySQL的 root使用者相當於 MS SQL 中的 sa 帳號擁有最高的 Database管理權限但系統預設 MySQL的 root 是不需要密碼所以通常我們一安裝

MySQL後首要任務便是修改 root的密碼 我們可以利用 mysqladmin工具或是直接修改 MySQL內部資料庫的使用者資

料 mysqladmin ndashu root ndashh cosaexamplecom password lsquo1234rsquo

46

-u 表示使用者帳號root 為 MySQL預設的管理帳號

-h 表示 MySQL主機的主機名稱也可使用 IP Address password 表示使用者的密碼因為字串請使用單引號將密碼括起來 密碼設定完成之後還是可以利用 mysqladmin修改密碼但是你必須提供目前的密碼

432 連線 MySQL

mysql -uroot -p密碼 (-p和密碼之間不能有空白) 或 mysql -uroot -p (此方式會在進入後要求密碼) [rootossc phpMyAdmin] mysql -u root -p1234

Welcome to the MySQL monitor Commands end with or g

Your MySQL connection id is 25 to server version 32354

Type help or h for help Type c to clear the buffer

mysqlgt show databases

+----------+

| Database |

+----------+

| mysql |

| test |

+----------+

2 rows in set (000 sec)

mysqlgt exit

Bye

[rootossc phpMyAdmin]

433 建立資料庫

可利用 mysqladmin指令建立 CONTACT資料庫 mysqladmin -u root -p1234 create CONTACT

47

或是利用 mysql指令 [rootossc bluepage] mysql -u root -p1234 Welcome to the MySQL monitor Commands end with or g Your MySQL connection id is 1057 to server version 32354 Type help or h for help Type c to clear the buffer mysqlgt create database CONTACT Query OK 1 row affected (000 sec) mysqlgt show databases +----------+ | Database | +----------+ | CONTACT | | address | | hello | | mysql | | nuke | | test | +----------+ 6 rows in set (000 sec) mysqlgt exit

434 建立資料表

編寫 adresssql內容如下 -- Table structure for table address CREATE TABLE address ( id int(11) NOT NULL auto_increment name varchar(20) NOT NULL default tel varchar(15) NOT NULL default PRIMARY KEY (id) ) TYPE=MyISAM

48

-- Dumping data for table address INSERT INTO address VALUES (1林小明0800016888) INSERT INTO address VALUES (2黃大雄0800016888) INSERT INTO address VALUES (3劉小芬0800024365) 然後執行此 sql script mysql -u root -p1234 CONTACT lt addresssql 或是利 mysql command [rootossc bluepage] mysql -u root -p1234 Welcome to the MySQL monitor Commands end with or g Your MySQL connection id is 1090 to server version 32354 Type help or h for help Type c to clear the buffer mysqlgt use CONTACT Database changed Database changed mysqlgt CREATE TABLE address ( -gt id int(11) NOT NULL auto_increment -gt name varchar(20) NOT NULL default -gt tel varchar(15) NOT NULL default -gt PRIMARY KEY (id) -gt ) TYPE=MyISAM Query OK 0 rows affected (000 sec) mysqlgt INSERT INTO address VALUES (1林小明0800016888) Query OK 1 row affected (000 sec) mysqlgt INSERT INTO address VALUES (2黃大雄0800016888) Query OK 1 row affected (000 sec) mysqlgt INSERT INTO address VALUES (3劉小芬0800024365) Query OK 1 row affected (000 sec) mysqlgt exit Bye

49

第五章 實用範例

51 任務一Web Base客戶通訊錄

任職於開放科技公司的林小明前些日子在最符合成本效益的條件下快

速地完成公司網站的建置老闆因此對小明讚譽有加最近因為公司存放客戶資

料的 SQL Server主機屢遭病毒攻擊加上作業系統本身的問題當機次數頻繁

老闆希望能儘快把公司的客戶通訊錄程式移轉到較穩定的環境上因為此客戶通

訊錄程式最主要給內部人員使用所以介面美觀並不特別要求只求穩定且能快

速得到查詢結果老闆希望在短時間先看到程式的雛型並鍵入資料對其效率

及穩定性進行測試因為上次小明表現突出所以這次不可能的任務自然又落到

小明身上 小明想來想去既然要快速又穩定他而且又不希望所有人都得安裝 Client

程式於是小明決定)捨棄他的舊愛「Delphi+MS SQL」投向新歡「Apache + MySQL + PHP」利用此架構來設計一個簡單實用的Web Base客戶通訊錄程式

511 Web Base客戶通訊錄架構

此程式需要建立 CONTACT的資料庫並建立 adress Tables其結構如下表建立步驟請參考第三章 欄位名稱 資料型態 長度 說明 id INT (自動編號) 連絡人編號 name varchar文字 20 連絡人姓名 tel Varchar文字 15 連絡人電話 Web Base通訊錄共有下列幾個檔案功能如下表

檔案名稱 說明 Indexhtml Web Base通訊錄首頁 addphp 新增連絡人的 php程式 searchphp 尋找連絡人的 php程式 editphp 具有更新及刪除功能的 php程式

50

我們將這些檔案放至varwwwhtmlbluepage (預設無 bluepage目錄)

512 Web Base通訊錄測試

httpwwwopencombluepage 新增資料

圖 5-1 新增連絡人

圖 5-2 填入資料

51

圖 5-3 新增成功

搜尋及異動資料

圖 5-4 搜尋通訊錄

52

圖 5-5 編輯資料

圖 5-6 更新資料

513 程式內容及說明

lt-- 程式範例indexhtml--gt lthtmlgt ltheadgtlttitlegt通訊錄lttitlegtltheadgt ltbodygt ltcentergt

53

lth2gt通訊錄lth2gtlthrgt lta href=indexhtmlgt通訊錄ltagt | lta href=addphpgt新增連絡人ltagt | lta href=searchphpgt搜尋通訊錄ltagt ltcentergt ltbodygt lthtmlgt lt-- 程式範例addphp --gt lthtmlgt ltheadgtlttitlegt新增連絡人lttitlegtltheadgt ltbodygt ltcentergtlth2gt新增連絡人lth2gtltcentergtlthrgt lt 取得欄位資料 if (isset($_POST[Name]) ampamp isset($_POST[Tel]) ) $name = $_POST[Name] $tel = $_POST[Tel] 檢查是否有輸入欄位資料 if ($name = ampamp $tel = ) 建立 SQL字串 $sql = INSERT INTO address (name tel) values( $sql= $name $tel) 建立 MySQL 連結 $link = mysql_connect(localhostroot1234) 選擇資料庫 mysql_select_db(CONTACT) 執行 SQL指令 mysql_query($sql) mysql_close($link) echo ltfont color=redgt新增連絡人成功ltfontgtltbrgt gt ltform action=addphp method=postgt lttable border=0 width=300gt lttrgtlttdgt姓名 lttdgt

54

lttdgtltinput type=text name=Name size=20 maxlength=10gtlttdgtlttrgt lttrgtlttdgt電話 lttdgt lttdgtltinput type=text name=Tel size=20 maxlength=20gtlttdgtlttrgt lttrgtlttd colspan=2 align=centergt ltinput type=submit value=新增連絡人gtlttdgtlttrgt lttablegt ltformgt ltbrgtlta href=indexhtmlgt通訊錄ltagt | lta href=addphpgt新增連絡人ltagt | lta href=searchphpgt搜尋通訊錄ltagt ltbodygt lthtmlgt

lt-- 程式範例searchphp --gt lthtmlgt ltheadgtlttitlegt搜尋通訊錄lttitlegtltheadgt ltbodygt ltcentergtlth2gt搜尋通訊錄lth2gtlthrgt lt if (isset($_POST[Search])) 建立資料庫連結並選定資料庫 $link = mysql_connect(localhostroot1234) mysql_select_db(CONTACT) 建立基本的 SQL字串 $sql = SELECT FROM address 檢查是否輸入姓名 if (chop($_POST[Name]) = ) $name = name LIKE $_POST[Name] else $name = 檢查是否輸入電話號碼 if (chop($_POST[Tel]) = ) $tel = tel LIKE $_POST[Tel] else $tel =

55

if條件組合 SQL字串 if (chop($name) = ampamp chop($tel) = ) $sql= WHERE $name AND $tel elseif (chop($name) = ) 只有姓名 $sql = WHERE $name elseif (chop($tel) = ) 只有電話號碼 $sql = WHERE $tel $sql= ORDER BY name 最後加上排序 $result = mysql_query($sql) 取得欄位數 $total_fields = mysql_num_fields($result) echo lttable border=1gt echo lttrgtlttdgt編號lttdgtlttdgt姓名lttdgtlttdgt電話lttdgtlttd colspan=2gt功能選項lttdgtlttrgt 表格顯示查詢結果 while ($rows = mysql_fetch_array($result MYSQL_NUM)) echo lttrgt for ($i = 0 $i lt $total_fields $i++) echo lttdgt$rows[$i]lttdgt echo lttdgtlta href=editphpaction=editampid= echo $rows[0]gtltbgt編輯ltbgtlttdgt echo lttdgtlta href=editphpaction=delampid= echo $rows[0]gtltbgt刪除ltbgtlttdgt echo lttrgt echo lttablegtlthrgt mysql_free_result($result) mysql_close($link) gt ltcentergt ltform action=searchphp method=postgt lttable border=0 width=450gt lttrgtlttdgt搜尋姓名 lttdgt lttdgtltinput type=text name=Name size=10 maxlength=20gtlttdgtlttrgt lttrgtlttdgt搜尋電話 lttdgt lttdgtltinput type=text name=Tel

56

size=20 maxlength=20gtlttdgtlttrgt lttrgtlttd colspan=2 align=centergt ltinput type=submit name=Search value=搜尋gtlttdgtlttrgt lttablegt ltformgt ltbrgtlta href=indexhtmlgt通訊錄ltagt | lta href=addphpgt新增連絡人ltagt | lta href=searchphpgt搜尋通訊錄ltagt ltbodygt lthtmlgt

lt ob_start() gt lt-- 程式範例editphp --gt lthtmlgt ltheadgtlttitlegt編輯通訊錄lttitlegtltheadgt ltbodygt lt 取得 URL 參數 $id = $_GET[id] $action = $_GET[action] 建立資料庫連結 $link = mysql_connect(localhostroot1234) mysql_select_db(CONTACT) 選擇資料庫 執行的操作 switch ($action) case update 更新 取得欄位資料 $name = $_POST[Name] $tel = $_POST[Tel] $sql = UPDATE address SET name=$name tel=$tel WHERE id=$id mysql_query($sql) 執行 SQL指令 mysql_close($link) header(Location searchphp) 轉向到 serachphp break case del 刪除 $sql = DELETE FROM address WHERE id=$id

57

mysql_query($sql) 執行 SQL指令 mysql_close($link) header(Location searchphp) 轉向到 serachphp break case edit 編輯 $sql = SELECT FROM address WHERE id=$id $result = mysql_query($sql) 執行 SQL指令 $row = mysql_fetch_row($result) 取回記錄 $name = $row[1] 取得欄位 name $tel = $row[2] 取得欄位 tel mysql_close($link) 顯示編輯表單 gt ltcentergtlth2gt更新通訊錄lth2gtltcentergtlthrgt ltform action=editphpaction=updateampid=lt echo $id gt method=postgt lttable border=0 width=300gt lttrgtlttdgt姓名 lttdgt lttdgtltinput type=text name=Name size=20 maxlength=10 value=lt echo $name gtgtlttdgtlttrgt lttrgtlttdgt電話 lttdgt lttdgtltinput type=text name=Tel size=20 maxlength=20 value=lt echo $tel gtgtlttdgtlttrgt lttrgtlttd colspan=2 align=centergt ltinput type=submit value=更新連絡人gtlttdgtlttrgt lttablegt ltformgt ltbrgtlta href=indexhtmlgt通訊錄ltagt | lta href=addphpgt新增連絡人ltagt | lta href=searchphpgt搜尋通訊錄ltagt lt break gt ltbodygt lthtmlgt

58

52 任務二Web Base群組軟體 ( twig )

順利完成Web Base客戶通訊錄程式測試一段時間後「Apache + MySQL + PHP」架構的穩定與快速巳深得老闆與公司所有同事的認同隨著公司業績蒸

蒸日上人員組織編罝愈來愈龐大跨部門的會議愈來愈多業務員每日排滿拜

訪客戶的行程跟客戶的 Email的往來也愈來愈頻繁 愈來愈多部門的同事希望公司能建置一套群組軟體提供 web mail可讓業

務人員方便收發 mail還有連絡人議事日程待辦工作書簽等功能讓整個

公司運作及個人時間管理更有效率

老闆問小明對這些需求有什麼看法小明認為如果這些功能完全由程式部

門開發必定曠日費時而且耗費公司資源小明在網路尋找是否有提供這些功能

的Free Software皇天不負苦心人小明發現了TWIG (The Web Information Gateway) httptwigscrewdrivernet這個群組軟體它在 Web 上整合郵件新聞聯絡人議事日程工作序書簽等功能非常符合公司的需求 Step 1 下載 twig-277targz 下載網址 httptwigscrewdrivernetdownloadphp3

Step 2 解開 twig-277targz tar -xzvf twig-277targz

59

Step 3 執行安裝動作安裝到 varwwwhtmltwig 目錄 cd twig-277 twig-install varwwwhtmltwig

Step 4 建立 MySQL 資料庫(twig)及各資料表

cd setup mysql -u root -p1234 mysqlgt create database twig Query OK 1 row affected (001 sec) mysqlgt quit mysql -u root ndashp1234 twiglt twigtablemysql

Step 5 修改 configincphp3 參數設定 vi varwwwhtmltwigconfigconfigincphp3 $config[fromdomain] = opencom 網域 $config[language] = chinesebig5 中文訊息 $config[imap_port] = 143notls

60

Step 6 修改連結 MySQL 的帳號密碼 vi varwwwhtmltwigconfigdbconfigincphp3 $dbconfig[sqlusername] = root username $dbconfig[sqlpassword] = 1234 password

Step 7 其他設定檔

vi etchttpdconfhttpdconf 加入 AddType applicationx-httpd-php php3 在 DirectoryIndex最後加入 indexphp3 DirectoryIndex indexhtml indexhtmlvar indexphp3 在 AddDefaultCharset ISO-8859-1加上 AddDefaultCharset ISO-8859-1

vi etcphpini register_globals = On service httpd restart Step 8 sendmail 設定 vi etcmailsendmailcf在 264 行前面加上並重新啟動 sendmail「service snedmail restart」 262 SMTP daemon options 263 264 O DaemonPortOptions=Port=smtpAddr=127001 Name=MTA 265 266 SMTP client options 267 O ClientPortOptions=Family=inet Address=00

61

Step 9 檢查設定有無錯誤 http主機名稱twigtestphp3

62

Step 10 登入 twig ( http主機名稱twig)

63

第六章 維護及更新程序

61 日常維護

系統管理員最好定期以 root 身份登入看看信件在 RedHat Linux 中有一支 logwatch 程式會定時去分析 log file如果發現異常便會發信給 root除此之外筆者建議讀者平時就檢查 MySQL log file ( varlogmysqldlog)是否有異常情形

62 更新程序

讀者可至httprpmfindnet 尋找MySQL相關套件至於升級的相關步驟請參

考Linux OS SOP 第 54節

63 備份重要檔案

預設 MySQL 的 DB 檔案是存在 varlibmysql 內以 DB名稱為目錄目錄

內就是該 DB 的所有資料通常得定期備份還有 MySQL的設定檔 etcmycnf也別忘了一起備份

64 離線備份與還原

641 離線備份

預設 MySQL 的 DB 檔案是存在 varlibmysql 內以 DB 名稱為目錄目錄內

就是該 DB 的所有資料像 CRM 這個 DB就是存在 varlibmysqlCRM 內在備份前因為怕資料尚未完全寫入磁碟而且 MySQL 會 Lock 在使用的 DB 檔案所以應該是要先把 MySQL 先 Shutdown 一下整個備份的程序可以下像下面的指令去完成 cd varlibmysql

64

service mysqld stop tar cvfz CRM_db_20030905tgz CRM service mysqld start 對這樣就可以了 不過要注意的是怕 DB 內每個 Tables 間的資料有關關

聯性所以最好是把整個 DB 一次備起來單獨只備哪個 Tables 的檔案以後回存時怕會有資料關聯不一致的問題

642 離線還原

DB 發生錯誤而要回存時其實也不難先找出最近一次完整正常的備份先把現在錯誤的網頁或 DB 先更名或 tar 起來再把好的備份給解開回原來目錄位

置就行了需要注意的是 MySQL 服務最好也是要先停止回存完成後再啟動服務回存 DB 的整個程序可能像下面 cd varlibmysql service mysqldstop mv CRM CRM_OLD tar xvfz CRM_db_20030905tg service mysqld start

65 線上備份與還原

651 線上備份

使用像上面的檔案方式備份是個不錯的方法它最少可以保持該主機某個時間點的完整檔案備份但還是有一些問題需要考慮到有些主機就不只建立一個 DB 而已總不能為了備份某個 DB 而把整個 MySQL 服務停止備份檔案的方式回存在原主機上一定適用但假如 MySQL 版本升級或是在那天該網頁空間需遷機移機到別的主機時那就沒人敢保證備出來的資料檔可以用所以我們可以考慮另一種備份的方式是使用 MySQL 本身提供的功能 MySQL Data Dump指令是 mysqldump

65

使用 MySQL 的 Dump 功能可以把 DB 的結構資料或結構加資料 Dump 成文字檔 mysqldump 指令提供的彈性很大你可以選擇把整個 DB Dump 成一個檔或是每個 Table 為一個檔甚至是把結構檔和資料分開儲存都

可以 mysqladmin -uroot -p flush-logs mysqldump CRM -uroot -p --opt gt CRM_20030905sql (CRM 是 DB 名稱 opt 是一個使用完整 Dump 參數) 假如只是要單獨 Dump 某個 Table 時只要在上面的指令後轉出符號 gt 前加個 Table 名稱就可以如只要 phpbb2_users 這個 Table 的 Dump 時只要下 mysqldump CRM -uroot -p --opt CUSTOMER gt CRM_CUSTOMER_20030905sql

652 線上還原

若要回存整個資料庫只需將壓縮的備份檔還原成 Dump 的檔案再用下面的指令回存 mysql CRM -uroot -p lt CRM_20030905sql 這邊需注意的是若建立備份時是以--opt或--add-drop-table為參數時回存的 動作是先將舊的 Table 先刪除重建 Table 的結構後再把 Data 匯入所以回存後所有的資料會回到你當時備份那個時間點因此在回存資料時可以考慮把現有錯誤或不完整的 DB 先備份一份下來以備不時之需或是拿來比對錯誤的地

方在那裡當然你也可以把資料回存到另一個測試用的 DB 內只要把上面指令

的 DB 名稱改成你的測試用 DB 名稱即可 使用這種回存方式 MySQL 服務不需停止也不會動到其他正在使用的 DB 在一些提供 MySQL 服務的虛擬主機可用這種方式作你自己的 DB 備份及回存

66

另外假如你是系統重建或是移機時切需在新的 MySQL 內新建一個空白 DB 後才行作回存的工作你可以用下面的指令建立 mysql -uroot -p -e CREATE DATABASE CRM (上面的 CRM是你要新建的 DB 名稱) 另一種作法先用 mysql 指令進入 mysql client console 然後再用 CREATE DATABASE CRM 這樣就行了記得尾端要加個 符號該行指令才會執行

67

第七章 問題與解答

Q1RedHat 90預附的 MySQL到底有無支援 Transcation機制 Ans MySQL自 32334a之後的 MySQL-Max版本加入 InnoDB的資料庫類型透過

InnoDBMySQL同樣可以進行 COMMIT與 ROLLRACK的動作RedHat 90預附的 MySQL為 32354a-11巳支援 InnoDB的資料庫類型不過必須做以

下設定 1cp usrsharedocmysql-server-32354amy-mediumcnf to etcmycnf 2 vi etcmycnf 將以下設定前的拿掉 innodb_data_home_dir = varlibmysql innodb_data_file_path = ibdata110Mautoextend innodb_log_group_home_dir = varlibmysql innodb_log_arch_dir = varlibmysql 3service mysqld restart 如此一來各位在建立Table時便可指定Table Type為 innodb ( ex create table with type=innodb ) Q2如何解決 php+mysql 許功蓋等字變亂的問題 Ans 方法一 【確定 MySQL 預設的字元集】 1 打開 WinMySQLadmin 管理畫面(在視窗右下角狀態列紅綠燈圖示中按滑鼠

右鍵點選 Show me 選項) 2 點選管理畫面中 [Variables] 標籤選項其中 character_set變數就是您預設

字元集的變數其預設是 latin1 字元集(我們要將他改回 big5)而 chatacters_set 變數則是 MySQL 可以支援哪些字元集 【修改預設字元集變數 character_set 】 1 請點選管理畫面中 [myini Setup] 標籤選項設定 myini 2 按一下 [Pick-up and Edit myini values] 按鈕以便編輯目前的 myini 設定 3 在 [mysqld] 設定區塊底下新增一行 default-character-set = big5 變數設

68

定 4 新增一個 [client] 設定區塊並加入第三步驟的變數設定(游標往下移到空白處新增兩行 [client] 和 default-character-set=big5) 5 按一下畫面左下方 [Save Modification] 按鈕儲存設定 6 重新啟動 MySQL 或 Windows 方法二 Server端注意事項 phpini 中有關的設定為(預設值) Magic quotes for incoming GETPOSTCookie data magic_quotes_gpc = On Use Sybase-style magic quotes (escape with instead of ) magic_quotes_sybase = Off Client端注意事項 1中文資料送進 mysql 前請用 addslashes($str) 處理 2處理後送進 mysql 時請用 括起來並在參數後留一個空白如 $sql = UPDATE ezf_table set tablename=$tname tableend=$endtime table inguser=$tguser tableingid=$tguserid tableallnumber=$tnumber tableloca l=$tablelocal tableanyone=$tableopen tabletext=$ttext WHERE tableid=$t ableid tablename=$tname c 取出時請用 stripslashes($str) Q3MySQL root 密碼忘了該怎麼辦 Ans 1先停掉 mysql etcrcdinitdmysql stop 2以--skip-grant-table 的參數啟動 mysql safe_mysql --skip-grant-tableamp 3 更改 root 密碼 mysql mysql mysqlgt UPDATE user SET password=password(newpassword)

69

WHERE user=root mysqlgt FLUSH PRIVILEGES mysqlgt exit 4停掉 mysql再重跑 mysqladmin -uroot -p shutdown Enter password 輸入新設定的密碼 etcrcdinitdmysql start

Q4NULL值問題

Ans

NULL值的概念是造成 SQL的新手的混淆的普遍原因他們經常認為 NULL是和一個空字符串的一樣的東西不是這樣的例如下列語句是完全不同的

mysqlgt INSERT INTO my_table (phone) VALUES (NULL)

mysqlgt INSERT INTO my_table (phone) VALUES ()

兩個語句把值插入到 phone 列但是第一個插入一個 NULL值而第二個插入一個空字符串第一個的含義可以認為是ldquo電話號碼不知道而第二個則可意味

著ldquo她沒有電話

在 SQL中NULL值在于任何其他值甚至 NULL值比較時總是假的(FALSE)包含 NULL的一個表達式總是產生一個 NULL值除非在包含在表達式中的運算符和函數的文檔中指出在下列例子所有的列返回 NULL

mysqlgt SELECT NULL1+NULLCONCAT(InvisibleNULL)

如果你想要尋找值是 NULL的列你不能使用=NULL測試下列語句不返回任

何行因為對任何表達式expr = NULL是假的

mysqlgt SELECT FROM my_table WHERE phone = NULL

要想尋找 NULL值你必須使用 IS NULL測試下例顯示如何找出 NULL電話號碼和空的電話號碼

70

mysqlgt SELECT FROM my_table WHERE phone IS NULL mysqlgt SELECT FROM my_table WHERE phone =

在 MySQL中就像很多其他的 SQL服務器一樣你不能索引可以有 NULL值的列你必須聲明這樣的列為 NOT NULL而且你不能插入 NULL到索引的

列中

當用 LOAD DATA INFILE 讀取數據時空列用更新如果你想要在一個列中有

NULL值你應該在文本文件中使用N字面上的詞NULL也可以在某些情形下使用

當使用 ORDER BY時首先呈現 NULL值如果你用 DESC以降序排序NULL值最後顯示當使用 GROUP BY時所有的 NULL值被認為是相等的

為了有助于NULL的處理你能使用 IS NULL和 IS NOT NULL運算符和 IFNULL()函數

對某些列類型NULL值被特殊地處理如果你將 NULL插入表的第一個TIMESTAMP 列則插入當前的日期和時間如果你將 NULL插入一個AUTO_INCREMENT 列則插入順序中的下一個數字

Q5如何將圖片存放於 MySQL中

Ans

Step 1建立資料庫 test

Step 2 建立表格 binary_data

CREATE TABLE binary_data (

id INT(4) NOT NULL AUTO_INCREMENT PRIMARY KEY

description CHAR(50)

bin_data LONGBLOB

filename CHAR(50)

filesize CHAR(50)

filetype CHAR(50)

71

)

Step 3 利用 storephp 寫入圖片

storephp 程式碼

ltHTMLgt ltHEADgtltTITLEgtStore binary data into SQL DatabaseltTITLEgtltHEADgt ltBODYgt lt code that will be executed if the form has been submitted

if ($submit) mysql_connect(localhostrootYOUR_PASSWORD) mysql_select_db(test) $data=Base64_Encode(fread(fopen($form_data r) filesize($form_data))) $result=MYSQL_QUERY(INSERT INTO binary_data (descriptionbin_datafilenamefilesizefiletype) VALUES ($form_description$data$form_data_name$form_data_size$form_data_type)) $id= mysql_insert_id() print ltpgtThis file has the following Database ID ltbgt$idltbgt MYSQL_CLOSE() else else show the form to submit new data

gt

ltform method=post action=ltphp echo $PHP_SELF gt enctype=multipartform-datagt File Descriptionltbrgt ltinput type=text name=form_description size=40gt ltINPUT TYPE=hidden name=MAX_FILE_SIZE value=4000000gt ltbrgtFile to uploadstore in databaseltbrgt ltinput type=file name=form_data size=40gt ltpgtltinput type=submit name=submit value=submitgt ltformgt lt

72

gt ltBODYgt ltHTMLgt

Step 3 利用 storephp 取出圖片

getdataphp 程式碼

lt Syntax getdataphp3id=ltidgt if($id) you may have to modify login information for your database server MYSQL_CONNECT(localhostrootYOUR_PASSWORD) mysql_select_db(test) $query = select bin_datafiletype from binary_data where id=$id $result = MYSQL_QUERY($query) $data = Base64_Decode(MYSQL_RESULT($result0bin_data)) $type = MYSQL_RESULT($result0filetype) Header( Content-type $type) echo $data gt

Q6MySQL裝好之後啟動時或是執行 mysqladmin會出現如下訊息 Cant connect to local MYSQL Server through Socket varlibmysqlmysqlsock或是

Cant connect to local MYSQL Server through Socket tmpmysqldsock

Ans 可能有下列幾個原因

1這個 mysqldsock 不見了被某人刪除了或是被一些系統自動執行程式給刪

了例如有些 cron任務便會設定定期刪除 tmp 裡的東西所以呢您只能修改

cron 裡的設定讓它不要清除 mysqldsock 2在啟動時也可以改變 mysqldsock的位置您在啟動 MySQL的時候可以加入此參數usrlocalmysqlbinsafe_mysqld --user=mysql --socket=其他路

徑socket amp 同時得去設定環境變數 MYSQL_UNIX_PORT的值以指定新的

73

路徑 3若是您沒改 MYSQL_UNIX_PORT的值那麼您可以在執行指令的時候才打

例如mysqladmin --socket=其他路徑socket version Q7How to get the last insert id Ans CREATE TABLE product ( id INT(4) NOT NULL AUTO_INCREMENT PRIMARY KEY description VARCHAR(50) ) 1利用 SQL的話 mysqlgt insert into product(description) values(123) Query OK 1 row affected (000 sec) mysqlgt select last_insert_id() +------------------+ | last_insert_id() | +------------------+ +------------------+ 1 row in set (000 sec) ======================================== 2如果是 PHP的話 你可以用mysql_insert_id()取得該 id PHP example $result=MYSQL_QUERY(INSERT INTO product (description) VALUES ($description)) $id= mysql_insert_id() print This file has the following Database ID $id Q8如何將文字檔匯入資料庫 Ans $addr=homehttpdhtmlphpschool001txt $sql_select = load data infile $addr into table test fields terminated by t 解說 $sql_select = load data infile 文字檔名 into table 表格名 fields terminated by

74

t

(欄位分隔以 TAB鍵) 該文字檔須與資料表欄位格式相符 例如欄位有三個 則文字檔為每行一筆資料如下 欄 1資料ltTABgt欄 2資料ltTABgt欄 3資料 欄 1資料ltTABgt欄 2資料ltTABgt欄 3資料 欄 1資料ltTABgt欄 2資料ltTABgt欄 3資料 欄 1資料ltTABgtltTABgt欄 3資料

Q9如何撰寫 MySQL C API Ans Step 1利用文字編輯器撰寫以下程式碼 mysqlcc

include ltstdiohgt

include ltmysqlmysqlhgt

int main (int argc char argv[])

MYSQL mysql

MYSQL_RES res

MYSQL_ROW row

if (argc = 2)

fputs (Usage myc ltdatabasegt stderr)

return 1

if ((mysql_connect(ampmysqllocalhostrootYour_Password)))

fputs (Error connecting stderr)

abort()

75

if (mysql_select_db(ampmysqlargv[1]))

fputs (Error selecting database stderr)

abort()

if (mysql_query(ampmysqlSELECT FROM test_table))

fputs (Error processing query stderr)

abort()

if ((res = mysql_store_result(ampmysql)))

fputs (Error storing results stderr)

abort()

while((row = mysql_fetch_row(res)))

uint i = 0

for (i=0 i lt mysql_num_fields(res) i++)

printf(s row[i])

printf(n)

return 0

Step 2 Compile

gcc -Iusrlocalmysqlinclude -Lusrlocalmysqllibmysql mysqlcc ndashlm -lmysqlclient

(其中 include path與 library path取決於你的 MySQL安裝路徑)

76

如果執行時發生如下 error Run problemerror in loading shared libraries libmysqlclientsoX 將你的 MySQL library path(for exampleusrlocalmysqllibmysql) 加入etcldsoconf and run sbinldconfig -v Q9ASP + MySQL 範例程式 Ans Dim myconn As New ADODBConnection Dim myrs As New Recordset Dim mySQL As String Dim myrows As Long myconnOpen DSN=MyODBCsample mySQL = SELECT from user myrsSource = mySQL Set myrsActiveConnection = myconn myrsCursorLocation = adUseClient myrsOpen myrows = myrsRecordCount myrsClose myconnClose 可參考 httpwwwdwamnetmysqlasp_myodbcasp 有詳細的資料 Q10如何將 MySQL中的資料庫匯出成txt檔 Ans select from TableName into outfile textxls all result fields will seperate by tab

77

第八章 參考資料

英文部份 網址 1 httpwwwmysqlcom MySQL 網站有第一手有關 MySQL的資料 2 httpwwwmysqlcomdocenReplicationhtml 有關 MySQL Replication 的文件 3 httpwwwgeocitiescomsqlhomefaqstore_blobhtml 如何在 MySQL 存放 BLOB的資料 4httpwwwsapdborg 有關 SAP跟 MySQL相關合作的網站 書藉 1 Cooking with MySQL

Paul DuBois has selected sample recipes from the hundreds youll find in his book MySQL

Cookbook In this third and final series of excerpts showcasing these recipes learn how to

compute team standings how to calculate the differences between successive Dec 26

2002 2 Tips for Building Web Database Applications with PHP and MySQL by Hugh E Williams co-author of Web Database Applications with PHP amp MySQL 04042002

3 Managing and Using MySQL 2nd Edition By Tim King George Reese Randy Jay Yarger

4 MySQL Cookbook By Paul DuBoisPublisher OReillyPub Date October 2002

中文部份

78

1 httplinuxtncedutwtechdocmysqlmysql_docmanual_tochtml MySQL 中文手冊 2 httpchenshloxaedutwphpZ_1php PHP+MySQ程式研習設計網站 3 httplinuxtncedutwtechdocbanicdownhtml PHP 4 手冊 4 httpwwwtncedutwadmin_zonephp台南縣教育網網路中心有很多 Linux相關文件 5 httpdobtncedutw網站建置百寶箱有很多 PHP MySQL 相關範例程式 5 httpwwwdbworldcomtw資料庫專家電子雜誌介紹資料庫的重要觀念及名詞

79

附錄一 SQL Command 介紹

SQL (讀音ess-que-el) 是一種結構查詢語法SQL 使用於資料庫交流

傳遞相容於 ANSI (American National Standards Institute) 是一套標準的關聯

式資料庫語言 SQL 語言是執行更新或從資料系統獲取資料一般常見的關聯

資料庫系統都有提供 SQL 如 Oracle Sybase Microsoft SQL Server Access Ingres 等雖然大部份的資料庫都有提供 SQL 但也多提供了自已獨特的語

法造成了不相容的情形但標準基本的語法是相通的如Select Insert Update Delete Create and Drop 每一個系統都有支援

Table相關 Command

Create Table

關聯式資料庫包含有很多元件稱為資料表(tables) 把資料或訊息放在資

料表中 資料表是以不同的名稱做分別資料表由欄列所構成的二維陣列

欄包含欄位名資料型態 及其他可判斷的資訊列是由全部欄位構成一筆一

筆的紀錄 create table 語法用在建立一個新的資料表語法格式如下

create table tablename (column1 data type column2 data type column3 data type)

Format of create table if you were to use optional constraints

create table tablename (column1 data type [constraint] column2 data type [constraint] column3 data type [constraint]) [ ] = optional

Note You may have as many columns as youd like and the constraints are optional

80

Example

create table employee (first varchar(15) last varchar(20) age number(3) address varchar(30) city varchar(20) state varchar(20))

注意建立資料表格式要以括號把前後框住而最後以(分號)做結尾

欄位名不要超過 30個字元長而且不要使用 sql 的關鍵字(如 where select等)而在後面接是型態的宣告(如字串數字日期格式等)

資料型態是來描述欄位的方式如一個欄位Last_Name 是一個姓氏可以使用varchar (可變動長度字串) 資料型態

以下是幾個常見的資料庫型態 char(size) 固定長度字串最長為 255 位元 varchar(size) 變動長度字串最大字元數以 size 來指定 number(size) 數值格式可以是整數也可以是小數最大數字以 size 位數判

斷未指定小數位數由系統內定 date 日期格式 number(sized) 數值格式最大數字以 size 位數判斷d 為小數位數整數位

數為 size-d 位

有何限制當資料表被建立通常有一或數個欄位是要使用來做關聯的功

能 例如unique 限制(唯一值)兩筆記錄不可以相同的值 not null (非空值)該欄位一定要輸入資料不可是空的primary key (主鍵)是每一筆記錄識別的主要方式

Drop a table drop table 刪除資料表(其中的資料也會一併刪除)

drop table tablename

Example

81

drop table 和刪除全部資料是不同的刪除全部資料欄位名稱資訊等還會

存在但刪除資料表會把這一些也一併移除掉

如何查詢資料

Select 基本用法

select 語法是關連式資料庫最常用的部份可以取得你想要的資料這是一個

簡單的範例 select column1[column2etc] from tablename [where condition] [] = optional 在 select 之後所列欄位名則是要顯示的資料部份你可以一一列出各欄位

名或是以 (星號)來代表選擇全部的欄位 from 之後放資料表名稱 where 子句 (選項) 指定要過濾的條件符合者才會顯現 where 可使用的條件運算元 = 等於 gt 大於 lt 小於 gt= 大或等於 lt= 小或等於 ltgt 大相等 LIKE 相似 For example select first last city

82

from empinfo where first LIKE Er 以Er 為開頭的字串就符合要以單引號框住 Or you can specify select first last from empinfo where last LIKE s 最後一字為 S 就符合 select from empinfo where first = Eric 則表示 first name 一定要是 Eric 才可以 範例資料表empinfo 統計函數

MIN 傳回指定欄位最小值

MAX 傳回指定欄位最大值

SUM 傳回指定欄位總和

AVG 傳回指定欄位平均值

COUNT 傳回指定欄位的筆數

COUNT() 傳回資料庫中的總筆數

統計函數使用於資料表中的數值欄位配合 SELECT 語法使用 只用於總結特定單一欄位可以配合 GROUP BY 做篩選但也可以不使用 GROUP BY 語句For example

SELECT AVG(salary) FROM employee

83

傳回全部 salary 平均值

Another example

SELECT AVG(salary) FROM employee WHERE title = Programmer

傳回 salary 平均值條件為 employees 資料表中當 title 等於 Programmer

Example

SELECT Count() FROM employees

傳回 employees 資料表中紀錄總筆數

GROUP BY 語法 SELECT column1 SUM(column2) FROM list-of-tables GROUP BY column-list The GROUP BY 語句可以先以所列的欄位為條件分組排序在一起(可以多欄

位) example 要列出每一個 dept 中最高 salary 值 SELECT max(salary) dept FROM employee GROUP BY dept HAVING 語法

SELECT column1 SUM(column2) FROM list-of-tables GROUP BY column-list HAVING condition

HAVING 子句是 GROUP BY 的一部份用來過濾在 GROUP BY 所選出的資料功能如同 select 命令中 where 條件式一樣只是 HAVING 必需配合 GROUP BY 使用

我們以例子來說明我們要取得每一公司名及每一公司的薪水平均值輸入如下

84

SELECT dept avg(salary) FROM employee GROUP BY dept

但如果我們只列出薪資平均值超過 20000元的公司資料

SELECT dept avg(salary) FROM employee GROUP BY dept HAVING avg(salary) gt 20000

ORDER BY子句語法

SELECT column1 SUM(column2) FROM list-of-tables ORDER BY column-list [ASC | DESC]

[ ] =選項

ORDER BY是一個選項子句當你以排序方式來顯示資料(正向由小到大反向由大到小)以指定的欄位資料做排序

ASC = 正向- 預設值 DESC = 反向排序

For example

SELECT employee_id dept name age salary FROM employee_info WHERE dept = Sales ORDER BY salary

以上列出公司代號公司名銷售員人名年紀及薪資而條件是公司名為 Sales 顯示順序以薪資多少排序(由小到大為預設值)

如果要以多個欄位做排序要以逗號做分隔如下

SELECT employee_id dept name age salary FROM employee_info WHERE dept = Sales ORDER BY salary age DESC

85

結合條件及布林運算 SELECT column1 SUM(column2) FROM list-of-tables WHERE condition1 AND condition2 AND運算可以結兩個或以上的條件放在 WHERE子句中 兩者都要為真才

會顯示該筆記錄 OR 運算可以結兩個或以上敘述放在 WHERE子句中只要其中一個為直就

會顯示該筆記錄 For example SELECT employeeid firstname lastname title salary FROM employee_info WHERE salary gt= 5000000 AND title = Programmer 必需要薪資大於等於 50000而且職稱為 Programmer同時符合才會顯示該筆資料 以下以括號括住雖然不是必需的但如此比較容易讀 SELECT employeeid firstname lastname title salary FROM employee_info WHERE (salary gt= 5000000) AND (title = Programmer) 另外範例 SELECT firstname lastname title salary FROM employee_info WHERE (title = Sales) OR (title = Programmer) 條件為只要是 Sales 或 Programmer 職稱的就會被列出 IN and BETWEEN 子句

SELECT column1 SUM(column2) FROM list-of-tables WHERE column3 IN (list-of-values) SELECT column1 SUM(column2) FROM list-of-tables WHERE column3 BETWEEN value1 AND value2 IN 子句使用在列舉項目的使用上也就是分別測試是否符合所列的值 For example

86

SELECT employeeid lastname salary FROM employee_info WHERE lastname IN (Hernandez Jones Roberts Ruiz) 條件為姓氏(astname)要符合 Hernandez Jones Roberts or Ruiz 其中一個才會被傳回 IN運算元也可以使用 OR 的語法來取代如下結果相同 SELECT employeeid lastname salary FROM employee_info WHERE lastname = Hernandez OR lastname = Jones OR lastname = Roberts OR lastname = Ruiz 但使用 IN 句子比較短也比較易懂 你也可以使用 NOT IN 來去掉不要的記錄 BETWEEN 運算元使用在判斷是否存在兩個數值之間 For example SELECT employeeid age lastname salary FROM employee_info WHERE age BETWEEN 30 AND 40 傳回年紀 30歲到 40歲之間的資料(含 30及 40歲者) 相同的也可以使用以下語法來達到相同的結果 SELECT employeeid age lastname salary FROM employee_info WHERE age gt= 30 AND age lt= 40 你也可使用 NOT BETWEEN 來濾掉中間值的資料 數學運算 標準 ANSI SQL-92 提供以下運算

87

+ 加

- 減

餘數

餘數為除法後剩整數這不在標準的 ANSI SQL 中但大部份的資料庫都會支

援這運算元以下列出有用的函數雖不在 ANSI SQL-92 提供但一般資料庫

也會支援他們

ABS(x) 傳回 x 絕對值

SIGN(x) returns the sign of input x as -1 0 or 1 (negative zero or positive respectively)

MOD(xy) 餘數 - returns the integer remainder of x divided by y (同 xy)

FLOOR(x) 傳回小或等於 x 的最大整數值

CEILING(x) or CEIL(x)

傳回大或等於 x 的最小整數值

POWER(xy) x的 y 次方

ROUND(x) 把 x 四捨五入為整數

ROUND(xd) 四捨五入取到小數 d 位

SQRT(x) x 開平方

For example SELECT round(salary) firstname FROM employee_info 傳回薪資取到整數位

如何新增資料

insert 加入一筆新紀錄到資料表中 insert into tablename (first_columnlast_column) values (first_valuelast_value) [] = optional Example insert into employee

88

(first last age address city state) values (Luke Duke 45 2130 Boars Nest Hazard Co Georgia) Note 字串要以單引號住如string 數字框住也無妨 insert into 後面接資料表名稱再接以括號括住的欄位名在 values 後括號分別對映各欄位的值 以上的例子新增了一筆名(first) 為 Luke而住所(state) 為 Georgia 的資料

如何刪除資料

delete 可以刪除單筆或多筆紀錄 delete from tablename where columnname OPERATOR value [and|or column OPERATOR value] [ ] = optional Examples delete from employee Note 如果你沒有指定 where 子句那麼全部的紀錄都會被刪除 delete from employee where lastname = May delete from employee where firstname = Mike or firstname = Eric delete from 接著資料表名 再接著是條件式判斷沒有條件式則全部紀錄會

被刪除

如何更新資料

update 用來更新你所指定的記錄要和 WHERE 配合小心使用 語法 update tablename set columnname = newvalue[nextcolumn = newvalue2] where columnname OPERATOR value [and|or column OPERATOR value] [] = optional Examples

89

update phone_book set area_code = 623 where prefix = 979 update phone_book set last_name = Smith prefix=555 suffix=9292 where last_name = Jones update employee set age = age+1 where first_name=Mary and last_name=Williams

90

附錄二Replication

測試環境

RedHat 90 + MySQL 32358 MySQL資料庫路徑 varlibmysql MySQL設定檔 etcmycnf Master IP 1921680100 Slave IP 1921680200 請至下列網址下載最新MySQL 32358套件並利用rpm ndashUvh 更新 httpupdatesredhatcom9enosi386

圖 最新 MySQL 套件

測試架構圖

91

1921680100

1921680200Master Server

erveSlave S r

圖 測試架構圖

測試步驟

Master server 部份 Step1 確認 MasterSlave機器上所裝的 MySQL版本能進行

replication( 32329 or higher ) Step2 在 Master MySQL上開放一個帳號給 Slave mysql ndashu root ndashp mysqlgtGRANT FILE ON TO repl1921680200 IDENTIFIED BY lsquoabc123rsquo mysqlgtq 上面是 Master開放一個帳號 repl密碼 abc123給 IP1921680200有檔案處理

的權限 Step3 shutdown MySQL on the Master mysqladmin ndashu root ndashp shutdown Step4 備份 Master所有資料庫 tar ndashcvf tmpmysql-snapshottar varlibmysql 注意tar的時候MySQL是要在 stop情況下 在mysql (wwwmysqlcom) 網站的FAQ有不用shutdown的方法

92

Step5 在 master機器上修改etcmycnf 在[mysqld]區段內加入參數 log-bin server-id=這邊設定 server-id=1 sql-bin-update-same binlog-do-db=CRM只針對 CRM資料庫做紀錄 Step6 Restart MySQL on the master service mysqld start 此時因為有加入 log-bin 參數因此開始有 index產生了在varlibmysql目錄下

有index檔案紀錄資料庫的異動 log Slave server 部份 Step1 在 slave設定etcmycnf 在[mysqld]區段加入 master-host= master-user= master-password= master-port= server-id= 這邊設定 master-host=1921680100 master-user=repl master-password=abc123 master-port=3306 server-id=2 master-connect-retry=60預設重試間隔 60秒 replicate-do-db=CRM告訴 slave只做 CRM資料庫的更新 log-slave-updates Step2 將 master上的 mysql-snapshottar copy到 slave上 用 ftp傳到 slave的tmp Step3 解壓縮 Master資料庫至 Slave Server上 cd varlib tar xvf tmpmysql-snapshottar chown ndashR mysqlmysql mysql

93

chmod ndashR 770 mysql (視情況) Step4 Restart MySQL on the slave server 這時在varlibmysql目錄會出現 masterinfo此檔案紀錄了 Master MySQL server的資訊

狀況測試

One-way replication

1921680100

1921680200Master Server

erveSlave S r

圖 One-way replication架構圖 Step1 Master跟 Slave網路及服務都正常情況下由 Master端異動資料後 到 Slave端瀏覽資料檢視是否有進行 replication Step2 模擬 Slave Server 當機 可用在於 slave真的當機或是 Slave 不一定需要一直跟 master connect將Slave MySQL server shutdown由 Master端異動資料到 slave端瀏覽此時Slave應該沒有被 replication 更新然後再將 Slave端 MySQL server start起來

預設 60秒後 Slave會嘗試跟 Master要求進行 replication再去 Slave端檢視是否有更新資料

94

Step3 模擬 Master當機因為是設定 One-way replication一旦 Master Server Slave端沒有 Master的 source可以 download Two-way replication 基於 Master當機狀況於是發展雙向 Replication即 1921680100 ( Host A ) 1921680200 ( Host B )都分別擔任 MasterSlave身分

1921680100

1921680200er

Server B MasterSlave Server

Server A MasterSlave Serv

圖 Two-way replication架構圖 以下是針對兩台 MySQL伺服器進行雙向 Replication Step1觀念同單向 replication只是改成 Master也有 Slave身分 Slave也有Master的身分先分別在 Server AServer B 都去 grant一個進行 replication的身分 [A]mysqlgtGRANT FILE ON TO repl1921680200 IDENTIFIED BY lsquoabc123rsquo [B]mysqlgt GRANT FILE ON TO repl1921680100 IDENTIFIED BY lsquoabc123rsquo Step2做完單向 replication後stop Server Aserver B MySQL service此時 AB資料是一樣的

95

修改etcmycnf設定 範例 Server A [mysqld] datadir=varlibmysql socket=varlibmysqlmysqlsock server-id=1 log-bin sql-bin-update-same binlog-do-db=CRM master-host=1921680200 master-user=repl master-password=abc123 log-slave-updates master-connect-retry=60 replicate-do-db=CRM Server B [mysqld] datadir=varlibmysql socket=varlibmysqlmysqlsock server-id=2 log-bin sql-bin-update-same binlog-do-db=CRM master-host=1921680100 master-user=repl master-password=abc123 log-slave-updates master-connect-retry=60 replicate-do-db=CRM 分別 start Server AServer B MySQL後此時雙方都是 MasterSlave身分一旦哪一方資料異動就會通知對方來 replication-若 replication失效則必須將Server AServer B的masterinfo及index00x 都砍掉然後分別 restart MySQL server進行測試檢視成果 實務上通常如果需要做Two-way replication通常會搭配Virtual Server使用

96

在前端架設一台Virtual Server不過此部份不在此份SOP討論範圍內有興趣

的讀者可參考 httpwwwlinuxvirtualserverorg 網站

1921680100 1921680200

Host A MasterSlave Server

Host B MasterSlave Server

Virtual Host

圖 Virtual Server + Two-way replication 架構圖

97

圖 High Availability Linux Virtual Server架構圖

98

  • COSA-SOP-03-006
  • 第一章 簡介
    • 11適用對象 (Audience)
    • 12 MySQL本身
    • 13 MySQL 40版跟50版重大的改進功能
    • 14 各家資料庫軟體比較
      • 第二章 前置需求
      • 第三章 安裝
        • 31 MySQL安裝
        • 32 phpMyAdmin安裝
        • 33 升級及注意事項
          • 第四章 MySQL管理
            • 41 Webmin 管理介面
            • 42 phpMyAdmin 的操作介面
            • 43管理指令介紹
              • 431 利用mysqladmin設定root的密碼
                  • 第五章 實用範例
                    • 51 任務一Web Base客戶通訊錄
                    • 52 任務二Web Base群組軟體 ( twig )
                      • 第六章 維護及更新程序
                        • 61 日常維護
                        • 62 更新程序
                        • 63 備份重要檔案
                        • 64 離線備份與還原
                        • 65 線上備份與還原
                          • 第七章 問題與解答
                          • 第八章 參考資料
                          • 附錄一 SQL Command 介紹
                          • 附錄二Replication
Page 44: DataBase Server Standard Operation Procedureebooks.lib.ntu.edu.tw/1_file/oss/63/93doc4-5.pdf · 業務的公司帶來了不少壓力,譬如微軟,甲骨文 ... 外的錢用在第三方的資料庫產品上,譬如就可以不用再購買甲骨文公司

423使用者管理

Step1建立使用者

圖 4-26

44

圖 4-27

Step2 給予權限

圖 4-28

Step3權限列表

45

圖 4-29

43管理指令介紹

431 利用 mysqladmin設定 root的密碼

當您在Windows 或 Linux 中安裝好 MySQL後系統會自動幫您建立兩個

帳分別是 root 和 匿名者MySQL的 root 跟 Linux 最高權限使用者 root無關MySQL的 root使用者相當於 MS SQL 中的 sa 帳號擁有最高的 Database管理權限但系統預設 MySQL的 root 是不需要密碼所以通常我們一安裝

MySQL後首要任務便是修改 root的密碼 我們可以利用 mysqladmin工具或是直接修改 MySQL內部資料庫的使用者資

料 mysqladmin ndashu root ndashh cosaexamplecom password lsquo1234rsquo

46

-u 表示使用者帳號root 為 MySQL預設的管理帳號

-h 表示 MySQL主機的主機名稱也可使用 IP Address password 表示使用者的密碼因為字串請使用單引號將密碼括起來 密碼設定完成之後還是可以利用 mysqladmin修改密碼但是你必須提供目前的密碼

432 連線 MySQL

mysql -uroot -p密碼 (-p和密碼之間不能有空白) 或 mysql -uroot -p (此方式會在進入後要求密碼) [rootossc phpMyAdmin] mysql -u root -p1234

Welcome to the MySQL monitor Commands end with or g

Your MySQL connection id is 25 to server version 32354

Type help or h for help Type c to clear the buffer

mysqlgt show databases

+----------+

| Database |

+----------+

| mysql |

| test |

+----------+

2 rows in set (000 sec)

mysqlgt exit

Bye

[rootossc phpMyAdmin]

433 建立資料庫

可利用 mysqladmin指令建立 CONTACT資料庫 mysqladmin -u root -p1234 create CONTACT

47

或是利用 mysql指令 [rootossc bluepage] mysql -u root -p1234 Welcome to the MySQL monitor Commands end with or g Your MySQL connection id is 1057 to server version 32354 Type help or h for help Type c to clear the buffer mysqlgt create database CONTACT Query OK 1 row affected (000 sec) mysqlgt show databases +----------+ | Database | +----------+ | CONTACT | | address | | hello | | mysql | | nuke | | test | +----------+ 6 rows in set (000 sec) mysqlgt exit

434 建立資料表

編寫 adresssql內容如下 -- Table structure for table address CREATE TABLE address ( id int(11) NOT NULL auto_increment name varchar(20) NOT NULL default tel varchar(15) NOT NULL default PRIMARY KEY (id) ) TYPE=MyISAM

48

-- Dumping data for table address INSERT INTO address VALUES (1林小明0800016888) INSERT INTO address VALUES (2黃大雄0800016888) INSERT INTO address VALUES (3劉小芬0800024365) 然後執行此 sql script mysql -u root -p1234 CONTACT lt addresssql 或是利 mysql command [rootossc bluepage] mysql -u root -p1234 Welcome to the MySQL monitor Commands end with or g Your MySQL connection id is 1090 to server version 32354 Type help or h for help Type c to clear the buffer mysqlgt use CONTACT Database changed Database changed mysqlgt CREATE TABLE address ( -gt id int(11) NOT NULL auto_increment -gt name varchar(20) NOT NULL default -gt tel varchar(15) NOT NULL default -gt PRIMARY KEY (id) -gt ) TYPE=MyISAM Query OK 0 rows affected (000 sec) mysqlgt INSERT INTO address VALUES (1林小明0800016888) Query OK 1 row affected (000 sec) mysqlgt INSERT INTO address VALUES (2黃大雄0800016888) Query OK 1 row affected (000 sec) mysqlgt INSERT INTO address VALUES (3劉小芬0800024365) Query OK 1 row affected (000 sec) mysqlgt exit Bye

49

第五章 實用範例

51 任務一Web Base客戶通訊錄

任職於開放科技公司的林小明前些日子在最符合成本效益的條件下快

速地完成公司網站的建置老闆因此對小明讚譽有加最近因為公司存放客戶資

料的 SQL Server主機屢遭病毒攻擊加上作業系統本身的問題當機次數頻繁

老闆希望能儘快把公司的客戶通訊錄程式移轉到較穩定的環境上因為此客戶通

訊錄程式最主要給內部人員使用所以介面美觀並不特別要求只求穩定且能快

速得到查詢結果老闆希望在短時間先看到程式的雛型並鍵入資料對其效率

及穩定性進行測試因為上次小明表現突出所以這次不可能的任務自然又落到

小明身上 小明想來想去既然要快速又穩定他而且又不希望所有人都得安裝 Client

程式於是小明決定)捨棄他的舊愛「Delphi+MS SQL」投向新歡「Apache + MySQL + PHP」利用此架構來設計一個簡單實用的Web Base客戶通訊錄程式

511 Web Base客戶通訊錄架構

此程式需要建立 CONTACT的資料庫並建立 adress Tables其結構如下表建立步驟請參考第三章 欄位名稱 資料型態 長度 說明 id INT (自動編號) 連絡人編號 name varchar文字 20 連絡人姓名 tel Varchar文字 15 連絡人電話 Web Base通訊錄共有下列幾個檔案功能如下表

檔案名稱 說明 Indexhtml Web Base通訊錄首頁 addphp 新增連絡人的 php程式 searchphp 尋找連絡人的 php程式 editphp 具有更新及刪除功能的 php程式

50

我們將這些檔案放至varwwwhtmlbluepage (預設無 bluepage目錄)

512 Web Base通訊錄測試

httpwwwopencombluepage 新增資料

圖 5-1 新增連絡人

圖 5-2 填入資料

51

圖 5-3 新增成功

搜尋及異動資料

圖 5-4 搜尋通訊錄

52

圖 5-5 編輯資料

圖 5-6 更新資料

513 程式內容及說明

lt-- 程式範例indexhtml--gt lthtmlgt ltheadgtlttitlegt通訊錄lttitlegtltheadgt ltbodygt ltcentergt

53

lth2gt通訊錄lth2gtlthrgt lta href=indexhtmlgt通訊錄ltagt | lta href=addphpgt新增連絡人ltagt | lta href=searchphpgt搜尋通訊錄ltagt ltcentergt ltbodygt lthtmlgt lt-- 程式範例addphp --gt lthtmlgt ltheadgtlttitlegt新增連絡人lttitlegtltheadgt ltbodygt ltcentergtlth2gt新增連絡人lth2gtltcentergtlthrgt lt 取得欄位資料 if (isset($_POST[Name]) ampamp isset($_POST[Tel]) ) $name = $_POST[Name] $tel = $_POST[Tel] 檢查是否有輸入欄位資料 if ($name = ampamp $tel = ) 建立 SQL字串 $sql = INSERT INTO address (name tel) values( $sql= $name $tel) 建立 MySQL 連結 $link = mysql_connect(localhostroot1234) 選擇資料庫 mysql_select_db(CONTACT) 執行 SQL指令 mysql_query($sql) mysql_close($link) echo ltfont color=redgt新增連絡人成功ltfontgtltbrgt gt ltform action=addphp method=postgt lttable border=0 width=300gt lttrgtlttdgt姓名 lttdgt

54

lttdgtltinput type=text name=Name size=20 maxlength=10gtlttdgtlttrgt lttrgtlttdgt電話 lttdgt lttdgtltinput type=text name=Tel size=20 maxlength=20gtlttdgtlttrgt lttrgtlttd colspan=2 align=centergt ltinput type=submit value=新增連絡人gtlttdgtlttrgt lttablegt ltformgt ltbrgtlta href=indexhtmlgt通訊錄ltagt | lta href=addphpgt新增連絡人ltagt | lta href=searchphpgt搜尋通訊錄ltagt ltbodygt lthtmlgt

lt-- 程式範例searchphp --gt lthtmlgt ltheadgtlttitlegt搜尋通訊錄lttitlegtltheadgt ltbodygt ltcentergtlth2gt搜尋通訊錄lth2gtlthrgt lt if (isset($_POST[Search])) 建立資料庫連結並選定資料庫 $link = mysql_connect(localhostroot1234) mysql_select_db(CONTACT) 建立基本的 SQL字串 $sql = SELECT FROM address 檢查是否輸入姓名 if (chop($_POST[Name]) = ) $name = name LIKE $_POST[Name] else $name = 檢查是否輸入電話號碼 if (chop($_POST[Tel]) = ) $tel = tel LIKE $_POST[Tel] else $tel =

55

if條件組合 SQL字串 if (chop($name) = ampamp chop($tel) = ) $sql= WHERE $name AND $tel elseif (chop($name) = ) 只有姓名 $sql = WHERE $name elseif (chop($tel) = ) 只有電話號碼 $sql = WHERE $tel $sql= ORDER BY name 最後加上排序 $result = mysql_query($sql) 取得欄位數 $total_fields = mysql_num_fields($result) echo lttable border=1gt echo lttrgtlttdgt編號lttdgtlttdgt姓名lttdgtlttdgt電話lttdgtlttd colspan=2gt功能選項lttdgtlttrgt 表格顯示查詢結果 while ($rows = mysql_fetch_array($result MYSQL_NUM)) echo lttrgt for ($i = 0 $i lt $total_fields $i++) echo lttdgt$rows[$i]lttdgt echo lttdgtlta href=editphpaction=editampid= echo $rows[0]gtltbgt編輯ltbgtlttdgt echo lttdgtlta href=editphpaction=delampid= echo $rows[0]gtltbgt刪除ltbgtlttdgt echo lttrgt echo lttablegtlthrgt mysql_free_result($result) mysql_close($link) gt ltcentergt ltform action=searchphp method=postgt lttable border=0 width=450gt lttrgtlttdgt搜尋姓名 lttdgt lttdgtltinput type=text name=Name size=10 maxlength=20gtlttdgtlttrgt lttrgtlttdgt搜尋電話 lttdgt lttdgtltinput type=text name=Tel

56

size=20 maxlength=20gtlttdgtlttrgt lttrgtlttd colspan=2 align=centergt ltinput type=submit name=Search value=搜尋gtlttdgtlttrgt lttablegt ltformgt ltbrgtlta href=indexhtmlgt通訊錄ltagt | lta href=addphpgt新增連絡人ltagt | lta href=searchphpgt搜尋通訊錄ltagt ltbodygt lthtmlgt

lt ob_start() gt lt-- 程式範例editphp --gt lthtmlgt ltheadgtlttitlegt編輯通訊錄lttitlegtltheadgt ltbodygt lt 取得 URL 參數 $id = $_GET[id] $action = $_GET[action] 建立資料庫連結 $link = mysql_connect(localhostroot1234) mysql_select_db(CONTACT) 選擇資料庫 執行的操作 switch ($action) case update 更新 取得欄位資料 $name = $_POST[Name] $tel = $_POST[Tel] $sql = UPDATE address SET name=$name tel=$tel WHERE id=$id mysql_query($sql) 執行 SQL指令 mysql_close($link) header(Location searchphp) 轉向到 serachphp break case del 刪除 $sql = DELETE FROM address WHERE id=$id

57

mysql_query($sql) 執行 SQL指令 mysql_close($link) header(Location searchphp) 轉向到 serachphp break case edit 編輯 $sql = SELECT FROM address WHERE id=$id $result = mysql_query($sql) 執行 SQL指令 $row = mysql_fetch_row($result) 取回記錄 $name = $row[1] 取得欄位 name $tel = $row[2] 取得欄位 tel mysql_close($link) 顯示編輯表單 gt ltcentergtlth2gt更新通訊錄lth2gtltcentergtlthrgt ltform action=editphpaction=updateampid=lt echo $id gt method=postgt lttable border=0 width=300gt lttrgtlttdgt姓名 lttdgt lttdgtltinput type=text name=Name size=20 maxlength=10 value=lt echo $name gtgtlttdgtlttrgt lttrgtlttdgt電話 lttdgt lttdgtltinput type=text name=Tel size=20 maxlength=20 value=lt echo $tel gtgtlttdgtlttrgt lttrgtlttd colspan=2 align=centergt ltinput type=submit value=更新連絡人gtlttdgtlttrgt lttablegt ltformgt ltbrgtlta href=indexhtmlgt通訊錄ltagt | lta href=addphpgt新增連絡人ltagt | lta href=searchphpgt搜尋通訊錄ltagt lt break gt ltbodygt lthtmlgt

58

52 任務二Web Base群組軟體 ( twig )

順利完成Web Base客戶通訊錄程式測試一段時間後「Apache + MySQL + PHP」架構的穩定與快速巳深得老闆與公司所有同事的認同隨著公司業績蒸

蒸日上人員組織編罝愈來愈龐大跨部門的會議愈來愈多業務員每日排滿拜

訪客戶的行程跟客戶的 Email的往來也愈來愈頻繁 愈來愈多部門的同事希望公司能建置一套群組軟體提供 web mail可讓業

務人員方便收發 mail還有連絡人議事日程待辦工作書簽等功能讓整個

公司運作及個人時間管理更有效率

老闆問小明對這些需求有什麼看法小明認為如果這些功能完全由程式部

門開發必定曠日費時而且耗費公司資源小明在網路尋找是否有提供這些功能

的Free Software皇天不負苦心人小明發現了TWIG (The Web Information Gateway) httptwigscrewdrivernet這個群組軟體它在 Web 上整合郵件新聞聯絡人議事日程工作序書簽等功能非常符合公司的需求 Step 1 下載 twig-277targz 下載網址 httptwigscrewdrivernetdownloadphp3

Step 2 解開 twig-277targz tar -xzvf twig-277targz

59

Step 3 執行安裝動作安裝到 varwwwhtmltwig 目錄 cd twig-277 twig-install varwwwhtmltwig

Step 4 建立 MySQL 資料庫(twig)及各資料表

cd setup mysql -u root -p1234 mysqlgt create database twig Query OK 1 row affected (001 sec) mysqlgt quit mysql -u root ndashp1234 twiglt twigtablemysql

Step 5 修改 configincphp3 參數設定 vi varwwwhtmltwigconfigconfigincphp3 $config[fromdomain] = opencom 網域 $config[language] = chinesebig5 中文訊息 $config[imap_port] = 143notls

60

Step 6 修改連結 MySQL 的帳號密碼 vi varwwwhtmltwigconfigdbconfigincphp3 $dbconfig[sqlusername] = root username $dbconfig[sqlpassword] = 1234 password

Step 7 其他設定檔

vi etchttpdconfhttpdconf 加入 AddType applicationx-httpd-php php3 在 DirectoryIndex最後加入 indexphp3 DirectoryIndex indexhtml indexhtmlvar indexphp3 在 AddDefaultCharset ISO-8859-1加上 AddDefaultCharset ISO-8859-1

vi etcphpini register_globals = On service httpd restart Step 8 sendmail 設定 vi etcmailsendmailcf在 264 行前面加上並重新啟動 sendmail「service snedmail restart」 262 SMTP daemon options 263 264 O DaemonPortOptions=Port=smtpAddr=127001 Name=MTA 265 266 SMTP client options 267 O ClientPortOptions=Family=inet Address=00

61

Step 9 檢查設定有無錯誤 http主機名稱twigtestphp3

62

Step 10 登入 twig ( http主機名稱twig)

63

第六章 維護及更新程序

61 日常維護

系統管理員最好定期以 root 身份登入看看信件在 RedHat Linux 中有一支 logwatch 程式會定時去分析 log file如果發現異常便會發信給 root除此之外筆者建議讀者平時就檢查 MySQL log file ( varlogmysqldlog)是否有異常情形

62 更新程序

讀者可至httprpmfindnet 尋找MySQL相關套件至於升級的相關步驟請參

考Linux OS SOP 第 54節

63 備份重要檔案

預設 MySQL 的 DB 檔案是存在 varlibmysql 內以 DB名稱為目錄目錄

內就是該 DB 的所有資料通常得定期備份還有 MySQL的設定檔 etcmycnf也別忘了一起備份

64 離線備份與還原

641 離線備份

預設 MySQL 的 DB 檔案是存在 varlibmysql 內以 DB 名稱為目錄目錄內

就是該 DB 的所有資料像 CRM 這個 DB就是存在 varlibmysqlCRM 內在備份前因為怕資料尚未完全寫入磁碟而且 MySQL 會 Lock 在使用的 DB 檔案所以應該是要先把 MySQL 先 Shutdown 一下整個備份的程序可以下像下面的指令去完成 cd varlibmysql

64

service mysqld stop tar cvfz CRM_db_20030905tgz CRM service mysqld start 對這樣就可以了 不過要注意的是怕 DB 內每個 Tables 間的資料有關關

聯性所以最好是把整個 DB 一次備起來單獨只備哪個 Tables 的檔案以後回存時怕會有資料關聯不一致的問題

642 離線還原

DB 發生錯誤而要回存時其實也不難先找出最近一次完整正常的備份先把現在錯誤的網頁或 DB 先更名或 tar 起來再把好的備份給解開回原來目錄位

置就行了需要注意的是 MySQL 服務最好也是要先停止回存完成後再啟動服務回存 DB 的整個程序可能像下面 cd varlibmysql service mysqldstop mv CRM CRM_OLD tar xvfz CRM_db_20030905tg service mysqld start

65 線上備份與還原

651 線上備份

使用像上面的檔案方式備份是個不錯的方法它最少可以保持該主機某個時間點的完整檔案備份但還是有一些問題需要考慮到有些主機就不只建立一個 DB 而已總不能為了備份某個 DB 而把整個 MySQL 服務停止備份檔案的方式回存在原主機上一定適用但假如 MySQL 版本升級或是在那天該網頁空間需遷機移機到別的主機時那就沒人敢保證備出來的資料檔可以用所以我們可以考慮另一種備份的方式是使用 MySQL 本身提供的功能 MySQL Data Dump指令是 mysqldump

65

使用 MySQL 的 Dump 功能可以把 DB 的結構資料或結構加資料 Dump 成文字檔 mysqldump 指令提供的彈性很大你可以選擇把整個 DB Dump 成一個檔或是每個 Table 為一個檔甚至是把結構檔和資料分開儲存都

可以 mysqladmin -uroot -p flush-logs mysqldump CRM -uroot -p --opt gt CRM_20030905sql (CRM 是 DB 名稱 opt 是一個使用完整 Dump 參數) 假如只是要單獨 Dump 某個 Table 時只要在上面的指令後轉出符號 gt 前加個 Table 名稱就可以如只要 phpbb2_users 這個 Table 的 Dump 時只要下 mysqldump CRM -uroot -p --opt CUSTOMER gt CRM_CUSTOMER_20030905sql

652 線上還原

若要回存整個資料庫只需將壓縮的備份檔還原成 Dump 的檔案再用下面的指令回存 mysql CRM -uroot -p lt CRM_20030905sql 這邊需注意的是若建立備份時是以--opt或--add-drop-table為參數時回存的 動作是先將舊的 Table 先刪除重建 Table 的結構後再把 Data 匯入所以回存後所有的資料會回到你當時備份那個時間點因此在回存資料時可以考慮把現有錯誤或不完整的 DB 先備份一份下來以備不時之需或是拿來比對錯誤的地

方在那裡當然你也可以把資料回存到另一個測試用的 DB 內只要把上面指令

的 DB 名稱改成你的測試用 DB 名稱即可 使用這種回存方式 MySQL 服務不需停止也不會動到其他正在使用的 DB 在一些提供 MySQL 服務的虛擬主機可用這種方式作你自己的 DB 備份及回存

66

另外假如你是系統重建或是移機時切需在新的 MySQL 內新建一個空白 DB 後才行作回存的工作你可以用下面的指令建立 mysql -uroot -p -e CREATE DATABASE CRM (上面的 CRM是你要新建的 DB 名稱) 另一種作法先用 mysql 指令進入 mysql client console 然後再用 CREATE DATABASE CRM 這樣就行了記得尾端要加個 符號該行指令才會執行

67

第七章 問題與解答

Q1RedHat 90預附的 MySQL到底有無支援 Transcation機制 Ans MySQL自 32334a之後的 MySQL-Max版本加入 InnoDB的資料庫類型透過

InnoDBMySQL同樣可以進行 COMMIT與 ROLLRACK的動作RedHat 90預附的 MySQL為 32354a-11巳支援 InnoDB的資料庫類型不過必須做以

下設定 1cp usrsharedocmysql-server-32354amy-mediumcnf to etcmycnf 2 vi etcmycnf 將以下設定前的拿掉 innodb_data_home_dir = varlibmysql innodb_data_file_path = ibdata110Mautoextend innodb_log_group_home_dir = varlibmysql innodb_log_arch_dir = varlibmysql 3service mysqld restart 如此一來各位在建立Table時便可指定Table Type為 innodb ( ex create table with type=innodb ) Q2如何解決 php+mysql 許功蓋等字變亂的問題 Ans 方法一 【確定 MySQL 預設的字元集】 1 打開 WinMySQLadmin 管理畫面(在視窗右下角狀態列紅綠燈圖示中按滑鼠

右鍵點選 Show me 選項) 2 點選管理畫面中 [Variables] 標籤選項其中 character_set變數就是您預設

字元集的變數其預設是 latin1 字元集(我們要將他改回 big5)而 chatacters_set 變數則是 MySQL 可以支援哪些字元集 【修改預設字元集變數 character_set 】 1 請點選管理畫面中 [myini Setup] 標籤選項設定 myini 2 按一下 [Pick-up and Edit myini values] 按鈕以便編輯目前的 myini 設定 3 在 [mysqld] 設定區塊底下新增一行 default-character-set = big5 變數設

68

定 4 新增一個 [client] 設定區塊並加入第三步驟的變數設定(游標往下移到空白處新增兩行 [client] 和 default-character-set=big5) 5 按一下畫面左下方 [Save Modification] 按鈕儲存設定 6 重新啟動 MySQL 或 Windows 方法二 Server端注意事項 phpini 中有關的設定為(預設值) Magic quotes for incoming GETPOSTCookie data magic_quotes_gpc = On Use Sybase-style magic quotes (escape with instead of ) magic_quotes_sybase = Off Client端注意事項 1中文資料送進 mysql 前請用 addslashes($str) 處理 2處理後送進 mysql 時請用 括起來並在參數後留一個空白如 $sql = UPDATE ezf_table set tablename=$tname tableend=$endtime table inguser=$tguser tableingid=$tguserid tableallnumber=$tnumber tableloca l=$tablelocal tableanyone=$tableopen tabletext=$ttext WHERE tableid=$t ableid tablename=$tname c 取出時請用 stripslashes($str) Q3MySQL root 密碼忘了該怎麼辦 Ans 1先停掉 mysql etcrcdinitdmysql stop 2以--skip-grant-table 的參數啟動 mysql safe_mysql --skip-grant-tableamp 3 更改 root 密碼 mysql mysql mysqlgt UPDATE user SET password=password(newpassword)

69

WHERE user=root mysqlgt FLUSH PRIVILEGES mysqlgt exit 4停掉 mysql再重跑 mysqladmin -uroot -p shutdown Enter password 輸入新設定的密碼 etcrcdinitdmysql start

Q4NULL值問題

Ans

NULL值的概念是造成 SQL的新手的混淆的普遍原因他們經常認為 NULL是和一個空字符串的一樣的東西不是這樣的例如下列語句是完全不同的

mysqlgt INSERT INTO my_table (phone) VALUES (NULL)

mysqlgt INSERT INTO my_table (phone) VALUES ()

兩個語句把值插入到 phone 列但是第一個插入一個 NULL值而第二個插入一個空字符串第一個的含義可以認為是ldquo電話號碼不知道而第二個則可意味

著ldquo她沒有電話

在 SQL中NULL值在于任何其他值甚至 NULL值比較時總是假的(FALSE)包含 NULL的一個表達式總是產生一個 NULL值除非在包含在表達式中的運算符和函數的文檔中指出在下列例子所有的列返回 NULL

mysqlgt SELECT NULL1+NULLCONCAT(InvisibleNULL)

如果你想要尋找值是 NULL的列你不能使用=NULL測試下列語句不返回任

何行因為對任何表達式expr = NULL是假的

mysqlgt SELECT FROM my_table WHERE phone = NULL

要想尋找 NULL值你必須使用 IS NULL測試下例顯示如何找出 NULL電話號碼和空的電話號碼

70

mysqlgt SELECT FROM my_table WHERE phone IS NULL mysqlgt SELECT FROM my_table WHERE phone =

在 MySQL中就像很多其他的 SQL服務器一樣你不能索引可以有 NULL值的列你必須聲明這樣的列為 NOT NULL而且你不能插入 NULL到索引的

列中

當用 LOAD DATA INFILE 讀取數據時空列用更新如果你想要在一個列中有

NULL值你應該在文本文件中使用N字面上的詞NULL也可以在某些情形下使用

當使用 ORDER BY時首先呈現 NULL值如果你用 DESC以降序排序NULL值最後顯示當使用 GROUP BY時所有的 NULL值被認為是相等的

為了有助于NULL的處理你能使用 IS NULL和 IS NOT NULL運算符和 IFNULL()函數

對某些列類型NULL值被特殊地處理如果你將 NULL插入表的第一個TIMESTAMP 列則插入當前的日期和時間如果你將 NULL插入一個AUTO_INCREMENT 列則插入順序中的下一個數字

Q5如何將圖片存放於 MySQL中

Ans

Step 1建立資料庫 test

Step 2 建立表格 binary_data

CREATE TABLE binary_data (

id INT(4) NOT NULL AUTO_INCREMENT PRIMARY KEY

description CHAR(50)

bin_data LONGBLOB

filename CHAR(50)

filesize CHAR(50)

filetype CHAR(50)

71

)

Step 3 利用 storephp 寫入圖片

storephp 程式碼

ltHTMLgt ltHEADgtltTITLEgtStore binary data into SQL DatabaseltTITLEgtltHEADgt ltBODYgt lt code that will be executed if the form has been submitted

if ($submit) mysql_connect(localhostrootYOUR_PASSWORD) mysql_select_db(test) $data=Base64_Encode(fread(fopen($form_data r) filesize($form_data))) $result=MYSQL_QUERY(INSERT INTO binary_data (descriptionbin_datafilenamefilesizefiletype) VALUES ($form_description$data$form_data_name$form_data_size$form_data_type)) $id= mysql_insert_id() print ltpgtThis file has the following Database ID ltbgt$idltbgt MYSQL_CLOSE() else else show the form to submit new data

gt

ltform method=post action=ltphp echo $PHP_SELF gt enctype=multipartform-datagt File Descriptionltbrgt ltinput type=text name=form_description size=40gt ltINPUT TYPE=hidden name=MAX_FILE_SIZE value=4000000gt ltbrgtFile to uploadstore in databaseltbrgt ltinput type=file name=form_data size=40gt ltpgtltinput type=submit name=submit value=submitgt ltformgt lt

72

gt ltBODYgt ltHTMLgt

Step 3 利用 storephp 取出圖片

getdataphp 程式碼

lt Syntax getdataphp3id=ltidgt if($id) you may have to modify login information for your database server MYSQL_CONNECT(localhostrootYOUR_PASSWORD) mysql_select_db(test) $query = select bin_datafiletype from binary_data where id=$id $result = MYSQL_QUERY($query) $data = Base64_Decode(MYSQL_RESULT($result0bin_data)) $type = MYSQL_RESULT($result0filetype) Header( Content-type $type) echo $data gt

Q6MySQL裝好之後啟動時或是執行 mysqladmin會出現如下訊息 Cant connect to local MYSQL Server through Socket varlibmysqlmysqlsock或是

Cant connect to local MYSQL Server through Socket tmpmysqldsock

Ans 可能有下列幾個原因

1這個 mysqldsock 不見了被某人刪除了或是被一些系統自動執行程式給刪

了例如有些 cron任務便會設定定期刪除 tmp 裡的東西所以呢您只能修改

cron 裡的設定讓它不要清除 mysqldsock 2在啟動時也可以改變 mysqldsock的位置您在啟動 MySQL的時候可以加入此參數usrlocalmysqlbinsafe_mysqld --user=mysql --socket=其他路

徑socket amp 同時得去設定環境變數 MYSQL_UNIX_PORT的值以指定新的

73

路徑 3若是您沒改 MYSQL_UNIX_PORT的值那麼您可以在執行指令的時候才打

例如mysqladmin --socket=其他路徑socket version Q7How to get the last insert id Ans CREATE TABLE product ( id INT(4) NOT NULL AUTO_INCREMENT PRIMARY KEY description VARCHAR(50) ) 1利用 SQL的話 mysqlgt insert into product(description) values(123) Query OK 1 row affected (000 sec) mysqlgt select last_insert_id() +------------------+ | last_insert_id() | +------------------+ +------------------+ 1 row in set (000 sec) ======================================== 2如果是 PHP的話 你可以用mysql_insert_id()取得該 id PHP example $result=MYSQL_QUERY(INSERT INTO product (description) VALUES ($description)) $id= mysql_insert_id() print This file has the following Database ID $id Q8如何將文字檔匯入資料庫 Ans $addr=homehttpdhtmlphpschool001txt $sql_select = load data infile $addr into table test fields terminated by t 解說 $sql_select = load data infile 文字檔名 into table 表格名 fields terminated by

74

t

(欄位分隔以 TAB鍵) 該文字檔須與資料表欄位格式相符 例如欄位有三個 則文字檔為每行一筆資料如下 欄 1資料ltTABgt欄 2資料ltTABgt欄 3資料 欄 1資料ltTABgt欄 2資料ltTABgt欄 3資料 欄 1資料ltTABgt欄 2資料ltTABgt欄 3資料 欄 1資料ltTABgtltTABgt欄 3資料

Q9如何撰寫 MySQL C API Ans Step 1利用文字編輯器撰寫以下程式碼 mysqlcc

include ltstdiohgt

include ltmysqlmysqlhgt

int main (int argc char argv[])

MYSQL mysql

MYSQL_RES res

MYSQL_ROW row

if (argc = 2)

fputs (Usage myc ltdatabasegt stderr)

return 1

if ((mysql_connect(ampmysqllocalhostrootYour_Password)))

fputs (Error connecting stderr)

abort()

75

if (mysql_select_db(ampmysqlargv[1]))

fputs (Error selecting database stderr)

abort()

if (mysql_query(ampmysqlSELECT FROM test_table))

fputs (Error processing query stderr)

abort()

if ((res = mysql_store_result(ampmysql)))

fputs (Error storing results stderr)

abort()

while((row = mysql_fetch_row(res)))

uint i = 0

for (i=0 i lt mysql_num_fields(res) i++)

printf(s row[i])

printf(n)

return 0

Step 2 Compile

gcc -Iusrlocalmysqlinclude -Lusrlocalmysqllibmysql mysqlcc ndashlm -lmysqlclient

(其中 include path與 library path取決於你的 MySQL安裝路徑)

76

如果執行時發生如下 error Run problemerror in loading shared libraries libmysqlclientsoX 將你的 MySQL library path(for exampleusrlocalmysqllibmysql) 加入etcldsoconf and run sbinldconfig -v Q9ASP + MySQL 範例程式 Ans Dim myconn As New ADODBConnection Dim myrs As New Recordset Dim mySQL As String Dim myrows As Long myconnOpen DSN=MyODBCsample mySQL = SELECT from user myrsSource = mySQL Set myrsActiveConnection = myconn myrsCursorLocation = adUseClient myrsOpen myrows = myrsRecordCount myrsClose myconnClose 可參考 httpwwwdwamnetmysqlasp_myodbcasp 有詳細的資料 Q10如何將 MySQL中的資料庫匯出成txt檔 Ans select from TableName into outfile textxls all result fields will seperate by tab

77

第八章 參考資料

英文部份 網址 1 httpwwwmysqlcom MySQL 網站有第一手有關 MySQL的資料 2 httpwwwmysqlcomdocenReplicationhtml 有關 MySQL Replication 的文件 3 httpwwwgeocitiescomsqlhomefaqstore_blobhtml 如何在 MySQL 存放 BLOB的資料 4httpwwwsapdborg 有關 SAP跟 MySQL相關合作的網站 書藉 1 Cooking with MySQL

Paul DuBois has selected sample recipes from the hundreds youll find in his book MySQL

Cookbook In this third and final series of excerpts showcasing these recipes learn how to

compute team standings how to calculate the differences between successive Dec 26

2002 2 Tips for Building Web Database Applications with PHP and MySQL by Hugh E Williams co-author of Web Database Applications with PHP amp MySQL 04042002

3 Managing and Using MySQL 2nd Edition By Tim King George Reese Randy Jay Yarger

4 MySQL Cookbook By Paul DuBoisPublisher OReillyPub Date October 2002

中文部份

78

1 httplinuxtncedutwtechdocmysqlmysql_docmanual_tochtml MySQL 中文手冊 2 httpchenshloxaedutwphpZ_1php PHP+MySQ程式研習設計網站 3 httplinuxtncedutwtechdocbanicdownhtml PHP 4 手冊 4 httpwwwtncedutwadmin_zonephp台南縣教育網網路中心有很多 Linux相關文件 5 httpdobtncedutw網站建置百寶箱有很多 PHP MySQL 相關範例程式 5 httpwwwdbworldcomtw資料庫專家電子雜誌介紹資料庫的重要觀念及名詞

79

附錄一 SQL Command 介紹

SQL (讀音ess-que-el) 是一種結構查詢語法SQL 使用於資料庫交流

傳遞相容於 ANSI (American National Standards Institute) 是一套標準的關聯

式資料庫語言 SQL 語言是執行更新或從資料系統獲取資料一般常見的關聯

資料庫系統都有提供 SQL 如 Oracle Sybase Microsoft SQL Server Access Ingres 等雖然大部份的資料庫都有提供 SQL 但也多提供了自已獨特的語

法造成了不相容的情形但標準基本的語法是相通的如Select Insert Update Delete Create and Drop 每一個系統都有支援

Table相關 Command

Create Table

關聯式資料庫包含有很多元件稱為資料表(tables) 把資料或訊息放在資

料表中 資料表是以不同的名稱做分別資料表由欄列所構成的二維陣列

欄包含欄位名資料型態 及其他可判斷的資訊列是由全部欄位構成一筆一

筆的紀錄 create table 語法用在建立一個新的資料表語法格式如下

create table tablename (column1 data type column2 data type column3 data type)

Format of create table if you were to use optional constraints

create table tablename (column1 data type [constraint] column2 data type [constraint] column3 data type [constraint]) [ ] = optional

Note You may have as many columns as youd like and the constraints are optional

80

Example

create table employee (first varchar(15) last varchar(20) age number(3) address varchar(30) city varchar(20) state varchar(20))

注意建立資料表格式要以括號把前後框住而最後以(分號)做結尾

欄位名不要超過 30個字元長而且不要使用 sql 的關鍵字(如 where select等)而在後面接是型態的宣告(如字串數字日期格式等)

資料型態是來描述欄位的方式如一個欄位Last_Name 是一個姓氏可以使用varchar (可變動長度字串) 資料型態

以下是幾個常見的資料庫型態 char(size) 固定長度字串最長為 255 位元 varchar(size) 變動長度字串最大字元數以 size 來指定 number(size) 數值格式可以是整數也可以是小數最大數字以 size 位數判

斷未指定小數位數由系統內定 date 日期格式 number(sized) 數值格式最大數字以 size 位數判斷d 為小數位數整數位

數為 size-d 位

有何限制當資料表被建立通常有一或數個欄位是要使用來做關聯的功

能 例如unique 限制(唯一值)兩筆記錄不可以相同的值 not null (非空值)該欄位一定要輸入資料不可是空的primary key (主鍵)是每一筆記錄識別的主要方式

Drop a table drop table 刪除資料表(其中的資料也會一併刪除)

drop table tablename

Example

81

drop table 和刪除全部資料是不同的刪除全部資料欄位名稱資訊等還會

存在但刪除資料表會把這一些也一併移除掉

如何查詢資料

Select 基本用法

select 語法是關連式資料庫最常用的部份可以取得你想要的資料這是一個

簡單的範例 select column1[column2etc] from tablename [where condition] [] = optional 在 select 之後所列欄位名則是要顯示的資料部份你可以一一列出各欄位

名或是以 (星號)來代表選擇全部的欄位 from 之後放資料表名稱 where 子句 (選項) 指定要過濾的條件符合者才會顯現 where 可使用的條件運算元 = 等於 gt 大於 lt 小於 gt= 大或等於 lt= 小或等於 ltgt 大相等 LIKE 相似 For example select first last city

82

from empinfo where first LIKE Er 以Er 為開頭的字串就符合要以單引號框住 Or you can specify select first last from empinfo where last LIKE s 最後一字為 S 就符合 select from empinfo where first = Eric 則表示 first name 一定要是 Eric 才可以 範例資料表empinfo 統計函數

MIN 傳回指定欄位最小值

MAX 傳回指定欄位最大值

SUM 傳回指定欄位總和

AVG 傳回指定欄位平均值

COUNT 傳回指定欄位的筆數

COUNT() 傳回資料庫中的總筆數

統計函數使用於資料表中的數值欄位配合 SELECT 語法使用 只用於總結特定單一欄位可以配合 GROUP BY 做篩選但也可以不使用 GROUP BY 語句For example

SELECT AVG(salary) FROM employee

83

傳回全部 salary 平均值

Another example

SELECT AVG(salary) FROM employee WHERE title = Programmer

傳回 salary 平均值條件為 employees 資料表中當 title 等於 Programmer

Example

SELECT Count() FROM employees

傳回 employees 資料表中紀錄總筆數

GROUP BY 語法 SELECT column1 SUM(column2) FROM list-of-tables GROUP BY column-list The GROUP BY 語句可以先以所列的欄位為條件分組排序在一起(可以多欄

位) example 要列出每一個 dept 中最高 salary 值 SELECT max(salary) dept FROM employee GROUP BY dept HAVING 語法

SELECT column1 SUM(column2) FROM list-of-tables GROUP BY column-list HAVING condition

HAVING 子句是 GROUP BY 的一部份用來過濾在 GROUP BY 所選出的資料功能如同 select 命令中 where 條件式一樣只是 HAVING 必需配合 GROUP BY 使用

我們以例子來說明我們要取得每一公司名及每一公司的薪水平均值輸入如下

84

SELECT dept avg(salary) FROM employee GROUP BY dept

但如果我們只列出薪資平均值超過 20000元的公司資料

SELECT dept avg(salary) FROM employee GROUP BY dept HAVING avg(salary) gt 20000

ORDER BY子句語法

SELECT column1 SUM(column2) FROM list-of-tables ORDER BY column-list [ASC | DESC]

[ ] =選項

ORDER BY是一個選項子句當你以排序方式來顯示資料(正向由小到大反向由大到小)以指定的欄位資料做排序

ASC = 正向- 預設值 DESC = 反向排序

For example

SELECT employee_id dept name age salary FROM employee_info WHERE dept = Sales ORDER BY salary

以上列出公司代號公司名銷售員人名年紀及薪資而條件是公司名為 Sales 顯示順序以薪資多少排序(由小到大為預設值)

如果要以多個欄位做排序要以逗號做分隔如下

SELECT employee_id dept name age salary FROM employee_info WHERE dept = Sales ORDER BY salary age DESC

85

結合條件及布林運算 SELECT column1 SUM(column2) FROM list-of-tables WHERE condition1 AND condition2 AND運算可以結兩個或以上的條件放在 WHERE子句中 兩者都要為真才

會顯示該筆記錄 OR 運算可以結兩個或以上敘述放在 WHERE子句中只要其中一個為直就

會顯示該筆記錄 For example SELECT employeeid firstname lastname title salary FROM employee_info WHERE salary gt= 5000000 AND title = Programmer 必需要薪資大於等於 50000而且職稱為 Programmer同時符合才會顯示該筆資料 以下以括號括住雖然不是必需的但如此比較容易讀 SELECT employeeid firstname lastname title salary FROM employee_info WHERE (salary gt= 5000000) AND (title = Programmer) 另外範例 SELECT firstname lastname title salary FROM employee_info WHERE (title = Sales) OR (title = Programmer) 條件為只要是 Sales 或 Programmer 職稱的就會被列出 IN and BETWEEN 子句

SELECT column1 SUM(column2) FROM list-of-tables WHERE column3 IN (list-of-values) SELECT column1 SUM(column2) FROM list-of-tables WHERE column3 BETWEEN value1 AND value2 IN 子句使用在列舉項目的使用上也就是分別測試是否符合所列的值 For example

86

SELECT employeeid lastname salary FROM employee_info WHERE lastname IN (Hernandez Jones Roberts Ruiz) 條件為姓氏(astname)要符合 Hernandez Jones Roberts or Ruiz 其中一個才會被傳回 IN運算元也可以使用 OR 的語法來取代如下結果相同 SELECT employeeid lastname salary FROM employee_info WHERE lastname = Hernandez OR lastname = Jones OR lastname = Roberts OR lastname = Ruiz 但使用 IN 句子比較短也比較易懂 你也可以使用 NOT IN 來去掉不要的記錄 BETWEEN 運算元使用在判斷是否存在兩個數值之間 For example SELECT employeeid age lastname salary FROM employee_info WHERE age BETWEEN 30 AND 40 傳回年紀 30歲到 40歲之間的資料(含 30及 40歲者) 相同的也可以使用以下語法來達到相同的結果 SELECT employeeid age lastname salary FROM employee_info WHERE age gt= 30 AND age lt= 40 你也可使用 NOT BETWEEN 來濾掉中間值的資料 數學運算 標準 ANSI SQL-92 提供以下運算

87

+ 加

- 減

餘數

餘數為除法後剩整數這不在標準的 ANSI SQL 中但大部份的資料庫都會支

援這運算元以下列出有用的函數雖不在 ANSI SQL-92 提供但一般資料庫

也會支援他們

ABS(x) 傳回 x 絕對值

SIGN(x) returns the sign of input x as -1 0 or 1 (negative zero or positive respectively)

MOD(xy) 餘數 - returns the integer remainder of x divided by y (同 xy)

FLOOR(x) 傳回小或等於 x 的最大整數值

CEILING(x) or CEIL(x)

傳回大或等於 x 的最小整數值

POWER(xy) x的 y 次方

ROUND(x) 把 x 四捨五入為整數

ROUND(xd) 四捨五入取到小數 d 位

SQRT(x) x 開平方

For example SELECT round(salary) firstname FROM employee_info 傳回薪資取到整數位

如何新增資料

insert 加入一筆新紀錄到資料表中 insert into tablename (first_columnlast_column) values (first_valuelast_value) [] = optional Example insert into employee

88

(first last age address city state) values (Luke Duke 45 2130 Boars Nest Hazard Co Georgia) Note 字串要以單引號住如string 數字框住也無妨 insert into 後面接資料表名稱再接以括號括住的欄位名在 values 後括號分別對映各欄位的值 以上的例子新增了一筆名(first) 為 Luke而住所(state) 為 Georgia 的資料

如何刪除資料

delete 可以刪除單筆或多筆紀錄 delete from tablename where columnname OPERATOR value [and|or column OPERATOR value] [ ] = optional Examples delete from employee Note 如果你沒有指定 where 子句那麼全部的紀錄都會被刪除 delete from employee where lastname = May delete from employee where firstname = Mike or firstname = Eric delete from 接著資料表名 再接著是條件式判斷沒有條件式則全部紀錄會

被刪除

如何更新資料

update 用來更新你所指定的記錄要和 WHERE 配合小心使用 語法 update tablename set columnname = newvalue[nextcolumn = newvalue2] where columnname OPERATOR value [and|or column OPERATOR value] [] = optional Examples

89

update phone_book set area_code = 623 where prefix = 979 update phone_book set last_name = Smith prefix=555 suffix=9292 where last_name = Jones update employee set age = age+1 where first_name=Mary and last_name=Williams

90

附錄二Replication

測試環境

RedHat 90 + MySQL 32358 MySQL資料庫路徑 varlibmysql MySQL設定檔 etcmycnf Master IP 1921680100 Slave IP 1921680200 請至下列網址下載最新MySQL 32358套件並利用rpm ndashUvh 更新 httpupdatesredhatcom9enosi386

圖 最新 MySQL 套件

測試架構圖

91

1921680100

1921680200Master Server

erveSlave S r

圖 測試架構圖

測試步驟

Master server 部份 Step1 確認 MasterSlave機器上所裝的 MySQL版本能進行

replication( 32329 or higher ) Step2 在 Master MySQL上開放一個帳號給 Slave mysql ndashu root ndashp mysqlgtGRANT FILE ON TO repl1921680200 IDENTIFIED BY lsquoabc123rsquo mysqlgtq 上面是 Master開放一個帳號 repl密碼 abc123給 IP1921680200有檔案處理

的權限 Step3 shutdown MySQL on the Master mysqladmin ndashu root ndashp shutdown Step4 備份 Master所有資料庫 tar ndashcvf tmpmysql-snapshottar varlibmysql 注意tar的時候MySQL是要在 stop情況下 在mysql (wwwmysqlcom) 網站的FAQ有不用shutdown的方法

92

Step5 在 master機器上修改etcmycnf 在[mysqld]區段內加入參數 log-bin server-id=這邊設定 server-id=1 sql-bin-update-same binlog-do-db=CRM只針對 CRM資料庫做紀錄 Step6 Restart MySQL on the master service mysqld start 此時因為有加入 log-bin 參數因此開始有 index產生了在varlibmysql目錄下

有index檔案紀錄資料庫的異動 log Slave server 部份 Step1 在 slave設定etcmycnf 在[mysqld]區段加入 master-host= master-user= master-password= master-port= server-id= 這邊設定 master-host=1921680100 master-user=repl master-password=abc123 master-port=3306 server-id=2 master-connect-retry=60預設重試間隔 60秒 replicate-do-db=CRM告訴 slave只做 CRM資料庫的更新 log-slave-updates Step2 將 master上的 mysql-snapshottar copy到 slave上 用 ftp傳到 slave的tmp Step3 解壓縮 Master資料庫至 Slave Server上 cd varlib tar xvf tmpmysql-snapshottar chown ndashR mysqlmysql mysql

93

chmod ndashR 770 mysql (視情況) Step4 Restart MySQL on the slave server 這時在varlibmysql目錄會出現 masterinfo此檔案紀錄了 Master MySQL server的資訊

狀況測試

One-way replication

1921680100

1921680200Master Server

erveSlave S r

圖 One-way replication架構圖 Step1 Master跟 Slave網路及服務都正常情況下由 Master端異動資料後 到 Slave端瀏覽資料檢視是否有進行 replication Step2 模擬 Slave Server 當機 可用在於 slave真的當機或是 Slave 不一定需要一直跟 master connect將Slave MySQL server shutdown由 Master端異動資料到 slave端瀏覽此時Slave應該沒有被 replication 更新然後再將 Slave端 MySQL server start起來

預設 60秒後 Slave會嘗試跟 Master要求進行 replication再去 Slave端檢視是否有更新資料

94

Step3 模擬 Master當機因為是設定 One-way replication一旦 Master Server Slave端沒有 Master的 source可以 download Two-way replication 基於 Master當機狀況於是發展雙向 Replication即 1921680100 ( Host A ) 1921680200 ( Host B )都分別擔任 MasterSlave身分

1921680100

1921680200er

Server B MasterSlave Server

Server A MasterSlave Serv

圖 Two-way replication架構圖 以下是針對兩台 MySQL伺服器進行雙向 Replication Step1觀念同單向 replication只是改成 Master也有 Slave身分 Slave也有Master的身分先分別在 Server AServer B 都去 grant一個進行 replication的身分 [A]mysqlgtGRANT FILE ON TO repl1921680200 IDENTIFIED BY lsquoabc123rsquo [B]mysqlgt GRANT FILE ON TO repl1921680100 IDENTIFIED BY lsquoabc123rsquo Step2做完單向 replication後stop Server Aserver B MySQL service此時 AB資料是一樣的

95

修改etcmycnf設定 範例 Server A [mysqld] datadir=varlibmysql socket=varlibmysqlmysqlsock server-id=1 log-bin sql-bin-update-same binlog-do-db=CRM master-host=1921680200 master-user=repl master-password=abc123 log-slave-updates master-connect-retry=60 replicate-do-db=CRM Server B [mysqld] datadir=varlibmysql socket=varlibmysqlmysqlsock server-id=2 log-bin sql-bin-update-same binlog-do-db=CRM master-host=1921680100 master-user=repl master-password=abc123 log-slave-updates master-connect-retry=60 replicate-do-db=CRM 分別 start Server AServer B MySQL後此時雙方都是 MasterSlave身分一旦哪一方資料異動就會通知對方來 replication-若 replication失效則必須將Server AServer B的masterinfo及index00x 都砍掉然後分別 restart MySQL server進行測試檢視成果 實務上通常如果需要做Two-way replication通常會搭配Virtual Server使用

96

在前端架設一台Virtual Server不過此部份不在此份SOP討論範圍內有興趣

的讀者可參考 httpwwwlinuxvirtualserverorg 網站

1921680100 1921680200

Host A MasterSlave Server

Host B MasterSlave Server

Virtual Host

圖 Virtual Server + Two-way replication 架構圖

97

圖 High Availability Linux Virtual Server架構圖

98

  • COSA-SOP-03-006
  • 第一章 簡介
    • 11適用對象 (Audience)
    • 12 MySQL本身
    • 13 MySQL 40版跟50版重大的改進功能
    • 14 各家資料庫軟體比較
      • 第二章 前置需求
      • 第三章 安裝
        • 31 MySQL安裝
        • 32 phpMyAdmin安裝
        • 33 升級及注意事項
          • 第四章 MySQL管理
            • 41 Webmin 管理介面
            • 42 phpMyAdmin 的操作介面
            • 43管理指令介紹
              • 431 利用mysqladmin設定root的密碼
                  • 第五章 實用範例
                    • 51 任務一Web Base客戶通訊錄
                    • 52 任務二Web Base群組軟體 ( twig )
                      • 第六章 維護及更新程序
                        • 61 日常維護
                        • 62 更新程序
                        • 63 備份重要檔案
                        • 64 離線備份與還原
                        • 65 線上備份與還原
                          • 第七章 問題與解答
                          • 第八章 參考資料
                          • 附錄一 SQL Command 介紹
                          • 附錄二Replication
Page 45: DataBase Server Standard Operation Procedureebooks.lib.ntu.edu.tw/1_file/oss/63/93doc4-5.pdf · 業務的公司帶來了不少壓力,譬如微軟,甲骨文 ... 外的錢用在第三方的資料庫產品上,譬如就可以不用再購買甲骨文公司

圖 4-27

Step2 給予權限

圖 4-28

Step3權限列表

45

圖 4-29

43管理指令介紹

431 利用 mysqladmin設定 root的密碼

當您在Windows 或 Linux 中安裝好 MySQL後系統會自動幫您建立兩個

帳分別是 root 和 匿名者MySQL的 root 跟 Linux 最高權限使用者 root無關MySQL的 root使用者相當於 MS SQL 中的 sa 帳號擁有最高的 Database管理權限但系統預設 MySQL的 root 是不需要密碼所以通常我們一安裝

MySQL後首要任務便是修改 root的密碼 我們可以利用 mysqladmin工具或是直接修改 MySQL內部資料庫的使用者資

料 mysqladmin ndashu root ndashh cosaexamplecom password lsquo1234rsquo

46

-u 表示使用者帳號root 為 MySQL預設的管理帳號

-h 表示 MySQL主機的主機名稱也可使用 IP Address password 表示使用者的密碼因為字串請使用單引號將密碼括起來 密碼設定完成之後還是可以利用 mysqladmin修改密碼但是你必須提供目前的密碼

432 連線 MySQL

mysql -uroot -p密碼 (-p和密碼之間不能有空白) 或 mysql -uroot -p (此方式會在進入後要求密碼) [rootossc phpMyAdmin] mysql -u root -p1234

Welcome to the MySQL monitor Commands end with or g

Your MySQL connection id is 25 to server version 32354

Type help or h for help Type c to clear the buffer

mysqlgt show databases

+----------+

| Database |

+----------+

| mysql |

| test |

+----------+

2 rows in set (000 sec)

mysqlgt exit

Bye

[rootossc phpMyAdmin]

433 建立資料庫

可利用 mysqladmin指令建立 CONTACT資料庫 mysqladmin -u root -p1234 create CONTACT

47

或是利用 mysql指令 [rootossc bluepage] mysql -u root -p1234 Welcome to the MySQL monitor Commands end with or g Your MySQL connection id is 1057 to server version 32354 Type help or h for help Type c to clear the buffer mysqlgt create database CONTACT Query OK 1 row affected (000 sec) mysqlgt show databases +----------+ | Database | +----------+ | CONTACT | | address | | hello | | mysql | | nuke | | test | +----------+ 6 rows in set (000 sec) mysqlgt exit

434 建立資料表

編寫 adresssql內容如下 -- Table structure for table address CREATE TABLE address ( id int(11) NOT NULL auto_increment name varchar(20) NOT NULL default tel varchar(15) NOT NULL default PRIMARY KEY (id) ) TYPE=MyISAM

48

-- Dumping data for table address INSERT INTO address VALUES (1林小明0800016888) INSERT INTO address VALUES (2黃大雄0800016888) INSERT INTO address VALUES (3劉小芬0800024365) 然後執行此 sql script mysql -u root -p1234 CONTACT lt addresssql 或是利 mysql command [rootossc bluepage] mysql -u root -p1234 Welcome to the MySQL monitor Commands end with or g Your MySQL connection id is 1090 to server version 32354 Type help or h for help Type c to clear the buffer mysqlgt use CONTACT Database changed Database changed mysqlgt CREATE TABLE address ( -gt id int(11) NOT NULL auto_increment -gt name varchar(20) NOT NULL default -gt tel varchar(15) NOT NULL default -gt PRIMARY KEY (id) -gt ) TYPE=MyISAM Query OK 0 rows affected (000 sec) mysqlgt INSERT INTO address VALUES (1林小明0800016888) Query OK 1 row affected (000 sec) mysqlgt INSERT INTO address VALUES (2黃大雄0800016888) Query OK 1 row affected (000 sec) mysqlgt INSERT INTO address VALUES (3劉小芬0800024365) Query OK 1 row affected (000 sec) mysqlgt exit Bye

49

第五章 實用範例

51 任務一Web Base客戶通訊錄

任職於開放科技公司的林小明前些日子在最符合成本效益的條件下快

速地完成公司網站的建置老闆因此對小明讚譽有加最近因為公司存放客戶資

料的 SQL Server主機屢遭病毒攻擊加上作業系統本身的問題當機次數頻繁

老闆希望能儘快把公司的客戶通訊錄程式移轉到較穩定的環境上因為此客戶通

訊錄程式最主要給內部人員使用所以介面美觀並不特別要求只求穩定且能快

速得到查詢結果老闆希望在短時間先看到程式的雛型並鍵入資料對其效率

及穩定性進行測試因為上次小明表現突出所以這次不可能的任務自然又落到

小明身上 小明想來想去既然要快速又穩定他而且又不希望所有人都得安裝 Client

程式於是小明決定)捨棄他的舊愛「Delphi+MS SQL」投向新歡「Apache + MySQL + PHP」利用此架構來設計一個簡單實用的Web Base客戶通訊錄程式

511 Web Base客戶通訊錄架構

此程式需要建立 CONTACT的資料庫並建立 adress Tables其結構如下表建立步驟請參考第三章 欄位名稱 資料型態 長度 說明 id INT (自動編號) 連絡人編號 name varchar文字 20 連絡人姓名 tel Varchar文字 15 連絡人電話 Web Base通訊錄共有下列幾個檔案功能如下表

檔案名稱 說明 Indexhtml Web Base通訊錄首頁 addphp 新增連絡人的 php程式 searchphp 尋找連絡人的 php程式 editphp 具有更新及刪除功能的 php程式

50

我們將這些檔案放至varwwwhtmlbluepage (預設無 bluepage目錄)

512 Web Base通訊錄測試

httpwwwopencombluepage 新增資料

圖 5-1 新增連絡人

圖 5-2 填入資料

51

圖 5-3 新增成功

搜尋及異動資料

圖 5-4 搜尋通訊錄

52

圖 5-5 編輯資料

圖 5-6 更新資料

513 程式內容及說明

lt-- 程式範例indexhtml--gt lthtmlgt ltheadgtlttitlegt通訊錄lttitlegtltheadgt ltbodygt ltcentergt

53

lth2gt通訊錄lth2gtlthrgt lta href=indexhtmlgt通訊錄ltagt | lta href=addphpgt新增連絡人ltagt | lta href=searchphpgt搜尋通訊錄ltagt ltcentergt ltbodygt lthtmlgt lt-- 程式範例addphp --gt lthtmlgt ltheadgtlttitlegt新增連絡人lttitlegtltheadgt ltbodygt ltcentergtlth2gt新增連絡人lth2gtltcentergtlthrgt lt 取得欄位資料 if (isset($_POST[Name]) ampamp isset($_POST[Tel]) ) $name = $_POST[Name] $tel = $_POST[Tel] 檢查是否有輸入欄位資料 if ($name = ampamp $tel = ) 建立 SQL字串 $sql = INSERT INTO address (name tel) values( $sql= $name $tel) 建立 MySQL 連結 $link = mysql_connect(localhostroot1234) 選擇資料庫 mysql_select_db(CONTACT) 執行 SQL指令 mysql_query($sql) mysql_close($link) echo ltfont color=redgt新增連絡人成功ltfontgtltbrgt gt ltform action=addphp method=postgt lttable border=0 width=300gt lttrgtlttdgt姓名 lttdgt

54

lttdgtltinput type=text name=Name size=20 maxlength=10gtlttdgtlttrgt lttrgtlttdgt電話 lttdgt lttdgtltinput type=text name=Tel size=20 maxlength=20gtlttdgtlttrgt lttrgtlttd colspan=2 align=centergt ltinput type=submit value=新增連絡人gtlttdgtlttrgt lttablegt ltformgt ltbrgtlta href=indexhtmlgt通訊錄ltagt | lta href=addphpgt新增連絡人ltagt | lta href=searchphpgt搜尋通訊錄ltagt ltbodygt lthtmlgt

lt-- 程式範例searchphp --gt lthtmlgt ltheadgtlttitlegt搜尋通訊錄lttitlegtltheadgt ltbodygt ltcentergtlth2gt搜尋通訊錄lth2gtlthrgt lt if (isset($_POST[Search])) 建立資料庫連結並選定資料庫 $link = mysql_connect(localhostroot1234) mysql_select_db(CONTACT) 建立基本的 SQL字串 $sql = SELECT FROM address 檢查是否輸入姓名 if (chop($_POST[Name]) = ) $name = name LIKE $_POST[Name] else $name = 檢查是否輸入電話號碼 if (chop($_POST[Tel]) = ) $tel = tel LIKE $_POST[Tel] else $tel =

55

if條件組合 SQL字串 if (chop($name) = ampamp chop($tel) = ) $sql= WHERE $name AND $tel elseif (chop($name) = ) 只有姓名 $sql = WHERE $name elseif (chop($tel) = ) 只有電話號碼 $sql = WHERE $tel $sql= ORDER BY name 最後加上排序 $result = mysql_query($sql) 取得欄位數 $total_fields = mysql_num_fields($result) echo lttable border=1gt echo lttrgtlttdgt編號lttdgtlttdgt姓名lttdgtlttdgt電話lttdgtlttd colspan=2gt功能選項lttdgtlttrgt 表格顯示查詢結果 while ($rows = mysql_fetch_array($result MYSQL_NUM)) echo lttrgt for ($i = 0 $i lt $total_fields $i++) echo lttdgt$rows[$i]lttdgt echo lttdgtlta href=editphpaction=editampid= echo $rows[0]gtltbgt編輯ltbgtlttdgt echo lttdgtlta href=editphpaction=delampid= echo $rows[0]gtltbgt刪除ltbgtlttdgt echo lttrgt echo lttablegtlthrgt mysql_free_result($result) mysql_close($link) gt ltcentergt ltform action=searchphp method=postgt lttable border=0 width=450gt lttrgtlttdgt搜尋姓名 lttdgt lttdgtltinput type=text name=Name size=10 maxlength=20gtlttdgtlttrgt lttrgtlttdgt搜尋電話 lttdgt lttdgtltinput type=text name=Tel

56

size=20 maxlength=20gtlttdgtlttrgt lttrgtlttd colspan=2 align=centergt ltinput type=submit name=Search value=搜尋gtlttdgtlttrgt lttablegt ltformgt ltbrgtlta href=indexhtmlgt通訊錄ltagt | lta href=addphpgt新增連絡人ltagt | lta href=searchphpgt搜尋通訊錄ltagt ltbodygt lthtmlgt

lt ob_start() gt lt-- 程式範例editphp --gt lthtmlgt ltheadgtlttitlegt編輯通訊錄lttitlegtltheadgt ltbodygt lt 取得 URL 參數 $id = $_GET[id] $action = $_GET[action] 建立資料庫連結 $link = mysql_connect(localhostroot1234) mysql_select_db(CONTACT) 選擇資料庫 執行的操作 switch ($action) case update 更新 取得欄位資料 $name = $_POST[Name] $tel = $_POST[Tel] $sql = UPDATE address SET name=$name tel=$tel WHERE id=$id mysql_query($sql) 執行 SQL指令 mysql_close($link) header(Location searchphp) 轉向到 serachphp break case del 刪除 $sql = DELETE FROM address WHERE id=$id

57

mysql_query($sql) 執行 SQL指令 mysql_close($link) header(Location searchphp) 轉向到 serachphp break case edit 編輯 $sql = SELECT FROM address WHERE id=$id $result = mysql_query($sql) 執行 SQL指令 $row = mysql_fetch_row($result) 取回記錄 $name = $row[1] 取得欄位 name $tel = $row[2] 取得欄位 tel mysql_close($link) 顯示編輯表單 gt ltcentergtlth2gt更新通訊錄lth2gtltcentergtlthrgt ltform action=editphpaction=updateampid=lt echo $id gt method=postgt lttable border=0 width=300gt lttrgtlttdgt姓名 lttdgt lttdgtltinput type=text name=Name size=20 maxlength=10 value=lt echo $name gtgtlttdgtlttrgt lttrgtlttdgt電話 lttdgt lttdgtltinput type=text name=Tel size=20 maxlength=20 value=lt echo $tel gtgtlttdgtlttrgt lttrgtlttd colspan=2 align=centergt ltinput type=submit value=更新連絡人gtlttdgtlttrgt lttablegt ltformgt ltbrgtlta href=indexhtmlgt通訊錄ltagt | lta href=addphpgt新增連絡人ltagt | lta href=searchphpgt搜尋通訊錄ltagt lt break gt ltbodygt lthtmlgt

58

52 任務二Web Base群組軟體 ( twig )

順利完成Web Base客戶通訊錄程式測試一段時間後「Apache + MySQL + PHP」架構的穩定與快速巳深得老闆與公司所有同事的認同隨著公司業績蒸

蒸日上人員組織編罝愈來愈龐大跨部門的會議愈來愈多業務員每日排滿拜

訪客戶的行程跟客戶的 Email的往來也愈來愈頻繁 愈來愈多部門的同事希望公司能建置一套群組軟體提供 web mail可讓業

務人員方便收發 mail還有連絡人議事日程待辦工作書簽等功能讓整個

公司運作及個人時間管理更有效率

老闆問小明對這些需求有什麼看法小明認為如果這些功能完全由程式部

門開發必定曠日費時而且耗費公司資源小明在網路尋找是否有提供這些功能

的Free Software皇天不負苦心人小明發現了TWIG (The Web Information Gateway) httptwigscrewdrivernet這個群組軟體它在 Web 上整合郵件新聞聯絡人議事日程工作序書簽等功能非常符合公司的需求 Step 1 下載 twig-277targz 下載網址 httptwigscrewdrivernetdownloadphp3

Step 2 解開 twig-277targz tar -xzvf twig-277targz

59

Step 3 執行安裝動作安裝到 varwwwhtmltwig 目錄 cd twig-277 twig-install varwwwhtmltwig

Step 4 建立 MySQL 資料庫(twig)及各資料表

cd setup mysql -u root -p1234 mysqlgt create database twig Query OK 1 row affected (001 sec) mysqlgt quit mysql -u root ndashp1234 twiglt twigtablemysql

Step 5 修改 configincphp3 參數設定 vi varwwwhtmltwigconfigconfigincphp3 $config[fromdomain] = opencom 網域 $config[language] = chinesebig5 中文訊息 $config[imap_port] = 143notls

60

Step 6 修改連結 MySQL 的帳號密碼 vi varwwwhtmltwigconfigdbconfigincphp3 $dbconfig[sqlusername] = root username $dbconfig[sqlpassword] = 1234 password

Step 7 其他設定檔

vi etchttpdconfhttpdconf 加入 AddType applicationx-httpd-php php3 在 DirectoryIndex最後加入 indexphp3 DirectoryIndex indexhtml indexhtmlvar indexphp3 在 AddDefaultCharset ISO-8859-1加上 AddDefaultCharset ISO-8859-1

vi etcphpini register_globals = On service httpd restart Step 8 sendmail 設定 vi etcmailsendmailcf在 264 行前面加上並重新啟動 sendmail「service snedmail restart」 262 SMTP daemon options 263 264 O DaemonPortOptions=Port=smtpAddr=127001 Name=MTA 265 266 SMTP client options 267 O ClientPortOptions=Family=inet Address=00

61

Step 9 檢查設定有無錯誤 http主機名稱twigtestphp3

62

Step 10 登入 twig ( http主機名稱twig)

63

第六章 維護及更新程序

61 日常維護

系統管理員最好定期以 root 身份登入看看信件在 RedHat Linux 中有一支 logwatch 程式會定時去分析 log file如果發現異常便會發信給 root除此之外筆者建議讀者平時就檢查 MySQL log file ( varlogmysqldlog)是否有異常情形

62 更新程序

讀者可至httprpmfindnet 尋找MySQL相關套件至於升級的相關步驟請參

考Linux OS SOP 第 54節

63 備份重要檔案

預設 MySQL 的 DB 檔案是存在 varlibmysql 內以 DB名稱為目錄目錄

內就是該 DB 的所有資料通常得定期備份還有 MySQL的設定檔 etcmycnf也別忘了一起備份

64 離線備份與還原

641 離線備份

預設 MySQL 的 DB 檔案是存在 varlibmysql 內以 DB 名稱為目錄目錄內

就是該 DB 的所有資料像 CRM 這個 DB就是存在 varlibmysqlCRM 內在備份前因為怕資料尚未完全寫入磁碟而且 MySQL 會 Lock 在使用的 DB 檔案所以應該是要先把 MySQL 先 Shutdown 一下整個備份的程序可以下像下面的指令去完成 cd varlibmysql

64

service mysqld stop tar cvfz CRM_db_20030905tgz CRM service mysqld start 對這樣就可以了 不過要注意的是怕 DB 內每個 Tables 間的資料有關關

聯性所以最好是把整個 DB 一次備起來單獨只備哪個 Tables 的檔案以後回存時怕會有資料關聯不一致的問題

642 離線還原

DB 發生錯誤而要回存時其實也不難先找出最近一次完整正常的備份先把現在錯誤的網頁或 DB 先更名或 tar 起來再把好的備份給解開回原來目錄位

置就行了需要注意的是 MySQL 服務最好也是要先停止回存完成後再啟動服務回存 DB 的整個程序可能像下面 cd varlibmysql service mysqldstop mv CRM CRM_OLD tar xvfz CRM_db_20030905tg service mysqld start

65 線上備份與還原

651 線上備份

使用像上面的檔案方式備份是個不錯的方法它最少可以保持該主機某個時間點的完整檔案備份但還是有一些問題需要考慮到有些主機就不只建立一個 DB 而已總不能為了備份某個 DB 而把整個 MySQL 服務停止備份檔案的方式回存在原主機上一定適用但假如 MySQL 版本升級或是在那天該網頁空間需遷機移機到別的主機時那就沒人敢保證備出來的資料檔可以用所以我們可以考慮另一種備份的方式是使用 MySQL 本身提供的功能 MySQL Data Dump指令是 mysqldump

65

使用 MySQL 的 Dump 功能可以把 DB 的結構資料或結構加資料 Dump 成文字檔 mysqldump 指令提供的彈性很大你可以選擇把整個 DB Dump 成一個檔或是每個 Table 為一個檔甚至是把結構檔和資料分開儲存都

可以 mysqladmin -uroot -p flush-logs mysqldump CRM -uroot -p --opt gt CRM_20030905sql (CRM 是 DB 名稱 opt 是一個使用完整 Dump 參數) 假如只是要單獨 Dump 某個 Table 時只要在上面的指令後轉出符號 gt 前加個 Table 名稱就可以如只要 phpbb2_users 這個 Table 的 Dump 時只要下 mysqldump CRM -uroot -p --opt CUSTOMER gt CRM_CUSTOMER_20030905sql

652 線上還原

若要回存整個資料庫只需將壓縮的備份檔還原成 Dump 的檔案再用下面的指令回存 mysql CRM -uroot -p lt CRM_20030905sql 這邊需注意的是若建立備份時是以--opt或--add-drop-table為參數時回存的 動作是先將舊的 Table 先刪除重建 Table 的結構後再把 Data 匯入所以回存後所有的資料會回到你當時備份那個時間點因此在回存資料時可以考慮把現有錯誤或不完整的 DB 先備份一份下來以備不時之需或是拿來比對錯誤的地

方在那裡當然你也可以把資料回存到另一個測試用的 DB 內只要把上面指令

的 DB 名稱改成你的測試用 DB 名稱即可 使用這種回存方式 MySQL 服務不需停止也不會動到其他正在使用的 DB 在一些提供 MySQL 服務的虛擬主機可用這種方式作你自己的 DB 備份及回存

66

另外假如你是系統重建或是移機時切需在新的 MySQL 內新建一個空白 DB 後才行作回存的工作你可以用下面的指令建立 mysql -uroot -p -e CREATE DATABASE CRM (上面的 CRM是你要新建的 DB 名稱) 另一種作法先用 mysql 指令進入 mysql client console 然後再用 CREATE DATABASE CRM 這樣就行了記得尾端要加個 符號該行指令才會執行

67

第七章 問題與解答

Q1RedHat 90預附的 MySQL到底有無支援 Transcation機制 Ans MySQL自 32334a之後的 MySQL-Max版本加入 InnoDB的資料庫類型透過

InnoDBMySQL同樣可以進行 COMMIT與 ROLLRACK的動作RedHat 90預附的 MySQL為 32354a-11巳支援 InnoDB的資料庫類型不過必須做以

下設定 1cp usrsharedocmysql-server-32354amy-mediumcnf to etcmycnf 2 vi etcmycnf 將以下設定前的拿掉 innodb_data_home_dir = varlibmysql innodb_data_file_path = ibdata110Mautoextend innodb_log_group_home_dir = varlibmysql innodb_log_arch_dir = varlibmysql 3service mysqld restart 如此一來各位在建立Table時便可指定Table Type為 innodb ( ex create table with type=innodb ) Q2如何解決 php+mysql 許功蓋等字變亂的問題 Ans 方法一 【確定 MySQL 預設的字元集】 1 打開 WinMySQLadmin 管理畫面(在視窗右下角狀態列紅綠燈圖示中按滑鼠

右鍵點選 Show me 選項) 2 點選管理畫面中 [Variables] 標籤選項其中 character_set變數就是您預設

字元集的變數其預設是 latin1 字元集(我們要將他改回 big5)而 chatacters_set 變數則是 MySQL 可以支援哪些字元集 【修改預設字元集變數 character_set 】 1 請點選管理畫面中 [myini Setup] 標籤選項設定 myini 2 按一下 [Pick-up and Edit myini values] 按鈕以便編輯目前的 myini 設定 3 在 [mysqld] 設定區塊底下新增一行 default-character-set = big5 變數設

68

定 4 新增一個 [client] 設定區塊並加入第三步驟的變數設定(游標往下移到空白處新增兩行 [client] 和 default-character-set=big5) 5 按一下畫面左下方 [Save Modification] 按鈕儲存設定 6 重新啟動 MySQL 或 Windows 方法二 Server端注意事項 phpini 中有關的設定為(預設值) Magic quotes for incoming GETPOSTCookie data magic_quotes_gpc = On Use Sybase-style magic quotes (escape with instead of ) magic_quotes_sybase = Off Client端注意事項 1中文資料送進 mysql 前請用 addslashes($str) 處理 2處理後送進 mysql 時請用 括起來並在參數後留一個空白如 $sql = UPDATE ezf_table set tablename=$tname tableend=$endtime table inguser=$tguser tableingid=$tguserid tableallnumber=$tnumber tableloca l=$tablelocal tableanyone=$tableopen tabletext=$ttext WHERE tableid=$t ableid tablename=$tname c 取出時請用 stripslashes($str) Q3MySQL root 密碼忘了該怎麼辦 Ans 1先停掉 mysql etcrcdinitdmysql stop 2以--skip-grant-table 的參數啟動 mysql safe_mysql --skip-grant-tableamp 3 更改 root 密碼 mysql mysql mysqlgt UPDATE user SET password=password(newpassword)

69

WHERE user=root mysqlgt FLUSH PRIVILEGES mysqlgt exit 4停掉 mysql再重跑 mysqladmin -uroot -p shutdown Enter password 輸入新設定的密碼 etcrcdinitdmysql start

Q4NULL值問題

Ans

NULL值的概念是造成 SQL的新手的混淆的普遍原因他們經常認為 NULL是和一個空字符串的一樣的東西不是這樣的例如下列語句是完全不同的

mysqlgt INSERT INTO my_table (phone) VALUES (NULL)

mysqlgt INSERT INTO my_table (phone) VALUES ()

兩個語句把值插入到 phone 列但是第一個插入一個 NULL值而第二個插入一個空字符串第一個的含義可以認為是ldquo電話號碼不知道而第二個則可意味

著ldquo她沒有電話

在 SQL中NULL值在于任何其他值甚至 NULL值比較時總是假的(FALSE)包含 NULL的一個表達式總是產生一個 NULL值除非在包含在表達式中的運算符和函數的文檔中指出在下列例子所有的列返回 NULL

mysqlgt SELECT NULL1+NULLCONCAT(InvisibleNULL)

如果你想要尋找值是 NULL的列你不能使用=NULL測試下列語句不返回任

何行因為對任何表達式expr = NULL是假的

mysqlgt SELECT FROM my_table WHERE phone = NULL

要想尋找 NULL值你必須使用 IS NULL測試下例顯示如何找出 NULL電話號碼和空的電話號碼

70

mysqlgt SELECT FROM my_table WHERE phone IS NULL mysqlgt SELECT FROM my_table WHERE phone =

在 MySQL中就像很多其他的 SQL服務器一樣你不能索引可以有 NULL值的列你必須聲明這樣的列為 NOT NULL而且你不能插入 NULL到索引的

列中

當用 LOAD DATA INFILE 讀取數據時空列用更新如果你想要在一個列中有

NULL值你應該在文本文件中使用N字面上的詞NULL也可以在某些情形下使用

當使用 ORDER BY時首先呈現 NULL值如果你用 DESC以降序排序NULL值最後顯示當使用 GROUP BY時所有的 NULL值被認為是相等的

為了有助于NULL的處理你能使用 IS NULL和 IS NOT NULL運算符和 IFNULL()函數

對某些列類型NULL值被特殊地處理如果你將 NULL插入表的第一個TIMESTAMP 列則插入當前的日期和時間如果你將 NULL插入一個AUTO_INCREMENT 列則插入順序中的下一個數字

Q5如何將圖片存放於 MySQL中

Ans

Step 1建立資料庫 test

Step 2 建立表格 binary_data

CREATE TABLE binary_data (

id INT(4) NOT NULL AUTO_INCREMENT PRIMARY KEY

description CHAR(50)

bin_data LONGBLOB

filename CHAR(50)

filesize CHAR(50)

filetype CHAR(50)

71

)

Step 3 利用 storephp 寫入圖片

storephp 程式碼

ltHTMLgt ltHEADgtltTITLEgtStore binary data into SQL DatabaseltTITLEgtltHEADgt ltBODYgt lt code that will be executed if the form has been submitted

if ($submit) mysql_connect(localhostrootYOUR_PASSWORD) mysql_select_db(test) $data=Base64_Encode(fread(fopen($form_data r) filesize($form_data))) $result=MYSQL_QUERY(INSERT INTO binary_data (descriptionbin_datafilenamefilesizefiletype) VALUES ($form_description$data$form_data_name$form_data_size$form_data_type)) $id= mysql_insert_id() print ltpgtThis file has the following Database ID ltbgt$idltbgt MYSQL_CLOSE() else else show the form to submit new data

gt

ltform method=post action=ltphp echo $PHP_SELF gt enctype=multipartform-datagt File Descriptionltbrgt ltinput type=text name=form_description size=40gt ltINPUT TYPE=hidden name=MAX_FILE_SIZE value=4000000gt ltbrgtFile to uploadstore in databaseltbrgt ltinput type=file name=form_data size=40gt ltpgtltinput type=submit name=submit value=submitgt ltformgt lt

72

gt ltBODYgt ltHTMLgt

Step 3 利用 storephp 取出圖片

getdataphp 程式碼

lt Syntax getdataphp3id=ltidgt if($id) you may have to modify login information for your database server MYSQL_CONNECT(localhostrootYOUR_PASSWORD) mysql_select_db(test) $query = select bin_datafiletype from binary_data where id=$id $result = MYSQL_QUERY($query) $data = Base64_Decode(MYSQL_RESULT($result0bin_data)) $type = MYSQL_RESULT($result0filetype) Header( Content-type $type) echo $data gt

Q6MySQL裝好之後啟動時或是執行 mysqladmin會出現如下訊息 Cant connect to local MYSQL Server through Socket varlibmysqlmysqlsock或是

Cant connect to local MYSQL Server through Socket tmpmysqldsock

Ans 可能有下列幾個原因

1這個 mysqldsock 不見了被某人刪除了或是被一些系統自動執行程式給刪

了例如有些 cron任務便會設定定期刪除 tmp 裡的東西所以呢您只能修改

cron 裡的設定讓它不要清除 mysqldsock 2在啟動時也可以改變 mysqldsock的位置您在啟動 MySQL的時候可以加入此參數usrlocalmysqlbinsafe_mysqld --user=mysql --socket=其他路

徑socket amp 同時得去設定環境變數 MYSQL_UNIX_PORT的值以指定新的

73

路徑 3若是您沒改 MYSQL_UNIX_PORT的值那麼您可以在執行指令的時候才打

例如mysqladmin --socket=其他路徑socket version Q7How to get the last insert id Ans CREATE TABLE product ( id INT(4) NOT NULL AUTO_INCREMENT PRIMARY KEY description VARCHAR(50) ) 1利用 SQL的話 mysqlgt insert into product(description) values(123) Query OK 1 row affected (000 sec) mysqlgt select last_insert_id() +------------------+ | last_insert_id() | +------------------+ +------------------+ 1 row in set (000 sec) ======================================== 2如果是 PHP的話 你可以用mysql_insert_id()取得該 id PHP example $result=MYSQL_QUERY(INSERT INTO product (description) VALUES ($description)) $id= mysql_insert_id() print This file has the following Database ID $id Q8如何將文字檔匯入資料庫 Ans $addr=homehttpdhtmlphpschool001txt $sql_select = load data infile $addr into table test fields terminated by t 解說 $sql_select = load data infile 文字檔名 into table 表格名 fields terminated by

74

t

(欄位分隔以 TAB鍵) 該文字檔須與資料表欄位格式相符 例如欄位有三個 則文字檔為每行一筆資料如下 欄 1資料ltTABgt欄 2資料ltTABgt欄 3資料 欄 1資料ltTABgt欄 2資料ltTABgt欄 3資料 欄 1資料ltTABgt欄 2資料ltTABgt欄 3資料 欄 1資料ltTABgtltTABgt欄 3資料

Q9如何撰寫 MySQL C API Ans Step 1利用文字編輯器撰寫以下程式碼 mysqlcc

include ltstdiohgt

include ltmysqlmysqlhgt

int main (int argc char argv[])

MYSQL mysql

MYSQL_RES res

MYSQL_ROW row

if (argc = 2)

fputs (Usage myc ltdatabasegt stderr)

return 1

if ((mysql_connect(ampmysqllocalhostrootYour_Password)))

fputs (Error connecting stderr)

abort()

75

if (mysql_select_db(ampmysqlargv[1]))

fputs (Error selecting database stderr)

abort()

if (mysql_query(ampmysqlSELECT FROM test_table))

fputs (Error processing query stderr)

abort()

if ((res = mysql_store_result(ampmysql)))

fputs (Error storing results stderr)

abort()

while((row = mysql_fetch_row(res)))

uint i = 0

for (i=0 i lt mysql_num_fields(res) i++)

printf(s row[i])

printf(n)

return 0

Step 2 Compile

gcc -Iusrlocalmysqlinclude -Lusrlocalmysqllibmysql mysqlcc ndashlm -lmysqlclient

(其中 include path與 library path取決於你的 MySQL安裝路徑)

76

如果執行時發生如下 error Run problemerror in loading shared libraries libmysqlclientsoX 將你的 MySQL library path(for exampleusrlocalmysqllibmysql) 加入etcldsoconf and run sbinldconfig -v Q9ASP + MySQL 範例程式 Ans Dim myconn As New ADODBConnection Dim myrs As New Recordset Dim mySQL As String Dim myrows As Long myconnOpen DSN=MyODBCsample mySQL = SELECT from user myrsSource = mySQL Set myrsActiveConnection = myconn myrsCursorLocation = adUseClient myrsOpen myrows = myrsRecordCount myrsClose myconnClose 可參考 httpwwwdwamnetmysqlasp_myodbcasp 有詳細的資料 Q10如何將 MySQL中的資料庫匯出成txt檔 Ans select from TableName into outfile textxls all result fields will seperate by tab

77

第八章 參考資料

英文部份 網址 1 httpwwwmysqlcom MySQL 網站有第一手有關 MySQL的資料 2 httpwwwmysqlcomdocenReplicationhtml 有關 MySQL Replication 的文件 3 httpwwwgeocitiescomsqlhomefaqstore_blobhtml 如何在 MySQL 存放 BLOB的資料 4httpwwwsapdborg 有關 SAP跟 MySQL相關合作的網站 書藉 1 Cooking with MySQL

Paul DuBois has selected sample recipes from the hundreds youll find in his book MySQL

Cookbook In this third and final series of excerpts showcasing these recipes learn how to

compute team standings how to calculate the differences between successive Dec 26

2002 2 Tips for Building Web Database Applications with PHP and MySQL by Hugh E Williams co-author of Web Database Applications with PHP amp MySQL 04042002

3 Managing and Using MySQL 2nd Edition By Tim King George Reese Randy Jay Yarger

4 MySQL Cookbook By Paul DuBoisPublisher OReillyPub Date October 2002

中文部份

78

1 httplinuxtncedutwtechdocmysqlmysql_docmanual_tochtml MySQL 中文手冊 2 httpchenshloxaedutwphpZ_1php PHP+MySQ程式研習設計網站 3 httplinuxtncedutwtechdocbanicdownhtml PHP 4 手冊 4 httpwwwtncedutwadmin_zonephp台南縣教育網網路中心有很多 Linux相關文件 5 httpdobtncedutw網站建置百寶箱有很多 PHP MySQL 相關範例程式 5 httpwwwdbworldcomtw資料庫專家電子雜誌介紹資料庫的重要觀念及名詞

79

附錄一 SQL Command 介紹

SQL (讀音ess-que-el) 是一種結構查詢語法SQL 使用於資料庫交流

傳遞相容於 ANSI (American National Standards Institute) 是一套標準的關聯

式資料庫語言 SQL 語言是執行更新或從資料系統獲取資料一般常見的關聯

資料庫系統都有提供 SQL 如 Oracle Sybase Microsoft SQL Server Access Ingres 等雖然大部份的資料庫都有提供 SQL 但也多提供了自已獨特的語

法造成了不相容的情形但標準基本的語法是相通的如Select Insert Update Delete Create and Drop 每一個系統都有支援

Table相關 Command

Create Table

關聯式資料庫包含有很多元件稱為資料表(tables) 把資料或訊息放在資

料表中 資料表是以不同的名稱做分別資料表由欄列所構成的二維陣列

欄包含欄位名資料型態 及其他可判斷的資訊列是由全部欄位構成一筆一

筆的紀錄 create table 語法用在建立一個新的資料表語法格式如下

create table tablename (column1 data type column2 data type column3 data type)

Format of create table if you were to use optional constraints

create table tablename (column1 data type [constraint] column2 data type [constraint] column3 data type [constraint]) [ ] = optional

Note You may have as many columns as youd like and the constraints are optional

80

Example

create table employee (first varchar(15) last varchar(20) age number(3) address varchar(30) city varchar(20) state varchar(20))

注意建立資料表格式要以括號把前後框住而最後以(分號)做結尾

欄位名不要超過 30個字元長而且不要使用 sql 的關鍵字(如 where select等)而在後面接是型態的宣告(如字串數字日期格式等)

資料型態是來描述欄位的方式如一個欄位Last_Name 是一個姓氏可以使用varchar (可變動長度字串) 資料型態

以下是幾個常見的資料庫型態 char(size) 固定長度字串最長為 255 位元 varchar(size) 變動長度字串最大字元數以 size 來指定 number(size) 數值格式可以是整數也可以是小數最大數字以 size 位數判

斷未指定小數位數由系統內定 date 日期格式 number(sized) 數值格式最大數字以 size 位數判斷d 為小數位數整數位

數為 size-d 位

有何限制當資料表被建立通常有一或數個欄位是要使用來做關聯的功

能 例如unique 限制(唯一值)兩筆記錄不可以相同的值 not null (非空值)該欄位一定要輸入資料不可是空的primary key (主鍵)是每一筆記錄識別的主要方式

Drop a table drop table 刪除資料表(其中的資料也會一併刪除)

drop table tablename

Example

81

drop table 和刪除全部資料是不同的刪除全部資料欄位名稱資訊等還會

存在但刪除資料表會把這一些也一併移除掉

如何查詢資料

Select 基本用法

select 語法是關連式資料庫最常用的部份可以取得你想要的資料這是一個

簡單的範例 select column1[column2etc] from tablename [where condition] [] = optional 在 select 之後所列欄位名則是要顯示的資料部份你可以一一列出各欄位

名或是以 (星號)來代表選擇全部的欄位 from 之後放資料表名稱 where 子句 (選項) 指定要過濾的條件符合者才會顯現 where 可使用的條件運算元 = 等於 gt 大於 lt 小於 gt= 大或等於 lt= 小或等於 ltgt 大相等 LIKE 相似 For example select first last city

82

from empinfo where first LIKE Er 以Er 為開頭的字串就符合要以單引號框住 Or you can specify select first last from empinfo where last LIKE s 最後一字為 S 就符合 select from empinfo where first = Eric 則表示 first name 一定要是 Eric 才可以 範例資料表empinfo 統計函數

MIN 傳回指定欄位最小值

MAX 傳回指定欄位最大值

SUM 傳回指定欄位總和

AVG 傳回指定欄位平均值

COUNT 傳回指定欄位的筆數

COUNT() 傳回資料庫中的總筆數

統計函數使用於資料表中的數值欄位配合 SELECT 語法使用 只用於總結特定單一欄位可以配合 GROUP BY 做篩選但也可以不使用 GROUP BY 語句For example

SELECT AVG(salary) FROM employee

83

傳回全部 salary 平均值

Another example

SELECT AVG(salary) FROM employee WHERE title = Programmer

傳回 salary 平均值條件為 employees 資料表中當 title 等於 Programmer

Example

SELECT Count() FROM employees

傳回 employees 資料表中紀錄總筆數

GROUP BY 語法 SELECT column1 SUM(column2) FROM list-of-tables GROUP BY column-list The GROUP BY 語句可以先以所列的欄位為條件分組排序在一起(可以多欄

位) example 要列出每一個 dept 中最高 salary 值 SELECT max(salary) dept FROM employee GROUP BY dept HAVING 語法

SELECT column1 SUM(column2) FROM list-of-tables GROUP BY column-list HAVING condition

HAVING 子句是 GROUP BY 的一部份用來過濾在 GROUP BY 所選出的資料功能如同 select 命令中 where 條件式一樣只是 HAVING 必需配合 GROUP BY 使用

我們以例子來說明我們要取得每一公司名及每一公司的薪水平均值輸入如下

84

SELECT dept avg(salary) FROM employee GROUP BY dept

但如果我們只列出薪資平均值超過 20000元的公司資料

SELECT dept avg(salary) FROM employee GROUP BY dept HAVING avg(salary) gt 20000

ORDER BY子句語法

SELECT column1 SUM(column2) FROM list-of-tables ORDER BY column-list [ASC | DESC]

[ ] =選項

ORDER BY是一個選項子句當你以排序方式來顯示資料(正向由小到大反向由大到小)以指定的欄位資料做排序

ASC = 正向- 預設值 DESC = 反向排序

For example

SELECT employee_id dept name age salary FROM employee_info WHERE dept = Sales ORDER BY salary

以上列出公司代號公司名銷售員人名年紀及薪資而條件是公司名為 Sales 顯示順序以薪資多少排序(由小到大為預設值)

如果要以多個欄位做排序要以逗號做分隔如下

SELECT employee_id dept name age salary FROM employee_info WHERE dept = Sales ORDER BY salary age DESC

85

結合條件及布林運算 SELECT column1 SUM(column2) FROM list-of-tables WHERE condition1 AND condition2 AND運算可以結兩個或以上的條件放在 WHERE子句中 兩者都要為真才

會顯示該筆記錄 OR 運算可以結兩個或以上敘述放在 WHERE子句中只要其中一個為直就

會顯示該筆記錄 For example SELECT employeeid firstname lastname title salary FROM employee_info WHERE salary gt= 5000000 AND title = Programmer 必需要薪資大於等於 50000而且職稱為 Programmer同時符合才會顯示該筆資料 以下以括號括住雖然不是必需的但如此比較容易讀 SELECT employeeid firstname lastname title salary FROM employee_info WHERE (salary gt= 5000000) AND (title = Programmer) 另外範例 SELECT firstname lastname title salary FROM employee_info WHERE (title = Sales) OR (title = Programmer) 條件為只要是 Sales 或 Programmer 職稱的就會被列出 IN and BETWEEN 子句

SELECT column1 SUM(column2) FROM list-of-tables WHERE column3 IN (list-of-values) SELECT column1 SUM(column2) FROM list-of-tables WHERE column3 BETWEEN value1 AND value2 IN 子句使用在列舉項目的使用上也就是分別測試是否符合所列的值 For example

86

SELECT employeeid lastname salary FROM employee_info WHERE lastname IN (Hernandez Jones Roberts Ruiz) 條件為姓氏(astname)要符合 Hernandez Jones Roberts or Ruiz 其中一個才會被傳回 IN運算元也可以使用 OR 的語法來取代如下結果相同 SELECT employeeid lastname salary FROM employee_info WHERE lastname = Hernandez OR lastname = Jones OR lastname = Roberts OR lastname = Ruiz 但使用 IN 句子比較短也比較易懂 你也可以使用 NOT IN 來去掉不要的記錄 BETWEEN 運算元使用在判斷是否存在兩個數值之間 For example SELECT employeeid age lastname salary FROM employee_info WHERE age BETWEEN 30 AND 40 傳回年紀 30歲到 40歲之間的資料(含 30及 40歲者) 相同的也可以使用以下語法來達到相同的結果 SELECT employeeid age lastname salary FROM employee_info WHERE age gt= 30 AND age lt= 40 你也可使用 NOT BETWEEN 來濾掉中間值的資料 數學運算 標準 ANSI SQL-92 提供以下運算

87

+ 加

- 減

餘數

餘數為除法後剩整數這不在標準的 ANSI SQL 中但大部份的資料庫都會支

援這運算元以下列出有用的函數雖不在 ANSI SQL-92 提供但一般資料庫

也會支援他們

ABS(x) 傳回 x 絕對值

SIGN(x) returns the sign of input x as -1 0 or 1 (negative zero or positive respectively)

MOD(xy) 餘數 - returns the integer remainder of x divided by y (同 xy)

FLOOR(x) 傳回小或等於 x 的最大整數值

CEILING(x) or CEIL(x)

傳回大或等於 x 的最小整數值

POWER(xy) x的 y 次方

ROUND(x) 把 x 四捨五入為整數

ROUND(xd) 四捨五入取到小數 d 位

SQRT(x) x 開平方

For example SELECT round(salary) firstname FROM employee_info 傳回薪資取到整數位

如何新增資料

insert 加入一筆新紀錄到資料表中 insert into tablename (first_columnlast_column) values (first_valuelast_value) [] = optional Example insert into employee

88

(first last age address city state) values (Luke Duke 45 2130 Boars Nest Hazard Co Georgia) Note 字串要以單引號住如string 數字框住也無妨 insert into 後面接資料表名稱再接以括號括住的欄位名在 values 後括號分別對映各欄位的值 以上的例子新增了一筆名(first) 為 Luke而住所(state) 為 Georgia 的資料

如何刪除資料

delete 可以刪除單筆或多筆紀錄 delete from tablename where columnname OPERATOR value [and|or column OPERATOR value] [ ] = optional Examples delete from employee Note 如果你沒有指定 where 子句那麼全部的紀錄都會被刪除 delete from employee where lastname = May delete from employee where firstname = Mike or firstname = Eric delete from 接著資料表名 再接著是條件式判斷沒有條件式則全部紀錄會

被刪除

如何更新資料

update 用來更新你所指定的記錄要和 WHERE 配合小心使用 語法 update tablename set columnname = newvalue[nextcolumn = newvalue2] where columnname OPERATOR value [and|or column OPERATOR value] [] = optional Examples

89

update phone_book set area_code = 623 where prefix = 979 update phone_book set last_name = Smith prefix=555 suffix=9292 where last_name = Jones update employee set age = age+1 where first_name=Mary and last_name=Williams

90

附錄二Replication

測試環境

RedHat 90 + MySQL 32358 MySQL資料庫路徑 varlibmysql MySQL設定檔 etcmycnf Master IP 1921680100 Slave IP 1921680200 請至下列網址下載最新MySQL 32358套件並利用rpm ndashUvh 更新 httpupdatesredhatcom9enosi386

圖 最新 MySQL 套件

測試架構圖

91

1921680100

1921680200Master Server

erveSlave S r

圖 測試架構圖

測試步驟

Master server 部份 Step1 確認 MasterSlave機器上所裝的 MySQL版本能進行

replication( 32329 or higher ) Step2 在 Master MySQL上開放一個帳號給 Slave mysql ndashu root ndashp mysqlgtGRANT FILE ON TO repl1921680200 IDENTIFIED BY lsquoabc123rsquo mysqlgtq 上面是 Master開放一個帳號 repl密碼 abc123給 IP1921680200有檔案處理

的權限 Step3 shutdown MySQL on the Master mysqladmin ndashu root ndashp shutdown Step4 備份 Master所有資料庫 tar ndashcvf tmpmysql-snapshottar varlibmysql 注意tar的時候MySQL是要在 stop情況下 在mysql (wwwmysqlcom) 網站的FAQ有不用shutdown的方法

92

Step5 在 master機器上修改etcmycnf 在[mysqld]區段內加入參數 log-bin server-id=這邊設定 server-id=1 sql-bin-update-same binlog-do-db=CRM只針對 CRM資料庫做紀錄 Step6 Restart MySQL on the master service mysqld start 此時因為有加入 log-bin 參數因此開始有 index產生了在varlibmysql目錄下

有index檔案紀錄資料庫的異動 log Slave server 部份 Step1 在 slave設定etcmycnf 在[mysqld]區段加入 master-host= master-user= master-password= master-port= server-id= 這邊設定 master-host=1921680100 master-user=repl master-password=abc123 master-port=3306 server-id=2 master-connect-retry=60預設重試間隔 60秒 replicate-do-db=CRM告訴 slave只做 CRM資料庫的更新 log-slave-updates Step2 將 master上的 mysql-snapshottar copy到 slave上 用 ftp傳到 slave的tmp Step3 解壓縮 Master資料庫至 Slave Server上 cd varlib tar xvf tmpmysql-snapshottar chown ndashR mysqlmysql mysql

93

chmod ndashR 770 mysql (視情況) Step4 Restart MySQL on the slave server 這時在varlibmysql目錄會出現 masterinfo此檔案紀錄了 Master MySQL server的資訊

狀況測試

One-way replication

1921680100

1921680200Master Server

erveSlave S r

圖 One-way replication架構圖 Step1 Master跟 Slave網路及服務都正常情況下由 Master端異動資料後 到 Slave端瀏覽資料檢視是否有進行 replication Step2 模擬 Slave Server 當機 可用在於 slave真的當機或是 Slave 不一定需要一直跟 master connect將Slave MySQL server shutdown由 Master端異動資料到 slave端瀏覽此時Slave應該沒有被 replication 更新然後再將 Slave端 MySQL server start起來

預設 60秒後 Slave會嘗試跟 Master要求進行 replication再去 Slave端檢視是否有更新資料

94

Step3 模擬 Master當機因為是設定 One-way replication一旦 Master Server Slave端沒有 Master的 source可以 download Two-way replication 基於 Master當機狀況於是發展雙向 Replication即 1921680100 ( Host A ) 1921680200 ( Host B )都分別擔任 MasterSlave身分

1921680100

1921680200er

Server B MasterSlave Server

Server A MasterSlave Serv

圖 Two-way replication架構圖 以下是針對兩台 MySQL伺服器進行雙向 Replication Step1觀念同單向 replication只是改成 Master也有 Slave身分 Slave也有Master的身分先分別在 Server AServer B 都去 grant一個進行 replication的身分 [A]mysqlgtGRANT FILE ON TO repl1921680200 IDENTIFIED BY lsquoabc123rsquo [B]mysqlgt GRANT FILE ON TO repl1921680100 IDENTIFIED BY lsquoabc123rsquo Step2做完單向 replication後stop Server Aserver B MySQL service此時 AB資料是一樣的

95

修改etcmycnf設定 範例 Server A [mysqld] datadir=varlibmysql socket=varlibmysqlmysqlsock server-id=1 log-bin sql-bin-update-same binlog-do-db=CRM master-host=1921680200 master-user=repl master-password=abc123 log-slave-updates master-connect-retry=60 replicate-do-db=CRM Server B [mysqld] datadir=varlibmysql socket=varlibmysqlmysqlsock server-id=2 log-bin sql-bin-update-same binlog-do-db=CRM master-host=1921680100 master-user=repl master-password=abc123 log-slave-updates master-connect-retry=60 replicate-do-db=CRM 分別 start Server AServer B MySQL後此時雙方都是 MasterSlave身分一旦哪一方資料異動就會通知對方來 replication-若 replication失效則必須將Server AServer B的masterinfo及index00x 都砍掉然後分別 restart MySQL server進行測試檢視成果 實務上通常如果需要做Two-way replication通常會搭配Virtual Server使用

96

在前端架設一台Virtual Server不過此部份不在此份SOP討論範圍內有興趣

的讀者可參考 httpwwwlinuxvirtualserverorg 網站

1921680100 1921680200

Host A MasterSlave Server

Host B MasterSlave Server

Virtual Host

圖 Virtual Server + Two-way replication 架構圖

97

圖 High Availability Linux Virtual Server架構圖

98

  • COSA-SOP-03-006
  • 第一章 簡介
    • 11適用對象 (Audience)
    • 12 MySQL本身
    • 13 MySQL 40版跟50版重大的改進功能
    • 14 各家資料庫軟體比較
      • 第二章 前置需求
      • 第三章 安裝
        • 31 MySQL安裝
        • 32 phpMyAdmin安裝
        • 33 升級及注意事項
          • 第四章 MySQL管理
            • 41 Webmin 管理介面
            • 42 phpMyAdmin 的操作介面
            • 43管理指令介紹
              • 431 利用mysqladmin設定root的密碼
                  • 第五章 實用範例
                    • 51 任務一Web Base客戶通訊錄
                    • 52 任務二Web Base群組軟體 ( twig )
                      • 第六章 維護及更新程序
                        • 61 日常維護
                        • 62 更新程序
                        • 63 備份重要檔案
                        • 64 離線備份與還原
                        • 65 線上備份與還原
                          • 第七章 問題與解答
                          • 第八章 參考資料
                          • 附錄一 SQL Command 介紹
                          • 附錄二Replication
Page 46: DataBase Server Standard Operation Procedureebooks.lib.ntu.edu.tw/1_file/oss/63/93doc4-5.pdf · 業務的公司帶來了不少壓力,譬如微軟,甲骨文 ... 外的錢用在第三方的資料庫產品上,譬如就可以不用再購買甲骨文公司

圖 4-29

43管理指令介紹

431 利用 mysqladmin設定 root的密碼

當您在Windows 或 Linux 中安裝好 MySQL後系統會自動幫您建立兩個

帳分別是 root 和 匿名者MySQL的 root 跟 Linux 最高權限使用者 root無關MySQL的 root使用者相當於 MS SQL 中的 sa 帳號擁有最高的 Database管理權限但系統預設 MySQL的 root 是不需要密碼所以通常我們一安裝

MySQL後首要任務便是修改 root的密碼 我們可以利用 mysqladmin工具或是直接修改 MySQL內部資料庫的使用者資

料 mysqladmin ndashu root ndashh cosaexamplecom password lsquo1234rsquo

46

-u 表示使用者帳號root 為 MySQL預設的管理帳號

-h 表示 MySQL主機的主機名稱也可使用 IP Address password 表示使用者的密碼因為字串請使用單引號將密碼括起來 密碼設定完成之後還是可以利用 mysqladmin修改密碼但是你必須提供目前的密碼

432 連線 MySQL

mysql -uroot -p密碼 (-p和密碼之間不能有空白) 或 mysql -uroot -p (此方式會在進入後要求密碼) [rootossc phpMyAdmin] mysql -u root -p1234

Welcome to the MySQL monitor Commands end with or g

Your MySQL connection id is 25 to server version 32354

Type help or h for help Type c to clear the buffer

mysqlgt show databases

+----------+

| Database |

+----------+

| mysql |

| test |

+----------+

2 rows in set (000 sec)

mysqlgt exit

Bye

[rootossc phpMyAdmin]

433 建立資料庫

可利用 mysqladmin指令建立 CONTACT資料庫 mysqladmin -u root -p1234 create CONTACT

47

或是利用 mysql指令 [rootossc bluepage] mysql -u root -p1234 Welcome to the MySQL monitor Commands end with or g Your MySQL connection id is 1057 to server version 32354 Type help or h for help Type c to clear the buffer mysqlgt create database CONTACT Query OK 1 row affected (000 sec) mysqlgt show databases +----------+ | Database | +----------+ | CONTACT | | address | | hello | | mysql | | nuke | | test | +----------+ 6 rows in set (000 sec) mysqlgt exit

434 建立資料表

編寫 adresssql內容如下 -- Table structure for table address CREATE TABLE address ( id int(11) NOT NULL auto_increment name varchar(20) NOT NULL default tel varchar(15) NOT NULL default PRIMARY KEY (id) ) TYPE=MyISAM

48

-- Dumping data for table address INSERT INTO address VALUES (1林小明0800016888) INSERT INTO address VALUES (2黃大雄0800016888) INSERT INTO address VALUES (3劉小芬0800024365) 然後執行此 sql script mysql -u root -p1234 CONTACT lt addresssql 或是利 mysql command [rootossc bluepage] mysql -u root -p1234 Welcome to the MySQL monitor Commands end with or g Your MySQL connection id is 1090 to server version 32354 Type help or h for help Type c to clear the buffer mysqlgt use CONTACT Database changed Database changed mysqlgt CREATE TABLE address ( -gt id int(11) NOT NULL auto_increment -gt name varchar(20) NOT NULL default -gt tel varchar(15) NOT NULL default -gt PRIMARY KEY (id) -gt ) TYPE=MyISAM Query OK 0 rows affected (000 sec) mysqlgt INSERT INTO address VALUES (1林小明0800016888) Query OK 1 row affected (000 sec) mysqlgt INSERT INTO address VALUES (2黃大雄0800016888) Query OK 1 row affected (000 sec) mysqlgt INSERT INTO address VALUES (3劉小芬0800024365) Query OK 1 row affected (000 sec) mysqlgt exit Bye

49

第五章 實用範例

51 任務一Web Base客戶通訊錄

任職於開放科技公司的林小明前些日子在最符合成本效益的條件下快

速地完成公司網站的建置老闆因此對小明讚譽有加最近因為公司存放客戶資

料的 SQL Server主機屢遭病毒攻擊加上作業系統本身的問題當機次數頻繁

老闆希望能儘快把公司的客戶通訊錄程式移轉到較穩定的環境上因為此客戶通

訊錄程式最主要給內部人員使用所以介面美觀並不特別要求只求穩定且能快

速得到查詢結果老闆希望在短時間先看到程式的雛型並鍵入資料對其效率

及穩定性進行測試因為上次小明表現突出所以這次不可能的任務自然又落到

小明身上 小明想來想去既然要快速又穩定他而且又不希望所有人都得安裝 Client

程式於是小明決定)捨棄他的舊愛「Delphi+MS SQL」投向新歡「Apache + MySQL + PHP」利用此架構來設計一個簡單實用的Web Base客戶通訊錄程式

511 Web Base客戶通訊錄架構

此程式需要建立 CONTACT的資料庫並建立 adress Tables其結構如下表建立步驟請參考第三章 欄位名稱 資料型態 長度 說明 id INT (自動編號) 連絡人編號 name varchar文字 20 連絡人姓名 tel Varchar文字 15 連絡人電話 Web Base通訊錄共有下列幾個檔案功能如下表

檔案名稱 說明 Indexhtml Web Base通訊錄首頁 addphp 新增連絡人的 php程式 searchphp 尋找連絡人的 php程式 editphp 具有更新及刪除功能的 php程式

50

我們將這些檔案放至varwwwhtmlbluepage (預設無 bluepage目錄)

512 Web Base通訊錄測試

httpwwwopencombluepage 新增資料

圖 5-1 新增連絡人

圖 5-2 填入資料

51

圖 5-3 新增成功

搜尋及異動資料

圖 5-4 搜尋通訊錄

52

圖 5-5 編輯資料

圖 5-6 更新資料

513 程式內容及說明

lt-- 程式範例indexhtml--gt lthtmlgt ltheadgtlttitlegt通訊錄lttitlegtltheadgt ltbodygt ltcentergt

53

lth2gt通訊錄lth2gtlthrgt lta href=indexhtmlgt通訊錄ltagt | lta href=addphpgt新增連絡人ltagt | lta href=searchphpgt搜尋通訊錄ltagt ltcentergt ltbodygt lthtmlgt lt-- 程式範例addphp --gt lthtmlgt ltheadgtlttitlegt新增連絡人lttitlegtltheadgt ltbodygt ltcentergtlth2gt新增連絡人lth2gtltcentergtlthrgt lt 取得欄位資料 if (isset($_POST[Name]) ampamp isset($_POST[Tel]) ) $name = $_POST[Name] $tel = $_POST[Tel] 檢查是否有輸入欄位資料 if ($name = ampamp $tel = ) 建立 SQL字串 $sql = INSERT INTO address (name tel) values( $sql= $name $tel) 建立 MySQL 連結 $link = mysql_connect(localhostroot1234) 選擇資料庫 mysql_select_db(CONTACT) 執行 SQL指令 mysql_query($sql) mysql_close($link) echo ltfont color=redgt新增連絡人成功ltfontgtltbrgt gt ltform action=addphp method=postgt lttable border=0 width=300gt lttrgtlttdgt姓名 lttdgt

54

lttdgtltinput type=text name=Name size=20 maxlength=10gtlttdgtlttrgt lttrgtlttdgt電話 lttdgt lttdgtltinput type=text name=Tel size=20 maxlength=20gtlttdgtlttrgt lttrgtlttd colspan=2 align=centergt ltinput type=submit value=新增連絡人gtlttdgtlttrgt lttablegt ltformgt ltbrgtlta href=indexhtmlgt通訊錄ltagt | lta href=addphpgt新增連絡人ltagt | lta href=searchphpgt搜尋通訊錄ltagt ltbodygt lthtmlgt

lt-- 程式範例searchphp --gt lthtmlgt ltheadgtlttitlegt搜尋通訊錄lttitlegtltheadgt ltbodygt ltcentergtlth2gt搜尋通訊錄lth2gtlthrgt lt if (isset($_POST[Search])) 建立資料庫連結並選定資料庫 $link = mysql_connect(localhostroot1234) mysql_select_db(CONTACT) 建立基本的 SQL字串 $sql = SELECT FROM address 檢查是否輸入姓名 if (chop($_POST[Name]) = ) $name = name LIKE $_POST[Name] else $name = 檢查是否輸入電話號碼 if (chop($_POST[Tel]) = ) $tel = tel LIKE $_POST[Tel] else $tel =

55

if條件組合 SQL字串 if (chop($name) = ampamp chop($tel) = ) $sql= WHERE $name AND $tel elseif (chop($name) = ) 只有姓名 $sql = WHERE $name elseif (chop($tel) = ) 只有電話號碼 $sql = WHERE $tel $sql= ORDER BY name 最後加上排序 $result = mysql_query($sql) 取得欄位數 $total_fields = mysql_num_fields($result) echo lttable border=1gt echo lttrgtlttdgt編號lttdgtlttdgt姓名lttdgtlttdgt電話lttdgtlttd colspan=2gt功能選項lttdgtlttrgt 表格顯示查詢結果 while ($rows = mysql_fetch_array($result MYSQL_NUM)) echo lttrgt for ($i = 0 $i lt $total_fields $i++) echo lttdgt$rows[$i]lttdgt echo lttdgtlta href=editphpaction=editampid= echo $rows[0]gtltbgt編輯ltbgtlttdgt echo lttdgtlta href=editphpaction=delampid= echo $rows[0]gtltbgt刪除ltbgtlttdgt echo lttrgt echo lttablegtlthrgt mysql_free_result($result) mysql_close($link) gt ltcentergt ltform action=searchphp method=postgt lttable border=0 width=450gt lttrgtlttdgt搜尋姓名 lttdgt lttdgtltinput type=text name=Name size=10 maxlength=20gtlttdgtlttrgt lttrgtlttdgt搜尋電話 lttdgt lttdgtltinput type=text name=Tel

56

size=20 maxlength=20gtlttdgtlttrgt lttrgtlttd colspan=2 align=centergt ltinput type=submit name=Search value=搜尋gtlttdgtlttrgt lttablegt ltformgt ltbrgtlta href=indexhtmlgt通訊錄ltagt | lta href=addphpgt新增連絡人ltagt | lta href=searchphpgt搜尋通訊錄ltagt ltbodygt lthtmlgt

lt ob_start() gt lt-- 程式範例editphp --gt lthtmlgt ltheadgtlttitlegt編輯通訊錄lttitlegtltheadgt ltbodygt lt 取得 URL 參數 $id = $_GET[id] $action = $_GET[action] 建立資料庫連結 $link = mysql_connect(localhostroot1234) mysql_select_db(CONTACT) 選擇資料庫 執行的操作 switch ($action) case update 更新 取得欄位資料 $name = $_POST[Name] $tel = $_POST[Tel] $sql = UPDATE address SET name=$name tel=$tel WHERE id=$id mysql_query($sql) 執行 SQL指令 mysql_close($link) header(Location searchphp) 轉向到 serachphp break case del 刪除 $sql = DELETE FROM address WHERE id=$id

57

mysql_query($sql) 執行 SQL指令 mysql_close($link) header(Location searchphp) 轉向到 serachphp break case edit 編輯 $sql = SELECT FROM address WHERE id=$id $result = mysql_query($sql) 執行 SQL指令 $row = mysql_fetch_row($result) 取回記錄 $name = $row[1] 取得欄位 name $tel = $row[2] 取得欄位 tel mysql_close($link) 顯示編輯表單 gt ltcentergtlth2gt更新通訊錄lth2gtltcentergtlthrgt ltform action=editphpaction=updateampid=lt echo $id gt method=postgt lttable border=0 width=300gt lttrgtlttdgt姓名 lttdgt lttdgtltinput type=text name=Name size=20 maxlength=10 value=lt echo $name gtgtlttdgtlttrgt lttrgtlttdgt電話 lttdgt lttdgtltinput type=text name=Tel size=20 maxlength=20 value=lt echo $tel gtgtlttdgtlttrgt lttrgtlttd colspan=2 align=centergt ltinput type=submit value=更新連絡人gtlttdgtlttrgt lttablegt ltformgt ltbrgtlta href=indexhtmlgt通訊錄ltagt | lta href=addphpgt新增連絡人ltagt | lta href=searchphpgt搜尋通訊錄ltagt lt break gt ltbodygt lthtmlgt

58

52 任務二Web Base群組軟體 ( twig )

順利完成Web Base客戶通訊錄程式測試一段時間後「Apache + MySQL + PHP」架構的穩定與快速巳深得老闆與公司所有同事的認同隨著公司業績蒸

蒸日上人員組織編罝愈來愈龐大跨部門的會議愈來愈多業務員每日排滿拜

訪客戶的行程跟客戶的 Email的往來也愈來愈頻繁 愈來愈多部門的同事希望公司能建置一套群組軟體提供 web mail可讓業

務人員方便收發 mail還有連絡人議事日程待辦工作書簽等功能讓整個

公司運作及個人時間管理更有效率

老闆問小明對這些需求有什麼看法小明認為如果這些功能完全由程式部

門開發必定曠日費時而且耗費公司資源小明在網路尋找是否有提供這些功能

的Free Software皇天不負苦心人小明發現了TWIG (The Web Information Gateway) httptwigscrewdrivernet這個群組軟體它在 Web 上整合郵件新聞聯絡人議事日程工作序書簽等功能非常符合公司的需求 Step 1 下載 twig-277targz 下載網址 httptwigscrewdrivernetdownloadphp3

Step 2 解開 twig-277targz tar -xzvf twig-277targz

59

Step 3 執行安裝動作安裝到 varwwwhtmltwig 目錄 cd twig-277 twig-install varwwwhtmltwig

Step 4 建立 MySQL 資料庫(twig)及各資料表

cd setup mysql -u root -p1234 mysqlgt create database twig Query OK 1 row affected (001 sec) mysqlgt quit mysql -u root ndashp1234 twiglt twigtablemysql

Step 5 修改 configincphp3 參數設定 vi varwwwhtmltwigconfigconfigincphp3 $config[fromdomain] = opencom 網域 $config[language] = chinesebig5 中文訊息 $config[imap_port] = 143notls

60

Step 6 修改連結 MySQL 的帳號密碼 vi varwwwhtmltwigconfigdbconfigincphp3 $dbconfig[sqlusername] = root username $dbconfig[sqlpassword] = 1234 password

Step 7 其他設定檔

vi etchttpdconfhttpdconf 加入 AddType applicationx-httpd-php php3 在 DirectoryIndex最後加入 indexphp3 DirectoryIndex indexhtml indexhtmlvar indexphp3 在 AddDefaultCharset ISO-8859-1加上 AddDefaultCharset ISO-8859-1

vi etcphpini register_globals = On service httpd restart Step 8 sendmail 設定 vi etcmailsendmailcf在 264 行前面加上並重新啟動 sendmail「service snedmail restart」 262 SMTP daemon options 263 264 O DaemonPortOptions=Port=smtpAddr=127001 Name=MTA 265 266 SMTP client options 267 O ClientPortOptions=Family=inet Address=00

61

Step 9 檢查設定有無錯誤 http主機名稱twigtestphp3

62

Step 10 登入 twig ( http主機名稱twig)

63

第六章 維護及更新程序

61 日常維護

系統管理員最好定期以 root 身份登入看看信件在 RedHat Linux 中有一支 logwatch 程式會定時去分析 log file如果發現異常便會發信給 root除此之外筆者建議讀者平時就檢查 MySQL log file ( varlogmysqldlog)是否有異常情形

62 更新程序

讀者可至httprpmfindnet 尋找MySQL相關套件至於升級的相關步驟請參

考Linux OS SOP 第 54節

63 備份重要檔案

預設 MySQL 的 DB 檔案是存在 varlibmysql 內以 DB名稱為目錄目錄

內就是該 DB 的所有資料通常得定期備份還有 MySQL的設定檔 etcmycnf也別忘了一起備份

64 離線備份與還原

641 離線備份

預設 MySQL 的 DB 檔案是存在 varlibmysql 內以 DB 名稱為目錄目錄內

就是該 DB 的所有資料像 CRM 這個 DB就是存在 varlibmysqlCRM 內在備份前因為怕資料尚未完全寫入磁碟而且 MySQL 會 Lock 在使用的 DB 檔案所以應該是要先把 MySQL 先 Shutdown 一下整個備份的程序可以下像下面的指令去完成 cd varlibmysql

64

service mysqld stop tar cvfz CRM_db_20030905tgz CRM service mysqld start 對這樣就可以了 不過要注意的是怕 DB 內每個 Tables 間的資料有關關

聯性所以最好是把整個 DB 一次備起來單獨只備哪個 Tables 的檔案以後回存時怕會有資料關聯不一致的問題

642 離線還原

DB 發生錯誤而要回存時其實也不難先找出最近一次完整正常的備份先把現在錯誤的網頁或 DB 先更名或 tar 起來再把好的備份給解開回原來目錄位

置就行了需要注意的是 MySQL 服務最好也是要先停止回存完成後再啟動服務回存 DB 的整個程序可能像下面 cd varlibmysql service mysqldstop mv CRM CRM_OLD tar xvfz CRM_db_20030905tg service mysqld start

65 線上備份與還原

651 線上備份

使用像上面的檔案方式備份是個不錯的方法它最少可以保持該主機某個時間點的完整檔案備份但還是有一些問題需要考慮到有些主機就不只建立一個 DB 而已總不能為了備份某個 DB 而把整個 MySQL 服務停止備份檔案的方式回存在原主機上一定適用但假如 MySQL 版本升級或是在那天該網頁空間需遷機移機到別的主機時那就沒人敢保證備出來的資料檔可以用所以我們可以考慮另一種備份的方式是使用 MySQL 本身提供的功能 MySQL Data Dump指令是 mysqldump

65

使用 MySQL 的 Dump 功能可以把 DB 的結構資料或結構加資料 Dump 成文字檔 mysqldump 指令提供的彈性很大你可以選擇把整個 DB Dump 成一個檔或是每個 Table 為一個檔甚至是把結構檔和資料分開儲存都

可以 mysqladmin -uroot -p flush-logs mysqldump CRM -uroot -p --opt gt CRM_20030905sql (CRM 是 DB 名稱 opt 是一個使用完整 Dump 參數) 假如只是要單獨 Dump 某個 Table 時只要在上面的指令後轉出符號 gt 前加個 Table 名稱就可以如只要 phpbb2_users 這個 Table 的 Dump 時只要下 mysqldump CRM -uroot -p --opt CUSTOMER gt CRM_CUSTOMER_20030905sql

652 線上還原

若要回存整個資料庫只需將壓縮的備份檔還原成 Dump 的檔案再用下面的指令回存 mysql CRM -uroot -p lt CRM_20030905sql 這邊需注意的是若建立備份時是以--opt或--add-drop-table為參數時回存的 動作是先將舊的 Table 先刪除重建 Table 的結構後再把 Data 匯入所以回存後所有的資料會回到你當時備份那個時間點因此在回存資料時可以考慮把現有錯誤或不完整的 DB 先備份一份下來以備不時之需或是拿來比對錯誤的地

方在那裡當然你也可以把資料回存到另一個測試用的 DB 內只要把上面指令

的 DB 名稱改成你的測試用 DB 名稱即可 使用這種回存方式 MySQL 服務不需停止也不會動到其他正在使用的 DB 在一些提供 MySQL 服務的虛擬主機可用這種方式作你自己的 DB 備份及回存

66

另外假如你是系統重建或是移機時切需在新的 MySQL 內新建一個空白 DB 後才行作回存的工作你可以用下面的指令建立 mysql -uroot -p -e CREATE DATABASE CRM (上面的 CRM是你要新建的 DB 名稱) 另一種作法先用 mysql 指令進入 mysql client console 然後再用 CREATE DATABASE CRM 這樣就行了記得尾端要加個 符號該行指令才會執行

67

第七章 問題與解答

Q1RedHat 90預附的 MySQL到底有無支援 Transcation機制 Ans MySQL自 32334a之後的 MySQL-Max版本加入 InnoDB的資料庫類型透過

InnoDBMySQL同樣可以進行 COMMIT與 ROLLRACK的動作RedHat 90預附的 MySQL為 32354a-11巳支援 InnoDB的資料庫類型不過必須做以

下設定 1cp usrsharedocmysql-server-32354amy-mediumcnf to etcmycnf 2 vi etcmycnf 將以下設定前的拿掉 innodb_data_home_dir = varlibmysql innodb_data_file_path = ibdata110Mautoextend innodb_log_group_home_dir = varlibmysql innodb_log_arch_dir = varlibmysql 3service mysqld restart 如此一來各位在建立Table時便可指定Table Type為 innodb ( ex create table with type=innodb ) Q2如何解決 php+mysql 許功蓋等字變亂的問題 Ans 方法一 【確定 MySQL 預設的字元集】 1 打開 WinMySQLadmin 管理畫面(在視窗右下角狀態列紅綠燈圖示中按滑鼠

右鍵點選 Show me 選項) 2 點選管理畫面中 [Variables] 標籤選項其中 character_set變數就是您預設

字元集的變數其預設是 latin1 字元集(我們要將他改回 big5)而 chatacters_set 變數則是 MySQL 可以支援哪些字元集 【修改預設字元集變數 character_set 】 1 請點選管理畫面中 [myini Setup] 標籤選項設定 myini 2 按一下 [Pick-up and Edit myini values] 按鈕以便編輯目前的 myini 設定 3 在 [mysqld] 設定區塊底下新增一行 default-character-set = big5 變數設

68

定 4 新增一個 [client] 設定區塊並加入第三步驟的變數設定(游標往下移到空白處新增兩行 [client] 和 default-character-set=big5) 5 按一下畫面左下方 [Save Modification] 按鈕儲存設定 6 重新啟動 MySQL 或 Windows 方法二 Server端注意事項 phpini 中有關的設定為(預設值) Magic quotes for incoming GETPOSTCookie data magic_quotes_gpc = On Use Sybase-style magic quotes (escape with instead of ) magic_quotes_sybase = Off Client端注意事項 1中文資料送進 mysql 前請用 addslashes($str) 處理 2處理後送進 mysql 時請用 括起來並在參數後留一個空白如 $sql = UPDATE ezf_table set tablename=$tname tableend=$endtime table inguser=$tguser tableingid=$tguserid tableallnumber=$tnumber tableloca l=$tablelocal tableanyone=$tableopen tabletext=$ttext WHERE tableid=$t ableid tablename=$tname c 取出時請用 stripslashes($str) Q3MySQL root 密碼忘了該怎麼辦 Ans 1先停掉 mysql etcrcdinitdmysql stop 2以--skip-grant-table 的參數啟動 mysql safe_mysql --skip-grant-tableamp 3 更改 root 密碼 mysql mysql mysqlgt UPDATE user SET password=password(newpassword)

69

WHERE user=root mysqlgt FLUSH PRIVILEGES mysqlgt exit 4停掉 mysql再重跑 mysqladmin -uroot -p shutdown Enter password 輸入新設定的密碼 etcrcdinitdmysql start

Q4NULL值問題

Ans

NULL值的概念是造成 SQL的新手的混淆的普遍原因他們經常認為 NULL是和一個空字符串的一樣的東西不是這樣的例如下列語句是完全不同的

mysqlgt INSERT INTO my_table (phone) VALUES (NULL)

mysqlgt INSERT INTO my_table (phone) VALUES ()

兩個語句把值插入到 phone 列但是第一個插入一個 NULL值而第二個插入一個空字符串第一個的含義可以認為是ldquo電話號碼不知道而第二個則可意味

著ldquo她沒有電話

在 SQL中NULL值在于任何其他值甚至 NULL值比較時總是假的(FALSE)包含 NULL的一個表達式總是產生一個 NULL值除非在包含在表達式中的運算符和函數的文檔中指出在下列例子所有的列返回 NULL

mysqlgt SELECT NULL1+NULLCONCAT(InvisibleNULL)

如果你想要尋找值是 NULL的列你不能使用=NULL測試下列語句不返回任

何行因為對任何表達式expr = NULL是假的

mysqlgt SELECT FROM my_table WHERE phone = NULL

要想尋找 NULL值你必須使用 IS NULL測試下例顯示如何找出 NULL電話號碼和空的電話號碼

70

mysqlgt SELECT FROM my_table WHERE phone IS NULL mysqlgt SELECT FROM my_table WHERE phone =

在 MySQL中就像很多其他的 SQL服務器一樣你不能索引可以有 NULL值的列你必須聲明這樣的列為 NOT NULL而且你不能插入 NULL到索引的

列中

當用 LOAD DATA INFILE 讀取數據時空列用更新如果你想要在一個列中有

NULL值你應該在文本文件中使用N字面上的詞NULL也可以在某些情形下使用

當使用 ORDER BY時首先呈現 NULL值如果你用 DESC以降序排序NULL值最後顯示當使用 GROUP BY時所有的 NULL值被認為是相等的

為了有助于NULL的處理你能使用 IS NULL和 IS NOT NULL運算符和 IFNULL()函數

對某些列類型NULL值被特殊地處理如果你將 NULL插入表的第一個TIMESTAMP 列則插入當前的日期和時間如果你將 NULL插入一個AUTO_INCREMENT 列則插入順序中的下一個數字

Q5如何將圖片存放於 MySQL中

Ans

Step 1建立資料庫 test

Step 2 建立表格 binary_data

CREATE TABLE binary_data (

id INT(4) NOT NULL AUTO_INCREMENT PRIMARY KEY

description CHAR(50)

bin_data LONGBLOB

filename CHAR(50)

filesize CHAR(50)

filetype CHAR(50)

71

)

Step 3 利用 storephp 寫入圖片

storephp 程式碼

ltHTMLgt ltHEADgtltTITLEgtStore binary data into SQL DatabaseltTITLEgtltHEADgt ltBODYgt lt code that will be executed if the form has been submitted

if ($submit) mysql_connect(localhostrootYOUR_PASSWORD) mysql_select_db(test) $data=Base64_Encode(fread(fopen($form_data r) filesize($form_data))) $result=MYSQL_QUERY(INSERT INTO binary_data (descriptionbin_datafilenamefilesizefiletype) VALUES ($form_description$data$form_data_name$form_data_size$form_data_type)) $id= mysql_insert_id() print ltpgtThis file has the following Database ID ltbgt$idltbgt MYSQL_CLOSE() else else show the form to submit new data

gt

ltform method=post action=ltphp echo $PHP_SELF gt enctype=multipartform-datagt File Descriptionltbrgt ltinput type=text name=form_description size=40gt ltINPUT TYPE=hidden name=MAX_FILE_SIZE value=4000000gt ltbrgtFile to uploadstore in databaseltbrgt ltinput type=file name=form_data size=40gt ltpgtltinput type=submit name=submit value=submitgt ltformgt lt

72

gt ltBODYgt ltHTMLgt

Step 3 利用 storephp 取出圖片

getdataphp 程式碼

lt Syntax getdataphp3id=ltidgt if($id) you may have to modify login information for your database server MYSQL_CONNECT(localhostrootYOUR_PASSWORD) mysql_select_db(test) $query = select bin_datafiletype from binary_data where id=$id $result = MYSQL_QUERY($query) $data = Base64_Decode(MYSQL_RESULT($result0bin_data)) $type = MYSQL_RESULT($result0filetype) Header( Content-type $type) echo $data gt

Q6MySQL裝好之後啟動時或是執行 mysqladmin會出現如下訊息 Cant connect to local MYSQL Server through Socket varlibmysqlmysqlsock或是

Cant connect to local MYSQL Server through Socket tmpmysqldsock

Ans 可能有下列幾個原因

1這個 mysqldsock 不見了被某人刪除了或是被一些系統自動執行程式給刪

了例如有些 cron任務便會設定定期刪除 tmp 裡的東西所以呢您只能修改

cron 裡的設定讓它不要清除 mysqldsock 2在啟動時也可以改變 mysqldsock的位置您在啟動 MySQL的時候可以加入此參數usrlocalmysqlbinsafe_mysqld --user=mysql --socket=其他路

徑socket amp 同時得去設定環境變數 MYSQL_UNIX_PORT的值以指定新的

73

路徑 3若是您沒改 MYSQL_UNIX_PORT的值那麼您可以在執行指令的時候才打

例如mysqladmin --socket=其他路徑socket version Q7How to get the last insert id Ans CREATE TABLE product ( id INT(4) NOT NULL AUTO_INCREMENT PRIMARY KEY description VARCHAR(50) ) 1利用 SQL的話 mysqlgt insert into product(description) values(123) Query OK 1 row affected (000 sec) mysqlgt select last_insert_id() +------------------+ | last_insert_id() | +------------------+ +------------------+ 1 row in set (000 sec) ======================================== 2如果是 PHP的話 你可以用mysql_insert_id()取得該 id PHP example $result=MYSQL_QUERY(INSERT INTO product (description) VALUES ($description)) $id= mysql_insert_id() print This file has the following Database ID $id Q8如何將文字檔匯入資料庫 Ans $addr=homehttpdhtmlphpschool001txt $sql_select = load data infile $addr into table test fields terminated by t 解說 $sql_select = load data infile 文字檔名 into table 表格名 fields terminated by

74

t

(欄位分隔以 TAB鍵) 該文字檔須與資料表欄位格式相符 例如欄位有三個 則文字檔為每行一筆資料如下 欄 1資料ltTABgt欄 2資料ltTABgt欄 3資料 欄 1資料ltTABgt欄 2資料ltTABgt欄 3資料 欄 1資料ltTABgt欄 2資料ltTABgt欄 3資料 欄 1資料ltTABgtltTABgt欄 3資料

Q9如何撰寫 MySQL C API Ans Step 1利用文字編輯器撰寫以下程式碼 mysqlcc

include ltstdiohgt

include ltmysqlmysqlhgt

int main (int argc char argv[])

MYSQL mysql

MYSQL_RES res

MYSQL_ROW row

if (argc = 2)

fputs (Usage myc ltdatabasegt stderr)

return 1

if ((mysql_connect(ampmysqllocalhostrootYour_Password)))

fputs (Error connecting stderr)

abort()

75

if (mysql_select_db(ampmysqlargv[1]))

fputs (Error selecting database stderr)

abort()

if (mysql_query(ampmysqlSELECT FROM test_table))

fputs (Error processing query stderr)

abort()

if ((res = mysql_store_result(ampmysql)))

fputs (Error storing results stderr)

abort()

while((row = mysql_fetch_row(res)))

uint i = 0

for (i=0 i lt mysql_num_fields(res) i++)

printf(s row[i])

printf(n)

return 0

Step 2 Compile

gcc -Iusrlocalmysqlinclude -Lusrlocalmysqllibmysql mysqlcc ndashlm -lmysqlclient

(其中 include path與 library path取決於你的 MySQL安裝路徑)

76

如果執行時發生如下 error Run problemerror in loading shared libraries libmysqlclientsoX 將你的 MySQL library path(for exampleusrlocalmysqllibmysql) 加入etcldsoconf and run sbinldconfig -v Q9ASP + MySQL 範例程式 Ans Dim myconn As New ADODBConnection Dim myrs As New Recordset Dim mySQL As String Dim myrows As Long myconnOpen DSN=MyODBCsample mySQL = SELECT from user myrsSource = mySQL Set myrsActiveConnection = myconn myrsCursorLocation = adUseClient myrsOpen myrows = myrsRecordCount myrsClose myconnClose 可參考 httpwwwdwamnetmysqlasp_myodbcasp 有詳細的資料 Q10如何將 MySQL中的資料庫匯出成txt檔 Ans select from TableName into outfile textxls all result fields will seperate by tab

77

第八章 參考資料

英文部份 網址 1 httpwwwmysqlcom MySQL 網站有第一手有關 MySQL的資料 2 httpwwwmysqlcomdocenReplicationhtml 有關 MySQL Replication 的文件 3 httpwwwgeocitiescomsqlhomefaqstore_blobhtml 如何在 MySQL 存放 BLOB的資料 4httpwwwsapdborg 有關 SAP跟 MySQL相關合作的網站 書藉 1 Cooking with MySQL

Paul DuBois has selected sample recipes from the hundreds youll find in his book MySQL

Cookbook In this third and final series of excerpts showcasing these recipes learn how to

compute team standings how to calculate the differences between successive Dec 26

2002 2 Tips for Building Web Database Applications with PHP and MySQL by Hugh E Williams co-author of Web Database Applications with PHP amp MySQL 04042002

3 Managing and Using MySQL 2nd Edition By Tim King George Reese Randy Jay Yarger

4 MySQL Cookbook By Paul DuBoisPublisher OReillyPub Date October 2002

中文部份

78

1 httplinuxtncedutwtechdocmysqlmysql_docmanual_tochtml MySQL 中文手冊 2 httpchenshloxaedutwphpZ_1php PHP+MySQ程式研習設計網站 3 httplinuxtncedutwtechdocbanicdownhtml PHP 4 手冊 4 httpwwwtncedutwadmin_zonephp台南縣教育網網路中心有很多 Linux相關文件 5 httpdobtncedutw網站建置百寶箱有很多 PHP MySQL 相關範例程式 5 httpwwwdbworldcomtw資料庫專家電子雜誌介紹資料庫的重要觀念及名詞

79

附錄一 SQL Command 介紹

SQL (讀音ess-que-el) 是一種結構查詢語法SQL 使用於資料庫交流

傳遞相容於 ANSI (American National Standards Institute) 是一套標準的關聯

式資料庫語言 SQL 語言是執行更新或從資料系統獲取資料一般常見的關聯

資料庫系統都有提供 SQL 如 Oracle Sybase Microsoft SQL Server Access Ingres 等雖然大部份的資料庫都有提供 SQL 但也多提供了自已獨特的語

法造成了不相容的情形但標準基本的語法是相通的如Select Insert Update Delete Create and Drop 每一個系統都有支援

Table相關 Command

Create Table

關聯式資料庫包含有很多元件稱為資料表(tables) 把資料或訊息放在資

料表中 資料表是以不同的名稱做分別資料表由欄列所構成的二維陣列

欄包含欄位名資料型態 及其他可判斷的資訊列是由全部欄位構成一筆一

筆的紀錄 create table 語法用在建立一個新的資料表語法格式如下

create table tablename (column1 data type column2 data type column3 data type)

Format of create table if you were to use optional constraints

create table tablename (column1 data type [constraint] column2 data type [constraint] column3 data type [constraint]) [ ] = optional

Note You may have as many columns as youd like and the constraints are optional

80

Example

create table employee (first varchar(15) last varchar(20) age number(3) address varchar(30) city varchar(20) state varchar(20))

注意建立資料表格式要以括號把前後框住而最後以(分號)做結尾

欄位名不要超過 30個字元長而且不要使用 sql 的關鍵字(如 where select等)而在後面接是型態的宣告(如字串數字日期格式等)

資料型態是來描述欄位的方式如一個欄位Last_Name 是一個姓氏可以使用varchar (可變動長度字串) 資料型態

以下是幾個常見的資料庫型態 char(size) 固定長度字串最長為 255 位元 varchar(size) 變動長度字串最大字元數以 size 來指定 number(size) 數值格式可以是整數也可以是小數最大數字以 size 位數判

斷未指定小數位數由系統內定 date 日期格式 number(sized) 數值格式最大數字以 size 位數判斷d 為小數位數整數位

數為 size-d 位

有何限制當資料表被建立通常有一或數個欄位是要使用來做關聯的功

能 例如unique 限制(唯一值)兩筆記錄不可以相同的值 not null (非空值)該欄位一定要輸入資料不可是空的primary key (主鍵)是每一筆記錄識別的主要方式

Drop a table drop table 刪除資料表(其中的資料也會一併刪除)

drop table tablename

Example

81

drop table 和刪除全部資料是不同的刪除全部資料欄位名稱資訊等還會

存在但刪除資料表會把這一些也一併移除掉

如何查詢資料

Select 基本用法

select 語法是關連式資料庫最常用的部份可以取得你想要的資料這是一個

簡單的範例 select column1[column2etc] from tablename [where condition] [] = optional 在 select 之後所列欄位名則是要顯示的資料部份你可以一一列出各欄位

名或是以 (星號)來代表選擇全部的欄位 from 之後放資料表名稱 where 子句 (選項) 指定要過濾的條件符合者才會顯現 where 可使用的條件運算元 = 等於 gt 大於 lt 小於 gt= 大或等於 lt= 小或等於 ltgt 大相等 LIKE 相似 For example select first last city

82

from empinfo where first LIKE Er 以Er 為開頭的字串就符合要以單引號框住 Or you can specify select first last from empinfo where last LIKE s 最後一字為 S 就符合 select from empinfo where first = Eric 則表示 first name 一定要是 Eric 才可以 範例資料表empinfo 統計函數

MIN 傳回指定欄位最小值

MAX 傳回指定欄位最大值

SUM 傳回指定欄位總和

AVG 傳回指定欄位平均值

COUNT 傳回指定欄位的筆數

COUNT() 傳回資料庫中的總筆數

統計函數使用於資料表中的數值欄位配合 SELECT 語法使用 只用於總結特定單一欄位可以配合 GROUP BY 做篩選但也可以不使用 GROUP BY 語句For example

SELECT AVG(salary) FROM employee

83

傳回全部 salary 平均值

Another example

SELECT AVG(salary) FROM employee WHERE title = Programmer

傳回 salary 平均值條件為 employees 資料表中當 title 等於 Programmer

Example

SELECT Count() FROM employees

傳回 employees 資料表中紀錄總筆數

GROUP BY 語法 SELECT column1 SUM(column2) FROM list-of-tables GROUP BY column-list The GROUP BY 語句可以先以所列的欄位為條件分組排序在一起(可以多欄

位) example 要列出每一個 dept 中最高 salary 值 SELECT max(salary) dept FROM employee GROUP BY dept HAVING 語法

SELECT column1 SUM(column2) FROM list-of-tables GROUP BY column-list HAVING condition

HAVING 子句是 GROUP BY 的一部份用來過濾在 GROUP BY 所選出的資料功能如同 select 命令中 where 條件式一樣只是 HAVING 必需配合 GROUP BY 使用

我們以例子來說明我們要取得每一公司名及每一公司的薪水平均值輸入如下

84

SELECT dept avg(salary) FROM employee GROUP BY dept

但如果我們只列出薪資平均值超過 20000元的公司資料

SELECT dept avg(salary) FROM employee GROUP BY dept HAVING avg(salary) gt 20000

ORDER BY子句語法

SELECT column1 SUM(column2) FROM list-of-tables ORDER BY column-list [ASC | DESC]

[ ] =選項

ORDER BY是一個選項子句當你以排序方式來顯示資料(正向由小到大反向由大到小)以指定的欄位資料做排序

ASC = 正向- 預設值 DESC = 反向排序

For example

SELECT employee_id dept name age salary FROM employee_info WHERE dept = Sales ORDER BY salary

以上列出公司代號公司名銷售員人名年紀及薪資而條件是公司名為 Sales 顯示順序以薪資多少排序(由小到大為預設值)

如果要以多個欄位做排序要以逗號做分隔如下

SELECT employee_id dept name age salary FROM employee_info WHERE dept = Sales ORDER BY salary age DESC

85

結合條件及布林運算 SELECT column1 SUM(column2) FROM list-of-tables WHERE condition1 AND condition2 AND運算可以結兩個或以上的條件放在 WHERE子句中 兩者都要為真才

會顯示該筆記錄 OR 運算可以結兩個或以上敘述放在 WHERE子句中只要其中一個為直就

會顯示該筆記錄 For example SELECT employeeid firstname lastname title salary FROM employee_info WHERE salary gt= 5000000 AND title = Programmer 必需要薪資大於等於 50000而且職稱為 Programmer同時符合才會顯示該筆資料 以下以括號括住雖然不是必需的但如此比較容易讀 SELECT employeeid firstname lastname title salary FROM employee_info WHERE (salary gt= 5000000) AND (title = Programmer) 另外範例 SELECT firstname lastname title salary FROM employee_info WHERE (title = Sales) OR (title = Programmer) 條件為只要是 Sales 或 Programmer 職稱的就會被列出 IN and BETWEEN 子句

SELECT column1 SUM(column2) FROM list-of-tables WHERE column3 IN (list-of-values) SELECT column1 SUM(column2) FROM list-of-tables WHERE column3 BETWEEN value1 AND value2 IN 子句使用在列舉項目的使用上也就是分別測試是否符合所列的值 For example

86

SELECT employeeid lastname salary FROM employee_info WHERE lastname IN (Hernandez Jones Roberts Ruiz) 條件為姓氏(astname)要符合 Hernandez Jones Roberts or Ruiz 其中一個才會被傳回 IN運算元也可以使用 OR 的語法來取代如下結果相同 SELECT employeeid lastname salary FROM employee_info WHERE lastname = Hernandez OR lastname = Jones OR lastname = Roberts OR lastname = Ruiz 但使用 IN 句子比較短也比較易懂 你也可以使用 NOT IN 來去掉不要的記錄 BETWEEN 運算元使用在判斷是否存在兩個數值之間 For example SELECT employeeid age lastname salary FROM employee_info WHERE age BETWEEN 30 AND 40 傳回年紀 30歲到 40歲之間的資料(含 30及 40歲者) 相同的也可以使用以下語法來達到相同的結果 SELECT employeeid age lastname salary FROM employee_info WHERE age gt= 30 AND age lt= 40 你也可使用 NOT BETWEEN 來濾掉中間值的資料 數學運算 標準 ANSI SQL-92 提供以下運算

87

+ 加

- 減

餘數

餘數為除法後剩整數這不在標準的 ANSI SQL 中但大部份的資料庫都會支

援這運算元以下列出有用的函數雖不在 ANSI SQL-92 提供但一般資料庫

也會支援他們

ABS(x) 傳回 x 絕對值

SIGN(x) returns the sign of input x as -1 0 or 1 (negative zero or positive respectively)

MOD(xy) 餘數 - returns the integer remainder of x divided by y (同 xy)

FLOOR(x) 傳回小或等於 x 的最大整數值

CEILING(x) or CEIL(x)

傳回大或等於 x 的最小整數值

POWER(xy) x的 y 次方

ROUND(x) 把 x 四捨五入為整數

ROUND(xd) 四捨五入取到小數 d 位

SQRT(x) x 開平方

For example SELECT round(salary) firstname FROM employee_info 傳回薪資取到整數位

如何新增資料

insert 加入一筆新紀錄到資料表中 insert into tablename (first_columnlast_column) values (first_valuelast_value) [] = optional Example insert into employee

88

(first last age address city state) values (Luke Duke 45 2130 Boars Nest Hazard Co Georgia) Note 字串要以單引號住如string 數字框住也無妨 insert into 後面接資料表名稱再接以括號括住的欄位名在 values 後括號分別對映各欄位的值 以上的例子新增了一筆名(first) 為 Luke而住所(state) 為 Georgia 的資料

如何刪除資料

delete 可以刪除單筆或多筆紀錄 delete from tablename where columnname OPERATOR value [and|or column OPERATOR value] [ ] = optional Examples delete from employee Note 如果你沒有指定 where 子句那麼全部的紀錄都會被刪除 delete from employee where lastname = May delete from employee where firstname = Mike or firstname = Eric delete from 接著資料表名 再接著是條件式判斷沒有條件式則全部紀錄會

被刪除

如何更新資料

update 用來更新你所指定的記錄要和 WHERE 配合小心使用 語法 update tablename set columnname = newvalue[nextcolumn = newvalue2] where columnname OPERATOR value [and|or column OPERATOR value] [] = optional Examples

89

update phone_book set area_code = 623 where prefix = 979 update phone_book set last_name = Smith prefix=555 suffix=9292 where last_name = Jones update employee set age = age+1 where first_name=Mary and last_name=Williams

90

附錄二Replication

測試環境

RedHat 90 + MySQL 32358 MySQL資料庫路徑 varlibmysql MySQL設定檔 etcmycnf Master IP 1921680100 Slave IP 1921680200 請至下列網址下載最新MySQL 32358套件並利用rpm ndashUvh 更新 httpupdatesredhatcom9enosi386

圖 最新 MySQL 套件

測試架構圖

91

1921680100

1921680200Master Server

erveSlave S r

圖 測試架構圖

測試步驟

Master server 部份 Step1 確認 MasterSlave機器上所裝的 MySQL版本能進行

replication( 32329 or higher ) Step2 在 Master MySQL上開放一個帳號給 Slave mysql ndashu root ndashp mysqlgtGRANT FILE ON TO repl1921680200 IDENTIFIED BY lsquoabc123rsquo mysqlgtq 上面是 Master開放一個帳號 repl密碼 abc123給 IP1921680200有檔案處理

的權限 Step3 shutdown MySQL on the Master mysqladmin ndashu root ndashp shutdown Step4 備份 Master所有資料庫 tar ndashcvf tmpmysql-snapshottar varlibmysql 注意tar的時候MySQL是要在 stop情況下 在mysql (wwwmysqlcom) 網站的FAQ有不用shutdown的方法

92

Step5 在 master機器上修改etcmycnf 在[mysqld]區段內加入參數 log-bin server-id=這邊設定 server-id=1 sql-bin-update-same binlog-do-db=CRM只針對 CRM資料庫做紀錄 Step6 Restart MySQL on the master service mysqld start 此時因為有加入 log-bin 參數因此開始有 index產生了在varlibmysql目錄下

有index檔案紀錄資料庫的異動 log Slave server 部份 Step1 在 slave設定etcmycnf 在[mysqld]區段加入 master-host= master-user= master-password= master-port= server-id= 這邊設定 master-host=1921680100 master-user=repl master-password=abc123 master-port=3306 server-id=2 master-connect-retry=60預設重試間隔 60秒 replicate-do-db=CRM告訴 slave只做 CRM資料庫的更新 log-slave-updates Step2 將 master上的 mysql-snapshottar copy到 slave上 用 ftp傳到 slave的tmp Step3 解壓縮 Master資料庫至 Slave Server上 cd varlib tar xvf tmpmysql-snapshottar chown ndashR mysqlmysql mysql

93

chmod ndashR 770 mysql (視情況) Step4 Restart MySQL on the slave server 這時在varlibmysql目錄會出現 masterinfo此檔案紀錄了 Master MySQL server的資訊

狀況測試

One-way replication

1921680100

1921680200Master Server

erveSlave S r

圖 One-way replication架構圖 Step1 Master跟 Slave網路及服務都正常情況下由 Master端異動資料後 到 Slave端瀏覽資料檢視是否有進行 replication Step2 模擬 Slave Server 當機 可用在於 slave真的當機或是 Slave 不一定需要一直跟 master connect將Slave MySQL server shutdown由 Master端異動資料到 slave端瀏覽此時Slave應該沒有被 replication 更新然後再將 Slave端 MySQL server start起來

預設 60秒後 Slave會嘗試跟 Master要求進行 replication再去 Slave端檢視是否有更新資料

94

Step3 模擬 Master當機因為是設定 One-way replication一旦 Master Server Slave端沒有 Master的 source可以 download Two-way replication 基於 Master當機狀況於是發展雙向 Replication即 1921680100 ( Host A ) 1921680200 ( Host B )都分別擔任 MasterSlave身分

1921680100

1921680200er

Server B MasterSlave Server

Server A MasterSlave Serv

圖 Two-way replication架構圖 以下是針對兩台 MySQL伺服器進行雙向 Replication Step1觀念同單向 replication只是改成 Master也有 Slave身分 Slave也有Master的身分先分別在 Server AServer B 都去 grant一個進行 replication的身分 [A]mysqlgtGRANT FILE ON TO repl1921680200 IDENTIFIED BY lsquoabc123rsquo [B]mysqlgt GRANT FILE ON TO repl1921680100 IDENTIFIED BY lsquoabc123rsquo Step2做完單向 replication後stop Server Aserver B MySQL service此時 AB資料是一樣的

95

修改etcmycnf設定 範例 Server A [mysqld] datadir=varlibmysql socket=varlibmysqlmysqlsock server-id=1 log-bin sql-bin-update-same binlog-do-db=CRM master-host=1921680200 master-user=repl master-password=abc123 log-slave-updates master-connect-retry=60 replicate-do-db=CRM Server B [mysqld] datadir=varlibmysql socket=varlibmysqlmysqlsock server-id=2 log-bin sql-bin-update-same binlog-do-db=CRM master-host=1921680100 master-user=repl master-password=abc123 log-slave-updates master-connect-retry=60 replicate-do-db=CRM 分別 start Server AServer B MySQL後此時雙方都是 MasterSlave身分一旦哪一方資料異動就會通知對方來 replication-若 replication失效則必須將Server AServer B的masterinfo及index00x 都砍掉然後分別 restart MySQL server進行測試檢視成果 實務上通常如果需要做Two-way replication通常會搭配Virtual Server使用

96

在前端架設一台Virtual Server不過此部份不在此份SOP討論範圍內有興趣

的讀者可參考 httpwwwlinuxvirtualserverorg 網站

1921680100 1921680200

Host A MasterSlave Server

Host B MasterSlave Server

Virtual Host

圖 Virtual Server + Two-way replication 架構圖

97

圖 High Availability Linux Virtual Server架構圖

98

  • COSA-SOP-03-006
  • 第一章 簡介
    • 11適用對象 (Audience)
    • 12 MySQL本身
    • 13 MySQL 40版跟50版重大的改進功能
    • 14 各家資料庫軟體比較
      • 第二章 前置需求
      • 第三章 安裝
        • 31 MySQL安裝
        • 32 phpMyAdmin安裝
        • 33 升級及注意事項
          • 第四章 MySQL管理
            • 41 Webmin 管理介面
            • 42 phpMyAdmin 的操作介面
            • 43管理指令介紹
              • 431 利用mysqladmin設定root的密碼
                  • 第五章 實用範例
                    • 51 任務一Web Base客戶通訊錄
                    • 52 任務二Web Base群組軟體 ( twig )
                      • 第六章 維護及更新程序
                        • 61 日常維護
                        • 62 更新程序
                        • 63 備份重要檔案
                        • 64 離線備份與還原
                        • 65 線上備份與還原
                          • 第七章 問題與解答
                          • 第八章 參考資料
                          • 附錄一 SQL Command 介紹
                          • 附錄二Replication
Page 47: DataBase Server Standard Operation Procedureebooks.lib.ntu.edu.tw/1_file/oss/63/93doc4-5.pdf · 業務的公司帶來了不少壓力,譬如微軟,甲骨文 ... 外的錢用在第三方的資料庫產品上,譬如就可以不用再購買甲骨文公司

-u 表示使用者帳號root 為 MySQL預設的管理帳號

-h 表示 MySQL主機的主機名稱也可使用 IP Address password 表示使用者的密碼因為字串請使用單引號將密碼括起來 密碼設定完成之後還是可以利用 mysqladmin修改密碼但是你必須提供目前的密碼

432 連線 MySQL

mysql -uroot -p密碼 (-p和密碼之間不能有空白) 或 mysql -uroot -p (此方式會在進入後要求密碼) [rootossc phpMyAdmin] mysql -u root -p1234

Welcome to the MySQL monitor Commands end with or g

Your MySQL connection id is 25 to server version 32354

Type help or h for help Type c to clear the buffer

mysqlgt show databases

+----------+

| Database |

+----------+

| mysql |

| test |

+----------+

2 rows in set (000 sec)

mysqlgt exit

Bye

[rootossc phpMyAdmin]

433 建立資料庫

可利用 mysqladmin指令建立 CONTACT資料庫 mysqladmin -u root -p1234 create CONTACT

47

或是利用 mysql指令 [rootossc bluepage] mysql -u root -p1234 Welcome to the MySQL monitor Commands end with or g Your MySQL connection id is 1057 to server version 32354 Type help or h for help Type c to clear the buffer mysqlgt create database CONTACT Query OK 1 row affected (000 sec) mysqlgt show databases +----------+ | Database | +----------+ | CONTACT | | address | | hello | | mysql | | nuke | | test | +----------+ 6 rows in set (000 sec) mysqlgt exit

434 建立資料表

編寫 adresssql內容如下 -- Table structure for table address CREATE TABLE address ( id int(11) NOT NULL auto_increment name varchar(20) NOT NULL default tel varchar(15) NOT NULL default PRIMARY KEY (id) ) TYPE=MyISAM

48

-- Dumping data for table address INSERT INTO address VALUES (1林小明0800016888) INSERT INTO address VALUES (2黃大雄0800016888) INSERT INTO address VALUES (3劉小芬0800024365) 然後執行此 sql script mysql -u root -p1234 CONTACT lt addresssql 或是利 mysql command [rootossc bluepage] mysql -u root -p1234 Welcome to the MySQL monitor Commands end with or g Your MySQL connection id is 1090 to server version 32354 Type help or h for help Type c to clear the buffer mysqlgt use CONTACT Database changed Database changed mysqlgt CREATE TABLE address ( -gt id int(11) NOT NULL auto_increment -gt name varchar(20) NOT NULL default -gt tel varchar(15) NOT NULL default -gt PRIMARY KEY (id) -gt ) TYPE=MyISAM Query OK 0 rows affected (000 sec) mysqlgt INSERT INTO address VALUES (1林小明0800016888) Query OK 1 row affected (000 sec) mysqlgt INSERT INTO address VALUES (2黃大雄0800016888) Query OK 1 row affected (000 sec) mysqlgt INSERT INTO address VALUES (3劉小芬0800024365) Query OK 1 row affected (000 sec) mysqlgt exit Bye

49

第五章 實用範例

51 任務一Web Base客戶通訊錄

任職於開放科技公司的林小明前些日子在最符合成本效益的條件下快

速地完成公司網站的建置老闆因此對小明讚譽有加最近因為公司存放客戶資

料的 SQL Server主機屢遭病毒攻擊加上作業系統本身的問題當機次數頻繁

老闆希望能儘快把公司的客戶通訊錄程式移轉到較穩定的環境上因為此客戶通

訊錄程式最主要給內部人員使用所以介面美觀並不特別要求只求穩定且能快

速得到查詢結果老闆希望在短時間先看到程式的雛型並鍵入資料對其效率

及穩定性進行測試因為上次小明表現突出所以這次不可能的任務自然又落到

小明身上 小明想來想去既然要快速又穩定他而且又不希望所有人都得安裝 Client

程式於是小明決定)捨棄他的舊愛「Delphi+MS SQL」投向新歡「Apache + MySQL + PHP」利用此架構來設計一個簡單實用的Web Base客戶通訊錄程式

511 Web Base客戶通訊錄架構

此程式需要建立 CONTACT的資料庫並建立 adress Tables其結構如下表建立步驟請參考第三章 欄位名稱 資料型態 長度 說明 id INT (自動編號) 連絡人編號 name varchar文字 20 連絡人姓名 tel Varchar文字 15 連絡人電話 Web Base通訊錄共有下列幾個檔案功能如下表

檔案名稱 說明 Indexhtml Web Base通訊錄首頁 addphp 新增連絡人的 php程式 searchphp 尋找連絡人的 php程式 editphp 具有更新及刪除功能的 php程式

50

我們將這些檔案放至varwwwhtmlbluepage (預設無 bluepage目錄)

512 Web Base通訊錄測試

httpwwwopencombluepage 新增資料

圖 5-1 新增連絡人

圖 5-2 填入資料

51

圖 5-3 新增成功

搜尋及異動資料

圖 5-4 搜尋通訊錄

52

圖 5-5 編輯資料

圖 5-6 更新資料

513 程式內容及說明

lt-- 程式範例indexhtml--gt lthtmlgt ltheadgtlttitlegt通訊錄lttitlegtltheadgt ltbodygt ltcentergt

53

lth2gt通訊錄lth2gtlthrgt lta href=indexhtmlgt通訊錄ltagt | lta href=addphpgt新增連絡人ltagt | lta href=searchphpgt搜尋通訊錄ltagt ltcentergt ltbodygt lthtmlgt lt-- 程式範例addphp --gt lthtmlgt ltheadgtlttitlegt新增連絡人lttitlegtltheadgt ltbodygt ltcentergtlth2gt新增連絡人lth2gtltcentergtlthrgt lt 取得欄位資料 if (isset($_POST[Name]) ampamp isset($_POST[Tel]) ) $name = $_POST[Name] $tel = $_POST[Tel] 檢查是否有輸入欄位資料 if ($name = ampamp $tel = ) 建立 SQL字串 $sql = INSERT INTO address (name tel) values( $sql= $name $tel) 建立 MySQL 連結 $link = mysql_connect(localhostroot1234) 選擇資料庫 mysql_select_db(CONTACT) 執行 SQL指令 mysql_query($sql) mysql_close($link) echo ltfont color=redgt新增連絡人成功ltfontgtltbrgt gt ltform action=addphp method=postgt lttable border=0 width=300gt lttrgtlttdgt姓名 lttdgt

54

lttdgtltinput type=text name=Name size=20 maxlength=10gtlttdgtlttrgt lttrgtlttdgt電話 lttdgt lttdgtltinput type=text name=Tel size=20 maxlength=20gtlttdgtlttrgt lttrgtlttd colspan=2 align=centergt ltinput type=submit value=新增連絡人gtlttdgtlttrgt lttablegt ltformgt ltbrgtlta href=indexhtmlgt通訊錄ltagt | lta href=addphpgt新增連絡人ltagt | lta href=searchphpgt搜尋通訊錄ltagt ltbodygt lthtmlgt

lt-- 程式範例searchphp --gt lthtmlgt ltheadgtlttitlegt搜尋通訊錄lttitlegtltheadgt ltbodygt ltcentergtlth2gt搜尋通訊錄lth2gtlthrgt lt if (isset($_POST[Search])) 建立資料庫連結並選定資料庫 $link = mysql_connect(localhostroot1234) mysql_select_db(CONTACT) 建立基本的 SQL字串 $sql = SELECT FROM address 檢查是否輸入姓名 if (chop($_POST[Name]) = ) $name = name LIKE $_POST[Name] else $name = 檢查是否輸入電話號碼 if (chop($_POST[Tel]) = ) $tel = tel LIKE $_POST[Tel] else $tel =

55

if條件組合 SQL字串 if (chop($name) = ampamp chop($tel) = ) $sql= WHERE $name AND $tel elseif (chop($name) = ) 只有姓名 $sql = WHERE $name elseif (chop($tel) = ) 只有電話號碼 $sql = WHERE $tel $sql= ORDER BY name 最後加上排序 $result = mysql_query($sql) 取得欄位數 $total_fields = mysql_num_fields($result) echo lttable border=1gt echo lttrgtlttdgt編號lttdgtlttdgt姓名lttdgtlttdgt電話lttdgtlttd colspan=2gt功能選項lttdgtlttrgt 表格顯示查詢結果 while ($rows = mysql_fetch_array($result MYSQL_NUM)) echo lttrgt for ($i = 0 $i lt $total_fields $i++) echo lttdgt$rows[$i]lttdgt echo lttdgtlta href=editphpaction=editampid= echo $rows[0]gtltbgt編輯ltbgtlttdgt echo lttdgtlta href=editphpaction=delampid= echo $rows[0]gtltbgt刪除ltbgtlttdgt echo lttrgt echo lttablegtlthrgt mysql_free_result($result) mysql_close($link) gt ltcentergt ltform action=searchphp method=postgt lttable border=0 width=450gt lttrgtlttdgt搜尋姓名 lttdgt lttdgtltinput type=text name=Name size=10 maxlength=20gtlttdgtlttrgt lttrgtlttdgt搜尋電話 lttdgt lttdgtltinput type=text name=Tel

56

size=20 maxlength=20gtlttdgtlttrgt lttrgtlttd colspan=2 align=centergt ltinput type=submit name=Search value=搜尋gtlttdgtlttrgt lttablegt ltformgt ltbrgtlta href=indexhtmlgt通訊錄ltagt | lta href=addphpgt新增連絡人ltagt | lta href=searchphpgt搜尋通訊錄ltagt ltbodygt lthtmlgt

lt ob_start() gt lt-- 程式範例editphp --gt lthtmlgt ltheadgtlttitlegt編輯通訊錄lttitlegtltheadgt ltbodygt lt 取得 URL 參數 $id = $_GET[id] $action = $_GET[action] 建立資料庫連結 $link = mysql_connect(localhostroot1234) mysql_select_db(CONTACT) 選擇資料庫 執行的操作 switch ($action) case update 更新 取得欄位資料 $name = $_POST[Name] $tel = $_POST[Tel] $sql = UPDATE address SET name=$name tel=$tel WHERE id=$id mysql_query($sql) 執行 SQL指令 mysql_close($link) header(Location searchphp) 轉向到 serachphp break case del 刪除 $sql = DELETE FROM address WHERE id=$id

57

mysql_query($sql) 執行 SQL指令 mysql_close($link) header(Location searchphp) 轉向到 serachphp break case edit 編輯 $sql = SELECT FROM address WHERE id=$id $result = mysql_query($sql) 執行 SQL指令 $row = mysql_fetch_row($result) 取回記錄 $name = $row[1] 取得欄位 name $tel = $row[2] 取得欄位 tel mysql_close($link) 顯示編輯表單 gt ltcentergtlth2gt更新通訊錄lth2gtltcentergtlthrgt ltform action=editphpaction=updateampid=lt echo $id gt method=postgt lttable border=0 width=300gt lttrgtlttdgt姓名 lttdgt lttdgtltinput type=text name=Name size=20 maxlength=10 value=lt echo $name gtgtlttdgtlttrgt lttrgtlttdgt電話 lttdgt lttdgtltinput type=text name=Tel size=20 maxlength=20 value=lt echo $tel gtgtlttdgtlttrgt lttrgtlttd colspan=2 align=centergt ltinput type=submit value=更新連絡人gtlttdgtlttrgt lttablegt ltformgt ltbrgtlta href=indexhtmlgt通訊錄ltagt | lta href=addphpgt新增連絡人ltagt | lta href=searchphpgt搜尋通訊錄ltagt lt break gt ltbodygt lthtmlgt

58

52 任務二Web Base群組軟體 ( twig )

順利完成Web Base客戶通訊錄程式測試一段時間後「Apache + MySQL + PHP」架構的穩定與快速巳深得老闆與公司所有同事的認同隨著公司業績蒸

蒸日上人員組織編罝愈來愈龐大跨部門的會議愈來愈多業務員每日排滿拜

訪客戶的行程跟客戶的 Email的往來也愈來愈頻繁 愈來愈多部門的同事希望公司能建置一套群組軟體提供 web mail可讓業

務人員方便收發 mail還有連絡人議事日程待辦工作書簽等功能讓整個

公司運作及個人時間管理更有效率

老闆問小明對這些需求有什麼看法小明認為如果這些功能完全由程式部

門開發必定曠日費時而且耗費公司資源小明在網路尋找是否有提供這些功能

的Free Software皇天不負苦心人小明發現了TWIG (The Web Information Gateway) httptwigscrewdrivernet這個群組軟體它在 Web 上整合郵件新聞聯絡人議事日程工作序書簽等功能非常符合公司的需求 Step 1 下載 twig-277targz 下載網址 httptwigscrewdrivernetdownloadphp3

Step 2 解開 twig-277targz tar -xzvf twig-277targz

59

Step 3 執行安裝動作安裝到 varwwwhtmltwig 目錄 cd twig-277 twig-install varwwwhtmltwig

Step 4 建立 MySQL 資料庫(twig)及各資料表

cd setup mysql -u root -p1234 mysqlgt create database twig Query OK 1 row affected (001 sec) mysqlgt quit mysql -u root ndashp1234 twiglt twigtablemysql

Step 5 修改 configincphp3 參數設定 vi varwwwhtmltwigconfigconfigincphp3 $config[fromdomain] = opencom 網域 $config[language] = chinesebig5 中文訊息 $config[imap_port] = 143notls

60

Step 6 修改連結 MySQL 的帳號密碼 vi varwwwhtmltwigconfigdbconfigincphp3 $dbconfig[sqlusername] = root username $dbconfig[sqlpassword] = 1234 password

Step 7 其他設定檔

vi etchttpdconfhttpdconf 加入 AddType applicationx-httpd-php php3 在 DirectoryIndex最後加入 indexphp3 DirectoryIndex indexhtml indexhtmlvar indexphp3 在 AddDefaultCharset ISO-8859-1加上 AddDefaultCharset ISO-8859-1

vi etcphpini register_globals = On service httpd restart Step 8 sendmail 設定 vi etcmailsendmailcf在 264 行前面加上並重新啟動 sendmail「service snedmail restart」 262 SMTP daemon options 263 264 O DaemonPortOptions=Port=smtpAddr=127001 Name=MTA 265 266 SMTP client options 267 O ClientPortOptions=Family=inet Address=00

61

Step 9 檢查設定有無錯誤 http主機名稱twigtestphp3

62

Step 10 登入 twig ( http主機名稱twig)

63

第六章 維護及更新程序

61 日常維護

系統管理員最好定期以 root 身份登入看看信件在 RedHat Linux 中有一支 logwatch 程式會定時去分析 log file如果發現異常便會發信給 root除此之外筆者建議讀者平時就檢查 MySQL log file ( varlogmysqldlog)是否有異常情形

62 更新程序

讀者可至httprpmfindnet 尋找MySQL相關套件至於升級的相關步驟請參

考Linux OS SOP 第 54節

63 備份重要檔案

預設 MySQL 的 DB 檔案是存在 varlibmysql 內以 DB名稱為目錄目錄

內就是該 DB 的所有資料通常得定期備份還有 MySQL的設定檔 etcmycnf也別忘了一起備份

64 離線備份與還原

641 離線備份

預設 MySQL 的 DB 檔案是存在 varlibmysql 內以 DB 名稱為目錄目錄內

就是該 DB 的所有資料像 CRM 這個 DB就是存在 varlibmysqlCRM 內在備份前因為怕資料尚未完全寫入磁碟而且 MySQL 會 Lock 在使用的 DB 檔案所以應該是要先把 MySQL 先 Shutdown 一下整個備份的程序可以下像下面的指令去完成 cd varlibmysql

64

service mysqld stop tar cvfz CRM_db_20030905tgz CRM service mysqld start 對這樣就可以了 不過要注意的是怕 DB 內每個 Tables 間的資料有關關

聯性所以最好是把整個 DB 一次備起來單獨只備哪個 Tables 的檔案以後回存時怕會有資料關聯不一致的問題

642 離線還原

DB 發生錯誤而要回存時其實也不難先找出最近一次完整正常的備份先把現在錯誤的網頁或 DB 先更名或 tar 起來再把好的備份給解開回原來目錄位

置就行了需要注意的是 MySQL 服務最好也是要先停止回存完成後再啟動服務回存 DB 的整個程序可能像下面 cd varlibmysql service mysqldstop mv CRM CRM_OLD tar xvfz CRM_db_20030905tg service mysqld start

65 線上備份與還原

651 線上備份

使用像上面的檔案方式備份是個不錯的方法它最少可以保持該主機某個時間點的完整檔案備份但還是有一些問題需要考慮到有些主機就不只建立一個 DB 而已總不能為了備份某個 DB 而把整個 MySQL 服務停止備份檔案的方式回存在原主機上一定適用但假如 MySQL 版本升級或是在那天該網頁空間需遷機移機到別的主機時那就沒人敢保證備出來的資料檔可以用所以我們可以考慮另一種備份的方式是使用 MySQL 本身提供的功能 MySQL Data Dump指令是 mysqldump

65

使用 MySQL 的 Dump 功能可以把 DB 的結構資料或結構加資料 Dump 成文字檔 mysqldump 指令提供的彈性很大你可以選擇把整個 DB Dump 成一個檔或是每個 Table 為一個檔甚至是把結構檔和資料分開儲存都

可以 mysqladmin -uroot -p flush-logs mysqldump CRM -uroot -p --opt gt CRM_20030905sql (CRM 是 DB 名稱 opt 是一個使用完整 Dump 參數) 假如只是要單獨 Dump 某個 Table 時只要在上面的指令後轉出符號 gt 前加個 Table 名稱就可以如只要 phpbb2_users 這個 Table 的 Dump 時只要下 mysqldump CRM -uroot -p --opt CUSTOMER gt CRM_CUSTOMER_20030905sql

652 線上還原

若要回存整個資料庫只需將壓縮的備份檔還原成 Dump 的檔案再用下面的指令回存 mysql CRM -uroot -p lt CRM_20030905sql 這邊需注意的是若建立備份時是以--opt或--add-drop-table為參數時回存的 動作是先將舊的 Table 先刪除重建 Table 的結構後再把 Data 匯入所以回存後所有的資料會回到你當時備份那個時間點因此在回存資料時可以考慮把現有錯誤或不完整的 DB 先備份一份下來以備不時之需或是拿來比對錯誤的地

方在那裡當然你也可以把資料回存到另一個測試用的 DB 內只要把上面指令

的 DB 名稱改成你的測試用 DB 名稱即可 使用這種回存方式 MySQL 服務不需停止也不會動到其他正在使用的 DB 在一些提供 MySQL 服務的虛擬主機可用這種方式作你自己的 DB 備份及回存

66

另外假如你是系統重建或是移機時切需在新的 MySQL 內新建一個空白 DB 後才行作回存的工作你可以用下面的指令建立 mysql -uroot -p -e CREATE DATABASE CRM (上面的 CRM是你要新建的 DB 名稱) 另一種作法先用 mysql 指令進入 mysql client console 然後再用 CREATE DATABASE CRM 這樣就行了記得尾端要加個 符號該行指令才會執行

67

第七章 問題與解答

Q1RedHat 90預附的 MySQL到底有無支援 Transcation機制 Ans MySQL自 32334a之後的 MySQL-Max版本加入 InnoDB的資料庫類型透過

InnoDBMySQL同樣可以進行 COMMIT與 ROLLRACK的動作RedHat 90預附的 MySQL為 32354a-11巳支援 InnoDB的資料庫類型不過必須做以

下設定 1cp usrsharedocmysql-server-32354amy-mediumcnf to etcmycnf 2 vi etcmycnf 將以下設定前的拿掉 innodb_data_home_dir = varlibmysql innodb_data_file_path = ibdata110Mautoextend innodb_log_group_home_dir = varlibmysql innodb_log_arch_dir = varlibmysql 3service mysqld restart 如此一來各位在建立Table時便可指定Table Type為 innodb ( ex create table with type=innodb ) Q2如何解決 php+mysql 許功蓋等字變亂的問題 Ans 方法一 【確定 MySQL 預設的字元集】 1 打開 WinMySQLadmin 管理畫面(在視窗右下角狀態列紅綠燈圖示中按滑鼠

右鍵點選 Show me 選項) 2 點選管理畫面中 [Variables] 標籤選項其中 character_set變數就是您預設

字元集的變數其預設是 latin1 字元集(我們要將他改回 big5)而 chatacters_set 變數則是 MySQL 可以支援哪些字元集 【修改預設字元集變數 character_set 】 1 請點選管理畫面中 [myini Setup] 標籤選項設定 myini 2 按一下 [Pick-up and Edit myini values] 按鈕以便編輯目前的 myini 設定 3 在 [mysqld] 設定區塊底下新增一行 default-character-set = big5 變數設

68

定 4 新增一個 [client] 設定區塊並加入第三步驟的變數設定(游標往下移到空白處新增兩行 [client] 和 default-character-set=big5) 5 按一下畫面左下方 [Save Modification] 按鈕儲存設定 6 重新啟動 MySQL 或 Windows 方法二 Server端注意事項 phpini 中有關的設定為(預設值) Magic quotes for incoming GETPOSTCookie data magic_quotes_gpc = On Use Sybase-style magic quotes (escape with instead of ) magic_quotes_sybase = Off Client端注意事項 1中文資料送進 mysql 前請用 addslashes($str) 處理 2處理後送進 mysql 時請用 括起來並在參數後留一個空白如 $sql = UPDATE ezf_table set tablename=$tname tableend=$endtime table inguser=$tguser tableingid=$tguserid tableallnumber=$tnumber tableloca l=$tablelocal tableanyone=$tableopen tabletext=$ttext WHERE tableid=$t ableid tablename=$tname c 取出時請用 stripslashes($str) Q3MySQL root 密碼忘了該怎麼辦 Ans 1先停掉 mysql etcrcdinitdmysql stop 2以--skip-grant-table 的參數啟動 mysql safe_mysql --skip-grant-tableamp 3 更改 root 密碼 mysql mysql mysqlgt UPDATE user SET password=password(newpassword)

69

WHERE user=root mysqlgt FLUSH PRIVILEGES mysqlgt exit 4停掉 mysql再重跑 mysqladmin -uroot -p shutdown Enter password 輸入新設定的密碼 etcrcdinitdmysql start

Q4NULL值問題

Ans

NULL值的概念是造成 SQL的新手的混淆的普遍原因他們經常認為 NULL是和一個空字符串的一樣的東西不是這樣的例如下列語句是完全不同的

mysqlgt INSERT INTO my_table (phone) VALUES (NULL)

mysqlgt INSERT INTO my_table (phone) VALUES ()

兩個語句把值插入到 phone 列但是第一個插入一個 NULL值而第二個插入一個空字符串第一個的含義可以認為是ldquo電話號碼不知道而第二個則可意味

著ldquo她沒有電話

在 SQL中NULL值在于任何其他值甚至 NULL值比較時總是假的(FALSE)包含 NULL的一個表達式總是產生一個 NULL值除非在包含在表達式中的運算符和函數的文檔中指出在下列例子所有的列返回 NULL

mysqlgt SELECT NULL1+NULLCONCAT(InvisibleNULL)

如果你想要尋找值是 NULL的列你不能使用=NULL測試下列語句不返回任

何行因為對任何表達式expr = NULL是假的

mysqlgt SELECT FROM my_table WHERE phone = NULL

要想尋找 NULL值你必須使用 IS NULL測試下例顯示如何找出 NULL電話號碼和空的電話號碼

70

mysqlgt SELECT FROM my_table WHERE phone IS NULL mysqlgt SELECT FROM my_table WHERE phone =

在 MySQL中就像很多其他的 SQL服務器一樣你不能索引可以有 NULL值的列你必須聲明這樣的列為 NOT NULL而且你不能插入 NULL到索引的

列中

當用 LOAD DATA INFILE 讀取數據時空列用更新如果你想要在一個列中有

NULL值你應該在文本文件中使用N字面上的詞NULL也可以在某些情形下使用

當使用 ORDER BY時首先呈現 NULL值如果你用 DESC以降序排序NULL值最後顯示當使用 GROUP BY時所有的 NULL值被認為是相等的

為了有助于NULL的處理你能使用 IS NULL和 IS NOT NULL運算符和 IFNULL()函數

對某些列類型NULL值被特殊地處理如果你將 NULL插入表的第一個TIMESTAMP 列則插入當前的日期和時間如果你將 NULL插入一個AUTO_INCREMENT 列則插入順序中的下一個數字

Q5如何將圖片存放於 MySQL中

Ans

Step 1建立資料庫 test

Step 2 建立表格 binary_data

CREATE TABLE binary_data (

id INT(4) NOT NULL AUTO_INCREMENT PRIMARY KEY

description CHAR(50)

bin_data LONGBLOB

filename CHAR(50)

filesize CHAR(50)

filetype CHAR(50)

71

)

Step 3 利用 storephp 寫入圖片

storephp 程式碼

ltHTMLgt ltHEADgtltTITLEgtStore binary data into SQL DatabaseltTITLEgtltHEADgt ltBODYgt lt code that will be executed if the form has been submitted

if ($submit) mysql_connect(localhostrootYOUR_PASSWORD) mysql_select_db(test) $data=Base64_Encode(fread(fopen($form_data r) filesize($form_data))) $result=MYSQL_QUERY(INSERT INTO binary_data (descriptionbin_datafilenamefilesizefiletype) VALUES ($form_description$data$form_data_name$form_data_size$form_data_type)) $id= mysql_insert_id() print ltpgtThis file has the following Database ID ltbgt$idltbgt MYSQL_CLOSE() else else show the form to submit new data

gt

ltform method=post action=ltphp echo $PHP_SELF gt enctype=multipartform-datagt File Descriptionltbrgt ltinput type=text name=form_description size=40gt ltINPUT TYPE=hidden name=MAX_FILE_SIZE value=4000000gt ltbrgtFile to uploadstore in databaseltbrgt ltinput type=file name=form_data size=40gt ltpgtltinput type=submit name=submit value=submitgt ltformgt lt

72

gt ltBODYgt ltHTMLgt

Step 3 利用 storephp 取出圖片

getdataphp 程式碼

lt Syntax getdataphp3id=ltidgt if($id) you may have to modify login information for your database server MYSQL_CONNECT(localhostrootYOUR_PASSWORD) mysql_select_db(test) $query = select bin_datafiletype from binary_data where id=$id $result = MYSQL_QUERY($query) $data = Base64_Decode(MYSQL_RESULT($result0bin_data)) $type = MYSQL_RESULT($result0filetype) Header( Content-type $type) echo $data gt

Q6MySQL裝好之後啟動時或是執行 mysqladmin會出現如下訊息 Cant connect to local MYSQL Server through Socket varlibmysqlmysqlsock或是

Cant connect to local MYSQL Server through Socket tmpmysqldsock

Ans 可能有下列幾個原因

1這個 mysqldsock 不見了被某人刪除了或是被一些系統自動執行程式給刪

了例如有些 cron任務便會設定定期刪除 tmp 裡的東西所以呢您只能修改

cron 裡的設定讓它不要清除 mysqldsock 2在啟動時也可以改變 mysqldsock的位置您在啟動 MySQL的時候可以加入此參數usrlocalmysqlbinsafe_mysqld --user=mysql --socket=其他路

徑socket amp 同時得去設定環境變數 MYSQL_UNIX_PORT的值以指定新的

73

路徑 3若是您沒改 MYSQL_UNIX_PORT的值那麼您可以在執行指令的時候才打

例如mysqladmin --socket=其他路徑socket version Q7How to get the last insert id Ans CREATE TABLE product ( id INT(4) NOT NULL AUTO_INCREMENT PRIMARY KEY description VARCHAR(50) ) 1利用 SQL的話 mysqlgt insert into product(description) values(123) Query OK 1 row affected (000 sec) mysqlgt select last_insert_id() +------------------+ | last_insert_id() | +------------------+ +------------------+ 1 row in set (000 sec) ======================================== 2如果是 PHP的話 你可以用mysql_insert_id()取得該 id PHP example $result=MYSQL_QUERY(INSERT INTO product (description) VALUES ($description)) $id= mysql_insert_id() print This file has the following Database ID $id Q8如何將文字檔匯入資料庫 Ans $addr=homehttpdhtmlphpschool001txt $sql_select = load data infile $addr into table test fields terminated by t 解說 $sql_select = load data infile 文字檔名 into table 表格名 fields terminated by

74

t

(欄位分隔以 TAB鍵) 該文字檔須與資料表欄位格式相符 例如欄位有三個 則文字檔為每行一筆資料如下 欄 1資料ltTABgt欄 2資料ltTABgt欄 3資料 欄 1資料ltTABgt欄 2資料ltTABgt欄 3資料 欄 1資料ltTABgt欄 2資料ltTABgt欄 3資料 欄 1資料ltTABgtltTABgt欄 3資料

Q9如何撰寫 MySQL C API Ans Step 1利用文字編輯器撰寫以下程式碼 mysqlcc

include ltstdiohgt

include ltmysqlmysqlhgt

int main (int argc char argv[])

MYSQL mysql

MYSQL_RES res

MYSQL_ROW row

if (argc = 2)

fputs (Usage myc ltdatabasegt stderr)

return 1

if ((mysql_connect(ampmysqllocalhostrootYour_Password)))

fputs (Error connecting stderr)

abort()

75

if (mysql_select_db(ampmysqlargv[1]))

fputs (Error selecting database stderr)

abort()

if (mysql_query(ampmysqlSELECT FROM test_table))

fputs (Error processing query stderr)

abort()

if ((res = mysql_store_result(ampmysql)))

fputs (Error storing results stderr)

abort()

while((row = mysql_fetch_row(res)))

uint i = 0

for (i=0 i lt mysql_num_fields(res) i++)

printf(s row[i])

printf(n)

return 0

Step 2 Compile

gcc -Iusrlocalmysqlinclude -Lusrlocalmysqllibmysql mysqlcc ndashlm -lmysqlclient

(其中 include path與 library path取決於你的 MySQL安裝路徑)

76

如果執行時發生如下 error Run problemerror in loading shared libraries libmysqlclientsoX 將你的 MySQL library path(for exampleusrlocalmysqllibmysql) 加入etcldsoconf and run sbinldconfig -v Q9ASP + MySQL 範例程式 Ans Dim myconn As New ADODBConnection Dim myrs As New Recordset Dim mySQL As String Dim myrows As Long myconnOpen DSN=MyODBCsample mySQL = SELECT from user myrsSource = mySQL Set myrsActiveConnection = myconn myrsCursorLocation = adUseClient myrsOpen myrows = myrsRecordCount myrsClose myconnClose 可參考 httpwwwdwamnetmysqlasp_myodbcasp 有詳細的資料 Q10如何將 MySQL中的資料庫匯出成txt檔 Ans select from TableName into outfile textxls all result fields will seperate by tab

77

第八章 參考資料

英文部份 網址 1 httpwwwmysqlcom MySQL 網站有第一手有關 MySQL的資料 2 httpwwwmysqlcomdocenReplicationhtml 有關 MySQL Replication 的文件 3 httpwwwgeocitiescomsqlhomefaqstore_blobhtml 如何在 MySQL 存放 BLOB的資料 4httpwwwsapdborg 有關 SAP跟 MySQL相關合作的網站 書藉 1 Cooking with MySQL

Paul DuBois has selected sample recipes from the hundreds youll find in his book MySQL

Cookbook In this third and final series of excerpts showcasing these recipes learn how to

compute team standings how to calculate the differences between successive Dec 26

2002 2 Tips for Building Web Database Applications with PHP and MySQL by Hugh E Williams co-author of Web Database Applications with PHP amp MySQL 04042002

3 Managing and Using MySQL 2nd Edition By Tim King George Reese Randy Jay Yarger

4 MySQL Cookbook By Paul DuBoisPublisher OReillyPub Date October 2002

中文部份

78

1 httplinuxtncedutwtechdocmysqlmysql_docmanual_tochtml MySQL 中文手冊 2 httpchenshloxaedutwphpZ_1php PHP+MySQ程式研習設計網站 3 httplinuxtncedutwtechdocbanicdownhtml PHP 4 手冊 4 httpwwwtncedutwadmin_zonephp台南縣教育網網路中心有很多 Linux相關文件 5 httpdobtncedutw網站建置百寶箱有很多 PHP MySQL 相關範例程式 5 httpwwwdbworldcomtw資料庫專家電子雜誌介紹資料庫的重要觀念及名詞

79

附錄一 SQL Command 介紹

SQL (讀音ess-que-el) 是一種結構查詢語法SQL 使用於資料庫交流

傳遞相容於 ANSI (American National Standards Institute) 是一套標準的關聯

式資料庫語言 SQL 語言是執行更新或從資料系統獲取資料一般常見的關聯

資料庫系統都有提供 SQL 如 Oracle Sybase Microsoft SQL Server Access Ingres 等雖然大部份的資料庫都有提供 SQL 但也多提供了自已獨特的語

法造成了不相容的情形但標準基本的語法是相通的如Select Insert Update Delete Create and Drop 每一個系統都有支援

Table相關 Command

Create Table

關聯式資料庫包含有很多元件稱為資料表(tables) 把資料或訊息放在資

料表中 資料表是以不同的名稱做分別資料表由欄列所構成的二維陣列

欄包含欄位名資料型態 及其他可判斷的資訊列是由全部欄位構成一筆一

筆的紀錄 create table 語法用在建立一個新的資料表語法格式如下

create table tablename (column1 data type column2 data type column3 data type)

Format of create table if you were to use optional constraints

create table tablename (column1 data type [constraint] column2 data type [constraint] column3 data type [constraint]) [ ] = optional

Note You may have as many columns as youd like and the constraints are optional

80

Example

create table employee (first varchar(15) last varchar(20) age number(3) address varchar(30) city varchar(20) state varchar(20))

注意建立資料表格式要以括號把前後框住而最後以(分號)做結尾

欄位名不要超過 30個字元長而且不要使用 sql 的關鍵字(如 where select等)而在後面接是型態的宣告(如字串數字日期格式等)

資料型態是來描述欄位的方式如一個欄位Last_Name 是一個姓氏可以使用varchar (可變動長度字串) 資料型態

以下是幾個常見的資料庫型態 char(size) 固定長度字串最長為 255 位元 varchar(size) 變動長度字串最大字元數以 size 來指定 number(size) 數值格式可以是整數也可以是小數最大數字以 size 位數判

斷未指定小數位數由系統內定 date 日期格式 number(sized) 數值格式最大數字以 size 位數判斷d 為小數位數整數位

數為 size-d 位

有何限制當資料表被建立通常有一或數個欄位是要使用來做關聯的功

能 例如unique 限制(唯一值)兩筆記錄不可以相同的值 not null (非空值)該欄位一定要輸入資料不可是空的primary key (主鍵)是每一筆記錄識別的主要方式

Drop a table drop table 刪除資料表(其中的資料也會一併刪除)

drop table tablename

Example

81

drop table 和刪除全部資料是不同的刪除全部資料欄位名稱資訊等還會

存在但刪除資料表會把這一些也一併移除掉

如何查詢資料

Select 基本用法

select 語法是關連式資料庫最常用的部份可以取得你想要的資料這是一個

簡單的範例 select column1[column2etc] from tablename [where condition] [] = optional 在 select 之後所列欄位名則是要顯示的資料部份你可以一一列出各欄位

名或是以 (星號)來代表選擇全部的欄位 from 之後放資料表名稱 where 子句 (選項) 指定要過濾的條件符合者才會顯現 where 可使用的條件運算元 = 等於 gt 大於 lt 小於 gt= 大或等於 lt= 小或等於 ltgt 大相等 LIKE 相似 For example select first last city

82

from empinfo where first LIKE Er 以Er 為開頭的字串就符合要以單引號框住 Or you can specify select first last from empinfo where last LIKE s 最後一字為 S 就符合 select from empinfo where first = Eric 則表示 first name 一定要是 Eric 才可以 範例資料表empinfo 統計函數

MIN 傳回指定欄位最小值

MAX 傳回指定欄位最大值

SUM 傳回指定欄位總和

AVG 傳回指定欄位平均值

COUNT 傳回指定欄位的筆數

COUNT() 傳回資料庫中的總筆數

統計函數使用於資料表中的數值欄位配合 SELECT 語法使用 只用於總結特定單一欄位可以配合 GROUP BY 做篩選但也可以不使用 GROUP BY 語句For example

SELECT AVG(salary) FROM employee

83

傳回全部 salary 平均值

Another example

SELECT AVG(salary) FROM employee WHERE title = Programmer

傳回 salary 平均值條件為 employees 資料表中當 title 等於 Programmer

Example

SELECT Count() FROM employees

傳回 employees 資料表中紀錄總筆數

GROUP BY 語法 SELECT column1 SUM(column2) FROM list-of-tables GROUP BY column-list The GROUP BY 語句可以先以所列的欄位為條件分組排序在一起(可以多欄

位) example 要列出每一個 dept 中最高 salary 值 SELECT max(salary) dept FROM employee GROUP BY dept HAVING 語法

SELECT column1 SUM(column2) FROM list-of-tables GROUP BY column-list HAVING condition

HAVING 子句是 GROUP BY 的一部份用來過濾在 GROUP BY 所選出的資料功能如同 select 命令中 where 條件式一樣只是 HAVING 必需配合 GROUP BY 使用

我們以例子來說明我們要取得每一公司名及每一公司的薪水平均值輸入如下

84

SELECT dept avg(salary) FROM employee GROUP BY dept

但如果我們只列出薪資平均值超過 20000元的公司資料

SELECT dept avg(salary) FROM employee GROUP BY dept HAVING avg(salary) gt 20000

ORDER BY子句語法

SELECT column1 SUM(column2) FROM list-of-tables ORDER BY column-list [ASC | DESC]

[ ] =選項

ORDER BY是一個選項子句當你以排序方式來顯示資料(正向由小到大反向由大到小)以指定的欄位資料做排序

ASC = 正向- 預設值 DESC = 反向排序

For example

SELECT employee_id dept name age salary FROM employee_info WHERE dept = Sales ORDER BY salary

以上列出公司代號公司名銷售員人名年紀及薪資而條件是公司名為 Sales 顯示順序以薪資多少排序(由小到大為預設值)

如果要以多個欄位做排序要以逗號做分隔如下

SELECT employee_id dept name age salary FROM employee_info WHERE dept = Sales ORDER BY salary age DESC

85

結合條件及布林運算 SELECT column1 SUM(column2) FROM list-of-tables WHERE condition1 AND condition2 AND運算可以結兩個或以上的條件放在 WHERE子句中 兩者都要為真才

會顯示該筆記錄 OR 運算可以結兩個或以上敘述放在 WHERE子句中只要其中一個為直就

會顯示該筆記錄 For example SELECT employeeid firstname lastname title salary FROM employee_info WHERE salary gt= 5000000 AND title = Programmer 必需要薪資大於等於 50000而且職稱為 Programmer同時符合才會顯示該筆資料 以下以括號括住雖然不是必需的但如此比較容易讀 SELECT employeeid firstname lastname title salary FROM employee_info WHERE (salary gt= 5000000) AND (title = Programmer) 另外範例 SELECT firstname lastname title salary FROM employee_info WHERE (title = Sales) OR (title = Programmer) 條件為只要是 Sales 或 Programmer 職稱的就會被列出 IN and BETWEEN 子句

SELECT column1 SUM(column2) FROM list-of-tables WHERE column3 IN (list-of-values) SELECT column1 SUM(column2) FROM list-of-tables WHERE column3 BETWEEN value1 AND value2 IN 子句使用在列舉項目的使用上也就是分別測試是否符合所列的值 For example

86

SELECT employeeid lastname salary FROM employee_info WHERE lastname IN (Hernandez Jones Roberts Ruiz) 條件為姓氏(astname)要符合 Hernandez Jones Roberts or Ruiz 其中一個才會被傳回 IN運算元也可以使用 OR 的語法來取代如下結果相同 SELECT employeeid lastname salary FROM employee_info WHERE lastname = Hernandez OR lastname = Jones OR lastname = Roberts OR lastname = Ruiz 但使用 IN 句子比較短也比較易懂 你也可以使用 NOT IN 來去掉不要的記錄 BETWEEN 運算元使用在判斷是否存在兩個數值之間 For example SELECT employeeid age lastname salary FROM employee_info WHERE age BETWEEN 30 AND 40 傳回年紀 30歲到 40歲之間的資料(含 30及 40歲者) 相同的也可以使用以下語法來達到相同的結果 SELECT employeeid age lastname salary FROM employee_info WHERE age gt= 30 AND age lt= 40 你也可使用 NOT BETWEEN 來濾掉中間值的資料 數學運算 標準 ANSI SQL-92 提供以下運算

87

+ 加

- 減

餘數

餘數為除法後剩整數這不在標準的 ANSI SQL 中但大部份的資料庫都會支

援這運算元以下列出有用的函數雖不在 ANSI SQL-92 提供但一般資料庫

也會支援他們

ABS(x) 傳回 x 絕對值

SIGN(x) returns the sign of input x as -1 0 or 1 (negative zero or positive respectively)

MOD(xy) 餘數 - returns the integer remainder of x divided by y (同 xy)

FLOOR(x) 傳回小或等於 x 的最大整數值

CEILING(x) or CEIL(x)

傳回大或等於 x 的最小整數值

POWER(xy) x的 y 次方

ROUND(x) 把 x 四捨五入為整數

ROUND(xd) 四捨五入取到小數 d 位

SQRT(x) x 開平方

For example SELECT round(salary) firstname FROM employee_info 傳回薪資取到整數位

如何新增資料

insert 加入一筆新紀錄到資料表中 insert into tablename (first_columnlast_column) values (first_valuelast_value) [] = optional Example insert into employee

88

(first last age address city state) values (Luke Duke 45 2130 Boars Nest Hazard Co Georgia) Note 字串要以單引號住如string 數字框住也無妨 insert into 後面接資料表名稱再接以括號括住的欄位名在 values 後括號分別對映各欄位的值 以上的例子新增了一筆名(first) 為 Luke而住所(state) 為 Georgia 的資料

如何刪除資料

delete 可以刪除單筆或多筆紀錄 delete from tablename where columnname OPERATOR value [and|or column OPERATOR value] [ ] = optional Examples delete from employee Note 如果你沒有指定 where 子句那麼全部的紀錄都會被刪除 delete from employee where lastname = May delete from employee where firstname = Mike or firstname = Eric delete from 接著資料表名 再接著是條件式判斷沒有條件式則全部紀錄會

被刪除

如何更新資料

update 用來更新你所指定的記錄要和 WHERE 配合小心使用 語法 update tablename set columnname = newvalue[nextcolumn = newvalue2] where columnname OPERATOR value [and|or column OPERATOR value] [] = optional Examples

89

update phone_book set area_code = 623 where prefix = 979 update phone_book set last_name = Smith prefix=555 suffix=9292 where last_name = Jones update employee set age = age+1 where first_name=Mary and last_name=Williams

90

附錄二Replication

測試環境

RedHat 90 + MySQL 32358 MySQL資料庫路徑 varlibmysql MySQL設定檔 etcmycnf Master IP 1921680100 Slave IP 1921680200 請至下列網址下載最新MySQL 32358套件並利用rpm ndashUvh 更新 httpupdatesredhatcom9enosi386

圖 最新 MySQL 套件

測試架構圖

91

1921680100

1921680200Master Server

erveSlave S r

圖 測試架構圖

測試步驟

Master server 部份 Step1 確認 MasterSlave機器上所裝的 MySQL版本能進行

replication( 32329 or higher ) Step2 在 Master MySQL上開放一個帳號給 Slave mysql ndashu root ndashp mysqlgtGRANT FILE ON TO repl1921680200 IDENTIFIED BY lsquoabc123rsquo mysqlgtq 上面是 Master開放一個帳號 repl密碼 abc123給 IP1921680200有檔案處理

的權限 Step3 shutdown MySQL on the Master mysqladmin ndashu root ndashp shutdown Step4 備份 Master所有資料庫 tar ndashcvf tmpmysql-snapshottar varlibmysql 注意tar的時候MySQL是要在 stop情況下 在mysql (wwwmysqlcom) 網站的FAQ有不用shutdown的方法

92

Step5 在 master機器上修改etcmycnf 在[mysqld]區段內加入參數 log-bin server-id=這邊設定 server-id=1 sql-bin-update-same binlog-do-db=CRM只針對 CRM資料庫做紀錄 Step6 Restart MySQL on the master service mysqld start 此時因為有加入 log-bin 參數因此開始有 index產生了在varlibmysql目錄下

有index檔案紀錄資料庫的異動 log Slave server 部份 Step1 在 slave設定etcmycnf 在[mysqld]區段加入 master-host= master-user= master-password= master-port= server-id= 這邊設定 master-host=1921680100 master-user=repl master-password=abc123 master-port=3306 server-id=2 master-connect-retry=60預設重試間隔 60秒 replicate-do-db=CRM告訴 slave只做 CRM資料庫的更新 log-slave-updates Step2 將 master上的 mysql-snapshottar copy到 slave上 用 ftp傳到 slave的tmp Step3 解壓縮 Master資料庫至 Slave Server上 cd varlib tar xvf tmpmysql-snapshottar chown ndashR mysqlmysql mysql

93

chmod ndashR 770 mysql (視情況) Step4 Restart MySQL on the slave server 這時在varlibmysql目錄會出現 masterinfo此檔案紀錄了 Master MySQL server的資訊

狀況測試

One-way replication

1921680100

1921680200Master Server

erveSlave S r

圖 One-way replication架構圖 Step1 Master跟 Slave網路及服務都正常情況下由 Master端異動資料後 到 Slave端瀏覽資料檢視是否有進行 replication Step2 模擬 Slave Server 當機 可用在於 slave真的當機或是 Slave 不一定需要一直跟 master connect將Slave MySQL server shutdown由 Master端異動資料到 slave端瀏覽此時Slave應該沒有被 replication 更新然後再將 Slave端 MySQL server start起來

預設 60秒後 Slave會嘗試跟 Master要求進行 replication再去 Slave端檢視是否有更新資料

94

Step3 模擬 Master當機因為是設定 One-way replication一旦 Master Server Slave端沒有 Master的 source可以 download Two-way replication 基於 Master當機狀況於是發展雙向 Replication即 1921680100 ( Host A ) 1921680200 ( Host B )都分別擔任 MasterSlave身分

1921680100

1921680200er

Server B MasterSlave Server

Server A MasterSlave Serv

圖 Two-way replication架構圖 以下是針對兩台 MySQL伺服器進行雙向 Replication Step1觀念同單向 replication只是改成 Master也有 Slave身分 Slave也有Master的身分先分別在 Server AServer B 都去 grant一個進行 replication的身分 [A]mysqlgtGRANT FILE ON TO repl1921680200 IDENTIFIED BY lsquoabc123rsquo [B]mysqlgt GRANT FILE ON TO repl1921680100 IDENTIFIED BY lsquoabc123rsquo Step2做完單向 replication後stop Server Aserver B MySQL service此時 AB資料是一樣的

95

修改etcmycnf設定 範例 Server A [mysqld] datadir=varlibmysql socket=varlibmysqlmysqlsock server-id=1 log-bin sql-bin-update-same binlog-do-db=CRM master-host=1921680200 master-user=repl master-password=abc123 log-slave-updates master-connect-retry=60 replicate-do-db=CRM Server B [mysqld] datadir=varlibmysql socket=varlibmysqlmysqlsock server-id=2 log-bin sql-bin-update-same binlog-do-db=CRM master-host=1921680100 master-user=repl master-password=abc123 log-slave-updates master-connect-retry=60 replicate-do-db=CRM 分別 start Server AServer B MySQL後此時雙方都是 MasterSlave身分一旦哪一方資料異動就會通知對方來 replication-若 replication失效則必須將Server AServer B的masterinfo及index00x 都砍掉然後分別 restart MySQL server進行測試檢視成果 實務上通常如果需要做Two-way replication通常會搭配Virtual Server使用

96

在前端架設一台Virtual Server不過此部份不在此份SOP討論範圍內有興趣

的讀者可參考 httpwwwlinuxvirtualserverorg 網站

1921680100 1921680200

Host A MasterSlave Server

Host B MasterSlave Server

Virtual Host

圖 Virtual Server + Two-way replication 架構圖

97

圖 High Availability Linux Virtual Server架構圖

98

  • COSA-SOP-03-006
  • 第一章 簡介
    • 11適用對象 (Audience)
    • 12 MySQL本身
    • 13 MySQL 40版跟50版重大的改進功能
    • 14 各家資料庫軟體比較
      • 第二章 前置需求
      • 第三章 安裝
        • 31 MySQL安裝
        • 32 phpMyAdmin安裝
        • 33 升級及注意事項
          • 第四章 MySQL管理
            • 41 Webmin 管理介面
            • 42 phpMyAdmin 的操作介面
            • 43管理指令介紹
              • 431 利用mysqladmin設定root的密碼
                  • 第五章 實用範例
                    • 51 任務一Web Base客戶通訊錄
                    • 52 任務二Web Base群組軟體 ( twig )
                      • 第六章 維護及更新程序
                        • 61 日常維護
                        • 62 更新程序
                        • 63 備份重要檔案
                        • 64 離線備份與還原
                        • 65 線上備份與還原
                          • 第七章 問題與解答
                          • 第八章 參考資料
                          • 附錄一 SQL Command 介紹
                          • 附錄二Replication
Page 48: DataBase Server Standard Operation Procedureebooks.lib.ntu.edu.tw/1_file/oss/63/93doc4-5.pdf · 業務的公司帶來了不少壓力,譬如微軟,甲骨文 ... 外的錢用在第三方的資料庫產品上,譬如就可以不用再購買甲骨文公司

或是利用 mysql指令 [rootossc bluepage] mysql -u root -p1234 Welcome to the MySQL monitor Commands end with or g Your MySQL connection id is 1057 to server version 32354 Type help or h for help Type c to clear the buffer mysqlgt create database CONTACT Query OK 1 row affected (000 sec) mysqlgt show databases +----------+ | Database | +----------+ | CONTACT | | address | | hello | | mysql | | nuke | | test | +----------+ 6 rows in set (000 sec) mysqlgt exit

434 建立資料表

編寫 adresssql內容如下 -- Table structure for table address CREATE TABLE address ( id int(11) NOT NULL auto_increment name varchar(20) NOT NULL default tel varchar(15) NOT NULL default PRIMARY KEY (id) ) TYPE=MyISAM

48

-- Dumping data for table address INSERT INTO address VALUES (1林小明0800016888) INSERT INTO address VALUES (2黃大雄0800016888) INSERT INTO address VALUES (3劉小芬0800024365) 然後執行此 sql script mysql -u root -p1234 CONTACT lt addresssql 或是利 mysql command [rootossc bluepage] mysql -u root -p1234 Welcome to the MySQL monitor Commands end with or g Your MySQL connection id is 1090 to server version 32354 Type help or h for help Type c to clear the buffer mysqlgt use CONTACT Database changed Database changed mysqlgt CREATE TABLE address ( -gt id int(11) NOT NULL auto_increment -gt name varchar(20) NOT NULL default -gt tel varchar(15) NOT NULL default -gt PRIMARY KEY (id) -gt ) TYPE=MyISAM Query OK 0 rows affected (000 sec) mysqlgt INSERT INTO address VALUES (1林小明0800016888) Query OK 1 row affected (000 sec) mysqlgt INSERT INTO address VALUES (2黃大雄0800016888) Query OK 1 row affected (000 sec) mysqlgt INSERT INTO address VALUES (3劉小芬0800024365) Query OK 1 row affected (000 sec) mysqlgt exit Bye

49

第五章 實用範例

51 任務一Web Base客戶通訊錄

任職於開放科技公司的林小明前些日子在最符合成本效益的條件下快

速地完成公司網站的建置老闆因此對小明讚譽有加最近因為公司存放客戶資

料的 SQL Server主機屢遭病毒攻擊加上作業系統本身的問題當機次數頻繁

老闆希望能儘快把公司的客戶通訊錄程式移轉到較穩定的環境上因為此客戶通

訊錄程式最主要給內部人員使用所以介面美觀並不特別要求只求穩定且能快

速得到查詢結果老闆希望在短時間先看到程式的雛型並鍵入資料對其效率

及穩定性進行測試因為上次小明表現突出所以這次不可能的任務自然又落到

小明身上 小明想來想去既然要快速又穩定他而且又不希望所有人都得安裝 Client

程式於是小明決定)捨棄他的舊愛「Delphi+MS SQL」投向新歡「Apache + MySQL + PHP」利用此架構來設計一個簡單實用的Web Base客戶通訊錄程式

511 Web Base客戶通訊錄架構

此程式需要建立 CONTACT的資料庫並建立 adress Tables其結構如下表建立步驟請參考第三章 欄位名稱 資料型態 長度 說明 id INT (自動編號) 連絡人編號 name varchar文字 20 連絡人姓名 tel Varchar文字 15 連絡人電話 Web Base通訊錄共有下列幾個檔案功能如下表

檔案名稱 說明 Indexhtml Web Base通訊錄首頁 addphp 新增連絡人的 php程式 searchphp 尋找連絡人的 php程式 editphp 具有更新及刪除功能的 php程式

50

我們將這些檔案放至varwwwhtmlbluepage (預設無 bluepage目錄)

512 Web Base通訊錄測試

httpwwwopencombluepage 新增資料

圖 5-1 新增連絡人

圖 5-2 填入資料

51

圖 5-3 新增成功

搜尋及異動資料

圖 5-4 搜尋通訊錄

52

圖 5-5 編輯資料

圖 5-6 更新資料

513 程式內容及說明

lt-- 程式範例indexhtml--gt lthtmlgt ltheadgtlttitlegt通訊錄lttitlegtltheadgt ltbodygt ltcentergt

53

lth2gt通訊錄lth2gtlthrgt lta href=indexhtmlgt通訊錄ltagt | lta href=addphpgt新增連絡人ltagt | lta href=searchphpgt搜尋通訊錄ltagt ltcentergt ltbodygt lthtmlgt lt-- 程式範例addphp --gt lthtmlgt ltheadgtlttitlegt新增連絡人lttitlegtltheadgt ltbodygt ltcentergtlth2gt新增連絡人lth2gtltcentergtlthrgt lt 取得欄位資料 if (isset($_POST[Name]) ampamp isset($_POST[Tel]) ) $name = $_POST[Name] $tel = $_POST[Tel] 檢查是否有輸入欄位資料 if ($name = ampamp $tel = ) 建立 SQL字串 $sql = INSERT INTO address (name tel) values( $sql= $name $tel) 建立 MySQL 連結 $link = mysql_connect(localhostroot1234) 選擇資料庫 mysql_select_db(CONTACT) 執行 SQL指令 mysql_query($sql) mysql_close($link) echo ltfont color=redgt新增連絡人成功ltfontgtltbrgt gt ltform action=addphp method=postgt lttable border=0 width=300gt lttrgtlttdgt姓名 lttdgt

54

lttdgtltinput type=text name=Name size=20 maxlength=10gtlttdgtlttrgt lttrgtlttdgt電話 lttdgt lttdgtltinput type=text name=Tel size=20 maxlength=20gtlttdgtlttrgt lttrgtlttd colspan=2 align=centergt ltinput type=submit value=新增連絡人gtlttdgtlttrgt lttablegt ltformgt ltbrgtlta href=indexhtmlgt通訊錄ltagt | lta href=addphpgt新增連絡人ltagt | lta href=searchphpgt搜尋通訊錄ltagt ltbodygt lthtmlgt

lt-- 程式範例searchphp --gt lthtmlgt ltheadgtlttitlegt搜尋通訊錄lttitlegtltheadgt ltbodygt ltcentergtlth2gt搜尋通訊錄lth2gtlthrgt lt if (isset($_POST[Search])) 建立資料庫連結並選定資料庫 $link = mysql_connect(localhostroot1234) mysql_select_db(CONTACT) 建立基本的 SQL字串 $sql = SELECT FROM address 檢查是否輸入姓名 if (chop($_POST[Name]) = ) $name = name LIKE $_POST[Name] else $name = 檢查是否輸入電話號碼 if (chop($_POST[Tel]) = ) $tel = tel LIKE $_POST[Tel] else $tel =

55

if條件組合 SQL字串 if (chop($name) = ampamp chop($tel) = ) $sql= WHERE $name AND $tel elseif (chop($name) = ) 只有姓名 $sql = WHERE $name elseif (chop($tel) = ) 只有電話號碼 $sql = WHERE $tel $sql= ORDER BY name 最後加上排序 $result = mysql_query($sql) 取得欄位數 $total_fields = mysql_num_fields($result) echo lttable border=1gt echo lttrgtlttdgt編號lttdgtlttdgt姓名lttdgtlttdgt電話lttdgtlttd colspan=2gt功能選項lttdgtlttrgt 表格顯示查詢結果 while ($rows = mysql_fetch_array($result MYSQL_NUM)) echo lttrgt for ($i = 0 $i lt $total_fields $i++) echo lttdgt$rows[$i]lttdgt echo lttdgtlta href=editphpaction=editampid= echo $rows[0]gtltbgt編輯ltbgtlttdgt echo lttdgtlta href=editphpaction=delampid= echo $rows[0]gtltbgt刪除ltbgtlttdgt echo lttrgt echo lttablegtlthrgt mysql_free_result($result) mysql_close($link) gt ltcentergt ltform action=searchphp method=postgt lttable border=0 width=450gt lttrgtlttdgt搜尋姓名 lttdgt lttdgtltinput type=text name=Name size=10 maxlength=20gtlttdgtlttrgt lttrgtlttdgt搜尋電話 lttdgt lttdgtltinput type=text name=Tel

56

size=20 maxlength=20gtlttdgtlttrgt lttrgtlttd colspan=2 align=centergt ltinput type=submit name=Search value=搜尋gtlttdgtlttrgt lttablegt ltformgt ltbrgtlta href=indexhtmlgt通訊錄ltagt | lta href=addphpgt新增連絡人ltagt | lta href=searchphpgt搜尋通訊錄ltagt ltbodygt lthtmlgt

lt ob_start() gt lt-- 程式範例editphp --gt lthtmlgt ltheadgtlttitlegt編輯通訊錄lttitlegtltheadgt ltbodygt lt 取得 URL 參數 $id = $_GET[id] $action = $_GET[action] 建立資料庫連結 $link = mysql_connect(localhostroot1234) mysql_select_db(CONTACT) 選擇資料庫 執行的操作 switch ($action) case update 更新 取得欄位資料 $name = $_POST[Name] $tel = $_POST[Tel] $sql = UPDATE address SET name=$name tel=$tel WHERE id=$id mysql_query($sql) 執行 SQL指令 mysql_close($link) header(Location searchphp) 轉向到 serachphp break case del 刪除 $sql = DELETE FROM address WHERE id=$id

57

mysql_query($sql) 執行 SQL指令 mysql_close($link) header(Location searchphp) 轉向到 serachphp break case edit 編輯 $sql = SELECT FROM address WHERE id=$id $result = mysql_query($sql) 執行 SQL指令 $row = mysql_fetch_row($result) 取回記錄 $name = $row[1] 取得欄位 name $tel = $row[2] 取得欄位 tel mysql_close($link) 顯示編輯表單 gt ltcentergtlth2gt更新通訊錄lth2gtltcentergtlthrgt ltform action=editphpaction=updateampid=lt echo $id gt method=postgt lttable border=0 width=300gt lttrgtlttdgt姓名 lttdgt lttdgtltinput type=text name=Name size=20 maxlength=10 value=lt echo $name gtgtlttdgtlttrgt lttrgtlttdgt電話 lttdgt lttdgtltinput type=text name=Tel size=20 maxlength=20 value=lt echo $tel gtgtlttdgtlttrgt lttrgtlttd colspan=2 align=centergt ltinput type=submit value=更新連絡人gtlttdgtlttrgt lttablegt ltformgt ltbrgtlta href=indexhtmlgt通訊錄ltagt | lta href=addphpgt新增連絡人ltagt | lta href=searchphpgt搜尋通訊錄ltagt lt break gt ltbodygt lthtmlgt

58

52 任務二Web Base群組軟體 ( twig )

順利完成Web Base客戶通訊錄程式測試一段時間後「Apache + MySQL + PHP」架構的穩定與快速巳深得老闆與公司所有同事的認同隨著公司業績蒸

蒸日上人員組織編罝愈來愈龐大跨部門的會議愈來愈多業務員每日排滿拜

訪客戶的行程跟客戶的 Email的往來也愈來愈頻繁 愈來愈多部門的同事希望公司能建置一套群組軟體提供 web mail可讓業

務人員方便收發 mail還有連絡人議事日程待辦工作書簽等功能讓整個

公司運作及個人時間管理更有效率

老闆問小明對這些需求有什麼看法小明認為如果這些功能完全由程式部

門開發必定曠日費時而且耗費公司資源小明在網路尋找是否有提供這些功能

的Free Software皇天不負苦心人小明發現了TWIG (The Web Information Gateway) httptwigscrewdrivernet這個群組軟體它在 Web 上整合郵件新聞聯絡人議事日程工作序書簽等功能非常符合公司的需求 Step 1 下載 twig-277targz 下載網址 httptwigscrewdrivernetdownloadphp3

Step 2 解開 twig-277targz tar -xzvf twig-277targz

59

Step 3 執行安裝動作安裝到 varwwwhtmltwig 目錄 cd twig-277 twig-install varwwwhtmltwig

Step 4 建立 MySQL 資料庫(twig)及各資料表

cd setup mysql -u root -p1234 mysqlgt create database twig Query OK 1 row affected (001 sec) mysqlgt quit mysql -u root ndashp1234 twiglt twigtablemysql

Step 5 修改 configincphp3 參數設定 vi varwwwhtmltwigconfigconfigincphp3 $config[fromdomain] = opencom 網域 $config[language] = chinesebig5 中文訊息 $config[imap_port] = 143notls

60

Step 6 修改連結 MySQL 的帳號密碼 vi varwwwhtmltwigconfigdbconfigincphp3 $dbconfig[sqlusername] = root username $dbconfig[sqlpassword] = 1234 password

Step 7 其他設定檔

vi etchttpdconfhttpdconf 加入 AddType applicationx-httpd-php php3 在 DirectoryIndex最後加入 indexphp3 DirectoryIndex indexhtml indexhtmlvar indexphp3 在 AddDefaultCharset ISO-8859-1加上 AddDefaultCharset ISO-8859-1

vi etcphpini register_globals = On service httpd restart Step 8 sendmail 設定 vi etcmailsendmailcf在 264 行前面加上並重新啟動 sendmail「service snedmail restart」 262 SMTP daemon options 263 264 O DaemonPortOptions=Port=smtpAddr=127001 Name=MTA 265 266 SMTP client options 267 O ClientPortOptions=Family=inet Address=00

61

Step 9 檢查設定有無錯誤 http主機名稱twigtestphp3

62

Step 10 登入 twig ( http主機名稱twig)

63

第六章 維護及更新程序

61 日常維護

系統管理員最好定期以 root 身份登入看看信件在 RedHat Linux 中有一支 logwatch 程式會定時去分析 log file如果發現異常便會發信給 root除此之外筆者建議讀者平時就檢查 MySQL log file ( varlogmysqldlog)是否有異常情形

62 更新程序

讀者可至httprpmfindnet 尋找MySQL相關套件至於升級的相關步驟請參

考Linux OS SOP 第 54節

63 備份重要檔案

預設 MySQL 的 DB 檔案是存在 varlibmysql 內以 DB名稱為目錄目錄

內就是該 DB 的所有資料通常得定期備份還有 MySQL的設定檔 etcmycnf也別忘了一起備份

64 離線備份與還原

641 離線備份

預設 MySQL 的 DB 檔案是存在 varlibmysql 內以 DB 名稱為目錄目錄內

就是該 DB 的所有資料像 CRM 這個 DB就是存在 varlibmysqlCRM 內在備份前因為怕資料尚未完全寫入磁碟而且 MySQL 會 Lock 在使用的 DB 檔案所以應該是要先把 MySQL 先 Shutdown 一下整個備份的程序可以下像下面的指令去完成 cd varlibmysql

64

service mysqld stop tar cvfz CRM_db_20030905tgz CRM service mysqld start 對這樣就可以了 不過要注意的是怕 DB 內每個 Tables 間的資料有關關

聯性所以最好是把整個 DB 一次備起來單獨只備哪個 Tables 的檔案以後回存時怕會有資料關聯不一致的問題

642 離線還原

DB 發生錯誤而要回存時其實也不難先找出最近一次完整正常的備份先把現在錯誤的網頁或 DB 先更名或 tar 起來再把好的備份給解開回原來目錄位

置就行了需要注意的是 MySQL 服務最好也是要先停止回存完成後再啟動服務回存 DB 的整個程序可能像下面 cd varlibmysql service mysqldstop mv CRM CRM_OLD tar xvfz CRM_db_20030905tg service mysqld start

65 線上備份與還原

651 線上備份

使用像上面的檔案方式備份是個不錯的方法它最少可以保持該主機某個時間點的完整檔案備份但還是有一些問題需要考慮到有些主機就不只建立一個 DB 而已總不能為了備份某個 DB 而把整個 MySQL 服務停止備份檔案的方式回存在原主機上一定適用但假如 MySQL 版本升級或是在那天該網頁空間需遷機移機到別的主機時那就沒人敢保證備出來的資料檔可以用所以我們可以考慮另一種備份的方式是使用 MySQL 本身提供的功能 MySQL Data Dump指令是 mysqldump

65

使用 MySQL 的 Dump 功能可以把 DB 的結構資料或結構加資料 Dump 成文字檔 mysqldump 指令提供的彈性很大你可以選擇把整個 DB Dump 成一個檔或是每個 Table 為一個檔甚至是把結構檔和資料分開儲存都

可以 mysqladmin -uroot -p flush-logs mysqldump CRM -uroot -p --opt gt CRM_20030905sql (CRM 是 DB 名稱 opt 是一個使用完整 Dump 參數) 假如只是要單獨 Dump 某個 Table 時只要在上面的指令後轉出符號 gt 前加個 Table 名稱就可以如只要 phpbb2_users 這個 Table 的 Dump 時只要下 mysqldump CRM -uroot -p --opt CUSTOMER gt CRM_CUSTOMER_20030905sql

652 線上還原

若要回存整個資料庫只需將壓縮的備份檔還原成 Dump 的檔案再用下面的指令回存 mysql CRM -uroot -p lt CRM_20030905sql 這邊需注意的是若建立備份時是以--opt或--add-drop-table為參數時回存的 動作是先將舊的 Table 先刪除重建 Table 的結構後再把 Data 匯入所以回存後所有的資料會回到你當時備份那個時間點因此在回存資料時可以考慮把現有錯誤或不完整的 DB 先備份一份下來以備不時之需或是拿來比對錯誤的地

方在那裡當然你也可以把資料回存到另一個測試用的 DB 內只要把上面指令

的 DB 名稱改成你的測試用 DB 名稱即可 使用這種回存方式 MySQL 服務不需停止也不會動到其他正在使用的 DB 在一些提供 MySQL 服務的虛擬主機可用這種方式作你自己的 DB 備份及回存

66

另外假如你是系統重建或是移機時切需在新的 MySQL 內新建一個空白 DB 後才行作回存的工作你可以用下面的指令建立 mysql -uroot -p -e CREATE DATABASE CRM (上面的 CRM是你要新建的 DB 名稱) 另一種作法先用 mysql 指令進入 mysql client console 然後再用 CREATE DATABASE CRM 這樣就行了記得尾端要加個 符號該行指令才會執行

67

第七章 問題與解答

Q1RedHat 90預附的 MySQL到底有無支援 Transcation機制 Ans MySQL自 32334a之後的 MySQL-Max版本加入 InnoDB的資料庫類型透過

InnoDBMySQL同樣可以進行 COMMIT與 ROLLRACK的動作RedHat 90預附的 MySQL為 32354a-11巳支援 InnoDB的資料庫類型不過必須做以

下設定 1cp usrsharedocmysql-server-32354amy-mediumcnf to etcmycnf 2 vi etcmycnf 將以下設定前的拿掉 innodb_data_home_dir = varlibmysql innodb_data_file_path = ibdata110Mautoextend innodb_log_group_home_dir = varlibmysql innodb_log_arch_dir = varlibmysql 3service mysqld restart 如此一來各位在建立Table時便可指定Table Type為 innodb ( ex create table with type=innodb ) Q2如何解決 php+mysql 許功蓋等字變亂的問題 Ans 方法一 【確定 MySQL 預設的字元集】 1 打開 WinMySQLadmin 管理畫面(在視窗右下角狀態列紅綠燈圖示中按滑鼠

右鍵點選 Show me 選項) 2 點選管理畫面中 [Variables] 標籤選項其中 character_set變數就是您預設

字元集的變數其預設是 latin1 字元集(我們要將他改回 big5)而 chatacters_set 變數則是 MySQL 可以支援哪些字元集 【修改預設字元集變數 character_set 】 1 請點選管理畫面中 [myini Setup] 標籤選項設定 myini 2 按一下 [Pick-up and Edit myini values] 按鈕以便編輯目前的 myini 設定 3 在 [mysqld] 設定區塊底下新增一行 default-character-set = big5 變數設

68

定 4 新增一個 [client] 設定區塊並加入第三步驟的變數設定(游標往下移到空白處新增兩行 [client] 和 default-character-set=big5) 5 按一下畫面左下方 [Save Modification] 按鈕儲存設定 6 重新啟動 MySQL 或 Windows 方法二 Server端注意事項 phpini 中有關的設定為(預設值) Magic quotes for incoming GETPOSTCookie data magic_quotes_gpc = On Use Sybase-style magic quotes (escape with instead of ) magic_quotes_sybase = Off Client端注意事項 1中文資料送進 mysql 前請用 addslashes($str) 處理 2處理後送進 mysql 時請用 括起來並在參數後留一個空白如 $sql = UPDATE ezf_table set tablename=$tname tableend=$endtime table inguser=$tguser tableingid=$tguserid tableallnumber=$tnumber tableloca l=$tablelocal tableanyone=$tableopen tabletext=$ttext WHERE tableid=$t ableid tablename=$tname c 取出時請用 stripslashes($str) Q3MySQL root 密碼忘了該怎麼辦 Ans 1先停掉 mysql etcrcdinitdmysql stop 2以--skip-grant-table 的參數啟動 mysql safe_mysql --skip-grant-tableamp 3 更改 root 密碼 mysql mysql mysqlgt UPDATE user SET password=password(newpassword)

69

WHERE user=root mysqlgt FLUSH PRIVILEGES mysqlgt exit 4停掉 mysql再重跑 mysqladmin -uroot -p shutdown Enter password 輸入新設定的密碼 etcrcdinitdmysql start

Q4NULL值問題

Ans

NULL值的概念是造成 SQL的新手的混淆的普遍原因他們經常認為 NULL是和一個空字符串的一樣的東西不是這樣的例如下列語句是完全不同的

mysqlgt INSERT INTO my_table (phone) VALUES (NULL)

mysqlgt INSERT INTO my_table (phone) VALUES ()

兩個語句把值插入到 phone 列但是第一個插入一個 NULL值而第二個插入一個空字符串第一個的含義可以認為是ldquo電話號碼不知道而第二個則可意味

著ldquo她沒有電話

在 SQL中NULL值在于任何其他值甚至 NULL值比較時總是假的(FALSE)包含 NULL的一個表達式總是產生一個 NULL值除非在包含在表達式中的運算符和函數的文檔中指出在下列例子所有的列返回 NULL

mysqlgt SELECT NULL1+NULLCONCAT(InvisibleNULL)

如果你想要尋找值是 NULL的列你不能使用=NULL測試下列語句不返回任

何行因為對任何表達式expr = NULL是假的

mysqlgt SELECT FROM my_table WHERE phone = NULL

要想尋找 NULL值你必須使用 IS NULL測試下例顯示如何找出 NULL電話號碼和空的電話號碼

70

mysqlgt SELECT FROM my_table WHERE phone IS NULL mysqlgt SELECT FROM my_table WHERE phone =

在 MySQL中就像很多其他的 SQL服務器一樣你不能索引可以有 NULL值的列你必須聲明這樣的列為 NOT NULL而且你不能插入 NULL到索引的

列中

當用 LOAD DATA INFILE 讀取數據時空列用更新如果你想要在一個列中有

NULL值你應該在文本文件中使用N字面上的詞NULL也可以在某些情形下使用

當使用 ORDER BY時首先呈現 NULL值如果你用 DESC以降序排序NULL值最後顯示當使用 GROUP BY時所有的 NULL值被認為是相等的

為了有助于NULL的處理你能使用 IS NULL和 IS NOT NULL運算符和 IFNULL()函數

對某些列類型NULL值被特殊地處理如果你將 NULL插入表的第一個TIMESTAMP 列則插入當前的日期和時間如果你將 NULL插入一個AUTO_INCREMENT 列則插入順序中的下一個數字

Q5如何將圖片存放於 MySQL中

Ans

Step 1建立資料庫 test

Step 2 建立表格 binary_data

CREATE TABLE binary_data (

id INT(4) NOT NULL AUTO_INCREMENT PRIMARY KEY

description CHAR(50)

bin_data LONGBLOB

filename CHAR(50)

filesize CHAR(50)

filetype CHAR(50)

71

)

Step 3 利用 storephp 寫入圖片

storephp 程式碼

ltHTMLgt ltHEADgtltTITLEgtStore binary data into SQL DatabaseltTITLEgtltHEADgt ltBODYgt lt code that will be executed if the form has been submitted

if ($submit) mysql_connect(localhostrootYOUR_PASSWORD) mysql_select_db(test) $data=Base64_Encode(fread(fopen($form_data r) filesize($form_data))) $result=MYSQL_QUERY(INSERT INTO binary_data (descriptionbin_datafilenamefilesizefiletype) VALUES ($form_description$data$form_data_name$form_data_size$form_data_type)) $id= mysql_insert_id() print ltpgtThis file has the following Database ID ltbgt$idltbgt MYSQL_CLOSE() else else show the form to submit new data

gt

ltform method=post action=ltphp echo $PHP_SELF gt enctype=multipartform-datagt File Descriptionltbrgt ltinput type=text name=form_description size=40gt ltINPUT TYPE=hidden name=MAX_FILE_SIZE value=4000000gt ltbrgtFile to uploadstore in databaseltbrgt ltinput type=file name=form_data size=40gt ltpgtltinput type=submit name=submit value=submitgt ltformgt lt

72

gt ltBODYgt ltHTMLgt

Step 3 利用 storephp 取出圖片

getdataphp 程式碼

lt Syntax getdataphp3id=ltidgt if($id) you may have to modify login information for your database server MYSQL_CONNECT(localhostrootYOUR_PASSWORD) mysql_select_db(test) $query = select bin_datafiletype from binary_data where id=$id $result = MYSQL_QUERY($query) $data = Base64_Decode(MYSQL_RESULT($result0bin_data)) $type = MYSQL_RESULT($result0filetype) Header( Content-type $type) echo $data gt

Q6MySQL裝好之後啟動時或是執行 mysqladmin會出現如下訊息 Cant connect to local MYSQL Server through Socket varlibmysqlmysqlsock或是

Cant connect to local MYSQL Server through Socket tmpmysqldsock

Ans 可能有下列幾個原因

1這個 mysqldsock 不見了被某人刪除了或是被一些系統自動執行程式給刪

了例如有些 cron任務便會設定定期刪除 tmp 裡的東西所以呢您只能修改

cron 裡的設定讓它不要清除 mysqldsock 2在啟動時也可以改變 mysqldsock的位置您在啟動 MySQL的時候可以加入此參數usrlocalmysqlbinsafe_mysqld --user=mysql --socket=其他路

徑socket amp 同時得去設定環境變數 MYSQL_UNIX_PORT的值以指定新的

73

路徑 3若是您沒改 MYSQL_UNIX_PORT的值那麼您可以在執行指令的時候才打

例如mysqladmin --socket=其他路徑socket version Q7How to get the last insert id Ans CREATE TABLE product ( id INT(4) NOT NULL AUTO_INCREMENT PRIMARY KEY description VARCHAR(50) ) 1利用 SQL的話 mysqlgt insert into product(description) values(123) Query OK 1 row affected (000 sec) mysqlgt select last_insert_id() +------------------+ | last_insert_id() | +------------------+ +------------------+ 1 row in set (000 sec) ======================================== 2如果是 PHP的話 你可以用mysql_insert_id()取得該 id PHP example $result=MYSQL_QUERY(INSERT INTO product (description) VALUES ($description)) $id= mysql_insert_id() print This file has the following Database ID $id Q8如何將文字檔匯入資料庫 Ans $addr=homehttpdhtmlphpschool001txt $sql_select = load data infile $addr into table test fields terminated by t 解說 $sql_select = load data infile 文字檔名 into table 表格名 fields terminated by

74

t

(欄位分隔以 TAB鍵) 該文字檔須與資料表欄位格式相符 例如欄位有三個 則文字檔為每行一筆資料如下 欄 1資料ltTABgt欄 2資料ltTABgt欄 3資料 欄 1資料ltTABgt欄 2資料ltTABgt欄 3資料 欄 1資料ltTABgt欄 2資料ltTABgt欄 3資料 欄 1資料ltTABgtltTABgt欄 3資料

Q9如何撰寫 MySQL C API Ans Step 1利用文字編輯器撰寫以下程式碼 mysqlcc

include ltstdiohgt

include ltmysqlmysqlhgt

int main (int argc char argv[])

MYSQL mysql

MYSQL_RES res

MYSQL_ROW row

if (argc = 2)

fputs (Usage myc ltdatabasegt stderr)

return 1

if ((mysql_connect(ampmysqllocalhostrootYour_Password)))

fputs (Error connecting stderr)

abort()

75

if (mysql_select_db(ampmysqlargv[1]))

fputs (Error selecting database stderr)

abort()

if (mysql_query(ampmysqlSELECT FROM test_table))

fputs (Error processing query stderr)

abort()

if ((res = mysql_store_result(ampmysql)))

fputs (Error storing results stderr)

abort()

while((row = mysql_fetch_row(res)))

uint i = 0

for (i=0 i lt mysql_num_fields(res) i++)

printf(s row[i])

printf(n)

return 0

Step 2 Compile

gcc -Iusrlocalmysqlinclude -Lusrlocalmysqllibmysql mysqlcc ndashlm -lmysqlclient

(其中 include path與 library path取決於你的 MySQL安裝路徑)

76

如果執行時發生如下 error Run problemerror in loading shared libraries libmysqlclientsoX 將你的 MySQL library path(for exampleusrlocalmysqllibmysql) 加入etcldsoconf and run sbinldconfig -v Q9ASP + MySQL 範例程式 Ans Dim myconn As New ADODBConnection Dim myrs As New Recordset Dim mySQL As String Dim myrows As Long myconnOpen DSN=MyODBCsample mySQL = SELECT from user myrsSource = mySQL Set myrsActiveConnection = myconn myrsCursorLocation = adUseClient myrsOpen myrows = myrsRecordCount myrsClose myconnClose 可參考 httpwwwdwamnetmysqlasp_myodbcasp 有詳細的資料 Q10如何將 MySQL中的資料庫匯出成txt檔 Ans select from TableName into outfile textxls all result fields will seperate by tab

77

第八章 參考資料

英文部份 網址 1 httpwwwmysqlcom MySQL 網站有第一手有關 MySQL的資料 2 httpwwwmysqlcomdocenReplicationhtml 有關 MySQL Replication 的文件 3 httpwwwgeocitiescomsqlhomefaqstore_blobhtml 如何在 MySQL 存放 BLOB的資料 4httpwwwsapdborg 有關 SAP跟 MySQL相關合作的網站 書藉 1 Cooking with MySQL

Paul DuBois has selected sample recipes from the hundreds youll find in his book MySQL

Cookbook In this third and final series of excerpts showcasing these recipes learn how to

compute team standings how to calculate the differences between successive Dec 26

2002 2 Tips for Building Web Database Applications with PHP and MySQL by Hugh E Williams co-author of Web Database Applications with PHP amp MySQL 04042002

3 Managing and Using MySQL 2nd Edition By Tim King George Reese Randy Jay Yarger

4 MySQL Cookbook By Paul DuBoisPublisher OReillyPub Date October 2002

中文部份

78

1 httplinuxtncedutwtechdocmysqlmysql_docmanual_tochtml MySQL 中文手冊 2 httpchenshloxaedutwphpZ_1php PHP+MySQ程式研習設計網站 3 httplinuxtncedutwtechdocbanicdownhtml PHP 4 手冊 4 httpwwwtncedutwadmin_zonephp台南縣教育網網路中心有很多 Linux相關文件 5 httpdobtncedutw網站建置百寶箱有很多 PHP MySQL 相關範例程式 5 httpwwwdbworldcomtw資料庫專家電子雜誌介紹資料庫的重要觀念及名詞

79

附錄一 SQL Command 介紹

SQL (讀音ess-que-el) 是一種結構查詢語法SQL 使用於資料庫交流

傳遞相容於 ANSI (American National Standards Institute) 是一套標準的關聯

式資料庫語言 SQL 語言是執行更新或從資料系統獲取資料一般常見的關聯

資料庫系統都有提供 SQL 如 Oracle Sybase Microsoft SQL Server Access Ingres 等雖然大部份的資料庫都有提供 SQL 但也多提供了自已獨特的語

法造成了不相容的情形但標準基本的語法是相通的如Select Insert Update Delete Create and Drop 每一個系統都有支援

Table相關 Command

Create Table

關聯式資料庫包含有很多元件稱為資料表(tables) 把資料或訊息放在資

料表中 資料表是以不同的名稱做分別資料表由欄列所構成的二維陣列

欄包含欄位名資料型態 及其他可判斷的資訊列是由全部欄位構成一筆一

筆的紀錄 create table 語法用在建立一個新的資料表語法格式如下

create table tablename (column1 data type column2 data type column3 data type)

Format of create table if you were to use optional constraints

create table tablename (column1 data type [constraint] column2 data type [constraint] column3 data type [constraint]) [ ] = optional

Note You may have as many columns as youd like and the constraints are optional

80

Example

create table employee (first varchar(15) last varchar(20) age number(3) address varchar(30) city varchar(20) state varchar(20))

注意建立資料表格式要以括號把前後框住而最後以(分號)做結尾

欄位名不要超過 30個字元長而且不要使用 sql 的關鍵字(如 where select等)而在後面接是型態的宣告(如字串數字日期格式等)

資料型態是來描述欄位的方式如一個欄位Last_Name 是一個姓氏可以使用varchar (可變動長度字串) 資料型態

以下是幾個常見的資料庫型態 char(size) 固定長度字串最長為 255 位元 varchar(size) 變動長度字串最大字元數以 size 來指定 number(size) 數值格式可以是整數也可以是小數最大數字以 size 位數判

斷未指定小數位數由系統內定 date 日期格式 number(sized) 數值格式最大數字以 size 位數判斷d 為小數位數整數位

數為 size-d 位

有何限制當資料表被建立通常有一或數個欄位是要使用來做關聯的功

能 例如unique 限制(唯一值)兩筆記錄不可以相同的值 not null (非空值)該欄位一定要輸入資料不可是空的primary key (主鍵)是每一筆記錄識別的主要方式

Drop a table drop table 刪除資料表(其中的資料也會一併刪除)

drop table tablename

Example

81

drop table 和刪除全部資料是不同的刪除全部資料欄位名稱資訊等還會

存在但刪除資料表會把這一些也一併移除掉

如何查詢資料

Select 基本用法

select 語法是關連式資料庫最常用的部份可以取得你想要的資料這是一個

簡單的範例 select column1[column2etc] from tablename [where condition] [] = optional 在 select 之後所列欄位名則是要顯示的資料部份你可以一一列出各欄位

名或是以 (星號)來代表選擇全部的欄位 from 之後放資料表名稱 where 子句 (選項) 指定要過濾的條件符合者才會顯現 where 可使用的條件運算元 = 等於 gt 大於 lt 小於 gt= 大或等於 lt= 小或等於 ltgt 大相等 LIKE 相似 For example select first last city

82

from empinfo where first LIKE Er 以Er 為開頭的字串就符合要以單引號框住 Or you can specify select first last from empinfo where last LIKE s 最後一字為 S 就符合 select from empinfo where first = Eric 則表示 first name 一定要是 Eric 才可以 範例資料表empinfo 統計函數

MIN 傳回指定欄位最小值

MAX 傳回指定欄位最大值

SUM 傳回指定欄位總和

AVG 傳回指定欄位平均值

COUNT 傳回指定欄位的筆數

COUNT() 傳回資料庫中的總筆數

統計函數使用於資料表中的數值欄位配合 SELECT 語法使用 只用於總結特定單一欄位可以配合 GROUP BY 做篩選但也可以不使用 GROUP BY 語句For example

SELECT AVG(salary) FROM employee

83

傳回全部 salary 平均值

Another example

SELECT AVG(salary) FROM employee WHERE title = Programmer

傳回 salary 平均值條件為 employees 資料表中當 title 等於 Programmer

Example

SELECT Count() FROM employees

傳回 employees 資料表中紀錄總筆數

GROUP BY 語法 SELECT column1 SUM(column2) FROM list-of-tables GROUP BY column-list The GROUP BY 語句可以先以所列的欄位為條件分組排序在一起(可以多欄

位) example 要列出每一個 dept 中最高 salary 值 SELECT max(salary) dept FROM employee GROUP BY dept HAVING 語法

SELECT column1 SUM(column2) FROM list-of-tables GROUP BY column-list HAVING condition

HAVING 子句是 GROUP BY 的一部份用來過濾在 GROUP BY 所選出的資料功能如同 select 命令中 where 條件式一樣只是 HAVING 必需配合 GROUP BY 使用

我們以例子來說明我們要取得每一公司名及每一公司的薪水平均值輸入如下

84

SELECT dept avg(salary) FROM employee GROUP BY dept

但如果我們只列出薪資平均值超過 20000元的公司資料

SELECT dept avg(salary) FROM employee GROUP BY dept HAVING avg(salary) gt 20000

ORDER BY子句語法

SELECT column1 SUM(column2) FROM list-of-tables ORDER BY column-list [ASC | DESC]

[ ] =選項

ORDER BY是一個選項子句當你以排序方式來顯示資料(正向由小到大反向由大到小)以指定的欄位資料做排序

ASC = 正向- 預設值 DESC = 反向排序

For example

SELECT employee_id dept name age salary FROM employee_info WHERE dept = Sales ORDER BY salary

以上列出公司代號公司名銷售員人名年紀及薪資而條件是公司名為 Sales 顯示順序以薪資多少排序(由小到大為預設值)

如果要以多個欄位做排序要以逗號做分隔如下

SELECT employee_id dept name age salary FROM employee_info WHERE dept = Sales ORDER BY salary age DESC

85

結合條件及布林運算 SELECT column1 SUM(column2) FROM list-of-tables WHERE condition1 AND condition2 AND運算可以結兩個或以上的條件放在 WHERE子句中 兩者都要為真才

會顯示該筆記錄 OR 運算可以結兩個或以上敘述放在 WHERE子句中只要其中一個為直就

會顯示該筆記錄 For example SELECT employeeid firstname lastname title salary FROM employee_info WHERE salary gt= 5000000 AND title = Programmer 必需要薪資大於等於 50000而且職稱為 Programmer同時符合才會顯示該筆資料 以下以括號括住雖然不是必需的但如此比較容易讀 SELECT employeeid firstname lastname title salary FROM employee_info WHERE (salary gt= 5000000) AND (title = Programmer) 另外範例 SELECT firstname lastname title salary FROM employee_info WHERE (title = Sales) OR (title = Programmer) 條件為只要是 Sales 或 Programmer 職稱的就會被列出 IN and BETWEEN 子句

SELECT column1 SUM(column2) FROM list-of-tables WHERE column3 IN (list-of-values) SELECT column1 SUM(column2) FROM list-of-tables WHERE column3 BETWEEN value1 AND value2 IN 子句使用在列舉項目的使用上也就是分別測試是否符合所列的值 For example

86

SELECT employeeid lastname salary FROM employee_info WHERE lastname IN (Hernandez Jones Roberts Ruiz) 條件為姓氏(astname)要符合 Hernandez Jones Roberts or Ruiz 其中一個才會被傳回 IN運算元也可以使用 OR 的語法來取代如下結果相同 SELECT employeeid lastname salary FROM employee_info WHERE lastname = Hernandez OR lastname = Jones OR lastname = Roberts OR lastname = Ruiz 但使用 IN 句子比較短也比較易懂 你也可以使用 NOT IN 來去掉不要的記錄 BETWEEN 運算元使用在判斷是否存在兩個數值之間 For example SELECT employeeid age lastname salary FROM employee_info WHERE age BETWEEN 30 AND 40 傳回年紀 30歲到 40歲之間的資料(含 30及 40歲者) 相同的也可以使用以下語法來達到相同的結果 SELECT employeeid age lastname salary FROM employee_info WHERE age gt= 30 AND age lt= 40 你也可使用 NOT BETWEEN 來濾掉中間值的資料 數學運算 標準 ANSI SQL-92 提供以下運算

87

+ 加

- 減

餘數

餘數為除法後剩整數這不在標準的 ANSI SQL 中但大部份的資料庫都會支

援這運算元以下列出有用的函數雖不在 ANSI SQL-92 提供但一般資料庫

也會支援他們

ABS(x) 傳回 x 絕對值

SIGN(x) returns the sign of input x as -1 0 or 1 (negative zero or positive respectively)

MOD(xy) 餘數 - returns the integer remainder of x divided by y (同 xy)

FLOOR(x) 傳回小或等於 x 的最大整數值

CEILING(x) or CEIL(x)

傳回大或等於 x 的最小整數值

POWER(xy) x的 y 次方

ROUND(x) 把 x 四捨五入為整數

ROUND(xd) 四捨五入取到小數 d 位

SQRT(x) x 開平方

For example SELECT round(salary) firstname FROM employee_info 傳回薪資取到整數位

如何新增資料

insert 加入一筆新紀錄到資料表中 insert into tablename (first_columnlast_column) values (first_valuelast_value) [] = optional Example insert into employee

88

(first last age address city state) values (Luke Duke 45 2130 Boars Nest Hazard Co Georgia) Note 字串要以單引號住如string 數字框住也無妨 insert into 後面接資料表名稱再接以括號括住的欄位名在 values 後括號分別對映各欄位的值 以上的例子新增了一筆名(first) 為 Luke而住所(state) 為 Georgia 的資料

如何刪除資料

delete 可以刪除單筆或多筆紀錄 delete from tablename where columnname OPERATOR value [and|or column OPERATOR value] [ ] = optional Examples delete from employee Note 如果你沒有指定 where 子句那麼全部的紀錄都會被刪除 delete from employee where lastname = May delete from employee where firstname = Mike or firstname = Eric delete from 接著資料表名 再接著是條件式判斷沒有條件式則全部紀錄會

被刪除

如何更新資料

update 用來更新你所指定的記錄要和 WHERE 配合小心使用 語法 update tablename set columnname = newvalue[nextcolumn = newvalue2] where columnname OPERATOR value [and|or column OPERATOR value] [] = optional Examples

89

update phone_book set area_code = 623 where prefix = 979 update phone_book set last_name = Smith prefix=555 suffix=9292 where last_name = Jones update employee set age = age+1 where first_name=Mary and last_name=Williams

90

附錄二Replication

測試環境

RedHat 90 + MySQL 32358 MySQL資料庫路徑 varlibmysql MySQL設定檔 etcmycnf Master IP 1921680100 Slave IP 1921680200 請至下列網址下載最新MySQL 32358套件並利用rpm ndashUvh 更新 httpupdatesredhatcom9enosi386

圖 最新 MySQL 套件

測試架構圖

91

1921680100

1921680200Master Server

erveSlave S r

圖 測試架構圖

測試步驟

Master server 部份 Step1 確認 MasterSlave機器上所裝的 MySQL版本能進行

replication( 32329 or higher ) Step2 在 Master MySQL上開放一個帳號給 Slave mysql ndashu root ndashp mysqlgtGRANT FILE ON TO repl1921680200 IDENTIFIED BY lsquoabc123rsquo mysqlgtq 上面是 Master開放一個帳號 repl密碼 abc123給 IP1921680200有檔案處理

的權限 Step3 shutdown MySQL on the Master mysqladmin ndashu root ndashp shutdown Step4 備份 Master所有資料庫 tar ndashcvf tmpmysql-snapshottar varlibmysql 注意tar的時候MySQL是要在 stop情況下 在mysql (wwwmysqlcom) 網站的FAQ有不用shutdown的方法

92

Step5 在 master機器上修改etcmycnf 在[mysqld]區段內加入參數 log-bin server-id=這邊設定 server-id=1 sql-bin-update-same binlog-do-db=CRM只針對 CRM資料庫做紀錄 Step6 Restart MySQL on the master service mysqld start 此時因為有加入 log-bin 參數因此開始有 index產生了在varlibmysql目錄下

有index檔案紀錄資料庫的異動 log Slave server 部份 Step1 在 slave設定etcmycnf 在[mysqld]區段加入 master-host= master-user= master-password= master-port= server-id= 這邊設定 master-host=1921680100 master-user=repl master-password=abc123 master-port=3306 server-id=2 master-connect-retry=60預設重試間隔 60秒 replicate-do-db=CRM告訴 slave只做 CRM資料庫的更新 log-slave-updates Step2 將 master上的 mysql-snapshottar copy到 slave上 用 ftp傳到 slave的tmp Step3 解壓縮 Master資料庫至 Slave Server上 cd varlib tar xvf tmpmysql-snapshottar chown ndashR mysqlmysql mysql

93

chmod ndashR 770 mysql (視情況) Step4 Restart MySQL on the slave server 這時在varlibmysql目錄會出現 masterinfo此檔案紀錄了 Master MySQL server的資訊

狀況測試

One-way replication

1921680100

1921680200Master Server

erveSlave S r

圖 One-way replication架構圖 Step1 Master跟 Slave網路及服務都正常情況下由 Master端異動資料後 到 Slave端瀏覽資料檢視是否有進行 replication Step2 模擬 Slave Server 當機 可用在於 slave真的當機或是 Slave 不一定需要一直跟 master connect將Slave MySQL server shutdown由 Master端異動資料到 slave端瀏覽此時Slave應該沒有被 replication 更新然後再將 Slave端 MySQL server start起來

預設 60秒後 Slave會嘗試跟 Master要求進行 replication再去 Slave端檢視是否有更新資料

94

Step3 模擬 Master當機因為是設定 One-way replication一旦 Master Server Slave端沒有 Master的 source可以 download Two-way replication 基於 Master當機狀況於是發展雙向 Replication即 1921680100 ( Host A ) 1921680200 ( Host B )都分別擔任 MasterSlave身分

1921680100

1921680200er

Server B MasterSlave Server

Server A MasterSlave Serv

圖 Two-way replication架構圖 以下是針對兩台 MySQL伺服器進行雙向 Replication Step1觀念同單向 replication只是改成 Master也有 Slave身分 Slave也有Master的身分先分別在 Server AServer B 都去 grant一個進行 replication的身分 [A]mysqlgtGRANT FILE ON TO repl1921680200 IDENTIFIED BY lsquoabc123rsquo [B]mysqlgt GRANT FILE ON TO repl1921680100 IDENTIFIED BY lsquoabc123rsquo Step2做完單向 replication後stop Server Aserver B MySQL service此時 AB資料是一樣的

95

修改etcmycnf設定 範例 Server A [mysqld] datadir=varlibmysql socket=varlibmysqlmysqlsock server-id=1 log-bin sql-bin-update-same binlog-do-db=CRM master-host=1921680200 master-user=repl master-password=abc123 log-slave-updates master-connect-retry=60 replicate-do-db=CRM Server B [mysqld] datadir=varlibmysql socket=varlibmysqlmysqlsock server-id=2 log-bin sql-bin-update-same binlog-do-db=CRM master-host=1921680100 master-user=repl master-password=abc123 log-slave-updates master-connect-retry=60 replicate-do-db=CRM 分別 start Server AServer B MySQL後此時雙方都是 MasterSlave身分一旦哪一方資料異動就會通知對方來 replication-若 replication失效則必須將Server AServer B的masterinfo及index00x 都砍掉然後分別 restart MySQL server進行測試檢視成果 實務上通常如果需要做Two-way replication通常會搭配Virtual Server使用

96

在前端架設一台Virtual Server不過此部份不在此份SOP討論範圍內有興趣

的讀者可參考 httpwwwlinuxvirtualserverorg 網站

1921680100 1921680200

Host A MasterSlave Server

Host B MasterSlave Server

Virtual Host

圖 Virtual Server + Two-way replication 架構圖

97

圖 High Availability Linux Virtual Server架構圖

98

  • COSA-SOP-03-006
  • 第一章 簡介
    • 11適用對象 (Audience)
    • 12 MySQL本身
    • 13 MySQL 40版跟50版重大的改進功能
    • 14 各家資料庫軟體比較
      • 第二章 前置需求
      • 第三章 安裝
        • 31 MySQL安裝
        • 32 phpMyAdmin安裝
        • 33 升級及注意事項
          • 第四章 MySQL管理
            • 41 Webmin 管理介面
            • 42 phpMyAdmin 的操作介面
            • 43管理指令介紹
              • 431 利用mysqladmin設定root的密碼
                  • 第五章 實用範例
                    • 51 任務一Web Base客戶通訊錄
                    • 52 任務二Web Base群組軟體 ( twig )
                      • 第六章 維護及更新程序
                        • 61 日常維護
                        • 62 更新程序
                        • 63 備份重要檔案
                        • 64 離線備份與還原
                        • 65 線上備份與還原
                          • 第七章 問題與解答
                          • 第八章 參考資料
                          • 附錄一 SQL Command 介紹
                          • 附錄二Replication
Page 49: DataBase Server Standard Operation Procedureebooks.lib.ntu.edu.tw/1_file/oss/63/93doc4-5.pdf · 業務的公司帶來了不少壓力,譬如微軟,甲骨文 ... 外的錢用在第三方的資料庫產品上,譬如就可以不用再購買甲骨文公司

-- Dumping data for table address INSERT INTO address VALUES (1林小明0800016888) INSERT INTO address VALUES (2黃大雄0800016888) INSERT INTO address VALUES (3劉小芬0800024365) 然後執行此 sql script mysql -u root -p1234 CONTACT lt addresssql 或是利 mysql command [rootossc bluepage] mysql -u root -p1234 Welcome to the MySQL monitor Commands end with or g Your MySQL connection id is 1090 to server version 32354 Type help or h for help Type c to clear the buffer mysqlgt use CONTACT Database changed Database changed mysqlgt CREATE TABLE address ( -gt id int(11) NOT NULL auto_increment -gt name varchar(20) NOT NULL default -gt tel varchar(15) NOT NULL default -gt PRIMARY KEY (id) -gt ) TYPE=MyISAM Query OK 0 rows affected (000 sec) mysqlgt INSERT INTO address VALUES (1林小明0800016888) Query OK 1 row affected (000 sec) mysqlgt INSERT INTO address VALUES (2黃大雄0800016888) Query OK 1 row affected (000 sec) mysqlgt INSERT INTO address VALUES (3劉小芬0800024365) Query OK 1 row affected (000 sec) mysqlgt exit Bye

49

第五章 實用範例

51 任務一Web Base客戶通訊錄

任職於開放科技公司的林小明前些日子在最符合成本效益的條件下快

速地完成公司網站的建置老闆因此對小明讚譽有加最近因為公司存放客戶資

料的 SQL Server主機屢遭病毒攻擊加上作業系統本身的問題當機次數頻繁

老闆希望能儘快把公司的客戶通訊錄程式移轉到較穩定的環境上因為此客戶通

訊錄程式最主要給內部人員使用所以介面美觀並不特別要求只求穩定且能快

速得到查詢結果老闆希望在短時間先看到程式的雛型並鍵入資料對其效率

及穩定性進行測試因為上次小明表現突出所以這次不可能的任務自然又落到

小明身上 小明想來想去既然要快速又穩定他而且又不希望所有人都得安裝 Client

程式於是小明決定)捨棄他的舊愛「Delphi+MS SQL」投向新歡「Apache + MySQL + PHP」利用此架構來設計一個簡單實用的Web Base客戶通訊錄程式

511 Web Base客戶通訊錄架構

此程式需要建立 CONTACT的資料庫並建立 adress Tables其結構如下表建立步驟請參考第三章 欄位名稱 資料型態 長度 說明 id INT (自動編號) 連絡人編號 name varchar文字 20 連絡人姓名 tel Varchar文字 15 連絡人電話 Web Base通訊錄共有下列幾個檔案功能如下表

檔案名稱 說明 Indexhtml Web Base通訊錄首頁 addphp 新增連絡人的 php程式 searchphp 尋找連絡人的 php程式 editphp 具有更新及刪除功能的 php程式

50

我們將這些檔案放至varwwwhtmlbluepage (預設無 bluepage目錄)

512 Web Base通訊錄測試

httpwwwopencombluepage 新增資料

圖 5-1 新增連絡人

圖 5-2 填入資料

51

圖 5-3 新增成功

搜尋及異動資料

圖 5-4 搜尋通訊錄

52

圖 5-5 編輯資料

圖 5-6 更新資料

513 程式內容及說明

lt-- 程式範例indexhtml--gt lthtmlgt ltheadgtlttitlegt通訊錄lttitlegtltheadgt ltbodygt ltcentergt

53

lth2gt通訊錄lth2gtlthrgt lta href=indexhtmlgt通訊錄ltagt | lta href=addphpgt新增連絡人ltagt | lta href=searchphpgt搜尋通訊錄ltagt ltcentergt ltbodygt lthtmlgt lt-- 程式範例addphp --gt lthtmlgt ltheadgtlttitlegt新增連絡人lttitlegtltheadgt ltbodygt ltcentergtlth2gt新增連絡人lth2gtltcentergtlthrgt lt 取得欄位資料 if (isset($_POST[Name]) ampamp isset($_POST[Tel]) ) $name = $_POST[Name] $tel = $_POST[Tel] 檢查是否有輸入欄位資料 if ($name = ampamp $tel = ) 建立 SQL字串 $sql = INSERT INTO address (name tel) values( $sql= $name $tel) 建立 MySQL 連結 $link = mysql_connect(localhostroot1234) 選擇資料庫 mysql_select_db(CONTACT) 執行 SQL指令 mysql_query($sql) mysql_close($link) echo ltfont color=redgt新增連絡人成功ltfontgtltbrgt gt ltform action=addphp method=postgt lttable border=0 width=300gt lttrgtlttdgt姓名 lttdgt

54

lttdgtltinput type=text name=Name size=20 maxlength=10gtlttdgtlttrgt lttrgtlttdgt電話 lttdgt lttdgtltinput type=text name=Tel size=20 maxlength=20gtlttdgtlttrgt lttrgtlttd colspan=2 align=centergt ltinput type=submit value=新增連絡人gtlttdgtlttrgt lttablegt ltformgt ltbrgtlta href=indexhtmlgt通訊錄ltagt | lta href=addphpgt新增連絡人ltagt | lta href=searchphpgt搜尋通訊錄ltagt ltbodygt lthtmlgt

lt-- 程式範例searchphp --gt lthtmlgt ltheadgtlttitlegt搜尋通訊錄lttitlegtltheadgt ltbodygt ltcentergtlth2gt搜尋通訊錄lth2gtlthrgt lt if (isset($_POST[Search])) 建立資料庫連結並選定資料庫 $link = mysql_connect(localhostroot1234) mysql_select_db(CONTACT) 建立基本的 SQL字串 $sql = SELECT FROM address 檢查是否輸入姓名 if (chop($_POST[Name]) = ) $name = name LIKE $_POST[Name] else $name = 檢查是否輸入電話號碼 if (chop($_POST[Tel]) = ) $tel = tel LIKE $_POST[Tel] else $tel =

55

if條件組合 SQL字串 if (chop($name) = ampamp chop($tel) = ) $sql= WHERE $name AND $tel elseif (chop($name) = ) 只有姓名 $sql = WHERE $name elseif (chop($tel) = ) 只有電話號碼 $sql = WHERE $tel $sql= ORDER BY name 最後加上排序 $result = mysql_query($sql) 取得欄位數 $total_fields = mysql_num_fields($result) echo lttable border=1gt echo lttrgtlttdgt編號lttdgtlttdgt姓名lttdgtlttdgt電話lttdgtlttd colspan=2gt功能選項lttdgtlttrgt 表格顯示查詢結果 while ($rows = mysql_fetch_array($result MYSQL_NUM)) echo lttrgt for ($i = 0 $i lt $total_fields $i++) echo lttdgt$rows[$i]lttdgt echo lttdgtlta href=editphpaction=editampid= echo $rows[0]gtltbgt編輯ltbgtlttdgt echo lttdgtlta href=editphpaction=delampid= echo $rows[0]gtltbgt刪除ltbgtlttdgt echo lttrgt echo lttablegtlthrgt mysql_free_result($result) mysql_close($link) gt ltcentergt ltform action=searchphp method=postgt lttable border=0 width=450gt lttrgtlttdgt搜尋姓名 lttdgt lttdgtltinput type=text name=Name size=10 maxlength=20gtlttdgtlttrgt lttrgtlttdgt搜尋電話 lttdgt lttdgtltinput type=text name=Tel

56

size=20 maxlength=20gtlttdgtlttrgt lttrgtlttd colspan=2 align=centergt ltinput type=submit name=Search value=搜尋gtlttdgtlttrgt lttablegt ltformgt ltbrgtlta href=indexhtmlgt通訊錄ltagt | lta href=addphpgt新增連絡人ltagt | lta href=searchphpgt搜尋通訊錄ltagt ltbodygt lthtmlgt

lt ob_start() gt lt-- 程式範例editphp --gt lthtmlgt ltheadgtlttitlegt編輯通訊錄lttitlegtltheadgt ltbodygt lt 取得 URL 參數 $id = $_GET[id] $action = $_GET[action] 建立資料庫連結 $link = mysql_connect(localhostroot1234) mysql_select_db(CONTACT) 選擇資料庫 執行的操作 switch ($action) case update 更新 取得欄位資料 $name = $_POST[Name] $tel = $_POST[Tel] $sql = UPDATE address SET name=$name tel=$tel WHERE id=$id mysql_query($sql) 執行 SQL指令 mysql_close($link) header(Location searchphp) 轉向到 serachphp break case del 刪除 $sql = DELETE FROM address WHERE id=$id

57

mysql_query($sql) 執行 SQL指令 mysql_close($link) header(Location searchphp) 轉向到 serachphp break case edit 編輯 $sql = SELECT FROM address WHERE id=$id $result = mysql_query($sql) 執行 SQL指令 $row = mysql_fetch_row($result) 取回記錄 $name = $row[1] 取得欄位 name $tel = $row[2] 取得欄位 tel mysql_close($link) 顯示編輯表單 gt ltcentergtlth2gt更新通訊錄lth2gtltcentergtlthrgt ltform action=editphpaction=updateampid=lt echo $id gt method=postgt lttable border=0 width=300gt lttrgtlttdgt姓名 lttdgt lttdgtltinput type=text name=Name size=20 maxlength=10 value=lt echo $name gtgtlttdgtlttrgt lttrgtlttdgt電話 lttdgt lttdgtltinput type=text name=Tel size=20 maxlength=20 value=lt echo $tel gtgtlttdgtlttrgt lttrgtlttd colspan=2 align=centergt ltinput type=submit value=更新連絡人gtlttdgtlttrgt lttablegt ltformgt ltbrgtlta href=indexhtmlgt通訊錄ltagt | lta href=addphpgt新增連絡人ltagt | lta href=searchphpgt搜尋通訊錄ltagt lt break gt ltbodygt lthtmlgt

58

52 任務二Web Base群組軟體 ( twig )

順利完成Web Base客戶通訊錄程式測試一段時間後「Apache + MySQL + PHP」架構的穩定與快速巳深得老闆與公司所有同事的認同隨著公司業績蒸

蒸日上人員組織編罝愈來愈龐大跨部門的會議愈來愈多業務員每日排滿拜

訪客戶的行程跟客戶的 Email的往來也愈來愈頻繁 愈來愈多部門的同事希望公司能建置一套群組軟體提供 web mail可讓業

務人員方便收發 mail還有連絡人議事日程待辦工作書簽等功能讓整個

公司運作及個人時間管理更有效率

老闆問小明對這些需求有什麼看法小明認為如果這些功能完全由程式部

門開發必定曠日費時而且耗費公司資源小明在網路尋找是否有提供這些功能

的Free Software皇天不負苦心人小明發現了TWIG (The Web Information Gateway) httptwigscrewdrivernet這個群組軟體它在 Web 上整合郵件新聞聯絡人議事日程工作序書簽等功能非常符合公司的需求 Step 1 下載 twig-277targz 下載網址 httptwigscrewdrivernetdownloadphp3

Step 2 解開 twig-277targz tar -xzvf twig-277targz

59

Step 3 執行安裝動作安裝到 varwwwhtmltwig 目錄 cd twig-277 twig-install varwwwhtmltwig

Step 4 建立 MySQL 資料庫(twig)及各資料表

cd setup mysql -u root -p1234 mysqlgt create database twig Query OK 1 row affected (001 sec) mysqlgt quit mysql -u root ndashp1234 twiglt twigtablemysql

Step 5 修改 configincphp3 參數設定 vi varwwwhtmltwigconfigconfigincphp3 $config[fromdomain] = opencom 網域 $config[language] = chinesebig5 中文訊息 $config[imap_port] = 143notls

60

Step 6 修改連結 MySQL 的帳號密碼 vi varwwwhtmltwigconfigdbconfigincphp3 $dbconfig[sqlusername] = root username $dbconfig[sqlpassword] = 1234 password

Step 7 其他設定檔

vi etchttpdconfhttpdconf 加入 AddType applicationx-httpd-php php3 在 DirectoryIndex最後加入 indexphp3 DirectoryIndex indexhtml indexhtmlvar indexphp3 在 AddDefaultCharset ISO-8859-1加上 AddDefaultCharset ISO-8859-1

vi etcphpini register_globals = On service httpd restart Step 8 sendmail 設定 vi etcmailsendmailcf在 264 行前面加上並重新啟動 sendmail「service snedmail restart」 262 SMTP daemon options 263 264 O DaemonPortOptions=Port=smtpAddr=127001 Name=MTA 265 266 SMTP client options 267 O ClientPortOptions=Family=inet Address=00

61

Step 9 檢查設定有無錯誤 http主機名稱twigtestphp3

62

Step 10 登入 twig ( http主機名稱twig)

63

第六章 維護及更新程序

61 日常維護

系統管理員最好定期以 root 身份登入看看信件在 RedHat Linux 中有一支 logwatch 程式會定時去分析 log file如果發現異常便會發信給 root除此之外筆者建議讀者平時就檢查 MySQL log file ( varlogmysqldlog)是否有異常情形

62 更新程序

讀者可至httprpmfindnet 尋找MySQL相關套件至於升級的相關步驟請參

考Linux OS SOP 第 54節

63 備份重要檔案

預設 MySQL 的 DB 檔案是存在 varlibmysql 內以 DB名稱為目錄目錄

內就是該 DB 的所有資料通常得定期備份還有 MySQL的設定檔 etcmycnf也別忘了一起備份

64 離線備份與還原

641 離線備份

預設 MySQL 的 DB 檔案是存在 varlibmysql 內以 DB 名稱為目錄目錄內

就是該 DB 的所有資料像 CRM 這個 DB就是存在 varlibmysqlCRM 內在備份前因為怕資料尚未完全寫入磁碟而且 MySQL 會 Lock 在使用的 DB 檔案所以應該是要先把 MySQL 先 Shutdown 一下整個備份的程序可以下像下面的指令去完成 cd varlibmysql

64

service mysqld stop tar cvfz CRM_db_20030905tgz CRM service mysqld start 對這樣就可以了 不過要注意的是怕 DB 內每個 Tables 間的資料有關關

聯性所以最好是把整個 DB 一次備起來單獨只備哪個 Tables 的檔案以後回存時怕會有資料關聯不一致的問題

642 離線還原

DB 發生錯誤而要回存時其實也不難先找出最近一次完整正常的備份先把現在錯誤的網頁或 DB 先更名或 tar 起來再把好的備份給解開回原來目錄位

置就行了需要注意的是 MySQL 服務最好也是要先停止回存完成後再啟動服務回存 DB 的整個程序可能像下面 cd varlibmysql service mysqldstop mv CRM CRM_OLD tar xvfz CRM_db_20030905tg service mysqld start

65 線上備份與還原

651 線上備份

使用像上面的檔案方式備份是個不錯的方法它最少可以保持該主機某個時間點的完整檔案備份但還是有一些問題需要考慮到有些主機就不只建立一個 DB 而已總不能為了備份某個 DB 而把整個 MySQL 服務停止備份檔案的方式回存在原主機上一定適用但假如 MySQL 版本升級或是在那天該網頁空間需遷機移機到別的主機時那就沒人敢保證備出來的資料檔可以用所以我們可以考慮另一種備份的方式是使用 MySQL 本身提供的功能 MySQL Data Dump指令是 mysqldump

65

使用 MySQL 的 Dump 功能可以把 DB 的結構資料或結構加資料 Dump 成文字檔 mysqldump 指令提供的彈性很大你可以選擇把整個 DB Dump 成一個檔或是每個 Table 為一個檔甚至是把結構檔和資料分開儲存都

可以 mysqladmin -uroot -p flush-logs mysqldump CRM -uroot -p --opt gt CRM_20030905sql (CRM 是 DB 名稱 opt 是一個使用完整 Dump 參數) 假如只是要單獨 Dump 某個 Table 時只要在上面的指令後轉出符號 gt 前加個 Table 名稱就可以如只要 phpbb2_users 這個 Table 的 Dump 時只要下 mysqldump CRM -uroot -p --opt CUSTOMER gt CRM_CUSTOMER_20030905sql

652 線上還原

若要回存整個資料庫只需將壓縮的備份檔還原成 Dump 的檔案再用下面的指令回存 mysql CRM -uroot -p lt CRM_20030905sql 這邊需注意的是若建立備份時是以--opt或--add-drop-table為參數時回存的 動作是先將舊的 Table 先刪除重建 Table 的結構後再把 Data 匯入所以回存後所有的資料會回到你當時備份那個時間點因此在回存資料時可以考慮把現有錯誤或不完整的 DB 先備份一份下來以備不時之需或是拿來比對錯誤的地

方在那裡當然你也可以把資料回存到另一個測試用的 DB 內只要把上面指令

的 DB 名稱改成你的測試用 DB 名稱即可 使用這種回存方式 MySQL 服務不需停止也不會動到其他正在使用的 DB 在一些提供 MySQL 服務的虛擬主機可用這種方式作你自己的 DB 備份及回存

66

另外假如你是系統重建或是移機時切需在新的 MySQL 內新建一個空白 DB 後才行作回存的工作你可以用下面的指令建立 mysql -uroot -p -e CREATE DATABASE CRM (上面的 CRM是你要新建的 DB 名稱) 另一種作法先用 mysql 指令進入 mysql client console 然後再用 CREATE DATABASE CRM 這樣就行了記得尾端要加個 符號該行指令才會執行

67

第七章 問題與解答

Q1RedHat 90預附的 MySQL到底有無支援 Transcation機制 Ans MySQL自 32334a之後的 MySQL-Max版本加入 InnoDB的資料庫類型透過

InnoDBMySQL同樣可以進行 COMMIT與 ROLLRACK的動作RedHat 90預附的 MySQL為 32354a-11巳支援 InnoDB的資料庫類型不過必須做以

下設定 1cp usrsharedocmysql-server-32354amy-mediumcnf to etcmycnf 2 vi etcmycnf 將以下設定前的拿掉 innodb_data_home_dir = varlibmysql innodb_data_file_path = ibdata110Mautoextend innodb_log_group_home_dir = varlibmysql innodb_log_arch_dir = varlibmysql 3service mysqld restart 如此一來各位在建立Table時便可指定Table Type為 innodb ( ex create table with type=innodb ) Q2如何解決 php+mysql 許功蓋等字變亂的問題 Ans 方法一 【確定 MySQL 預設的字元集】 1 打開 WinMySQLadmin 管理畫面(在視窗右下角狀態列紅綠燈圖示中按滑鼠

右鍵點選 Show me 選項) 2 點選管理畫面中 [Variables] 標籤選項其中 character_set變數就是您預設

字元集的變數其預設是 latin1 字元集(我們要將他改回 big5)而 chatacters_set 變數則是 MySQL 可以支援哪些字元集 【修改預設字元集變數 character_set 】 1 請點選管理畫面中 [myini Setup] 標籤選項設定 myini 2 按一下 [Pick-up and Edit myini values] 按鈕以便編輯目前的 myini 設定 3 在 [mysqld] 設定區塊底下新增一行 default-character-set = big5 變數設

68

定 4 新增一個 [client] 設定區塊並加入第三步驟的變數設定(游標往下移到空白處新增兩行 [client] 和 default-character-set=big5) 5 按一下畫面左下方 [Save Modification] 按鈕儲存設定 6 重新啟動 MySQL 或 Windows 方法二 Server端注意事項 phpini 中有關的設定為(預設值) Magic quotes for incoming GETPOSTCookie data magic_quotes_gpc = On Use Sybase-style magic quotes (escape with instead of ) magic_quotes_sybase = Off Client端注意事項 1中文資料送進 mysql 前請用 addslashes($str) 處理 2處理後送進 mysql 時請用 括起來並在參數後留一個空白如 $sql = UPDATE ezf_table set tablename=$tname tableend=$endtime table inguser=$tguser tableingid=$tguserid tableallnumber=$tnumber tableloca l=$tablelocal tableanyone=$tableopen tabletext=$ttext WHERE tableid=$t ableid tablename=$tname c 取出時請用 stripslashes($str) Q3MySQL root 密碼忘了該怎麼辦 Ans 1先停掉 mysql etcrcdinitdmysql stop 2以--skip-grant-table 的參數啟動 mysql safe_mysql --skip-grant-tableamp 3 更改 root 密碼 mysql mysql mysqlgt UPDATE user SET password=password(newpassword)

69

WHERE user=root mysqlgt FLUSH PRIVILEGES mysqlgt exit 4停掉 mysql再重跑 mysqladmin -uroot -p shutdown Enter password 輸入新設定的密碼 etcrcdinitdmysql start

Q4NULL值問題

Ans

NULL值的概念是造成 SQL的新手的混淆的普遍原因他們經常認為 NULL是和一個空字符串的一樣的東西不是這樣的例如下列語句是完全不同的

mysqlgt INSERT INTO my_table (phone) VALUES (NULL)

mysqlgt INSERT INTO my_table (phone) VALUES ()

兩個語句把值插入到 phone 列但是第一個插入一個 NULL值而第二個插入一個空字符串第一個的含義可以認為是ldquo電話號碼不知道而第二個則可意味

著ldquo她沒有電話

在 SQL中NULL值在于任何其他值甚至 NULL值比較時總是假的(FALSE)包含 NULL的一個表達式總是產生一個 NULL值除非在包含在表達式中的運算符和函數的文檔中指出在下列例子所有的列返回 NULL

mysqlgt SELECT NULL1+NULLCONCAT(InvisibleNULL)

如果你想要尋找值是 NULL的列你不能使用=NULL測試下列語句不返回任

何行因為對任何表達式expr = NULL是假的

mysqlgt SELECT FROM my_table WHERE phone = NULL

要想尋找 NULL值你必須使用 IS NULL測試下例顯示如何找出 NULL電話號碼和空的電話號碼

70

mysqlgt SELECT FROM my_table WHERE phone IS NULL mysqlgt SELECT FROM my_table WHERE phone =

在 MySQL中就像很多其他的 SQL服務器一樣你不能索引可以有 NULL值的列你必須聲明這樣的列為 NOT NULL而且你不能插入 NULL到索引的

列中

當用 LOAD DATA INFILE 讀取數據時空列用更新如果你想要在一個列中有

NULL值你應該在文本文件中使用N字面上的詞NULL也可以在某些情形下使用

當使用 ORDER BY時首先呈現 NULL值如果你用 DESC以降序排序NULL值最後顯示當使用 GROUP BY時所有的 NULL值被認為是相等的

為了有助于NULL的處理你能使用 IS NULL和 IS NOT NULL運算符和 IFNULL()函數

對某些列類型NULL值被特殊地處理如果你將 NULL插入表的第一個TIMESTAMP 列則插入當前的日期和時間如果你將 NULL插入一個AUTO_INCREMENT 列則插入順序中的下一個數字

Q5如何將圖片存放於 MySQL中

Ans

Step 1建立資料庫 test

Step 2 建立表格 binary_data

CREATE TABLE binary_data (

id INT(4) NOT NULL AUTO_INCREMENT PRIMARY KEY

description CHAR(50)

bin_data LONGBLOB

filename CHAR(50)

filesize CHAR(50)

filetype CHAR(50)

71

)

Step 3 利用 storephp 寫入圖片

storephp 程式碼

ltHTMLgt ltHEADgtltTITLEgtStore binary data into SQL DatabaseltTITLEgtltHEADgt ltBODYgt lt code that will be executed if the form has been submitted

if ($submit) mysql_connect(localhostrootYOUR_PASSWORD) mysql_select_db(test) $data=Base64_Encode(fread(fopen($form_data r) filesize($form_data))) $result=MYSQL_QUERY(INSERT INTO binary_data (descriptionbin_datafilenamefilesizefiletype) VALUES ($form_description$data$form_data_name$form_data_size$form_data_type)) $id= mysql_insert_id() print ltpgtThis file has the following Database ID ltbgt$idltbgt MYSQL_CLOSE() else else show the form to submit new data

gt

ltform method=post action=ltphp echo $PHP_SELF gt enctype=multipartform-datagt File Descriptionltbrgt ltinput type=text name=form_description size=40gt ltINPUT TYPE=hidden name=MAX_FILE_SIZE value=4000000gt ltbrgtFile to uploadstore in databaseltbrgt ltinput type=file name=form_data size=40gt ltpgtltinput type=submit name=submit value=submitgt ltformgt lt

72

gt ltBODYgt ltHTMLgt

Step 3 利用 storephp 取出圖片

getdataphp 程式碼

lt Syntax getdataphp3id=ltidgt if($id) you may have to modify login information for your database server MYSQL_CONNECT(localhostrootYOUR_PASSWORD) mysql_select_db(test) $query = select bin_datafiletype from binary_data where id=$id $result = MYSQL_QUERY($query) $data = Base64_Decode(MYSQL_RESULT($result0bin_data)) $type = MYSQL_RESULT($result0filetype) Header( Content-type $type) echo $data gt

Q6MySQL裝好之後啟動時或是執行 mysqladmin會出現如下訊息 Cant connect to local MYSQL Server through Socket varlibmysqlmysqlsock或是

Cant connect to local MYSQL Server through Socket tmpmysqldsock

Ans 可能有下列幾個原因

1這個 mysqldsock 不見了被某人刪除了或是被一些系統自動執行程式給刪

了例如有些 cron任務便會設定定期刪除 tmp 裡的東西所以呢您只能修改

cron 裡的設定讓它不要清除 mysqldsock 2在啟動時也可以改變 mysqldsock的位置您在啟動 MySQL的時候可以加入此參數usrlocalmysqlbinsafe_mysqld --user=mysql --socket=其他路

徑socket amp 同時得去設定環境變數 MYSQL_UNIX_PORT的值以指定新的

73

路徑 3若是您沒改 MYSQL_UNIX_PORT的值那麼您可以在執行指令的時候才打

例如mysqladmin --socket=其他路徑socket version Q7How to get the last insert id Ans CREATE TABLE product ( id INT(4) NOT NULL AUTO_INCREMENT PRIMARY KEY description VARCHAR(50) ) 1利用 SQL的話 mysqlgt insert into product(description) values(123) Query OK 1 row affected (000 sec) mysqlgt select last_insert_id() +------------------+ | last_insert_id() | +------------------+ +------------------+ 1 row in set (000 sec) ======================================== 2如果是 PHP的話 你可以用mysql_insert_id()取得該 id PHP example $result=MYSQL_QUERY(INSERT INTO product (description) VALUES ($description)) $id= mysql_insert_id() print This file has the following Database ID $id Q8如何將文字檔匯入資料庫 Ans $addr=homehttpdhtmlphpschool001txt $sql_select = load data infile $addr into table test fields terminated by t 解說 $sql_select = load data infile 文字檔名 into table 表格名 fields terminated by

74

t

(欄位分隔以 TAB鍵) 該文字檔須與資料表欄位格式相符 例如欄位有三個 則文字檔為每行一筆資料如下 欄 1資料ltTABgt欄 2資料ltTABgt欄 3資料 欄 1資料ltTABgt欄 2資料ltTABgt欄 3資料 欄 1資料ltTABgt欄 2資料ltTABgt欄 3資料 欄 1資料ltTABgtltTABgt欄 3資料

Q9如何撰寫 MySQL C API Ans Step 1利用文字編輯器撰寫以下程式碼 mysqlcc

include ltstdiohgt

include ltmysqlmysqlhgt

int main (int argc char argv[])

MYSQL mysql

MYSQL_RES res

MYSQL_ROW row

if (argc = 2)

fputs (Usage myc ltdatabasegt stderr)

return 1

if ((mysql_connect(ampmysqllocalhostrootYour_Password)))

fputs (Error connecting stderr)

abort()

75

if (mysql_select_db(ampmysqlargv[1]))

fputs (Error selecting database stderr)

abort()

if (mysql_query(ampmysqlSELECT FROM test_table))

fputs (Error processing query stderr)

abort()

if ((res = mysql_store_result(ampmysql)))

fputs (Error storing results stderr)

abort()

while((row = mysql_fetch_row(res)))

uint i = 0

for (i=0 i lt mysql_num_fields(res) i++)

printf(s row[i])

printf(n)

return 0

Step 2 Compile

gcc -Iusrlocalmysqlinclude -Lusrlocalmysqllibmysql mysqlcc ndashlm -lmysqlclient

(其中 include path與 library path取決於你的 MySQL安裝路徑)

76

如果執行時發生如下 error Run problemerror in loading shared libraries libmysqlclientsoX 將你的 MySQL library path(for exampleusrlocalmysqllibmysql) 加入etcldsoconf and run sbinldconfig -v Q9ASP + MySQL 範例程式 Ans Dim myconn As New ADODBConnection Dim myrs As New Recordset Dim mySQL As String Dim myrows As Long myconnOpen DSN=MyODBCsample mySQL = SELECT from user myrsSource = mySQL Set myrsActiveConnection = myconn myrsCursorLocation = adUseClient myrsOpen myrows = myrsRecordCount myrsClose myconnClose 可參考 httpwwwdwamnetmysqlasp_myodbcasp 有詳細的資料 Q10如何將 MySQL中的資料庫匯出成txt檔 Ans select from TableName into outfile textxls all result fields will seperate by tab

77

第八章 參考資料

英文部份 網址 1 httpwwwmysqlcom MySQL 網站有第一手有關 MySQL的資料 2 httpwwwmysqlcomdocenReplicationhtml 有關 MySQL Replication 的文件 3 httpwwwgeocitiescomsqlhomefaqstore_blobhtml 如何在 MySQL 存放 BLOB的資料 4httpwwwsapdborg 有關 SAP跟 MySQL相關合作的網站 書藉 1 Cooking with MySQL

Paul DuBois has selected sample recipes from the hundreds youll find in his book MySQL

Cookbook In this third and final series of excerpts showcasing these recipes learn how to

compute team standings how to calculate the differences between successive Dec 26

2002 2 Tips for Building Web Database Applications with PHP and MySQL by Hugh E Williams co-author of Web Database Applications with PHP amp MySQL 04042002

3 Managing and Using MySQL 2nd Edition By Tim King George Reese Randy Jay Yarger

4 MySQL Cookbook By Paul DuBoisPublisher OReillyPub Date October 2002

中文部份

78

1 httplinuxtncedutwtechdocmysqlmysql_docmanual_tochtml MySQL 中文手冊 2 httpchenshloxaedutwphpZ_1php PHP+MySQ程式研習設計網站 3 httplinuxtncedutwtechdocbanicdownhtml PHP 4 手冊 4 httpwwwtncedutwadmin_zonephp台南縣教育網網路中心有很多 Linux相關文件 5 httpdobtncedutw網站建置百寶箱有很多 PHP MySQL 相關範例程式 5 httpwwwdbworldcomtw資料庫專家電子雜誌介紹資料庫的重要觀念及名詞

79

附錄一 SQL Command 介紹

SQL (讀音ess-que-el) 是一種結構查詢語法SQL 使用於資料庫交流

傳遞相容於 ANSI (American National Standards Institute) 是一套標準的關聯

式資料庫語言 SQL 語言是執行更新或從資料系統獲取資料一般常見的關聯

資料庫系統都有提供 SQL 如 Oracle Sybase Microsoft SQL Server Access Ingres 等雖然大部份的資料庫都有提供 SQL 但也多提供了自已獨特的語

法造成了不相容的情形但標準基本的語法是相通的如Select Insert Update Delete Create and Drop 每一個系統都有支援

Table相關 Command

Create Table

關聯式資料庫包含有很多元件稱為資料表(tables) 把資料或訊息放在資

料表中 資料表是以不同的名稱做分別資料表由欄列所構成的二維陣列

欄包含欄位名資料型態 及其他可判斷的資訊列是由全部欄位構成一筆一

筆的紀錄 create table 語法用在建立一個新的資料表語法格式如下

create table tablename (column1 data type column2 data type column3 data type)

Format of create table if you were to use optional constraints

create table tablename (column1 data type [constraint] column2 data type [constraint] column3 data type [constraint]) [ ] = optional

Note You may have as many columns as youd like and the constraints are optional

80

Example

create table employee (first varchar(15) last varchar(20) age number(3) address varchar(30) city varchar(20) state varchar(20))

注意建立資料表格式要以括號把前後框住而最後以(分號)做結尾

欄位名不要超過 30個字元長而且不要使用 sql 的關鍵字(如 where select等)而在後面接是型態的宣告(如字串數字日期格式等)

資料型態是來描述欄位的方式如一個欄位Last_Name 是一個姓氏可以使用varchar (可變動長度字串) 資料型態

以下是幾個常見的資料庫型態 char(size) 固定長度字串最長為 255 位元 varchar(size) 變動長度字串最大字元數以 size 來指定 number(size) 數值格式可以是整數也可以是小數最大數字以 size 位數判

斷未指定小數位數由系統內定 date 日期格式 number(sized) 數值格式最大數字以 size 位數判斷d 為小數位數整數位

數為 size-d 位

有何限制當資料表被建立通常有一或數個欄位是要使用來做關聯的功

能 例如unique 限制(唯一值)兩筆記錄不可以相同的值 not null (非空值)該欄位一定要輸入資料不可是空的primary key (主鍵)是每一筆記錄識別的主要方式

Drop a table drop table 刪除資料表(其中的資料也會一併刪除)

drop table tablename

Example

81

drop table 和刪除全部資料是不同的刪除全部資料欄位名稱資訊等還會

存在但刪除資料表會把這一些也一併移除掉

如何查詢資料

Select 基本用法

select 語法是關連式資料庫最常用的部份可以取得你想要的資料這是一個

簡單的範例 select column1[column2etc] from tablename [where condition] [] = optional 在 select 之後所列欄位名則是要顯示的資料部份你可以一一列出各欄位

名或是以 (星號)來代表選擇全部的欄位 from 之後放資料表名稱 where 子句 (選項) 指定要過濾的條件符合者才會顯現 where 可使用的條件運算元 = 等於 gt 大於 lt 小於 gt= 大或等於 lt= 小或等於 ltgt 大相等 LIKE 相似 For example select first last city

82

from empinfo where first LIKE Er 以Er 為開頭的字串就符合要以單引號框住 Or you can specify select first last from empinfo where last LIKE s 最後一字為 S 就符合 select from empinfo where first = Eric 則表示 first name 一定要是 Eric 才可以 範例資料表empinfo 統計函數

MIN 傳回指定欄位最小值

MAX 傳回指定欄位最大值

SUM 傳回指定欄位總和

AVG 傳回指定欄位平均值

COUNT 傳回指定欄位的筆數

COUNT() 傳回資料庫中的總筆數

統計函數使用於資料表中的數值欄位配合 SELECT 語法使用 只用於總結特定單一欄位可以配合 GROUP BY 做篩選但也可以不使用 GROUP BY 語句For example

SELECT AVG(salary) FROM employee

83

傳回全部 salary 平均值

Another example

SELECT AVG(salary) FROM employee WHERE title = Programmer

傳回 salary 平均值條件為 employees 資料表中當 title 等於 Programmer

Example

SELECT Count() FROM employees

傳回 employees 資料表中紀錄總筆數

GROUP BY 語法 SELECT column1 SUM(column2) FROM list-of-tables GROUP BY column-list The GROUP BY 語句可以先以所列的欄位為條件分組排序在一起(可以多欄

位) example 要列出每一個 dept 中最高 salary 值 SELECT max(salary) dept FROM employee GROUP BY dept HAVING 語法

SELECT column1 SUM(column2) FROM list-of-tables GROUP BY column-list HAVING condition

HAVING 子句是 GROUP BY 的一部份用來過濾在 GROUP BY 所選出的資料功能如同 select 命令中 where 條件式一樣只是 HAVING 必需配合 GROUP BY 使用

我們以例子來說明我們要取得每一公司名及每一公司的薪水平均值輸入如下

84

SELECT dept avg(salary) FROM employee GROUP BY dept

但如果我們只列出薪資平均值超過 20000元的公司資料

SELECT dept avg(salary) FROM employee GROUP BY dept HAVING avg(salary) gt 20000

ORDER BY子句語法

SELECT column1 SUM(column2) FROM list-of-tables ORDER BY column-list [ASC | DESC]

[ ] =選項

ORDER BY是一個選項子句當你以排序方式來顯示資料(正向由小到大反向由大到小)以指定的欄位資料做排序

ASC = 正向- 預設值 DESC = 反向排序

For example

SELECT employee_id dept name age salary FROM employee_info WHERE dept = Sales ORDER BY salary

以上列出公司代號公司名銷售員人名年紀及薪資而條件是公司名為 Sales 顯示順序以薪資多少排序(由小到大為預設值)

如果要以多個欄位做排序要以逗號做分隔如下

SELECT employee_id dept name age salary FROM employee_info WHERE dept = Sales ORDER BY salary age DESC

85

結合條件及布林運算 SELECT column1 SUM(column2) FROM list-of-tables WHERE condition1 AND condition2 AND運算可以結兩個或以上的條件放在 WHERE子句中 兩者都要為真才

會顯示該筆記錄 OR 運算可以結兩個或以上敘述放在 WHERE子句中只要其中一個為直就

會顯示該筆記錄 For example SELECT employeeid firstname lastname title salary FROM employee_info WHERE salary gt= 5000000 AND title = Programmer 必需要薪資大於等於 50000而且職稱為 Programmer同時符合才會顯示該筆資料 以下以括號括住雖然不是必需的但如此比較容易讀 SELECT employeeid firstname lastname title salary FROM employee_info WHERE (salary gt= 5000000) AND (title = Programmer) 另外範例 SELECT firstname lastname title salary FROM employee_info WHERE (title = Sales) OR (title = Programmer) 條件為只要是 Sales 或 Programmer 職稱的就會被列出 IN and BETWEEN 子句

SELECT column1 SUM(column2) FROM list-of-tables WHERE column3 IN (list-of-values) SELECT column1 SUM(column2) FROM list-of-tables WHERE column3 BETWEEN value1 AND value2 IN 子句使用在列舉項目的使用上也就是分別測試是否符合所列的值 For example

86

SELECT employeeid lastname salary FROM employee_info WHERE lastname IN (Hernandez Jones Roberts Ruiz) 條件為姓氏(astname)要符合 Hernandez Jones Roberts or Ruiz 其中一個才會被傳回 IN運算元也可以使用 OR 的語法來取代如下結果相同 SELECT employeeid lastname salary FROM employee_info WHERE lastname = Hernandez OR lastname = Jones OR lastname = Roberts OR lastname = Ruiz 但使用 IN 句子比較短也比較易懂 你也可以使用 NOT IN 來去掉不要的記錄 BETWEEN 運算元使用在判斷是否存在兩個數值之間 For example SELECT employeeid age lastname salary FROM employee_info WHERE age BETWEEN 30 AND 40 傳回年紀 30歲到 40歲之間的資料(含 30及 40歲者) 相同的也可以使用以下語法來達到相同的結果 SELECT employeeid age lastname salary FROM employee_info WHERE age gt= 30 AND age lt= 40 你也可使用 NOT BETWEEN 來濾掉中間值的資料 數學運算 標準 ANSI SQL-92 提供以下運算

87

+ 加

- 減

餘數

餘數為除法後剩整數這不在標準的 ANSI SQL 中但大部份的資料庫都會支

援這運算元以下列出有用的函數雖不在 ANSI SQL-92 提供但一般資料庫

也會支援他們

ABS(x) 傳回 x 絕對值

SIGN(x) returns the sign of input x as -1 0 or 1 (negative zero or positive respectively)

MOD(xy) 餘數 - returns the integer remainder of x divided by y (同 xy)

FLOOR(x) 傳回小或等於 x 的最大整數值

CEILING(x) or CEIL(x)

傳回大或等於 x 的最小整數值

POWER(xy) x的 y 次方

ROUND(x) 把 x 四捨五入為整數

ROUND(xd) 四捨五入取到小數 d 位

SQRT(x) x 開平方

For example SELECT round(salary) firstname FROM employee_info 傳回薪資取到整數位

如何新增資料

insert 加入一筆新紀錄到資料表中 insert into tablename (first_columnlast_column) values (first_valuelast_value) [] = optional Example insert into employee

88

(first last age address city state) values (Luke Duke 45 2130 Boars Nest Hazard Co Georgia) Note 字串要以單引號住如string 數字框住也無妨 insert into 後面接資料表名稱再接以括號括住的欄位名在 values 後括號分別對映各欄位的值 以上的例子新增了一筆名(first) 為 Luke而住所(state) 為 Georgia 的資料

如何刪除資料

delete 可以刪除單筆或多筆紀錄 delete from tablename where columnname OPERATOR value [and|or column OPERATOR value] [ ] = optional Examples delete from employee Note 如果你沒有指定 where 子句那麼全部的紀錄都會被刪除 delete from employee where lastname = May delete from employee where firstname = Mike or firstname = Eric delete from 接著資料表名 再接著是條件式判斷沒有條件式則全部紀錄會

被刪除

如何更新資料

update 用來更新你所指定的記錄要和 WHERE 配合小心使用 語法 update tablename set columnname = newvalue[nextcolumn = newvalue2] where columnname OPERATOR value [and|or column OPERATOR value] [] = optional Examples

89

update phone_book set area_code = 623 where prefix = 979 update phone_book set last_name = Smith prefix=555 suffix=9292 where last_name = Jones update employee set age = age+1 where first_name=Mary and last_name=Williams

90

附錄二Replication

測試環境

RedHat 90 + MySQL 32358 MySQL資料庫路徑 varlibmysql MySQL設定檔 etcmycnf Master IP 1921680100 Slave IP 1921680200 請至下列網址下載最新MySQL 32358套件並利用rpm ndashUvh 更新 httpupdatesredhatcom9enosi386

圖 最新 MySQL 套件

測試架構圖

91

1921680100

1921680200Master Server

erveSlave S r

圖 測試架構圖

測試步驟

Master server 部份 Step1 確認 MasterSlave機器上所裝的 MySQL版本能進行

replication( 32329 or higher ) Step2 在 Master MySQL上開放一個帳號給 Slave mysql ndashu root ndashp mysqlgtGRANT FILE ON TO repl1921680200 IDENTIFIED BY lsquoabc123rsquo mysqlgtq 上面是 Master開放一個帳號 repl密碼 abc123給 IP1921680200有檔案處理

的權限 Step3 shutdown MySQL on the Master mysqladmin ndashu root ndashp shutdown Step4 備份 Master所有資料庫 tar ndashcvf tmpmysql-snapshottar varlibmysql 注意tar的時候MySQL是要在 stop情況下 在mysql (wwwmysqlcom) 網站的FAQ有不用shutdown的方法

92

Step5 在 master機器上修改etcmycnf 在[mysqld]區段內加入參數 log-bin server-id=這邊設定 server-id=1 sql-bin-update-same binlog-do-db=CRM只針對 CRM資料庫做紀錄 Step6 Restart MySQL on the master service mysqld start 此時因為有加入 log-bin 參數因此開始有 index產生了在varlibmysql目錄下

有index檔案紀錄資料庫的異動 log Slave server 部份 Step1 在 slave設定etcmycnf 在[mysqld]區段加入 master-host= master-user= master-password= master-port= server-id= 這邊設定 master-host=1921680100 master-user=repl master-password=abc123 master-port=3306 server-id=2 master-connect-retry=60預設重試間隔 60秒 replicate-do-db=CRM告訴 slave只做 CRM資料庫的更新 log-slave-updates Step2 將 master上的 mysql-snapshottar copy到 slave上 用 ftp傳到 slave的tmp Step3 解壓縮 Master資料庫至 Slave Server上 cd varlib tar xvf tmpmysql-snapshottar chown ndashR mysqlmysql mysql

93

chmod ndashR 770 mysql (視情況) Step4 Restart MySQL on the slave server 這時在varlibmysql目錄會出現 masterinfo此檔案紀錄了 Master MySQL server的資訊

狀況測試

One-way replication

1921680100

1921680200Master Server

erveSlave S r

圖 One-way replication架構圖 Step1 Master跟 Slave網路及服務都正常情況下由 Master端異動資料後 到 Slave端瀏覽資料檢視是否有進行 replication Step2 模擬 Slave Server 當機 可用在於 slave真的當機或是 Slave 不一定需要一直跟 master connect將Slave MySQL server shutdown由 Master端異動資料到 slave端瀏覽此時Slave應該沒有被 replication 更新然後再將 Slave端 MySQL server start起來

預設 60秒後 Slave會嘗試跟 Master要求進行 replication再去 Slave端檢視是否有更新資料

94

Step3 模擬 Master當機因為是設定 One-way replication一旦 Master Server Slave端沒有 Master的 source可以 download Two-way replication 基於 Master當機狀況於是發展雙向 Replication即 1921680100 ( Host A ) 1921680200 ( Host B )都分別擔任 MasterSlave身分

1921680100

1921680200er

Server B MasterSlave Server

Server A MasterSlave Serv

圖 Two-way replication架構圖 以下是針對兩台 MySQL伺服器進行雙向 Replication Step1觀念同單向 replication只是改成 Master也有 Slave身分 Slave也有Master的身分先分別在 Server AServer B 都去 grant一個進行 replication的身分 [A]mysqlgtGRANT FILE ON TO repl1921680200 IDENTIFIED BY lsquoabc123rsquo [B]mysqlgt GRANT FILE ON TO repl1921680100 IDENTIFIED BY lsquoabc123rsquo Step2做完單向 replication後stop Server Aserver B MySQL service此時 AB資料是一樣的

95

修改etcmycnf設定 範例 Server A [mysqld] datadir=varlibmysql socket=varlibmysqlmysqlsock server-id=1 log-bin sql-bin-update-same binlog-do-db=CRM master-host=1921680200 master-user=repl master-password=abc123 log-slave-updates master-connect-retry=60 replicate-do-db=CRM Server B [mysqld] datadir=varlibmysql socket=varlibmysqlmysqlsock server-id=2 log-bin sql-bin-update-same binlog-do-db=CRM master-host=1921680100 master-user=repl master-password=abc123 log-slave-updates master-connect-retry=60 replicate-do-db=CRM 分別 start Server AServer B MySQL後此時雙方都是 MasterSlave身分一旦哪一方資料異動就會通知對方來 replication-若 replication失效則必須將Server AServer B的masterinfo及index00x 都砍掉然後分別 restart MySQL server進行測試檢視成果 實務上通常如果需要做Two-way replication通常會搭配Virtual Server使用

96

在前端架設一台Virtual Server不過此部份不在此份SOP討論範圍內有興趣

的讀者可參考 httpwwwlinuxvirtualserverorg 網站

1921680100 1921680200

Host A MasterSlave Server

Host B MasterSlave Server

Virtual Host

圖 Virtual Server + Two-way replication 架構圖

97

圖 High Availability Linux Virtual Server架構圖

98

  • COSA-SOP-03-006
  • 第一章 簡介
    • 11適用對象 (Audience)
    • 12 MySQL本身
    • 13 MySQL 40版跟50版重大的改進功能
    • 14 各家資料庫軟體比較
      • 第二章 前置需求
      • 第三章 安裝
        • 31 MySQL安裝
        • 32 phpMyAdmin安裝
        • 33 升級及注意事項
          • 第四章 MySQL管理
            • 41 Webmin 管理介面
            • 42 phpMyAdmin 的操作介面
            • 43管理指令介紹
              • 431 利用mysqladmin設定root的密碼
                  • 第五章 實用範例
                    • 51 任務一Web Base客戶通訊錄
                    • 52 任務二Web Base群組軟體 ( twig )
                      • 第六章 維護及更新程序
                        • 61 日常維護
                        • 62 更新程序
                        • 63 備份重要檔案
                        • 64 離線備份與還原
                        • 65 線上備份與還原
                          • 第七章 問題與解答
                          • 第八章 參考資料
                          • 附錄一 SQL Command 介紹
                          • 附錄二Replication
Page 50: DataBase Server Standard Operation Procedureebooks.lib.ntu.edu.tw/1_file/oss/63/93doc4-5.pdf · 業務的公司帶來了不少壓力,譬如微軟,甲骨文 ... 外的錢用在第三方的資料庫產品上,譬如就可以不用再購買甲骨文公司

第五章 實用範例

51 任務一Web Base客戶通訊錄

任職於開放科技公司的林小明前些日子在最符合成本效益的條件下快

速地完成公司網站的建置老闆因此對小明讚譽有加最近因為公司存放客戶資

料的 SQL Server主機屢遭病毒攻擊加上作業系統本身的問題當機次數頻繁

老闆希望能儘快把公司的客戶通訊錄程式移轉到較穩定的環境上因為此客戶通

訊錄程式最主要給內部人員使用所以介面美觀並不特別要求只求穩定且能快

速得到查詢結果老闆希望在短時間先看到程式的雛型並鍵入資料對其效率

及穩定性進行測試因為上次小明表現突出所以這次不可能的任務自然又落到

小明身上 小明想來想去既然要快速又穩定他而且又不希望所有人都得安裝 Client

程式於是小明決定)捨棄他的舊愛「Delphi+MS SQL」投向新歡「Apache + MySQL + PHP」利用此架構來設計一個簡單實用的Web Base客戶通訊錄程式

511 Web Base客戶通訊錄架構

此程式需要建立 CONTACT的資料庫並建立 adress Tables其結構如下表建立步驟請參考第三章 欄位名稱 資料型態 長度 說明 id INT (自動編號) 連絡人編號 name varchar文字 20 連絡人姓名 tel Varchar文字 15 連絡人電話 Web Base通訊錄共有下列幾個檔案功能如下表

檔案名稱 說明 Indexhtml Web Base通訊錄首頁 addphp 新增連絡人的 php程式 searchphp 尋找連絡人的 php程式 editphp 具有更新及刪除功能的 php程式

50

我們將這些檔案放至varwwwhtmlbluepage (預設無 bluepage目錄)

512 Web Base通訊錄測試

httpwwwopencombluepage 新增資料

圖 5-1 新增連絡人

圖 5-2 填入資料

51

圖 5-3 新增成功

搜尋及異動資料

圖 5-4 搜尋通訊錄

52

圖 5-5 編輯資料

圖 5-6 更新資料

513 程式內容及說明

lt-- 程式範例indexhtml--gt lthtmlgt ltheadgtlttitlegt通訊錄lttitlegtltheadgt ltbodygt ltcentergt

53

lth2gt通訊錄lth2gtlthrgt lta href=indexhtmlgt通訊錄ltagt | lta href=addphpgt新增連絡人ltagt | lta href=searchphpgt搜尋通訊錄ltagt ltcentergt ltbodygt lthtmlgt lt-- 程式範例addphp --gt lthtmlgt ltheadgtlttitlegt新增連絡人lttitlegtltheadgt ltbodygt ltcentergtlth2gt新增連絡人lth2gtltcentergtlthrgt lt 取得欄位資料 if (isset($_POST[Name]) ampamp isset($_POST[Tel]) ) $name = $_POST[Name] $tel = $_POST[Tel] 檢查是否有輸入欄位資料 if ($name = ampamp $tel = ) 建立 SQL字串 $sql = INSERT INTO address (name tel) values( $sql= $name $tel) 建立 MySQL 連結 $link = mysql_connect(localhostroot1234) 選擇資料庫 mysql_select_db(CONTACT) 執行 SQL指令 mysql_query($sql) mysql_close($link) echo ltfont color=redgt新增連絡人成功ltfontgtltbrgt gt ltform action=addphp method=postgt lttable border=0 width=300gt lttrgtlttdgt姓名 lttdgt

54

lttdgtltinput type=text name=Name size=20 maxlength=10gtlttdgtlttrgt lttrgtlttdgt電話 lttdgt lttdgtltinput type=text name=Tel size=20 maxlength=20gtlttdgtlttrgt lttrgtlttd colspan=2 align=centergt ltinput type=submit value=新增連絡人gtlttdgtlttrgt lttablegt ltformgt ltbrgtlta href=indexhtmlgt通訊錄ltagt | lta href=addphpgt新增連絡人ltagt | lta href=searchphpgt搜尋通訊錄ltagt ltbodygt lthtmlgt

lt-- 程式範例searchphp --gt lthtmlgt ltheadgtlttitlegt搜尋通訊錄lttitlegtltheadgt ltbodygt ltcentergtlth2gt搜尋通訊錄lth2gtlthrgt lt if (isset($_POST[Search])) 建立資料庫連結並選定資料庫 $link = mysql_connect(localhostroot1234) mysql_select_db(CONTACT) 建立基本的 SQL字串 $sql = SELECT FROM address 檢查是否輸入姓名 if (chop($_POST[Name]) = ) $name = name LIKE $_POST[Name] else $name = 檢查是否輸入電話號碼 if (chop($_POST[Tel]) = ) $tel = tel LIKE $_POST[Tel] else $tel =

55

if條件組合 SQL字串 if (chop($name) = ampamp chop($tel) = ) $sql= WHERE $name AND $tel elseif (chop($name) = ) 只有姓名 $sql = WHERE $name elseif (chop($tel) = ) 只有電話號碼 $sql = WHERE $tel $sql= ORDER BY name 最後加上排序 $result = mysql_query($sql) 取得欄位數 $total_fields = mysql_num_fields($result) echo lttable border=1gt echo lttrgtlttdgt編號lttdgtlttdgt姓名lttdgtlttdgt電話lttdgtlttd colspan=2gt功能選項lttdgtlttrgt 表格顯示查詢結果 while ($rows = mysql_fetch_array($result MYSQL_NUM)) echo lttrgt for ($i = 0 $i lt $total_fields $i++) echo lttdgt$rows[$i]lttdgt echo lttdgtlta href=editphpaction=editampid= echo $rows[0]gtltbgt編輯ltbgtlttdgt echo lttdgtlta href=editphpaction=delampid= echo $rows[0]gtltbgt刪除ltbgtlttdgt echo lttrgt echo lttablegtlthrgt mysql_free_result($result) mysql_close($link) gt ltcentergt ltform action=searchphp method=postgt lttable border=0 width=450gt lttrgtlttdgt搜尋姓名 lttdgt lttdgtltinput type=text name=Name size=10 maxlength=20gtlttdgtlttrgt lttrgtlttdgt搜尋電話 lttdgt lttdgtltinput type=text name=Tel

56

size=20 maxlength=20gtlttdgtlttrgt lttrgtlttd colspan=2 align=centergt ltinput type=submit name=Search value=搜尋gtlttdgtlttrgt lttablegt ltformgt ltbrgtlta href=indexhtmlgt通訊錄ltagt | lta href=addphpgt新增連絡人ltagt | lta href=searchphpgt搜尋通訊錄ltagt ltbodygt lthtmlgt

lt ob_start() gt lt-- 程式範例editphp --gt lthtmlgt ltheadgtlttitlegt編輯通訊錄lttitlegtltheadgt ltbodygt lt 取得 URL 參數 $id = $_GET[id] $action = $_GET[action] 建立資料庫連結 $link = mysql_connect(localhostroot1234) mysql_select_db(CONTACT) 選擇資料庫 執行的操作 switch ($action) case update 更新 取得欄位資料 $name = $_POST[Name] $tel = $_POST[Tel] $sql = UPDATE address SET name=$name tel=$tel WHERE id=$id mysql_query($sql) 執行 SQL指令 mysql_close($link) header(Location searchphp) 轉向到 serachphp break case del 刪除 $sql = DELETE FROM address WHERE id=$id

57

mysql_query($sql) 執行 SQL指令 mysql_close($link) header(Location searchphp) 轉向到 serachphp break case edit 編輯 $sql = SELECT FROM address WHERE id=$id $result = mysql_query($sql) 執行 SQL指令 $row = mysql_fetch_row($result) 取回記錄 $name = $row[1] 取得欄位 name $tel = $row[2] 取得欄位 tel mysql_close($link) 顯示編輯表單 gt ltcentergtlth2gt更新通訊錄lth2gtltcentergtlthrgt ltform action=editphpaction=updateampid=lt echo $id gt method=postgt lttable border=0 width=300gt lttrgtlttdgt姓名 lttdgt lttdgtltinput type=text name=Name size=20 maxlength=10 value=lt echo $name gtgtlttdgtlttrgt lttrgtlttdgt電話 lttdgt lttdgtltinput type=text name=Tel size=20 maxlength=20 value=lt echo $tel gtgtlttdgtlttrgt lttrgtlttd colspan=2 align=centergt ltinput type=submit value=更新連絡人gtlttdgtlttrgt lttablegt ltformgt ltbrgtlta href=indexhtmlgt通訊錄ltagt | lta href=addphpgt新增連絡人ltagt | lta href=searchphpgt搜尋通訊錄ltagt lt break gt ltbodygt lthtmlgt

58

52 任務二Web Base群組軟體 ( twig )

順利完成Web Base客戶通訊錄程式測試一段時間後「Apache + MySQL + PHP」架構的穩定與快速巳深得老闆與公司所有同事的認同隨著公司業績蒸

蒸日上人員組織編罝愈來愈龐大跨部門的會議愈來愈多業務員每日排滿拜

訪客戶的行程跟客戶的 Email的往來也愈來愈頻繁 愈來愈多部門的同事希望公司能建置一套群組軟體提供 web mail可讓業

務人員方便收發 mail還有連絡人議事日程待辦工作書簽等功能讓整個

公司運作及個人時間管理更有效率

老闆問小明對這些需求有什麼看法小明認為如果這些功能完全由程式部

門開發必定曠日費時而且耗費公司資源小明在網路尋找是否有提供這些功能

的Free Software皇天不負苦心人小明發現了TWIG (The Web Information Gateway) httptwigscrewdrivernet這個群組軟體它在 Web 上整合郵件新聞聯絡人議事日程工作序書簽等功能非常符合公司的需求 Step 1 下載 twig-277targz 下載網址 httptwigscrewdrivernetdownloadphp3

Step 2 解開 twig-277targz tar -xzvf twig-277targz

59

Step 3 執行安裝動作安裝到 varwwwhtmltwig 目錄 cd twig-277 twig-install varwwwhtmltwig

Step 4 建立 MySQL 資料庫(twig)及各資料表

cd setup mysql -u root -p1234 mysqlgt create database twig Query OK 1 row affected (001 sec) mysqlgt quit mysql -u root ndashp1234 twiglt twigtablemysql

Step 5 修改 configincphp3 參數設定 vi varwwwhtmltwigconfigconfigincphp3 $config[fromdomain] = opencom 網域 $config[language] = chinesebig5 中文訊息 $config[imap_port] = 143notls

60

Step 6 修改連結 MySQL 的帳號密碼 vi varwwwhtmltwigconfigdbconfigincphp3 $dbconfig[sqlusername] = root username $dbconfig[sqlpassword] = 1234 password

Step 7 其他設定檔

vi etchttpdconfhttpdconf 加入 AddType applicationx-httpd-php php3 在 DirectoryIndex最後加入 indexphp3 DirectoryIndex indexhtml indexhtmlvar indexphp3 在 AddDefaultCharset ISO-8859-1加上 AddDefaultCharset ISO-8859-1

vi etcphpini register_globals = On service httpd restart Step 8 sendmail 設定 vi etcmailsendmailcf在 264 行前面加上並重新啟動 sendmail「service snedmail restart」 262 SMTP daemon options 263 264 O DaemonPortOptions=Port=smtpAddr=127001 Name=MTA 265 266 SMTP client options 267 O ClientPortOptions=Family=inet Address=00

61

Step 9 檢查設定有無錯誤 http主機名稱twigtestphp3

62

Step 10 登入 twig ( http主機名稱twig)

63

第六章 維護及更新程序

61 日常維護

系統管理員最好定期以 root 身份登入看看信件在 RedHat Linux 中有一支 logwatch 程式會定時去分析 log file如果發現異常便會發信給 root除此之外筆者建議讀者平時就檢查 MySQL log file ( varlogmysqldlog)是否有異常情形

62 更新程序

讀者可至httprpmfindnet 尋找MySQL相關套件至於升級的相關步驟請參

考Linux OS SOP 第 54節

63 備份重要檔案

預設 MySQL 的 DB 檔案是存在 varlibmysql 內以 DB名稱為目錄目錄

內就是該 DB 的所有資料通常得定期備份還有 MySQL的設定檔 etcmycnf也別忘了一起備份

64 離線備份與還原

641 離線備份

預設 MySQL 的 DB 檔案是存在 varlibmysql 內以 DB 名稱為目錄目錄內

就是該 DB 的所有資料像 CRM 這個 DB就是存在 varlibmysqlCRM 內在備份前因為怕資料尚未完全寫入磁碟而且 MySQL 會 Lock 在使用的 DB 檔案所以應該是要先把 MySQL 先 Shutdown 一下整個備份的程序可以下像下面的指令去完成 cd varlibmysql

64

service mysqld stop tar cvfz CRM_db_20030905tgz CRM service mysqld start 對這樣就可以了 不過要注意的是怕 DB 內每個 Tables 間的資料有關關

聯性所以最好是把整個 DB 一次備起來單獨只備哪個 Tables 的檔案以後回存時怕會有資料關聯不一致的問題

642 離線還原

DB 發生錯誤而要回存時其實也不難先找出最近一次完整正常的備份先把現在錯誤的網頁或 DB 先更名或 tar 起來再把好的備份給解開回原來目錄位

置就行了需要注意的是 MySQL 服務最好也是要先停止回存完成後再啟動服務回存 DB 的整個程序可能像下面 cd varlibmysql service mysqldstop mv CRM CRM_OLD tar xvfz CRM_db_20030905tg service mysqld start

65 線上備份與還原

651 線上備份

使用像上面的檔案方式備份是個不錯的方法它最少可以保持該主機某個時間點的完整檔案備份但還是有一些問題需要考慮到有些主機就不只建立一個 DB 而已總不能為了備份某個 DB 而把整個 MySQL 服務停止備份檔案的方式回存在原主機上一定適用但假如 MySQL 版本升級或是在那天該網頁空間需遷機移機到別的主機時那就沒人敢保證備出來的資料檔可以用所以我們可以考慮另一種備份的方式是使用 MySQL 本身提供的功能 MySQL Data Dump指令是 mysqldump

65

使用 MySQL 的 Dump 功能可以把 DB 的結構資料或結構加資料 Dump 成文字檔 mysqldump 指令提供的彈性很大你可以選擇把整個 DB Dump 成一個檔或是每個 Table 為一個檔甚至是把結構檔和資料分開儲存都

可以 mysqladmin -uroot -p flush-logs mysqldump CRM -uroot -p --opt gt CRM_20030905sql (CRM 是 DB 名稱 opt 是一個使用完整 Dump 參數) 假如只是要單獨 Dump 某個 Table 時只要在上面的指令後轉出符號 gt 前加個 Table 名稱就可以如只要 phpbb2_users 這個 Table 的 Dump 時只要下 mysqldump CRM -uroot -p --opt CUSTOMER gt CRM_CUSTOMER_20030905sql

652 線上還原

若要回存整個資料庫只需將壓縮的備份檔還原成 Dump 的檔案再用下面的指令回存 mysql CRM -uroot -p lt CRM_20030905sql 這邊需注意的是若建立備份時是以--opt或--add-drop-table為參數時回存的 動作是先將舊的 Table 先刪除重建 Table 的結構後再把 Data 匯入所以回存後所有的資料會回到你當時備份那個時間點因此在回存資料時可以考慮把現有錯誤或不完整的 DB 先備份一份下來以備不時之需或是拿來比對錯誤的地

方在那裡當然你也可以把資料回存到另一個測試用的 DB 內只要把上面指令

的 DB 名稱改成你的測試用 DB 名稱即可 使用這種回存方式 MySQL 服務不需停止也不會動到其他正在使用的 DB 在一些提供 MySQL 服務的虛擬主機可用這種方式作你自己的 DB 備份及回存

66

另外假如你是系統重建或是移機時切需在新的 MySQL 內新建一個空白 DB 後才行作回存的工作你可以用下面的指令建立 mysql -uroot -p -e CREATE DATABASE CRM (上面的 CRM是你要新建的 DB 名稱) 另一種作法先用 mysql 指令進入 mysql client console 然後再用 CREATE DATABASE CRM 這樣就行了記得尾端要加個 符號該行指令才會執行

67

第七章 問題與解答

Q1RedHat 90預附的 MySQL到底有無支援 Transcation機制 Ans MySQL自 32334a之後的 MySQL-Max版本加入 InnoDB的資料庫類型透過

InnoDBMySQL同樣可以進行 COMMIT與 ROLLRACK的動作RedHat 90預附的 MySQL為 32354a-11巳支援 InnoDB的資料庫類型不過必須做以

下設定 1cp usrsharedocmysql-server-32354amy-mediumcnf to etcmycnf 2 vi etcmycnf 將以下設定前的拿掉 innodb_data_home_dir = varlibmysql innodb_data_file_path = ibdata110Mautoextend innodb_log_group_home_dir = varlibmysql innodb_log_arch_dir = varlibmysql 3service mysqld restart 如此一來各位在建立Table時便可指定Table Type為 innodb ( ex create table with type=innodb ) Q2如何解決 php+mysql 許功蓋等字變亂的問題 Ans 方法一 【確定 MySQL 預設的字元集】 1 打開 WinMySQLadmin 管理畫面(在視窗右下角狀態列紅綠燈圖示中按滑鼠

右鍵點選 Show me 選項) 2 點選管理畫面中 [Variables] 標籤選項其中 character_set變數就是您預設

字元集的變數其預設是 latin1 字元集(我們要將他改回 big5)而 chatacters_set 變數則是 MySQL 可以支援哪些字元集 【修改預設字元集變數 character_set 】 1 請點選管理畫面中 [myini Setup] 標籤選項設定 myini 2 按一下 [Pick-up and Edit myini values] 按鈕以便編輯目前的 myini 設定 3 在 [mysqld] 設定區塊底下新增一行 default-character-set = big5 變數設

68

定 4 新增一個 [client] 設定區塊並加入第三步驟的變數設定(游標往下移到空白處新增兩行 [client] 和 default-character-set=big5) 5 按一下畫面左下方 [Save Modification] 按鈕儲存設定 6 重新啟動 MySQL 或 Windows 方法二 Server端注意事項 phpini 中有關的設定為(預設值) Magic quotes for incoming GETPOSTCookie data magic_quotes_gpc = On Use Sybase-style magic quotes (escape with instead of ) magic_quotes_sybase = Off Client端注意事項 1中文資料送進 mysql 前請用 addslashes($str) 處理 2處理後送進 mysql 時請用 括起來並在參數後留一個空白如 $sql = UPDATE ezf_table set tablename=$tname tableend=$endtime table inguser=$tguser tableingid=$tguserid tableallnumber=$tnumber tableloca l=$tablelocal tableanyone=$tableopen tabletext=$ttext WHERE tableid=$t ableid tablename=$tname c 取出時請用 stripslashes($str) Q3MySQL root 密碼忘了該怎麼辦 Ans 1先停掉 mysql etcrcdinitdmysql stop 2以--skip-grant-table 的參數啟動 mysql safe_mysql --skip-grant-tableamp 3 更改 root 密碼 mysql mysql mysqlgt UPDATE user SET password=password(newpassword)

69

WHERE user=root mysqlgt FLUSH PRIVILEGES mysqlgt exit 4停掉 mysql再重跑 mysqladmin -uroot -p shutdown Enter password 輸入新設定的密碼 etcrcdinitdmysql start

Q4NULL值問題

Ans

NULL值的概念是造成 SQL的新手的混淆的普遍原因他們經常認為 NULL是和一個空字符串的一樣的東西不是這樣的例如下列語句是完全不同的

mysqlgt INSERT INTO my_table (phone) VALUES (NULL)

mysqlgt INSERT INTO my_table (phone) VALUES ()

兩個語句把值插入到 phone 列但是第一個插入一個 NULL值而第二個插入一個空字符串第一個的含義可以認為是ldquo電話號碼不知道而第二個則可意味

著ldquo她沒有電話

在 SQL中NULL值在于任何其他值甚至 NULL值比較時總是假的(FALSE)包含 NULL的一個表達式總是產生一個 NULL值除非在包含在表達式中的運算符和函數的文檔中指出在下列例子所有的列返回 NULL

mysqlgt SELECT NULL1+NULLCONCAT(InvisibleNULL)

如果你想要尋找值是 NULL的列你不能使用=NULL測試下列語句不返回任

何行因為對任何表達式expr = NULL是假的

mysqlgt SELECT FROM my_table WHERE phone = NULL

要想尋找 NULL值你必須使用 IS NULL測試下例顯示如何找出 NULL電話號碼和空的電話號碼

70

mysqlgt SELECT FROM my_table WHERE phone IS NULL mysqlgt SELECT FROM my_table WHERE phone =

在 MySQL中就像很多其他的 SQL服務器一樣你不能索引可以有 NULL值的列你必須聲明這樣的列為 NOT NULL而且你不能插入 NULL到索引的

列中

當用 LOAD DATA INFILE 讀取數據時空列用更新如果你想要在一個列中有

NULL值你應該在文本文件中使用N字面上的詞NULL也可以在某些情形下使用

當使用 ORDER BY時首先呈現 NULL值如果你用 DESC以降序排序NULL值最後顯示當使用 GROUP BY時所有的 NULL值被認為是相等的

為了有助于NULL的處理你能使用 IS NULL和 IS NOT NULL運算符和 IFNULL()函數

對某些列類型NULL值被特殊地處理如果你將 NULL插入表的第一個TIMESTAMP 列則插入當前的日期和時間如果你將 NULL插入一個AUTO_INCREMENT 列則插入順序中的下一個數字

Q5如何將圖片存放於 MySQL中

Ans

Step 1建立資料庫 test

Step 2 建立表格 binary_data

CREATE TABLE binary_data (

id INT(4) NOT NULL AUTO_INCREMENT PRIMARY KEY

description CHAR(50)

bin_data LONGBLOB

filename CHAR(50)

filesize CHAR(50)

filetype CHAR(50)

71

)

Step 3 利用 storephp 寫入圖片

storephp 程式碼

ltHTMLgt ltHEADgtltTITLEgtStore binary data into SQL DatabaseltTITLEgtltHEADgt ltBODYgt lt code that will be executed if the form has been submitted

if ($submit) mysql_connect(localhostrootYOUR_PASSWORD) mysql_select_db(test) $data=Base64_Encode(fread(fopen($form_data r) filesize($form_data))) $result=MYSQL_QUERY(INSERT INTO binary_data (descriptionbin_datafilenamefilesizefiletype) VALUES ($form_description$data$form_data_name$form_data_size$form_data_type)) $id= mysql_insert_id() print ltpgtThis file has the following Database ID ltbgt$idltbgt MYSQL_CLOSE() else else show the form to submit new data

gt

ltform method=post action=ltphp echo $PHP_SELF gt enctype=multipartform-datagt File Descriptionltbrgt ltinput type=text name=form_description size=40gt ltINPUT TYPE=hidden name=MAX_FILE_SIZE value=4000000gt ltbrgtFile to uploadstore in databaseltbrgt ltinput type=file name=form_data size=40gt ltpgtltinput type=submit name=submit value=submitgt ltformgt lt

72

gt ltBODYgt ltHTMLgt

Step 3 利用 storephp 取出圖片

getdataphp 程式碼

lt Syntax getdataphp3id=ltidgt if($id) you may have to modify login information for your database server MYSQL_CONNECT(localhostrootYOUR_PASSWORD) mysql_select_db(test) $query = select bin_datafiletype from binary_data where id=$id $result = MYSQL_QUERY($query) $data = Base64_Decode(MYSQL_RESULT($result0bin_data)) $type = MYSQL_RESULT($result0filetype) Header( Content-type $type) echo $data gt

Q6MySQL裝好之後啟動時或是執行 mysqladmin會出現如下訊息 Cant connect to local MYSQL Server through Socket varlibmysqlmysqlsock或是

Cant connect to local MYSQL Server through Socket tmpmysqldsock

Ans 可能有下列幾個原因

1這個 mysqldsock 不見了被某人刪除了或是被一些系統自動執行程式給刪

了例如有些 cron任務便會設定定期刪除 tmp 裡的東西所以呢您只能修改

cron 裡的設定讓它不要清除 mysqldsock 2在啟動時也可以改變 mysqldsock的位置您在啟動 MySQL的時候可以加入此參數usrlocalmysqlbinsafe_mysqld --user=mysql --socket=其他路

徑socket amp 同時得去設定環境變數 MYSQL_UNIX_PORT的值以指定新的

73

路徑 3若是您沒改 MYSQL_UNIX_PORT的值那麼您可以在執行指令的時候才打

例如mysqladmin --socket=其他路徑socket version Q7How to get the last insert id Ans CREATE TABLE product ( id INT(4) NOT NULL AUTO_INCREMENT PRIMARY KEY description VARCHAR(50) ) 1利用 SQL的話 mysqlgt insert into product(description) values(123) Query OK 1 row affected (000 sec) mysqlgt select last_insert_id() +------------------+ | last_insert_id() | +------------------+ +------------------+ 1 row in set (000 sec) ======================================== 2如果是 PHP的話 你可以用mysql_insert_id()取得該 id PHP example $result=MYSQL_QUERY(INSERT INTO product (description) VALUES ($description)) $id= mysql_insert_id() print This file has the following Database ID $id Q8如何將文字檔匯入資料庫 Ans $addr=homehttpdhtmlphpschool001txt $sql_select = load data infile $addr into table test fields terminated by t 解說 $sql_select = load data infile 文字檔名 into table 表格名 fields terminated by

74

t

(欄位分隔以 TAB鍵) 該文字檔須與資料表欄位格式相符 例如欄位有三個 則文字檔為每行一筆資料如下 欄 1資料ltTABgt欄 2資料ltTABgt欄 3資料 欄 1資料ltTABgt欄 2資料ltTABgt欄 3資料 欄 1資料ltTABgt欄 2資料ltTABgt欄 3資料 欄 1資料ltTABgtltTABgt欄 3資料

Q9如何撰寫 MySQL C API Ans Step 1利用文字編輯器撰寫以下程式碼 mysqlcc

include ltstdiohgt

include ltmysqlmysqlhgt

int main (int argc char argv[])

MYSQL mysql

MYSQL_RES res

MYSQL_ROW row

if (argc = 2)

fputs (Usage myc ltdatabasegt stderr)

return 1

if ((mysql_connect(ampmysqllocalhostrootYour_Password)))

fputs (Error connecting stderr)

abort()

75

if (mysql_select_db(ampmysqlargv[1]))

fputs (Error selecting database stderr)

abort()

if (mysql_query(ampmysqlSELECT FROM test_table))

fputs (Error processing query stderr)

abort()

if ((res = mysql_store_result(ampmysql)))

fputs (Error storing results stderr)

abort()

while((row = mysql_fetch_row(res)))

uint i = 0

for (i=0 i lt mysql_num_fields(res) i++)

printf(s row[i])

printf(n)

return 0

Step 2 Compile

gcc -Iusrlocalmysqlinclude -Lusrlocalmysqllibmysql mysqlcc ndashlm -lmysqlclient

(其中 include path與 library path取決於你的 MySQL安裝路徑)

76

如果執行時發生如下 error Run problemerror in loading shared libraries libmysqlclientsoX 將你的 MySQL library path(for exampleusrlocalmysqllibmysql) 加入etcldsoconf and run sbinldconfig -v Q9ASP + MySQL 範例程式 Ans Dim myconn As New ADODBConnection Dim myrs As New Recordset Dim mySQL As String Dim myrows As Long myconnOpen DSN=MyODBCsample mySQL = SELECT from user myrsSource = mySQL Set myrsActiveConnection = myconn myrsCursorLocation = adUseClient myrsOpen myrows = myrsRecordCount myrsClose myconnClose 可參考 httpwwwdwamnetmysqlasp_myodbcasp 有詳細的資料 Q10如何將 MySQL中的資料庫匯出成txt檔 Ans select from TableName into outfile textxls all result fields will seperate by tab

77

第八章 參考資料

英文部份 網址 1 httpwwwmysqlcom MySQL 網站有第一手有關 MySQL的資料 2 httpwwwmysqlcomdocenReplicationhtml 有關 MySQL Replication 的文件 3 httpwwwgeocitiescomsqlhomefaqstore_blobhtml 如何在 MySQL 存放 BLOB的資料 4httpwwwsapdborg 有關 SAP跟 MySQL相關合作的網站 書藉 1 Cooking with MySQL

Paul DuBois has selected sample recipes from the hundreds youll find in his book MySQL

Cookbook In this third and final series of excerpts showcasing these recipes learn how to

compute team standings how to calculate the differences between successive Dec 26

2002 2 Tips for Building Web Database Applications with PHP and MySQL by Hugh E Williams co-author of Web Database Applications with PHP amp MySQL 04042002

3 Managing and Using MySQL 2nd Edition By Tim King George Reese Randy Jay Yarger

4 MySQL Cookbook By Paul DuBoisPublisher OReillyPub Date October 2002

中文部份

78

1 httplinuxtncedutwtechdocmysqlmysql_docmanual_tochtml MySQL 中文手冊 2 httpchenshloxaedutwphpZ_1php PHP+MySQ程式研習設計網站 3 httplinuxtncedutwtechdocbanicdownhtml PHP 4 手冊 4 httpwwwtncedutwadmin_zonephp台南縣教育網網路中心有很多 Linux相關文件 5 httpdobtncedutw網站建置百寶箱有很多 PHP MySQL 相關範例程式 5 httpwwwdbworldcomtw資料庫專家電子雜誌介紹資料庫的重要觀念及名詞

79

附錄一 SQL Command 介紹

SQL (讀音ess-que-el) 是一種結構查詢語法SQL 使用於資料庫交流

傳遞相容於 ANSI (American National Standards Institute) 是一套標準的關聯

式資料庫語言 SQL 語言是執行更新或從資料系統獲取資料一般常見的關聯

資料庫系統都有提供 SQL 如 Oracle Sybase Microsoft SQL Server Access Ingres 等雖然大部份的資料庫都有提供 SQL 但也多提供了自已獨特的語

法造成了不相容的情形但標準基本的語法是相通的如Select Insert Update Delete Create and Drop 每一個系統都有支援

Table相關 Command

Create Table

關聯式資料庫包含有很多元件稱為資料表(tables) 把資料或訊息放在資

料表中 資料表是以不同的名稱做分別資料表由欄列所構成的二維陣列

欄包含欄位名資料型態 及其他可判斷的資訊列是由全部欄位構成一筆一

筆的紀錄 create table 語法用在建立一個新的資料表語法格式如下

create table tablename (column1 data type column2 data type column3 data type)

Format of create table if you were to use optional constraints

create table tablename (column1 data type [constraint] column2 data type [constraint] column3 data type [constraint]) [ ] = optional

Note You may have as many columns as youd like and the constraints are optional

80

Example

create table employee (first varchar(15) last varchar(20) age number(3) address varchar(30) city varchar(20) state varchar(20))

注意建立資料表格式要以括號把前後框住而最後以(分號)做結尾

欄位名不要超過 30個字元長而且不要使用 sql 的關鍵字(如 where select等)而在後面接是型態的宣告(如字串數字日期格式等)

資料型態是來描述欄位的方式如一個欄位Last_Name 是一個姓氏可以使用varchar (可變動長度字串) 資料型態

以下是幾個常見的資料庫型態 char(size) 固定長度字串最長為 255 位元 varchar(size) 變動長度字串最大字元數以 size 來指定 number(size) 數值格式可以是整數也可以是小數最大數字以 size 位數判

斷未指定小數位數由系統內定 date 日期格式 number(sized) 數值格式最大數字以 size 位數判斷d 為小數位數整數位

數為 size-d 位

有何限制當資料表被建立通常有一或數個欄位是要使用來做關聯的功

能 例如unique 限制(唯一值)兩筆記錄不可以相同的值 not null (非空值)該欄位一定要輸入資料不可是空的primary key (主鍵)是每一筆記錄識別的主要方式

Drop a table drop table 刪除資料表(其中的資料也會一併刪除)

drop table tablename

Example

81

drop table 和刪除全部資料是不同的刪除全部資料欄位名稱資訊等還會

存在但刪除資料表會把這一些也一併移除掉

如何查詢資料

Select 基本用法

select 語法是關連式資料庫最常用的部份可以取得你想要的資料這是一個

簡單的範例 select column1[column2etc] from tablename [where condition] [] = optional 在 select 之後所列欄位名則是要顯示的資料部份你可以一一列出各欄位

名或是以 (星號)來代表選擇全部的欄位 from 之後放資料表名稱 where 子句 (選項) 指定要過濾的條件符合者才會顯現 where 可使用的條件運算元 = 等於 gt 大於 lt 小於 gt= 大或等於 lt= 小或等於 ltgt 大相等 LIKE 相似 For example select first last city

82

from empinfo where first LIKE Er 以Er 為開頭的字串就符合要以單引號框住 Or you can specify select first last from empinfo where last LIKE s 最後一字為 S 就符合 select from empinfo where first = Eric 則表示 first name 一定要是 Eric 才可以 範例資料表empinfo 統計函數

MIN 傳回指定欄位最小值

MAX 傳回指定欄位最大值

SUM 傳回指定欄位總和

AVG 傳回指定欄位平均值

COUNT 傳回指定欄位的筆數

COUNT() 傳回資料庫中的總筆數

統計函數使用於資料表中的數值欄位配合 SELECT 語法使用 只用於總結特定單一欄位可以配合 GROUP BY 做篩選但也可以不使用 GROUP BY 語句For example

SELECT AVG(salary) FROM employee

83

傳回全部 salary 平均值

Another example

SELECT AVG(salary) FROM employee WHERE title = Programmer

傳回 salary 平均值條件為 employees 資料表中當 title 等於 Programmer

Example

SELECT Count() FROM employees

傳回 employees 資料表中紀錄總筆數

GROUP BY 語法 SELECT column1 SUM(column2) FROM list-of-tables GROUP BY column-list The GROUP BY 語句可以先以所列的欄位為條件分組排序在一起(可以多欄

位) example 要列出每一個 dept 中最高 salary 值 SELECT max(salary) dept FROM employee GROUP BY dept HAVING 語法

SELECT column1 SUM(column2) FROM list-of-tables GROUP BY column-list HAVING condition

HAVING 子句是 GROUP BY 的一部份用來過濾在 GROUP BY 所選出的資料功能如同 select 命令中 where 條件式一樣只是 HAVING 必需配合 GROUP BY 使用

我們以例子來說明我們要取得每一公司名及每一公司的薪水平均值輸入如下

84

SELECT dept avg(salary) FROM employee GROUP BY dept

但如果我們只列出薪資平均值超過 20000元的公司資料

SELECT dept avg(salary) FROM employee GROUP BY dept HAVING avg(salary) gt 20000

ORDER BY子句語法

SELECT column1 SUM(column2) FROM list-of-tables ORDER BY column-list [ASC | DESC]

[ ] =選項

ORDER BY是一個選項子句當你以排序方式來顯示資料(正向由小到大反向由大到小)以指定的欄位資料做排序

ASC = 正向- 預設值 DESC = 反向排序

For example

SELECT employee_id dept name age salary FROM employee_info WHERE dept = Sales ORDER BY salary

以上列出公司代號公司名銷售員人名年紀及薪資而條件是公司名為 Sales 顯示順序以薪資多少排序(由小到大為預設值)

如果要以多個欄位做排序要以逗號做分隔如下

SELECT employee_id dept name age salary FROM employee_info WHERE dept = Sales ORDER BY salary age DESC

85

結合條件及布林運算 SELECT column1 SUM(column2) FROM list-of-tables WHERE condition1 AND condition2 AND運算可以結兩個或以上的條件放在 WHERE子句中 兩者都要為真才

會顯示該筆記錄 OR 運算可以結兩個或以上敘述放在 WHERE子句中只要其中一個為直就

會顯示該筆記錄 For example SELECT employeeid firstname lastname title salary FROM employee_info WHERE salary gt= 5000000 AND title = Programmer 必需要薪資大於等於 50000而且職稱為 Programmer同時符合才會顯示該筆資料 以下以括號括住雖然不是必需的但如此比較容易讀 SELECT employeeid firstname lastname title salary FROM employee_info WHERE (salary gt= 5000000) AND (title = Programmer) 另外範例 SELECT firstname lastname title salary FROM employee_info WHERE (title = Sales) OR (title = Programmer) 條件為只要是 Sales 或 Programmer 職稱的就會被列出 IN and BETWEEN 子句

SELECT column1 SUM(column2) FROM list-of-tables WHERE column3 IN (list-of-values) SELECT column1 SUM(column2) FROM list-of-tables WHERE column3 BETWEEN value1 AND value2 IN 子句使用在列舉項目的使用上也就是分別測試是否符合所列的值 For example

86

SELECT employeeid lastname salary FROM employee_info WHERE lastname IN (Hernandez Jones Roberts Ruiz) 條件為姓氏(astname)要符合 Hernandez Jones Roberts or Ruiz 其中一個才會被傳回 IN運算元也可以使用 OR 的語法來取代如下結果相同 SELECT employeeid lastname salary FROM employee_info WHERE lastname = Hernandez OR lastname = Jones OR lastname = Roberts OR lastname = Ruiz 但使用 IN 句子比較短也比較易懂 你也可以使用 NOT IN 來去掉不要的記錄 BETWEEN 運算元使用在判斷是否存在兩個數值之間 For example SELECT employeeid age lastname salary FROM employee_info WHERE age BETWEEN 30 AND 40 傳回年紀 30歲到 40歲之間的資料(含 30及 40歲者) 相同的也可以使用以下語法來達到相同的結果 SELECT employeeid age lastname salary FROM employee_info WHERE age gt= 30 AND age lt= 40 你也可使用 NOT BETWEEN 來濾掉中間值的資料 數學運算 標準 ANSI SQL-92 提供以下運算

87

+ 加

- 減

餘數

餘數為除法後剩整數這不在標準的 ANSI SQL 中但大部份的資料庫都會支

援這運算元以下列出有用的函數雖不在 ANSI SQL-92 提供但一般資料庫

也會支援他們

ABS(x) 傳回 x 絕對值

SIGN(x) returns the sign of input x as -1 0 or 1 (negative zero or positive respectively)

MOD(xy) 餘數 - returns the integer remainder of x divided by y (同 xy)

FLOOR(x) 傳回小或等於 x 的最大整數值

CEILING(x) or CEIL(x)

傳回大或等於 x 的最小整數值

POWER(xy) x的 y 次方

ROUND(x) 把 x 四捨五入為整數

ROUND(xd) 四捨五入取到小數 d 位

SQRT(x) x 開平方

For example SELECT round(salary) firstname FROM employee_info 傳回薪資取到整數位

如何新增資料

insert 加入一筆新紀錄到資料表中 insert into tablename (first_columnlast_column) values (first_valuelast_value) [] = optional Example insert into employee

88

(first last age address city state) values (Luke Duke 45 2130 Boars Nest Hazard Co Georgia) Note 字串要以單引號住如string 數字框住也無妨 insert into 後面接資料表名稱再接以括號括住的欄位名在 values 後括號分別對映各欄位的值 以上的例子新增了一筆名(first) 為 Luke而住所(state) 為 Georgia 的資料

如何刪除資料

delete 可以刪除單筆或多筆紀錄 delete from tablename where columnname OPERATOR value [and|or column OPERATOR value] [ ] = optional Examples delete from employee Note 如果你沒有指定 where 子句那麼全部的紀錄都會被刪除 delete from employee where lastname = May delete from employee where firstname = Mike or firstname = Eric delete from 接著資料表名 再接著是條件式判斷沒有條件式則全部紀錄會

被刪除

如何更新資料

update 用來更新你所指定的記錄要和 WHERE 配合小心使用 語法 update tablename set columnname = newvalue[nextcolumn = newvalue2] where columnname OPERATOR value [and|or column OPERATOR value] [] = optional Examples

89

update phone_book set area_code = 623 where prefix = 979 update phone_book set last_name = Smith prefix=555 suffix=9292 where last_name = Jones update employee set age = age+1 where first_name=Mary and last_name=Williams

90

附錄二Replication

測試環境

RedHat 90 + MySQL 32358 MySQL資料庫路徑 varlibmysql MySQL設定檔 etcmycnf Master IP 1921680100 Slave IP 1921680200 請至下列網址下載最新MySQL 32358套件並利用rpm ndashUvh 更新 httpupdatesredhatcom9enosi386

圖 最新 MySQL 套件

測試架構圖

91

1921680100

1921680200Master Server

erveSlave S r

圖 測試架構圖

測試步驟

Master server 部份 Step1 確認 MasterSlave機器上所裝的 MySQL版本能進行

replication( 32329 or higher ) Step2 在 Master MySQL上開放一個帳號給 Slave mysql ndashu root ndashp mysqlgtGRANT FILE ON TO repl1921680200 IDENTIFIED BY lsquoabc123rsquo mysqlgtq 上面是 Master開放一個帳號 repl密碼 abc123給 IP1921680200有檔案處理

的權限 Step3 shutdown MySQL on the Master mysqladmin ndashu root ndashp shutdown Step4 備份 Master所有資料庫 tar ndashcvf tmpmysql-snapshottar varlibmysql 注意tar的時候MySQL是要在 stop情況下 在mysql (wwwmysqlcom) 網站的FAQ有不用shutdown的方法

92

Step5 在 master機器上修改etcmycnf 在[mysqld]區段內加入參數 log-bin server-id=這邊設定 server-id=1 sql-bin-update-same binlog-do-db=CRM只針對 CRM資料庫做紀錄 Step6 Restart MySQL on the master service mysqld start 此時因為有加入 log-bin 參數因此開始有 index產生了在varlibmysql目錄下

有index檔案紀錄資料庫的異動 log Slave server 部份 Step1 在 slave設定etcmycnf 在[mysqld]區段加入 master-host= master-user= master-password= master-port= server-id= 這邊設定 master-host=1921680100 master-user=repl master-password=abc123 master-port=3306 server-id=2 master-connect-retry=60預設重試間隔 60秒 replicate-do-db=CRM告訴 slave只做 CRM資料庫的更新 log-slave-updates Step2 將 master上的 mysql-snapshottar copy到 slave上 用 ftp傳到 slave的tmp Step3 解壓縮 Master資料庫至 Slave Server上 cd varlib tar xvf tmpmysql-snapshottar chown ndashR mysqlmysql mysql

93

chmod ndashR 770 mysql (視情況) Step4 Restart MySQL on the slave server 這時在varlibmysql目錄會出現 masterinfo此檔案紀錄了 Master MySQL server的資訊

狀況測試

One-way replication

1921680100

1921680200Master Server

erveSlave S r

圖 One-way replication架構圖 Step1 Master跟 Slave網路及服務都正常情況下由 Master端異動資料後 到 Slave端瀏覽資料檢視是否有進行 replication Step2 模擬 Slave Server 當機 可用在於 slave真的當機或是 Slave 不一定需要一直跟 master connect將Slave MySQL server shutdown由 Master端異動資料到 slave端瀏覽此時Slave應該沒有被 replication 更新然後再將 Slave端 MySQL server start起來

預設 60秒後 Slave會嘗試跟 Master要求進行 replication再去 Slave端檢視是否有更新資料

94

Step3 模擬 Master當機因為是設定 One-way replication一旦 Master Server Slave端沒有 Master的 source可以 download Two-way replication 基於 Master當機狀況於是發展雙向 Replication即 1921680100 ( Host A ) 1921680200 ( Host B )都分別擔任 MasterSlave身分

1921680100

1921680200er

Server B MasterSlave Server

Server A MasterSlave Serv

圖 Two-way replication架構圖 以下是針對兩台 MySQL伺服器進行雙向 Replication Step1觀念同單向 replication只是改成 Master也有 Slave身分 Slave也有Master的身分先分別在 Server AServer B 都去 grant一個進行 replication的身分 [A]mysqlgtGRANT FILE ON TO repl1921680200 IDENTIFIED BY lsquoabc123rsquo [B]mysqlgt GRANT FILE ON TO repl1921680100 IDENTIFIED BY lsquoabc123rsquo Step2做完單向 replication後stop Server Aserver B MySQL service此時 AB資料是一樣的

95

修改etcmycnf設定 範例 Server A [mysqld] datadir=varlibmysql socket=varlibmysqlmysqlsock server-id=1 log-bin sql-bin-update-same binlog-do-db=CRM master-host=1921680200 master-user=repl master-password=abc123 log-slave-updates master-connect-retry=60 replicate-do-db=CRM Server B [mysqld] datadir=varlibmysql socket=varlibmysqlmysqlsock server-id=2 log-bin sql-bin-update-same binlog-do-db=CRM master-host=1921680100 master-user=repl master-password=abc123 log-slave-updates master-connect-retry=60 replicate-do-db=CRM 分別 start Server AServer B MySQL後此時雙方都是 MasterSlave身分一旦哪一方資料異動就會通知對方來 replication-若 replication失效則必須將Server AServer B的masterinfo及index00x 都砍掉然後分別 restart MySQL server進行測試檢視成果 實務上通常如果需要做Two-way replication通常會搭配Virtual Server使用

96

在前端架設一台Virtual Server不過此部份不在此份SOP討論範圍內有興趣

的讀者可參考 httpwwwlinuxvirtualserverorg 網站

1921680100 1921680200

Host A MasterSlave Server

Host B MasterSlave Server

Virtual Host

圖 Virtual Server + Two-way replication 架構圖

97

圖 High Availability Linux Virtual Server架構圖

98

  • COSA-SOP-03-006
  • 第一章 簡介
    • 11適用對象 (Audience)
    • 12 MySQL本身
    • 13 MySQL 40版跟50版重大的改進功能
    • 14 各家資料庫軟體比較
      • 第二章 前置需求
      • 第三章 安裝
        • 31 MySQL安裝
        • 32 phpMyAdmin安裝
        • 33 升級及注意事項
          • 第四章 MySQL管理
            • 41 Webmin 管理介面
            • 42 phpMyAdmin 的操作介面
            • 43管理指令介紹
              • 431 利用mysqladmin設定root的密碼
                  • 第五章 實用範例
                    • 51 任務一Web Base客戶通訊錄
                    • 52 任務二Web Base群組軟體 ( twig )
                      • 第六章 維護及更新程序
                        • 61 日常維護
                        • 62 更新程序
                        • 63 備份重要檔案
                        • 64 離線備份與還原
                        • 65 線上備份與還原
                          • 第七章 問題與解答
                          • 第八章 參考資料
                          • 附錄一 SQL Command 介紹
                          • 附錄二Replication
Page 51: DataBase Server Standard Operation Procedureebooks.lib.ntu.edu.tw/1_file/oss/63/93doc4-5.pdf · 業務的公司帶來了不少壓力,譬如微軟,甲骨文 ... 外的錢用在第三方的資料庫產品上,譬如就可以不用再購買甲骨文公司

我們將這些檔案放至varwwwhtmlbluepage (預設無 bluepage目錄)

512 Web Base通訊錄測試

httpwwwopencombluepage 新增資料

圖 5-1 新增連絡人

圖 5-2 填入資料

51

圖 5-3 新增成功

搜尋及異動資料

圖 5-4 搜尋通訊錄

52

圖 5-5 編輯資料

圖 5-6 更新資料

513 程式內容及說明

lt-- 程式範例indexhtml--gt lthtmlgt ltheadgtlttitlegt通訊錄lttitlegtltheadgt ltbodygt ltcentergt

53

lth2gt通訊錄lth2gtlthrgt lta href=indexhtmlgt通訊錄ltagt | lta href=addphpgt新增連絡人ltagt | lta href=searchphpgt搜尋通訊錄ltagt ltcentergt ltbodygt lthtmlgt lt-- 程式範例addphp --gt lthtmlgt ltheadgtlttitlegt新增連絡人lttitlegtltheadgt ltbodygt ltcentergtlth2gt新增連絡人lth2gtltcentergtlthrgt lt 取得欄位資料 if (isset($_POST[Name]) ampamp isset($_POST[Tel]) ) $name = $_POST[Name] $tel = $_POST[Tel] 檢查是否有輸入欄位資料 if ($name = ampamp $tel = ) 建立 SQL字串 $sql = INSERT INTO address (name tel) values( $sql= $name $tel) 建立 MySQL 連結 $link = mysql_connect(localhostroot1234) 選擇資料庫 mysql_select_db(CONTACT) 執行 SQL指令 mysql_query($sql) mysql_close($link) echo ltfont color=redgt新增連絡人成功ltfontgtltbrgt gt ltform action=addphp method=postgt lttable border=0 width=300gt lttrgtlttdgt姓名 lttdgt

54

lttdgtltinput type=text name=Name size=20 maxlength=10gtlttdgtlttrgt lttrgtlttdgt電話 lttdgt lttdgtltinput type=text name=Tel size=20 maxlength=20gtlttdgtlttrgt lttrgtlttd colspan=2 align=centergt ltinput type=submit value=新增連絡人gtlttdgtlttrgt lttablegt ltformgt ltbrgtlta href=indexhtmlgt通訊錄ltagt | lta href=addphpgt新增連絡人ltagt | lta href=searchphpgt搜尋通訊錄ltagt ltbodygt lthtmlgt

lt-- 程式範例searchphp --gt lthtmlgt ltheadgtlttitlegt搜尋通訊錄lttitlegtltheadgt ltbodygt ltcentergtlth2gt搜尋通訊錄lth2gtlthrgt lt if (isset($_POST[Search])) 建立資料庫連結並選定資料庫 $link = mysql_connect(localhostroot1234) mysql_select_db(CONTACT) 建立基本的 SQL字串 $sql = SELECT FROM address 檢查是否輸入姓名 if (chop($_POST[Name]) = ) $name = name LIKE $_POST[Name] else $name = 檢查是否輸入電話號碼 if (chop($_POST[Tel]) = ) $tel = tel LIKE $_POST[Tel] else $tel =

55

if條件組合 SQL字串 if (chop($name) = ampamp chop($tel) = ) $sql= WHERE $name AND $tel elseif (chop($name) = ) 只有姓名 $sql = WHERE $name elseif (chop($tel) = ) 只有電話號碼 $sql = WHERE $tel $sql= ORDER BY name 最後加上排序 $result = mysql_query($sql) 取得欄位數 $total_fields = mysql_num_fields($result) echo lttable border=1gt echo lttrgtlttdgt編號lttdgtlttdgt姓名lttdgtlttdgt電話lttdgtlttd colspan=2gt功能選項lttdgtlttrgt 表格顯示查詢結果 while ($rows = mysql_fetch_array($result MYSQL_NUM)) echo lttrgt for ($i = 0 $i lt $total_fields $i++) echo lttdgt$rows[$i]lttdgt echo lttdgtlta href=editphpaction=editampid= echo $rows[0]gtltbgt編輯ltbgtlttdgt echo lttdgtlta href=editphpaction=delampid= echo $rows[0]gtltbgt刪除ltbgtlttdgt echo lttrgt echo lttablegtlthrgt mysql_free_result($result) mysql_close($link) gt ltcentergt ltform action=searchphp method=postgt lttable border=0 width=450gt lttrgtlttdgt搜尋姓名 lttdgt lttdgtltinput type=text name=Name size=10 maxlength=20gtlttdgtlttrgt lttrgtlttdgt搜尋電話 lttdgt lttdgtltinput type=text name=Tel

56

size=20 maxlength=20gtlttdgtlttrgt lttrgtlttd colspan=2 align=centergt ltinput type=submit name=Search value=搜尋gtlttdgtlttrgt lttablegt ltformgt ltbrgtlta href=indexhtmlgt通訊錄ltagt | lta href=addphpgt新增連絡人ltagt | lta href=searchphpgt搜尋通訊錄ltagt ltbodygt lthtmlgt

lt ob_start() gt lt-- 程式範例editphp --gt lthtmlgt ltheadgtlttitlegt編輯通訊錄lttitlegtltheadgt ltbodygt lt 取得 URL 參數 $id = $_GET[id] $action = $_GET[action] 建立資料庫連結 $link = mysql_connect(localhostroot1234) mysql_select_db(CONTACT) 選擇資料庫 執行的操作 switch ($action) case update 更新 取得欄位資料 $name = $_POST[Name] $tel = $_POST[Tel] $sql = UPDATE address SET name=$name tel=$tel WHERE id=$id mysql_query($sql) 執行 SQL指令 mysql_close($link) header(Location searchphp) 轉向到 serachphp break case del 刪除 $sql = DELETE FROM address WHERE id=$id

57

mysql_query($sql) 執行 SQL指令 mysql_close($link) header(Location searchphp) 轉向到 serachphp break case edit 編輯 $sql = SELECT FROM address WHERE id=$id $result = mysql_query($sql) 執行 SQL指令 $row = mysql_fetch_row($result) 取回記錄 $name = $row[1] 取得欄位 name $tel = $row[2] 取得欄位 tel mysql_close($link) 顯示編輯表單 gt ltcentergtlth2gt更新通訊錄lth2gtltcentergtlthrgt ltform action=editphpaction=updateampid=lt echo $id gt method=postgt lttable border=0 width=300gt lttrgtlttdgt姓名 lttdgt lttdgtltinput type=text name=Name size=20 maxlength=10 value=lt echo $name gtgtlttdgtlttrgt lttrgtlttdgt電話 lttdgt lttdgtltinput type=text name=Tel size=20 maxlength=20 value=lt echo $tel gtgtlttdgtlttrgt lttrgtlttd colspan=2 align=centergt ltinput type=submit value=更新連絡人gtlttdgtlttrgt lttablegt ltformgt ltbrgtlta href=indexhtmlgt通訊錄ltagt | lta href=addphpgt新增連絡人ltagt | lta href=searchphpgt搜尋通訊錄ltagt lt break gt ltbodygt lthtmlgt

58

52 任務二Web Base群組軟體 ( twig )

順利完成Web Base客戶通訊錄程式測試一段時間後「Apache + MySQL + PHP」架構的穩定與快速巳深得老闆與公司所有同事的認同隨著公司業績蒸

蒸日上人員組織編罝愈來愈龐大跨部門的會議愈來愈多業務員每日排滿拜

訪客戶的行程跟客戶的 Email的往來也愈來愈頻繁 愈來愈多部門的同事希望公司能建置一套群組軟體提供 web mail可讓業

務人員方便收發 mail還有連絡人議事日程待辦工作書簽等功能讓整個

公司運作及個人時間管理更有效率

老闆問小明對這些需求有什麼看法小明認為如果這些功能完全由程式部

門開發必定曠日費時而且耗費公司資源小明在網路尋找是否有提供這些功能

的Free Software皇天不負苦心人小明發現了TWIG (The Web Information Gateway) httptwigscrewdrivernet這個群組軟體它在 Web 上整合郵件新聞聯絡人議事日程工作序書簽等功能非常符合公司的需求 Step 1 下載 twig-277targz 下載網址 httptwigscrewdrivernetdownloadphp3

Step 2 解開 twig-277targz tar -xzvf twig-277targz

59

Step 3 執行安裝動作安裝到 varwwwhtmltwig 目錄 cd twig-277 twig-install varwwwhtmltwig

Step 4 建立 MySQL 資料庫(twig)及各資料表

cd setup mysql -u root -p1234 mysqlgt create database twig Query OK 1 row affected (001 sec) mysqlgt quit mysql -u root ndashp1234 twiglt twigtablemysql

Step 5 修改 configincphp3 參數設定 vi varwwwhtmltwigconfigconfigincphp3 $config[fromdomain] = opencom 網域 $config[language] = chinesebig5 中文訊息 $config[imap_port] = 143notls

60

Step 6 修改連結 MySQL 的帳號密碼 vi varwwwhtmltwigconfigdbconfigincphp3 $dbconfig[sqlusername] = root username $dbconfig[sqlpassword] = 1234 password

Step 7 其他設定檔

vi etchttpdconfhttpdconf 加入 AddType applicationx-httpd-php php3 在 DirectoryIndex最後加入 indexphp3 DirectoryIndex indexhtml indexhtmlvar indexphp3 在 AddDefaultCharset ISO-8859-1加上 AddDefaultCharset ISO-8859-1

vi etcphpini register_globals = On service httpd restart Step 8 sendmail 設定 vi etcmailsendmailcf在 264 行前面加上並重新啟動 sendmail「service snedmail restart」 262 SMTP daemon options 263 264 O DaemonPortOptions=Port=smtpAddr=127001 Name=MTA 265 266 SMTP client options 267 O ClientPortOptions=Family=inet Address=00

61

Step 9 檢查設定有無錯誤 http主機名稱twigtestphp3

62

Step 10 登入 twig ( http主機名稱twig)

63

第六章 維護及更新程序

61 日常維護

系統管理員最好定期以 root 身份登入看看信件在 RedHat Linux 中有一支 logwatch 程式會定時去分析 log file如果發現異常便會發信給 root除此之外筆者建議讀者平時就檢查 MySQL log file ( varlogmysqldlog)是否有異常情形

62 更新程序

讀者可至httprpmfindnet 尋找MySQL相關套件至於升級的相關步驟請參

考Linux OS SOP 第 54節

63 備份重要檔案

預設 MySQL 的 DB 檔案是存在 varlibmysql 內以 DB名稱為目錄目錄

內就是該 DB 的所有資料通常得定期備份還有 MySQL的設定檔 etcmycnf也別忘了一起備份

64 離線備份與還原

641 離線備份

預設 MySQL 的 DB 檔案是存在 varlibmysql 內以 DB 名稱為目錄目錄內

就是該 DB 的所有資料像 CRM 這個 DB就是存在 varlibmysqlCRM 內在備份前因為怕資料尚未完全寫入磁碟而且 MySQL 會 Lock 在使用的 DB 檔案所以應該是要先把 MySQL 先 Shutdown 一下整個備份的程序可以下像下面的指令去完成 cd varlibmysql

64

service mysqld stop tar cvfz CRM_db_20030905tgz CRM service mysqld start 對這樣就可以了 不過要注意的是怕 DB 內每個 Tables 間的資料有關關

聯性所以最好是把整個 DB 一次備起來單獨只備哪個 Tables 的檔案以後回存時怕會有資料關聯不一致的問題

642 離線還原

DB 發生錯誤而要回存時其實也不難先找出最近一次完整正常的備份先把現在錯誤的網頁或 DB 先更名或 tar 起來再把好的備份給解開回原來目錄位

置就行了需要注意的是 MySQL 服務最好也是要先停止回存完成後再啟動服務回存 DB 的整個程序可能像下面 cd varlibmysql service mysqldstop mv CRM CRM_OLD tar xvfz CRM_db_20030905tg service mysqld start

65 線上備份與還原

651 線上備份

使用像上面的檔案方式備份是個不錯的方法它最少可以保持該主機某個時間點的完整檔案備份但還是有一些問題需要考慮到有些主機就不只建立一個 DB 而已總不能為了備份某個 DB 而把整個 MySQL 服務停止備份檔案的方式回存在原主機上一定適用但假如 MySQL 版本升級或是在那天該網頁空間需遷機移機到別的主機時那就沒人敢保證備出來的資料檔可以用所以我們可以考慮另一種備份的方式是使用 MySQL 本身提供的功能 MySQL Data Dump指令是 mysqldump

65

使用 MySQL 的 Dump 功能可以把 DB 的結構資料或結構加資料 Dump 成文字檔 mysqldump 指令提供的彈性很大你可以選擇把整個 DB Dump 成一個檔或是每個 Table 為一個檔甚至是把結構檔和資料分開儲存都

可以 mysqladmin -uroot -p flush-logs mysqldump CRM -uroot -p --opt gt CRM_20030905sql (CRM 是 DB 名稱 opt 是一個使用完整 Dump 參數) 假如只是要單獨 Dump 某個 Table 時只要在上面的指令後轉出符號 gt 前加個 Table 名稱就可以如只要 phpbb2_users 這個 Table 的 Dump 時只要下 mysqldump CRM -uroot -p --opt CUSTOMER gt CRM_CUSTOMER_20030905sql

652 線上還原

若要回存整個資料庫只需將壓縮的備份檔還原成 Dump 的檔案再用下面的指令回存 mysql CRM -uroot -p lt CRM_20030905sql 這邊需注意的是若建立備份時是以--opt或--add-drop-table為參數時回存的 動作是先將舊的 Table 先刪除重建 Table 的結構後再把 Data 匯入所以回存後所有的資料會回到你當時備份那個時間點因此在回存資料時可以考慮把現有錯誤或不完整的 DB 先備份一份下來以備不時之需或是拿來比對錯誤的地

方在那裡當然你也可以把資料回存到另一個測試用的 DB 內只要把上面指令

的 DB 名稱改成你的測試用 DB 名稱即可 使用這種回存方式 MySQL 服務不需停止也不會動到其他正在使用的 DB 在一些提供 MySQL 服務的虛擬主機可用這種方式作你自己的 DB 備份及回存

66

另外假如你是系統重建或是移機時切需在新的 MySQL 內新建一個空白 DB 後才行作回存的工作你可以用下面的指令建立 mysql -uroot -p -e CREATE DATABASE CRM (上面的 CRM是你要新建的 DB 名稱) 另一種作法先用 mysql 指令進入 mysql client console 然後再用 CREATE DATABASE CRM 這樣就行了記得尾端要加個 符號該行指令才會執行

67

第七章 問題與解答

Q1RedHat 90預附的 MySQL到底有無支援 Transcation機制 Ans MySQL自 32334a之後的 MySQL-Max版本加入 InnoDB的資料庫類型透過

InnoDBMySQL同樣可以進行 COMMIT與 ROLLRACK的動作RedHat 90預附的 MySQL為 32354a-11巳支援 InnoDB的資料庫類型不過必須做以

下設定 1cp usrsharedocmysql-server-32354amy-mediumcnf to etcmycnf 2 vi etcmycnf 將以下設定前的拿掉 innodb_data_home_dir = varlibmysql innodb_data_file_path = ibdata110Mautoextend innodb_log_group_home_dir = varlibmysql innodb_log_arch_dir = varlibmysql 3service mysqld restart 如此一來各位在建立Table時便可指定Table Type為 innodb ( ex create table with type=innodb ) Q2如何解決 php+mysql 許功蓋等字變亂的問題 Ans 方法一 【確定 MySQL 預設的字元集】 1 打開 WinMySQLadmin 管理畫面(在視窗右下角狀態列紅綠燈圖示中按滑鼠

右鍵點選 Show me 選項) 2 點選管理畫面中 [Variables] 標籤選項其中 character_set變數就是您預設

字元集的變數其預設是 latin1 字元集(我們要將他改回 big5)而 chatacters_set 變數則是 MySQL 可以支援哪些字元集 【修改預設字元集變數 character_set 】 1 請點選管理畫面中 [myini Setup] 標籤選項設定 myini 2 按一下 [Pick-up and Edit myini values] 按鈕以便編輯目前的 myini 設定 3 在 [mysqld] 設定區塊底下新增一行 default-character-set = big5 變數設

68

定 4 新增一個 [client] 設定區塊並加入第三步驟的變數設定(游標往下移到空白處新增兩行 [client] 和 default-character-set=big5) 5 按一下畫面左下方 [Save Modification] 按鈕儲存設定 6 重新啟動 MySQL 或 Windows 方法二 Server端注意事項 phpini 中有關的設定為(預設值) Magic quotes for incoming GETPOSTCookie data magic_quotes_gpc = On Use Sybase-style magic quotes (escape with instead of ) magic_quotes_sybase = Off Client端注意事項 1中文資料送進 mysql 前請用 addslashes($str) 處理 2處理後送進 mysql 時請用 括起來並在參數後留一個空白如 $sql = UPDATE ezf_table set tablename=$tname tableend=$endtime table inguser=$tguser tableingid=$tguserid tableallnumber=$tnumber tableloca l=$tablelocal tableanyone=$tableopen tabletext=$ttext WHERE tableid=$t ableid tablename=$tname c 取出時請用 stripslashes($str) Q3MySQL root 密碼忘了該怎麼辦 Ans 1先停掉 mysql etcrcdinitdmysql stop 2以--skip-grant-table 的參數啟動 mysql safe_mysql --skip-grant-tableamp 3 更改 root 密碼 mysql mysql mysqlgt UPDATE user SET password=password(newpassword)

69

WHERE user=root mysqlgt FLUSH PRIVILEGES mysqlgt exit 4停掉 mysql再重跑 mysqladmin -uroot -p shutdown Enter password 輸入新設定的密碼 etcrcdinitdmysql start

Q4NULL值問題

Ans

NULL值的概念是造成 SQL的新手的混淆的普遍原因他們經常認為 NULL是和一個空字符串的一樣的東西不是這樣的例如下列語句是完全不同的

mysqlgt INSERT INTO my_table (phone) VALUES (NULL)

mysqlgt INSERT INTO my_table (phone) VALUES ()

兩個語句把值插入到 phone 列但是第一個插入一個 NULL值而第二個插入一個空字符串第一個的含義可以認為是ldquo電話號碼不知道而第二個則可意味

著ldquo她沒有電話

在 SQL中NULL值在于任何其他值甚至 NULL值比較時總是假的(FALSE)包含 NULL的一個表達式總是產生一個 NULL值除非在包含在表達式中的運算符和函數的文檔中指出在下列例子所有的列返回 NULL

mysqlgt SELECT NULL1+NULLCONCAT(InvisibleNULL)

如果你想要尋找值是 NULL的列你不能使用=NULL測試下列語句不返回任

何行因為對任何表達式expr = NULL是假的

mysqlgt SELECT FROM my_table WHERE phone = NULL

要想尋找 NULL值你必須使用 IS NULL測試下例顯示如何找出 NULL電話號碼和空的電話號碼

70

mysqlgt SELECT FROM my_table WHERE phone IS NULL mysqlgt SELECT FROM my_table WHERE phone =

在 MySQL中就像很多其他的 SQL服務器一樣你不能索引可以有 NULL值的列你必須聲明這樣的列為 NOT NULL而且你不能插入 NULL到索引的

列中

當用 LOAD DATA INFILE 讀取數據時空列用更新如果你想要在一個列中有

NULL值你應該在文本文件中使用N字面上的詞NULL也可以在某些情形下使用

當使用 ORDER BY時首先呈現 NULL值如果你用 DESC以降序排序NULL值最後顯示當使用 GROUP BY時所有的 NULL值被認為是相等的

為了有助于NULL的處理你能使用 IS NULL和 IS NOT NULL運算符和 IFNULL()函數

對某些列類型NULL值被特殊地處理如果你將 NULL插入表的第一個TIMESTAMP 列則插入當前的日期和時間如果你將 NULL插入一個AUTO_INCREMENT 列則插入順序中的下一個數字

Q5如何將圖片存放於 MySQL中

Ans

Step 1建立資料庫 test

Step 2 建立表格 binary_data

CREATE TABLE binary_data (

id INT(4) NOT NULL AUTO_INCREMENT PRIMARY KEY

description CHAR(50)

bin_data LONGBLOB

filename CHAR(50)

filesize CHAR(50)

filetype CHAR(50)

71

)

Step 3 利用 storephp 寫入圖片

storephp 程式碼

ltHTMLgt ltHEADgtltTITLEgtStore binary data into SQL DatabaseltTITLEgtltHEADgt ltBODYgt lt code that will be executed if the form has been submitted

if ($submit) mysql_connect(localhostrootYOUR_PASSWORD) mysql_select_db(test) $data=Base64_Encode(fread(fopen($form_data r) filesize($form_data))) $result=MYSQL_QUERY(INSERT INTO binary_data (descriptionbin_datafilenamefilesizefiletype) VALUES ($form_description$data$form_data_name$form_data_size$form_data_type)) $id= mysql_insert_id() print ltpgtThis file has the following Database ID ltbgt$idltbgt MYSQL_CLOSE() else else show the form to submit new data

gt

ltform method=post action=ltphp echo $PHP_SELF gt enctype=multipartform-datagt File Descriptionltbrgt ltinput type=text name=form_description size=40gt ltINPUT TYPE=hidden name=MAX_FILE_SIZE value=4000000gt ltbrgtFile to uploadstore in databaseltbrgt ltinput type=file name=form_data size=40gt ltpgtltinput type=submit name=submit value=submitgt ltformgt lt

72

gt ltBODYgt ltHTMLgt

Step 3 利用 storephp 取出圖片

getdataphp 程式碼

lt Syntax getdataphp3id=ltidgt if($id) you may have to modify login information for your database server MYSQL_CONNECT(localhostrootYOUR_PASSWORD) mysql_select_db(test) $query = select bin_datafiletype from binary_data where id=$id $result = MYSQL_QUERY($query) $data = Base64_Decode(MYSQL_RESULT($result0bin_data)) $type = MYSQL_RESULT($result0filetype) Header( Content-type $type) echo $data gt

Q6MySQL裝好之後啟動時或是執行 mysqladmin會出現如下訊息 Cant connect to local MYSQL Server through Socket varlibmysqlmysqlsock或是

Cant connect to local MYSQL Server through Socket tmpmysqldsock

Ans 可能有下列幾個原因

1這個 mysqldsock 不見了被某人刪除了或是被一些系統自動執行程式給刪

了例如有些 cron任務便會設定定期刪除 tmp 裡的東西所以呢您只能修改

cron 裡的設定讓它不要清除 mysqldsock 2在啟動時也可以改變 mysqldsock的位置您在啟動 MySQL的時候可以加入此參數usrlocalmysqlbinsafe_mysqld --user=mysql --socket=其他路

徑socket amp 同時得去設定環境變數 MYSQL_UNIX_PORT的值以指定新的

73

路徑 3若是您沒改 MYSQL_UNIX_PORT的值那麼您可以在執行指令的時候才打

例如mysqladmin --socket=其他路徑socket version Q7How to get the last insert id Ans CREATE TABLE product ( id INT(4) NOT NULL AUTO_INCREMENT PRIMARY KEY description VARCHAR(50) ) 1利用 SQL的話 mysqlgt insert into product(description) values(123) Query OK 1 row affected (000 sec) mysqlgt select last_insert_id() +------------------+ | last_insert_id() | +------------------+ +------------------+ 1 row in set (000 sec) ======================================== 2如果是 PHP的話 你可以用mysql_insert_id()取得該 id PHP example $result=MYSQL_QUERY(INSERT INTO product (description) VALUES ($description)) $id= mysql_insert_id() print This file has the following Database ID $id Q8如何將文字檔匯入資料庫 Ans $addr=homehttpdhtmlphpschool001txt $sql_select = load data infile $addr into table test fields terminated by t 解說 $sql_select = load data infile 文字檔名 into table 表格名 fields terminated by

74

t

(欄位分隔以 TAB鍵) 該文字檔須與資料表欄位格式相符 例如欄位有三個 則文字檔為每行一筆資料如下 欄 1資料ltTABgt欄 2資料ltTABgt欄 3資料 欄 1資料ltTABgt欄 2資料ltTABgt欄 3資料 欄 1資料ltTABgt欄 2資料ltTABgt欄 3資料 欄 1資料ltTABgtltTABgt欄 3資料

Q9如何撰寫 MySQL C API Ans Step 1利用文字編輯器撰寫以下程式碼 mysqlcc

include ltstdiohgt

include ltmysqlmysqlhgt

int main (int argc char argv[])

MYSQL mysql

MYSQL_RES res

MYSQL_ROW row

if (argc = 2)

fputs (Usage myc ltdatabasegt stderr)

return 1

if ((mysql_connect(ampmysqllocalhostrootYour_Password)))

fputs (Error connecting stderr)

abort()

75

if (mysql_select_db(ampmysqlargv[1]))

fputs (Error selecting database stderr)

abort()

if (mysql_query(ampmysqlSELECT FROM test_table))

fputs (Error processing query stderr)

abort()

if ((res = mysql_store_result(ampmysql)))

fputs (Error storing results stderr)

abort()

while((row = mysql_fetch_row(res)))

uint i = 0

for (i=0 i lt mysql_num_fields(res) i++)

printf(s row[i])

printf(n)

return 0

Step 2 Compile

gcc -Iusrlocalmysqlinclude -Lusrlocalmysqllibmysql mysqlcc ndashlm -lmysqlclient

(其中 include path與 library path取決於你的 MySQL安裝路徑)

76

如果執行時發生如下 error Run problemerror in loading shared libraries libmysqlclientsoX 將你的 MySQL library path(for exampleusrlocalmysqllibmysql) 加入etcldsoconf and run sbinldconfig -v Q9ASP + MySQL 範例程式 Ans Dim myconn As New ADODBConnection Dim myrs As New Recordset Dim mySQL As String Dim myrows As Long myconnOpen DSN=MyODBCsample mySQL = SELECT from user myrsSource = mySQL Set myrsActiveConnection = myconn myrsCursorLocation = adUseClient myrsOpen myrows = myrsRecordCount myrsClose myconnClose 可參考 httpwwwdwamnetmysqlasp_myodbcasp 有詳細的資料 Q10如何將 MySQL中的資料庫匯出成txt檔 Ans select from TableName into outfile textxls all result fields will seperate by tab

77

第八章 參考資料

英文部份 網址 1 httpwwwmysqlcom MySQL 網站有第一手有關 MySQL的資料 2 httpwwwmysqlcomdocenReplicationhtml 有關 MySQL Replication 的文件 3 httpwwwgeocitiescomsqlhomefaqstore_blobhtml 如何在 MySQL 存放 BLOB的資料 4httpwwwsapdborg 有關 SAP跟 MySQL相關合作的網站 書藉 1 Cooking with MySQL

Paul DuBois has selected sample recipes from the hundreds youll find in his book MySQL

Cookbook In this third and final series of excerpts showcasing these recipes learn how to

compute team standings how to calculate the differences between successive Dec 26

2002 2 Tips for Building Web Database Applications with PHP and MySQL by Hugh E Williams co-author of Web Database Applications with PHP amp MySQL 04042002

3 Managing and Using MySQL 2nd Edition By Tim King George Reese Randy Jay Yarger

4 MySQL Cookbook By Paul DuBoisPublisher OReillyPub Date October 2002

中文部份

78

1 httplinuxtncedutwtechdocmysqlmysql_docmanual_tochtml MySQL 中文手冊 2 httpchenshloxaedutwphpZ_1php PHP+MySQ程式研習設計網站 3 httplinuxtncedutwtechdocbanicdownhtml PHP 4 手冊 4 httpwwwtncedutwadmin_zonephp台南縣教育網網路中心有很多 Linux相關文件 5 httpdobtncedutw網站建置百寶箱有很多 PHP MySQL 相關範例程式 5 httpwwwdbworldcomtw資料庫專家電子雜誌介紹資料庫的重要觀念及名詞

79

附錄一 SQL Command 介紹

SQL (讀音ess-que-el) 是一種結構查詢語法SQL 使用於資料庫交流

傳遞相容於 ANSI (American National Standards Institute) 是一套標準的關聯

式資料庫語言 SQL 語言是執行更新或從資料系統獲取資料一般常見的關聯

資料庫系統都有提供 SQL 如 Oracle Sybase Microsoft SQL Server Access Ingres 等雖然大部份的資料庫都有提供 SQL 但也多提供了自已獨特的語

法造成了不相容的情形但標準基本的語法是相通的如Select Insert Update Delete Create and Drop 每一個系統都有支援

Table相關 Command

Create Table

關聯式資料庫包含有很多元件稱為資料表(tables) 把資料或訊息放在資

料表中 資料表是以不同的名稱做分別資料表由欄列所構成的二維陣列

欄包含欄位名資料型態 及其他可判斷的資訊列是由全部欄位構成一筆一

筆的紀錄 create table 語法用在建立一個新的資料表語法格式如下

create table tablename (column1 data type column2 data type column3 data type)

Format of create table if you were to use optional constraints

create table tablename (column1 data type [constraint] column2 data type [constraint] column3 data type [constraint]) [ ] = optional

Note You may have as many columns as youd like and the constraints are optional

80

Example

create table employee (first varchar(15) last varchar(20) age number(3) address varchar(30) city varchar(20) state varchar(20))

注意建立資料表格式要以括號把前後框住而最後以(分號)做結尾

欄位名不要超過 30個字元長而且不要使用 sql 的關鍵字(如 where select等)而在後面接是型態的宣告(如字串數字日期格式等)

資料型態是來描述欄位的方式如一個欄位Last_Name 是一個姓氏可以使用varchar (可變動長度字串) 資料型態

以下是幾個常見的資料庫型態 char(size) 固定長度字串最長為 255 位元 varchar(size) 變動長度字串最大字元數以 size 來指定 number(size) 數值格式可以是整數也可以是小數最大數字以 size 位數判

斷未指定小數位數由系統內定 date 日期格式 number(sized) 數值格式最大數字以 size 位數判斷d 為小數位數整數位

數為 size-d 位

有何限制當資料表被建立通常有一或數個欄位是要使用來做關聯的功

能 例如unique 限制(唯一值)兩筆記錄不可以相同的值 not null (非空值)該欄位一定要輸入資料不可是空的primary key (主鍵)是每一筆記錄識別的主要方式

Drop a table drop table 刪除資料表(其中的資料也會一併刪除)

drop table tablename

Example

81

drop table 和刪除全部資料是不同的刪除全部資料欄位名稱資訊等還會

存在但刪除資料表會把這一些也一併移除掉

如何查詢資料

Select 基本用法

select 語法是關連式資料庫最常用的部份可以取得你想要的資料這是一個

簡單的範例 select column1[column2etc] from tablename [where condition] [] = optional 在 select 之後所列欄位名則是要顯示的資料部份你可以一一列出各欄位

名或是以 (星號)來代表選擇全部的欄位 from 之後放資料表名稱 where 子句 (選項) 指定要過濾的條件符合者才會顯現 where 可使用的條件運算元 = 等於 gt 大於 lt 小於 gt= 大或等於 lt= 小或等於 ltgt 大相等 LIKE 相似 For example select first last city

82

from empinfo where first LIKE Er 以Er 為開頭的字串就符合要以單引號框住 Or you can specify select first last from empinfo where last LIKE s 最後一字為 S 就符合 select from empinfo where first = Eric 則表示 first name 一定要是 Eric 才可以 範例資料表empinfo 統計函數

MIN 傳回指定欄位最小值

MAX 傳回指定欄位最大值

SUM 傳回指定欄位總和

AVG 傳回指定欄位平均值

COUNT 傳回指定欄位的筆數

COUNT() 傳回資料庫中的總筆數

統計函數使用於資料表中的數值欄位配合 SELECT 語法使用 只用於總結特定單一欄位可以配合 GROUP BY 做篩選但也可以不使用 GROUP BY 語句For example

SELECT AVG(salary) FROM employee

83

傳回全部 salary 平均值

Another example

SELECT AVG(salary) FROM employee WHERE title = Programmer

傳回 salary 平均值條件為 employees 資料表中當 title 等於 Programmer

Example

SELECT Count() FROM employees

傳回 employees 資料表中紀錄總筆數

GROUP BY 語法 SELECT column1 SUM(column2) FROM list-of-tables GROUP BY column-list The GROUP BY 語句可以先以所列的欄位為條件分組排序在一起(可以多欄

位) example 要列出每一個 dept 中最高 salary 值 SELECT max(salary) dept FROM employee GROUP BY dept HAVING 語法

SELECT column1 SUM(column2) FROM list-of-tables GROUP BY column-list HAVING condition

HAVING 子句是 GROUP BY 的一部份用來過濾在 GROUP BY 所選出的資料功能如同 select 命令中 where 條件式一樣只是 HAVING 必需配合 GROUP BY 使用

我們以例子來說明我們要取得每一公司名及每一公司的薪水平均值輸入如下

84

SELECT dept avg(salary) FROM employee GROUP BY dept

但如果我們只列出薪資平均值超過 20000元的公司資料

SELECT dept avg(salary) FROM employee GROUP BY dept HAVING avg(salary) gt 20000

ORDER BY子句語法

SELECT column1 SUM(column2) FROM list-of-tables ORDER BY column-list [ASC | DESC]

[ ] =選項

ORDER BY是一個選項子句當你以排序方式來顯示資料(正向由小到大反向由大到小)以指定的欄位資料做排序

ASC = 正向- 預設值 DESC = 反向排序

For example

SELECT employee_id dept name age salary FROM employee_info WHERE dept = Sales ORDER BY salary

以上列出公司代號公司名銷售員人名年紀及薪資而條件是公司名為 Sales 顯示順序以薪資多少排序(由小到大為預設值)

如果要以多個欄位做排序要以逗號做分隔如下

SELECT employee_id dept name age salary FROM employee_info WHERE dept = Sales ORDER BY salary age DESC

85

結合條件及布林運算 SELECT column1 SUM(column2) FROM list-of-tables WHERE condition1 AND condition2 AND運算可以結兩個或以上的條件放在 WHERE子句中 兩者都要為真才

會顯示該筆記錄 OR 運算可以結兩個或以上敘述放在 WHERE子句中只要其中一個為直就

會顯示該筆記錄 For example SELECT employeeid firstname lastname title salary FROM employee_info WHERE salary gt= 5000000 AND title = Programmer 必需要薪資大於等於 50000而且職稱為 Programmer同時符合才會顯示該筆資料 以下以括號括住雖然不是必需的但如此比較容易讀 SELECT employeeid firstname lastname title salary FROM employee_info WHERE (salary gt= 5000000) AND (title = Programmer) 另外範例 SELECT firstname lastname title salary FROM employee_info WHERE (title = Sales) OR (title = Programmer) 條件為只要是 Sales 或 Programmer 職稱的就會被列出 IN and BETWEEN 子句

SELECT column1 SUM(column2) FROM list-of-tables WHERE column3 IN (list-of-values) SELECT column1 SUM(column2) FROM list-of-tables WHERE column3 BETWEEN value1 AND value2 IN 子句使用在列舉項目的使用上也就是分別測試是否符合所列的值 For example

86

SELECT employeeid lastname salary FROM employee_info WHERE lastname IN (Hernandez Jones Roberts Ruiz) 條件為姓氏(astname)要符合 Hernandez Jones Roberts or Ruiz 其中一個才會被傳回 IN運算元也可以使用 OR 的語法來取代如下結果相同 SELECT employeeid lastname salary FROM employee_info WHERE lastname = Hernandez OR lastname = Jones OR lastname = Roberts OR lastname = Ruiz 但使用 IN 句子比較短也比較易懂 你也可以使用 NOT IN 來去掉不要的記錄 BETWEEN 運算元使用在判斷是否存在兩個數值之間 For example SELECT employeeid age lastname salary FROM employee_info WHERE age BETWEEN 30 AND 40 傳回年紀 30歲到 40歲之間的資料(含 30及 40歲者) 相同的也可以使用以下語法來達到相同的結果 SELECT employeeid age lastname salary FROM employee_info WHERE age gt= 30 AND age lt= 40 你也可使用 NOT BETWEEN 來濾掉中間值的資料 數學運算 標準 ANSI SQL-92 提供以下運算

87

+ 加

- 減

餘數

餘數為除法後剩整數這不在標準的 ANSI SQL 中但大部份的資料庫都會支

援這運算元以下列出有用的函數雖不在 ANSI SQL-92 提供但一般資料庫

也會支援他們

ABS(x) 傳回 x 絕對值

SIGN(x) returns the sign of input x as -1 0 or 1 (negative zero or positive respectively)

MOD(xy) 餘數 - returns the integer remainder of x divided by y (同 xy)

FLOOR(x) 傳回小或等於 x 的最大整數值

CEILING(x) or CEIL(x)

傳回大或等於 x 的最小整數值

POWER(xy) x的 y 次方

ROUND(x) 把 x 四捨五入為整數

ROUND(xd) 四捨五入取到小數 d 位

SQRT(x) x 開平方

For example SELECT round(salary) firstname FROM employee_info 傳回薪資取到整數位

如何新增資料

insert 加入一筆新紀錄到資料表中 insert into tablename (first_columnlast_column) values (first_valuelast_value) [] = optional Example insert into employee

88

(first last age address city state) values (Luke Duke 45 2130 Boars Nest Hazard Co Georgia) Note 字串要以單引號住如string 數字框住也無妨 insert into 後面接資料表名稱再接以括號括住的欄位名在 values 後括號分別對映各欄位的值 以上的例子新增了一筆名(first) 為 Luke而住所(state) 為 Georgia 的資料

如何刪除資料

delete 可以刪除單筆或多筆紀錄 delete from tablename where columnname OPERATOR value [and|or column OPERATOR value] [ ] = optional Examples delete from employee Note 如果你沒有指定 where 子句那麼全部的紀錄都會被刪除 delete from employee where lastname = May delete from employee where firstname = Mike or firstname = Eric delete from 接著資料表名 再接著是條件式判斷沒有條件式則全部紀錄會

被刪除

如何更新資料

update 用來更新你所指定的記錄要和 WHERE 配合小心使用 語法 update tablename set columnname = newvalue[nextcolumn = newvalue2] where columnname OPERATOR value [and|or column OPERATOR value] [] = optional Examples

89

update phone_book set area_code = 623 where prefix = 979 update phone_book set last_name = Smith prefix=555 suffix=9292 where last_name = Jones update employee set age = age+1 where first_name=Mary and last_name=Williams

90

附錄二Replication

測試環境

RedHat 90 + MySQL 32358 MySQL資料庫路徑 varlibmysql MySQL設定檔 etcmycnf Master IP 1921680100 Slave IP 1921680200 請至下列網址下載最新MySQL 32358套件並利用rpm ndashUvh 更新 httpupdatesredhatcom9enosi386

圖 最新 MySQL 套件

測試架構圖

91

1921680100

1921680200Master Server

erveSlave S r

圖 測試架構圖

測試步驟

Master server 部份 Step1 確認 MasterSlave機器上所裝的 MySQL版本能進行

replication( 32329 or higher ) Step2 在 Master MySQL上開放一個帳號給 Slave mysql ndashu root ndashp mysqlgtGRANT FILE ON TO repl1921680200 IDENTIFIED BY lsquoabc123rsquo mysqlgtq 上面是 Master開放一個帳號 repl密碼 abc123給 IP1921680200有檔案處理

的權限 Step3 shutdown MySQL on the Master mysqladmin ndashu root ndashp shutdown Step4 備份 Master所有資料庫 tar ndashcvf tmpmysql-snapshottar varlibmysql 注意tar的時候MySQL是要在 stop情況下 在mysql (wwwmysqlcom) 網站的FAQ有不用shutdown的方法

92

Step5 在 master機器上修改etcmycnf 在[mysqld]區段內加入參數 log-bin server-id=這邊設定 server-id=1 sql-bin-update-same binlog-do-db=CRM只針對 CRM資料庫做紀錄 Step6 Restart MySQL on the master service mysqld start 此時因為有加入 log-bin 參數因此開始有 index產生了在varlibmysql目錄下

有index檔案紀錄資料庫的異動 log Slave server 部份 Step1 在 slave設定etcmycnf 在[mysqld]區段加入 master-host= master-user= master-password= master-port= server-id= 這邊設定 master-host=1921680100 master-user=repl master-password=abc123 master-port=3306 server-id=2 master-connect-retry=60預設重試間隔 60秒 replicate-do-db=CRM告訴 slave只做 CRM資料庫的更新 log-slave-updates Step2 將 master上的 mysql-snapshottar copy到 slave上 用 ftp傳到 slave的tmp Step3 解壓縮 Master資料庫至 Slave Server上 cd varlib tar xvf tmpmysql-snapshottar chown ndashR mysqlmysql mysql

93

chmod ndashR 770 mysql (視情況) Step4 Restart MySQL on the slave server 這時在varlibmysql目錄會出現 masterinfo此檔案紀錄了 Master MySQL server的資訊

狀況測試

One-way replication

1921680100

1921680200Master Server

erveSlave S r

圖 One-way replication架構圖 Step1 Master跟 Slave網路及服務都正常情況下由 Master端異動資料後 到 Slave端瀏覽資料檢視是否有進行 replication Step2 模擬 Slave Server 當機 可用在於 slave真的當機或是 Slave 不一定需要一直跟 master connect將Slave MySQL server shutdown由 Master端異動資料到 slave端瀏覽此時Slave應該沒有被 replication 更新然後再將 Slave端 MySQL server start起來

預設 60秒後 Slave會嘗試跟 Master要求進行 replication再去 Slave端檢視是否有更新資料

94

Step3 模擬 Master當機因為是設定 One-way replication一旦 Master Server Slave端沒有 Master的 source可以 download Two-way replication 基於 Master當機狀況於是發展雙向 Replication即 1921680100 ( Host A ) 1921680200 ( Host B )都分別擔任 MasterSlave身分

1921680100

1921680200er

Server B MasterSlave Server

Server A MasterSlave Serv

圖 Two-way replication架構圖 以下是針對兩台 MySQL伺服器進行雙向 Replication Step1觀念同單向 replication只是改成 Master也有 Slave身分 Slave也有Master的身分先分別在 Server AServer B 都去 grant一個進行 replication的身分 [A]mysqlgtGRANT FILE ON TO repl1921680200 IDENTIFIED BY lsquoabc123rsquo [B]mysqlgt GRANT FILE ON TO repl1921680100 IDENTIFIED BY lsquoabc123rsquo Step2做完單向 replication後stop Server Aserver B MySQL service此時 AB資料是一樣的

95

修改etcmycnf設定 範例 Server A [mysqld] datadir=varlibmysql socket=varlibmysqlmysqlsock server-id=1 log-bin sql-bin-update-same binlog-do-db=CRM master-host=1921680200 master-user=repl master-password=abc123 log-slave-updates master-connect-retry=60 replicate-do-db=CRM Server B [mysqld] datadir=varlibmysql socket=varlibmysqlmysqlsock server-id=2 log-bin sql-bin-update-same binlog-do-db=CRM master-host=1921680100 master-user=repl master-password=abc123 log-slave-updates master-connect-retry=60 replicate-do-db=CRM 分別 start Server AServer B MySQL後此時雙方都是 MasterSlave身分一旦哪一方資料異動就會通知對方來 replication-若 replication失效則必須將Server AServer B的masterinfo及index00x 都砍掉然後分別 restart MySQL server進行測試檢視成果 實務上通常如果需要做Two-way replication通常會搭配Virtual Server使用

96

在前端架設一台Virtual Server不過此部份不在此份SOP討論範圍內有興趣

的讀者可參考 httpwwwlinuxvirtualserverorg 網站

1921680100 1921680200

Host A MasterSlave Server

Host B MasterSlave Server

Virtual Host

圖 Virtual Server + Two-way replication 架構圖

97

圖 High Availability Linux Virtual Server架構圖

98

  • COSA-SOP-03-006
  • 第一章 簡介
    • 11適用對象 (Audience)
    • 12 MySQL本身
    • 13 MySQL 40版跟50版重大的改進功能
    • 14 各家資料庫軟體比較
      • 第二章 前置需求
      • 第三章 安裝
        • 31 MySQL安裝
        • 32 phpMyAdmin安裝
        • 33 升級及注意事項
          • 第四章 MySQL管理
            • 41 Webmin 管理介面
            • 42 phpMyAdmin 的操作介面
            • 43管理指令介紹
              • 431 利用mysqladmin設定root的密碼
                  • 第五章 實用範例
                    • 51 任務一Web Base客戶通訊錄
                    • 52 任務二Web Base群組軟體 ( twig )
                      • 第六章 維護及更新程序
                        • 61 日常維護
                        • 62 更新程序
                        • 63 備份重要檔案
                        • 64 離線備份與還原
                        • 65 線上備份與還原
                          • 第七章 問題與解答
                          • 第八章 參考資料
                          • 附錄一 SQL Command 介紹
                          • 附錄二Replication
Page 52: DataBase Server Standard Operation Procedureebooks.lib.ntu.edu.tw/1_file/oss/63/93doc4-5.pdf · 業務的公司帶來了不少壓力,譬如微軟,甲骨文 ... 外的錢用在第三方的資料庫產品上,譬如就可以不用再購買甲骨文公司

圖 5-3 新增成功

搜尋及異動資料

圖 5-4 搜尋通訊錄

52

圖 5-5 編輯資料

圖 5-6 更新資料

513 程式內容及說明

lt-- 程式範例indexhtml--gt lthtmlgt ltheadgtlttitlegt通訊錄lttitlegtltheadgt ltbodygt ltcentergt

53

lth2gt通訊錄lth2gtlthrgt lta href=indexhtmlgt通訊錄ltagt | lta href=addphpgt新增連絡人ltagt | lta href=searchphpgt搜尋通訊錄ltagt ltcentergt ltbodygt lthtmlgt lt-- 程式範例addphp --gt lthtmlgt ltheadgtlttitlegt新增連絡人lttitlegtltheadgt ltbodygt ltcentergtlth2gt新增連絡人lth2gtltcentergtlthrgt lt 取得欄位資料 if (isset($_POST[Name]) ampamp isset($_POST[Tel]) ) $name = $_POST[Name] $tel = $_POST[Tel] 檢查是否有輸入欄位資料 if ($name = ampamp $tel = ) 建立 SQL字串 $sql = INSERT INTO address (name tel) values( $sql= $name $tel) 建立 MySQL 連結 $link = mysql_connect(localhostroot1234) 選擇資料庫 mysql_select_db(CONTACT) 執行 SQL指令 mysql_query($sql) mysql_close($link) echo ltfont color=redgt新增連絡人成功ltfontgtltbrgt gt ltform action=addphp method=postgt lttable border=0 width=300gt lttrgtlttdgt姓名 lttdgt

54

lttdgtltinput type=text name=Name size=20 maxlength=10gtlttdgtlttrgt lttrgtlttdgt電話 lttdgt lttdgtltinput type=text name=Tel size=20 maxlength=20gtlttdgtlttrgt lttrgtlttd colspan=2 align=centergt ltinput type=submit value=新增連絡人gtlttdgtlttrgt lttablegt ltformgt ltbrgtlta href=indexhtmlgt通訊錄ltagt | lta href=addphpgt新增連絡人ltagt | lta href=searchphpgt搜尋通訊錄ltagt ltbodygt lthtmlgt

lt-- 程式範例searchphp --gt lthtmlgt ltheadgtlttitlegt搜尋通訊錄lttitlegtltheadgt ltbodygt ltcentergtlth2gt搜尋通訊錄lth2gtlthrgt lt if (isset($_POST[Search])) 建立資料庫連結並選定資料庫 $link = mysql_connect(localhostroot1234) mysql_select_db(CONTACT) 建立基本的 SQL字串 $sql = SELECT FROM address 檢查是否輸入姓名 if (chop($_POST[Name]) = ) $name = name LIKE $_POST[Name] else $name = 檢查是否輸入電話號碼 if (chop($_POST[Tel]) = ) $tel = tel LIKE $_POST[Tel] else $tel =

55

if條件組合 SQL字串 if (chop($name) = ampamp chop($tel) = ) $sql= WHERE $name AND $tel elseif (chop($name) = ) 只有姓名 $sql = WHERE $name elseif (chop($tel) = ) 只有電話號碼 $sql = WHERE $tel $sql= ORDER BY name 最後加上排序 $result = mysql_query($sql) 取得欄位數 $total_fields = mysql_num_fields($result) echo lttable border=1gt echo lttrgtlttdgt編號lttdgtlttdgt姓名lttdgtlttdgt電話lttdgtlttd colspan=2gt功能選項lttdgtlttrgt 表格顯示查詢結果 while ($rows = mysql_fetch_array($result MYSQL_NUM)) echo lttrgt for ($i = 0 $i lt $total_fields $i++) echo lttdgt$rows[$i]lttdgt echo lttdgtlta href=editphpaction=editampid= echo $rows[0]gtltbgt編輯ltbgtlttdgt echo lttdgtlta href=editphpaction=delampid= echo $rows[0]gtltbgt刪除ltbgtlttdgt echo lttrgt echo lttablegtlthrgt mysql_free_result($result) mysql_close($link) gt ltcentergt ltform action=searchphp method=postgt lttable border=0 width=450gt lttrgtlttdgt搜尋姓名 lttdgt lttdgtltinput type=text name=Name size=10 maxlength=20gtlttdgtlttrgt lttrgtlttdgt搜尋電話 lttdgt lttdgtltinput type=text name=Tel

56

size=20 maxlength=20gtlttdgtlttrgt lttrgtlttd colspan=2 align=centergt ltinput type=submit name=Search value=搜尋gtlttdgtlttrgt lttablegt ltformgt ltbrgtlta href=indexhtmlgt通訊錄ltagt | lta href=addphpgt新增連絡人ltagt | lta href=searchphpgt搜尋通訊錄ltagt ltbodygt lthtmlgt

lt ob_start() gt lt-- 程式範例editphp --gt lthtmlgt ltheadgtlttitlegt編輯通訊錄lttitlegtltheadgt ltbodygt lt 取得 URL 參數 $id = $_GET[id] $action = $_GET[action] 建立資料庫連結 $link = mysql_connect(localhostroot1234) mysql_select_db(CONTACT) 選擇資料庫 執行的操作 switch ($action) case update 更新 取得欄位資料 $name = $_POST[Name] $tel = $_POST[Tel] $sql = UPDATE address SET name=$name tel=$tel WHERE id=$id mysql_query($sql) 執行 SQL指令 mysql_close($link) header(Location searchphp) 轉向到 serachphp break case del 刪除 $sql = DELETE FROM address WHERE id=$id

57

mysql_query($sql) 執行 SQL指令 mysql_close($link) header(Location searchphp) 轉向到 serachphp break case edit 編輯 $sql = SELECT FROM address WHERE id=$id $result = mysql_query($sql) 執行 SQL指令 $row = mysql_fetch_row($result) 取回記錄 $name = $row[1] 取得欄位 name $tel = $row[2] 取得欄位 tel mysql_close($link) 顯示編輯表單 gt ltcentergtlth2gt更新通訊錄lth2gtltcentergtlthrgt ltform action=editphpaction=updateampid=lt echo $id gt method=postgt lttable border=0 width=300gt lttrgtlttdgt姓名 lttdgt lttdgtltinput type=text name=Name size=20 maxlength=10 value=lt echo $name gtgtlttdgtlttrgt lttrgtlttdgt電話 lttdgt lttdgtltinput type=text name=Tel size=20 maxlength=20 value=lt echo $tel gtgtlttdgtlttrgt lttrgtlttd colspan=2 align=centergt ltinput type=submit value=更新連絡人gtlttdgtlttrgt lttablegt ltformgt ltbrgtlta href=indexhtmlgt通訊錄ltagt | lta href=addphpgt新增連絡人ltagt | lta href=searchphpgt搜尋通訊錄ltagt lt break gt ltbodygt lthtmlgt

58

52 任務二Web Base群組軟體 ( twig )

順利完成Web Base客戶通訊錄程式測試一段時間後「Apache + MySQL + PHP」架構的穩定與快速巳深得老闆與公司所有同事的認同隨著公司業績蒸

蒸日上人員組織編罝愈來愈龐大跨部門的會議愈來愈多業務員每日排滿拜

訪客戶的行程跟客戶的 Email的往來也愈來愈頻繁 愈來愈多部門的同事希望公司能建置一套群組軟體提供 web mail可讓業

務人員方便收發 mail還有連絡人議事日程待辦工作書簽等功能讓整個

公司運作及個人時間管理更有效率

老闆問小明對這些需求有什麼看法小明認為如果這些功能完全由程式部

門開發必定曠日費時而且耗費公司資源小明在網路尋找是否有提供這些功能

的Free Software皇天不負苦心人小明發現了TWIG (The Web Information Gateway) httptwigscrewdrivernet這個群組軟體它在 Web 上整合郵件新聞聯絡人議事日程工作序書簽等功能非常符合公司的需求 Step 1 下載 twig-277targz 下載網址 httptwigscrewdrivernetdownloadphp3

Step 2 解開 twig-277targz tar -xzvf twig-277targz

59

Step 3 執行安裝動作安裝到 varwwwhtmltwig 目錄 cd twig-277 twig-install varwwwhtmltwig

Step 4 建立 MySQL 資料庫(twig)及各資料表

cd setup mysql -u root -p1234 mysqlgt create database twig Query OK 1 row affected (001 sec) mysqlgt quit mysql -u root ndashp1234 twiglt twigtablemysql

Step 5 修改 configincphp3 參數設定 vi varwwwhtmltwigconfigconfigincphp3 $config[fromdomain] = opencom 網域 $config[language] = chinesebig5 中文訊息 $config[imap_port] = 143notls

60

Step 6 修改連結 MySQL 的帳號密碼 vi varwwwhtmltwigconfigdbconfigincphp3 $dbconfig[sqlusername] = root username $dbconfig[sqlpassword] = 1234 password

Step 7 其他設定檔

vi etchttpdconfhttpdconf 加入 AddType applicationx-httpd-php php3 在 DirectoryIndex最後加入 indexphp3 DirectoryIndex indexhtml indexhtmlvar indexphp3 在 AddDefaultCharset ISO-8859-1加上 AddDefaultCharset ISO-8859-1

vi etcphpini register_globals = On service httpd restart Step 8 sendmail 設定 vi etcmailsendmailcf在 264 行前面加上並重新啟動 sendmail「service snedmail restart」 262 SMTP daemon options 263 264 O DaemonPortOptions=Port=smtpAddr=127001 Name=MTA 265 266 SMTP client options 267 O ClientPortOptions=Family=inet Address=00

61

Step 9 檢查設定有無錯誤 http主機名稱twigtestphp3

62

Step 10 登入 twig ( http主機名稱twig)

63

第六章 維護及更新程序

61 日常維護

系統管理員最好定期以 root 身份登入看看信件在 RedHat Linux 中有一支 logwatch 程式會定時去分析 log file如果發現異常便會發信給 root除此之外筆者建議讀者平時就檢查 MySQL log file ( varlogmysqldlog)是否有異常情形

62 更新程序

讀者可至httprpmfindnet 尋找MySQL相關套件至於升級的相關步驟請參

考Linux OS SOP 第 54節

63 備份重要檔案

預設 MySQL 的 DB 檔案是存在 varlibmysql 內以 DB名稱為目錄目錄

內就是該 DB 的所有資料通常得定期備份還有 MySQL的設定檔 etcmycnf也別忘了一起備份

64 離線備份與還原

641 離線備份

預設 MySQL 的 DB 檔案是存在 varlibmysql 內以 DB 名稱為目錄目錄內

就是該 DB 的所有資料像 CRM 這個 DB就是存在 varlibmysqlCRM 內在備份前因為怕資料尚未完全寫入磁碟而且 MySQL 會 Lock 在使用的 DB 檔案所以應該是要先把 MySQL 先 Shutdown 一下整個備份的程序可以下像下面的指令去完成 cd varlibmysql

64

service mysqld stop tar cvfz CRM_db_20030905tgz CRM service mysqld start 對這樣就可以了 不過要注意的是怕 DB 內每個 Tables 間的資料有關關

聯性所以最好是把整個 DB 一次備起來單獨只備哪個 Tables 的檔案以後回存時怕會有資料關聯不一致的問題

642 離線還原

DB 發生錯誤而要回存時其實也不難先找出最近一次完整正常的備份先把現在錯誤的網頁或 DB 先更名或 tar 起來再把好的備份給解開回原來目錄位

置就行了需要注意的是 MySQL 服務最好也是要先停止回存完成後再啟動服務回存 DB 的整個程序可能像下面 cd varlibmysql service mysqldstop mv CRM CRM_OLD tar xvfz CRM_db_20030905tg service mysqld start

65 線上備份與還原

651 線上備份

使用像上面的檔案方式備份是個不錯的方法它最少可以保持該主機某個時間點的完整檔案備份但還是有一些問題需要考慮到有些主機就不只建立一個 DB 而已總不能為了備份某個 DB 而把整個 MySQL 服務停止備份檔案的方式回存在原主機上一定適用但假如 MySQL 版本升級或是在那天該網頁空間需遷機移機到別的主機時那就沒人敢保證備出來的資料檔可以用所以我們可以考慮另一種備份的方式是使用 MySQL 本身提供的功能 MySQL Data Dump指令是 mysqldump

65

使用 MySQL 的 Dump 功能可以把 DB 的結構資料或結構加資料 Dump 成文字檔 mysqldump 指令提供的彈性很大你可以選擇把整個 DB Dump 成一個檔或是每個 Table 為一個檔甚至是把結構檔和資料分開儲存都

可以 mysqladmin -uroot -p flush-logs mysqldump CRM -uroot -p --opt gt CRM_20030905sql (CRM 是 DB 名稱 opt 是一個使用完整 Dump 參數) 假如只是要單獨 Dump 某個 Table 時只要在上面的指令後轉出符號 gt 前加個 Table 名稱就可以如只要 phpbb2_users 這個 Table 的 Dump 時只要下 mysqldump CRM -uroot -p --opt CUSTOMER gt CRM_CUSTOMER_20030905sql

652 線上還原

若要回存整個資料庫只需將壓縮的備份檔還原成 Dump 的檔案再用下面的指令回存 mysql CRM -uroot -p lt CRM_20030905sql 這邊需注意的是若建立備份時是以--opt或--add-drop-table為參數時回存的 動作是先將舊的 Table 先刪除重建 Table 的結構後再把 Data 匯入所以回存後所有的資料會回到你當時備份那個時間點因此在回存資料時可以考慮把現有錯誤或不完整的 DB 先備份一份下來以備不時之需或是拿來比對錯誤的地

方在那裡當然你也可以把資料回存到另一個測試用的 DB 內只要把上面指令

的 DB 名稱改成你的測試用 DB 名稱即可 使用這種回存方式 MySQL 服務不需停止也不會動到其他正在使用的 DB 在一些提供 MySQL 服務的虛擬主機可用這種方式作你自己的 DB 備份及回存

66

另外假如你是系統重建或是移機時切需在新的 MySQL 內新建一個空白 DB 後才行作回存的工作你可以用下面的指令建立 mysql -uroot -p -e CREATE DATABASE CRM (上面的 CRM是你要新建的 DB 名稱) 另一種作法先用 mysql 指令進入 mysql client console 然後再用 CREATE DATABASE CRM 這樣就行了記得尾端要加個 符號該行指令才會執行

67

第七章 問題與解答

Q1RedHat 90預附的 MySQL到底有無支援 Transcation機制 Ans MySQL自 32334a之後的 MySQL-Max版本加入 InnoDB的資料庫類型透過

InnoDBMySQL同樣可以進行 COMMIT與 ROLLRACK的動作RedHat 90預附的 MySQL為 32354a-11巳支援 InnoDB的資料庫類型不過必須做以

下設定 1cp usrsharedocmysql-server-32354amy-mediumcnf to etcmycnf 2 vi etcmycnf 將以下設定前的拿掉 innodb_data_home_dir = varlibmysql innodb_data_file_path = ibdata110Mautoextend innodb_log_group_home_dir = varlibmysql innodb_log_arch_dir = varlibmysql 3service mysqld restart 如此一來各位在建立Table時便可指定Table Type為 innodb ( ex create table with type=innodb ) Q2如何解決 php+mysql 許功蓋等字變亂的問題 Ans 方法一 【確定 MySQL 預設的字元集】 1 打開 WinMySQLadmin 管理畫面(在視窗右下角狀態列紅綠燈圖示中按滑鼠

右鍵點選 Show me 選項) 2 點選管理畫面中 [Variables] 標籤選項其中 character_set變數就是您預設

字元集的變數其預設是 latin1 字元集(我們要將他改回 big5)而 chatacters_set 變數則是 MySQL 可以支援哪些字元集 【修改預設字元集變數 character_set 】 1 請點選管理畫面中 [myini Setup] 標籤選項設定 myini 2 按一下 [Pick-up and Edit myini values] 按鈕以便編輯目前的 myini 設定 3 在 [mysqld] 設定區塊底下新增一行 default-character-set = big5 變數設

68

定 4 新增一個 [client] 設定區塊並加入第三步驟的變數設定(游標往下移到空白處新增兩行 [client] 和 default-character-set=big5) 5 按一下畫面左下方 [Save Modification] 按鈕儲存設定 6 重新啟動 MySQL 或 Windows 方法二 Server端注意事項 phpini 中有關的設定為(預設值) Magic quotes for incoming GETPOSTCookie data magic_quotes_gpc = On Use Sybase-style magic quotes (escape with instead of ) magic_quotes_sybase = Off Client端注意事項 1中文資料送進 mysql 前請用 addslashes($str) 處理 2處理後送進 mysql 時請用 括起來並在參數後留一個空白如 $sql = UPDATE ezf_table set tablename=$tname tableend=$endtime table inguser=$tguser tableingid=$tguserid tableallnumber=$tnumber tableloca l=$tablelocal tableanyone=$tableopen tabletext=$ttext WHERE tableid=$t ableid tablename=$tname c 取出時請用 stripslashes($str) Q3MySQL root 密碼忘了該怎麼辦 Ans 1先停掉 mysql etcrcdinitdmysql stop 2以--skip-grant-table 的參數啟動 mysql safe_mysql --skip-grant-tableamp 3 更改 root 密碼 mysql mysql mysqlgt UPDATE user SET password=password(newpassword)

69

WHERE user=root mysqlgt FLUSH PRIVILEGES mysqlgt exit 4停掉 mysql再重跑 mysqladmin -uroot -p shutdown Enter password 輸入新設定的密碼 etcrcdinitdmysql start

Q4NULL值問題

Ans

NULL值的概念是造成 SQL的新手的混淆的普遍原因他們經常認為 NULL是和一個空字符串的一樣的東西不是這樣的例如下列語句是完全不同的

mysqlgt INSERT INTO my_table (phone) VALUES (NULL)

mysqlgt INSERT INTO my_table (phone) VALUES ()

兩個語句把值插入到 phone 列但是第一個插入一個 NULL值而第二個插入一個空字符串第一個的含義可以認為是ldquo電話號碼不知道而第二個則可意味

著ldquo她沒有電話

在 SQL中NULL值在于任何其他值甚至 NULL值比較時總是假的(FALSE)包含 NULL的一個表達式總是產生一個 NULL值除非在包含在表達式中的運算符和函數的文檔中指出在下列例子所有的列返回 NULL

mysqlgt SELECT NULL1+NULLCONCAT(InvisibleNULL)

如果你想要尋找值是 NULL的列你不能使用=NULL測試下列語句不返回任

何行因為對任何表達式expr = NULL是假的

mysqlgt SELECT FROM my_table WHERE phone = NULL

要想尋找 NULL值你必須使用 IS NULL測試下例顯示如何找出 NULL電話號碼和空的電話號碼

70

mysqlgt SELECT FROM my_table WHERE phone IS NULL mysqlgt SELECT FROM my_table WHERE phone =

在 MySQL中就像很多其他的 SQL服務器一樣你不能索引可以有 NULL值的列你必須聲明這樣的列為 NOT NULL而且你不能插入 NULL到索引的

列中

當用 LOAD DATA INFILE 讀取數據時空列用更新如果你想要在一個列中有

NULL值你應該在文本文件中使用N字面上的詞NULL也可以在某些情形下使用

當使用 ORDER BY時首先呈現 NULL值如果你用 DESC以降序排序NULL值最後顯示當使用 GROUP BY時所有的 NULL值被認為是相等的

為了有助于NULL的處理你能使用 IS NULL和 IS NOT NULL運算符和 IFNULL()函數

對某些列類型NULL值被特殊地處理如果你將 NULL插入表的第一個TIMESTAMP 列則插入當前的日期和時間如果你將 NULL插入一個AUTO_INCREMENT 列則插入順序中的下一個數字

Q5如何將圖片存放於 MySQL中

Ans

Step 1建立資料庫 test

Step 2 建立表格 binary_data

CREATE TABLE binary_data (

id INT(4) NOT NULL AUTO_INCREMENT PRIMARY KEY

description CHAR(50)

bin_data LONGBLOB

filename CHAR(50)

filesize CHAR(50)

filetype CHAR(50)

71

)

Step 3 利用 storephp 寫入圖片

storephp 程式碼

ltHTMLgt ltHEADgtltTITLEgtStore binary data into SQL DatabaseltTITLEgtltHEADgt ltBODYgt lt code that will be executed if the form has been submitted

if ($submit) mysql_connect(localhostrootYOUR_PASSWORD) mysql_select_db(test) $data=Base64_Encode(fread(fopen($form_data r) filesize($form_data))) $result=MYSQL_QUERY(INSERT INTO binary_data (descriptionbin_datafilenamefilesizefiletype) VALUES ($form_description$data$form_data_name$form_data_size$form_data_type)) $id= mysql_insert_id() print ltpgtThis file has the following Database ID ltbgt$idltbgt MYSQL_CLOSE() else else show the form to submit new data

gt

ltform method=post action=ltphp echo $PHP_SELF gt enctype=multipartform-datagt File Descriptionltbrgt ltinput type=text name=form_description size=40gt ltINPUT TYPE=hidden name=MAX_FILE_SIZE value=4000000gt ltbrgtFile to uploadstore in databaseltbrgt ltinput type=file name=form_data size=40gt ltpgtltinput type=submit name=submit value=submitgt ltformgt lt

72

gt ltBODYgt ltHTMLgt

Step 3 利用 storephp 取出圖片

getdataphp 程式碼

lt Syntax getdataphp3id=ltidgt if($id) you may have to modify login information for your database server MYSQL_CONNECT(localhostrootYOUR_PASSWORD) mysql_select_db(test) $query = select bin_datafiletype from binary_data where id=$id $result = MYSQL_QUERY($query) $data = Base64_Decode(MYSQL_RESULT($result0bin_data)) $type = MYSQL_RESULT($result0filetype) Header( Content-type $type) echo $data gt

Q6MySQL裝好之後啟動時或是執行 mysqladmin會出現如下訊息 Cant connect to local MYSQL Server through Socket varlibmysqlmysqlsock或是

Cant connect to local MYSQL Server through Socket tmpmysqldsock

Ans 可能有下列幾個原因

1這個 mysqldsock 不見了被某人刪除了或是被一些系統自動執行程式給刪

了例如有些 cron任務便會設定定期刪除 tmp 裡的東西所以呢您只能修改

cron 裡的設定讓它不要清除 mysqldsock 2在啟動時也可以改變 mysqldsock的位置您在啟動 MySQL的時候可以加入此參數usrlocalmysqlbinsafe_mysqld --user=mysql --socket=其他路

徑socket amp 同時得去設定環境變數 MYSQL_UNIX_PORT的值以指定新的

73

路徑 3若是您沒改 MYSQL_UNIX_PORT的值那麼您可以在執行指令的時候才打

例如mysqladmin --socket=其他路徑socket version Q7How to get the last insert id Ans CREATE TABLE product ( id INT(4) NOT NULL AUTO_INCREMENT PRIMARY KEY description VARCHAR(50) ) 1利用 SQL的話 mysqlgt insert into product(description) values(123) Query OK 1 row affected (000 sec) mysqlgt select last_insert_id() +------------------+ | last_insert_id() | +------------------+ +------------------+ 1 row in set (000 sec) ======================================== 2如果是 PHP的話 你可以用mysql_insert_id()取得該 id PHP example $result=MYSQL_QUERY(INSERT INTO product (description) VALUES ($description)) $id= mysql_insert_id() print This file has the following Database ID $id Q8如何將文字檔匯入資料庫 Ans $addr=homehttpdhtmlphpschool001txt $sql_select = load data infile $addr into table test fields terminated by t 解說 $sql_select = load data infile 文字檔名 into table 表格名 fields terminated by

74

t

(欄位分隔以 TAB鍵) 該文字檔須與資料表欄位格式相符 例如欄位有三個 則文字檔為每行一筆資料如下 欄 1資料ltTABgt欄 2資料ltTABgt欄 3資料 欄 1資料ltTABgt欄 2資料ltTABgt欄 3資料 欄 1資料ltTABgt欄 2資料ltTABgt欄 3資料 欄 1資料ltTABgtltTABgt欄 3資料

Q9如何撰寫 MySQL C API Ans Step 1利用文字編輯器撰寫以下程式碼 mysqlcc

include ltstdiohgt

include ltmysqlmysqlhgt

int main (int argc char argv[])

MYSQL mysql

MYSQL_RES res

MYSQL_ROW row

if (argc = 2)

fputs (Usage myc ltdatabasegt stderr)

return 1

if ((mysql_connect(ampmysqllocalhostrootYour_Password)))

fputs (Error connecting stderr)

abort()

75

if (mysql_select_db(ampmysqlargv[1]))

fputs (Error selecting database stderr)

abort()

if (mysql_query(ampmysqlSELECT FROM test_table))

fputs (Error processing query stderr)

abort()

if ((res = mysql_store_result(ampmysql)))

fputs (Error storing results stderr)

abort()

while((row = mysql_fetch_row(res)))

uint i = 0

for (i=0 i lt mysql_num_fields(res) i++)

printf(s row[i])

printf(n)

return 0

Step 2 Compile

gcc -Iusrlocalmysqlinclude -Lusrlocalmysqllibmysql mysqlcc ndashlm -lmysqlclient

(其中 include path與 library path取決於你的 MySQL安裝路徑)

76

如果執行時發生如下 error Run problemerror in loading shared libraries libmysqlclientsoX 將你的 MySQL library path(for exampleusrlocalmysqllibmysql) 加入etcldsoconf and run sbinldconfig -v Q9ASP + MySQL 範例程式 Ans Dim myconn As New ADODBConnection Dim myrs As New Recordset Dim mySQL As String Dim myrows As Long myconnOpen DSN=MyODBCsample mySQL = SELECT from user myrsSource = mySQL Set myrsActiveConnection = myconn myrsCursorLocation = adUseClient myrsOpen myrows = myrsRecordCount myrsClose myconnClose 可參考 httpwwwdwamnetmysqlasp_myodbcasp 有詳細的資料 Q10如何將 MySQL中的資料庫匯出成txt檔 Ans select from TableName into outfile textxls all result fields will seperate by tab

77

第八章 參考資料

英文部份 網址 1 httpwwwmysqlcom MySQL 網站有第一手有關 MySQL的資料 2 httpwwwmysqlcomdocenReplicationhtml 有關 MySQL Replication 的文件 3 httpwwwgeocitiescomsqlhomefaqstore_blobhtml 如何在 MySQL 存放 BLOB的資料 4httpwwwsapdborg 有關 SAP跟 MySQL相關合作的網站 書藉 1 Cooking with MySQL

Paul DuBois has selected sample recipes from the hundreds youll find in his book MySQL

Cookbook In this third and final series of excerpts showcasing these recipes learn how to

compute team standings how to calculate the differences between successive Dec 26

2002 2 Tips for Building Web Database Applications with PHP and MySQL by Hugh E Williams co-author of Web Database Applications with PHP amp MySQL 04042002

3 Managing and Using MySQL 2nd Edition By Tim King George Reese Randy Jay Yarger

4 MySQL Cookbook By Paul DuBoisPublisher OReillyPub Date October 2002

中文部份

78

1 httplinuxtncedutwtechdocmysqlmysql_docmanual_tochtml MySQL 中文手冊 2 httpchenshloxaedutwphpZ_1php PHP+MySQ程式研習設計網站 3 httplinuxtncedutwtechdocbanicdownhtml PHP 4 手冊 4 httpwwwtncedutwadmin_zonephp台南縣教育網網路中心有很多 Linux相關文件 5 httpdobtncedutw網站建置百寶箱有很多 PHP MySQL 相關範例程式 5 httpwwwdbworldcomtw資料庫專家電子雜誌介紹資料庫的重要觀念及名詞

79

附錄一 SQL Command 介紹

SQL (讀音ess-que-el) 是一種結構查詢語法SQL 使用於資料庫交流

傳遞相容於 ANSI (American National Standards Institute) 是一套標準的關聯

式資料庫語言 SQL 語言是執行更新或從資料系統獲取資料一般常見的關聯

資料庫系統都有提供 SQL 如 Oracle Sybase Microsoft SQL Server Access Ingres 等雖然大部份的資料庫都有提供 SQL 但也多提供了自已獨特的語

法造成了不相容的情形但標準基本的語法是相通的如Select Insert Update Delete Create and Drop 每一個系統都有支援

Table相關 Command

Create Table

關聯式資料庫包含有很多元件稱為資料表(tables) 把資料或訊息放在資

料表中 資料表是以不同的名稱做分別資料表由欄列所構成的二維陣列

欄包含欄位名資料型態 及其他可判斷的資訊列是由全部欄位構成一筆一

筆的紀錄 create table 語法用在建立一個新的資料表語法格式如下

create table tablename (column1 data type column2 data type column3 data type)

Format of create table if you were to use optional constraints

create table tablename (column1 data type [constraint] column2 data type [constraint] column3 data type [constraint]) [ ] = optional

Note You may have as many columns as youd like and the constraints are optional

80

Example

create table employee (first varchar(15) last varchar(20) age number(3) address varchar(30) city varchar(20) state varchar(20))

注意建立資料表格式要以括號把前後框住而最後以(分號)做結尾

欄位名不要超過 30個字元長而且不要使用 sql 的關鍵字(如 where select等)而在後面接是型態的宣告(如字串數字日期格式等)

資料型態是來描述欄位的方式如一個欄位Last_Name 是一個姓氏可以使用varchar (可變動長度字串) 資料型態

以下是幾個常見的資料庫型態 char(size) 固定長度字串最長為 255 位元 varchar(size) 變動長度字串最大字元數以 size 來指定 number(size) 數值格式可以是整數也可以是小數最大數字以 size 位數判

斷未指定小數位數由系統內定 date 日期格式 number(sized) 數值格式最大數字以 size 位數判斷d 為小數位數整數位

數為 size-d 位

有何限制當資料表被建立通常有一或數個欄位是要使用來做關聯的功

能 例如unique 限制(唯一值)兩筆記錄不可以相同的值 not null (非空值)該欄位一定要輸入資料不可是空的primary key (主鍵)是每一筆記錄識別的主要方式

Drop a table drop table 刪除資料表(其中的資料也會一併刪除)

drop table tablename

Example

81

drop table 和刪除全部資料是不同的刪除全部資料欄位名稱資訊等還會

存在但刪除資料表會把這一些也一併移除掉

如何查詢資料

Select 基本用法

select 語法是關連式資料庫最常用的部份可以取得你想要的資料這是一個

簡單的範例 select column1[column2etc] from tablename [where condition] [] = optional 在 select 之後所列欄位名則是要顯示的資料部份你可以一一列出各欄位

名或是以 (星號)來代表選擇全部的欄位 from 之後放資料表名稱 where 子句 (選項) 指定要過濾的條件符合者才會顯現 where 可使用的條件運算元 = 等於 gt 大於 lt 小於 gt= 大或等於 lt= 小或等於 ltgt 大相等 LIKE 相似 For example select first last city

82

from empinfo where first LIKE Er 以Er 為開頭的字串就符合要以單引號框住 Or you can specify select first last from empinfo where last LIKE s 最後一字為 S 就符合 select from empinfo where first = Eric 則表示 first name 一定要是 Eric 才可以 範例資料表empinfo 統計函數

MIN 傳回指定欄位最小值

MAX 傳回指定欄位最大值

SUM 傳回指定欄位總和

AVG 傳回指定欄位平均值

COUNT 傳回指定欄位的筆數

COUNT() 傳回資料庫中的總筆數

統計函數使用於資料表中的數值欄位配合 SELECT 語法使用 只用於總結特定單一欄位可以配合 GROUP BY 做篩選但也可以不使用 GROUP BY 語句For example

SELECT AVG(salary) FROM employee

83

傳回全部 salary 平均值

Another example

SELECT AVG(salary) FROM employee WHERE title = Programmer

傳回 salary 平均值條件為 employees 資料表中當 title 等於 Programmer

Example

SELECT Count() FROM employees

傳回 employees 資料表中紀錄總筆數

GROUP BY 語法 SELECT column1 SUM(column2) FROM list-of-tables GROUP BY column-list The GROUP BY 語句可以先以所列的欄位為條件分組排序在一起(可以多欄

位) example 要列出每一個 dept 中最高 salary 值 SELECT max(salary) dept FROM employee GROUP BY dept HAVING 語法

SELECT column1 SUM(column2) FROM list-of-tables GROUP BY column-list HAVING condition

HAVING 子句是 GROUP BY 的一部份用來過濾在 GROUP BY 所選出的資料功能如同 select 命令中 where 條件式一樣只是 HAVING 必需配合 GROUP BY 使用

我們以例子來說明我們要取得每一公司名及每一公司的薪水平均值輸入如下

84

SELECT dept avg(salary) FROM employee GROUP BY dept

但如果我們只列出薪資平均值超過 20000元的公司資料

SELECT dept avg(salary) FROM employee GROUP BY dept HAVING avg(salary) gt 20000

ORDER BY子句語法

SELECT column1 SUM(column2) FROM list-of-tables ORDER BY column-list [ASC | DESC]

[ ] =選項

ORDER BY是一個選項子句當你以排序方式來顯示資料(正向由小到大反向由大到小)以指定的欄位資料做排序

ASC = 正向- 預設值 DESC = 反向排序

For example

SELECT employee_id dept name age salary FROM employee_info WHERE dept = Sales ORDER BY salary

以上列出公司代號公司名銷售員人名年紀及薪資而條件是公司名為 Sales 顯示順序以薪資多少排序(由小到大為預設值)

如果要以多個欄位做排序要以逗號做分隔如下

SELECT employee_id dept name age salary FROM employee_info WHERE dept = Sales ORDER BY salary age DESC

85

結合條件及布林運算 SELECT column1 SUM(column2) FROM list-of-tables WHERE condition1 AND condition2 AND運算可以結兩個或以上的條件放在 WHERE子句中 兩者都要為真才

會顯示該筆記錄 OR 運算可以結兩個或以上敘述放在 WHERE子句中只要其中一個為直就

會顯示該筆記錄 For example SELECT employeeid firstname lastname title salary FROM employee_info WHERE salary gt= 5000000 AND title = Programmer 必需要薪資大於等於 50000而且職稱為 Programmer同時符合才會顯示該筆資料 以下以括號括住雖然不是必需的但如此比較容易讀 SELECT employeeid firstname lastname title salary FROM employee_info WHERE (salary gt= 5000000) AND (title = Programmer) 另外範例 SELECT firstname lastname title salary FROM employee_info WHERE (title = Sales) OR (title = Programmer) 條件為只要是 Sales 或 Programmer 職稱的就會被列出 IN and BETWEEN 子句

SELECT column1 SUM(column2) FROM list-of-tables WHERE column3 IN (list-of-values) SELECT column1 SUM(column2) FROM list-of-tables WHERE column3 BETWEEN value1 AND value2 IN 子句使用在列舉項目的使用上也就是分別測試是否符合所列的值 For example

86

SELECT employeeid lastname salary FROM employee_info WHERE lastname IN (Hernandez Jones Roberts Ruiz) 條件為姓氏(astname)要符合 Hernandez Jones Roberts or Ruiz 其中一個才會被傳回 IN運算元也可以使用 OR 的語法來取代如下結果相同 SELECT employeeid lastname salary FROM employee_info WHERE lastname = Hernandez OR lastname = Jones OR lastname = Roberts OR lastname = Ruiz 但使用 IN 句子比較短也比較易懂 你也可以使用 NOT IN 來去掉不要的記錄 BETWEEN 運算元使用在判斷是否存在兩個數值之間 For example SELECT employeeid age lastname salary FROM employee_info WHERE age BETWEEN 30 AND 40 傳回年紀 30歲到 40歲之間的資料(含 30及 40歲者) 相同的也可以使用以下語法來達到相同的結果 SELECT employeeid age lastname salary FROM employee_info WHERE age gt= 30 AND age lt= 40 你也可使用 NOT BETWEEN 來濾掉中間值的資料 數學運算 標準 ANSI SQL-92 提供以下運算

87

+ 加

- 減

餘數

餘數為除法後剩整數這不在標準的 ANSI SQL 中但大部份的資料庫都會支

援這運算元以下列出有用的函數雖不在 ANSI SQL-92 提供但一般資料庫

也會支援他們

ABS(x) 傳回 x 絕對值

SIGN(x) returns the sign of input x as -1 0 or 1 (negative zero or positive respectively)

MOD(xy) 餘數 - returns the integer remainder of x divided by y (同 xy)

FLOOR(x) 傳回小或等於 x 的最大整數值

CEILING(x) or CEIL(x)

傳回大或等於 x 的最小整數值

POWER(xy) x的 y 次方

ROUND(x) 把 x 四捨五入為整數

ROUND(xd) 四捨五入取到小數 d 位

SQRT(x) x 開平方

For example SELECT round(salary) firstname FROM employee_info 傳回薪資取到整數位

如何新增資料

insert 加入一筆新紀錄到資料表中 insert into tablename (first_columnlast_column) values (first_valuelast_value) [] = optional Example insert into employee

88

(first last age address city state) values (Luke Duke 45 2130 Boars Nest Hazard Co Georgia) Note 字串要以單引號住如string 數字框住也無妨 insert into 後面接資料表名稱再接以括號括住的欄位名在 values 後括號分別對映各欄位的值 以上的例子新增了一筆名(first) 為 Luke而住所(state) 為 Georgia 的資料

如何刪除資料

delete 可以刪除單筆或多筆紀錄 delete from tablename where columnname OPERATOR value [and|or column OPERATOR value] [ ] = optional Examples delete from employee Note 如果你沒有指定 where 子句那麼全部的紀錄都會被刪除 delete from employee where lastname = May delete from employee where firstname = Mike or firstname = Eric delete from 接著資料表名 再接著是條件式判斷沒有條件式則全部紀錄會

被刪除

如何更新資料

update 用來更新你所指定的記錄要和 WHERE 配合小心使用 語法 update tablename set columnname = newvalue[nextcolumn = newvalue2] where columnname OPERATOR value [and|or column OPERATOR value] [] = optional Examples

89

update phone_book set area_code = 623 where prefix = 979 update phone_book set last_name = Smith prefix=555 suffix=9292 where last_name = Jones update employee set age = age+1 where first_name=Mary and last_name=Williams

90

附錄二Replication

測試環境

RedHat 90 + MySQL 32358 MySQL資料庫路徑 varlibmysql MySQL設定檔 etcmycnf Master IP 1921680100 Slave IP 1921680200 請至下列網址下載最新MySQL 32358套件並利用rpm ndashUvh 更新 httpupdatesredhatcom9enosi386

圖 最新 MySQL 套件

測試架構圖

91

1921680100

1921680200Master Server

erveSlave S r

圖 測試架構圖

測試步驟

Master server 部份 Step1 確認 MasterSlave機器上所裝的 MySQL版本能進行

replication( 32329 or higher ) Step2 在 Master MySQL上開放一個帳號給 Slave mysql ndashu root ndashp mysqlgtGRANT FILE ON TO repl1921680200 IDENTIFIED BY lsquoabc123rsquo mysqlgtq 上面是 Master開放一個帳號 repl密碼 abc123給 IP1921680200有檔案處理

的權限 Step3 shutdown MySQL on the Master mysqladmin ndashu root ndashp shutdown Step4 備份 Master所有資料庫 tar ndashcvf tmpmysql-snapshottar varlibmysql 注意tar的時候MySQL是要在 stop情況下 在mysql (wwwmysqlcom) 網站的FAQ有不用shutdown的方法

92

Step5 在 master機器上修改etcmycnf 在[mysqld]區段內加入參數 log-bin server-id=這邊設定 server-id=1 sql-bin-update-same binlog-do-db=CRM只針對 CRM資料庫做紀錄 Step6 Restart MySQL on the master service mysqld start 此時因為有加入 log-bin 參數因此開始有 index產生了在varlibmysql目錄下

有index檔案紀錄資料庫的異動 log Slave server 部份 Step1 在 slave設定etcmycnf 在[mysqld]區段加入 master-host= master-user= master-password= master-port= server-id= 這邊設定 master-host=1921680100 master-user=repl master-password=abc123 master-port=3306 server-id=2 master-connect-retry=60預設重試間隔 60秒 replicate-do-db=CRM告訴 slave只做 CRM資料庫的更新 log-slave-updates Step2 將 master上的 mysql-snapshottar copy到 slave上 用 ftp傳到 slave的tmp Step3 解壓縮 Master資料庫至 Slave Server上 cd varlib tar xvf tmpmysql-snapshottar chown ndashR mysqlmysql mysql

93

chmod ndashR 770 mysql (視情況) Step4 Restart MySQL on the slave server 這時在varlibmysql目錄會出現 masterinfo此檔案紀錄了 Master MySQL server的資訊

狀況測試

One-way replication

1921680100

1921680200Master Server

erveSlave S r

圖 One-way replication架構圖 Step1 Master跟 Slave網路及服務都正常情況下由 Master端異動資料後 到 Slave端瀏覽資料檢視是否有進行 replication Step2 模擬 Slave Server 當機 可用在於 slave真的當機或是 Slave 不一定需要一直跟 master connect將Slave MySQL server shutdown由 Master端異動資料到 slave端瀏覽此時Slave應該沒有被 replication 更新然後再將 Slave端 MySQL server start起來

預設 60秒後 Slave會嘗試跟 Master要求進行 replication再去 Slave端檢視是否有更新資料

94

Step3 模擬 Master當機因為是設定 One-way replication一旦 Master Server Slave端沒有 Master的 source可以 download Two-way replication 基於 Master當機狀況於是發展雙向 Replication即 1921680100 ( Host A ) 1921680200 ( Host B )都分別擔任 MasterSlave身分

1921680100

1921680200er

Server B MasterSlave Server

Server A MasterSlave Serv

圖 Two-way replication架構圖 以下是針對兩台 MySQL伺服器進行雙向 Replication Step1觀念同單向 replication只是改成 Master也有 Slave身分 Slave也有Master的身分先分別在 Server AServer B 都去 grant一個進行 replication的身分 [A]mysqlgtGRANT FILE ON TO repl1921680200 IDENTIFIED BY lsquoabc123rsquo [B]mysqlgt GRANT FILE ON TO repl1921680100 IDENTIFIED BY lsquoabc123rsquo Step2做完單向 replication後stop Server Aserver B MySQL service此時 AB資料是一樣的

95

修改etcmycnf設定 範例 Server A [mysqld] datadir=varlibmysql socket=varlibmysqlmysqlsock server-id=1 log-bin sql-bin-update-same binlog-do-db=CRM master-host=1921680200 master-user=repl master-password=abc123 log-slave-updates master-connect-retry=60 replicate-do-db=CRM Server B [mysqld] datadir=varlibmysql socket=varlibmysqlmysqlsock server-id=2 log-bin sql-bin-update-same binlog-do-db=CRM master-host=1921680100 master-user=repl master-password=abc123 log-slave-updates master-connect-retry=60 replicate-do-db=CRM 分別 start Server AServer B MySQL後此時雙方都是 MasterSlave身分一旦哪一方資料異動就會通知對方來 replication-若 replication失效則必須將Server AServer B的masterinfo及index00x 都砍掉然後分別 restart MySQL server進行測試檢視成果 實務上通常如果需要做Two-way replication通常會搭配Virtual Server使用

96

在前端架設一台Virtual Server不過此部份不在此份SOP討論範圍內有興趣

的讀者可參考 httpwwwlinuxvirtualserverorg 網站

1921680100 1921680200

Host A MasterSlave Server

Host B MasterSlave Server

Virtual Host

圖 Virtual Server + Two-way replication 架構圖

97

圖 High Availability Linux Virtual Server架構圖

98

  • COSA-SOP-03-006
  • 第一章 簡介
    • 11適用對象 (Audience)
    • 12 MySQL本身
    • 13 MySQL 40版跟50版重大的改進功能
    • 14 各家資料庫軟體比較
      • 第二章 前置需求
      • 第三章 安裝
        • 31 MySQL安裝
        • 32 phpMyAdmin安裝
        • 33 升級及注意事項
          • 第四章 MySQL管理
            • 41 Webmin 管理介面
            • 42 phpMyAdmin 的操作介面
            • 43管理指令介紹
              • 431 利用mysqladmin設定root的密碼
                  • 第五章 實用範例
                    • 51 任務一Web Base客戶通訊錄
                    • 52 任務二Web Base群組軟體 ( twig )
                      • 第六章 維護及更新程序
                        • 61 日常維護
                        • 62 更新程序
                        • 63 備份重要檔案
                        • 64 離線備份與還原
                        • 65 線上備份與還原
                          • 第七章 問題與解答
                          • 第八章 參考資料
                          • 附錄一 SQL Command 介紹
                          • 附錄二Replication
Page 53: DataBase Server Standard Operation Procedureebooks.lib.ntu.edu.tw/1_file/oss/63/93doc4-5.pdf · 業務的公司帶來了不少壓力,譬如微軟,甲骨文 ... 外的錢用在第三方的資料庫產品上,譬如就可以不用再購買甲骨文公司

圖 5-5 編輯資料

圖 5-6 更新資料

513 程式內容及說明

lt-- 程式範例indexhtml--gt lthtmlgt ltheadgtlttitlegt通訊錄lttitlegtltheadgt ltbodygt ltcentergt

53

lth2gt通訊錄lth2gtlthrgt lta href=indexhtmlgt通訊錄ltagt | lta href=addphpgt新增連絡人ltagt | lta href=searchphpgt搜尋通訊錄ltagt ltcentergt ltbodygt lthtmlgt lt-- 程式範例addphp --gt lthtmlgt ltheadgtlttitlegt新增連絡人lttitlegtltheadgt ltbodygt ltcentergtlth2gt新增連絡人lth2gtltcentergtlthrgt lt 取得欄位資料 if (isset($_POST[Name]) ampamp isset($_POST[Tel]) ) $name = $_POST[Name] $tel = $_POST[Tel] 檢查是否有輸入欄位資料 if ($name = ampamp $tel = ) 建立 SQL字串 $sql = INSERT INTO address (name tel) values( $sql= $name $tel) 建立 MySQL 連結 $link = mysql_connect(localhostroot1234) 選擇資料庫 mysql_select_db(CONTACT) 執行 SQL指令 mysql_query($sql) mysql_close($link) echo ltfont color=redgt新增連絡人成功ltfontgtltbrgt gt ltform action=addphp method=postgt lttable border=0 width=300gt lttrgtlttdgt姓名 lttdgt

54

lttdgtltinput type=text name=Name size=20 maxlength=10gtlttdgtlttrgt lttrgtlttdgt電話 lttdgt lttdgtltinput type=text name=Tel size=20 maxlength=20gtlttdgtlttrgt lttrgtlttd colspan=2 align=centergt ltinput type=submit value=新增連絡人gtlttdgtlttrgt lttablegt ltformgt ltbrgtlta href=indexhtmlgt通訊錄ltagt | lta href=addphpgt新增連絡人ltagt | lta href=searchphpgt搜尋通訊錄ltagt ltbodygt lthtmlgt

lt-- 程式範例searchphp --gt lthtmlgt ltheadgtlttitlegt搜尋通訊錄lttitlegtltheadgt ltbodygt ltcentergtlth2gt搜尋通訊錄lth2gtlthrgt lt if (isset($_POST[Search])) 建立資料庫連結並選定資料庫 $link = mysql_connect(localhostroot1234) mysql_select_db(CONTACT) 建立基本的 SQL字串 $sql = SELECT FROM address 檢查是否輸入姓名 if (chop($_POST[Name]) = ) $name = name LIKE $_POST[Name] else $name = 檢查是否輸入電話號碼 if (chop($_POST[Tel]) = ) $tel = tel LIKE $_POST[Tel] else $tel =

55

if條件組合 SQL字串 if (chop($name) = ampamp chop($tel) = ) $sql= WHERE $name AND $tel elseif (chop($name) = ) 只有姓名 $sql = WHERE $name elseif (chop($tel) = ) 只有電話號碼 $sql = WHERE $tel $sql= ORDER BY name 最後加上排序 $result = mysql_query($sql) 取得欄位數 $total_fields = mysql_num_fields($result) echo lttable border=1gt echo lttrgtlttdgt編號lttdgtlttdgt姓名lttdgtlttdgt電話lttdgtlttd colspan=2gt功能選項lttdgtlttrgt 表格顯示查詢結果 while ($rows = mysql_fetch_array($result MYSQL_NUM)) echo lttrgt for ($i = 0 $i lt $total_fields $i++) echo lttdgt$rows[$i]lttdgt echo lttdgtlta href=editphpaction=editampid= echo $rows[0]gtltbgt編輯ltbgtlttdgt echo lttdgtlta href=editphpaction=delampid= echo $rows[0]gtltbgt刪除ltbgtlttdgt echo lttrgt echo lttablegtlthrgt mysql_free_result($result) mysql_close($link) gt ltcentergt ltform action=searchphp method=postgt lttable border=0 width=450gt lttrgtlttdgt搜尋姓名 lttdgt lttdgtltinput type=text name=Name size=10 maxlength=20gtlttdgtlttrgt lttrgtlttdgt搜尋電話 lttdgt lttdgtltinput type=text name=Tel

56

size=20 maxlength=20gtlttdgtlttrgt lttrgtlttd colspan=2 align=centergt ltinput type=submit name=Search value=搜尋gtlttdgtlttrgt lttablegt ltformgt ltbrgtlta href=indexhtmlgt通訊錄ltagt | lta href=addphpgt新增連絡人ltagt | lta href=searchphpgt搜尋通訊錄ltagt ltbodygt lthtmlgt

lt ob_start() gt lt-- 程式範例editphp --gt lthtmlgt ltheadgtlttitlegt編輯通訊錄lttitlegtltheadgt ltbodygt lt 取得 URL 參數 $id = $_GET[id] $action = $_GET[action] 建立資料庫連結 $link = mysql_connect(localhostroot1234) mysql_select_db(CONTACT) 選擇資料庫 執行的操作 switch ($action) case update 更新 取得欄位資料 $name = $_POST[Name] $tel = $_POST[Tel] $sql = UPDATE address SET name=$name tel=$tel WHERE id=$id mysql_query($sql) 執行 SQL指令 mysql_close($link) header(Location searchphp) 轉向到 serachphp break case del 刪除 $sql = DELETE FROM address WHERE id=$id

57

mysql_query($sql) 執行 SQL指令 mysql_close($link) header(Location searchphp) 轉向到 serachphp break case edit 編輯 $sql = SELECT FROM address WHERE id=$id $result = mysql_query($sql) 執行 SQL指令 $row = mysql_fetch_row($result) 取回記錄 $name = $row[1] 取得欄位 name $tel = $row[2] 取得欄位 tel mysql_close($link) 顯示編輯表單 gt ltcentergtlth2gt更新通訊錄lth2gtltcentergtlthrgt ltform action=editphpaction=updateampid=lt echo $id gt method=postgt lttable border=0 width=300gt lttrgtlttdgt姓名 lttdgt lttdgtltinput type=text name=Name size=20 maxlength=10 value=lt echo $name gtgtlttdgtlttrgt lttrgtlttdgt電話 lttdgt lttdgtltinput type=text name=Tel size=20 maxlength=20 value=lt echo $tel gtgtlttdgtlttrgt lttrgtlttd colspan=2 align=centergt ltinput type=submit value=更新連絡人gtlttdgtlttrgt lttablegt ltformgt ltbrgtlta href=indexhtmlgt通訊錄ltagt | lta href=addphpgt新增連絡人ltagt | lta href=searchphpgt搜尋通訊錄ltagt lt break gt ltbodygt lthtmlgt

58

52 任務二Web Base群組軟體 ( twig )

順利完成Web Base客戶通訊錄程式測試一段時間後「Apache + MySQL + PHP」架構的穩定與快速巳深得老闆與公司所有同事的認同隨著公司業績蒸

蒸日上人員組織編罝愈來愈龐大跨部門的會議愈來愈多業務員每日排滿拜

訪客戶的行程跟客戶的 Email的往來也愈來愈頻繁 愈來愈多部門的同事希望公司能建置一套群組軟體提供 web mail可讓業

務人員方便收發 mail還有連絡人議事日程待辦工作書簽等功能讓整個

公司運作及個人時間管理更有效率

老闆問小明對這些需求有什麼看法小明認為如果這些功能完全由程式部

門開發必定曠日費時而且耗費公司資源小明在網路尋找是否有提供這些功能

的Free Software皇天不負苦心人小明發現了TWIG (The Web Information Gateway) httptwigscrewdrivernet這個群組軟體它在 Web 上整合郵件新聞聯絡人議事日程工作序書簽等功能非常符合公司的需求 Step 1 下載 twig-277targz 下載網址 httptwigscrewdrivernetdownloadphp3

Step 2 解開 twig-277targz tar -xzvf twig-277targz

59

Step 3 執行安裝動作安裝到 varwwwhtmltwig 目錄 cd twig-277 twig-install varwwwhtmltwig

Step 4 建立 MySQL 資料庫(twig)及各資料表

cd setup mysql -u root -p1234 mysqlgt create database twig Query OK 1 row affected (001 sec) mysqlgt quit mysql -u root ndashp1234 twiglt twigtablemysql

Step 5 修改 configincphp3 參數設定 vi varwwwhtmltwigconfigconfigincphp3 $config[fromdomain] = opencom 網域 $config[language] = chinesebig5 中文訊息 $config[imap_port] = 143notls

60

Step 6 修改連結 MySQL 的帳號密碼 vi varwwwhtmltwigconfigdbconfigincphp3 $dbconfig[sqlusername] = root username $dbconfig[sqlpassword] = 1234 password

Step 7 其他設定檔

vi etchttpdconfhttpdconf 加入 AddType applicationx-httpd-php php3 在 DirectoryIndex最後加入 indexphp3 DirectoryIndex indexhtml indexhtmlvar indexphp3 在 AddDefaultCharset ISO-8859-1加上 AddDefaultCharset ISO-8859-1

vi etcphpini register_globals = On service httpd restart Step 8 sendmail 設定 vi etcmailsendmailcf在 264 行前面加上並重新啟動 sendmail「service snedmail restart」 262 SMTP daemon options 263 264 O DaemonPortOptions=Port=smtpAddr=127001 Name=MTA 265 266 SMTP client options 267 O ClientPortOptions=Family=inet Address=00

61

Step 9 檢查設定有無錯誤 http主機名稱twigtestphp3

62

Step 10 登入 twig ( http主機名稱twig)

63

第六章 維護及更新程序

61 日常維護

系統管理員最好定期以 root 身份登入看看信件在 RedHat Linux 中有一支 logwatch 程式會定時去分析 log file如果發現異常便會發信給 root除此之外筆者建議讀者平時就檢查 MySQL log file ( varlogmysqldlog)是否有異常情形

62 更新程序

讀者可至httprpmfindnet 尋找MySQL相關套件至於升級的相關步驟請參

考Linux OS SOP 第 54節

63 備份重要檔案

預設 MySQL 的 DB 檔案是存在 varlibmysql 內以 DB名稱為目錄目錄

內就是該 DB 的所有資料通常得定期備份還有 MySQL的設定檔 etcmycnf也別忘了一起備份

64 離線備份與還原

641 離線備份

預設 MySQL 的 DB 檔案是存在 varlibmysql 內以 DB 名稱為目錄目錄內

就是該 DB 的所有資料像 CRM 這個 DB就是存在 varlibmysqlCRM 內在備份前因為怕資料尚未完全寫入磁碟而且 MySQL 會 Lock 在使用的 DB 檔案所以應該是要先把 MySQL 先 Shutdown 一下整個備份的程序可以下像下面的指令去完成 cd varlibmysql

64

service mysqld stop tar cvfz CRM_db_20030905tgz CRM service mysqld start 對這樣就可以了 不過要注意的是怕 DB 內每個 Tables 間的資料有關關

聯性所以最好是把整個 DB 一次備起來單獨只備哪個 Tables 的檔案以後回存時怕會有資料關聯不一致的問題

642 離線還原

DB 發生錯誤而要回存時其實也不難先找出最近一次完整正常的備份先把現在錯誤的網頁或 DB 先更名或 tar 起來再把好的備份給解開回原來目錄位

置就行了需要注意的是 MySQL 服務最好也是要先停止回存完成後再啟動服務回存 DB 的整個程序可能像下面 cd varlibmysql service mysqldstop mv CRM CRM_OLD tar xvfz CRM_db_20030905tg service mysqld start

65 線上備份與還原

651 線上備份

使用像上面的檔案方式備份是個不錯的方法它最少可以保持該主機某個時間點的完整檔案備份但還是有一些問題需要考慮到有些主機就不只建立一個 DB 而已總不能為了備份某個 DB 而把整個 MySQL 服務停止備份檔案的方式回存在原主機上一定適用但假如 MySQL 版本升級或是在那天該網頁空間需遷機移機到別的主機時那就沒人敢保證備出來的資料檔可以用所以我們可以考慮另一種備份的方式是使用 MySQL 本身提供的功能 MySQL Data Dump指令是 mysqldump

65

使用 MySQL 的 Dump 功能可以把 DB 的結構資料或結構加資料 Dump 成文字檔 mysqldump 指令提供的彈性很大你可以選擇把整個 DB Dump 成一個檔或是每個 Table 為一個檔甚至是把結構檔和資料分開儲存都

可以 mysqladmin -uroot -p flush-logs mysqldump CRM -uroot -p --opt gt CRM_20030905sql (CRM 是 DB 名稱 opt 是一個使用完整 Dump 參數) 假如只是要單獨 Dump 某個 Table 時只要在上面的指令後轉出符號 gt 前加個 Table 名稱就可以如只要 phpbb2_users 這個 Table 的 Dump 時只要下 mysqldump CRM -uroot -p --opt CUSTOMER gt CRM_CUSTOMER_20030905sql

652 線上還原

若要回存整個資料庫只需將壓縮的備份檔還原成 Dump 的檔案再用下面的指令回存 mysql CRM -uroot -p lt CRM_20030905sql 這邊需注意的是若建立備份時是以--opt或--add-drop-table為參數時回存的 動作是先將舊的 Table 先刪除重建 Table 的結構後再把 Data 匯入所以回存後所有的資料會回到你當時備份那個時間點因此在回存資料時可以考慮把現有錯誤或不完整的 DB 先備份一份下來以備不時之需或是拿來比對錯誤的地

方在那裡當然你也可以把資料回存到另一個測試用的 DB 內只要把上面指令

的 DB 名稱改成你的測試用 DB 名稱即可 使用這種回存方式 MySQL 服務不需停止也不會動到其他正在使用的 DB 在一些提供 MySQL 服務的虛擬主機可用這種方式作你自己的 DB 備份及回存

66

另外假如你是系統重建或是移機時切需在新的 MySQL 內新建一個空白 DB 後才行作回存的工作你可以用下面的指令建立 mysql -uroot -p -e CREATE DATABASE CRM (上面的 CRM是你要新建的 DB 名稱) 另一種作法先用 mysql 指令進入 mysql client console 然後再用 CREATE DATABASE CRM 這樣就行了記得尾端要加個 符號該行指令才會執行

67

第七章 問題與解答

Q1RedHat 90預附的 MySQL到底有無支援 Transcation機制 Ans MySQL自 32334a之後的 MySQL-Max版本加入 InnoDB的資料庫類型透過

InnoDBMySQL同樣可以進行 COMMIT與 ROLLRACK的動作RedHat 90預附的 MySQL為 32354a-11巳支援 InnoDB的資料庫類型不過必須做以

下設定 1cp usrsharedocmysql-server-32354amy-mediumcnf to etcmycnf 2 vi etcmycnf 將以下設定前的拿掉 innodb_data_home_dir = varlibmysql innodb_data_file_path = ibdata110Mautoextend innodb_log_group_home_dir = varlibmysql innodb_log_arch_dir = varlibmysql 3service mysqld restart 如此一來各位在建立Table時便可指定Table Type為 innodb ( ex create table with type=innodb ) Q2如何解決 php+mysql 許功蓋等字變亂的問題 Ans 方法一 【確定 MySQL 預設的字元集】 1 打開 WinMySQLadmin 管理畫面(在視窗右下角狀態列紅綠燈圖示中按滑鼠

右鍵點選 Show me 選項) 2 點選管理畫面中 [Variables] 標籤選項其中 character_set變數就是您預設

字元集的變數其預設是 latin1 字元集(我們要將他改回 big5)而 chatacters_set 變數則是 MySQL 可以支援哪些字元集 【修改預設字元集變數 character_set 】 1 請點選管理畫面中 [myini Setup] 標籤選項設定 myini 2 按一下 [Pick-up and Edit myini values] 按鈕以便編輯目前的 myini 設定 3 在 [mysqld] 設定區塊底下新增一行 default-character-set = big5 變數設

68

定 4 新增一個 [client] 設定區塊並加入第三步驟的變數設定(游標往下移到空白處新增兩行 [client] 和 default-character-set=big5) 5 按一下畫面左下方 [Save Modification] 按鈕儲存設定 6 重新啟動 MySQL 或 Windows 方法二 Server端注意事項 phpini 中有關的設定為(預設值) Magic quotes for incoming GETPOSTCookie data magic_quotes_gpc = On Use Sybase-style magic quotes (escape with instead of ) magic_quotes_sybase = Off Client端注意事項 1中文資料送進 mysql 前請用 addslashes($str) 處理 2處理後送進 mysql 時請用 括起來並在參數後留一個空白如 $sql = UPDATE ezf_table set tablename=$tname tableend=$endtime table inguser=$tguser tableingid=$tguserid tableallnumber=$tnumber tableloca l=$tablelocal tableanyone=$tableopen tabletext=$ttext WHERE tableid=$t ableid tablename=$tname c 取出時請用 stripslashes($str) Q3MySQL root 密碼忘了該怎麼辦 Ans 1先停掉 mysql etcrcdinitdmysql stop 2以--skip-grant-table 的參數啟動 mysql safe_mysql --skip-grant-tableamp 3 更改 root 密碼 mysql mysql mysqlgt UPDATE user SET password=password(newpassword)

69

WHERE user=root mysqlgt FLUSH PRIVILEGES mysqlgt exit 4停掉 mysql再重跑 mysqladmin -uroot -p shutdown Enter password 輸入新設定的密碼 etcrcdinitdmysql start

Q4NULL值問題

Ans

NULL值的概念是造成 SQL的新手的混淆的普遍原因他們經常認為 NULL是和一個空字符串的一樣的東西不是這樣的例如下列語句是完全不同的

mysqlgt INSERT INTO my_table (phone) VALUES (NULL)

mysqlgt INSERT INTO my_table (phone) VALUES ()

兩個語句把值插入到 phone 列但是第一個插入一個 NULL值而第二個插入一個空字符串第一個的含義可以認為是ldquo電話號碼不知道而第二個則可意味

著ldquo她沒有電話

在 SQL中NULL值在于任何其他值甚至 NULL值比較時總是假的(FALSE)包含 NULL的一個表達式總是產生一個 NULL值除非在包含在表達式中的運算符和函數的文檔中指出在下列例子所有的列返回 NULL

mysqlgt SELECT NULL1+NULLCONCAT(InvisibleNULL)

如果你想要尋找值是 NULL的列你不能使用=NULL測試下列語句不返回任

何行因為對任何表達式expr = NULL是假的

mysqlgt SELECT FROM my_table WHERE phone = NULL

要想尋找 NULL值你必須使用 IS NULL測試下例顯示如何找出 NULL電話號碼和空的電話號碼

70

mysqlgt SELECT FROM my_table WHERE phone IS NULL mysqlgt SELECT FROM my_table WHERE phone =

在 MySQL中就像很多其他的 SQL服務器一樣你不能索引可以有 NULL值的列你必須聲明這樣的列為 NOT NULL而且你不能插入 NULL到索引的

列中

當用 LOAD DATA INFILE 讀取數據時空列用更新如果你想要在一個列中有

NULL值你應該在文本文件中使用N字面上的詞NULL也可以在某些情形下使用

當使用 ORDER BY時首先呈現 NULL值如果你用 DESC以降序排序NULL值最後顯示當使用 GROUP BY時所有的 NULL值被認為是相等的

為了有助于NULL的處理你能使用 IS NULL和 IS NOT NULL運算符和 IFNULL()函數

對某些列類型NULL值被特殊地處理如果你將 NULL插入表的第一個TIMESTAMP 列則插入當前的日期和時間如果你將 NULL插入一個AUTO_INCREMENT 列則插入順序中的下一個數字

Q5如何將圖片存放於 MySQL中

Ans

Step 1建立資料庫 test

Step 2 建立表格 binary_data

CREATE TABLE binary_data (

id INT(4) NOT NULL AUTO_INCREMENT PRIMARY KEY

description CHAR(50)

bin_data LONGBLOB

filename CHAR(50)

filesize CHAR(50)

filetype CHAR(50)

71

)

Step 3 利用 storephp 寫入圖片

storephp 程式碼

ltHTMLgt ltHEADgtltTITLEgtStore binary data into SQL DatabaseltTITLEgtltHEADgt ltBODYgt lt code that will be executed if the form has been submitted

if ($submit) mysql_connect(localhostrootYOUR_PASSWORD) mysql_select_db(test) $data=Base64_Encode(fread(fopen($form_data r) filesize($form_data))) $result=MYSQL_QUERY(INSERT INTO binary_data (descriptionbin_datafilenamefilesizefiletype) VALUES ($form_description$data$form_data_name$form_data_size$form_data_type)) $id= mysql_insert_id() print ltpgtThis file has the following Database ID ltbgt$idltbgt MYSQL_CLOSE() else else show the form to submit new data

gt

ltform method=post action=ltphp echo $PHP_SELF gt enctype=multipartform-datagt File Descriptionltbrgt ltinput type=text name=form_description size=40gt ltINPUT TYPE=hidden name=MAX_FILE_SIZE value=4000000gt ltbrgtFile to uploadstore in databaseltbrgt ltinput type=file name=form_data size=40gt ltpgtltinput type=submit name=submit value=submitgt ltformgt lt

72

gt ltBODYgt ltHTMLgt

Step 3 利用 storephp 取出圖片

getdataphp 程式碼

lt Syntax getdataphp3id=ltidgt if($id) you may have to modify login information for your database server MYSQL_CONNECT(localhostrootYOUR_PASSWORD) mysql_select_db(test) $query = select bin_datafiletype from binary_data where id=$id $result = MYSQL_QUERY($query) $data = Base64_Decode(MYSQL_RESULT($result0bin_data)) $type = MYSQL_RESULT($result0filetype) Header( Content-type $type) echo $data gt

Q6MySQL裝好之後啟動時或是執行 mysqladmin會出現如下訊息 Cant connect to local MYSQL Server through Socket varlibmysqlmysqlsock或是

Cant connect to local MYSQL Server through Socket tmpmysqldsock

Ans 可能有下列幾個原因

1這個 mysqldsock 不見了被某人刪除了或是被一些系統自動執行程式給刪

了例如有些 cron任務便會設定定期刪除 tmp 裡的東西所以呢您只能修改

cron 裡的設定讓它不要清除 mysqldsock 2在啟動時也可以改變 mysqldsock的位置您在啟動 MySQL的時候可以加入此參數usrlocalmysqlbinsafe_mysqld --user=mysql --socket=其他路

徑socket amp 同時得去設定環境變數 MYSQL_UNIX_PORT的值以指定新的

73

路徑 3若是您沒改 MYSQL_UNIX_PORT的值那麼您可以在執行指令的時候才打

例如mysqladmin --socket=其他路徑socket version Q7How to get the last insert id Ans CREATE TABLE product ( id INT(4) NOT NULL AUTO_INCREMENT PRIMARY KEY description VARCHAR(50) ) 1利用 SQL的話 mysqlgt insert into product(description) values(123) Query OK 1 row affected (000 sec) mysqlgt select last_insert_id() +------------------+ | last_insert_id() | +------------------+ +------------------+ 1 row in set (000 sec) ======================================== 2如果是 PHP的話 你可以用mysql_insert_id()取得該 id PHP example $result=MYSQL_QUERY(INSERT INTO product (description) VALUES ($description)) $id= mysql_insert_id() print This file has the following Database ID $id Q8如何將文字檔匯入資料庫 Ans $addr=homehttpdhtmlphpschool001txt $sql_select = load data infile $addr into table test fields terminated by t 解說 $sql_select = load data infile 文字檔名 into table 表格名 fields terminated by

74

t

(欄位分隔以 TAB鍵) 該文字檔須與資料表欄位格式相符 例如欄位有三個 則文字檔為每行一筆資料如下 欄 1資料ltTABgt欄 2資料ltTABgt欄 3資料 欄 1資料ltTABgt欄 2資料ltTABgt欄 3資料 欄 1資料ltTABgt欄 2資料ltTABgt欄 3資料 欄 1資料ltTABgtltTABgt欄 3資料

Q9如何撰寫 MySQL C API Ans Step 1利用文字編輯器撰寫以下程式碼 mysqlcc

include ltstdiohgt

include ltmysqlmysqlhgt

int main (int argc char argv[])

MYSQL mysql

MYSQL_RES res

MYSQL_ROW row

if (argc = 2)

fputs (Usage myc ltdatabasegt stderr)

return 1

if ((mysql_connect(ampmysqllocalhostrootYour_Password)))

fputs (Error connecting stderr)

abort()

75

if (mysql_select_db(ampmysqlargv[1]))

fputs (Error selecting database stderr)

abort()

if (mysql_query(ampmysqlSELECT FROM test_table))

fputs (Error processing query stderr)

abort()

if ((res = mysql_store_result(ampmysql)))

fputs (Error storing results stderr)

abort()

while((row = mysql_fetch_row(res)))

uint i = 0

for (i=0 i lt mysql_num_fields(res) i++)

printf(s row[i])

printf(n)

return 0

Step 2 Compile

gcc -Iusrlocalmysqlinclude -Lusrlocalmysqllibmysql mysqlcc ndashlm -lmysqlclient

(其中 include path與 library path取決於你的 MySQL安裝路徑)

76

如果執行時發生如下 error Run problemerror in loading shared libraries libmysqlclientsoX 將你的 MySQL library path(for exampleusrlocalmysqllibmysql) 加入etcldsoconf and run sbinldconfig -v Q9ASP + MySQL 範例程式 Ans Dim myconn As New ADODBConnection Dim myrs As New Recordset Dim mySQL As String Dim myrows As Long myconnOpen DSN=MyODBCsample mySQL = SELECT from user myrsSource = mySQL Set myrsActiveConnection = myconn myrsCursorLocation = adUseClient myrsOpen myrows = myrsRecordCount myrsClose myconnClose 可參考 httpwwwdwamnetmysqlasp_myodbcasp 有詳細的資料 Q10如何將 MySQL中的資料庫匯出成txt檔 Ans select from TableName into outfile textxls all result fields will seperate by tab

77

第八章 參考資料

英文部份 網址 1 httpwwwmysqlcom MySQL 網站有第一手有關 MySQL的資料 2 httpwwwmysqlcomdocenReplicationhtml 有關 MySQL Replication 的文件 3 httpwwwgeocitiescomsqlhomefaqstore_blobhtml 如何在 MySQL 存放 BLOB的資料 4httpwwwsapdborg 有關 SAP跟 MySQL相關合作的網站 書藉 1 Cooking with MySQL

Paul DuBois has selected sample recipes from the hundreds youll find in his book MySQL

Cookbook In this third and final series of excerpts showcasing these recipes learn how to

compute team standings how to calculate the differences between successive Dec 26

2002 2 Tips for Building Web Database Applications with PHP and MySQL by Hugh E Williams co-author of Web Database Applications with PHP amp MySQL 04042002

3 Managing and Using MySQL 2nd Edition By Tim King George Reese Randy Jay Yarger

4 MySQL Cookbook By Paul DuBoisPublisher OReillyPub Date October 2002

中文部份

78

1 httplinuxtncedutwtechdocmysqlmysql_docmanual_tochtml MySQL 中文手冊 2 httpchenshloxaedutwphpZ_1php PHP+MySQ程式研習設計網站 3 httplinuxtncedutwtechdocbanicdownhtml PHP 4 手冊 4 httpwwwtncedutwadmin_zonephp台南縣教育網網路中心有很多 Linux相關文件 5 httpdobtncedutw網站建置百寶箱有很多 PHP MySQL 相關範例程式 5 httpwwwdbworldcomtw資料庫專家電子雜誌介紹資料庫的重要觀念及名詞

79

附錄一 SQL Command 介紹

SQL (讀音ess-que-el) 是一種結構查詢語法SQL 使用於資料庫交流

傳遞相容於 ANSI (American National Standards Institute) 是一套標準的關聯

式資料庫語言 SQL 語言是執行更新或從資料系統獲取資料一般常見的關聯

資料庫系統都有提供 SQL 如 Oracle Sybase Microsoft SQL Server Access Ingres 等雖然大部份的資料庫都有提供 SQL 但也多提供了自已獨特的語

法造成了不相容的情形但標準基本的語法是相通的如Select Insert Update Delete Create and Drop 每一個系統都有支援

Table相關 Command

Create Table

關聯式資料庫包含有很多元件稱為資料表(tables) 把資料或訊息放在資

料表中 資料表是以不同的名稱做分別資料表由欄列所構成的二維陣列

欄包含欄位名資料型態 及其他可判斷的資訊列是由全部欄位構成一筆一

筆的紀錄 create table 語法用在建立一個新的資料表語法格式如下

create table tablename (column1 data type column2 data type column3 data type)

Format of create table if you were to use optional constraints

create table tablename (column1 data type [constraint] column2 data type [constraint] column3 data type [constraint]) [ ] = optional

Note You may have as many columns as youd like and the constraints are optional

80

Example

create table employee (first varchar(15) last varchar(20) age number(3) address varchar(30) city varchar(20) state varchar(20))

注意建立資料表格式要以括號把前後框住而最後以(分號)做結尾

欄位名不要超過 30個字元長而且不要使用 sql 的關鍵字(如 where select等)而在後面接是型態的宣告(如字串數字日期格式等)

資料型態是來描述欄位的方式如一個欄位Last_Name 是一個姓氏可以使用varchar (可變動長度字串) 資料型態

以下是幾個常見的資料庫型態 char(size) 固定長度字串最長為 255 位元 varchar(size) 變動長度字串最大字元數以 size 來指定 number(size) 數值格式可以是整數也可以是小數最大數字以 size 位數判

斷未指定小數位數由系統內定 date 日期格式 number(sized) 數值格式最大數字以 size 位數判斷d 為小數位數整數位

數為 size-d 位

有何限制當資料表被建立通常有一或數個欄位是要使用來做關聯的功

能 例如unique 限制(唯一值)兩筆記錄不可以相同的值 not null (非空值)該欄位一定要輸入資料不可是空的primary key (主鍵)是每一筆記錄識別的主要方式

Drop a table drop table 刪除資料表(其中的資料也會一併刪除)

drop table tablename

Example

81

drop table 和刪除全部資料是不同的刪除全部資料欄位名稱資訊等還會

存在但刪除資料表會把這一些也一併移除掉

如何查詢資料

Select 基本用法

select 語法是關連式資料庫最常用的部份可以取得你想要的資料這是一個

簡單的範例 select column1[column2etc] from tablename [where condition] [] = optional 在 select 之後所列欄位名則是要顯示的資料部份你可以一一列出各欄位

名或是以 (星號)來代表選擇全部的欄位 from 之後放資料表名稱 where 子句 (選項) 指定要過濾的條件符合者才會顯現 where 可使用的條件運算元 = 等於 gt 大於 lt 小於 gt= 大或等於 lt= 小或等於 ltgt 大相等 LIKE 相似 For example select first last city

82

from empinfo where first LIKE Er 以Er 為開頭的字串就符合要以單引號框住 Or you can specify select first last from empinfo where last LIKE s 最後一字為 S 就符合 select from empinfo where first = Eric 則表示 first name 一定要是 Eric 才可以 範例資料表empinfo 統計函數

MIN 傳回指定欄位最小值

MAX 傳回指定欄位最大值

SUM 傳回指定欄位總和

AVG 傳回指定欄位平均值

COUNT 傳回指定欄位的筆數

COUNT() 傳回資料庫中的總筆數

統計函數使用於資料表中的數值欄位配合 SELECT 語法使用 只用於總結特定單一欄位可以配合 GROUP BY 做篩選但也可以不使用 GROUP BY 語句For example

SELECT AVG(salary) FROM employee

83

傳回全部 salary 平均值

Another example

SELECT AVG(salary) FROM employee WHERE title = Programmer

傳回 salary 平均值條件為 employees 資料表中當 title 等於 Programmer

Example

SELECT Count() FROM employees

傳回 employees 資料表中紀錄總筆數

GROUP BY 語法 SELECT column1 SUM(column2) FROM list-of-tables GROUP BY column-list The GROUP BY 語句可以先以所列的欄位為條件分組排序在一起(可以多欄

位) example 要列出每一個 dept 中最高 salary 值 SELECT max(salary) dept FROM employee GROUP BY dept HAVING 語法

SELECT column1 SUM(column2) FROM list-of-tables GROUP BY column-list HAVING condition

HAVING 子句是 GROUP BY 的一部份用來過濾在 GROUP BY 所選出的資料功能如同 select 命令中 where 條件式一樣只是 HAVING 必需配合 GROUP BY 使用

我們以例子來說明我們要取得每一公司名及每一公司的薪水平均值輸入如下

84

SELECT dept avg(salary) FROM employee GROUP BY dept

但如果我們只列出薪資平均值超過 20000元的公司資料

SELECT dept avg(salary) FROM employee GROUP BY dept HAVING avg(salary) gt 20000

ORDER BY子句語法

SELECT column1 SUM(column2) FROM list-of-tables ORDER BY column-list [ASC | DESC]

[ ] =選項

ORDER BY是一個選項子句當你以排序方式來顯示資料(正向由小到大反向由大到小)以指定的欄位資料做排序

ASC = 正向- 預設值 DESC = 反向排序

For example

SELECT employee_id dept name age salary FROM employee_info WHERE dept = Sales ORDER BY salary

以上列出公司代號公司名銷售員人名年紀及薪資而條件是公司名為 Sales 顯示順序以薪資多少排序(由小到大為預設值)

如果要以多個欄位做排序要以逗號做分隔如下

SELECT employee_id dept name age salary FROM employee_info WHERE dept = Sales ORDER BY salary age DESC

85

結合條件及布林運算 SELECT column1 SUM(column2) FROM list-of-tables WHERE condition1 AND condition2 AND運算可以結兩個或以上的條件放在 WHERE子句中 兩者都要為真才

會顯示該筆記錄 OR 運算可以結兩個或以上敘述放在 WHERE子句中只要其中一個為直就

會顯示該筆記錄 For example SELECT employeeid firstname lastname title salary FROM employee_info WHERE salary gt= 5000000 AND title = Programmer 必需要薪資大於等於 50000而且職稱為 Programmer同時符合才會顯示該筆資料 以下以括號括住雖然不是必需的但如此比較容易讀 SELECT employeeid firstname lastname title salary FROM employee_info WHERE (salary gt= 5000000) AND (title = Programmer) 另外範例 SELECT firstname lastname title salary FROM employee_info WHERE (title = Sales) OR (title = Programmer) 條件為只要是 Sales 或 Programmer 職稱的就會被列出 IN and BETWEEN 子句

SELECT column1 SUM(column2) FROM list-of-tables WHERE column3 IN (list-of-values) SELECT column1 SUM(column2) FROM list-of-tables WHERE column3 BETWEEN value1 AND value2 IN 子句使用在列舉項目的使用上也就是分別測試是否符合所列的值 For example

86

SELECT employeeid lastname salary FROM employee_info WHERE lastname IN (Hernandez Jones Roberts Ruiz) 條件為姓氏(astname)要符合 Hernandez Jones Roberts or Ruiz 其中一個才會被傳回 IN運算元也可以使用 OR 的語法來取代如下結果相同 SELECT employeeid lastname salary FROM employee_info WHERE lastname = Hernandez OR lastname = Jones OR lastname = Roberts OR lastname = Ruiz 但使用 IN 句子比較短也比較易懂 你也可以使用 NOT IN 來去掉不要的記錄 BETWEEN 運算元使用在判斷是否存在兩個數值之間 For example SELECT employeeid age lastname salary FROM employee_info WHERE age BETWEEN 30 AND 40 傳回年紀 30歲到 40歲之間的資料(含 30及 40歲者) 相同的也可以使用以下語法來達到相同的結果 SELECT employeeid age lastname salary FROM employee_info WHERE age gt= 30 AND age lt= 40 你也可使用 NOT BETWEEN 來濾掉中間值的資料 數學運算 標準 ANSI SQL-92 提供以下運算

87

+ 加

- 減

餘數

餘數為除法後剩整數這不在標準的 ANSI SQL 中但大部份的資料庫都會支

援這運算元以下列出有用的函數雖不在 ANSI SQL-92 提供但一般資料庫

也會支援他們

ABS(x) 傳回 x 絕對值

SIGN(x) returns the sign of input x as -1 0 or 1 (negative zero or positive respectively)

MOD(xy) 餘數 - returns the integer remainder of x divided by y (同 xy)

FLOOR(x) 傳回小或等於 x 的最大整數值

CEILING(x) or CEIL(x)

傳回大或等於 x 的最小整數值

POWER(xy) x的 y 次方

ROUND(x) 把 x 四捨五入為整數

ROUND(xd) 四捨五入取到小數 d 位

SQRT(x) x 開平方

For example SELECT round(salary) firstname FROM employee_info 傳回薪資取到整數位

如何新增資料

insert 加入一筆新紀錄到資料表中 insert into tablename (first_columnlast_column) values (first_valuelast_value) [] = optional Example insert into employee

88

(first last age address city state) values (Luke Duke 45 2130 Boars Nest Hazard Co Georgia) Note 字串要以單引號住如string 數字框住也無妨 insert into 後面接資料表名稱再接以括號括住的欄位名在 values 後括號分別對映各欄位的值 以上的例子新增了一筆名(first) 為 Luke而住所(state) 為 Georgia 的資料

如何刪除資料

delete 可以刪除單筆或多筆紀錄 delete from tablename where columnname OPERATOR value [and|or column OPERATOR value] [ ] = optional Examples delete from employee Note 如果你沒有指定 where 子句那麼全部的紀錄都會被刪除 delete from employee where lastname = May delete from employee where firstname = Mike or firstname = Eric delete from 接著資料表名 再接著是條件式判斷沒有條件式則全部紀錄會

被刪除

如何更新資料

update 用來更新你所指定的記錄要和 WHERE 配合小心使用 語法 update tablename set columnname = newvalue[nextcolumn = newvalue2] where columnname OPERATOR value [and|or column OPERATOR value] [] = optional Examples

89

update phone_book set area_code = 623 where prefix = 979 update phone_book set last_name = Smith prefix=555 suffix=9292 where last_name = Jones update employee set age = age+1 where first_name=Mary and last_name=Williams

90

附錄二Replication

測試環境

RedHat 90 + MySQL 32358 MySQL資料庫路徑 varlibmysql MySQL設定檔 etcmycnf Master IP 1921680100 Slave IP 1921680200 請至下列網址下載最新MySQL 32358套件並利用rpm ndashUvh 更新 httpupdatesredhatcom9enosi386

圖 最新 MySQL 套件

測試架構圖

91

1921680100

1921680200Master Server

erveSlave S r

圖 測試架構圖

測試步驟

Master server 部份 Step1 確認 MasterSlave機器上所裝的 MySQL版本能進行

replication( 32329 or higher ) Step2 在 Master MySQL上開放一個帳號給 Slave mysql ndashu root ndashp mysqlgtGRANT FILE ON TO repl1921680200 IDENTIFIED BY lsquoabc123rsquo mysqlgtq 上面是 Master開放一個帳號 repl密碼 abc123給 IP1921680200有檔案處理

的權限 Step3 shutdown MySQL on the Master mysqladmin ndashu root ndashp shutdown Step4 備份 Master所有資料庫 tar ndashcvf tmpmysql-snapshottar varlibmysql 注意tar的時候MySQL是要在 stop情況下 在mysql (wwwmysqlcom) 網站的FAQ有不用shutdown的方法

92

Step5 在 master機器上修改etcmycnf 在[mysqld]區段內加入參數 log-bin server-id=這邊設定 server-id=1 sql-bin-update-same binlog-do-db=CRM只針對 CRM資料庫做紀錄 Step6 Restart MySQL on the master service mysqld start 此時因為有加入 log-bin 參數因此開始有 index產生了在varlibmysql目錄下

有index檔案紀錄資料庫的異動 log Slave server 部份 Step1 在 slave設定etcmycnf 在[mysqld]區段加入 master-host= master-user= master-password= master-port= server-id= 這邊設定 master-host=1921680100 master-user=repl master-password=abc123 master-port=3306 server-id=2 master-connect-retry=60預設重試間隔 60秒 replicate-do-db=CRM告訴 slave只做 CRM資料庫的更新 log-slave-updates Step2 將 master上的 mysql-snapshottar copy到 slave上 用 ftp傳到 slave的tmp Step3 解壓縮 Master資料庫至 Slave Server上 cd varlib tar xvf tmpmysql-snapshottar chown ndashR mysqlmysql mysql

93

chmod ndashR 770 mysql (視情況) Step4 Restart MySQL on the slave server 這時在varlibmysql目錄會出現 masterinfo此檔案紀錄了 Master MySQL server的資訊

狀況測試

One-way replication

1921680100

1921680200Master Server

erveSlave S r

圖 One-way replication架構圖 Step1 Master跟 Slave網路及服務都正常情況下由 Master端異動資料後 到 Slave端瀏覽資料檢視是否有進行 replication Step2 模擬 Slave Server 當機 可用在於 slave真的當機或是 Slave 不一定需要一直跟 master connect將Slave MySQL server shutdown由 Master端異動資料到 slave端瀏覽此時Slave應該沒有被 replication 更新然後再將 Slave端 MySQL server start起來

預設 60秒後 Slave會嘗試跟 Master要求進行 replication再去 Slave端檢視是否有更新資料

94

Step3 模擬 Master當機因為是設定 One-way replication一旦 Master Server Slave端沒有 Master的 source可以 download Two-way replication 基於 Master當機狀況於是發展雙向 Replication即 1921680100 ( Host A ) 1921680200 ( Host B )都分別擔任 MasterSlave身分

1921680100

1921680200er

Server B MasterSlave Server

Server A MasterSlave Serv

圖 Two-way replication架構圖 以下是針對兩台 MySQL伺服器進行雙向 Replication Step1觀念同單向 replication只是改成 Master也有 Slave身分 Slave也有Master的身分先分別在 Server AServer B 都去 grant一個進行 replication的身分 [A]mysqlgtGRANT FILE ON TO repl1921680200 IDENTIFIED BY lsquoabc123rsquo [B]mysqlgt GRANT FILE ON TO repl1921680100 IDENTIFIED BY lsquoabc123rsquo Step2做完單向 replication後stop Server Aserver B MySQL service此時 AB資料是一樣的

95

修改etcmycnf設定 範例 Server A [mysqld] datadir=varlibmysql socket=varlibmysqlmysqlsock server-id=1 log-bin sql-bin-update-same binlog-do-db=CRM master-host=1921680200 master-user=repl master-password=abc123 log-slave-updates master-connect-retry=60 replicate-do-db=CRM Server B [mysqld] datadir=varlibmysql socket=varlibmysqlmysqlsock server-id=2 log-bin sql-bin-update-same binlog-do-db=CRM master-host=1921680100 master-user=repl master-password=abc123 log-slave-updates master-connect-retry=60 replicate-do-db=CRM 分別 start Server AServer B MySQL後此時雙方都是 MasterSlave身分一旦哪一方資料異動就會通知對方來 replication-若 replication失效則必須將Server AServer B的masterinfo及index00x 都砍掉然後分別 restart MySQL server進行測試檢視成果 實務上通常如果需要做Two-way replication通常會搭配Virtual Server使用

96

在前端架設一台Virtual Server不過此部份不在此份SOP討論範圍內有興趣

的讀者可參考 httpwwwlinuxvirtualserverorg 網站

1921680100 1921680200

Host A MasterSlave Server

Host B MasterSlave Server

Virtual Host

圖 Virtual Server + Two-way replication 架構圖

97

圖 High Availability Linux Virtual Server架構圖

98

  • COSA-SOP-03-006
  • 第一章 簡介
    • 11適用對象 (Audience)
    • 12 MySQL本身
    • 13 MySQL 40版跟50版重大的改進功能
    • 14 各家資料庫軟體比較
      • 第二章 前置需求
      • 第三章 安裝
        • 31 MySQL安裝
        • 32 phpMyAdmin安裝
        • 33 升級及注意事項
          • 第四章 MySQL管理
            • 41 Webmin 管理介面
            • 42 phpMyAdmin 的操作介面
            • 43管理指令介紹
              • 431 利用mysqladmin設定root的密碼
                  • 第五章 實用範例
                    • 51 任務一Web Base客戶通訊錄
                    • 52 任務二Web Base群組軟體 ( twig )
                      • 第六章 維護及更新程序
                        • 61 日常維護
                        • 62 更新程序
                        • 63 備份重要檔案
                        • 64 離線備份與還原
                        • 65 線上備份與還原
                          • 第七章 問題與解答
                          • 第八章 參考資料
                          • 附錄一 SQL Command 介紹
                          • 附錄二Replication
Page 54: DataBase Server Standard Operation Procedureebooks.lib.ntu.edu.tw/1_file/oss/63/93doc4-5.pdf · 業務的公司帶來了不少壓力,譬如微軟,甲骨文 ... 外的錢用在第三方的資料庫產品上,譬如就可以不用再購買甲骨文公司

lth2gt通訊錄lth2gtlthrgt lta href=indexhtmlgt通訊錄ltagt | lta href=addphpgt新增連絡人ltagt | lta href=searchphpgt搜尋通訊錄ltagt ltcentergt ltbodygt lthtmlgt lt-- 程式範例addphp --gt lthtmlgt ltheadgtlttitlegt新增連絡人lttitlegtltheadgt ltbodygt ltcentergtlth2gt新增連絡人lth2gtltcentergtlthrgt lt 取得欄位資料 if (isset($_POST[Name]) ampamp isset($_POST[Tel]) ) $name = $_POST[Name] $tel = $_POST[Tel] 檢查是否有輸入欄位資料 if ($name = ampamp $tel = ) 建立 SQL字串 $sql = INSERT INTO address (name tel) values( $sql= $name $tel) 建立 MySQL 連結 $link = mysql_connect(localhostroot1234) 選擇資料庫 mysql_select_db(CONTACT) 執行 SQL指令 mysql_query($sql) mysql_close($link) echo ltfont color=redgt新增連絡人成功ltfontgtltbrgt gt ltform action=addphp method=postgt lttable border=0 width=300gt lttrgtlttdgt姓名 lttdgt

54

lttdgtltinput type=text name=Name size=20 maxlength=10gtlttdgtlttrgt lttrgtlttdgt電話 lttdgt lttdgtltinput type=text name=Tel size=20 maxlength=20gtlttdgtlttrgt lttrgtlttd colspan=2 align=centergt ltinput type=submit value=新增連絡人gtlttdgtlttrgt lttablegt ltformgt ltbrgtlta href=indexhtmlgt通訊錄ltagt | lta href=addphpgt新增連絡人ltagt | lta href=searchphpgt搜尋通訊錄ltagt ltbodygt lthtmlgt

lt-- 程式範例searchphp --gt lthtmlgt ltheadgtlttitlegt搜尋通訊錄lttitlegtltheadgt ltbodygt ltcentergtlth2gt搜尋通訊錄lth2gtlthrgt lt if (isset($_POST[Search])) 建立資料庫連結並選定資料庫 $link = mysql_connect(localhostroot1234) mysql_select_db(CONTACT) 建立基本的 SQL字串 $sql = SELECT FROM address 檢查是否輸入姓名 if (chop($_POST[Name]) = ) $name = name LIKE $_POST[Name] else $name = 檢查是否輸入電話號碼 if (chop($_POST[Tel]) = ) $tel = tel LIKE $_POST[Tel] else $tel =

55

if條件組合 SQL字串 if (chop($name) = ampamp chop($tel) = ) $sql= WHERE $name AND $tel elseif (chop($name) = ) 只有姓名 $sql = WHERE $name elseif (chop($tel) = ) 只有電話號碼 $sql = WHERE $tel $sql= ORDER BY name 最後加上排序 $result = mysql_query($sql) 取得欄位數 $total_fields = mysql_num_fields($result) echo lttable border=1gt echo lttrgtlttdgt編號lttdgtlttdgt姓名lttdgtlttdgt電話lttdgtlttd colspan=2gt功能選項lttdgtlttrgt 表格顯示查詢結果 while ($rows = mysql_fetch_array($result MYSQL_NUM)) echo lttrgt for ($i = 0 $i lt $total_fields $i++) echo lttdgt$rows[$i]lttdgt echo lttdgtlta href=editphpaction=editampid= echo $rows[0]gtltbgt編輯ltbgtlttdgt echo lttdgtlta href=editphpaction=delampid= echo $rows[0]gtltbgt刪除ltbgtlttdgt echo lttrgt echo lttablegtlthrgt mysql_free_result($result) mysql_close($link) gt ltcentergt ltform action=searchphp method=postgt lttable border=0 width=450gt lttrgtlttdgt搜尋姓名 lttdgt lttdgtltinput type=text name=Name size=10 maxlength=20gtlttdgtlttrgt lttrgtlttdgt搜尋電話 lttdgt lttdgtltinput type=text name=Tel

56

size=20 maxlength=20gtlttdgtlttrgt lttrgtlttd colspan=2 align=centergt ltinput type=submit name=Search value=搜尋gtlttdgtlttrgt lttablegt ltformgt ltbrgtlta href=indexhtmlgt通訊錄ltagt | lta href=addphpgt新增連絡人ltagt | lta href=searchphpgt搜尋通訊錄ltagt ltbodygt lthtmlgt

lt ob_start() gt lt-- 程式範例editphp --gt lthtmlgt ltheadgtlttitlegt編輯通訊錄lttitlegtltheadgt ltbodygt lt 取得 URL 參數 $id = $_GET[id] $action = $_GET[action] 建立資料庫連結 $link = mysql_connect(localhostroot1234) mysql_select_db(CONTACT) 選擇資料庫 執行的操作 switch ($action) case update 更新 取得欄位資料 $name = $_POST[Name] $tel = $_POST[Tel] $sql = UPDATE address SET name=$name tel=$tel WHERE id=$id mysql_query($sql) 執行 SQL指令 mysql_close($link) header(Location searchphp) 轉向到 serachphp break case del 刪除 $sql = DELETE FROM address WHERE id=$id

57

mysql_query($sql) 執行 SQL指令 mysql_close($link) header(Location searchphp) 轉向到 serachphp break case edit 編輯 $sql = SELECT FROM address WHERE id=$id $result = mysql_query($sql) 執行 SQL指令 $row = mysql_fetch_row($result) 取回記錄 $name = $row[1] 取得欄位 name $tel = $row[2] 取得欄位 tel mysql_close($link) 顯示編輯表單 gt ltcentergtlth2gt更新通訊錄lth2gtltcentergtlthrgt ltform action=editphpaction=updateampid=lt echo $id gt method=postgt lttable border=0 width=300gt lttrgtlttdgt姓名 lttdgt lttdgtltinput type=text name=Name size=20 maxlength=10 value=lt echo $name gtgtlttdgtlttrgt lttrgtlttdgt電話 lttdgt lttdgtltinput type=text name=Tel size=20 maxlength=20 value=lt echo $tel gtgtlttdgtlttrgt lttrgtlttd colspan=2 align=centergt ltinput type=submit value=更新連絡人gtlttdgtlttrgt lttablegt ltformgt ltbrgtlta href=indexhtmlgt通訊錄ltagt | lta href=addphpgt新增連絡人ltagt | lta href=searchphpgt搜尋通訊錄ltagt lt break gt ltbodygt lthtmlgt

58

52 任務二Web Base群組軟體 ( twig )

順利完成Web Base客戶通訊錄程式測試一段時間後「Apache + MySQL + PHP」架構的穩定與快速巳深得老闆與公司所有同事的認同隨著公司業績蒸

蒸日上人員組織編罝愈來愈龐大跨部門的會議愈來愈多業務員每日排滿拜

訪客戶的行程跟客戶的 Email的往來也愈來愈頻繁 愈來愈多部門的同事希望公司能建置一套群組軟體提供 web mail可讓業

務人員方便收發 mail還有連絡人議事日程待辦工作書簽等功能讓整個

公司運作及個人時間管理更有效率

老闆問小明對這些需求有什麼看法小明認為如果這些功能完全由程式部

門開發必定曠日費時而且耗費公司資源小明在網路尋找是否有提供這些功能

的Free Software皇天不負苦心人小明發現了TWIG (The Web Information Gateway) httptwigscrewdrivernet這個群組軟體它在 Web 上整合郵件新聞聯絡人議事日程工作序書簽等功能非常符合公司的需求 Step 1 下載 twig-277targz 下載網址 httptwigscrewdrivernetdownloadphp3

Step 2 解開 twig-277targz tar -xzvf twig-277targz

59

Step 3 執行安裝動作安裝到 varwwwhtmltwig 目錄 cd twig-277 twig-install varwwwhtmltwig

Step 4 建立 MySQL 資料庫(twig)及各資料表

cd setup mysql -u root -p1234 mysqlgt create database twig Query OK 1 row affected (001 sec) mysqlgt quit mysql -u root ndashp1234 twiglt twigtablemysql

Step 5 修改 configincphp3 參數設定 vi varwwwhtmltwigconfigconfigincphp3 $config[fromdomain] = opencom 網域 $config[language] = chinesebig5 中文訊息 $config[imap_port] = 143notls

60

Step 6 修改連結 MySQL 的帳號密碼 vi varwwwhtmltwigconfigdbconfigincphp3 $dbconfig[sqlusername] = root username $dbconfig[sqlpassword] = 1234 password

Step 7 其他設定檔

vi etchttpdconfhttpdconf 加入 AddType applicationx-httpd-php php3 在 DirectoryIndex最後加入 indexphp3 DirectoryIndex indexhtml indexhtmlvar indexphp3 在 AddDefaultCharset ISO-8859-1加上 AddDefaultCharset ISO-8859-1

vi etcphpini register_globals = On service httpd restart Step 8 sendmail 設定 vi etcmailsendmailcf在 264 行前面加上並重新啟動 sendmail「service snedmail restart」 262 SMTP daemon options 263 264 O DaemonPortOptions=Port=smtpAddr=127001 Name=MTA 265 266 SMTP client options 267 O ClientPortOptions=Family=inet Address=00

61

Step 9 檢查設定有無錯誤 http主機名稱twigtestphp3

62

Step 10 登入 twig ( http主機名稱twig)

63

第六章 維護及更新程序

61 日常維護

系統管理員最好定期以 root 身份登入看看信件在 RedHat Linux 中有一支 logwatch 程式會定時去分析 log file如果發現異常便會發信給 root除此之外筆者建議讀者平時就檢查 MySQL log file ( varlogmysqldlog)是否有異常情形

62 更新程序

讀者可至httprpmfindnet 尋找MySQL相關套件至於升級的相關步驟請參

考Linux OS SOP 第 54節

63 備份重要檔案

預設 MySQL 的 DB 檔案是存在 varlibmysql 內以 DB名稱為目錄目錄

內就是該 DB 的所有資料通常得定期備份還有 MySQL的設定檔 etcmycnf也別忘了一起備份

64 離線備份與還原

641 離線備份

預設 MySQL 的 DB 檔案是存在 varlibmysql 內以 DB 名稱為目錄目錄內

就是該 DB 的所有資料像 CRM 這個 DB就是存在 varlibmysqlCRM 內在備份前因為怕資料尚未完全寫入磁碟而且 MySQL 會 Lock 在使用的 DB 檔案所以應該是要先把 MySQL 先 Shutdown 一下整個備份的程序可以下像下面的指令去完成 cd varlibmysql

64

service mysqld stop tar cvfz CRM_db_20030905tgz CRM service mysqld start 對這樣就可以了 不過要注意的是怕 DB 內每個 Tables 間的資料有關關

聯性所以最好是把整個 DB 一次備起來單獨只備哪個 Tables 的檔案以後回存時怕會有資料關聯不一致的問題

642 離線還原

DB 發生錯誤而要回存時其實也不難先找出最近一次完整正常的備份先把現在錯誤的網頁或 DB 先更名或 tar 起來再把好的備份給解開回原來目錄位

置就行了需要注意的是 MySQL 服務最好也是要先停止回存完成後再啟動服務回存 DB 的整個程序可能像下面 cd varlibmysql service mysqldstop mv CRM CRM_OLD tar xvfz CRM_db_20030905tg service mysqld start

65 線上備份與還原

651 線上備份

使用像上面的檔案方式備份是個不錯的方法它最少可以保持該主機某個時間點的完整檔案備份但還是有一些問題需要考慮到有些主機就不只建立一個 DB 而已總不能為了備份某個 DB 而把整個 MySQL 服務停止備份檔案的方式回存在原主機上一定適用但假如 MySQL 版本升級或是在那天該網頁空間需遷機移機到別的主機時那就沒人敢保證備出來的資料檔可以用所以我們可以考慮另一種備份的方式是使用 MySQL 本身提供的功能 MySQL Data Dump指令是 mysqldump

65

使用 MySQL 的 Dump 功能可以把 DB 的結構資料或結構加資料 Dump 成文字檔 mysqldump 指令提供的彈性很大你可以選擇把整個 DB Dump 成一個檔或是每個 Table 為一個檔甚至是把結構檔和資料分開儲存都

可以 mysqladmin -uroot -p flush-logs mysqldump CRM -uroot -p --opt gt CRM_20030905sql (CRM 是 DB 名稱 opt 是一個使用完整 Dump 參數) 假如只是要單獨 Dump 某個 Table 時只要在上面的指令後轉出符號 gt 前加個 Table 名稱就可以如只要 phpbb2_users 這個 Table 的 Dump 時只要下 mysqldump CRM -uroot -p --opt CUSTOMER gt CRM_CUSTOMER_20030905sql

652 線上還原

若要回存整個資料庫只需將壓縮的備份檔還原成 Dump 的檔案再用下面的指令回存 mysql CRM -uroot -p lt CRM_20030905sql 這邊需注意的是若建立備份時是以--opt或--add-drop-table為參數時回存的 動作是先將舊的 Table 先刪除重建 Table 的結構後再把 Data 匯入所以回存後所有的資料會回到你當時備份那個時間點因此在回存資料時可以考慮把現有錯誤或不完整的 DB 先備份一份下來以備不時之需或是拿來比對錯誤的地

方在那裡當然你也可以把資料回存到另一個測試用的 DB 內只要把上面指令

的 DB 名稱改成你的測試用 DB 名稱即可 使用這種回存方式 MySQL 服務不需停止也不會動到其他正在使用的 DB 在一些提供 MySQL 服務的虛擬主機可用這種方式作你自己的 DB 備份及回存

66

另外假如你是系統重建或是移機時切需在新的 MySQL 內新建一個空白 DB 後才行作回存的工作你可以用下面的指令建立 mysql -uroot -p -e CREATE DATABASE CRM (上面的 CRM是你要新建的 DB 名稱) 另一種作法先用 mysql 指令進入 mysql client console 然後再用 CREATE DATABASE CRM 這樣就行了記得尾端要加個 符號該行指令才會執行

67

第七章 問題與解答

Q1RedHat 90預附的 MySQL到底有無支援 Transcation機制 Ans MySQL自 32334a之後的 MySQL-Max版本加入 InnoDB的資料庫類型透過

InnoDBMySQL同樣可以進行 COMMIT與 ROLLRACK的動作RedHat 90預附的 MySQL為 32354a-11巳支援 InnoDB的資料庫類型不過必須做以

下設定 1cp usrsharedocmysql-server-32354amy-mediumcnf to etcmycnf 2 vi etcmycnf 將以下設定前的拿掉 innodb_data_home_dir = varlibmysql innodb_data_file_path = ibdata110Mautoextend innodb_log_group_home_dir = varlibmysql innodb_log_arch_dir = varlibmysql 3service mysqld restart 如此一來各位在建立Table時便可指定Table Type為 innodb ( ex create table with type=innodb ) Q2如何解決 php+mysql 許功蓋等字變亂的問題 Ans 方法一 【確定 MySQL 預設的字元集】 1 打開 WinMySQLadmin 管理畫面(在視窗右下角狀態列紅綠燈圖示中按滑鼠

右鍵點選 Show me 選項) 2 點選管理畫面中 [Variables] 標籤選項其中 character_set變數就是您預設

字元集的變數其預設是 latin1 字元集(我們要將他改回 big5)而 chatacters_set 變數則是 MySQL 可以支援哪些字元集 【修改預設字元集變數 character_set 】 1 請點選管理畫面中 [myini Setup] 標籤選項設定 myini 2 按一下 [Pick-up and Edit myini values] 按鈕以便編輯目前的 myini 設定 3 在 [mysqld] 設定區塊底下新增一行 default-character-set = big5 變數設

68

定 4 新增一個 [client] 設定區塊並加入第三步驟的變數設定(游標往下移到空白處新增兩行 [client] 和 default-character-set=big5) 5 按一下畫面左下方 [Save Modification] 按鈕儲存設定 6 重新啟動 MySQL 或 Windows 方法二 Server端注意事項 phpini 中有關的設定為(預設值) Magic quotes for incoming GETPOSTCookie data magic_quotes_gpc = On Use Sybase-style magic quotes (escape with instead of ) magic_quotes_sybase = Off Client端注意事項 1中文資料送進 mysql 前請用 addslashes($str) 處理 2處理後送進 mysql 時請用 括起來並在參數後留一個空白如 $sql = UPDATE ezf_table set tablename=$tname tableend=$endtime table inguser=$tguser tableingid=$tguserid tableallnumber=$tnumber tableloca l=$tablelocal tableanyone=$tableopen tabletext=$ttext WHERE tableid=$t ableid tablename=$tname c 取出時請用 stripslashes($str) Q3MySQL root 密碼忘了該怎麼辦 Ans 1先停掉 mysql etcrcdinitdmysql stop 2以--skip-grant-table 的參數啟動 mysql safe_mysql --skip-grant-tableamp 3 更改 root 密碼 mysql mysql mysqlgt UPDATE user SET password=password(newpassword)

69

WHERE user=root mysqlgt FLUSH PRIVILEGES mysqlgt exit 4停掉 mysql再重跑 mysqladmin -uroot -p shutdown Enter password 輸入新設定的密碼 etcrcdinitdmysql start

Q4NULL值問題

Ans

NULL值的概念是造成 SQL的新手的混淆的普遍原因他們經常認為 NULL是和一個空字符串的一樣的東西不是這樣的例如下列語句是完全不同的

mysqlgt INSERT INTO my_table (phone) VALUES (NULL)

mysqlgt INSERT INTO my_table (phone) VALUES ()

兩個語句把值插入到 phone 列但是第一個插入一個 NULL值而第二個插入一個空字符串第一個的含義可以認為是ldquo電話號碼不知道而第二個則可意味

著ldquo她沒有電話

在 SQL中NULL值在于任何其他值甚至 NULL值比較時總是假的(FALSE)包含 NULL的一個表達式總是產生一個 NULL值除非在包含在表達式中的運算符和函數的文檔中指出在下列例子所有的列返回 NULL

mysqlgt SELECT NULL1+NULLCONCAT(InvisibleNULL)

如果你想要尋找值是 NULL的列你不能使用=NULL測試下列語句不返回任

何行因為對任何表達式expr = NULL是假的

mysqlgt SELECT FROM my_table WHERE phone = NULL

要想尋找 NULL值你必須使用 IS NULL測試下例顯示如何找出 NULL電話號碼和空的電話號碼

70

mysqlgt SELECT FROM my_table WHERE phone IS NULL mysqlgt SELECT FROM my_table WHERE phone =

在 MySQL中就像很多其他的 SQL服務器一樣你不能索引可以有 NULL值的列你必須聲明這樣的列為 NOT NULL而且你不能插入 NULL到索引的

列中

當用 LOAD DATA INFILE 讀取數據時空列用更新如果你想要在一個列中有

NULL值你應該在文本文件中使用N字面上的詞NULL也可以在某些情形下使用

當使用 ORDER BY時首先呈現 NULL值如果你用 DESC以降序排序NULL值最後顯示當使用 GROUP BY時所有的 NULL值被認為是相等的

為了有助于NULL的處理你能使用 IS NULL和 IS NOT NULL運算符和 IFNULL()函數

對某些列類型NULL值被特殊地處理如果你將 NULL插入表的第一個TIMESTAMP 列則插入當前的日期和時間如果你將 NULL插入一個AUTO_INCREMENT 列則插入順序中的下一個數字

Q5如何將圖片存放於 MySQL中

Ans

Step 1建立資料庫 test

Step 2 建立表格 binary_data

CREATE TABLE binary_data (

id INT(4) NOT NULL AUTO_INCREMENT PRIMARY KEY

description CHAR(50)

bin_data LONGBLOB

filename CHAR(50)

filesize CHAR(50)

filetype CHAR(50)

71

)

Step 3 利用 storephp 寫入圖片

storephp 程式碼

ltHTMLgt ltHEADgtltTITLEgtStore binary data into SQL DatabaseltTITLEgtltHEADgt ltBODYgt lt code that will be executed if the form has been submitted

if ($submit) mysql_connect(localhostrootYOUR_PASSWORD) mysql_select_db(test) $data=Base64_Encode(fread(fopen($form_data r) filesize($form_data))) $result=MYSQL_QUERY(INSERT INTO binary_data (descriptionbin_datafilenamefilesizefiletype) VALUES ($form_description$data$form_data_name$form_data_size$form_data_type)) $id= mysql_insert_id() print ltpgtThis file has the following Database ID ltbgt$idltbgt MYSQL_CLOSE() else else show the form to submit new data

gt

ltform method=post action=ltphp echo $PHP_SELF gt enctype=multipartform-datagt File Descriptionltbrgt ltinput type=text name=form_description size=40gt ltINPUT TYPE=hidden name=MAX_FILE_SIZE value=4000000gt ltbrgtFile to uploadstore in databaseltbrgt ltinput type=file name=form_data size=40gt ltpgtltinput type=submit name=submit value=submitgt ltformgt lt

72

gt ltBODYgt ltHTMLgt

Step 3 利用 storephp 取出圖片

getdataphp 程式碼

lt Syntax getdataphp3id=ltidgt if($id) you may have to modify login information for your database server MYSQL_CONNECT(localhostrootYOUR_PASSWORD) mysql_select_db(test) $query = select bin_datafiletype from binary_data where id=$id $result = MYSQL_QUERY($query) $data = Base64_Decode(MYSQL_RESULT($result0bin_data)) $type = MYSQL_RESULT($result0filetype) Header( Content-type $type) echo $data gt

Q6MySQL裝好之後啟動時或是執行 mysqladmin會出現如下訊息 Cant connect to local MYSQL Server through Socket varlibmysqlmysqlsock或是

Cant connect to local MYSQL Server through Socket tmpmysqldsock

Ans 可能有下列幾個原因

1這個 mysqldsock 不見了被某人刪除了或是被一些系統自動執行程式給刪

了例如有些 cron任務便會設定定期刪除 tmp 裡的東西所以呢您只能修改

cron 裡的設定讓它不要清除 mysqldsock 2在啟動時也可以改變 mysqldsock的位置您在啟動 MySQL的時候可以加入此參數usrlocalmysqlbinsafe_mysqld --user=mysql --socket=其他路

徑socket amp 同時得去設定環境變數 MYSQL_UNIX_PORT的值以指定新的

73

路徑 3若是您沒改 MYSQL_UNIX_PORT的值那麼您可以在執行指令的時候才打

例如mysqladmin --socket=其他路徑socket version Q7How to get the last insert id Ans CREATE TABLE product ( id INT(4) NOT NULL AUTO_INCREMENT PRIMARY KEY description VARCHAR(50) ) 1利用 SQL的話 mysqlgt insert into product(description) values(123) Query OK 1 row affected (000 sec) mysqlgt select last_insert_id() +------------------+ | last_insert_id() | +------------------+ +------------------+ 1 row in set (000 sec) ======================================== 2如果是 PHP的話 你可以用mysql_insert_id()取得該 id PHP example $result=MYSQL_QUERY(INSERT INTO product (description) VALUES ($description)) $id= mysql_insert_id() print This file has the following Database ID $id Q8如何將文字檔匯入資料庫 Ans $addr=homehttpdhtmlphpschool001txt $sql_select = load data infile $addr into table test fields terminated by t 解說 $sql_select = load data infile 文字檔名 into table 表格名 fields terminated by

74

t

(欄位分隔以 TAB鍵) 該文字檔須與資料表欄位格式相符 例如欄位有三個 則文字檔為每行一筆資料如下 欄 1資料ltTABgt欄 2資料ltTABgt欄 3資料 欄 1資料ltTABgt欄 2資料ltTABgt欄 3資料 欄 1資料ltTABgt欄 2資料ltTABgt欄 3資料 欄 1資料ltTABgtltTABgt欄 3資料

Q9如何撰寫 MySQL C API Ans Step 1利用文字編輯器撰寫以下程式碼 mysqlcc

include ltstdiohgt

include ltmysqlmysqlhgt

int main (int argc char argv[])

MYSQL mysql

MYSQL_RES res

MYSQL_ROW row

if (argc = 2)

fputs (Usage myc ltdatabasegt stderr)

return 1

if ((mysql_connect(ampmysqllocalhostrootYour_Password)))

fputs (Error connecting stderr)

abort()

75

if (mysql_select_db(ampmysqlargv[1]))

fputs (Error selecting database stderr)

abort()

if (mysql_query(ampmysqlSELECT FROM test_table))

fputs (Error processing query stderr)

abort()

if ((res = mysql_store_result(ampmysql)))

fputs (Error storing results stderr)

abort()

while((row = mysql_fetch_row(res)))

uint i = 0

for (i=0 i lt mysql_num_fields(res) i++)

printf(s row[i])

printf(n)

return 0

Step 2 Compile

gcc -Iusrlocalmysqlinclude -Lusrlocalmysqllibmysql mysqlcc ndashlm -lmysqlclient

(其中 include path與 library path取決於你的 MySQL安裝路徑)

76

如果執行時發生如下 error Run problemerror in loading shared libraries libmysqlclientsoX 將你的 MySQL library path(for exampleusrlocalmysqllibmysql) 加入etcldsoconf and run sbinldconfig -v Q9ASP + MySQL 範例程式 Ans Dim myconn As New ADODBConnection Dim myrs As New Recordset Dim mySQL As String Dim myrows As Long myconnOpen DSN=MyODBCsample mySQL = SELECT from user myrsSource = mySQL Set myrsActiveConnection = myconn myrsCursorLocation = adUseClient myrsOpen myrows = myrsRecordCount myrsClose myconnClose 可參考 httpwwwdwamnetmysqlasp_myodbcasp 有詳細的資料 Q10如何將 MySQL中的資料庫匯出成txt檔 Ans select from TableName into outfile textxls all result fields will seperate by tab

77

第八章 參考資料

英文部份 網址 1 httpwwwmysqlcom MySQL 網站有第一手有關 MySQL的資料 2 httpwwwmysqlcomdocenReplicationhtml 有關 MySQL Replication 的文件 3 httpwwwgeocitiescomsqlhomefaqstore_blobhtml 如何在 MySQL 存放 BLOB的資料 4httpwwwsapdborg 有關 SAP跟 MySQL相關合作的網站 書藉 1 Cooking with MySQL

Paul DuBois has selected sample recipes from the hundreds youll find in his book MySQL

Cookbook In this third and final series of excerpts showcasing these recipes learn how to

compute team standings how to calculate the differences between successive Dec 26

2002 2 Tips for Building Web Database Applications with PHP and MySQL by Hugh E Williams co-author of Web Database Applications with PHP amp MySQL 04042002

3 Managing and Using MySQL 2nd Edition By Tim King George Reese Randy Jay Yarger

4 MySQL Cookbook By Paul DuBoisPublisher OReillyPub Date October 2002

中文部份

78

1 httplinuxtncedutwtechdocmysqlmysql_docmanual_tochtml MySQL 中文手冊 2 httpchenshloxaedutwphpZ_1php PHP+MySQ程式研習設計網站 3 httplinuxtncedutwtechdocbanicdownhtml PHP 4 手冊 4 httpwwwtncedutwadmin_zonephp台南縣教育網網路中心有很多 Linux相關文件 5 httpdobtncedutw網站建置百寶箱有很多 PHP MySQL 相關範例程式 5 httpwwwdbworldcomtw資料庫專家電子雜誌介紹資料庫的重要觀念及名詞

79

附錄一 SQL Command 介紹

SQL (讀音ess-que-el) 是一種結構查詢語法SQL 使用於資料庫交流

傳遞相容於 ANSI (American National Standards Institute) 是一套標準的關聯

式資料庫語言 SQL 語言是執行更新或從資料系統獲取資料一般常見的關聯

資料庫系統都有提供 SQL 如 Oracle Sybase Microsoft SQL Server Access Ingres 等雖然大部份的資料庫都有提供 SQL 但也多提供了自已獨特的語

法造成了不相容的情形但標準基本的語法是相通的如Select Insert Update Delete Create and Drop 每一個系統都有支援

Table相關 Command

Create Table

關聯式資料庫包含有很多元件稱為資料表(tables) 把資料或訊息放在資

料表中 資料表是以不同的名稱做分別資料表由欄列所構成的二維陣列

欄包含欄位名資料型態 及其他可判斷的資訊列是由全部欄位構成一筆一

筆的紀錄 create table 語法用在建立一個新的資料表語法格式如下

create table tablename (column1 data type column2 data type column3 data type)

Format of create table if you were to use optional constraints

create table tablename (column1 data type [constraint] column2 data type [constraint] column3 data type [constraint]) [ ] = optional

Note You may have as many columns as youd like and the constraints are optional

80

Example

create table employee (first varchar(15) last varchar(20) age number(3) address varchar(30) city varchar(20) state varchar(20))

注意建立資料表格式要以括號把前後框住而最後以(分號)做結尾

欄位名不要超過 30個字元長而且不要使用 sql 的關鍵字(如 where select等)而在後面接是型態的宣告(如字串數字日期格式等)

資料型態是來描述欄位的方式如一個欄位Last_Name 是一個姓氏可以使用varchar (可變動長度字串) 資料型態

以下是幾個常見的資料庫型態 char(size) 固定長度字串最長為 255 位元 varchar(size) 變動長度字串最大字元數以 size 來指定 number(size) 數值格式可以是整數也可以是小數最大數字以 size 位數判

斷未指定小數位數由系統內定 date 日期格式 number(sized) 數值格式最大數字以 size 位數判斷d 為小數位數整數位

數為 size-d 位

有何限制當資料表被建立通常有一或數個欄位是要使用來做關聯的功

能 例如unique 限制(唯一值)兩筆記錄不可以相同的值 not null (非空值)該欄位一定要輸入資料不可是空的primary key (主鍵)是每一筆記錄識別的主要方式

Drop a table drop table 刪除資料表(其中的資料也會一併刪除)

drop table tablename

Example

81

drop table 和刪除全部資料是不同的刪除全部資料欄位名稱資訊等還會

存在但刪除資料表會把這一些也一併移除掉

如何查詢資料

Select 基本用法

select 語法是關連式資料庫最常用的部份可以取得你想要的資料這是一個

簡單的範例 select column1[column2etc] from tablename [where condition] [] = optional 在 select 之後所列欄位名則是要顯示的資料部份你可以一一列出各欄位

名或是以 (星號)來代表選擇全部的欄位 from 之後放資料表名稱 where 子句 (選項) 指定要過濾的條件符合者才會顯現 where 可使用的條件運算元 = 等於 gt 大於 lt 小於 gt= 大或等於 lt= 小或等於 ltgt 大相等 LIKE 相似 For example select first last city

82

from empinfo where first LIKE Er 以Er 為開頭的字串就符合要以單引號框住 Or you can specify select first last from empinfo where last LIKE s 最後一字為 S 就符合 select from empinfo where first = Eric 則表示 first name 一定要是 Eric 才可以 範例資料表empinfo 統計函數

MIN 傳回指定欄位最小值

MAX 傳回指定欄位最大值

SUM 傳回指定欄位總和

AVG 傳回指定欄位平均值

COUNT 傳回指定欄位的筆數

COUNT() 傳回資料庫中的總筆數

統計函數使用於資料表中的數值欄位配合 SELECT 語法使用 只用於總結特定單一欄位可以配合 GROUP BY 做篩選但也可以不使用 GROUP BY 語句For example

SELECT AVG(salary) FROM employee

83

傳回全部 salary 平均值

Another example

SELECT AVG(salary) FROM employee WHERE title = Programmer

傳回 salary 平均值條件為 employees 資料表中當 title 等於 Programmer

Example

SELECT Count() FROM employees

傳回 employees 資料表中紀錄總筆數

GROUP BY 語法 SELECT column1 SUM(column2) FROM list-of-tables GROUP BY column-list The GROUP BY 語句可以先以所列的欄位為條件分組排序在一起(可以多欄

位) example 要列出每一個 dept 中最高 salary 值 SELECT max(salary) dept FROM employee GROUP BY dept HAVING 語法

SELECT column1 SUM(column2) FROM list-of-tables GROUP BY column-list HAVING condition

HAVING 子句是 GROUP BY 的一部份用來過濾在 GROUP BY 所選出的資料功能如同 select 命令中 where 條件式一樣只是 HAVING 必需配合 GROUP BY 使用

我們以例子來說明我們要取得每一公司名及每一公司的薪水平均值輸入如下

84

SELECT dept avg(salary) FROM employee GROUP BY dept

但如果我們只列出薪資平均值超過 20000元的公司資料

SELECT dept avg(salary) FROM employee GROUP BY dept HAVING avg(salary) gt 20000

ORDER BY子句語法

SELECT column1 SUM(column2) FROM list-of-tables ORDER BY column-list [ASC | DESC]

[ ] =選項

ORDER BY是一個選項子句當你以排序方式來顯示資料(正向由小到大反向由大到小)以指定的欄位資料做排序

ASC = 正向- 預設值 DESC = 反向排序

For example

SELECT employee_id dept name age salary FROM employee_info WHERE dept = Sales ORDER BY salary

以上列出公司代號公司名銷售員人名年紀及薪資而條件是公司名為 Sales 顯示順序以薪資多少排序(由小到大為預設值)

如果要以多個欄位做排序要以逗號做分隔如下

SELECT employee_id dept name age salary FROM employee_info WHERE dept = Sales ORDER BY salary age DESC

85

結合條件及布林運算 SELECT column1 SUM(column2) FROM list-of-tables WHERE condition1 AND condition2 AND運算可以結兩個或以上的條件放在 WHERE子句中 兩者都要為真才

會顯示該筆記錄 OR 運算可以結兩個或以上敘述放在 WHERE子句中只要其中一個為直就

會顯示該筆記錄 For example SELECT employeeid firstname lastname title salary FROM employee_info WHERE salary gt= 5000000 AND title = Programmer 必需要薪資大於等於 50000而且職稱為 Programmer同時符合才會顯示該筆資料 以下以括號括住雖然不是必需的但如此比較容易讀 SELECT employeeid firstname lastname title salary FROM employee_info WHERE (salary gt= 5000000) AND (title = Programmer) 另外範例 SELECT firstname lastname title salary FROM employee_info WHERE (title = Sales) OR (title = Programmer) 條件為只要是 Sales 或 Programmer 職稱的就會被列出 IN and BETWEEN 子句

SELECT column1 SUM(column2) FROM list-of-tables WHERE column3 IN (list-of-values) SELECT column1 SUM(column2) FROM list-of-tables WHERE column3 BETWEEN value1 AND value2 IN 子句使用在列舉項目的使用上也就是分別測試是否符合所列的值 For example

86

SELECT employeeid lastname salary FROM employee_info WHERE lastname IN (Hernandez Jones Roberts Ruiz) 條件為姓氏(astname)要符合 Hernandez Jones Roberts or Ruiz 其中一個才會被傳回 IN運算元也可以使用 OR 的語法來取代如下結果相同 SELECT employeeid lastname salary FROM employee_info WHERE lastname = Hernandez OR lastname = Jones OR lastname = Roberts OR lastname = Ruiz 但使用 IN 句子比較短也比較易懂 你也可以使用 NOT IN 來去掉不要的記錄 BETWEEN 運算元使用在判斷是否存在兩個數值之間 For example SELECT employeeid age lastname salary FROM employee_info WHERE age BETWEEN 30 AND 40 傳回年紀 30歲到 40歲之間的資料(含 30及 40歲者) 相同的也可以使用以下語法來達到相同的結果 SELECT employeeid age lastname salary FROM employee_info WHERE age gt= 30 AND age lt= 40 你也可使用 NOT BETWEEN 來濾掉中間值的資料 數學運算 標準 ANSI SQL-92 提供以下運算

87

+ 加

- 減

餘數

餘數為除法後剩整數這不在標準的 ANSI SQL 中但大部份的資料庫都會支

援這運算元以下列出有用的函數雖不在 ANSI SQL-92 提供但一般資料庫

也會支援他們

ABS(x) 傳回 x 絕對值

SIGN(x) returns the sign of input x as -1 0 or 1 (negative zero or positive respectively)

MOD(xy) 餘數 - returns the integer remainder of x divided by y (同 xy)

FLOOR(x) 傳回小或等於 x 的最大整數值

CEILING(x) or CEIL(x)

傳回大或等於 x 的最小整數值

POWER(xy) x的 y 次方

ROUND(x) 把 x 四捨五入為整數

ROUND(xd) 四捨五入取到小數 d 位

SQRT(x) x 開平方

For example SELECT round(salary) firstname FROM employee_info 傳回薪資取到整數位

如何新增資料

insert 加入一筆新紀錄到資料表中 insert into tablename (first_columnlast_column) values (first_valuelast_value) [] = optional Example insert into employee

88

(first last age address city state) values (Luke Duke 45 2130 Boars Nest Hazard Co Georgia) Note 字串要以單引號住如string 數字框住也無妨 insert into 後面接資料表名稱再接以括號括住的欄位名在 values 後括號分別對映各欄位的值 以上的例子新增了一筆名(first) 為 Luke而住所(state) 為 Georgia 的資料

如何刪除資料

delete 可以刪除單筆或多筆紀錄 delete from tablename where columnname OPERATOR value [and|or column OPERATOR value] [ ] = optional Examples delete from employee Note 如果你沒有指定 where 子句那麼全部的紀錄都會被刪除 delete from employee where lastname = May delete from employee where firstname = Mike or firstname = Eric delete from 接著資料表名 再接著是條件式判斷沒有條件式則全部紀錄會

被刪除

如何更新資料

update 用來更新你所指定的記錄要和 WHERE 配合小心使用 語法 update tablename set columnname = newvalue[nextcolumn = newvalue2] where columnname OPERATOR value [and|or column OPERATOR value] [] = optional Examples

89

update phone_book set area_code = 623 where prefix = 979 update phone_book set last_name = Smith prefix=555 suffix=9292 where last_name = Jones update employee set age = age+1 where first_name=Mary and last_name=Williams

90

附錄二Replication

測試環境

RedHat 90 + MySQL 32358 MySQL資料庫路徑 varlibmysql MySQL設定檔 etcmycnf Master IP 1921680100 Slave IP 1921680200 請至下列網址下載最新MySQL 32358套件並利用rpm ndashUvh 更新 httpupdatesredhatcom9enosi386

圖 最新 MySQL 套件

測試架構圖

91

1921680100

1921680200Master Server

erveSlave S r

圖 測試架構圖

測試步驟

Master server 部份 Step1 確認 MasterSlave機器上所裝的 MySQL版本能進行

replication( 32329 or higher ) Step2 在 Master MySQL上開放一個帳號給 Slave mysql ndashu root ndashp mysqlgtGRANT FILE ON TO repl1921680200 IDENTIFIED BY lsquoabc123rsquo mysqlgtq 上面是 Master開放一個帳號 repl密碼 abc123給 IP1921680200有檔案處理

的權限 Step3 shutdown MySQL on the Master mysqladmin ndashu root ndashp shutdown Step4 備份 Master所有資料庫 tar ndashcvf tmpmysql-snapshottar varlibmysql 注意tar的時候MySQL是要在 stop情況下 在mysql (wwwmysqlcom) 網站的FAQ有不用shutdown的方法

92

Step5 在 master機器上修改etcmycnf 在[mysqld]區段內加入參數 log-bin server-id=這邊設定 server-id=1 sql-bin-update-same binlog-do-db=CRM只針對 CRM資料庫做紀錄 Step6 Restart MySQL on the master service mysqld start 此時因為有加入 log-bin 參數因此開始有 index產生了在varlibmysql目錄下

有index檔案紀錄資料庫的異動 log Slave server 部份 Step1 在 slave設定etcmycnf 在[mysqld]區段加入 master-host= master-user= master-password= master-port= server-id= 這邊設定 master-host=1921680100 master-user=repl master-password=abc123 master-port=3306 server-id=2 master-connect-retry=60預設重試間隔 60秒 replicate-do-db=CRM告訴 slave只做 CRM資料庫的更新 log-slave-updates Step2 將 master上的 mysql-snapshottar copy到 slave上 用 ftp傳到 slave的tmp Step3 解壓縮 Master資料庫至 Slave Server上 cd varlib tar xvf tmpmysql-snapshottar chown ndashR mysqlmysql mysql

93

chmod ndashR 770 mysql (視情況) Step4 Restart MySQL on the slave server 這時在varlibmysql目錄會出現 masterinfo此檔案紀錄了 Master MySQL server的資訊

狀況測試

One-way replication

1921680100

1921680200Master Server

erveSlave S r

圖 One-way replication架構圖 Step1 Master跟 Slave網路及服務都正常情況下由 Master端異動資料後 到 Slave端瀏覽資料檢視是否有進行 replication Step2 模擬 Slave Server 當機 可用在於 slave真的當機或是 Slave 不一定需要一直跟 master connect將Slave MySQL server shutdown由 Master端異動資料到 slave端瀏覽此時Slave應該沒有被 replication 更新然後再將 Slave端 MySQL server start起來

預設 60秒後 Slave會嘗試跟 Master要求進行 replication再去 Slave端檢視是否有更新資料

94

Step3 模擬 Master當機因為是設定 One-way replication一旦 Master Server Slave端沒有 Master的 source可以 download Two-way replication 基於 Master當機狀況於是發展雙向 Replication即 1921680100 ( Host A ) 1921680200 ( Host B )都分別擔任 MasterSlave身分

1921680100

1921680200er

Server B MasterSlave Server

Server A MasterSlave Serv

圖 Two-way replication架構圖 以下是針對兩台 MySQL伺服器進行雙向 Replication Step1觀念同單向 replication只是改成 Master也有 Slave身分 Slave也有Master的身分先分別在 Server AServer B 都去 grant一個進行 replication的身分 [A]mysqlgtGRANT FILE ON TO repl1921680200 IDENTIFIED BY lsquoabc123rsquo [B]mysqlgt GRANT FILE ON TO repl1921680100 IDENTIFIED BY lsquoabc123rsquo Step2做完單向 replication後stop Server Aserver B MySQL service此時 AB資料是一樣的

95

修改etcmycnf設定 範例 Server A [mysqld] datadir=varlibmysql socket=varlibmysqlmysqlsock server-id=1 log-bin sql-bin-update-same binlog-do-db=CRM master-host=1921680200 master-user=repl master-password=abc123 log-slave-updates master-connect-retry=60 replicate-do-db=CRM Server B [mysqld] datadir=varlibmysql socket=varlibmysqlmysqlsock server-id=2 log-bin sql-bin-update-same binlog-do-db=CRM master-host=1921680100 master-user=repl master-password=abc123 log-slave-updates master-connect-retry=60 replicate-do-db=CRM 分別 start Server AServer B MySQL後此時雙方都是 MasterSlave身分一旦哪一方資料異動就會通知對方來 replication-若 replication失效則必須將Server AServer B的masterinfo及index00x 都砍掉然後分別 restart MySQL server進行測試檢視成果 實務上通常如果需要做Two-way replication通常會搭配Virtual Server使用

96

在前端架設一台Virtual Server不過此部份不在此份SOP討論範圍內有興趣

的讀者可參考 httpwwwlinuxvirtualserverorg 網站

1921680100 1921680200

Host A MasterSlave Server

Host B MasterSlave Server

Virtual Host

圖 Virtual Server + Two-way replication 架構圖

97

圖 High Availability Linux Virtual Server架構圖

98

  • COSA-SOP-03-006
  • 第一章 簡介
    • 11適用對象 (Audience)
    • 12 MySQL本身
    • 13 MySQL 40版跟50版重大的改進功能
    • 14 各家資料庫軟體比較
      • 第二章 前置需求
      • 第三章 安裝
        • 31 MySQL安裝
        • 32 phpMyAdmin安裝
        • 33 升級及注意事項
          • 第四章 MySQL管理
            • 41 Webmin 管理介面
            • 42 phpMyAdmin 的操作介面
            • 43管理指令介紹
              • 431 利用mysqladmin設定root的密碼
                  • 第五章 實用範例
                    • 51 任務一Web Base客戶通訊錄
                    • 52 任務二Web Base群組軟體 ( twig )
                      • 第六章 維護及更新程序
                        • 61 日常維護
                        • 62 更新程序
                        • 63 備份重要檔案
                        • 64 離線備份與還原
                        • 65 線上備份與還原
                          • 第七章 問題與解答
                          • 第八章 參考資料
                          • 附錄一 SQL Command 介紹
                          • 附錄二Replication
Page 55: DataBase Server Standard Operation Procedureebooks.lib.ntu.edu.tw/1_file/oss/63/93doc4-5.pdf · 業務的公司帶來了不少壓力,譬如微軟,甲骨文 ... 外的錢用在第三方的資料庫產品上,譬如就可以不用再購買甲骨文公司

lttdgtltinput type=text name=Name size=20 maxlength=10gtlttdgtlttrgt lttrgtlttdgt電話 lttdgt lttdgtltinput type=text name=Tel size=20 maxlength=20gtlttdgtlttrgt lttrgtlttd colspan=2 align=centergt ltinput type=submit value=新增連絡人gtlttdgtlttrgt lttablegt ltformgt ltbrgtlta href=indexhtmlgt通訊錄ltagt | lta href=addphpgt新增連絡人ltagt | lta href=searchphpgt搜尋通訊錄ltagt ltbodygt lthtmlgt

lt-- 程式範例searchphp --gt lthtmlgt ltheadgtlttitlegt搜尋通訊錄lttitlegtltheadgt ltbodygt ltcentergtlth2gt搜尋通訊錄lth2gtlthrgt lt if (isset($_POST[Search])) 建立資料庫連結並選定資料庫 $link = mysql_connect(localhostroot1234) mysql_select_db(CONTACT) 建立基本的 SQL字串 $sql = SELECT FROM address 檢查是否輸入姓名 if (chop($_POST[Name]) = ) $name = name LIKE $_POST[Name] else $name = 檢查是否輸入電話號碼 if (chop($_POST[Tel]) = ) $tel = tel LIKE $_POST[Tel] else $tel =

55

if條件組合 SQL字串 if (chop($name) = ampamp chop($tel) = ) $sql= WHERE $name AND $tel elseif (chop($name) = ) 只有姓名 $sql = WHERE $name elseif (chop($tel) = ) 只有電話號碼 $sql = WHERE $tel $sql= ORDER BY name 最後加上排序 $result = mysql_query($sql) 取得欄位數 $total_fields = mysql_num_fields($result) echo lttable border=1gt echo lttrgtlttdgt編號lttdgtlttdgt姓名lttdgtlttdgt電話lttdgtlttd colspan=2gt功能選項lttdgtlttrgt 表格顯示查詢結果 while ($rows = mysql_fetch_array($result MYSQL_NUM)) echo lttrgt for ($i = 0 $i lt $total_fields $i++) echo lttdgt$rows[$i]lttdgt echo lttdgtlta href=editphpaction=editampid= echo $rows[0]gtltbgt編輯ltbgtlttdgt echo lttdgtlta href=editphpaction=delampid= echo $rows[0]gtltbgt刪除ltbgtlttdgt echo lttrgt echo lttablegtlthrgt mysql_free_result($result) mysql_close($link) gt ltcentergt ltform action=searchphp method=postgt lttable border=0 width=450gt lttrgtlttdgt搜尋姓名 lttdgt lttdgtltinput type=text name=Name size=10 maxlength=20gtlttdgtlttrgt lttrgtlttdgt搜尋電話 lttdgt lttdgtltinput type=text name=Tel

56

size=20 maxlength=20gtlttdgtlttrgt lttrgtlttd colspan=2 align=centergt ltinput type=submit name=Search value=搜尋gtlttdgtlttrgt lttablegt ltformgt ltbrgtlta href=indexhtmlgt通訊錄ltagt | lta href=addphpgt新增連絡人ltagt | lta href=searchphpgt搜尋通訊錄ltagt ltbodygt lthtmlgt

lt ob_start() gt lt-- 程式範例editphp --gt lthtmlgt ltheadgtlttitlegt編輯通訊錄lttitlegtltheadgt ltbodygt lt 取得 URL 參數 $id = $_GET[id] $action = $_GET[action] 建立資料庫連結 $link = mysql_connect(localhostroot1234) mysql_select_db(CONTACT) 選擇資料庫 執行的操作 switch ($action) case update 更新 取得欄位資料 $name = $_POST[Name] $tel = $_POST[Tel] $sql = UPDATE address SET name=$name tel=$tel WHERE id=$id mysql_query($sql) 執行 SQL指令 mysql_close($link) header(Location searchphp) 轉向到 serachphp break case del 刪除 $sql = DELETE FROM address WHERE id=$id

57

mysql_query($sql) 執行 SQL指令 mysql_close($link) header(Location searchphp) 轉向到 serachphp break case edit 編輯 $sql = SELECT FROM address WHERE id=$id $result = mysql_query($sql) 執行 SQL指令 $row = mysql_fetch_row($result) 取回記錄 $name = $row[1] 取得欄位 name $tel = $row[2] 取得欄位 tel mysql_close($link) 顯示編輯表單 gt ltcentergtlth2gt更新通訊錄lth2gtltcentergtlthrgt ltform action=editphpaction=updateampid=lt echo $id gt method=postgt lttable border=0 width=300gt lttrgtlttdgt姓名 lttdgt lttdgtltinput type=text name=Name size=20 maxlength=10 value=lt echo $name gtgtlttdgtlttrgt lttrgtlttdgt電話 lttdgt lttdgtltinput type=text name=Tel size=20 maxlength=20 value=lt echo $tel gtgtlttdgtlttrgt lttrgtlttd colspan=2 align=centergt ltinput type=submit value=更新連絡人gtlttdgtlttrgt lttablegt ltformgt ltbrgtlta href=indexhtmlgt通訊錄ltagt | lta href=addphpgt新增連絡人ltagt | lta href=searchphpgt搜尋通訊錄ltagt lt break gt ltbodygt lthtmlgt

58

52 任務二Web Base群組軟體 ( twig )

順利完成Web Base客戶通訊錄程式測試一段時間後「Apache + MySQL + PHP」架構的穩定與快速巳深得老闆與公司所有同事的認同隨著公司業績蒸

蒸日上人員組織編罝愈來愈龐大跨部門的會議愈來愈多業務員每日排滿拜

訪客戶的行程跟客戶的 Email的往來也愈來愈頻繁 愈來愈多部門的同事希望公司能建置一套群組軟體提供 web mail可讓業

務人員方便收發 mail還有連絡人議事日程待辦工作書簽等功能讓整個

公司運作及個人時間管理更有效率

老闆問小明對這些需求有什麼看法小明認為如果這些功能完全由程式部

門開發必定曠日費時而且耗費公司資源小明在網路尋找是否有提供這些功能

的Free Software皇天不負苦心人小明發現了TWIG (The Web Information Gateway) httptwigscrewdrivernet這個群組軟體它在 Web 上整合郵件新聞聯絡人議事日程工作序書簽等功能非常符合公司的需求 Step 1 下載 twig-277targz 下載網址 httptwigscrewdrivernetdownloadphp3

Step 2 解開 twig-277targz tar -xzvf twig-277targz

59

Step 3 執行安裝動作安裝到 varwwwhtmltwig 目錄 cd twig-277 twig-install varwwwhtmltwig

Step 4 建立 MySQL 資料庫(twig)及各資料表

cd setup mysql -u root -p1234 mysqlgt create database twig Query OK 1 row affected (001 sec) mysqlgt quit mysql -u root ndashp1234 twiglt twigtablemysql

Step 5 修改 configincphp3 參數設定 vi varwwwhtmltwigconfigconfigincphp3 $config[fromdomain] = opencom 網域 $config[language] = chinesebig5 中文訊息 $config[imap_port] = 143notls

60

Step 6 修改連結 MySQL 的帳號密碼 vi varwwwhtmltwigconfigdbconfigincphp3 $dbconfig[sqlusername] = root username $dbconfig[sqlpassword] = 1234 password

Step 7 其他設定檔

vi etchttpdconfhttpdconf 加入 AddType applicationx-httpd-php php3 在 DirectoryIndex最後加入 indexphp3 DirectoryIndex indexhtml indexhtmlvar indexphp3 在 AddDefaultCharset ISO-8859-1加上 AddDefaultCharset ISO-8859-1

vi etcphpini register_globals = On service httpd restart Step 8 sendmail 設定 vi etcmailsendmailcf在 264 行前面加上並重新啟動 sendmail「service snedmail restart」 262 SMTP daemon options 263 264 O DaemonPortOptions=Port=smtpAddr=127001 Name=MTA 265 266 SMTP client options 267 O ClientPortOptions=Family=inet Address=00

61

Step 9 檢查設定有無錯誤 http主機名稱twigtestphp3

62

Step 10 登入 twig ( http主機名稱twig)

63

第六章 維護及更新程序

61 日常維護

系統管理員最好定期以 root 身份登入看看信件在 RedHat Linux 中有一支 logwatch 程式會定時去分析 log file如果發現異常便會發信給 root除此之外筆者建議讀者平時就檢查 MySQL log file ( varlogmysqldlog)是否有異常情形

62 更新程序

讀者可至httprpmfindnet 尋找MySQL相關套件至於升級的相關步驟請參

考Linux OS SOP 第 54節

63 備份重要檔案

預設 MySQL 的 DB 檔案是存在 varlibmysql 內以 DB名稱為目錄目錄

內就是該 DB 的所有資料通常得定期備份還有 MySQL的設定檔 etcmycnf也別忘了一起備份

64 離線備份與還原

641 離線備份

預設 MySQL 的 DB 檔案是存在 varlibmysql 內以 DB 名稱為目錄目錄內

就是該 DB 的所有資料像 CRM 這個 DB就是存在 varlibmysqlCRM 內在備份前因為怕資料尚未完全寫入磁碟而且 MySQL 會 Lock 在使用的 DB 檔案所以應該是要先把 MySQL 先 Shutdown 一下整個備份的程序可以下像下面的指令去完成 cd varlibmysql

64

service mysqld stop tar cvfz CRM_db_20030905tgz CRM service mysqld start 對這樣就可以了 不過要注意的是怕 DB 內每個 Tables 間的資料有關關

聯性所以最好是把整個 DB 一次備起來單獨只備哪個 Tables 的檔案以後回存時怕會有資料關聯不一致的問題

642 離線還原

DB 發生錯誤而要回存時其實也不難先找出最近一次完整正常的備份先把現在錯誤的網頁或 DB 先更名或 tar 起來再把好的備份給解開回原來目錄位

置就行了需要注意的是 MySQL 服務最好也是要先停止回存完成後再啟動服務回存 DB 的整個程序可能像下面 cd varlibmysql service mysqldstop mv CRM CRM_OLD tar xvfz CRM_db_20030905tg service mysqld start

65 線上備份與還原

651 線上備份

使用像上面的檔案方式備份是個不錯的方法它最少可以保持該主機某個時間點的完整檔案備份但還是有一些問題需要考慮到有些主機就不只建立一個 DB 而已總不能為了備份某個 DB 而把整個 MySQL 服務停止備份檔案的方式回存在原主機上一定適用但假如 MySQL 版本升級或是在那天該網頁空間需遷機移機到別的主機時那就沒人敢保證備出來的資料檔可以用所以我們可以考慮另一種備份的方式是使用 MySQL 本身提供的功能 MySQL Data Dump指令是 mysqldump

65

使用 MySQL 的 Dump 功能可以把 DB 的結構資料或結構加資料 Dump 成文字檔 mysqldump 指令提供的彈性很大你可以選擇把整個 DB Dump 成一個檔或是每個 Table 為一個檔甚至是把結構檔和資料分開儲存都

可以 mysqladmin -uroot -p flush-logs mysqldump CRM -uroot -p --opt gt CRM_20030905sql (CRM 是 DB 名稱 opt 是一個使用完整 Dump 參數) 假如只是要單獨 Dump 某個 Table 時只要在上面的指令後轉出符號 gt 前加個 Table 名稱就可以如只要 phpbb2_users 這個 Table 的 Dump 時只要下 mysqldump CRM -uroot -p --opt CUSTOMER gt CRM_CUSTOMER_20030905sql

652 線上還原

若要回存整個資料庫只需將壓縮的備份檔還原成 Dump 的檔案再用下面的指令回存 mysql CRM -uroot -p lt CRM_20030905sql 這邊需注意的是若建立備份時是以--opt或--add-drop-table為參數時回存的 動作是先將舊的 Table 先刪除重建 Table 的結構後再把 Data 匯入所以回存後所有的資料會回到你當時備份那個時間點因此在回存資料時可以考慮把現有錯誤或不完整的 DB 先備份一份下來以備不時之需或是拿來比對錯誤的地

方在那裡當然你也可以把資料回存到另一個測試用的 DB 內只要把上面指令

的 DB 名稱改成你的測試用 DB 名稱即可 使用這種回存方式 MySQL 服務不需停止也不會動到其他正在使用的 DB 在一些提供 MySQL 服務的虛擬主機可用這種方式作你自己的 DB 備份及回存

66

另外假如你是系統重建或是移機時切需在新的 MySQL 內新建一個空白 DB 後才行作回存的工作你可以用下面的指令建立 mysql -uroot -p -e CREATE DATABASE CRM (上面的 CRM是你要新建的 DB 名稱) 另一種作法先用 mysql 指令進入 mysql client console 然後再用 CREATE DATABASE CRM 這樣就行了記得尾端要加個 符號該行指令才會執行

67

第七章 問題與解答

Q1RedHat 90預附的 MySQL到底有無支援 Transcation機制 Ans MySQL自 32334a之後的 MySQL-Max版本加入 InnoDB的資料庫類型透過

InnoDBMySQL同樣可以進行 COMMIT與 ROLLRACK的動作RedHat 90預附的 MySQL為 32354a-11巳支援 InnoDB的資料庫類型不過必須做以

下設定 1cp usrsharedocmysql-server-32354amy-mediumcnf to etcmycnf 2 vi etcmycnf 將以下設定前的拿掉 innodb_data_home_dir = varlibmysql innodb_data_file_path = ibdata110Mautoextend innodb_log_group_home_dir = varlibmysql innodb_log_arch_dir = varlibmysql 3service mysqld restart 如此一來各位在建立Table時便可指定Table Type為 innodb ( ex create table with type=innodb ) Q2如何解決 php+mysql 許功蓋等字變亂的問題 Ans 方法一 【確定 MySQL 預設的字元集】 1 打開 WinMySQLadmin 管理畫面(在視窗右下角狀態列紅綠燈圖示中按滑鼠

右鍵點選 Show me 選項) 2 點選管理畫面中 [Variables] 標籤選項其中 character_set變數就是您預設

字元集的變數其預設是 latin1 字元集(我們要將他改回 big5)而 chatacters_set 變數則是 MySQL 可以支援哪些字元集 【修改預設字元集變數 character_set 】 1 請點選管理畫面中 [myini Setup] 標籤選項設定 myini 2 按一下 [Pick-up and Edit myini values] 按鈕以便編輯目前的 myini 設定 3 在 [mysqld] 設定區塊底下新增一行 default-character-set = big5 變數設

68

定 4 新增一個 [client] 設定區塊並加入第三步驟的變數設定(游標往下移到空白處新增兩行 [client] 和 default-character-set=big5) 5 按一下畫面左下方 [Save Modification] 按鈕儲存設定 6 重新啟動 MySQL 或 Windows 方法二 Server端注意事項 phpini 中有關的設定為(預設值) Magic quotes for incoming GETPOSTCookie data magic_quotes_gpc = On Use Sybase-style magic quotes (escape with instead of ) magic_quotes_sybase = Off Client端注意事項 1中文資料送進 mysql 前請用 addslashes($str) 處理 2處理後送進 mysql 時請用 括起來並在參數後留一個空白如 $sql = UPDATE ezf_table set tablename=$tname tableend=$endtime table inguser=$tguser tableingid=$tguserid tableallnumber=$tnumber tableloca l=$tablelocal tableanyone=$tableopen tabletext=$ttext WHERE tableid=$t ableid tablename=$tname c 取出時請用 stripslashes($str) Q3MySQL root 密碼忘了該怎麼辦 Ans 1先停掉 mysql etcrcdinitdmysql stop 2以--skip-grant-table 的參數啟動 mysql safe_mysql --skip-grant-tableamp 3 更改 root 密碼 mysql mysql mysqlgt UPDATE user SET password=password(newpassword)

69

WHERE user=root mysqlgt FLUSH PRIVILEGES mysqlgt exit 4停掉 mysql再重跑 mysqladmin -uroot -p shutdown Enter password 輸入新設定的密碼 etcrcdinitdmysql start

Q4NULL值問題

Ans

NULL值的概念是造成 SQL的新手的混淆的普遍原因他們經常認為 NULL是和一個空字符串的一樣的東西不是這樣的例如下列語句是完全不同的

mysqlgt INSERT INTO my_table (phone) VALUES (NULL)

mysqlgt INSERT INTO my_table (phone) VALUES ()

兩個語句把值插入到 phone 列但是第一個插入一個 NULL值而第二個插入一個空字符串第一個的含義可以認為是ldquo電話號碼不知道而第二個則可意味

著ldquo她沒有電話

在 SQL中NULL值在于任何其他值甚至 NULL值比較時總是假的(FALSE)包含 NULL的一個表達式總是產生一個 NULL值除非在包含在表達式中的運算符和函數的文檔中指出在下列例子所有的列返回 NULL

mysqlgt SELECT NULL1+NULLCONCAT(InvisibleNULL)

如果你想要尋找值是 NULL的列你不能使用=NULL測試下列語句不返回任

何行因為對任何表達式expr = NULL是假的

mysqlgt SELECT FROM my_table WHERE phone = NULL

要想尋找 NULL值你必須使用 IS NULL測試下例顯示如何找出 NULL電話號碼和空的電話號碼

70

mysqlgt SELECT FROM my_table WHERE phone IS NULL mysqlgt SELECT FROM my_table WHERE phone =

在 MySQL中就像很多其他的 SQL服務器一樣你不能索引可以有 NULL值的列你必須聲明這樣的列為 NOT NULL而且你不能插入 NULL到索引的

列中

當用 LOAD DATA INFILE 讀取數據時空列用更新如果你想要在一個列中有

NULL值你應該在文本文件中使用N字面上的詞NULL也可以在某些情形下使用

當使用 ORDER BY時首先呈現 NULL值如果你用 DESC以降序排序NULL值最後顯示當使用 GROUP BY時所有的 NULL值被認為是相等的

為了有助于NULL的處理你能使用 IS NULL和 IS NOT NULL運算符和 IFNULL()函數

對某些列類型NULL值被特殊地處理如果你將 NULL插入表的第一個TIMESTAMP 列則插入當前的日期和時間如果你將 NULL插入一個AUTO_INCREMENT 列則插入順序中的下一個數字

Q5如何將圖片存放於 MySQL中

Ans

Step 1建立資料庫 test

Step 2 建立表格 binary_data

CREATE TABLE binary_data (

id INT(4) NOT NULL AUTO_INCREMENT PRIMARY KEY

description CHAR(50)

bin_data LONGBLOB

filename CHAR(50)

filesize CHAR(50)

filetype CHAR(50)

71

)

Step 3 利用 storephp 寫入圖片

storephp 程式碼

ltHTMLgt ltHEADgtltTITLEgtStore binary data into SQL DatabaseltTITLEgtltHEADgt ltBODYgt lt code that will be executed if the form has been submitted

if ($submit) mysql_connect(localhostrootYOUR_PASSWORD) mysql_select_db(test) $data=Base64_Encode(fread(fopen($form_data r) filesize($form_data))) $result=MYSQL_QUERY(INSERT INTO binary_data (descriptionbin_datafilenamefilesizefiletype) VALUES ($form_description$data$form_data_name$form_data_size$form_data_type)) $id= mysql_insert_id() print ltpgtThis file has the following Database ID ltbgt$idltbgt MYSQL_CLOSE() else else show the form to submit new data

gt

ltform method=post action=ltphp echo $PHP_SELF gt enctype=multipartform-datagt File Descriptionltbrgt ltinput type=text name=form_description size=40gt ltINPUT TYPE=hidden name=MAX_FILE_SIZE value=4000000gt ltbrgtFile to uploadstore in databaseltbrgt ltinput type=file name=form_data size=40gt ltpgtltinput type=submit name=submit value=submitgt ltformgt lt

72

gt ltBODYgt ltHTMLgt

Step 3 利用 storephp 取出圖片

getdataphp 程式碼

lt Syntax getdataphp3id=ltidgt if($id) you may have to modify login information for your database server MYSQL_CONNECT(localhostrootYOUR_PASSWORD) mysql_select_db(test) $query = select bin_datafiletype from binary_data where id=$id $result = MYSQL_QUERY($query) $data = Base64_Decode(MYSQL_RESULT($result0bin_data)) $type = MYSQL_RESULT($result0filetype) Header( Content-type $type) echo $data gt

Q6MySQL裝好之後啟動時或是執行 mysqladmin會出現如下訊息 Cant connect to local MYSQL Server through Socket varlibmysqlmysqlsock或是

Cant connect to local MYSQL Server through Socket tmpmysqldsock

Ans 可能有下列幾個原因

1這個 mysqldsock 不見了被某人刪除了或是被一些系統自動執行程式給刪

了例如有些 cron任務便會設定定期刪除 tmp 裡的東西所以呢您只能修改

cron 裡的設定讓它不要清除 mysqldsock 2在啟動時也可以改變 mysqldsock的位置您在啟動 MySQL的時候可以加入此參數usrlocalmysqlbinsafe_mysqld --user=mysql --socket=其他路

徑socket amp 同時得去設定環境變數 MYSQL_UNIX_PORT的值以指定新的

73

路徑 3若是您沒改 MYSQL_UNIX_PORT的值那麼您可以在執行指令的時候才打

例如mysqladmin --socket=其他路徑socket version Q7How to get the last insert id Ans CREATE TABLE product ( id INT(4) NOT NULL AUTO_INCREMENT PRIMARY KEY description VARCHAR(50) ) 1利用 SQL的話 mysqlgt insert into product(description) values(123) Query OK 1 row affected (000 sec) mysqlgt select last_insert_id() +------------------+ | last_insert_id() | +------------------+ +------------------+ 1 row in set (000 sec) ======================================== 2如果是 PHP的話 你可以用mysql_insert_id()取得該 id PHP example $result=MYSQL_QUERY(INSERT INTO product (description) VALUES ($description)) $id= mysql_insert_id() print This file has the following Database ID $id Q8如何將文字檔匯入資料庫 Ans $addr=homehttpdhtmlphpschool001txt $sql_select = load data infile $addr into table test fields terminated by t 解說 $sql_select = load data infile 文字檔名 into table 表格名 fields terminated by

74

t

(欄位分隔以 TAB鍵) 該文字檔須與資料表欄位格式相符 例如欄位有三個 則文字檔為每行一筆資料如下 欄 1資料ltTABgt欄 2資料ltTABgt欄 3資料 欄 1資料ltTABgt欄 2資料ltTABgt欄 3資料 欄 1資料ltTABgt欄 2資料ltTABgt欄 3資料 欄 1資料ltTABgtltTABgt欄 3資料

Q9如何撰寫 MySQL C API Ans Step 1利用文字編輯器撰寫以下程式碼 mysqlcc

include ltstdiohgt

include ltmysqlmysqlhgt

int main (int argc char argv[])

MYSQL mysql

MYSQL_RES res

MYSQL_ROW row

if (argc = 2)

fputs (Usage myc ltdatabasegt stderr)

return 1

if ((mysql_connect(ampmysqllocalhostrootYour_Password)))

fputs (Error connecting stderr)

abort()

75

if (mysql_select_db(ampmysqlargv[1]))

fputs (Error selecting database stderr)

abort()

if (mysql_query(ampmysqlSELECT FROM test_table))

fputs (Error processing query stderr)

abort()

if ((res = mysql_store_result(ampmysql)))

fputs (Error storing results stderr)

abort()

while((row = mysql_fetch_row(res)))

uint i = 0

for (i=0 i lt mysql_num_fields(res) i++)

printf(s row[i])

printf(n)

return 0

Step 2 Compile

gcc -Iusrlocalmysqlinclude -Lusrlocalmysqllibmysql mysqlcc ndashlm -lmysqlclient

(其中 include path與 library path取決於你的 MySQL安裝路徑)

76

如果執行時發生如下 error Run problemerror in loading shared libraries libmysqlclientsoX 將你的 MySQL library path(for exampleusrlocalmysqllibmysql) 加入etcldsoconf and run sbinldconfig -v Q9ASP + MySQL 範例程式 Ans Dim myconn As New ADODBConnection Dim myrs As New Recordset Dim mySQL As String Dim myrows As Long myconnOpen DSN=MyODBCsample mySQL = SELECT from user myrsSource = mySQL Set myrsActiveConnection = myconn myrsCursorLocation = adUseClient myrsOpen myrows = myrsRecordCount myrsClose myconnClose 可參考 httpwwwdwamnetmysqlasp_myodbcasp 有詳細的資料 Q10如何將 MySQL中的資料庫匯出成txt檔 Ans select from TableName into outfile textxls all result fields will seperate by tab

77

第八章 參考資料

英文部份 網址 1 httpwwwmysqlcom MySQL 網站有第一手有關 MySQL的資料 2 httpwwwmysqlcomdocenReplicationhtml 有關 MySQL Replication 的文件 3 httpwwwgeocitiescomsqlhomefaqstore_blobhtml 如何在 MySQL 存放 BLOB的資料 4httpwwwsapdborg 有關 SAP跟 MySQL相關合作的網站 書藉 1 Cooking with MySQL

Paul DuBois has selected sample recipes from the hundreds youll find in his book MySQL

Cookbook In this third and final series of excerpts showcasing these recipes learn how to

compute team standings how to calculate the differences between successive Dec 26

2002 2 Tips for Building Web Database Applications with PHP and MySQL by Hugh E Williams co-author of Web Database Applications with PHP amp MySQL 04042002

3 Managing and Using MySQL 2nd Edition By Tim King George Reese Randy Jay Yarger

4 MySQL Cookbook By Paul DuBoisPublisher OReillyPub Date October 2002

中文部份

78

1 httplinuxtncedutwtechdocmysqlmysql_docmanual_tochtml MySQL 中文手冊 2 httpchenshloxaedutwphpZ_1php PHP+MySQ程式研習設計網站 3 httplinuxtncedutwtechdocbanicdownhtml PHP 4 手冊 4 httpwwwtncedutwadmin_zonephp台南縣教育網網路中心有很多 Linux相關文件 5 httpdobtncedutw網站建置百寶箱有很多 PHP MySQL 相關範例程式 5 httpwwwdbworldcomtw資料庫專家電子雜誌介紹資料庫的重要觀念及名詞

79

附錄一 SQL Command 介紹

SQL (讀音ess-que-el) 是一種結構查詢語法SQL 使用於資料庫交流

傳遞相容於 ANSI (American National Standards Institute) 是一套標準的關聯

式資料庫語言 SQL 語言是執行更新或從資料系統獲取資料一般常見的關聯

資料庫系統都有提供 SQL 如 Oracle Sybase Microsoft SQL Server Access Ingres 等雖然大部份的資料庫都有提供 SQL 但也多提供了自已獨特的語

法造成了不相容的情形但標準基本的語法是相通的如Select Insert Update Delete Create and Drop 每一個系統都有支援

Table相關 Command

Create Table

關聯式資料庫包含有很多元件稱為資料表(tables) 把資料或訊息放在資

料表中 資料表是以不同的名稱做分別資料表由欄列所構成的二維陣列

欄包含欄位名資料型態 及其他可判斷的資訊列是由全部欄位構成一筆一

筆的紀錄 create table 語法用在建立一個新的資料表語法格式如下

create table tablename (column1 data type column2 data type column3 data type)

Format of create table if you were to use optional constraints

create table tablename (column1 data type [constraint] column2 data type [constraint] column3 data type [constraint]) [ ] = optional

Note You may have as many columns as youd like and the constraints are optional

80

Example

create table employee (first varchar(15) last varchar(20) age number(3) address varchar(30) city varchar(20) state varchar(20))

注意建立資料表格式要以括號把前後框住而最後以(分號)做結尾

欄位名不要超過 30個字元長而且不要使用 sql 的關鍵字(如 where select等)而在後面接是型態的宣告(如字串數字日期格式等)

資料型態是來描述欄位的方式如一個欄位Last_Name 是一個姓氏可以使用varchar (可變動長度字串) 資料型態

以下是幾個常見的資料庫型態 char(size) 固定長度字串最長為 255 位元 varchar(size) 變動長度字串最大字元數以 size 來指定 number(size) 數值格式可以是整數也可以是小數最大數字以 size 位數判

斷未指定小數位數由系統內定 date 日期格式 number(sized) 數值格式最大數字以 size 位數判斷d 為小數位數整數位

數為 size-d 位

有何限制當資料表被建立通常有一或數個欄位是要使用來做關聯的功

能 例如unique 限制(唯一值)兩筆記錄不可以相同的值 not null (非空值)該欄位一定要輸入資料不可是空的primary key (主鍵)是每一筆記錄識別的主要方式

Drop a table drop table 刪除資料表(其中的資料也會一併刪除)

drop table tablename

Example

81

drop table 和刪除全部資料是不同的刪除全部資料欄位名稱資訊等還會

存在但刪除資料表會把這一些也一併移除掉

如何查詢資料

Select 基本用法

select 語法是關連式資料庫最常用的部份可以取得你想要的資料這是一個

簡單的範例 select column1[column2etc] from tablename [where condition] [] = optional 在 select 之後所列欄位名則是要顯示的資料部份你可以一一列出各欄位

名或是以 (星號)來代表選擇全部的欄位 from 之後放資料表名稱 where 子句 (選項) 指定要過濾的條件符合者才會顯現 where 可使用的條件運算元 = 等於 gt 大於 lt 小於 gt= 大或等於 lt= 小或等於 ltgt 大相等 LIKE 相似 For example select first last city

82

from empinfo where first LIKE Er 以Er 為開頭的字串就符合要以單引號框住 Or you can specify select first last from empinfo where last LIKE s 最後一字為 S 就符合 select from empinfo where first = Eric 則表示 first name 一定要是 Eric 才可以 範例資料表empinfo 統計函數

MIN 傳回指定欄位最小值

MAX 傳回指定欄位最大值

SUM 傳回指定欄位總和

AVG 傳回指定欄位平均值

COUNT 傳回指定欄位的筆數

COUNT() 傳回資料庫中的總筆數

統計函數使用於資料表中的數值欄位配合 SELECT 語法使用 只用於總結特定單一欄位可以配合 GROUP BY 做篩選但也可以不使用 GROUP BY 語句For example

SELECT AVG(salary) FROM employee

83

傳回全部 salary 平均值

Another example

SELECT AVG(salary) FROM employee WHERE title = Programmer

傳回 salary 平均值條件為 employees 資料表中當 title 等於 Programmer

Example

SELECT Count() FROM employees

傳回 employees 資料表中紀錄總筆數

GROUP BY 語法 SELECT column1 SUM(column2) FROM list-of-tables GROUP BY column-list The GROUP BY 語句可以先以所列的欄位為條件分組排序在一起(可以多欄

位) example 要列出每一個 dept 中最高 salary 值 SELECT max(salary) dept FROM employee GROUP BY dept HAVING 語法

SELECT column1 SUM(column2) FROM list-of-tables GROUP BY column-list HAVING condition

HAVING 子句是 GROUP BY 的一部份用來過濾在 GROUP BY 所選出的資料功能如同 select 命令中 where 條件式一樣只是 HAVING 必需配合 GROUP BY 使用

我們以例子來說明我們要取得每一公司名及每一公司的薪水平均值輸入如下

84

SELECT dept avg(salary) FROM employee GROUP BY dept

但如果我們只列出薪資平均值超過 20000元的公司資料

SELECT dept avg(salary) FROM employee GROUP BY dept HAVING avg(salary) gt 20000

ORDER BY子句語法

SELECT column1 SUM(column2) FROM list-of-tables ORDER BY column-list [ASC | DESC]

[ ] =選項

ORDER BY是一個選項子句當你以排序方式來顯示資料(正向由小到大反向由大到小)以指定的欄位資料做排序

ASC = 正向- 預設值 DESC = 反向排序

For example

SELECT employee_id dept name age salary FROM employee_info WHERE dept = Sales ORDER BY salary

以上列出公司代號公司名銷售員人名年紀及薪資而條件是公司名為 Sales 顯示順序以薪資多少排序(由小到大為預設值)

如果要以多個欄位做排序要以逗號做分隔如下

SELECT employee_id dept name age salary FROM employee_info WHERE dept = Sales ORDER BY salary age DESC

85

結合條件及布林運算 SELECT column1 SUM(column2) FROM list-of-tables WHERE condition1 AND condition2 AND運算可以結兩個或以上的條件放在 WHERE子句中 兩者都要為真才

會顯示該筆記錄 OR 運算可以結兩個或以上敘述放在 WHERE子句中只要其中一個為直就

會顯示該筆記錄 For example SELECT employeeid firstname lastname title salary FROM employee_info WHERE salary gt= 5000000 AND title = Programmer 必需要薪資大於等於 50000而且職稱為 Programmer同時符合才會顯示該筆資料 以下以括號括住雖然不是必需的但如此比較容易讀 SELECT employeeid firstname lastname title salary FROM employee_info WHERE (salary gt= 5000000) AND (title = Programmer) 另外範例 SELECT firstname lastname title salary FROM employee_info WHERE (title = Sales) OR (title = Programmer) 條件為只要是 Sales 或 Programmer 職稱的就會被列出 IN and BETWEEN 子句

SELECT column1 SUM(column2) FROM list-of-tables WHERE column3 IN (list-of-values) SELECT column1 SUM(column2) FROM list-of-tables WHERE column3 BETWEEN value1 AND value2 IN 子句使用在列舉項目的使用上也就是分別測試是否符合所列的值 For example

86

SELECT employeeid lastname salary FROM employee_info WHERE lastname IN (Hernandez Jones Roberts Ruiz) 條件為姓氏(astname)要符合 Hernandez Jones Roberts or Ruiz 其中一個才會被傳回 IN運算元也可以使用 OR 的語法來取代如下結果相同 SELECT employeeid lastname salary FROM employee_info WHERE lastname = Hernandez OR lastname = Jones OR lastname = Roberts OR lastname = Ruiz 但使用 IN 句子比較短也比較易懂 你也可以使用 NOT IN 來去掉不要的記錄 BETWEEN 運算元使用在判斷是否存在兩個數值之間 For example SELECT employeeid age lastname salary FROM employee_info WHERE age BETWEEN 30 AND 40 傳回年紀 30歲到 40歲之間的資料(含 30及 40歲者) 相同的也可以使用以下語法來達到相同的結果 SELECT employeeid age lastname salary FROM employee_info WHERE age gt= 30 AND age lt= 40 你也可使用 NOT BETWEEN 來濾掉中間值的資料 數學運算 標準 ANSI SQL-92 提供以下運算

87

+ 加

- 減

餘數

餘數為除法後剩整數這不在標準的 ANSI SQL 中但大部份的資料庫都會支

援這運算元以下列出有用的函數雖不在 ANSI SQL-92 提供但一般資料庫

也會支援他們

ABS(x) 傳回 x 絕對值

SIGN(x) returns the sign of input x as -1 0 or 1 (negative zero or positive respectively)

MOD(xy) 餘數 - returns the integer remainder of x divided by y (同 xy)

FLOOR(x) 傳回小或等於 x 的最大整數值

CEILING(x) or CEIL(x)

傳回大或等於 x 的最小整數值

POWER(xy) x的 y 次方

ROUND(x) 把 x 四捨五入為整數

ROUND(xd) 四捨五入取到小數 d 位

SQRT(x) x 開平方

For example SELECT round(salary) firstname FROM employee_info 傳回薪資取到整數位

如何新增資料

insert 加入一筆新紀錄到資料表中 insert into tablename (first_columnlast_column) values (first_valuelast_value) [] = optional Example insert into employee

88

(first last age address city state) values (Luke Duke 45 2130 Boars Nest Hazard Co Georgia) Note 字串要以單引號住如string 數字框住也無妨 insert into 後面接資料表名稱再接以括號括住的欄位名在 values 後括號分別對映各欄位的值 以上的例子新增了一筆名(first) 為 Luke而住所(state) 為 Georgia 的資料

如何刪除資料

delete 可以刪除單筆或多筆紀錄 delete from tablename where columnname OPERATOR value [and|or column OPERATOR value] [ ] = optional Examples delete from employee Note 如果你沒有指定 where 子句那麼全部的紀錄都會被刪除 delete from employee where lastname = May delete from employee where firstname = Mike or firstname = Eric delete from 接著資料表名 再接著是條件式判斷沒有條件式則全部紀錄會

被刪除

如何更新資料

update 用來更新你所指定的記錄要和 WHERE 配合小心使用 語法 update tablename set columnname = newvalue[nextcolumn = newvalue2] where columnname OPERATOR value [and|or column OPERATOR value] [] = optional Examples

89

update phone_book set area_code = 623 where prefix = 979 update phone_book set last_name = Smith prefix=555 suffix=9292 where last_name = Jones update employee set age = age+1 where first_name=Mary and last_name=Williams

90

附錄二Replication

測試環境

RedHat 90 + MySQL 32358 MySQL資料庫路徑 varlibmysql MySQL設定檔 etcmycnf Master IP 1921680100 Slave IP 1921680200 請至下列網址下載最新MySQL 32358套件並利用rpm ndashUvh 更新 httpupdatesredhatcom9enosi386

圖 最新 MySQL 套件

測試架構圖

91

1921680100

1921680200Master Server

erveSlave S r

圖 測試架構圖

測試步驟

Master server 部份 Step1 確認 MasterSlave機器上所裝的 MySQL版本能進行

replication( 32329 or higher ) Step2 在 Master MySQL上開放一個帳號給 Slave mysql ndashu root ndashp mysqlgtGRANT FILE ON TO repl1921680200 IDENTIFIED BY lsquoabc123rsquo mysqlgtq 上面是 Master開放一個帳號 repl密碼 abc123給 IP1921680200有檔案處理

的權限 Step3 shutdown MySQL on the Master mysqladmin ndashu root ndashp shutdown Step4 備份 Master所有資料庫 tar ndashcvf tmpmysql-snapshottar varlibmysql 注意tar的時候MySQL是要在 stop情況下 在mysql (wwwmysqlcom) 網站的FAQ有不用shutdown的方法

92

Step5 在 master機器上修改etcmycnf 在[mysqld]區段內加入參數 log-bin server-id=這邊設定 server-id=1 sql-bin-update-same binlog-do-db=CRM只針對 CRM資料庫做紀錄 Step6 Restart MySQL on the master service mysqld start 此時因為有加入 log-bin 參數因此開始有 index產生了在varlibmysql目錄下

有index檔案紀錄資料庫的異動 log Slave server 部份 Step1 在 slave設定etcmycnf 在[mysqld]區段加入 master-host= master-user= master-password= master-port= server-id= 這邊設定 master-host=1921680100 master-user=repl master-password=abc123 master-port=3306 server-id=2 master-connect-retry=60預設重試間隔 60秒 replicate-do-db=CRM告訴 slave只做 CRM資料庫的更新 log-slave-updates Step2 將 master上的 mysql-snapshottar copy到 slave上 用 ftp傳到 slave的tmp Step3 解壓縮 Master資料庫至 Slave Server上 cd varlib tar xvf tmpmysql-snapshottar chown ndashR mysqlmysql mysql

93

chmod ndashR 770 mysql (視情況) Step4 Restart MySQL on the slave server 這時在varlibmysql目錄會出現 masterinfo此檔案紀錄了 Master MySQL server的資訊

狀況測試

One-way replication

1921680100

1921680200Master Server

erveSlave S r

圖 One-way replication架構圖 Step1 Master跟 Slave網路及服務都正常情況下由 Master端異動資料後 到 Slave端瀏覽資料檢視是否有進行 replication Step2 模擬 Slave Server 當機 可用在於 slave真的當機或是 Slave 不一定需要一直跟 master connect將Slave MySQL server shutdown由 Master端異動資料到 slave端瀏覽此時Slave應該沒有被 replication 更新然後再將 Slave端 MySQL server start起來

預設 60秒後 Slave會嘗試跟 Master要求進行 replication再去 Slave端檢視是否有更新資料

94

Step3 模擬 Master當機因為是設定 One-way replication一旦 Master Server Slave端沒有 Master的 source可以 download Two-way replication 基於 Master當機狀況於是發展雙向 Replication即 1921680100 ( Host A ) 1921680200 ( Host B )都分別擔任 MasterSlave身分

1921680100

1921680200er

Server B MasterSlave Server

Server A MasterSlave Serv

圖 Two-way replication架構圖 以下是針對兩台 MySQL伺服器進行雙向 Replication Step1觀念同單向 replication只是改成 Master也有 Slave身分 Slave也有Master的身分先分別在 Server AServer B 都去 grant一個進行 replication的身分 [A]mysqlgtGRANT FILE ON TO repl1921680200 IDENTIFIED BY lsquoabc123rsquo [B]mysqlgt GRANT FILE ON TO repl1921680100 IDENTIFIED BY lsquoabc123rsquo Step2做完單向 replication後stop Server Aserver B MySQL service此時 AB資料是一樣的

95

修改etcmycnf設定 範例 Server A [mysqld] datadir=varlibmysql socket=varlibmysqlmysqlsock server-id=1 log-bin sql-bin-update-same binlog-do-db=CRM master-host=1921680200 master-user=repl master-password=abc123 log-slave-updates master-connect-retry=60 replicate-do-db=CRM Server B [mysqld] datadir=varlibmysql socket=varlibmysqlmysqlsock server-id=2 log-bin sql-bin-update-same binlog-do-db=CRM master-host=1921680100 master-user=repl master-password=abc123 log-slave-updates master-connect-retry=60 replicate-do-db=CRM 分別 start Server AServer B MySQL後此時雙方都是 MasterSlave身分一旦哪一方資料異動就會通知對方來 replication-若 replication失效則必須將Server AServer B的masterinfo及index00x 都砍掉然後分別 restart MySQL server進行測試檢視成果 實務上通常如果需要做Two-way replication通常會搭配Virtual Server使用

96

在前端架設一台Virtual Server不過此部份不在此份SOP討論範圍內有興趣

的讀者可參考 httpwwwlinuxvirtualserverorg 網站

1921680100 1921680200

Host A MasterSlave Server

Host B MasterSlave Server

Virtual Host

圖 Virtual Server + Two-way replication 架構圖

97

圖 High Availability Linux Virtual Server架構圖

98

  • COSA-SOP-03-006
  • 第一章 簡介
    • 11適用對象 (Audience)
    • 12 MySQL本身
    • 13 MySQL 40版跟50版重大的改進功能
    • 14 各家資料庫軟體比較
      • 第二章 前置需求
      • 第三章 安裝
        • 31 MySQL安裝
        • 32 phpMyAdmin安裝
        • 33 升級及注意事項
          • 第四章 MySQL管理
            • 41 Webmin 管理介面
            • 42 phpMyAdmin 的操作介面
            • 43管理指令介紹
              • 431 利用mysqladmin設定root的密碼
                  • 第五章 實用範例
                    • 51 任務一Web Base客戶通訊錄
                    • 52 任務二Web Base群組軟體 ( twig )
                      • 第六章 維護及更新程序
                        • 61 日常維護
                        • 62 更新程序
                        • 63 備份重要檔案
                        • 64 離線備份與還原
                        • 65 線上備份與還原
                          • 第七章 問題與解答
                          • 第八章 參考資料
                          • 附錄一 SQL Command 介紹
                          • 附錄二Replication
Page 56: DataBase Server Standard Operation Procedureebooks.lib.ntu.edu.tw/1_file/oss/63/93doc4-5.pdf · 業務的公司帶來了不少壓力,譬如微軟,甲骨文 ... 外的錢用在第三方的資料庫產品上,譬如就可以不用再購買甲骨文公司

if條件組合 SQL字串 if (chop($name) = ampamp chop($tel) = ) $sql= WHERE $name AND $tel elseif (chop($name) = ) 只有姓名 $sql = WHERE $name elseif (chop($tel) = ) 只有電話號碼 $sql = WHERE $tel $sql= ORDER BY name 最後加上排序 $result = mysql_query($sql) 取得欄位數 $total_fields = mysql_num_fields($result) echo lttable border=1gt echo lttrgtlttdgt編號lttdgtlttdgt姓名lttdgtlttdgt電話lttdgtlttd colspan=2gt功能選項lttdgtlttrgt 表格顯示查詢結果 while ($rows = mysql_fetch_array($result MYSQL_NUM)) echo lttrgt for ($i = 0 $i lt $total_fields $i++) echo lttdgt$rows[$i]lttdgt echo lttdgtlta href=editphpaction=editampid= echo $rows[0]gtltbgt編輯ltbgtlttdgt echo lttdgtlta href=editphpaction=delampid= echo $rows[0]gtltbgt刪除ltbgtlttdgt echo lttrgt echo lttablegtlthrgt mysql_free_result($result) mysql_close($link) gt ltcentergt ltform action=searchphp method=postgt lttable border=0 width=450gt lttrgtlttdgt搜尋姓名 lttdgt lttdgtltinput type=text name=Name size=10 maxlength=20gtlttdgtlttrgt lttrgtlttdgt搜尋電話 lttdgt lttdgtltinput type=text name=Tel

56

size=20 maxlength=20gtlttdgtlttrgt lttrgtlttd colspan=2 align=centergt ltinput type=submit name=Search value=搜尋gtlttdgtlttrgt lttablegt ltformgt ltbrgtlta href=indexhtmlgt通訊錄ltagt | lta href=addphpgt新增連絡人ltagt | lta href=searchphpgt搜尋通訊錄ltagt ltbodygt lthtmlgt

lt ob_start() gt lt-- 程式範例editphp --gt lthtmlgt ltheadgtlttitlegt編輯通訊錄lttitlegtltheadgt ltbodygt lt 取得 URL 參數 $id = $_GET[id] $action = $_GET[action] 建立資料庫連結 $link = mysql_connect(localhostroot1234) mysql_select_db(CONTACT) 選擇資料庫 執行的操作 switch ($action) case update 更新 取得欄位資料 $name = $_POST[Name] $tel = $_POST[Tel] $sql = UPDATE address SET name=$name tel=$tel WHERE id=$id mysql_query($sql) 執行 SQL指令 mysql_close($link) header(Location searchphp) 轉向到 serachphp break case del 刪除 $sql = DELETE FROM address WHERE id=$id

57

mysql_query($sql) 執行 SQL指令 mysql_close($link) header(Location searchphp) 轉向到 serachphp break case edit 編輯 $sql = SELECT FROM address WHERE id=$id $result = mysql_query($sql) 執行 SQL指令 $row = mysql_fetch_row($result) 取回記錄 $name = $row[1] 取得欄位 name $tel = $row[2] 取得欄位 tel mysql_close($link) 顯示編輯表單 gt ltcentergtlth2gt更新通訊錄lth2gtltcentergtlthrgt ltform action=editphpaction=updateampid=lt echo $id gt method=postgt lttable border=0 width=300gt lttrgtlttdgt姓名 lttdgt lttdgtltinput type=text name=Name size=20 maxlength=10 value=lt echo $name gtgtlttdgtlttrgt lttrgtlttdgt電話 lttdgt lttdgtltinput type=text name=Tel size=20 maxlength=20 value=lt echo $tel gtgtlttdgtlttrgt lttrgtlttd colspan=2 align=centergt ltinput type=submit value=更新連絡人gtlttdgtlttrgt lttablegt ltformgt ltbrgtlta href=indexhtmlgt通訊錄ltagt | lta href=addphpgt新增連絡人ltagt | lta href=searchphpgt搜尋通訊錄ltagt lt break gt ltbodygt lthtmlgt

58

52 任務二Web Base群組軟體 ( twig )

順利完成Web Base客戶通訊錄程式測試一段時間後「Apache + MySQL + PHP」架構的穩定與快速巳深得老闆與公司所有同事的認同隨著公司業績蒸

蒸日上人員組織編罝愈來愈龐大跨部門的會議愈來愈多業務員每日排滿拜

訪客戶的行程跟客戶的 Email的往來也愈來愈頻繁 愈來愈多部門的同事希望公司能建置一套群組軟體提供 web mail可讓業

務人員方便收發 mail還有連絡人議事日程待辦工作書簽等功能讓整個

公司運作及個人時間管理更有效率

老闆問小明對這些需求有什麼看法小明認為如果這些功能完全由程式部

門開發必定曠日費時而且耗費公司資源小明在網路尋找是否有提供這些功能

的Free Software皇天不負苦心人小明發現了TWIG (The Web Information Gateway) httptwigscrewdrivernet這個群組軟體它在 Web 上整合郵件新聞聯絡人議事日程工作序書簽等功能非常符合公司的需求 Step 1 下載 twig-277targz 下載網址 httptwigscrewdrivernetdownloadphp3

Step 2 解開 twig-277targz tar -xzvf twig-277targz

59

Step 3 執行安裝動作安裝到 varwwwhtmltwig 目錄 cd twig-277 twig-install varwwwhtmltwig

Step 4 建立 MySQL 資料庫(twig)及各資料表

cd setup mysql -u root -p1234 mysqlgt create database twig Query OK 1 row affected (001 sec) mysqlgt quit mysql -u root ndashp1234 twiglt twigtablemysql

Step 5 修改 configincphp3 參數設定 vi varwwwhtmltwigconfigconfigincphp3 $config[fromdomain] = opencom 網域 $config[language] = chinesebig5 中文訊息 $config[imap_port] = 143notls

60

Step 6 修改連結 MySQL 的帳號密碼 vi varwwwhtmltwigconfigdbconfigincphp3 $dbconfig[sqlusername] = root username $dbconfig[sqlpassword] = 1234 password

Step 7 其他設定檔

vi etchttpdconfhttpdconf 加入 AddType applicationx-httpd-php php3 在 DirectoryIndex最後加入 indexphp3 DirectoryIndex indexhtml indexhtmlvar indexphp3 在 AddDefaultCharset ISO-8859-1加上 AddDefaultCharset ISO-8859-1

vi etcphpini register_globals = On service httpd restart Step 8 sendmail 設定 vi etcmailsendmailcf在 264 行前面加上並重新啟動 sendmail「service snedmail restart」 262 SMTP daemon options 263 264 O DaemonPortOptions=Port=smtpAddr=127001 Name=MTA 265 266 SMTP client options 267 O ClientPortOptions=Family=inet Address=00

61

Step 9 檢查設定有無錯誤 http主機名稱twigtestphp3

62

Step 10 登入 twig ( http主機名稱twig)

63

第六章 維護及更新程序

61 日常維護

系統管理員最好定期以 root 身份登入看看信件在 RedHat Linux 中有一支 logwatch 程式會定時去分析 log file如果發現異常便會發信給 root除此之外筆者建議讀者平時就檢查 MySQL log file ( varlogmysqldlog)是否有異常情形

62 更新程序

讀者可至httprpmfindnet 尋找MySQL相關套件至於升級的相關步驟請參

考Linux OS SOP 第 54節

63 備份重要檔案

預設 MySQL 的 DB 檔案是存在 varlibmysql 內以 DB名稱為目錄目錄

內就是該 DB 的所有資料通常得定期備份還有 MySQL的設定檔 etcmycnf也別忘了一起備份

64 離線備份與還原

641 離線備份

預設 MySQL 的 DB 檔案是存在 varlibmysql 內以 DB 名稱為目錄目錄內

就是該 DB 的所有資料像 CRM 這個 DB就是存在 varlibmysqlCRM 內在備份前因為怕資料尚未完全寫入磁碟而且 MySQL 會 Lock 在使用的 DB 檔案所以應該是要先把 MySQL 先 Shutdown 一下整個備份的程序可以下像下面的指令去完成 cd varlibmysql

64

service mysqld stop tar cvfz CRM_db_20030905tgz CRM service mysqld start 對這樣就可以了 不過要注意的是怕 DB 內每個 Tables 間的資料有關關

聯性所以最好是把整個 DB 一次備起來單獨只備哪個 Tables 的檔案以後回存時怕會有資料關聯不一致的問題

642 離線還原

DB 發生錯誤而要回存時其實也不難先找出最近一次完整正常的備份先把現在錯誤的網頁或 DB 先更名或 tar 起來再把好的備份給解開回原來目錄位

置就行了需要注意的是 MySQL 服務最好也是要先停止回存完成後再啟動服務回存 DB 的整個程序可能像下面 cd varlibmysql service mysqldstop mv CRM CRM_OLD tar xvfz CRM_db_20030905tg service mysqld start

65 線上備份與還原

651 線上備份

使用像上面的檔案方式備份是個不錯的方法它最少可以保持該主機某個時間點的完整檔案備份但還是有一些問題需要考慮到有些主機就不只建立一個 DB 而已總不能為了備份某個 DB 而把整個 MySQL 服務停止備份檔案的方式回存在原主機上一定適用但假如 MySQL 版本升級或是在那天該網頁空間需遷機移機到別的主機時那就沒人敢保證備出來的資料檔可以用所以我們可以考慮另一種備份的方式是使用 MySQL 本身提供的功能 MySQL Data Dump指令是 mysqldump

65

使用 MySQL 的 Dump 功能可以把 DB 的結構資料或結構加資料 Dump 成文字檔 mysqldump 指令提供的彈性很大你可以選擇把整個 DB Dump 成一個檔或是每個 Table 為一個檔甚至是把結構檔和資料分開儲存都

可以 mysqladmin -uroot -p flush-logs mysqldump CRM -uroot -p --opt gt CRM_20030905sql (CRM 是 DB 名稱 opt 是一個使用完整 Dump 參數) 假如只是要單獨 Dump 某個 Table 時只要在上面的指令後轉出符號 gt 前加個 Table 名稱就可以如只要 phpbb2_users 這個 Table 的 Dump 時只要下 mysqldump CRM -uroot -p --opt CUSTOMER gt CRM_CUSTOMER_20030905sql

652 線上還原

若要回存整個資料庫只需將壓縮的備份檔還原成 Dump 的檔案再用下面的指令回存 mysql CRM -uroot -p lt CRM_20030905sql 這邊需注意的是若建立備份時是以--opt或--add-drop-table為參數時回存的 動作是先將舊的 Table 先刪除重建 Table 的結構後再把 Data 匯入所以回存後所有的資料會回到你當時備份那個時間點因此在回存資料時可以考慮把現有錯誤或不完整的 DB 先備份一份下來以備不時之需或是拿來比對錯誤的地

方在那裡當然你也可以把資料回存到另一個測試用的 DB 內只要把上面指令

的 DB 名稱改成你的測試用 DB 名稱即可 使用這種回存方式 MySQL 服務不需停止也不會動到其他正在使用的 DB 在一些提供 MySQL 服務的虛擬主機可用這種方式作你自己的 DB 備份及回存

66

另外假如你是系統重建或是移機時切需在新的 MySQL 內新建一個空白 DB 後才行作回存的工作你可以用下面的指令建立 mysql -uroot -p -e CREATE DATABASE CRM (上面的 CRM是你要新建的 DB 名稱) 另一種作法先用 mysql 指令進入 mysql client console 然後再用 CREATE DATABASE CRM 這樣就行了記得尾端要加個 符號該行指令才會執行

67

第七章 問題與解答

Q1RedHat 90預附的 MySQL到底有無支援 Transcation機制 Ans MySQL自 32334a之後的 MySQL-Max版本加入 InnoDB的資料庫類型透過

InnoDBMySQL同樣可以進行 COMMIT與 ROLLRACK的動作RedHat 90預附的 MySQL為 32354a-11巳支援 InnoDB的資料庫類型不過必須做以

下設定 1cp usrsharedocmysql-server-32354amy-mediumcnf to etcmycnf 2 vi etcmycnf 將以下設定前的拿掉 innodb_data_home_dir = varlibmysql innodb_data_file_path = ibdata110Mautoextend innodb_log_group_home_dir = varlibmysql innodb_log_arch_dir = varlibmysql 3service mysqld restart 如此一來各位在建立Table時便可指定Table Type為 innodb ( ex create table with type=innodb ) Q2如何解決 php+mysql 許功蓋等字變亂的問題 Ans 方法一 【確定 MySQL 預設的字元集】 1 打開 WinMySQLadmin 管理畫面(在視窗右下角狀態列紅綠燈圖示中按滑鼠

右鍵點選 Show me 選項) 2 點選管理畫面中 [Variables] 標籤選項其中 character_set變數就是您預設

字元集的變數其預設是 latin1 字元集(我們要將他改回 big5)而 chatacters_set 變數則是 MySQL 可以支援哪些字元集 【修改預設字元集變數 character_set 】 1 請點選管理畫面中 [myini Setup] 標籤選項設定 myini 2 按一下 [Pick-up and Edit myini values] 按鈕以便編輯目前的 myini 設定 3 在 [mysqld] 設定區塊底下新增一行 default-character-set = big5 變數設

68

定 4 新增一個 [client] 設定區塊並加入第三步驟的變數設定(游標往下移到空白處新增兩行 [client] 和 default-character-set=big5) 5 按一下畫面左下方 [Save Modification] 按鈕儲存設定 6 重新啟動 MySQL 或 Windows 方法二 Server端注意事項 phpini 中有關的設定為(預設值) Magic quotes for incoming GETPOSTCookie data magic_quotes_gpc = On Use Sybase-style magic quotes (escape with instead of ) magic_quotes_sybase = Off Client端注意事項 1中文資料送進 mysql 前請用 addslashes($str) 處理 2處理後送進 mysql 時請用 括起來並在參數後留一個空白如 $sql = UPDATE ezf_table set tablename=$tname tableend=$endtime table inguser=$tguser tableingid=$tguserid tableallnumber=$tnumber tableloca l=$tablelocal tableanyone=$tableopen tabletext=$ttext WHERE tableid=$t ableid tablename=$tname c 取出時請用 stripslashes($str) Q3MySQL root 密碼忘了該怎麼辦 Ans 1先停掉 mysql etcrcdinitdmysql stop 2以--skip-grant-table 的參數啟動 mysql safe_mysql --skip-grant-tableamp 3 更改 root 密碼 mysql mysql mysqlgt UPDATE user SET password=password(newpassword)

69

WHERE user=root mysqlgt FLUSH PRIVILEGES mysqlgt exit 4停掉 mysql再重跑 mysqladmin -uroot -p shutdown Enter password 輸入新設定的密碼 etcrcdinitdmysql start

Q4NULL值問題

Ans

NULL值的概念是造成 SQL的新手的混淆的普遍原因他們經常認為 NULL是和一個空字符串的一樣的東西不是這樣的例如下列語句是完全不同的

mysqlgt INSERT INTO my_table (phone) VALUES (NULL)

mysqlgt INSERT INTO my_table (phone) VALUES ()

兩個語句把值插入到 phone 列但是第一個插入一個 NULL值而第二個插入一個空字符串第一個的含義可以認為是ldquo電話號碼不知道而第二個則可意味

著ldquo她沒有電話

在 SQL中NULL值在于任何其他值甚至 NULL值比較時總是假的(FALSE)包含 NULL的一個表達式總是產生一個 NULL值除非在包含在表達式中的運算符和函數的文檔中指出在下列例子所有的列返回 NULL

mysqlgt SELECT NULL1+NULLCONCAT(InvisibleNULL)

如果你想要尋找值是 NULL的列你不能使用=NULL測試下列語句不返回任

何行因為對任何表達式expr = NULL是假的

mysqlgt SELECT FROM my_table WHERE phone = NULL

要想尋找 NULL值你必須使用 IS NULL測試下例顯示如何找出 NULL電話號碼和空的電話號碼

70

mysqlgt SELECT FROM my_table WHERE phone IS NULL mysqlgt SELECT FROM my_table WHERE phone =

在 MySQL中就像很多其他的 SQL服務器一樣你不能索引可以有 NULL值的列你必須聲明這樣的列為 NOT NULL而且你不能插入 NULL到索引的

列中

當用 LOAD DATA INFILE 讀取數據時空列用更新如果你想要在一個列中有

NULL值你應該在文本文件中使用N字面上的詞NULL也可以在某些情形下使用

當使用 ORDER BY時首先呈現 NULL值如果你用 DESC以降序排序NULL值最後顯示當使用 GROUP BY時所有的 NULL值被認為是相等的

為了有助于NULL的處理你能使用 IS NULL和 IS NOT NULL運算符和 IFNULL()函數

對某些列類型NULL值被特殊地處理如果你將 NULL插入表的第一個TIMESTAMP 列則插入當前的日期和時間如果你將 NULL插入一個AUTO_INCREMENT 列則插入順序中的下一個數字

Q5如何將圖片存放於 MySQL中

Ans

Step 1建立資料庫 test

Step 2 建立表格 binary_data

CREATE TABLE binary_data (

id INT(4) NOT NULL AUTO_INCREMENT PRIMARY KEY

description CHAR(50)

bin_data LONGBLOB

filename CHAR(50)

filesize CHAR(50)

filetype CHAR(50)

71

)

Step 3 利用 storephp 寫入圖片

storephp 程式碼

ltHTMLgt ltHEADgtltTITLEgtStore binary data into SQL DatabaseltTITLEgtltHEADgt ltBODYgt lt code that will be executed if the form has been submitted

if ($submit) mysql_connect(localhostrootYOUR_PASSWORD) mysql_select_db(test) $data=Base64_Encode(fread(fopen($form_data r) filesize($form_data))) $result=MYSQL_QUERY(INSERT INTO binary_data (descriptionbin_datafilenamefilesizefiletype) VALUES ($form_description$data$form_data_name$form_data_size$form_data_type)) $id= mysql_insert_id() print ltpgtThis file has the following Database ID ltbgt$idltbgt MYSQL_CLOSE() else else show the form to submit new data

gt

ltform method=post action=ltphp echo $PHP_SELF gt enctype=multipartform-datagt File Descriptionltbrgt ltinput type=text name=form_description size=40gt ltINPUT TYPE=hidden name=MAX_FILE_SIZE value=4000000gt ltbrgtFile to uploadstore in databaseltbrgt ltinput type=file name=form_data size=40gt ltpgtltinput type=submit name=submit value=submitgt ltformgt lt

72

gt ltBODYgt ltHTMLgt

Step 3 利用 storephp 取出圖片

getdataphp 程式碼

lt Syntax getdataphp3id=ltidgt if($id) you may have to modify login information for your database server MYSQL_CONNECT(localhostrootYOUR_PASSWORD) mysql_select_db(test) $query = select bin_datafiletype from binary_data where id=$id $result = MYSQL_QUERY($query) $data = Base64_Decode(MYSQL_RESULT($result0bin_data)) $type = MYSQL_RESULT($result0filetype) Header( Content-type $type) echo $data gt

Q6MySQL裝好之後啟動時或是執行 mysqladmin會出現如下訊息 Cant connect to local MYSQL Server through Socket varlibmysqlmysqlsock或是

Cant connect to local MYSQL Server through Socket tmpmysqldsock

Ans 可能有下列幾個原因

1這個 mysqldsock 不見了被某人刪除了或是被一些系統自動執行程式給刪

了例如有些 cron任務便會設定定期刪除 tmp 裡的東西所以呢您只能修改

cron 裡的設定讓它不要清除 mysqldsock 2在啟動時也可以改變 mysqldsock的位置您在啟動 MySQL的時候可以加入此參數usrlocalmysqlbinsafe_mysqld --user=mysql --socket=其他路

徑socket amp 同時得去設定環境變數 MYSQL_UNIX_PORT的值以指定新的

73

路徑 3若是您沒改 MYSQL_UNIX_PORT的值那麼您可以在執行指令的時候才打

例如mysqladmin --socket=其他路徑socket version Q7How to get the last insert id Ans CREATE TABLE product ( id INT(4) NOT NULL AUTO_INCREMENT PRIMARY KEY description VARCHAR(50) ) 1利用 SQL的話 mysqlgt insert into product(description) values(123) Query OK 1 row affected (000 sec) mysqlgt select last_insert_id() +------------------+ | last_insert_id() | +------------------+ +------------------+ 1 row in set (000 sec) ======================================== 2如果是 PHP的話 你可以用mysql_insert_id()取得該 id PHP example $result=MYSQL_QUERY(INSERT INTO product (description) VALUES ($description)) $id= mysql_insert_id() print This file has the following Database ID $id Q8如何將文字檔匯入資料庫 Ans $addr=homehttpdhtmlphpschool001txt $sql_select = load data infile $addr into table test fields terminated by t 解說 $sql_select = load data infile 文字檔名 into table 表格名 fields terminated by

74

t

(欄位分隔以 TAB鍵) 該文字檔須與資料表欄位格式相符 例如欄位有三個 則文字檔為每行一筆資料如下 欄 1資料ltTABgt欄 2資料ltTABgt欄 3資料 欄 1資料ltTABgt欄 2資料ltTABgt欄 3資料 欄 1資料ltTABgt欄 2資料ltTABgt欄 3資料 欄 1資料ltTABgtltTABgt欄 3資料

Q9如何撰寫 MySQL C API Ans Step 1利用文字編輯器撰寫以下程式碼 mysqlcc

include ltstdiohgt

include ltmysqlmysqlhgt

int main (int argc char argv[])

MYSQL mysql

MYSQL_RES res

MYSQL_ROW row

if (argc = 2)

fputs (Usage myc ltdatabasegt stderr)

return 1

if ((mysql_connect(ampmysqllocalhostrootYour_Password)))

fputs (Error connecting stderr)

abort()

75

if (mysql_select_db(ampmysqlargv[1]))

fputs (Error selecting database stderr)

abort()

if (mysql_query(ampmysqlSELECT FROM test_table))

fputs (Error processing query stderr)

abort()

if ((res = mysql_store_result(ampmysql)))

fputs (Error storing results stderr)

abort()

while((row = mysql_fetch_row(res)))

uint i = 0

for (i=0 i lt mysql_num_fields(res) i++)

printf(s row[i])

printf(n)

return 0

Step 2 Compile

gcc -Iusrlocalmysqlinclude -Lusrlocalmysqllibmysql mysqlcc ndashlm -lmysqlclient

(其中 include path與 library path取決於你的 MySQL安裝路徑)

76

如果執行時發生如下 error Run problemerror in loading shared libraries libmysqlclientsoX 將你的 MySQL library path(for exampleusrlocalmysqllibmysql) 加入etcldsoconf and run sbinldconfig -v Q9ASP + MySQL 範例程式 Ans Dim myconn As New ADODBConnection Dim myrs As New Recordset Dim mySQL As String Dim myrows As Long myconnOpen DSN=MyODBCsample mySQL = SELECT from user myrsSource = mySQL Set myrsActiveConnection = myconn myrsCursorLocation = adUseClient myrsOpen myrows = myrsRecordCount myrsClose myconnClose 可參考 httpwwwdwamnetmysqlasp_myodbcasp 有詳細的資料 Q10如何將 MySQL中的資料庫匯出成txt檔 Ans select from TableName into outfile textxls all result fields will seperate by tab

77

第八章 參考資料

英文部份 網址 1 httpwwwmysqlcom MySQL 網站有第一手有關 MySQL的資料 2 httpwwwmysqlcomdocenReplicationhtml 有關 MySQL Replication 的文件 3 httpwwwgeocitiescomsqlhomefaqstore_blobhtml 如何在 MySQL 存放 BLOB的資料 4httpwwwsapdborg 有關 SAP跟 MySQL相關合作的網站 書藉 1 Cooking with MySQL

Paul DuBois has selected sample recipes from the hundreds youll find in his book MySQL

Cookbook In this third and final series of excerpts showcasing these recipes learn how to

compute team standings how to calculate the differences between successive Dec 26

2002 2 Tips for Building Web Database Applications with PHP and MySQL by Hugh E Williams co-author of Web Database Applications with PHP amp MySQL 04042002

3 Managing and Using MySQL 2nd Edition By Tim King George Reese Randy Jay Yarger

4 MySQL Cookbook By Paul DuBoisPublisher OReillyPub Date October 2002

中文部份

78

1 httplinuxtncedutwtechdocmysqlmysql_docmanual_tochtml MySQL 中文手冊 2 httpchenshloxaedutwphpZ_1php PHP+MySQ程式研習設計網站 3 httplinuxtncedutwtechdocbanicdownhtml PHP 4 手冊 4 httpwwwtncedutwadmin_zonephp台南縣教育網網路中心有很多 Linux相關文件 5 httpdobtncedutw網站建置百寶箱有很多 PHP MySQL 相關範例程式 5 httpwwwdbworldcomtw資料庫專家電子雜誌介紹資料庫的重要觀念及名詞

79

附錄一 SQL Command 介紹

SQL (讀音ess-que-el) 是一種結構查詢語法SQL 使用於資料庫交流

傳遞相容於 ANSI (American National Standards Institute) 是一套標準的關聯

式資料庫語言 SQL 語言是執行更新或從資料系統獲取資料一般常見的關聯

資料庫系統都有提供 SQL 如 Oracle Sybase Microsoft SQL Server Access Ingres 等雖然大部份的資料庫都有提供 SQL 但也多提供了自已獨特的語

法造成了不相容的情形但標準基本的語法是相通的如Select Insert Update Delete Create and Drop 每一個系統都有支援

Table相關 Command

Create Table

關聯式資料庫包含有很多元件稱為資料表(tables) 把資料或訊息放在資

料表中 資料表是以不同的名稱做分別資料表由欄列所構成的二維陣列

欄包含欄位名資料型態 及其他可判斷的資訊列是由全部欄位構成一筆一

筆的紀錄 create table 語法用在建立一個新的資料表語法格式如下

create table tablename (column1 data type column2 data type column3 data type)

Format of create table if you were to use optional constraints

create table tablename (column1 data type [constraint] column2 data type [constraint] column3 data type [constraint]) [ ] = optional

Note You may have as many columns as youd like and the constraints are optional

80

Example

create table employee (first varchar(15) last varchar(20) age number(3) address varchar(30) city varchar(20) state varchar(20))

注意建立資料表格式要以括號把前後框住而最後以(分號)做結尾

欄位名不要超過 30個字元長而且不要使用 sql 的關鍵字(如 where select等)而在後面接是型態的宣告(如字串數字日期格式等)

資料型態是來描述欄位的方式如一個欄位Last_Name 是一個姓氏可以使用varchar (可變動長度字串) 資料型態

以下是幾個常見的資料庫型態 char(size) 固定長度字串最長為 255 位元 varchar(size) 變動長度字串最大字元數以 size 來指定 number(size) 數值格式可以是整數也可以是小數最大數字以 size 位數判

斷未指定小數位數由系統內定 date 日期格式 number(sized) 數值格式最大數字以 size 位數判斷d 為小數位數整數位

數為 size-d 位

有何限制當資料表被建立通常有一或數個欄位是要使用來做關聯的功

能 例如unique 限制(唯一值)兩筆記錄不可以相同的值 not null (非空值)該欄位一定要輸入資料不可是空的primary key (主鍵)是每一筆記錄識別的主要方式

Drop a table drop table 刪除資料表(其中的資料也會一併刪除)

drop table tablename

Example

81

drop table 和刪除全部資料是不同的刪除全部資料欄位名稱資訊等還會

存在但刪除資料表會把這一些也一併移除掉

如何查詢資料

Select 基本用法

select 語法是關連式資料庫最常用的部份可以取得你想要的資料這是一個

簡單的範例 select column1[column2etc] from tablename [where condition] [] = optional 在 select 之後所列欄位名則是要顯示的資料部份你可以一一列出各欄位

名或是以 (星號)來代表選擇全部的欄位 from 之後放資料表名稱 where 子句 (選項) 指定要過濾的條件符合者才會顯現 where 可使用的條件運算元 = 等於 gt 大於 lt 小於 gt= 大或等於 lt= 小或等於 ltgt 大相等 LIKE 相似 For example select first last city

82

from empinfo where first LIKE Er 以Er 為開頭的字串就符合要以單引號框住 Or you can specify select first last from empinfo where last LIKE s 最後一字為 S 就符合 select from empinfo where first = Eric 則表示 first name 一定要是 Eric 才可以 範例資料表empinfo 統計函數

MIN 傳回指定欄位最小值

MAX 傳回指定欄位最大值

SUM 傳回指定欄位總和

AVG 傳回指定欄位平均值

COUNT 傳回指定欄位的筆數

COUNT() 傳回資料庫中的總筆數

統計函數使用於資料表中的數值欄位配合 SELECT 語法使用 只用於總結特定單一欄位可以配合 GROUP BY 做篩選但也可以不使用 GROUP BY 語句For example

SELECT AVG(salary) FROM employee

83

傳回全部 salary 平均值

Another example

SELECT AVG(salary) FROM employee WHERE title = Programmer

傳回 salary 平均值條件為 employees 資料表中當 title 等於 Programmer

Example

SELECT Count() FROM employees

傳回 employees 資料表中紀錄總筆數

GROUP BY 語法 SELECT column1 SUM(column2) FROM list-of-tables GROUP BY column-list The GROUP BY 語句可以先以所列的欄位為條件分組排序在一起(可以多欄

位) example 要列出每一個 dept 中最高 salary 值 SELECT max(salary) dept FROM employee GROUP BY dept HAVING 語法

SELECT column1 SUM(column2) FROM list-of-tables GROUP BY column-list HAVING condition

HAVING 子句是 GROUP BY 的一部份用來過濾在 GROUP BY 所選出的資料功能如同 select 命令中 where 條件式一樣只是 HAVING 必需配合 GROUP BY 使用

我們以例子來說明我們要取得每一公司名及每一公司的薪水平均值輸入如下

84

SELECT dept avg(salary) FROM employee GROUP BY dept

但如果我們只列出薪資平均值超過 20000元的公司資料

SELECT dept avg(salary) FROM employee GROUP BY dept HAVING avg(salary) gt 20000

ORDER BY子句語法

SELECT column1 SUM(column2) FROM list-of-tables ORDER BY column-list [ASC | DESC]

[ ] =選項

ORDER BY是一個選項子句當你以排序方式來顯示資料(正向由小到大反向由大到小)以指定的欄位資料做排序

ASC = 正向- 預設值 DESC = 反向排序

For example

SELECT employee_id dept name age salary FROM employee_info WHERE dept = Sales ORDER BY salary

以上列出公司代號公司名銷售員人名年紀及薪資而條件是公司名為 Sales 顯示順序以薪資多少排序(由小到大為預設值)

如果要以多個欄位做排序要以逗號做分隔如下

SELECT employee_id dept name age salary FROM employee_info WHERE dept = Sales ORDER BY salary age DESC

85

結合條件及布林運算 SELECT column1 SUM(column2) FROM list-of-tables WHERE condition1 AND condition2 AND運算可以結兩個或以上的條件放在 WHERE子句中 兩者都要為真才

會顯示該筆記錄 OR 運算可以結兩個或以上敘述放在 WHERE子句中只要其中一個為直就

會顯示該筆記錄 For example SELECT employeeid firstname lastname title salary FROM employee_info WHERE salary gt= 5000000 AND title = Programmer 必需要薪資大於等於 50000而且職稱為 Programmer同時符合才會顯示該筆資料 以下以括號括住雖然不是必需的但如此比較容易讀 SELECT employeeid firstname lastname title salary FROM employee_info WHERE (salary gt= 5000000) AND (title = Programmer) 另外範例 SELECT firstname lastname title salary FROM employee_info WHERE (title = Sales) OR (title = Programmer) 條件為只要是 Sales 或 Programmer 職稱的就會被列出 IN and BETWEEN 子句

SELECT column1 SUM(column2) FROM list-of-tables WHERE column3 IN (list-of-values) SELECT column1 SUM(column2) FROM list-of-tables WHERE column3 BETWEEN value1 AND value2 IN 子句使用在列舉項目的使用上也就是分別測試是否符合所列的值 For example

86

SELECT employeeid lastname salary FROM employee_info WHERE lastname IN (Hernandez Jones Roberts Ruiz) 條件為姓氏(astname)要符合 Hernandez Jones Roberts or Ruiz 其中一個才會被傳回 IN運算元也可以使用 OR 的語法來取代如下結果相同 SELECT employeeid lastname salary FROM employee_info WHERE lastname = Hernandez OR lastname = Jones OR lastname = Roberts OR lastname = Ruiz 但使用 IN 句子比較短也比較易懂 你也可以使用 NOT IN 來去掉不要的記錄 BETWEEN 運算元使用在判斷是否存在兩個數值之間 For example SELECT employeeid age lastname salary FROM employee_info WHERE age BETWEEN 30 AND 40 傳回年紀 30歲到 40歲之間的資料(含 30及 40歲者) 相同的也可以使用以下語法來達到相同的結果 SELECT employeeid age lastname salary FROM employee_info WHERE age gt= 30 AND age lt= 40 你也可使用 NOT BETWEEN 來濾掉中間值的資料 數學運算 標準 ANSI SQL-92 提供以下運算

87

+ 加

- 減

餘數

餘數為除法後剩整數這不在標準的 ANSI SQL 中但大部份的資料庫都會支

援這運算元以下列出有用的函數雖不在 ANSI SQL-92 提供但一般資料庫

也會支援他們

ABS(x) 傳回 x 絕對值

SIGN(x) returns the sign of input x as -1 0 or 1 (negative zero or positive respectively)

MOD(xy) 餘數 - returns the integer remainder of x divided by y (同 xy)

FLOOR(x) 傳回小或等於 x 的最大整數值

CEILING(x) or CEIL(x)

傳回大或等於 x 的最小整數值

POWER(xy) x的 y 次方

ROUND(x) 把 x 四捨五入為整數

ROUND(xd) 四捨五入取到小數 d 位

SQRT(x) x 開平方

For example SELECT round(salary) firstname FROM employee_info 傳回薪資取到整數位

如何新增資料

insert 加入一筆新紀錄到資料表中 insert into tablename (first_columnlast_column) values (first_valuelast_value) [] = optional Example insert into employee

88

(first last age address city state) values (Luke Duke 45 2130 Boars Nest Hazard Co Georgia) Note 字串要以單引號住如string 數字框住也無妨 insert into 後面接資料表名稱再接以括號括住的欄位名在 values 後括號分別對映各欄位的值 以上的例子新增了一筆名(first) 為 Luke而住所(state) 為 Georgia 的資料

如何刪除資料

delete 可以刪除單筆或多筆紀錄 delete from tablename where columnname OPERATOR value [and|or column OPERATOR value] [ ] = optional Examples delete from employee Note 如果你沒有指定 where 子句那麼全部的紀錄都會被刪除 delete from employee where lastname = May delete from employee where firstname = Mike or firstname = Eric delete from 接著資料表名 再接著是條件式判斷沒有條件式則全部紀錄會

被刪除

如何更新資料

update 用來更新你所指定的記錄要和 WHERE 配合小心使用 語法 update tablename set columnname = newvalue[nextcolumn = newvalue2] where columnname OPERATOR value [and|or column OPERATOR value] [] = optional Examples

89

update phone_book set area_code = 623 where prefix = 979 update phone_book set last_name = Smith prefix=555 suffix=9292 where last_name = Jones update employee set age = age+1 where first_name=Mary and last_name=Williams

90

附錄二Replication

測試環境

RedHat 90 + MySQL 32358 MySQL資料庫路徑 varlibmysql MySQL設定檔 etcmycnf Master IP 1921680100 Slave IP 1921680200 請至下列網址下載最新MySQL 32358套件並利用rpm ndashUvh 更新 httpupdatesredhatcom9enosi386

圖 最新 MySQL 套件

測試架構圖

91

1921680100

1921680200Master Server

erveSlave S r

圖 測試架構圖

測試步驟

Master server 部份 Step1 確認 MasterSlave機器上所裝的 MySQL版本能進行

replication( 32329 or higher ) Step2 在 Master MySQL上開放一個帳號給 Slave mysql ndashu root ndashp mysqlgtGRANT FILE ON TO repl1921680200 IDENTIFIED BY lsquoabc123rsquo mysqlgtq 上面是 Master開放一個帳號 repl密碼 abc123給 IP1921680200有檔案處理

的權限 Step3 shutdown MySQL on the Master mysqladmin ndashu root ndashp shutdown Step4 備份 Master所有資料庫 tar ndashcvf tmpmysql-snapshottar varlibmysql 注意tar的時候MySQL是要在 stop情況下 在mysql (wwwmysqlcom) 網站的FAQ有不用shutdown的方法

92

Step5 在 master機器上修改etcmycnf 在[mysqld]區段內加入參數 log-bin server-id=這邊設定 server-id=1 sql-bin-update-same binlog-do-db=CRM只針對 CRM資料庫做紀錄 Step6 Restart MySQL on the master service mysqld start 此時因為有加入 log-bin 參數因此開始有 index產生了在varlibmysql目錄下

有index檔案紀錄資料庫的異動 log Slave server 部份 Step1 在 slave設定etcmycnf 在[mysqld]區段加入 master-host= master-user= master-password= master-port= server-id= 這邊設定 master-host=1921680100 master-user=repl master-password=abc123 master-port=3306 server-id=2 master-connect-retry=60預設重試間隔 60秒 replicate-do-db=CRM告訴 slave只做 CRM資料庫的更新 log-slave-updates Step2 將 master上的 mysql-snapshottar copy到 slave上 用 ftp傳到 slave的tmp Step3 解壓縮 Master資料庫至 Slave Server上 cd varlib tar xvf tmpmysql-snapshottar chown ndashR mysqlmysql mysql

93

chmod ndashR 770 mysql (視情況) Step4 Restart MySQL on the slave server 這時在varlibmysql目錄會出現 masterinfo此檔案紀錄了 Master MySQL server的資訊

狀況測試

One-way replication

1921680100

1921680200Master Server

erveSlave S r

圖 One-way replication架構圖 Step1 Master跟 Slave網路及服務都正常情況下由 Master端異動資料後 到 Slave端瀏覽資料檢視是否有進行 replication Step2 模擬 Slave Server 當機 可用在於 slave真的當機或是 Slave 不一定需要一直跟 master connect將Slave MySQL server shutdown由 Master端異動資料到 slave端瀏覽此時Slave應該沒有被 replication 更新然後再將 Slave端 MySQL server start起來

預設 60秒後 Slave會嘗試跟 Master要求進行 replication再去 Slave端檢視是否有更新資料

94

Step3 模擬 Master當機因為是設定 One-way replication一旦 Master Server Slave端沒有 Master的 source可以 download Two-way replication 基於 Master當機狀況於是發展雙向 Replication即 1921680100 ( Host A ) 1921680200 ( Host B )都分別擔任 MasterSlave身分

1921680100

1921680200er

Server B MasterSlave Server

Server A MasterSlave Serv

圖 Two-way replication架構圖 以下是針對兩台 MySQL伺服器進行雙向 Replication Step1觀念同單向 replication只是改成 Master也有 Slave身分 Slave也有Master的身分先分別在 Server AServer B 都去 grant一個進行 replication的身分 [A]mysqlgtGRANT FILE ON TO repl1921680200 IDENTIFIED BY lsquoabc123rsquo [B]mysqlgt GRANT FILE ON TO repl1921680100 IDENTIFIED BY lsquoabc123rsquo Step2做完單向 replication後stop Server Aserver B MySQL service此時 AB資料是一樣的

95

修改etcmycnf設定 範例 Server A [mysqld] datadir=varlibmysql socket=varlibmysqlmysqlsock server-id=1 log-bin sql-bin-update-same binlog-do-db=CRM master-host=1921680200 master-user=repl master-password=abc123 log-slave-updates master-connect-retry=60 replicate-do-db=CRM Server B [mysqld] datadir=varlibmysql socket=varlibmysqlmysqlsock server-id=2 log-bin sql-bin-update-same binlog-do-db=CRM master-host=1921680100 master-user=repl master-password=abc123 log-slave-updates master-connect-retry=60 replicate-do-db=CRM 分別 start Server AServer B MySQL後此時雙方都是 MasterSlave身分一旦哪一方資料異動就會通知對方來 replication-若 replication失效則必須將Server AServer B的masterinfo及index00x 都砍掉然後分別 restart MySQL server進行測試檢視成果 實務上通常如果需要做Two-way replication通常會搭配Virtual Server使用

96

在前端架設一台Virtual Server不過此部份不在此份SOP討論範圍內有興趣

的讀者可參考 httpwwwlinuxvirtualserverorg 網站

1921680100 1921680200

Host A MasterSlave Server

Host B MasterSlave Server

Virtual Host

圖 Virtual Server + Two-way replication 架構圖

97

圖 High Availability Linux Virtual Server架構圖

98

  • COSA-SOP-03-006
  • 第一章 簡介
    • 11適用對象 (Audience)
    • 12 MySQL本身
    • 13 MySQL 40版跟50版重大的改進功能
    • 14 各家資料庫軟體比較
      • 第二章 前置需求
      • 第三章 安裝
        • 31 MySQL安裝
        • 32 phpMyAdmin安裝
        • 33 升級及注意事項
          • 第四章 MySQL管理
            • 41 Webmin 管理介面
            • 42 phpMyAdmin 的操作介面
            • 43管理指令介紹
              • 431 利用mysqladmin設定root的密碼
                  • 第五章 實用範例
                    • 51 任務一Web Base客戶通訊錄
                    • 52 任務二Web Base群組軟體 ( twig )
                      • 第六章 維護及更新程序
                        • 61 日常維護
                        • 62 更新程序
                        • 63 備份重要檔案
                        • 64 離線備份與還原
                        • 65 線上備份與還原
                          • 第七章 問題與解答
                          • 第八章 參考資料
                          • 附錄一 SQL Command 介紹
                          • 附錄二Replication
Page 57: DataBase Server Standard Operation Procedureebooks.lib.ntu.edu.tw/1_file/oss/63/93doc4-5.pdf · 業務的公司帶來了不少壓力,譬如微軟,甲骨文 ... 外的錢用在第三方的資料庫產品上,譬如就可以不用再購買甲骨文公司

size=20 maxlength=20gtlttdgtlttrgt lttrgtlttd colspan=2 align=centergt ltinput type=submit name=Search value=搜尋gtlttdgtlttrgt lttablegt ltformgt ltbrgtlta href=indexhtmlgt通訊錄ltagt | lta href=addphpgt新增連絡人ltagt | lta href=searchphpgt搜尋通訊錄ltagt ltbodygt lthtmlgt

lt ob_start() gt lt-- 程式範例editphp --gt lthtmlgt ltheadgtlttitlegt編輯通訊錄lttitlegtltheadgt ltbodygt lt 取得 URL 參數 $id = $_GET[id] $action = $_GET[action] 建立資料庫連結 $link = mysql_connect(localhostroot1234) mysql_select_db(CONTACT) 選擇資料庫 執行的操作 switch ($action) case update 更新 取得欄位資料 $name = $_POST[Name] $tel = $_POST[Tel] $sql = UPDATE address SET name=$name tel=$tel WHERE id=$id mysql_query($sql) 執行 SQL指令 mysql_close($link) header(Location searchphp) 轉向到 serachphp break case del 刪除 $sql = DELETE FROM address WHERE id=$id

57

mysql_query($sql) 執行 SQL指令 mysql_close($link) header(Location searchphp) 轉向到 serachphp break case edit 編輯 $sql = SELECT FROM address WHERE id=$id $result = mysql_query($sql) 執行 SQL指令 $row = mysql_fetch_row($result) 取回記錄 $name = $row[1] 取得欄位 name $tel = $row[2] 取得欄位 tel mysql_close($link) 顯示編輯表單 gt ltcentergtlth2gt更新通訊錄lth2gtltcentergtlthrgt ltform action=editphpaction=updateampid=lt echo $id gt method=postgt lttable border=0 width=300gt lttrgtlttdgt姓名 lttdgt lttdgtltinput type=text name=Name size=20 maxlength=10 value=lt echo $name gtgtlttdgtlttrgt lttrgtlttdgt電話 lttdgt lttdgtltinput type=text name=Tel size=20 maxlength=20 value=lt echo $tel gtgtlttdgtlttrgt lttrgtlttd colspan=2 align=centergt ltinput type=submit value=更新連絡人gtlttdgtlttrgt lttablegt ltformgt ltbrgtlta href=indexhtmlgt通訊錄ltagt | lta href=addphpgt新增連絡人ltagt | lta href=searchphpgt搜尋通訊錄ltagt lt break gt ltbodygt lthtmlgt

58

52 任務二Web Base群組軟體 ( twig )

順利完成Web Base客戶通訊錄程式測試一段時間後「Apache + MySQL + PHP」架構的穩定與快速巳深得老闆與公司所有同事的認同隨著公司業績蒸

蒸日上人員組織編罝愈來愈龐大跨部門的會議愈來愈多業務員每日排滿拜

訪客戶的行程跟客戶的 Email的往來也愈來愈頻繁 愈來愈多部門的同事希望公司能建置一套群組軟體提供 web mail可讓業

務人員方便收發 mail還有連絡人議事日程待辦工作書簽等功能讓整個

公司運作及個人時間管理更有效率

老闆問小明對這些需求有什麼看法小明認為如果這些功能完全由程式部

門開發必定曠日費時而且耗費公司資源小明在網路尋找是否有提供這些功能

的Free Software皇天不負苦心人小明發現了TWIG (The Web Information Gateway) httptwigscrewdrivernet這個群組軟體它在 Web 上整合郵件新聞聯絡人議事日程工作序書簽等功能非常符合公司的需求 Step 1 下載 twig-277targz 下載網址 httptwigscrewdrivernetdownloadphp3

Step 2 解開 twig-277targz tar -xzvf twig-277targz

59

Step 3 執行安裝動作安裝到 varwwwhtmltwig 目錄 cd twig-277 twig-install varwwwhtmltwig

Step 4 建立 MySQL 資料庫(twig)及各資料表

cd setup mysql -u root -p1234 mysqlgt create database twig Query OK 1 row affected (001 sec) mysqlgt quit mysql -u root ndashp1234 twiglt twigtablemysql

Step 5 修改 configincphp3 參數設定 vi varwwwhtmltwigconfigconfigincphp3 $config[fromdomain] = opencom 網域 $config[language] = chinesebig5 中文訊息 $config[imap_port] = 143notls

60

Step 6 修改連結 MySQL 的帳號密碼 vi varwwwhtmltwigconfigdbconfigincphp3 $dbconfig[sqlusername] = root username $dbconfig[sqlpassword] = 1234 password

Step 7 其他設定檔

vi etchttpdconfhttpdconf 加入 AddType applicationx-httpd-php php3 在 DirectoryIndex最後加入 indexphp3 DirectoryIndex indexhtml indexhtmlvar indexphp3 在 AddDefaultCharset ISO-8859-1加上 AddDefaultCharset ISO-8859-1

vi etcphpini register_globals = On service httpd restart Step 8 sendmail 設定 vi etcmailsendmailcf在 264 行前面加上並重新啟動 sendmail「service snedmail restart」 262 SMTP daemon options 263 264 O DaemonPortOptions=Port=smtpAddr=127001 Name=MTA 265 266 SMTP client options 267 O ClientPortOptions=Family=inet Address=00

61

Step 9 檢查設定有無錯誤 http主機名稱twigtestphp3

62

Step 10 登入 twig ( http主機名稱twig)

63

第六章 維護及更新程序

61 日常維護

系統管理員最好定期以 root 身份登入看看信件在 RedHat Linux 中有一支 logwatch 程式會定時去分析 log file如果發現異常便會發信給 root除此之外筆者建議讀者平時就檢查 MySQL log file ( varlogmysqldlog)是否有異常情形

62 更新程序

讀者可至httprpmfindnet 尋找MySQL相關套件至於升級的相關步驟請參

考Linux OS SOP 第 54節

63 備份重要檔案

預設 MySQL 的 DB 檔案是存在 varlibmysql 內以 DB名稱為目錄目錄

內就是該 DB 的所有資料通常得定期備份還有 MySQL的設定檔 etcmycnf也別忘了一起備份

64 離線備份與還原

641 離線備份

預設 MySQL 的 DB 檔案是存在 varlibmysql 內以 DB 名稱為目錄目錄內

就是該 DB 的所有資料像 CRM 這個 DB就是存在 varlibmysqlCRM 內在備份前因為怕資料尚未完全寫入磁碟而且 MySQL 會 Lock 在使用的 DB 檔案所以應該是要先把 MySQL 先 Shutdown 一下整個備份的程序可以下像下面的指令去完成 cd varlibmysql

64

service mysqld stop tar cvfz CRM_db_20030905tgz CRM service mysqld start 對這樣就可以了 不過要注意的是怕 DB 內每個 Tables 間的資料有關關

聯性所以最好是把整個 DB 一次備起來單獨只備哪個 Tables 的檔案以後回存時怕會有資料關聯不一致的問題

642 離線還原

DB 發生錯誤而要回存時其實也不難先找出最近一次完整正常的備份先把現在錯誤的網頁或 DB 先更名或 tar 起來再把好的備份給解開回原來目錄位

置就行了需要注意的是 MySQL 服務最好也是要先停止回存完成後再啟動服務回存 DB 的整個程序可能像下面 cd varlibmysql service mysqldstop mv CRM CRM_OLD tar xvfz CRM_db_20030905tg service mysqld start

65 線上備份與還原

651 線上備份

使用像上面的檔案方式備份是個不錯的方法它最少可以保持該主機某個時間點的完整檔案備份但還是有一些問題需要考慮到有些主機就不只建立一個 DB 而已總不能為了備份某個 DB 而把整個 MySQL 服務停止備份檔案的方式回存在原主機上一定適用但假如 MySQL 版本升級或是在那天該網頁空間需遷機移機到別的主機時那就沒人敢保證備出來的資料檔可以用所以我們可以考慮另一種備份的方式是使用 MySQL 本身提供的功能 MySQL Data Dump指令是 mysqldump

65

使用 MySQL 的 Dump 功能可以把 DB 的結構資料或結構加資料 Dump 成文字檔 mysqldump 指令提供的彈性很大你可以選擇把整個 DB Dump 成一個檔或是每個 Table 為一個檔甚至是把結構檔和資料分開儲存都

可以 mysqladmin -uroot -p flush-logs mysqldump CRM -uroot -p --opt gt CRM_20030905sql (CRM 是 DB 名稱 opt 是一個使用完整 Dump 參數) 假如只是要單獨 Dump 某個 Table 時只要在上面的指令後轉出符號 gt 前加個 Table 名稱就可以如只要 phpbb2_users 這個 Table 的 Dump 時只要下 mysqldump CRM -uroot -p --opt CUSTOMER gt CRM_CUSTOMER_20030905sql

652 線上還原

若要回存整個資料庫只需將壓縮的備份檔還原成 Dump 的檔案再用下面的指令回存 mysql CRM -uroot -p lt CRM_20030905sql 這邊需注意的是若建立備份時是以--opt或--add-drop-table為參數時回存的 動作是先將舊的 Table 先刪除重建 Table 的結構後再把 Data 匯入所以回存後所有的資料會回到你當時備份那個時間點因此在回存資料時可以考慮把現有錯誤或不完整的 DB 先備份一份下來以備不時之需或是拿來比對錯誤的地

方在那裡當然你也可以把資料回存到另一個測試用的 DB 內只要把上面指令

的 DB 名稱改成你的測試用 DB 名稱即可 使用這種回存方式 MySQL 服務不需停止也不會動到其他正在使用的 DB 在一些提供 MySQL 服務的虛擬主機可用這種方式作你自己的 DB 備份及回存

66

另外假如你是系統重建或是移機時切需在新的 MySQL 內新建一個空白 DB 後才行作回存的工作你可以用下面的指令建立 mysql -uroot -p -e CREATE DATABASE CRM (上面的 CRM是你要新建的 DB 名稱) 另一種作法先用 mysql 指令進入 mysql client console 然後再用 CREATE DATABASE CRM 這樣就行了記得尾端要加個 符號該行指令才會執行

67

第七章 問題與解答

Q1RedHat 90預附的 MySQL到底有無支援 Transcation機制 Ans MySQL自 32334a之後的 MySQL-Max版本加入 InnoDB的資料庫類型透過

InnoDBMySQL同樣可以進行 COMMIT與 ROLLRACK的動作RedHat 90預附的 MySQL為 32354a-11巳支援 InnoDB的資料庫類型不過必須做以

下設定 1cp usrsharedocmysql-server-32354amy-mediumcnf to etcmycnf 2 vi etcmycnf 將以下設定前的拿掉 innodb_data_home_dir = varlibmysql innodb_data_file_path = ibdata110Mautoextend innodb_log_group_home_dir = varlibmysql innodb_log_arch_dir = varlibmysql 3service mysqld restart 如此一來各位在建立Table時便可指定Table Type為 innodb ( ex create table with type=innodb ) Q2如何解決 php+mysql 許功蓋等字變亂的問題 Ans 方法一 【確定 MySQL 預設的字元集】 1 打開 WinMySQLadmin 管理畫面(在視窗右下角狀態列紅綠燈圖示中按滑鼠

右鍵點選 Show me 選項) 2 點選管理畫面中 [Variables] 標籤選項其中 character_set變數就是您預設

字元集的變數其預設是 latin1 字元集(我們要將他改回 big5)而 chatacters_set 變數則是 MySQL 可以支援哪些字元集 【修改預設字元集變數 character_set 】 1 請點選管理畫面中 [myini Setup] 標籤選項設定 myini 2 按一下 [Pick-up and Edit myini values] 按鈕以便編輯目前的 myini 設定 3 在 [mysqld] 設定區塊底下新增一行 default-character-set = big5 變數設

68

定 4 新增一個 [client] 設定區塊並加入第三步驟的變數設定(游標往下移到空白處新增兩行 [client] 和 default-character-set=big5) 5 按一下畫面左下方 [Save Modification] 按鈕儲存設定 6 重新啟動 MySQL 或 Windows 方法二 Server端注意事項 phpini 中有關的設定為(預設值) Magic quotes for incoming GETPOSTCookie data magic_quotes_gpc = On Use Sybase-style magic quotes (escape with instead of ) magic_quotes_sybase = Off Client端注意事項 1中文資料送進 mysql 前請用 addslashes($str) 處理 2處理後送進 mysql 時請用 括起來並在參數後留一個空白如 $sql = UPDATE ezf_table set tablename=$tname tableend=$endtime table inguser=$tguser tableingid=$tguserid tableallnumber=$tnumber tableloca l=$tablelocal tableanyone=$tableopen tabletext=$ttext WHERE tableid=$t ableid tablename=$tname c 取出時請用 stripslashes($str) Q3MySQL root 密碼忘了該怎麼辦 Ans 1先停掉 mysql etcrcdinitdmysql stop 2以--skip-grant-table 的參數啟動 mysql safe_mysql --skip-grant-tableamp 3 更改 root 密碼 mysql mysql mysqlgt UPDATE user SET password=password(newpassword)

69

WHERE user=root mysqlgt FLUSH PRIVILEGES mysqlgt exit 4停掉 mysql再重跑 mysqladmin -uroot -p shutdown Enter password 輸入新設定的密碼 etcrcdinitdmysql start

Q4NULL值問題

Ans

NULL值的概念是造成 SQL的新手的混淆的普遍原因他們經常認為 NULL是和一個空字符串的一樣的東西不是這樣的例如下列語句是完全不同的

mysqlgt INSERT INTO my_table (phone) VALUES (NULL)

mysqlgt INSERT INTO my_table (phone) VALUES ()

兩個語句把值插入到 phone 列但是第一個插入一個 NULL值而第二個插入一個空字符串第一個的含義可以認為是ldquo電話號碼不知道而第二個則可意味

著ldquo她沒有電話

在 SQL中NULL值在于任何其他值甚至 NULL值比較時總是假的(FALSE)包含 NULL的一個表達式總是產生一個 NULL值除非在包含在表達式中的運算符和函數的文檔中指出在下列例子所有的列返回 NULL

mysqlgt SELECT NULL1+NULLCONCAT(InvisibleNULL)

如果你想要尋找值是 NULL的列你不能使用=NULL測試下列語句不返回任

何行因為對任何表達式expr = NULL是假的

mysqlgt SELECT FROM my_table WHERE phone = NULL

要想尋找 NULL值你必須使用 IS NULL測試下例顯示如何找出 NULL電話號碼和空的電話號碼

70

mysqlgt SELECT FROM my_table WHERE phone IS NULL mysqlgt SELECT FROM my_table WHERE phone =

在 MySQL中就像很多其他的 SQL服務器一樣你不能索引可以有 NULL值的列你必須聲明這樣的列為 NOT NULL而且你不能插入 NULL到索引的

列中

當用 LOAD DATA INFILE 讀取數據時空列用更新如果你想要在一個列中有

NULL值你應該在文本文件中使用N字面上的詞NULL也可以在某些情形下使用

當使用 ORDER BY時首先呈現 NULL值如果你用 DESC以降序排序NULL值最後顯示當使用 GROUP BY時所有的 NULL值被認為是相等的

為了有助于NULL的處理你能使用 IS NULL和 IS NOT NULL運算符和 IFNULL()函數

對某些列類型NULL值被特殊地處理如果你將 NULL插入表的第一個TIMESTAMP 列則插入當前的日期和時間如果你將 NULL插入一個AUTO_INCREMENT 列則插入順序中的下一個數字

Q5如何將圖片存放於 MySQL中

Ans

Step 1建立資料庫 test

Step 2 建立表格 binary_data

CREATE TABLE binary_data (

id INT(4) NOT NULL AUTO_INCREMENT PRIMARY KEY

description CHAR(50)

bin_data LONGBLOB

filename CHAR(50)

filesize CHAR(50)

filetype CHAR(50)

71

)

Step 3 利用 storephp 寫入圖片

storephp 程式碼

ltHTMLgt ltHEADgtltTITLEgtStore binary data into SQL DatabaseltTITLEgtltHEADgt ltBODYgt lt code that will be executed if the form has been submitted

if ($submit) mysql_connect(localhostrootYOUR_PASSWORD) mysql_select_db(test) $data=Base64_Encode(fread(fopen($form_data r) filesize($form_data))) $result=MYSQL_QUERY(INSERT INTO binary_data (descriptionbin_datafilenamefilesizefiletype) VALUES ($form_description$data$form_data_name$form_data_size$form_data_type)) $id= mysql_insert_id() print ltpgtThis file has the following Database ID ltbgt$idltbgt MYSQL_CLOSE() else else show the form to submit new data

gt

ltform method=post action=ltphp echo $PHP_SELF gt enctype=multipartform-datagt File Descriptionltbrgt ltinput type=text name=form_description size=40gt ltINPUT TYPE=hidden name=MAX_FILE_SIZE value=4000000gt ltbrgtFile to uploadstore in databaseltbrgt ltinput type=file name=form_data size=40gt ltpgtltinput type=submit name=submit value=submitgt ltformgt lt

72

gt ltBODYgt ltHTMLgt

Step 3 利用 storephp 取出圖片

getdataphp 程式碼

lt Syntax getdataphp3id=ltidgt if($id) you may have to modify login information for your database server MYSQL_CONNECT(localhostrootYOUR_PASSWORD) mysql_select_db(test) $query = select bin_datafiletype from binary_data where id=$id $result = MYSQL_QUERY($query) $data = Base64_Decode(MYSQL_RESULT($result0bin_data)) $type = MYSQL_RESULT($result0filetype) Header( Content-type $type) echo $data gt

Q6MySQL裝好之後啟動時或是執行 mysqladmin會出現如下訊息 Cant connect to local MYSQL Server through Socket varlibmysqlmysqlsock或是

Cant connect to local MYSQL Server through Socket tmpmysqldsock

Ans 可能有下列幾個原因

1這個 mysqldsock 不見了被某人刪除了或是被一些系統自動執行程式給刪

了例如有些 cron任務便會設定定期刪除 tmp 裡的東西所以呢您只能修改

cron 裡的設定讓它不要清除 mysqldsock 2在啟動時也可以改變 mysqldsock的位置您在啟動 MySQL的時候可以加入此參數usrlocalmysqlbinsafe_mysqld --user=mysql --socket=其他路

徑socket amp 同時得去設定環境變數 MYSQL_UNIX_PORT的值以指定新的

73

路徑 3若是您沒改 MYSQL_UNIX_PORT的值那麼您可以在執行指令的時候才打

例如mysqladmin --socket=其他路徑socket version Q7How to get the last insert id Ans CREATE TABLE product ( id INT(4) NOT NULL AUTO_INCREMENT PRIMARY KEY description VARCHAR(50) ) 1利用 SQL的話 mysqlgt insert into product(description) values(123) Query OK 1 row affected (000 sec) mysqlgt select last_insert_id() +------------------+ | last_insert_id() | +------------------+ +------------------+ 1 row in set (000 sec) ======================================== 2如果是 PHP的話 你可以用mysql_insert_id()取得該 id PHP example $result=MYSQL_QUERY(INSERT INTO product (description) VALUES ($description)) $id= mysql_insert_id() print This file has the following Database ID $id Q8如何將文字檔匯入資料庫 Ans $addr=homehttpdhtmlphpschool001txt $sql_select = load data infile $addr into table test fields terminated by t 解說 $sql_select = load data infile 文字檔名 into table 表格名 fields terminated by

74

t

(欄位分隔以 TAB鍵) 該文字檔須與資料表欄位格式相符 例如欄位有三個 則文字檔為每行一筆資料如下 欄 1資料ltTABgt欄 2資料ltTABgt欄 3資料 欄 1資料ltTABgt欄 2資料ltTABgt欄 3資料 欄 1資料ltTABgt欄 2資料ltTABgt欄 3資料 欄 1資料ltTABgtltTABgt欄 3資料

Q9如何撰寫 MySQL C API Ans Step 1利用文字編輯器撰寫以下程式碼 mysqlcc

include ltstdiohgt

include ltmysqlmysqlhgt

int main (int argc char argv[])

MYSQL mysql

MYSQL_RES res

MYSQL_ROW row

if (argc = 2)

fputs (Usage myc ltdatabasegt stderr)

return 1

if ((mysql_connect(ampmysqllocalhostrootYour_Password)))

fputs (Error connecting stderr)

abort()

75

if (mysql_select_db(ampmysqlargv[1]))

fputs (Error selecting database stderr)

abort()

if (mysql_query(ampmysqlSELECT FROM test_table))

fputs (Error processing query stderr)

abort()

if ((res = mysql_store_result(ampmysql)))

fputs (Error storing results stderr)

abort()

while((row = mysql_fetch_row(res)))

uint i = 0

for (i=0 i lt mysql_num_fields(res) i++)

printf(s row[i])

printf(n)

return 0

Step 2 Compile

gcc -Iusrlocalmysqlinclude -Lusrlocalmysqllibmysql mysqlcc ndashlm -lmysqlclient

(其中 include path與 library path取決於你的 MySQL安裝路徑)

76

如果執行時發生如下 error Run problemerror in loading shared libraries libmysqlclientsoX 將你的 MySQL library path(for exampleusrlocalmysqllibmysql) 加入etcldsoconf and run sbinldconfig -v Q9ASP + MySQL 範例程式 Ans Dim myconn As New ADODBConnection Dim myrs As New Recordset Dim mySQL As String Dim myrows As Long myconnOpen DSN=MyODBCsample mySQL = SELECT from user myrsSource = mySQL Set myrsActiveConnection = myconn myrsCursorLocation = adUseClient myrsOpen myrows = myrsRecordCount myrsClose myconnClose 可參考 httpwwwdwamnetmysqlasp_myodbcasp 有詳細的資料 Q10如何將 MySQL中的資料庫匯出成txt檔 Ans select from TableName into outfile textxls all result fields will seperate by tab

77

第八章 參考資料

英文部份 網址 1 httpwwwmysqlcom MySQL 網站有第一手有關 MySQL的資料 2 httpwwwmysqlcomdocenReplicationhtml 有關 MySQL Replication 的文件 3 httpwwwgeocitiescomsqlhomefaqstore_blobhtml 如何在 MySQL 存放 BLOB的資料 4httpwwwsapdborg 有關 SAP跟 MySQL相關合作的網站 書藉 1 Cooking with MySQL

Paul DuBois has selected sample recipes from the hundreds youll find in his book MySQL

Cookbook In this third and final series of excerpts showcasing these recipes learn how to

compute team standings how to calculate the differences between successive Dec 26

2002 2 Tips for Building Web Database Applications with PHP and MySQL by Hugh E Williams co-author of Web Database Applications with PHP amp MySQL 04042002

3 Managing and Using MySQL 2nd Edition By Tim King George Reese Randy Jay Yarger

4 MySQL Cookbook By Paul DuBoisPublisher OReillyPub Date October 2002

中文部份

78

1 httplinuxtncedutwtechdocmysqlmysql_docmanual_tochtml MySQL 中文手冊 2 httpchenshloxaedutwphpZ_1php PHP+MySQ程式研習設計網站 3 httplinuxtncedutwtechdocbanicdownhtml PHP 4 手冊 4 httpwwwtncedutwadmin_zonephp台南縣教育網網路中心有很多 Linux相關文件 5 httpdobtncedutw網站建置百寶箱有很多 PHP MySQL 相關範例程式 5 httpwwwdbworldcomtw資料庫專家電子雜誌介紹資料庫的重要觀念及名詞

79

附錄一 SQL Command 介紹

SQL (讀音ess-que-el) 是一種結構查詢語法SQL 使用於資料庫交流

傳遞相容於 ANSI (American National Standards Institute) 是一套標準的關聯

式資料庫語言 SQL 語言是執行更新或從資料系統獲取資料一般常見的關聯

資料庫系統都有提供 SQL 如 Oracle Sybase Microsoft SQL Server Access Ingres 等雖然大部份的資料庫都有提供 SQL 但也多提供了自已獨特的語

法造成了不相容的情形但標準基本的語法是相通的如Select Insert Update Delete Create and Drop 每一個系統都有支援

Table相關 Command

Create Table

關聯式資料庫包含有很多元件稱為資料表(tables) 把資料或訊息放在資

料表中 資料表是以不同的名稱做分別資料表由欄列所構成的二維陣列

欄包含欄位名資料型態 及其他可判斷的資訊列是由全部欄位構成一筆一

筆的紀錄 create table 語法用在建立一個新的資料表語法格式如下

create table tablename (column1 data type column2 data type column3 data type)

Format of create table if you were to use optional constraints

create table tablename (column1 data type [constraint] column2 data type [constraint] column3 data type [constraint]) [ ] = optional

Note You may have as many columns as youd like and the constraints are optional

80

Example

create table employee (first varchar(15) last varchar(20) age number(3) address varchar(30) city varchar(20) state varchar(20))

注意建立資料表格式要以括號把前後框住而最後以(分號)做結尾

欄位名不要超過 30個字元長而且不要使用 sql 的關鍵字(如 where select等)而在後面接是型態的宣告(如字串數字日期格式等)

資料型態是來描述欄位的方式如一個欄位Last_Name 是一個姓氏可以使用varchar (可變動長度字串) 資料型態

以下是幾個常見的資料庫型態 char(size) 固定長度字串最長為 255 位元 varchar(size) 變動長度字串最大字元數以 size 來指定 number(size) 數值格式可以是整數也可以是小數最大數字以 size 位數判

斷未指定小數位數由系統內定 date 日期格式 number(sized) 數值格式最大數字以 size 位數判斷d 為小數位數整數位

數為 size-d 位

有何限制當資料表被建立通常有一或數個欄位是要使用來做關聯的功

能 例如unique 限制(唯一值)兩筆記錄不可以相同的值 not null (非空值)該欄位一定要輸入資料不可是空的primary key (主鍵)是每一筆記錄識別的主要方式

Drop a table drop table 刪除資料表(其中的資料也會一併刪除)

drop table tablename

Example

81

drop table 和刪除全部資料是不同的刪除全部資料欄位名稱資訊等還會

存在但刪除資料表會把這一些也一併移除掉

如何查詢資料

Select 基本用法

select 語法是關連式資料庫最常用的部份可以取得你想要的資料這是一個

簡單的範例 select column1[column2etc] from tablename [where condition] [] = optional 在 select 之後所列欄位名則是要顯示的資料部份你可以一一列出各欄位

名或是以 (星號)來代表選擇全部的欄位 from 之後放資料表名稱 where 子句 (選項) 指定要過濾的條件符合者才會顯現 where 可使用的條件運算元 = 等於 gt 大於 lt 小於 gt= 大或等於 lt= 小或等於 ltgt 大相等 LIKE 相似 For example select first last city

82

from empinfo where first LIKE Er 以Er 為開頭的字串就符合要以單引號框住 Or you can specify select first last from empinfo where last LIKE s 最後一字為 S 就符合 select from empinfo where first = Eric 則表示 first name 一定要是 Eric 才可以 範例資料表empinfo 統計函數

MIN 傳回指定欄位最小值

MAX 傳回指定欄位最大值

SUM 傳回指定欄位總和

AVG 傳回指定欄位平均值

COUNT 傳回指定欄位的筆數

COUNT() 傳回資料庫中的總筆數

統計函數使用於資料表中的數值欄位配合 SELECT 語法使用 只用於總結特定單一欄位可以配合 GROUP BY 做篩選但也可以不使用 GROUP BY 語句For example

SELECT AVG(salary) FROM employee

83

傳回全部 salary 平均值

Another example

SELECT AVG(salary) FROM employee WHERE title = Programmer

傳回 salary 平均值條件為 employees 資料表中當 title 等於 Programmer

Example

SELECT Count() FROM employees

傳回 employees 資料表中紀錄總筆數

GROUP BY 語法 SELECT column1 SUM(column2) FROM list-of-tables GROUP BY column-list The GROUP BY 語句可以先以所列的欄位為條件分組排序在一起(可以多欄

位) example 要列出每一個 dept 中最高 salary 值 SELECT max(salary) dept FROM employee GROUP BY dept HAVING 語法

SELECT column1 SUM(column2) FROM list-of-tables GROUP BY column-list HAVING condition

HAVING 子句是 GROUP BY 的一部份用來過濾在 GROUP BY 所選出的資料功能如同 select 命令中 where 條件式一樣只是 HAVING 必需配合 GROUP BY 使用

我們以例子來說明我們要取得每一公司名及每一公司的薪水平均值輸入如下

84

SELECT dept avg(salary) FROM employee GROUP BY dept

但如果我們只列出薪資平均值超過 20000元的公司資料

SELECT dept avg(salary) FROM employee GROUP BY dept HAVING avg(salary) gt 20000

ORDER BY子句語法

SELECT column1 SUM(column2) FROM list-of-tables ORDER BY column-list [ASC | DESC]

[ ] =選項

ORDER BY是一個選項子句當你以排序方式來顯示資料(正向由小到大反向由大到小)以指定的欄位資料做排序

ASC = 正向- 預設值 DESC = 反向排序

For example

SELECT employee_id dept name age salary FROM employee_info WHERE dept = Sales ORDER BY salary

以上列出公司代號公司名銷售員人名年紀及薪資而條件是公司名為 Sales 顯示順序以薪資多少排序(由小到大為預設值)

如果要以多個欄位做排序要以逗號做分隔如下

SELECT employee_id dept name age salary FROM employee_info WHERE dept = Sales ORDER BY salary age DESC

85

結合條件及布林運算 SELECT column1 SUM(column2) FROM list-of-tables WHERE condition1 AND condition2 AND運算可以結兩個或以上的條件放在 WHERE子句中 兩者都要為真才

會顯示該筆記錄 OR 運算可以結兩個或以上敘述放在 WHERE子句中只要其中一個為直就

會顯示該筆記錄 For example SELECT employeeid firstname lastname title salary FROM employee_info WHERE salary gt= 5000000 AND title = Programmer 必需要薪資大於等於 50000而且職稱為 Programmer同時符合才會顯示該筆資料 以下以括號括住雖然不是必需的但如此比較容易讀 SELECT employeeid firstname lastname title salary FROM employee_info WHERE (salary gt= 5000000) AND (title = Programmer) 另外範例 SELECT firstname lastname title salary FROM employee_info WHERE (title = Sales) OR (title = Programmer) 條件為只要是 Sales 或 Programmer 職稱的就會被列出 IN and BETWEEN 子句

SELECT column1 SUM(column2) FROM list-of-tables WHERE column3 IN (list-of-values) SELECT column1 SUM(column2) FROM list-of-tables WHERE column3 BETWEEN value1 AND value2 IN 子句使用在列舉項目的使用上也就是分別測試是否符合所列的值 For example

86

SELECT employeeid lastname salary FROM employee_info WHERE lastname IN (Hernandez Jones Roberts Ruiz) 條件為姓氏(astname)要符合 Hernandez Jones Roberts or Ruiz 其中一個才會被傳回 IN運算元也可以使用 OR 的語法來取代如下結果相同 SELECT employeeid lastname salary FROM employee_info WHERE lastname = Hernandez OR lastname = Jones OR lastname = Roberts OR lastname = Ruiz 但使用 IN 句子比較短也比較易懂 你也可以使用 NOT IN 來去掉不要的記錄 BETWEEN 運算元使用在判斷是否存在兩個數值之間 For example SELECT employeeid age lastname salary FROM employee_info WHERE age BETWEEN 30 AND 40 傳回年紀 30歲到 40歲之間的資料(含 30及 40歲者) 相同的也可以使用以下語法來達到相同的結果 SELECT employeeid age lastname salary FROM employee_info WHERE age gt= 30 AND age lt= 40 你也可使用 NOT BETWEEN 來濾掉中間值的資料 數學運算 標準 ANSI SQL-92 提供以下運算

87

+ 加

- 減

餘數

餘數為除法後剩整數這不在標準的 ANSI SQL 中但大部份的資料庫都會支

援這運算元以下列出有用的函數雖不在 ANSI SQL-92 提供但一般資料庫

也會支援他們

ABS(x) 傳回 x 絕對值

SIGN(x) returns the sign of input x as -1 0 or 1 (negative zero or positive respectively)

MOD(xy) 餘數 - returns the integer remainder of x divided by y (同 xy)

FLOOR(x) 傳回小或等於 x 的最大整數值

CEILING(x) or CEIL(x)

傳回大或等於 x 的最小整數值

POWER(xy) x的 y 次方

ROUND(x) 把 x 四捨五入為整數

ROUND(xd) 四捨五入取到小數 d 位

SQRT(x) x 開平方

For example SELECT round(salary) firstname FROM employee_info 傳回薪資取到整數位

如何新增資料

insert 加入一筆新紀錄到資料表中 insert into tablename (first_columnlast_column) values (first_valuelast_value) [] = optional Example insert into employee

88

(first last age address city state) values (Luke Duke 45 2130 Boars Nest Hazard Co Georgia) Note 字串要以單引號住如string 數字框住也無妨 insert into 後面接資料表名稱再接以括號括住的欄位名在 values 後括號分別對映各欄位的值 以上的例子新增了一筆名(first) 為 Luke而住所(state) 為 Georgia 的資料

如何刪除資料

delete 可以刪除單筆或多筆紀錄 delete from tablename where columnname OPERATOR value [and|or column OPERATOR value] [ ] = optional Examples delete from employee Note 如果你沒有指定 where 子句那麼全部的紀錄都會被刪除 delete from employee where lastname = May delete from employee where firstname = Mike or firstname = Eric delete from 接著資料表名 再接著是條件式判斷沒有條件式則全部紀錄會

被刪除

如何更新資料

update 用來更新你所指定的記錄要和 WHERE 配合小心使用 語法 update tablename set columnname = newvalue[nextcolumn = newvalue2] where columnname OPERATOR value [and|or column OPERATOR value] [] = optional Examples

89

update phone_book set area_code = 623 where prefix = 979 update phone_book set last_name = Smith prefix=555 suffix=9292 where last_name = Jones update employee set age = age+1 where first_name=Mary and last_name=Williams

90

附錄二Replication

測試環境

RedHat 90 + MySQL 32358 MySQL資料庫路徑 varlibmysql MySQL設定檔 etcmycnf Master IP 1921680100 Slave IP 1921680200 請至下列網址下載最新MySQL 32358套件並利用rpm ndashUvh 更新 httpupdatesredhatcom9enosi386

圖 最新 MySQL 套件

測試架構圖

91

1921680100

1921680200Master Server

erveSlave S r

圖 測試架構圖

測試步驟

Master server 部份 Step1 確認 MasterSlave機器上所裝的 MySQL版本能進行

replication( 32329 or higher ) Step2 在 Master MySQL上開放一個帳號給 Slave mysql ndashu root ndashp mysqlgtGRANT FILE ON TO repl1921680200 IDENTIFIED BY lsquoabc123rsquo mysqlgtq 上面是 Master開放一個帳號 repl密碼 abc123給 IP1921680200有檔案處理

的權限 Step3 shutdown MySQL on the Master mysqladmin ndashu root ndashp shutdown Step4 備份 Master所有資料庫 tar ndashcvf tmpmysql-snapshottar varlibmysql 注意tar的時候MySQL是要在 stop情況下 在mysql (wwwmysqlcom) 網站的FAQ有不用shutdown的方法

92

Step5 在 master機器上修改etcmycnf 在[mysqld]區段內加入參數 log-bin server-id=這邊設定 server-id=1 sql-bin-update-same binlog-do-db=CRM只針對 CRM資料庫做紀錄 Step6 Restart MySQL on the master service mysqld start 此時因為有加入 log-bin 參數因此開始有 index產生了在varlibmysql目錄下

有index檔案紀錄資料庫的異動 log Slave server 部份 Step1 在 slave設定etcmycnf 在[mysqld]區段加入 master-host= master-user= master-password= master-port= server-id= 這邊設定 master-host=1921680100 master-user=repl master-password=abc123 master-port=3306 server-id=2 master-connect-retry=60預設重試間隔 60秒 replicate-do-db=CRM告訴 slave只做 CRM資料庫的更新 log-slave-updates Step2 將 master上的 mysql-snapshottar copy到 slave上 用 ftp傳到 slave的tmp Step3 解壓縮 Master資料庫至 Slave Server上 cd varlib tar xvf tmpmysql-snapshottar chown ndashR mysqlmysql mysql

93

chmod ndashR 770 mysql (視情況) Step4 Restart MySQL on the slave server 這時在varlibmysql目錄會出現 masterinfo此檔案紀錄了 Master MySQL server的資訊

狀況測試

One-way replication

1921680100

1921680200Master Server

erveSlave S r

圖 One-way replication架構圖 Step1 Master跟 Slave網路及服務都正常情況下由 Master端異動資料後 到 Slave端瀏覽資料檢視是否有進行 replication Step2 模擬 Slave Server 當機 可用在於 slave真的當機或是 Slave 不一定需要一直跟 master connect將Slave MySQL server shutdown由 Master端異動資料到 slave端瀏覽此時Slave應該沒有被 replication 更新然後再將 Slave端 MySQL server start起來

預設 60秒後 Slave會嘗試跟 Master要求進行 replication再去 Slave端檢視是否有更新資料

94

Step3 模擬 Master當機因為是設定 One-way replication一旦 Master Server Slave端沒有 Master的 source可以 download Two-way replication 基於 Master當機狀況於是發展雙向 Replication即 1921680100 ( Host A ) 1921680200 ( Host B )都分別擔任 MasterSlave身分

1921680100

1921680200er

Server B MasterSlave Server

Server A MasterSlave Serv

圖 Two-way replication架構圖 以下是針對兩台 MySQL伺服器進行雙向 Replication Step1觀念同單向 replication只是改成 Master也有 Slave身分 Slave也有Master的身分先分別在 Server AServer B 都去 grant一個進行 replication的身分 [A]mysqlgtGRANT FILE ON TO repl1921680200 IDENTIFIED BY lsquoabc123rsquo [B]mysqlgt GRANT FILE ON TO repl1921680100 IDENTIFIED BY lsquoabc123rsquo Step2做完單向 replication後stop Server Aserver B MySQL service此時 AB資料是一樣的

95

修改etcmycnf設定 範例 Server A [mysqld] datadir=varlibmysql socket=varlibmysqlmysqlsock server-id=1 log-bin sql-bin-update-same binlog-do-db=CRM master-host=1921680200 master-user=repl master-password=abc123 log-slave-updates master-connect-retry=60 replicate-do-db=CRM Server B [mysqld] datadir=varlibmysql socket=varlibmysqlmysqlsock server-id=2 log-bin sql-bin-update-same binlog-do-db=CRM master-host=1921680100 master-user=repl master-password=abc123 log-slave-updates master-connect-retry=60 replicate-do-db=CRM 分別 start Server AServer B MySQL後此時雙方都是 MasterSlave身分一旦哪一方資料異動就會通知對方來 replication-若 replication失效則必須將Server AServer B的masterinfo及index00x 都砍掉然後分別 restart MySQL server進行測試檢視成果 實務上通常如果需要做Two-way replication通常會搭配Virtual Server使用

96

在前端架設一台Virtual Server不過此部份不在此份SOP討論範圍內有興趣

的讀者可參考 httpwwwlinuxvirtualserverorg 網站

1921680100 1921680200

Host A MasterSlave Server

Host B MasterSlave Server

Virtual Host

圖 Virtual Server + Two-way replication 架構圖

97

圖 High Availability Linux Virtual Server架構圖

98

  • COSA-SOP-03-006
  • 第一章 簡介
    • 11適用對象 (Audience)
    • 12 MySQL本身
    • 13 MySQL 40版跟50版重大的改進功能
    • 14 各家資料庫軟體比較
      • 第二章 前置需求
      • 第三章 安裝
        • 31 MySQL安裝
        • 32 phpMyAdmin安裝
        • 33 升級及注意事項
          • 第四章 MySQL管理
            • 41 Webmin 管理介面
            • 42 phpMyAdmin 的操作介面
            • 43管理指令介紹
              • 431 利用mysqladmin設定root的密碼
                  • 第五章 實用範例
                    • 51 任務一Web Base客戶通訊錄
                    • 52 任務二Web Base群組軟體 ( twig )
                      • 第六章 維護及更新程序
                        • 61 日常維護
                        • 62 更新程序
                        • 63 備份重要檔案
                        • 64 離線備份與還原
                        • 65 線上備份與還原
                          • 第七章 問題與解答
                          • 第八章 參考資料
                          • 附錄一 SQL Command 介紹
                          • 附錄二Replication
Page 58: DataBase Server Standard Operation Procedureebooks.lib.ntu.edu.tw/1_file/oss/63/93doc4-5.pdf · 業務的公司帶來了不少壓力,譬如微軟,甲骨文 ... 外的錢用在第三方的資料庫產品上,譬如就可以不用再購買甲骨文公司

mysql_query($sql) 執行 SQL指令 mysql_close($link) header(Location searchphp) 轉向到 serachphp break case edit 編輯 $sql = SELECT FROM address WHERE id=$id $result = mysql_query($sql) 執行 SQL指令 $row = mysql_fetch_row($result) 取回記錄 $name = $row[1] 取得欄位 name $tel = $row[2] 取得欄位 tel mysql_close($link) 顯示編輯表單 gt ltcentergtlth2gt更新通訊錄lth2gtltcentergtlthrgt ltform action=editphpaction=updateampid=lt echo $id gt method=postgt lttable border=0 width=300gt lttrgtlttdgt姓名 lttdgt lttdgtltinput type=text name=Name size=20 maxlength=10 value=lt echo $name gtgtlttdgtlttrgt lttrgtlttdgt電話 lttdgt lttdgtltinput type=text name=Tel size=20 maxlength=20 value=lt echo $tel gtgtlttdgtlttrgt lttrgtlttd colspan=2 align=centergt ltinput type=submit value=更新連絡人gtlttdgtlttrgt lttablegt ltformgt ltbrgtlta href=indexhtmlgt通訊錄ltagt | lta href=addphpgt新增連絡人ltagt | lta href=searchphpgt搜尋通訊錄ltagt lt break gt ltbodygt lthtmlgt

58

52 任務二Web Base群組軟體 ( twig )

順利完成Web Base客戶通訊錄程式測試一段時間後「Apache + MySQL + PHP」架構的穩定與快速巳深得老闆與公司所有同事的認同隨著公司業績蒸

蒸日上人員組織編罝愈來愈龐大跨部門的會議愈來愈多業務員每日排滿拜

訪客戶的行程跟客戶的 Email的往來也愈來愈頻繁 愈來愈多部門的同事希望公司能建置一套群組軟體提供 web mail可讓業

務人員方便收發 mail還有連絡人議事日程待辦工作書簽等功能讓整個

公司運作及個人時間管理更有效率

老闆問小明對這些需求有什麼看法小明認為如果這些功能完全由程式部

門開發必定曠日費時而且耗費公司資源小明在網路尋找是否有提供這些功能

的Free Software皇天不負苦心人小明發現了TWIG (The Web Information Gateway) httptwigscrewdrivernet這個群組軟體它在 Web 上整合郵件新聞聯絡人議事日程工作序書簽等功能非常符合公司的需求 Step 1 下載 twig-277targz 下載網址 httptwigscrewdrivernetdownloadphp3

Step 2 解開 twig-277targz tar -xzvf twig-277targz

59

Step 3 執行安裝動作安裝到 varwwwhtmltwig 目錄 cd twig-277 twig-install varwwwhtmltwig

Step 4 建立 MySQL 資料庫(twig)及各資料表

cd setup mysql -u root -p1234 mysqlgt create database twig Query OK 1 row affected (001 sec) mysqlgt quit mysql -u root ndashp1234 twiglt twigtablemysql

Step 5 修改 configincphp3 參數設定 vi varwwwhtmltwigconfigconfigincphp3 $config[fromdomain] = opencom 網域 $config[language] = chinesebig5 中文訊息 $config[imap_port] = 143notls

60

Step 6 修改連結 MySQL 的帳號密碼 vi varwwwhtmltwigconfigdbconfigincphp3 $dbconfig[sqlusername] = root username $dbconfig[sqlpassword] = 1234 password

Step 7 其他設定檔

vi etchttpdconfhttpdconf 加入 AddType applicationx-httpd-php php3 在 DirectoryIndex最後加入 indexphp3 DirectoryIndex indexhtml indexhtmlvar indexphp3 在 AddDefaultCharset ISO-8859-1加上 AddDefaultCharset ISO-8859-1

vi etcphpini register_globals = On service httpd restart Step 8 sendmail 設定 vi etcmailsendmailcf在 264 行前面加上並重新啟動 sendmail「service snedmail restart」 262 SMTP daemon options 263 264 O DaemonPortOptions=Port=smtpAddr=127001 Name=MTA 265 266 SMTP client options 267 O ClientPortOptions=Family=inet Address=00

61

Step 9 檢查設定有無錯誤 http主機名稱twigtestphp3

62

Step 10 登入 twig ( http主機名稱twig)

63

第六章 維護及更新程序

61 日常維護

系統管理員最好定期以 root 身份登入看看信件在 RedHat Linux 中有一支 logwatch 程式會定時去分析 log file如果發現異常便會發信給 root除此之外筆者建議讀者平時就檢查 MySQL log file ( varlogmysqldlog)是否有異常情形

62 更新程序

讀者可至httprpmfindnet 尋找MySQL相關套件至於升級的相關步驟請參

考Linux OS SOP 第 54節

63 備份重要檔案

預設 MySQL 的 DB 檔案是存在 varlibmysql 內以 DB名稱為目錄目錄

內就是該 DB 的所有資料通常得定期備份還有 MySQL的設定檔 etcmycnf也別忘了一起備份

64 離線備份與還原

641 離線備份

預設 MySQL 的 DB 檔案是存在 varlibmysql 內以 DB 名稱為目錄目錄內

就是該 DB 的所有資料像 CRM 這個 DB就是存在 varlibmysqlCRM 內在備份前因為怕資料尚未完全寫入磁碟而且 MySQL 會 Lock 在使用的 DB 檔案所以應該是要先把 MySQL 先 Shutdown 一下整個備份的程序可以下像下面的指令去完成 cd varlibmysql

64

service mysqld stop tar cvfz CRM_db_20030905tgz CRM service mysqld start 對這樣就可以了 不過要注意的是怕 DB 內每個 Tables 間的資料有關關

聯性所以最好是把整個 DB 一次備起來單獨只備哪個 Tables 的檔案以後回存時怕會有資料關聯不一致的問題

642 離線還原

DB 發生錯誤而要回存時其實也不難先找出最近一次完整正常的備份先把現在錯誤的網頁或 DB 先更名或 tar 起來再把好的備份給解開回原來目錄位

置就行了需要注意的是 MySQL 服務最好也是要先停止回存完成後再啟動服務回存 DB 的整個程序可能像下面 cd varlibmysql service mysqldstop mv CRM CRM_OLD tar xvfz CRM_db_20030905tg service mysqld start

65 線上備份與還原

651 線上備份

使用像上面的檔案方式備份是個不錯的方法它最少可以保持該主機某個時間點的完整檔案備份但還是有一些問題需要考慮到有些主機就不只建立一個 DB 而已總不能為了備份某個 DB 而把整個 MySQL 服務停止備份檔案的方式回存在原主機上一定適用但假如 MySQL 版本升級或是在那天該網頁空間需遷機移機到別的主機時那就沒人敢保證備出來的資料檔可以用所以我們可以考慮另一種備份的方式是使用 MySQL 本身提供的功能 MySQL Data Dump指令是 mysqldump

65

使用 MySQL 的 Dump 功能可以把 DB 的結構資料或結構加資料 Dump 成文字檔 mysqldump 指令提供的彈性很大你可以選擇把整個 DB Dump 成一個檔或是每個 Table 為一個檔甚至是把結構檔和資料分開儲存都

可以 mysqladmin -uroot -p flush-logs mysqldump CRM -uroot -p --opt gt CRM_20030905sql (CRM 是 DB 名稱 opt 是一個使用完整 Dump 參數) 假如只是要單獨 Dump 某個 Table 時只要在上面的指令後轉出符號 gt 前加個 Table 名稱就可以如只要 phpbb2_users 這個 Table 的 Dump 時只要下 mysqldump CRM -uroot -p --opt CUSTOMER gt CRM_CUSTOMER_20030905sql

652 線上還原

若要回存整個資料庫只需將壓縮的備份檔還原成 Dump 的檔案再用下面的指令回存 mysql CRM -uroot -p lt CRM_20030905sql 這邊需注意的是若建立備份時是以--opt或--add-drop-table為參數時回存的 動作是先將舊的 Table 先刪除重建 Table 的結構後再把 Data 匯入所以回存後所有的資料會回到你當時備份那個時間點因此在回存資料時可以考慮把現有錯誤或不完整的 DB 先備份一份下來以備不時之需或是拿來比對錯誤的地

方在那裡當然你也可以把資料回存到另一個測試用的 DB 內只要把上面指令

的 DB 名稱改成你的測試用 DB 名稱即可 使用這種回存方式 MySQL 服務不需停止也不會動到其他正在使用的 DB 在一些提供 MySQL 服務的虛擬主機可用這種方式作你自己的 DB 備份及回存

66

另外假如你是系統重建或是移機時切需在新的 MySQL 內新建一個空白 DB 後才行作回存的工作你可以用下面的指令建立 mysql -uroot -p -e CREATE DATABASE CRM (上面的 CRM是你要新建的 DB 名稱) 另一種作法先用 mysql 指令進入 mysql client console 然後再用 CREATE DATABASE CRM 這樣就行了記得尾端要加個 符號該行指令才會執行

67

第七章 問題與解答

Q1RedHat 90預附的 MySQL到底有無支援 Transcation機制 Ans MySQL自 32334a之後的 MySQL-Max版本加入 InnoDB的資料庫類型透過

InnoDBMySQL同樣可以進行 COMMIT與 ROLLRACK的動作RedHat 90預附的 MySQL為 32354a-11巳支援 InnoDB的資料庫類型不過必須做以

下設定 1cp usrsharedocmysql-server-32354amy-mediumcnf to etcmycnf 2 vi etcmycnf 將以下設定前的拿掉 innodb_data_home_dir = varlibmysql innodb_data_file_path = ibdata110Mautoextend innodb_log_group_home_dir = varlibmysql innodb_log_arch_dir = varlibmysql 3service mysqld restart 如此一來各位在建立Table時便可指定Table Type為 innodb ( ex create table with type=innodb ) Q2如何解決 php+mysql 許功蓋等字變亂的問題 Ans 方法一 【確定 MySQL 預設的字元集】 1 打開 WinMySQLadmin 管理畫面(在視窗右下角狀態列紅綠燈圖示中按滑鼠

右鍵點選 Show me 選項) 2 點選管理畫面中 [Variables] 標籤選項其中 character_set變數就是您預設

字元集的變數其預設是 latin1 字元集(我們要將他改回 big5)而 chatacters_set 變數則是 MySQL 可以支援哪些字元集 【修改預設字元集變數 character_set 】 1 請點選管理畫面中 [myini Setup] 標籤選項設定 myini 2 按一下 [Pick-up and Edit myini values] 按鈕以便編輯目前的 myini 設定 3 在 [mysqld] 設定區塊底下新增一行 default-character-set = big5 變數設

68

定 4 新增一個 [client] 設定區塊並加入第三步驟的變數設定(游標往下移到空白處新增兩行 [client] 和 default-character-set=big5) 5 按一下畫面左下方 [Save Modification] 按鈕儲存設定 6 重新啟動 MySQL 或 Windows 方法二 Server端注意事項 phpini 中有關的設定為(預設值) Magic quotes for incoming GETPOSTCookie data magic_quotes_gpc = On Use Sybase-style magic quotes (escape with instead of ) magic_quotes_sybase = Off Client端注意事項 1中文資料送進 mysql 前請用 addslashes($str) 處理 2處理後送進 mysql 時請用 括起來並在參數後留一個空白如 $sql = UPDATE ezf_table set tablename=$tname tableend=$endtime table inguser=$tguser tableingid=$tguserid tableallnumber=$tnumber tableloca l=$tablelocal tableanyone=$tableopen tabletext=$ttext WHERE tableid=$t ableid tablename=$tname c 取出時請用 stripslashes($str) Q3MySQL root 密碼忘了該怎麼辦 Ans 1先停掉 mysql etcrcdinitdmysql stop 2以--skip-grant-table 的參數啟動 mysql safe_mysql --skip-grant-tableamp 3 更改 root 密碼 mysql mysql mysqlgt UPDATE user SET password=password(newpassword)

69

WHERE user=root mysqlgt FLUSH PRIVILEGES mysqlgt exit 4停掉 mysql再重跑 mysqladmin -uroot -p shutdown Enter password 輸入新設定的密碼 etcrcdinitdmysql start

Q4NULL值問題

Ans

NULL值的概念是造成 SQL的新手的混淆的普遍原因他們經常認為 NULL是和一個空字符串的一樣的東西不是這樣的例如下列語句是完全不同的

mysqlgt INSERT INTO my_table (phone) VALUES (NULL)

mysqlgt INSERT INTO my_table (phone) VALUES ()

兩個語句把值插入到 phone 列但是第一個插入一個 NULL值而第二個插入一個空字符串第一個的含義可以認為是ldquo電話號碼不知道而第二個則可意味

著ldquo她沒有電話

在 SQL中NULL值在于任何其他值甚至 NULL值比較時總是假的(FALSE)包含 NULL的一個表達式總是產生一個 NULL值除非在包含在表達式中的運算符和函數的文檔中指出在下列例子所有的列返回 NULL

mysqlgt SELECT NULL1+NULLCONCAT(InvisibleNULL)

如果你想要尋找值是 NULL的列你不能使用=NULL測試下列語句不返回任

何行因為對任何表達式expr = NULL是假的

mysqlgt SELECT FROM my_table WHERE phone = NULL

要想尋找 NULL值你必須使用 IS NULL測試下例顯示如何找出 NULL電話號碼和空的電話號碼

70

mysqlgt SELECT FROM my_table WHERE phone IS NULL mysqlgt SELECT FROM my_table WHERE phone =

在 MySQL中就像很多其他的 SQL服務器一樣你不能索引可以有 NULL值的列你必須聲明這樣的列為 NOT NULL而且你不能插入 NULL到索引的

列中

當用 LOAD DATA INFILE 讀取數據時空列用更新如果你想要在一個列中有

NULL值你應該在文本文件中使用N字面上的詞NULL也可以在某些情形下使用

當使用 ORDER BY時首先呈現 NULL值如果你用 DESC以降序排序NULL值最後顯示當使用 GROUP BY時所有的 NULL值被認為是相等的

為了有助于NULL的處理你能使用 IS NULL和 IS NOT NULL運算符和 IFNULL()函數

對某些列類型NULL值被特殊地處理如果你將 NULL插入表的第一個TIMESTAMP 列則插入當前的日期和時間如果你將 NULL插入一個AUTO_INCREMENT 列則插入順序中的下一個數字

Q5如何將圖片存放於 MySQL中

Ans

Step 1建立資料庫 test

Step 2 建立表格 binary_data

CREATE TABLE binary_data (

id INT(4) NOT NULL AUTO_INCREMENT PRIMARY KEY

description CHAR(50)

bin_data LONGBLOB

filename CHAR(50)

filesize CHAR(50)

filetype CHAR(50)

71

)

Step 3 利用 storephp 寫入圖片

storephp 程式碼

ltHTMLgt ltHEADgtltTITLEgtStore binary data into SQL DatabaseltTITLEgtltHEADgt ltBODYgt lt code that will be executed if the form has been submitted

if ($submit) mysql_connect(localhostrootYOUR_PASSWORD) mysql_select_db(test) $data=Base64_Encode(fread(fopen($form_data r) filesize($form_data))) $result=MYSQL_QUERY(INSERT INTO binary_data (descriptionbin_datafilenamefilesizefiletype) VALUES ($form_description$data$form_data_name$form_data_size$form_data_type)) $id= mysql_insert_id() print ltpgtThis file has the following Database ID ltbgt$idltbgt MYSQL_CLOSE() else else show the form to submit new data

gt

ltform method=post action=ltphp echo $PHP_SELF gt enctype=multipartform-datagt File Descriptionltbrgt ltinput type=text name=form_description size=40gt ltINPUT TYPE=hidden name=MAX_FILE_SIZE value=4000000gt ltbrgtFile to uploadstore in databaseltbrgt ltinput type=file name=form_data size=40gt ltpgtltinput type=submit name=submit value=submitgt ltformgt lt

72

gt ltBODYgt ltHTMLgt

Step 3 利用 storephp 取出圖片

getdataphp 程式碼

lt Syntax getdataphp3id=ltidgt if($id) you may have to modify login information for your database server MYSQL_CONNECT(localhostrootYOUR_PASSWORD) mysql_select_db(test) $query = select bin_datafiletype from binary_data where id=$id $result = MYSQL_QUERY($query) $data = Base64_Decode(MYSQL_RESULT($result0bin_data)) $type = MYSQL_RESULT($result0filetype) Header( Content-type $type) echo $data gt

Q6MySQL裝好之後啟動時或是執行 mysqladmin會出現如下訊息 Cant connect to local MYSQL Server through Socket varlibmysqlmysqlsock或是

Cant connect to local MYSQL Server through Socket tmpmysqldsock

Ans 可能有下列幾個原因

1這個 mysqldsock 不見了被某人刪除了或是被一些系統自動執行程式給刪

了例如有些 cron任務便會設定定期刪除 tmp 裡的東西所以呢您只能修改

cron 裡的設定讓它不要清除 mysqldsock 2在啟動時也可以改變 mysqldsock的位置您在啟動 MySQL的時候可以加入此參數usrlocalmysqlbinsafe_mysqld --user=mysql --socket=其他路

徑socket amp 同時得去設定環境變數 MYSQL_UNIX_PORT的值以指定新的

73

路徑 3若是您沒改 MYSQL_UNIX_PORT的值那麼您可以在執行指令的時候才打

例如mysqladmin --socket=其他路徑socket version Q7How to get the last insert id Ans CREATE TABLE product ( id INT(4) NOT NULL AUTO_INCREMENT PRIMARY KEY description VARCHAR(50) ) 1利用 SQL的話 mysqlgt insert into product(description) values(123) Query OK 1 row affected (000 sec) mysqlgt select last_insert_id() +------------------+ | last_insert_id() | +------------------+ +------------------+ 1 row in set (000 sec) ======================================== 2如果是 PHP的話 你可以用mysql_insert_id()取得該 id PHP example $result=MYSQL_QUERY(INSERT INTO product (description) VALUES ($description)) $id= mysql_insert_id() print This file has the following Database ID $id Q8如何將文字檔匯入資料庫 Ans $addr=homehttpdhtmlphpschool001txt $sql_select = load data infile $addr into table test fields terminated by t 解說 $sql_select = load data infile 文字檔名 into table 表格名 fields terminated by

74

t

(欄位分隔以 TAB鍵) 該文字檔須與資料表欄位格式相符 例如欄位有三個 則文字檔為每行一筆資料如下 欄 1資料ltTABgt欄 2資料ltTABgt欄 3資料 欄 1資料ltTABgt欄 2資料ltTABgt欄 3資料 欄 1資料ltTABgt欄 2資料ltTABgt欄 3資料 欄 1資料ltTABgtltTABgt欄 3資料

Q9如何撰寫 MySQL C API Ans Step 1利用文字編輯器撰寫以下程式碼 mysqlcc

include ltstdiohgt

include ltmysqlmysqlhgt

int main (int argc char argv[])

MYSQL mysql

MYSQL_RES res

MYSQL_ROW row

if (argc = 2)

fputs (Usage myc ltdatabasegt stderr)

return 1

if ((mysql_connect(ampmysqllocalhostrootYour_Password)))

fputs (Error connecting stderr)

abort()

75

if (mysql_select_db(ampmysqlargv[1]))

fputs (Error selecting database stderr)

abort()

if (mysql_query(ampmysqlSELECT FROM test_table))

fputs (Error processing query stderr)

abort()

if ((res = mysql_store_result(ampmysql)))

fputs (Error storing results stderr)

abort()

while((row = mysql_fetch_row(res)))

uint i = 0

for (i=0 i lt mysql_num_fields(res) i++)

printf(s row[i])

printf(n)

return 0

Step 2 Compile

gcc -Iusrlocalmysqlinclude -Lusrlocalmysqllibmysql mysqlcc ndashlm -lmysqlclient

(其中 include path與 library path取決於你的 MySQL安裝路徑)

76

如果執行時發生如下 error Run problemerror in loading shared libraries libmysqlclientsoX 將你的 MySQL library path(for exampleusrlocalmysqllibmysql) 加入etcldsoconf and run sbinldconfig -v Q9ASP + MySQL 範例程式 Ans Dim myconn As New ADODBConnection Dim myrs As New Recordset Dim mySQL As String Dim myrows As Long myconnOpen DSN=MyODBCsample mySQL = SELECT from user myrsSource = mySQL Set myrsActiveConnection = myconn myrsCursorLocation = adUseClient myrsOpen myrows = myrsRecordCount myrsClose myconnClose 可參考 httpwwwdwamnetmysqlasp_myodbcasp 有詳細的資料 Q10如何將 MySQL中的資料庫匯出成txt檔 Ans select from TableName into outfile textxls all result fields will seperate by tab

77

第八章 參考資料

英文部份 網址 1 httpwwwmysqlcom MySQL 網站有第一手有關 MySQL的資料 2 httpwwwmysqlcomdocenReplicationhtml 有關 MySQL Replication 的文件 3 httpwwwgeocitiescomsqlhomefaqstore_blobhtml 如何在 MySQL 存放 BLOB的資料 4httpwwwsapdborg 有關 SAP跟 MySQL相關合作的網站 書藉 1 Cooking with MySQL

Paul DuBois has selected sample recipes from the hundreds youll find in his book MySQL

Cookbook In this third and final series of excerpts showcasing these recipes learn how to

compute team standings how to calculate the differences between successive Dec 26

2002 2 Tips for Building Web Database Applications with PHP and MySQL by Hugh E Williams co-author of Web Database Applications with PHP amp MySQL 04042002

3 Managing and Using MySQL 2nd Edition By Tim King George Reese Randy Jay Yarger

4 MySQL Cookbook By Paul DuBoisPublisher OReillyPub Date October 2002

中文部份

78

1 httplinuxtncedutwtechdocmysqlmysql_docmanual_tochtml MySQL 中文手冊 2 httpchenshloxaedutwphpZ_1php PHP+MySQ程式研習設計網站 3 httplinuxtncedutwtechdocbanicdownhtml PHP 4 手冊 4 httpwwwtncedutwadmin_zonephp台南縣教育網網路中心有很多 Linux相關文件 5 httpdobtncedutw網站建置百寶箱有很多 PHP MySQL 相關範例程式 5 httpwwwdbworldcomtw資料庫專家電子雜誌介紹資料庫的重要觀念及名詞

79

附錄一 SQL Command 介紹

SQL (讀音ess-que-el) 是一種結構查詢語法SQL 使用於資料庫交流

傳遞相容於 ANSI (American National Standards Institute) 是一套標準的關聯

式資料庫語言 SQL 語言是執行更新或從資料系統獲取資料一般常見的關聯

資料庫系統都有提供 SQL 如 Oracle Sybase Microsoft SQL Server Access Ingres 等雖然大部份的資料庫都有提供 SQL 但也多提供了自已獨特的語

法造成了不相容的情形但標準基本的語法是相通的如Select Insert Update Delete Create and Drop 每一個系統都有支援

Table相關 Command

Create Table

關聯式資料庫包含有很多元件稱為資料表(tables) 把資料或訊息放在資

料表中 資料表是以不同的名稱做分別資料表由欄列所構成的二維陣列

欄包含欄位名資料型態 及其他可判斷的資訊列是由全部欄位構成一筆一

筆的紀錄 create table 語法用在建立一個新的資料表語法格式如下

create table tablename (column1 data type column2 data type column3 data type)

Format of create table if you were to use optional constraints

create table tablename (column1 data type [constraint] column2 data type [constraint] column3 data type [constraint]) [ ] = optional

Note You may have as many columns as youd like and the constraints are optional

80

Example

create table employee (first varchar(15) last varchar(20) age number(3) address varchar(30) city varchar(20) state varchar(20))

注意建立資料表格式要以括號把前後框住而最後以(分號)做結尾

欄位名不要超過 30個字元長而且不要使用 sql 的關鍵字(如 where select等)而在後面接是型態的宣告(如字串數字日期格式等)

資料型態是來描述欄位的方式如一個欄位Last_Name 是一個姓氏可以使用varchar (可變動長度字串) 資料型態

以下是幾個常見的資料庫型態 char(size) 固定長度字串最長為 255 位元 varchar(size) 變動長度字串最大字元數以 size 來指定 number(size) 數值格式可以是整數也可以是小數最大數字以 size 位數判

斷未指定小數位數由系統內定 date 日期格式 number(sized) 數值格式最大數字以 size 位數判斷d 為小數位數整數位

數為 size-d 位

有何限制當資料表被建立通常有一或數個欄位是要使用來做關聯的功

能 例如unique 限制(唯一值)兩筆記錄不可以相同的值 not null (非空值)該欄位一定要輸入資料不可是空的primary key (主鍵)是每一筆記錄識別的主要方式

Drop a table drop table 刪除資料表(其中的資料也會一併刪除)

drop table tablename

Example

81

drop table 和刪除全部資料是不同的刪除全部資料欄位名稱資訊等還會

存在但刪除資料表會把這一些也一併移除掉

如何查詢資料

Select 基本用法

select 語法是關連式資料庫最常用的部份可以取得你想要的資料這是一個

簡單的範例 select column1[column2etc] from tablename [where condition] [] = optional 在 select 之後所列欄位名則是要顯示的資料部份你可以一一列出各欄位

名或是以 (星號)來代表選擇全部的欄位 from 之後放資料表名稱 where 子句 (選項) 指定要過濾的條件符合者才會顯現 where 可使用的條件運算元 = 等於 gt 大於 lt 小於 gt= 大或等於 lt= 小或等於 ltgt 大相等 LIKE 相似 For example select first last city

82

from empinfo where first LIKE Er 以Er 為開頭的字串就符合要以單引號框住 Or you can specify select first last from empinfo where last LIKE s 最後一字為 S 就符合 select from empinfo where first = Eric 則表示 first name 一定要是 Eric 才可以 範例資料表empinfo 統計函數

MIN 傳回指定欄位最小值

MAX 傳回指定欄位最大值

SUM 傳回指定欄位總和

AVG 傳回指定欄位平均值

COUNT 傳回指定欄位的筆數

COUNT() 傳回資料庫中的總筆數

統計函數使用於資料表中的數值欄位配合 SELECT 語法使用 只用於總結特定單一欄位可以配合 GROUP BY 做篩選但也可以不使用 GROUP BY 語句For example

SELECT AVG(salary) FROM employee

83

傳回全部 salary 平均值

Another example

SELECT AVG(salary) FROM employee WHERE title = Programmer

傳回 salary 平均值條件為 employees 資料表中當 title 等於 Programmer

Example

SELECT Count() FROM employees

傳回 employees 資料表中紀錄總筆數

GROUP BY 語法 SELECT column1 SUM(column2) FROM list-of-tables GROUP BY column-list The GROUP BY 語句可以先以所列的欄位為條件分組排序在一起(可以多欄

位) example 要列出每一個 dept 中最高 salary 值 SELECT max(salary) dept FROM employee GROUP BY dept HAVING 語法

SELECT column1 SUM(column2) FROM list-of-tables GROUP BY column-list HAVING condition

HAVING 子句是 GROUP BY 的一部份用來過濾在 GROUP BY 所選出的資料功能如同 select 命令中 where 條件式一樣只是 HAVING 必需配合 GROUP BY 使用

我們以例子來說明我們要取得每一公司名及每一公司的薪水平均值輸入如下

84

SELECT dept avg(salary) FROM employee GROUP BY dept

但如果我們只列出薪資平均值超過 20000元的公司資料

SELECT dept avg(salary) FROM employee GROUP BY dept HAVING avg(salary) gt 20000

ORDER BY子句語法

SELECT column1 SUM(column2) FROM list-of-tables ORDER BY column-list [ASC | DESC]

[ ] =選項

ORDER BY是一個選項子句當你以排序方式來顯示資料(正向由小到大反向由大到小)以指定的欄位資料做排序

ASC = 正向- 預設值 DESC = 反向排序

For example

SELECT employee_id dept name age salary FROM employee_info WHERE dept = Sales ORDER BY salary

以上列出公司代號公司名銷售員人名年紀及薪資而條件是公司名為 Sales 顯示順序以薪資多少排序(由小到大為預設值)

如果要以多個欄位做排序要以逗號做分隔如下

SELECT employee_id dept name age salary FROM employee_info WHERE dept = Sales ORDER BY salary age DESC

85

結合條件及布林運算 SELECT column1 SUM(column2) FROM list-of-tables WHERE condition1 AND condition2 AND運算可以結兩個或以上的條件放在 WHERE子句中 兩者都要為真才

會顯示該筆記錄 OR 運算可以結兩個或以上敘述放在 WHERE子句中只要其中一個為直就

會顯示該筆記錄 For example SELECT employeeid firstname lastname title salary FROM employee_info WHERE salary gt= 5000000 AND title = Programmer 必需要薪資大於等於 50000而且職稱為 Programmer同時符合才會顯示該筆資料 以下以括號括住雖然不是必需的但如此比較容易讀 SELECT employeeid firstname lastname title salary FROM employee_info WHERE (salary gt= 5000000) AND (title = Programmer) 另外範例 SELECT firstname lastname title salary FROM employee_info WHERE (title = Sales) OR (title = Programmer) 條件為只要是 Sales 或 Programmer 職稱的就會被列出 IN and BETWEEN 子句

SELECT column1 SUM(column2) FROM list-of-tables WHERE column3 IN (list-of-values) SELECT column1 SUM(column2) FROM list-of-tables WHERE column3 BETWEEN value1 AND value2 IN 子句使用在列舉項目的使用上也就是分別測試是否符合所列的值 For example

86

SELECT employeeid lastname salary FROM employee_info WHERE lastname IN (Hernandez Jones Roberts Ruiz) 條件為姓氏(astname)要符合 Hernandez Jones Roberts or Ruiz 其中一個才會被傳回 IN運算元也可以使用 OR 的語法來取代如下結果相同 SELECT employeeid lastname salary FROM employee_info WHERE lastname = Hernandez OR lastname = Jones OR lastname = Roberts OR lastname = Ruiz 但使用 IN 句子比較短也比較易懂 你也可以使用 NOT IN 來去掉不要的記錄 BETWEEN 運算元使用在判斷是否存在兩個數值之間 For example SELECT employeeid age lastname salary FROM employee_info WHERE age BETWEEN 30 AND 40 傳回年紀 30歲到 40歲之間的資料(含 30及 40歲者) 相同的也可以使用以下語法來達到相同的結果 SELECT employeeid age lastname salary FROM employee_info WHERE age gt= 30 AND age lt= 40 你也可使用 NOT BETWEEN 來濾掉中間值的資料 數學運算 標準 ANSI SQL-92 提供以下運算

87

+ 加

- 減

餘數

餘數為除法後剩整數這不在標準的 ANSI SQL 中但大部份的資料庫都會支

援這運算元以下列出有用的函數雖不在 ANSI SQL-92 提供但一般資料庫

也會支援他們

ABS(x) 傳回 x 絕對值

SIGN(x) returns the sign of input x as -1 0 or 1 (negative zero or positive respectively)

MOD(xy) 餘數 - returns the integer remainder of x divided by y (同 xy)

FLOOR(x) 傳回小或等於 x 的最大整數值

CEILING(x) or CEIL(x)

傳回大或等於 x 的最小整數值

POWER(xy) x的 y 次方

ROUND(x) 把 x 四捨五入為整數

ROUND(xd) 四捨五入取到小數 d 位

SQRT(x) x 開平方

For example SELECT round(salary) firstname FROM employee_info 傳回薪資取到整數位

如何新增資料

insert 加入一筆新紀錄到資料表中 insert into tablename (first_columnlast_column) values (first_valuelast_value) [] = optional Example insert into employee

88

(first last age address city state) values (Luke Duke 45 2130 Boars Nest Hazard Co Georgia) Note 字串要以單引號住如string 數字框住也無妨 insert into 後面接資料表名稱再接以括號括住的欄位名在 values 後括號分別對映各欄位的值 以上的例子新增了一筆名(first) 為 Luke而住所(state) 為 Georgia 的資料

如何刪除資料

delete 可以刪除單筆或多筆紀錄 delete from tablename where columnname OPERATOR value [and|or column OPERATOR value] [ ] = optional Examples delete from employee Note 如果你沒有指定 where 子句那麼全部的紀錄都會被刪除 delete from employee where lastname = May delete from employee where firstname = Mike or firstname = Eric delete from 接著資料表名 再接著是條件式判斷沒有條件式則全部紀錄會

被刪除

如何更新資料

update 用來更新你所指定的記錄要和 WHERE 配合小心使用 語法 update tablename set columnname = newvalue[nextcolumn = newvalue2] where columnname OPERATOR value [and|or column OPERATOR value] [] = optional Examples

89

update phone_book set area_code = 623 where prefix = 979 update phone_book set last_name = Smith prefix=555 suffix=9292 where last_name = Jones update employee set age = age+1 where first_name=Mary and last_name=Williams

90

附錄二Replication

測試環境

RedHat 90 + MySQL 32358 MySQL資料庫路徑 varlibmysql MySQL設定檔 etcmycnf Master IP 1921680100 Slave IP 1921680200 請至下列網址下載最新MySQL 32358套件並利用rpm ndashUvh 更新 httpupdatesredhatcom9enosi386

圖 最新 MySQL 套件

測試架構圖

91

1921680100

1921680200Master Server

erveSlave S r

圖 測試架構圖

測試步驟

Master server 部份 Step1 確認 MasterSlave機器上所裝的 MySQL版本能進行

replication( 32329 or higher ) Step2 在 Master MySQL上開放一個帳號給 Slave mysql ndashu root ndashp mysqlgtGRANT FILE ON TO repl1921680200 IDENTIFIED BY lsquoabc123rsquo mysqlgtq 上面是 Master開放一個帳號 repl密碼 abc123給 IP1921680200有檔案處理

的權限 Step3 shutdown MySQL on the Master mysqladmin ndashu root ndashp shutdown Step4 備份 Master所有資料庫 tar ndashcvf tmpmysql-snapshottar varlibmysql 注意tar的時候MySQL是要在 stop情況下 在mysql (wwwmysqlcom) 網站的FAQ有不用shutdown的方法

92

Step5 在 master機器上修改etcmycnf 在[mysqld]區段內加入參數 log-bin server-id=這邊設定 server-id=1 sql-bin-update-same binlog-do-db=CRM只針對 CRM資料庫做紀錄 Step6 Restart MySQL on the master service mysqld start 此時因為有加入 log-bin 參數因此開始有 index產生了在varlibmysql目錄下

有index檔案紀錄資料庫的異動 log Slave server 部份 Step1 在 slave設定etcmycnf 在[mysqld]區段加入 master-host= master-user= master-password= master-port= server-id= 這邊設定 master-host=1921680100 master-user=repl master-password=abc123 master-port=3306 server-id=2 master-connect-retry=60預設重試間隔 60秒 replicate-do-db=CRM告訴 slave只做 CRM資料庫的更新 log-slave-updates Step2 將 master上的 mysql-snapshottar copy到 slave上 用 ftp傳到 slave的tmp Step3 解壓縮 Master資料庫至 Slave Server上 cd varlib tar xvf tmpmysql-snapshottar chown ndashR mysqlmysql mysql

93

chmod ndashR 770 mysql (視情況) Step4 Restart MySQL on the slave server 這時在varlibmysql目錄會出現 masterinfo此檔案紀錄了 Master MySQL server的資訊

狀況測試

One-way replication

1921680100

1921680200Master Server

erveSlave S r

圖 One-way replication架構圖 Step1 Master跟 Slave網路及服務都正常情況下由 Master端異動資料後 到 Slave端瀏覽資料檢視是否有進行 replication Step2 模擬 Slave Server 當機 可用在於 slave真的當機或是 Slave 不一定需要一直跟 master connect將Slave MySQL server shutdown由 Master端異動資料到 slave端瀏覽此時Slave應該沒有被 replication 更新然後再將 Slave端 MySQL server start起來

預設 60秒後 Slave會嘗試跟 Master要求進行 replication再去 Slave端檢視是否有更新資料

94

Step3 模擬 Master當機因為是設定 One-way replication一旦 Master Server Slave端沒有 Master的 source可以 download Two-way replication 基於 Master當機狀況於是發展雙向 Replication即 1921680100 ( Host A ) 1921680200 ( Host B )都分別擔任 MasterSlave身分

1921680100

1921680200er

Server B MasterSlave Server

Server A MasterSlave Serv

圖 Two-way replication架構圖 以下是針對兩台 MySQL伺服器進行雙向 Replication Step1觀念同單向 replication只是改成 Master也有 Slave身分 Slave也有Master的身分先分別在 Server AServer B 都去 grant一個進行 replication的身分 [A]mysqlgtGRANT FILE ON TO repl1921680200 IDENTIFIED BY lsquoabc123rsquo [B]mysqlgt GRANT FILE ON TO repl1921680100 IDENTIFIED BY lsquoabc123rsquo Step2做完單向 replication後stop Server Aserver B MySQL service此時 AB資料是一樣的

95

修改etcmycnf設定 範例 Server A [mysqld] datadir=varlibmysql socket=varlibmysqlmysqlsock server-id=1 log-bin sql-bin-update-same binlog-do-db=CRM master-host=1921680200 master-user=repl master-password=abc123 log-slave-updates master-connect-retry=60 replicate-do-db=CRM Server B [mysqld] datadir=varlibmysql socket=varlibmysqlmysqlsock server-id=2 log-bin sql-bin-update-same binlog-do-db=CRM master-host=1921680100 master-user=repl master-password=abc123 log-slave-updates master-connect-retry=60 replicate-do-db=CRM 分別 start Server AServer B MySQL後此時雙方都是 MasterSlave身分一旦哪一方資料異動就會通知對方來 replication-若 replication失效則必須將Server AServer B的masterinfo及index00x 都砍掉然後分別 restart MySQL server進行測試檢視成果 實務上通常如果需要做Two-way replication通常會搭配Virtual Server使用

96

在前端架設一台Virtual Server不過此部份不在此份SOP討論範圍內有興趣

的讀者可參考 httpwwwlinuxvirtualserverorg 網站

1921680100 1921680200

Host A MasterSlave Server

Host B MasterSlave Server

Virtual Host

圖 Virtual Server + Two-way replication 架構圖

97

圖 High Availability Linux Virtual Server架構圖

98

  • COSA-SOP-03-006
  • 第一章 簡介
    • 11適用對象 (Audience)
    • 12 MySQL本身
    • 13 MySQL 40版跟50版重大的改進功能
    • 14 各家資料庫軟體比較
      • 第二章 前置需求
      • 第三章 安裝
        • 31 MySQL安裝
        • 32 phpMyAdmin安裝
        • 33 升級及注意事項
          • 第四章 MySQL管理
            • 41 Webmin 管理介面
            • 42 phpMyAdmin 的操作介面
            • 43管理指令介紹
              • 431 利用mysqladmin設定root的密碼
                  • 第五章 實用範例
                    • 51 任務一Web Base客戶通訊錄
                    • 52 任務二Web Base群組軟體 ( twig )
                      • 第六章 維護及更新程序
                        • 61 日常維護
                        • 62 更新程序
                        • 63 備份重要檔案
                        • 64 離線備份與還原
                        • 65 線上備份與還原
                          • 第七章 問題與解答
                          • 第八章 參考資料
                          • 附錄一 SQL Command 介紹
                          • 附錄二Replication
Page 59: DataBase Server Standard Operation Procedureebooks.lib.ntu.edu.tw/1_file/oss/63/93doc4-5.pdf · 業務的公司帶來了不少壓力,譬如微軟,甲骨文 ... 外的錢用在第三方的資料庫產品上,譬如就可以不用再購買甲骨文公司

52 任務二Web Base群組軟體 ( twig )

順利完成Web Base客戶通訊錄程式測試一段時間後「Apache + MySQL + PHP」架構的穩定與快速巳深得老闆與公司所有同事的認同隨著公司業績蒸

蒸日上人員組織編罝愈來愈龐大跨部門的會議愈來愈多業務員每日排滿拜

訪客戶的行程跟客戶的 Email的往來也愈來愈頻繁 愈來愈多部門的同事希望公司能建置一套群組軟體提供 web mail可讓業

務人員方便收發 mail還有連絡人議事日程待辦工作書簽等功能讓整個

公司運作及個人時間管理更有效率

老闆問小明對這些需求有什麼看法小明認為如果這些功能完全由程式部

門開發必定曠日費時而且耗費公司資源小明在網路尋找是否有提供這些功能

的Free Software皇天不負苦心人小明發現了TWIG (The Web Information Gateway) httptwigscrewdrivernet這個群組軟體它在 Web 上整合郵件新聞聯絡人議事日程工作序書簽等功能非常符合公司的需求 Step 1 下載 twig-277targz 下載網址 httptwigscrewdrivernetdownloadphp3

Step 2 解開 twig-277targz tar -xzvf twig-277targz

59

Step 3 執行安裝動作安裝到 varwwwhtmltwig 目錄 cd twig-277 twig-install varwwwhtmltwig

Step 4 建立 MySQL 資料庫(twig)及各資料表

cd setup mysql -u root -p1234 mysqlgt create database twig Query OK 1 row affected (001 sec) mysqlgt quit mysql -u root ndashp1234 twiglt twigtablemysql

Step 5 修改 configincphp3 參數設定 vi varwwwhtmltwigconfigconfigincphp3 $config[fromdomain] = opencom 網域 $config[language] = chinesebig5 中文訊息 $config[imap_port] = 143notls

60

Step 6 修改連結 MySQL 的帳號密碼 vi varwwwhtmltwigconfigdbconfigincphp3 $dbconfig[sqlusername] = root username $dbconfig[sqlpassword] = 1234 password

Step 7 其他設定檔

vi etchttpdconfhttpdconf 加入 AddType applicationx-httpd-php php3 在 DirectoryIndex最後加入 indexphp3 DirectoryIndex indexhtml indexhtmlvar indexphp3 在 AddDefaultCharset ISO-8859-1加上 AddDefaultCharset ISO-8859-1

vi etcphpini register_globals = On service httpd restart Step 8 sendmail 設定 vi etcmailsendmailcf在 264 行前面加上並重新啟動 sendmail「service snedmail restart」 262 SMTP daemon options 263 264 O DaemonPortOptions=Port=smtpAddr=127001 Name=MTA 265 266 SMTP client options 267 O ClientPortOptions=Family=inet Address=00

61

Step 9 檢查設定有無錯誤 http主機名稱twigtestphp3

62

Step 10 登入 twig ( http主機名稱twig)

63

第六章 維護及更新程序

61 日常維護

系統管理員最好定期以 root 身份登入看看信件在 RedHat Linux 中有一支 logwatch 程式會定時去分析 log file如果發現異常便會發信給 root除此之外筆者建議讀者平時就檢查 MySQL log file ( varlogmysqldlog)是否有異常情形

62 更新程序

讀者可至httprpmfindnet 尋找MySQL相關套件至於升級的相關步驟請參

考Linux OS SOP 第 54節

63 備份重要檔案

預設 MySQL 的 DB 檔案是存在 varlibmysql 內以 DB名稱為目錄目錄

內就是該 DB 的所有資料通常得定期備份還有 MySQL的設定檔 etcmycnf也別忘了一起備份

64 離線備份與還原

641 離線備份

預設 MySQL 的 DB 檔案是存在 varlibmysql 內以 DB 名稱為目錄目錄內

就是該 DB 的所有資料像 CRM 這個 DB就是存在 varlibmysqlCRM 內在備份前因為怕資料尚未完全寫入磁碟而且 MySQL 會 Lock 在使用的 DB 檔案所以應該是要先把 MySQL 先 Shutdown 一下整個備份的程序可以下像下面的指令去完成 cd varlibmysql

64

service mysqld stop tar cvfz CRM_db_20030905tgz CRM service mysqld start 對這樣就可以了 不過要注意的是怕 DB 內每個 Tables 間的資料有關關

聯性所以最好是把整個 DB 一次備起來單獨只備哪個 Tables 的檔案以後回存時怕會有資料關聯不一致的問題

642 離線還原

DB 發生錯誤而要回存時其實也不難先找出最近一次完整正常的備份先把現在錯誤的網頁或 DB 先更名或 tar 起來再把好的備份給解開回原來目錄位

置就行了需要注意的是 MySQL 服務最好也是要先停止回存完成後再啟動服務回存 DB 的整個程序可能像下面 cd varlibmysql service mysqldstop mv CRM CRM_OLD tar xvfz CRM_db_20030905tg service mysqld start

65 線上備份與還原

651 線上備份

使用像上面的檔案方式備份是個不錯的方法它最少可以保持該主機某個時間點的完整檔案備份但還是有一些問題需要考慮到有些主機就不只建立一個 DB 而已總不能為了備份某個 DB 而把整個 MySQL 服務停止備份檔案的方式回存在原主機上一定適用但假如 MySQL 版本升級或是在那天該網頁空間需遷機移機到別的主機時那就沒人敢保證備出來的資料檔可以用所以我們可以考慮另一種備份的方式是使用 MySQL 本身提供的功能 MySQL Data Dump指令是 mysqldump

65

使用 MySQL 的 Dump 功能可以把 DB 的結構資料或結構加資料 Dump 成文字檔 mysqldump 指令提供的彈性很大你可以選擇把整個 DB Dump 成一個檔或是每個 Table 為一個檔甚至是把結構檔和資料分開儲存都

可以 mysqladmin -uroot -p flush-logs mysqldump CRM -uroot -p --opt gt CRM_20030905sql (CRM 是 DB 名稱 opt 是一個使用完整 Dump 參數) 假如只是要單獨 Dump 某個 Table 時只要在上面的指令後轉出符號 gt 前加個 Table 名稱就可以如只要 phpbb2_users 這個 Table 的 Dump 時只要下 mysqldump CRM -uroot -p --opt CUSTOMER gt CRM_CUSTOMER_20030905sql

652 線上還原

若要回存整個資料庫只需將壓縮的備份檔還原成 Dump 的檔案再用下面的指令回存 mysql CRM -uroot -p lt CRM_20030905sql 這邊需注意的是若建立備份時是以--opt或--add-drop-table為參數時回存的 動作是先將舊的 Table 先刪除重建 Table 的結構後再把 Data 匯入所以回存後所有的資料會回到你當時備份那個時間點因此在回存資料時可以考慮把現有錯誤或不完整的 DB 先備份一份下來以備不時之需或是拿來比對錯誤的地

方在那裡當然你也可以把資料回存到另一個測試用的 DB 內只要把上面指令

的 DB 名稱改成你的測試用 DB 名稱即可 使用這種回存方式 MySQL 服務不需停止也不會動到其他正在使用的 DB 在一些提供 MySQL 服務的虛擬主機可用這種方式作你自己的 DB 備份及回存

66

另外假如你是系統重建或是移機時切需在新的 MySQL 內新建一個空白 DB 後才行作回存的工作你可以用下面的指令建立 mysql -uroot -p -e CREATE DATABASE CRM (上面的 CRM是你要新建的 DB 名稱) 另一種作法先用 mysql 指令進入 mysql client console 然後再用 CREATE DATABASE CRM 這樣就行了記得尾端要加個 符號該行指令才會執行

67

第七章 問題與解答

Q1RedHat 90預附的 MySQL到底有無支援 Transcation機制 Ans MySQL自 32334a之後的 MySQL-Max版本加入 InnoDB的資料庫類型透過

InnoDBMySQL同樣可以進行 COMMIT與 ROLLRACK的動作RedHat 90預附的 MySQL為 32354a-11巳支援 InnoDB的資料庫類型不過必須做以

下設定 1cp usrsharedocmysql-server-32354amy-mediumcnf to etcmycnf 2 vi etcmycnf 將以下設定前的拿掉 innodb_data_home_dir = varlibmysql innodb_data_file_path = ibdata110Mautoextend innodb_log_group_home_dir = varlibmysql innodb_log_arch_dir = varlibmysql 3service mysqld restart 如此一來各位在建立Table時便可指定Table Type為 innodb ( ex create table with type=innodb ) Q2如何解決 php+mysql 許功蓋等字變亂的問題 Ans 方法一 【確定 MySQL 預設的字元集】 1 打開 WinMySQLadmin 管理畫面(在視窗右下角狀態列紅綠燈圖示中按滑鼠

右鍵點選 Show me 選項) 2 點選管理畫面中 [Variables] 標籤選項其中 character_set變數就是您預設

字元集的變數其預設是 latin1 字元集(我們要將他改回 big5)而 chatacters_set 變數則是 MySQL 可以支援哪些字元集 【修改預設字元集變數 character_set 】 1 請點選管理畫面中 [myini Setup] 標籤選項設定 myini 2 按一下 [Pick-up and Edit myini values] 按鈕以便編輯目前的 myini 設定 3 在 [mysqld] 設定區塊底下新增一行 default-character-set = big5 變數設

68

定 4 新增一個 [client] 設定區塊並加入第三步驟的變數設定(游標往下移到空白處新增兩行 [client] 和 default-character-set=big5) 5 按一下畫面左下方 [Save Modification] 按鈕儲存設定 6 重新啟動 MySQL 或 Windows 方法二 Server端注意事項 phpini 中有關的設定為(預設值) Magic quotes for incoming GETPOSTCookie data magic_quotes_gpc = On Use Sybase-style magic quotes (escape with instead of ) magic_quotes_sybase = Off Client端注意事項 1中文資料送進 mysql 前請用 addslashes($str) 處理 2處理後送進 mysql 時請用 括起來並在參數後留一個空白如 $sql = UPDATE ezf_table set tablename=$tname tableend=$endtime table inguser=$tguser tableingid=$tguserid tableallnumber=$tnumber tableloca l=$tablelocal tableanyone=$tableopen tabletext=$ttext WHERE tableid=$t ableid tablename=$tname c 取出時請用 stripslashes($str) Q3MySQL root 密碼忘了該怎麼辦 Ans 1先停掉 mysql etcrcdinitdmysql stop 2以--skip-grant-table 的參數啟動 mysql safe_mysql --skip-grant-tableamp 3 更改 root 密碼 mysql mysql mysqlgt UPDATE user SET password=password(newpassword)

69

WHERE user=root mysqlgt FLUSH PRIVILEGES mysqlgt exit 4停掉 mysql再重跑 mysqladmin -uroot -p shutdown Enter password 輸入新設定的密碼 etcrcdinitdmysql start

Q4NULL值問題

Ans

NULL值的概念是造成 SQL的新手的混淆的普遍原因他們經常認為 NULL是和一個空字符串的一樣的東西不是這樣的例如下列語句是完全不同的

mysqlgt INSERT INTO my_table (phone) VALUES (NULL)

mysqlgt INSERT INTO my_table (phone) VALUES ()

兩個語句把值插入到 phone 列但是第一個插入一個 NULL值而第二個插入一個空字符串第一個的含義可以認為是ldquo電話號碼不知道而第二個則可意味

著ldquo她沒有電話

在 SQL中NULL值在于任何其他值甚至 NULL值比較時總是假的(FALSE)包含 NULL的一個表達式總是產生一個 NULL值除非在包含在表達式中的運算符和函數的文檔中指出在下列例子所有的列返回 NULL

mysqlgt SELECT NULL1+NULLCONCAT(InvisibleNULL)

如果你想要尋找值是 NULL的列你不能使用=NULL測試下列語句不返回任

何行因為對任何表達式expr = NULL是假的

mysqlgt SELECT FROM my_table WHERE phone = NULL

要想尋找 NULL值你必須使用 IS NULL測試下例顯示如何找出 NULL電話號碼和空的電話號碼

70

mysqlgt SELECT FROM my_table WHERE phone IS NULL mysqlgt SELECT FROM my_table WHERE phone =

在 MySQL中就像很多其他的 SQL服務器一樣你不能索引可以有 NULL值的列你必須聲明這樣的列為 NOT NULL而且你不能插入 NULL到索引的

列中

當用 LOAD DATA INFILE 讀取數據時空列用更新如果你想要在一個列中有

NULL值你應該在文本文件中使用N字面上的詞NULL也可以在某些情形下使用

當使用 ORDER BY時首先呈現 NULL值如果你用 DESC以降序排序NULL值最後顯示當使用 GROUP BY時所有的 NULL值被認為是相等的

為了有助于NULL的處理你能使用 IS NULL和 IS NOT NULL運算符和 IFNULL()函數

對某些列類型NULL值被特殊地處理如果你將 NULL插入表的第一個TIMESTAMP 列則插入當前的日期和時間如果你將 NULL插入一個AUTO_INCREMENT 列則插入順序中的下一個數字

Q5如何將圖片存放於 MySQL中

Ans

Step 1建立資料庫 test

Step 2 建立表格 binary_data

CREATE TABLE binary_data (

id INT(4) NOT NULL AUTO_INCREMENT PRIMARY KEY

description CHAR(50)

bin_data LONGBLOB

filename CHAR(50)

filesize CHAR(50)

filetype CHAR(50)

71

)

Step 3 利用 storephp 寫入圖片

storephp 程式碼

ltHTMLgt ltHEADgtltTITLEgtStore binary data into SQL DatabaseltTITLEgtltHEADgt ltBODYgt lt code that will be executed if the form has been submitted

if ($submit) mysql_connect(localhostrootYOUR_PASSWORD) mysql_select_db(test) $data=Base64_Encode(fread(fopen($form_data r) filesize($form_data))) $result=MYSQL_QUERY(INSERT INTO binary_data (descriptionbin_datafilenamefilesizefiletype) VALUES ($form_description$data$form_data_name$form_data_size$form_data_type)) $id= mysql_insert_id() print ltpgtThis file has the following Database ID ltbgt$idltbgt MYSQL_CLOSE() else else show the form to submit new data

gt

ltform method=post action=ltphp echo $PHP_SELF gt enctype=multipartform-datagt File Descriptionltbrgt ltinput type=text name=form_description size=40gt ltINPUT TYPE=hidden name=MAX_FILE_SIZE value=4000000gt ltbrgtFile to uploadstore in databaseltbrgt ltinput type=file name=form_data size=40gt ltpgtltinput type=submit name=submit value=submitgt ltformgt lt

72

gt ltBODYgt ltHTMLgt

Step 3 利用 storephp 取出圖片

getdataphp 程式碼

lt Syntax getdataphp3id=ltidgt if($id) you may have to modify login information for your database server MYSQL_CONNECT(localhostrootYOUR_PASSWORD) mysql_select_db(test) $query = select bin_datafiletype from binary_data where id=$id $result = MYSQL_QUERY($query) $data = Base64_Decode(MYSQL_RESULT($result0bin_data)) $type = MYSQL_RESULT($result0filetype) Header( Content-type $type) echo $data gt

Q6MySQL裝好之後啟動時或是執行 mysqladmin會出現如下訊息 Cant connect to local MYSQL Server through Socket varlibmysqlmysqlsock或是

Cant connect to local MYSQL Server through Socket tmpmysqldsock

Ans 可能有下列幾個原因

1這個 mysqldsock 不見了被某人刪除了或是被一些系統自動執行程式給刪

了例如有些 cron任務便會設定定期刪除 tmp 裡的東西所以呢您只能修改

cron 裡的設定讓它不要清除 mysqldsock 2在啟動時也可以改變 mysqldsock的位置您在啟動 MySQL的時候可以加入此參數usrlocalmysqlbinsafe_mysqld --user=mysql --socket=其他路

徑socket amp 同時得去設定環境變數 MYSQL_UNIX_PORT的值以指定新的

73

路徑 3若是您沒改 MYSQL_UNIX_PORT的值那麼您可以在執行指令的時候才打

例如mysqladmin --socket=其他路徑socket version Q7How to get the last insert id Ans CREATE TABLE product ( id INT(4) NOT NULL AUTO_INCREMENT PRIMARY KEY description VARCHAR(50) ) 1利用 SQL的話 mysqlgt insert into product(description) values(123) Query OK 1 row affected (000 sec) mysqlgt select last_insert_id() +------------------+ | last_insert_id() | +------------------+ +------------------+ 1 row in set (000 sec) ======================================== 2如果是 PHP的話 你可以用mysql_insert_id()取得該 id PHP example $result=MYSQL_QUERY(INSERT INTO product (description) VALUES ($description)) $id= mysql_insert_id() print This file has the following Database ID $id Q8如何將文字檔匯入資料庫 Ans $addr=homehttpdhtmlphpschool001txt $sql_select = load data infile $addr into table test fields terminated by t 解說 $sql_select = load data infile 文字檔名 into table 表格名 fields terminated by

74

t

(欄位分隔以 TAB鍵) 該文字檔須與資料表欄位格式相符 例如欄位有三個 則文字檔為每行一筆資料如下 欄 1資料ltTABgt欄 2資料ltTABgt欄 3資料 欄 1資料ltTABgt欄 2資料ltTABgt欄 3資料 欄 1資料ltTABgt欄 2資料ltTABgt欄 3資料 欄 1資料ltTABgtltTABgt欄 3資料

Q9如何撰寫 MySQL C API Ans Step 1利用文字編輯器撰寫以下程式碼 mysqlcc

include ltstdiohgt

include ltmysqlmysqlhgt

int main (int argc char argv[])

MYSQL mysql

MYSQL_RES res

MYSQL_ROW row

if (argc = 2)

fputs (Usage myc ltdatabasegt stderr)

return 1

if ((mysql_connect(ampmysqllocalhostrootYour_Password)))

fputs (Error connecting stderr)

abort()

75

if (mysql_select_db(ampmysqlargv[1]))

fputs (Error selecting database stderr)

abort()

if (mysql_query(ampmysqlSELECT FROM test_table))

fputs (Error processing query stderr)

abort()

if ((res = mysql_store_result(ampmysql)))

fputs (Error storing results stderr)

abort()

while((row = mysql_fetch_row(res)))

uint i = 0

for (i=0 i lt mysql_num_fields(res) i++)

printf(s row[i])

printf(n)

return 0

Step 2 Compile

gcc -Iusrlocalmysqlinclude -Lusrlocalmysqllibmysql mysqlcc ndashlm -lmysqlclient

(其中 include path與 library path取決於你的 MySQL安裝路徑)

76

如果執行時發生如下 error Run problemerror in loading shared libraries libmysqlclientsoX 將你的 MySQL library path(for exampleusrlocalmysqllibmysql) 加入etcldsoconf and run sbinldconfig -v Q9ASP + MySQL 範例程式 Ans Dim myconn As New ADODBConnection Dim myrs As New Recordset Dim mySQL As String Dim myrows As Long myconnOpen DSN=MyODBCsample mySQL = SELECT from user myrsSource = mySQL Set myrsActiveConnection = myconn myrsCursorLocation = adUseClient myrsOpen myrows = myrsRecordCount myrsClose myconnClose 可參考 httpwwwdwamnetmysqlasp_myodbcasp 有詳細的資料 Q10如何將 MySQL中的資料庫匯出成txt檔 Ans select from TableName into outfile textxls all result fields will seperate by tab

77

第八章 參考資料

英文部份 網址 1 httpwwwmysqlcom MySQL 網站有第一手有關 MySQL的資料 2 httpwwwmysqlcomdocenReplicationhtml 有關 MySQL Replication 的文件 3 httpwwwgeocitiescomsqlhomefaqstore_blobhtml 如何在 MySQL 存放 BLOB的資料 4httpwwwsapdborg 有關 SAP跟 MySQL相關合作的網站 書藉 1 Cooking with MySQL

Paul DuBois has selected sample recipes from the hundreds youll find in his book MySQL

Cookbook In this third and final series of excerpts showcasing these recipes learn how to

compute team standings how to calculate the differences between successive Dec 26

2002 2 Tips for Building Web Database Applications with PHP and MySQL by Hugh E Williams co-author of Web Database Applications with PHP amp MySQL 04042002

3 Managing and Using MySQL 2nd Edition By Tim King George Reese Randy Jay Yarger

4 MySQL Cookbook By Paul DuBoisPublisher OReillyPub Date October 2002

中文部份

78

1 httplinuxtncedutwtechdocmysqlmysql_docmanual_tochtml MySQL 中文手冊 2 httpchenshloxaedutwphpZ_1php PHP+MySQ程式研習設計網站 3 httplinuxtncedutwtechdocbanicdownhtml PHP 4 手冊 4 httpwwwtncedutwadmin_zonephp台南縣教育網網路中心有很多 Linux相關文件 5 httpdobtncedutw網站建置百寶箱有很多 PHP MySQL 相關範例程式 5 httpwwwdbworldcomtw資料庫專家電子雜誌介紹資料庫的重要觀念及名詞

79

附錄一 SQL Command 介紹

SQL (讀音ess-que-el) 是一種結構查詢語法SQL 使用於資料庫交流

傳遞相容於 ANSI (American National Standards Institute) 是一套標準的關聯

式資料庫語言 SQL 語言是執行更新或從資料系統獲取資料一般常見的關聯

資料庫系統都有提供 SQL 如 Oracle Sybase Microsoft SQL Server Access Ingres 等雖然大部份的資料庫都有提供 SQL 但也多提供了自已獨特的語

法造成了不相容的情形但標準基本的語法是相通的如Select Insert Update Delete Create and Drop 每一個系統都有支援

Table相關 Command

Create Table

關聯式資料庫包含有很多元件稱為資料表(tables) 把資料或訊息放在資

料表中 資料表是以不同的名稱做分別資料表由欄列所構成的二維陣列

欄包含欄位名資料型態 及其他可判斷的資訊列是由全部欄位構成一筆一

筆的紀錄 create table 語法用在建立一個新的資料表語法格式如下

create table tablename (column1 data type column2 data type column3 data type)

Format of create table if you were to use optional constraints

create table tablename (column1 data type [constraint] column2 data type [constraint] column3 data type [constraint]) [ ] = optional

Note You may have as many columns as youd like and the constraints are optional

80

Example

create table employee (first varchar(15) last varchar(20) age number(3) address varchar(30) city varchar(20) state varchar(20))

注意建立資料表格式要以括號把前後框住而最後以(分號)做結尾

欄位名不要超過 30個字元長而且不要使用 sql 的關鍵字(如 where select等)而在後面接是型態的宣告(如字串數字日期格式等)

資料型態是來描述欄位的方式如一個欄位Last_Name 是一個姓氏可以使用varchar (可變動長度字串) 資料型態

以下是幾個常見的資料庫型態 char(size) 固定長度字串最長為 255 位元 varchar(size) 變動長度字串最大字元數以 size 來指定 number(size) 數值格式可以是整數也可以是小數最大數字以 size 位數判

斷未指定小數位數由系統內定 date 日期格式 number(sized) 數值格式最大數字以 size 位數判斷d 為小數位數整數位

數為 size-d 位

有何限制當資料表被建立通常有一或數個欄位是要使用來做關聯的功

能 例如unique 限制(唯一值)兩筆記錄不可以相同的值 not null (非空值)該欄位一定要輸入資料不可是空的primary key (主鍵)是每一筆記錄識別的主要方式

Drop a table drop table 刪除資料表(其中的資料也會一併刪除)

drop table tablename

Example

81

drop table 和刪除全部資料是不同的刪除全部資料欄位名稱資訊等還會

存在但刪除資料表會把這一些也一併移除掉

如何查詢資料

Select 基本用法

select 語法是關連式資料庫最常用的部份可以取得你想要的資料這是一個

簡單的範例 select column1[column2etc] from tablename [where condition] [] = optional 在 select 之後所列欄位名則是要顯示的資料部份你可以一一列出各欄位

名或是以 (星號)來代表選擇全部的欄位 from 之後放資料表名稱 where 子句 (選項) 指定要過濾的條件符合者才會顯現 where 可使用的條件運算元 = 等於 gt 大於 lt 小於 gt= 大或等於 lt= 小或等於 ltgt 大相等 LIKE 相似 For example select first last city

82

from empinfo where first LIKE Er 以Er 為開頭的字串就符合要以單引號框住 Or you can specify select first last from empinfo where last LIKE s 最後一字為 S 就符合 select from empinfo where first = Eric 則表示 first name 一定要是 Eric 才可以 範例資料表empinfo 統計函數

MIN 傳回指定欄位最小值

MAX 傳回指定欄位最大值

SUM 傳回指定欄位總和

AVG 傳回指定欄位平均值

COUNT 傳回指定欄位的筆數

COUNT() 傳回資料庫中的總筆數

統計函數使用於資料表中的數值欄位配合 SELECT 語法使用 只用於總結特定單一欄位可以配合 GROUP BY 做篩選但也可以不使用 GROUP BY 語句For example

SELECT AVG(salary) FROM employee

83

傳回全部 salary 平均值

Another example

SELECT AVG(salary) FROM employee WHERE title = Programmer

傳回 salary 平均值條件為 employees 資料表中當 title 等於 Programmer

Example

SELECT Count() FROM employees

傳回 employees 資料表中紀錄總筆數

GROUP BY 語法 SELECT column1 SUM(column2) FROM list-of-tables GROUP BY column-list The GROUP BY 語句可以先以所列的欄位為條件分組排序在一起(可以多欄

位) example 要列出每一個 dept 中最高 salary 值 SELECT max(salary) dept FROM employee GROUP BY dept HAVING 語法

SELECT column1 SUM(column2) FROM list-of-tables GROUP BY column-list HAVING condition

HAVING 子句是 GROUP BY 的一部份用來過濾在 GROUP BY 所選出的資料功能如同 select 命令中 where 條件式一樣只是 HAVING 必需配合 GROUP BY 使用

我們以例子來說明我們要取得每一公司名及每一公司的薪水平均值輸入如下

84

SELECT dept avg(salary) FROM employee GROUP BY dept

但如果我們只列出薪資平均值超過 20000元的公司資料

SELECT dept avg(salary) FROM employee GROUP BY dept HAVING avg(salary) gt 20000

ORDER BY子句語法

SELECT column1 SUM(column2) FROM list-of-tables ORDER BY column-list [ASC | DESC]

[ ] =選項

ORDER BY是一個選項子句當你以排序方式來顯示資料(正向由小到大反向由大到小)以指定的欄位資料做排序

ASC = 正向- 預設值 DESC = 反向排序

For example

SELECT employee_id dept name age salary FROM employee_info WHERE dept = Sales ORDER BY salary

以上列出公司代號公司名銷售員人名年紀及薪資而條件是公司名為 Sales 顯示順序以薪資多少排序(由小到大為預設值)

如果要以多個欄位做排序要以逗號做分隔如下

SELECT employee_id dept name age salary FROM employee_info WHERE dept = Sales ORDER BY salary age DESC

85

結合條件及布林運算 SELECT column1 SUM(column2) FROM list-of-tables WHERE condition1 AND condition2 AND運算可以結兩個或以上的條件放在 WHERE子句中 兩者都要為真才

會顯示該筆記錄 OR 運算可以結兩個或以上敘述放在 WHERE子句中只要其中一個為直就

會顯示該筆記錄 For example SELECT employeeid firstname lastname title salary FROM employee_info WHERE salary gt= 5000000 AND title = Programmer 必需要薪資大於等於 50000而且職稱為 Programmer同時符合才會顯示該筆資料 以下以括號括住雖然不是必需的但如此比較容易讀 SELECT employeeid firstname lastname title salary FROM employee_info WHERE (salary gt= 5000000) AND (title = Programmer) 另外範例 SELECT firstname lastname title salary FROM employee_info WHERE (title = Sales) OR (title = Programmer) 條件為只要是 Sales 或 Programmer 職稱的就會被列出 IN and BETWEEN 子句

SELECT column1 SUM(column2) FROM list-of-tables WHERE column3 IN (list-of-values) SELECT column1 SUM(column2) FROM list-of-tables WHERE column3 BETWEEN value1 AND value2 IN 子句使用在列舉項目的使用上也就是分別測試是否符合所列的值 For example

86

SELECT employeeid lastname salary FROM employee_info WHERE lastname IN (Hernandez Jones Roberts Ruiz) 條件為姓氏(astname)要符合 Hernandez Jones Roberts or Ruiz 其中一個才會被傳回 IN運算元也可以使用 OR 的語法來取代如下結果相同 SELECT employeeid lastname salary FROM employee_info WHERE lastname = Hernandez OR lastname = Jones OR lastname = Roberts OR lastname = Ruiz 但使用 IN 句子比較短也比較易懂 你也可以使用 NOT IN 來去掉不要的記錄 BETWEEN 運算元使用在判斷是否存在兩個數值之間 For example SELECT employeeid age lastname salary FROM employee_info WHERE age BETWEEN 30 AND 40 傳回年紀 30歲到 40歲之間的資料(含 30及 40歲者) 相同的也可以使用以下語法來達到相同的結果 SELECT employeeid age lastname salary FROM employee_info WHERE age gt= 30 AND age lt= 40 你也可使用 NOT BETWEEN 來濾掉中間值的資料 數學運算 標準 ANSI SQL-92 提供以下運算

87

+ 加

- 減

餘數

餘數為除法後剩整數這不在標準的 ANSI SQL 中但大部份的資料庫都會支

援這運算元以下列出有用的函數雖不在 ANSI SQL-92 提供但一般資料庫

也會支援他們

ABS(x) 傳回 x 絕對值

SIGN(x) returns the sign of input x as -1 0 or 1 (negative zero or positive respectively)

MOD(xy) 餘數 - returns the integer remainder of x divided by y (同 xy)

FLOOR(x) 傳回小或等於 x 的最大整數值

CEILING(x) or CEIL(x)

傳回大或等於 x 的最小整數值

POWER(xy) x的 y 次方

ROUND(x) 把 x 四捨五入為整數

ROUND(xd) 四捨五入取到小數 d 位

SQRT(x) x 開平方

For example SELECT round(salary) firstname FROM employee_info 傳回薪資取到整數位

如何新增資料

insert 加入一筆新紀錄到資料表中 insert into tablename (first_columnlast_column) values (first_valuelast_value) [] = optional Example insert into employee

88

(first last age address city state) values (Luke Duke 45 2130 Boars Nest Hazard Co Georgia) Note 字串要以單引號住如string 數字框住也無妨 insert into 後面接資料表名稱再接以括號括住的欄位名在 values 後括號分別對映各欄位的值 以上的例子新增了一筆名(first) 為 Luke而住所(state) 為 Georgia 的資料

如何刪除資料

delete 可以刪除單筆或多筆紀錄 delete from tablename where columnname OPERATOR value [and|or column OPERATOR value] [ ] = optional Examples delete from employee Note 如果你沒有指定 where 子句那麼全部的紀錄都會被刪除 delete from employee where lastname = May delete from employee where firstname = Mike or firstname = Eric delete from 接著資料表名 再接著是條件式判斷沒有條件式則全部紀錄會

被刪除

如何更新資料

update 用來更新你所指定的記錄要和 WHERE 配合小心使用 語法 update tablename set columnname = newvalue[nextcolumn = newvalue2] where columnname OPERATOR value [and|or column OPERATOR value] [] = optional Examples

89

update phone_book set area_code = 623 where prefix = 979 update phone_book set last_name = Smith prefix=555 suffix=9292 where last_name = Jones update employee set age = age+1 where first_name=Mary and last_name=Williams

90

附錄二Replication

測試環境

RedHat 90 + MySQL 32358 MySQL資料庫路徑 varlibmysql MySQL設定檔 etcmycnf Master IP 1921680100 Slave IP 1921680200 請至下列網址下載最新MySQL 32358套件並利用rpm ndashUvh 更新 httpupdatesredhatcom9enosi386

圖 最新 MySQL 套件

測試架構圖

91

1921680100

1921680200Master Server

erveSlave S r

圖 測試架構圖

測試步驟

Master server 部份 Step1 確認 MasterSlave機器上所裝的 MySQL版本能進行

replication( 32329 or higher ) Step2 在 Master MySQL上開放一個帳號給 Slave mysql ndashu root ndashp mysqlgtGRANT FILE ON TO repl1921680200 IDENTIFIED BY lsquoabc123rsquo mysqlgtq 上面是 Master開放一個帳號 repl密碼 abc123給 IP1921680200有檔案處理

的權限 Step3 shutdown MySQL on the Master mysqladmin ndashu root ndashp shutdown Step4 備份 Master所有資料庫 tar ndashcvf tmpmysql-snapshottar varlibmysql 注意tar的時候MySQL是要在 stop情況下 在mysql (wwwmysqlcom) 網站的FAQ有不用shutdown的方法

92

Step5 在 master機器上修改etcmycnf 在[mysqld]區段內加入參數 log-bin server-id=這邊設定 server-id=1 sql-bin-update-same binlog-do-db=CRM只針對 CRM資料庫做紀錄 Step6 Restart MySQL on the master service mysqld start 此時因為有加入 log-bin 參數因此開始有 index產生了在varlibmysql目錄下

有index檔案紀錄資料庫的異動 log Slave server 部份 Step1 在 slave設定etcmycnf 在[mysqld]區段加入 master-host= master-user= master-password= master-port= server-id= 這邊設定 master-host=1921680100 master-user=repl master-password=abc123 master-port=3306 server-id=2 master-connect-retry=60預設重試間隔 60秒 replicate-do-db=CRM告訴 slave只做 CRM資料庫的更新 log-slave-updates Step2 將 master上的 mysql-snapshottar copy到 slave上 用 ftp傳到 slave的tmp Step3 解壓縮 Master資料庫至 Slave Server上 cd varlib tar xvf tmpmysql-snapshottar chown ndashR mysqlmysql mysql

93

chmod ndashR 770 mysql (視情況) Step4 Restart MySQL on the slave server 這時在varlibmysql目錄會出現 masterinfo此檔案紀錄了 Master MySQL server的資訊

狀況測試

One-way replication

1921680100

1921680200Master Server

erveSlave S r

圖 One-way replication架構圖 Step1 Master跟 Slave網路及服務都正常情況下由 Master端異動資料後 到 Slave端瀏覽資料檢視是否有進行 replication Step2 模擬 Slave Server 當機 可用在於 slave真的當機或是 Slave 不一定需要一直跟 master connect將Slave MySQL server shutdown由 Master端異動資料到 slave端瀏覽此時Slave應該沒有被 replication 更新然後再將 Slave端 MySQL server start起來

預設 60秒後 Slave會嘗試跟 Master要求進行 replication再去 Slave端檢視是否有更新資料

94

Step3 模擬 Master當機因為是設定 One-way replication一旦 Master Server Slave端沒有 Master的 source可以 download Two-way replication 基於 Master當機狀況於是發展雙向 Replication即 1921680100 ( Host A ) 1921680200 ( Host B )都分別擔任 MasterSlave身分

1921680100

1921680200er

Server B MasterSlave Server

Server A MasterSlave Serv

圖 Two-way replication架構圖 以下是針對兩台 MySQL伺服器進行雙向 Replication Step1觀念同單向 replication只是改成 Master也有 Slave身分 Slave也有Master的身分先分別在 Server AServer B 都去 grant一個進行 replication的身分 [A]mysqlgtGRANT FILE ON TO repl1921680200 IDENTIFIED BY lsquoabc123rsquo [B]mysqlgt GRANT FILE ON TO repl1921680100 IDENTIFIED BY lsquoabc123rsquo Step2做完單向 replication後stop Server Aserver B MySQL service此時 AB資料是一樣的

95

修改etcmycnf設定 範例 Server A [mysqld] datadir=varlibmysql socket=varlibmysqlmysqlsock server-id=1 log-bin sql-bin-update-same binlog-do-db=CRM master-host=1921680200 master-user=repl master-password=abc123 log-slave-updates master-connect-retry=60 replicate-do-db=CRM Server B [mysqld] datadir=varlibmysql socket=varlibmysqlmysqlsock server-id=2 log-bin sql-bin-update-same binlog-do-db=CRM master-host=1921680100 master-user=repl master-password=abc123 log-slave-updates master-connect-retry=60 replicate-do-db=CRM 分別 start Server AServer B MySQL後此時雙方都是 MasterSlave身分一旦哪一方資料異動就會通知對方來 replication-若 replication失效則必須將Server AServer B的masterinfo及index00x 都砍掉然後分別 restart MySQL server進行測試檢視成果 實務上通常如果需要做Two-way replication通常會搭配Virtual Server使用

96

在前端架設一台Virtual Server不過此部份不在此份SOP討論範圍內有興趣

的讀者可參考 httpwwwlinuxvirtualserverorg 網站

1921680100 1921680200

Host A MasterSlave Server

Host B MasterSlave Server

Virtual Host

圖 Virtual Server + Two-way replication 架構圖

97

圖 High Availability Linux Virtual Server架構圖

98

  • COSA-SOP-03-006
  • 第一章 簡介
    • 11適用對象 (Audience)
    • 12 MySQL本身
    • 13 MySQL 40版跟50版重大的改進功能
    • 14 各家資料庫軟體比較
      • 第二章 前置需求
      • 第三章 安裝
        • 31 MySQL安裝
        • 32 phpMyAdmin安裝
        • 33 升級及注意事項
          • 第四章 MySQL管理
            • 41 Webmin 管理介面
            • 42 phpMyAdmin 的操作介面
            • 43管理指令介紹
              • 431 利用mysqladmin設定root的密碼
                  • 第五章 實用範例
                    • 51 任務一Web Base客戶通訊錄
                    • 52 任務二Web Base群組軟體 ( twig )
                      • 第六章 維護及更新程序
                        • 61 日常維護
                        • 62 更新程序
                        • 63 備份重要檔案
                        • 64 離線備份與還原
                        • 65 線上備份與還原
                          • 第七章 問題與解答
                          • 第八章 參考資料
                          • 附錄一 SQL Command 介紹
                          • 附錄二Replication
Page 60: DataBase Server Standard Operation Procedureebooks.lib.ntu.edu.tw/1_file/oss/63/93doc4-5.pdf · 業務的公司帶來了不少壓力,譬如微軟,甲骨文 ... 外的錢用在第三方的資料庫產品上,譬如就可以不用再購買甲骨文公司

Step 3 執行安裝動作安裝到 varwwwhtmltwig 目錄 cd twig-277 twig-install varwwwhtmltwig

Step 4 建立 MySQL 資料庫(twig)及各資料表

cd setup mysql -u root -p1234 mysqlgt create database twig Query OK 1 row affected (001 sec) mysqlgt quit mysql -u root ndashp1234 twiglt twigtablemysql

Step 5 修改 configincphp3 參數設定 vi varwwwhtmltwigconfigconfigincphp3 $config[fromdomain] = opencom 網域 $config[language] = chinesebig5 中文訊息 $config[imap_port] = 143notls

60

Step 6 修改連結 MySQL 的帳號密碼 vi varwwwhtmltwigconfigdbconfigincphp3 $dbconfig[sqlusername] = root username $dbconfig[sqlpassword] = 1234 password

Step 7 其他設定檔

vi etchttpdconfhttpdconf 加入 AddType applicationx-httpd-php php3 在 DirectoryIndex最後加入 indexphp3 DirectoryIndex indexhtml indexhtmlvar indexphp3 在 AddDefaultCharset ISO-8859-1加上 AddDefaultCharset ISO-8859-1

vi etcphpini register_globals = On service httpd restart Step 8 sendmail 設定 vi etcmailsendmailcf在 264 行前面加上並重新啟動 sendmail「service snedmail restart」 262 SMTP daemon options 263 264 O DaemonPortOptions=Port=smtpAddr=127001 Name=MTA 265 266 SMTP client options 267 O ClientPortOptions=Family=inet Address=00

61

Step 9 檢查設定有無錯誤 http主機名稱twigtestphp3

62

Step 10 登入 twig ( http主機名稱twig)

63

第六章 維護及更新程序

61 日常維護

系統管理員最好定期以 root 身份登入看看信件在 RedHat Linux 中有一支 logwatch 程式會定時去分析 log file如果發現異常便會發信給 root除此之外筆者建議讀者平時就檢查 MySQL log file ( varlogmysqldlog)是否有異常情形

62 更新程序

讀者可至httprpmfindnet 尋找MySQL相關套件至於升級的相關步驟請參

考Linux OS SOP 第 54節

63 備份重要檔案

預設 MySQL 的 DB 檔案是存在 varlibmysql 內以 DB名稱為目錄目錄

內就是該 DB 的所有資料通常得定期備份還有 MySQL的設定檔 etcmycnf也別忘了一起備份

64 離線備份與還原

641 離線備份

預設 MySQL 的 DB 檔案是存在 varlibmysql 內以 DB 名稱為目錄目錄內

就是該 DB 的所有資料像 CRM 這個 DB就是存在 varlibmysqlCRM 內在備份前因為怕資料尚未完全寫入磁碟而且 MySQL 會 Lock 在使用的 DB 檔案所以應該是要先把 MySQL 先 Shutdown 一下整個備份的程序可以下像下面的指令去完成 cd varlibmysql

64

service mysqld stop tar cvfz CRM_db_20030905tgz CRM service mysqld start 對這樣就可以了 不過要注意的是怕 DB 內每個 Tables 間的資料有關關

聯性所以最好是把整個 DB 一次備起來單獨只備哪個 Tables 的檔案以後回存時怕會有資料關聯不一致的問題

642 離線還原

DB 發生錯誤而要回存時其實也不難先找出最近一次完整正常的備份先把現在錯誤的網頁或 DB 先更名或 tar 起來再把好的備份給解開回原來目錄位

置就行了需要注意的是 MySQL 服務最好也是要先停止回存完成後再啟動服務回存 DB 的整個程序可能像下面 cd varlibmysql service mysqldstop mv CRM CRM_OLD tar xvfz CRM_db_20030905tg service mysqld start

65 線上備份與還原

651 線上備份

使用像上面的檔案方式備份是個不錯的方法它最少可以保持該主機某個時間點的完整檔案備份但還是有一些問題需要考慮到有些主機就不只建立一個 DB 而已總不能為了備份某個 DB 而把整個 MySQL 服務停止備份檔案的方式回存在原主機上一定適用但假如 MySQL 版本升級或是在那天該網頁空間需遷機移機到別的主機時那就沒人敢保證備出來的資料檔可以用所以我們可以考慮另一種備份的方式是使用 MySQL 本身提供的功能 MySQL Data Dump指令是 mysqldump

65

使用 MySQL 的 Dump 功能可以把 DB 的結構資料或結構加資料 Dump 成文字檔 mysqldump 指令提供的彈性很大你可以選擇把整個 DB Dump 成一個檔或是每個 Table 為一個檔甚至是把結構檔和資料分開儲存都

可以 mysqladmin -uroot -p flush-logs mysqldump CRM -uroot -p --opt gt CRM_20030905sql (CRM 是 DB 名稱 opt 是一個使用完整 Dump 參數) 假如只是要單獨 Dump 某個 Table 時只要在上面的指令後轉出符號 gt 前加個 Table 名稱就可以如只要 phpbb2_users 這個 Table 的 Dump 時只要下 mysqldump CRM -uroot -p --opt CUSTOMER gt CRM_CUSTOMER_20030905sql

652 線上還原

若要回存整個資料庫只需將壓縮的備份檔還原成 Dump 的檔案再用下面的指令回存 mysql CRM -uroot -p lt CRM_20030905sql 這邊需注意的是若建立備份時是以--opt或--add-drop-table為參數時回存的 動作是先將舊的 Table 先刪除重建 Table 的結構後再把 Data 匯入所以回存後所有的資料會回到你當時備份那個時間點因此在回存資料時可以考慮把現有錯誤或不完整的 DB 先備份一份下來以備不時之需或是拿來比對錯誤的地

方在那裡當然你也可以把資料回存到另一個測試用的 DB 內只要把上面指令

的 DB 名稱改成你的測試用 DB 名稱即可 使用這種回存方式 MySQL 服務不需停止也不會動到其他正在使用的 DB 在一些提供 MySQL 服務的虛擬主機可用這種方式作你自己的 DB 備份及回存

66

另外假如你是系統重建或是移機時切需在新的 MySQL 內新建一個空白 DB 後才行作回存的工作你可以用下面的指令建立 mysql -uroot -p -e CREATE DATABASE CRM (上面的 CRM是你要新建的 DB 名稱) 另一種作法先用 mysql 指令進入 mysql client console 然後再用 CREATE DATABASE CRM 這樣就行了記得尾端要加個 符號該行指令才會執行

67

第七章 問題與解答

Q1RedHat 90預附的 MySQL到底有無支援 Transcation機制 Ans MySQL自 32334a之後的 MySQL-Max版本加入 InnoDB的資料庫類型透過

InnoDBMySQL同樣可以進行 COMMIT與 ROLLRACK的動作RedHat 90預附的 MySQL為 32354a-11巳支援 InnoDB的資料庫類型不過必須做以

下設定 1cp usrsharedocmysql-server-32354amy-mediumcnf to etcmycnf 2 vi etcmycnf 將以下設定前的拿掉 innodb_data_home_dir = varlibmysql innodb_data_file_path = ibdata110Mautoextend innodb_log_group_home_dir = varlibmysql innodb_log_arch_dir = varlibmysql 3service mysqld restart 如此一來各位在建立Table時便可指定Table Type為 innodb ( ex create table with type=innodb ) Q2如何解決 php+mysql 許功蓋等字變亂的問題 Ans 方法一 【確定 MySQL 預設的字元集】 1 打開 WinMySQLadmin 管理畫面(在視窗右下角狀態列紅綠燈圖示中按滑鼠

右鍵點選 Show me 選項) 2 點選管理畫面中 [Variables] 標籤選項其中 character_set變數就是您預設

字元集的變數其預設是 latin1 字元集(我們要將他改回 big5)而 chatacters_set 變數則是 MySQL 可以支援哪些字元集 【修改預設字元集變數 character_set 】 1 請點選管理畫面中 [myini Setup] 標籤選項設定 myini 2 按一下 [Pick-up and Edit myini values] 按鈕以便編輯目前的 myini 設定 3 在 [mysqld] 設定區塊底下新增一行 default-character-set = big5 變數設

68

定 4 新增一個 [client] 設定區塊並加入第三步驟的變數設定(游標往下移到空白處新增兩行 [client] 和 default-character-set=big5) 5 按一下畫面左下方 [Save Modification] 按鈕儲存設定 6 重新啟動 MySQL 或 Windows 方法二 Server端注意事項 phpini 中有關的設定為(預設值) Magic quotes for incoming GETPOSTCookie data magic_quotes_gpc = On Use Sybase-style magic quotes (escape with instead of ) magic_quotes_sybase = Off Client端注意事項 1中文資料送進 mysql 前請用 addslashes($str) 處理 2處理後送進 mysql 時請用 括起來並在參數後留一個空白如 $sql = UPDATE ezf_table set tablename=$tname tableend=$endtime table inguser=$tguser tableingid=$tguserid tableallnumber=$tnumber tableloca l=$tablelocal tableanyone=$tableopen tabletext=$ttext WHERE tableid=$t ableid tablename=$tname c 取出時請用 stripslashes($str) Q3MySQL root 密碼忘了該怎麼辦 Ans 1先停掉 mysql etcrcdinitdmysql stop 2以--skip-grant-table 的參數啟動 mysql safe_mysql --skip-grant-tableamp 3 更改 root 密碼 mysql mysql mysqlgt UPDATE user SET password=password(newpassword)

69

WHERE user=root mysqlgt FLUSH PRIVILEGES mysqlgt exit 4停掉 mysql再重跑 mysqladmin -uroot -p shutdown Enter password 輸入新設定的密碼 etcrcdinitdmysql start

Q4NULL值問題

Ans

NULL值的概念是造成 SQL的新手的混淆的普遍原因他們經常認為 NULL是和一個空字符串的一樣的東西不是這樣的例如下列語句是完全不同的

mysqlgt INSERT INTO my_table (phone) VALUES (NULL)

mysqlgt INSERT INTO my_table (phone) VALUES ()

兩個語句把值插入到 phone 列但是第一個插入一個 NULL值而第二個插入一個空字符串第一個的含義可以認為是ldquo電話號碼不知道而第二個則可意味

著ldquo她沒有電話

在 SQL中NULL值在于任何其他值甚至 NULL值比較時總是假的(FALSE)包含 NULL的一個表達式總是產生一個 NULL值除非在包含在表達式中的運算符和函數的文檔中指出在下列例子所有的列返回 NULL

mysqlgt SELECT NULL1+NULLCONCAT(InvisibleNULL)

如果你想要尋找值是 NULL的列你不能使用=NULL測試下列語句不返回任

何行因為對任何表達式expr = NULL是假的

mysqlgt SELECT FROM my_table WHERE phone = NULL

要想尋找 NULL值你必須使用 IS NULL測試下例顯示如何找出 NULL電話號碼和空的電話號碼

70

mysqlgt SELECT FROM my_table WHERE phone IS NULL mysqlgt SELECT FROM my_table WHERE phone =

在 MySQL中就像很多其他的 SQL服務器一樣你不能索引可以有 NULL值的列你必須聲明這樣的列為 NOT NULL而且你不能插入 NULL到索引的

列中

當用 LOAD DATA INFILE 讀取數據時空列用更新如果你想要在一個列中有

NULL值你應該在文本文件中使用N字面上的詞NULL也可以在某些情形下使用

當使用 ORDER BY時首先呈現 NULL值如果你用 DESC以降序排序NULL值最後顯示當使用 GROUP BY時所有的 NULL值被認為是相等的

為了有助于NULL的處理你能使用 IS NULL和 IS NOT NULL運算符和 IFNULL()函數

對某些列類型NULL值被特殊地處理如果你將 NULL插入表的第一個TIMESTAMP 列則插入當前的日期和時間如果你將 NULL插入一個AUTO_INCREMENT 列則插入順序中的下一個數字

Q5如何將圖片存放於 MySQL中

Ans

Step 1建立資料庫 test

Step 2 建立表格 binary_data

CREATE TABLE binary_data (

id INT(4) NOT NULL AUTO_INCREMENT PRIMARY KEY

description CHAR(50)

bin_data LONGBLOB

filename CHAR(50)

filesize CHAR(50)

filetype CHAR(50)

71

)

Step 3 利用 storephp 寫入圖片

storephp 程式碼

ltHTMLgt ltHEADgtltTITLEgtStore binary data into SQL DatabaseltTITLEgtltHEADgt ltBODYgt lt code that will be executed if the form has been submitted

if ($submit) mysql_connect(localhostrootYOUR_PASSWORD) mysql_select_db(test) $data=Base64_Encode(fread(fopen($form_data r) filesize($form_data))) $result=MYSQL_QUERY(INSERT INTO binary_data (descriptionbin_datafilenamefilesizefiletype) VALUES ($form_description$data$form_data_name$form_data_size$form_data_type)) $id= mysql_insert_id() print ltpgtThis file has the following Database ID ltbgt$idltbgt MYSQL_CLOSE() else else show the form to submit new data

gt

ltform method=post action=ltphp echo $PHP_SELF gt enctype=multipartform-datagt File Descriptionltbrgt ltinput type=text name=form_description size=40gt ltINPUT TYPE=hidden name=MAX_FILE_SIZE value=4000000gt ltbrgtFile to uploadstore in databaseltbrgt ltinput type=file name=form_data size=40gt ltpgtltinput type=submit name=submit value=submitgt ltformgt lt

72

gt ltBODYgt ltHTMLgt

Step 3 利用 storephp 取出圖片

getdataphp 程式碼

lt Syntax getdataphp3id=ltidgt if($id) you may have to modify login information for your database server MYSQL_CONNECT(localhostrootYOUR_PASSWORD) mysql_select_db(test) $query = select bin_datafiletype from binary_data where id=$id $result = MYSQL_QUERY($query) $data = Base64_Decode(MYSQL_RESULT($result0bin_data)) $type = MYSQL_RESULT($result0filetype) Header( Content-type $type) echo $data gt

Q6MySQL裝好之後啟動時或是執行 mysqladmin會出現如下訊息 Cant connect to local MYSQL Server through Socket varlibmysqlmysqlsock或是

Cant connect to local MYSQL Server through Socket tmpmysqldsock

Ans 可能有下列幾個原因

1這個 mysqldsock 不見了被某人刪除了或是被一些系統自動執行程式給刪

了例如有些 cron任務便會設定定期刪除 tmp 裡的東西所以呢您只能修改

cron 裡的設定讓它不要清除 mysqldsock 2在啟動時也可以改變 mysqldsock的位置您在啟動 MySQL的時候可以加入此參數usrlocalmysqlbinsafe_mysqld --user=mysql --socket=其他路

徑socket amp 同時得去設定環境變數 MYSQL_UNIX_PORT的值以指定新的

73

路徑 3若是您沒改 MYSQL_UNIX_PORT的值那麼您可以在執行指令的時候才打

例如mysqladmin --socket=其他路徑socket version Q7How to get the last insert id Ans CREATE TABLE product ( id INT(4) NOT NULL AUTO_INCREMENT PRIMARY KEY description VARCHAR(50) ) 1利用 SQL的話 mysqlgt insert into product(description) values(123) Query OK 1 row affected (000 sec) mysqlgt select last_insert_id() +------------------+ | last_insert_id() | +------------------+ +------------------+ 1 row in set (000 sec) ======================================== 2如果是 PHP的話 你可以用mysql_insert_id()取得該 id PHP example $result=MYSQL_QUERY(INSERT INTO product (description) VALUES ($description)) $id= mysql_insert_id() print This file has the following Database ID $id Q8如何將文字檔匯入資料庫 Ans $addr=homehttpdhtmlphpschool001txt $sql_select = load data infile $addr into table test fields terminated by t 解說 $sql_select = load data infile 文字檔名 into table 表格名 fields terminated by

74

t

(欄位分隔以 TAB鍵) 該文字檔須與資料表欄位格式相符 例如欄位有三個 則文字檔為每行一筆資料如下 欄 1資料ltTABgt欄 2資料ltTABgt欄 3資料 欄 1資料ltTABgt欄 2資料ltTABgt欄 3資料 欄 1資料ltTABgt欄 2資料ltTABgt欄 3資料 欄 1資料ltTABgtltTABgt欄 3資料

Q9如何撰寫 MySQL C API Ans Step 1利用文字編輯器撰寫以下程式碼 mysqlcc

include ltstdiohgt

include ltmysqlmysqlhgt

int main (int argc char argv[])

MYSQL mysql

MYSQL_RES res

MYSQL_ROW row

if (argc = 2)

fputs (Usage myc ltdatabasegt stderr)

return 1

if ((mysql_connect(ampmysqllocalhostrootYour_Password)))

fputs (Error connecting stderr)

abort()

75

if (mysql_select_db(ampmysqlargv[1]))

fputs (Error selecting database stderr)

abort()

if (mysql_query(ampmysqlSELECT FROM test_table))

fputs (Error processing query stderr)

abort()

if ((res = mysql_store_result(ampmysql)))

fputs (Error storing results stderr)

abort()

while((row = mysql_fetch_row(res)))

uint i = 0

for (i=0 i lt mysql_num_fields(res) i++)

printf(s row[i])

printf(n)

return 0

Step 2 Compile

gcc -Iusrlocalmysqlinclude -Lusrlocalmysqllibmysql mysqlcc ndashlm -lmysqlclient

(其中 include path與 library path取決於你的 MySQL安裝路徑)

76

如果執行時發生如下 error Run problemerror in loading shared libraries libmysqlclientsoX 將你的 MySQL library path(for exampleusrlocalmysqllibmysql) 加入etcldsoconf and run sbinldconfig -v Q9ASP + MySQL 範例程式 Ans Dim myconn As New ADODBConnection Dim myrs As New Recordset Dim mySQL As String Dim myrows As Long myconnOpen DSN=MyODBCsample mySQL = SELECT from user myrsSource = mySQL Set myrsActiveConnection = myconn myrsCursorLocation = adUseClient myrsOpen myrows = myrsRecordCount myrsClose myconnClose 可參考 httpwwwdwamnetmysqlasp_myodbcasp 有詳細的資料 Q10如何將 MySQL中的資料庫匯出成txt檔 Ans select from TableName into outfile textxls all result fields will seperate by tab

77

第八章 參考資料

英文部份 網址 1 httpwwwmysqlcom MySQL 網站有第一手有關 MySQL的資料 2 httpwwwmysqlcomdocenReplicationhtml 有關 MySQL Replication 的文件 3 httpwwwgeocitiescomsqlhomefaqstore_blobhtml 如何在 MySQL 存放 BLOB的資料 4httpwwwsapdborg 有關 SAP跟 MySQL相關合作的網站 書藉 1 Cooking with MySQL

Paul DuBois has selected sample recipes from the hundreds youll find in his book MySQL

Cookbook In this third and final series of excerpts showcasing these recipes learn how to

compute team standings how to calculate the differences between successive Dec 26

2002 2 Tips for Building Web Database Applications with PHP and MySQL by Hugh E Williams co-author of Web Database Applications with PHP amp MySQL 04042002

3 Managing and Using MySQL 2nd Edition By Tim King George Reese Randy Jay Yarger

4 MySQL Cookbook By Paul DuBoisPublisher OReillyPub Date October 2002

中文部份

78

1 httplinuxtncedutwtechdocmysqlmysql_docmanual_tochtml MySQL 中文手冊 2 httpchenshloxaedutwphpZ_1php PHP+MySQ程式研習設計網站 3 httplinuxtncedutwtechdocbanicdownhtml PHP 4 手冊 4 httpwwwtncedutwadmin_zonephp台南縣教育網網路中心有很多 Linux相關文件 5 httpdobtncedutw網站建置百寶箱有很多 PHP MySQL 相關範例程式 5 httpwwwdbworldcomtw資料庫專家電子雜誌介紹資料庫的重要觀念及名詞

79

附錄一 SQL Command 介紹

SQL (讀音ess-que-el) 是一種結構查詢語法SQL 使用於資料庫交流

傳遞相容於 ANSI (American National Standards Institute) 是一套標準的關聯

式資料庫語言 SQL 語言是執行更新或從資料系統獲取資料一般常見的關聯

資料庫系統都有提供 SQL 如 Oracle Sybase Microsoft SQL Server Access Ingres 等雖然大部份的資料庫都有提供 SQL 但也多提供了自已獨特的語

法造成了不相容的情形但標準基本的語法是相通的如Select Insert Update Delete Create and Drop 每一個系統都有支援

Table相關 Command

Create Table

關聯式資料庫包含有很多元件稱為資料表(tables) 把資料或訊息放在資

料表中 資料表是以不同的名稱做分別資料表由欄列所構成的二維陣列

欄包含欄位名資料型態 及其他可判斷的資訊列是由全部欄位構成一筆一

筆的紀錄 create table 語法用在建立一個新的資料表語法格式如下

create table tablename (column1 data type column2 data type column3 data type)

Format of create table if you were to use optional constraints

create table tablename (column1 data type [constraint] column2 data type [constraint] column3 data type [constraint]) [ ] = optional

Note You may have as many columns as youd like and the constraints are optional

80

Example

create table employee (first varchar(15) last varchar(20) age number(3) address varchar(30) city varchar(20) state varchar(20))

注意建立資料表格式要以括號把前後框住而最後以(分號)做結尾

欄位名不要超過 30個字元長而且不要使用 sql 的關鍵字(如 where select等)而在後面接是型態的宣告(如字串數字日期格式等)

資料型態是來描述欄位的方式如一個欄位Last_Name 是一個姓氏可以使用varchar (可變動長度字串) 資料型態

以下是幾個常見的資料庫型態 char(size) 固定長度字串最長為 255 位元 varchar(size) 變動長度字串最大字元數以 size 來指定 number(size) 數值格式可以是整數也可以是小數最大數字以 size 位數判

斷未指定小數位數由系統內定 date 日期格式 number(sized) 數值格式最大數字以 size 位數判斷d 為小數位數整數位

數為 size-d 位

有何限制當資料表被建立通常有一或數個欄位是要使用來做關聯的功

能 例如unique 限制(唯一值)兩筆記錄不可以相同的值 not null (非空值)該欄位一定要輸入資料不可是空的primary key (主鍵)是每一筆記錄識別的主要方式

Drop a table drop table 刪除資料表(其中的資料也會一併刪除)

drop table tablename

Example

81

drop table 和刪除全部資料是不同的刪除全部資料欄位名稱資訊等還會

存在但刪除資料表會把這一些也一併移除掉

如何查詢資料

Select 基本用法

select 語法是關連式資料庫最常用的部份可以取得你想要的資料這是一個

簡單的範例 select column1[column2etc] from tablename [where condition] [] = optional 在 select 之後所列欄位名則是要顯示的資料部份你可以一一列出各欄位

名或是以 (星號)來代表選擇全部的欄位 from 之後放資料表名稱 where 子句 (選項) 指定要過濾的條件符合者才會顯現 where 可使用的條件運算元 = 等於 gt 大於 lt 小於 gt= 大或等於 lt= 小或等於 ltgt 大相等 LIKE 相似 For example select first last city

82

from empinfo where first LIKE Er 以Er 為開頭的字串就符合要以單引號框住 Or you can specify select first last from empinfo where last LIKE s 最後一字為 S 就符合 select from empinfo where first = Eric 則表示 first name 一定要是 Eric 才可以 範例資料表empinfo 統計函數

MIN 傳回指定欄位最小值

MAX 傳回指定欄位最大值

SUM 傳回指定欄位總和

AVG 傳回指定欄位平均值

COUNT 傳回指定欄位的筆數

COUNT() 傳回資料庫中的總筆數

統計函數使用於資料表中的數值欄位配合 SELECT 語法使用 只用於總結特定單一欄位可以配合 GROUP BY 做篩選但也可以不使用 GROUP BY 語句For example

SELECT AVG(salary) FROM employee

83

傳回全部 salary 平均值

Another example

SELECT AVG(salary) FROM employee WHERE title = Programmer

傳回 salary 平均值條件為 employees 資料表中當 title 等於 Programmer

Example

SELECT Count() FROM employees

傳回 employees 資料表中紀錄總筆數

GROUP BY 語法 SELECT column1 SUM(column2) FROM list-of-tables GROUP BY column-list The GROUP BY 語句可以先以所列的欄位為條件分組排序在一起(可以多欄

位) example 要列出每一個 dept 中最高 salary 值 SELECT max(salary) dept FROM employee GROUP BY dept HAVING 語法

SELECT column1 SUM(column2) FROM list-of-tables GROUP BY column-list HAVING condition

HAVING 子句是 GROUP BY 的一部份用來過濾在 GROUP BY 所選出的資料功能如同 select 命令中 where 條件式一樣只是 HAVING 必需配合 GROUP BY 使用

我們以例子來說明我們要取得每一公司名及每一公司的薪水平均值輸入如下

84

SELECT dept avg(salary) FROM employee GROUP BY dept

但如果我們只列出薪資平均值超過 20000元的公司資料

SELECT dept avg(salary) FROM employee GROUP BY dept HAVING avg(salary) gt 20000

ORDER BY子句語法

SELECT column1 SUM(column2) FROM list-of-tables ORDER BY column-list [ASC | DESC]

[ ] =選項

ORDER BY是一個選項子句當你以排序方式來顯示資料(正向由小到大反向由大到小)以指定的欄位資料做排序

ASC = 正向- 預設值 DESC = 反向排序

For example

SELECT employee_id dept name age salary FROM employee_info WHERE dept = Sales ORDER BY salary

以上列出公司代號公司名銷售員人名年紀及薪資而條件是公司名為 Sales 顯示順序以薪資多少排序(由小到大為預設值)

如果要以多個欄位做排序要以逗號做分隔如下

SELECT employee_id dept name age salary FROM employee_info WHERE dept = Sales ORDER BY salary age DESC

85

結合條件及布林運算 SELECT column1 SUM(column2) FROM list-of-tables WHERE condition1 AND condition2 AND運算可以結兩個或以上的條件放在 WHERE子句中 兩者都要為真才

會顯示該筆記錄 OR 運算可以結兩個或以上敘述放在 WHERE子句中只要其中一個為直就

會顯示該筆記錄 For example SELECT employeeid firstname lastname title salary FROM employee_info WHERE salary gt= 5000000 AND title = Programmer 必需要薪資大於等於 50000而且職稱為 Programmer同時符合才會顯示該筆資料 以下以括號括住雖然不是必需的但如此比較容易讀 SELECT employeeid firstname lastname title salary FROM employee_info WHERE (salary gt= 5000000) AND (title = Programmer) 另外範例 SELECT firstname lastname title salary FROM employee_info WHERE (title = Sales) OR (title = Programmer) 條件為只要是 Sales 或 Programmer 職稱的就會被列出 IN and BETWEEN 子句

SELECT column1 SUM(column2) FROM list-of-tables WHERE column3 IN (list-of-values) SELECT column1 SUM(column2) FROM list-of-tables WHERE column3 BETWEEN value1 AND value2 IN 子句使用在列舉項目的使用上也就是分別測試是否符合所列的值 For example

86

SELECT employeeid lastname salary FROM employee_info WHERE lastname IN (Hernandez Jones Roberts Ruiz) 條件為姓氏(astname)要符合 Hernandez Jones Roberts or Ruiz 其中一個才會被傳回 IN運算元也可以使用 OR 的語法來取代如下結果相同 SELECT employeeid lastname salary FROM employee_info WHERE lastname = Hernandez OR lastname = Jones OR lastname = Roberts OR lastname = Ruiz 但使用 IN 句子比較短也比較易懂 你也可以使用 NOT IN 來去掉不要的記錄 BETWEEN 運算元使用在判斷是否存在兩個數值之間 For example SELECT employeeid age lastname salary FROM employee_info WHERE age BETWEEN 30 AND 40 傳回年紀 30歲到 40歲之間的資料(含 30及 40歲者) 相同的也可以使用以下語法來達到相同的結果 SELECT employeeid age lastname salary FROM employee_info WHERE age gt= 30 AND age lt= 40 你也可使用 NOT BETWEEN 來濾掉中間值的資料 數學運算 標準 ANSI SQL-92 提供以下運算

87

+ 加

- 減

餘數

餘數為除法後剩整數這不在標準的 ANSI SQL 中但大部份的資料庫都會支

援這運算元以下列出有用的函數雖不在 ANSI SQL-92 提供但一般資料庫

也會支援他們

ABS(x) 傳回 x 絕對值

SIGN(x) returns the sign of input x as -1 0 or 1 (negative zero or positive respectively)

MOD(xy) 餘數 - returns the integer remainder of x divided by y (同 xy)

FLOOR(x) 傳回小或等於 x 的最大整數值

CEILING(x) or CEIL(x)

傳回大或等於 x 的最小整數值

POWER(xy) x的 y 次方

ROUND(x) 把 x 四捨五入為整數

ROUND(xd) 四捨五入取到小數 d 位

SQRT(x) x 開平方

For example SELECT round(salary) firstname FROM employee_info 傳回薪資取到整數位

如何新增資料

insert 加入一筆新紀錄到資料表中 insert into tablename (first_columnlast_column) values (first_valuelast_value) [] = optional Example insert into employee

88

(first last age address city state) values (Luke Duke 45 2130 Boars Nest Hazard Co Georgia) Note 字串要以單引號住如string 數字框住也無妨 insert into 後面接資料表名稱再接以括號括住的欄位名在 values 後括號分別對映各欄位的值 以上的例子新增了一筆名(first) 為 Luke而住所(state) 為 Georgia 的資料

如何刪除資料

delete 可以刪除單筆或多筆紀錄 delete from tablename where columnname OPERATOR value [and|or column OPERATOR value] [ ] = optional Examples delete from employee Note 如果你沒有指定 where 子句那麼全部的紀錄都會被刪除 delete from employee where lastname = May delete from employee where firstname = Mike or firstname = Eric delete from 接著資料表名 再接著是條件式判斷沒有條件式則全部紀錄會

被刪除

如何更新資料

update 用來更新你所指定的記錄要和 WHERE 配合小心使用 語法 update tablename set columnname = newvalue[nextcolumn = newvalue2] where columnname OPERATOR value [and|or column OPERATOR value] [] = optional Examples

89

update phone_book set area_code = 623 where prefix = 979 update phone_book set last_name = Smith prefix=555 suffix=9292 where last_name = Jones update employee set age = age+1 where first_name=Mary and last_name=Williams

90

附錄二Replication

測試環境

RedHat 90 + MySQL 32358 MySQL資料庫路徑 varlibmysql MySQL設定檔 etcmycnf Master IP 1921680100 Slave IP 1921680200 請至下列網址下載最新MySQL 32358套件並利用rpm ndashUvh 更新 httpupdatesredhatcom9enosi386

圖 最新 MySQL 套件

測試架構圖

91

1921680100

1921680200Master Server

erveSlave S r

圖 測試架構圖

測試步驟

Master server 部份 Step1 確認 MasterSlave機器上所裝的 MySQL版本能進行

replication( 32329 or higher ) Step2 在 Master MySQL上開放一個帳號給 Slave mysql ndashu root ndashp mysqlgtGRANT FILE ON TO repl1921680200 IDENTIFIED BY lsquoabc123rsquo mysqlgtq 上面是 Master開放一個帳號 repl密碼 abc123給 IP1921680200有檔案處理

的權限 Step3 shutdown MySQL on the Master mysqladmin ndashu root ndashp shutdown Step4 備份 Master所有資料庫 tar ndashcvf tmpmysql-snapshottar varlibmysql 注意tar的時候MySQL是要在 stop情況下 在mysql (wwwmysqlcom) 網站的FAQ有不用shutdown的方法

92

Step5 在 master機器上修改etcmycnf 在[mysqld]區段內加入參數 log-bin server-id=這邊設定 server-id=1 sql-bin-update-same binlog-do-db=CRM只針對 CRM資料庫做紀錄 Step6 Restart MySQL on the master service mysqld start 此時因為有加入 log-bin 參數因此開始有 index產生了在varlibmysql目錄下

有index檔案紀錄資料庫的異動 log Slave server 部份 Step1 在 slave設定etcmycnf 在[mysqld]區段加入 master-host= master-user= master-password= master-port= server-id= 這邊設定 master-host=1921680100 master-user=repl master-password=abc123 master-port=3306 server-id=2 master-connect-retry=60預設重試間隔 60秒 replicate-do-db=CRM告訴 slave只做 CRM資料庫的更新 log-slave-updates Step2 將 master上的 mysql-snapshottar copy到 slave上 用 ftp傳到 slave的tmp Step3 解壓縮 Master資料庫至 Slave Server上 cd varlib tar xvf tmpmysql-snapshottar chown ndashR mysqlmysql mysql

93

chmod ndashR 770 mysql (視情況) Step4 Restart MySQL on the slave server 這時在varlibmysql目錄會出現 masterinfo此檔案紀錄了 Master MySQL server的資訊

狀況測試

One-way replication

1921680100

1921680200Master Server

erveSlave S r

圖 One-way replication架構圖 Step1 Master跟 Slave網路及服務都正常情況下由 Master端異動資料後 到 Slave端瀏覽資料檢視是否有進行 replication Step2 模擬 Slave Server 當機 可用在於 slave真的當機或是 Slave 不一定需要一直跟 master connect將Slave MySQL server shutdown由 Master端異動資料到 slave端瀏覽此時Slave應該沒有被 replication 更新然後再將 Slave端 MySQL server start起來

預設 60秒後 Slave會嘗試跟 Master要求進行 replication再去 Slave端檢視是否有更新資料

94

Step3 模擬 Master當機因為是設定 One-way replication一旦 Master Server Slave端沒有 Master的 source可以 download Two-way replication 基於 Master當機狀況於是發展雙向 Replication即 1921680100 ( Host A ) 1921680200 ( Host B )都分別擔任 MasterSlave身分

1921680100

1921680200er

Server B MasterSlave Server

Server A MasterSlave Serv

圖 Two-way replication架構圖 以下是針對兩台 MySQL伺服器進行雙向 Replication Step1觀念同單向 replication只是改成 Master也有 Slave身分 Slave也有Master的身分先分別在 Server AServer B 都去 grant一個進行 replication的身分 [A]mysqlgtGRANT FILE ON TO repl1921680200 IDENTIFIED BY lsquoabc123rsquo [B]mysqlgt GRANT FILE ON TO repl1921680100 IDENTIFIED BY lsquoabc123rsquo Step2做完單向 replication後stop Server Aserver B MySQL service此時 AB資料是一樣的

95

修改etcmycnf設定 範例 Server A [mysqld] datadir=varlibmysql socket=varlibmysqlmysqlsock server-id=1 log-bin sql-bin-update-same binlog-do-db=CRM master-host=1921680200 master-user=repl master-password=abc123 log-slave-updates master-connect-retry=60 replicate-do-db=CRM Server B [mysqld] datadir=varlibmysql socket=varlibmysqlmysqlsock server-id=2 log-bin sql-bin-update-same binlog-do-db=CRM master-host=1921680100 master-user=repl master-password=abc123 log-slave-updates master-connect-retry=60 replicate-do-db=CRM 分別 start Server AServer B MySQL後此時雙方都是 MasterSlave身分一旦哪一方資料異動就會通知對方來 replication-若 replication失效則必須將Server AServer B的masterinfo及index00x 都砍掉然後分別 restart MySQL server進行測試檢視成果 實務上通常如果需要做Two-way replication通常會搭配Virtual Server使用

96

在前端架設一台Virtual Server不過此部份不在此份SOP討論範圍內有興趣

的讀者可參考 httpwwwlinuxvirtualserverorg 網站

1921680100 1921680200

Host A MasterSlave Server

Host B MasterSlave Server

Virtual Host

圖 Virtual Server + Two-way replication 架構圖

97

圖 High Availability Linux Virtual Server架構圖

98

  • COSA-SOP-03-006
  • 第一章 簡介
    • 11適用對象 (Audience)
    • 12 MySQL本身
    • 13 MySQL 40版跟50版重大的改進功能
    • 14 各家資料庫軟體比較
      • 第二章 前置需求
      • 第三章 安裝
        • 31 MySQL安裝
        • 32 phpMyAdmin安裝
        • 33 升級及注意事項
          • 第四章 MySQL管理
            • 41 Webmin 管理介面
            • 42 phpMyAdmin 的操作介面
            • 43管理指令介紹
              • 431 利用mysqladmin設定root的密碼
                  • 第五章 實用範例
                    • 51 任務一Web Base客戶通訊錄
                    • 52 任務二Web Base群組軟體 ( twig )
                      • 第六章 維護及更新程序
                        • 61 日常維護
                        • 62 更新程序
                        • 63 備份重要檔案
                        • 64 離線備份與還原
                        • 65 線上備份與還原
                          • 第七章 問題與解答
                          • 第八章 參考資料
                          • 附錄一 SQL Command 介紹
                          • 附錄二Replication
Page 61: DataBase Server Standard Operation Procedureebooks.lib.ntu.edu.tw/1_file/oss/63/93doc4-5.pdf · 業務的公司帶來了不少壓力,譬如微軟,甲骨文 ... 外的錢用在第三方的資料庫產品上,譬如就可以不用再購買甲骨文公司

Step 6 修改連結 MySQL 的帳號密碼 vi varwwwhtmltwigconfigdbconfigincphp3 $dbconfig[sqlusername] = root username $dbconfig[sqlpassword] = 1234 password

Step 7 其他設定檔

vi etchttpdconfhttpdconf 加入 AddType applicationx-httpd-php php3 在 DirectoryIndex最後加入 indexphp3 DirectoryIndex indexhtml indexhtmlvar indexphp3 在 AddDefaultCharset ISO-8859-1加上 AddDefaultCharset ISO-8859-1

vi etcphpini register_globals = On service httpd restart Step 8 sendmail 設定 vi etcmailsendmailcf在 264 行前面加上並重新啟動 sendmail「service snedmail restart」 262 SMTP daemon options 263 264 O DaemonPortOptions=Port=smtpAddr=127001 Name=MTA 265 266 SMTP client options 267 O ClientPortOptions=Family=inet Address=00

61

Step 9 檢查設定有無錯誤 http主機名稱twigtestphp3

62

Step 10 登入 twig ( http主機名稱twig)

63

第六章 維護及更新程序

61 日常維護

系統管理員最好定期以 root 身份登入看看信件在 RedHat Linux 中有一支 logwatch 程式會定時去分析 log file如果發現異常便會發信給 root除此之外筆者建議讀者平時就檢查 MySQL log file ( varlogmysqldlog)是否有異常情形

62 更新程序

讀者可至httprpmfindnet 尋找MySQL相關套件至於升級的相關步驟請參

考Linux OS SOP 第 54節

63 備份重要檔案

預設 MySQL 的 DB 檔案是存在 varlibmysql 內以 DB名稱為目錄目錄

內就是該 DB 的所有資料通常得定期備份還有 MySQL的設定檔 etcmycnf也別忘了一起備份

64 離線備份與還原

641 離線備份

預設 MySQL 的 DB 檔案是存在 varlibmysql 內以 DB 名稱為目錄目錄內

就是該 DB 的所有資料像 CRM 這個 DB就是存在 varlibmysqlCRM 內在備份前因為怕資料尚未完全寫入磁碟而且 MySQL 會 Lock 在使用的 DB 檔案所以應該是要先把 MySQL 先 Shutdown 一下整個備份的程序可以下像下面的指令去完成 cd varlibmysql

64

service mysqld stop tar cvfz CRM_db_20030905tgz CRM service mysqld start 對這樣就可以了 不過要注意的是怕 DB 內每個 Tables 間的資料有關關

聯性所以最好是把整個 DB 一次備起來單獨只備哪個 Tables 的檔案以後回存時怕會有資料關聯不一致的問題

642 離線還原

DB 發生錯誤而要回存時其實也不難先找出最近一次完整正常的備份先把現在錯誤的網頁或 DB 先更名或 tar 起來再把好的備份給解開回原來目錄位

置就行了需要注意的是 MySQL 服務最好也是要先停止回存完成後再啟動服務回存 DB 的整個程序可能像下面 cd varlibmysql service mysqldstop mv CRM CRM_OLD tar xvfz CRM_db_20030905tg service mysqld start

65 線上備份與還原

651 線上備份

使用像上面的檔案方式備份是個不錯的方法它最少可以保持該主機某個時間點的完整檔案備份但還是有一些問題需要考慮到有些主機就不只建立一個 DB 而已總不能為了備份某個 DB 而把整個 MySQL 服務停止備份檔案的方式回存在原主機上一定適用但假如 MySQL 版本升級或是在那天該網頁空間需遷機移機到別的主機時那就沒人敢保證備出來的資料檔可以用所以我們可以考慮另一種備份的方式是使用 MySQL 本身提供的功能 MySQL Data Dump指令是 mysqldump

65

使用 MySQL 的 Dump 功能可以把 DB 的結構資料或結構加資料 Dump 成文字檔 mysqldump 指令提供的彈性很大你可以選擇把整個 DB Dump 成一個檔或是每個 Table 為一個檔甚至是把結構檔和資料分開儲存都

可以 mysqladmin -uroot -p flush-logs mysqldump CRM -uroot -p --opt gt CRM_20030905sql (CRM 是 DB 名稱 opt 是一個使用完整 Dump 參數) 假如只是要單獨 Dump 某個 Table 時只要在上面的指令後轉出符號 gt 前加個 Table 名稱就可以如只要 phpbb2_users 這個 Table 的 Dump 時只要下 mysqldump CRM -uroot -p --opt CUSTOMER gt CRM_CUSTOMER_20030905sql

652 線上還原

若要回存整個資料庫只需將壓縮的備份檔還原成 Dump 的檔案再用下面的指令回存 mysql CRM -uroot -p lt CRM_20030905sql 這邊需注意的是若建立備份時是以--opt或--add-drop-table為參數時回存的 動作是先將舊的 Table 先刪除重建 Table 的結構後再把 Data 匯入所以回存後所有的資料會回到你當時備份那個時間點因此在回存資料時可以考慮把現有錯誤或不完整的 DB 先備份一份下來以備不時之需或是拿來比對錯誤的地

方在那裡當然你也可以把資料回存到另一個測試用的 DB 內只要把上面指令

的 DB 名稱改成你的測試用 DB 名稱即可 使用這種回存方式 MySQL 服務不需停止也不會動到其他正在使用的 DB 在一些提供 MySQL 服務的虛擬主機可用這種方式作你自己的 DB 備份及回存

66

另外假如你是系統重建或是移機時切需在新的 MySQL 內新建一個空白 DB 後才行作回存的工作你可以用下面的指令建立 mysql -uroot -p -e CREATE DATABASE CRM (上面的 CRM是你要新建的 DB 名稱) 另一種作法先用 mysql 指令進入 mysql client console 然後再用 CREATE DATABASE CRM 這樣就行了記得尾端要加個 符號該行指令才會執行

67

第七章 問題與解答

Q1RedHat 90預附的 MySQL到底有無支援 Transcation機制 Ans MySQL自 32334a之後的 MySQL-Max版本加入 InnoDB的資料庫類型透過

InnoDBMySQL同樣可以進行 COMMIT與 ROLLRACK的動作RedHat 90預附的 MySQL為 32354a-11巳支援 InnoDB的資料庫類型不過必須做以

下設定 1cp usrsharedocmysql-server-32354amy-mediumcnf to etcmycnf 2 vi etcmycnf 將以下設定前的拿掉 innodb_data_home_dir = varlibmysql innodb_data_file_path = ibdata110Mautoextend innodb_log_group_home_dir = varlibmysql innodb_log_arch_dir = varlibmysql 3service mysqld restart 如此一來各位在建立Table時便可指定Table Type為 innodb ( ex create table with type=innodb ) Q2如何解決 php+mysql 許功蓋等字變亂的問題 Ans 方法一 【確定 MySQL 預設的字元集】 1 打開 WinMySQLadmin 管理畫面(在視窗右下角狀態列紅綠燈圖示中按滑鼠

右鍵點選 Show me 選項) 2 點選管理畫面中 [Variables] 標籤選項其中 character_set變數就是您預設

字元集的變數其預設是 latin1 字元集(我們要將他改回 big5)而 chatacters_set 變數則是 MySQL 可以支援哪些字元集 【修改預設字元集變數 character_set 】 1 請點選管理畫面中 [myini Setup] 標籤選項設定 myini 2 按一下 [Pick-up and Edit myini values] 按鈕以便編輯目前的 myini 設定 3 在 [mysqld] 設定區塊底下新增一行 default-character-set = big5 變數設

68

定 4 新增一個 [client] 設定區塊並加入第三步驟的變數設定(游標往下移到空白處新增兩行 [client] 和 default-character-set=big5) 5 按一下畫面左下方 [Save Modification] 按鈕儲存設定 6 重新啟動 MySQL 或 Windows 方法二 Server端注意事項 phpini 中有關的設定為(預設值) Magic quotes for incoming GETPOSTCookie data magic_quotes_gpc = On Use Sybase-style magic quotes (escape with instead of ) magic_quotes_sybase = Off Client端注意事項 1中文資料送進 mysql 前請用 addslashes($str) 處理 2處理後送進 mysql 時請用 括起來並在參數後留一個空白如 $sql = UPDATE ezf_table set tablename=$tname tableend=$endtime table inguser=$tguser tableingid=$tguserid tableallnumber=$tnumber tableloca l=$tablelocal tableanyone=$tableopen tabletext=$ttext WHERE tableid=$t ableid tablename=$tname c 取出時請用 stripslashes($str) Q3MySQL root 密碼忘了該怎麼辦 Ans 1先停掉 mysql etcrcdinitdmysql stop 2以--skip-grant-table 的參數啟動 mysql safe_mysql --skip-grant-tableamp 3 更改 root 密碼 mysql mysql mysqlgt UPDATE user SET password=password(newpassword)

69

WHERE user=root mysqlgt FLUSH PRIVILEGES mysqlgt exit 4停掉 mysql再重跑 mysqladmin -uroot -p shutdown Enter password 輸入新設定的密碼 etcrcdinitdmysql start

Q4NULL值問題

Ans

NULL值的概念是造成 SQL的新手的混淆的普遍原因他們經常認為 NULL是和一個空字符串的一樣的東西不是這樣的例如下列語句是完全不同的

mysqlgt INSERT INTO my_table (phone) VALUES (NULL)

mysqlgt INSERT INTO my_table (phone) VALUES ()

兩個語句把值插入到 phone 列但是第一個插入一個 NULL值而第二個插入一個空字符串第一個的含義可以認為是ldquo電話號碼不知道而第二個則可意味

著ldquo她沒有電話

在 SQL中NULL值在于任何其他值甚至 NULL值比較時總是假的(FALSE)包含 NULL的一個表達式總是產生一個 NULL值除非在包含在表達式中的運算符和函數的文檔中指出在下列例子所有的列返回 NULL

mysqlgt SELECT NULL1+NULLCONCAT(InvisibleNULL)

如果你想要尋找值是 NULL的列你不能使用=NULL測試下列語句不返回任

何行因為對任何表達式expr = NULL是假的

mysqlgt SELECT FROM my_table WHERE phone = NULL

要想尋找 NULL值你必須使用 IS NULL測試下例顯示如何找出 NULL電話號碼和空的電話號碼

70

mysqlgt SELECT FROM my_table WHERE phone IS NULL mysqlgt SELECT FROM my_table WHERE phone =

在 MySQL中就像很多其他的 SQL服務器一樣你不能索引可以有 NULL值的列你必須聲明這樣的列為 NOT NULL而且你不能插入 NULL到索引的

列中

當用 LOAD DATA INFILE 讀取數據時空列用更新如果你想要在一個列中有

NULL值你應該在文本文件中使用N字面上的詞NULL也可以在某些情形下使用

當使用 ORDER BY時首先呈現 NULL值如果你用 DESC以降序排序NULL值最後顯示當使用 GROUP BY時所有的 NULL值被認為是相等的

為了有助于NULL的處理你能使用 IS NULL和 IS NOT NULL運算符和 IFNULL()函數

對某些列類型NULL值被特殊地處理如果你將 NULL插入表的第一個TIMESTAMP 列則插入當前的日期和時間如果你將 NULL插入一個AUTO_INCREMENT 列則插入順序中的下一個數字

Q5如何將圖片存放於 MySQL中

Ans

Step 1建立資料庫 test

Step 2 建立表格 binary_data

CREATE TABLE binary_data (

id INT(4) NOT NULL AUTO_INCREMENT PRIMARY KEY

description CHAR(50)

bin_data LONGBLOB

filename CHAR(50)

filesize CHAR(50)

filetype CHAR(50)

71

)

Step 3 利用 storephp 寫入圖片

storephp 程式碼

ltHTMLgt ltHEADgtltTITLEgtStore binary data into SQL DatabaseltTITLEgtltHEADgt ltBODYgt lt code that will be executed if the form has been submitted

if ($submit) mysql_connect(localhostrootYOUR_PASSWORD) mysql_select_db(test) $data=Base64_Encode(fread(fopen($form_data r) filesize($form_data))) $result=MYSQL_QUERY(INSERT INTO binary_data (descriptionbin_datafilenamefilesizefiletype) VALUES ($form_description$data$form_data_name$form_data_size$form_data_type)) $id= mysql_insert_id() print ltpgtThis file has the following Database ID ltbgt$idltbgt MYSQL_CLOSE() else else show the form to submit new data

gt

ltform method=post action=ltphp echo $PHP_SELF gt enctype=multipartform-datagt File Descriptionltbrgt ltinput type=text name=form_description size=40gt ltINPUT TYPE=hidden name=MAX_FILE_SIZE value=4000000gt ltbrgtFile to uploadstore in databaseltbrgt ltinput type=file name=form_data size=40gt ltpgtltinput type=submit name=submit value=submitgt ltformgt lt

72

gt ltBODYgt ltHTMLgt

Step 3 利用 storephp 取出圖片

getdataphp 程式碼

lt Syntax getdataphp3id=ltidgt if($id) you may have to modify login information for your database server MYSQL_CONNECT(localhostrootYOUR_PASSWORD) mysql_select_db(test) $query = select bin_datafiletype from binary_data where id=$id $result = MYSQL_QUERY($query) $data = Base64_Decode(MYSQL_RESULT($result0bin_data)) $type = MYSQL_RESULT($result0filetype) Header( Content-type $type) echo $data gt

Q6MySQL裝好之後啟動時或是執行 mysqladmin會出現如下訊息 Cant connect to local MYSQL Server through Socket varlibmysqlmysqlsock或是

Cant connect to local MYSQL Server through Socket tmpmysqldsock

Ans 可能有下列幾個原因

1這個 mysqldsock 不見了被某人刪除了或是被一些系統自動執行程式給刪

了例如有些 cron任務便會設定定期刪除 tmp 裡的東西所以呢您只能修改

cron 裡的設定讓它不要清除 mysqldsock 2在啟動時也可以改變 mysqldsock的位置您在啟動 MySQL的時候可以加入此參數usrlocalmysqlbinsafe_mysqld --user=mysql --socket=其他路

徑socket amp 同時得去設定環境變數 MYSQL_UNIX_PORT的值以指定新的

73

路徑 3若是您沒改 MYSQL_UNIX_PORT的值那麼您可以在執行指令的時候才打

例如mysqladmin --socket=其他路徑socket version Q7How to get the last insert id Ans CREATE TABLE product ( id INT(4) NOT NULL AUTO_INCREMENT PRIMARY KEY description VARCHAR(50) ) 1利用 SQL的話 mysqlgt insert into product(description) values(123) Query OK 1 row affected (000 sec) mysqlgt select last_insert_id() +------------------+ | last_insert_id() | +------------------+ +------------------+ 1 row in set (000 sec) ======================================== 2如果是 PHP的話 你可以用mysql_insert_id()取得該 id PHP example $result=MYSQL_QUERY(INSERT INTO product (description) VALUES ($description)) $id= mysql_insert_id() print This file has the following Database ID $id Q8如何將文字檔匯入資料庫 Ans $addr=homehttpdhtmlphpschool001txt $sql_select = load data infile $addr into table test fields terminated by t 解說 $sql_select = load data infile 文字檔名 into table 表格名 fields terminated by

74

t

(欄位分隔以 TAB鍵) 該文字檔須與資料表欄位格式相符 例如欄位有三個 則文字檔為每行一筆資料如下 欄 1資料ltTABgt欄 2資料ltTABgt欄 3資料 欄 1資料ltTABgt欄 2資料ltTABgt欄 3資料 欄 1資料ltTABgt欄 2資料ltTABgt欄 3資料 欄 1資料ltTABgtltTABgt欄 3資料

Q9如何撰寫 MySQL C API Ans Step 1利用文字編輯器撰寫以下程式碼 mysqlcc

include ltstdiohgt

include ltmysqlmysqlhgt

int main (int argc char argv[])

MYSQL mysql

MYSQL_RES res

MYSQL_ROW row

if (argc = 2)

fputs (Usage myc ltdatabasegt stderr)

return 1

if ((mysql_connect(ampmysqllocalhostrootYour_Password)))

fputs (Error connecting stderr)

abort()

75

if (mysql_select_db(ampmysqlargv[1]))

fputs (Error selecting database stderr)

abort()

if (mysql_query(ampmysqlSELECT FROM test_table))

fputs (Error processing query stderr)

abort()

if ((res = mysql_store_result(ampmysql)))

fputs (Error storing results stderr)

abort()

while((row = mysql_fetch_row(res)))

uint i = 0

for (i=0 i lt mysql_num_fields(res) i++)

printf(s row[i])

printf(n)

return 0

Step 2 Compile

gcc -Iusrlocalmysqlinclude -Lusrlocalmysqllibmysql mysqlcc ndashlm -lmysqlclient

(其中 include path與 library path取決於你的 MySQL安裝路徑)

76

如果執行時發生如下 error Run problemerror in loading shared libraries libmysqlclientsoX 將你的 MySQL library path(for exampleusrlocalmysqllibmysql) 加入etcldsoconf and run sbinldconfig -v Q9ASP + MySQL 範例程式 Ans Dim myconn As New ADODBConnection Dim myrs As New Recordset Dim mySQL As String Dim myrows As Long myconnOpen DSN=MyODBCsample mySQL = SELECT from user myrsSource = mySQL Set myrsActiveConnection = myconn myrsCursorLocation = adUseClient myrsOpen myrows = myrsRecordCount myrsClose myconnClose 可參考 httpwwwdwamnetmysqlasp_myodbcasp 有詳細的資料 Q10如何將 MySQL中的資料庫匯出成txt檔 Ans select from TableName into outfile textxls all result fields will seperate by tab

77

第八章 參考資料

英文部份 網址 1 httpwwwmysqlcom MySQL 網站有第一手有關 MySQL的資料 2 httpwwwmysqlcomdocenReplicationhtml 有關 MySQL Replication 的文件 3 httpwwwgeocitiescomsqlhomefaqstore_blobhtml 如何在 MySQL 存放 BLOB的資料 4httpwwwsapdborg 有關 SAP跟 MySQL相關合作的網站 書藉 1 Cooking with MySQL

Paul DuBois has selected sample recipes from the hundreds youll find in his book MySQL

Cookbook In this third and final series of excerpts showcasing these recipes learn how to

compute team standings how to calculate the differences between successive Dec 26

2002 2 Tips for Building Web Database Applications with PHP and MySQL by Hugh E Williams co-author of Web Database Applications with PHP amp MySQL 04042002

3 Managing and Using MySQL 2nd Edition By Tim King George Reese Randy Jay Yarger

4 MySQL Cookbook By Paul DuBoisPublisher OReillyPub Date October 2002

中文部份

78

1 httplinuxtncedutwtechdocmysqlmysql_docmanual_tochtml MySQL 中文手冊 2 httpchenshloxaedutwphpZ_1php PHP+MySQ程式研習設計網站 3 httplinuxtncedutwtechdocbanicdownhtml PHP 4 手冊 4 httpwwwtncedutwadmin_zonephp台南縣教育網網路中心有很多 Linux相關文件 5 httpdobtncedutw網站建置百寶箱有很多 PHP MySQL 相關範例程式 5 httpwwwdbworldcomtw資料庫專家電子雜誌介紹資料庫的重要觀念及名詞

79

附錄一 SQL Command 介紹

SQL (讀音ess-que-el) 是一種結構查詢語法SQL 使用於資料庫交流

傳遞相容於 ANSI (American National Standards Institute) 是一套標準的關聯

式資料庫語言 SQL 語言是執行更新或從資料系統獲取資料一般常見的關聯

資料庫系統都有提供 SQL 如 Oracle Sybase Microsoft SQL Server Access Ingres 等雖然大部份的資料庫都有提供 SQL 但也多提供了自已獨特的語

法造成了不相容的情形但標準基本的語法是相通的如Select Insert Update Delete Create and Drop 每一個系統都有支援

Table相關 Command

Create Table

關聯式資料庫包含有很多元件稱為資料表(tables) 把資料或訊息放在資

料表中 資料表是以不同的名稱做分別資料表由欄列所構成的二維陣列

欄包含欄位名資料型態 及其他可判斷的資訊列是由全部欄位構成一筆一

筆的紀錄 create table 語法用在建立一個新的資料表語法格式如下

create table tablename (column1 data type column2 data type column3 data type)

Format of create table if you were to use optional constraints

create table tablename (column1 data type [constraint] column2 data type [constraint] column3 data type [constraint]) [ ] = optional

Note You may have as many columns as youd like and the constraints are optional

80

Example

create table employee (first varchar(15) last varchar(20) age number(3) address varchar(30) city varchar(20) state varchar(20))

注意建立資料表格式要以括號把前後框住而最後以(分號)做結尾

欄位名不要超過 30個字元長而且不要使用 sql 的關鍵字(如 where select等)而在後面接是型態的宣告(如字串數字日期格式等)

資料型態是來描述欄位的方式如一個欄位Last_Name 是一個姓氏可以使用varchar (可變動長度字串) 資料型態

以下是幾個常見的資料庫型態 char(size) 固定長度字串最長為 255 位元 varchar(size) 變動長度字串最大字元數以 size 來指定 number(size) 數值格式可以是整數也可以是小數最大數字以 size 位數判

斷未指定小數位數由系統內定 date 日期格式 number(sized) 數值格式最大數字以 size 位數判斷d 為小數位數整數位

數為 size-d 位

有何限制當資料表被建立通常有一或數個欄位是要使用來做關聯的功

能 例如unique 限制(唯一值)兩筆記錄不可以相同的值 not null (非空值)該欄位一定要輸入資料不可是空的primary key (主鍵)是每一筆記錄識別的主要方式

Drop a table drop table 刪除資料表(其中的資料也會一併刪除)

drop table tablename

Example

81

drop table 和刪除全部資料是不同的刪除全部資料欄位名稱資訊等還會

存在但刪除資料表會把這一些也一併移除掉

如何查詢資料

Select 基本用法

select 語法是關連式資料庫最常用的部份可以取得你想要的資料這是一個

簡單的範例 select column1[column2etc] from tablename [where condition] [] = optional 在 select 之後所列欄位名則是要顯示的資料部份你可以一一列出各欄位

名或是以 (星號)來代表選擇全部的欄位 from 之後放資料表名稱 where 子句 (選項) 指定要過濾的條件符合者才會顯現 where 可使用的條件運算元 = 等於 gt 大於 lt 小於 gt= 大或等於 lt= 小或等於 ltgt 大相等 LIKE 相似 For example select first last city

82

from empinfo where first LIKE Er 以Er 為開頭的字串就符合要以單引號框住 Or you can specify select first last from empinfo where last LIKE s 最後一字為 S 就符合 select from empinfo where first = Eric 則表示 first name 一定要是 Eric 才可以 範例資料表empinfo 統計函數

MIN 傳回指定欄位最小值

MAX 傳回指定欄位最大值

SUM 傳回指定欄位總和

AVG 傳回指定欄位平均值

COUNT 傳回指定欄位的筆數

COUNT() 傳回資料庫中的總筆數

統計函數使用於資料表中的數值欄位配合 SELECT 語法使用 只用於總結特定單一欄位可以配合 GROUP BY 做篩選但也可以不使用 GROUP BY 語句For example

SELECT AVG(salary) FROM employee

83

傳回全部 salary 平均值

Another example

SELECT AVG(salary) FROM employee WHERE title = Programmer

傳回 salary 平均值條件為 employees 資料表中當 title 等於 Programmer

Example

SELECT Count() FROM employees

傳回 employees 資料表中紀錄總筆數

GROUP BY 語法 SELECT column1 SUM(column2) FROM list-of-tables GROUP BY column-list The GROUP BY 語句可以先以所列的欄位為條件分組排序在一起(可以多欄

位) example 要列出每一個 dept 中最高 salary 值 SELECT max(salary) dept FROM employee GROUP BY dept HAVING 語法

SELECT column1 SUM(column2) FROM list-of-tables GROUP BY column-list HAVING condition

HAVING 子句是 GROUP BY 的一部份用來過濾在 GROUP BY 所選出的資料功能如同 select 命令中 where 條件式一樣只是 HAVING 必需配合 GROUP BY 使用

我們以例子來說明我們要取得每一公司名及每一公司的薪水平均值輸入如下

84

SELECT dept avg(salary) FROM employee GROUP BY dept

但如果我們只列出薪資平均值超過 20000元的公司資料

SELECT dept avg(salary) FROM employee GROUP BY dept HAVING avg(salary) gt 20000

ORDER BY子句語法

SELECT column1 SUM(column2) FROM list-of-tables ORDER BY column-list [ASC | DESC]

[ ] =選項

ORDER BY是一個選項子句當你以排序方式來顯示資料(正向由小到大反向由大到小)以指定的欄位資料做排序

ASC = 正向- 預設值 DESC = 反向排序

For example

SELECT employee_id dept name age salary FROM employee_info WHERE dept = Sales ORDER BY salary

以上列出公司代號公司名銷售員人名年紀及薪資而條件是公司名為 Sales 顯示順序以薪資多少排序(由小到大為預設值)

如果要以多個欄位做排序要以逗號做分隔如下

SELECT employee_id dept name age salary FROM employee_info WHERE dept = Sales ORDER BY salary age DESC

85

結合條件及布林運算 SELECT column1 SUM(column2) FROM list-of-tables WHERE condition1 AND condition2 AND運算可以結兩個或以上的條件放在 WHERE子句中 兩者都要為真才

會顯示該筆記錄 OR 運算可以結兩個或以上敘述放在 WHERE子句中只要其中一個為直就

會顯示該筆記錄 For example SELECT employeeid firstname lastname title salary FROM employee_info WHERE salary gt= 5000000 AND title = Programmer 必需要薪資大於等於 50000而且職稱為 Programmer同時符合才會顯示該筆資料 以下以括號括住雖然不是必需的但如此比較容易讀 SELECT employeeid firstname lastname title salary FROM employee_info WHERE (salary gt= 5000000) AND (title = Programmer) 另外範例 SELECT firstname lastname title salary FROM employee_info WHERE (title = Sales) OR (title = Programmer) 條件為只要是 Sales 或 Programmer 職稱的就會被列出 IN and BETWEEN 子句

SELECT column1 SUM(column2) FROM list-of-tables WHERE column3 IN (list-of-values) SELECT column1 SUM(column2) FROM list-of-tables WHERE column3 BETWEEN value1 AND value2 IN 子句使用在列舉項目的使用上也就是分別測試是否符合所列的值 For example

86

SELECT employeeid lastname salary FROM employee_info WHERE lastname IN (Hernandez Jones Roberts Ruiz) 條件為姓氏(astname)要符合 Hernandez Jones Roberts or Ruiz 其中一個才會被傳回 IN運算元也可以使用 OR 的語法來取代如下結果相同 SELECT employeeid lastname salary FROM employee_info WHERE lastname = Hernandez OR lastname = Jones OR lastname = Roberts OR lastname = Ruiz 但使用 IN 句子比較短也比較易懂 你也可以使用 NOT IN 來去掉不要的記錄 BETWEEN 運算元使用在判斷是否存在兩個數值之間 For example SELECT employeeid age lastname salary FROM employee_info WHERE age BETWEEN 30 AND 40 傳回年紀 30歲到 40歲之間的資料(含 30及 40歲者) 相同的也可以使用以下語法來達到相同的結果 SELECT employeeid age lastname salary FROM employee_info WHERE age gt= 30 AND age lt= 40 你也可使用 NOT BETWEEN 來濾掉中間值的資料 數學運算 標準 ANSI SQL-92 提供以下運算

87

+ 加

- 減

餘數

餘數為除法後剩整數這不在標準的 ANSI SQL 中但大部份的資料庫都會支

援這運算元以下列出有用的函數雖不在 ANSI SQL-92 提供但一般資料庫

也會支援他們

ABS(x) 傳回 x 絕對值

SIGN(x) returns the sign of input x as -1 0 or 1 (negative zero or positive respectively)

MOD(xy) 餘數 - returns the integer remainder of x divided by y (同 xy)

FLOOR(x) 傳回小或等於 x 的最大整數值

CEILING(x) or CEIL(x)

傳回大或等於 x 的最小整數值

POWER(xy) x的 y 次方

ROUND(x) 把 x 四捨五入為整數

ROUND(xd) 四捨五入取到小數 d 位

SQRT(x) x 開平方

For example SELECT round(salary) firstname FROM employee_info 傳回薪資取到整數位

如何新增資料

insert 加入一筆新紀錄到資料表中 insert into tablename (first_columnlast_column) values (first_valuelast_value) [] = optional Example insert into employee

88

(first last age address city state) values (Luke Duke 45 2130 Boars Nest Hazard Co Georgia) Note 字串要以單引號住如string 數字框住也無妨 insert into 後面接資料表名稱再接以括號括住的欄位名在 values 後括號分別對映各欄位的值 以上的例子新增了一筆名(first) 為 Luke而住所(state) 為 Georgia 的資料

如何刪除資料

delete 可以刪除單筆或多筆紀錄 delete from tablename where columnname OPERATOR value [and|or column OPERATOR value] [ ] = optional Examples delete from employee Note 如果你沒有指定 where 子句那麼全部的紀錄都會被刪除 delete from employee where lastname = May delete from employee where firstname = Mike or firstname = Eric delete from 接著資料表名 再接著是條件式判斷沒有條件式則全部紀錄會

被刪除

如何更新資料

update 用來更新你所指定的記錄要和 WHERE 配合小心使用 語法 update tablename set columnname = newvalue[nextcolumn = newvalue2] where columnname OPERATOR value [and|or column OPERATOR value] [] = optional Examples

89

update phone_book set area_code = 623 where prefix = 979 update phone_book set last_name = Smith prefix=555 suffix=9292 where last_name = Jones update employee set age = age+1 where first_name=Mary and last_name=Williams

90

附錄二Replication

測試環境

RedHat 90 + MySQL 32358 MySQL資料庫路徑 varlibmysql MySQL設定檔 etcmycnf Master IP 1921680100 Slave IP 1921680200 請至下列網址下載最新MySQL 32358套件並利用rpm ndashUvh 更新 httpupdatesredhatcom9enosi386

圖 最新 MySQL 套件

測試架構圖

91

1921680100

1921680200Master Server

erveSlave S r

圖 測試架構圖

測試步驟

Master server 部份 Step1 確認 MasterSlave機器上所裝的 MySQL版本能進行

replication( 32329 or higher ) Step2 在 Master MySQL上開放一個帳號給 Slave mysql ndashu root ndashp mysqlgtGRANT FILE ON TO repl1921680200 IDENTIFIED BY lsquoabc123rsquo mysqlgtq 上面是 Master開放一個帳號 repl密碼 abc123給 IP1921680200有檔案處理

的權限 Step3 shutdown MySQL on the Master mysqladmin ndashu root ndashp shutdown Step4 備份 Master所有資料庫 tar ndashcvf tmpmysql-snapshottar varlibmysql 注意tar的時候MySQL是要在 stop情況下 在mysql (wwwmysqlcom) 網站的FAQ有不用shutdown的方法

92

Step5 在 master機器上修改etcmycnf 在[mysqld]區段內加入參數 log-bin server-id=這邊設定 server-id=1 sql-bin-update-same binlog-do-db=CRM只針對 CRM資料庫做紀錄 Step6 Restart MySQL on the master service mysqld start 此時因為有加入 log-bin 參數因此開始有 index產生了在varlibmysql目錄下

有index檔案紀錄資料庫的異動 log Slave server 部份 Step1 在 slave設定etcmycnf 在[mysqld]區段加入 master-host= master-user= master-password= master-port= server-id= 這邊設定 master-host=1921680100 master-user=repl master-password=abc123 master-port=3306 server-id=2 master-connect-retry=60預設重試間隔 60秒 replicate-do-db=CRM告訴 slave只做 CRM資料庫的更新 log-slave-updates Step2 將 master上的 mysql-snapshottar copy到 slave上 用 ftp傳到 slave的tmp Step3 解壓縮 Master資料庫至 Slave Server上 cd varlib tar xvf tmpmysql-snapshottar chown ndashR mysqlmysql mysql

93

chmod ndashR 770 mysql (視情況) Step4 Restart MySQL on the slave server 這時在varlibmysql目錄會出現 masterinfo此檔案紀錄了 Master MySQL server的資訊

狀況測試

One-way replication

1921680100

1921680200Master Server

erveSlave S r

圖 One-way replication架構圖 Step1 Master跟 Slave網路及服務都正常情況下由 Master端異動資料後 到 Slave端瀏覽資料檢視是否有進行 replication Step2 模擬 Slave Server 當機 可用在於 slave真的當機或是 Slave 不一定需要一直跟 master connect將Slave MySQL server shutdown由 Master端異動資料到 slave端瀏覽此時Slave應該沒有被 replication 更新然後再將 Slave端 MySQL server start起來

預設 60秒後 Slave會嘗試跟 Master要求進行 replication再去 Slave端檢視是否有更新資料

94

Step3 模擬 Master當機因為是設定 One-way replication一旦 Master Server Slave端沒有 Master的 source可以 download Two-way replication 基於 Master當機狀況於是發展雙向 Replication即 1921680100 ( Host A ) 1921680200 ( Host B )都分別擔任 MasterSlave身分

1921680100

1921680200er

Server B MasterSlave Server

Server A MasterSlave Serv

圖 Two-way replication架構圖 以下是針對兩台 MySQL伺服器進行雙向 Replication Step1觀念同單向 replication只是改成 Master也有 Slave身分 Slave也有Master的身分先分別在 Server AServer B 都去 grant一個進行 replication的身分 [A]mysqlgtGRANT FILE ON TO repl1921680200 IDENTIFIED BY lsquoabc123rsquo [B]mysqlgt GRANT FILE ON TO repl1921680100 IDENTIFIED BY lsquoabc123rsquo Step2做完單向 replication後stop Server Aserver B MySQL service此時 AB資料是一樣的

95

修改etcmycnf設定 範例 Server A [mysqld] datadir=varlibmysql socket=varlibmysqlmysqlsock server-id=1 log-bin sql-bin-update-same binlog-do-db=CRM master-host=1921680200 master-user=repl master-password=abc123 log-slave-updates master-connect-retry=60 replicate-do-db=CRM Server B [mysqld] datadir=varlibmysql socket=varlibmysqlmysqlsock server-id=2 log-bin sql-bin-update-same binlog-do-db=CRM master-host=1921680100 master-user=repl master-password=abc123 log-slave-updates master-connect-retry=60 replicate-do-db=CRM 分別 start Server AServer B MySQL後此時雙方都是 MasterSlave身分一旦哪一方資料異動就會通知對方來 replication-若 replication失效則必須將Server AServer B的masterinfo及index00x 都砍掉然後分別 restart MySQL server進行測試檢視成果 實務上通常如果需要做Two-way replication通常會搭配Virtual Server使用

96

在前端架設一台Virtual Server不過此部份不在此份SOP討論範圍內有興趣

的讀者可參考 httpwwwlinuxvirtualserverorg 網站

1921680100 1921680200

Host A MasterSlave Server

Host B MasterSlave Server

Virtual Host

圖 Virtual Server + Two-way replication 架構圖

97

圖 High Availability Linux Virtual Server架構圖

98

  • COSA-SOP-03-006
  • 第一章 簡介
    • 11適用對象 (Audience)
    • 12 MySQL本身
    • 13 MySQL 40版跟50版重大的改進功能
    • 14 各家資料庫軟體比較
      • 第二章 前置需求
      • 第三章 安裝
        • 31 MySQL安裝
        • 32 phpMyAdmin安裝
        • 33 升級及注意事項
          • 第四章 MySQL管理
            • 41 Webmin 管理介面
            • 42 phpMyAdmin 的操作介面
            • 43管理指令介紹
              • 431 利用mysqladmin設定root的密碼
                  • 第五章 實用範例
                    • 51 任務一Web Base客戶通訊錄
                    • 52 任務二Web Base群組軟體 ( twig )
                      • 第六章 維護及更新程序
                        • 61 日常維護
                        • 62 更新程序
                        • 63 備份重要檔案
                        • 64 離線備份與還原
                        • 65 線上備份與還原
                          • 第七章 問題與解答
                          • 第八章 參考資料
                          • 附錄一 SQL Command 介紹
                          • 附錄二Replication
Page 62: DataBase Server Standard Operation Procedureebooks.lib.ntu.edu.tw/1_file/oss/63/93doc4-5.pdf · 業務的公司帶來了不少壓力,譬如微軟,甲骨文 ... 外的錢用在第三方的資料庫產品上,譬如就可以不用再購買甲骨文公司

Step 9 檢查設定有無錯誤 http主機名稱twigtestphp3

62

Step 10 登入 twig ( http主機名稱twig)

63

第六章 維護及更新程序

61 日常維護

系統管理員最好定期以 root 身份登入看看信件在 RedHat Linux 中有一支 logwatch 程式會定時去分析 log file如果發現異常便會發信給 root除此之外筆者建議讀者平時就檢查 MySQL log file ( varlogmysqldlog)是否有異常情形

62 更新程序

讀者可至httprpmfindnet 尋找MySQL相關套件至於升級的相關步驟請參

考Linux OS SOP 第 54節

63 備份重要檔案

預設 MySQL 的 DB 檔案是存在 varlibmysql 內以 DB名稱為目錄目錄

內就是該 DB 的所有資料通常得定期備份還有 MySQL的設定檔 etcmycnf也別忘了一起備份

64 離線備份與還原

641 離線備份

預設 MySQL 的 DB 檔案是存在 varlibmysql 內以 DB 名稱為目錄目錄內

就是該 DB 的所有資料像 CRM 這個 DB就是存在 varlibmysqlCRM 內在備份前因為怕資料尚未完全寫入磁碟而且 MySQL 會 Lock 在使用的 DB 檔案所以應該是要先把 MySQL 先 Shutdown 一下整個備份的程序可以下像下面的指令去完成 cd varlibmysql

64

service mysqld stop tar cvfz CRM_db_20030905tgz CRM service mysqld start 對這樣就可以了 不過要注意的是怕 DB 內每個 Tables 間的資料有關關

聯性所以最好是把整個 DB 一次備起來單獨只備哪個 Tables 的檔案以後回存時怕會有資料關聯不一致的問題

642 離線還原

DB 發生錯誤而要回存時其實也不難先找出最近一次完整正常的備份先把現在錯誤的網頁或 DB 先更名或 tar 起來再把好的備份給解開回原來目錄位

置就行了需要注意的是 MySQL 服務最好也是要先停止回存完成後再啟動服務回存 DB 的整個程序可能像下面 cd varlibmysql service mysqldstop mv CRM CRM_OLD tar xvfz CRM_db_20030905tg service mysqld start

65 線上備份與還原

651 線上備份

使用像上面的檔案方式備份是個不錯的方法它最少可以保持該主機某個時間點的完整檔案備份但還是有一些問題需要考慮到有些主機就不只建立一個 DB 而已總不能為了備份某個 DB 而把整個 MySQL 服務停止備份檔案的方式回存在原主機上一定適用但假如 MySQL 版本升級或是在那天該網頁空間需遷機移機到別的主機時那就沒人敢保證備出來的資料檔可以用所以我們可以考慮另一種備份的方式是使用 MySQL 本身提供的功能 MySQL Data Dump指令是 mysqldump

65

使用 MySQL 的 Dump 功能可以把 DB 的結構資料或結構加資料 Dump 成文字檔 mysqldump 指令提供的彈性很大你可以選擇把整個 DB Dump 成一個檔或是每個 Table 為一個檔甚至是把結構檔和資料分開儲存都

可以 mysqladmin -uroot -p flush-logs mysqldump CRM -uroot -p --opt gt CRM_20030905sql (CRM 是 DB 名稱 opt 是一個使用完整 Dump 參數) 假如只是要單獨 Dump 某個 Table 時只要在上面的指令後轉出符號 gt 前加個 Table 名稱就可以如只要 phpbb2_users 這個 Table 的 Dump 時只要下 mysqldump CRM -uroot -p --opt CUSTOMER gt CRM_CUSTOMER_20030905sql

652 線上還原

若要回存整個資料庫只需將壓縮的備份檔還原成 Dump 的檔案再用下面的指令回存 mysql CRM -uroot -p lt CRM_20030905sql 這邊需注意的是若建立備份時是以--opt或--add-drop-table為參數時回存的 動作是先將舊的 Table 先刪除重建 Table 的結構後再把 Data 匯入所以回存後所有的資料會回到你當時備份那個時間點因此在回存資料時可以考慮把現有錯誤或不完整的 DB 先備份一份下來以備不時之需或是拿來比對錯誤的地

方在那裡當然你也可以把資料回存到另一個測試用的 DB 內只要把上面指令

的 DB 名稱改成你的測試用 DB 名稱即可 使用這種回存方式 MySQL 服務不需停止也不會動到其他正在使用的 DB 在一些提供 MySQL 服務的虛擬主機可用這種方式作你自己的 DB 備份及回存

66

另外假如你是系統重建或是移機時切需在新的 MySQL 內新建一個空白 DB 後才行作回存的工作你可以用下面的指令建立 mysql -uroot -p -e CREATE DATABASE CRM (上面的 CRM是你要新建的 DB 名稱) 另一種作法先用 mysql 指令進入 mysql client console 然後再用 CREATE DATABASE CRM 這樣就行了記得尾端要加個 符號該行指令才會執行

67

第七章 問題與解答

Q1RedHat 90預附的 MySQL到底有無支援 Transcation機制 Ans MySQL自 32334a之後的 MySQL-Max版本加入 InnoDB的資料庫類型透過

InnoDBMySQL同樣可以進行 COMMIT與 ROLLRACK的動作RedHat 90預附的 MySQL為 32354a-11巳支援 InnoDB的資料庫類型不過必須做以

下設定 1cp usrsharedocmysql-server-32354amy-mediumcnf to etcmycnf 2 vi etcmycnf 將以下設定前的拿掉 innodb_data_home_dir = varlibmysql innodb_data_file_path = ibdata110Mautoextend innodb_log_group_home_dir = varlibmysql innodb_log_arch_dir = varlibmysql 3service mysqld restart 如此一來各位在建立Table時便可指定Table Type為 innodb ( ex create table with type=innodb ) Q2如何解決 php+mysql 許功蓋等字變亂的問題 Ans 方法一 【確定 MySQL 預設的字元集】 1 打開 WinMySQLadmin 管理畫面(在視窗右下角狀態列紅綠燈圖示中按滑鼠

右鍵點選 Show me 選項) 2 點選管理畫面中 [Variables] 標籤選項其中 character_set變數就是您預設

字元集的變數其預設是 latin1 字元集(我們要將他改回 big5)而 chatacters_set 變數則是 MySQL 可以支援哪些字元集 【修改預設字元集變數 character_set 】 1 請點選管理畫面中 [myini Setup] 標籤選項設定 myini 2 按一下 [Pick-up and Edit myini values] 按鈕以便編輯目前的 myini 設定 3 在 [mysqld] 設定區塊底下新增一行 default-character-set = big5 變數設

68

定 4 新增一個 [client] 設定區塊並加入第三步驟的變數設定(游標往下移到空白處新增兩行 [client] 和 default-character-set=big5) 5 按一下畫面左下方 [Save Modification] 按鈕儲存設定 6 重新啟動 MySQL 或 Windows 方法二 Server端注意事項 phpini 中有關的設定為(預設值) Magic quotes for incoming GETPOSTCookie data magic_quotes_gpc = On Use Sybase-style magic quotes (escape with instead of ) magic_quotes_sybase = Off Client端注意事項 1中文資料送進 mysql 前請用 addslashes($str) 處理 2處理後送進 mysql 時請用 括起來並在參數後留一個空白如 $sql = UPDATE ezf_table set tablename=$tname tableend=$endtime table inguser=$tguser tableingid=$tguserid tableallnumber=$tnumber tableloca l=$tablelocal tableanyone=$tableopen tabletext=$ttext WHERE tableid=$t ableid tablename=$tname c 取出時請用 stripslashes($str) Q3MySQL root 密碼忘了該怎麼辦 Ans 1先停掉 mysql etcrcdinitdmysql stop 2以--skip-grant-table 的參數啟動 mysql safe_mysql --skip-grant-tableamp 3 更改 root 密碼 mysql mysql mysqlgt UPDATE user SET password=password(newpassword)

69

WHERE user=root mysqlgt FLUSH PRIVILEGES mysqlgt exit 4停掉 mysql再重跑 mysqladmin -uroot -p shutdown Enter password 輸入新設定的密碼 etcrcdinitdmysql start

Q4NULL值問題

Ans

NULL值的概念是造成 SQL的新手的混淆的普遍原因他們經常認為 NULL是和一個空字符串的一樣的東西不是這樣的例如下列語句是完全不同的

mysqlgt INSERT INTO my_table (phone) VALUES (NULL)

mysqlgt INSERT INTO my_table (phone) VALUES ()

兩個語句把值插入到 phone 列但是第一個插入一個 NULL值而第二個插入一個空字符串第一個的含義可以認為是ldquo電話號碼不知道而第二個則可意味

著ldquo她沒有電話

在 SQL中NULL值在于任何其他值甚至 NULL值比較時總是假的(FALSE)包含 NULL的一個表達式總是產生一個 NULL值除非在包含在表達式中的運算符和函數的文檔中指出在下列例子所有的列返回 NULL

mysqlgt SELECT NULL1+NULLCONCAT(InvisibleNULL)

如果你想要尋找值是 NULL的列你不能使用=NULL測試下列語句不返回任

何行因為對任何表達式expr = NULL是假的

mysqlgt SELECT FROM my_table WHERE phone = NULL

要想尋找 NULL值你必須使用 IS NULL測試下例顯示如何找出 NULL電話號碼和空的電話號碼

70

mysqlgt SELECT FROM my_table WHERE phone IS NULL mysqlgt SELECT FROM my_table WHERE phone =

在 MySQL中就像很多其他的 SQL服務器一樣你不能索引可以有 NULL值的列你必須聲明這樣的列為 NOT NULL而且你不能插入 NULL到索引的

列中

當用 LOAD DATA INFILE 讀取數據時空列用更新如果你想要在一個列中有

NULL值你應該在文本文件中使用N字面上的詞NULL也可以在某些情形下使用

當使用 ORDER BY時首先呈現 NULL值如果你用 DESC以降序排序NULL值最後顯示當使用 GROUP BY時所有的 NULL值被認為是相等的

為了有助于NULL的處理你能使用 IS NULL和 IS NOT NULL運算符和 IFNULL()函數

對某些列類型NULL值被特殊地處理如果你將 NULL插入表的第一個TIMESTAMP 列則插入當前的日期和時間如果你將 NULL插入一個AUTO_INCREMENT 列則插入順序中的下一個數字

Q5如何將圖片存放於 MySQL中

Ans

Step 1建立資料庫 test

Step 2 建立表格 binary_data

CREATE TABLE binary_data (

id INT(4) NOT NULL AUTO_INCREMENT PRIMARY KEY

description CHAR(50)

bin_data LONGBLOB

filename CHAR(50)

filesize CHAR(50)

filetype CHAR(50)

71

)

Step 3 利用 storephp 寫入圖片

storephp 程式碼

ltHTMLgt ltHEADgtltTITLEgtStore binary data into SQL DatabaseltTITLEgtltHEADgt ltBODYgt lt code that will be executed if the form has been submitted

if ($submit) mysql_connect(localhostrootYOUR_PASSWORD) mysql_select_db(test) $data=Base64_Encode(fread(fopen($form_data r) filesize($form_data))) $result=MYSQL_QUERY(INSERT INTO binary_data (descriptionbin_datafilenamefilesizefiletype) VALUES ($form_description$data$form_data_name$form_data_size$form_data_type)) $id= mysql_insert_id() print ltpgtThis file has the following Database ID ltbgt$idltbgt MYSQL_CLOSE() else else show the form to submit new data

gt

ltform method=post action=ltphp echo $PHP_SELF gt enctype=multipartform-datagt File Descriptionltbrgt ltinput type=text name=form_description size=40gt ltINPUT TYPE=hidden name=MAX_FILE_SIZE value=4000000gt ltbrgtFile to uploadstore in databaseltbrgt ltinput type=file name=form_data size=40gt ltpgtltinput type=submit name=submit value=submitgt ltformgt lt

72

gt ltBODYgt ltHTMLgt

Step 3 利用 storephp 取出圖片

getdataphp 程式碼

lt Syntax getdataphp3id=ltidgt if($id) you may have to modify login information for your database server MYSQL_CONNECT(localhostrootYOUR_PASSWORD) mysql_select_db(test) $query = select bin_datafiletype from binary_data where id=$id $result = MYSQL_QUERY($query) $data = Base64_Decode(MYSQL_RESULT($result0bin_data)) $type = MYSQL_RESULT($result0filetype) Header( Content-type $type) echo $data gt

Q6MySQL裝好之後啟動時或是執行 mysqladmin會出現如下訊息 Cant connect to local MYSQL Server through Socket varlibmysqlmysqlsock或是

Cant connect to local MYSQL Server through Socket tmpmysqldsock

Ans 可能有下列幾個原因

1這個 mysqldsock 不見了被某人刪除了或是被一些系統自動執行程式給刪

了例如有些 cron任務便會設定定期刪除 tmp 裡的東西所以呢您只能修改

cron 裡的設定讓它不要清除 mysqldsock 2在啟動時也可以改變 mysqldsock的位置您在啟動 MySQL的時候可以加入此參數usrlocalmysqlbinsafe_mysqld --user=mysql --socket=其他路

徑socket amp 同時得去設定環境變數 MYSQL_UNIX_PORT的值以指定新的

73

路徑 3若是您沒改 MYSQL_UNIX_PORT的值那麼您可以在執行指令的時候才打

例如mysqladmin --socket=其他路徑socket version Q7How to get the last insert id Ans CREATE TABLE product ( id INT(4) NOT NULL AUTO_INCREMENT PRIMARY KEY description VARCHAR(50) ) 1利用 SQL的話 mysqlgt insert into product(description) values(123) Query OK 1 row affected (000 sec) mysqlgt select last_insert_id() +------------------+ | last_insert_id() | +------------------+ +------------------+ 1 row in set (000 sec) ======================================== 2如果是 PHP的話 你可以用mysql_insert_id()取得該 id PHP example $result=MYSQL_QUERY(INSERT INTO product (description) VALUES ($description)) $id= mysql_insert_id() print This file has the following Database ID $id Q8如何將文字檔匯入資料庫 Ans $addr=homehttpdhtmlphpschool001txt $sql_select = load data infile $addr into table test fields terminated by t 解說 $sql_select = load data infile 文字檔名 into table 表格名 fields terminated by

74

t

(欄位分隔以 TAB鍵) 該文字檔須與資料表欄位格式相符 例如欄位有三個 則文字檔為每行一筆資料如下 欄 1資料ltTABgt欄 2資料ltTABgt欄 3資料 欄 1資料ltTABgt欄 2資料ltTABgt欄 3資料 欄 1資料ltTABgt欄 2資料ltTABgt欄 3資料 欄 1資料ltTABgtltTABgt欄 3資料

Q9如何撰寫 MySQL C API Ans Step 1利用文字編輯器撰寫以下程式碼 mysqlcc

include ltstdiohgt

include ltmysqlmysqlhgt

int main (int argc char argv[])

MYSQL mysql

MYSQL_RES res

MYSQL_ROW row

if (argc = 2)

fputs (Usage myc ltdatabasegt stderr)

return 1

if ((mysql_connect(ampmysqllocalhostrootYour_Password)))

fputs (Error connecting stderr)

abort()

75

if (mysql_select_db(ampmysqlargv[1]))

fputs (Error selecting database stderr)

abort()

if (mysql_query(ampmysqlSELECT FROM test_table))

fputs (Error processing query stderr)

abort()

if ((res = mysql_store_result(ampmysql)))

fputs (Error storing results stderr)

abort()

while((row = mysql_fetch_row(res)))

uint i = 0

for (i=0 i lt mysql_num_fields(res) i++)

printf(s row[i])

printf(n)

return 0

Step 2 Compile

gcc -Iusrlocalmysqlinclude -Lusrlocalmysqllibmysql mysqlcc ndashlm -lmysqlclient

(其中 include path與 library path取決於你的 MySQL安裝路徑)

76

如果執行時發生如下 error Run problemerror in loading shared libraries libmysqlclientsoX 將你的 MySQL library path(for exampleusrlocalmysqllibmysql) 加入etcldsoconf and run sbinldconfig -v Q9ASP + MySQL 範例程式 Ans Dim myconn As New ADODBConnection Dim myrs As New Recordset Dim mySQL As String Dim myrows As Long myconnOpen DSN=MyODBCsample mySQL = SELECT from user myrsSource = mySQL Set myrsActiveConnection = myconn myrsCursorLocation = adUseClient myrsOpen myrows = myrsRecordCount myrsClose myconnClose 可參考 httpwwwdwamnetmysqlasp_myodbcasp 有詳細的資料 Q10如何將 MySQL中的資料庫匯出成txt檔 Ans select from TableName into outfile textxls all result fields will seperate by tab

77

第八章 參考資料

英文部份 網址 1 httpwwwmysqlcom MySQL 網站有第一手有關 MySQL的資料 2 httpwwwmysqlcomdocenReplicationhtml 有關 MySQL Replication 的文件 3 httpwwwgeocitiescomsqlhomefaqstore_blobhtml 如何在 MySQL 存放 BLOB的資料 4httpwwwsapdborg 有關 SAP跟 MySQL相關合作的網站 書藉 1 Cooking with MySQL

Paul DuBois has selected sample recipes from the hundreds youll find in his book MySQL

Cookbook In this third and final series of excerpts showcasing these recipes learn how to

compute team standings how to calculate the differences between successive Dec 26

2002 2 Tips for Building Web Database Applications with PHP and MySQL by Hugh E Williams co-author of Web Database Applications with PHP amp MySQL 04042002

3 Managing and Using MySQL 2nd Edition By Tim King George Reese Randy Jay Yarger

4 MySQL Cookbook By Paul DuBoisPublisher OReillyPub Date October 2002

中文部份

78

1 httplinuxtncedutwtechdocmysqlmysql_docmanual_tochtml MySQL 中文手冊 2 httpchenshloxaedutwphpZ_1php PHP+MySQ程式研習設計網站 3 httplinuxtncedutwtechdocbanicdownhtml PHP 4 手冊 4 httpwwwtncedutwadmin_zonephp台南縣教育網網路中心有很多 Linux相關文件 5 httpdobtncedutw網站建置百寶箱有很多 PHP MySQL 相關範例程式 5 httpwwwdbworldcomtw資料庫專家電子雜誌介紹資料庫的重要觀念及名詞

79

附錄一 SQL Command 介紹

SQL (讀音ess-que-el) 是一種結構查詢語法SQL 使用於資料庫交流

傳遞相容於 ANSI (American National Standards Institute) 是一套標準的關聯

式資料庫語言 SQL 語言是執行更新或從資料系統獲取資料一般常見的關聯

資料庫系統都有提供 SQL 如 Oracle Sybase Microsoft SQL Server Access Ingres 等雖然大部份的資料庫都有提供 SQL 但也多提供了自已獨特的語

法造成了不相容的情形但標準基本的語法是相通的如Select Insert Update Delete Create and Drop 每一個系統都有支援

Table相關 Command

Create Table

關聯式資料庫包含有很多元件稱為資料表(tables) 把資料或訊息放在資

料表中 資料表是以不同的名稱做分別資料表由欄列所構成的二維陣列

欄包含欄位名資料型態 及其他可判斷的資訊列是由全部欄位構成一筆一

筆的紀錄 create table 語法用在建立一個新的資料表語法格式如下

create table tablename (column1 data type column2 data type column3 data type)

Format of create table if you were to use optional constraints

create table tablename (column1 data type [constraint] column2 data type [constraint] column3 data type [constraint]) [ ] = optional

Note You may have as many columns as youd like and the constraints are optional

80

Example

create table employee (first varchar(15) last varchar(20) age number(3) address varchar(30) city varchar(20) state varchar(20))

注意建立資料表格式要以括號把前後框住而最後以(分號)做結尾

欄位名不要超過 30個字元長而且不要使用 sql 的關鍵字(如 where select等)而在後面接是型態的宣告(如字串數字日期格式等)

資料型態是來描述欄位的方式如一個欄位Last_Name 是一個姓氏可以使用varchar (可變動長度字串) 資料型態

以下是幾個常見的資料庫型態 char(size) 固定長度字串最長為 255 位元 varchar(size) 變動長度字串最大字元數以 size 來指定 number(size) 數值格式可以是整數也可以是小數最大數字以 size 位數判

斷未指定小數位數由系統內定 date 日期格式 number(sized) 數值格式最大數字以 size 位數判斷d 為小數位數整數位

數為 size-d 位

有何限制當資料表被建立通常有一或數個欄位是要使用來做關聯的功

能 例如unique 限制(唯一值)兩筆記錄不可以相同的值 not null (非空值)該欄位一定要輸入資料不可是空的primary key (主鍵)是每一筆記錄識別的主要方式

Drop a table drop table 刪除資料表(其中的資料也會一併刪除)

drop table tablename

Example

81

drop table 和刪除全部資料是不同的刪除全部資料欄位名稱資訊等還會

存在但刪除資料表會把這一些也一併移除掉

如何查詢資料

Select 基本用法

select 語法是關連式資料庫最常用的部份可以取得你想要的資料這是一個

簡單的範例 select column1[column2etc] from tablename [where condition] [] = optional 在 select 之後所列欄位名則是要顯示的資料部份你可以一一列出各欄位

名或是以 (星號)來代表選擇全部的欄位 from 之後放資料表名稱 where 子句 (選項) 指定要過濾的條件符合者才會顯現 where 可使用的條件運算元 = 等於 gt 大於 lt 小於 gt= 大或等於 lt= 小或等於 ltgt 大相等 LIKE 相似 For example select first last city

82

from empinfo where first LIKE Er 以Er 為開頭的字串就符合要以單引號框住 Or you can specify select first last from empinfo where last LIKE s 最後一字為 S 就符合 select from empinfo where first = Eric 則表示 first name 一定要是 Eric 才可以 範例資料表empinfo 統計函數

MIN 傳回指定欄位最小值

MAX 傳回指定欄位最大值

SUM 傳回指定欄位總和

AVG 傳回指定欄位平均值

COUNT 傳回指定欄位的筆數

COUNT() 傳回資料庫中的總筆數

統計函數使用於資料表中的數值欄位配合 SELECT 語法使用 只用於總結特定單一欄位可以配合 GROUP BY 做篩選但也可以不使用 GROUP BY 語句For example

SELECT AVG(salary) FROM employee

83

傳回全部 salary 平均值

Another example

SELECT AVG(salary) FROM employee WHERE title = Programmer

傳回 salary 平均值條件為 employees 資料表中當 title 等於 Programmer

Example

SELECT Count() FROM employees

傳回 employees 資料表中紀錄總筆數

GROUP BY 語法 SELECT column1 SUM(column2) FROM list-of-tables GROUP BY column-list The GROUP BY 語句可以先以所列的欄位為條件分組排序在一起(可以多欄

位) example 要列出每一個 dept 中最高 salary 值 SELECT max(salary) dept FROM employee GROUP BY dept HAVING 語法

SELECT column1 SUM(column2) FROM list-of-tables GROUP BY column-list HAVING condition

HAVING 子句是 GROUP BY 的一部份用來過濾在 GROUP BY 所選出的資料功能如同 select 命令中 where 條件式一樣只是 HAVING 必需配合 GROUP BY 使用

我們以例子來說明我們要取得每一公司名及每一公司的薪水平均值輸入如下

84

SELECT dept avg(salary) FROM employee GROUP BY dept

但如果我們只列出薪資平均值超過 20000元的公司資料

SELECT dept avg(salary) FROM employee GROUP BY dept HAVING avg(salary) gt 20000

ORDER BY子句語法

SELECT column1 SUM(column2) FROM list-of-tables ORDER BY column-list [ASC | DESC]

[ ] =選項

ORDER BY是一個選項子句當你以排序方式來顯示資料(正向由小到大反向由大到小)以指定的欄位資料做排序

ASC = 正向- 預設值 DESC = 反向排序

For example

SELECT employee_id dept name age salary FROM employee_info WHERE dept = Sales ORDER BY salary

以上列出公司代號公司名銷售員人名年紀及薪資而條件是公司名為 Sales 顯示順序以薪資多少排序(由小到大為預設值)

如果要以多個欄位做排序要以逗號做分隔如下

SELECT employee_id dept name age salary FROM employee_info WHERE dept = Sales ORDER BY salary age DESC

85

結合條件及布林運算 SELECT column1 SUM(column2) FROM list-of-tables WHERE condition1 AND condition2 AND運算可以結兩個或以上的條件放在 WHERE子句中 兩者都要為真才

會顯示該筆記錄 OR 運算可以結兩個或以上敘述放在 WHERE子句中只要其中一個為直就

會顯示該筆記錄 For example SELECT employeeid firstname lastname title salary FROM employee_info WHERE salary gt= 5000000 AND title = Programmer 必需要薪資大於等於 50000而且職稱為 Programmer同時符合才會顯示該筆資料 以下以括號括住雖然不是必需的但如此比較容易讀 SELECT employeeid firstname lastname title salary FROM employee_info WHERE (salary gt= 5000000) AND (title = Programmer) 另外範例 SELECT firstname lastname title salary FROM employee_info WHERE (title = Sales) OR (title = Programmer) 條件為只要是 Sales 或 Programmer 職稱的就會被列出 IN and BETWEEN 子句

SELECT column1 SUM(column2) FROM list-of-tables WHERE column3 IN (list-of-values) SELECT column1 SUM(column2) FROM list-of-tables WHERE column3 BETWEEN value1 AND value2 IN 子句使用在列舉項目的使用上也就是分別測試是否符合所列的值 For example

86

SELECT employeeid lastname salary FROM employee_info WHERE lastname IN (Hernandez Jones Roberts Ruiz) 條件為姓氏(astname)要符合 Hernandez Jones Roberts or Ruiz 其中一個才會被傳回 IN運算元也可以使用 OR 的語法來取代如下結果相同 SELECT employeeid lastname salary FROM employee_info WHERE lastname = Hernandez OR lastname = Jones OR lastname = Roberts OR lastname = Ruiz 但使用 IN 句子比較短也比較易懂 你也可以使用 NOT IN 來去掉不要的記錄 BETWEEN 運算元使用在判斷是否存在兩個數值之間 For example SELECT employeeid age lastname salary FROM employee_info WHERE age BETWEEN 30 AND 40 傳回年紀 30歲到 40歲之間的資料(含 30及 40歲者) 相同的也可以使用以下語法來達到相同的結果 SELECT employeeid age lastname salary FROM employee_info WHERE age gt= 30 AND age lt= 40 你也可使用 NOT BETWEEN 來濾掉中間值的資料 數學運算 標準 ANSI SQL-92 提供以下運算

87

+ 加

- 減

餘數

餘數為除法後剩整數這不在標準的 ANSI SQL 中但大部份的資料庫都會支

援這運算元以下列出有用的函數雖不在 ANSI SQL-92 提供但一般資料庫

也會支援他們

ABS(x) 傳回 x 絕對值

SIGN(x) returns the sign of input x as -1 0 or 1 (negative zero or positive respectively)

MOD(xy) 餘數 - returns the integer remainder of x divided by y (同 xy)

FLOOR(x) 傳回小或等於 x 的最大整數值

CEILING(x) or CEIL(x)

傳回大或等於 x 的最小整數值

POWER(xy) x的 y 次方

ROUND(x) 把 x 四捨五入為整數

ROUND(xd) 四捨五入取到小數 d 位

SQRT(x) x 開平方

For example SELECT round(salary) firstname FROM employee_info 傳回薪資取到整數位

如何新增資料

insert 加入一筆新紀錄到資料表中 insert into tablename (first_columnlast_column) values (first_valuelast_value) [] = optional Example insert into employee

88

(first last age address city state) values (Luke Duke 45 2130 Boars Nest Hazard Co Georgia) Note 字串要以單引號住如string 數字框住也無妨 insert into 後面接資料表名稱再接以括號括住的欄位名在 values 後括號分別對映各欄位的值 以上的例子新增了一筆名(first) 為 Luke而住所(state) 為 Georgia 的資料

如何刪除資料

delete 可以刪除單筆或多筆紀錄 delete from tablename where columnname OPERATOR value [and|or column OPERATOR value] [ ] = optional Examples delete from employee Note 如果你沒有指定 where 子句那麼全部的紀錄都會被刪除 delete from employee where lastname = May delete from employee where firstname = Mike or firstname = Eric delete from 接著資料表名 再接著是條件式判斷沒有條件式則全部紀錄會

被刪除

如何更新資料

update 用來更新你所指定的記錄要和 WHERE 配合小心使用 語法 update tablename set columnname = newvalue[nextcolumn = newvalue2] where columnname OPERATOR value [and|or column OPERATOR value] [] = optional Examples

89

update phone_book set area_code = 623 where prefix = 979 update phone_book set last_name = Smith prefix=555 suffix=9292 where last_name = Jones update employee set age = age+1 where first_name=Mary and last_name=Williams

90

附錄二Replication

測試環境

RedHat 90 + MySQL 32358 MySQL資料庫路徑 varlibmysql MySQL設定檔 etcmycnf Master IP 1921680100 Slave IP 1921680200 請至下列網址下載最新MySQL 32358套件並利用rpm ndashUvh 更新 httpupdatesredhatcom9enosi386

圖 最新 MySQL 套件

測試架構圖

91

1921680100

1921680200Master Server

erveSlave S r

圖 測試架構圖

測試步驟

Master server 部份 Step1 確認 MasterSlave機器上所裝的 MySQL版本能進行

replication( 32329 or higher ) Step2 在 Master MySQL上開放一個帳號給 Slave mysql ndashu root ndashp mysqlgtGRANT FILE ON TO repl1921680200 IDENTIFIED BY lsquoabc123rsquo mysqlgtq 上面是 Master開放一個帳號 repl密碼 abc123給 IP1921680200有檔案處理

的權限 Step3 shutdown MySQL on the Master mysqladmin ndashu root ndashp shutdown Step4 備份 Master所有資料庫 tar ndashcvf tmpmysql-snapshottar varlibmysql 注意tar的時候MySQL是要在 stop情況下 在mysql (wwwmysqlcom) 網站的FAQ有不用shutdown的方法

92

Step5 在 master機器上修改etcmycnf 在[mysqld]區段內加入參數 log-bin server-id=這邊設定 server-id=1 sql-bin-update-same binlog-do-db=CRM只針對 CRM資料庫做紀錄 Step6 Restart MySQL on the master service mysqld start 此時因為有加入 log-bin 參數因此開始有 index產生了在varlibmysql目錄下

有index檔案紀錄資料庫的異動 log Slave server 部份 Step1 在 slave設定etcmycnf 在[mysqld]區段加入 master-host= master-user= master-password= master-port= server-id= 這邊設定 master-host=1921680100 master-user=repl master-password=abc123 master-port=3306 server-id=2 master-connect-retry=60預設重試間隔 60秒 replicate-do-db=CRM告訴 slave只做 CRM資料庫的更新 log-slave-updates Step2 將 master上的 mysql-snapshottar copy到 slave上 用 ftp傳到 slave的tmp Step3 解壓縮 Master資料庫至 Slave Server上 cd varlib tar xvf tmpmysql-snapshottar chown ndashR mysqlmysql mysql

93

chmod ndashR 770 mysql (視情況) Step4 Restart MySQL on the slave server 這時在varlibmysql目錄會出現 masterinfo此檔案紀錄了 Master MySQL server的資訊

狀況測試

One-way replication

1921680100

1921680200Master Server

erveSlave S r

圖 One-way replication架構圖 Step1 Master跟 Slave網路及服務都正常情況下由 Master端異動資料後 到 Slave端瀏覽資料檢視是否有進行 replication Step2 模擬 Slave Server 當機 可用在於 slave真的當機或是 Slave 不一定需要一直跟 master connect將Slave MySQL server shutdown由 Master端異動資料到 slave端瀏覽此時Slave應該沒有被 replication 更新然後再將 Slave端 MySQL server start起來

預設 60秒後 Slave會嘗試跟 Master要求進行 replication再去 Slave端檢視是否有更新資料

94

Step3 模擬 Master當機因為是設定 One-way replication一旦 Master Server Slave端沒有 Master的 source可以 download Two-way replication 基於 Master當機狀況於是發展雙向 Replication即 1921680100 ( Host A ) 1921680200 ( Host B )都分別擔任 MasterSlave身分

1921680100

1921680200er

Server B MasterSlave Server

Server A MasterSlave Serv

圖 Two-way replication架構圖 以下是針對兩台 MySQL伺服器進行雙向 Replication Step1觀念同單向 replication只是改成 Master也有 Slave身分 Slave也有Master的身分先分別在 Server AServer B 都去 grant一個進行 replication的身分 [A]mysqlgtGRANT FILE ON TO repl1921680200 IDENTIFIED BY lsquoabc123rsquo [B]mysqlgt GRANT FILE ON TO repl1921680100 IDENTIFIED BY lsquoabc123rsquo Step2做完單向 replication後stop Server Aserver B MySQL service此時 AB資料是一樣的

95

修改etcmycnf設定 範例 Server A [mysqld] datadir=varlibmysql socket=varlibmysqlmysqlsock server-id=1 log-bin sql-bin-update-same binlog-do-db=CRM master-host=1921680200 master-user=repl master-password=abc123 log-slave-updates master-connect-retry=60 replicate-do-db=CRM Server B [mysqld] datadir=varlibmysql socket=varlibmysqlmysqlsock server-id=2 log-bin sql-bin-update-same binlog-do-db=CRM master-host=1921680100 master-user=repl master-password=abc123 log-slave-updates master-connect-retry=60 replicate-do-db=CRM 分別 start Server AServer B MySQL後此時雙方都是 MasterSlave身分一旦哪一方資料異動就會通知對方來 replication-若 replication失效則必須將Server AServer B的masterinfo及index00x 都砍掉然後分別 restart MySQL server進行測試檢視成果 實務上通常如果需要做Two-way replication通常會搭配Virtual Server使用

96

在前端架設一台Virtual Server不過此部份不在此份SOP討論範圍內有興趣

的讀者可參考 httpwwwlinuxvirtualserverorg 網站

1921680100 1921680200

Host A MasterSlave Server

Host B MasterSlave Server

Virtual Host

圖 Virtual Server + Two-way replication 架構圖

97

圖 High Availability Linux Virtual Server架構圖

98

  • COSA-SOP-03-006
  • 第一章 簡介
    • 11適用對象 (Audience)
    • 12 MySQL本身
    • 13 MySQL 40版跟50版重大的改進功能
    • 14 各家資料庫軟體比較
      • 第二章 前置需求
      • 第三章 安裝
        • 31 MySQL安裝
        • 32 phpMyAdmin安裝
        • 33 升級及注意事項
          • 第四章 MySQL管理
            • 41 Webmin 管理介面
            • 42 phpMyAdmin 的操作介面
            • 43管理指令介紹
              • 431 利用mysqladmin設定root的密碼
                  • 第五章 實用範例
                    • 51 任務一Web Base客戶通訊錄
                    • 52 任務二Web Base群組軟體 ( twig )
                      • 第六章 維護及更新程序
                        • 61 日常維護
                        • 62 更新程序
                        • 63 備份重要檔案
                        • 64 離線備份與還原
                        • 65 線上備份與還原
                          • 第七章 問題與解答
                          • 第八章 參考資料
                          • 附錄一 SQL Command 介紹
                          • 附錄二Replication
Page 63: DataBase Server Standard Operation Procedureebooks.lib.ntu.edu.tw/1_file/oss/63/93doc4-5.pdf · 業務的公司帶來了不少壓力,譬如微軟,甲骨文 ... 外的錢用在第三方的資料庫產品上,譬如就可以不用再購買甲骨文公司

Step 10 登入 twig ( http主機名稱twig)

63

第六章 維護及更新程序

61 日常維護

系統管理員最好定期以 root 身份登入看看信件在 RedHat Linux 中有一支 logwatch 程式會定時去分析 log file如果發現異常便會發信給 root除此之外筆者建議讀者平時就檢查 MySQL log file ( varlogmysqldlog)是否有異常情形

62 更新程序

讀者可至httprpmfindnet 尋找MySQL相關套件至於升級的相關步驟請參

考Linux OS SOP 第 54節

63 備份重要檔案

預設 MySQL 的 DB 檔案是存在 varlibmysql 內以 DB名稱為目錄目錄

內就是該 DB 的所有資料通常得定期備份還有 MySQL的設定檔 etcmycnf也別忘了一起備份

64 離線備份與還原

641 離線備份

預設 MySQL 的 DB 檔案是存在 varlibmysql 內以 DB 名稱為目錄目錄內

就是該 DB 的所有資料像 CRM 這個 DB就是存在 varlibmysqlCRM 內在備份前因為怕資料尚未完全寫入磁碟而且 MySQL 會 Lock 在使用的 DB 檔案所以應該是要先把 MySQL 先 Shutdown 一下整個備份的程序可以下像下面的指令去完成 cd varlibmysql

64

service mysqld stop tar cvfz CRM_db_20030905tgz CRM service mysqld start 對這樣就可以了 不過要注意的是怕 DB 內每個 Tables 間的資料有關關

聯性所以最好是把整個 DB 一次備起來單獨只備哪個 Tables 的檔案以後回存時怕會有資料關聯不一致的問題

642 離線還原

DB 發生錯誤而要回存時其實也不難先找出最近一次完整正常的備份先把現在錯誤的網頁或 DB 先更名或 tar 起來再把好的備份給解開回原來目錄位

置就行了需要注意的是 MySQL 服務最好也是要先停止回存完成後再啟動服務回存 DB 的整個程序可能像下面 cd varlibmysql service mysqldstop mv CRM CRM_OLD tar xvfz CRM_db_20030905tg service mysqld start

65 線上備份與還原

651 線上備份

使用像上面的檔案方式備份是個不錯的方法它最少可以保持該主機某個時間點的完整檔案備份但還是有一些問題需要考慮到有些主機就不只建立一個 DB 而已總不能為了備份某個 DB 而把整個 MySQL 服務停止備份檔案的方式回存在原主機上一定適用但假如 MySQL 版本升級或是在那天該網頁空間需遷機移機到別的主機時那就沒人敢保證備出來的資料檔可以用所以我們可以考慮另一種備份的方式是使用 MySQL 本身提供的功能 MySQL Data Dump指令是 mysqldump

65

使用 MySQL 的 Dump 功能可以把 DB 的結構資料或結構加資料 Dump 成文字檔 mysqldump 指令提供的彈性很大你可以選擇把整個 DB Dump 成一個檔或是每個 Table 為一個檔甚至是把結構檔和資料分開儲存都

可以 mysqladmin -uroot -p flush-logs mysqldump CRM -uroot -p --opt gt CRM_20030905sql (CRM 是 DB 名稱 opt 是一個使用完整 Dump 參數) 假如只是要單獨 Dump 某個 Table 時只要在上面的指令後轉出符號 gt 前加個 Table 名稱就可以如只要 phpbb2_users 這個 Table 的 Dump 時只要下 mysqldump CRM -uroot -p --opt CUSTOMER gt CRM_CUSTOMER_20030905sql

652 線上還原

若要回存整個資料庫只需將壓縮的備份檔還原成 Dump 的檔案再用下面的指令回存 mysql CRM -uroot -p lt CRM_20030905sql 這邊需注意的是若建立備份時是以--opt或--add-drop-table為參數時回存的 動作是先將舊的 Table 先刪除重建 Table 的結構後再把 Data 匯入所以回存後所有的資料會回到你當時備份那個時間點因此在回存資料時可以考慮把現有錯誤或不完整的 DB 先備份一份下來以備不時之需或是拿來比對錯誤的地

方在那裡當然你也可以把資料回存到另一個測試用的 DB 內只要把上面指令

的 DB 名稱改成你的測試用 DB 名稱即可 使用這種回存方式 MySQL 服務不需停止也不會動到其他正在使用的 DB 在一些提供 MySQL 服務的虛擬主機可用這種方式作你自己的 DB 備份及回存

66

另外假如你是系統重建或是移機時切需在新的 MySQL 內新建一個空白 DB 後才行作回存的工作你可以用下面的指令建立 mysql -uroot -p -e CREATE DATABASE CRM (上面的 CRM是你要新建的 DB 名稱) 另一種作法先用 mysql 指令進入 mysql client console 然後再用 CREATE DATABASE CRM 這樣就行了記得尾端要加個 符號該行指令才會執行

67

第七章 問題與解答

Q1RedHat 90預附的 MySQL到底有無支援 Transcation機制 Ans MySQL自 32334a之後的 MySQL-Max版本加入 InnoDB的資料庫類型透過

InnoDBMySQL同樣可以進行 COMMIT與 ROLLRACK的動作RedHat 90預附的 MySQL為 32354a-11巳支援 InnoDB的資料庫類型不過必須做以

下設定 1cp usrsharedocmysql-server-32354amy-mediumcnf to etcmycnf 2 vi etcmycnf 將以下設定前的拿掉 innodb_data_home_dir = varlibmysql innodb_data_file_path = ibdata110Mautoextend innodb_log_group_home_dir = varlibmysql innodb_log_arch_dir = varlibmysql 3service mysqld restart 如此一來各位在建立Table時便可指定Table Type為 innodb ( ex create table with type=innodb ) Q2如何解決 php+mysql 許功蓋等字變亂的問題 Ans 方法一 【確定 MySQL 預設的字元集】 1 打開 WinMySQLadmin 管理畫面(在視窗右下角狀態列紅綠燈圖示中按滑鼠

右鍵點選 Show me 選項) 2 點選管理畫面中 [Variables] 標籤選項其中 character_set變數就是您預設

字元集的變數其預設是 latin1 字元集(我們要將他改回 big5)而 chatacters_set 變數則是 MySQL 可以支援哪些字元集 【修改預設字元集變數 character_set 】 1 請點選管理畫面中 [myini Setup] 標籤選項設定 myini 2 按一下 [Pick-up and Edit myini values] 按鈕以便編輯目前的 myini 設定 3 在 [mysqld] 設定區塊底下新增一行 default-character-set = big5 變數設

68

定 4 新增一個 [client] 設定區塊並加入第三步驟的變數設定(游標往下移到空白處新增兩行 [client] 和 default-character-set=big5) 5 按一下畫面左下方 [Save Modification] 按鈕儲存設定 6 重新啟動 MySQL 或 Windows 方法二 Server端注意事項 phpini 中有關的設定為(預設值) Magic quotes for incoming GETPOSTCookie data magic_quotes_gpc = On Use Sybase-style magic quotes (escape with instead of ) magic_quotes_sybase = Off Client端注意事項 1中文資料送進 mysql 前請用 addslashes($str) 處理 2處理後送進 mysql 時請用 括起來並在參數後留一個空白如 $sql = UPDATE ezf_table set tablename=$tname tableend=$endtime table inguser=$tguser tableingid=$tguserid tableallnumber=$tnumber tableloca l=$tablelocal tableanyone=$tableopen tabletext=$ttext WHERE tableid=$t ableid tablename=$tname c 取出時請用 stripslashes($str) Q3MySQL root 密碼忘了該怎麼辦 Ans 1先停掉 mysql etcrcdinitdmysql stop 2以--skip-grant-table 的參數啟動 mysql safe_mysql --skip-grant-tableamp 3 更改 root 密碼 mysql mysql mysqlgt UPDATE user SET password=password(newpassword)

69

WHERE user=root mysqlgt FLUSH PRIVILEGES mysqlgt exit 4停掉 mysql再重跑 mysqladmin -uroot -p shutdown Enter password 輸入新設定的密碼 etcrcdinitdmysql start

Q4NULL值問題

Ans

NULL值的概念是造成 SQL的新手的混淆的普遍原因他們經常認為 NULL是和一個空字符串的一樣的東西不是這樣的例如下列語句是完全不同的

mysqlgt INSERT INTO my_table (phone) VALUES (NULL)

mysqlgt INSERT INTO my_table (phone) VALUES ()

兩個語句把值插入到 phone 列但是第一個插入一個 NULL值而第二個插入一個空字符串第一個的含義可以認為是ldquo電話號碼不知道而第二個則可意味

著ldquo她沒有電話

在 SQL中NULL值在于任何其他值甚至 NULL值比較時總是假的(FALSE)包含 NULL的一個表達式總是產生一個 NULL值除非在包含在表達式中的運算符和函數的文檔中指出在下列例子所有的列返回 NULL

mysqlgt SELECT NULL1+NULLCONCAT(InvisibleNULL)

如果你想要尋找值是 NULL的列你不能使用=NULL測試下列語句不返回任

何行因為對任何表達式expr = NULL是假的

mysqlgt SELECT FROM my_table WHERE phone = NULL

要想尋找 NULL值你必須使用 IS NULL測試下例顯示如何找出 NULL電話號碼和空的電話號碼

70

mysqlgt SELECT FROM my_table WHERE phone IS NULL mysqlgt SELECT FROM my_table WHERE phone =

在 MySQL中就像很多其他的 SQL服務器一樣你不能索引可以有 NULL值的列你必須聲明這樣的列為 NOT NULL而且你不能插入 NULL到索引的

列中

當用 LOAD DATA INFILE 讀取數據時空列用更新如果你想要在一個列中有

NULL值你應該在文本文件中使用N字面上的詞NULL也可以在某些情形下使用

當使用 ORDER BY時首先呈現 NULL值如果你用 DESC以降序排序NULL值最後顯示當使用 GROUP BY時所有的 NULL值被認為是相等的

為了有助于NULL的處理你能使用 IS NULL和 IS NOT NULL運算符和 IFNULL()函數

對某些列類型NULL值被特殊地處理如果你將 NULL插入表的第一個TIMESTAMP 列則插入當前的日期和時間如果你將 NULL插入一個AUTO_INCREMENT 列則插入順序中的下一個數字

Q5如何將圖片存放於 MySQL中

Ans

Step 1建立資料庫 test

Step 2 建立表格 binary_data

CREATE TABLE binary_data (

id INT(4) NOT NULL AUTO_INCREMENT PRIMARY KEY

description CHAR(50)

bin_data LONGBLOB

filename CHAR(50)

filesize CHAR(50)

filetype CHAR(50)

71

)

Step 3 利用 storephp 寫入圖片

storephp 程式碼

ltHTMLgt ltHEADgtltTITLEgtStore binary data into SQL DatabaseltTITLEgtltHEADgt ltBODYgt lt code that will be executed if the form has been submitted

if ($submit) mysql_connect(localhostrootYOUR_PASSWORD) mysql_select_db(test) $data=Base64_Encode(fread(fopen($form_data r) filesize($form_data))) $result=MYSQL_QUERY(INSERT INTO binary_data (descriptionbin_datafilenamefilesizefiletype) VALUES ($form_description$data$form_data_name$form_data_size$form_data_type)) $id= mysql_insert_id() print ltpgtThis file has the following Database ID ltbgt$idltbgt MYSQL_CLOSE() else else show the form to submit new data

gt

ltform method=post action=ltphp echo $PHP_SELF gt enctype=multipartform-datagt File Descriptionltbrgt ltinput type=text name=form_description size=40gt ltINPUT TYPE=hidden name=MAX_FILE_SIZE value=4000000gt ltbrgtFile to uploadstore in databaseltbrgt ltinput type=file name=form_data size=40gt ltpgtltinput type=submit name=submit value=submitgt ltformgt lt

72

gt ltBODYgt ltHTMLgt

Step 3 利用 storephp 取出圖片

getdataphp 程式碼

lt Syntax getdataphp3id=ltidgt if($id) you may have to modify login information for your database server MYSQL_CONNECT(localhostrootYOUR_PASSWORD) mysql_select_db(test) $query = select bin_datafiletype from binary_data where id=$id $result = MYSQL_QUERY($query) $data = Base64_Decode(MYSQL_RESULT($result0bin_data)) $type = MYSQL_RESULT($result0filetype) Header( Content-type $type) echo $data gt

Q6MySQL裝好之後啟動時或是執行 mysqladmin會出現如下訊息 Cant connect to local MYSQL Server through Socket varlibmysqlmysqlsock或是

Cant connect to local MYSQL Server through Socket tmpmysqldsock

Ans 可能有下列幾個原因

1這個 mysqldsock 不見了被某人刪除了或是被一些系統自動執行程式給刪

了例如有些 cron任務便會設定定期刪除 tmp 裡的東西所以呢您只能修改

cron 裡的設定讓它不要清除 mysqldsock 2在啟動時也可以改變 mysqldsock的位置您在啟動 MySQL的時候可以加入此參數usrlocalmysqlbinsafe_mysqld --user=mysql --socket=其他路

徑socket amp 同時得去設定環境變數 MYSQL_UNIX_PORT的值以指定新的

73

路徑 3若是您沒改 MYSQL_UNIX_PORT的值那麼您可以在執行指令的時候才打

例如mysqladmin --socket=其他路徑socket version Q7How to get the last insert id Ans CREATE TABLE product ( id INT(4) NOT NULL AUTO_INCREMENT PRIMARY KEY description VARCHAR(50) ) 1利用 SQL的話 mysqlgt insert into product(description) values(123) Query OK 1 row affected (000 sec) mysqlgt select last_insert_id() +------------------+ | last_insert_id() | +------------------+ +------------------+ 1 row in set (000 sec) ======================================== 2如果是 PHP的話 你可以用mysql_insert_id()取得該 id PHP example $result=MYSQL_QUERY(INSERT INTO product (description) VALUES ($description)) $id= mysql_insert_id() print This file has the following Database ID $id Q8如何將文字檔匯入資料庫 Ans $addr=homehttpdhtmlphpschool001txt $sql_select = load data infile $addr into table test fields terminated by t 解說 $sql_select = load data infile 文字檔名 into table 表格名 fields terminated by

74

t

(欄位分隔以 TAB鍵) 該文字檔須與資料表欄位格式相符 例如欄位有三個 則文字檔為每行一筆資料如下 欄 1資料ltTABgt欄 2資料ltTABgt欄 3資料 欄 1資料ltTABgt欄 2資料ltTABgt欄 3資料 欄 1資料ltTABgt欄 2資料ltTABgt欄 3資料 欄 1資料ltTABgtltTABgt欄 3資料

Q9如何撰寫 MySQL C API Ans Step 1利用文字編輯器撰寫以下程式碼 mysqlcc

include ltstdiohgt

include ltmysqlmysqlhgt

int main (int argc char argv[])

MYSQL mysql

MYSQL_RES res

MYSQL_ROW row

if (argc = 2)

fputs (Usage myc ltdatabasegt stderr)

return 1

if ((mysql_connect(ampmysqllocalhostrootYour_Password)))

fputs (Error connecting stderr)

abort()

75

if (mysql_select_db(ampmysqlargv[1]))

fputs (Error selecting database stderr)

abort()

if (mysql_query(ampmysqlSELECT FROM test_table))

fputs (Error processing query stderr)

abort()

if ((res = mysql_store_result(ampmysql)))

fputs (Error storing results stderr)

abort()

while((row = mysql_fetch_row(res)))

uint i = 0

for (i=0 i lt mysql_num_fields(res) i++)

printf(s row[i])

printf(n)

return 0

Step 2 Compile

gcc -Iusrlocalmysqlinclude -Lusrlocalmysqllibmysql mysqlcc ndashlm -lmysqlclient

(其中 include path與 library path取決於你的 MySQL安裝路徑)

76

如果執行時發生如下 error Run problemerror in loading shared libraries libmysqlclientsoX 將你的 MySQL library path(for exampleusrlocalmysqllibmysql) 加入etcldsoconf and run sbinldconfig -v Q9ASP + MySQL 範例程式 Ans Dim myconn As New ADODBConnection Dim myrs As New Recordset Dim mySQL As String Dim myrows As Long myconnOpen DSN=MyODBCsample mySQL = SELECT from user myrsSource = mySQL Set myrsActiveConnection = myconn myrsCursorLocation = adUseClient myrsOpen myrows = myrsRecordCount myrsClose myconnClose 可參考 httpwwwdwamnetmysqlasp_myodbcasp 有詳細的資料 Q10如何將 MySQL中的資料庫匯出成txt檔 Ans select from TableName into outfile textxls all result fields will seperate by tab

77

第八章 參考資料

英文部份 網址 1 httpwwwmysqlcom MySQL 網站有第一手有關 MySQL的資料 2 httpwwwmysqlcomdocenReplicationhtml 有關 MySQL Replication 的文件 3 httpwwwgeocitiescomsqlhomefaqstore_blobhtml 如何在 MySQL 存放 BLOB的資料 4httpwwwsapdborg 有關 SAP跟 MySQL相關合作的網站 書藉 1 Cooking with MySQL

Paul DuBois has selected sample recipes from the hundreds youll find in his book MySQL

Cookbook In this third and final series of excerpts showcasing these recipes learn how to

compute team standings how to calculate the differences between successive Dec 26

2002 2 Tips for Building Web Database Applications with PHP and MySQL by Hugh E Williams co-author of Web Database Applications with PHP amp MySQL 04042002

3 Managing and Using MySQL 2nd Edition By Tim King George Reese Randy Jay Yarger

4 MySQL Cookbook By Paul DuBoisPublisher OReillyPub Date October 2002

中文部份

78

1 httplinuxtncedutwtechdocmysqlmysql_docmanual_tochtml MySQL 中文手冊 2 httpchenshloxaedutwphpZ_1php PHP+MySQ程式研習設計網站 3 httplinuxtncedutwtechdocbanicdownhtml PHP 4 手冊 4 httpwwwtncedutwadmin_zonephp台南縣教育網網路中心有很多 Linux相關文件 5 httpdobtncedutw網站建置百寶箱有很多 PHP MySQL 相關範例程式 5 httpwwwdbworldcomtw資料庫專家電子雜誌介紹資料庫的重要觀念及名詞

79

附錄一 SQL Command 介紹

SQL (讀音ess-que-el) 是一種結構查詢語法SQL 使用於資料庫交流

傳遞相容於 ANSI (American National Standards Institute) 是一套標準的關聯

式資料庫語言 SQL 語言是執行更新或從資料系統獲取資料一般常見的關聯

資料庫系統都有提供 SQL 如 Oracle Sybase Microsoft SQL Server Access Ingres 等雖然大部份的資料庫都有提供 SQL 但也多提供了自已獨特的語

法造成了不相容的情形但標準基本的語法是相通的如Select Insert Update Delete Create and Drop 每一個系統都有支援

Table相關 Command

Create Table

關聯式資料庫包含有很多元件稱為資料表(tables) 把資料或訊息放在資

料表中 資料表是以不同的名稱做分別資料表由欄列所構成的二維陣列

欄包含欄位名資料型態 及其他可判斷的資訊列是由全部欄位構成一筆一

筆的紀錄 create table 語法用在建立一個新的資料表語法格式如下

create table tablename (column1 data type column2 data type column3 data type)

Format of create table if you were to use optional constraints

create table tablename (column1 data type [constraint] column2 data type [constraint] column3 data type [constraint]) [ ] = optional

Note You may have as many columns as youd like and the constraints are optional

80

Example

create table employee (first varchar(15) last varchar(20) age number(3) address varchar(30) city varchar(20) state varchar(20))

注意建立資料表格式要以括號把前後框住而最後以(分號)做結尾

欄位名不要超過 30個字元長而且不要使用 sql 的關鍵字(如 where select等)而在後面接是型態的宣告(如字串數字日期格式等)

資料型態是來描述欄位的方式如一個欄位Last_Name 是一個姓氏可以使用varchar (可變動長度字串) 資料型態

以下是幾個常見的資料庫型態 char(size) 固定長度字串最長為 255 位元 varchar(size) 變動長度字串最大字元數以 size 來指定 number(size) 數值格式可以是整數也可以是小數最大數字以 size 位數判

斷未指定小數位數由系統內定 date 日期格式 number(sized) 數值格式最大數字以 size 位數判斷d 為小數位數整數位

數為 size-d 位

有何限制當資料表被建立通常有一或數個欄位是要使用來做關聯的功

能 例如unique 限制(唯一值)兩筆記錄不可以相同的值 not null (非空值)該欄位一定要輸入資料不可是空的primary key (主鍵)是每一筆記錄識別的主要方式

Drop a table drop table 刪除資料表(其中的資料也會一併刪除)

drop table tablename

Example

81

drop table 和刪除全部資料是不同的刪除全部資料欄位名稱資訊等還會

存在但刪除資料表會把這一些也一併移除掉

如何查詢資料

Select 基本用法

select 語法是關連式資料庫最常用的部份可以取得你想要的資料這是一個

簡單的範例 select column1[column2etc] from tablename [where condition] [] = optional 在 select 之後所列欄位名則是要顯示的資料部份你可以一一列出各欄位

名或是以 (星號)來代表選擇全部的欄位 from 之後放資料表名稱 where 子句 (選項) 指定要過濾的條件符合者才會顯現 where 可使用的條件運算元 = 等於 gt 大於 lt 小於 gt= 大或等於 lt= 小或等於 ltgt 大相等 LIKE 相似 For example select first last city

82

from empinfo where first LIKE Er 以Er 為開頭的字串就符合要以單引號框住 Or you can specify select first last from empinfo where last LIKE s 最後一字為 S 就符合 select from empinfo where first = Eric 則表示 first name 一定要是 Eric 才可以 範例資料表empinfo 統計函數

MIN 傳回指定欄位最小值

MAX 傳回指定欄位最大值

SUM 傳回指定欄位總和

AVG 傳回指定欄位平均值

COUNT 傳回指定欄位的筆數

COUNT() 傳回資料庫中的總筆數

統計函數使用於資料表中的數值欄位配合 SELECT 語法使用 只用於總結特定單一欄位可以配合 GROUP BY 做篩選但也可以不使用 GROUP BY 語句For example

SELECT AVG(salary) FROM employee

83

傳回全部 salary 平均值

Another example

SELECT AVG(salary) FROM employee WHERE title = Programmer

傳回 salary 平均值條件為 employees 資料表中當 title 等於 Programmer

Example

SELECT Count() FROM employees

傳回 employees 資料表中紀錄總筆數

GROUP BY 語法 SELECT column1 SUM(column2) FROM list-of-tables GROUP BY column-list The GROUP BY 語句可以先以所列的欄位為條件分組排序在一起(可以多欄

位) example 要列出每一個 dept 中最高 salary 值 SELECT max(salary) dept FROM employee GROUP BY dept HAVING 語法

SELECT column1 SUM(column2) FROM list-of-tables GROUP BY column-list HAVING condition

HAVING 子句是 GROUP BY 的一部份用來過濾在 GROUP BY 所選出的資料功能如同 select 命令中 where 條件式一樣只是 HAVING 必需配合 GROUP BY 使用

我們以例子來說明我們要取得每一公司名及每一公司的薪水平均值輸入如下

84

SELECT dept avg(salary) FROM employee GROUP BY dept

但如果我們只列出薪資平均值超過 20000元的公司資料

SELECT dept avg(salary) FROM employee GROUP BY dept HAVING avg(salary) gt 20000

ORDER BY子句語法

SELECT column1 SUM(column2) FROM list-of-tables ORDER BY column-list [ASC | DESC]

[ ] =選項

ORDER BY是一個選項子句當你以排序方式來顯示資料(正向由小到大反向由大到小)以指定的欄位資料做排序

ASC = 正向- 預設值 DESC = 反向排序

For example

SELECT employee_id dept name age salary FROM employee_info WHERE dept = Sales ORDER BY salary

以上列出公司代號公司名銷售員人名年紀及薪資而條件是公司名為 Sales 顯示順序以薪資多少排序(由小到大為預設值)

如果要以多個欄位做排序要以逗號做分隔如下

SELECT employee_id dept name age salary FROM employee_info WHERE dept = Sales ORDER BY salary age DESC

85

結合條件及布林運算 SELECT column1 SUM(column2) FROM list-of-tables WHERE condition1 AND condition2 AND運算可以結兩個或以上的條件放在 WHERE子句中 兩者都要為真才

會顯示該筆記錄 OR 運算可以結兩個或以上敘述放在 WHERE子句中只要其中一個為直就

會顯示該筆記錄 For example SELECT employeeid firstname lastname title salary FROM employee_info WHERE salary gt= 5000000 AND title = Programmer 必需要薪資大於等於 50000而且職稱為 Programmer同時符合才會顯示該筆資料 以下以括號括住雖然不是必需的但如此比較容易讀 SELECT employeeid firstname lastname title salary FROM employee_info WHERE (salary gt= 5000000) AND (title = Programmer) 另外範例 SELECT firstname lastname title salary FROM employee_info WHERE (title = Sales) OR (title = Programmer) 條件為只要是 Sales 或 Programmer 職稱的就會被列出 IN and BETWEEN 子句

SELECT column1 SUM(column2) FROM list-of-tables WHERE column3 IN (list-of-values) SELECT column1 SUM(column2) FROM list-of-tables WHERE column3 BETWEEN value1 AND value2 IN 子句使用在列舉項目的使用上也就是分別測試是否符合所列的值 For example

86

SELECT employeeid lastname salary FROM employee_info WHERE lastname IN (Hernandez Jones Roberts Ruiz) 條件為姓氏(astname)要符合 Hernandez Jones Roberts or Ruiz 其中一個才會被傳回 IN運算元也可以使用 OR 的語法來取代如下結果相同 SELECT employeeid lastname salary FROM employee_info WHERE lastname = Hernandez OR lastname = Jones OR lastname = Roberts OR lastname = Ruiz 但使用 IN 句子比較短也比較易懂 你也可以使用 NOT IN 來去掉不要的記錄 BETWEEN 運算元使用在判斷是否存在兩個數值之間 For example SELECT employeeid age lastname salary FROM employee_info WHERE age BETWEEN 30 AND 40 傳回年紀 30歲到 40歲之間的資料(含 30及 40歲者) 相同的也可以使用以下語法來達到相同的結果 SELECT employeeid age lastname salary FROM employee_info WHERE age gt= 30 AND age lt= 40 你也可使用 NOT BETWEEN 來濾掉中間值的資料 數學運算 標準 ANSI SQL-92 提供以下運算

87

+ 加

- 減

餘數

餘數為除法後剩整數這不在標準的 ANSI SQL 中但大部份的資料庫都會支

援這運算元以下列出有用的函數雖不在 ANSI SQL-92 提供但一般資料庫

也會支援他們

ABS(x) 傳回 x 絕對值

SIGN(x) returns the sign of input x as -1 0 or 1 (negative zero or positive respectively)

MOD(xy) 餘數 - returns the integer remainder of x divided by y (同 xy)

FLOOR(x) 傳回小或等於 x 的最大整數值

CEILING(x) or CEIL(x)

傳回大或等於 x 的最小整數值

POWER(xy) x的 y 次方

ROUND(x) 把 x 四捨五入為整數

ROUND(xd) 四捨五入取到小數 d 位

SQRT(x) x 開平方

For example SELECT round(salary) firstname FROM employee_info 傳回薪資取到整數位

如何新增資料

insert 加入一筆新紀錄到資料表中 insert into tablename (first_columnlast_column) values (first_valuelast_value) [] = optional Example insert into employee

88

(first last age address city state) values (Luke Duke 45 2130 Boars Nest Hazard Co Georgia) Note 字串要以單引號住如string 數字框住也無妨 insert into 後面接資料表名稱再接以括號括住的欄位名在 values 後括號分別對映各欄位的值 以上的例子新增了一筆名(first) 為 Luke而住所(state) 為 Georgia 的資料

如何刪除資料

delete 可以刪除單筆或多筆紀錄 delete from tablename where columnname OPERATOR value [and|or column OPERATOR value] [ ] = optional Examples delete from employee Note 如果你沒有指定 where 子句那麼全部的紀錄都會被刪除 delete from employee where lastname = May delete from employee where firstname = Mike or firstname = Eric delete from 接著資料表名 再接著是條件式判斷沒有條件式則全部紀錄會

被刪除

如何更新資料

update 用來更新你所指定的記錄要和 WHERE 配合小心使用 語法 update tablename set columnname = newvalue[nextcolumn = newvalue2] where columnname OPERATOR value [and|or column OPERATOR value] [] = optional Examples

89

update phone_book set area_code = 623 where prefix = 979 update phone_book set last_name = Smith prefix=555 suffix=9292 where last_name = Jones update employee set age = age+1 where first_name=Mary and last_name=Williams

90

附錄二Replication

測試環境

RedHat 90 + MySQL 32358 MySQL資料庫路徑 varlibmysql MySQL設定檔 etcmycnf Master IP 1921680100 Slave IP 1921680200 請至下列網址下載最新MySQL 32358套件並利用rpm ndashUvh 更新 httpupdatesredhatcom9enosi386

圖 最新 MySQL 套件

測試架構圖

91

1921680100

1921680200Master Server

erveSlave S r

圖 測試架構圖

測試步驟

Master server 部份 Step1 確認 MasterSlave機器上所裝的 MySQL版本能進行

replication( 32329 or higher ) Step2 在 Master MySQL上開放一個帳號給 Slave mysql ndashu root ndashp mysqlgtGRANT FILE ON TO repl1921680200 IDENTIFIED BY lsquoabc123rsquo mysqlgtq 上面是 Master開放一個帳號 repl密碼 abc123給 IP1921680200有檔案處理

的權限 Step3 shutdown MySQL on the Master mysqladmin ndashu root ndashp shutdown Step4 備份 Master所有資料庫 tar ndashcvf tmpmysql-snapshottar varlibmysql 注意tar的時候MySQL是要在 stop情況下 在mysql (wwwmysqlcom) 網站的FAQ有不用shutdown的方法

92

Step5 在 master機器上修改etcmycnf 在[mysqld]區段內加入參數 log-bin server-id=這邊設定 server-id=1 sql-bin-update-same binlog-do-db=CRM只針對 CRM資料庫做紀錄 Step6 Restart MySQL on the master service mysqld start 此時因為有加入 log-bin 參數因此開始有 index產生了在varlibmysql目錄下

有index檔案紀錄資料庫的異動 log Slave server 部份 Step1 在 slave設定etcmycnf 在[mysqld]區段加入 master-host= master-user= master-password= master-port= server-id= 這邊設定 master-host=1921680100 master-user=repl master-password=abc123 master-port=3306 server-id=2 master-connect-retry=60預設重試間隔 60秒 replicate-do-db=CRM告訴 slave只做 CRM資料庫的更新 log-slave-updates Step2 將 master上的 mysql-snapshottar copy到 slave上 用 ftp傳到 slave的tmp Step3 解壓縮 Master資料庫至 Slave Server上 cd varlib tar xvf tmpmysql-snapshottar chown ndashR mysqlmysql mysql

93

chmod ndashR 770 mysql (視情況) Step4 Restart MySQL on the slave server 這時在varlibmysql目錄會出現 masterinfo此檔案紀錄了 Master MySQL server的資訊

狀況測試

One-way replication

1921680100

1921680200Master Server

erveSlave S r

圖 One-way replication架構圖 Step1 Master跟 Slave網路及服務都正常情況下由 Master端異動資料後 到 Slave端瀏覽資料檢視是否有進行 replication Step2 模擬 Slave Server 當機 可用在於 slave真的當機或是 Slave 不一定需要一直跟 master connect將Slave MySQL server shutdown由 Master端異動資料到 slave端瀏覽此時Slave應該沒有被 replication 更新然後再將 Slave端 MySQL server start起來

預設 60秒後 Slave會嘗試跟 Master要求進行 replication再去 Slave端檢視是否有更新資料

94

Step3 模擬 Master當機因為是設定 One-way replication一旦 Master Server Slave端沒有 Master的 source可以 download Two-way replication 基於 Master當機狀況於是發展雙向 Replication即 1921680100 ( Host A ) 1921680200 ( Host B )都分別擔任 MasterSlave身分

1921680100

1921680200er

Server B MasterSlave Server

Server A MasterSlave Serv

圖 Two-way replication架構圖 以下是針對兩台 MySQL伺服器進行雙向 Replication Step1觀念同單向 replication只是改成 Master也有 Slave身分 Slave也有Master的身分先分別在 Server AServer B 都去 grant一個進行 replication的身分 [A]mysqlgtGRANT FILE ON TO repl1921680200 IDENTIFIED BY lsquoabc123rsquo [B]mysqlgt GRANT FILE ON TO repl1921680100 IDENTIFIED BY lsquoabc123rsquo Step2做完單向 replication後stop Server Aserver B MySQL service此時 AB資料是一樣的

95

修改etcmycnf設定 範例 Server A [mysqld] datadir=varlibmysql socket=varlibmysqlmysqlsock server-id=1 log-bin sql-bin-update-same binlog-do-db=CRM master-host=1921680200 master-user=repl master-password=abc123 log-slave-updates master-connect-retry=60 replicate-do-db=CRM Server B [mysqld] datadir=varlibmysql socket=varlibmysqlmysqlsock server-id=2 log-bin sql-bin-update-same binlog-do-db=CRM master-host=1921680100 master-user=repl master-password=abc123 log-slave-updates master-connect-retry=60 replicate-do-db=CRM 分別 start Server AServer B MySQL後此時雙方都是 MasterSlave身分一旦哪一方資料異動就會通知對方來 replication-若 replication失效則必須將Server AServer B的masterinfo及index00x 都砍掉然後分別 restart MySQL server進行測試檢視成果 實務上通常如果需要做Two-way replication通常會搭配Virtual Server使用

96

在前端架設一台Virtual Server不過此部份不在此份SOP討論範圍內有興趣

的讀者可參考 httpwwwlinuxvirtualserverorg 網站

1921680100 1921680200

Host A MasterSlave Server

Host B MasterSlave Server

Virtual Host

圖 Virtual Server + Two-way replication 架構圖

97

圖 High Availability Linux Virtual Server架構圖

98

  • COSA-SOP-03-006
  • 第一章 簡介
    • 11適用對象 (Audience)
    • 12 MySQL本身
    • 13 MySQL 40版跟50版重大的改進功能
    • 14 各家資料庫軟體比較
      • 第二章 前置需求
      • 第三章 安裝
        • 31 MySQL安裝
        • 32 phpMyAdmin安裝
        • 33 升級及注意事項
          • 第四章 MySQL管理
            • 41 Webmin 管理介面
            • 42 phpMyAdmin 的操作介面
            • 43管理指令介紹
              • 431 利用mysqladmin設定root的密碼
                  • 第五章 實用範例
                    • 51 任務一Web Base客戶通訊錄
                    • 52 任務二Web Base群組軟體 ( twig )
                      • 第六章 維護及更新程序
                        • 61 日常維護
                        • 62 更新程序
                        • 63 備份重要檔案
                        • 64 離線備份與還原
                        • 65 線上備份與還原
                          • 第七章 問題與解答
                          • 第八章 參考資料
                          • 附錄一 SQL Command 介紹
                          • 附錄二Replication
Page 64: DataBase Server Standard Operation Procedureebooks.lib.ntu.edu.tw/1_file/oss/63/93doc4-5.pdf · 業務的公司帶來了不少壓力,譬如微軟,甲骨文 ... 外的錢用在第三方的資料庫產品上,譬如就可以不用再購買甲骨文公司

第六章 維護及更新程序

61 日常維護

系統管理員最好定期以 root 身份登入看看信件在 RedHat Linux 中有一支 logwatch 程式會定時去分析 log file如果發現異常便會發信給 root除此之外筆者建議讀者平時就檢查 MySQL log file ( varlogmysqldlog)是否有異常情形

62 更新程序

讀者可至httprpmfindnet 尋找MySQL相關套件至於升級的相關步驟請參

考Linux OS SOP 第 54節

63 備份重要檔案

預設 MySQL 的 DB 檔案是存在 varlibmysql 內以 DB名稱為目錄目錄

內就是該 DB 的所有資料通常得定期備份還有 MySQL的設定檔 etcmycnf也別忘了一起備份

64 離線備份與還原

641 離線備份

預設 MySQL 的 DB 檔案是存在 varlibmysql 內以 DB 名稱為目錄目錄內

就是該 DB 的所有資料像 CRM 這個 DB就是存在 varlibmysqlCRM 內在備份前因為怕資料尚未完全寫入磁碟而且 MySQL 會 Lock 在使用的 DB 檔案所以應該是要先把 MySQL 先 Shutdown 一下整個備份的程序可以下像下面的指令去完成 cd varlibmysql

64

service mysqld stop tar cvfz CRM_db_20030905tgz CRM service mysqld start 對這樣就可以了 不過要注意的是怕 DB 內每個 Tables 間的資料有關關

聯性所以最好是把整個 DB 一次備起來單獨只備哪個 Tables 的檔案以後回存時怕會有資料關聯不一致的問題

642 離線還原

DB 發生錯誤而要回存時其實也不難先找出最近一次完整正常的備份先把現在錯誤的網頁或 DB 先更名或 tar 起來再把好的備份給解開回原來目錄位

置就行了需要注意的是 MySQL 服務最好也是要先停止回存完成後再啟動服務回存 DB 的整個程序可能像下面 cd varlibmysql service mysqldstop mv CRM CRM_OLD tar xvfz CRM_db_20030905tg service mysqld start

65 線上備份與還原

651 線上備份

使用像上面的檔案方式備份是個不錯的方法它最少可以保持該主機某個時間點的完整檔案備份但還是有一些問題需要考慮到有些主機就不只建立一個 DB 而已總不能為了備份某個 DB 而把整個 MySQL 服務停止備份檔案的方式回存在原主機上一定適用但假如 MySQL 版本升級或是在那天該網頁空間需遷機移機到別的主機時那就沒人敢保證備出來的資料檔可以用所以我們可以考慮另一種備份的方式是使用 MySQL 本身提供的功能 MySQL Data Dump指令是 mysqldump

65

使用 MySQL 的 Dump 功能可以把 DB 的結構資料或結構加資料 Dump 成文字檔 mysqldump 指令提供的彈性很大你可以選擇把整個 DB Dump 成一個檔或是每個 Table 為一個檔甚至是把結構檔和資料分開儲存都

可以 mysqladmin -uroot -p flush-logs mysqldump CRM -uroot -p --opt gt CRM_20030905sql (CRM 是 DB 名稱 opt 是一個使用完整 Dump 參數) 假如只是要單獨 Dump 某個 Table 時只要在上面的指令後轉出符號 gt 前加個 Table 名稱就可以如只要 phpbb2_users 這個 Table 的 Dump 時只要下 mysqldump CRM -uroot -p --opt CUSTOMER gt CRM_CUSTOMER_20030905sql

652 線上還原

若要回存整個資料庫只需將壓縮的備份檔還原成 Dump 的檔案再用下面的指令回存 mysql CRM -uroot -p lt CRM_20030905sql 這邊需注意的是若建立備份時是以--opt或--add-drop-table為參數時回存的 動作是先將舊的 Table 先刪除重建 Table 的結構後再把 Data 匯入所以回存後所有的資料會回到你當時備份那個時間點因此在回存資料時可以考慮把現有錯誤或不完整的 DB 先備份一份下來以備不時之需或是拿來比對錯誤的地

方在那裡當然你也可以把資料回存到另一個測試用的 DB 內只要把上面指令

的 DB 名稱改成你的測試用 DB 名稱即可 使用這種回存方式 MySQL 服務不需停止也不會動到其他正在使用的 DB 在一些提供 MySQL 服務的虛擬主機可用這種方式作你自己的 DB 備份及回存

66

另外假如你是系統重建或是移機時切需在新的 MySQL 內新建一個空白 DB 後才行作回存的工作你可以用下面的指令建立 mysql -uroot -p -e CREATE DATABASE CRM (上面的 CRM是你要新建的 DB 名稱) 另一種作法先用 mysql 指令進入 mysql client console 然後再用 CREATE DATABASE CRM 這樣就行了記得尾端要加個 符號該行指令才會執行

67

第七章 問題與解答

Q1RedHat 90預附的 MySQL到底有無支援 Transcation機制 Ans MySQL自 32334a之後的 MySQL-Max版本加入 InnoDB的資料庫類型透過

InnoDBMySQL同樣可以進行 COMMIT與 ROLLRACK的動作RedHat 90預附的 MySQL為 32354a-11巳支援 InnoDB的資料庫類型不過必須做以

下設定 1cp usrsharedocmysql-server-32354amy-mediumcnf to etcmycnf 2 vi etcmycnf 將以下設定前的拿掉 innodb_data_home_dir = varlibmysql innodb_data_file_path = ibdata110Mautoextend innodb_log_group_home_dir = varlibmysql innodb_log_arch_dir = varlibmysql 3service mysqld restart 如此一來各位在建立Table時便可指定Table Type為 innodb ( ex create table with type=innodb ) Q2如何解決 php+mysql 許功蓋等字變亂的問題 Ans 方法一 【確定 MySQL 預設的字元集】 1 打開 WinMySQLadmin 管理畫面(在視窗右下角狀態列紅綠燈圖示中按滑鼠

右鍵點選 Show me 選項) 2 點選管理畫面中 [Variables] 標籤選項其中 character_set變數就是您預設

字元集的變數其預設是 latin1 字元集(我們要將他改回 big5)而 chatacters_set 變數則是 MySQL 可以支援哪些字元集 【修改預設字元集變數 character_set 】 1 請點選管理畫面中 [myini Setup] 標籤選項設定 myini 2 按一下 [Pick-up and Edit myini values] 按鈕以便編輯目前的 myini 設定 3 在 [mysqld] 設定區塊底下新增一行 default-character-set = big5 變數設

68

定 4 新增一個 [client] 設定區塊並加入第三步驟的變數設定(游標往下移到空白處新增兩行 [client] 和 default-character-set=big5) 5 按一下畫面左下方 [Save Modification] 按鈕儲存設定 6 重新啟動 MySQL 或 Windows 方法二 Server端注意事項 phpini 中有關的設定為(預設值) Magic quotes for incoming GETPOSTCookie data magic_quotes_gpc = On Use Sybase-style magic quotes (escape with instead of ) magic_quotes_sybase = Off Client端注意事項 1中文資料送進 mysql 前請用 addslashes($str) 處理 2處理後送進 mysql 時請用 括起來並在參數後留一個空白如 $sql = UPDATE ezf_table set tablename=$tname tableend=$endtime table inguser=$tguser tableingid=$tguserid tableallnumber=$tnumber tableloca l=$tablelocal tableanyone=$tableopen tabletext=$ttext WHERE tableid=$t ableid tablename=$tname c 取出時請用 stripslashes($str) Q3MySQL root 密碼忘了該怎麼辦 Ans 1先停掉 mysql etcrcdinitdmysql stop 2以--skip-grant-table 的參數啟動 mysql safe_mysql --skip-grant-tableamp 3 更改 root 密碼 mysql mysql mysqlgt UPDATE user SET password=password(newpassword)

69

WHERE user=root mysqlgt FLUSH PRIVILEGES mysqlgt exit 4停掉 mysql再重跑 mysqladmin -uroot -p shutdown Enter password 輸入新設定的密碼 etcrcdinitdmysql start

Q4NULL值問題

Ans

NULL值的概念是造成 SQL的新手的混淆的普遍原因他們經常認為 NULL是和一個空字符串的一樣的東西不是這樣的例如下列語句是完全不同的

mysqlgt INSERT INTO my_table (phone) VALUES (NULL)

mysqlgt INSERT INTO my_table (phone) VALUES ()

兩個語句把值插入到 phone 列但是第一個插入一個 NULL值而第二個插入一個空字符串第一個的含義可以認為是ldquo電話號碼不知道而第二個則可意味

著ldquo她沒有電話

在 SQL中NULL值在于任何其他值甚至 NULL值比較時總是假的(FALSE)包含 NULL的一個表達式總是產生一個 NULL值除非在包含在表達式中的運算符和函數的文檔中指出在下列例子所有的列返回 NULL

mysqlgt SELECT NULL1+NULLCONCAT(InvisibleNULL)

如果你想要尋找值是 NULL的列你不能使用=NULL測試下列語句不返回任

何行因為對任何表達式expr = NULL是假的

mysqlgt SELECT FROM my_table WHERE phone = NULL

要想尋找 NULL值你必須使用 IS NULL測試下例顯示如何找出 NULL電話號碼和空的電話號碼

70

mysqlgt SELECT FROM my_table WHERE phone IS NULL mysqlgt SELECT FROM my_table WHERE phone =

在 MySQL中就像很多其他的 SQL服務器一樣你不能索引可以有 NULL值的列你必須聲明這樣的列為 NOT NULL而且你不能插入 NULL到索引的

列中

當用 LOAD DATA INFILE 讀取數據時空列用更新如果你想要在一個列中有

NULL值你應該在文本文件中使用N字面上的詞NULL也可以在某些情形下使用

當使用 ORDER BY時首先呈現 NULL值如果你用 DESC以降序排序NULL值最後顯示當使用 GROUP BY時所有的 NULL值被認為是相等的

為了有助于NULL的處理你能使用 IS NULL和 IS NOT NULL運算符和 IFNULL()函數

對某些列類型NULL值被特殊地處理如果你將 NULL插入表的第一個TIMESTAMP 列則插入當前的日期和時間如果你將 NULL插入一個AUTO_INCREMENT 列則插入順序中的下一個數字

Q5如何將圖片存放於 MySQL中

Ans

Step 1建立資料庫 test

Step 2 建立表格 binary_data

CREATE TABLE binary_data (

id INT(4) NOT NULL AUTO_INCREMENT PRIMARY KEY

description CHAR(50)

bin_data LONGBLOB

filename CHAR(50)

filesize CHAR(50)

filetype CHAR(50)

71

)

Step 3 利用 storephp 寫入圖片

storephp 程式碼

ltHTMLgt ltHEADgtltTITLEgtStore binary data into SQL DatabaseltTITLEgtltHEADgt ltBODYgt lt code that will be executed if the form has been submitted

if ($submit) mysql_connect(localhostrootYOUR_PASSWORD) mysql_select_db(test) $data=Base64_Encode(fread(fopen($form_data r) filesize($form_data))) $result=MYSQL_QUERY(INSERT INTO binary_data (descriptionbin_datafilenamefilesizefiletype) VALUES ($form_description$data$form_data_name$form_data_size$form_data_type)) $id= mysql_insert_id() print ltpgtThis file has the following Database ID ltbgt$idltbgt MYSQL_CLOSE() else else show the form to submit new data

gt

ltform method=post action=ltphp echo $PHP_SELF gt enctype=multipartform-datagt File Descriptionltbrgt ltinput type=text name=form_description size=40gt ltINPUT TYPE=hidden name=MAX_FILE_SIZE value=4000000gt ltbrgtFile to uploadstore in databaseltbrgt ltinput type=file name=form_data size=40gt ltpgtltinput type=submit name=submit value=submitgt ltformgt lt

72

gt ltBODYgt ltHTMLgt

Step 3 利用 storephp 取出圖片

getdataphp 程式碼

lt Syntax getdataphp3id=ltidgt if($id) you may have to modify login information for your database server MYSQL_CONNECT(localhostrootYOUR_PASSWORD) mysql_select_db(test) $query = select bin_datafiletype from binary_data where id=$id $result = MYSQL_QUERY($query) $data = Base64_Decode(MYSQL_RESULT($result0bin_data)) $type = MYSQL_RESULT($result0filetype) Header( Content-type $type) echo $data gt

Q6MySQL裝好之後啟動時或是執行 mysqladmin會出現如下訊息 Cant connect to local MYSQL Server through Socket varlibmysqlmysqlsock或是

Cant connect to local MYSQL Server through Socket tmpmysqldsock

Ans 可能有下列幾個原因

1這個 mysqldsock 不見了被某人刪除了或是被一些系統自動執行程式給刪

了例如有些 cron任務便會設定定期刪除 tmp 裡的東西所以呢您只能修改

cron 裡的設定讓它不要清除 mysqldsock 2在啟動時也可以改變 mysqldsock的位置您在啟動 MySQL的時候可以加入此參數usrlocalmysqlbinsafe_mysqld --user=mysql --socket=其他路

徑socket amp 同時得去設定環境變數 MYSQL_UNIX_PORT的值以指定新的

73

路徑 3若是您沒改 MYSQL_UNIX_PORT的值那麼您可以在執行指令的時候才打

例如mysqladmin --socket=其他路徑socket version Q7How to get the last insert id Ans CREATE TABLE product ( id INT(4) NOT NULL AUTO_INCREMENT PRIMARY KEY description VARCHAR(50) ) 1利用 SQL的話 mysqlgt insert into product(description) values(123) Query OK 1 row affected (000 sec) mysqlgt select last_insert_id() +------------------+ | last_insert_id() | +------------------+ +------------------+ 1 row in set (000 sec) ======================================== 2如果是 PHP的話 你可以用mysql_insert_id()取得該 id PHP example $result=MYSQL_QUERY(INSERT INTO product (description) VALUES ($description)) $id= mysql_insert_id() print This file has the following Database ID $id Q8如何將文字檔匯入資料庫 Ans $addr=homehttpdhtmlphpschool001txt $sql_select = load data infile $addr into table test fields terminated by t 解說 $sql_select = load data infile 文字檔名 into table 表格名 fields terminated by

74

t

(欄位分隔以 TAB鍵) 該文字檔須與資料表欄位格式相符 例如欄位有三個 則文字檔為每行一筆資料如下 欄 1資料ltTABgt欄 2資料ltTABgt欄 3資料 欄 1資料ltTABgt欄 2資料ltTABgt欄 3資料 欄 1資料ltTABgt欄 2資料ltTABgt欄 3資料 欄 1資料ltTABgtltTABgt欄 3資料

Q9如何撰寫 MySQL C API Ans Step 1利用文字編輯器撰寫以下程式碼 mysqlcc

include ltstdiohgt

include ltmysqlmysqlhgt

int main (int argc char argv[])

MYSQL mysql

MYSQL_RES res

MYSQL_ROW row

if (argc = 2)

fputs (Usage myc ltdatabasegt stderr)

return 1

if ((mysql_connect(ampmysqllocalhostrootYour_Password)))

fputs (Error connecting stderr)

abort()

75

if (mysql_select_db(ampmysqlargv[1]))

fputs (Error selecting database stderr)

abort()

if (mysql_query(ampmysqlSELECT FROM test_table))

fputs (Error processing query stderr)

abort()

if ((res = mysql_store_result(ampmysql)))

fputs (Error storing results stderr)

abort()

while((row = mysql_fetch_row(res)))

uint i = 0

for (i=0 i lt mysql_num_fields(res) i++)

printf(s row[i])

printf(n)

return 0

Step 2 Compile

gcc -Iusrlocalmysqlinclude -Lusrlocalmysqllibmysql mysqlcc ndashlm -lmysqlclient

(其中 include path與 library path取決於你的 MySQL安裝路徑)

76

如果執行時發生如下 error Run problemerror in loading shared libraries libmysqlclientsoX 將你的 MySQL library path(for exampleusrlocalmysqllibmysql) 加入etcldsoconf and run sbinldconfig -v Q9ASP + MySQL 範例程式 Ans Dim myconn As New ADODBConnection Dim myrs As New Recordset Dim mySQL As String Dim myrows As Long myconnOpen DSN=MyODBCsample mySQL = SELECT from user myrsSource = mySQL Set myrsActiveConnection = myconn myrsCursorLocation = adUseClient myrsOpen myrows = myrsRecordCount myrsClose myconnClose 可參考 httpwwwdwamnetmysqlasp_myodbcasp 有詳細的資料 Q10如何將 MySQL中的資料庫匯出成txt檔 Ans select from TableName into outfile textxls all result fields will seperate by tab

77

第八章 參考資料

英文部份 網址 1 httpwwwmysqlcom MySQL 網站有第一手有關 MySQL的資料 2 httpwwwmysqlcomdocenReplicationhtml 有關 MySQL Replication 的文件 3 httpwwwgeocitiescomsqlhomefaqstore_blobhtml 如何在 MySQL 存放 BLOB的資料 4httpwwwsapdborg 有關 SAP跟 MySQL相關合作的網站 書藉 1 Cooking with MySQL

Paul DuBois has selected sample recipes from the hundreds youll find in his book MySQL

Cookbook In this third and final series of excerpts showcasing these recipes learn how to

compute team standings how to calculate the differences between successive Dec 26

2002 2 Tips for Building Web Database Applications with PHP and MySQL by Hugh E Williams co-author of Web Database Applications with PHP amp MySQL 04042002

3 Managing and Using MySQL 2nd Edition By Tim King George Reese Randy Jay Yarger

4 MySQL Cookbook By Paul DuBoisPublisher OReillyPub Date October 2002

中文部份

78

1 httplinuxtncedutwtechdocmysqlmysql_docmanual_tochtml MySQL 中文手冊 2 httpchenshloxaedutwphpZ_1php PHP+MySQ程式研習設計網站 3 httplinuxtncedutwtechdocbanicdownhtml PHP 4 手冊 4 httpwwwtncedutwadmin_zonephp台南縣教育網網路中心有很多 Linux相關文件 5 httpdobtncedutw網站建置百寶箱有很多 PHP MySQL 相關範例程式 5 httpwwwdbworldcomtw資料庫專家電子雜誌介紹資料庫的重要觀念及名詞

79

附錄一 SQL Command 介紹

SQL (讀音ess-que-el) 是一種結構查詢語法SQL 使用於資料庫交流

傳遞相容於 ANSI (American National Standards Institute) 是一套標準的關聯

式資料庫語言 SQL 語言是執行更新或從資料系統獲取資料一般常見的關聯

資料庫系統都有提供 SQL 如 Oracle Sybase Microsoft SQL Server Access Ingres 等雖然大部份的資料庫都有提供 SQL 但也多提供了自已獨特的語

法造成了不相容的情形但標準基本的語法是相通的如Select Insert Update Delete Create and Drop 每一個系統都有支援

Table相關 Command

Create Table

關聯式資料庫包含有很多元件稱為資料表(tables) 把資料或訊息放在資

料表中 資料表是以不同的名稱做分別資料表由欄列所構成的二維陣列

欄包含欄位名資料型態 及其他可判斷的資訊列是由全部欄位構成一筆一

筆的紀錄 create table 語法用在建立一個新的資料表語法格式如下

create table tablename (column1 data type column2 data type column3 data type)

Format of create table if you were to use optional constraints

create table tablename (column1 data type [constraint] column2 data type [constraint] column3 data type [constraint]) [ ] = optional

Note You may have as many columns as youd like and the constraints are optional

80

Example

create table employee (first varchar(15) last varchar(20) age number(3) address varchar(30) city varchar(20) state varchar(20))

注意建立資料表格式要以括號把前後框住而最後以(分號)做結尾

欄位名不要超過 30個字元長而且不要使用 sql 的關鍵字(如 where select等)而在後面接是型態的宣告(如字串數字日期格式等)

資料型態是來描述欄位的方式如一個欄位Last_Name 是一個姓氏可以使用varchar (可變動長度字串) 資料型態

以下是幾個常見的資料庫型態 char(size) 固定長度字串最長為 255 位元 varchar(size) 變動長度字串最大字元數以 size 來指定 number(size) 數值格式可以是整數也可以是小數最大數字以 size 位數判

斷未指定小數位數由系統內定 date 日期格式 number(sized) 數值格式最大數字以 size 位數判斷d 為小數位數整數位

數為 size-d 位

有何限制當資料表被建立通常有一或數個欄位是要使用來做關聯的功

能 例如unique 限制(唯一值)兩筆記錄不可以相同的值 not null (非空值)該欄位一定要輸入資料不可是空的primary key (主鍵)是每一筆記錄識別的主要方式

Drop a table drop table 刪除資料表(其中的資料也會一併刪除)

drop table tablename

Example

81

drop table 和刪除全部資料是不同的刪除全部資料欄位名稱資訊等還會

存在但刪除資料表會把這一些也一併移除掉

如何查詢資料

Select 基本用法

select 語法是關連式資料庫最常用的部份可以取得你想要的資料這是一個

簡單的範例 select column1[column2etc] from tablename [where condition] [] = optional 在 select 之後所列欄位名則是要顯示的資料部份你可以一一列出各欄位

名或是以 (星號)來代表選擇全部的欄位 from 之後放資料表名稱 where 子句 (選項) 指定要過濾的條件符合者才會顯現 where 可使用的條件運算元 = 等於 gt 大於 lt 小於 gt= 大或等於 lt= 小或等於 ltgt 大相等 LIKE 相似 For example select first last city

82

from empinfo where first LIKE Er 以Er 為開頭的字串就符合要以單引號框住 Or you can specify select first last from empinfo where last LIKE s 最後一字為 S 就符合 select from empinfo where first = Eric 則表示 first name 一定要是 Eric 才可以 範例資料表empinfo 統計函數

MIN 傳回指定欄位最小值

MAX 傳回指定欄位最大值

SUM 傳回指定欄位總和

AVG 傳回指定欄位平均值

COUNT 傳回指定欄位的筆數

COUNT() 傳回資料庫中的總筆數

統計函數使用於資料表中的數值欄位配合 SELECT 語法使用 只用於總結特定單一欄位可以配合 GROUP BY 做篩選但也可以不使用 GROUP BY 語句For example

SELECT AVG(salary) FROM employee

83

傳回全部 salary 平均值

Another example

SELECT AVG(salary) FROM employee WHERE title = Programmer

傳回 salary 平均值條件為 employees 資料表中當 title 等於 Programmer

Example

SELECT Count() FROM employees

傳回 employees 資料表中紀錄總筆數

GROUP BY 語法 SELECT column1 SUM(column2) FROM list-of-tables GROUP BY column-list The GROUP BY 語句可以先以所列的欄位為條件分組排序在一起(可以多欄

位) example 要列出每一個 dept 中最高 salary 值 SELECT max(salary) dept FROM employee GROUP BY dept HAVING 語法

SELECT column1 SUM(column2) FROM list-of-tables GROUP BY column-list HAVING condition

HAVING 子句是 GROUP BY 的一部份用來過濾在 GROUP BY 所選出的資料功能如同 select 命令中 where 條件式一樣只是 HAVING 必需配合 GROUP BY 使用

我們以例子來說明我們要取得每一公司名及每一公司的薪水平均值輸入如下

84

SELECT dept avg(salary) FROM employee GROUP BY dept

但如果我們只列出薪資平均值超過 20000元的公司資料

SELECT dept avg(salary) FROM employee GROUP BY dept HAVING avg(salary) gt 20000

ORDER BY子句語法

SELECT column1 SUM(column2) FROM list-of-tables ORDER BY column-list [ASC | DESC]

[ ] =選項

ORDER BY是一個選項子句當你以排序方式來顯示資料(正向由小到大反向由大到小)以指定的欄位資料做排序

ASC = 正向- 預設值 DESC = 反向排序

For example

SELECT employee_id dept name age salary FROM employee_info WHERE dept = Sales ORDER BY salary

以上列出公司代號公司名銷售員人名年紀及薪資而條件是公司名為 Sales 顯示順序以薪資多少排序(由小到大為預設值)

如果要以多個欄位做排序要以逗號做分隔如下

SELECT employee_id dept name age salary FROM employee_info WHERE dept = Sales ORDER BY salary age DESC

85

結合條件及布林運算 SELECT column1 SUM(column2) FROM list-of-tables WHERE condition1 AND condition2 AND運算可以結兩個或以上的條件放在 WHERE子句中 兩者都要為真才

會顯示該筆記錄 OR 運算可以結兩個或以上敘述放在 WHERE子句中只要其中一個為直就

會顯示該筆記錄 For example SELECT employeeid firstname lastname title salary FROM employee_info WHERE salary gt= 5000000 AND title = Programmer 必需要薪資大於等於 50000而且職稱為 Programmer同時符合才會顯示該筆資料 以下以括號括住雖然不是必需的但如此比較容易讀 SELECT employeeid firstname lastname title salary FROM employee_info WHERE (salary gt= 5000000) AND (title = Programmer) 另外範例 SELECT firstname lastname title salary FROM employee_info WHERE (title = Sales) OR (title = Programmer) 條件為只要是 Sales 或 Programmer 職稱的就會被列出 IN and BETWEEN 子句

SELECT column1 SUM(column2) FROM list-of-tables WHERE column3 IN (list-of-values) SELECT column1 SUM(column2) FROM list-of-tables WHERE column3 BETWEEN value1 AND value2 IN 子句使用在列舉項目的使用上也就是分別測試是否符合所列的值 For example

86

SELECT employeeid lastname salary FROM employee_info WHERE lastname IN (Hernandez Jones Roberts Ruiz) 條件為姓氏(astname)要符合 Hernandez Jones Roberts or Ruiz 其中一個才會被傳回 IN運算元也可以使用 OR 的語法來取代如下結果相同 SELECT employeeid lastname salary FROM employee_info WHERE lastname = Hernandez OR lastname = Jones OR lastname = Roberts OR lastname = Ruiz 但使用 IN 句子比較短也比較易懂 你也可以使用 NOT IN 來去掉不要的記錄 BETWEEN 運算元使用在判斷是否存在兩個數值之間 For example SELECT employeeid age lastname salary FROM employee_info WHERE age BETWEEN 30 AND 40 傳回年紀 30歲到 40歲之間的資料(含 30及 40歲者) 相同的也可以使用以下語法來達到相同的結果 SELECT employeeid age lastname salary FROM employee_info WHERE age gt= 30 AND age lt= 40 你也可使用 NOT BETWEEN 來濾掉中間值的資料 數學運算 標準 ANSI SQL-92 提供以下運算

87

+ 加

- 減

餘數

餘數為除法後剩整數這不在標準的 ANSI SQL 中但大部份的資料庫都會支

援這運算元以下列出有用的函數雖不在 ANSI SQL-92 提供但一般資料庫

也會支援他們

ABS(x) 傳回 x 絕對值

SIGN(x) returns the sign of input x as -1 0 or 1 (negative zero or positive respectively)

MOD(xy) 餘數 - returns the integer remainder of x divided by y (同 xy)

FLOOR(x) 傳回小或等於 x 的最大整數值

CEILING(x) or CEIL(x)

傳回大或等於 x 的最小整數值

POWER(xy) x的 y 次方

ROUND(x) 把 x 四捨五入為整數

ROUND(xd) 四捨五入取到小數 d 位

SQRT(x) x 開平方

For example SELECT round(salary) firstname FROM employee_info 傳回薪資取到整數位

如何新增資料

insert 加入一筆新紀錄到資料表中 insert into tablename (first_columnlast_column) values (first_valuelast_value) [] = optional Example insert into employee

88

(first last age address city state) values (Luke Duke 45 2130 Boars Nest Hazard Co Georgia) Note 字串要以單引號住如string 數字框住也無妨 insert into 後面接資料表名稱再接以括號括住的欄位名在 values 後括號分別對映各欄位的值 以上的例子新增了一筆名(first) 為 Luke而住所(state) 為 Georgia 的資料

如何刪除資料

delete 可以刪除單筆或多筆紀錄 delete from tablename where columnname OPERATOR value [and|or column OPERATOR value] [ ] = optional Examples delete from employee Note 如果你沒有指定 where 子句那麼全部的紀錄都會被刪除 delete from employee where lastname = May delete from employee where firstname = Mike or firstname = Eric delete from 接著資料表名 再接著是條件式判斷沒有條件式則全部紀錄會

被刪除

如何更新資料

update 用來更新你所指定的記錄要和 WHERE 配合小心使用 語法 update tablename set columnname = newvalue[nextcolumn = newvalue2] where columnname OPERATOR value [and|or column OPERATOR value] [] = optional Examples

89

update phone_book set area_code = 623 where prefix = 979 update phone_book set last_name = Smith prefix=555 suffix=9292 where last_name = Jones update employee set age = age+1 where first_name=Mary and last_name=Williams

90

附錄二Replication

測試環境

RedHat 90 + MySQL 32358 MySQL資料庫路徑 varlibmysql MySQL設定檔 etcmycnf Master IP 1921680100 Slave IP 1921680200 請至下列網址下載最新MySQL 32358套件並利用rpm ndashUvh 更新 httpupdatesredhatcom9enosi386

圖 最新 MySQL 套件

測試架構圖

91

1921680100

1921680200Master Server

erveSlave S r

圖 測試架構圖

測試步驟

Master server 部份 Step1 確認 MasterSlave機器上所裝的 MySQL版本能進行

replication( 32329 or higher ) Step2 在 Master MySQL上開放一個帳號給 Slave mysql ndashu root ndashp mysqlgtGRANT FILE ON TO repl1921680200 IDENTIFIED BY lsquoabc123rsquo mysqlgtq 上面是 Master開放一個帳號 repl密碼 abc123給 IP1921680200有檔案處理

的權限 Step3 shutdown MySQL on the Master mysqladmin ndashu root ndashp shutdown Step4 備份 Master所有資料庫 tar ndashcvf tmpmysql-snapshottar varlibmysql 注意tar的時候MySQL是要在 stop情況下 在mysql (wwwmysqlcom) 網站的FAQ有不用shutdown的方法

92

Step5 在 master機器上修改etcmycnf 在[mysqld]區段內加入參數 log-bin server-id=這邊設定 server-id=1 sql-bin-update-same binlog-do-db=CRM只針對 CRM資料庫做紀錄 Step6 Restart MySQL on the master service mysqld start 此時因為有加入 log-bin 參數因此開始有 index產生了在varlibmysql目錄下

有index檔案紀錄資料庫的異動 log Slave server 部份 Step1 在 slave設定etcmycnf 在[mysqld]區段加入 master-host= master-user= master-password= master-port= server-id= 這邊設定 master-host=1921680100 master-user=repl master-password=abc123 master-port=3306 server-id=2 master-connect-retry=60預設重試間隔 60秒 replicate-do-db=CRM告訴 slave只做 CRM資料庫的更新 log-slave-updates Step2 將 master上的 mysql-snapshottar copy到 slave上 用 ftp傳到 slave的tmp Step3 解壓縮 Master資料庫至 Slave Server上 cd varlib tar xvf tmpmysql-snapshottar chown ndashR mysqlmysql mysql

93

chmod ndashR 770 mysql (視情況) Step4 Restart MySQL on the slave server 這時在varlibmysql目錄會出現 masterinfo此檔案紀錄了 Master MySQL server的資訊

狀況測試

One-way replication

1921680100

1921680200Master Server

erveSlave S r

圖 One-way replication架構圖 Step1 Master跟 Slave網路及服務都正常情況下由 Master端異動資料後 到 Slave端瀏覽資料檢視是否有進行 replication Step2 模擬 Slave Server 當機 可用在於 slave真的當機或是 Slave 不一定需要一直跟 master connect將Slave MySQL server shutdown由 Master端異動資料到 slave端瀏覽此時Slave應該沒有被 replication 更新然後再將 Slave端 MySQL server start起來

預設 60秒後 Slave會嘗試跟 Master要求進行 replication再去 Slave端檢視是否有更新資料

94

Step3 模擬 Master當機因為是設定 One-way replication一旦 Master Server Slave端沒有 Master的 source可以 download Two-way replication 基於 Master當機狀況於是發展雙向 Replication即 1921680100 ( Host A ) 1921680200 ( Host B )都分別擔任 MasterSlave身分

1921680100

1921680200er

Server B MasterSlave Server

Server A MasterSlave Serv

圖 Two-way replication架構圖 以下是針對兩台 MySQL伺服器進行雙向 Replication Step1觀念同單向 replication只是改成 Master也有 Slave身分 Slave也有Master的身分先分別在 Server AServer B 都去 grant一個進行 replication的身分 [A]mysqlgtGRANT FILE ON TO repl1921680200 IDENTIFIED BY lsquoabc123rsquo [B]mysqlgt GRANT FILE ON TO repl1921680100 IDENTIFIED BY lsquoabc123rsquo Step2做完單向 replication後stop Server Aserver B MySQL service此時 AB資料是一樣的

95

修改etcmycnf設定 範例 Server A [mysqld] datadir=varlibmysql socket=varlibmysqlmysqlsock server-id=1 log-bin sql-bin-update-same binlog-do-db=CRM master-host=1921680200 master-user=repl master-password=abc123 log-slave-updates master-connect-retry=60 replicate-do-db=CRM Server B [mysqld] datadir=varlibmysql socket=varlibmysqlmysqlsock server-id=2 log-bin sql-bin-update-same binlog-do-db=CRM master-host=1921680100 master-user=repl master-password=abc123 log-slave-updates master-connect-retry=60 replicate-do-db=CRM 分別 start Server AServer B MySQL後此時雙方都是 MasterSlave身分一旦哪一方資料異動就會通知對方來 replication-若 replication失效則必須將Server AServer B的masterinfo及index00x 都砍掉然後分別 restart MySQL server進行測試檢視成果 實務上通常如果需要做Two-way replication通常會搭配Virtual Server使用

96

在前端架設一台Virtual Server不過此部份不在此份SOP討論範圍內有興趣

的讀者可參考 httpwwwlinuxvirtualserverorg 網站

1921680100 1921680200

Host A MasterSlave Server

Host B MasterSlave Server

Virtual Host

圖 Virtual Server + Two-way replication 架構圖

97

圖 High Availability Linux Virtual Server架構圖

98

  • COSA-SOP-03-006
  • 第一章 簡介
    • 11適用對象 (Audience)
    • 12 MySQL本身
    • 13 MySQL 40版跟50版重大的改進功能
    • 14 各家資料庫軟體比較
      • 第二章 前置需求
      • 第三章 安裝
        • 31 MySQL安裝
        • 32 phpMyAdmin安裝
        • 33 升級及注意事項
          • 第四章 MySQL管理
            • 41 Webmin 管理介面
            • 42 phpMyAdmin 的操作介面
            • 43管理指令介紹
              • 431 利用mysqladmin設定root的密碼
                  • 第五章 實用範例
                    • 51 任務一Web Base客戶通訊錄
                    • 52 任務二Web Base群組軟體 ( twig )
                      • 第六章 維護及更新程序
                        • 61 日常維護
                        • 62 更新程序
                        • 63 備份重要檔案
                        • 64 離線備份與還原
                        • 65 線上備份與還原
                          • 第七章 問題與解答
                          • 第八章 參考資料
                          • 附錄一 SQL Command 介紹
                          • 附錄二Replication
Page 65: DataBase Server Standard Operation Procedureebooks.lib.ntu.edu.tw/1_file/oss/63/93doc4-5.pdf · 業務的公司帶來了不少壓力,譬如微軟,甲骨文 ... 外的錢用在第三方的資料庫產品上,譬如就可以不用再購買甲骨文公司

service mysqld stop tar cvfz CRM_db_20030905tgz CRM service mysqld start 對這樣就可以了 不過要注意的是怕 DB 內每個 Tables 間的資料有關關

聯性所以最好是把整個 DB 一次備起來單獨只備哪個 Tables 的檔案以後回存時怕會有資料關聯不一致的問題

642 離線還原

DB 發生錯誤而要回存時其實也不難先找出最近一次完整正常的備份先把現在錯誤的網頁或 DB 先更名或 tar 起來再把好的備份給解開回原來目錄位

置就行了需要注意的是 MySQL 服務最好也是要先停止回存完成後再啟動服務回存 DB 的整個程序可能像下面 cd varlibmysql service mysqldstop mv CRM CRM_OLD tar xvfz CRM_db_20030905tg service mysqld start

65 線上備份與還原

651 線上備份

使用像上面的檔案方式備份是個不錯的方法它最少可以保持該主機某個時間點的完整檔案備份但還是有一些問題需要考慮到有些主機就不只建立一個 DB 而已總不能為了備份某個 DB 而把整個 MySQL 服務停止備份檔案的方式回存在原主機上一定適用但假如 MySQL 版本升級或是在那天該網頁空間需遷機移機到別的主機時那就沒人敢保證備出來的資料檔可以用所以我們可以考慮另一種備份的方式是使用 MySQL 本身提供的功能 MySQL Data Dump指令是 mysqldump

65

使用 MySQL 的 Dump 功能可以把 DB 的結構資料或結構加資料 Dump 成文字檔 mysqldump 指令提供的彈性很大你可以選擇把整個 DB Dump 成一個檔或是每個 Table 為一個檔甚至是把結構檔和資料分開儲存都

可以 mysqladmin -uroot -p flush-logs mysqldump CRM -uroot -p --opt gt CRM_20030905sql (CRM 是 DB 名稱 opt 是一個使用完整 Dump 參數) 假如只是要單獨 Dump 某個 Table 時只要在上面的指令後轉出符號 gt 前加個 Table 名稱就可以如只要 phpbb2_users 這個 Table 的 Dump 時只要下 mysqldump CRM -uroot -p --opt CUSTOMER gt CRM_CUSTOMER_20030905sql

652 線上還原

若要回存整個資料庫只需將壓縮的備份檔還原成 Dump 的檔案再用下面的指令回存 mysql CRM -uroot -p lt CRM_20030905sql 這邊需注意的是若建立備份時是以--opt或--add-drop-table為參數時回存的 動作是先將舊的 Table 先刪除重建 Table 的結構後再把 Data 匯入所以回存後所有的資料會回到你當時備份那個時間點因此在回存資料時可以考慮把現有錯誤或不完整的 DB 先備份一份下來以備不時之需或是拿來比對錯誤的地

方在那裡當然你也可以把資料回存到另一個測試用的 DB 內只要把上面指令

的 DB 名稱改成你的測試用 DB 名稱即可 使用這種回存方式 MySQL 服務不需停止也不會動到其他正在使用的 DB 在一些提供 MySQL 服務的虛擬主機可用這種方式作你自己的 DB 備份及回存

66

另外假如你是系統重建或是移機時切需在新的 MySQL 內新建一個空白 DB 後才行作回存的工作你可以用下面的指令建立 mysql -uroot -p -e CREATE DATABASE CRM (上面的 CRM是你要新建的 DB 名稱) 另一種作法先用 mysql 指令進入 mysql client console 然後再用 CREATE DATABASE CRM 這樣就行了記得尾端要加個 符號該行指令才會執行

67

第七章 問題與解答

Q1RedHat 90預附的 MySQL到底有無支援 Transcation機制 Ans MySQL自 32334a之後的 MySQL-Max版本加入 InnoDB的資料庫類型透過

InnoDBMySQL同樣可以進行 COMMIT與 ROLLRACK的動作RedHat 90預附的 MySQL為 32354a-11巳支援 InnoDB的資料庫類型不過必須做以

下設定 1cp usrsharedocmysql-server-32354amy-mediumcnf to etcmycnf 2 vi etcmycnf 將以下設定前的拿掉 innodb_data_home_dir = varlibmysql innodb_data_file_path = ibdata110Mautoextend innodb_log_group_home_dir = varlibmysql innodb_log_arch_dir = varlibmysql 3service mysqld restart 如此一來各位在建立Table時便可指定Table Type為 innodb ( ex create table with type=innodb ) Q2如何解決 php+mysql 許功蓋等字變亂的問題 Ans 方法一 【確定 MySQL 預設的字元集】 1 打開 WinMySQLadmin 管理畫面(在視窗右下角狀態列紅綠燈圖示中按滑鼠

右鍵點選 Show me 選項) 2 點選管理畫面中 [Variables] 標籤選項其中 character_set變數就是您預設

字元集的變數其預設是 latin1 字元集(我們要將他改回 big5)而 chatacters_set 變數則是 MySQL 可以支援哪些字元集 【修改預設字元集變數 character_set 】 1 請點選管理畫面中 [myini Setup] 標籤選項設定 myini 2 按一下 [Pick-up and Edit myini values] 按鈕以便編輯目前的 myini 設定 3 在 [mysqld] 設定區塊底下新增一行 default-character-set = big5 變數設

68

定 4 新增一個 [client] 設定區塊並加入第三步驟的變數設定(游標往下移到空白處新增兩行 [client] 和 default-character-set=big5) 5 按一下畫面左下方 [Save Modification] 按鈕儲存設定 6 重新啟動 MySQL 或 Windows 方法二 Server端注意事項 phpini 中有關的設定為(預設值) Magic quotes for incoming GETPOSTCookie data magic_quotes_gpc = On Use Sybase-style magic quotes (escape with instead of ) magic_quotes_sybase = Off Client端注意事項 1中文資料送進 mysql 前請用 addslashes($str) 處理 2處理後送進 mysql 時請用 括起來並在參數後留一個空白如 $sql = UPDATE ezf_table set tablename=$tname tableend=$endtime table inguser=$tguser tableingid=$tguserid tableallnumber=$tnumber tableloca l=$tablelocal tableanyone=$tableopen tabletext=$ttext WHERE tableid=$t ableid tablename=$tname c 取出時請用 stripslashes($str) Q3MySQL root 密碼忘了該怎麼辦 Ans 1先停掉 mysql etcrcdinitdmysql stop 2以--skip-grant-table 的參數啟動 mysql safe_mysql --skip-grant-tableamp 3 更改 root 密碼 mysql mysql mysqlgt UPDATE user SET password=password(newpassword)

69

WHERE user=root mysqlgt FLUSH PRIVILEGES mysqlgt exit 4停掉 mysql再重跑 mysqladmin -uroot -p shutdown Enter password 輸入新設定的密碼 etcrcdinitdmysql start

Q4NULL值問題

Ans

NULL值的概念是造成 SQL的新手的混淆的普遍原因他們經常認為 NULL是和一個空字符串的一樣的東西不是這樣的例如下列語句是完全不同的

mysqlgt INSERT INTO my_table (phone) VALUES (NULL)

mysqlgt INSERT INTO my_table (phone) VALUES ()

兩個語句把值插入到 phone 列但是第一個插入一個 NULL值而第二個插入一個空字符串第一個的含義可以認為是ldquo電話號碼不知道而第二個則可意味

著ldquo她沒有電話

在 SQL中NULL值在于任何其他值甚至 NULL值比較時總是假的(FALSE)包含 NULL的一個表達式總是產生一個 NULL值除非在包含在表達式中的運算符和函數的文檔中指出在下列例子所有的列返回 NULL

mysqlgt SELECT NULL1+NULLCONCAT(InvisibleNULL)

如果你想要尋找值是 NULL的列你不能使用=NULL測試下列語句不返回任

何行因為對任何表達式expr = NULL是假的

mysqlgt SELECT FROM my_table WHERE phone = NULL

要想尋找 NULL值你必須使用 IS NULL測試下例顯示如何找出 NULL電話號碼和空的電話號碼

70

mysqlgt SELECT FROM my_table WHERE phone IS NULL mysqlgt SELECT FROM my_table WHERE phone =

在 MySQL中就像很多其他的 SQL服務器一樣你不能索引可以有 NULL值的列你必須聲明這樣的列為 NOT NULL而且你不能插入 NULL到索引的

列中

當用 LOAD DATA INFILE 讀取數據時空列用更新如果你想要在一個列中有

NULL值你應該在文本文件中使用N字面上的詞NULL也可以在某些情形下使用

當使用 ORDER BY時首先呈現 NULL值如果你用 DESC以降序排序NULL值最後顯示當使用 GROUP BY時所有的 NULL值被認為是相等的

為了有助于NULL的處理你能使用 IS NULL和 IS NOT NULL運算符和 IFNULL()函數

對某些列類型NULL值被特殊地處理如果你將 NULL插入表的第一個TIMESTAMP 列則插入當前的日期和時間如果你將 NULL插入一個AUTO_INCREMENT 列則插入順序中的下一個數字

Q5如何將圖片存放於 MySQL中

Ans

Step 1建立資料庫 test

Step 2 建立表格 binary_data

CREATE TABLE binary_data (

id INT(4) NOT NULL AUTO_INCREMENT PRIMARY KEY

description CHAR(50)

bin_data LONGBLOB

filename CHAR(50)

filesize CHAR(50)

filetype CHAR(50)

71

)

Step 3 利用 storephp 寫入圖片

storephp 程式碼

ltHTMLgt ltHEADgtltTITLEgtStore binary data into SQL DatabaseltTITLEgtltHEADgt ltBODYgt lt code that will be executed if the form has been submitted

if ($submit) mysql_connect(localhostrootYOUR_PASSWORD) mysql_select_db(test) $data=Base64_Encode(fread(fopen($form_data r) filesize($form_data))) $result=MYSQL_QUERY(INSERT INTO binary_data (descriptionbin_datafilenamefilesizefiletype) VALUES ($form_description$data$form_data_name$form_data_size$form_data_type)) $id= mysql_insert_id() print ltpgtThis file has the following Database ID ltbgt$idltbgt MYSQL_CLOSE() else else show the form to submit new data

gt

ltform method=post action=ltphp echo $PHP_SELF gt enctype=multipartform-datagt File Descriptionltbrgt ltinput type=text name=form_description size=40gt ltINPUT TYPE=hidden name=MAX_FILE_SIZE value=4000000gt ltbrgtFile to uploadstore in databaseltbrgt ltinput type=file name=form_data size=40gt ltpgtltinput type=submit name=submit value=submitgt ltformgt lt

72

gt ltBODYgt ltHTMLgt

Step 3 利用 storephp 取出圖片

getdataphp 程式碼

lt Syntax getdataphp3id=ltidgt if($id) you may have to modify login information for your database server MYSQL_CONNECT(localhostrootYOUR_PASSWORD) mysql_select_db(test) $query = select bin_datafiletype from binary_data where id=$id $result = MYSQL_QUERY($query) $data = Base64_Decode(MYSQL_RESULT($result0bin_data)) $type = MYSQL_RESULT($result0filetype) Header( Content-type $type) echo $data gt

Q6MySQL裝好之後啟動時或是執行 mysqladmin會出現如下訊息 Cant connect to local MYSQL Server through Socket varlibmysqlmysqlsock或是

Cant connect to local MYSQL Server through Socket tmpmysqldsock

Ans 可能有下列幾個原因

1這個 mysqldsock 不見了被某人刪除了或是被一些系統自動執行程式給刪

了例如有些 cron任務便會設定定期刪除 tmp 裡的東西所以呢您只能修改

cron 裡的設定讓它不要清除 mysqldsock 2在啟動時也可以改變 mysqldsock的位置您在啟動 MySQL的時候可以加入此參數usrlocalmysqlbinsafe_mysqld --user=mysql --socket=其他路

徑socket amp 同時得去設定環境變數 MYSQL_UNIX_PORT的值以指定新的

73

路徑 3若是您沒改 MYSQL_UNIX_PORT的值那麼您可以在執行指令的時候才打

例如mysqladmin --socket=其他路徑socket version Q7How to get the last insert id Ans CREATE TABLE product ( id INT(4) NOT NULL AUTO_INCREMENT PRIMARY KEY description VARCHAR(50) ) 1利用 SQL的話 mysqlgt insert into product(description) values(123) Query OK 1 row affected (000 sec) mysqlgt select last_insert_id() +------------------+ | last_insert_id() | +------------------+ +------------------+ 1 row in set (000 sec) ======================================== 2如果是 PHP的話 你可以用mysql_insert_id()取得該 id PHP example $result=MYSQL_QUERY(INSERT INTO product (description) VALUES ($description)) $id= mysql_insert_id() print This file has the following Database ID $id Q8如何將文字檔匯入資料庫 Ans $addr=homehttpdhtmlphpschool001txt $sql_select = load data infile $addr into table test fields terminated by t 解說 $sql_select = load data infile 文字檔名 into table 表格名 fields terminated by

74

t

(欄位分隔以 TAB鍵) 該文字檔須與資料表欄位格式相符 例如欄位有三個 則文字檔為每行一筆資料如下 欄 1資料ltTABgt欄 2資料ltTABgt欄 3資料 欄 1資料ltTABgt欄 2資料ltTABgt欄 3資料 欄 1資料ltTABgt欄 2資料ltTABgt欄 3資料 欄 1資料ltTABgtltTABgt欄 3資料

Q9如何撰寫 MySQL C API Ans Step 1利用文字編輯器撰寫以下程式碼 mysqlcc

include ltstdiohgt

include ltmysqlmysqlhgt

int main (int argc char argv[])

MYSQL mysql

MYSQL_RES res

MYSQL_ROW row

if (argc = 2)

fputs (Usage myc ltdatabasegt stderr)

return 1

if ((mysql_connect(ampmysqllocalhostrootYour_Password)))

fputs (Error connecting stderr)

abort()

75

if (mysql_select_db(ampmysqlargv[1]))

fputs (Error selecting database stderr)

abort()

if (mysql_query(ampmysqlSELECT FROM test_table))

fputs (Error processing query stderr)

abort()

if ((res = mysql_store_result(ampmysql)))

fputs (Error storing results stderr)

abort()

while((row = mysql_fetch_row(res)))

uint i = 0

for (i=0 i lt mysql_num_fields(res) i++)

printf(s row[i])

printf(n)

return 0

Step 2 Compile

gcc -Iusrlocalmysqlinclude -Lusrlocalmysqllibmysql mysqlcc ndashlm -lmysqlclient

(其中 include path與 library path取決於你的 MySQL安裝路徑)

76

如果執行時發生如下 error Run problemerror in loading shared libraries libmysqlclientsoX 將你的 MySQL library path(for exampleusrlocalmysqllibmysql) 加入etcldsoconf and run sbinldconfig -v Q9ASP + MySQL 範例程式 Ans Dim myconn As New ADODBConnection Dim myrs As New Recordset Dim mySQL As String Dim myrows As Long myconnOpen DSN=MyODBCsample mySQL = SELECT from user myrsSource = mySQL Set myrsActiveConnection = myconn myrsCursorLocation = adUseClient myrsOpen myrows = myrsRecordCount myrsClose myconnClose 可參考 httpwwwdwamnetmysqlasp_myodbcasp 有詳細的資料 Q10如何將 MySQL中的資料庫匯出成txt檔 Ans select from TableName into outfile textxls all result fields will seperate by tab

77

第八章 參考資料

英文部份 網址 1 httpwwwmysqlcom MySQL 網站有第一手有關 MySQL的資料 2 httpwwwmysqlcomdocenReplicationhtml 有關 MySQL Replication 的文件 3 httpwwwgeocitiescomsqlhomefaqstore_blobhtml 如何在 MySQL 存放 BLOB的資料 4httpwwwsapdborg 有關 SAP跟 MySQL相關合作的網站 書藉 1 Cooking with MySQL

Paul DuBois has selected sample recipes from the hundreds youll find in his book MySQL

Cookbook In this third and final series of excerpts showcasing these recipes learn how to

compute team standings how to calculate the differences between successive Dec 26

2002 2 Tips for Building Web Database Applications with PHP and MySQL by Hugh E Williams co-author of Web Database Applications with PHP amp MySQL 04042002

3 Managing and Using MySQL 2nd Edition By Tim King George Reese Randy Jay Yarger

4 MySQL Cookbook By Paul DuBoisPublisher OReillyPub Date October 2002

中文部份

78

1 httplinuxtncedutwtechdocmysqlmysql_docmanual_tochtml MySQL 中文手冊 2 httpchenshloxaedutwphpZ_1php PHP+MySQ程式研習設計網站 3 httplinuxtncedutwtechdocbanicdownhtml PHP 4 手冊 4 httpwwwtncedutwadmin_zonephp台南縣教育網網路中心有很多 Linux相關文件 5 httpdobtncedutw網站建置百寶箱有很多 PHP MySQL 相關範例程式 5 httpwwwdbworldcomtw資料庫專家電子雜誌介紹資料庫的重要觀念及名詞

79

附錄一 SQL Command 介紹

SQL (讀音ess-que-el) 是一種結構查詢語法SQL 使用於資料庫交流

傳遞相容於 ANSI (American National Standards Institute) 是一套標準的關聯

式資料庫語言 SQL 語言是執行更新或從資料系統獲取資料一般常見的關聯

資料庫系統都有提供 SQL 如 Oracle Sybase Microsoft SQL Server Access Ingres 等雖然大部份的資料庫都有提供 SQL 但也多提供了自已獨特的語

法造成了不相容的情形但標準基本的語法是相通的如Select Insert Update Delete Create and Drop 每一個系統都有支援

Table相關 Command

Create Table

關聯式資料庫包含有很多元件稱為資料表(tables) 把資料或訊息放在資

料表中 資料表是以不同的名稱做分別資料表由欄列所構成的二維陣列

欄包含欄位名資料型態 及其他可判斷的資訊列是由全部欄位構成一筆一

筆的紀錄 create table 語法用在建立一個新的資料表語法格式如下

create table tablename (column1 data type column2 data type column3 data type)

Format of create table if you were to use optional constraints

create table tablename (column1 data type [constraint] column2 data type [constraint] column3 data type [constraint]) [ ] = optional

Note You may have as many columns as youd like and the constraints are optional

80

Example

create table employee (first varchar(15) last varchar(20) age number(3) address varchar(30) city varchar(20) state varchar(20))

注意建立資料表格式要以括號把前後框住而最後以(分號)做結尾

欄位名不要超過 30個字元長而且不要使用 sql 的關鍵字(如 where select等)而在後面接是型態的宣告(如字串數字日期格式等)

資料型態是來描述欄位的方式如一個欄位Last_Name 是一個姓氏可以使用varchar (可變動長度字串) 資料型態

以下是幾個常見的資料庫型態 char(size) 固定長度字串最長為 255 位元 varchar(size) 變動長度字串最大字元數以 size 來指定 number(size) 數值格式可以是整數也可以是小數最大數字以 size 位數判

斷未指定小數位數由系統內定 date 日期格式 number(sized) 數值格式最大數字以 size 位數判斷d 為小數位數整數位

數為 size-d 位

有何限制當資料表被建立通常有一或數個欄位是要使用來做關聯的功

能 例如unique 限制(唯一值)兩筆記錄不可以相同的值 not null (非空值)該欄位一定要輸入資料不可是空的primary key (主鍵)是每一筆記錄識別的主要方式

Drop a table drop table 刪除資料表(其中的資料也會一併刪除)

drop table tablename

Example

81

drop table 和刪除全部資料是不同的刪除全部資料欄位名稱資訊等還會

存在但刪除資料表會把這一些也一併移除掉

如何查詢資料

Select 基本用法

select 語法是關連式資料庫最常用的部份可以取得你想要的資料這是一個

簡單的範例 select column1[column2etc] from tablename [where condition] [] = optional 在 select 之後所列欄位名則是要顯示的資料部份你可以一一列出各欄位

名或是以 (星號)來代表選擇全部的欄位 from 之後放資料表名稱 where 子句 (選項) 指定要過濾的條件符合者才會顯現 where 可使用的條件運算元 = 等於 gt 大於 lt 小於 gt= 大或等於 lt= 小或等於 ltgt 大相等 LIKE 相似 For example select first last city

82

from empinfo where first LIKE Er 以Er 為開頭的字串就符合要以單引號框住 Or you can specify select first last from empinfo where last LIKE s 最後一字為 S 就符合 select from empinfo where first = Eric 則表示 first name 一定要是 Eric 才可以 範例資料表empinfo 統計函數

MIN 傳回指定欄位最小值

MAX 傳回指定欄位最大值

SUM 傳回指定欄位總和

AVG 傳回指定欄位平均值

COUNT 傳回指定欄位的筆數

COUNT() 傳回資料庫中的總筆數

統計函數使用於資料表中的數值欄位配合 SELECT 語法使用 只用於總結特定單一欄位可以配合 GROUP BY 做篩選但也可以不使用 GROUP BY 語句For example

SELECT AVG(salary) FROM employee

83

傳回全部 salary 平均值

Another example

SELECT AVG(salary) FROM employee WHERE title = Programmer

傳回 salary 平均值條件為 employees 資料表中當 title 等於 Programmer

Example

SELECT Count() FROM employees

傳回 employees 資料表中紀錄總筆數

GROUP BY 語法 SELECT column1 SUM(column2) FROM list-of-tables GROUP BY column-list The GROUP BY 語句可以先以所列的欄位為條件分組排序在一起(可以多欄

位) example 要列出每一個 dept 中最高 salary 值 SELECT max(salary) dept FROM employee GROUP BY dept HAVING 語法

SELECT column1 SUM(column2) FROM list-of-tables GROUP BY column-list HAVING condition

HAVING 子句是 GROUP BY 的一部份用來過濾在 GROUP BY 所選出的資料功能如同 select 命令中 where 條件式一樣只是 HAVING 必需配合 GROUP BY 使用

我們以例子來說明我們要取得每一公司名及每一公司的薪水平均值輸入如下

84

SELECT dept avg(salary) FROM employee GROUP BY dept

但如果我們只列出薪資平均值超過 20000元的公司資料

SELECT dept avg(salary) FROM employee GROUP BY dept HAVING avg(salary) gt 20000

ORDER BY子句語法

SELECT column1 SUM(column2) FROM list-of-tables ORDER BY column-list [ASC | DESC]

[ ] =選項

ORDER BY是一個選項子句當你以排序方式來顯示資料(正向由小到大反向由大到小)以指定的欄位資料做排序

ASC = 正向- 預設值 DESC = 反向排序

For example

SELECT employee_id dept name age salary FROM employee_info WHERE dept = Sales ORDER BY salary

以上列出公司代號公司名銷售員人名年紀及薪資而條件是公司名為 Sales 顯示順序以薪資多少排序(由小到大為預設值)

如果要以多個欄位做排序要以逗號做分隔如下

SELECT employee_id dept name age salary FROM employee_info WHERE dept = Sales ORDER BY salary age DESC

85

結合條件及布林運算 SELECT column1 SUM(column2) FROM list-of-tables WHERE condition1 AND condition2 AND運算可以結兩個或以上的條件放在 WHERE子句中 兩者都要為真才

會顯示該筆記錄 OR 運算可以結兩個或以上敘述放在 WHERE子句中只要其中一個為直就

會顯示該筆記錄 For example SELECT employeeid firstname lastname title salary FROM employee_info WHERE salary gt= 5000000 AND title = Programmer 必需要薪資大於等於 50000而且職稱為 Programmer同時符合才會顯示該筆資料 以下以括號括住雖然不是必需的但如此比較容易讀 SELECT employeeid firstname lastname title salary FROM employee_info WHERE (salary gt= 5000000) AND (title = Programmer) 另外範例 SELECT firstname lastname title salary FROM employee_info WHERE (title = Sales) OR (title = Programmer) 條件為只要是 Sales 或 Programmer 職稱的就會被列出 IN and BETWEEN 子句

SELECT column1 SUM(column2) FROM list-of-tables WHERE column3 IN (list-of-values) SELECT column1 SUM(column2) FROM list-of-tables WHERE column3 BETWEEN value1 AND value2 IN 子句使用在列舉項目的使用上也就是分別測試是否符合所列的值 For example

86

SELECT employeeid lastname salary FROM employee_info WHERE lastname IN (Hernandez Jones Roberts Ruiz) 條件為姓氏(astname)要符合 Hernandez Jones Roberts or Ruiz 其中一個才會被傳回 IN運算元也可以使用 OR 的語法來取代如下結果相同 SELECT employeeid lastname salary FROM employee_info WHERE lastname = Hernandez OR lastname = Jones OR lastname = Roberts OR lastname = Ruiz 但使用 IN 句子比較短也比較易懂 你也可以使用 NOT IN 來去掉不要的記錄 BETWEEN 運算元使用在判斷是否存在兩個數值之間 For example SELECT employeeid age lastname salary FROM employee_info WHERE age BETWEEN 30 AND 40 傳回年紀 30歲到 40歲之間的資料(含 30及 40歲者) 相同的也可以使用以下語法來達到相同的結果 SELECT employeeid age lastname salary FROM employee_info WHERE age gt= 30 AND age lt= 40 你也可使用 NOT BETWEEN 來濾掉中間值的資料 數學運算 標準 ANSI SQL-92 提供以下運算

87

+ 加

- 減

餘數

餘數為除法後剩整數這不在標準的 ANSI SQL 中但大部份的資料庫都會支

援這運算元以下列出有用的函數雖不在 ANSI SQL-92 提供但一般資料庫

也會支援他們

ABS(x) 傳回 x 絕對值

SIGN(x) returns the sign of input x as -1 0 or 1 (negative zero or positive respectively)

MOD(xy) 餘數 - returns the integer remainder of x divided by y (同 xy)

FLOOR(x) 傳回小或等於 x 的最大整數值

CEILING(x) or CEIL(x)

傳回大或等於 x 的最小整數值

POWER(xy) x的 y 次方

ROUND(x) 把 x 四捨五入為整數

ROUND(xd) 四捨五入取到小數 d 位

SQRT(x) x 開平方

For example SELECT round(salary) firstname FROM employee_info 傳回薪資取到整數位

如何新增資料

insert 加入一筆新紀錄到資料表中 insert into tablename (first_columnlast_column) values (first_valuelast_value) [] = optional Example insert into employee

88

(first last age address city state) values (Luke Duke 45 2130 Boars Nest Hazard Co Georgia) Note 字串要以單引號住如string 數字框住也無妨 insert into 後面接資料表名稱再接以括號括住的欄位名在 values 後括號分別對映各欄位的值 以上的例子新增了一筆名(first) 為 Luke而住所(state) 為 Georgia 的資料

如何刪除資料

delete 可以刪除單筆或多筆紀錄 delete from tablename where columnname OPERATOR value [and|or column OPERATOR value] [ ] = optional Examples delete from employee Note 如果你沒有指定 where 子句那麼全部的紀錄都會被刪除 delete from employee where lastname = May delete from employee where firstname = Mike or firstname = Eric delete from 接著資料表名 再接著是條件式判斷沒有條件式則全部紀錄會

被刪除

如何更新資料

update 用來更新你所指定的記錄要和 WHERE 配合小心使用 語法 update tablename set columnname = newvalue[nextcolumn = newvalue2] where columnname OPERATOR value [and|or column OPERATOR value] [] = optional Examples

89

update phone_book set area_code = 623 where prefix = 979 update phone_book set last_name = Smith prefix=555 suffix=9292 where last_name = Jones update employee set age = age+1 where first_name=Mary and last_name=Williams

90

附錄二Replication

測試環境

RedHat 90 + MySQL 32358 MySQL資料庫路徑 varlibmysql MySQL設定檔 etcmycnf Master IP 1921680100 Slave IP 1921680200 請至下列網址下載最新MySQL 32358套件並利用rpm ndashUvh 更新 httpupdatesredhatcom9enosi386

圖 最新 MySQL 套件

測試架構圖

91

1921680100

1921680200Master Server

erveSlave S r

圖 測試架構圖

測試步驟

Master server 部份 Step1 確認 MasterSlave機器上所裝的 MySQL版本能進行

replication( 32329 or higher ) Step2 在 Master MySQL上開放一個帳號給 Slave mysql ndashu root ndashp mysqlgtGRANT FILE ON TO repl1921680200 IDENTIFIED BY lsquoabc123rsquo mysqlgtq 上面是 Master開放一個帳號 repl密碼 abc123給 IP1921680200有檔案處理

的權限 Step3 shutdown MySQL on the Master mysqladmin ndashu root ndashp shutdown Step4 備份 Master所有資料庫 tar ndashcvf tmpmysql-snapshottar varlibmysql 注意tar的時候MySQL是要在 stop情況下 在mysql (wwwmysqlcom) 網站的FAQ有不用shutdown的方法

92

Step5 在 master機器上修改etcmycnf 在[mysqld]區段內加入參數 log-bin server-id=這邊設定 server-id=1 sql-bin-update-same binlog-do-db=CRM只針對 CRM資料庫做紀錄 Step6 Restart MySQL on the master service mysqld start 此時因為有加入 log-bin 參數因此開始有 index產生了在varlibmysql目錄下

有index檔案紀錄資料庫的異動 log Slave server 部份 Step1 在 slave設定etcmycnf 在[mysqld]區段加入 master-host= master-user= master-password= master-port= server-id= 這邊設定 master-host=1921680100 master-user=repl master-password=abc123 master-port=3306 server-id=2 master-connect-retry=60預設重試間隔 60秒 replicate-do-db=CRM告訴 slave只做 CRM資料庫的更新 log-slave-updates Step2 將 master上的 mysql-snapshottar copy到 slave上 用 ftp傳到 slave的tmp Step3 解壓縮 Master資料庫至 Slave Server上 cd varlib tar xvf tmpmysql-snapshottar chown ndashR mysqlmysql mysql

93

chmod ndashR 770 mysql (視情況) Step4 Restart MySQL on the slave server 這時在varlibmysql目錄會出現 masterinfo此檔案紀錄了 Master MySQL server的資訊

狀況測試

One-way replication

1921680100

1921680200Master Server

erveSlave S r

圖 One-way replication架構圖 Step1 Master跟 Slave網路及服務都正常情況下由 Master端異動資料後 到 Slave端瀏覽資料檢視是否有進行 replication Step2 模擬 Slave Server 當機 可用在於 slave真的當機或是 Slave 不一定需要一直跟 master connect將Slave MySQL server shutdown由 Master端異動資料到 slave端瀏覽此時Slave應該沒有被 replication 更新然後再將 Slave端 MySQL server start起來

預設 60秒後 Slave會嘗試跟 Master要求進行 replication再去 Slave端檢視是否有更新資料

94

Step3 模擬 Master當機因為是設定 One-way replication一旦 Master Server Slave端沒有 Master的 source可以 download Two-way replication 基於 Master當機狀況於是發展雙向 Replication即 1921680100 ( Host A ) 1921680200 ( Host B )都分別擔任 MasterSlave身分

1921680100

1921680200er

Server B MasterSlave Server

Server A MasterSlave Serv

圖 Two-way replication架構圖 以下是針對兩台 MySQL伺服器進行雙向 Replication Step1觀念同單向 replication只是改成 Master也有 Slave身分 Slave也有Master的身分先分別在 Server AServer B 都去 grant一個進行 replication的身分 [A]mysqlgtGRANT FILE ON TO repl1921680200 IDENTIFIED BY lsquoabc123rsquo [B]mysqlgt GRANT FILE ON TO repl1921680100 IDENTIFIED BY lsquoabc123rsquo Step2做完單向 replication後stop Server Aserver B MySQL service此時 AB資料是一樣的

95

修改etcmycnf設定 範例 Server A [mysqld] datadir=varlibmysql socket=varlibmysqlmysqlsock server-id=1 log-bin sql-bin-update-same binlog-do-db=CRM master-host=1921680200 master-user=repl master-password=abc123 log-slave-updates master-connect-retry=60 replicate-do-db=CRM Server B [mysqld] datadir=varlibmysql socket=varlibmysqlmysqlsock server-id=2 log-bin sql-bin-update-same binlog-do-db=CRM master-host=1921680100 master-user=repl master-password=abc123 log-slave-updates master-connect-retry=60 replicate-do-db=CRM 分別 start Server AServer B MySQL後此時雙方都是 MasterSlave身分一旦哪一方資料異動就會通知對方來 replication-若 replication失效則必須將Server AServer B的masterinfo及index00x 都砍掉然後分別 restart MySQL server進行測試檢視成果 實務上通常如果需要做Two-way replication通常會搭配Virtual Server使用

96

在前端架設一台Virtual Server不過此部份不在此份SOP討論範圍內有興趣

的讀者可參考 httpwwwlinuxvirtualserverorg 網站

1921680100 1921680200

Host A MasterSlave Server

Host B MasterSlave Server

Virtual Host

圖 Virtual Server + Two-way replication 架構圖

97

圖 High Availability Linux Virtual Server架構圖

98

  • COSA-SOP-03-006
  • 第一章 簡介
    • 11適用對象 (Audience)
    • 12 MySQL本身
    • 13 MySQL 40版跟50版重大的改進功能
    • 14 各家資料庫軟體比較
      • 第二章 前置需求
      • 第三章 安裝
        • 31 MySQL安裝
        • 32 phpMyAdmin安裝
        • 33 升級及注意事項
          • 第四章 MySQL管理
            • 41 Webmin 管理介面
            • 42 phpMyAdmin 的操作介面
            • 43管理指令介紹
              • 431 利用mysqladmin設定root的密碼
                  • 第五章 實用範例
                    • 51 任務一Web Base客戶通訊錄
                    • 52 任務二Web Base群組軟體 ( twig )
                      • 第六章 維護及更新程序
                        • 61 日常維護
                        • 62 更新程序
                        • 63 備份重要檔案
                        • 64 離線備份與還原
                        • 65 線上備份與還原
                          • 第七章 問題與解答
                          • 第八章 參考資料
                          • 附錄一 SQL Command 介紹
                          • 附錄二Replication
Page 66: DataBase Server Standard Operation Procedureebooks.lib.ntu.edu.tw/1_file/oss/63/93doc4-5.pdf · 業務的公司帶來了不少壓力,譬如微軟,甲骨文 ... 外的錢用在第三方的資料庫產品上,譬如就可以不用再購買甲骨文公司

使用 MySQL 的 Dump 功能可以把 DB 的結構資料或結構加資料 Dump 成文字檔 mysqldump 指令提供的彈性很大你可以選擇把整個 DB Dump 成一個檔或是每個 Table 為一個檔甚至是把結構檔和資料分開儲存都

可以 mysqladmin -uroot -p flush-logs mysqldump CRM -uroot -p --opt gt CRM_20030905sql (CRM 是 DB 名稱 opt 是一個使用完整 Dump 參數) 假如只是要單獨 Dump 某個 Table 時只要在上面的指令後轉出符號 gt 前加個 Table 名稱就可以如只要 phpbb2_users 這個 Table 的 Dump 時只要下 mysqldump CRM -uroot -p --opt CUSTOMER gt CRM_CUSTOMER_20030905sql

652 線上還原

若要回存整個資料庫只需將壓縮的備份檔還原成 Dump 的檔案再用下面的指令回存 mysql CRM -uroot -p lt CRM_20030905sql 這邊需注意的是若建立備份時是以--opt或--add-drop-table為參數時回存的 動作是先將舊的 Table 先刪除重建 Table 的結構後再把 Data 匯入所以回存後所有的資料會回到你當時備份那個時間點因此在回存資料時可以考慮把現有錯誤或不完整的 DB 先備份一份下來以備不時之需或是拿來比對錯誤的地

方在那裡當然你也可以把資料回存到另一個測試用的 DB 內只要把上面指令

的 DB 名稱改成你的測試用 DB 名稱即可 使用這種回存方式 MySQL 服務不需停止也不會動到其他正在使用的 DB 在一些提供 MySQL 服務的虛擬主機可用這種方式作你自己的 DB 備份及回存

66

另外假如你是系統重建或是移機時切需在新的 MySQL 內新建一個空白 DB 後才行作回存的工作你可以用下面的指令建立 mysql -uroot -p -e CREATE DATABASE CRM (上面的 CRM是你要新建的 DB 名稱) 另一種作法先用 mysql 指令進入 mysql client console 然後再用 CREATE DATABASE CRM 這樣就行了記得尾端要加個 符號該行指令才會執行

67

第七章 問題與解答

Q1RedHat 90預附的 MySQL到底有無支援 Transcation機制 Ans MySQL自 32334a之後的 MySQL-Max版本加入 InnoDB的資料庫類型透過

InnoDBMySQL同樣可以進行 COMMIT與 ROLLRACK的動作RedHat 90預附的 MySQL為 32354a-11巳支援 InnoDB的資料庫類型不過必須做以

下設定 1cp usrsharedocmysql-server-32354amy-mediumcnf to etcmycnf 2 vi etcmycnf 將以下設定前的拿掉 innodb_data_home_dir = varlibmysql innodb_data_file_path = ibdata110Mautoextend innodb_log_group_home_dir = varlibmysql innodb_log_arch_dir = varlibmysql 3service mysqld restart 如此一來各位在建立Table時便可指定Table Type為 innodb ( ex create table with type=innodb ) Q2如何解決 php+mysql 許功蓋等字變亂的問題 Ans 方法一 【確定 MySQL 預設的字元集】 1 打開 WinMySQLadmin 管理畫面(在視窗右下角狀態列紅綠燈圖示中按滑鼠

右鍵點選 Show me 選項) 2 點選管理畫面中 [Variables] 標籤選項其中 character_set變數就是您預設

字元集的變數其預設是 latin1 字元集(我們要將他改回 big5)而 chatacters_set 變數則是 MySQL 可以支援哪些字元集 【修改預設字元集變數 character_set 】 1 請點選管理畫面中 [myini Setup] 標籤選項設定 myini 2 按一下 [Pick-up and Edit myini values] 按鈕以便編輯目前的 myini 設定 3 在 [mysqld] 設定區塊底下新增一行 default-character-set = big5 變數設

68

定 4 新增一個 [client] 設定區塊並加入第三步驟的變數設定(游標往下移到空白處新增兩行 [client] 和 default-character-set=big5) 5 按一下畫面左下方 [Save Modification] 按鈕儲存設定 6 重新啟動 MySQL 或 Windows 方法二 Server端注意事項 phpini 中有關的設定為(預設值) Magic quotes for incoming GETPOSTCookie data magic_quotes_gpc = On Use Sybase-style magic quotes (escape with instead of ) magic_quotes_sybase = Off Client端注意事項 1中文資料送進 mysql 前請用 addslashes($str) 處理 2處理後送進 mysql 時請用 括起來並在參數後留一個空白如 $sql = UPDATE ezf_table set tablename=$tname tableend=$endtime table inguser=$tguser tableingid=$tguserid tableallnumber=$tnumber tableloca l=$tablelocal tableanyone=$tableopen tabletext=$ttext WHERE tableid=$t ableid tablename=$tname c 取出時請用 stripslashes($str) Q3MySQL root 密碼忘了該怎麼辦 Ans 1先停掉 mysql etcrcdinitdmysql stop 2以--skip-grant-table 的參數啟動 mysql safe_mysql --skip-grant-tableamp 3 更改 root 密碼 mysql mysql mysqlgt UPDATE user SET password=password(newpassword)

69

WHERE user=root mysqlgt FLUSH PRIVILEGES mysqlgt exit 4停掉 mysql再重跑 mysqladmin -uroot -p shutdown Enter password 輸入新設定的密碼 etcrcdinitdmysql start

Q4NULL值問題

Ans

NULL值的概念是造成 SQL的新手的混淆的普遍原因他們經常認為 NULL是和一個空字符串的一樣的東西不是這樣的例如下列語句是完全不同的

mysqlgt INSERT INTO my_table (phone) VALUES (NULL)

mysqlgt INSERT INTO my_table (phone) VALUES ()

兩個語句把值插入到 phone 列但是第一個插入一個 NULL值而第二個插入一個空字符串第一個的含義可以認為是ldquo電話號碼不知道而第二個則可意味

著ldquo她沒有電話

在 SQL中NULL值在于任何其他值甚至 NULL值比較時總是假的(FALSE)包含 NULL的一個表達式總是產生一個 NULL值除非在包含在表達式中的運算符和函數的文檔中指出在下列例子所有的列返回 NULL

mysqlgt SELECT NULL1+NULLCONCAT(InvisibleNULL)

如果你想要尋找值是 NULL的列你不能使用=NULL測試下列語句不返回任

何行因為對任何表達式expr = NULL是假的

mysqlgt SELECT FROM my_table WHERE phone = NULL

要想尋找 NULL值你必須使用 IS NULL測試下例顯示如何找出 NULL電話號碼和空的電話號碼

70

mysqlgt SELECT FROM my_table WHERE phone IS NULL mysqlgt SELECT FROM my_table WHERE phone =

在 MySQL中就像很多其他的 SQL服務器一樣你不能索引可以有 NULL值的列你必須聲明這樣的列為 NOT NULL而且你不能插入 NULL到索引的

列中

當用 LOAD DATA INFILE 讀取數據時空列用更新如果你想要在一個列中有

NULL值你應該在文本文件中使用N字面上的詞NULL也可以在某些情形下使用

當使用 ORDER BY時首先呈現 NULL值如果你用 DESC以降序排序NULL值最後顯示當使用 GROUP BY時所有的 NULL值被認為是相等的

為了有助于NULL的處理你能使用 IS NULL和 IS NOT NULL運算符和 IFNULL()函數

對某些列類型NULL值被特殊地處理如果你將 NULL插入表的第一個TIMESTAMP 列則插入當前的日期和時間如果你將 NULL插入一個AUTO_INCREMENT 列則插入順序中的下一個數字

Q5如何將圖片存放於 MySQL中

Ans

Step 1建立資料庫 test

Step 2 建立表格 binary_data

CREATE TABLE binary_data (

id INT(4) NOT NULL AUTO_INCREMENT PRIMARY KEY

description CHAR(50)

bin_data LONGBLOB

filename CHAR(50)

filesize CHAR(50)

filetype CHAR(50)

71

)

Step 3 利用 storephp 寫入圖片

storephp 程式碼

ltHTMLgt ltHEADgtltTITLEgtStore binary data into SQL DatabaseltTITLEgtltHEADgt ltBODYgt lt code that will be executed if the form has been submitted

if ($submit) mysql_connect(localhostrootYOUR_PASSWORD) mysql_select_db(test) $data=Base64_Encode(fread(fopen($form_data r) filesize($form_data))) $result=MYSQL_QUERY(INSERT INTO binary_data (descriptionbin_datafilenamefilesizefiletype) VALUES ($form_description$data$form_data_name$form_data_size$form_data_type)) $id= mysql_insert_id() print ltpgtThis file has the following Database ID ltbgt$idltbgt MYSQL_CLOSE() else else show the form to submit new data

gt

ltform method=post action=ltphp echo $PHP_SELF gt enctype=multipartform-datagt File Descriptionltbrgt ltinput type=text name=form_description size=40gt ltINPUT TYPE=hidden name=MAX_FILE_SIZE value=4000000gt ltbrgtFile to uploadstore in databaseltbrgt ltinput type=file name=form_data size=40gt ltpgtltinput type=submit name=submit value=submitgt ltformgt lt

72

gt ltBODYgt ltHTMLgt

Step 3 利用 storephp 取出圖片

getdataphp 程式碼

lt Syntax getdataphp3id=ltidgt if($id) you may have to modify login information for your database server MYSQL_CONNECT(localhostrootYOUR_PASSWORD) mysql_select_db(test) $query = select bin_datafiletype from binary_data where id=$id $result = MYSQL_QUERY($query) $data = Base64_Decode(MYSQL_RESULT($result0bin_data)) $type = MYSQL_RESULT($result0filetype) Header( Content-type $type) echo $data gt

Q6MySQL裝好之後啟動時或是執行 mysqladmin會出現如下訊息 Cant connect to local MYSQL Server through Socket varlibmysqlmysqlsock或是

Cant connect to local MYSQL Server through Socket tmpmysqldsock

Ans 可能有下列幾個原因

1這個 mysqldsock 不見了被某人刪除了或是被一些系統自動執行程式給刪

了例如有些 cron任務便會設定定期刪除 tmp 裡的東西所以呢您只能修改

cron 裡的設定讓它不要清除 mysqldsock 2在啟動時也可以改變 mysqldsock的位置您在啟動 MySQL的時候可以加入此參數usrlocalmysqlbinsafe_mysqld --user=mysql --socket=其他路

徑socket amp 同時得去設定環境變數 MYSQL_UNIX_PORT的值以指定新的

73

路徑 3若是您沒改 MYSQL_UNIX_PORT的值那麼您可以在執行指令的時候才打

例如mysqladmin --socket=其他路徑socket version Q7How to get the last insert id Ans CREATE TABLE product ( id INT(4) NOT NULL AUTO_INCREMENT PRIMARY KEY description VARCHAR(50) ) 1利用 SQL的話 mysqlgt insert into product(description) values(123) Query OK 1 row affected (000 sec) mysqlgt select last_insert_id() +------------------+ | last_insert_id() | +------------------+ +------------------+ 1 row in set (000 sec) ======================================== 2如果是 PHP的話 你可以用mysql_insert_id()取得該 id PHP example $result=MYSQL_QUERY(INSERT INTO product (description) VALUES ($description)) $id= mysql_insert_id() print This file has the following Database ID $id Q8如何將文字檔匯入資料庫 Ans $addr=homehttpdhtmlphpschool001txt $sql_select = load data infile $addr into table test fields terminated by t 解說 $sql_select = load data infile 文字檔名 into table 表格名 fields terminated by

74

t

(欄位分隔以 TAB鍵) 該文字檔須與資料表欄位格式相符 例如欄位有三個 則文字檔為每行一筆資料如下 欄 1資料ltTABgt欄 2資料ltTABgt欄 3資料 欄 1資料ltTABgt欄 2資料ltTABgt欄 3資料 欄 1資料ltTABgt欄 2資料ltTABgt欄 3資料 欄 1資料ltTABgtltTABgt欄 3資料

Q9如何撰寫 MySQL C API Ans Step 1利用文字編輯器撰寫以下程式碼 mysqlcc

include ltstdiohgt

include ltmysqlmysqlhgt

int main (int argc char argv[])

MYSQL mysql

MYSQL_RES res

MYSQL_ROW row

if (argc = 2)

fputs (Usage myc ltdatabasegt stderr)

return 1

if ((mysql_connect(ampmysqllocalhostrootYour_Password)))

fputs (Error connecting stderr)

abort()

75

if (mysql_select_db(ampmysqlargv[1]))

fputs (Error selecting database stderr)

abort()

if (mysql_query(ampmysqlSELECT FROM test_table))

fputs (Error processing query stderr)

abort()

if ((res = mysql_store_result(ampmysql)))

fputs (Error storing results stderr)

abort()

while((row = mysql_fetch_row(res)))

uint i = 0

for (i=0 i lt mysql_num_fields(res) i++)

printf(s row[i])

printf(n)

return 0

Step 2 Compile

gcc -Iusrlocalmysqlinclude -Lusrlocalmysqllibmysql mysqlcc ndashlm -lmysqlclient

(其中 include path與 library path取決於你的 MySQL安裝路徑)

76

如果執行時發生如下 error Run problemerror in loading shared libraries libmysqlclientsoX 將你的 MySQL library path(for exampleusrlocalmysqllibmysql) 加入etcldsoconf and run sbinldconfig -v Q9ASP + MySQL 範例程式 Ans Dim myconn As New ADODBConnection Dim myrs As New Recordset Dim mySQL As String Dim myrows As Long myconnOpen DSN=MyODBCsample mySQL = SELECT from user myrsSource = mySQL Set myrsActiveConnection = myconn myrsCursorLocation = adUseClient myrsOpen myrows = myrsRecordCount myrsClose myconnClose 可參考 httpwwwdwamnetmysqlasp_myodbcasp 有詳細的資料 Q10如何將 MySQL中的資料庫匯出成txt檔 Ans select from TableName into outfile textxls all result fields will seperate by tab

77

第八章 參考資料

英文部份 網址 1 httpwwwmysqlcom MySQL 網站有第一手有關 MySQL的資料 2 httpwwwmysqlcomdocenReplicationhtml 有關 MySQL Replication 的文件 3 httpwwwgeocitiescomsqlhomefaqstore_blobhtml 如何在 MySQL 存放 BLOB的資料 4httpwwwsapdborg 有關 SAP跟 MySQL相關合作的網站 書藉 1 Cooking with MySQL

Paul DuBois has selected sample recipes from the hundreds youll find in his book MySQL

Cookbook In this third and final series of excerpts showcasing these recipes learn how to

compute team standings how to calculate the differences between successive Dec 26

2002 2 Tips for Building Web Database Applications with PHP and MySQL by Hugh E Williams co-author of Web Database Applications with PHP amp MySQL 04042002

3 Managing and Using MySQL 2nd Edition By Tim King George Reese Randy Jay Yarger

4 MySQL Cookbook By Paul DuBoisPublisher OReillyPub Date October 2002

中文部份

78

1 httplinuxtncedutwtechdocmysqlmysql_docmanual_tochtml MySQL 中文手冊 2 httpchenshloxaedutwphpZ_1php PHP+MySQ程式研習設計網站 3 httplinuxtncedutwtechdocbanicdownhtml PHP 4 手冊 4 httpwwwtncedutwadmin_zonephp台南縣教育網網路中心有很多 Linux相關文件 5 httpdobtncedutw網站建置百寶箱有很多 PHP MySQL 相關範例程式 5 httpwwwdbworldcomtw資料庫專家電子雜誌介紹資料庫的重要觀念及名詞

79

附錄一 SQL Command 介紹

SQL (讀音ess-que-el) 是一種結構查詢語法SQL 使用於資料庫交流

傳遞相容於 ANSI (American National Standards Institute) 是一套標準的關聯

式資料庫語言 SQL 語言是執行更新或從資料系統獲取資料一般常見的關聯

資料庫系統都有提供 SQL 如 Oracle Sybase Microsoft SQL Server Access Ingres 等雖然大部份的資料庫都有提供 SQL 但也多提供了自已獨特的語

法造成了不相容的情形但標準基本的語法是相通的如Select Insert Update Delete Create and Drop 每一個系統都有支援

Table相關 Command

Create Table

關聯式資料庫包含有很多元件稱為資料表(tables) 把資料或訊息放在資

料表中 資料表是以不同的名稱做分別資料表由欄列所構成的二維陣列

欄包含欄位名資料型態 及其他可判斷的資訊列是由全部欄位構成一筆一

筆的紀錄 create table 語法用在建立一個新的資料表語法格式如下

create table tablename (column1 data type column2 data type column3 data type)

Format of create table if you were to use optional constraints

create table tablename (column1 data type [constraint] column2 data type [constraint] column3 data type [constraint]) [ ] = optional

Note You may have as many columns as youd like and the constraints are optional

80

Example

create table employee (first varchar(15) last varchar(20) age number(3) address varchar(30) city varchar(20) state varchar(20))

注意建立資料表格式要以括號把前後框住而最後以(分號)做結尾

欄位名不要超過 30個字元長而且不要使用 sql 的關鍵字(如 where select等)而在後面接是型態的宣告(如字串數字日期格式等)

資料型態是來描述欄位的方式如一個欄位Last_Name 是一個姓氏可以使用varchar (可變動長度字串) 資料型態

以下是幾個常見的資料庫型態 char(size) 固定長度字串最長為 255 位元 varchar(size) 變動長度字串最大字元數以 size 來指定 number(size) 數值格式可以是整數也可以是小數最大數字以 size 位數判

斷未指定小數位數由系統內定 date 日期格式 number(sized) 數值格式最大數字以 size 位數判斷d 為小數位數整數位

數為 size-d 位

有何限制當資料表被建立通常有一或數個欄位是要使用來做關聯的功

能 例如unique 限制(唯一值)兩筆記錄不可以相同的值 not null (非空值)該欄位一定要輸入資料不可是空的primary key (主鍵)是每一筆記錄識別的主要方式

Drop a table drop table 刪除資料表(其中的資料也會一併刪除)

drop table tablename

Example

81

drop table 和刪除全部資料是不同的刪除全部資料欄位名稱資訊等還會

存在但刪除資料表會把這一些也一併移除掉

如何查詢資料

Select 基本用法

select 語法是關連式資料庫最常用的部份可以取得你想要的資料這是一個

簡單的範例 select column1[column2etc] from tablename [where condition] [] = optional 在 select 之後所列欄位名則是要顯示的資料部份你可以一一列出各欄位

名或是以 (星號)來代表選擇全部的欄位 from 之後放資料表名稱 where 子句 (選項) 指定要過濾的條件符合者才會顯現 where 可使用的條件運算元 = 等於 gt 大於 lt 小於 gt= 大或等於 lt= 小或等於 ltgt 大相等 LIKE 相似 For example select first last city

82

from empinfo where first LIKE Er 以Er 為開頭的字串就符合要以單引號框住 Or you can specify select first last from empinfo where last LIKE s 最後一字為 S 就符合 select from empinfo where first = Eric 則表示 first name 一定要是 Eric 才可以 範例資料表empinfo 統計函數

MIN 傳回指定欄位最小值

MAX 傳回指定欄位最大值

SUM 傳回指定欄位總和

AVG 傳回指定欄位平均值

COUNT 傳回指定欄位的筆數

COUNT() 傳回資料庫中的總筆數

統計函數使用於資料表中的數值欄位配合 SELECT 語法使用 只用於總結特定單一欄位可以配合 GROUP BY 做篩選但也可以不使用 GROUP BY 語句For example

SELECT AVG(salary) FROM employee

83

傳回全部 salary 平均值

Another example

SELECT AVG(salary) FROM employee WHERE title = Programmer

傳回 salary 平均值條件為 employees 資料表中當 title 等於 Programmer

Example

SELECT Count() FROM employees

傳回 employees 資料表中紀錄總筆數

GROUP BY 語法 SELECT column1 SUM(column2) FROM list-of-tables GROUP BY column-list The GROUP BY 語句可以先以所列的欄位為條件分組排序在一起(可以多欄

位) example 要列出每一個 dept 中最高 salary 值 SELECT max(salary) dept FROM employee GROUP BY dept HAVING 語法

SELECT column1 SUM(column2) FROM list-of-tables GROUP BY column-list HAVING condition

HAVING 子句是 GROUP BY 的一部份用來過濾在 GROUP BY 所選出的資料功能如同 select 命令中 where 條件式一樣只是 HAVING 必需配合 GROUP BY 使用

我們以例子來說明我們要取得每一公司名及每一公司的薪水平均值輸入如下

84

SELECT dept avg(salary) FROM employee GROUP BY dept

但如果我們只列出薪資平均值超過 20000元的公司資料

SELECT dept avg(salary) FROM employee GROUP BY dept HAVING avg(salary) gt 20000

ORDER BY子句語法

SELECT column1 SUM(column2) FROM list-of-tables ORDER BY column-list [ASC | DESC]

[ ] =選項

ORDER BY是一個選項子句當你以排序方式來顯示資料(正向由小到大反向由大到小)以指定的欄位資料做排序

ASC = 正向- 預設值 DESC = 反向排序

For example

SELECT employee_id dept name age salary FROM employee_info WHERE dept = Sales ORDER BY salary

以上列出公司代號公司名銷售員人名年紀及薪資而條件是公司名為 Sales 顯示順序以薪資多少排序(由小到大為預設值)

如果要以多個欄位做排序要以逗號做分隔如下

SELECT employee_id dept name age salary FROM employee_info WHERE dept = Sales ORDER BY salary age DESC

85

結合條件及布林運算 SELECT column1 SUM(column2) FROM list-of-tables WHERE condition1 AND condition2 AND運算可以結兩個或以上的條件放在 WHERE子句中 兩者都要為真才

會顯示該筆記錄 OR 運算可以結兩個或以上敘述放在 WHERE子句中只要其中一個為直就

會顯示該筆記錄 For example SELECT employeeid firstname lastname title salary FROM employee_info WHERE salary gt= 5000000 AND title = Programmer 必需要薪資大於等於 50000而且職稱為 Programmer同時符合才會顯示該筆資料 以下以括號括住雖然不是必需的但如此比較容易讀 SELECT employeeid firstname lastname title salary FROM employee_info WHERE (salary gt= 5000000) AND (title = Programmer) 另外範例 SELECT firstname lastname title salary FROM employee_info WHERE (title = Sales) OR (title = Programmer) 條件為只要是 Sales 或 Programmer 職稱的就會被列出 IN and BETWEEN 子句

SELECT column1 SUM(column2) FROM list-of-tables WHERE column3 IN (list-of-values) SELECT column1 SUM(column2) FROM list-of-tables WHERE column3 BETWEEN value1 AND value2 IN 子句使用在列舉項目的使用上也就是分別測試是否符合所列的值 For example

86

SELECT employeeid lastname salary FROM employee_info WHERE lastname IN (Hernandez Jones Roberts Ruiz) 條件為姓氏(astname)要符合 Hernandez Jones Roberts or Ruiz 其中一個才會被傳回 IN運算元也可以使用 OR 的語法來取代如下結果相同 SELECT employeeid lastname salary FROM employee_info WHERE lastname = Hernandez OR lastname = Jones OR lastname = Roberts OR lastname = Ruiz 但使用 IN 句子比較短也比較易懂 你也可以使用 NOT IN 來去掉不要的記錄 BETWEEN 運算元使用在判斷是否存在兩個數值之間 For example SELECT employeeid age lastname salary FROM employee_info WHERE age BETWEEN 30 AND 40 傳回年紀 30歲到 40歲之間的資料(含 30及 40歲者) 相同的也可以使用以下語法來達到相同的結果 SELECT employeeid age lastname salary FROM employee_info WHERE age gt= 30 AND age lt= 40 你也可使用 NOT BETWEEN 來濾掉中間值的資料 數學運算 標準 ANSI SQL-92 提供以下運算

87

+ 加

- 減

餘數

餘數為除法後剩整數這不在標準的 ANSI SQL 中但大部份的資料庫都會支

援這運算元以下列出有用的函數雖不在 ANSI SQL-92 提供但一般資料庫

也會支援他們

ABS(x) 傳回 x 絕對值

SIGN(x) returns the sign of input x as -1 0 or 1 (negative zero or positive respectively)

MOD(xy) 餘數 - returns the integer remainder of x divided by y (同 xy)

FLOOR(x) 傳回小或等於 x 的最大整數值

CEILING(x) or CEIL(x)

傳回大或等於 x 的最小整數值

POWER(xy) x的 y 次方

ROUND(x) 把 x 四捨五入為整數

ROUND(xd) 四捨五入取到小數 d 位

SQRT(x) x 開平方

For example SELECT round(salary) firstname FROM employee_info 傳回薪資取到整數位

如何新增資料

insert 加入一筆新紀錄到資料表中 insert into tablename (first_columnlast_column) values (first_valuelast_value) [] = optional Example insert into employee

88

(first last age address city state) values (Luke Duke 45 2130 Boars Nest Hazard Co Georgia) Note 字串要以單引號住如string 數字框住也無妨 insert into 後面接資料表名稱再接以括號括住的欄位名在 values 後括號分別對映各欄位的值 以上的例子新增了一筆名(first) 為 Luke而住所(state) 為 Georgia 的資料

如何刪除資料

delete 可以刪除單筆或多筆紀錄 delete from tablename where columnname OPERATOR value [and|or column OPERATOR value] [ ] = optional Examples delete from employee Note 如果你沒有指定 where 子句那麼全部的紀錄都會被刪除 delete from employee where lastname = May delete from employee where firstname = Mike or firstname = Eric delete from 接著資料表名 再接著是條件式判斷沒有條件式則全部紀錄會

被刪除

如何更新資料

update 用來更新你所指定的記錄要和 WHERE 配合小心使用 語法 update tablename set columnname = newvalue[nextcolumn = newvalue2] where columnname OPERATOR value [and|or column OPERATOR value] [] = optional Examples

89

update phone_book set area_code = 623 where prefix = 979 update phone_book set last_name = Smith prefix=555 suffix=9292 where last_name = Jones update employee set age = age+1 where first_name=Mary and last_name=Williams

90

附錄二Replication

測試環境

RedHat 90 + MySQL 32358 MySQL資料庫路徑 varlibmysql MySQL設定檔 etcmycnf Master IP 1921680100 Slave IP 1921680200 請至下列網址下載最新MySQL 32358套件並利用rpm ndashUvh 更新 httpupdatesredhatcom9enosi386

圖 最新 MySQL 套件

測試架構圖

91

1921680100

1921680200Master Server

erveSlave S r

圖 測試架構圖

測試步驟

Master server 部份 Step1 確認 MasterSlave機器上所裝的 MySQL版本能進行

replication( 32329 or higher ) Step2 在 Master MySQL上開放一個帳號給 Slave mysql ndashu root ndashp mysqlgtGRANT FILE ON TO repl1921680200 IDENTIFIED BY lsquoabc123rsquo mysqlgtq 上面是 Master開放一個帳號 repl密碼 abc123給 IP1921680200有檔案處理

的權限 Step3 shutdown MySQL on the Master mysqladmin ndashu root ndashp shutdown Step4 備份 Master所有資料庫 tar ndashcvf tmpmysql-snapshottar varlibmysql 注意tar的時候MySQL是要在 stop情況下 在mysql (wwwmysqlcom) 網站的FAQ有不用shutdown的方法

92

Step5 在 master機器上修改etcmycnf 在[mysqld]區段內加入參數 log-bin server-id=這邊設定 server-id=1 sql-bin-update-same binlog-do-db=CRM只針對 CRM資料庫做紀錄 Step6 Restart MySQL on the master service mysqld start 此時因為有加入 log-bin 參數因此開始有 index產生了在varlibmysql目錄下

有index檔案紀錄資料庫的異動 log Slave server 部份 Step1 在 slave設定etcmycnf 在[mysqld]區段加入 master-host= master-user= master-password= master-port= server-id= 這邊設定 master-host=1921680100 master-user=repl master-password=abc123 master-port=3306 server-id=2 master-connect-retry=60預設重試間隔 60秒 replicate-do-db=CRM告訴 slave只做 CRM資料庫的更新 log-slave-updates Step2 將 master上的 mysql-snapshottar copy到 slave上 用 ftp傳到 slave的tmp Step3 解壓縮 Master資料庫至 Slave Server上 cd varlib tar xvf tmpmysql-snapshottar chown ndashR mysqlmysql mysql

93

chmod ndashR 770 mysql (視情況) Step4 Restart MySQL on the slave server 這時在varlibmysql目錄會出現 masterinfo此檔案紀錄了 Master MySQL server的資訊

狀況測試

One-way replication

1921680100

1921680200Master Server

erveSlave S r

圖 One-way replication架構圖 Step1 Master跟 Slave網路及服務都正常情況下由 Master端異動資料後 到 Slave端瀏覽資料檢視是否有進行 replication Step2 模擬 Slave Server 當機 可用在於 slave真的當機或是 Slave 不一定需要一直跟 master connect將Slave MySQL server shutdown由 Master端異動資料到 slave端瀏覽此時Slave應該沒有被 replication 更新然後再將 Slave端 MySQL server start起來

預設 60秒後 Slave會嘗試跟 Master要求進行 replication再去 Slave端檢視是否有更新資料

94

Step3 模擬 Master當機因為是設定 One-way replication一旦 Master Server Slave端沒有 Master的 source可以 download Two-way replication 基於 Master當機狀況於是發展雙向 Replication即 1921680100 ( Host A ) 1921680200 ( Host B )都分別擔任 MasterSlave身分

1921680100

1921680200er

Server B MasterSlave Server

Server A MasterSlave Serv

圖 Two-way replication架構圖 以下是針對兩台 MySQL伺服器進行雙向 Replication Step1觀念同單向 replication只是改成 Master也有 Slave身分 Slave也有Master的身分先分別在 Server AServer B 都去 grant一個進行 replication的身分 [A]mysqlgtGRANT FILE ON TO repl1921680200 IDENTIFIED BY lsquoabc123rsquo [B]mysqlgt GRANT FILE ON TO repl1921680100 IDENTIFIED BY lsquoabc123rsquo Step2做完單向 replication後stop Server Aserver B MySQL service此時 AB資料是一樣的

95

修改etcmycnf設定 範例 Server A [mysqld] datadir=varlibmysql socket=varlibmysqlmysqlsock server-id=1 log-bin sql-bin-update-same binlog-do-db=CRM master-host=1921680200 master-user=repl master-password=abc123 log-slave-updates master-connect-retry=60 replicate-do-db=CRM Server B [mysqld] datadir=varlibmysql socket=varlibmysqlmysqlsock server-id=2 log-bin sql-bin-update-same binlog-do-db=CRM master-host=1921680100 master-user=repl master-password=abc123 log-slave-updates master-connect-retry=60 replicate-do-db=CRM 分別 start Server AServer B MySQL後此時雙方都是 MasterSlave身分一旦哪一方資料異動就會通知對方來 replication-若 replication失效則必須將Server AServer B的masterinfo及index00x 都砍掉然後分別 restart MySQL server進行測試檢視成果 實務上通常如果需要做Two-way replication通常會搭配Virtual Server使用

96

在前端架設一台Virtual Server不過此部份不在此份SOP討論範圍內有興趣

的讀者可參考 httpwwwlinuxvirtualserverorg 網站

1921680100 1921680200

Host A MasterSlave Server

Host B MasterSlave Server

Virtual Host

圖 Virtual Server + Two-way replication 架構圖

97

圖 High Availability Linux Virtual Server架構圖

98

  • COSA-SOP-03-006
  • 第一章 簡介
    • 11適用對象 (Audience)
    • 12 MySQL本身
    • 13 MySQL 40版跟50版重大的改進功能
    • 14 各家資料庫軟體比較
      • 第二章 前置需求
      • 第三章 安裝
        • 31 MySQL安裝
        • 32 phpMyAdmin安裝
        • 33 升級及注意事項
          • 第四章 MySQL管理
            • 41 Webmin 管理介面
            • 42 phpMyAdmin 的操作介面
            • 43管理指令介紹
              • 431 利用mysqladmin設定root的密碼
                  • 第五章 實用範例
                    • 51 任務一Web Base客戶通訊錄
                    • 52 任務二Web Base群組軟體 ( twig )
                      • 第六章 維護及更新程序
                        • 61 日常維護
                        • 62 更新程序
                        • 63 備份重要檔案
                        • 64 離線備份與還原
                        • 65 線上備份與還原
                          • 第七章 問題與解答
                          • 第八章 參考資料
                          • 附錄一 SQL Command 介紹
                          • 附錄二Replication
Page 67: DataBase Server Standard Operation Procedureebooks.lib.ntu.edu.tw/1_file/oss/63/93doc4-5.pdf · 業務的公司帶來了不少壓力,譬如微軟,甲骨文 ... 外的錢用在第三方的資料庫產品上,譬如就可以不用再購買甲骨文公司

另外假如你是系統重建或是移機時切需在新的 MySQL 內新建一個空白 DB 後才行作回存的工作你可以用下面的指令建立 mysql -uroot -p -e CREATE DATABASE CRM (上面的 CRM是你要新建的 DB 名稱) 另一種作法先用 mysql 指令進入 mysql client console 然後再用 CREATE DATABASE CRM 這樣就行了記得尾端要加個 符號該行指令才會執行

67

第七章 問題與解答

Q1RedHat 90預附的 MySQL到底有無支援 Transcation機制 Ans MySQL自 32334a之後的 MySQL-Max版本加入 InnoDB的資料庫類型透過

InnoDBMySQL同樣可以進行 COMMIT與 ROLLRACK的動作RedHat 90預附的 MySQL為 32354a-11巳支援 InnoDB的資料庫類型不過必須做以

下設定 1cp usrsharedocmysql-server-32354amy-mediumcnf to etcmycnf 2 vi etcmycnf 將以下設定前的拿掉 innodb_data_home_dir = varlibmysql innodb_data_file_path = ibdata110Mautoextend innodb_log_group_home_dir = varlibmysql innodb_log_arch_dir = varlibmysql 3service mysqld restart 如此一來各位在建立Table時便可指定Table Type為 innodb ( ex create table with type=innodb ) Q2如何解決 php+mysql 許功蓋等字變亂的問題 Ans 方法一 【確定 MySQL 預設的字元集】 1 打開 WinMySQLadmin 管理畫面(在視窗右下角狀態列紅綠燈圖示中按滑鼠

右鍵點選 Show me 選項) 2 點選管理畫面中 [Variables] 標籤選項其中 character_set變數就是您預設

字元集的變數其預設是 latin1 字元集(我們要將他改回 big5)而 chatacters_set 變數則是 MySQL 可以支援哪些字元集 【修改預設字元集變數 character_set 】 1 請點選管理畫面中 [myini Setup] 標籤選項設定 myini 2 按一下 [Pick-up and Edit myini values] 按鈕以便編輯目前的 myini 設定 3 在 [mysqld] 設定區塊底下新增一行 default-character-set = big5 變數設

68

定 4 新增一個 [client] 設定區塊並加入第三步驟的變數設定(游標往下移到空白處新增兩行 [client] 和 default-character-set=big5) 5 按一下畫面左下方 [Save Modification] 按鈕儲存設定 6 重新啟動 MySQL 或 Windows 方法二 Server端注意事項 phpini 中有關的設定為(預設值) Magic quotes for incoming GETPOSTCookie data magic_quotes_gpc = On Use Sybase-style magic quotes (escape with instead of ) magic_quotes_sybase = Off Client端注意事項 1中文資料送進 mysql 前請用 addslashes($str) 處理 2處理後送進 mysql 時請用 括起來並在參數後留一個空白如 $sql = UPDATE ezf_table set tablename=$tname tableend=$endtime table inguser=$tguser tableingid=$tguserid tableallnumber=$tnumber tableloca l=$tablelocal tableanyone=$tableopen tabletext=$ttext WHERE tableid=$t ableid tablename=$tname c 取出時請用 stripslashes($str) Q3MySQL root 密碼忘了該怎麼辦 Ans 1先停掉 mysql etcrcdinitdmysql stop 2以--skip-grant-table 的參數啟動 mysql safe_mysql --skip-grant-tableamp 3 更改 root 密碼 mysql mysql mysqlgt UPDATE user SET password=password(newpassword)

69

WHERE user=root mysqlgt FLUSH PRIVILEGES mysqlgt exit 4停掉 mysql再重跑 mysqladmin -uroot -p shutdown Enter password 輸入新設定的密碼 etcrcdinitdmysql start

Q4NULL值問題

Ans

NULL值的概念是造成 SQL的新手的混淆的普遍原因他們經常認為 NULL是和一個空字符串的一樣的東西不是這樣的例如下列語句是完全不同的

mysqlgt INSERT INTO my_table (phone) VALUES (NULL)

mysqlgt INSERT INTO my_table (phone) VALUES ()

兩個語句把值插入到 phone 列但是第一個插入一個 NULL值而第二個插入一個空字符串第一個的含義可以認為是ldquo電話號碼不知道而第二個則可意味

著ldquo她沒有電話

在 SQL中NULL值在于任何其他值甚至 NULL值比較時總是假的(FALSE)包含 NULL的一個表達式總是產生一個 NULL值除非在包含在表達式中的運算符和函數的文檔中指出在下列例子所有的列返回 NULL

mysqlgt SELECT NULL1+NULLCONCAT(InvisibleNULL)

如果你想要尋找值是 NULL的列你不能使用=NULL測試下列語句不返回任

何行因為對任何表達式expr = NULL是假的

mysqlgt SELECT FROM my_table WHERE phone = NULL

要想尋找 NULL值你必須使用 IS NULL測試下例顯示如何找出 NULL電話號碼和空的電話號碼

70

mysqlgt SELECT FROM my_table WHERE phone IS NULL mysqlgt SELECT FROM my_table WHERE phone =

在 MySQL中就像很多其他的 SQL服務器一樣你不能索引可以有 NULL值的列你必須聲明這樣的列為 NOT NULL而且你不能插入 NULL到索引的

列中

當用 LOAD DATA INFILE 讀取數據時空列用更新如果你想要在一個列中有

NULL值你應該在文本文件中使用N字面上的詞NULL也可以在某些情形下使用

當使用 ORDER BY時首先呈現 NULL值如果你用 DESC以降序排序NULL值最後顯示當使用 GROUP BY時所有的 NULL值被認為是相等的

為了有助于NULL的處理你能使用 IS NULL和 IS NOT NULL運算符和 IFNULL()函數

對某些列類型NULL值被特殊地處理如果你將 NULL插入表的第一個TIMESTAMP 列則插入當前的日期和時間如果你將 NULL插入一個AUTO_INCREMENT 列則插入順序中的下一個數字

Q5如何將圖片存放於 MySQL中

Ans

Step 1建立資料庫 test

Step 2 建立表格 binary_data

CREATE TABLE binary_data (

id INT(4) NOT NULL AUTO_INCREMENT PRIMARY KEY

description CHAR(50)

bin_data LONGBLOB

filename CHAR(50)

filesize CHAR(50)

filetype CHAR(50)

71

)

Step 3 利用 storephp 寫入圖片

storephp 程式碼

ltHTMLgt ltHEADgtltTITLEgtStore binary data into SQL DatabaseltTITLEgtltHEADgt ltBODYgt lt code that will be executed if the form has been submitted

if ($submit) mysql_connect(localhostrootYOUR_PASSWORD) mysql_select_db(test) $data=Base64_Encode(fread(fopen($form_data r) filesize($form_data))) $result=MYSQL_QUERY(INSERT INTO binary_data (descriptionbin_datafilenamefilesizefiletype) VALUES ($form_description$data$form_data_name$form_data_size$form_data_type)) $id= mysql_insert_id() print ltpgtThis file has the following Database ID ltbgt$idltbgt MYSQL_CLOSE() else else show the form to submit new data

gt

ltform method=post action=ltphp echo $PHP_SELF gt enctype=multipartform-datagt File Descriptionltbrgt ltinput type=text name=form_description size=40gt ltINPUT TYPE=hidden name=MAX_FILE_SIZE value=4000000gt ltbrgtFile to uploadstore in databaseltbrgt ltinput type=file name=form_data size=40gt ltpgtltinput type=submit name=submit value=submitgt ltformgt lt

72

gt ltBODYgt ltHTMLgt

Step 3 利用 storephp 取出圖片

getdataphp 程式碼

lt Syntax getdataphp3id=ltidgt if($id) you may have to modify login information for your database server MYSQL_CONNECT(localhostrootYOUR_PASSWORD) mysql_select_db(test) $query = select bin_datafiletype from binary_data where id=$id $result = MYSQL_QUERY($query) $data = Base64_Decode(MYSQL_RESULT($result0bin_data)) $type = MYSQL_RESULT($result0filetype) Header( Content-type $type) echo $data gt

Q6MySQL裝好之後啟動時或是執行 mysqladmin會出現如下訊息 Cant connect to local MYSQL Server through Socket varlibmysqlmysqlsock或是

Cant connect to local MYSQL Server through Socket tmpmysqldsock

Ans 可能有下列幾個原因

1這個 mysqldsock 不見了被某人刪除了或是被一些系統自動執行程式給刪

了例如有些 cron任務便會設定定期刪除 tmp 裡的東西所以呢您只能修改

cron 裡的設定讓它不要清除 mysqldsock 2在啟動時也可以改變 mysqldsock的位置您在啟動 MySQL的時候可以加入此參數usrlocalmysqlbinsafe_mysqld --user=mysql --socket=其他路

徑socket amp 同時得去設定環境變數 MYSQL_UNIX_PORT的值以指定新的

73

路徑 3若是您沒改 MYSQL_UNIX_PORT的值那麼您可以在執行指令的時候才打

例如mysqladmin --socket=其他路徑socket version Q7How to get the last insert id Ans CREATE TABLE product ( id INT(4) NOT NULL AUTO_INCREMENT PRIMARY KEY description VARCHAR(50) ) 1利用 SQL的話 mysqlgt insert into product(description) values(123) Query OK 1 row affected (000 sec) mysqlgt select last_insert_id() +------------------+ | last_insert_id() | +------------------+ +------------------+ 1 row in set (000 sec) ======================================== 2如果是 PHP的話 你可以用mysql_insert_id()取得該 id PHP example $result=MYSQL_QUERY(INSERT INTO product (description) VALUES ($description)) $id= mysql_insert_id() print This file has the following Database ID $id Q8如何將文字檔匯入資料庫 Ans $addr=homehttpdhtmlphpschool001txt $sql_select = load data infile $addr into table test fields terminated by t 解說 $sql_select = load data infile 文字檔名 into table 表格名 fields terminated by

74

t

(欄位分隔以 TAB鍵) 該文字檔須與資料表欄位格式相符 例如欄位有三個 則文字檔為每行一筆資料如下 欄 1資料ltTABgt欄 2資料ltTABgt欄 3資料 欄 1資料ltTABgt欄 2資料ltTABgt欄 3資料 欄 1資料ltTABgt欄 2資料ltTABgt欄 3資料 欄 1資料ltTABgtltTABgt欄 3資料

Q9如何撰寫 MySQL C API Ans Step 1利用文字編輯器撰寫以下程式碼 mysqlcc

include ltstdiohgt

include ltmysqlmysqlhgt

int main (int argc char argv[])

MYSQL mysql

MYSQL_RES res

MYSQL_ROW row

if (argc = 2)

fputs (Usage myc ltdatabasegt stderr)

return 1

if ((mysql_connect(ampmysqllocalhostrootYour_Password)))

fputs (Error connecting stderr)

abort()

75

if (mysql_select_db(ampmysqlargv[1]))

fputs (Error selecting database stderr)

abort()

if (mysql_query(ampmysqlSELECT FROM test_table))

fputs (Error processing query stderr)

abort()

if ((res = mysql_store_result(ampmysql)))

fputs (Error storing results stderr)

abort()

while((row = mysql_fetch_row(res)))

uint i = 0

for (i=0 i lt mysql_num_fields(res) i++)

printf(s row[i])

printf(n)

return 0

Step 2 Compile

gcc -Iusrlocalmysqlinclude -Lusrlocalmysqllibmysql mysqlcc ndashlm -lmysqlclient

(其中 include path與 library path取決於你的 MySQL安裝路徑)

76

如果執行時發生如下 error Run problemerror in loading shared libraries libmysqlclientsoX 將你的 MySQL library path(for exampleusrlocalmysqllibmysql) 加入etcldsoconf and run sbinldconfig -v Q9ASP + MySQL 範例程式 Ans Dim myconn As New ADODBConnection Dim myrs As New Recordset Dim mySQL As String Dim myrows As Long myconnOpen DSN=MyODBCsample mySQL = SELECT from user myrsSource = mySQL Set myrsActiveConnection = myconn myrsCursorLocation = adUseClient myrsOpen myrows = myrsRecordCount myrsClose myconnClose 可參考 httpwwwdwamnetmysqlasp_myodbcasp 有詳細的資料 Q10如何將 MySQL中的資料庫匯出成txt檔 Ans select from TableName into outfile textxls all result fields will seperate by tab

77

第八章 參考資料

英文部份 網址 1 httpwwwmysqlcom MySQL 網站有第一手有關 MySQL的資料 2 httpwwwmysqlcomdocenReplicationhtml 有關 MySQL Replication 的文件 3 httpwwwgeocitiescomsqlhomefaqstore_blobhtml 如何在 MySQL 存放 BLOB的資料 4httpwwwsapdborg 有關 SAP跟 MySQL相關合作的網站 書藉 1 Cooking with MySQL

Paul DuBois has selected sample recipes from the hundreds youll find in his book MySQL

Cookbook In this third and final series of excerpts showcasing these recipes learn how to

compute team standings how to calculate the differences between successive Dec 26

2002 2 Tips for Building Web Database Applications with PHP and MySQL by Hugh E Williams co-author of Web Database Applications with PHP amp MySQL 04042002

3 Managing and Using MySQL 2nd Edition By Tim King George Reese Randy Jay Yarger

4 MySQL Cookbook By Paul DuBoisPublisher OReillyPub Date October 2002

中文部份

78

1 httplinuxtncedutwtechdocmysqlmysql_docmanual_tochtml MySQL 中文手冊 2 httpchenshloxaedutwphpZ_1php PHP+MySQ程式研習設計網站 3 httplinuxtncedutwtechdocbanicdownhtml PHP 4 手冊 4 httpwwwtncedutwadmin_zonephp台南縣教育網網路中心有很多 Linux相關文件 5 httpdobtncedutw網站建置百寶箱有很多 PHP MySQL 相關範例程式 5 httpwwwdbworldcomtw資料庫專家電子雜誌介紹資料庫的重要觀念及名詞

79

附錄一 SQL Command 介紹

SQL (讀音ess-que-el) 是一種結構查詢語法SQL 使用於資料庫交流

傳遞相容於 ANSI (American National Standards Institute) 是一套標準的關聯

式資料庫語言 SQL 語言是執行更新或從資料系統獲取資料一般常見的關聯

資料庫系統都有提供 SQL 如 Oracle Sybase Microsoft SQL Server Access Ingres 等雖然大部份的資料庫都有提供 SQL 但也多提供了自已獨特的語

法造成了不相容的情形但標準基本的語法是相通的如Select Insert Update Delete Create and Drop 每一個系統都有支援

Table相關 Command

Create Table

關聯式資料庫包含有很多元件稱為資料表(tables) 把資料或訊息放在資

料表中 資料表是以不同的名稱做分別資料表由欄列所構成的二維陣列

欄包含欄位名資料型態 及其他可判斷的資訊列是由全部欄位構成一筆一

筆的紀錄 create table 語法用在建立一個新的資料表語法格式如下

create table tablename (column1 data type column2 data type column3 data type)

Format of create table if you were to use optional constraints

create table tablename (column1 data type [constraint] column2 data type [constraint] column3 data type [constraint]) [ ] = optional

Note You may have as many columns as youd like and the constraints are optional

80

Example

create table employee (first varchar(15) last varchar(20) age number(3) address varchar(30) city varchar(20) state varchar(20))

注意建立資料表格式要以括號把前後框住而最後以(分號)做結尾

欄位名不要超過 30個字元長而且不要使用 sql 的關鍵字(如 where select等)而在後面接是型態的宣告(如字串數字日期格式等)

資料型態是來描述欄位的方式如一個欄位Last_Name 是一個姓氏可以使用varchar (可變動長度字串) 資料型態

以下是幾個常見的資料庫型態 char(size) 固定長度字串最長為 255 位元 varchar(size) 變動長度字串最大字元數以 size 來指定 number(size) 數值格式可以是整數也可以是小數最大數字以 size 位數判

斷未指定小數位數由系統內定 date 日期格式 number(sized) 數值格式最大數字以 size 位數判斷d 為小數位數整數位

數為 size-d 位

有何限制當資料表被建立通常有一或數個欄位是要使用來做關聯的功

能 例如unique 限制(唯一值)兩筆記錄不可以相同的值 not null (非空值)該欄位一定要輸入資料不可是空的primary key (主鍵)是每一筆記錄識別的主要方式

Drop a table drop table 刪除資料表(其中的資料也會一併刪除)

drop table tablename

Example

81

drop table 和刪除全部資料是不同的刪除全部資料欄位名稱資訊等還會

存在但刪除資料表會把這一些也一併移除掉

如何查詢資料

Select 基本用法

select 語法是關連式資料庫最常用的部份可以取得你想要的資料這是一個

簡單的範例 select column1[column2etc] from tablename [where condition] [] = optional 在 select 之後所列欄位名則是要顯示的資料部份你可以一一列出各欄位

名或是以 (星號)來代表選擇全部的欄位 from 之後放資料表名稱 where 子句 (選項) 指定要過濾的條件符合者才會顯現 where 可使用的條件運算元 = 等於 gt 大於 lt 小於 gt= 大或等於 lt= 小或等於 ltgt 大相等 LIKE 相似 For example select first last city

82

from empinfo where first LIKE Er 以Er 為開頭的字串就符合要以單引號框住 Or you can specify select first last from empinfo where last LIKE s 最後一字為 S 就符合 select from empinfo where first = Eric 則表示 first name 一定要是 Eric 才可以 範例資料表empinfo 統計函數

MIN 傳回指定欄位最小值

MAX 傳回指定欄位最大值

SUM 傳回指定欄位總和

AVG 傳回指定欄位平均值

COUNT 傳回指定欄位的筆數

COUNT() 傳回資料庫中的總筆數

統計函數使用於資料表中的數值欄位配合 SELECT 語法使用 只用於總結特定單一欄位可以配合 GROUP BY 做篩選但也可以不使用 GROUP BY 語句For example

SELECT AVG(salary) FROM employee

83

傳回全部 salary 平均值

Another example

SELECT AVG(salary) FROM employee WHERE title = Programmer

傳回 salary 平均值條件為 employees 資料表中當 title 等於 Programmer

Example

SELECT Count() FROM employees

傳回 employees 資料表中紀錄總筆數

GROUP BY 語法 SELECT column1 SUM(column2) FROM list-of-tables GROUP BY column-list The GROUP BY 語句可以先以所列的欄位為條件分組排序在一起(可以多欄

位) example 要列出每一個 dept 中最高 salary 值 SELECT max(salary) dept FROM employee GROUP BY dept HAVING 語法

SELECT column1 SUM(column2) FROM list-of-tables GROUP BY column-list HAVING condition

HAVING 子句是 GROUP BY 的一部份用來過濾在 GROUP BY 所選出的資料功能如同 select 命令中 where 條件式一樣只是 HAVING 必需配合 GROUP BY 使用

我們以例子來說明我們要取得每一公司名及每一公司的薪水平均值輸入如下

84

SELECT dept avg(salary) FROM employee GROUP BY dept

但如果我們只列出薪資平均值超過 20000元的公司資料

SELECT dept avg(salary) FROM employee GROUP BY dept HAVING avg(salary) gt 20000

ORDER BY子句語法

SELECT column1 SUM(column2) FROM list-of-tables ORDER BY column-list [ASC | DESC]

[ ] =選項

ORDER BY是一個選項子句當你以排序方式來顯示資料(正向由小到大反向由大到小)以指定的欄位資料做排序

ASC = 正向- 預設值 DESC = 反向排序

For example

SELECT employee_id dept name age salary FROM employee_info WHERE dept = Sales ORDER BY salary

以上列出公司代號公司名銷售員人名年紀及薪資而條件是公司名為 Sales 顯示順序以薪資多少排序(由小到大為預設值)

如果要以多個欄位做排序要以逗號做分隔如下

SELECT employee_id dept name age salary FROM employee_info WHERE dept = Sales ORDER BY salary age DESC

85

結合條件及布林運算 SELECT column1 SUM(column2) FROM list-of-tables WHERE condition1 AND condition2 AND運算可以結兩個或以上的條件放在 WHERE子句中 兩者都要為真才

會顯示該筆記錄 OR 運算可以結兩個或以上敘述放在 WHERE子句中只要其中一個為直就

會顯示該筆記錄 For example SELECT employeeid firstname lastname title salary FROM employee_info WHERE salary gt= 5000000 AND title = Programmer 必需要薪資大於等於 50000而且職稱為 Programmer同時符合才會顯示該筆資料 以下以括號括住雖然不是必需的但如此比較容易讀 SELECT employeeid firstname lastname title salary FROM employee_info WHERE (salary gt= 5000000) AND (title = Programmer) 另外範例 SELECT firstname lastname title salary FROM employee_info WHERE (title = Sales) OR (title = Programmer) 條件為只要是 Sales 或 Programmer 職稱的就會被列出 IN and BETWEEN 子句

SELECT column1 SUM(column2) FROM list-of-tables WHERE column3 IN (list-of-values) SELECT column1 SUM(column2) FROM list-of-tables WHERE column3 BETWEEN value1 AND value2 IN 子句使用在列舉項目的使用上也就是分別測試是否符合所列的值 For example

86

SELECT employeeid lastname salary FROM employee_info WHERE lastname IN (Hernandez Jones Roberts Ruiz) 條件為姓氏(astname)要符合 Hernandez Jones Roberts or Ruiz 其中一個才會被傳回 IN運算元也可以使用 OR 的語法來取代如下結果相同 SELECT employeeid lastname salary FROM employee_info WHERE lastname = Hernandez OR lastname = Jones OR lastname = Roberts OR lastname = Ruiz 但使用 IN 句子比較短也比較易懂 你也可以使用 NOT IN 來去掉不要的記錄 BETWEEN 運算元使用在判斷是否存在兩個數值之間 For example SELECT employeeid age lastname salary FROM employee_info WHERE age BETWEEN 30 AND 40 傳回年紀 30歲到 40歲之間的資料(含 30及 40歲者) 相同的也可以使用以下語法來達到相同的結果 SELECT employeeid age lastname salary FROM employee_info WHERE age gt= 30 AND age lt= 40 你也可使用 NOT BETWEEN 來濾掉中間值的資料 數學運算 標準 ANSI SQL-92 提供以下運算

87

+ 加

- 減

餘數

餘數為除法後剩整數這不在標準的 ANSI SQL 中但大部份的資料庫都會支

援這運算元以下列出有用的函數雖不在 ANSI SQL-92 提供但一般資料庫

也會支援他們

ABS(x) 傳回 x 絕對值

SIGN(x) returns the sign of input x as -1 0 or 1 (negative zero or positive respectively)

MOD(xy) 餘數 - returns the integer remainder of x divided by y (同 xy)

FLOOR(x) 傳回小或等於 x 的最大整數值

CEILING(x) or CEIL(x)

傳回大或等於 x 的最小整數值

POWER(xy) x的 y 次方

ROUND(x) 把 x 四捨五入為整數

ROUND(xd) 四捨五入取到小數 d 位

SQRT(x) x 開平方

For example SELECT round(salary) firstname FROM employee_info 傳回薪資取到整數位

如何新增資料

insert 加入一筆新紀錄到資料表中 insert into tablename (first_columnlast_column) values (first_valuelast_value) [] = optional Example insert into employee

88

(first last age address city state) values (Luke Duke 45 2130 Boars Nest Hazard Co Georgia) Note 字串要以單引號住如string 數字框住也無妨 insert into 後面接資料表名稱再接以括號括住的欄位名在 values 後括號分別對映各欄位的值 以上的例子新增了一筆名(first) 為 Luke而住所(state) 為 Georgia 的資料

如何刪除資料

delete 可以刪除單筆或多筆紀錄 delete from tablename where columnname OPERATOR value [and|or column OPERATOR value] [ ] = optional Examples delete from employee Note 如果你沒有指定 where 子句那麼全部的紀錄都會被刪除 delete from employee where lastname = May delete from employee where firstname = Mike or firstname = Eric delete from 接著資料表名 再接著是條件式判斷沒有條件式則全部紀錄會

被刪除

如何更新資料

update 用來更新你所指定的記錄要和 WHERE 配合小心使用 語法 update tablename set columnname = newvalue[nextcolumn = newvalue2] where columnname OPERATOR value [and|or column OPERATOR value] [] = optional Examples

89

update phone_book set area_code = 623 where prefix = 979 update phone_book set last_name = Smith prefix=555 suffix=9292 where last_name = Jones update employee set age = age+1 where first_name=Mary and last_name=Williams

90

附錄二Replication

測試環境

RedHat 90 + MySQL 32358 MySQL資料庫路徑 varlibmysql MySQL設定檔 etcmycnf Master IP 1921680100 Slave IP 1921680200 請至下列網址下載最新MySQL 32358套件並利用rpm ndashUvh 更新 httpupdatesredhatcom9enosi386

圖 最新 MySQL 套件

測試架構圖

91

1921680100

1921680200Master Server

erveSlave S r

圖 測試架構圖

測試步驟

Master server 部份 Step1 確認 MasterSlave機器上所裝的 MySQL版本能進行

replication( 32329 or higher ) Step2 在 Master MySQL上開放一個帳號給 Slave mysql ndashu root ndashp mysqlgtGRANT FILE ON TO repl1921680200 IDENTIFIED BY lsquoabc123rsquo mysqlgtq 上面是 Master開放一個帳號 repl密碼 abc123給 IP1921680200有檔案處理

的權限 Step3 shutdown MySQL on the Master mysqladmin ndashu root ndashp shutdown Step4 備份 Master所有資料庫 tar ndashcvf tmpmysql-snapshottar varlibmysql 注意tar的時候MySQL是要在 stop情況下 在mysql (wwwmysqlcom) 網站的FAQ有不用shutdown的方法

92

Step5 在 master機器上修改etcmycnf 在[mysqld]區段內加入參數 log-bin server-id=這邊設定 server-id=1 sql-bin-update-same binlog-do-db=CRM只針對 CRM資料庫做紀錄 Step6 Restart MySQL on the master service mysqld start 此時因為有加入 log-bin 參數因此開始有 index產生了在varlibmysql目錄下

有index檔案紀錄資料庫的異動 log Slave server 部份 Step1 在 slave設定etcmycnf 在[mysqld]區段加入 master-host= master-user= master-password= master-port= server-id= 這邊設定 master-host=1921680100 master-user=repl master-password=abc123 master-port=3306 server-id=2 master-connect-retry=60預設重試間隔 60秒 replicate-do-db=CRM告訴 slave只做 CRM資料庫的更新 log-slave-updates Step2 將 master上的 mysql-snapshottar copy到 slave上 用 ftp傳到 slave的tmp Step3 解壓縮 Master資料庫至 Slave Server上 cd varlib tar xvf tmpmysql-snapshottar chown ndashR mysqlmysql mysql

93

chmod ndashR 770 mysql (視情況) Step4 Restart MySQL on the slave server 這時在varlibmysql目錄會出現 masterinfo此檔案紀錄了 Master MySQL server的資訊

狀況測試

One-way replication

1921680100

1921680200Master Server

erveSlave S r

圖 One-way replication架構圖 Step1 Master跟 Slave網路及服務都正常情況下由 Master端異動資料後 到 Slave端瀏覽資料檢視是否有進行 replication Step2 模擬 Slave Server 當機 可用在於 slave真的當機或是 Slave 不一定需要一直跟 master connect將Slave MySQL server shutdown由 Master端異動資料到 slave端瀏覽此時Slave應該沒有被 replication 更新然後再將 Slave端 MySQL server start起來

預設 60秒後 Slave會嘗試跟 Master要求進行 replication再去 Slave端檢視是否有更新資料

94

Step3 模擬 Master當機因為是設定 One-way replication一旦 Master Server Slave端沒有 Master的 source可以 download Two-way replication 基於 Master當機狀況於是發展雙向 Replication即 1921680100 ( Host A ) 1921680200 ( Host B )都分別擔任 MasterSlave身分

1921680100

1921680200er

Server B MasterSlave Server

Server A MasterSlave Serv

圖 Two-way replication架構圖 以下是針對兩台 MySQL伺服器進行雙向 Replication Step1觀念同單向 replication只是改成 Master也有 Slave身分 Slave也有Master的身分先分別在 Server AServer B 都去 grant一個進行 replication的身分 [A]mysqlgtGRANT FILE ON TO repl1921680200 IDENTIFIED BY lsquoabc123rsquo [B]mysqlgt GRANT FILE ON TO repl1921680100 IDENTIFIED BY lsquoabc123rsquo Step2做完單向 replication後stop Server Aserver B MySQL service此時 AB資料是一樣的

95

修改etcmycnf設定 範例 Server A [mysqld] datadir=varlibmysql socket=varlibmysqlmysqlsock server-id=1 log-bin sql-bin-update-same binlog-do-db=CRM master-host=1921680200 master-user=repl master-password=abc123 log-slave-updates master-connect-retry=60 replicate-do-db=CRM Server B [mysqld] datadir=varlibmysql socket=varlibmysqlmysqlsock server-id=2 log-bin sql-bin-update-same binlog-do-db=CRM master-host=1921680100 master-user=repl master-password=abc123 log-slave-updates master-connect-retry=60 replicate-do-db=CRM 分別 start Server AServer B MySQL後此時雙方都是 MasterSlave身分一旦哪一方資料異動就會通知對方來 replication-若 replication失效則必須將Server AServer B的masterinfo及index00x 都砍掉然後分別 restart MySQL server進行測試檢視成果 實務上通常如果需要做Two-way replication通常會搭配Virtual Server使用

96

在前端架設一台Virtual Server不過此部份不在此份SOP討論範圍內有興趣

的讀者可參考 httpwwwlinuxvirtualserverorg 網站

1921680100 1921680200

Host A MasterSlave Server

Host B MasterSlave Server

Virtual Host

圖 Virtual Server + Two-way replication 架構圖

97

圖 High Availability Linux Virtual Server架構圖

98

  • COSA-SOP-03-006
  • 第一章 簡介
    • 11適用對象 (Audience)
    • 12 MySQL本身
    • 13 MySQL 40版跟50版重大的改進功能
    • 14 各家資料庫軟體比較
      • 第二章 前置需求
      • 第三章 安裝
        • 31 MySQL安裝
        • 32 phpMyAdmin安裝
        • 33 升級及注意事項
          • 第四章 MySQL管理
            • 41 Webmin 管理介面
            • 42 phpMyAdmin 的操作介面
            • 43管理指令介紹
              • 431 利用mysqladmin設定root的密碼
                  • 第五章 實用範例
                    • 51 任務一Web Base客戶通訊錄
                    • 52 任務二Web Base群組軟體 ( twig )
                      • 第六章 維護及更新程序
                        • 61 日常維護
                        • 62 更新程序
                        • 63 備份重要檔案
                        • 64 離線備份與還原
                        • 65 線上備份與還原
                          • 第七章 問題與解答
                          • 第八章 參考資料
                          • 附錄一 SQL Command 介紹
                          • 附錄二Replication
Page 68: DataBase Server Standard Operation Procedureebooks.lib.ntu.edu.tw/1_file/oss/63/93doc4-5.pdf · 業務的公司帶來了不少壓力,譬如微軟,甲骨文 ... 外的錢用在第三方的資料庫產品上,譬如就可以不用再購買甲骨文公司

第七章 問題與解答

Q1RedHat 90預附的 MySQL到底有無支援 Transcation機制 Ans MySQL自 32334a之後的 MySQL-Max版本加入 InnoDB的資料庫類型透過

InnoDBMySQL同樣可以進行 COMMIT與 ROLLRACK的動作RedHat 90預附的 MySQL為 32354a-11巳支援 InnoDB的資料庫類型不過必須做以

下設定 1cp usrsharedocmysql-server-32354amy-mediumcnf to etcmycnf 2 vi etcmycnf 將以下設定前的拿掉 innodb_data_home_dir = varlibmysql innodb_data_file_path = ibdata110Mautoextend innodb_log_group_home_dir = varlibmysql innodb_log_arch_dir = varlibmysql 3service mysqld restart 如此一來各位在建立Table時便可指定Table Type為 innodb ( ex create table with type=innodb ) Q2如何解決 php+mysql 許功蓋等字變亂的問題 Ans 方法一 【確定 MySQL 預設的字元集】 1 打開 WinMySQLadmin 管理畫面(在視窗右下角狀態列紅綠燈圖示中按滑鼠

右鍵點選 Show me 選項) 2 點選管理畫面中 [Variables] 標籤選項其中 character_set變數就是您預設

字元集的變數其預設是 latin1 字元集(我們要將他改回 big5)而 chatacters_set 變數則是 MySQL 可以支援哪些字元集 【修改預設字元集變數 character_set 】 1 請點選管理畫面中 [myini Setup] 標籤選項設定 myini 2 按一下 [Pick-up and Edit myini values] 按鈕以便編輯目前的 myini 設定 3 在 [mysqld] 設定區塊底下新增一行 default-character-set = big5 變數設

68

定 4 新增一個 [client] 設定區塊並加入第三步驟的變數設定(游標往下移到空白處新增兩行 [client] 和 default-character-set=big5) 5 按一下畫面左下方 [Save Modification] 按鈕儲存設定 6 重新啟動 MySQL 或 Windows 方法二 Server端注意事項 phpini 中有關的設定為(預設值) Magic quotes for incoming GETPOSTCookie data magic_quotes_gpc = On Use Sybase-style magic quotes (escape with instead of ) magic_quotes_sybase = Off Client端注意事項 1中文資料送進 mysql 前請用 addslashes($str) 處理 2處理後送進 mysql 時請用 括起來並在參數後留一個空白如 $sql = UPDATE ezf_table set tablename=$tname tableend=$endtime table inguser=$tguser tableingid=$tguserid tableallnumber=$tnumber tableloca l=$tablelocal tableanyone=$tableopen tabletext=$ttext WHERE tableid=$t ableid tablename=$tname c 取出時請用 stripslashes($str) Q3MySQL root 密碼忘了該怎麼辦 Ans 1先停掉 mysql etcrcdinitdmysql stop 2以--skip-grant-table 的參數啟動 mysql safe_mysql --skip-grant-tableamp 3 更改 root 密碼 mysql mysql mysqlgt UPDATE user SET password=password(newpassword)

69

WHERE user=root mysqlgt FLUSH PRIVILEGES mysqlgt exit 4停掉 mysql再重跑 mysqladmin -uroot -p shutdown Enter password 輸入新設定的密碼 etcrcdinitdmysql start

Q4NULL值問題

Ans

NULL值的概念是造成 SQL的新手的混淆的普遍原因他們經常認為 NULL是和一個空字符串的一樣的東西不是這樣的例如下列語句是完全不同的

mysqlgt INSERT INTO my_table (phone) VALUES (NULL)

mysqlgt INSERT INTO my_table (phone) VALUES ()

兩個語句把值插入到 phone 列但是第一個插入一個 NULL值而第二個插入一個空字符串第一個的含義可以認為是ldquo電話號碼不知道而第二個則可意味

著ldquo她沒有電話

在 SQL中NULL值在于任何其他值甚至 NULL值比較時總是假的(FALSE)包含 NULL的一個表達式總是產生一個 NULL值除非在包含在表達式中的運算符和函數的文檔中指出在下列例子所有的列返回 NULL

mysqlgt SELECT NULL1+NULLCONCAT(InvisibleNULL)

如果你想要尋找值是 NULL的列你不能使用=NULL測試下列語句不返回任

何行因為對任何表達式expr = NULL是假的

mysqlgt SELECT FROM my_table WHERE phone = NULL

要想尋找 NULL值你必須使用 IS NULL測試下例顯示如何找出 NULL電話號碼和空的電話號碼

70

mysqlgt SELECT FROM my_table WHERE phone IS NULL mysqlgt SELECT FROM my_table WHERE phone =

在 MySQL中就像很多其他的 SQL服務器一樣你不能索引可以有 NULL值的列你必須聲明這樣的列為 NOT NULL而且你不能插入 NULL到索引的

列中

當用 LOAD DATA INFILE 讀取數據時空列用更新如果你想要在一個列中有

NULL值你應該在文本文件中使用N字面上的詞NULL也可以在某些情形下使用

當使用 ORDER BY時首先呈現 NULL值如果你用 DESC以降序排序NULL值最後顯示當使用 GROUP BY時所有的 NULL值被認為是相等的

為了有助于NULL的處理你能使用 IS NULL和 IS NOT NULL運算符和 IFNULL()函數

對某些列類型NULL值被特殊地處理如果你將 NULL插入表的第一個TIMESTAMP 列則插入當前的日期和時間如果你將 NULL插入一個AUTO_INCREMENT 列則插入順序中的下一個數字

Q5如何將圖片存放於 MySQL中

Ans

Step 1建立資料庫 test

Step 2 建立表格 binary_data

CREATE TABLE binary_data (

id INT(4) NOT NULL AUTO_INCREMENT PRIMARY KEY

description CHAR(50)

bin_data LONGBLOB

filename CHAR(50)

filesize CHAR(50)

filetype CHAR(50)

71

)

Step 3 利用 storephp 寫入圖片

storephp 程式碼

ltHTMLgt ltHEADgtltTITLEgtStore binary data into SQL DatabaseltTITLEgtltHEADgt ltBODYgt lt code that will be executed if the form has been submitted

if ($submit) mysql_connect(localhostrootYOUR_PASSWORD) mysql_select_db(test) $data=Base64_Encode(fread(fopen($form_data r) filesize($form_data))) $result=MYSQL_QUERY(INSERT INTO binary_data (descriptionbin_datafilenamefilesizefiletype) VALUES ($form_description$data$form_data_name$form_data_size$form_data_type)) $id= mysql_insert_id() print ltpgtThis file has the following Database ID ltbgt$idltbgt MYSQL_CLOSE() else else show the form to submit new data

gt

ltform method=post action=ltphp echo $PHP_SELF gt enctype=multipartform-datagt File Descriptionltbrgt ltinput type=text name=form_description size=40gt ltINPUT TYPE=hidden name=MAX_FILE_SIZE value=4000000gt ltbrgtFile to uploadstore in databaseltbrgt ltinput type=file name=form_data size=40gt ltpgtltinput type=submit name=submit value=submitgt ltformgt lt

72

gt ltBODYgt ltHTMLgt

Step 3 利用 storephp 取出圖片

getdataphp 程式碼

lt Syntax getdataphp3id=ltidgt if($id) you may have to modify login information for your database server MYSQL_CONNECT(localhostrootYOUR_PASSWORD) mysql_select_db(test) $query = select bin_datafiletype from binary_data where id=$id $result = MYSQL_QUERY($query) $data = Base64_Decode(MYSQL_RESULT($result0bin_data)) $type = MYSQL_RESULT($result0filetype) Header( Content-type $type) echo $data gt

Q6MySQL裝好之後啟動時或是執行 mysqladmin會出現如下訊息 Cant connect to local MYSQL Server through Socket varlibmysqlmysqlsock或是

Cant connect to local MYSQL Server through Socket tmpmysqldsock

Ans 可能有下列幾個原因

1這個 mysqldsock 不見了被某人刪除了或是被一些系統自動執行程式給刪

了例如有些 cron任務便會設定定期刪除 tmp 裡的東西所以呢您只能修改

cron 裡的設定讓它不要清除 mysqldsock 2在啟動時也可以改變 mysqldsock的位置您在啟動 MySQL的時候可以加入此參數usrlocalmysqlbinsafe_mysqld --user=mysql --socket=其他路

徑socket amp 同時得去設定環境變數 MYSQL_UNIX_PORT的值以指定新的

73

路徑 3若是您沒改 MYSQL_UNIX_PORT的值那麼您可以在執行指令的時候才打

例如mysqladmin --socket=其他路徑socket version Q7How to get the last insert id Ans CREATE TABLE product ( id INT(4) NOT NULL AUTO_INCREMENT PRIMARY KEY description VARCHAR(50) ) 1利用 SQL的話 mysqlgt insert into product(description) values(123) Query OK 1 row affected (000 sec) mysqlgt select last_insert_id() +------------------+ | last_insert_id() | +------------------+ +------------------+ 1 row in set (000 sec) ======================================== 2如果是 PHP的話 你可以用mysql_insert_id()取得該 id PHP example $result=MYSQL_QUERY(INSERT INTO product (description) VALUES ($description)) $id= mysql_insert_id() print This file has the following Database ID $id Q8如何將文字檔匯入資料庫 Ans $addr=homehttpdhtmlphpschool001txt $sql_select = load data infile $addr into table test fields terminated by t 解說 $sql_select = load data infile 文字檔名 into table 表格名 fields terminated by

74

t

(欄位分隔以 TAB鍵) 該文字檔須與資料表欄位格式相符 例如欄位有三個 則文字檔為每行一筆資料如下 欄 1資料ltTABgt欄 2資料ltTABgt欄 3資料 欄 1資料ltTABgt欄 2資料ltTABgt欄 3資料 欄 1資料ltTABgt欄 2資料ltTABgt欄 3資料 欄 1資料ltTABgtltTABgt欄 3資料

Q9如何撰寫 MySQL C API Ans Step 1利用文字編輯器撰寫以下程式碼 mysqlcc

include ltstdiohgt

include ltmysqlmysqlhgt

int main (int argc char argv[])

MYSQL mysql

MYSQL_RES res

MYSQL_ROW row

if (argc = 2)

fputs (Usage myc ltdatabasegt stderr)

return 1

if ((mysql_connect(ampmysqllocalhostrootYour_Password)))

fputs (Error connecting stderr)

abort()

75

if (mysql_select_db(ampmysqlargv[1]))

fputs (Error selecting database stderr)

abort()

if (mysql_query(ampmysqlSELECT FROM test_table))

fputs (Error processing query stderr)

abort()

if ((res = mysql_store_result(ampmysql)))

fputs (Error storing results stderr)

abort()

while((row = mysql_fetch_row(res)))

uint i = 0

for (i=0 i lt mysql_num_fields(res) i++)

printf(s row[i])

printf(n)

return 0

Step 2 Compile

gcc -Iusrlocalmysqlinclude -Lusrlocalmysqllibmysql mysqlcc ndashlm -lmysqlclient

(其中 include path與 library path取決於你的 MySQL安裝路徑)

76

如果執行時發生如下 error Run problemerror in loading shared libraries libmysqlclientsoX 將你的 MySQL library path(for exampleusrlocalmysqllibmysql) 加入etcldsoconf and run sbinldconfig -v Q9ASP + MySQL 範例程式 Ans Dim myconn As New ADODBConnection Dim myrs As New Recordset Dim mySQL As String Dim myrows As Long myconnOpen DSN=MyODBCsample mySQL = SELECT from user myrsSource = mySQL Set myrsActiveConnection = myconn myrsCursorLocation = adUseClient myrsOpen myrows = myrsRecordCount myrsClose myconnClose 可參考 httpwwwdwamnetmysqlasp_myodbcasp 有詳細的資料 Q10如何將 MySQL中的資料庫匯出成txt檔 Ans select from TableName into outfile textxls all result fields will seperate by tab

77

第八章 參考資料

英文部份 網址 1 httpwwwmysqlcom MySQL 網站有第一手有關 MySQL的資料 2 httpwwwmysqlcomdocenReplicationhtml 有關 MySQL Replication 的文件 3 httpwwwgeocitiescomsqlhomefaqstore_blobhtml 如何在 MySQL 存放 BLOB的資料 4httpwwwsapdborg 有關 SAP跟 MySQL相關合作的網站 書藉 1 Cooking with MySQL

Paul DuBois has selected sample recipes from the hundreds youll find in his book MySQL

Cookbook In this third and final series of excerpts showcasing these recipes learn how to

compute team standings how to calculate the differences between successive Dec 26

2002 2 Tips for Building Web Database Applications with PHP and MySQL by Hugh E Williams co-author of Web Database Applications with PHP amp MySQL 04042002

3 Managing and Using MySQL 2nd Edition By Tim King George Reese Randy Jay Yarger

4 MySQL Cookbook By Paul DuBoisPublisher OReillyPub Date October 2002

中文部份

78

1 httplinuxtncedutwtechdocmysqlmysql_docmanual_tochtml MySQL 中文手冊 2 httpchenshloxaedutwphpZ_1php PHP+MySQ程式研習設計網站 3 httplinuxtncedutwtechdocbanicdownhtml PHP 4 手冊 4 httpwwwtncedutwadmin_zonephp台南縣教育網網路中心有很多 Linux相關文件 5 httpdobtncedutw網站建置百寶箱有很多 PHP MySQL 相關範例程式 5 httpwwwdbworldcomtw資料庫專家電子雜誌介紹資料庫的重要觀念及名詞

79

附錄一 SQL Command 介紹

SQL (讀音ess-que-el) 是一種結構查詢語法SQL 使用於資料庫交流

傳遞相容於 ANSI (American National Standards Institute) 是一套標準的關聯

式資料庫語言 SQL 語言是執行更新或從資料系統獲取資料一般常見的關聯

資料庫系統都有提供 SQL 如 Oracle Sybase Microsoft SQL Server Access Ingres 等雖然大部份的資料庫都有提供 SQL 但也多提供了自已獨特的語

法造成了不相容的情形但標準基本的語法是相通的如Select Insert Update Delete Create and Drop 每一個系統都有支援

Table相關 Command

Create Table

關聯式資料庫包含有很多元件稱為資料表(tables) 把資料或訊息放在資

料表中 資料表是以不同的名稱做分別資料表由欄列所構成的二維陣列

欄包含欄位名資料型態 及其他可判斷的資訊列是由全部欄位構成一筆一

筆的紀錄 create table 語法用在建立一個新的資料表語法格式如下

create table tablename (column1 data type column2 data type column3 data type)

Format of create table if you were to use optional constraints

create table tablename (column1 data type [constraint] column2 data type [constraint] column3 data type [constraint]) [ ] = optional

Note You may have as many columns as youd like and the constraints are optional

80

Example

create table employee (first varchar(15) last varchar(20) age number(3) address varchar(30) city varchar(20) state varchar(20))

注意建立資料表格式要以括號把前後框住而最後以(分號)做結尾

欄位名不要超過 30個字元長而且不要使用 sql 的關鍵字(如 where select等)而在後面接是型態的宣告(如字串數字日期格式等)

資料型態是來描述欄位的方式如一個欄位Last_Name 是一個姓氏可以使用varchar (可變動長度字串) 資料型態

以下是幾個常見的資料庫型態 char(size) 固定長度字串最長為 255 位元 varchar(size) 變動長度字串最大字元數以 size 來指定 number(size) 數值格式可以是整數也可以是小數最大數字以 size 位數判

斷未指定小數位數由系統內定 date 日期格式 number(sized) 數值格式最大數字以 size 位數判斷d 為小數位數整數位

數為 size-d 位

有何限制當資料表被建立通常有一或數個欄位是要使用來做關聯的功

能 例如unique 限制(唯一值)兩筆記錄不可以相同的值 not null (非空值)該欄位一定要輸入資料不可是空的primary key (主鍵)是每一筆記錄識別的主要方式

Drop a table drop table 刪除資料表(其中的資料也會一併刪除)

drop table tablename

Example

81

drop table 和刪除全部資料是不同的刪除全部資料欄位名稱資訊等還會

存在但刪除資料表會把這一些也一併移除掉

如何查詢資料

Select 基本用法

select 語法是關連式資料庫最常用的部份可以取得你想要的資料這是一個

簡單的範例 select column1[column2etc] from tablename [where condition] [] = optional 在 select 之後所列欄位名則是要顯示的資料部份你可以一一列出各欄位

名或是以 (星號)來代表選擇全部的欄位 from 之後放資料表名稱 where 子句 (選項) 指定要過濾的條件符合者才會顯現 where 可使用的條件運算元 = 等於 gt 大於 lt 小於 gt= 大或等於 lt= 小或等於 ltgt 大相等 LIKE 相似 For example select first last city

82

from empinfo where first LIKE Er 以Er 為開頭的字串就符合要以單引號框住 Or you can specify select first last from empinfo where last LIKE s 最後一字為 S 就符合 select from empinfo where first = Eric 則表示 first name 一定要是 Eric 才可以 範例資料表empinfo 統計函數

MIN 傳回指定欄位最小值

MAX 傳回指定欄位最大值

SUM 傳回指定欄位總和

AVG 傳回指定欄位平均值

COUNT 傳回指定欄位的筆數

COUNT() 傳回資料庫中的總筆數

統計函數使用於資料表中的數值欄位配合 SELECT 語法使用 只用於總結特定單一欄位可以配合 GROUP BY 做篩選但也可以不使用 GROUP BY 語句For example

SELECT AVG(salary) FROM employee

83

傳回全部 salary 平均值

Another example

SELECT AVG(salary) FROM employee WHERE title = Programmer

傳回 salary 平均值條件為 employees 資料表中當 title 等於 Programmer

Example

SELECT Count() FROM employees

傳回 employees 資料表中紀錄總筆數

GROUP BY 語法 SELECT column1 SUM(column2) FROM list-of-tables GROUP BY column-list The GROUP BY 語句可以先以所列的欄位為條件分組排序在一起(可以多欄

位) example 要列出每一個 dept 中最高 salary 值 SELECT max(salary) dept FROM employee GROUP BY dept HAVING 語法

SELECT column1 SUM(column2) FROM list-of-tables GROUP BY column-list HAVING condition

HAVING 子句是 GROUP BY 的一部份用來過濾在 GROUP BY 所選出的資料功能如同 select 命令中 where 條件式一樣只是 HAVING 必需配合 GROUP BY 使用

我們以例子來說明我們要取得每一公司名及每一公司的薪水平均值輸入如下

84

SELECT dept avg(salary) FROM employee GROUP BY dept

但如果我們只列出薪資平均值超過 20000元的公司資料

SELECT dept avg(salary) FROM employee GROUP BY dept HAVING avg(salary) gt 20000

ORDER BY子句語法

SELECT column1 SUM(column2) FROM list-of-tables ORDER BY column-list [ASC | DESC]

[ ] =選項

ORDER BY是一個選項子句當你以排序方式來顯示資料(正向由小到大反向由大到小)以指定的欄位資料做排序

ASC = 正向- 預設值 DESC = 反向排序

For example

SELECT employee_id dept name age salary FROM employee_info WHERE dept = Sales ORDER BY salary

以上列出公司代號公司名銷售員人名年紀及薪資而條件是公司名為 Sales 顯示順序以薪資多少排序(由小到大為預設值)

如果要以多個欄位做排序要以逗號做分隔如下

SELECT employee_id dept name age salary FROM employee_info WHERE dept = Sales ORDER BY salary age DESC

85

結合條件及布林運算 SELECT column1 SUM(column2) FROM list-of-tables WHERE condition1 AND condition2 AND運算可以結兩個或以上的條件放在 WHERE子句中 兩者都要為真才

會顯示該筆記錄 OR 運算可以結兩個或以上敘述放在 WHERE子句中只要其中一個為直就

會顯示該筆記錄 For example SELECT employeeid firstname lastname title salary FROM employee_info WHERE salary gt= 5000000 AND title = Programmer 必需要薪資大於等於 50000而且職稱為 Programmer同時符合才會顯示該筆資料 以下以括號括住雖然不是必需的但如此比較容易讀 SELECT employeeid firstname lastname title salary FROM employee_info WHERE (salary gt= 5000000) AND (title = Programmer) 另外範例 SELECT firstname lastname title salary FROM employee_info WHERE (title = Sales) OR (title = Programmer) 條件為只要是 Sales 或 Programmer 職稱的就會被列出 IN and BETWEEN 子句

SELECT column1 SUM(column2) FROM list-of-tables WHERE column3 IN (list-of-values) SELECT column1 SUM(column2) FROM list-of-tables WHERE column3 BETWEEN value1 AND value2 IN 子句使用在列舉項目的使用上也就是分別測試是否符合所列的值 For example

86

SELECT employeeid lastname salary FROM employee_info WHERE lastname IN (Hernandez Jones Roberts Ruiz) 條件為姓氏(astname)要符合 Hernandez Jones Roberts or Ruiz 其中一個才會被傳回 IN運算元也可以使用 OR 的語法來取代如下結果相同 SELECT employeeid lastname salary FROM employee_info WHERE lastname = Hernandez OR lastname = Jones OR lastname = Roberts OR lastname = Ruiz 但使用 IN 句子比較短也比較易懂 你也可以使用 NOT IN 來去掉不要的記錄 BETWEEN 運算元使用在判斷是否存在兩個數值之間 For example SELECT employeeid age lastname salary FROM employee_info WHERE age BETWEEN 30 AND 40 傳回年紀 30歲到 40歲之間的資料(含 30及 40歲者) 相同的也可以使用以下語法來達到相同的結果 SELECT employeeid age lastname salary FROM employee_info WHERE age gt= 30 AND age lt= 40 你也可使用 NOT BETWEEN 來濾掉中間值的資料 數學運算 標準 ANSI SQL-92 提供以下運算

87

+ 加

- 減

餘數

餘數為除法後剩整數這不在標準的 ANSI SQL 中但大部份的資料庫都會支

援這運算元以下列出有用的函數雖不在 ANSI SQL-92 提供但一般資料庫

也會支援他們

ABS(x) 傳回 x 絕對值

SIGN(x) returns the sign of input x as -1 0 or 1 (negative zero or positive respectively)

MOD(xy) 餘數 - returns the integer remainder of x divided by y (同 xy)

FLOOR(x) 傳回小或等於 x 的最大整數值

CEILING(x) or CEIL(x)

傳回大或等於 x 的最小整數值

POWER(xy) x的 y 次方

ROUND(x) 把 x 四捨五入為整數

ROUND(xd) 四捨五入取到小數 d 位

SQRT(x) x 開平方

For example SELECT round(salary) firstname FROM employee_info 傳回薪資取到整數位

如何新增資料

insert 加入一筆新紀錄到資料表中 insert into tablename (first_columnlast_column) values (first_valuelast_value) [] = optional Example insert into employee

88

(first last age address city state) values (Luke Duke 45 2130 Boars Nest Hazard Co Georgia) Note 字串要以單引號住如string 數字框住也無妨 insert into 後面接資料表名稱再接以括號括住的欄位名在 values 後括號分別對映各欄位的值 以上的例子新增了一筆名(first) 為 Luke而住所(state) 為 Georgia 的資料

如何刪除資料

delete 可以刪除單筆或多筆紀錄 delete from tablename where columnname OPERATOR value [and|or column OPERATOR value] [ ] = optional Examples delete from employee Note 如果你沒有指定 where 子句那麼全部的紀錄都會被刪除 delete from employee where lastname = May delete from employee where firstname = Mike or firstname = Eric delete from 接著資料表名 再接著是條件式判斷沒有條件式則全部紀錄會

被刪除

如何更新資料

update 用來更新你所指定的記錄要和 WHERE 配合小心使用 語法 update tablename set columnname = newvalue[nextcolumn = newvalue2] where columnname OPERATOR value [and|or column OPERATOR value] [] = optional Examples

89

update phone_book set area_code = 623 where prefix = 979 update phone_book set last_name = Smith prefix=555 suffix=9292 where last_name = Jones update employee set age = age+1 where first_name=Mary and last_name=Williams

90

附錄二Replication

測試環境

RedHat 90 + MySQL 32358 MySQL資料庫路徑 varlibmysql MySQL設定檔 etcmycnf Master IP 1921680100 Slave IP 1921680200 請至下列網址下載最新MySQL 32358套件並利用rpm ndashUvh 更新 httpupdatesredhatcom9enosi386

圖 最新 MySQL 套件

測試架構圖

91

1921680100

1921680200Master Server

erveSlave S r

圖 測試架構圖

測試步驟

Master server 部份 Step1 確認 MasterSlave機器上所裝的 MySQL版本能進行

replication( 32329 or higher ) Step2 在 Master MySQL上開放一個帳號給 Slave mysql ndashu root ndashp mysqlgtGRANT FILE ON TO repl1921680200 IDENTIFIED BY lsquoabc123rsquo mysqlgtq 上面是 Master開放一個帳號 repl密碼 abc123給 IP1921680200有檔案處理

的權限 Step3 shutdown MySQL on the Master mysqladmin ndashu root ndashp shutdown Step4 備份 Master所有資料庫 tar ndashcvf tmpmysql-snapshottar varlibmysql 注意tar的時候MySQL是要在 stop情況下 在mysql (wwwmysqlcom) 網站的FAQ有不用shutdown的方法

92

Step5 在 master機器上修改etcmycnf 在[mysqld]區段內加入參數 log-bin server-id=這邊設定 server-id=1 sql-bin-update-same binlog-do-db=CRM只針對 CRM資料庫做紀錄 Step6 Restart MySQL on the master service mysqld start 此時因為有加入 log-bin 參數因此開始有 index產生了在varlibmysql目錄下

有index檔案紀錄資料庫的異動 log Slave server 部份 Step1 在 slave設定etcmycnf 在[mysqld]區段加入 master-host= master-user= master-password= master-port= server-id= 這邊設定 master-host=1921680100 master-user=repl master-password=abc123 master-port=3306 server-id=2 master-connect-retry=60預設重試間隔 60秒 replicate-do-db=CRM告訴 slave只做 CRM資料庫的更新 log-slave-updates Step2 將 master上的 mysql-snapshottar copy到 slave上 用 ftp傳到 slave的tmp Step3 解壓縮 Master資料庫至 Slave Server上 cd varlib tar xvf tmpmysql-snapshottar chown ndashR mysqlmysql mysql

93

chmod ndashR 770 mysql (視情況) Step4 Restart MySQL on the slave server 這時在varlibmysql目錄會出現 masterinfo此檔案紀錄了 Master MySQL server的資訊

狀況測試

One-way replication

1921680100

1921680200Master Server

erveSlave S r

圖 One-way replication架構圖 Step1 Master跟 Slave網路及服務都正常情況下由 Master端異動資料後 到 Slave端瀏覽資料檢視是否有進行 replication Step2 模擬 Slave Server 當機 可用在於 slave真的當機或是 Slave 不一定需要一直跟 master connect將Slave MySQL server shutdown由 Master端異動資料到 slave端瀏覽此時Slave應該沒有被 replication 更新然後再將 Slave端 MySQL server start起來

預設 60秒後 Slave會嘗試跟 Master要求進行 replication再去 Slave端檢視是否有更新資料

94

Step3 模擬 Master當機因為是設定 One-way replication一旦 Master Server Slave端沒有 Master的 source可以 download Two-way replication 基於 Master當機狀況於是發展雙向 Replication即 1921680100 ( Host A ) 1921680200 ( Host B )都分別擔任 MasterSlave身分

1921680100

1921680200er

Server B MasterSlave Server

Server A MasterSlave Serv

圖 Two-way replication架構圖 以下是針對兩台 MySQL伺服器進行雙向 Replication Step1觀念同單向 replication只是改成 Master也有 Slave身分 Slave也有Master的身分先分別在 Server AServer B 都去 grant一個進行 replication的身分 [A]mysqlgtGRANT FILE ON TO repl1921680200 IDENTIFIED BY lsquoabc123rsquo [B]mysqlgt GRANT FILE ON TO repl1921680100 IDENTIFIED BY lsquoabc123rsquo Step2做完單向 replication後stop Server Aserver B MySQL service此時 AB資料是一樣的

95

修改etcmycnf設定 範例 Server A [mysqld] datadir=varlibmysql socket=varlibmysqlmysqlsock server-id=1 log-bin sql-bin-update-same binlog-do-db=CRM master-host=1921680200 master-user=repl master-password=abc123 log-slave-updates master-connect-retry=60 replicate-do-db=CRM Server B [mysqld] datadir=varlibmysql socket=varlibmysqlmysqlsock server-id=2 log-bin sql-bin-update-same binlog-do-db=CRM master-host=1921680100 master-user=repl master-password=abc123 log-slave-updates master-connect-retry=60 replicate-do-db=CRM 分別 start Server AServer B MySQL後此時雙方都是 MasterSlave身分一旦哪一方資料異動就會通知對方來 replication-若 replication失效則必須將Server AServer B的masterinfo及index00x 都砍掉然後分別 restart MySQL server進行測試檢視成果 實務上通常如果需要做Two-way replication通常會搭配Virtual Server使用

96

在前端架設一台Virtual Server不過此部份不在此份SOP討論範圍內有興趣

的讀者可參考 httpwwwlinuxvirtualserverorg 網站

1921680100 1921680200

Host A MasterSlave Server

Host B MasterSlave Server

Virtual Host

圖 Virtual Server + Two-way replication 架構圖

97

圖 High Availability Linux Virtual Server架構圖

98

  • COSA-SOP-03-006
  • 第一章 簡介
    • 11適用對象 (Audience)
    • 12 MySQL本身
    • 13 MySQL 40版跟50版重大的改進功能
    • 14 各家資料庫軟體比較
      • 第二章 前置需求
      • 第三章 安裝
        • 31 MySQL安裝
        • 32 phpMyAdmin安裝
        • 33 升級及注意事項
          • 第四章 MySQL管理
            • 41 Webmin 管理介面
            • 42 phpMyAdmin 的操作介面
            • 43管理指令介紹
              • 431 利用mysqladmin設定root的密碼
                  • 第五章 實用範例
                    • 51 任務一Web Base客戶通訊錄
                    • 52 任務二Web Base群組軟體 ( twig )
                      • 第六章 維護及更新程序
                        • 61 日常維護
                        • 62 更新程序
                        • 63 備份重要檔案
                        • 64 離線備份與還原
                        • 65 線上備份與還原
                          • 第七章 問題與解答
                          • 第八章 參考資料
                          • 附錄一 SQL Command 介紹
                          • 附錄二Replication
Page 69: DataBase Server Standard Operation Procedureebooks.lib.ntu.edu.tw/1_file/oss/63/93doc4-5.pdf · 業務的公司帶來了不少壓力,譬如微軟,甲骨文 ... 外的錢用在第三方的資料庫產品上,譬如就可以不用再購買甲骨文公司

定 4 新增一個 [client] 設定區塊並加入第三步驟的變數設定(游標往下移到空白處新增兩行 [client] 和 default-character-set=big5) 5 按一下畫面左下方 [Save Modification] 按鈕儲存設定 6 重新啟動 MySQL 或 Windows 方法二 Server端注意事項 phpini 中有關的設定為(預設值) Magic quotes for incoming GETPOSTCookie data magic_quotes_gpc = On Use Sybase-style magic quotes (escape with instead of ) magic_quotes_sybase = Off Client端注意事項 1中文資料送進 mysql 前請用 addslashes($str) 處理 2處理後送進 mysql 時請用 括起來並在參數後留一個空白如 $sql = UPDATE ezf_table set tablename=$tname tableend=$endtime table inguser=$tguser tableingid=$tguserid tableallnumber=$tnumber tableloca l=$tablelocal tableanyone=$tableopen tabletext=$ttext WHERE tableid=$t ableid tablename=$tname c 取出時請用 stripslashes($str) Q3MySQL root 密碼忘了該怎麼辦 Ans 1先停掉 mysql etcrcdinitdmysql stop 2以--skip-grant-table 的參數啟動 mysql safe_mysql --skip-grant-tableamp 3 更改 root 密碼 mysql mysql mysqlgt UPDATE user SET password=password(newpassword)

69

WHERE user=root mysqlgt FLUSH PRIVILEGES mysqlgt exit 4停掉 mysql再重跑 mysqladmin -uroot -p shutdown Enter password 輸入新設定的密碼 etcrcdinitdmysql start

Q4NULL值問題

Ans

NULL值的概念是造成 SQL的新手的混淆的普遍原因他們經常認為 NULL是和一個空字符串的一樣的東西不是這樣的例如下列語句是完全不同的

mysqlgt INSERT INTO my_table (phone) VALUES (NULL)

mysqlgt INSERT INTO my_table (phone) VALUES ()

兩個語句把值插入到 phone 列但是第一個插入一個 NULL值而第二個插入一個空字符串第一個的含義可以認為是ldquo電話號碼不知道而第二個則可意味

著ldquo她沒有電話

在 SQL中NULL值在于任何其他值甚至 NULL值比較時總是假的(FALSE)包含 NULL的一個表達式總是產生一個 NULL值除非在包含在表達式中的運算符和函數的文檔中指出在下列例子所有的列返回 NULL

mysqlgt SELECT NULL1+NULLCONCAT(InvisibleNULL)

如果你想要尋找值是 NULL的列你不能使用=NULL測試下列語句不返回任

何行因為對任何表達式expr = NULL是假的

mysqlgt SELECT FROM my_table WHERE phone = NULL

要想尋找 NULL值你必須使用 IS NULL測試下例顯示如何找出 NULL電話號碼和空的電話號碼

70

mysqlgt SELECT FROM my_table WHERE phone IS NULL mysqlgt SELECT FROM my_table WHERE phone =

在 MySQL中就像很多其他的 SQL服務器一樣你不能索引可以有 NULL值的列你必須聲明這樣的列為 NOT NULL而且你不能插入 NULL到索引的

列中

當用 LOAD DATA INFILE 讀取數據時空列用更新如果你想要在一個列中有

NULL值你應該在文本文件中使用N字面上的詞NULL也可以在某些情形下使用

當使用 ORDER BY時首先呈現 NULL值如果你用 DESC以降序排序NULL值最後顯示當使用 GROUP BY時所有的 NULL值被認為是相等的

為了有助于NULL的處理你能使用 IS NULL和 IS NOT NULL運算符和 IFNULL()函數

對某些列類型NULL值被特殊地處理如果你將 NULL插入表的第一個TIMESTAMP 列則插入當前的日期和時間如果你將 NULL插入一個AUTO_INCREMENT 列則插入順序中的下一個數字

Q5如何將圖片存放於 MySQL中

Ans

Step 1建立資料庫 test

Step 2 建立表格 binary_data

CREATE TABLE binary_data (

id INT(4) NOT NULL AUTO_INCREMENT PRIMARY KEY

description CHAR(50)

bin_data LONGBLOB

filename CHAR(50)

filesize CHAR(50)

filetype CHAR(50)

71

)

Step 3 利用 storephp 寫入圖片

storephp 程式碼

ltHTMLgt ltHEADgtltTITLEgtStore binary data into SQL DatabaseltTITLEgtltHEADgt ltBODYgt lt code that will be executed if the form has been submitted

if ($submit) mysql_connect(localhostrootYOUR_PASSWORD) mysql_select_db(test) $data=Base64_Encode(fread(fopen($form_data r) filesize($form_data))) $result=MYSQL_QUERY(INSERT INTO binary_data (descriptionbin_datafilenamefilesizefiletype) VALUES ($form_description$data$form_data_name$form_data_size$form_data_type)) $id= mysql_insert_id() print ltpgtThis file has the following Database ID ltbgt$idltbgt MYSQL_CLOSE() else else show the form to submit new data

gt

ltform method=post action=ltphp echo $PHP_SELF gt enctype=multipartform-datagt File Descriptionltbrgt ltinput type=text name=form_description size=40gt ltINPUT TYPE=hidden name=MAX_FILE_SIZE value=4000000gt ltbrgtFile to uploadstore in databaseltbrgt ltinput type=file name=form_data size=40gt ltpgtltinput type=submit name=submit value=submitgt ltformgt lt

72

gt ltBODYgt ltHTMLgt

Step 3 利用 storephp 取出圖片

getdataphp 程式碼

lt Syntax getdataphp3id=ltidgt if($id) you may have to modify login information for your database server MYSQL_CONNECT(localhostrootYOUR_PASSWORD) mysql_select_db(test) $query = select bin_datafiletype from binary_data where id=$id $result = MYSQL_QUERY($query) $data = Base64_Decode(MYSQL_RESULT($result0bin_data)) $type = MYSQL_RESULT($result0filetype) Header( Content-type $type) echo $data gt

Q6MySQL裝好之後啟動時或是執行 mysqladmin會出現如下訊息 Cant connect to local MYSQL Server through Socket varlibmysqlmysqlsock或是

Cant connect to local MYSQL Server through Socket tmpmysqldsock

Ans 可能有下列幾個原因

1這個 mysqldsock 不見了被某人刪除了或是被一些系統自動執行程式給刪

了例如有些 cron任務便會設定定期刪除 tmp 裡的東西所以呢您只能修改

cron 裡的設定讓它不要清除 mysqldsock 2在啟動時也可以改變 mysqldsock的位置您在啟動 MySQL的時候可以加入此參數usrlocalmysqlbinsafe_mysqld --user=mysql --socket=其他路

徑socket amp 同時得去設定環境變數 MYSQL_UNIX_PORT的值以指定新的

73

路徑 3若是您沒改 MYSQL_UNIX_PORT的值那麼您可以在執行指令的時候才打

例如mysqladmin --socket=其他路徑socket version Q7How to get the last insert id Ans CREATE TABLE product ( id INT(4) NOT NULL AUTO_INCREMENT PRIMARY KEY description VARCHAR(50) ) 1利用 SQL的話 mysqlgt insert into product(description) values(123) Query OK 1 row affected (000 sec) mysqlgt select last_insert_id() +------------------+ | last_insert_id() | +------------------+ +------------------+ 1 row in set (000 sec) ======================================== 2如果是 PHP的話 你可以用mysql_insert_id()取得該 id PHP example $result=MYSQL_QUERY(INSERT INTO product (description) VALUES ($description)) $id= mysql_insert_id() print This file has the following Database ID $id Q8如何將文字檔匯入資料庫 Ans $addr=homehttpdhtmlphpschool001txt $sql_select = load data infile $addr into table test fields terminated by t 解說 $sql_select = load data infile 文字檔名 into table 表格名 fields terminated by

74

t

(欄位分隔以 TAB鍵) 該文字檔須與資料表欄位格式相符 例如欄位有三個 則文字檔為每行一筆資料如下 欄 1資料ltTABgt欄 2資料ltTABgt欄 3資料 欄 1資料ltTABgt欄 2資料ltTABgt欄 3資料 欄 1資料ltTABgt欄 2資料ltTABgt欄 3資料 欄 1資料ltTABgtltTABgt欄 3資料

Q9如何撰寫 MySQL C API Ans Step 1利用文字編輯器撰寫以下程式碼 mysqlcc

include ltstdiohgt

include ltmysqlmysqlhgt

int main (int argc char argv[])

MYSQL mysql

MYSQL_RES res

MYSQL_ROW row

if (argc = 2)

fputs (Usage myc ltdatabasegt stderr)

return 1

if ((mysql_connect(ampmysqllocalhostrootYour_Password)))

fputs (Error connecting stderr)

abort()

75

if (mysql_select_db(ampmysqlargv[1]))

fputs (Error selecting database stderr)

abort()

if (mysql_query(ampmysqlSELECT FROM test_table))

fputs (Error processing query stderr)

abort()

if ((res = mysql_store_result(ampmysql)))

fputs (Error storing results stderr)

abort()

while((row = mysql_fetch_row(res)))

uint i = 0

for (i=0 i lt mysql_num_fields(res) i++)

printf(s row[i])

printf(n)

return 0

Step 2 Compile

gcc -Iusrlocalmysqlinclude -Lusrlocalmysqllibmysql mysqlcc ndashlm -lmysqlclient

(其中 include path與 library path取決於你的 MySQL安裝路徑)

76

如果執行時發生如下 error Run problemerror in loading shared libraries libmysqlclientsoX 將你的 MySQL library path(for exampleusrlocalmysqllibmysql) 加入etcldsoconf and run sbinldconfig -v Q9ASP + MySQL 範例程式 Ans Dim myconn As New ADODBConnection Dim myrs As New Recordset Dim mySQL As String Dim myrows As Long myconnOpen DSN=MyODBCsample mySQL = SELECT from user myrsSource = mySQL Set myrsActiveConnection = myconn myrsCursorLocation = adUseClient myrsOpen myrows = myrsRecordCount myrsClose myconnClose 可參考 httpwwwdwamnetmysqlasp_myodbcasp 有詳細的資料 Q10如何將 MySQL中的資料庫匯出成txt檔 Ans select from TableName into outfile textxls all result fields will seperate by tab

77

第八章 參考資料

英文部份 網址 1 httpwwwmysqlcom MySQL 網站有第一手有關 MySQL的資料 2 httpwwwmysqlcomdocenReplicationhtml 有關 MySQL Replication 的文件 3 httpwwwgeocitiescomsqlhomefaqstore_blobhtml 如何在 MySQL 存放 BLOB的資料 4httpwwwsapdborg 有關 SAP跟 MySQL相關合作的網站 書藉 1 Cooking with MySQL

Paul DuBois has selected sample recipes from the hundreds youll find in his book MySQL

Cookbook In this third and final series of excerpts showcasing these recipes learn how to

compute team standings how to calculate the differences between successive Dec 26

2002 2 Tips for Building Web Database Applications with PHP and MySQL by Hugh E Williams co-author of Web Database Applications with PHP amp MySQL 04042002

3 Managing and Using MySQL 2nd Edition By Tim King George Reese Randy Jay Yarger

4 MySQL Cookbook By Paul DuBoisPublisher OReillyPub Date October 2002

中文部份

78

1 httplinuxtncedutwtechdocmysqlmysql_docmanual_tochtml MySQL 中文手冊 2 httpchenshloxaedutwphpZ_1php PHP+MySQ程式研習設計網站 3 httplinuxtncedutwtechdocbanicdownhtml PHP 4 手冊 4 httpwwwtncedutwadmin_zonephp台南縣教育網網路中心有很多 Linux相關文件 5 httpdobtncedutw網站建置百寶箱有很多 PHP MySQL 相關範例程式 5 httpwwwdbworldcomtw資料庫專家電子雜誌介紹資料庫的重要觀念及名詞

79

附錄一 SQL Command 介紹

SQL (讀音ess-que-el) 是一種結構查詢語法SQL 使用於資料庫交流

傳遞相容於 ANSI (American National Standards Institute) 是一套標準的關聯

式資料庫語言 SQL 語言是執行更新或從資料系統獲取資料一般常見的關聯

資料庫系統都有提供 SQL 如 Oracle Sybase Microsoft SQL Server Access Ingres 等雖然大部份的資料庫都有提供 SQL 但也多提供了自已獨特的語

法造成了不相容的情形但標準基本的語法是相通的如Select Insert Update Delete Create and Drop 每一個系統都有支援

Table相關 Command

Create Table

關聯式資料庫包含有很多元件稱為資料表(tables) 把資料或訊息放在資

料表中 資料表是以不同的名稱做分別資料表由欄列所構成的二維陣列

欄包含欄位名資料型態 及其他可判斷的資訊列是由全部欄位構成一筆一

筆的紀錄 create table 語法用在建立一個新的資料表語法格式如下

create table tablename (column1 data type column2 data type column3 data type)

Format of create table if you were to use optional constraints

create table tablename (column1 data type [constraint] column2 data type [constraint] column3 data type [constraint]) [ ] = optional

Note You may have as many columns as youd like and the constraints are optional

80

Example

create table employee (first varchar(15) last varchar(20) age number(3) address varchar(30) city varchar(20) state varchar(20))

注意建立資料表格式要以括號把前後框住而最後以(分號)做結尾

欄位名不要超過 30個字元長而且不要使用 sql 的關鍵字(如 where select等)而在後面接是型態的宣告(如字串數字日期格式等)

資料型態是來描述欄位的方式如一個欄位Last_Name 是一個姓氏可以使用varchar (可變動長度字串) 資料型態

以下是幾個常見的資料庫型態 char(size) 固定長度字串最長為 255 位元 varchar(size) 變動長度字串最大字元數以 size 來指定 number(size) 數值格式可以是整數也可以是小數最大數字以 size 位數判

斷未指定小數位數由系統內定 date 日期格式 number(sized) 數值格式最大數字以 size 位數判斷d 為小數位數整數位

數為 size-d 位

有何限制當資料表被建立通常有一或數個欄位是要使用來做關聯的功

能 例如unique 限制(唯一值)兩筆記錄不可以相同的值 not null (非空值)該欄位一定要輸入資料不可是空的primary key (主鍵)是每一筆記錄識別的主要方式

Drop a table drop table 刪除資料表(其中的資料也會一併刪除)

drop table tablename

Example

81

drop table 和刪除全部資料是不同的刪除全部資料欄位名稱資訊等還會

存在但刪除資料表會把這一些也一併移除掉

如何查詢資料

Select 基本用法

select 語法是關連式資料庫最常用的部份可以取得你想要的資料這是一個

簡單的範例 select column1[column2etc] from tablename [where condition] [] = optional 在 select 之後所列欄位名則是要顯示的資料部份你可以一一列出各欄位

名或是以 (星號)來代表選擇全部的欄位 from 之後放資料表名稱 where 子句 (選項) 指定要過濾的條件符合者才會顯現 where 可使用的條件運算元 = 等於 gt 大於 lt 小於 gt= 大或等於 lt= 小或等於 ltgt 大相等 LIKE 相似 For example select first last city

82

from empinfo where first LIKE Er 以Er 為開頭的字串就符合要以單引號框住 Or you can specify select first last from empinfo where last LIKE s 最後一字為 S 就符合 select from empinfo where first = Eric 則表示 first name 一定要是 Eric 才可以 範例資料表empinfo 統計函數

MIN 傳回指定欄位最小值

MAX 傳回指定欄位最大值

SUM 傳回指定欄位總和

AVG 傳回指定欄位平均值

COUNT 傳回指定欄位的筆數

COUNT() 傳回資料庫中的總筆數

統計函數使用於資料表中的數值欄位配合 SELECT 語法使用 只用於總結特定單一欄位可以配合 GROUP BY 做篩選但也可以不使用 GROUP BY 語句For example

SELECT AVG(salary) FROM employee

83

傳回全部 salary 平均值

Another example

SELECT AVG(salary) FROM employee WHERE title = Programmer

傳回 salary 平均值條件為 employees 資料表中當 title 等於 Programmer

Example

SELECT Count() FROM employees

傳回 employees 資料表中紀錄總筆數

GROUP BY 語法 SELECT column1 SUM(column2) FROM list-of-tables GROUP BY column-list The GROUP BY 語句可以先以所列的欄位為條件分組排序在一起(可以多欄

位) example 要列出每一個 dept 中最高 salary 值 SELECT max(salary) dept FROM employee GROUP BY dept HAVING 語法

SELECT column1 SUM(column2) FROM list-of-tables GROUP BY column-list HAVING condition

HAVING 子句是 GROUP BY 的一部份用來過濾在 GROUP BY 所選出的資料功能如同 select 命令中 where 條件式一樣只是 HAVING 必需配合 GROUP BY 使用

我們以例子來說明我們要取得每一公司名及每一公司的薪水平均值輸入如下

84

SELECT dept avg(salary) FROM employee GROUP BY dept

但如果我們只列出薪資平均值超過 20000元的公司資料

SELECT dept avg(salary) FROM employee GROUP BY dept HAVING avg(salary) gt 20000

ORDER BY子句語法

SELECT column1 SUM(column2) FROM list-of-tables ORDER BY column-list [ASC | DESC]

[ ] =選項

ORDER BY是一個選項子句當你以排序方式來顯示資料(正向由小到大反向由大到小)以指定的欄位資料做排序

ASC = 正向- 預設值 DESC = 反向排序

For example

SELECT employee_id dept name age salary FROM employee_info WHERE dept = Sales ORDER BY salary

以上列出公司代號公司名銷售員人名年紀及薪資而條件是公司名為 Sales 顯示順序以薪資多少排序(由小到大為預設值)

如果要以多個欄位做排序要以逗號做分隔如下

SELECT employee_id dept name age salary FROM employee_info WHERE dept = Sales ORDER BY salary age DESC

85

結合條件及布林運算 SELECT column1 SUM(column2) FROM list-of-tables WHERE condition1 AND condition2 AND運算可以結兩個或以上的條件放在 WHERE子句中 兩者都要為真才

會顯示該筆記錄 OR 運算可以結兩個或以上敘述放在 WHERE子句中只要其中一個為直就

會顯示該筆記錄 For example SELECT employeeid firstname lastname title salary FROM employee_info WHERE salary gt= 5000000 AND title = Programmer 必需要薪資大於等於 50000而且職稱為 Programmer同時符合才會顯示該筆資料 以下以括號括住雖然不是必需的但如此比較容易讀 SELECT employeeid firstname lastname title salary FROM employee_info WHERE (salary gt= 5000000) AND (title = Programmer) 另外範例 SELECT firstname lastname title salary FROM employee_info WHERE (title = Sales) OR (title = Programmer) 條件為只要是 Sales 或 Programmer 職稱的就會被列出 IN and BETWEEN 子句

SELECT column1 SUM(column2) FROM list-of-tables WHERE column3 IN (list-of-values) SELECT column1 SUM(column2) FROM list-of-tables WHERE column3 BETWEEN value1 AND value2 IN 子句使用在列舉項目的使用上也就是分別測試是否符合所列的值 For example

86

SELECT employeeid lastname salary FROM employee_info WHERE lastname IN (Hernandez Jones Roberts Ruiz) 條件為姓氏(astname)要符合 Hernandez Jones Roberts or Ruiz 其中一個才會被傳回 IN運算元也可以使用 OR 的語法來取代如下結果相同 SELECT employeeid lastname salary FROM employee_info WHERE lastname = Hernandez OR lastname = Jones OR lastname = Roberts OR lastname = Ruiz 但使用 IN 句子比較短也比較易懂 你也可以使用 NOT IN 來去掉不要的記錄 BETWEEN 運算元使用在判斷是否存在兩個數值之間 For example SELECT employeeid age lastname salary FROM employee_info WHERE age BETWEEN 30 AND 40 傳回年紀 30歲到 40歲之間的資料(含 30及 40歲者) 相同的也可以使用以下語法來達到相同的結果 SELECT employeeid age lastname salary FROM employee_info WHERE age gt= 30 AND age lt= 40 你也可使用 NOT BETWEEN 來濾掉中間值的資料 數學運算 標準 ANSI SQL-92 提供以下運算

87

+ 加

- 減

餘數

餘數為除法後剩整數這不在標準的 ANSI SQL 中但大部份的資料庫都會支

援這運算元以下列出有用的函數雖不在 ANSI SQL-92 提供但一般資料庫

也會支援他們

ABS(x) 傳回 x 絕對值

SIGN(x) returns the sign of input x as -1 0 or 1 (negative zero or positive respectively)

MOD(xy) 餘數 - returns the integer remainder of x divided by y (同 xy)

FLOOR(x) 傳回小或等於 x 的最大整數值

CEILING(x) or CEIL(x)

傳回大或等於 x 的最小整數值

POWER(xy) x的 y 次方

ROUND(x) 把 x 四捨五入為整數

ROUND(xd) 四捨五入取到小數 d 位

SQRT(x) x 開平方

For example SELECT round(salary) firstname FROM employee_info 傳回薪資取到整數位

如何新增資料

insert 加入一筆新紀錄到資料表中 insert into tablename (first_columnlast_column) values (first_valuelast_value) [] = optional Example insert into employee

88

(first last age address city state) values (Luke Duke 45 2130 Boars Nest Hazard Co Georgia) Note 字串要以單引號住如string 數字框住也無妨 insert into 後面接資料表名稱再接以括號括住的欄位名在 values 後括號分別對映各欄位的值 以上的例子新增了一筆名(first) 為 Luke而住所(state) 為 Georgia 的資料

如何刪除資料

delete 可以刪除單筆或多筆紀錄 delete from tablename where columnname OPERATOR value [and|or column OPERATOR value] [ ] = optional Examples delete from employee Note 如果你沒有指定 where 子句那麼全部的紀錄都會被刪除 delete from employee where lastname = May delete from employee where firstname = Mike or firstname = Eric delete from 接著資料表名 再接著是條件式判斷沒有條件式則全部紀錄會

被刪除

如何更新資料

update 用來更新你所指定的記錄要和 WHERE 配合小心使用 語法 update tablename set columnname = newvalue[nextcolumn = newvalue2] where columnname OPERATOR value [and|or column OPERATOR value] [] = optional Examples

89

update phone_book set area_code = 623 where prefix = 979 update phone_book set last_name = Smith prefix=555 suffix=9292 where last_name = Jones update employee set age = age+1 where first_name=Mary and last_name=Williams

90

附錄二Replication

測試環境

RedHat 90 + MySQL 32358 MySQL資料庫路徑 varlibmysql MySQL設定檔 etcmycnf Master IP 1921680100 Slave IP 1921680200 請至下列網址下載最新MySQL 32358套件並利用rpm ndashUvh 更新 httpupdatesredhatcom9enosi386

圖 最新 MySQL 套件

測試架構圖

91

1921680100

1921680200Master Server

erveSlave S r

圖 測試架構圖

測試步驟

Master server 部份 Step1 確認 MasterSlave機器上所裝的 MySQL版本能進行

replication( 32329 or higher ) Step2 在 Master MySQL上開放一個帳號給 Slave mysql ndashu root ndashp mysqlgtGRANT FILE ON TO repl1921680200 IDENTIFIED BY lsquoabc123rsquo mysqlgtq 上面是 Master開放一個帳號 repl密碼 abc123給 IP1921680200有檔案處理

的權限 Step3 shutdown MySQL on the Master mysqladmin ndashu root ndashp shutdown Step4 備份 Master所有資料庫 tar ndashcvf tmpmysql-snapshottar varlibmysql 注意tar的時候MySQL是要在 stop情況下 在mysql (wwwmysqlcom) 網站的FAQ有不用shutdown的方法

92

Step5 在 master機器上修改etcmycnf 在[mysqld]區段內加入參數 log-bin server-id=這邊設定 server-id=1 sql-bin-update-same binlog-do-db=CRM只針對 CRM資料庫做紀錄 Step6 Restart MySQL on the master service mysqld start 此時因為有加入 log-bin 參數因此開始有 index產生了在varlibmysql目錄下

有index檔案紀錄資料庫的異動 log Slave server 部份 Step1 在 slave設定etcmycnf 在[mysqld]區段加入 master-host= master-user= master-password= master-port= server-id= 這邊設定 master-host=1921680100 master-user=repl master-password=abc123 master-port=3306 server-id=2 master-connect-retry=60預設重試間隔 60秒 replicate-do-db=CRM告訴 slave只做 CRM資料庫的更新 log-slave-updates Step2 將 master上的 mysql-snapshottar copy到 slave上 用 ftp傳到 slave的tmp Step3 解壓縮 Master資料庫至 Slave Server上 cd varlib tar xvf tmpmysql-snapshottar chown ndashR mysqlmysql mysql

93

chmod ndashR 770 mysql (視情況) Step4 Restart MySQL on the slave server 這時在varlibmysql目錄會出現 masterinfo此檔案紀錄了 Master MySQL server的資訊

狀況測試

One-way replication

1921680100

1921680200Master Server

erveSlave S r

圖 One-way replication架構圖 Step1 Master跟 Slave網路及服務都正常情況下由 Master端異動資料後 到 Slave端瀏覽資料檢視是否有進行 replication Step2 模擬 Slave Server 當機 可用在於 slave真的當機或是 Slave 不一定需要一直跟 master connect將Slave MySQL server shutdown由 Master端異動資料到 slave端瀏覽此時Slave應該沒有被 replication 更新然後再將 Slave端 MySQL server start起來

預設 60秒後 Slave會嘗試跟 Master要求進行 replication再去 Slave端檢視是否有更新資料

94

Step3 模擬 Master當機因為是設定 One-way replication一旦 Master Server Slave端沒有 Master的 source可以 download Two-way replication 基於 Master當機狀況於是發展雙向 Replication即 1921680100 ( Host A ) 1921680200 ( Host B )都分別擔任 MasterSlave身分

1921680100

1921680200er

Server B MasterSlave Server

Server A MasterSlave Serv

圖 Two-way replication架構圖 以下是針對兩台 MySQL伺服器進行雙向 Replication Step1觀念同單向 replication只是改成 Master也有 Slave身分 Slave也有Master的身分先分別在 Server AServer B 都去 grant一個進行 replication的身分 [A]mysqlgtGRANT FILE ON TO repl1921680200 IDENTIFIED BY lsquoabc123rsquo [B]mysqlgt GRANT FILE ON TO repl1921680100 IDENTIFIED BY lsquoabc123rsquo Step2做完單向 replication後stop Server Aserver B MySQL service此時 AB資料是一樣的

95

修改etcmycnf設定 範例 Server A [mysqld] datadir=varlibmysql socket=varlibmysqlmysqlsock server-id=1 log-bin sql-bin-update-same binlog-do-db=CRM master-host=1921680200 master-user=repl master-password=abc123 log-slave-updates master-connect-retry=60 replicate-do-db=CRM Server B [mysqld] datadir=varlibmysql socket=varlibmysqlmysqlsock server-id=2 log-bin sql-bin-update-same binlog-do-db=CRM master-host=1921680100 master-user=repl master-password=abc123 log-slave-updates master-connect-retry=60 replicate-do-db=CRM 分別 start Server AServer B MySQL後此時雙方都是 MasterSlave身分一旦哪一方資料異動就會通知對方來 replication-若 replication失效則必須將Server AServer B的masterinfo及index00x 都砍掉然後分別 restart MySQL server進行測試檢視成果 實務上通常如果需要做Two-way replication通常會搭配Virtual Server使用

96

在前端架設一台Virtual Server不過此部份不在此份SOP討論範圍內有興趣

的讀者可參考 httpwwwlinuxvirtualserverorg 網站

1921680100 1921680200

Host A MasterSlave Server

Host B MasterSlave Server

Virtual Host

圖 Virtual Server + Two-way replication 架構圖

97

圖 High Availability Linux Virtual Server架構圖

98

  • COSA-SOP-03-006
  • 第一章 簡介
    • 11適用對象 (Audience)
    • 12 MySQL本身
    • 13 MySQL 40版跟50版重大的改進功能
    • 14 各家資料庫軟體比較
      • 第二章 前置需求
      • 第三章 安裝
        • 31 MySQL安裝
        • 32 phpMyAdmin安裝
        • 33 升級及注意事項
          • 第四章 MySQL管理
            • 41 Webmin 管理介面
            • 42 phpMyAdmin 的操作介面
            • 43管理指令介紹
              • 431 利用mysqladmin設定root的密碼
                  • 第五章 實用範例
                    • 51 任務一Web Base客戶通訊錄
                    • 52 任務二Web Base群組軟體 ( twig )
                      • 第六章 維護及更新程序
                        • 61 日常維護
                        • 62 更新程序
                        • 63 備份重要檔案
                        • 64 離線備份與還原
                        • 65 線上備份與還原
                          • 第七章 問題與解答
                          • 第八章 參考資料
                          • 附錄一 SQL Command 介紹
                          • 附錄二Replication
Page 70: DataBase Server Standard Operation Procedureebooks.lib.ntu.edu.tw/1_file/oss/63/93doc4-5.pdf · 業務的公司帶來了不少壓力,譬如微軟,甲骨文 ... 外的錢用在第三方的資料庫產品上,譬如就可以不用再購買甲骨文公司

WHERE user=root mysqlgt FLUSH PRIVILEGES mysqlgt exit 4停掉 mysql再重跑 mysqladmin -uroot -p shutdown Enter password 輸入新設定的密碼 etcrcdinitdmysql start

Q4NULL值問題

Ans

NULL值的概念是造成 SQL的新手的混淆的普遍原因他們經常認為 NULL是和一個空字符串的一樣的東西不是這樣的例如下列語句是完全不同的

mysqlgt INSERT INTO my_table (phone) VALUES (NULL)

mysqlgt INSERT INTO my_table (phone) VALUES ()

兩個語句把值插入到 phone 列但是第一個插入一個 NULL值而第二個插入一個空字符串第一個的含義可以認為是ldquo電話號碼不知道而第二個則可意味

著ldquo她沒有電話

在 SQL中NULL值在于任何其他值甚至 NULL值比較時總是假的(FALSE)包含 NULL的一個表達式總是產生一個 NULL值除非在包含在表達式中的運算符和函數的文檔中指出在下列例子所有的列返回 NULL

mysqlgt SELECT NULL1+NULLCONCAT(InvisibleNULL)

如果你想要尋找值是 NULL的列你不能使用=NULL測試下列語句不返回任

何行因為對任何表達式expr = NULL是假的

mysqlgt SELECT FROM my_table WHERE phone = NULL

要想尋找 NULL值你必須使用 IS NULL測試下例顯示如何找出 NULL電話號碼和空的電話號碼

70

mysqlgt SELECT FROM my_table WHERE phone IS NULL mysqlgt SELECT FROM my_table WHERE phone =

在 MySQL中就像很多其他的 SQL服務器一樣你不能索引可以有 NULL值的列你必須聲明這樣的列為 NOT NULL而且你不能插入 NULL到索引的

列中

當用 LOAD DATA INFILE 讀取數據時空列用更新如果你想要在一個列中有

NULL值你應該在文本文件中使用N字面上的詞NULL也可以在某些情形下使用

當使用 ORDER BY時首先呈現 NULL值如果你用 DESC以降序排序NULL值最後顯示當使用 GROUP BY時所有的 NULL值被認為是相等的

為了有助于NULL的處理你能使用 IS NULL和 IS NOT NULL運算符和 IFNULL()函數

對某些列類型NULL值被特殊地處理如果你將 NULL插入表的第一個TIMESTAMP 列則插入當前的日期和時間如果你將 NULL插入一個AUTO_INCREMENT 列則插入順序中的下一個數字

Q5如何將圖片存放於 MySQL中

Ans

Step 1建立資料庫 test

Step 2 建立表格 binary_data

CREATE TABLE binary_data (

id INT(4) NOT NULL AUTO_INCREMENT PRIMARY KEY

description CHAR(50)

bin_data LONGBLOB

filename CHAR(50)

filesize CHAR(50)

filetype CHAR(50)

71

)

Step 3 利用 storephp 寫入圖片

storephp 程式碼

ltHTMLgt ltHEADgtltTITLEgtStore binary data into SQL DatabaseltTITLEgtltHEADgt ltBODYgt lt code that will be executed if the form has been submitted

if ($submit) mysql_connect(localhostrootYOUR_PASSWORD) mysql_select_db(test) $data=Base64_Encode(fread(fopen($form_data r) filesize($form_data))) $result=MYSQL_QUERY(INSERT INTO binary_data (descriptionbin_datafilenamefilesizefiletype) VALUES ($form_description$data$form_data_name$form_data_size$form_data_type)) $id= mysql_insert_id() print ltpgtThis file has the following Database ID ltbgt$idltbgt MYSQL_CLOSE() else else show the form to submit new data

gt

ltform method=post action=ltphp echo $PHP_SELF gt enctype=multipartform-datagt File Descriptionltbrgt ltinput type=text name=form_description size=40gt ltINPUT TYPE=hidden name=MAX_FILE_SIZE value=4000000gt ltbrgtFile to uploadstore in databaseltbrgt ltinput type=file name=form_data size=40gt ltpgtltinput type=submit name=submit value=submitgt ltformgt lt

72

gt ltBODYgt ltHTMLgt

Step 3 利用 storephp 取出圖片

getdataphp 程式碼

lt Syntax getdataphp3id=ltidgt if($id) you may have to modify login information for your database server MYSQL_CONNECT(localhostrootYOUR_PASSWORD) mysql_select_db(test) $query = select bin_datafiletype from binary_data where id=$id $result = MYSQL_QUERY($query) $data = Base64_Decode(MYSQL_RESULT($result0bin_data)) $type = MYSQL_RESULT($result0filetype) Header( Content-type $type) echo $data gt

Q6MySQL裝好之後啟動時或是執行 mysqladmin會出現如下訊息 Cant connect to local MYSQL Server through Socket varlibmysqlmysqlsock或是

Cant connect to local MYSQL Server through Socket tmpmysqldsock

Ans 可能有下列幾個原因

1這個 mysqldsock 不見了被某人刪除了或是被一些系統自動執行程式給刪

了例如有些 cron任務便會設定定期刪除 tmp 裡的東西所以呢您只能修改

cron 裡的設定讓它不要清除 mysqldsock 2在啟動時也可以改變 mysqldsock的位置您在啟動 MySQL的時候可以加入此參數usrlocalmysqlbinsafe_mysqld --user=mysql --socket=其他路

徑socket amp 同時得去設定環境變數 MYSQL_UNIX_PORT的值以指定新的

73

路徑 3若是您沒改 MYSQL_UNIX_PORT的值那麼您可以在執行指令的時候才打

例如mysqladmin --socket=其他路徑socket version Q7How to get the last insert id Ans CREATE TABLE product ( id INT(4) NOT NULL AUTO_INCREMENT PRIMARY KEY description VARCHAR(50) ) 1利用 SQL的話 mysqlgt insert into product(description) values(123) Query OK 1 row affected (000 sec) mysqlgt select last_insert_id() +------------------+ | last_insert_id() | +------------------+ +------------------+ 1 row in set (000 sec) ======================================== 2如果是 PHP的話 你可以用mysql_insert_id()取得該 id PHP example $result=MYSQL_QUERY(INSERT INTO product (description) VALUES ($description)) $id= mysql_insert_id() print This file has the following Database ID $id Q8如何將文字檔匯入資料庫 Ans $addr=homehttpdhtmlphpschool001txt $sql_select = load data infile $addr into table test fields terminated by t 解說 $sql_select = load data infile 文字檔名 into table 表格名 fields terminated by

74

t

(欄位分隔以 TAB鍵) 該文字檔須與資料表欄位格式相符 例如欄位有三個 則文字檔為每行一筆資料如下 欄 1資料ltTABgt欄 2資料ltTABgt欄 3資料 欄 1資料ltTABgt欄 2資料ltTABgt欄 3資料 欄 1資料ltTABgt欄 2資料ltTABgt欄 3資料 欄 1資料ltTABgtltTABgt欄 3資料

Q9如何撰寫 MySQL C API Ans Step 1利用文字編輯器撰寫以下程式碼 mysqlcc

include ltstdiohgt

include ltmysqlmysqlhgt

int main (int argc char argv[])

MYSQL mysql

MYSQL_RES res

MYSQL_ROW row

if (argc = 2)

fputs (Usage myc ltdatabasegt stderr)

return 1

if ((mysql_connect(ampmysqllocalhostrootYour_Password)))

fputs (Error connecting stderr)

abort()

75

if (mysql_select_db(ampmysqlargv[1]))

fputs (Error selecting database stderr)

abort()

if (mysql_query(ampmysqlSELECT FROM test_table))

fputs (Error processing query stderr)

abort()

if ((res = mysql_store_result(ampmysql)))

fputs (Error storing results stderr)

abort()

while((row = mysql_fetch_row(res)))

uint i = 0

for (i=0 i lt mysql_num_fields(res) i++)

printf(s row[i])

printf(n)

return 0

Step 2 Compile

gcc -Iusrlocalmysqlinclude -Lusrlocalmysqllibmysql mysqlcc ndashlm -lmysqlclient

(其中 include path與 library path取決於你的 MySQL安裝路徑)

76

如果執行時發生如下 error Run problemerror in loading shared libraries libmysqlclientsoX 將你的 MySQL library path(for exampleusrlocalmysqllibmysql) 加入etcldsoconf and run sbinldconfig -v Q9ASP + MySQL 範例程式 Ans Dim myconn As New ADODBConnection Dim myrs As New Recordset Dim mySQL As String Dim myrows As Long myconnOpen DSN=MyODBCsample mySQL = SELECT from user myrsSource = mySQL Set myrsActiveConnection = myconn myrsCursorLocation = adUseClient myrsOpen myrows = myrsRecordCount myrsClose myconnClose 可參考 httpwwwdwamnetmysqlasp_myodbcasp 有詳細的資料 Q10如何將 MySQL中的資料庫匯出成txt檔 Ans select from TableName into outfile textxls all result fields will seperate by tab

77

第八章 參考資料

英文部份 網址 1 httpwwwmysqlcom MySQL 網站有第一手有關 MySQL的資料 2 httpwwwmysqlcomdocenReplicationhtml 有關 MySQL Replication 的文件 3 httpwwwgeocitiescomsqlhomefaqstore_blobhtml 如何在 MySQL 存放 BLOB的資料 4httpwwwsapdborg 有關 SAP跟 MySQL相關合作的網站 書藉 1 Cooking with MySQL

Paul DuBois has selected sample recipes from the hundreds youll find in his book MySQL

Cookbook In this third and final series of excerpts showcasing these recipes learn how to

compute team standings how to calculate the differences between successive Dec 26

2002 2 Tips for Building Web Database Applications with PHP and MySQL by Hugh E Williams co-author of Web Database Applications with PHP amp MySQL 04042002

3 Managing and Using MySQL 2nd Edition By Tim King George Reese Randy Jay Yarger

4 MySQL Cookbook By Paul DuBoisPublisher OReillyPub Date October 2002

中文部份

78

1 httplinuxtncedutwtechdocmysqlmysql_docmanual_tochtml MySQL 中文手冊 2 httpchenshloxaedutwphpZ_1php PHP+MySQ程式研習設計網站 3 httplinuxtncedutwtechdocbanicdownhtml PHP 4 手冊 4 httpwwwtncedutwadmin_zonephp台南縣教育網網路中心有很多 Linux相關文件 5 httpdobtncedutw網站建置百寶箱有很多 PHP MySQL 相關範例程式 5 httpwwwdbworldcomtw資料庫專家電子雜誌介紹資料庫的重要觀念及名詞

79

附錄一 SQL Command 介紹

SQL (讀音ess-que-el) 是一種結構查詢語法SQL 使用於資料庫交流

傳遞相容於 ANSI (American National Standards Institute) 是一套標準的關聯

式資料庫語言 SQL 語言是執行更新或從資料系統獲取資料一般常見的關聯

資料庫系統都有提供 SQL 如 Oracle Sybase Microsoft SQL Server Access Ingres 等雖然大部份的資料庫都有提供 SQL 但也多提供了自已獨特的語

法造成了不相容的情形但標準基本的語法是相通的如Select Insert Update Delete Create and Drop 每一個系統都有支援

Table相關 Command

Create Table

關聯式資料庫包含有很多元件稱為資料表(tables) 把資料或訊息放在資

料表中 資料表是以不同的名稱做分別資料表由欄列所構成的二維陣列

欄包含欄位名資料型態 及其他可判斷的資訊列是由全部欄位構成一筆一

筆的紀錄 create table 語法用在建立一個新的資料表語法格式如下

create table tablename (column1 data type column2 data type column3 data type)

Format of create table if you were to use optional constraints

create table tablename (column1 data type [constraint] column2 data type [constraint] column3 data type [constraint]) [ ] = optional

Note You may have as many columns as youd like and the constraints are optional

80

Example

create table employee (first varchar(15) last varchar(20) age number(3) address varchar(30) city varchar(20) state varchar(20))

注意建立資料表格式要以括號把前後框住而最後以(分號)做結尾

欄位名不要超過 30個字元長而且不要使用 sql 的關鍵字(如 where select等)而在後面接是型態的宣告(如字串數字日期格式等)

資料型態是來描述欄位的方式如一個欄位Last_Name 是一個姓氏可以使用varchar (可變動長度字串) 資料型態

以下是幾個常見的資料庫型態 char(size) 固定長度字串最長為 255 位元 varchar(size) 變動長度字串最大字元數以 size 來指定 number(size) 數值格式可以是整數也可以是小數最大數字以 size 位數判

斷未指定小數位數由系統內定 date 日期格式 number(sized) 數值格式最大數字以 size 位數判斷d 為小數位數整數位

數為 size-d 位

有何限制當資料表被建立通常有一或數個欄位是要使用來做關聯的功

能 例如unique 限制(唯一值)兩筆記錄不可以相同的值 not null (非空值)該欄位一定要輸入資料不可是空的primary key (主鍵)是每一筆記錄識別的主要方式

Drop a table drop table 刪除資料表(其中的資料也會一併刪除)

drop table tablename

Example

81

drop table 和刪除全部資料是不同的刪除全部資料欄位名稱資訊等還會

存在但刪除資料表會把這一些也一併移除掉

如何查詢資料

Select 基本用法

select 語法是關連式資料庫最常用的部份可以取得你想要的資料這是一個

簡單的範例 select column1[column2etc] from tablename [where condition] [] = optional 在 select 之後所列欄位名則是要顯示的資料部份你可以一一列出各欄位

名或是以 (星號)來代表選擇全部的欄位 from 之後放資料表名稱 where 子句 (選項) 指定要過濾的條件符合者才會顯現 where 可使用的條件運算元 = 等於 gt 大於 lt 小於 gt= 大或等於 lt= 小或等於 ltgt 大相等 LIKE 相似 For example select first last city

82

from empinfo where first LIKE Er 以Er 為開頭的字串就符合要以單引號框住 Or you can specify select first last from empinfo where last LIKE s 最後一字為 S 就符合 select from empinfo where first = Eric 則表示 first name 一定要是 Eric 才可以 範例資料表empinfo 統計函數

MIN 傳回指定欄位最小值

MAX 傳回指定欄位最大值

SUM 傳回指定欄位總和

AVG 傳回指定欄位平均值

COUNT 傳回指定欄位的筆數

COUNT() 傳回資料庫中的總筆數

統計函數使用於資料表中的數值欄位配合 SELECT 語法使用 只用於總結特定單一欄位可以配合 GROUP BY 做篩選但也可以不使用 GROUP BY 語句For example

SELECT AVG(salary) FROM employee

83

傳回全部 salary 平均值

Another example

SELECT AVG(salary) FROM employee WHERE title = Programmer

傳回 salary 平均值條件為 employees 資料表中當 title 等於 Programmer

Example

SELECT Count() FROM employees

傳回 employees 資料表中紀錄總筆數

GROUP BY 語法 SELECT column1 SUM(column2) FROM list-of-tables GROUP BY column-list The GROUP BY 語句可以先以所列的欄位為條件分組排序在一起(可以多欄

位) example 要列出每一個 dept 中最高 salary 值 SELECT max(salary) dept FROM employee GROUP BY dept HAVING 語法

SELECT column1 SUM(column2) FROM list-of-tables GROUP BY column-list HAVING condition

HAVING 子句是 GROUP BY 的一部份用來過濾在 GROUP BY 所選出的資料功能如同 select 命令中 where 條件式一樣只是 HAVING 必需配合 GROUP BY 使用

我們以例子來說明我們要取得每一公司名及每一公司的薪水平均值輸入如下

84

SELECT dept avg(salary) FROM employee GROUP BY dept

但如果我們只列出薪資平均值超過 20000元的公司資料

SELECT dept avg(salary) FROM employee GROUP BY dept HAVING avg(salary) gt 20000

ORDER BY子句語法

SELECT column1 SUM(column2) FROM list-of-tables ORDER BY column-list [ASC | DESC]

[ ] =選項

ORDER BY是一個選項子句當你以排序方式來顯示資料(正向由小到大反向由大到小)以指定的欄位資料做排序

ASC = 正向- 預設值 DESC = 反向排序

For example

SELECT employee_id dept name age salary FROM employee_info WHERE dept = Sales ORDER BY salary

以上列出公司代號公司名銷售員人名年紀及薪資而條件是公司名為 Sales 顯示順序以薪資多少排序(由小到大為預設值)

如果要以多個欄位做排序要以逗號做分隔如下

SELECT employee_id dept name age salary FROM employee_info WHERE dept = Sales ORDER BY salary age DESC

85

結合條件及布林運算 SELECT column1 SUM(column2) FROM list-of-tables WHERE condition1 AND condition2 AND運算可以結兩個或以上的條件放在 WHERE子句中 兩者都要為真才

會顯示該筆記錄 OR 運算可以結兩個或以上敘述放在 WHERE子句中只要其中一個為直就

會顯示該筆記錄 For example SELECT employeeid firstname lastname title salary FROM employee_info WHERE salary gt= 5000000 AND title = Programmer 必需要薪資大於等於 50000而且職稱為 Programmer同時符合才會顯示該筆資料 以下以括號括住雖然不是必需的但如此比較容易讀 SELECT employeeid firstname lastname title salary FROM employee_info WHERE (salary gt= 5000000) AND (title = Programmer) 另外範例 SELECT firstname lastname title salary FROM employee_info WHERE (title = Sales) OR (title = Programmer) 條件為只要是 Sales 或 Programmer 職稱的就會被列出 IN and BETWEEN 子句

SELECT column1 SUM(column2) FROM list-of-tables WHERE column3 IN (list-of-values) SELECT column1 SUM(column2) FROM list-of-tables WHERE column3 BETWEEN value1 AND value2 IN 子句使用在列舉項目的使用上也就是分別測試是否符合所列的值 For example

86

SELECT employeeid lastname salary FROM employee_info WHERE lastname IN (Hernandez Jones Roberts Ruiz) 條件為姓氏(astname)要符合 Hernandez Jones Roberts or Ruiz 其中一個才會被傳回 IN運算元也可以使用 OR 的語法來取代如下結果相同 SELECT employeeid lastname salary FROM employee_info WHERE lastname = Hernandez OR lastname = Jones OR lastname = Roberts OR lastname = Ruiz 但使用 IN 句子比較短也比較易懂 你也可以使用 NOT IN 來去掉不要的記錄 BETWEEN 運算元使用在判斷是否存在兩個數值之間 For example SELECT employeeid age lastname salary FROM employee_info WHERE age BETWEEN 30 AND 40 傳回年紀 30歲到 40歲之間的資料(含 30及 40歲者) 相同的也可以使用以下語法來達到相同的結果 SELECT employeeid age lastname salary FROM employee_info WHERE age gt= 30 AND age lt= 40 你也可使用 NOT BETWEEN 來濾掉中間值的資料 數學運算 標準 ANSI SQL-92 提供以下運算

87

+ 加

- 減

餘數

餘數為除法後剩整數這不在標準的 ANSI SQL 中但大部份的資料庫都會支

援這運算元以下列出有用的函數雖不在 ANSI SQL-92 提供但一般資料庫

也會支援他們

ABS(x) 傳回 x 絕對值

SIGN(x) returns the sign of input x as -1 0 or 1 (negative zero or positive respectively)

MOD(xy) 餘數 - returns the integer remainder of x divided by y (同 xy)

FLOOR(x) 傳回小或等於 x 的最大整數值

CEILING(x) or CEIL(x)

傳回大或等於 x 的最小整數值

POWER(xy) x的 y 次方

ROUND(x) 把 x 四捨五入為整數

ROUND(xd) 四捨五入取到小數 d 位

SQRT(x) x 開平方

For example SELECT round(salary) firstname FROM employee_info 傳回薪資取到整數位

如何新增資料

insert 加入一筆新紀錄到資料表中 insert into tablename (first_columnlast_column) values (first_valuelast_value) [] = optional Example insert into employee

88

(first last age address city state) values (Luke Duke 45 2130 Boars Nest Hazard Co Georgia) Note 字串要以單引號住如string 數字框住也無妨 insert into 後面接資料表名稱再接以括號括住的欄位名在 values 後括號分別對映各欄位的值 以上的例子新增了一筆名(first) 為 Luke而住所(state) 為 Georgia 的資料

如何刪除資料

delete 可以刪除單筆或多筆紀錄 delete from tablename where columnname OPERATOR value [and|or column OPERATOR value] [ ] = optional Examples delete from employee Note 如果你沒有指定 where 子句那麼全部的紀錄都會被刪除 delete from employee where lastname = May delete from employee where firstname = Mike or firstname = Eric delete from 接著資料表名 再接著是條件式判斷沒有條件式則全部紀錄會

被刪除

如何更新資料

update 用來更新你所指定的記錄要和 WHERE 配合小心使用 語法 update tablename set columnname = newvalue[nextcolumn = newvalue2] where columnname OPERATOR value [and|or column OPERATOR value] [] = optional Examples

89

update phone_book set area_code = 623 where prefix = 979 update phone_book set last_name = Smith prefix=555 suffix=9292 where last_name = Jones update employee set age = age+1 where first_name=Mary and last_name=Williams

90

附錄二Replication

測試環境

RedHat 90 + MySQL 32358 MySQL資料庫路徑 varlibmysql MySQL設定檔 etcmycnf Master IP 1921680100 Slave IP 1921680200 請至下列網址下載最新MySQL 32358套件並利用rpm ndashUvh 更新 httpupdatesredhatcom9enosi386

圖 最新 MySQL 套件

測試架構圖

91

1921680100

1921680200Master Server

erveSlave S r

圖 測試架構圖

測試步驟

Master server 部份 Step1 確認 MasterSlave機器上所裝的 MySQL版本能進行

replication( 32329 or higher ) Step2 在 Master MySQL上開放一個帳號給 Slave mysql ndashu root ndashp mysqlgtGRANT FILE ON TO repl1921680200 IDENTIFIED BY lsquoabc123rsquo mysqlgtq 上面是 Master開放一個帳號 repl密碼 abc123給 IP1921680200有檔案處理

的權限 Step3 shutdown MySQL on the Master mysqladmin ndashu root ndashp shutdown Step4 備份 Master所有資料庫 tar ndashcvf tmpmysql-snapshottar varlibmysql 注意tar的時候MySQL是要在 stop情況下 在mysql (wwwmysqlcom) 網站的FAQ有不用shutdown的方法

92

Step5 在 master機器上修改etcmycnf 在[mysqld]區段內加入參數 log-bin server-id=這邊設定 server-id=1 sql-bin-update-same binlog-do-db=CRM只針對 CRM資料庫做紀錄 Step6 Restart MySQL on the master service mysqld start 此時因為有加入 log-bin 參數因此開始有 index產生了在varlibmysql目錄下

有index檔案紀錄資料庫的異動 log Slave server 部份 Step1 在 slave設定etcmycnf 在[mysqld]區段加入 master-host= master-user= master-password= master-port= server-id= 這邊設定 master-host=1921680100 master-user=repl master-password=abc123 master-port=3306 server-id=2 master-connect-retry=60預設重試間隔 60秒 replicate-do-db=CRM告訴 slave只做 CRM資料庫的更新 log-slave-updates Step2 將 master上的 mysql-snapshottar copy到 slave上 用 ftp傳到 slave的tmp Step3 解壓縮 Master資料庫至 Slave Server上 cd varlib tar xvf tmpmysql-snapshottar chown ndashR mysqlmysql mysql

93

chmod ndashR 770 mysql (視情況) Step4 Restart MySQL on the slave server 這時在varlibmysql目錄會出現 masterinfo此檔案紀錄了 Master MySQL server的資訊

狀況測試

One-way replication

1921680100

1921680200Master Server

erveSlave S r

圖 One-way replication架構圖 Step1 Master跟 Slave網路及服務都正常情況下由 Master端異動資料後 到 Slave端瀏覽資料檢視是否有進行 replication Step2 模擬 Slave Server 當機 可用在於 slave真的當機或是 Slave 不一定需要一直跟 master connect將Slave MySQL server shutdown由 Master端異動資料到 slave端瀏覽此時Slave應該沒有被 replication 更新然後再將 Slave端 MySQL server start起來

預設 60秒後 Slave會嘗試跟 Master要求進行 replication再去 Slave端檢視是否有更新資料

94

Step3 模擬 Master當機因為是設定 One-way replication一旦 Master Server Slave端沒有 Master的 source可以 download Two-way replication 基於 Master當機狀況於是發展雙向 Replication即 1921680100 ( Host A ) 1921680200 ( Host B )都分別擔任 MasterSlave身分

1921680100

1921680200er

Server B MasterSlave Server

Server A MasterSlave Serv

圖 Two-way replication架構圖 以下是針對兩台 MySQL伺服器進行雙向 Replication Step1觀念同單向 replication只是改成 Master也有 Slave身分 Slave也有Master的身分先分別在 Server AServer B 都去 grant一個進行 replication的身分 [A]mysqlgtGRANT FILE ON TO repl1921680200 IDENTIFIED BY lsquoabc123rsquo [B]mysqlgt GRANT FILE ON TO repl1921680100 IDENTIFIED BY lsquoabc123rsquo Step2做完單向 replication後stop Server Aserver B MySQL service此時 AB資料是一樣的

95

修改etcmycnf設定 範例 Server A [mysqld] datadir=varlibmysql socket=varlibmysqlmysqlsock server-id=1 log-bin sql-bin-update-same binlog-do-db=CRM master-host=1921680200 master-user=repl master-password=abc123 log-slave-updates master-connect-retry=60 replicate-do-db=CRM Server B [mysqld] datadir=varlibmysql socket=varlibmysqlmysqlsock server-id=2 log-bin sql-bin-update-same binlog-do-db=CRM master-host=1921680100 master-user=repl master-password=abc123 log-slave-updates master-connect-retry=60 replicate-do-db=CRM 分別 start Server AServer B MySQL後此時雙方都是 MasterSlave身分一旦哪一方資料異動就會通知對方來 replication-若 replication失效則必須將Server AServer B的masterinfo及index00x 都砍掉然後分別 restart MySQL server進行測試檢視成果 實務上通常如果需要做Two-way replication通常會搭配Virtual Server使用

96

在前端架設一台Virtual Server不過此部份不在此份SOP討論範圍內有興趣

的讀者可參考 httpwwwlinuxvirtualserverorg 網站

1921680100 1921680200

Host A MasterSlave Server

Host B MasterSlave Server

Virtual Host

圖 Virtual Server + Two-way replication 架構圖

97

圖 High Availability Linux Virtual Server架構圖

98

  • COSA-SOP-03-006
  • 第一章 簡介
    • 11適用對象 (Audience)
    • 12 MySQL本身
    • 13 MySQL 40版跟50版重大的改進功能
    • 14 各家資料庫軟體比較
      • 第二章 前置需求
      • 第三章 安裝
        • 31 MySQL安裝
        • 32 phpMyAdmin安裝
        • 33 升級及注意事項
          • 第四章 MySQL管理
            • 41 Webmin 管理介面
            • 42 phpMyAdmin 的操作介面
            • 43管理指令介紹
              • 431 利用mysqladmin設定root的密碼
                  • 第五章 實用範例
                    • 51 任務一Web Base客戶通訊錄
                    • 52 任務二Web Base群組軟體 ( twig )
                      • 第六章 維護及更新程序
                        • 61 日常維護
                        • 62 更新程序
                        • 63 備份重要檔案
                        • 64 離線備份與還原
                        • 65 線上備份與還原
                          • 第七章 問題與解答
                          • 第八章 參考資料
                          • 附錄一 SQL Command 介紹
                          • 附錄二Replication
Page 71: DataBase Server Standard Operation Procedureebooks.lib.ntu.edu.tw/1_file/oss/63/93doc4-5.pdf · 業務的公司帶來了不少壓力,譬如微軟,甲骨文 ... 外的錢用在第三方的資料庫產品上,譬如就可以不用再購買甲骨文公司

mysqlgt SELECT FROM my_table WHERE phone IS NULL mysqlgt SELECT FROM my_table WHERE phone =

在 MySQL中就像很多其他的 SQL服務器一樣你不能索引可以有 NULL值的列你必須聲明這樣的列為 NOT NULL而且你不能插入 NULL到索引的

列中

當用 LOAD DATA INFILE 讀取數據時空列用更新如果你想要在一個列中有

NULL值你應該在文本文件中使用N字面上的詞NULL也可以在某些情形下使用

當使用 ORDER BY時首先呈現 NULL值如果你用 DESC以降序排序NULL值最後顯示當使用 GROUP BY時所有的 NULL值被認為是相等的

為了有助于NULL的處理你能使用 IS NULL和 IS NOT NULL運算符和 IFNULL()函數

對某些列類型NULL值被特殊地處理如果你將 NULL插入表的第一個TIMESTAMP 列則插入當前的日期和時間如果你將 NULL插入一個AUTO_INCREMENT 列則插入順序中的下一個數字

Q5如何將圖片存放於 MySQL中

Ans

Step 1建立資料庫 test

Step 2 建立表格 binary_data

CREATE TABLE binary_data (

id INT(4) NOT NULL AUTO_INCREMENT PRIMARY KEY

description CHAR(50)

bin_data LONGBLOB

filename CHAR(50)

filesize CHAR(50)

filetype CHAR(50)

71

)

Step 3 利用 storephp 寫入圖片

storephp 程式碼

ltHTMLgt ltHEADgtltTITLEgtStore binary data into SQL DatabaseltTITLEgtltHEADgt ltBODYgt lt code that will be executed if the form has been submitted

if ($submit) mysql_connect(localhostrootYOUR_PASSWORD) mysql_select_db(test) $data=Base64_Encode(fread(fopen($form_data r) filesize($form_data))) $result=MYSQL_QUERY(INSERT INTO binary_data (descriptionbin_datafilenamefilesizefiletype) VALUES ($form_description$data$form_data_name$form_data_size$form_data_type)) $id= mysql_insert_id() print ltpgtThis file has the following Database ID ltbgt$idltbgt MYSQL_CLOSE() else else show the form to submit new data

gt

ltform method=post action=ltphp echo $PHP_SELF gt enctype=multipartform-datagt File Descriptionltbrgt ltinput type=text name=form_description size=40gt ltINPUT TYPE=hidden name=MAX_FILE_SIZE value=4000000gt ltbrgtFile to uploadstore in databaseltbrgt ltinput type=file name=form_data size=40gt ltpgtltinput type=submit name=submit value=submitgt ltformgt lt

72

gt ltBODYgt ltHTMLgt

Step 3 利用 storephp 取出圖片

getdataphp 程式碼

lt Syntax getdataphp3id=ltidgt if($id) you may have to modify login information for your database server MYSQL_CONNECT(localhostrootYOUR_PASSWORD) mysql_select_db(test) $query = select bin_datafiletype from binary_data where id=$id $result = MYSQL_QUERY($query) $data = Base64_Decode(MYSQL_RESULT($result0bin_data)) $type = MYSQL_RESULT($result0filetype) Header( Content-type $type) echo $data gt

Q6MySQL裝好之後啟動時或是執行 mysqladmin會出現如下訊息 Cant connect to local MYSQL Server through Socket varlibmysqlmysqlsock或是

Cant connect to local MYSQL Server through Socket tmpmysqldsock

Ans 可能有下列幾個原因

1這個 mysqldsock 不見了被某人刪除了或是被一些系統自動執行程式給刪

了例如有些 cron任務便會設定定期刪除 tmp 裡的東西所以呢您只能修改

cron 裡的設定讓它不要清除 mysqldsock 2在啟動時也可以改變 mysqldsock的位置您在啟動 MySQL的時候可以加入此參數usrlocalmysqlbinsafe_mysqld --user=mysql --socket=其他路

徑socket amp 同時得去設定環境變數 MYSQL_UNIX_PORT的值以指定新的

73

路徑 3若是您沒改 MYSQL_UNIX_PORT的值那麼您可以在執行指令的時候才打

例如mysqladmin --socket=其他路徑socket version Q7How to get the last insert id Ans CREATE TABLE product ( id INT(4) NOT NULL AUTO_INCREMENT PRIMARY KEY description VARCHAR(50) ) 1利用 SQL的話 mysqlgt insert into product(description) values(123) Query OK 1 row affected (000 sec) mysqlgt select last_insert_id() +------------------+ | last_insert_id() | +------------------+ +------------------+ 1 row in set (000 sec) ======================================== 2如果是 PHP的話 你可以用mysql_insert_id()取得該 id PHP example $result=MYSQL_QUERY(INSERT INTO product (description) VALUES ($description)) $id= mysql_insert_id() print This file has the following Database ID $id Q8如何將文字檔匯入資料庫 Ans $addr=homehttpdhtmlphpschool001txt $sql_select = load data infile $addr into table test fields terminated by t 解說 $sql_select = load data infile 文字檔名 into table 表格名 fields terminated by

74

t

(欄位分隔以 TAB鍵) 該文字檔須與資料表欄位格式相符 例如欄位有三個 則文字檔為每行一筆資料如下 欄 1資料ltTABgt欄 2資料ltTABgt欄 3資料 欄 1資料ltTABgt欄 2資料ltTABgt欄 3資料 欄 1資料ltTABgt欄 2資料ltTABgt欄 3資料 欄 1資料ltTABgtltTABgt欄 3資料

Q9如何撰寫 MySQL C API Ans Step 1利用文字編輯器撰寫以下程式碼 mysqlcc

include ltstdiohgt

include ltmysqlmysqlhgt

int main (int argc char argv[])

MYSQL mysql

MYSQL_RES res

MYSQL_ROW row

if (argc = 2)

fputs (Usage myc ltdatabasegt stderr)

return 1

if ((mysql_connect(ampmysqllocalhostrootYour_Password)))

fputs (Error connecting stderr)

abort()

75

if (mysql_select_db(ampmysqlargv[1]))

fputs (Error selecting database stderr)

abort()

if (mysql_query(ampmysqlSELECT FROM test_table))

fputs (Error processing query stderr)

abort()

if ((res = mysql_store_result(ampmysql)))

fputs (Error storing results stderr)

abort()

while((row = mysql_fetch_row(res)))

uint i = 0

for (i=0 i lt mysql_num_fields(res) i++)

printf(s row[i])

printf(n)

return 0

Step 2 Compile

gcc -Iusrlocalmysqlinclude -Lusrlocalmysqllibmysql mysqlcc ndashlm -lmysqlclient

(其中 include path與 library path取決於你的 MySQL安裝路徑)

76

如果執行時發生如下 error Run problemerror in loading shared libraries libmysqlclientsoX 將你的 MySQL library path(for exampleusrlocalmysqllibmysql) 加入etcldsoconf and run sbinldconfig -v Q9ASP + MySQL 範例程式 Ans Dim myconn As New ADODBConnection Dim myrs As New Recordset Dim mySQL As String Dim myrows As Long myconnOpen DSN=MyODBCsample mySQL = SELECT from user myrsSource = mySQL Set myrsActiveConnection = myconn myrsCursorLocation = adUseClient myrsOpen myrows = myrsRecordCount myrsClose myconnClose 可參考 httpwwwdwamnetmysqlasp_myodbcasp 有詳細的資料 Q10如何將 MySQL中的資料庫匯出成txt檔 Ans select from TableName into outfile textxls all result fields will seperate by tab

77

第八章 參考資料

英文部份 網址 1 httpwwwmysqlcom MySQL 網站有第一手有關 MySQL的資料 2 httpwwwmysqlcomdocenReplicationhtml 有關 MySQL Replication 的文件 3 httpwwwgeocitiescomsqlhomefaqstore_blobhtml 如何在 MySQL 存放 BLOB的資料 4httpwwwsapdborg 有關 SAP跟 MySQL相關合作的網站 書藉 1 Cooking with MySQL

Paul DuBois has selected sample recipes from the hundreds youll find in his book MySQL

Cookbook In this third and final series of excerpts showcasing these recipes learn how to

compute team standings how to calculate the differences between successive Dec 26

2002 2 Tips for Building Web Database Applications with PHP and MySQL by Hugh E Williams co-author of Web Database Applications with PHP amp MySQL 04042002

3 Managing and Using MySQL 2nd Edition By Tim King George Reese Randy Jay Yarger

4 MySQL Cookbook By Paul DuBoisPublisher OReillyPub Date October 2002

中文部份

78

1 httplinuxtncedutwtechdocmysqlmysql_docmanual_tochtml MySQL 中文手冊 2 httpchenshloxaedutwphpZ_1php PHP+MySQ程式研習設計網站 3 httplinuxtncedutwtechdocbanicdownhtml PHP 4 手冊 4 httpwwwtncedutwadmin_zonephp台南縣教育網網路中心有很多 Linux相關文件 5 httpdobtncedutw網站建置百寶箱有很多 PHP MySQL 相關範例程式 5 httpwwwdbworldcomtw資料庫專家電子雜誌介紹資料庫的重要觀念及名詞

79

附錄一 SQL Command 介紹

SQL (讀音ess-que-el) 是一種結構查詢語法SQL 使用於資料庫交流

傳遞相容於 ANSI (American National Standards Institute) 是一套標準的關聯

式資料庫語言 SQL 語言是執行更新或從資料系統獲取資料一般常見的關聯

資料庫系統都有提供 SQL 如 Oracle Sybase Microsoft SQL Server Access Ingres 等雖然大部份的資料庫都有提供 SQL 但也多提供了自已獨特的語

法造成了不相容的情形但標準基本的語法是相通的如Select Insert Update Delete Create and Drop 每一個系統都有支援

Table相關 Command

Create Table

關聯式資料庫包含有很多元件稱為資料表(tables) 把資料或訊息放在資

料表中 資料表是以不同的名稱做分別資料表由欄列所構成的二維陣列

欄包含欄位名資料型態 及其他可判斷的資訊列是由全部欄位構成一筆一

筆的紀錄 create table 語法用在建立一個新的資料表語法格式如下

create table tablename (column1 data type column2 data type column3 data type)

Format of create table if you were to use optional constraints

create table tablename (column1 data type [constraint] column2 data type [constraint] column3 data type [constraint]) [ ] = optional

Note You may have as many columns as youd like and the constraints are optional

80

Example

create table employee (first varchar(15) last varchar(20) age number(3) address varchar(30) city varchar(20) state varchar(20))

注意建立資料表格式要以括號把前後框住而最後以(分號)做結尾

欄位名不要超過 30個字元長而且不要使用 sql 的關鍵字(如 where select等)而在後面接是型態的宣告(如字串數字日期格式等)

資料型態是來描述欄位的方式如一個欄位Last_Name 是一個姓氏可以使用varchar (可變動長度字串) 資料型態

以下是幾個常見的資料庫型態 char(size) 固定長度字串最長為 255 位元 varchar(size) 變動長度字串最大字元數以 size 來指定 number(size) 數值格式可以是整數也可以是小數最大數字以 size 位數判

斷未指定小數位數由系統內定 date 日期格式 number(sized) 數值格式最大數字以 size 位數判斷d 為小數位數整數位

數為 size-d 位

有何限制當資料表被建立通常有一或數個欄位是要使用來做關聯的功

能 例如unique 限制(唯一值)兩筆記錄不可以相同的值 not null (非空值)該欄位一定要輸入資料不可是空的primary key (主鍵)是每一筆記錄識別的主要方式

Drop a table drop table 刪除資料表(其中的資料也會一併刪除)

drop table tablename

Example

81

drop table 和刪除全部資料是不同的刪除全部資料欄位名稱資訊等還會

存在但刪除資料表會把這一些也一併移除掉

如何查詢資料

Select 基本用法

select 語法是關連式資料庫最常用的部份可以取得你想要的資料這是一個

簡單的範例 select column1[column2etc] from tablename [where condition] [] = optional 在 select 之後所列欄位名則是要顯示的資料部份你可以一一列出各欄位

名或是以 (星號)來代表選擇全部的欄位 from 之後放資料表名稱 where 子句 (選項) 指定要過濾的條件符合者才會顯現 where 可使用的條件運算元 = 等於 gt 大於 lt 小於 gt= 大或等於 lt= 小或等於 ltgt 大相等 LIKE 相似 For example select first last city

82

from empinfo where first LIKE Er 以Er 為開頭的字串就符合要以單引號框住 Or you can specify select first last from empinfo where last LIKE s 最後一字為 S 就符合 select from empinfo where first = Eric 則表示 first name 一定要是 Eric 才可以 範例資料表empinfo 統計函數

MIN 傳回指定欄位最小值

MAX 傳回指定欄位最大值

SUM 傳回指定欄位總和

AVG 傳回指定欄位平均值

COUNT 傳回指定欄位的筆數

COUNT() 傳回資料庫中的總筆數

統計函數使用於資料表中的數值欄位配合 SELECT 語法使用 只用於總結特定單一欄位可以配合 GROUP BY 做篩選但也可以不使用 GROUP BY 語句For example

SELECT AVG(salary) FROM employee

83

傳回全部 salary 平均值

Another example

SELECT AVG(salary) FROM employee WHERE title = Programmer

傳回 salary 平均值條件為 employees 資料表中當 title 等於 Programmer

Example

SELECT Count() FROM employees

傳回 employees 資料表中紀錄總筆數

GROUP BY 語法 SELECT column1 SUM(column2) FROM list-of-tables GROUP BY column-list The GROUP BY 語句可以先以所列的欄位為條件分組排序在一起(可以多欄

位) example 要列出每一個 dept 中最高 salary 值 SELECT max(salary) dept FROM employee GROUP BY dept HAVING 語法

SELECT column1 SUM(column2) FROM list-of-tables GROUP BY column-list HAVING condition

HAVING 子句是 GROUP BY 的一部份用來過濾在 GROUP BY 所選出的資料功能如同 select 命令中 where 條件式一樣只是 HAVING 必需配合 GROUP BY 使用

我們以例子來說明我們要取得每一公司名及每一公司的薪水平均值輸入如下

84

SELECT dept avg(salary) FROM employee GROUP BY dept

但如果我們只列出薪資平均值超過 20000元的公司資料

SELECT dept avg(salary) FROM employee GROUP BY dept HAVING avg(salary) gt 20000

ORDER BY子句語法

SELECT column1 SUM(column2) FROM list-of-tables ORDER BY column-list [ASC | DESC]

[ ] =選項

ORDER BY是一個選項子句當你以排序方式來顯示資料(正向由小到大反向由大到小)以指定的欄位資料做排序

ASC = 正向- 預設值 DESC = 反向排序

For example

SELECT employee_id dept name age salary FROM employee_info WHERE dept = Sales ORDER BY salary

以上列出公司代號公司名銷售員人名年紀及薪資而條件是公司名為 Sales 顯示順序以薪資多少排序(由小到大為預設值)

如果要以多個欄位做排序要以逗號做分隔如下

SELECT employee_id dept name age salary FROM employee_info WHERE dept = Sales ORDER BY salary age DESC

85

結合條件及布林運算 SELECT column1 SUM(column2) FROM list-of-tables WHERE condition1 AND condition2 AND運算可以結兩個或以上的條件放在 WHERE子句中 兩者都要為真才

會顯示該筆記錄 OR 運算可以結兩個或以上敘述放在 WHERE子句中只要其中一個為直就

會顯示該筆記錄 For example SELECT employeeid firstname lastname title salary FROM employee_info WHERE salary gt= 5000000 AND title = Programmer 必需要薪資大於等於 50000而且職稱為 Programmer同時符合才會顯示該筆資料 以下以括號括住雖然不是必需的但如此比較容易讀 SELECT employeeid firstname lastname title salary FROM employee_info WHERE (salary gt= 5000000) AND (title = Programmer) 另外範例 SELECT firstname lastname title salary FROM employee_info WHERE (title = Sales) OR (title = Programmer) 條件為只要是 Sales 或 Programmer 職稱的就會被列出 IN and BETWEEN 子句

SELECT column1 SUM(column2) FROM list-of-tables WHERE column3 IN (list-of-values) SELECT column1 SUM(column2) FROM list-of-tables WHERE column3 BETWEEN value1 AND value2 IN 子句使用在列舉項目的使用上也就是分別測試是否符合所列的值 For example

86

SELECT employeeid lastname salary FROM employee_info WHERE lastname IN (Hernandez Jones Roberts Ruiz) 條件為姓氏(astname)要符合 Hernandez Jones Roberts or Ruiz 其中一個才會被傳回 IN運算元也可以使用 OR 的語法來取代如下結果相同 SELECT employeeid lastname salary FROM employee_info WHERE lastname = Hernandez OR lastname = Jones OR lastname = Roberts OR lastname = Ruiz 但使用 IN 句子比較短也比較易懂 你也可以使用 NOT IN 來去掉不要的記錄 BETWEEN 運算元使用在判斷是否存在兩個數值之間 For example SELECT employeeid age lastname salary FROM employee_info WHERE age BETWEEN 30 AND 40 傳回年紀 30歲到 40歲之間的資料(含 30及 40歲者) 相同的也可以使用以下語法來達到相同的結果 SELECT employeeid age lastname salary FROM employee_info WHERE age gt= 30 AND age lt= 40 你也可使用 NOT BETWEEN 來濾掉中間值的資料 數學運算 標準 ANSI SQL-92 提供以下運算

87

+ 加

- 減

餘數

餘數為除法後剩整數這不在標準的 ANSI SQL 中但大部份的資料庫都會支

援這運算元以下列出有用的函數雖不在 ANSI SQL-92 提供但一般資料庫

也會支援他們

ABS(x) 傳回 x 絕對值

SIGN(x) returns the sign of input x as -1 0 or 1 (negative zero or positive respectively)

MOD(xy) 餘數 - returns the integer remainder of x divided by y (同 xy)

FLOOR(x) 傳回小或等於 x 的最大整數值

CEILING(x) or CEIL(x)

傳回大或等於 x 的最小整數值

POWER(xy) x的 y 次方

ROUND(x) 把 x 四捨五入為整數

ROUND(xd) 四捨五入取到小數 d 位

SQRT(x) x 開平方

For example SELECT round(salary) firstname FROM employee_info 傳回薪資取到整數位

如何新增資料

insert 加入一筆新紀錄到資料表中 insert into tablename (first_columnlast_column) values (first_valuelast_value) [] = optional Example insert into employee

88

(first last age address city state) values (Luke Duke 45 2130 Boars Nest Hazard Co Georgia) Note 字串要以單引號住如string 數字框住也無妨 insert into 後面接資料表名稱再接以括號括住的欄位名在 values 後括號分別對映各欄位的值 以上的例子新增了一筆名(first) 為 Luke而住所(state) 為 Georgia 的資料

如何刪除資料

delete 可以刪除單筆或多筆紀錄 delete from tablename where columnname OPERATOR value [and|or column OPERATOR value] [ ] = optional Examples delete from employee Note 如果你沒有指定 where 子句那麼全部的紀錄都會被刪除 delete from employee where lastname = May delete from employee where firstname = Mike or firstname = Eric delete from 接著資料表名 再接著是條件式判斷沒有條件式則全部紀錄會

被刪除

如何更新資料

update 用來更新你所指定的記錄要和 WHERE 配合小心使用 語法 update tablename set columnname = newvalue[nextcolumn = newvalue2] where columnname OPERATOR value [and|or column OPERATOR value] [] = optional Examples

89

update phone_book set area_code = 623 where prefix = 979 update phone_book set last_name = Smith prefix=555 suffix=9292 where last_name = Jones update employee set age = age+1 where first_name=Mary and last_name=Williams

90

附錄二Replication

測試環境

RedHat 90 + MySQL 32358 MySQL資料庫路徑 varlibmysql MySQL設定檔 etcmycnf Master IP 1921680100 Slave IP 1921680200 請至下列網址下載最新MySQL 32358套件並利用rpm ndashUvh 更新 httpupdatesredhatcom9enosi386

圖 最新 MySQL 套件

測試架構圖

91

1921680100

1921680200Master Server

erveSlave S r

圖 測試架構圖

測試步驟

Master server 部份 Step1 確認 MasterSlave機器上所裝的 MySQL版本能進行

replication( 32329 or higher ) Step2 在 Master MySQL上開放一個帳號給 Slave mysql ndashu root ndashp mysqlgtGRANT FILE ON TO repl1921680200 IDENTIFIED BY lsquoabc123rsquo mysqlgtq 上面是 Master開放一個帳號 repl密碼 abc123給 IP1921680200有檔案處理

的權限 Step3 shutdown MySQL on the Master mysqladmin ndashu root ndashp shutdown Step4 備份 Master所有資料庫 tar ndashcvf tmpmysql-snapshottar varlibmysql 注意tar的時候MySQL是要在 stop情況下 在mysql (wwwmysqlcom) 網站的FAQ有不用shutdown的方法

92

Step5 在 master機器上修改etcmycnf 在[mysqld]區段內加入參數 log-bin server-id=這邊設定 server-id=1 sql-bin-update-same binlog-do-db=CRM只針對 CRM資料庫做紀錄 Step6 Restart MySQL on the master service mysqld start 此時因為有加入 log-bin 參數因此開始有 index產生了在varlibmysql目錄下

有index檔案紀錄資料庫的異動 log Slave server 部份 Step1 在 slave設定etcmycnf 在[mysqld]區段加入 master-host= master-user= master-password= master-port= server-id= 這邊設定 master-host=1921680100 master-user=repl master-password=abc123 master-port=3306 server-id=2 master-connect-retry=60預設重試間隔 60秒 replicate-do-db=CRM告訴 slave只做 CRM資料庫的更新 log-slave-updates Step2 將 master上的 mysql-snapshottar copy到 slave上 用 ftp傳到 slave的tmp Step3 解壓縮 Master資料庫至 Slave Server上 cd varlib tar xvf tmpmysql-snapshottar chown ndashR mysqlmysql mysql

93

chmod ndashR 770 mysql (視情況) Step4 Restart MySQL on the slave server 這時在varlibmysql目錄會出現 masterinfo此檔案紀錄了 Master MySQL server的資訊

狀況測試

One-way replication

1921680100

1921680200Master Server

erveSlave S r

圖 One-way replication架構圖 Step1 Master跟 Slave網路及服務都正常情況下由 Master端異動資料後 到 Slave端瀏覽資料檢視是否有進行 replication Step2 模擬 Slave Server 當機 可用在於 slave真的當機或是 Slave 不一定需要一直跟 master connect將Slave MySQL server shutdown由 Master端異動資料到 slave端瀏覽此時Slave應該沒有被 replication 更新然後再將 Slave端 MySQL server start起來

預設 60秒後 Slave會嘗試跟 Master要求進行 replication再去 Slave端檢視是否有更新資料

94

Step3 模擬 Master當機因為是設定 One-way replication一旦 Master Server Slave端沒有 Master的 source可以 download Two-way replication 基於 Master當機狀況於是發展雙向 Replication即 1921680100 ( Host A ) 1921680200 ( Host B )都分別擔任 MasterSlave身分

1921680100

1921680200er

Server B MasterSlave Server

Server A MasterSlave Serv

圖 Two-way replication架構圖 以下是針對兩台 MySQL伺服器進行雙向 Replication Step1觀念同單向 replication只是改成 Master也有 Slave身分 Slave也有Master的身分先分別在 Server AServer B 都去 grant一個進行 replication的身分 [A]mysqlgtGRANT FILE ON TO repl1921680200 IDENTIFIED BY lsquoabc123rsquo [B]mysqlgt GRANT FILE ON TO repl1921680100 IDENTIFIED BY lsquoabc123rsquo Step2做完單向 replication後stop Server Aserver B MySQL service此時 AB資料是一樣的

95

修改etcmycnf設定 範例 Server A [mysqld] datadir=varlibmysql socket=varlibmysqlmysqlsock server-id=1 log-bin sql-bin-update-same binlog-do-db=CRM master-host=1921680200 master-user=repl master-password=abc123 log-slave-updates master-connect-retry=60 replicate-do-db=CRM Server B [mysqld] datadir=varlibmysql socket=varlibmysqlmysqlsock server-id=2 log-bin sql-bin-update-same binlog-do-db=CRM master-host=1921680100 master-user=repl master-password=abc123 log-slave-updates master-connect-retry=60 replicate-do-db=CRM 分別 start Server AServer B MySQL後此時雙方都是 MasterSlave身分一旦哪一方資料異動就會通知對方來 replication-若 replication失效則必須將Server AServer B的masterinfo及index00x 都砍掉然後分別 restart MySQL server進行測試檢視成果 實務上通常如果需要做Two-way replication通常會搭配Virtual Server使用

96

在前端架設一台Virtual Server不過此部份不在此份SOP討論範圍內有興趣

的讀者可參考 httpwwwlinuxvirtualserverorg 網站

1921680100 1921680200

Host A MasterSlave Server

Host B MasterSlave Server

Virtual Host

圖 Virtual Server + Two-way replication 架構圖

97

圖 High Availability Linux Virtual Server架構圖

98

  • COSA-SOP-03-006
  • 第一章 簡介
    • 11適用對象 (Audience)
    • 12 MySQL本身
    • 13 MySQL 40版跟50版重大的改進功能
    • 14 各家資料庫軟體比較
      • 第二章 前置需求
      • 第三章 安裝
        • 31 MySQL安裝
        • 32 phpMyAdmin安裝
        • 33 升級及注意事項
          • 第四章 MySQL管理
            • 41 Webmin 管理介面
            • 42 phpMyAdmin 的操作介面
            • 43管理指令介紹
              • 431 利用mysqladmin設定root的密碼
                  • 第五章 實用範例
                    • 51 任務一Web Base客戶通訊錄
                    • 52 任務二Web Base群組軟體 ( twig )
                      • 第六章 維護及更新程序
                        • 61 日常維護
                        • 62 更新程序
                        • 63 備份重要檔案
                        • 64 離線備份與還原
                        • 65 線上備份與還原
                          • 第七章 問題與解答
                          • 第八章 參考資料
                          • 附錄一 SQL Command 介紹
                          • 附錄二Replication
Page 72: DataBase Server Standard Operation Procedureebooks.lib.ntu.edu.tw/1_file/oss/63/93doc4-5.pdf · 業務的公司帶來了不少壓力,譬如微軟,甲骨文 ... 外的錢用在第三方的資料庫產品上,譬如就可以不用再購買甲骨文公司

)

Step 3 利用 storephp 寫入圖片

storephp 程式碼

ltHTMLgt ltHEADgtltTITLEgtStore binary data into SQL DatabaseltTITLEgtltHEADgt ltBODYgt lt code that will be executed if the form has been submitted

if ($submit) mysql_connect(localhostrootYOUR_PASSWORD) mysql_select_db(test) $data=Base64_Encode(fread(fopen($form_data r) filesize($form_data))) $result=MYSQL_QUERY(INSERT INTO binary_data (descriptionbin_datafilenamefilesizefiletype) VALUES ($form_description$data$form_data_name$form_data_size$form_data_type)) $id= mysql_insert_id() print ltpgtThis file has the following Database ID ltbgt$idltbgt MYSQL_CLOSE() else else show the form to submit new data

gt

ltform method=post action=ltphp echo $PHP_SELF gt enctype=multipartform-datagt File Descriptionltbrgt ltinput type=text name=form_description size=40gt ltINPUT TYPE=hidden name=MAX_FILE_SIZE value=4000000gt ltbrgtFile to uploadstore in databaseltbrgt ltinput type=file name=form_data size=40gt ltpgtltinput type=submit name=submit value=submitgt ltformgt lt

72

gt ltBODYgt ltHTMLgt

Step 3 利用 storephp 取出圖片

getdataphp 程式碼

lt Syntax getdataphp3id=ltidgt if($id) you may have to modify login information for your database server MYSQL_CONNECT(localhostrootYOUR_PASSWORD) mysql_select_db(test) $query = select bin_datafiletype from binary_data where id=$id $result = MYSQL_QUERY($query) $data = Base64_Decode(MYSQL_RESULT($result0bin_data)) $type = MYSQL_RESULT($result0filetype) Header( Content-type $type) echo $data gt

Q6MySQL裝好之後啟動時或是執行 mysqladmin會出現如下訊息 Cant connect to local MYSQL Server through Socket varlibmysqlmysqlsock或是

Cant connect to local MYSQL Server through Socket tmpmysqldsock

Ans 可能有下列幾個原因

1這個 mysqldsock 不見了被某人刪除了或是被一些系統自動執行程式給刪

了例如有些 cron任務便會設定定期刪除 tmp 裡的東西所以呢您只能修改

cron 裡的設定讓它不要清除 mysqldsock 2在啟動時也可以改變 mysqldsock的位置您在啟動 MySQL的時候可以加入此參數usrlocalmysqlbinsafe_mysqld --user=mysql --socket=其他路

徑socket amp 同時得去設定環境變數 MYSQL_UNIX_PORT的值以指定新的

73

路徑 3若是您沒改 MYSQL_UNIX_PORT的值那麼您可以在執行指令的時候才打

例如mysqladmin --socket=其他路徑socket version Q7How to get the last insert id Ans CREATE TABLE product ( id INT(4) NOT NULL AUTO_INCREMENT PRIMARY KEY description VARCHAR(50) ) 1利用 SQL的話 mysqlgt insert into product(description) values(123) Query OK 1 row affected (000 sec) mysqlgt select last_insert_id() +------------------+ | last_insert_id() | +------------------+ +------------------+ 1 row in set (000 sec) ======================================== 2如果是 PHP的話 你可以用mysql_insert_id()取得該 id PHP example $result=MYSQL_QUERY(INSERT INTO product (description) VALUES ($description)) $id= mysql_insert_id() print This file has the following Database ID $id Q8如何將文字檔匯入資料庫 Ans $addr=homehttpdhtmlphpschool001txt $sql_select = load data infile $addr into table test fields terminated by t 解說 $sql_select = load data infile 文字檔名 into table 表格名 fields terminated by

74

t

(欄位分隔以 TAB鍵) 該文字檔須與資料表欄位格式相符 例如欄位有三個 則文字檔為每行一筆資料如下 欄 1資料ltTABgt欄 2資料ltTABgt欄 3資料 欄 1資料ltTABgt欄 2資料ltTABgt欄 3資料 欄 1資料ltTABgt欄 2資料ltTABgt欄 3資料 欄 1資料ltTABgtltTABgt欄 3資料

Q9如何撰寫 MySQL C API Ans Step 1利用文字編輯器撰寫以下程式碼 mysqlcc

include ltstdiohgt

include ltmysqlmysqlhgt

int main (int argc char argv[])

MYSQL mysql

MYSQL_RES res

MYSQL_ROW row

if (argc = 2)

fputs (Usage myc ltdatabasegt stderr)

return 1

if ((mysql_connect(ampmysqllocalhostrootYour_Password)))

fputs (Error connecting stderr)

abort()

75

if (mysql_select_db(ampmysqlargv[1]))

fputs (Error selecting database stderr)

abort()

if (mysql_query(ampmysqlSELECT FROM test_table))

fputs (Error processing query stderr)

abort()

if ((res = mysql_store_result(ampmysql)))

fputs (Error storing results stderr)

abort()

while((row = mysql_fetch_row(res)))

uint i = 0

for (i=0 i lt mysql_num_fields(res) i++)

printf(s row[i])

printf(n)

return 0

Step 2 Compile

gcc -Iusrlocalmysqlinclude -Lusrlocalmysqllibmysql mysqlcc ndashlm -lmysqlclient

(其中 include path與 library path取決於你的 MySQL安裝路徑)

76

如果執行時發生如下 error Run problemerror in loading shared libraries libmysqlclientsoX 將你的 MySQL library path(for exampleusrlocalmysqllibmysql) 加入etcldsoconf and run sbinldconfig -v Q9ASP + MySQL 範例程式 Ans Dim myconn As New ADODBConnection Dim myrs As New Recordset Dim mySQL As String Dim myrows As Long myconnOpen DSN=MyODBCsample mySQL = SELECT from user myrsSource = mySQL Set myrsActiveConnection = myconn myrsCursorLocation = adUseClient myrsOpen myrows = myrsRecordCount myrsClose myconnClose 可參考 httpwwwdwamnetmysqlasp_myodbcasp 有詳細的資料 Q10如何將 MySQL中的資料庫匯出成txt檔 Ans select from TableName into outfile textxls all result fields will seperate by tab

77

第八章 參考資料

英文部份 網址 1 httpwwwmysqlcom MySQL 網站有第一手有關 MySQL的資料 2 httpwwwmysqlcomdocenReplicationhtml 有關 MySQL Replication 的文件 3 httpwwwgeocitiescomsqlhomefaqstore_blobhtml 如何在 MySQL 存放 BLOB的資料 4httpwwwsapdborg 有關 SAP跟 MySQL相關合作的網站 書藉 1 Cooking with MySQL

Paul DuBois has selected sample recipes from the hundreds youll find in his book MySQL

Cookbook In this third and final series of excerpts showcasing these recipes learn how to

compute team standings how to calculate the differences between successive Dec 26

2002 2 Tips for Building Web Database Applications with PHP and MySQL by Hugh E Williams co-author of Web Database Applications with PHP amp MySQL 04042002

3 Managing and Using MySQL 2nd Edition By Tim King George Reese Randy Jay Yarger

4 MySQL Cookbook By Paul DuBoisPublisher OReillyPub Date October 2002

中文部份

78

1 httplinuxtncedutwtechdocmysqlmysql_docmanual_tochtml MySQL 中文手冊 2 httpchenshloxaedutwphpZ_1php PHP+MySQ程式研習設計網站 3 httplinuxtncedutwtechdocbanicdownhtml PHP 4 手冊 4 httpwwwtncedutwadmin_zonephp台南縣教育網網路中心有很多 Linux相關文件 5 httpdobtncedutw網站建置百寶箱有很多 PHP MySQL 相關範例程式 5 httpwwwdbworldcomtw資料庫專家電子雜誌介紹資料庫的重要觀念及名詞

79

附錄一 SQL Command 介紹

SQL (讀音ess-que-el) 是一種結構查詢語法SQL 使用於資料庫交流

傳遞相容於 ANSI (American National Standards Institute) 是一套標準的關聯

式資料庫語言 SQL 語言是執行更新或從資料系統獲取資料一般常見的關聯

資料庫系統都有提供 SQL 如 Oracle Sybase Microsoft SQL Server Access Ingres 等雖然大部份的資料庫都有提供 SQL 但也多提供了自已獨特的語

法造成了不相容的情形但標準基本的語法是相通的如Select Insert Update Delete Create and Drop 每一個系統都有支援

Table相關 Command

Create Table

關聯式資料庫包含有很多元件稱為資料表(tables) 把資料或訊息放在資

料表中 資料表是以不同的名稱做分別資料表由欄列所構成的二維陣列

欄包含欄位名資料型態 及其他可判斷的資訊列是由全部欄位構成一筆一

筆的紀錄 create table 語法用在建立一個新的資料表語法格式如下

create table tablename (column1 data type column2 data type column3 data type)

Format of create table if you were to use optional constraints

create table tablename (column1 data type [constraint] column2 data type [constraint] column3 data type [constraint]) [ ] = optional

Note You may have as many columns as youd like and the constraints are optional

80

Example

create table employee (first varchar(15) last varchar(20) age number(3) address varchar(30) city varchar(20) state varchar(20))

注意建立資料表格式要以括號把前後框住而最後以(分號)做結尾

欄位名不要超過 30個字元長而且不要使用 sql 的關鍵字(如 where select等)而在後面接是型態的宣告(如字串數字日期格式等)

資料型態是來描述欄位的方式如一個欄位Last_Name 是一個姓氏可以使用varchar (可變動長度字串) 資料型態

以下是幾個常見的資料庫型態 char(size) 固定長度字串最長為 255 位元 varchar(size) 變動長度字串最大字元數以 size 來指定 number(size) 數值格式可以是整數也可以是小數最大數字以 size 位數判

斷未指定小數位數由系統內定 date 日期格式 number(sized) 數值格式最大數字以 size 位數判斷d 為小數位數整數位

數為 size-d 位

有何限制當資料表被建立通常有一或數個欄位是要使用來做關聯的功

能 例如unique 限制(唯一值)兩筆記錄不可以相同的值 not null (非空值)該欄位一定要輸入資料不可是空的primary key (主鍵)是每一筆記錄識別的主要方式

Drop a table drop table 刪除資料表(其中的資料也會一併刪除)

drop table tablename

Example

81

drop table 和刪除全部資料是不同的刪除全部資料欄位名稱資訊等還會

存在但刪除資料表會把這一些也一併移除掉

如何查詢資料

Select 基本用法

select 語法是關連式資料庫最常用的部份可以取得你想要的資料這是一個

簡單的範例 select column1[column2etc] from tablename [where condition] [] = optional 在 select 之後所列欄位名則是要顯示的資料部份你可以一一列出各欄位

名或是以 (星號)來代表選擇全部的欄位 from 之後放資料表名稱 where 子句 (選項) 指定要過濾的條件符合者才會顯現 where 可使用的條件運算元 = 等於 gt 大於 lt 小於 gt= 大或等於 lt= 小或等於 ltgt 大相等 LIKE 相似 For example select first last city

82

from empinfo where first LIKE Er 以Er 為開頭的字串就符合要以單引號框住 Or you can specify select first last from empinfo where last LIKE s 最後一字為 S 就符合 select from empinfo where first = Eric 則表示 first name 一定要是 Eric 才可以 範例資料表empinfo 統計函數

MIN 傳回指定欄位最小值

MAX 傳回指定欄位最大值

SUM 傳回指定欄位總和

AVG 傳回指定欄位平均值

COUNT 傳回指定欄位的筆數

COUNT() 傳回資料庫中的總筆數

統計函數使用於資料表中的數值欄位配合 SELECT 語法使用 只用於總結特定單一欄位可以配合 GROUP BY 做篩選但也可以不使用 GROUP BY 語句For example

SELECT AVG(salary) FROM employee

83

傳回全部 salary 平均值

Another example

SELECT AVG(salary) FROM employee WHERE title = Programmer

傳回 salary 平均值條件為 employees 資料表中當 title 等於 Programmer

Example

SELECT Count() FROM employees

傳回 employees 資料表中紀錄總筆數

GROUP BY 語法 SELECT column1 SUM(column2) FROM list-of-tables GROUP BY column-list The GROUP BY 語句可以先以所列的欄位為條件分組排序在一起(可以多欄

位) example 要列出每一個 dept 中最高 salary 值 SELECT max(salary) dept FROM employee GROUP BY dept HAVING 語法

SELECT column1 SUM(column2) FROM list-of-tables GROUP BY column-list HAVING condition

HAVING 子句是 GROUP BY 的一部份用來過濾在 GROUP BY 所選出的資料功能如同 select 命令中 where 條件式一樣只是 HAVING 必需配合 GROUP BY 使用

我們以例子來說明我們要取得每一公司名及每一公司的薪水平均值輸入如下

84

SELECT dept avg(salary) FROM employee GROUP BY dept

但如果我們只列出薪資平均值超過 20000元的公司資料

SELECT dept avg(salary) FROM employee GROUP BY dept HAVING avg(salary) gt 20000

ORDER BY子句語法

SELECT column1 SUM(column2) FROM list-of-tables ORDER BY column-list [ASC | DESC]

[ ] =選項

ORDER BY是一個選項子句當你以排序方式來顯示資料(正向由小到大反向由大到小)以指定的欄位資料做排序

ASC = 正向- 預設值 DESC = 反向排序

For example

SELECT employee_id dept name age salary FROM employee_info WHERE dept = Sales ORDER BY salary

以上列出公司代號公司名銷售員人名年紀及薪資而條件是公司名為 Sales 顯示順序以薪資多少排序(由小到大為預設值)

如果要以多個欄位做排序要以逗號做分隔如下

SELECT employee_id dept name age salary FROM employee_info WHERE dept = Sales ORDER BY salary age DESC

85

結合條件及布林運算 SELECT column1 SUM(column2) FROM list-of-tables WHERE condition1 AND condition2 AND運算可以結兩個或以上的條件放在 WHERE子句中 兩者都要為真才

會顯示該筆記錄 OR 運算可以結兩個或以上敘述放在 WHERE子句中只要其中一個為直就

會顯示該筆記錄 For example SELECT employeeid firstname lastname title salary FROM employee_info WHERE salary gt= 5000000 AND title = Programmer 必需要薪資大於等於 50000而且職稱為 Programmer同時符合才會顯示該筆資料 以下以括號括住雖然不是必需的但如此比較容易讀 SELECT employeeid firstname lastname title salary FROM employee_info WHERE (salary gt= 5000000) AND (title = Programmer) 另外範例 SELECT firstname lastname title salary FROM employee_info WHERE (title = Sales) OR (title = Programmer) 條件為只要是 Sales 或 Programmer 職稱的就會被列出 IN and BETWEEN 子句

SELECT column1 SUM(column2) FROM list-of-tables WHERE column3 IN (list-of-values) SELECT column1 SUM(column2) FROM list-of-tables WHERE column3 BETWEEN value1 AND value2 IN 子句使用在列舉項目的使用上也就是分別測試是否符合所列的值 For example

86

SELECT employeeid lastname salary FROM employee_info WHERE lastname IN (Hernandez Jones Roberts Ruiz) 條件為姓氏(astname)要符合 Hernandez Jones Roberts or Ruiz 其中一個才會被傳回 IN運算元也可以使用 OR 的語法來取代如下結果相同 SELECT employeeid lastname salary FROM employee_info WHERE lastname = Hernandez OR lastname = Jones OR lastname = Roberts OR lastname = Ruiz 但使用 IN 句子比較短也比較易懂 你也可以使用 NOT IN 來去掉不要的記錄 BETWEEN 運算元使用在判斷是否存在兩個數值之間 For example SELECT employeeid age lastname salary FROM employee_info WHERE age BETWEEN 30 AND 40 傳回年紀 30歲到 40歲之間的資料(含 30及 40歲者) 相同的也可以使用以下語法來達到相同的結果 SELECT employeeid age lastname salary FROM employee_info WHERE age gt= 30 AND age lt= 40 你也可使用 NOT BETWEEN 來濾掉中間值的資料 數學運算 標準 ANSI SQL-92 提供以下運算

87

+ 加

- 減

餘數

餘數為除法後剩整數這不在標準的 ANSI SQL 中但大部份的資料庫都會支

援這運算元以下列出有用的函數雖不在 ANSI SQL-92 提供但一般資料庫

也會支援他們

ABS(x) 傳回 x 絕對值

SIGN(x) returns the sign of input x as -1 0 or 1 (negative zero or positive respectively)

MOD(xy) 餘數 - returns the integer remainder of x divided by y (同 xy)

FLOOR(x) 傳回小或等於 x 的最大整數值

CEILING(x) or CEIL(x)

傳回大或等於 x 的最小整數值

POWER(xy) x的 y 次方

ROUND(x) 把 x 四捨五入為整數

ROUND(xd) 四捨五入取到小數 d 位

SQRT(x) x 開平方

For example SELECT round(salary) firstname FROM employee_info 傳回薪資取到整數位

如何新增資料

insert 加入一筆新紀錄到資料表中 insert into tablename (first_columnlast_column) values (first_valuelast_value) [] = optional Example insert into employee

88

(first last age address city state) values (Luke Duke 45 2130 Boars Nest Hazard Co Georgia) Note 字串要以單引號住如string 數字框住也無妨 insert into 後面接資料表名稱再接以括號括住的欄位名在 values 後括號分別對映各欄位的值 以上的例子新增了一筆名(first) 為 Luke而住所(state) 為 Georgia 的資料

如何刪除資料

delete 可以刪除單筆或多筆紀錄 delete from tablename where columnname OPERATOR value [and|or column OPERATOR value] [ ] = optional Examples delete from employee Note 如果你沒有指定 where 子句那麼全部的紀錄都會被刪除 delete from employee where lastname = May delete from employee where firstname = Mike or firstname = Eric delete from 接著資料表名 再接著是條件式判斷沒有條件式則全部紀錄會

被刪除

如何更新資料

update 用來更新你所指定的記錄要和 WHERE 配合小心使用 語法 update tablename set columnname = newvalue[nextcolumn = newvalue2] where columnname OPERATOR value [and|or column OPERATOR value] [] = optional Examples

89

update phone_book set area_code = 623 where prefix = 979 update phone_book set last_name = Smith prefix=555 suffix=9292 where last_name = Jones update employee set age = age+1 where first_name=Mary and last_name=Williams

90

附錄二Replication

測試環境

RedHat 90 + MySQL 32358 MySQL資料庫路徑 varlibmysql MySQL設定檔 etcmycnf Master IP 1921680100 Slave IP 1921680200 請至下列網址下載最新MySQL 32358套件並利用rpm ndashUvh 更新 httpupdatesredhatcom9enosi386

圖 最新 MySQL 套件

測試架構圖

91

1921680100

1921680200Master Server

erveSlave S r

圖 測試架構圖

測試步驟

Master server 部份 Step1 確認 MasterSlave機器上所裝的 MySQL版本能進行

replication( 32329 or higher ) Step2 在 Master MySQL上開放一個帳號給 Slave mysql ndashu root ndashp mysqlgtGRANT FILE ON TO repl1921680200 IDENTIFIED BY lsquoabc123rsquo mysqlgtq 上面是 Master開放一個帳號 repl密碼 abc123給 IP1921680200有檔案處理

的權限 Step3 shutdown MySQL on the Master mysqladmin ndashu root ndashp shutdown Step4 備份 Master所有資料庫 tar ndashcvf tmpmysql-snapshottar varlibmysql 注意tar的時候MySQL是要在 stop情況下 在mysql (wwwmysqlcom) 網站的FAQ有不用shutdown的方法

92

Step5 在 master機器上修改etcmycnf 在[mysqld]區段內加入參數 log-bin server-id=這邊設定 server-id=1 sql-bin-update-same binlog-do-db=CRM只針對 CRM資料庫做紀錄 Step6 Restart MySQL on the master service mysqld start 此時因為有加入 log-bin 參數因此開始有 index產生了在varlibmysql目錄下

有index檔案紀錄資料庫的異動 log Slave server 部份 Step1 在 slave設定etcmycnf 在[mysqld]區段加入 master-host= master-user= master-password= master-port= server-id= 這邊設定 master-host=1921680100 master-user=repl master-password=abc123 master-port=3306 server-id=2 master-connect-retry=60預設重試間隔 60秒 replicate-do-db=CRM告訴 slave只做 CRM資料庫的更新 log-slave-updates Step2 將 master上的 mysql-snapshottar copy到 slave上 用 ftp傳到 slave的tmp Step3 解壓縮 Master資料庫至 Slave Server上 cd varlib tar xvf tmpmysql-snapshottar chown ndashR mysqlmysql mysql

93

chmod ndashR 770 mysql (視情況) Step4 Restart MySQL on the slave server 這時在varlibmysql目錄會出現 masterinfo此檔案紀錄了 Master MySQL server的資訊

狀況測試

One-way replication

1921680100

1921680200Master Server

erveSlave S r

圖 One-way replication架構圖 Step1 Master跟 Slave網路及服務都正常情況下由 Master端異動資料後 到 Slave端瀏覽資料檢視是否有進行 replication Step2 模擬 Slave Server 當機 可用在於 slave真的當機或是 Slave 不一定需要一直跟 master connect將Slave MySQL server shutdown由 Master端異動資料到 slave端瀏覽此時Slave應該沒有被 replication 更新然後再將 Slave端 MySQL server start起來

預設 60秒後 Slave會嘗試跟 Master要求進行 replication再去 Slave端檢視是否有更新資料

94

Step3 模擬 Master當機因為是設定 One-way replication一旦 Master Server Slave端沒有 Master的 source可以 download Two-way replication 基於 Master當機狀況於是發展雙向 Replication即 1921680100 ( Host A ) 1921680200 ( Host B )都分別擔任 MasterSlave身分

1921680100

1921680200er

Server B MasterSlave Server

Server A MasterSlave Serv

圖 Two-way replication架構圖 以下是針對兩台 MySQL伺服器進行雙向 Replication Step1觀念同單向 replication只是改成 Master也有 Slave身分 Slave也有Master的身分先分別在 Server AServer B 都去 grant一個進行 replication的身分 [A]mysqlgtGRANT FILE ON TO repl1921680200 IDENTIFIED BY lsquoabc123rsquo [B]mysqlgt GRANT FILE ON TO repl1921680100 IDENTIFIED BY lsquoabc123rsquo Step2做完單向 replication後stop Server Aserver B MySQL service此時 AB資料是一樣的

95

修改etcmycnf設定 範例 Server A [mysqld] datadir=varlibmysql socket=varlibmysqlmysqlsock server-id=1 log-bin sql-bin-update-same binlog-do-db=CRM master-host=1921680200 master-user=repl master-password=abc123 log-slave-updates master-connect-retry=60 replicate-do-db=CRM Server B [mysqld] datadir=varlibmysql socket=varlibmysqlmysqlsock server-id=2 log-bin sql-bin-update-same binlog-do-db=CRM master-host=1921680100 master-user=repl master-password=abc123 log-slave-updates master-connect-retry=60 replicate-do-db=CRM 分別 start Server AServer B MySQL後此時雙方都是 MasterSlave身分一旦哪一方資料異動就會通知對方來 replication-若 replication失效則必須將Server AServer B的masterinfo及index00x 都砍掉然後分別 restart MySQL server進行測試檢視成果 實務上通常如果需要做Two-way replication通常會搭配Virtual Server使用

96

在前端架設一台Virtual Server不過此部份不在此份SOP討論範圍內有興趣

的讀者可參考 httpwwwlinuxvirtualserverorg 網站

1921680100 1921680200

Host A MasterSlave Server

Host B MasterSlave Server

Virtual Host

圖 Virtual Server + Two-way replication 架構圖

97

圖 High Availability Linux Virtual Server架構圖

98

  • COSA-SOP-03-006
  • 第一章 簡介
    • 11適用對象 (Audience)
    • 12 MySQL本身
    • 13 MySQL 40版跟50版重大的改進功能
    • 14 各家資料庫軟體比較
      • 第二章 前置需求
      • 第三章 安裝
        • 31 MySQL安裝
        • 32 phpMyAdmin安裝
        • 33 升級及注意事項
          • 第四章 MySQL管理
            • 41 Webmin 管理介面
            • 42 phpMyAdmin 的操作介面
            • 43管理指令介紹
              • 431 利用mysqladmin設定root的密碼
                  • 第五章 實用範例
                    • 51 任務一Web Base客戶通訊錄
                    • 52 任務二Web Base群組軟體 ( twig )
                      • 第六章 維護及更新程序
                        • 61 日常維護
                        • 62 更新程序
                        • 63 備份重要檔案
                        • 64 離線備份與還原
                        • 65 線上備份與還原
                          • 第七章 問題與解答
                          • 第八章 參考資料
                          • 附錄一 SQL Command 介紹
                          • 附錄二Replication
Page 73: DataBase Server Standard Operation Procedureebooks.lib.ntu.edu.tw/1_file/oss/63/93doc4-5.pdf · 業務的公司帶來了不少壓力,譬如微軟,甲骨文 ... 外的錢用在第三方的資料庫產品上,譬如就可以不用再購買甲骨文公司

gt ltBODYgt ltHTMLgt

Step 3 利用 storephp 取出圖片

getdataphp 程式碼

lt Syntax getdataphp3id=ltidgt if($id) you may have to modify login information for your database server MYSQL_CONNECT(localhostrootYOUR_PASSWORD) mysql_select_db(test) $query = select bin_datafiletype from binary_data where id=$id $result = MYSQL_QUERY($query) $data = Base64_Decode(MYSQL_RESULT($result0bin_data)) $type = MYSQL_RESULT($result0filetype) Header( Content-type $type) echo $data gt

Q6MySQL裝好之後啟動時或是執行 mysqladmin會出現如下訊息 Cant connect to local MYSQL Server through Socket varlibmysqlmysqlsock或是

Cant connect to local MYSQL Server through Socket tmpmysqldsock

Ans 可能有下列幾個原因

1這個 mysqldsock 不見了被某人刪除了或是被一些系統自動執行程式給刪

了例如有些 cron任務便會設定定期刪除 tmp 裡的東西所以呢您只能修改

cron 裡的設定讓它不要清除 mysqldsock 2在啟動時也可以改變 mysqldsock的位置您在啟動 MySQL的時候可以加入此參數usrlocalmysqlbinsafe_mysqld --user=mysql --socket=其他路

徑socket amp 同時得去設定環境變數 MYSQL_UNIX_PORT的值以指定新的

73

路徑 3若是您沒改 MYSQL_UNIX_PORT的值那麼您可以在執行指令的時候才打

例如mysqladmin --socket=其他路徑socket version Q7How to get the last insert id Ans CREATE TABLE product ( id INT(4) NOT NULL AUTO_INCREMENT PRIMARY KEY description VARCHAR(50) ) 1利用 SQL的話 mysqlgt insert into product(description) values(123) Query OK 1 row affected (000 sec) mysqlgt select last_insert_id() +------------------+ | last_insert_id() | +------------------+ +------------------+ 1 row in set (000 sec) ======================================== 2如果是 PHP的話 你可以用mysql_insert_id()取得該 id PHP example $result=MYSQL_QUERY(INSERT INTO product (description) VALUES ($description)) $id= mysql_insert_id() print This file has the following Database ID $id Q8如何將文字檔匯入資料庫 Ans $addr=homehttpdhtmlphpschool001txt $sql_select = load data infile $addr into table test fields terminated by t 解說 $sql_select = load data infile 文字檔名 into table 表格名 fields terminated by

74

t

(欄位分隔以 TAB鍵) 該文字檔須與資料表欄位格式相符 例如欄位有三個 則文字檔為每行一筆資料如下 欄 1資料ltTABgt欄 2資料ltTABgt欄 3資料 欄 1資料ltTABgt欄 2資料ltTABgt欄 3資料 欄 1資料ltTABgt欄 2資料ltTABgt欄 3資料 欄 1資料ltTABgtltTABgt欄 3資料

Q9如何撰寫 MySQL C API Ans Step 1利用文字編輯器撰寫以下程式碼 mysqlcc

include ltstdiohgt

include ltmysqlmysqlhgt

int main (int argc char argv[])

MYSQL mysql

MYSQL_RES res

MYSQL_ROW row

if (argc = 2)

fputs (Usage myc ltdatabasegt stderr)

return 1

if ((mysql_connect(ampmysqllocalhostrootYour_Password)))

fputs (Error connecting stderr)

abort()

75

if (mysql_select_db(ampmysqlargv[1]))

fputs (Error selecting database stderr)

abort()

if (mysql_query(ampmysqlSELECT FROM test_table))

fputs (Error processing query stderr)

abort()

if ((res = mysql_store_result(ampmysql)))

fputs (Error storing results stderr)

abort()

while((row = mysql_fetch_row(res)))

uint i = 0

for (i=0 i lt mysql_num_fields(res) i++)

printf(s row[i])

printf(n)

return 0

Step 2 Compile

gcc -Iusrlocalmysqlinclude -Lusrlocalmysqllibmysql mysqlcc ndashlm -lmysqlclient

(其中 include path與 library path取決於你的 MySQL安裝路徑)

76

如果執行時發生如下 error Run problemerror in loading shared libraries libmysqlclientsoX 將你的 MySQL library path(for exampleusrlocalmysqllibmysql) 加入etcldsoconf and run sbinldconfig -v Q9ASP + MySQL 範例程式 Ans Dim myconn As New ADODBConnection Dim myrs As New Recordset Dim mySQL As String Dim myrows As Long myconnOpen DSN=MyODBCsample mySQL = SELECT from user myrsSource = mySQL Set myrsActiveConnection = myconn myrsCursorLocation = adUseClient myrsOpen myrows = myrsRecordCount myrsClose myconnClose 可參考 httpwwwdwamnetmysqlasp_myodbcasp 有詳細的資料 Q10如何將 MySQL中的資料庫匯出成txt檔 Ans select from TableName into outfile textxls all result fields will seperate by tab

77

第八章 參考資料

英文部份 網址 1 httpwwwmysqlcom MySQL 網站有第一手有關 MySQL的資料 2 httpwwwmysqlcomdocenReplicationhtml 有關 MySQL Replication 的文件 3 httpwwwgeocitiescomsqlhomefaqstore_blobhtml 如何在 MySQL 存放 BLOB的資料 4httpwwwsapdborg 有關 SAP跟 MySQL相關合作的網站 書藉 1 Cooking with MySQL

Paul DuBois has selected sample recipes from the hundreds youll find in his book MySQL

Cookbook In this third and final series of excerpts showcasing these recipes learn how to

compute team standings how to calculate the differences between successive Dec 26

2002 2 Tips for Building Web Database Applications with PHP and MySQL by Hugh E Williams co-author of Web Database Applications with PHP amp MySQL 04042002

3 Managing and Using MySQL 2nd Edition By Tim King George Reese Randy Jay Yarger

4 MySQL Cookbook By Paul DuBoisPublisher OReillyPub Date October 2002

中文部份

78

1 httplinuxtncedutwtechdocmysqlmysql_docmanual_tochtml MySQL 中文手冊 2 httpchenshloxaedutwphpZ_1php PHP+MySQ程式研習設計網站 3 httplinuxtncedutwtechdocbanicdownhtml PHP 4 手冊 4 httpwwwtncedutwadmin_zonephp台南縣教育網網路中心有很多 Linux相關文件 5 httpdobtncedutw網站建置百寶箱有很多 PHP MySQL 相關範例程式 5 httpwwwdbworldcomtw資料庫專家電子雜誌介紹資料庫的重要觀念及名詞

79

附錄一 SQL Command 介紹

SQL (讀音ess-que-el) 是一種結構查詢語法SQL 使用於資料庫交流

傳遞相容於 ANSI (American National Standards Institute) 是一套標準的關聯

式資料庫語言 SQL 語言是執行更新或從資料系統獲取資料一般常見的關聯

資料庫系統都有提供 SQL 如 Oracle Sybase Microsoft SQL Server Access Ingres 等雖然大部份的資料庫都有提供 SQL 但也多提供了自已獨特的語

法造成了不相容的情形但標準基本的語法是相通的如Select Insert Update Delete Create and Drop 每一個系統都有支援

Table相關 Command

Create Table

關聯式資料庫包含有很多元件稱為資料表(tables) 把資料或訊息放在資

料表中 資料表是以不同的名稱做分別資料表由欄列所構成的二維陣列

欄包含欄位名資料型態 及其他可判斷的資訊列是由全部欄位構成一筆一

筆的紀錄 create table 語法用在建立一個新的資料表語法格式如下

create table tablename (column1 data type column2 data type column3 data type)

Format of create table if you were to use optional constraints

create table tablename (column1 data type [constraint] column2 data type [constraint] column3 data type [constraint]) [ ] = optional

Note You may have as many columns as youd like and the constraints are optional

80

Example

create table employee (first varchar(15) last varchar(20) age number(3) address varchar(30) city varchar(20) state varchar(20))

注意建立資料表格式要以括號把前後框住而最後以(分號)做結尾

欄位名不要超過 30個字元長而且不要使用 sql 的關鍵字(如 where select等)而在後面接是型態的宣告(如字串數字日期格式等)

資料型態是來描述欄位的方式如一個欄位Last_Name 是一個姓氏可以使用varchar (可變動長度字串) 資料型態

以下是幾個常見的資料庫型態 char(size) 固定長度字串最長為 255 位元 varchar(size) 變動長度字串最大字元數以 size 來指定 number(size) 數值格式可以是整數也可以是小數最大數字以 size 位數判

斷未指定小數位數由系統內定 date 日期格式 number(sized) 數值格式最大數字以 size 位數判斷d 為小數位數整數位

數為 size-d 位

有何限制當資料表被建立通常有一或數個欄位是要使用來做關聯的功

能 例如unique 限制(唯一值)兩筆記錄不可以相同的值 not null (非空值)該欄位一定要輸入資料不可是空的primary key (主鍵)是每一筆記錄識別的主要方式

Drop a table drop table 刪除資料表(其中的資料也會一併刪除)

drop table tablename

Example

81

drop table 和刪除全部資料是不同的刪除全部資料欄位名稱資訊等還會

存在但刪除資料表會把這一些也一併移除掉

如何查詢資料

Select 基本用法

select 語法是關連式資料庫最常用的部份可以取得你想要的資料這是一個

簡單的範例 select column1[column2etc] from tablename [where condition] [] = optional 在 select 之後所列欄位名則是要顯示的資料部份你可以一一列出各欄位

名或是以 (星號)來代表選擇全部的欄位 from 之後放資料表名稱 where 子句 (選項) 指定要過濾的條件符合者才會顯現 where 可使用的條件運算元 = 等於 gt 大於 lt 小於 gt= 大或等於 lt= 小或等於 ltgt 大相等 LIKE 相似 For example select first last city

82

from empinfo where first LIKE Er 以Er 為開頭的字串就符合要以單引號框住 Or you can specify select first last from empinfo where last LIKE s 最後一字為 S 就符合 select from empinfo where first = Eric 則表示 first name 一定要是 Eric 才可以 範例資料表empinfo 統計函數

MIN 傳回指定欄位最小值

MAX 傳回指定欄位最大值

SUM 傳回指定欄位總和

AVG 傳回指定欄位平均值

COUNT 傳回指定欄位的筆數

COUNT() 傳回資料庫中的總筆數

統計函數使用於資料表中的數值欄位配合 SELECT 語法使用 只用於總結特定單一欄位可以配合 GROUP BY 做篩選但也可以不使用 GROUP BY 語句For example

SELECT AVG(salary) FROM employee

83

傳回全部 salary 平均值

Another example

SELECT AVG(salary) FROM employee WHERE title = Programmer

傳回 salary 平均值條件為 employees 資料表中當 title 等於 Programmer

Example

SELECT Count() FROM employees

傳回 employees 資料表中紀錄總筆數

GROUP BY 語法 SELECT column1 SUM(column2) FROM list-of-tables GROUP BY column-list The GROUP BY 語句可以先以所列的欄位為條件分組排序在一起(可以多欄

位) example 要列出每一個 dept 中最高 salary 值 SELECT max(salary) dept FROM employee GROUP BY dept HAVING 語法

SELECT column1 SUM(column2) FROM list-of-tables GROUP BY column-list HAVING condition

HAVING 子句是 GROUP BY 的一部份用來過濾在 GROUP BY 所選出的資料功能如同 select 命令中 where 條件式一樣只是 HAVING 必需配合 GROUP BY 使用

我們以例子來說明我們要取得每一公司名及每一公司的薪水平均值輸入如下

84

SELECT dept avg(salary) FROM employee GROUP BY dept

但如果我們只列出薪資平均值超過 20000元的公司資料

SELECT dept avg(salary) FROM employee GROUP BY dept HAVING avg(salary) gt 20000

ORDER BY子句語法

SELECT column1 SUM(column2) FROM list-of-tables ORDER BY column-list [ASC | DESC]

[ ] =選項

ORDER BY是一個選項子句當你以排序方式來顯示資料(正向由小到大反向由大到小)以指定的欄位資料做排序

ASC = 正向- 預設值 DESC = 反向排序

For example

SELECT employee_id dept name age salary FROM employee_info WHERE dept = Sales ORDER BY salary

以上列出公司代號公司名銷售員人名年紀及薪資而條件是公司名為 Sales 顯示順序以薪資多少排序(由小到大為預設值)

如果要以多個欄位做排序要以逗號做分隔如下

SELECT employee_id dept name age salary FROM employee_info WHERE dept = Sales ORDER BY salary age DESC

85

結合條件及布林運算 SELECT column1 SUM(column2) FROM list-of-tables WHERE condition1 AND condition2 AND運算可以結兩個或以上的條件放在 WHERE子句中 兩者都要為真才

會顯示該筆記錄 OR 運算可以結兩個或以上敘述放在 WHERE子句中只要其中一個為直就

會顯示該筆記錄 For example SELECT employeeid firstname lastname title salary FROM employee_info WHERE salary gt= 5000000 AND title = Programmer 必需要薪資大於等於 50000而且職稱為 Programmer同時符合才會顯示該筆資料 以下以括號括住雖然不是必需的但如此比較容易讀 SELECT employeeid firstname lastname title salary FROM employee_info WHERE (salary gt= 5000000) AND (title = Programmer) 另外範例 SELECT firstname lastname title salary FROM employee_info WHERE (title = Sales) OR (title = Programmer) 條件為只要是 Sales 或 Programmer 職稱的就會被列出 IN and BETWEEN 子句

SELECT column1 SUM(column2) FROM list-of-tables WHERE column3 IN (list-of-values) SELECT column1 SUM(column2) FROM list-of-tables WHERE column3 BETWEEN value1 AND value2 IN 子句使用在列舉項目的使用上也就是分別測試是否符合所列的值 For example

86

SELECT employeeid lastname salary FROM employee_info WHERE lastname IN (Hernandez Jones Roberts Ruiz) 條件為姓氏(astname)要符合 Hernandez Jones Roberts or Ruiz 其中一個才會被傳回 IN運算元也可以使用 OR 的語法來取代如下結果相同 SELECT employeeid lastname salary FROM employee_info WHERE lastname = Hernandez OR lastname = Jones OR lastname = Roberts OR lastname = Ruiz 但使用 IN 句子比較短也比較易懂 你也可以使用 NOT IN 來去掉不要的記錄 BETWEEN 運算元使用在判斷是否存在兩個數值之間 For example SELECT employeeid age lastname salary FROM employee_info WHERE age BETWEEN 30 AND 40 傳回年紀 30歲到 40歲之間的資料(含 30及 40歲者) 相同的也可以使用以下語法來達到相同的結果 SELECT employeeid age lastname salary FROM employee_info WHERE age gt= 30 AND age lt= 40 你也可使用 NOT BETWEEN 來濾掉中間值的資料 數學運算 標準 ANSI SQL-92 提供以下運算

87

+ 加

- 減

餘數

餘數為除法後剩整數這不在標準的 ANSI SQL 中但大部份的資料庫都會支

援這運算元以下列出有用的函數雖不在 ANSI SQL-92 提供但一般資料庫

也會支援他們

ABS(x) 傳回 x 絕對值

SIGN(x) returns the sign of input x as -1 0 or 1 (negative zero or positive respectively)

MOD(xy) 餘數 - returns the integer remainder of x divided by y (同 xy)

FLOOR(x) 傳回小或等於 x 的最大整數值

CEILING(x) or CEIL(x)

傳回大或等於 x 的最小整數值

POWER(xy) x的 y 次方

ROUND(x) 把 x 四捨五入為整數

ROUND(xd) 四捨五入取到小數 d 位

SQRT(x) x 開平方

For example SELECT round(salary) firstname FROM employee_info 傳回薪資取到整數位

如何新增資料

insert 加入一筆新紀錄到資料表中 insert into tablename (first_columnlast_column) values (first_valuelast_value) [] = optional Example insert into employee

88

(first last age address city state) values (Luke Duke 45 2130 Boars Nest Hazard Co Georgia) Note 字串要以單引號住如string 數字框住也無妨 insert into 後面接資料表名稱再接以括號括住的欄位名在 values 後括號分別對映各欄位的值 以上的例子新增了一筆名(first) 為 Luke而住所(state) 為 Georgia 的資料

如何刪除資料

delete 可以刪除單筆或多筆紀錄 delete from tablename where columnname OPERATOR value [and|or column OPERATOR value] [ ] = optional Examples delete from employee Note 如果你沒有指定 where 子句那麼全部的紀錄都會被刪除 delete from employee where lastname = May delete from employee where firstname = Mike or firstname = Eric delete from 接著資料表名 再接著是條件式判斷沒有條件式則全部紀錄會

被刪除

如何更新資料

update 用來更新你所指定的記錄要和 WHERE 配合小心使用 語法 update tablename set columnname = newvalue[nextcolumn = newvalue2] where columnname OPERATOR value [and|or column OPERATOR value] [] = optional Examples

89

update phone_book set area_code = 623 where prefix = 979 update phone_book set last_name = Smith prefix=555 suffix=9292 where last_name = Jones update employee set age = age+1 where first_name=Mary and last_name=Williams

90

附錄二Replication

測試環境

RedHat 90 + MySQL 32358 MySQL資料庫路徑 varlibmysql MySQL設定檔 etcmycnf Master IP 1921680100 Slave IP 1921680200 請至下列網址下載最新MySQL 32358套件並利用rpm ndashUvh 更新 httpupdatesredhatcom9enosi386

圖 最新 MySQL 套件

測試架構圖

91

1921680100

1921680200Master Server

erveSlave S r

圖 測試架構圖

測試步驟

Master server 部份 Step1 確認 MasterSlave機器上所裝的 MySQL版本能進行

replication( 32329 or higher ) Step2 在 Master MySQL上開放一個帳號給 Slave mysql ndashu root ndashp mysqlgtGRANT FILE ON TO repl1921680200 IDENTIFIED BY lsquoabc123rsquo mysqlgtq 上面是 Master開放一個帳號 repl密碼 abc123給 IP1921680200有檔案處理

的權限 Step3 shutdown MySQL on the Master mysqladmin ndashu root ndashp shutdown Step4 備份 Master所有資料庫 tar ndashcvf tmpmysql-snapshottar varlibmysql 注意tar的時候MySQL是要在 stop情況下 在mysql (wwwmysqlcom) 網站的FAQ有不用shutdown的方法

92

Step5 在 master機器上修改etcmycnf 在[mysqld]區段內加入參數 log-bin server-id=這邊設定 server-id=1 sql-bin-update-same binlog-do-db=CRM只針對 CRM資料庫做紀錄 Step6 Restart MySQL on the master service mysqld start 此時因為有加入 log-bin 參數因此開始有 index產生了在varlibmysql目錄下

有index檔案紀錄資料庫的異動 log Slave server 部份 Step1 在 slave設定etcmycnf 在[mysqld]區段加入 master-host= master-user= master-password= master-port= server-id= 這邊設定 master-host=1921680100 master-user=repl master-password=abc123 master-port=3306 server-id=2 master-connect-retry=60預設重試間隔 60秒 replicate-do-db=CRM告訴 slave只做 CRM資料庫的更新 log-slave-updates Step2 將 master上的 mysql-snapshottar copy到 slave上 用 ftp傳到 slave的tmp Step3 解壓縮 Master資料庫至 Slave Server上 cd varlib tar xvf tmpmysql-snapshottar chown ndashR mysqlmysql mysql

93

chmod ndashR 770 mysql (視情況) Step4 Restart MySQL on the slave server 這時在varlibmysql目錄會出現 masterinfo此檔案紀錄了 Master MySQL server的資訊

狀況測試

One-way replication

1921680100

1921680200Master Server

erveSlave S r

圖 One-way replication架構圖 Step1 Master跟 Slave網路及服務都正常情況下由 Master端異動資料後 到 Slave端瀏覽資料檢視是否有進行 replication Step2 模擬 Slave Server 當機 可用在於 slave真的當機或是 Slave 不一定需要一直跟 master connect將Slave MySQL server shutdown由 Master端異動資料到 slave端瀏覽此時Slave應該沒有被 replication 更新然後再將 Slave端 MySQL server start起來

預設 60秒後 Slave會嘗試跟 Master要求進行 replication再去 Slave端檢視是否有更新資料

94

Step3 模擬 Master當機因為是設定 One-way replication一旦 Master Server Slave端沒有 Master的 source可以 download Two-way replication 基於 Master當機狀況於是發展雙向 Replication即 1921680100 ( Host A ) 1921680200 ( Host B )都分別擔任 MasterSlave身分

1921680100

1921680200er

Server B MasterSlave Server

Server A MasterSlave Serv

圖 Two-way replication架構圖 以下是針對兩台 MySQL伺服器進行雙向 Replication Step1觀念同單向 replication只是改成 Master也有 Slave身分 Slave也有Master的身分先分別在 Server AServer B 都去 grant一個進行 replication的身分 [A]mysqlgtGRANT FILE ON TO repl1921680200 IDENTIFIED BY lsquoabc123rsquo [B]mysqlgt GRANT FILE ON TO repl1921680100 IDENTIFIED BY lsquoabc123rsquo Step2做完單向 replication後stop Server Aserver B MySQL service此時 AB資料是一樣的

95

修改etcmycnf設定 範例 Server A [mysqld] datadir=varlibmysql socket=varlibmysqlmysqlsock server-id=1 log-bin sql-bin-update-same binlog-do-db=CRM master-host=1921680200 master-user=repl master-password=abc123 log-slave-updates master-connect-retry=60 replicate-do-db=CRM Server B [mysqld] datadir=varlibmysql socket=varlibmysqlmysqlsock server-id=2 log-bin sql-bin-update-same binlog-do-db=CRM master-host=1921680100 master-user=repl master-password=abc123 log-slave-updates master-connect-retry=60 replicate-do-db=CRM 分別 start Server AServer B MySQL後此時雙方都是 MasterSlave身分一旦哪一方資料異動就會通知對方來 replication-若 replication失效則必須將Server AServer B的masterinfo及index00x 都砍掉然後分別 restart MySQL server進行測試檢視成果 實務上通常如果需要做Two-way replication通常會搭配Virtual Server使用

96

在前端架設一台Virtual Server不過此部份不在此份SOP討論範圍內有興趣

的讀者可參考 httpwwwlinuxvirtualserverorg 網站

1921680100 1921680200

Host A MasterSlave Server

Host B MasterSlave Server

Virtual Host

圖 Virtual Server + Two-way replication 架構圖

97

圖 High Availability Linux Virtual Server架構圖

98

  • COSA-SOP-03-006
  • 第一章 簡介
    • 11適用對象 (Audience)
    • 12 MySQL本身
    • 13 MySQL 40版跟50版重大的改進功能
    • 14 各家資料庫軟體比較
      • 第二章 前置需求
      • 第三章 安裝
        • 31 MySQL安裝
        • 32 phpMyAdmin安裝
        • 33 升級及注意事項
          • 第四章 MySQL管理
            • 41 Webmin 管理介面
            • 42 phpMyAdmin 的操作介面
            • 43管理指令介紹
              • 431 利用mysqladmin設定root的密碼
                  • 第五章 實用範例
                    • 51 任務一Web Base客戶通訊錄
                    • 52 任務二Web Base群組軟體 ( twig )
                      • 第六章 維護及更新程序
                        • 61 日常維護
                        • 62 更新程序
                        • 63 備份重要檔案
                        • 64 離線備份與還原
                        • 65 線上備份與還原
                          • 第七章 問題與解答
                          • 第八章 參考資料
                          • 附錄一 SQL Command 介紹
                          • 附錄二Replication
Page 74: DataBase Server Standard Operation Procedureebooks.lib.ntu.edu.tw/1_file/oss/63/93doc4-5.pdf · 業務的公司帶來了不少壓力,譬如微軟,甲骨文 ... 外的錢用在第三方的資料庫產品上,譬如就可以不用再購買甲骨文公司

路徑 3若是您沒改 MYSQL_UNIX_PORT的值那麼您可以在執行指令的時候才打

例如mysqladmin --socket=其他路徑socket version Q7How to get the last insert id Ans CREATE TABLE product ( id INT(4) NOT NULL AUTO_INCREMENT PRIMARY KEY description VARCHAR(50) ) 1利用 SQL的話 mysqlgt insert into product(description) values(123) Query OK 1 row affected (000 sec) mysqlgt select last_insert_id() +------------------+ | last_insert_id() | +------------------+ +------------------+ 1 row in set (000 sec) ======================================== 2如果是 PHP的話 你可以用mysql_insert_id()取得該 id PHP example $result=MYSQL_QUERY(INSERT INTO product (description) VALUES ($description)) $id= mysql_insert_id() print This file has the following Database ID $id Q8如何將文字檔匯入資料庫 Ans $addr=homehttpdhtmlphpschool001txt $sql_select = load data infile $addr into table test fields terminated by t 解說 $sql_select = load data infile 文字檔名 into table 表格名 fields terminated by

74

t

(欄位分隔以 TAB鍵) 該文字檔須與資料表欄位格式相符 例如欄位有三個 則文字檔為每行一筆資料如下 欄 1資料ltTABgt欄 2資料ltTABgt欄 3資料 欄 1資料ltTABgt欄 2資料ltTABgt欄 3資料 欄 1資料ltTABgt欄 2資料ltTABgt欄 3資料 欄 1資料ltTABgtltTABgt欄 3資料

Q9如何撰寫 MySQL C API Ans Step 1利用文字編輯器撰寫以下程式碼 mysqlcc

include ltstdiohgt

include ltmysqlmysqlhgt

int main (int argc char argv[])

MYSQL mysql

MYSQL_RES res

MYSQL_ROW row

if (argc = 2)

fputs (Usage myc ltdatabasegt stderr)

return 1

if ((mysql_connect(ampmysqllocalhostrootYour_Password)))

fputs (Error connecting stderr)

abort()

75

if (mysql_select_db(ampmysqlargv[1]))

fputs (Error selecting database stderr)

abort()

if (mysql_query(ampmysqlSELECT FROM test_table))

fputs (Error processing query stderr)

abort()

if ((res = mysql_store_result(ampmysql)))

fputs (Error storing results stderr)

abort()

while((row = mysql_fetch_row(res)))

uint i = 0

for (i=0 i lt mysql_num_fields(res) i++)

printf(s row[i])

printf(n)

return 0

Step 2 Compile

gcc -Iusrlocalmysqlinclude -Lusrlocalmysqllibmysql mysqlcc ndashlm -lmysqlclient

(其中 include path與 library path取決於你的 MySQL安裝路徑)

76

如果執行時發生如下 error Run problemerror in loading shared libraries libmysqlclientsoX 將你的 MySQL library path(for exampleusrlocalmysqllibmysql) 加入etcldsoconf and run sbinldconfig -v Q9ASP + MySQL 範例程式 Ans Dim myconn As New ADODBConnection Dim myrs As New Recordset Dim mySQL As String Dim myrows As Long myconnOpen DSN=MyODBCsample mySQL = SELECT from user myrsSource = mySQL Set myrsActiveConnection = myconn myrsCursorLocation = adUseClient myrsOpen myrows = myrsRecordCount myrsClose myconnClose 可參考 httpwwwdwamnetmysqlasp_myodbcasp 有詳細的資料 Q10如何將 MySQL中的資料庫匯出成txt檔 Ans select from TableName into outfile textxls all result fields will seperate by tab

77

第八章 參考資料

英文部份 網址 1 httpwwwmysqlcom MySQL 網站有第一手有關 MySQL的資料 2 httpwwwmysqlcomdocenReplicationhtml 有關 MySQL Replication 的文件 3 httpwwwgeocitiescomsqlhomefaqstore_blobhtml 如何在 MySQL 存放 BLOB的資料 4httpwwwsapdborg 有關 SAP跟 MySQL相關合作的網站 書藉 1 Cooking with MySQL

Paul DuBois has selected sample recipes from the hundreds youll find in his book MySQL

Cookbook In this third and final series of excerpts showcasing these recipes learn how to

compute team standings how to calculate the differences between successive Dec 26

2002 2 Tips for Building Web Database Applications with PHP and MySQL by Hugh E Williams co-author of Web Database Applications with PHP amp MySQL 04042002

3 Managing and Using MySQL 2nd Edition By Tim King George Reese Randy Jay Yarger

4 MySQL Cookbook By Paul DuBoisPublisher OReillyPub Date October 2002

中文部份

78

1 httplinuxtncedutwtechdocmysqlmysql_docmanual_tochtml MySQL 中文手冊 2 httpchenshloxaedutwphpZ_1php PHP+MySQ程式研習設計網站 3 httplinuxtncedutwtechdocbanicdownhtml PHP 4 手冊 4 httpwwwtncedutwadmin_zonephp台南縣教育網網路中心有很多 Linux相關文件 5 httpdobtncedutw網站建置百寶箱有很多 PHP MySQL 相關範例程式 5 httpwwwdbworldcomtw資料庫專家電子雜誌介紹資料庫的重要觀念及名詞

79

附錄一 SQL Command 介紹

SQL (讀音ess-que-el) 是一種結構查詢語法SQL 使用於資料庫交流

傳遞相容於 ANSI (American National Standards Institute) 是一套標準的關聯

式資料庫語言 SQL 語言是執行更新或從資料系統獲取資料一般常見的關聯

資料庫系統都有提供 SQL 如 Oracle Sybase Microsoft SQL Server Access Ingres 等雖然大部份的資料庫都有提供 SQL 但也多提供了自已獨特的語

法造成了不相容的情形但標準基本的語法是相通的如Select Insert Update Delete Create and Drop 每一個系統都有支援

Table相關 Command

Create Table

關聯式資料庫包含有很多元件稱為資料表(tables) 把資料或訊息放在資

料表中 資料表是以不同的名稱做分別資料表由欄列所構成的二維陣列

欄包含欄位名資料型態 及其他可判斷的資訊列是由全部欄位構成一筆一

筆的紀錄 create table 語法用在建立一個新的資料表語法格式如下

create table tablename (column1 data type column2 data type column3 data type)

Format of create table if you were to use optional constraints

create table tablename (column1 data type [constraint] column2 data type [constraint] column3 data type [constraint]) [ ] = optional

Note You may have as many columns as youd like and the constraints are optional

80

Example

create table employee (first varchar(15) last varchar(20) age number(3) address varchar(30) city varchar(20) state varchar(20))

注意建立資料表格式要以括號把前後框住而最後以(分號)做結尾

欄位名不要超過 30個字元長而且不要使用 sql 的關鍵字(如 where select等)而在後面接是型態的宣告(如字串數字日期格式等)

資料型態是來描述欄位的方式如一個欄位Last_Name 是一個姓氏可以使用varchar (可變動長度字串) 資料型態

以下是幾個常見的資料庫型態 char(size) 固定長度字串最長為 255 位元 varchar(size) 變動長度字串最大字元數以 size 來指定 number(size) 數值格式可以是整數也可以是小數最大數字以 size 位數判

斷未指定小數位數由系統內定 date 日期格式 number(sized) 數值格式最大數字以 size 位數判斷d 為小數位數整數位

數為 size-d 位

有何限制當資料表被建立通常有一或數個欄位是要使用來做關聯的功

能 例如unique 限制(唯一值)兩筆記錄不可以相同的值 not null (非空值)該欄位一定要輸入資料不可是空的primary key (主鍵)是每一筆記錄識別的主要方式

Drop a table drop table 刪除資料表(其中的資料也會一併刪除)

drop table tablename

Example

81

drop table 和刪除全部資料是不同的刪除全部資料欄位名稱資訊等還會

存在但刪除資料表會把這一些也一併移除掉

如何查詢資料

Select 基本用法

select 語法是關連式資料庫最常用的部份可以取得你想要的資料這是一個

簡單的範例 select column1[column2etc] from tablename [where condition] [] = optional 在 select 之後所列欄位名則是要顯示的資料部份你可以一一列出各欄位

名或是以 (星號)來代表選擇全部的欄位 from 之後放資料表名稱 where 子句 (選項) 指定要過濾的條件符合者才會顯現 where 可使用的條件運算元 = 等於 gt 大於 lt 小於 gt= 大或等於 lt= 小或等於 ltgt 大相等 LIKE 相似 For example select first last city

82

from empinfo where first LIKE Er 以Er 為開頭的字串就符合要以單引號框住 Or you can specify select first last from empinfo where last LIKE s 最後一字為 S 就符合 select from empinfo where first = Eric 則表示 first name 一定要是 Eric 才可以 範例資料表empinfo 統計函數

MIN 傳回指定欄位最小值

MAX 傳回指定欄位最大值

SUM 傳回指定欄位總和

AVG 傳回指定欄位平均值

COUNT 傳回指定欄位的筆數

COUNT() 傳回資料庫中的總筆數

統計函數使用於資料表中的數值欄位配合 SELECT 語法使用 只用於總結特定單一欄位可以配合 GROUP BY 做篩選但也可以不使用 GROUP BY 語句For example

SELECT AVG(salary) FROM employee

83

傳回全部 salary 平均值

Another example

SELECT AVG(salary) FROM employee WHERE title = Programmer

傳回 salary 平均值條件為 employees 資料表中當 title 等於 Programmer

Example

SELECT Count() FROM employees

傳回 employees 資料表中紀錄總筆數

GROUP BY 語法 SELECT column1 SUM(column2) FROM list-of-tables GROUP BY column-list The GROUP BY 語句可以先以所列的欄位為條件分組排序在一起(可以多欄

位) example 要列出每一個 dept 中最高 salary 值 SELECT max(salary) dept FROM employee GROUP BY dept HAVING 語法

SELECT column1 SUM(column2) FROM list-of-tables GROUP BY column-list HAVING condition

HAVING 子句是 GROUP BY 的一部份用來過濾在 GROUP BY 所選出的資料功能如同 select 命令中 where 條件式一樣只是 HAVING 必需配合 GROUP BY 使用

我們以例子來說明我們要取得每一公司名及每一公司的薪水平均值輸入如下

84

SELECT dept avg(salary) FROM employee GROUP BY dept

但如果我們只列出薪資平均值超過 20000元的公司資料

SELECT dept avg(salary) FROM employee GROUP BY dept HAVING avg(salary) gt 20000

ORDER BY子句語法

SELECT column1 SUM(column2) FROM list-of-tables ORDER BY column-list [ASC | DESC]

[ ] =選項

ORDER BY是一個選項子句當你以排序方式來顯示資料(正向由小到大反向由大到小)以指定的欄位資料做排序

ASC = 正向- 預設值 DESC = 反向排序

For example

SELECT employee_id dept name age salary FROM employee_info WHERE dept = Sales ORDER BY salary

以上列出公司代號公司名銷售員人名年紀及薪資而條件是公司名為 Sales 顯示順序以薪資多少排序(由小到大為預設值)

如果要以多個欄位做排序要以逗號做分隔如下

SELECT employee_id dept name age salary FROM employee_info WHERE dept = Sales ORDER BY salary age DESC

85

結合條件及布林運算 SELECT column1 SUM(column2) FROM list-of-tables WHERE condition1 AND condition2 AND運算可以結兩個或以上的條件放在 WHERE子句中 兩者都要為真才

會顯示該筆記錄 OR 運算可以結兩個或以上敘述放在 WHERE子句中只要其中一個為直就

會顯示該筆記錄 For example SELECT employeeid firstname lastname title salary FROM employee_info WHERE salary gt= 5000000 AND title = Programmer 必需要薪資大於等於 50000而且職稱為 Programmer同時符合才會顯示該筆資料 以下以括號括住雖然不是必需的但如此比較容易讀 SELECT employeeid firstname lastname title salary FROM employee_info WHERE (salary gt= 5000000) AND (title = Programmer) 另外範例 SELECT firstname lastname title salary FROM employee_info WHERE (title = Sales) OR (title = Programmer) 條件為只要是 Sales 或 Programmer 職稱的就會被列出 IN and BETWEEN 子句

SELECT column1 SUM(column2) FROM list-of-tables WHERE column3 IN (list-of-values) SELECT column1 SUM(column2) FROM list-of-tables WHERE column3 BETWEEN value1 AND value2 IN 子句使用在列舉項目的使用上也就是分別測試是否符合所列的值 For example

86

SELECT employeeid lastname salary FROM employee_info WHERE lastname IN (Hernandez Jones Roberts Ruiz) 條件為姓氏(astname)要符合 Hernandez Jones Roberts or Ruiz 其中一個才會被傳回 IN運算元也可以使用 OR 的語法來取代如下結果相同 SELECT employeeid lastname salary FROM employee_info WHERE lastname = Hernandez OR lastname = Jones OR lastname = Roberts OR lastname = Ruiz 但使用 IN 句子比較短也比較易懂 你也可以使用 NOT IN 來去掉不要的記錄 BETWEEN 運算元使用在判斷是否存在兩個數值之間 For example SELECT employeeid age lastname salary FROM employee_info WHERE age BETWEEN 30 AND 40 傳回年紀 30歲到 40歲之間的資料(含 30及 40歲者) 相同的也可以使用以下語法來達到相同的結果 SELECT employeeid age lastname salary FROM employee_info WHERE age gt= 30 AND age lt= 40 你也可使用 NOT BETWEEN 來濾掉中間值的資料 數學運算 標準 ANSI SQL-92 提供以下運算

87

+ 加

- 減

餘數

餘數為除法後剩整數這不在標準的 ANSI SQL 中但大部份的資料庫都會支

援這運算元以下列出有用的函數雖不在 ANSI SQL-92 提供但一般資料庫

也會支援他們

ABS(x) 傳回 x 絕對值

SIGN(x) returns the sign of input x as -1 0 or 1 (negative zero or positive respectively)

MOD(xy) 餘數 - returns the integer remainder of x divided by y (同 xy)

FLOOR(x) 傳回小或等於 x 的最大整數值

CEILING(x) or CEIL(x)

傳回大或等於 x 的最小整數值

POWER(xy) x的 y 次方

ROUND(x) 把 x 四捨五入為整數

ROUND(xd) 四捨五入取到小數 d 位

SQRT(x) x 開平方

For example SELECT round(salary) firstname FROM employee_info 傳回薪資取到整數位

如何新增資料

insert 加入一筆新紀錄到資料表中 insert into tablename (first_columnlast_column) values (first_valuelast_value) [] = optional Example insert into employee

88

(first last age address city state) values (Luke Duke 45 2130 Boars Nest Hazard Co Georgia) Note 字串要以單引號住如string 數字框住也無妨 insert into 後面接資料表名稱再接以括號括住的欄位名在 values 後括號分別對映各欄位的值 以上的例子新增了一筆名(first) 為 Luke而住所(state) 為 Georgia 的資料

如何刪除資料

delete 可以刪除單筆或多筆紀錄 delete from tablename where columnname OPERATOR value [and|or column OPERATOR value] [ ] = optional Examples delete from employee Note 如果你沒有指定 where 子句那麼全部的紀錄都會被刪除 delete from employee where lastname = May delete from employee where firstname = Mike or firstname = Eric delete from 接著資料表名 再接著是條件式判斷沒有條件式則全部紀錄會

被刪除

如何更新資料

update 用來更新你所指定的記錄要和 WHERE 配合小心使用 語法 update tablename set columnname = newvalue[nextcolumn = newvalue2] where columnname OPERATOR value [and|or column OPERATOR value] [] = optional Examples

89

update phone_book set area_code = 623 where prefix = 979 update phone_book set last_name = Smith prefix=555 suffix=9292 where last_name = Jones update employee set age = age+1 where first_name=Mary and last_name=Williams

90

附錄二Replication

測試環境

RedHat 90 + MySQL 32358 MySQL資料庫路徑 varlibmysql MySQL設定檔 etcmycnf Master IP 1921680100 Slave IP 1921680200 請至下列網址下載最新MySQL 32358套件並利用rpm ndashUvh 更新 httpupdatesredhatcom9enosi386

圖 最新 MySQL 套件

測試架構圖

91

1921680100

1921680200Master Server

erveSlave S r

圖 測試架構圖

測試步驟

Master server 部份 Step1 確認 MasterSlave機器上所裝的 MySQL版本能進行

replication( 32329 or higher ) Step2 在 Master MySQL上開放一個帳號給 Slave mysql ndashu root ndashp mysqlgtGRANT FILE ON TO repl1921680200 IDENTIFIED BY lsquoabc123rsquo mysqlgtq 上面是 Master開放一個帳號 repl密碼 abc123給 IP1921680200有檔案處理

的權限 Step3 shutdown MySQL on the Master mysqladmin ndashu root ndashp shutdown Step4 備份 Master所有資料庫 tar ndashcvf tmpmysql-snapshottar varlibmysql 注意tar的時候MySQL是要在 stop情況下 在mysql (wwwmysqlcom) 網站的FAQ有不用shutdown的方法

92

Step5 在 master機器上修改etcmycnf 在[mysqld]區段內加入參數 log-bin server-id=這邊設定 server-id=1 sql-bin-update-same binlog-do-db=CRM只針對 CRM資料庫做紀錄 Step6 Restart MySQL on the master service mysqld start 此時因為有加入 log-bin 參數因此開始有 index產生了在varlibmysql目錄下

有index檔案紀錄資料庫的異動 log Slave server 部份 Step1 在 slave設定etcmycnf 在[mysqld]區段加入 master-host= master-user= master-password= master-port= server-id= 這邊設定 master-host=1921680100 master-user=repl master-password=abc123 master-port=3306 server-id=2 master-connect-retry=60預設重試間隔 60秒 replicate-do-db=CRM告訴 slave只做 CRM資料庫的更新 log-slave-updates Step2 將 master上的 mysql-snapshottar copy到 slave上 用 ftp傳到 slave的tmp Step3 解壓縮 Master資料庫至 Slave Server上 cd varlib tar xvf tmpmysql-snapshottar chown ndashR mysqlmysql mysql

93

chmod ndashR 770 mysql (視情況) Step4 Restart MySQL on the slave server 這時在varlibmysql目錄會出現 masterinfo此檔案紀錄了 Master MySQL server的資訊

狀況測試

One-way replication

1921680100

1921680200Master Server

erveSlave S r

圖 One-way replication架構圖 Step1 Master跟 Slave網路及服務都正常情況下由 Master端異動資料後 到 Slave端瀏覽資料檢視是否有進行 replication Step2 模擬 Slave Server 當機 可用在於 slave真的當機或是 Slave 不一定需要一直跟 master connect將Slave MySQL server shutdown由 Master端異動資料到 slave端瀏覽此時Slave應該沒有被 replication 更新然後再將 Slave端 MySQL server start起來

預設 60秒後 Slave會嘗試跟 Master要求進行 replication再去 Slave端檢視是否有更新資料

94

Step3 模擬 Master當機因為是設定 One-way replication一旦 Master Server Slave端沒有 Master的 source可以 download Two-way replication 基於 Master當機狀況於是發展雙向 Replication即 1921680100 ( Host A ) 1921680200 ( Host B )都分別擔任 MasterSlave身分

1921680100

1921680200er

Server B MasterSlave Server

Server A MasterSlave Serv

圖 Two-way replication架構圖 以下是針對兩台 MySQL伺服器進行雙向 Replication Step1觀念同單向 replication只是改成 Master也有 Slave身分 Slave也有Master的身分先分別在 Server AServer B 都去 grant一個進行 replication的身分 [A]mysqlgtGRANT FILE ON TO repl1921680200 IDENTIFIED BY lsquoabc123rsquo [B]mysqlgt GRANT FILE ON TO repl1921680100 IDENTIFIED BY lsquoabc123rsquo Step2做完單向 replication後stop Server Aserver B MySQL service此時 AB資料是一樣的

95

修改etcmycnf設定 範例 Server A [mysqld] datadir=varlibmysql socket=varlibmysqlmysqlsock server-id=1 log-bin sql-bin-update-same binlog-do-db=CRM master-host=1921680200 master-user=repl master-password=abc123 log-slave-updates master-connect-retry=60 replicate-do-db=CRM Server B [mysqld] datadir=varlibmysql socket=varlibmysqlmysqlsock server-id=2 log-bin sql-bin-update-same binlog-do-db=CRM master-host=1921680100 master-user=repl master-password=abc123 log-slave-updates master-connect-retry=60 replicate-do-db=CRM 分別 start Server AServer B MySQL後此時雙方都是 MasterSlave身分一旦哪一方資料異動就會通知對方來 replication-若 replication失效則必須將Server AServer B的masterinfo及index00x 都砍掉然後分別 restart MySQL server進行測試檢視成果 實務上通常如果需要做Two-way replication通常會搭配Virtual Server使用

96

在前端架設一台Virtual Server不過此部份不在此份SOP討論範圍內有興趣

的讀者可參考 httpwwwlinuxvirtualserverorg 網站

1921680100 1921680200

Host A MasterSlave Server

Host B MasterSlave Server

Virtual Host

圖 Virtual Server + Two-way replication 架構圖

97

圖 High Availability Linux Virtual Server架構圖

98

  • COSA-SOP-03-006
  • 第一章 簡介
    • 11適用對象 (Audience)
    • 12 MySQL本身
    • 13 MySQL 40版跟50版重大的改進功能
    • 14 各家資料庫軟體比較
      • 第二章 前置需求
      • 第三章 安裝
        • 31 MySQL安裝
        • 32 phpMyAdmin安裝
        • 33 升級及注意事項
          • 第四章 MySQL管理
            • 41 Webmin 管理介面
            • 42 phpMyAdmin 的操作介面
            • 43管理指令介紹
              • 431 利用mysqladmin設定root的密碼
                  • 第五章 實用範例
                    • 51 任務一Web Base客戶通訊錄
                    • 52 任務二Web Base群組軟體 ( twig )
                      • 第六章 維護及更新程序
                        • 61 日常維護
                        • 62 更新程序
                        • 63 備份重要檔案
                        • 64 離線備份與還原
                        • 65 線上備份與還原
                          • 第七章 問題與解答
                          • 第八章 參考資料
                          • 附錄一 SQL Command 介紹
                          • 附錄二Replication
Page 75: DataBase Server Standard Operation Procedureebooks.lib.ntu.edu.tw/1_file/oss/63/93doc4-5.pdf · 業務的公司帶來了不少壓力,譬如微軟,甲骨文 ... 外的錢用在第三方的資料庫產品上,譬如就可以不用再購買甲骨文公司

t

(欄位分隔以 TAB鍵) 該文字檔須與資料表欄位格式相符 例如欄位有三個 則文字檔為每行一筆資料如下 欄 1資料ltTABgt欄 2資料ltTABgt欄 3資料 欄 1資料ltTABgt欄 2資料ltTABgt欄 3資料 欄 1資料ltTABgt欄 2資料ltTABgt欄 3資料 欄 1資料ltTABgtltTABgt欄 3資料

Q9如何撰寫 MySQL C API Ans Step 1利用文字編輯器撰寫以下程式碼 mysqlcc

include ltstdiohgt

include ltmysqlmysqlhgt

int main (int argc char argv[])

MYSQL mysql

MYSQL_RES res

MYSQL_ROW row

if (argc = 2)

fputs (Usage myc ltdatabasegt stderr)

return 1

if ((mysql_connect(ampmysqllocalhostrootYour_Password)))

fputs (Error connecting stderr)

abort()

75

if (mysql_select_db(ampmysqlargv[1]))

fputs (Error selecting database stderr)

abort()

if (mysql_query(ampmysqlSELECT FROM test_table))

fputs (Error processing query stderr)

abort()

if ((res = mysql_store_result(ampmysql)))

fputs (Error storing results stderr)

abort()

while((row = mysql_fetch_row(res)))

uint i = 0

for (i=0 i lt mysql_num_fields(res) i++)

printf(s row[i])

printf(n)

return 0

Step 2 Compile

gcc -Iusrlocalmysqlinclude -Lusrlocalmysqllibmysql mysqlcc ndashlm -lmysqlclient

(其中 include path與 library path取決於你的 MySQL安裝路徑)

76

如果執行時發生如下 error Run problemerror in loading shared libraries libmysqlclientsoX 將你的 MySQL library path(for exampleusrlocalmysqllibmysql) 加入etcldsoconf and run sbinldconfig -v Q9ASP + MySQL 範例程式 Ans Dim myconn As New ADODBConnection Dim myrs As New Recordset Dim mySQL As String Dim myrows As Long myconnOpen DSN=MyODBCsample mySQL = SELECT from user myrsSource = mySQL Set myrsActiveConnection = myconn myrsCursorLocation = adUseClient myrsOpen myrows = myrsRecordCount myrsClose myconnClose 可參考 httpwwwdwamnetmysqlasp_myodbcasp 有詳細的資料 Q10如何將 MySQL中的資料庫匯出成txt檔 Ans select from TableName into outfile textxls all result fields will seperate by tab

77

第八章 參考資料

英文部份 網址 1 httpwwwmysqlcom MySQL 網站有第一手有關 MySQL的資料 2 httpwwwmysqlcomdocenReplicationhtml 有關 MySQL Replication 的文件 3 httpwwwgeocitiescomsqlhomefaqstore_blobhtml 如何在 MySQL 存放 BLOB的資料 4httpwwwsapdborg 有關 SAP跟 MySQL相關合作的網站 書藉 1 Cooking with MySQL

Paul DuBois has selected sample recipes from the hundreds youll find in his book MySQL

Cookbook In this third and final series of excerpts showcasing these recipes learn how to

compute team standings how to calculate the differences between successive Dec 26

2002 2 Tips for Building Web Database Applications with PHP and MySQL by Hugh E Williams co-author of Web Database Applications with PHP amp MySQL 04042002

3 Managing and Using MySQL 2nd Edition By Tim King George Reese Randy Jay Yarger

4 MySQL Cookbook By Paul DuBoisPublisher OReillyPub Date October 2002

中文部份

78

1 httplinuxtncedutwtechdocmysqlmysql_docmanual_tochtml MySQL 中文手冊 2 httpchenshloxaedutwphpZ_1php PHP+MySQ程式研習設計網站 3 httplinuxtncedutwtechdocbanicdownhtml PHP 4 手冊 4 httpwwwtncedutwadmin_zonephp台南縣教育網網路中心有很多 Linux相關文件 5 httpdobtncedutw網站建置百寶箱有很多 PHP MySQL 相關範例程式 5 httpwwwdbworldcomtw資料庫專家電子雜誌介紹資料庫的重要觀念及名詞

79

附錄一 SQL Command 介紹

SQL (讀音ess-que-el) 是一種結構查詢語法SQL 使用於資料庫交流

傳遞相容於 ANSI (American National Standards Institute) 是一套標準的關聯

式資料庫語言 SQL 語言是執行更新或從資料系統獲取資料一般常見的關聯

資料庫系統都有提供 SQL 如 Oracle Sybase Microsoft SQL Server Access Ingres 等雖然大部份的資料庫都有提供 SQL 但也多提供了自已獨特的語

法造成了不相容的情形但標準基本的語法是相通的如Select Insert Update Delete Create and Drop 每一個系統都有支援

Table相關 Command

Create Table

關聯式資料庫包含有很多元件稱為資料表(tables) 把資料或訊息放在資

料表中 資料表是以不同的名稱做分別資料表由欄列所構成的二維陣列

欄包含欄位名資料型態 及其他可判斷的資訊列是由全部欄位構成一筆一

筆的紀錄 create table 語法用在建立一個新的資料表語法格式如下

create table tablename (column1 data type column2 data type column3 data type)

Format of create table if you were to use optional constraints

create table tablename (column1 data type [constraint] column2 data type [constraint] column3 data type [constraint]) [ ] = optional

Note You may have as many columns as youd like and the constraints are optional

80

Example

create table employee (first varchar(15) last varchar(20) age number(3) address varchar(30) city varchar(20) state varchar(20))

注意建立資料表格式要以括號把前後框住而最後以(分號)做結尾

欄位名不要超過 30個字元長而且不要使用 sql 的關鍵字(如 where select等)而在後面接是型態的宣告(如字串數字日期格式等)

資料型態是來描述欄位的方式如一個欄位Last_Name 是一個姓氏可以使用varchar (可變動長度字串) 資料型態

以下是幾個常見的資料庫型態 char(size) 固定長度字串最長為 255 位元 varchar(size) 變動長度字串最大字元數以 size 來指定 number(size) 數值格式可以是整數也可以是小數最大數字以 size 位數判

斷未指定小數位數由系統內定 date 日期格式 number(sized) 數值格式最大數字以 size 位數判斷d 為小數位數整數位

數為 size-d 位

有何限制當資料表被建立通常有一或數個欄位是要使用來做關聯的功

能 例如unique 限制(唯一值)兩筆記錄不可以相同的值 not null (非空值)該欄位一定要輸入資料不可是空的primary key (主鍵)是每一筆記錄識別的主要方式

Drop a table drop table 刪除資料表(其中的資料也會一併刪除)

drop table tablename

Example

81

drop table 和刪除全部資料是不同的刪除全部資料欄位名稱資訊等還會

存在但刪除資料表會把這一些也一併移除掉

如何查詢資料

Select 基本用法

select 語法是關連式資料庫最常用的部份可以取得你想要的資料這是一個

簡單的範例 select column1[column2etc] from tablename [where condition] [] = optional 在 select 之後所列欄位名則是要顯示的資料部份你可以一一列出各欄位

名或是以 (星號)來代表選擇全部的欄位 from 之後放資料表名稱 where 子句 (選項) 指定要過濾的條件符合者才會顯現 where 可使用的條件運算元 = 等於 gt 大於 lt 小於 gt= 大或等於 lt= 小或等於 ltgt 大相等 LIKE 相似 For example select first last city

82

from empinfo where first LIKE Er 以Er 為開頭的字串就符合要以單引號框住 Or you can specify select first last from empinfo where last LIKE s 最後一字為 S 就符合 select from empinfo where first = Eric 則表示 first name 一定要是 Eric 才可以 範例資料表empinfo 統計函數

MIN 傳回指定欄位最小值

MAX 傳回指定欄位最大值

SUM 傳回指定欄位總和

AVG 傳回指定欄位平均值

COUNT 傳回指定欄位的筆數

COUNT() 傳回資料庫中的總筆數

統計函數使用於資料表中的數值欄位配合 SELECT 語法使用 只用於總結特定單一欄位可以配合 GROUP BY 做篩選但也可以不使用 GROUP BY 語句For example

SELECT AVG(salary) FROM employee

83

傳回全部 salary 平均值

Another example

SELECT AVG(salary) FROM employee WHERE title = Programmer

傳回 salary 平均值條件為 employees 資料表中當 title 等於 Programmer

Example

SELECT Count() FROM employees

傳回 employees 資料表中紀錄總筆數

GROUP BY 語法 SELECT column1 SUM(column2) FROM list-of-tables GROUP BY column-list The GROUP BY 語句可以先以所列的欄位為條件分組排序在一起(可以多欄

位) example 要列出每一個 dept 中最高 salary 值 SELECT max(salary) dept FROM employee GROUP BY dept HAVING 語法

SELECT column1 SUM(column2) FROM list-of-tables GROUP BY column-list HAVING condition

HAVING 子句是 GROUP BY 的一部份用來過濾在 GROUP BY 所選出的資料功能如同 select 命令中 where 條件式一樣只是 HAVING 必需配合 GROUP BY 使用

我們以例子來說明我們要取得每一公司名及每一公司的薪水平均值輸入如下

84

SELECT dept avg(salary) FROM employee GROUP BY dept

但如果我們只列出薪資平均值超過 20000元的公司資料

SELECT dept avg(salary) FROM employee GROUP BY dept HAVING avg(salary) gt 20000

ORDER BY子句語法

SELECT column1 SUM(column2) FROM list-of-tables ORDER BY column-list [ASC | DESC]

[ ] =選項

ORDER BY是一個選項子句當你以排序方式來顯示資料(正向由小到大反向由大到小)以指定的欄位資料做排序

ASC = 正向- 預設值 DESC = 反向排序

For example

SELECT employee_id dept name age salary FROM employee_info WHERE dept = Sales ORDER BY salary

以上列出公司代號公司名銷售員人名年紀及薪資而條件是公司名為 Sales 顯示順序以薪資多少排序(由小到大為預設值)

如果要以多個欄位做排序要以逗號做分隔如下

SELECT employee_id dept name age salary FROM employee_info WHERE dept = Sales ORDER BY salary age DESC

85

結合條件及布林運算 SELECT column1 SUM(column2) FROM list-of-tables WHERE condition1 AND condition2 AND運算可以結兩個或以上的條件放在 WHERE子句中 兩者都要為真才

會顯示該筆記錄 OR 運算可以結兩個或以上敘述放在 WHERE子句中只要其中一個為直就

會顯示該筆記錄 For example SELECT employeeid firstname lastname title salary FROM employee_info WHERE salary gt= 5000000 AND title = Programmer 必需要薪資大於等於 50000而且職稱為 Programmer同時符合才會顯示該筆資料 以下以括號括住雖然不是必需的但如此比較容易讀 SELECT employeeid firstname lastname title salary FROM employee_info WHERE (salary gt= 5000000) AND (title = Programmer) 另外範例 SELECT firstname lastname title salary FROM employee_info WHERE (title = Sales) OR (title = Programmer) 條件為只要是 Sales 或 Programmer 職稱的就會被列出 IN and BETWEEN 子句

SELECT column1 SUM(column2) FROM list-of-tables WHERE column3 IN (list-of-values) SELECT column1 SUM(column2) FROM list-of-tables WHERE column3 BETWEEN value1 AND value2 IN 子句使用在列舉項目的使用上也就是分別測試是否符合所列的值 For example

86

SELECT employeeid lastname salary FROM employee_info WHERE lastname IN (Hernandez Jones Roberts Ruiz) 條件為姓氏(astname)要符合 Hernandez Jones Roberts or Ruiz 其中一個才會被傳回 IN運算元也可以使用 OR 的語法來取代如下結果相同 SELECT employeeid lastname salary FROM employee_info WHERE lastname = Hernandez OR lastname = Jones OR lastname = Roberts OR lastname = Ruiz 但使用 IN 句子比較短也比較易懂 你也可以使用 NOT IN 來去掉不要的記錄 BETWEEN 運算元使用在判斷是否存在兩個數值之間 For example SELECT employeeid age lastname salary FROM employee_info WHERE age BETWEEN 30 AND 40 傳回年紀 30歲到 40歲之間的資料(含 30及 40歲者) 相同的也可以使用以下語法來達到相同的結果 SELECT employeeid age lastname salary FROM employee_info WHERE age gt= 30 AND age lt= 40 你也可使用 NOT BETWEEN 來濾掉中間值的資料 數學運算 標準 ANSI SQL-92 提供以下運算

87

+ 加

- 減

餘數

餘數為除法後剩整數這不在標準的 ANSI SQL 中但大部份的資料庫都會支

援這運算元以下列出有用的函數雖不在 ANSI SQL-92 提供但一般資料庫

也會支援他們

ABS(x) 傳回 x 絕對值

SIGN(x) returns the sign of input x as -1 0 or 1 (negative zero or positive respectively)

MOD(xy) 餘數 - returns the integer remainder of x divided by y (同 xy)

FLOOR(x) 傳回小或等於 x 的最大整數值

CEILING(x) or CEIL(x)

傳回大或等於 x 的最小整數值

POWER(xy) x的 y 次方

ROUND(x) 把 x 四捨五入為整數

ROUND(xd) 四捨五入取到小數 d 位

SQRT(x) x 開平方

For example SELECT round(salary) firstname FROM employee_info 傳回薪資取到整數位

如何新增資料

insert 加入一筆新紀錄到資料表中 insert into tablename (first_columnlast_column) values (first_valuelast_value) [] = optional Example insert into employee

88

(first last age address city state) values (Luke Duke 45 2130 Boars Nest Hazard Co Georgia) Note 字串要以單引號住如string 數字框住也無妨 insert into 後面接資料表名稱再接以括號括住的欄位名在 values 後括號分別對映各欄位的值 以上的例子新增了一筆名(first) 為 Luke而住所(state) 為 Georgia 的資料

如何刪除資料

delete 可以刪除單筆或多筆紀錄 delete from tablename where columnname OPERATOR value [and|or column OPERATOR value] [ ] = optional Examples delete from employee Note 如果你沒有指定 where 子句那麼全部的紀錄都會被刪除 delete from employee where lastname = May delete from employee where firstname = Mike or firstname = Eric delete from 接著資料表名 再接著是條件式判斷沒有條件式則全部紀錄會

被刪除

如何更新資料

update 用來更新你所指定的記錄要和 WHERE 配合小心使用 語法 update tablename set columnname = newvalue[nextcolumn = newvalue2] where columnname OPERATOR value [and|or column OPERATOR value] [] = optional Examples

89

update phone_book set area_code = 623 where prefix = 979 update phone_book set last_name = Smith prefix=555 suffix=9292 where last_name = Jones update employee set age = age+1 where first_name=Mary and last_name=Williams

90

附錄二Replication

測試環境

RedHat 90 + MySQL 32358 MySQL資料庫路徑 varlibmysql MySQL設定檔 etcmycnf Master IP 1921680100 Slave IP 1921680200 請至下列網址下載最新MySQL 32358套件並利用rpm ndashUvh 更新 httpupdatesredhatcom9enosi386

圖 最新 MySQL 套件

測試架構圖

91

1921680100

1921680200Master Server

erveSlave S r

圖 測試架構圖

測試步驟

Master server 部份 Step1 確認 MasterSlave機器上所裝的 MySQL版本能進行

replication( 32329 or higher ) Step2 在 Master MySQL上開放一個帳號給 Slave mysql ndashu root ndashp mysqlgtGRANT FILE ON TO repl1921680200 IDENTIFIED BY lsquoabc123rsquo mysqlgtq 上面是 Master開放一個帳號 repl密碼 abc123給 IP1921680200有檔案處理

的權限 Step3 shutdown MySQL on the Master mysqladmin ndashu root ndashp shutdown Step4 備份 Master所有資料庫 tar ndashcvf tmpmysql-snapshottar varlibmysql 注意tar的時候MySQL是要在 stop情況下 在mysql (wwwmysqlcom) 網站的FAQ有不用shutdown的方法

92

Step5 在 master機器上修改etcmycnf 在[mysqld]區段內加入參數 log-bin server-id=這邊設定 server-id=1 sql-bin-update-same binlog-do-db=CRM只針對 CRM資料庫做紀錄 Step6 Restart MySQL on the master service mysqld start 此時因為有加入 log-bin 參數因此開始有 index產生了在varlibmysql目錄下

有index檔案紀錄資料庫的異動 log Slave server 部份 Step1 在 slave設定etcmycnf 在[mysqld]區段加入 master-host= master-user= master-password= master-port= server-id= 這邊設定 master-host=1921680100 master-user=repl master-password=abc123 master-port=3306 server-id=2 master-connect-retry=60預設重試間隔 60秒 replicate-do-db=CRM告訴 slave只做 CRM資料庫的更新 log-slave-updates Step2 將 master上的 mysql-snapshottar copy到 slave上 用 ftp傳到 slave的tmp Step3 解壓縮 Master資料庫至 Slave Server上 cd varlib tar xvf tmpmysql-snapshottar chown ndashR mysqlmysql mysql

93

chmod ndashR 770 mysql (視情況) Step4 Restart MySQL on the slave server 這時在varlibmysql目錄會出現 masterinfo此檔案紀錄了 Master MySQL server的資訊

狀況測試

One-way replication

1921680100

1921680200Master Server

erveSlave S r

圖 One-way replication架構圖 Step1 Master跟 Slave網路及服務都正常情況下由 Master端異動資料後 到 Slave端瀏覽資料檢視是否有進行 replication Step2 模擬 Slave Server 當機 可用在於 slave真的當機或是 Slave 不一定需要一直跟 master connect將Slave MySQL server shutdown由 Master端異動資料到 slave端瀏覽此時Slave應該沒有被 replication 更新然後再將 Slave端 MySQL server start起來

預設 60秒後 Slave會嘗試跟 Master要求進行 replication再去 Slave端檢視是否有更新資料

94

Step3 模擬 Master當機因為是設定 One-way replication一旦 Master Server Slave端沒有 Master的 source可以 download Two-way replication 基於 Master當機狀況於是發展雙向 Replication即 1921680100 ( Host A ) 1921680200 ( Host B )都分別擔任 MasterSlave身分

1921680100

1921680200er

Server B MasterSlave Server

Server A MasterSlave Serv

圖 Two-way replication架構圖 以下是針對兩台 MySQL伺服器進行雙向 Replication Step1觀念同單向 replication只是改成 Master也有 Slave身分 Slave也有Master的身分先分別在 Server AServer B 都去 grant一個進行 replication的身分 [A]mysqlgtGRANT FILE ON TO repl1921680200 IDENTIFIED BY lsquoabc123rsquo [B]mysqlgt GRANT FILE ON TO repl1921680100 IDENTIFIED BY lsquoabc123rsquo Step2做完單向 replication後stop Server Aserver B MySQL service此時 AB資料是一樣的

95

修改etcmycnf設定 範例 Server A [mysqld] datadir=varlibmysql socket=varlibmysqlmysqlsock server-id=1 log-bin sql-bin-update-same binlog-do-db=CRM master-host=1921680200 master-user=repl master-password=abc123 log-slave-updates master-connect-retry=60 replicate-do-db=CRM Server B [mysqld] datadir=varlibmysql socket=varlibmysqlmysqlsock server-id=2 log-bin sql-bin-update-same binlog-do-db=CRM master-host=1921680100 master-user=repl master-password=abc123 log-slave-updates master-connect-retry=60 replicate-do-db=CRM 分別 start Server AServer B MySQL後此時雙方都是 MasterSlave身分一旦哪一方資料異動就會通知對方來 replication-若 replication失效則必須將Server AServer B的masterinfo及index00x 都砍掉然後分別 restart MySQL server進行測試檢視成果 實務上通常如果需要做Two-way replication通常會搭配Virtual Server使用

96

在前端架設一台Virtual Server不過此部份不在此份SOP討論範圍內有興趣

的讀者可參考 httpwwwlinuxvirtualserverorg 網站

1921680100 1921680200

Host A MasterSlave Server

Host B MasterSlave Server

Virtual Host

圖 Virtual Server + Two-way replication 架構圖

97

圖 High Availability Linux Virtual Server架構圖

98

  • COSA-SOP-03-006
  • 第一章 簡介
    • 11適用對象 (Audience)
    • 12 MySQL本身
    • 13 MySQL 40版跟50版重大的改進功能
    • 14 各家資料庫軟體比較
      • 第二章 前置需求
      • 第三章 安裝
        • 31 MySQL安裝
        • 32 phpMyAdmin安裝
        • 33 升級及注意事項
          • 第四章 MySQL管理
            • 41 Webmin 管理介面
            • 42 phpMyAdmin 的操作介面
            • 43管理指令介紹
              • 431 利用mysqladmin設定root的密碼
                  • 第五章 實用範例
                    • 51 任務一Web Base客戶通訊錄
                    • 52 任務二Web Base群組軟體 ( twig )
                      • 第六章 維護及更新程序
                        • 61 日常維護
                        • 62 更新程序
                        • 63 備份重要檔案
                        • 64 離線備份與還原
                        • 65 線上備份與還原
                          • 第七章 問題與解答
                          • 第八章 參考資料
                          • 附錄一 SQL Command 介紹
                          • 附錄二Replication
Page 76: DataBase Server Standard Operation Procedureebooks.lib.ntu.edu.tw/1_file/oss/63/93doc4-5.pdf · 業務的公司帶來了不少壓力,譬如微軟,甲骨文 ... 外的錢用在第三方的資料庫產品上,譬如就可以不用再購買甲骨文公司

if (mysql_select_db(ampmysqlargv[1]))

fputs (Error selecting database stderr)

abort()

if (mysql_query(ampmysqlSELECT FROM test_table))

fputs (Error processing query stderr)

abort()

if ((res = mysql_store_result(ampmysql)))

fputs (Error storing results stderr)

abort()

while((row = mysql_fetch_row(res)))

uint i = 0

for (i=0 i lt mysql_num_fields(res) i++)

printf(s row[i])

printf(n)

return 0

Step 2 Compile

gcc -Iusrlocalmysqlinclude -Lusrlocalmysqllibmysql mysqlcc ndashlm -lmysqlclient

(其中 include path與 library path取決於你的 MySQL安裝路徑)

76

如果執行時發生如下 error Run problemerror in loading shared libraries libmysqlclientsoX 將你的 MySQL library path(for exampleusrlocalmysqllibmysql) 加入etcldsoconf and run sbinldconfig -v Q9ASP + MySQL 範例程式 Ans Dim myconn As New ADODBConnection Dim myrs As New Recordset Dim mySQL As String Dim myrows As Long myconnOpen DSN=MyODBCsample mySQL = SELECT from user myrsSource = mySQL Set myrsActiveConnection = myconn myrsCursorLocation = adUseClient myrsOpen myrows = myrsRecordCount myrsClose myconnClose 可參考 httpwwwdwamnetmysqlasp_myodbcasp 有詳細的資料 Q10如何將 MySQL中的資料庫匯出成txt檔 Ans select from TableName into outfile textxls all result fields will seperate by tab

77

第八章 參考資料

英文部份 網址 1 httpwwwmysqlcom MySQL 網站有第一手有關 MySQL的資料 2 httpwwwmysqlcomdocenReplicationhtml 有關 MySQL Replication 的文件 3 httpwwwgeocitiescomsqlhomefaqstore_blobhtml 如何在 MySQL 存放 BLOB的資料 4httpwwwsapdborg 有關 SAP跟 MySQL相關合作的網站 書藉 1 Cooking with MySQL

Paul DuBois has selected sample recipes from the hundreds youll find in his book MySQL

Cookbook In this third and final series of excerpts showcasing these recipes learn how to

compute team standings how to calculate the differences between successive Dec 26

2002 2 Tips for Building Web Database Applications with PHP and MySQL by Hugh E Williams co-author of Web Database Applications with PHP amp MySQL 04042002

3 Managing and Using MySQL 2nd Edition By Tim King George Reese Randy Jay Yarger

4 MySQL Cookbook By Paul DuBoisPublisher OReillyPub Date October 2002

中文部份

78

1 httplinuxtncedutwtechdocmysqlmysql_docmanual_tochtml MySQL 中文手冊 2 httpchenshloxaedutwphpZ_1php PHP+MySQ程式研習設計網站 3 httplinuxtncedutwtechdocbanicdownhtml PHP 4 手冊 4 httpwwwtncedutwadmin_zonephp台南縣教育網網路中心有很多 Linux相關文件 5 httpdobtncedutw網站建置百寶箱有很多 PHP MySQL 相關範例程式 5 httpwwwdbworldcomtw資料庫專家電子雜誌介紹資料庫的重要觀念及名詞

79

附錄一 SQL Command 介紹

SQL (讀音ess-que-el) 是一種結構查詢語法SQL 使用於資料庫交流

傳遞相容於 ANSI (American National Standards Institute) 是一套標準的關聯

式資料庫語言 SQL 語言是執行更新或從資料系統獲取資料一般常見的關聯

資料庫系統都有提供 SQL 如 Oracle Sybase Microsoft SQL Server Access Ingres 等雖然大部份的資料庫都有提供 SQL 但也多提供了自已獨特的語

法造成了不相容的情形但標準基本的語法是相通的如Select Insert Update Delete Create and Drop 每一個系統都有支援

Table相關 Command

Create Table

關聯式資料庫包含有很多元件稱為資料表(tables) 把資料或訊息放在資

料表中 資料表是以不同的名稱做分別資料表由欄列所構成的二維陣列

欄包含欄位名資料型態 及其他可判斷的資訊列是由全部欄位構成一筆一

筆的紀錄 create table 語法用在建立一個新的資料表語法格式如下

create table tablename (column1 data type column2 data type column3 data type)

Format of create table if you were to use optional constraints

create table tablename (column1 data type [constraint] column2 data type [constraint] column3 data type [constraint]) [ ] = optional

Note You may have as many columns as youd like and the constraints are optional

80

Example

create table employee (first varchar(15) last varchar(20) age number(3) address varchar(30) city varchar(20) state varchar(20))

注意建立資料表格式要以括號把前後框住而最後以(分號)做結尾

欄位名不要超過 30個字元長而且不要使用 sql 的關鍵字(如 where select等)而在後面接是型態的宣告(如字串數字日期格式等)

資料型態是來描述欄位的方式如一個欄位Last_Name 是一個姓氏可以使用varchar (可變動長度字串) 資料型態

以下是幾個常見的資料庫型態 char(size) 固定長度字串最長為 255 位元 varchar(size) 變動長度字串最大字元數以 size 來指定 number(size) 數值格式可以是整數也可以是小數最大數字以 size 位數判

斷未指定小數位數由系統內定 date 日期格式 number(sized) 數值格式最大數字以 size 位數判斷d 為小數位數整數位

數為 size-d 位

有何限制當資料表被建立通常有一或數個欄位是要使用來做關聯的功

能 例如unique 限制(唯一值)兩筆記錄不可以相同的值 not null (非空值)該欄位一定要輸入資料不可是空的primary key (主鍵)是每一筆記錄識別的主要方式

Drop a table drop table 刪除資料表(其中的資料也會一併刪除)

drop table tablename

Example

81

drop table 和刪除全部資料是不同的刪除全部資料欄位名稱資訊等還會

存在但刪除資料表會把這一些也一併移除掉

如何查詢資料

Select 基本用法

select 語法是關連式資料庫最常用的部份可以取得你想要的資料這是一個

簡單的範例 select column1[column2etc] from tablename [where condition] [] = optional 在 select 之後所列欄位名則是要顯示的資料部份你可以一一列出各欄位

名或是以 (星號)來代表選擇全部的欄位 from 之後放資料表名稱 where 子句 (選項) 指定要過濾的條件符合者才會顯現 where 可使用的條件運算元 = 等於 gt 大於 lt 小於 gt= 大或等於 lt= 小或等於 ltgt 大相等 LIKE 相似 For example select first last city

82

from empinfo where first LIKE Er 以Er 為開頭的字串就符合要以單引號框住 Or you can specify select first last from empinfo where last LIKE s 最後一字為 S 就符合 select from empinfo where first = Eric 則表示 first name 一定要是 Eric 才可以 範例資料表empinfo 統計函數

MIN 傳回指定欄位最小值

MAX 傳回指定欄位最大值

SUM 傳回指定欄位總和

AVG 傳回指定欄位平均值

COUNT 傳回指定欄位的筆數

COUNT() 傳回資料庫中的總筆數

統計函數使用於資料表中的數值欄位配合 SELECT 語法使用 只用於總結特定單一欄位可以配合 GROUP BY 做篩選但也可以不使用 GROUP BY 語句For example

SELECT AVG(salary) FROM employee

83

傳回全部 salary 平均值

Another example

SELECT AVG(salary) FROM employee WHERE title = Programmer

傳回 salary 平均值條件為 employees 資料表中當 title 等於 Programmer

Example

SELECT Count() FROM employees

傳回 employees 資料表中紀錄總筆數

GROUP BY 語法 SELECT column1 SUM(column2) FROM list-of-tables GROUP BY column-list The GROUP BY 語句可以先以所列的欄位為條件分組排序在一起(可以多欄

位) example 要列出每一個 dept 中最高 salary 值 SELECT max(salary) dept FROM employee GROUP BY dept HAVING 語法

SELECT column1 SUM(column2) FROM list-of-tables GROUP BY column-list HAVING condition

HAVING 子句是 GROUP BY 的一部份用來過濾在 GROUP BY 所選出的資料功能如同 select 命令中 where 條件式一樣只是 HAVING 必需配合 GROUP BY 使用

我們以例子來說明我們要取得每一公司名及每一公司的薪水平均值輸入如下

84

SELECT dept avg(salary) FROM employee GROUP BY dept

但如果我們只列出薪資平均值超過 20000元的公司資料

SELECT dept avg(salary) FROM employee GROUP BY dept HAVING avg(salary) gt 20000

ORDER BY子句語法

SELECT column1 SUM(column2) FROM list-of-tables ORDER BY column-list [ASC | DESC]

[ ] =選項

ORDER BY是一個選項子句當你以排序方式來顯示資料(正向由小到大反向由大到小)以指定的欄位資料做排序

ASC = 正向- 預設值 DESC = 反向排序

For example

SELECT employee_id dept name age salary FROM employee_info WHERE dept = Sales ORDER BY salary

以上列出公司代號公司名銷售員人名年紀及薪資而條件是公司名為 Sales 顯示順序以薪資多少排序(由小到大為預設值)

如果要以多個欄位做排序要以逗號做分隔如下

SELECT employee_id dept name age salary FROM employee_info WHERE dept = Sales ORDER BY salary age DESC

85

結合條件及布林運算 SELECT column1 SUM(column2) FROM list-of-tables WHERE condition1 AND condition2 AND運算可以結兩個或以上的條件放在 WHERE子句中 兩者都要為真才

會顯示該筆記錄 OR 運算可以結兩個或以上敘述放在 WHERE子句中只要其中一個為直就

會顯示該筆記錄 For example SELECT employeeid firstname lastname title salary FROM employee_info WHERE salary gt= 5000000 AND title = Programmer 必需要薪資大於等於 50000而且職稱為 Programmer同時符合才會顯示該筆資料 以下以括號括住雖然不是必需的但如此比較容易讀 SELECT employeeid firstname lastname title salary FROM employee_info WHERE (salary gt= 5000000) AND (title = Programmer) 另外範例 SELECT firstname lastname title salary FROM employee_info WHERE (title = Sales) OR (title = Programmer) 條件為只要是 Sales 或 Programmer 職稱的就會被列出 IN and BETWEEN 子句

SELECT column1 SUM(column2) FROM list-of-tables WHERE column3 IN (list-of-values) SELECT column1 SUM(column2) FROM list-of-tables WHERE column3 BETWEEN value1 AND value2 IN 子句使用在列舉項目的使用上也就是分別測試是否符合所列的值 For example

86

SELECT employeeid lastname salary FROM employee_info WHERE lastname IN (Hernandez Jones Roberts Ruiz) 條件為姓氏(astname)要符合 Hernandez Jones Roberts or Ruiz 其中一個才會被傳回 IN運算元也可以使用 OR 的語法來取代如下結果相同 SELECT employeeid lastname salary FROM employee_info WHERE lastname = Hernandez OR lastname = Jones OR lastname = Roberts OR lastname = Ruiz 但使用 IN 句子比較短也比較易懂 你也可以使用 NOT IN 來去掉不要的記錄 BETWEEN 運算元使用在判斷是否存在兩個數值之間 For example SELECT employeeid age lastname salary FROM employee_info WHERE age BETWEEN 30 AND 40 傳回年紀 30歲到 40歲之間的資料(含 30及 40歲者) 相同的也可以使用以下語法來達到相同的結果 SELECT employeeid age lastname salary FROM employee_info WHERE age gt= 30 AND age lt= 40 你也可使用 NOT BETWEEN 來濾掉中間值的資料 數學運算 標準 ANSI SQL-92 提供以下運算

87

+ 加

- 減

餘數

餘數為除法後剩整數這不在標準的 ANSI SQL 中但大部份的資料庫都會支

援這運算元以下列出有用的函數雖不在 ANSI SQL-92 提供但一般資料庫

也會支援他們

ABS(x) 傳回 x 絕對值

SIGN(x) returns the sign of input x as -1 0 or 1 (negative zero or positive respectively)

MOD(xy) 餘數 - returns the integer remainder of x divided by y (同 xy)

FLOOR(x) 傳回小或等於 x 的最大整數值

CEILING(x) or CEIL(x)

傳回大或等於 x 的最小整數值

POWER(xy) x的 y 次方

ROUND(x) 把 x 四捨五入為整數

ROUND(xd) 四捨五入取到小數 d 位

SQRT(x) x 開平方

For example SELECT round(salary) firstname FROM employee_info 傳回薪資取到整數位

如何新增資料

insert 加入一筆新紀錄到資料表中 insert into tablename (first_columnlast_column) values (first_valuelast_value) [] = optional Example insert into employee

88

(first last age address city state) values (Luke Duke 45 2130 Boars Nest Hazard Co Georgia) Note 字串要以單引號住如string 數字框住也無妨 insert into 後面接資料表名稱再接以括號括住的欄位名在 values 後括號分別對映各欄位的值 以上的例子新增了一筆名(first) 為 Luke而住所(state) 為 Georgia 的資料

如何刪除資料

delete 可以刪除單筆或多筆紀錄 delete from tablename where columnname OPERATOR value [and|or column OPERATOR value] [ ] = optional Examples delete from employee Note 如果你沒有指定 where 子句那麼全部的紀錄都會被刪除 delete from employee where lastname = May delete from employee where firstname = Mike or firstname = Eric delete from 接著資料表名 再接著是條件式判斷沒有條件式則全部紀錄會

被刪除

如何更新資料

update 用來更新你所指定的記錄要和 WHERE 配合小心使用 語法 update tablename set columnname = newvalue[nextcolumn = newvalue2] where columnname OPERATOR value [and|or column OPERATOR value] [] = optional Examples

89

update phone_book set area_code = 623 where prefix = 979 update phone_book set last_name = Smith prefix=555 suffix=9292 where last_name = Jones update employee set age = age+1 where first_name=Mary and last_name=Williams

90

附錄二Replication

測試環境

RedHat 90 + MySQL 32358 MySQL資料庫路徑 varlibmysql MySQL設定檔 etcmycnf Master IP 1921680100 Slave IP 1921680200 請至下列網址下載最新MySQL 32358套件並利用rpm ndashUvh 更新 httpupdatesredhatcom9enosi386

圖 最新 MySQL 套件

測試架構圖

91

1921680100

1921680200Master Server

erveSlave S r

圖 測試架構圖

測試步驟

Master server 部份 Step1 確認 MasterSlave機器上所裝的 MySQL版本能進行

replication( 32329 or higher ) Step2 在 Master MySQL上開放一個帳號給 Slave mysql ndashu root ndashp mysqlgtGRANT FILE ON TO repl1921680200 IDENTIFIED BY lsquoabc123rsquo mysqlgtq 上面是 Master開放一個帳號 repl密碼 abc123給 IP1921680200有檔案處理

的權限 Step3 shutdown MySQL on the Master mysqladmin ndashu root ndashp shutdown Step4 備份 Master所有資料庫 tar ndashcvf tmpmysql-snapshottar varlibmysql 注意tar的時候MySQL是要在 stop情況下 在mysql (wwwmysqlcom) 網站的FAQ有不用shutdown的方法

92

Step5 在 master機器上修改etcmycnf 在[mysqld]區段內加入參數 log-bin server-id=這邊設定 server-id=1 sql-bin-update-same binlog-do-db=CRM只針對 CRM資料庫做紀錄 Step6 Restart MySQL on the master service mysqld start 此時因為有加入 log-bin 參數因此開始有 index產生了在varlibmysql目錄下

有index檔案紀錄資料庫的異動 log Slave server 部份 Step1 在 slave設定etcmycnf 在[mysqld]區段加入 master-host= master-user= master-password= master-port= server-id= 這邊設定 master-host=1921680100 master-user=repl master-password=abc123 master-port=3306 server-id=2 master-connect-retry=60預設重試間隔 60秒 replicate-do-db=CRM告訴 slave只做 CRM資料庫的更新 log-slave-updates Step2 將 master上的 mysql-snapshottar copy到 slave上 用 ftp傳到 slave的tmp Step3 解壓縮 Master資料庫至 Slave Server上 cd varlib tar xvf tmpmysql-snapshottar chown ndashR mysqlmysql mysql

93

chmod ndashR 770 mysql (視情況) Step4 Restart MySQL on the slave server 這時在varlibmysql目錄會出現 masterinfo此檔案紀錄了 Master MySQL server的資訊

狀況測試

One-way replication

1921680100

1921680200Master Server

erveSlave S r

圖 One-way replication架構圖 Step1 Master跟 Slave網路及服務都正常情況下由 Master端異動資料後 到 Slave端瀏覽資料檢視是否有進行 replication Step2 模擬 Slave Server 當機 可用在於 slave真的當機或是 Slave 不一定需要一直跟 master connect將Slave MySQL server shutdown由 Master端異動資料到 slave端瀏覽此時Slave應該沒有被 replication 更新然後再將 Slave端 MySQL server start起來

預設 60秒後 Slave會嘗試跟 Master要求進行 replication再去 Slave端檢視是否有更新資料

94

Step3 模擬 Master當機因為是設定 One-way replication一旦 Master Server Slave端沒有 Master的 source可以 download Two-way replication 基於 Master當機狀況於是發展雙向 Replication即 1921680100 ( Host A ) 1921680200 ( Host B )都分別擔任 MasterSlave身分

1921680100

1921680200er

Server B MasterSlave Server

Server A MasterSlave Serv

圖 Two-way replication架構圖 以下是針對兩台 MySQL伺服器進行雙向 Replication Step1觀念同單向 replication只是改成 Master也有 Slave身分 Slave也有Master的身分先分別在 Server AServer B 都去 grant一個進行 replication的身分 [A]mysqlgtGRANT FILE ON TO repl1921680200 IDENTIFIED BY lsquoabc123rsquo [B]mysqlgt GRANT FILE ON TO repl1921680100 IDENTIFIED BY lsquoabc123rsquo Step2做完單向 replication後stop Server Aserver B MySQL service此時 AB資料是一樣的

95

修改etcmycnf設定 範例 Server A [mysqld] datadir=varlibmysql socket=varlibmysqlmysqlsock server-id=1 log-bin sql-bin-update-same binlog-do-db=CRM master-host=1921680200 master-user=repl master-password=abc123 log-slave-updates master-connect-retry=60 replicate-do-db=CRM Server B [mysqld] datadir=varlibmysql socket=varlibmysqlmysqlsock server-id=2 log-bin sql-bin-update-same binlog-do-db=CRM master-host=1921680100 master-user=repl master-password=abc123 log-slave-updates master-connect-retry=60 replicate-do-db=CRM 分別 start Server AServer B MySQL後此時雙方都是 MasterSlave身分一旦哪一方資料異動就會通知對方來 replication-若 replication失效則必須將Server AServer B的masterinfo及index00x 都砍掉然後分別 restart MySQL server進行測試檢視成果 實務上通常如果需要做Two-way replication通常會搭配Virtual Server使用

96

在前端架設一台Virtual Server不過此部份不在此份SOP討論範圍內有興趣

的讀者可參考 httpwwwlinuxvirtualserverorg 網站

1921680100 1921680200

Host A MasterSlave Server

Host B MasterSlave Server

Virtual Host

圖 Virtual Server + Two-way replication 架構圖

97

圖 High Availability Linux Virtual Server架構圖

98

  • COSA-SOP-03-006
  • 第一章 簡介
    • 11適用對象 (Audience)
    • 12 MySQL本身
    • 13 MySQL 40版跟50版重大的改進功能
    • 14 各家資料庫軟體比較
      • 第二章 前置需求
      • 第三章 安裝
        • 31 MySQL安裝
        • 32 phpMyAdmin安裝
        • 33 升級及注意事項
          • 第四章 MySQL管理
            • 41 Webmin 管理介面
            • 42 phpMyAdmin 的操作介面
            • 43管理指令介紹
              • 431 利用mysqladmin設定root的密碼
                  • 第五章 實用範例
                    • 51 任務一Web Base客戶通訊錄
                    • 52 任務二Web Base群組軟體 ( twig )
                      • 第六章 維護及更新程序
                        • 61 日常維護
                        • 62 更新程序
                        • 63 備份重要檔案
                        • 64 離線備份與還原
                        • 65 線上備份與還原
                          • 第七章 問題與解答
                          • 第八章 參考資料
                          • 附錄一 SQL Command 介紹
                          • 附錄二Replication
Page 77: DataBase Server Standard Operation Procedureebooks.lib.ntu.edu.tw/1_file/oss/63/93doc4-5.pdf · 業務的公司帶來了不少壓力,譬如微軟,甲骨文 ... 外的錢用在第三方的資料庫產品上,譬如就可以不用再購買甲骨文公司

如果執行時發生如下 error Run problemerror in loading shared libraries libmysqlclientsoX 將你的 MySQL library path(for exampleusrlocalmysqllibmysql) 加入etcldsoconf and run sbinldconfig -v Q9ASP + MySQL 範例程式 Ans Dim myconn As New ADODBConnection Dim myrs As New Recordset Dim mySQL As String Dim myrows As Long myconnOpen DSN=MyODBCsample mySQL = SELECT from user myrsSource = mySQL Set myrsActiveConnection = myconn myrsCursorLocation = adUseClient myrsOpen myrows = myrsRecordCount myrsClose myconnClose 可參考 httpwwwdwamnetmysqlasp_myodbcasp 有詳細的資料 Q10如何將 MySQL中的資料庫匯出成txt檔 Ans select from TableName into outfile textxls all result fields will seperate by tab

77

第八章 參考資料

英文部份 網址 1 httpwwwmysqlcom MySQL 網站有第一手有關 MySQL的資料 2 httpwwwmysqlcomdocenReplicationhtml 有關 MySQL Replication 的文件 3 httpwwwgeocitiescomsqlhomefaqstore_blobhtml 如何在 MySQL 存放 BLOB的資料 4httpwwwsapdborg 有關 SAP跟 MySQL相關合作的網站 書藉 1 Cooking with MySQL

Paul DuBois has selected sample recipes from the hundreds youll find in his book MySQL

Cookbook In this third and final series of excerpts showcasing these recipes learn how to

compute team standings how to calculate the differences between successive Dec 26

2002 2 Tips for Building Web Database Applications with PHP and MySQL by Hugh E Williams co-author of Web Database Applications with PHP amp MySQL 04042002

3 Managing and Using MySQL 2nd Edition By Tim King George Reese Randy Jay Yarger

4 MySQL Cookbook By Paul DuBoisPublisher OReillyPub Date October 2002

中文部份

78

1 httplinuxtncedutwtechdocmysqlmysql_docmanual_tochtml MySQL 中文手冊 2 httpchenshloxaedutwphpZ_1php PHP+MySQ程式研習設計網站 3 httplinuxtncedutwtechdocbanicdownhtml PHP 4 手冊 4 httpwwwtncedutwadmin_zonephp台南縣教育網網路中心有很多 Linux相關文件 5 httpdobtncedutw網站建置百寶箱有很多 PHP MySQL 相關範例程式 5 httpwwwdbworldcomtw資料庫專家電子雜誌介紹資料庫的重要觀念及名詞

79

附錄一 SQL Command 介紹

SQL (讀音ess-que-el) 是一種結構查詢語法SQL 使用於資料庫交流

傳遞相容於 ANSI (American National Standards Institute) 是一套標準的關聯

式資料庫語言 SQL 語言是執行更新或從資料系統獲取資料一般常見的關聯

資料庫系統都有提供 SQL 如 Oracle Sybase Microsoft SQL Server Access Ingres 等雖然大部份的資料庫都有提供 SQL 但也多提供了自已獨特的語

法造成了不相容的情形但標準基本的語法是相通的如Select Insert Update Delete Create and Drop 每一個系統都有支援

Table相關 Command

Create Table

關聯式資料庫包含有很多元件稱為資料表(tables) 把資料或訊息放在資

料表中 資料表是以不同的名稱做分別資料表由欄列所構成的二維陣列

欄包含欄位名資料型態 及其他可判斷的資訊列是由全部欄位構成一筆一

筆的紀錄 create table 語法用在建立一個新的資料表語法格式如下

create table tablename (column1 data type column2 data type column3 data type)

Format of create table if you were to use optional constraints

create table tablename (column1 data type [constraint] column2 data type [constraint] column3 data type [constraint]) [ ] = optional

Note You may have as many columns as youd like and the constraints are optional

80

Example

create table employee (first varchar(15) last varchar(20) age number(3) address varchar(30) city varchar(20) state varchar(20))

注意建立資料表格式要以括號把前後框住而最後以(分號)做結尾

欄位名不要超過 30個字元長而且不要使用 sql 的關鍵字(如 where select等)而在後面接是型態的宣告(如字串數字日期格式等)

資料型態是來描述欄位的方式如一個欄位Last_Name 是一個姓氏可以使用varchar (可變動長度字串) 資料型態

以下是幾個常見的資料庫型態 char(size) 固定長度字串最長為 255 位元 varchar(size) 變動長度字串最大字元數以 size 來指定 number(size) 數值格式可以是整數也可以是小數最大數字以 size 位數判

斷未指定小數位數由系統內定 date 日期格式 number(sized) 數值格式最大數字以 size 位數判斷d 為小數位數整數位

數為 size-d 位

有何限制當資料表被建立通常有一或數個欄位是要使用來做關聯的功

能 例如unique 限制(唯一值)兩筆記錄不可以相同的值 not null (非空值)該欄位一定要輸入資料不可是空的primary key (主鍵)是每一筆記錄識別的主要方式

Drop a table drop table 刪除資料表(其中的資料也會一併刪除)

drop table tablename

Example

81

drop table 和刪除全部資料是不同的刪除全部資料欄位名稱資訊等還會

存在但刪除資料表會把這一些也一併移除掉

如何查詢資料

Select 基本用法

select 語法是關連式資料庫最常用的部份可以取得你想要的資料這是一個

簡單的範例 select column1[column2etc] from tablename [where condition] [] = optional 在 select 之後所列欄位名則是要顯示的資料部份你可以一一列出各欄位

名或是以 (星號)來代表選擇全部的欄位 from 之後放資料表名稱 where 子句 (選項) 指定要過濾的條件符合者才會顯現 where 可使用的條件運算元 = 等於 gt 大於 lt 小於 gt= 大或等於 lt= 小或等於 ltgt 大相等 LIKE 相似 For example select first last city

82

from empinfo where first LIKE Er 以Er 為開頭的字串就符合要以單引號框住 Or you can specify select first last from empinfo where last LIKE s 最後一字為 S 就符合 select from empinfo where first = Eric 則表示 first name 一定要是 Eric 才可以 範例資料表empinfo 統計函數

MIN 傳回指定欄位最小值

MAX 傳回指定欄位最大值

SUM 傳回指定欄位總和

AVG 傳回指定欄位平均值

COUNT 傳回指定欄位的筆數

COUNT() 傳回資料庫中的總筆數

統計函數使用於資料表中的數值欄位配合 SELECT 語法使用 只用於總結特定單一欄位可以配合 GROUP BY 做篩選但也可以不使用 GROUP BY 語句For example

SELECT AVG(salary) FROM employee

83

傳回全部 salary 平均值

Another example

SELECT AVG(salary) FROM employee WHERE title = Programmer

傳回 salary 平均值條件為 employees 資料表中當 title 等於 Programmer

Example

SELECT Count() FROM employees

傳回 employees 資料表中紀錄總筆數

GROUP BY 語法 SELECT column1 SUM(column2) FROM list-of-tables GROUP BY column-list The GROUP BY 語句可以先以所列的欄位為條件分組排序在一起(可以多欄

位) example 要列出每一個 dept 中最高 salary 值 SELECT max(salary) dept FROM employee GROUP BY dept HAVING 語法

SELECT column1 SUM(column2) FROM list-of-tables GROUP BY column-list HAVING condition

HAVING 子句是 GROUP BY 的一部份用來過濾在 GROUP BY 所選出的資料功能如同 select 命令中 where 條件式一樣只是 HAVING 必需配合 GROUP BY 使用

我們以例子來說明我們要取得每一公司名及每一公司的薪水平均值輸入如下

84

SELECT dept avg(salary) FROM employee GROUP BY dept

但如果我們只列出薪資平均值超過 20000元的公司資料

SELECT dept avg(salary) FROM employee GROUP BY dept HAVING avg(salary) gt 20000

ORDER BY子句語法

SELECT column1 SUM(column2) FROM list-of-tables ORDER BY column-list [ASC | DESC]

[ ] =選項

ORDER BY是一個選項子句當你以排序方式來顯示資料(正向由小到大反向由大到小)以指定的欄位資料做排序

ASC = 正向- 預設值 DESC = 反向排序

For example

SELECT employee_id dept name age salary FROM employee_info WHERE dept = Sales ORDER BY salary

以上列出公司代號公司名銷售員人名年紀及薪資而條件是公司名為 Sales 顯示順序以薪資多少排序(由小到大為預設值)

如果要以多個欄位做排序要以逗號做分隔如下

SELECT employee_id dept name age salary FROM employee_info WHERE dept = Sales ORDER BY salary age DESC

85

結合條件及布林運算 SELECT column1 SUM(column2) FROM list-of-tables WHERE condition1 AND condition2 AND運算可以結兩個或以上的條件放在 WHERE子句中 兩者都要為真才

會顯示該筆記錄 OR 運算可以結兩個或以上敘述放在 WHERE子句中只要其中一個為直就

會顯示該筆記錄 For example SELECT employeeid firstname lastname title salary FROM employee_info WHERE salary gt= 5000000 AND title = Programmer 必需要薪資大於等於 50000而且職稱為 Programmer同時符合才會顯示該筆資料 以下以括號括住雖然不是必需的但如此比較容易讀 SELECT employeeid firstname lastname title salary FROM employee_info WHERE (salary gt= 5000000) AND (title = Programmer) 另外範例 SELECT firstname lastname title salary FROM employee_info WHERE (title = Sales) OR (title = Programmer) 條件為只要是 Sales 或 Programmer 職稱的就會被列出 IN and BETWEEN 子句

SELECT column1 SUM(column2) FROM list-of-tables WHERE column3 IN (list-of-values) SELECT column1 SUM(column2) FROM list-of-tables WHERE column3 BETWEEN value1 AND value2 IN 子句使用在列舉項目的使用上也就是分別測試是否符合所列的值 For example

86

SELECT employeeid lastname salary FROM employee_info WHERE lastname IN (Hernandez Jones Roberts Ruiz) 條件為姓氏(astname)要符合 Hernandez Jones Roberts or Ruiz 其中一個才會被傳回 IN運算元也可以使用 OR 的語法來取代如下結果相同 SELECT employeeid lastname salary FROM employee_info WHERE lastname = Hernandez OR lastname = Jones OR lastname = Roberts OR lastname = Ruiz 但使用 IN 句子比較短也比較易懂 你也可以使用 NOT IN 來去掉不要的記錄 BETWEEN 運算元使用在判斷是否存在兩個數值之間 For example SELECT employeeid age lastname salary FROM employee_info WHERE age BETWEEN 30 AND 40 傳回年紀 30歲到 40歲之間的資料(含 30及 40歲者) 相同的也可以使用以下語法來達到相同的結果 SELECT employeeid age lastname salary FROM employee_info WHERE age gt= 30 AND age lt= 40 你也可使用 NOT BETWEEN 來濾掉中間值的資料 數學運算 標準 ANSI SQL-92 提供以下運算

87

+ 加

- 減

餘數

餘數為除法後剩整數這不在標準的 ANSI SQL 中但大部份的資料庫都會支

援這運算元以下列出有用的函數雖不在 ANSI SQL-92 提供但一般資料庫

也會支援他們

ABS(x) 傳回 x 絕對值

SIGN(x) returns the sign of input x as -1 0 or 1 (negative zero or positive respectively)

MOD(xy) 餘數 - returns the integer remainder of x divided by y (同 xy)

FLOOR(x) 傳回小或等於 x 的最大整數值

CEILING(x) or CEIL(x)

傳回大或等於 x 的最小整數值

POWER(xy) x的 y 次方

ROUND(x) 把 x 四捨五入為整數

ROUND(xd) 四捨五入取到小數 d 位

SQRT(x) x 開平方

For example SELECT round(salary) firstname FROM employee_info 傳回薪資取到整數位

如何新增資料

insert 加入一筆新紀錄到資料表中 insert into tablename (first_columnlast_column) values (first_valuelast_value) [] = optional Example insert into employee

88

(first last age address city state) values (Luke Duke 45 2130 Boars Nest Hazard Co Georgia) Note 字串要以單引號住如string 數字框住也無妨 insert into 後面接資料表名稱再接以括號括住的欄位名在 values 後括號分別對映各欄位的值 以上的例子新增了一筆名(first) 為 Luke而住所(state) 為 Georgia 的資料

如何刪除資料

delete 可以刪除單筆或多筆紀錄 delete from tablename where columnname OPERATOR value [and|or column OPERATOR value] [ ] = optional Examples delete from employee Note 如果你沒有指定 where 子句那麼全部的紀錄都會被刪除 delete from employee where lastname = May delete from employee where firstname = Mike or firstname = Eric delete from 接著資料表名 再接著是條件式判斷沒有條件式則全部紀錄會

被刪除

如何更新資料

update 用來更新你所指定的記錄要和 WHERE 配合小心使用 語法 update tablename set columnname = newvalue[nextcolumn = newvalue2] where columnname OPERATOR value [and|or column OPERATOR value] [] = optional Examples

89

update phone_book set area_code = 623 where prefix = 979 update phone_book set last_name = Smith prefix=555 suffix=9292 where last_name = Jones update employee set age = age+1 where first_name=Mary and last_name=Williams

90

附錄二Replication

測試環境

RedHat 90 + MySQL 32358 MySQL資料庫路徑 varlibmysql MySQL設定檔 etcmycnf Master IP 1921680100 Slave IP 1921680200 請至下列網址下載最新MySQL 32358套件並利用rpm ndashUvh 更新 httpupdatesredhatcom9enosi386

圖 最新 MySQL 套件

測試架構圖

91

1921680100

1921680200Master Server

erveSlave S r

圖 測試架構圖

測試步驟

Master server 部份 Step1 確認 MasterSlave機器上所裝的 MySQL版本能進行

replication( 32329 or higher ) Step2 在 Master MySQL上開放一個帳號給 Slave mysql ndashu root ndashp mysqlgtGRANT FILE ON TO repl1921680200 IDENTIFIED BY lsquoabc123rsquo mysqlgtq 上面是 Master開放一個帳號 repl密碼 abc123給 IP1921680200有檔案處理

的權限 Step3 shutdown MySQL on the Master mysqladmin ndashu root ndashp shutdown Step4 備份 Master所有資料庫 tar ndashcvf tmpmysql-snapshottar varlibmysql 注意tar的時候MySQL是要在 stop情況下 在mysql (wwwmysqlcom) 網站的FAQ有不用shutdown的方法

92

Step5 在 master機器上修改etcmycnf 在[mysqld]區段內加入參數 log-bin server-id=這邊設定 server-id=1 sql-bin-update-same binlog-do-db=CRM只針對 CRM資料庫做紀錄 Step6 Restart MySQL on the master service mysqld start 此時因為有加入 log-bin 參數因此開始有 index產生了在varlibmysql目錄下

有index檔案紀錄資料庫的異動 log Slave server 部份 Step1 在 slave設定etcmycnf 在[mysqld]區段加入 master-host= master-user= master-password= master-port= server-id= 這邊設定 master-host=1921680100 master-user=repl master-password=abc123 master-port=3306 server-id=2 master-connect-retry=60預設重試間隔 60秒 replicate-do-db=CRM告訴 slave只做 CRM資料庫的更新 log-slave-updates Step2 將 master上的 mysql-snapshottar copy到 slave上 用 ftp傳到 slave的tmp Step3 解壓縮 Master資料庫至 Slave Server上 cd varlib tar xvf tmpmysql-snapshottar chown ndashR mysqlmysql mysql

93

chmod ndashR 770 mysql (視情況) Step4 Restart MySQL on the slave server 這時在varlibmysql目錄會出現 masterinfo此檔案紀錄了 Master MySQL server的資訊

狀況測試

One-way replication

1921680100

1921680200Master Server

erveSlave S r

圖 One-way replication架構圖 Step1 Master跟 Slave網路及服務都正常情況下由 Master端異動資料後 到 Slave端瀏覽資料檢視是否有進行 replication Step2 模擬 Slave Server 當機 可用在於 slave真的當機或是 Slave 不一定需要一直跟 master connect將Slave MySQL server shutdown由 Master端異動資料到 slave端瀏覽此時Slave應該沒有被 replication 更新然後再將 Slave端 MySQL server start起來

預設 60秒後 Slave會嘗試跟 Master要求進行 replication再去 Slave端檢視是否有更新資料

94

Step3 模擬 Master當機因為是設定 One-way replication一旦 Master Server Slave端沒有 Master的 source可以 download Two-way replication 基於 Master當機狀況於是發展雙向 Replication即 1921680100 ( Host A ) 1921680200 ( Host B )都分別擔任 MasterSlave身分

1921680100

1921680200er

Server B MasterSlave Server

Server A MasterSlave Serv

圖 Two-way replication架構圖 以下是針對兩台 MySQL伺服器進行雙向 Replication Step1觀念同單向 replication只是改成 Master也有 Slave身分 Slave也有Master的身分先分別在 Server AServer B 都去 grant一個進行 replication的身分 [A]mysqlgtGRANT FILE ON TO repl1921680200 IDENTIFIED BY lsquoabc123rsquo [B]mysqlgt GRANT FILE ON TO repl1921680100 IDENTIFIED BY lsquoabc123rsquo Step2做完單向 replication後stop Server Aserver B MySQL service此時 AB資料是一樣的

95

修改etcmycnf設定 範例 Server A [mysqld] datadir=varlibmysql socket=varlibmysqlmysqlsock server-id=1 log-bin sql-bin-update-same binlog-do-db=CRM master-host=1921680200 master-user=repl master-password=abc123 log-slave-updates master-connect-retry=60 replicate-do-db=CRM Server B [mysqld] datadir=varlibmysql socket=varlibmysqlmysqlsock server-id=2 log-bin sql-bin-update-same binlog-do-db=CRM master-host=1921680100 master-user=repl master-password=abc123 log-slave-updates master-connect-retry=60 replicate-do-db=CRM 分別 start Server AServer B MySQL後此時雙方都是 MasterSlave身分一旦哪一方資料異動就會通知對方來 replication-若 replication失效則必須將Server AServer B的masterinfo及index00x 都砍掉然後分別 restart MySQL server進行測試檢視成果 實務上通常如果需要做Two-way replication通常會搭配Virtual Server使用

96

在前端架設一台Virtual Server不過此部份不在此份SOP討論範圍內有興趣

的讀者可參考 httpwwwlinuxvirtualserverorg 網站

1921680100 1921680200

Host A MasterSlave Server

Host B MasterSlave Server

Virtual Host

圖 Virtual Server + Two-way replication 架構圖

97

圖 High Availability Linux Virtual Server架構圖

98

  • COSA-SOP-03-006
  • 第一章 簡介
    • 11適用對象 (Audience)
    • 12 MySQL本身
    • 13 MySQL 40版跟50版重大的改進功能
    • 14 各家資料庫軟體比較
      • 第二章 前置需求
      • 第三章 安裝
        • 31 MySQL安裝
        • 32 phpMyAdmin安裝
        • 33 升級及注意事項
          • 第四章 MySQL管理
            • 41 Webmin 管理介面
            • 42 phpMyAdmin 的操作介面
            • 43管理指令介紹
              • 431 利用mysqladmin設定root的密碼
                  • 第五章 實用範例
                    • 51 任務一Web Base客戶通訊錄
                    • 52 任務二Web Base群組軟體 ( twig )
                      • 第六章 維護及更新程序
                        • 61 日常維護
                        • 62 更新程序
                        • 63 備份重要檔案
                        • 64 離線備份與還原
                        • 65 線上備份與還原
                          • 第七章 問題與解答
                          • 第八章 參考資料
                          • 附錄一 SQL Command 介紹
                          • 附錄二Replication
Page 78: DataBase Server Standard Operation Procedureebooks.lib.ntu.edu.tw/1_file/oss/63/93doc4-5.pdf · 業務的公司帶來了不少壓力,譬如微軟,甲骨文 ... 外的錢用在第三方的資料庫產品上,譬如就可以不用再購買甲骨文公司

第八章 參考資料

英文部份 網址 1 httpwwwmysqlcom MySQL 網站有第一手有關 MySQL的資料 2 httpwwwmysqlcomdocenReplicationhtml 有關 MySQL Replication 的文件 3 httpwwwgeocitiescomsqlhomefaqstore_blobhtml 如何在 MySQL 存放 BLOB的資料 4httpwwwsapdborg 有關 SAP跟 MySQL相關合作的網站 書藉 1 Cooking with MySQL

Paul DuBois has selected sample recipes from the hundreds youll find in his book MySQL

Cookbook In this third and final series of excerpts showcasing these recipes learn how to

compute team standings how to calculate the differences between successive Dec 26

2002 2 Tips for Building Web Database Applications with PHP and MySQL by Hugh E Williams co-author of Web Database Applications with PHP amp MySQL 04042002

3 Managing and Using MySQL 2nd Edition By Tim King George Reese Randy Jay Yarger

4 MySQL Cookbook By Paul DuBoisPublisher OReillyPub Date October 2002

中文部份

78

1 httplinuxtncedutwtechdocmysqlmysql_docmanual_tochtml MySQL 中文手冊 2 httpchenshloxaedutwphpZ_1php PHP+MySQ程式研習設計網站 3 httplinuxtncedutwtechdocbanicdownhtml PHP 4 手冊 4 httpwwwtncedutwadmin_zonephp台南縣教育網網路中心有很多 Linux相關文件 5 httpdobtncedutw網站建置百寶箱有很多 PHP MySQL 相關範例程式 5 httpwwwdbworldcomtw資料庫專家電子雜誌介紹資料庫的重要觀念及名詞

79

附錄一 SQL Command 介紹

SQL (讀音ess-que-el) 是一種結構查詢語法SQL 使用於資料庫交流

傳遞相容於 ANSI (American National Standards Institute) 是一套標準的關聯

式資料庫語言 SQL 語言是執行更新或從資料系統獲取資料一般常見的關聯

資料庫系統都有提供 SQL 如 Oracle Sybase Microsoft SQL Server Access Ingres 等雖然大部份的資料庫都有提供 SQL 但也多提供了自已獨特的語

法造成了不相容的情形但標準基本的語法是相通的如Select Insert Update Delete Create and Drop 每一個系統都有支援

Table相關 Command

Create Table

關聯式資料庫包含有很多元件稱為資料表(tables) 把資料或訊息放在資

料表中 資料表是以不同的名稱做分別資料表由欄列所構成的二維陣列

欄包含欄位名資料型態 及其他可判斷的資訊列是由全部欄位構成一筆一

筆的紀錄 create table 語法用在建立一個新的資料表語法格式如下

create table tablename (column1 data type column2 data type column3 data type)

Format of create table if you were to use optional constraints

create table tablename (column1 data type [constraint] column2 data type [constraint] column3 data type [constraint]) [ ] = optional

Note You may have as many columns as youd like and the constraints are optional

80

Example

create table employee (first varchar(15) last varchar(20) age number(3) address varchar(30) city varchar(20) state varchar(20))

注意建立資料表格式要以括號把前後框住而最後以(分號)做結尾

欄位名不要超過 30個字元長而且不要使用 sql 的關鍵字(如 where select等)而在後面接是型態的宣告(如字串數字日期格式等)

資料型態是來描述欄位的方式如一個欄位Last_Name 是一個姓氏可以使用varchar (可變動長度字串) 資料型態

以下是幾個常見的資料庫型態 char(size) 固定長度字串最長為 255 位元 varchar(size) 變動長度字串最大字元數以 size 來指定 number(size) 數值格式可以是整數也可以是小數最大數字以 size 位數判

斷未指定小數位數由系統內定 date 日期格式 number(sized) 數值格式最大數字以 size 位數判斷d 為小數位數整數位

數為 size-d 位

有何限制當資料表被建立通常有一或數個欄位是要使用來做關聯的功

能 例如unique 限制(唯一值)兩筆記錄不可以相同的值 not null (非空值)該欄位一定要輸入資料不可是空的primary key (主鍵)是每一筆記錄識別的主要方式

Drop a table drop table 刪除資料表(其中的資料也會一併刪除)

drop table tablename

Example

81

drop table 和刪除全部資料是不同的刪除全部資料欄位名稱資訊等還會

存在但刪除資料表會把這一些也一併移除掉

如何查詢資料

Select 基本用法

select 語法是關連式資料庫最常用的部份可以取得你想要的資料這是一個

簡單的範例 select column1[column2etc] from tablename [where condition] [] = optional 在 select 之後所列欄位名則是要顯示的資料部份你可以一一列出各欄位

名或是以 (星號)來代表選擇全部的欄位 from 之後放資料表名稱 where 子句 (選項) 指定要過濾的條件符合者才會顯現 where 可使用的條件運算元 = 等於 gt 大於 lt 小於 gt= 大或等於 lt= 小或等於 ltgt 大相等 LIKE 相似 For example select first last city

82

from empinfo where first LIKE Er 以Er 為開頭的字串就符合要以單引號框住 Or you can specify select first last from empinfo where last LIKE s 最後一字為 S 就符合 select from empinfo where first = Eric 則表示 first name 一定要是 Eric 才可以 範例資料表empinfo 統計函數

MIN 傳回指定欄位最小值

MAX 傳回指定欄位最大值

SUM 傳回指定欄位總和

AVG 傳回指定欄位平均值

COUNT 傳回指定欄位的筆數

COUNT() 傳回資料庫中的總筆數

統計函數使用於資料表中的數值欄位配合 SELECT 語法使用 只用於總結特定單一欄位可以配合 GROUP BY 做篩選但也可以不使用 GROUP BY 語句For example

SELECT AVG(salary) FROM employee

83

傳回全部 salary 平均值

Another example

SELECT AVG(salary) FROM employee WHERE title = Programmer

傳回 salary 平均值條件為 employees 資料表中當 title 等於 Programmer

Example

SELECT Count() FROM employees

傳回 employees 資料表中紀錄總筆數

GROUP BY 語法 SELECT column1 SUM(column2) FROM list-of-tables GROUP BY column-list The GROUP BY 語句可以先以所列的欄位為條件分組排序在一起(可以多欄

位) example 要列出每一個 dept 中最高 salary 值 SELECT max(salary) dept FROM employee GROUP BY dept HAVING 語法

SELECT column1 SUM(column2) FROM list-of-tables GROUP BY column-list HAVING condition

HAVING 子句是 GROUP BY 的一部份用來過濾在 GROUP BY 所選出的資料功能如同 select 命令中 where 條件式一樣只是 HAVING 必需配合 GROUP BY 使用

我們以例子來說明我們要取得每一公司名及每一公司的薪水平均值輸入如下

84

SELECT dept avg(salary) FROM employee GROUP BY dept

但如果我們只列出薪資平均值超過 20000元的公司資料

SELECT dept avg(salary) FROM employee GROUP BY dept HAVING avg(salary) gt 20000

ORDER BY子句語法

SELECT column1 SUM(column2) FROM list-of-tables ORDER BY column-list [ASC | DESC]

[ ] =選項

ORDER BY是一個選項子句當你以排序方式來顯示資料(正向由小到大反向由大到小)以指定的欄位資料做排序

ASC = 正向- 預設值 DESC = 反向排序

For example

SELECT employee_id dept name age salary FROM employee_info WHERE dept = Sales ORDER BY salary

以上列出公司代號公司名銷售員人名年紀及薪資而條件是公司名為 Sales 顯示順序以薪資多少排序(由小到大為預設值)

如果要以多個欄位做排序要以逗號做分隔如下

SELECT employee_id dept name age salary FROM employee_info WHERE dept = Sales ORDER BY salary age DESC

85

結合條件及布林運算 SELECT column1 SUM(column2) FROM list-of-tables WHERE condition1 AND condition2 AND運算可以結兩個或以上的條件放在 WHERE子句中 兩者都要為真才

會顯示該筆記錄 OR 運算可以結兩個或以上敘述放在 WHERE子句中只要其中一個為直就

會顯示該筆記錄 For example SELECT employeeid firstname lastname title salary FROM employee_info WHERE salary gt= 5000000 AND title = Programmer 必需要薪資大於等於 50000而且職稱為 Programmer同時符合才會顯示該筆資料 以下以括號括住雖然不是必需的但如此比較容易讀 SELECT employeeid firstname lastname title salary FROM employee_info WHERE (salary gt= 5000000) AND (title = Programmer) 另外範例 SELECT firstname lastname title salary FROM employee_info WHERE (title = Sales) OR (title = Programmer) 條件為只要是 Sales 或 Programmer 職稱的就會被列出 IN and BETWEEN 子句

SELECT column1 SUM(column2) FROM list-of-tables WHERE column3 IN (list-of-values) SELECT column1 SUM(column2) FROM list-of-tables WHERE column3 BETWEEN value1 AND value2 IN 子句使用在列舉項目的使用上也就是分別測試是否符合所列的值 For example

86

SELECT employeeid lastname salary FROM employee_info WHERE lastname IN (Hernandez Jones Roberts Ruiz) 條件為姓氏(astname)要符合 Hernandez Jones Roberts or Ruiz 其中一個才會被傳回 IN運算元也可以使用 OR 的語法來取代如下結果相同 SELECT employeeid lastname salary FROM employee_info WHERE lastname = Hernandez OR lastname = Jones OR lastname = Roberts OR lastname = Ruiz 但使用 IN 句子比較短也比較易懂 你也可以使用 NOT IN 來去掉不要的記錄 BETWEEN 運算元使用在判斷是否存在兩個數值之間 For example SELECT employeeid age lastname salary FROM employee_info WHERE age BETWEEN 30 AND 40 傳回年紀 30歲到 40歲之間的資料(含 30及 40歲者) 相同的也可以使用以下語法來達到相同的結果 SELECT employeeid age lastname salary FROM employee_info WHERE age gt= 30 AND age lt= 40 你也可使用 NOT BETWEEN 來濾掉中間值的資料 數學運算 標準 ANSI SQL-92 提供以下運算

87

+ 加

- 減

餘數

餘數為除法後剩整數這不在標準的 ANSI SQL 中但大部份的資料庫都會支

援這運算元以下列出有用的函數雖不在 ANSI SQL-92 提供但一般資料庫

也會支援他們

ABS(x) 傳回 x 絕對值

SIGN(x) returns the sign of input x as -1 0 or 1 (negative zero or positive respectively)

MOD(xy) 餘數 - returns the integer remainder of x divided by y (同 xy)

FLOOR(x) 傳回小或等於 x 的最大整數值

CEILING(x) or CEIL(x)

傳回大或等於 x 的最小整數值

POWER(xy) x的 y 次方

ROUND(x) 把 x 四捨五入為整數

ROUND(xd) 四捨五入取到小數 d 位

SQRT(x) x 開平方

For example SELECT round(salary) firstname FROM employee_info 傳回薪資取到整數位

如何新增資料

insert 加入一筆新紀錄到資料表中 insert into tablename (first_columnlast_column) values (first_valuelast_value) [] = optional Example insert into employee

88

(first last age address city state) values (Luke Duke 45 2130 Boars Nest Hazard Co Georgia) Note 字串要以單引號住如string 數字框住也無妨 insert into 後面接資料表名稱再接以括號括住的欄位名在 values 後括號分別對映各欄位的值 以上的例子新增了一筆名(first) 為 Luke而住所(state) 為 Georgia 的資料

如何刪除資料

delete 可以刪除單筆或多筆紀錄 delete from tablename where columnname OPERATOR value [and|or column OPERATOR value] [ ] = optional Examples delete from employee Note 如果你沒有指定 where 子句那麼全部的紀錄都會被刪除 delete from employee where lastname = May delete from employee where firstname = Mike or firstname = Eric delete from 接著資料表名 再接著是條件式判斷沒有條件式則全部紀錄會

被刪除

如何更新資料

update 用來更新你所指定的記錄要和 WHERE 配合小心使用 語法 update tablename set columnname = newvalue[nextcolumn = newvalue2] where columnname OPERATOR value [and|or column OPERATOR value] [] = optional Examples

89

update phone_book set area_code = 623 where prefix = 979 update phone_book set last_name = Smith prefix=555 suffix=9292 where last_name = Jones update employee set age = age+1 where first_name=Mary and last_name=Williams

90

附錄二Replication

測試環境

RedHat 90 + MySQL 32358 MySQL資料庫路徑 varlibmysql MySQL設定檔 etcmycnf Master IP 1921680100 Slave IP 1921680200 請至下列網址下載最新MySQL 32358套件並利用rpm ndashUvh 更新 httpupdatesredhatcom9enosi386

圖 最新 MySQL 套件

測試架構圖

91

1921680100

1921680200Master Server

erveSlave S r

圖 測試架構圖

測試步驟

Master server 部份 Step1 確認 MasterSlave機器上所裝的 MySQL版本能進行

replication( 32329 or higher ) Step2 在 Master MySQL上開放一個帳號給 Slave mysql ndashu root ndashp mysqlgtGRANT FILE ON TO repl1921680200 IDENTIFIED BY lsquoabc123rsquo mysqlgtq 上面是 Master開放一個帳號 repl密碼 abc123給 IP1921680200有檔案處理

的權限 Step3 shutdown MySQL on the Master mysqladmin ndashu root ndashp shutdown Step4 備份 Master所有資料庫 tar ndashcvf tmpmysql-snapshottar varlibmysql 注意tar的時候MySQL是要在 stop情況下 在mysql (wwwmysqlcom) 網站的FAQ有不用shutdown的方法

92

Step5 在 master機器上修改etcmycnf 在[mysqld]區段內加入參數 log-bin server-id=這邊設定 server-id=1 sql-bin-update-same binlog-do-db=CRM只針對 CRM資料庫做紀錄 Step6 Restart MySQL on the master service mysqld start 此時因為有加入 log-bin 參數因此開始有 index產生了在varlibmysql目錄下

有index檔案紀錄資料庫的異動 log Slave server 部份 Step1 在 slave設定etcmycnf 在[mysqld]區段加入 master-host= master-user= master-password= master-port= server-id= 這邊設定 master-host=1921680100 master-user=repl master-password=abc123 master-port=3306 server-id=2 master-connect-retry=60預設重試間隔 60秒 replicate-do-db=CRM告訴 slave只做 CRM資料庫的更新 log-slave-updates Step2 將 master上的 mysql-snapshottar copy到 slave上 用 ftp傳到 slave的tmp Step3 解壓縮 Master資料庫至 Slave Server上 cd varlib tar xvf tmpmysql-snapshottar chown ndashR mysqlmysql mysql

93

chmod ndashR 770 mysql (視情況) Step4 Restart MySQL on the slave server 這時在varlibmysql目錄會出現 masterinfo此檔案紀錄了 Master MySQL server的資訊

狀況測試

One-way replication

1921680100

1921680200Master Server

erveSlave S r

圖 One-way replication架構圖 Step1 Master跟 Slave網路及服務都正常情況下由 Master端異動資料後 到 Slave端瀏覽資料檢視是否有進行 replication Step2 模擬 Slave Server 當機 可用在於 slave真的當機或是 Slave 不一定需要一直跟 master connect將Slave MySQL server shutdown由 Master端異動資料到 slave端瀏覽此時Slave應該沒有被 replication 更新然後再將 Slave端 MySQL server start起來

預設 60秒後 Slave會嘗試跟 Master要求進行 replication再去 Slave端檢視是否有更新資料

94

Step3 模擬 Master當機因為是設定 One-way replication一旦 Master Server Slave端沒有 Master的 source可以 download Two-way replication 基於 Master當機狀況於是發展雙向 Replication即 1921680100 ( Host A ) 1921680200 ( Host B )都分別擔任 MasterSlave身分

1921680100

1921680200er

Server B MasterSlave Server

Server A MasterSlave Serv

圖 Two-way replication架構圖 以下是針對兩台 MySQL伺服器進行雙向 Replication Step1觀念同單向 replication只是改成 Master也有 Slave身分 Slave也有Master的身分先分別在 Server AServer B 都去 grant一個進行 replication的身分 [A]mysqlgtGRANT FILE ON TO repl1921680200 IDENTIFIED BY lsquoabc123rsquo [B]mysqlgt GRANT FILE ON TO repl1921680100 IDENTIFIED BY lsquoabc123rsquo Step2做完單向 replication後stop Server Aserver B MySQL service此時 AB資料是一樣的

95

修改etcmycnf設定 範例 Server A [mysqld] datadir=varlibmysql socket=varlibmysqlmysqlsock server-id=1 log-bin sql-bin-update-same binlog-do-db=CRM master-host=1921680200 master-user=repl master-password=abc123 log-slave-updates master-connect-retry=60 replicate-do-db=CRM Server B [mysqld] datadir=varlibmysql socket=varlibmysqlmysqlsock server-id=2 log-bin sql-bin-update-same binlog-do-db=CRM master-host=1921680100 master-user=repl master-password=abc123 log-slave-updates master-connect-retry=60 replicate-do-db=CRM 分別 start Server AServer B MySQL後此時雙方都是 MasterSlave身分一旦哪一方資料異動就會通知對方來 replication-若 replication失效則必須將Server AServer B的masterinfo及index00x 都砍掉然後分別 restart MySQL server進行測試檢視成果 實務上通常如果需要做Two-way replication通常會搭配Virtual Server使用

96

在前端架設一台Virtual Server不過此部份不在此份SOP討論範圍內有興趣

的讀者可參考 httpwwwlinuxvirtualserverorg 網站

1921680100 1921680200

Host A MasterSlave Server

Host B MasterSlave Server

Virtual Host

圖 Virtual Server + Two-way replication 架構圖

97

圖 High Availability Linux Virtual Server架構圖

98

  • COSA-SOP-03-006
  • 第一章 簡介
    • 11適用對象 (Audience)
    • 12 MySQL本身
    • 13 MySQL 40版跟50版重大的改進功能
    • 14 各家資料庫軟體比較
      • 第二章 前置需求
      • 第三章 安裝
        • 31 MySQL安裝
        • 32 phpMyAdmin安裝
        • 33 升級及注意事項
          • 第四章 MySQL管理
            • 41 Webmin 管理介面
            • 42 phpMyAdmin 的操作介面
            • 43管理指令介紹
              • 431 利用mysqladmin設定root的密碼
                  • 第五章 實用範例
                    • 51 任務一Web Base客戶通訊錄
                    • 52 任務二Web Base群組軟體 ( twig )
                      • 第六章 維護及更新程序
                        • 61 日常維護
                        • 62 更新程序
                        • 63 備份重要檔案
                        • 64 離線備份與還原
                        • 65 線上備份與還原
                          • 第七章 問題與解答
                          • 第八章 參考資料
                          • 附錄一 SQL Command 介紹
                          • 附錄二Replication
Page 79: DataBase Server Standard Operation Procedureebooks.lib.ntu.edu.tw/1_file/oss/63/93doc4-5.pdf · 業務的公司帶來了不少壓力,譬如微軟,甲骨文 ... 外的錢用在第三方的資料庫產品上,譬如就可以不用再購買甲骨文公司

1 httplinuxtncedutwtechdocmysqlmysql_docmanual_tochtml MySQL 中文手冊 2 httpchenshloxaedutwphpZ_1php PHP+MySQ程式研習設計網站 3 httplinuxtncedutwtechdocbanicdownhtml PHP 4 手冊 4 httpwwwtncedutwadmin_zonephp台南縣教育網網路中心有很多 Linux相關文件 5 httpdobtncedutw網站建置百寶箱有很多 PHP MySQL 相關範例程式 5 httpwwwdbworldcomtw資料庫專家電子雜誌介紹資料庫的重要觀念及名詞

79

附錄一 SQL Command 介紹

SQL (讀音ess-que-el) 是一種結構查詢語法SQL 使用於資料庫交流

傳遞相容於 ANSI (American National Standards Institute) 是一套標準的關聯

式資料庫語言 SQL 語言是執行更新或從資料系統獲取資料一般常見的關聯

資料庫系統都有提供 SQL 如 Oracle Sybase Microsoft SQL Server Access Ingres 等雖然大部份的資料庫都有提供 SQL 但也多提供了自已獨特的語

法造成了不相容的情形但標準基本的語法是相通的如Select Insert Update Delete Create and Drop 每一個系統都有支援

Table相關 Command

Create Table

關聯式資料庫包含有很多元件稱為資料表(tables) 把資料或訊息放在資

料表中 資料表是以不同的名稱做分別資料表由欄列所構成的二維陣列

欄包含欄位名資料型態 及其他可判斷的資訊列是由全部欄位構成一筆一

筆的紀錄 create table 語法用在建立一個新的資料表語法格式如下

create table tablename (column1 data type column2 data type column3 data type)

Format of create table if you were to use optional constraints

create table tablename (column1 data type [constraint] column2 data type [constraint] column3 data type [constraint]) [ ] = optional

Note You may have as many columns as youd like and the constraints are optional

80

Example

create table employee (first varchar(15) last varchar(20) age number(3) address varchar(30) city varchar(20) state varchar(20))

注意建立資料表格式要以括號把前後框住而最後以(分號)做結尾

欄位名不要超過 30個字元長而且不要使用 sql 的關鍵字(如 where select等)而在後面接是型態的宣告(如字串數字日期格式等)

資料型態是來描述欄位的方式如一個欄位Last_Name 是一個姓氏可以使用varchar (可變動長度字串) 資料型態

以下是幾個常見的資料庫型態 char(size) 固定長度字串最長為 255 位元 varchar(size) 變動長度字串最大字元數以 size 來指定 number(size) 數值格式可以是整數也可以是小數最大數字以 size 位數判

斷未指定小數位數由系統內定 date 日期格式 number(sized) 數值格式最大數字以 size 位數判斷d 為小數位數整數位

數為 size-d 位

有何限制當資料表被建立通常有一或數個欄位是要使用來做關聯的功

能 例如unique 限制(唯一值)兩筆記錄不可以相同的值 not null (非空值)該欄位一定要輸入資料不可是空的primary key (主鍵)是每一筆記錄識別的主要方式

Drop a table drop table 刪除資料表(其中的資料也會一併刪除)

drop table tablename

Example

81

drop table 和刪除全部資料是不同的刪除全部資料欄位名稱資訊等還會

存在但刪除資料表會把這一些也一併移除掉

如何查詢資料

Select 基本用法

select 語法是關連式資料庫最常用的部份可以取得你想要的資料這是一個

簡單的範例 select column1[column2etc] from tablename [where condition] [] = optional 在 select 之後所列欄位名則是要顯示的資料部份你可以一一列出各欄位

名或是以 (星號)來代表選擇全部的欄位 from 之後放資料表名稱 where 子句 (選項) 指定要過濾的條件符合者才會顯現 where 可使用的條件運算元 = 等於 gt 大於 lt 小於 gt= 大或等於 lt= 小或等於 ltgt 大相等 LIKE 相似 For example select first last city

82

from empinfo where first LIKE Er 以Er 為開頭的字串就符合要以單引號框住 Or you can specify select first last from empinfo where last LIKE s 最後一字為 S 就符合 select from empinfo where first = Eric 則表示 first name 一定要是 Eric 才可以 範例資料表empinfo 統計函數

MIN 傳回指定欄位最小值

MAX 傳回指定欄位最大值

SUM 傳回指定欄位總和

AVG 傳回指定欄位平均值

COUNT 傳回指定欄位的筆數

COUNT() 傳回資料庫中的總筆數

統計函數使用於資料表中的數值欄位配合 SELECT 語法使用 只用於總結特定單一欄位可以配合 GROUP BY 做篩選但也可以不使用 GROUP BY 語句For example

SELECT AVG(salary) FROM employee

83

傳回全部 salary 平均值

Another example

SELECT AVG(salary) FROM employee WHERE title = Programmer

傳回 salary 平均值條件為 employees 資料表中當 title 等於 Programmer

Example

SELECT Count() FROM employees

傳回 employees 資料表中紀錄總筆數

GROUP BY 語法 SELECT column1 SUM(column2) FROM list-of-tables GROUP BY column-list The GROUP BY 語句可以先以所列的欄位為條件分組排序在一起(可以多欄

位) example 要列出每一個 dept 中最高 salary 值 SELECT max(salary) dept FROM employee GROUP BY dept HAVING 語法

SELECT column1 SUM(column2) FROM list-of-tables GROUP BY column-list HAVING condition

HAVING 子句是 GROUP BY 的一部份用來過濾在 GROUP BY 所選出的資料功能如同 select 命令中 where 條件式一樣只是 HAVING 必需配合 GROUP BY 使用

我們以例子來說明我們要取得每一公司名及每一公司的薪水平均值輸入如下

84

SELECT dept avg(salary) FROM employee GROUP BY dept

但如果我們只列出薪資平均值超過 20000元的公司資料

SELECT dept avg(salary) FROM employee GROUP BY dept HAVING avg(salary) gt 20000

ORDER BY子句語法

SELECT column1 SUM(column2) FROM list-of-tables ORDER BY column-list [ASC | DESC]

[ ] =選項

ORDER BY是一個選項子句當你以排序方式來顯示資料(正向由小到大反向由大到小)以指定的欄位資料做排序

ASC = 正向- 預設值 DESC = 反向排序

For example

SELECT employee_id dept name age salary FROM employee_info WHERE dept = Sales ORDER BY salary

以上列出公司代號公司名銷售員人名年紀及薪資而條件是公司名為 Sales 顯示順序以薪資多少排序(由小到大為預設值)

如果要以多個欄位做排序要以逗號做分隔如下

SELECT employee_id dept name age salary FROM employee_info WHERE dept = Sales ORDER BY salary age DESC

85

結合條件及布林運算 SELECT column1 SUM(column2) FROM list-of-tables WHERE condition1 AND condition2 AND運算可以結兩個或以上的條件放在 WHERE子句中 兩者都要為真才

會顯示該筆記錄 OR 運算可以結兩個或以上敘述放在 WHERE子句中只要其中一個為直就

會顯示該筆記錄 For example SELECT employeeid firstname lastname title salary FROM employee_info WHERE salary gt= 5000000 AND title = Programmer 必需要薪資大於等於 50000而且職稱為 Programmer同時符合才會顯示該筆資料 以下以括號括住雖然不是必需的但如此比較容易讀 SELECT employeeid firstname lastname title salary FROM employee_info WHERE (salary gt= 5000000) AND (title = Programmer) 另外範例 SELECT firstname lastname title salary FROM employee_info WHERE (title = Sales) OR (title = Programmer) 條件為只要是 Sales 或 Programmer 職稱的就會被列出 IN and BETWEEN 子句

SELECT column1 SUM(column2) FROM list-of-tables WHERE column3 IN (list-of-values) SELECT column1 SUM(column2) FROM list-of-tables WHERE column3 BETWEEN value1 AND value2 IN 子句使用在列舉項目的使用上也就是分別測試是否符合所列的值 For example

86

SELECT employeeid lastname salary FROM employee_info WHERE lastname IN (Hernandez Jones Roberts Ruiz) 條件為姓氏(astname)要符合 Hernandez Jones Roberts or Ruiz 其中一個才會被傳回 IN運算元也可以使用 OR 的語法來取代如下結果相同 SELECT employeeid lastname salary FROM employee_info WHERE lastname = Hernandez OR lastname = Jones OR lastname = Roberts OR lastname = Ruiz 但使用 IN 句子比較短也比較易懂 你也可以使用 NOT IN 來去掉不要的記錄 BETWEEN 運算元使用在判斷是否存在兩個數值之間 For example SELECT employeeid age lastname salary FROM employee_info WHERE age BETWEEN 30 AND 40 傳回年紀 30歲到 40歲之間的資料(含 30及 40歲者) 相同的也可以使用以下語法來達到相同的結果 SELECT employeeid age lastname salary FROM employee_info WHERE age gt= 30 AND age lt= 40 你也可使用 NOT BETWEEN 來濾掉中間值的資料 數學運算 標準 ANSI SQL-92 提供以下運算

87

+ 加

- 減

餘數

餘數為除法後剩整數這不在標準的 ANSI SQL 中但大部份的資料庫都會支

援這運算元以下列出有用的函數雖不在 ANSI SQL-92 提供但一般資料庫

也會支援他們

ABS(x) 傳回 x 絕對值

SIGN(x) returns the sign of input x as -1 0 or 1 (negative zero or positive respectively)

MOD(xy) 餘數 - returns the integer remainder of x divided by y (同 xy)

FLOOR(x) 傳回小或等於 x 的最大整數值

CEILING(x) or CEIL(x)

傳回大或等於 x 的最小整數值

POWER(xy) x的 y 次方

ROUND(x) 把 x 四捨五入為整數

ROUND(xd) 四捨五入取到小數 d 位

SQRT(x) x 開平方

For example SELECT round(salary) firstname FROM employee_info 傳回薪資取到整數位

如何新增資料

insert 加入一筆新紀錄到資料表中 insert into tablename (first_columnlast_column) values (first_valuelast_value) [] = optional Example insert into employee

88

(first last age address city state) values (Luke Duke 45 2130 Boars Nest Hazard Co Georgia) Note 字串要以單引號住如string 數字框住也無妨 insert into 後面接資料表名稱再接以括號括住的欄位名在 values 後括號分別對映各欄位的值 以上的例子新增了一筆名(first) 為 Luke而住所(state) 為 Georgia 的資料

如何刪除資料

delete 可以刪除單筆或多筆紀錄 delete from tablename where columnname OPERATOR value [and|or column OPERATOR value] [ ] = optional Examples delete from employee Note 如果你沒有指定 where 子句那麼全部的紀錄都會被刪除 delete from employee where lastname = May delete from employee where firstname = Mike or firstname = Eric delete from 接著資料表名 再接著是條件式判斷沒有條件式則全部紀錄會

被刪除

如何更新資料

update 用來更新你所指定的記錄要和 WHERE 配合小心使用 語法 update tablename set columnname = newvalue[nextcolumn = newvalue2] where columnname OPERATOR value [and|or column OPERATOR value] [] = optional Examples

89

update phone_book set area_code = 623 where prefix = 979 update phone_book set last_name = Smith prefix=555 suffix=9292 where last_name = Jones update employee set age = age+1 where first_name=Mary and last_name=Williams

90

附錄二Replication

測試環境

RedHat 90 + MySQL 32358 MySQL資料庫路徑 varlibmysql MySQL設定檔 etcmycnf Master IP 1921680100 Slave IP 1921680200 請至下列網址下載最新MySQL 32358套件並利用rpm ndashUvh 更新 httpupdatesredhatcom9enosi386

圖 最新 MySQL 套件

測試架構圖

91

1921680100

1921680200Master Server

erveSlave S r

圖 測試架構圖

測試步驟

Master server 部份 Step1 確認 MasterSlave機器上所裝的 MySQL版本能進行

replication( 32329 or higher ) Step2 在 Master MySQL上開放一個帳號給 Slave mysql ndashu root ndashp mysqlgtGRANT FILE ON TO repl1921680200 IDENTIFIED BY lsquoabc123rsquo mysqlgtq 上面是 Master開放一個帳號 repl密碼 abc123給 IP1921680200有檔案處理

的權限 Step3 shutdown MySQL on the Master mysqladmin ndashu root ndashp shutdown Step4 備份 Master所有資料庫 tar ndashcvf tmpmysql-snapshottar varlibmysql 注意tar的時候MySQL是要在 stop情況下 在mysql (wwwmysqlcom) 網站的FAQ有不用shutdown的方法

92

Step5 在 master機器上修改etcmycnf 在[mysqld]區段內加入參數 log-bin server-id=這邊設定 server-id=1 sql-bin-update-same binlog-do-db=CRM只針對 CRM資料庫做紀錄 Step6 Restart MySQL on the master service mysqld start 此時因為有加入 log-bin 參數因此開始有 index產生了在varlibmysql目錄下

有index檔案紀錄資料庫的異動 log Slave server 部份 Step1 在 slave設定etcmycnf 在[mysqld]區段加入 master-host= master-user= master-password= master-port= server-id= 這邊設定 master-host=1921680100 master-user=repl master-password=abc123 master-port=3306 server-id=2 master-connect-retry=60預設重試間隔 60秒 replicate-do-db=CRM告訴 slave只做 CRM資料庫的更新 log-slave-updates Step2 將 master上的 mysql-snapshottar copy到 slave上 用 ftp傳到 slave的tmp Step3 解壓縮 Master資料庫至 Slave Server上 cd varlib tar xvf tmpmysql-snapshottar chown ndashR mysqlmysql mysql

93

chmod ndashR 770 mysql (視情況) Step4 Restart MySQL on the slave server 這時在varlibmysql目錄會出現 masterinfo此檔案紀錄了 Master MySQL server的資訊

狀況測試

One-way replication

1921680100

1921680200Master Server

erveSlave S r

圖 One-way replication架構圖 Step1 Master跟 Slave網路及服務都正常情況下由 Master端異動資料後 到 Slave端瀏覽資料檢視是否有進行 replication Step2 模擬 Slave Server 當機 可用在於 slave真的當機或是 Slave 不一定需要一直跟 master connect將Slave MySQL server shutdown由 Master端異動資料到 slave端瀏覽此時Slave應該沒有被 replication 更新然後再將 Slave端 MySQL server start起來

預設 60秒後 Slave會嘗試跟 Master要求進行 replication再去 Slave端檢視是否有更新資料

94

Step3 模擬 Master當機因為是設定 One-way replication一旦 Master Server Slave端沒有 Master的 source可以 download Two-way replication 基於 Master當機狀況於是發展雙向 Replication即 1921680100 ( Host A ) 1921680200 ( Host B )都分別擔任 MasterSlave身分

1921680100

1921680200er

Server B MasterSlave Server

Server A MasterSlave Serv

圖 Two-way replication架構圖 以下是針對兩台 MySQL伺服器進行雙向 Replication Step1觀念同單向 replication只是改成 Master也有 Slave身分 Slave也有Master的身分先分別在 Server AServer B 都去 grant一個進行 replication的身分 [A]mysqlgtGRANT FILE ON TO repl1921680200 IDENTIFIED BY lsquoabc123rsquo [B]mysqlgt GRANT FILE ON TO repl1921680100 IDENTIFIED BY lsquoabc123rsquo Step2做完單向 replication後stop Server Aserver B MySQL service此時 AB資料是一樣的

95

修改etcmycnf設定 範例 Server A [mysqld] datadir=varlibmysql socket=varlibmysqlmysqlsock server-id=1 log-bin sql-bin-update-same binlog-do-db=CRM master-host=1921680200 master-user=repl master-password=abc123 log-slave-updates master-connect-retry=60 replicate-do-db=CRM Server B [mysqld] datadir=varlibmysql socket=varlibmysqlmysqlsock server-id=2 log-bin sql-bin-update-same binlog-do-db=CRM master-host=1921680100 master-user=repl master-password=abc123 log-slave-updates master-connect-retry=60 replicate-do-db=CRM 分別 start Server AServer B MySQL後此時雙方都是 MasterSlave身分一旦哪一方資料異動就會通知對方來 replication-若 replication失效則必須將Server AServer B的masterinfo及index00x 都砍掉然後分別 restart MySQL server進行測試檢視成果 實務上通常如果需要做Two-way replication通常會搭配Virtual Server使用

96

在前端架設一台Virtual Server不過此部份不在此份SOP討論範圍內有興趣

的讀者可參考 httpwwwlinuxvirtualserverorg 網站

1921680100 1921680200

Host A MasterSlave Server

Host B MasterSlave Server

Virtual Host

圖 Virtual Server + Two-way replication 架構圖

97

圖 High Availability Linux Virtual Server架構圖

98

  • COSA-SOP-03-006
  • 第一章 簡介
    • 11適用對象 (Audience)
    • 12 MySQL本身
    • 13 MySQL 40版跟50版重大的改進功能
    • 14 各家資料庫軟體比較
      • 第二章 前置需求
      • 第三章 安裝
        • 31 MySQL安裝
        • 32 phpMyAdmin安裝
        • 33 升級及注意事項
          • 第四章 MySQL管理
            • 41 Webmin 管理介面
            • 42 phpMyAdmin 的操作介面
            • 43管理指令介紹
              • 431 利用mysqladmin設定root的密碼
                  • 第五章 實用範例
                    • 51 任務一Web Base客戶通訊錄
                    • 52 任務二Web Base群組軟體 ( twig )
                      • 第六章 維護及更新程序
                        • 61 日常維護
                        • 62 更新程序
                        • 63 備份重要檔案
                        • 64 離線備份與還原
                        • 65 線上備份與還原
                          • 第七章 問題與解答
                          • 第八章 參考資料
                          • 附錄一 SQL Command 介紹
                          • 附錄二Replication
Page 80: DataBase Server Standard Operation Procedureebooks.lib.ntu.edu.tw/1_file/oss/63/93doc4-5.pdf · 業務的公司帶來了不少壓力,譬如微軟,甲骨文 ... 外的錢用在第三方的資料庫產品上,譬如就可以不用再購買甲骨文公司

附錄一 SQL Command 介紹

SQL (讀音ess-que-el) 是一種結構查詢語法SQL 使用於資料庫交流

傳遞相容於 ANSI (American National Standards Institute) 是一套標準的關聯

式資料庫語言 SQL 語言是執行更新或從資料系統獲取資料一般常見的關聯

資料庫系統都有提供 SQL 如 Oracle Sybase Microsoft SQL Server Access Ingres 等雖然大部份的資料庫都有提供 SQL 但也多提供了自已獨特的語

法造成了不相容的情形但標準基本的語法是相通的如Select Insert Update Delete Create and Drop 每一個系統都有支援

Table相關 Command

Create Table

關聯式資料庫包含有很多元件稱為資料表(tables) 把資料或訊息放在資

料表中 資料表是以不同的名稱做分別資料表由欄列所構成的二維陣列

欄包含欄位名資料型態 及其他可判斷的資訊列是由全部欄位構成一筆一

筆的紀錄 create table 語法用在建立一個新的資料表語法格式如下

create table tablename (column1 data type column2 data type column3 data type)

Format of create table if you were to use optional constraints

create table tablename (column1 data type [constraint] column2 data type [constraint] column3 data type [constraint]) [ ] = optional

Note You may have as many columns as youd like and the constraints are optional

80

Example

create table employee (first varchar(15) last varchar(20) age number(3) address varchar(30) city varchar(20) state varchar(20))

注意建立資料表格式要以括號把前後框住而最後以(分號)做結尾

欄位名不要超過 30個字元長而且不要使用 sql 的關鍵字(如 where select等)而在後面接是型態的宣告(如字串數字日期格式等)

資料型態是來描述欄位的方式如一個欄位Last_Name 是一個姓氏可以使用varchar (可變動長度字串) 資料型態

以下是幾個常見的資料庫型態 char(size) 固定長度字串最長為 255 位元 varchar(size) 變動長度字串最大字元數以 size 來指定 number(size) 數值格式可以是整數也可以是小數最大數字以 size 位數判

斷未指定小數位數由系統內定 date 日期格式 number(sized) 數值格式最大數字以 size 位數判斷d 為小數位數整數位

數為 size-d 位

有何限制當資料表被建立通常有一或數個欄位是要使用來做關聯的功

能 例如unique 限制(唯一值)兩筆記錄不可以相同的值 not null (非空值)該欄位一定要輸入資料不可是空的primary key (主鍵)是每一筆記錄識別的主要方式

Drop a table drop table 刪除資料表(其中的資料也會一併刪除)

drop table tablename

Example

81

drop table 和刪除全部資料是不同的刪除全部資料欄位名稱資訊等還會

存在但刪除資料表會把這一些也一併移除掉

如何查詢資料

Select 基本用法

select 語法是關連式資料庫最常用的部份可以取得你想要的資料這是一個

簡單的範例 select column1[column2etc] from tablename [where condition] [] = optional 在 select 之後所列欄位名則是要顯示的資料部份你可以一一列出各欄位

名或是以 (星號)來代表選擇全部的欄位 from 之後放資料表名稱 where 子句 (選項) 指定要過濾的條件符合者才會顯現 where 可使用的條件運算元 = 等於 gt 大於 lt 小於 gt= 大或等於 lt= 小或等於 ltgt 大相等 LIKE 相似 For example select first last city

82

from empinfo where first LIKE Er 以Er 為開頭的字串就符合要以單引號框住 Or you can specify select first last from empinfo where last LIKE s 最後一字為 S 就符合 select from empinfo where first = Eric 則表示 first name 一定要是 Eric 才可以 範例資料表empinfo 統計函數

MIN 傳回指定欄位最小值

MAX 傳回指定欄位最大值

SUM 傳回指定欄位總和

AVG 傳回指定欄位平均值

COUNT 傳回指定欄位的筆數

COUNT() 傳回資料庫中的總筆數

統計函數使用於資料表中的數值欄位配合 SELECT 語法使用 只用於總結特定單一欄位可以配合 GROUP BY 做篩選但也可以不使用 GROUP BY 語句For example

SELECT AVG(salary) FROM employee

83

傳回全部 salary 平均值

Another example

SELECT AVG(salary) FROM employee WHERE title = Programmer

傳回 salary 平均值條件為 employees 資料表中當 title 等於 Programmer

Example

SELECT Count() FROM employees

傳回 employees 資料表中紀錄總筆數

GROUP BY 語法 SELECT column1 SUM(column2) FROM list-of-tables GROUP BY column-list The GROUP BY 語句可以先以所列的欄位為條件分組排序在一起(可以多欄

位) example 要列出每一個 dept 中最高 salary 值 SELECT max(salary) dept FROM employee GROUP BY dept HAVING 語法

SELECT column1 SUM(column2) FROM list-of-tables GROUP BY column-list HAVING condition

HAVING 子句是 GROUP BY 的一部份用來過濾在 GROUP BY 所選出的資料功能如同 select 命令中 where 條件式一樣只是 HAVING 必需配合 GROUP BY 使用

我們以例子來說明我們要取得每一公司名及每一公司的薪水平均值輸入如下

84

SELECT dept avg(salary) FROM employee GROUP BY dept

但如果我們只列出薪資平均值超過 20000元的公司資料

SELECT dept avg(salary) FROM employee GROUP BY dept HAVING avg(salary) gt 20000

ORDER BY子句語法

SELECT column1 SUM(column2) FROM list-of-tables ORDER BY column-list [ASC | DESC]

[ ] =選項

ORDER BY是一個選項子句當你以排序方式來顯示資料(正向由小到大反向由大到小)以指定的欄位資料做排序

ASC = 正向- 預設值 DESC = 反向排序

For example

SELECT employee_id dept name age salary FROM employee_info WHERE dept = Sales ORDER BY salary

以上列出公司代號公司名銷售員人名年紀及薪資而條件是公司名為 Sales 顯示順序以薪資多少排序(由小到大為預設值)

如果要以多個欄位做排序要以逗號做分隔如下

SELECT employee_id dept name age salary FROM employee_info WHERE dept = Sales ORDER BY salary age DESC

85

結合條件及布林運算 SELECT column1 SUM(column2) FROM list-of-tables WHERE condition1 AND condition2 AND運算可以結兩個或以上的條件放在 WHERE子句中 兩者都要為真才

會顯示該筆記錄 OR 運算可以結兩個或以上敘述放在 WHERE子句中只要其中一個為直就

會顯示該筆記錄 For example SELECT employeeid firstname lastname title salary FROM employee_info WHERE salary gt= 5000000 AND title = Programmer 必需要薪資大於等於 50000而且職稱為 Programmer同時符合才會顯示該筆資料 以下以括號括住雖然不是必需的但如此比較容易讀 SELECT employeeid firstname lastname title salary FROM employee_info WHERE (salary gt= 5000000) AND (title = Programmer) 另外範例 SELECT firstname lastname title salary FROM employee_info WHERE (title = Sales) OR (title = Programmer) 條件為只要是 Sales 或 Programmer 職稱的就會被列出 IN and BETWEEN 子句

SELECT column1 SUM(column2) FROM list-of-tables WHERE column3 IN (list-of-values) SELECT column1 SUM(column2) FROM list-of-tables WHERE column3 BETWEEN value1 AND value2 IN 子句使用在列舉項目的使用上也就是分別測試是否符合所列的值 For example

86

SELECT employeeid lastname salary FROM employee_info WHERE lastname IN (Hernandez Jones Roberts Ruiz) 條件為姓氏(astname)要符合 Hernandez Jones Roberts or Ruiz 其中一個才會被傳回 IN運算元也可以使用 OR 的語法來取代如下結果相同 SELECT employeeid lastname salary FROM employee_info WHERE lastname = Hernandez OR lastname = Jones OR lastname = Roberts OR lastname = Ruiz 但使用 IN 句子比較短也比較易懂 你也可以使用 NOT IN 來去掉不要的記錄 BETWEEN 運算元使用在判斷是否存在兩個數值之間 For example SELECT employeeid age lastname salary FROM employee_info WHERE age BETWEEN 30 AND 40 傳回年紀 30歲到 40歲之間的資料(含 30及 40歲者) 相同的也可以使用以下語法來達到相同的結果 SELECT employeeid age lastname salary FROM employee_info WHERE age gt= 30 AND age lt= 40 你也可使用 NOT BETWEEN 來濾掉中間值的資料 數學運算 標準 ANSI SQL-92 提供以下運算

87

+ 加

- 減

餘數

餘數為除法後剩整數這不在標準的 ANSI SQL 中但大部份的資料庫都會支

援這運算元以下列出有用的函數雖不在 ANSI SQL-92 提供但一般資料庫

也會支援他們

ABS(x) 傳回 x 絕對值

SIGN(x) returns the sign of input x as -1 0 or 1 (negative zero or positive respectively)

MOD(xy) 餘數 - returns the integer remainder of x divided by y (同 xy)

FLOOR(x) 傳回小或等於 x 的最大整數值

CEILING(x) or CEIL(x)

傳回大或等於 x 的最小整數值

POWER(xy) x的 y 次方

ROUND(x) 把 x 四捨五入為整數

ROUND(xd) 四捨五入取到小數 d 位

SQRT(x) x 開平方

For example SELECT round(salary) firstname FROM employee_info 傳回薪資取到整數位

如何新增資料

insert 加入一筆新紀錄到資料表中 insert into tablename (first_columnlast_column) values (first_valuelast_value) [] = optional Example insert into employee

88

(first last age address city state) values (Luke Duke 45 2130 Boars Nest Hazard Co Georgia) Note 字串要以單引號住如string 數字框住也無妨 insert into 後面接資料表名稱再接以括號括住的欄位名在 values 後括號分別對映各欄位的值 以上的例子新增了一筆名(first) 為 Luke而住所(state) 為 Georgia 的資料

如何刪除資料

delete 可以刪除單筆或多筆紀錄 delete from tablename where columnname OPERATOR value [and|or column OPERATOR value] [ ] = optional Examples delete from employee Note 如果你沒有指定 where 子句那麼全部的紀錄都會被刪除 delete from employee where lastname = May delete from employee where firstname = Mike or firstname = Eric delete from 接著資料表名 再接著是條件式判斷沒有條件式則全部紀錄會

被刪除

如何更新資料

update 用來更新你所指定的記錄要和 WHERE 配合小心使用 語法 update tablename set columnname = newvalue[nextcolumn = newvalue2] where columnname OPERATOR value [and|or column OPERATOR value] [] = optional Examples

89

update phone_book set area_code = 623 where prefix = 979 update phone_book set last_name = Smith prefix=555 suffix=9292 where last_name = Jones update employee set age = age+1 where first_name=Mary and last_name=Williams

90

附錄二Replication

測試環境

RedHat 90 + MySQL 32358 MySQL資料庫路徑 varlibmysql MySQL設定檔 etcmycnf Master IP 1921680100 Slave IP 1921680200 請至下列網址下載最新MySQL 32358套件並利用rpm ndashUvh 更新 httpupdatesredhatcom9enosi386

圖 最新 MySQL 套件

測試架構圖

91

1921680100

1921680200Master Server

erveSlave S r

圖 測試架構圖

測試步驟

Master server 部份 Step1 確認 MasterSlave機器上所裝的 MySQL版本能進行

replication( 32329 or higher ) Step2 在 Master MySQL上開放一個帳號給 Slave mysql ndashu root ndashp mysqlgtGRANT FILE ON TO repl1921680200 IDENTIFIED BY lsquoabc123rsquo mysqlgtq 上面是 Master開放一個帳號 repl密碼 abc123給 IP1921680200有檔案處理

的權限 Step3 shutdown MySQL on the Master mysqladmin ndashu root ndashp shutdown Step4 備份 Master所有資料庫 tar ndashcvf tmpmysql-snapshottar varlibmysql 注意tar的時候MySQL是要在 stop情況下 在mysql (wwwmysqlcom) 網站的FAQ有不用shutdown的方法

92

Step5 在 master機器上修改etcmycnf 在[mysqld]區段內加入參數 log-bin server-id=這邊設定 server-id=1 sql-bin-update-same binlog-do-db=CRM只針對 CRM資料庫做紀錄 Step6 Restart MySQL on the master service mysqld start 此時因為有加入 log-bin 參數因此開始有 index產生了在varlibmysql目錄下

有index檔案紀錄資料庫的異動 log Slave server 部份 Step1 在 slave設定etcmycnf 在[mysqld]區段加入 master-host= master-user= master-password= master-port= server-id= 這邊設定 master-host=1921680100 master-user=repl master-password=abc123 master-port=3306 server-id=2 master-connect-retry=60預設重試間隔 60秒 replicate-do-db=CRM告訴 slave只做 CRM資料庫的更新 log-slave-updates Step2 將 master上的 mysql-snapshottar copy到 slave上 用 ftp傳到 slave的tmp Step3 解壓縮 Master資料庫至 Slave Server上 cd varlib tar xvf tmpmysql-snapshottar chown ndashR mysqlmysql mysql

93

chmod ndashR 770 mysql (視情況) Step4 Restart MySQL on the slave server 這時在varlibmysql目錄會出現 masterinfo此檔案紀錄了 Master MySQL server的資訊

狀況測試

One-way replication

1921680100

1921680200Master Server

erveSlave S r

圖 One-way replication架構圖 Step1 Master跟 Slave網路及服務都正常情況下由 Master端異動資料後 到 Slave端瀏覽資料檢視是否有進行 replication Step2 模擬 Slave Server 當機 可用在於 slave真的當機或是 Slave 不一定需要一直跟 master connect將Slave MySQL server shutdown由 Master端異動資料到 slave端瀏覽此時Slave應該沒有被 replication 更新然後再將 Slave端 MySQL server start起來

預設 60秒後 Slave會嘗試跟 Master要求進行 replication再去 Slave端檢視是否有更新資料

94

Step3 模擬 Master當機因為是設定 One-way replication一旦 Master Server Slave端沒有 Master的 source可以 download Two-way replication 基於 Master當機狀況於是發展雙向 Replication即 1921680100 ( Host A ) 1921680200 ( Host B )都分別擔任 MasterSlave身分

1921680100

1921680200er

Server B MasterSlave Server

Server A MasterSlave Serv

圖 Two-way replication架構圖 以下是針對兩台 MySQL伺服器進行雙向 Replication Step1觀念同單向 replication只是改成 Master也有 Slave身分 Slave也有Master的身分先分別在 Server AServer B 都去 grant一個進行 replication的身分 [A]mysqlgtGRANT FILE ON TO repl1921680200 IDENTIFIED BY lsquoabc123rsquo [B]mysqlgt GRANT FILE ON TO repl1921680100 IDENTIFIED BY lsquoabc123rsquo Step2做完單向 replication後stop Server Aserver B MySQL service此時 AB資料是一樣的

95

修改etcmycnf設定 範例 Server A [mysqld] datadir=varlibmysql socket=varlibmysqlmysqlsock server-id=1 log-bin sql-bin-update-same binlog-do-db=CRM master-host=1921680200 master-user=repl master-password=abc123 log-slave-updates master-connect-retry=60 replicate-do-db=CRM Server B [mysqld] datadir=varlibmysql socket=varlibmysqlmysqlsock server-id=2 log-bin sql-bin-update-same binlog-do-db=CRM master-host=1921680100 master-user=repl master-password=abc123 log-slave-updates master-connect-retry=60 replicate-do-db=CRM 分別 start Server AServer B MySQL後此時雙方都是 MasterSlave身分一旦哪一方資料異動就會通知對方來 replication-若 replication失效則必須將Server AServer B的masterinfo及index00x 都砍掉然後分別 restart MySQL server進行測試檢視成果 實務上通常如果需要做Two-way replication通常會搭配Virtual Server使用

96

在前端架設一台Virtual Server不過此部份不在此份SOP討論範圍內有興趣

的讀者可參考 httpwwwlinuxvirtualserverorg 網站

1921680100 1921680200

Host A MasterSlave Server

Host B MasterSlave Server

Virtual Host

圖 Virtual Server + Two-way replication 架構圖

97

圖 High Availability Linux Virtual Server架構圖

98

  • COSA-SOP-03-006
  • 第一章 簡介
    • 11適用對象 (Audience)
    • 12 MySQL本身
    • 13 MySQL 40版跟50版重大的改進功能
    • 14 各家資料庫軟體比較
      • 第二章 前置需求
      • 第三章 安裝
        • 31 MySQL安裝
        • 32 phpMyAdmin安裝
        • 33 升級及注意事項
          • 第四章 MySQL管理
            • 41 Webmin 管理介面
            • 42 phpMyAdmin 的操作介面
            • 43管理指令介紹
              • 431 利用mysqladmin設定root的密碼
                  • 第五章 實用範例
                    • 51 任務一Web Base客戶通訊錄
                    • 52 任務二Web Base群組軟體 ( twig )
                      • 第六章 維護及更新程序
                        • 61 日常維護
                        • 62 更新程序
                        • 63 備份重要檔案
                        • 64 離線備份與還原
                        • 65 線上備份與還原
                          • 第七章 問題與解答
                          • 第八章 參考資料
                          • 附錄一 SQL Command 介紹
                          • 附錄二Replication
Page 81: DataBase Server Standard Operation Procedureebooks.lib.ntu.edu.tw/1_file/oss/63/93doc4-5.pdf · 業務的公司帶來了不少壓力,譬如微軟,甲骨文 ... 外的錢用在第三方的資料庫產品上,譬如就可以不用再購買甲骨文公司

Example

create table employee (first varchar(15) last varchar(20) age number(3) address varchar(30) city varchar(20) state varchar(20))

注意建立資料表格式要以括號把前後框住而最後以(分號)做結尾

欄位名不要超過 30個字元長而且不要使用 sql 的關鍵字(如 where select等)而在後面接是型態的宣告(如字串數字日期格式等)

資料型態是來描述欄位的方式如一個欄位Last_Name 是一個姓氏可以使用varchar (可變動長度字串) 資料型態

以下是幾個常見的資料庫型態 char(size) 固定長度字串最長為 255 位元 varchar(size) 變動長度字串最大字元數以 size 來指定 number(size) 數值格式可以是整數也可以是小數最大數字以 size 位數判

斷未指定小數位數由系統內定 date 日期格式 number(sized) 數值格式最大數字以 size 位數判斷d 為小數位數整數位

數為 size-d 位

有何限制當資料表被建立通常有一或數個欄位是要使用來做關聯的功

能 例如unique 限制(唯一值)兩筆記錄不可以相同的值 not null (非空值)該欄位一定要輸入資料不可是空的primary key (主鍵)是每一筆記錄識別的主要方式

Drop a table drop table 刪除資料表(其中的資料也會一併刪除)

drop table tablename

Example

81

drop table 和刪除全部資料是不同的刪除全部資料欄位名稱資訊等還會

存在但刪除資料表會把這一些也一併移除掉

如何查詢資料

Select 基本用法

select 語法是關連式資料庫最常用的部份可以取得你想要的資料這是一個

簡單的範例 select column1[column2etc] from tablename [where condition] [] = optional 在 select 之後所列欄位名則是要顯示的資料部份你可以一一列出各欄位

名或是以 (星號)來代表選擇全部的欄位 from 之後放資料表名稱 where 子句 (選項) 指定要過濾的條件符合者才會顯現 where 可使用的條件運算元 = 等於 gt 大於 lt 小於 gt= 大或等於 lt= 小或等於 ltgt 大相等 LIKE 相似 For example select first last city

82

from empinfo where first LIKE Er 以Er 為開頭的字串就符合要以單引號框住 Or you can specify select first last from empinfo where last LIKE s 最後一字為 S 就符合 select from empinfo where first = Eric 則表示 first name 一定要是 Eric 才可以 範例資料表empinfo 統計函數

MIN 傳回指定欄位最小值

MAX 傳回指定欄位最大值

SUM 傳回指定欄位總和

AVG 傳回指定欄位平均值

COUNT 傳回指定欄位的筆數

COUNT() 傳回資料庫中的總筆數

統計函數使用於資料表中的數值欄位配合 SELECT 語法使用 只用於總結特定單一欄位可以配合 GROUP BY 做篩選但也可以不使用 GROUP BY 語句For example

SELECT AVG(salary) FROM employee

83

傳回全部 salary 平均值

Another example

SELECT AVG(salary) FROM employee WHERE title = Programmer

傳回 salary 平均值條件為 employees 資料表中當 title 等於 Programmer

Example

SELECT Count() FROM employees

傳回 employees 資料表中紀錄總筆數

GROUP BY 語法 SELECT column1 SUM(column2) FROM list-of-tables GROUP BY column-list The GROUP BY 語句可以先以所列的欄位為條件分組排序在一起(可以多欄

位) example 要列出每一個 dept 中最高 salary 值 SELECT max(salary) dept FROM employee GROUP BY dept HAVING 語法

SELECT column1 SUM(column2) FROM list-of-tables GROUP BY column-list HAVING condition

HAVING 子句是 GROUP BY 的一部份用來過濾在 GROUP BY 所選出的資料功能如同 select 命令中 where 條件式一樣只是 HAVING 必需配合 GROUP BY 使用

我們以例子來說明我們要取得每一公司名及每一公司的薪水平均值輸入如下

84

SELECT dept avg(salary) FROM employee GROUP BY dept

但如果我們只列出薪資平均值超過 20000元的公司資料

SELECT dept avg(salary) FROM employee GROUP BY dept HAVING avg(salary) gt 20000

ORDER BY子句語法

SELECT column1 SUM(column2) FROM list-of-tables ORDER BY column-list [ASC | DESC]

[ ] =選項

ORDER BY是一個選項子句當你以排序方式來顯示資料(正向由小到大反向由大到小)以指定的欄位資料做排序

ASC = 正向- 預設值 DESC = 反向排序

For example

SELECT employee_id dept name age salary FROM employee_info WHERE dept = Sales ORDER BY salary

以上列出公司代號公司名銷售員人名年紀及薪資而條件是公司名為 Sales 顯示順序以薪資多少排序(由小到大為預設值)

如果要以多個欄位做排序要以逗號做分隔如下

SELECT employee_id dept name age salary FROM employee_info WHERE dept = Sales ORDER BY salary age DESC

85

結合條件及布林運算 SELECT column1 SUM(column2) FROM list-of-tables WHERE condition1 AND condition2 AND運算可以結兩個或以上的條件放在 WHERE子句中 兩者都要為真才

會顯示該筆記錄 OR 運算可以結兩個或以上敘述放在 WHERE子句中只要其中一個為直就

會顯示該筆記錄 For example SELECT employeeid firstname lastname title salary FROM employee_info WHERE salary gt= 5000000 AND title = Programmer 必需要薪資大於等於 50000而且職稱為 Programmer同時符合才會顯示該筆資料 以下以括號括住雖然不是必需的但如此比較容易讀 SELECT employeeid firstname lastname title salary FROM employee_info WHERE (salary gt= 5000000) AND (title = Programmer) 另外範例 SELECT firstname lastname title salary FROM employee_info WHERE (title = Sales) OR (title = Programmer) 條件為只要是 Sales 或 Programmer 職稱的就會被列出 IN and BETWEEN 子句

SELECT column1 SUM(column2) FROM list-of-tables WHERE column3 IN (list-of-values) SELECT column1 SUM(column2) FROM list-of-tables WHERE column3 BETWEEN value1 AND value2 IN 子句使用在列舉項目的使用上也就是分別測試是否符合所列的值 For example

86

SELECT employeeid lastname salary FROM employee_info WHERE lastname IN (Hernandez Jones Roberts Ruiz) 條件為姓氏(astname)要符合 Hernandez Jones Roberts or Ruiz 其中一個才會被傳回 IN運算元也可以使用 OR 的語法來取代如下結果相同 SELECT employeeid lastname salary FROM employee_info WHERE lastname = Hernandez OR lastname = Jones OR lastname = Roberts OR lastname = Ruiz 但使用 IN 句子比較短也比較易懂 你也可以使用 NOT IN 來去掉不要的記錄 BETWEEN 運算元使用在判斷是否存在兩個數值之間 For example SELECT employeeid age lastname salary FROM employee_info WHERE age BETWEEN 30 AND 40 傳回年紀 30歲到 40歲之間的資料(含 30及 40歲者) 相同的也可以使用以下語法來達到相同的結果 SELECT employeeid age lastname salary FROM employee_info WHERE age gt= 30 AND age lt= 40 你也可使用 NOT BETWEEN 來濾掉中間值的資料 數學運算 標準 ANSI SQL-92 提供以下運算

87

+ 加

- 減

餘數

餘數為除法後剩整數這不在標準的 ANSI SQL 中但大部份的資料庫都會支

援這運算元以下列出有用的函數雖不在 ANSI SQL-92 提供但一般資料庫

也會支援他們

ABS(x) 傳回 x 絕對值

SIGN(x) returns the sign of input x as -1 0 or 1 (negative zero or positive respectively)

MOD(xy) 餘數 - returns the integer remainder of x divided by y (同 xy)

FLOOR(x) 傳回小或等於 x 的最大整數值

CEILING(x) or CEIL(x)

傳回大或等於 x 的最小整數值

POWER(xy) x的 y 次方

ROUND(x) 把 x 四捨五入為整數

ROUND(xd) 四捨五入取到小數 d 位

SQRT(x) x 開平方

For example SELECT round(salary) firstname FROM employee_info 傳回薪資取到整數位

如何新增資料

insert 加入一筆新紀錄到資料表中 insert into tablename (first_columnlast_column) values (first_valuelast_value) [] = optional Example insert into employee

88

(first last age address city state) values (Luke Duke 45 2130 Boars Nest Hazard Co Georgia) Note 字串要以單引號住如string 數字框住也無妨 insert into 後面接資料表名稱再接以括號括住的欄位名在 values 後括號分別對映各欄位的值 以上的例子新增了一筆名(first) 為 Luke而住所(state) 為 Georgia 的資料

如何刪除資料

delete 可以刪除單筆或多筆紀錄 delete from tablename where columnname OPERATOR value [and|or column OPERATOR value] [ ] = optional Examples delete from employee Note 如果你沒有指定 where 子句那麼全部的紀錄都會被刪除 delete from employee where lastname = May delete from employee where firstname = Mike or firstname = Eric delete from 接著資料表名 再接著是條件式判斷沒有條件式則全部紀錄會

被刪除

如何更新資料

update 用來更新你所指定的記錄要和 WHERE 配合小心使用 語法 update tablename set columnname = newvalue[nextcolumn = newvalue2] where columnname OPERATOR value [and|or column OPERATOR value] [] = optional Examples

89

update phone_book set area_code = 623 where prefix = 979 update phone_book set last_name = Smith prefix=555 suffix=9292 where last_name = Jones update employee set age = age+1 where first_name=Mary and last_name=Williams

90

附錄二Replication

測試環境

RedHat 90 + MySQL 32358 MySQL資料庫路徑 varlibmysql MySQL設定檔 etcmycnf Master IP 1921680100 Slave IP 1921680200 請至下列網址下載最新MySQL 32358套件並利用rpm ndashUvh 更新 httpupdatesredhatcom9enosi386

圖 最新 MySQL 套件

測試架構圖

91

1921680100

1921680200Master Server

erveSlave S r

圖 測試架構圖

測試步驟

Master server 部份 Step1 確認 MasterSlave機器上所裝的 MySQL版本能進行

replication( 32329 or higher ) Step2 在 Master MySQL上開放一個帳號給 Slave mysql ndashu root ndashp mysqlgtGRANT FILE ON TO repl1921680200 IDENTIFIED BY lsquoabc123rsquo mysqlgtq 上面是 Master開放一個帳號 repl密碼 abc123給 IP1921680200有檔案處理

的權限 Step3 shutdown MySQL on the Master mysqladmin ndashu root ndashp shutdown Step4 備份 Master所有資料庫 tar ndashcvf tmpmysql-snapshottar varlibmysql 注意tar的時候MySQL是要在 stop情況下 在mysql (wwwmysqlcom) 網站的FAQ有不用shutdown的方法

92

Step5 在 master機器上修改etcmycnf 在[mysqld]區段內加入參數 log-bin server-id=這邊設定 server-id=1 sql-bin-update-same binlog-do-db=CRM只針對 CRM資料庫做紀錄 Step6 Restart MySQL on the master service mysqld start 此時因為有加入 log-bin 參數因此開始有 index產生了在varlibmysql目錄下

有index檔案紀錄資料庫的異動 log Slave server 部份 Step1 在 slave設定etcmycnf 在[mysqld]區段加入 master-host= master-user= master-password= master-port= server-id= 這邊設定 master-host=1921680100 master-user=repl master-password=abc123 master-port=3306 server-id=2 master-connect-retry=60預設重試間隔 60秒 replicate-do-db=CRM告訴 slave只做 CRM資料庫的更新 log-slave-updates Step2 將 master上的 mysql-snapshottar copy到 slave上 用 ftp傳到 slave的tmp Step3 解壓縮 Master資料庫至 Slave Server上 cd varlib tar xvf tmpmysql-snapshottar chown ndashR mysqlmysql mysql

93

chmod ndashR 770 mysql (視情況) Step4 Restart MySQL on the slave server 這時在varlibmysql目錄會出現 masterinfo此檔案紀錄了 Master MySQL server的資訊

狀況測試

One-way replication

1921680100

1921680200Master Server

erveSlave S r

圖 One-way replication架構圖 Step1 Master跟 Slave網路及服務都正常情況下由 Master端異動資料後 到 Slave端瀏覽資料檢視是否有進行 replication Step2 模擬 Slave Server 當機 可用在於 slave真的當機或是 Slave 不一定需要一直跟 master connect將Slave MySQL server shutdown由 Master端異動資料到 slave端瀏覽此時Slave應該沒有被 replication 更新然後再將 Slave端 MySQL server start起來

預設 60秒後 Slave會嘗試跟 Master要求進行 replication再去 Slave端檢視是否有更新資料

94

Step3 模擬 Master當機因為是設定 One-way replication一旦 Master Server Slave端沒有 Master的 source可以 download Two-way replication 基於 Master當機狀況於是發展雙向 Replication即 1921680100 ( Host A ) 1921680200 ( Host B )都分別擔任 MasterSlave身分

1921680100

1921680200er

Server B MasterSlave Server

Server A MasterSlave Serv

圖 Two-way replication架構圖 以下是針對兩台 MySQL伺服器進行雙向 Replication Step1觀念同單向 replication只是改成 Master也有 Slave身分 Slave也有Master的身分先分別在 Server AServer B 都去 grant一個進行 replication的身分 [A]mysqlgtGRANT FILE ON TO repl1921680200 IDENTIFIED BY lsquoabc123rsquo [B]mysqlgt GRANT FILE ON TO repl1921680100 IDENTIFIED BY lsquoabc123rsquo Step2做完單向 replication後stop Server Aserver B MySQL service此時 AB資料是一樣的

95

修改etcmycnf設定 範例 Server A [mysqld] datadir=varlibmysql socket=varlibmysqlmysqlsock server-id=1 log-bin sql-bin-update-same binlog-do-db=CRM master-host=1921680200 master-user=repl master-password=abc123 log-slave-updates master-connect-retry=60 replicate-do-db=CRM Server B [mysqld] datadir=varlibmysql socket=varlibmysqlmysqlsock server-id=2 log-bin sql-bin-update-same binlog-do-db=CRM master-host=1921680100 master-user=repl master-password=abc123 log-slave-updates master-connect-retry=60 replicate-do-db=CRM 分別 start Server AServer B MySQL後此時雙方都是 MasterSlave身分一旦哪一方資料異動就會通知對方來 replication-若 replication失效則必須將Server AServer B的masterinfo及index00x 都砍掉然後分別 restart MySQL server進行測試檢視成果 實務上通常如果需要做Two-way replication通常會搭配Virtual Server使用

96

在前端架設一台Virtual Server不過此部份不在此份SOP討論範圍內有興趣

的讀者可參考 httpwwwlinuxvirtualserverorg 網站

1921680100 1921680200

Host A MasterSlave Server

Host B MasterSlave Server

Virtual Host

圖 Virtual Server + Two-way replication 架構圖

97

圖 High Availability Linux Virtual Server架構圖

98

  • COSA-SOP-03-006
  • 第一章 簡介
    • 11適用對象 (Audience)
    • 12 MySQL本身
    • 13 MySQL 40版跟50版重大的改進功能
    • 14 各家資料庫軟體比較
      • 第二章 前置需求
      • 第三章 安裝
        • 31 MySQL安裝
        • 32 phpMyAdmin安裝
        • 33 升級及注意事項
          • 第四章 MySQL管理
            • 41 Webmin 管理介面
            • 42 phpMyAdmin 的操作介面
            • 43管理指令介紹
              • 431 利用mysqladmin設定root的密碼
                  • 第五章 實用範例
                    • 51 任務一Web Base客戶通訊錄
                    • 52 任務二Web Base群組軟體 ( twig )
                      • 第六章 維護及更新程序
                        • 61 日常維護
                        • 62 更新程序
                        • 63 備份重要檔案
                        • 64 離線備份與還原
                        • 65 線上備份與還原
                          • 第七章 問題與解答
                          • 第八章 參考資料
                          • 附錄一 SQL Command 介紹
                          • 附錄二Replication
Page 82: DataBase Server Standard Operation Procedureebooks.lib.ntu.edu.tw/1_file/oss/63/93doc4-5.pdf · 業務的公司帶來了不少壓力,譬如微軟,甲骨文 ... 外的錢用在第三方的資料庫產品上,譬如就可以不用再購買甲骨文公司

drop table 和刪除全部資料是不同的刪除全部資料欄位名稱資訊等還會

存在但刪除資料表會把這一些也一併移除掉

如何查詢資料

Select 基本用法

select 語法是關連式資料庫最常用的部份可以取得你想要的資料這是一個

簡單的範例 select column1[column2etc] from tablename [where condition] [] = optional 在 select 之後所列欄位名則是要顯示的資料部份你可以一一列出各欄位

名或是以 (星號)來代表選擇全部的欄位 from 之後放資料表名稱 where 子句 (選項) 指定要過濾的條件符合者才會顯現 where 可使用的條件運算元 = 等於 gt 大於 lt 小於 gt= 大或等於 lt= 小或等於 ltgt 大相等 LIKE 相似 For example select first last city

82

from empinfo where first LIKE Er 以Er 為開頭的字串就符合要以單引號框住 Or you can specify select first last from empinfo where last LIKE s 最後一字為 S 就符合 select from empinfo where first = Eric 則表示 first name 一定要是 Eric 才可以 範例資料表empinfo 統計函數

MIN 傳回指定欄位最小值

MAX 傳回指定欄位最大值

SUM 傳回指定欄位總和

AVG 傳回指定欄位平均值

COUNT 傳回指定欄位的筆數

COUNT() 傳回資料庫中的總筆數

統計函數使用於資料表中的數值欄位配合 SELECT 語法使用 只用於總結特定單一欄位可以配合 GROUP BY 做篩選但也可以不使用 GROUP BY 語句For example

SELECT AVG(salary) FROM employee

83

傳回全部 salary 平均值

Another example

SELECT AVG(salary) FROM employee WHERE title = Programmer

傳回 salary 平均值條件為 employees 資料表中當 title 等於 Programmer

Example

SELECT Count() FROM employees

傳回 employees 資料表中紀錄總筆數

GROUP BY 語法 SELECT column1 SUM(column2) FROM list-of-tables GROUP BY column-list The GROUP BY 語句可以先以所列的欄位為條件分組排序在一起(可以多欄

位) example 要列出每一個 dept 中最高 salary 值 SELECT max(salary) dept FROM employee GROUP BY dept HAVING 語法

SELECT column1 SUM(column2) FROM list-of-tables GROUP BY column-list HAVING condition

HAVING 子句是 GROUP BY 的一部份用來過濾在 GROUP BY 所選出的資料功能如同 select 命令中 where 條件式一樣只是 HAVING 必需配合 GROUP BY 使用

我們以例子來說明我們要取得每一公司名及每一公司的薪水平均值輸入如下

84

SELECT dept avg(salary) FROM employee GROUP BY dept

但如果我們只列出薪資平均值超過 20000元的公司資料

SELECT dept avg(salary) FROM employee GROUP BY dept HAVING avg(salary) gt 20000

ORDER BY子句語法

SELECT column1 SUM(column2) FROM list-of-tables ORDER BY column-list [ASC | DESC]

[ ] =選項

ORDER BY是一個選項子句當你以排序方式來顯示資料(正向由小到大反向由大到小)以指定的欄位資料做排序

ASC = 正向- 預設值 DESC = 反向排序

For example

SELECT employee_id dept name age salary FROM employee_info WHERE dept = Sales ORDER BY salary

以上列出公司代號公司名銷售員人名年紀及薪資而條件是公司名為 Sales 顯示順序以薪資多少排序(由小到大為預設值)

如果要以多個欄位做排序要以逗號做分隔如下

SELECT employee_id dept name age salary FROM employee_info WHERE dept = Sales ORDER BY salary age DESC

85

結合條件及布林運算 SELECT column1 SUM(column2) FROM list-of-tables WHERE condition1 AND condition2 AND運算可以結兩個或以上的條件放在 WHERE子句中 兩者都要為真才

會顯示該筆記錄 OR 運算可以結兩個或以上敘述放在 WHERE子句中只要其中一個為直就

會顯示該筆記錄 For example SELECT employeeid firstname lastname title salary FROM employee_info WHERE salary gt= 5000000 AND title = Programmer 必需要薪資大於等於 50000而且職稱為 Programmer同時符合才會顯示該筆資料 以下以括號括住雖然不是必需的但如此比較容易讀 SELECT employeeid firstname lastname title salary FROM employee_info WHERE (salary gt= 5000000) AND (title = Programmer) 另外範例 SELECT firstname lastname title salary FROM employee_info WHERE (title = Sales) OR (title = Programmer) 條件為只要是 Sales 或 Programmer 職稱的就會被列出 IN and BETWEEN 子句

SELECT column1 SUM(column2) FROM list-of-tables WHERE column3 IN (list-of-values) SELECT column1 SUM(column2) FROM list-of-tables WHERE column3 BETWEEN value1 AND value2 IN 子句使用在列舉項目的使用上也就是分別測試是否符合所列的值 For example

86

SELECT employeeid lastname salary FROM employee_info WHERE lastname IN (Hernandez Jones Roberts Ruiz) 條件為姓氏(astname)要符合 Hernandez Jones Roberts or Ruiz 其中一個才會被傳回 IN運算元也可以使用 OR 的語法來取代如下結果相同 SELECT employeeid lastname salary FROM employee_info WHERE lastname = Hernandez OR lastname = Jones OR lastname = Roberts OR lastname = Ruiz 但使用 IN 句子比較短也比較易懂 你也可以使用 NOT IN 來去掉不要的記錄 BETWEEN 運算元使用在判斷是否存在兩個數值之間 For example SELECT employeeid age lastname salary FROM employee_info WHERE age BETWEEN 30 AND 40 傳回年紀 30歲到 40歲之間的資料(含 30及 40歲者) 相同的也可以使用以下語法來達到相同的結果 SELECT employeeid age lastname salary FROM employee_info WHERE age gt= 30 AND age lt= 40 你也可使用 NOT BETWEEN 來濾掉中間值的資料 數學運算 標準 ANSI SQL-92 提供以下運算

87

+ 加

- 減

餘數

餘數為除法後剩整數這不在標準的 ANSI SQL 中但大部份的資料庫都會支

援這運算元以下列出有用的函數雖不在 ANSI SQL-92 提供但一般資料庫

也會支援他們

ABS(x) 傳回 x 絕對值

SIGN(x) returns the sign of input x as -1 0 or 1 (negative zero or positive respectively)

MOD(xy) 餘數 - returns the integer remainder of x divided by y (同 xy)

FLOOR(x) 傳回小或等於 x 的最大整數值

CEILING(x) or CEIL(x)

傳回大或等於 x 的最小整數值

POWER(xy) x的 y 次方

ROUND(x) 把 x 四捨五入為整數

ROUND(xd) 四捨五入取到小數 d 位

SQRT(x) x 開平方

For example SELECT round(salary) firstname FROM employee_info 傳回薪資取到整數位

如何新增資料

insert 加入一筆新紀錄到資料表中 insert into tablename (first_columnlast_column) values (first_valuelast_value) [] = optional Example insert into employee

88

(first last age address city state) values (Luke Duke 45 2130 Boars Nest Hazard Co Georgia) Note 字串要以單引號住如string 數字框住也無妨 insert into 後面接資料表名稱再接以括號括住的欄位名在 values 後括號分別對映各欄位的值 以上的例子新增了一筆名(first) 為 Luke而住所(state) 為 Georgia 的資料

如何刪除資料

delete 可以刪除單筆或多筆紀錄 delete from tablename where columnname OPERATOR value [and|or column OPERATOR value] [ ] = optional Examples delete from employee Note 如果你沒有指定 where 子句那麼全部的紀錄都會被刪除 delete from employee where lastname = May delete from employee where firstname = Mike or firstname = Eric delete from 接著資料表名 再接著是條件式判斷沒有條件式則全部紀錄會

被刪除

如何更新資料

update 用來更新你所指定的記錄要和 WHERE 配合小心使用 語法 update tablename set columnname = newvalue[nextcolumn = newvalue2] where columnname OPERATOR value [and|or column OPERATOR value] [] = optional Examples

89

update phone_book set area_code = 623 where prefix = 979 update phone_book set last_name = Smith prefix=555 suffix=9292 where last_name = Jones update employee set age = age+1 where first_name=Mary and last_name=Williams

90

附錄二Replication

測試環境

RedHat 90 + MySQL 32358 MySQL資料庫路徑 varlibmysql MySQL設定檔 etcmycnf Master IP 1921680100 Slave IP 1921680200 請至下列網址下載最新MySQL 32358套件並利用rpm ndashUvh 更新 httpupdatesredhatcom9enosi386

圖 最新 MySQL 套件

測試架構圖

91

1921680100

1921680200Master Server

erveSlave S r

圖 測試架構圖

測試步驟

Master server 部份 Step1 確認 MasterSlave機器上所裝的 MySQL版本能進行

replication( 32329 or higher ) Step2 在 Master MySQL上開放一個帳號給 Slave mysql ndashu root ndashp mysqlgtGRANT FILE ON TO repl1921680200 IDENTIFIED BY lsquoabc123rsquo mysqlgtq 上面是 Master開放一個帳號 repl密碼 abc123給 IP1921680200有檔案處理

的權限 Step3 shutdown MySQL on the Master mysqladmin ndashu root ndashp shutdown Step4 備份 Master所有資料庫 tar ndashcvf tmpmysql-snapshottar varlibmysql 注意tar的時候MySQL是要在 stop情況下 在mysql (wwwmysqlcom) 網站的FAQ有不用shutdown的方法

92

Step5 在 master機器上修改etcmycnf 在[mysqld]區段內加入參數 log-bin server-id=這邊設定 server-id=1 sql-bin-update-same binlog-do-db=CRM只針對 CRM資料庫做紀錄 Step6 Restart MySQL on the master service mysqld start 此時因為有加入 log-bin 參數因此開始有 index產生了在varlibmysql目錄下

有index檔案紀錄資料庫的異動 log Slave server 部份 Step1 在 slave設定etcmycnf 在[mysqld]區段加入 master-host= master-user= master-password= master-port= server-id= 這邊設定 master-host=1921680100 master-user=repl master-password=abc123 master-port=3306 server-id=2 master-connect-retry=60預設重試間隔 60秒 replicate-do-db=CRM告訴 slave只做 CRM資料庫的更新 log-slave-updates Step2 將 master上的 mysql-snapshottar copy到 slave上 用 ftp傳到 slave的tmp Step3 解壓縮 Master資料庫至 Slave Server上 cd varlib tar xvf tmpmysql-snapshottar chown ndashR mysqlmysql mysql

93

chmod ndashR 770 mysql (視情況) Step4 Restart MySQL on the slave server 這時在varlibmysql目錄會出現 masterinfo此檔案紀錄了 Master MySQL server的資訊

狀況測試

One-way replication

1921680100

1921680200Master Server

erveSlave S r

圖 One-way replication架構圖 Step1 Master跟 Slave網路及服務都正常情況下由 Master端異動資料後 到 Slave端瀏覽資料檢視是否有進行 replication Step2 模擬 Slave Server 當機 可用在於 slave真的當機或是 Slave 不一定需要一直跟 master connect將Slave MySQL server shutdown由 Master端異動資料到 slave端瀏覽此時Slave應該沒有被 replication 更新然後再將 Slave端 MySQL server start起來

預設 60秒後 Slave會嘗試跟 Master要求進行 replication再去 Slave端檢視是否有更新資料

94

Step3 模擬 Master當機因為是設定 One-way replication一旦 Master Server Slave端沒有 Master的 source可以 download Two-way replication 基於 Master當機狀況於是發展雙向 Replication即 1921680100 ( Host A ) 1921680200 ( Host B )都分別擔任 MasterSlave身分

1921680100

1921680200er

Server B MasterSlave Server

Server A MasterSlave Serv

圖 Two-way replication架構圖 以下是針對兩台 MySQL伺服器進行雙向 Replication Step1觀念同單向 replication只是改成 Master也有 Slave身分 Slave也有Master的身分先分別在 Server AServer B 都去 grant一個進行 replication的身分 [A]mysqlgtGRANT FILE ON TO repl1921680200 IDENTIFIED BY lsquoabc123rsquo [B]mysqlgt GRANT FILE ON TO repl1921680100 IDENTIFIED BY lsquoabc123rsquo Step2做完單向 replication後stop Server Aserver B MySQL service此時 AB資料是一樣的

95

修改etcmycnf設定 範例 Server A [mysqld] datadir=varlibmysql socket=varlibmysqlmysqlsock server-id=1 log-bin sql-bin-update-same binlog-do-db=CRM master-host=1921680200 master-user=repl master-password=abc123 log-slave-updates master-connect-retry=60 replicate-do-db=CRM Server B [mysqld] datadir=varlibmysql socket=varlibmysqlmysqlsock server-id=2 log-bin sql-bin-update-same binlog-do-db=CRM master-host=1921680100 master-user=repl master-password=abc123 log-slave-updates master-connect-retry=60 replicate-do-db=CRM 分別 start Server AServer B MySQL後此時雙方都是 MasterSlave身分一旦哪一方資料異動就會通知對方來 replication-若 replication失效則必須將Server AServer B的masterinfo及index00x 都砍掉然後分別 restart MySQL server進行測試檢視成果 實務上通常如果需要做Two-way replication通常會搭配Virtual Server使用

96

在前端架設一台Virtual Server不過此部份不在此份SOP討論範圍內有興趣

的讀者可參考 httpwwwlinuxvirtualserverorg 網站

1921680100 1921680200

Host A MasterSlave Server

Host B MasterSlave Server

Virtual Host

圖 Virtual Server + Two-way replication 架構圖

97

圖 High Availability Linux Virtual Server架構圖

98

  • COSA-SOP-03-006
  • 第一章 簡介
    • 11適用對象 (Audience)
    • 12 MySQL本身
    • 13 MySQL 40版跟50版重大的改進功能
    • 14 各家資料庫軟體比較
      • 第二章 前置需求
      • 第三章 安裝
        • 31 MySQL安裝
        • 32 phpMyAdmin安裝
        • 33 升級及注意事項
          • 第四章 MySQL管理
            • 41 Webmin 管理介面
            • 42 phpMyAdmin 的操作介面
            • 43管理指令介紹
              • 431 利用mysqladmin設定root的密碼
                  • 第五章 實用範例
                    • 51 任務一Web Base客戶通訊錄
                    • 52 任務二Web Base群組軟體 ( twig )
                      • 第六章 維護及更新程序
                        • 61 日常維護
                        • 62 更新程序
                        • 63 備份重要檔案
                        • 64 離線備份與還原
                        • 65 線上備份與還原
                          • 第七章 問題與解答
                          • 第八章 參考資料
                          • 附錄一 SQL Command 介紹
                          • 附錄二Replication
Page 83: DataBase Server Standard Operation Procedureebooks.lib.ntu.edu.tw/1_file/oss/63/93doc4-5.pdf · 業務的公司帶來了不少壓力,譬如微軟,甲骨文 ... 外的錢用在第三方的資料庫產品上,譬如就可以不用再購買甲骨文公司

from empinfo where first LIKE Er 以Er 為開頭的字串就符合要以單引號框住 Or you can specify select first last from empinfo where last LIKE s 最後一字為 S 就符合 select from empinfo where first = Eric 則表示 first name 一定要是 Eric 才可以 範例資料表empinfo 統計函數

MIN 傳回指定欄位最小值

MAX 傳回指定欄位最大值

SUM 傳回指定欄位總和

AVG 傳回指定欄位平均值

COUNT 傳回指定欄位的筆數

COUNT() 傳回資料庫中的總筆數

統計函數使用於資料表中的數值欄位配合 SELECT 語法使用 只用於總結特定單一欄位可以配合 GROUP BY 做篩選但也可以不使用 GROUP BY 語句For example

SELECT AVG(salary) FROM employee

83

傳回全部 salary 平均值

Another example

SELECT AVG(salary) FROM employee WHERE title = Programmer

傳回 salary 平均值條件為 employees 資料表中當 title 等於 Programmer

Example

SELECT Count() FROM employees

傳回 employees 資料表中紀錄總筆數

GROUP BY 語法 SELECT column1 SUM(column2) FROM list-of-tables GROUP BY column-list The GROUP BY 語句可以先以所列的欄位為條件分組排序在一起(可以多欄

位) example 要列出每一個 dept 中最高 salary 值 SELECT max(salary) dept FROM employee GROUP BY dept HAVING 語法

SELECT column1 SUM(column2) FROM list-of-tables GROUP BY column-list HAVING condition

HAVING 子句是 GROUP BY 的一部份用來過濾在 GROUP BY 所選出的資料功能如同 select 命令中 where 條件式一樣只是 HAVING 必需配合 GROUP BY 使用

我們以例子來說明我們要取得每一公司名及每一公司的薪水平均值輸入如下

84

SELECT dept avg(salary) FROM employee GROUP BY dept

但如果我們只列出薪資平均值超過 20000元的公司資料

SELECT dept avg(salary) FROM employee GROUP BY dept HAVING avg(salary) gt 20000

ORDER BY子句語法

SELECT column1 SUM(column2) FROM list-of-tables ORDER BY column-list [ASC | DESC]

[ ] =選項

ORDER BY是一個選項子句當你以排序方式來顯示資料(正向由小到大反向由大到小)以指定的欄位資料做排序

ASC = 正向- 預設值 DESC = 反向排序

For example

SELECT employee_id dept name age salary FROM employee_info WHERE dept = Sales ORDER BY salary

以上列出公司代號公司名銷售員人名年紀及薪資而條件是公司名為 Sales 顯示順序以薪資多少排序(由小到大為預設值)

如果要以多個欄位做排序要以逗號做分隔如下

SELECT employee_id dept name age salary FROM employee_info WHERE dept = Sales ORDER BY salary age DESC

85

結合條件及布林運算 SELECT column1 SUM(column2) FROM list-of-tables WHERE condition1 AND condition2 AND運算可以結兩個或以上的條件放在 WHERE子句中 兩者都要為真才

會顯示該筆記錄 OR 運算可以結兩個或以上敘述放在 WHERE子句中只要其中一個為直就

會顯示該筆記錄 For example SELECT employeeid firstname lastname title salary FROM employee_info WHERE salary gt= 5000000 AND title = Programmer 必需要薪資大於等於 50000而且職稱為 Programmer同時符合才會顯示該筆資料 以下以括號括住雖然不是必需的但如此比較容易讀 SELECT employeeid firstname lastname title salary FROM employee_info WHERE (salary gt= 5000000) AND (title = Programmer) 另外範例 SELECT firstname lastname title salary FROM employee_info WHERE (title = Sales) OR (title = Programmer) 條件為只要是 Sales 或 Programmer 職稱的就會被列出 IN and BETWEEN 子句

SELECT column1 SUM(column2) FROM list-of-tables WHERE column3 IN (list-of-values) SELECT column1 SUM(column2) FROM list-of-tables WHERE column3 BETWEEN value1 AND value2 IN 子句使用在列舉項目的使用上也就是分別測試是否符合所列的值 For example

86

SELECT employeeid lastname salary FROM employee_info WHERE lastname IN (Hernandez Jones Roberts Ruiz) 條件為姓氏(astname)要符合 Hernandez Jones Roberts or Ruiz 其中一個才會被傳回 IN運算元也可以使用 OR 的語法來取代如下結果相同 SELECT employeeid lastname salary FROM employee_info WHERE lastname = Hernandez OR lastname = Jones OR lastname = Roberts OR lastname = Ruiz 但使用 IN 句子比較短也比較易懂 你也可以使用 NOT IN 來去掉不要的記錄 BETWEEN 運算元使用在判斷是否存在兩個數值之間 For example SELECT employeeid age lastname salary FROM employee_info WHERE age BETWEEN 30 AND 40 傳回年紀 30歲到 40歲之間的資料(含 30及 40歲者) 相同的也可以使用以下語法來達到相同的結果 SELECT employeeid age lastname salary FROM employee_info WHERE age gt= 30 AND age lt= 40 你也可使用 NOT BETWEEN 來濾掉中間值的資料 數學運算 標準 ANSI SQL-92 提供以下運算

87

+ 加

- 減

餘數

餘數為除法後剩整數這不在標準的 ANSI SQL 中但大部份的資料庫都會支

援這運算元以下列出有用的函數雖不在 ANSI SQL-92 提供但一般資料庫

也會支援他們

ABS(x) 傳回 x 絕對值

SIGN(x) returns the sign of input x as -1 0 or 1 (negative zero or positive respectively)

MOD(xy) 餘數 - returns the integer remainder of x divided by y (同 xy)

FLOOR(x) 傳回小或等於 x 的最大整數值

CEILING(x) or CEIL(x)

傳回大或等於 x 的最小整數值

POWER(xy) x的 y 次方

ROUND(x) 把 x 四捨五入為整數

ROUND(xd) 四捨五入取到小數 d 位

SQRT(x) x 開平方

For example SELECT round(salary) firstname FROM employee_info 傳回薪資取到整數位

如何新增資料

insert 加入一筆新紀錄到資料表中 insert into tablename (first_columnlast_column) values (first_valuelast_value) [] = optional Example insert into employee

88

(first last age address city state) values (Luke Duke 45 2130 Boars Nest Hazard Co Georgia) Note 字串要以單引號住如string 數字框住也無妨 insert into 後面接資料表名稱再接以括號括住的欄位名在 values 後括號分別對映各欄位的值 以上的例子新增了一筆名(first) 為 Luke而住所(state) 為 Georgia 的資料

如何刪除資料

delete 可以刪除單筆或多筆紀錄 delete from tablename where columnname OPERATOR value [and|or column OPERATOR value] [ ] = optional Examples delete from employee Note 如果你沒有指定 where 子句那麼全部的紀錄都會被刪除 delete from employee where lastname = May delete from employee where firstname = Mike or firstname = Eric delete from 接著資料表名 再接著是條件式判斷沒有條件式則全部紀錄會

被刪除

如何更新資料

update 用來更新你所指定的記錄要和 WHERE 配合小心使用 語法 update tablename set columnname = newvalue[nextcolumn = newvalue2] where columnname OPERATOR value [and|or column OPERATOR value] [] = optional Examples

89

update phone_book set area_code = 623 where prefix = 979 update phone_book set last_name = Smith prefix=555 suffix=9292 where last_name = Jones update employee set age = age+1 where first_name=Mary and last_name=Williams

90

附錄二Replication

測試環境

RedHat 90 + MySQL 32358 MySQL資料庫路徑 varlibmysql MySQL設定檔 etcmycnf Master IP 1921680100 Slave IP 1921680200 請至下列網址下載最新MySQL 32358套件並利用rpm ndashUvh 更新 httpupdatesredhatcom9enosi386

圖 最新 MySQL 套件

測試架構圖

91

1921680100

1921680200Master Server

erveSlave S r

圖 測試架構圖

測試步驟

Master server 部份 Step1 確認 MasterSlave機器上所裝的 MySQL版本能進行

replication( 32329 or higher ) Step2 在 Master MySQL上開放一個帳號給 Slave mysql ndashu root ndashp mysqlgtGRANT FILE ON TO repl1921680200 IDENTIFIED BY lsquoabc123rsquo mysqlgtq 上面是 Master開放一個帳號 repl密碼 abc123給 IP1921680200有檔案處理

的權限 Step3 shutdown MySQL on the Master mysqladmin ndashu root ndashp shutdown Step4 備份 Master所有資料庫 tar ndashcvf tmpmysql-snapshottar varlibmysql 注意tar的時候MySQL是要在 stop情況下 在mysql (wwwmysqlcom) 網站的FAQ有不用shutdown的方法

92

Step5 在 master機器上修改etcmycnf 在[mysqld]區段內加入參數 log-bin server-id=這邊設定 server-id=1 sql-bin-update-same binlog-do-db=CRM只針對 CRM資料庫做紀錄 Step6 Restart MySQL on the master service mysqld start 此時因為有加入 log-bin 參數因此開始有 index產生了在varlibmysql目錄下

有index檔案紀錄資料庫的異動 log Slave server 部份 Step1 在 slave設定etcmycnf 在[mysqld]區段加入 master-host= master-user= master-password= master-port= server-id= 這邊設定 master-host=1921680100 master-user=repl master-password=abc123 master-port=3306 server-id=2 master-connect-retry=60預設重試間隔 60秒 replicate-do-db=CRM告訴 slave只做 CRM資料庫的更新 log-slave-updates Step2 將 master上的 mysql-snapshottar copy到 slave上 用 ftp傳到 slave的tmp Step3 解壓縮 Master資料庫至 Slave Server上 cd varlib tar xvf tmpmysql-snapshottar chown ndashR mysqlmysql mysql

93

chmod ndashR 770 mysql (視情況) Step4 Restart MySQL on the slave server 這時在varlibmysql目錄會出現 masterinfo此檔案紀錄了 Master MySQL server的資訊

狀況測試

One-way replication

1921680100

1921680200Master Server

erveSlave S r

圖 One-way replication架構圖 Step1 Master跟 Slave網路及服務都正常情況下由 Master端異動資料後 到 Slave端瀏覽資料檢視是否有進行 replication Step2 模擬 Slave Server 當機 可用在於 slave真的當機或是 Slave 不一定需要一直跟 master connect將Slave MySQL server shutdown由 Master端異動資料到 slave端瀏覽此時Slave應該沒有被 replication 更新然後再將 Slave端 MySQL server start起來

預設 60秒後 Slave會嘗試跟 Master要求進行 replication再去 Slave端檢視是否有更新資料

94

Step3 模擬 Master當機因為是設定 One-way replication一旦 Master Server Slave端沒有 Master的 source可以 download Two-way replication 基於 Master當機狀況於是發展雙向 Replication即 1921680100 ( Host A ) 1921680200 ( Host B )都分別擔任 MasterSlave身分

1921680100

1921680200er

Server B MasterSlave Server

Server A MasterSlave Serv

圖 Two-way replication架構圖 以下是針對兩台 MySQL伺服器進行雙向 Replication Step1觀念同單向 replication只是改成 Master也有 Slave身分 Slave也有Master的身分先分別在 Server AServer B 都去 grant一個進行 replication的身分 [A]mysqlgtGRANT FILE ON TO repl1921680200 IDENTIFIED BY lsquoabc123rsquo [B]mysqlgt GRANT FILE ON TO repl1921680100 IDENTIFIED BY lsquoabc123rsquo Step2做完單向 replication後stop Server Aserver B MySQL service此時 AB資料是一樣的

95

修改etcmycnf設定 範例 Server A [mysqld] datadir=varlibmysql socket=varlibmysqlmysqlsock server-id=1 log-bin sql-bin-update-same binlog-do-db=CRM master-host=1921680200 master-user=repl master-password=abc123 log-slave-updates master-connect-retry=60 replicate-do-db=CRM Server B [mysqld] datadir=varlibmysql socket=varlibmysqlmysqlsock server-id=2 log-bin sql-bin-update-same binlog-do-db=CRM master-host=1921680100 master-user=repl master-password=abc123 log-slave-updates master-connect-retry=60 replicate-do-db=CRM 分別 start Server AServer B MySQL後此時雙方都是 MasterSlave身分一旦哪一方資料異動就會通知對方來 replication-若 replication失效則必須將Server AServer B的masterinfo及index00x 都砍掉然後分別 restart MySQL server進行測試檢視成果 實務上通常如果需要做Two-way replication通常會搭配Virtual Server使用

96

在前端架設一台Virtual Server不過此部份不在此份SOP討論範圍內有興趣

的讀者可參考 httpwwwlinuxvirtualserverorg 網站

1921680100 1921680200

Host A MasterSlave Server

Host B MasterSlave Server

Virtual Host

圖 Virtual Server + Two-way replication 架構圖

97

圖 High Availability Linux Virtual Server架構圖

98

  • COSA-SOP-03-006
  • 第一章 簡介
    • 11適用對象 (Audience)
    • 12 MySQL本身
    • 13 MySQL 40版跟50版重大的改進功能
    • 14 各家資料庫軟體比較
      • 第二章 前置需求
      • 第三章 安裝
        • 31 MySQL安裝
        • 32 phpMyAdmin安裝
        • 33 升級及注意事項
          • 第四章 MySQL管理
            • 41 Webmin 管理介面
            • 42 phpMyAdmin 的操作介面
            • 43管理指令介紹
              • 431 利用mysqladmin設定root的密碼
                  • 第五章 實用範例
                    • 51 任務一Web Base客戶通訊錄
                    • 52 任務二Web Base群組軟體 ( twig )
                      • 第六章 維護及更新程序
                        • 61 日常維護
                        • 62 更新程序
                        • 63 備份重要檔案
                        • 64 離線備份與還原
                        • 65 線上備份與還原
                          • 第七章 問題與解答
                          • 第八章 參考資料
                          • 附錄一 SQL Command 介紹
                          • 附錄二Replication
Page 84: DataBase Server Standard Operation Procedureebooks.lib.ntu.edu.tw/1_file/oss/63/93doc4-5.pdf · 業務的公司帶來了不少壓力,譬如微軟,甲骨文 ... 外的錢用在第三方的資料庫產品上,譬如就可以不用再購買甲骨文公司

傳回全部 salary 平均值

Another example

SELECT AVG(salary) FROM employee WHERE title = Programmer

傳回 salary 平均值條件為 employees 資料表中當 title 等於 Programmer

Example

SELECT Count() FROM employees

傳回 employees 資料表中紀錄總筆數

GROUP BY 語法 SELECT column1 SUM(column2) FROM list-of-tables GROUP BY column-list The GROUP BY 語句可以先以所列的欄位為條件分組排序在一起(可以多欄

位) example 要列出每一個 dept 中最高 salary 值 SELECT max(salary) dept FROM employee GROUP BY dept HAVING 語法

SELECT column1 SUM(column2) FROM list-of-tables GROUP BY column-list HAVING condition

HAVING 子句是 GROUP BY 的一部份用來過濾在 GROUP BY 所選出的資料功能如同 select 命令中 where 條件式一樣只是 HAVING 必需配合 GROUP BY 使用

我們以例子來說明我們要取得每一公司名及每一公司的薪水平均值輸入如下

84

SELECT dept avg(salary) FROM employee GROUP BY dept

但如果我們只列出薪資平均值超過 20000元的公司資料

SELECT dept avg(salary) FROM employee GROUP BY dept HAVING avg(salary) gt 20000

ORDER BY子句語法

SELECT column1 SUM(column2) FROM list-of-tables ORDER BY column-list [ASC | DESC]

[ ] =選項

ORDER BY是一個選項子句當你以排序方式來顯示資料(正向由小到大反向由大到小)以指定的欄位資料做排序

ASC = 正向- 預設值 DESC = 反向排序

For example

SELECT employee_id dept name age salary FROM employee_info WHERE dept = Sales ORDER BY salary

以上列出公司代號公司名銷售員人名年紀及薪資而條件是公司名為 Sales 顯示順序以薪資多少排序(由小到大為預設值)

如果要以多個欄位做排序要以逗號做分隔如下

SELECT employee_id dept name age salary FROM employee_info WHERE dept = Sales ORDER BY salary age DESC

85

結合條件及布林運算 SELECT column1 SUM(column2) FROM list-of-tables WHERE condition1 AND condition2 AND運算可以結兩個或以上的條件放在 WHERE子句中 兩者都要為真才

會顯示該筆記錄 OR 運算可以結兩個或以上敘述放在 WHERE子句中只要其中一個為直就

會顯示該筆記錄 For example SELECT employeeid firstname lastname title salary FROM employee_info WHERE salary gt= 5000000 AND title = Programmer 必需要薪資大於等於 50000而且職稱為 Programmer同時符合才會顯示該筆資料 以下以括號括住雖然不是必需的但如此比較容易讀 SELECT employeeid firstname lastname title salary FROM employee_info WHERE (salary gt= 5000000) AND (title = Programmer) 另外範例 SELECT firstname lastname title salary FROM employee_info WHERE (title = Sales) OR (title = Programmer) 條件為只要是 Sales 或 Programmer 職稱的就會被列出 IN and BETWEEN 子句

SELECT column1 SUM(column2) FROM list-of-tables WHERE column3 IN (list-of-values) SELECT column1 SUM(column2) FROM list-of-tables WHERE column3 BETWEEN value1 AND value2 IN 子句使用在列舉項目的使用上也就是分別測試是否符合所列的值 For example

86

SELECT employeeid lastname salary FROM employee_info WHERE lastname IN (Hernandez Jones Roberts Ruiz) 條件為姓氏(astname)要符合 Hernandez Jones Roberts or Ruiz 其中一個才會被傳回 IN運算元也可以使用 OR 的語法來取代如下結果相同 SELECT employeeid lastname salary FROM employee_info WHERE lastname = Hernandez OR lastname = Jones OR lastname = Roberts OR lastname = Ruiz 但使用 IN 句子比較短也比較易懂 你也可以使用 NOT IN 來去掉不要的記錄 BETWEEN 運算元使用在判斷是否存在兩個數值之間 For example SELECT employeeid age lastname salary FROM employee_info WHERE age BETWEEN 30 AND 40 傳回年紀 30歲到 40歲之間的資料(含 30及 40歲者) 相同的也可以使用以下語法來達到相同的結果 SELECT employeeid age lastname salary FROM employee_info WHERE age gt= 30 AND age lt= 40 你也可使用 NOT BETWEEN 來濾掉中間值的資料 數學運算 標準 ANSI SQL-92 提供以下運算

87

+ 加

- 減

餘數

餘數為除法後剩整數這不在標準的 ANSI SQL 中但大部份的資料庫都會支

援這運算元以下列出有用的函數雖不在 ANSI SQL-92 提供但一般資料庫

也會支援他們

ABS(x) 傳回 x 絕對值

SIGN(x) returns the sign of input x as -1 0 or 1 (negative zero or positive respectively)

MOD(xy) 餘數 - returns the integer remainder of x divided by y (同 xy)

FLOOR(x) 傳回小或等於 x 的最大整數值

CEILING(x) or CEIL(x)

傳回大或等於 x 的最小整數值

POWER(xy) x的 y 次方

ROUND(x) 把 x 四捨五入為整數

ROUND(xd) 四捨五入取到小數 d 位

SQRT(x) x 開平方

For example SELECT round(salary) firstname FROM employee_info 傳回薪資取到整數位

如何新增資料

insert 加入一筆新紀錄到資料表中 insert into tablename (first_columnlast_column) values (first_valuelast_value) [] = optional Example insert into employee

88

(first last age address city state) values (Luke Duke 45 2130 Boars Nest Hazard Co Georgia) Note 字串要以單引號住如string 數字框住也無妨 insert into 後面接資料表名稱再接以括號括住的欄位名在 values 後括號分別對映各欄位的值 以上的例子新增了一筆名(first) 為 Luke而住所(state) 為 Georgia 的資料

如何刪除資料

delete 可以刪除單筆或多筆紀錄 delete from tablename where columnname OPERATOR value [and|or column OPERATOR value] [ ] = optional Examples delete from employee Note 如果你沒有指定 where 子句那麼全部的紀錄都會被刪除 delete from employee where lastname = May delete from employee where firstname = Mike or firstname = Eric delete from 接著資料表名 再接著是條件式判斷沒有條件式則全部紀錄會

被刪除

如何更新資料

update 用來更新你所指定的記錄要和 WHERE 配合小心使用 語法 update tablename set columnname = newvalue[nextcolumn = newvalue2] where columnname OPERATOR value [and|or column OPERATOR value] [] = optional Examples

89

update phone_book set area_code = 623 where prefix = 979 update phone_book set last_name = Smith prefix=555 suffix=9292 where last_name = Jones update employee set age = age+1 where first_name=Mary and last_name=Williams

90

附錄二Replication

測試環境

RedHat 90 + MySQL 32358 MySQL資料庫路徑 varlibmysql MySQL設定檔 etcmycnf Master IP 1921680100 Slave IP 1921680200 請至下列網址下載最新MySQL 32358套件並利用rpm ndashUvh 更新 httpupdatesredhatcom9enosi386

圖 最新 MySQL 套件

測試架構圖

91

1921680100

1921680200Master Server

erveSlave S r

圖 測試架構圖

測試步驟

Master server 部份 Step1 確認 MasterSlave機器上所裝的 MySQL版本能進行

replication( 32329 or higher ) Step2 在 Master MySQL上開放一個帳號給 Slave mysql ndashu root ndashp mysqlgtGRANT FILE ON TO repl1921680200 IDENTIFIED BY lsquoabc123rsquo mysqlgtq 上面是 Master開放一個帳號 repl密碼 abc123給 IP1921680200有檔案處理

的權限 Step3 shutdown MySQL on the Master mysqladmin ndashu root ndashp shutdown Step4 備份 Master所有資料庫 tar ndashcvf tmpmysql-snapshottar varlibmysql 注意tar的時候MySQL是要在 stop情況下 在mysql (wwwmysqlcom) 網站的FAQ有不用shutdown的方法

92

Step5 在 master機器上修改etcmycnf 在[mysqld]區段內加入參數 log-bin server-id=這邊設定 server-id=1 sql-bin-update-same binlog-do-db=CRM只針對 CRM資料庫做紀錄 Step6 Restart MySQL on the master service mysqld start 此時因為有加入 log-bin 參數因此開始有 index產生了在varlibmysql目錄下

有index檔案紀錄資料庫的異動 log Slave server 部份 Step1 在 slave設定etcmycnf 在[mysqld]區段加入 master-host= master-user= master-password= master-port= server-id= 這邊設定 master-host=1921680100 master-user=repl master-password=abc123 master-port=3306 server-id=2 master-connect-retry=60預設重試間隔 60秒 replicate-do-db=CRM告訴 slave只做 CRM資料庫的更新 log-slave-updates Step2 將 master上的 mysql-snapshottar copy到 slave上 用 ftp傳到 slave的tmp Step3 解壓縮 Master資料庫至 Slave Server上 cd varlib tar xvf tmpmysql-snapshottar chown ndashR mysqlmysql mysql

93

chmod ndashR 770 mysql (視情況) Step4 Restart MySQL on the slave server 這時在varlibmysql目錄會出現 masterinfo此檔案紀錄了 Master MySQL server的資訊

狀況測試

One-way replication

1921680100

1921680200Master Server

erveSlave S r

圖 One-way replication架構圖 Step1 Master跟 Slave網路及服務都正常情況下由 Master端異動資料後 到 Slave端瀏覽資料檢視是否有進行 replication Step2 模擬 Slave Server 當機 可用在於 slave真的當機或是 Slave 不一定需要一直跟 master connect將Slave MySQL server shutdown由 Master端異動資料到 slave端瀏覽此時Slave應該沒有被 replication 更新然後再將 Slave端 MySQL server start起來

預設 60秒後 Slave會嘗試跟 Master要求進行 replication再去 Slave端檢視是否有更新資料

94

Step3 模擬 Master當機因為是設定 One-way replication一旦 Master Server Slave端沒有 Master的 source可以 download Two-way replication 基於 Master當機狀況於是發展雙向 Replication即 1921680100 ( Host A ) 1921680200 ( Host B )都分別擔任 MasterSlave身分

1921680100

1921680200er

Server B MasterSlave Server

Server A MasterSlave Serv

圖 Two-way replication架構圖 以下是針對兩台 MySQL伺服器進行雙向 Replication Step1觀念同單向 replication只是改成 Master也有 Slave身分 Slave也有Master的身分先分別在 Server AServer B 都去 grant一個進行 replication的身分 [A]mysqlgtGRANT FILE ON TO repl1921680200 IDENTIFIED BY lsquoabc123rsquo [B]mysqlgt GRANT FILE ON TO repl1921680100 IDENTIFIED BY lsquoabc123rsquo Step2做完單向 replication後stop Server Aserver B MySQL service此時 AB資料是一樣的

95

修改etcmycnf設定 範例 Server A [mysqld] datadir=varlibmysql socket=varlibmysqlmysqlsock server-id=1 log-bin sql-bin-update-same binlog-do-db=CRM master-host=1921680200 master-user=repl master-password=abc123 log-slave-updates master-connect-retry=60 replicate-do-db=CRM Server B [mysqld] datadir=varlibmysql socket=varlibmysqlmysqlsock server-id=2 log-bin sql-bin-update-same binlog-do-db=CRM master-host=1921680100 master-user=repl master-password=abc123 log-slave-updates master-connect-retry=60 replicate-do-db=CRM 分別 start Server AServer B MySQL後此時雙方都是 MasterSlave身分一旦哪一方資料異動就會通知對方來 replication-若 replication失效則必須將Server AServer B的masterinfo及index00x 都砍掉然後分別 restart MySQL server進行測試檢視成果 實務上通常如果需要做Two-way replication通常會搭配Virtual Server使用

96

在前端架設一台Virtual Server不過此部份不在此份SOP討論範圍內有興趣

的讀者可參考 httpwwwlinuxvirtualserverorg 網站

1921680100 1921680200

Host A MasterSlave Server

Host B MasterSlave Server

Virtual Host

圖 Virtual Server + Two-way replication 架構圖

97

圖 High Availability Linux Virtual Server架構圖

98

  • COSA-SOP-03-006
  • 第一章 簡介
    • 11適用對象 (Audience)
    • 12 MySQL本身
    • 13 MySQL 40版跟50版重大的改進功能
    • 14 各家資料庫軟體比較
      • 第二章 前置需求
      • 第三章 安裝
        • 31 MySQL安裝
        • 32 phpMyAdmin安裝
        • 33 升級及注意事項
          • 第四章 MySQL管理
            • 41 Webmin 管理介面
            • 42 phpMyAdmin 的操作介面
            • 43管理指令介紹
              • 431 利用mysqladmin設定root的密碼
                  • 第五章 實用範例
                    • 51 任務一Web Base客戶通訊錄
                    • 52 任務二Web Base群組軟體 ( twig )
                      • 第六章 維護及更新程序
                        • 61 日常維護
                        • 62 更新程序
                        • 63 備份重要檔案
                        • 64 離線備份與還原
                        • 65 線上備份與還原
                          • 第七章 問題與解答
                          • 第八章 參考資料
                          • 附錄一 SQL Command 介紹
                          • 附錄二Replication
Page 85: DataBase Server Standard Operation Procedureebooks.lib.ntu.edu.tw/1_file/oss/63/93doc4-5.pdf · 業務的公司帶來了不少壓力,譬如微軟,甲骨文 ... 外的錢用在第三方的資料庫產品上,譬如就可以不用再購買甲骨文公司

SELECT dept avg(salary) FROM employee GROUP BY dept

但如果我們只列出薪資平均值超過 20000元的公司資料

SELECT dept avg(salary) FROM employee GROUP BY dept HAVING avg(salary) gt 20000

ORDER BY子句語法

SELECT column1 SUM(column2) FROM list-of-tables ORDER BY column-list [ASC | DESC]

[ ] =選項

ORDER BY是一個選項子句當你以排序方式來顯示資料(正向由小到大反向由大到小)以指定的欄位資料做排序

ASC = 正向- 預設值 DESC = 反向排序

For example

SELECT employee_id dept name age salary FROM employee_info WHERE dept = Sales ORDER BY salary

以上列出公司代號公司名銷售員人名年紀及薪資而條件是公司名為 Sales 顯示順序以薪資多少排序(由小到大為預設值)

如果要以多個欄位做排序要以逗號做分隔如下

SELECT employee_id dept name age salary FROM employee_info WHERE dept = Sales ORDER BY salary age DESC

85

結合條件及布林運算 SELECT column1 SUM(column2) FROM list-of-tables WHERE condition1 AND condition2 AND運算可以結兩個或以上的條件放在 WHERE子句中 兩者都要為真才

會顯示該筆記錄 OR 運算可以結兩個或以上敘述放在 WHERE子句中只要其中一個為直就

會顯示該筆記錄 For example SELECT employeeid firstname lastname title salary FROM employee_info WHERE salary gt= 5000000 AND title = Programmer 必需要薪資大於等於 50000而且職稱為 Programmer同時符合才會顯示該筆資料 以下以括號括住雖然不是必需的但如此比較容易讀 SELECT employeeid firstname lastname title salary FROM employee_info WHERE (salary gt= 5000000) AND (title = Programmer) 另外範例 SELECT firstname lastname title salary FROM employee_info WHERE (title = Sales) OR (title = Programmer) 條件為只要是 Sales 或 Programmer 職稱的就會被列出 IN and BETWEEN 子句

SELECT column1 SUM(column2) FROM list-of-tables WHERE column3 IN (list-of-values) SELECT column1 SUM(column2) FROM list-of-tables WHERE column3 BETWEEN value1 AND value2 IN 子句使用在列舉項目的使用上也就是分別測試是否符合所列的值 For example

86

SELECT employeeid lastname salary FROM employee_info WHERE lastname IN (Hernandez Jones Roberts Ruiz) 條件為姓氏(astname)要符合 Hernandez Jones Roberts or Ruiz 其中一個才會被傳回 IN運算元也可以使用 OR 的語法來取代如下結果相同 SELECT employeeid lastname salary FROM employee_info WHERE lastname = Hernandez OR lastname = Jones OR lastname = Roberts OR lastname = Ruiz 但使用 IN 句子比較短也比較易懂 你也可以使用 NOT IN 來去掉不要的記錄 BETWEEN 運算元使用在判斷是否存在兩個數值之間 For example SELECT employeeid age lastname salary FROM employee_info WHERE age BETWEEN 30 AND 40 傳回年紀 30歲到 40歲之間的資料(含 30及 40歲者) 相同的也可以使用以下語法來達到相同的結果 SELECT employeeid age lastname salary FROM employee_info WHERE age gt= 30 AND age lt= 40 你也可使用 NOT BETWEEN 來濾掉中間值的資料 數學運算 標準 ANSI SQL-92 提供以下運算

87

+ 加

- 減

餘數

餘數為除法後剩整數這不在標準的 ANSI SQL 中但大部份的資料庫都會支

援這運算元以下列出有用的函數雖不在 ANSI SQL-92 提供但一般資料庫

也會支援他們

ABS(x) 傳回 x 絕對值

SIGN(x) returns the sign of input x as -1 0 or 1 (negative zero or positive respectively)

MOD(xy) 餘數 - returns the integer remainder of x divided by y (同 xy)

FLOOR(x) 傳回小或等於 x 的最大整數值

CEILING(x) or CEIL(x)

傳回大或等於 x 的最小整數值

POWER(xy) x的 y 次方

ROUND(x) 把 x 四捨五入為整數

ROUND(xd) 四捨五入取到小數 d 位

SQRT(x) x 開平方

For example SELECT round(salary) firstname FROM employee_info 傳回薪資取到整數位

如何新增資料

insert 加入一筆新紀錄到資料表中 insert into tablename (first_columnlast_column) values (first_valuelast_value) [] = optional Example insert into employee

88

(first last age address city state) values (Luke Duke 45 2130 Boars Nest Hazard Co Georgia) Note 字串要以單引號住如string 數字框住也無妨 insert into 後面接資料表名稱再接以括號括住的欄位名在 values 後括號分別對映各欄位的值 以上的例子新增了一筆名(first) 為 Luke而住所(state) 為 Georgia 的資料

如何刪除資料

delete 可以刪除單筆或多筆紀錄 delete from tablename where columnname OPERATOR value [and|or column OPERATOR value] [ ] = optional Examples delete from employee Note 如果你沒有指定 where 子句那麼全部的紀錄都會被刪除 delete from employee where lastname = May delete from employee where firstname = Mike or firstname = Eric delete from 接著資料表名 再接著是條件式判斷沒有條件式則全部紀錄會

被刪除

如何更新資料

update 用來更新你所指定的記錄要和 WHERE 配合小心使用 語法 update tablename set columnname = newvalue[nextcolumn = newvalue2] where columnname OPERATOR value [and|or column OPERATOR value] [] = optional Examples

89

update phone_book set area_code = 623 where prefix = 979 update phone_book set last_name = Smith prefix=555 suffix=9292 where last_name = Jones update employee set age = age+1 where first_name=Mary and last_name=Williams

90

附錄二Replication

測試環境

RedHat 90 + MySQL 32358 MySQL資料庫路徑 varlibmysql MySQL設定檔 etcmycnf Master IP 1921680100 Slave IP 1921680200 請至下列網址下載最新MySQL 32358套件並利用rpm ndashUvh 更新 httpupdatesredhatcom9enosi386

圖 最新 MySQL 套件

測試架構圖

91

1921680100

1921680200Master Server

erveSlave S r

圖 測試架構圖

測試步驟

Master server 部份 Step1 確認 MasterSlave機器上所裝的 MySQL版本能進行

replication( 32329 or higher ) Step2 在 Master MySQL上開放一個帳號給 Slave mysql ndashu root ndashp mysqlgtGRANT FILE ON TO repl1921680200 IDENTIFIED BY lsquoabc123rsquo mysqlgtq 上面是 Master開放一個帳號 repl密碼 abc123給 IP1921680200有檔案處理

的權限 Step3 shutdown MySQL on the Master mysqladmin ndashu root ndashp shutdown Step4 備份 Master所有資料庫 tar ndashcvf tmpmysql-snapshottar varlibmysql 注意tar的時候MySQL是要在 stop情況下 在mysql (wwwmysqlcom) 網站的FAQ有不用shutdown的方法

92

Step5 在 master機器上修改etcmycnf 在[mysqld]區段內加入參數 log-bin server-id=這邊設定 server-id=1 sql-bin-update-same binlog-do-db=CRM只針對 CRM資料庫做紀錄 Step6 Restart MySQL on the master service mysqld start 此時因為有加入 log-bin 參數因此開始有 index產生了在varlibmysql目錄下

有index檔案紀錄資料庫的異動 log Slave server 部份 Step1 在 slave設定etcmycnf 在[mysqld]區段加入 master-host= master-user= master-password= master-port= server-id= 這邊設定 master-host=1921680100 master-user=repl master-password=abc123 master-port=3306 server-id=2 master-connect-retry=60預設重試間隔 60秒 replicate-do-db=CRM告訴 slave只做 CRM資料庫的更新 log-slave-updates Step2 將 master上的 mysql-snapshottar copy到 slave上 用 ftp傳到 slave的tmp Step3 解壓縮 Master資料庫至 Slave Server上 cd varlib tar xvf tmpmysql-snapshottar chown ndashR mysqlmysql mysql

93

chmod ndashR 770 mysql (視情況) Step4 Restart MySQL on the slave server 這時在varlibmysql目錄會出現 masterinfo此檔案紀錄了 Master MySQL server的資訊

狀況測試

One-way replication

1921680100

1921680200Master Server

erveSlave S r

圖 One-way replication架構圖 Step1 Master跟 Slave網路及服務都正常情況下由 Master端異動資料後 到 Slave端瀏覽資料檢視是否有進行 replication Step2 模擬 Slave Server 當機 可用在於 slave真的當機或是 Slave 不一定需要一直跟 master connect將Slave MySQL server shutdown由 Master端異動資料到 slave端瀏覽此時Slave應該沒有被 replication 更新然後再將 Slave端 MySQL server start起來

預設 60秒後 Slave會嘗試跟 Master要求進行 replication再去 Slave端檢視是否有更新資料

94

Step3 模擬 Master當機因為是設定 One-way replication一旦 Master Server Slave端沒有 Master的 source可以 download Two-way replication 基於 Master當機狀況於是發展雙向 Replication即 1921680100 ( Host A ) 1921680200 ( Host B )都分別擔任 MasterSlave身分

1921680100

1921680200er

Server B MasterSlave Server

Server A MasterSlave Serv

圖 Two-way replication架構圖 以下是針對兩台 MySQL伺服器進行雙向 Replication Step1觀念同單向 replication只是改成 Master也有 Slave身分 Slave也有Master的身分先分別在 Server AServer B 都去 grant一個進行 replication的身分 [A]mysqlgtGRANT FILE ON TO repl1921680200 IDENTIFIED BY lsquoabc123rsquo [B]mysqlgt GRANT FILE ON TO repl1921680100 IDENTIFIED BY lsquoabc123rsquo Step2做完單向 replication後stop Server Aserver B MySQL service此時 AB資料是一樣的

95

修改etcmycnf設定 範例 Server A [mysqld] datadir=varlibmysql socket=varlibmysqlmysqlsock server-id=1 log-bin sql-bin-update-same binlog-do-db=CRM master-host=1921680200 master-user=repl master-password=abc123 log-slave-updates master-connect-retry=60 replicate-do-db=CRM Server B [mysqld] datadir=varlibmysql socket=varlibmysqlmysqlsock server-id=2 log-bin sql-bin-update-same binlog-do-db=CRM master-host=1921680100 master-user=repl master-password=abc123 log-slave-updates master-connect-retry=60 replicate-do-db=CRM 分別 start Server AServer B MySQL後此時雙方都是 MasterSlave身分一旦哪一方資料異動就會通知對方來 replication-若 replication失效則必須將Server AServer B的masterinfo及index00x 都砍掉然後分別 restart MySQL server進行測試檢視成果 實務上通常如果需要做Two-way replication通常會搭配Virtual Server使用

96

在前端架設一台Virtual Server不過此部份不在此份SOP討論範圍內有興趣

的讀者可參考 httpwwwlinuxvirtualserverorg 網站

1921680100 1921680200

Host A MasterSlave Server

Host B MasterSlave Server

Virtual Host

圖 Virtual Server + Two-way replication 架構圖

97

圖 High Availability Linux Virtual Server架構圖

98

  • COSA-SOP-03-006
  • 第一章 簡介
    • 11適用對象 (Audience)
    • 12 MySQL本身
    • 13 MySQL 40版跟50版重大的改進功能
    • 14 各家資料庫軟體比較
      • 第二章 前置需求
      • 第三章 安裝
        • 31 MySQL安裝
        • 32 phpMyAdmin安裝
        • 33 升級及注意事項
          • 第四章 MySQL管理
            • 41 Webmin 管理介面
            • 42 phpMyAdmin 的操作介面
            • 43管理指令介紹
              • 431 利用mysqladmin設定root的密碼
                  • 第五章 實用範例
                    • 51 任務一Web Base客戶通訊錄
                    • 52 任務二Web Base群組軟體 ( twig )
                      • 第六章 維護及更新程序
                        • 61 日常維護
                        • 62 更新程序
                        • 63 備份重要檔案
                        • 64 離線備份與還原
                        • 65 線上備份與還原
                          • 第七章 問題與解答
                          • 第八章 參考資料
                          • 附錄一 SQL Command 介紹
                          • 附錄二Replication
Page 86: DataBase Server Standard Operation Procedureebooks.lib.ntu.edu.tw/1_file/oss/63/93doc4-5.pdf · 業務的公司帶來了不少壓力,譬如微軟,甲骨文 ... 外的錢用在第三方的資料庫產品上,譬如就可以不用再購買甲骨文公司

結合條件及布林運算 SELECT column1 SUM(column2) FROM list-of-tables WHERE condition1 AND condition2 AND運算可以結兩個或以上的條件放在 WHERE子句中 兩者都要為真才

會顯示該筆記錄 OR 運算可以結兩個或以上敘述放在 WHERE子句中只要其中一個為直就

會顯示該筆記錄 For example SELECT employeeid firstname lastname title salary FROM employee_info WHERE salary gt= 5000000 AND title = Programmer 必需要薪資大於等於 50000而且職稱為 Programmer同時符合才會顯示該筆資料 以下以括號括住雖然不是必需的但如此比較容易讀 SELECT employeeid firstname lastname title salary FROM employee_info WHERE (salary gt= 5000000) AND (title = Programmer) 另外範例 SELECT firstname lastname title salary FROM employee_info WHERE (title = Sales) OR (title = Programmer) 條件為只要是 Sales 或 Programmer 職稱的就會被列出 IN and BETWEEN 子句

SELECT column1 SUM(column2) FROM list-of-tables WHERE column3 IN (list-of-values) SELECT column1 SUM(column2) FROM list-of-tables WHERE column3 BETWEEN value1 AND value2 IN 子句使用在列舉項目的使用上也就是分別測試是否符合所列的值 For example

86

SELECT employeeid lastname salary FROM employee_info WHERE lastname IN (Hernandez Jones Roberts Ruiz) 條件為姓氏(astname)要符合 Hernandez Jones Roberts or Ruiz 其中一個才會被傳回 IN運算元也可以使用 OR 的語法來取代如下結果相同 SELECT employeeid lastname salary FROM employee_info WHERE lastname = Hernandez OR lastname = Jones OR lastname = Roberts OR lastname = Ruiz 但使用 IN 句子比較短也比較易懂 你也可以使用 NOT IN 來去掉不要的記錄 BETWEEN 運算元使用在判斷是否存在兩個數值之間 For example SELECT employeeid age lastname salary FROM employee_info WHERE age BETWEEN 30 AND 40 傳回年紀 30歲到 40歲之間的資料(含 30及 40歲者) 相同的也可以使用以下語法來達到相同的結果 SELECT employeeid age lastname salary FROM employee_info WHERE age gt= 30 AND age lt= 40 你也可使用 NOT BETWEEN 來濾掉中間值的資料 數學運算 標準 ANSI SQL-92 提供以下運算

87

+ 加

- 減

餘數

餘數為除法後剩整數這不在標準的 ANSI SQL 中但大部份的資料庫都會支

援這運算元以下列出有用的函數雖不在 ANSI SQL-92 提供但一般資料庫

也會支援他們

ABS(x) 傳回 x 絕對值

SIGN(x) returns the sign of input x as -1 0 or 1 (negative zero or positive respectively)

MOD(xy) 餘數 - returns the integer remainder of x divided by y (同 xy)

FLOOR(x) 傳回小或等於 x 的最大整數值

CEILING(x) or CEIL(x)

傳回大或等於 x 的最小整數值

POWER(xy) x的 y 次方

ROUND(x) 把 x 四捨五入為整數

ROUND(xd) 四捨五入取到小數 d 位

SQRT(x) x 開平方

For example SELECT round(salary) firstname FROM employee_info 傳回薪資取到整數位

如何新增資料

insert 加入一筆新紀錄到資料表中 insert into tablename (first_columnlast_column) values (first_valuelast_value) [] = optional Example insert into employee

88

(first last age address city state) values (Luke Duke 45 2130 Boars Nest Hazard Co Georgia) Note 字串要以單引號住如string 數字框住也無妨 insert into 後面接資料表名稱再接以括號括住的欄位名在 values 後括號分別對映各欄位的值 以上的例子新增了一筆名(first) 為 Luke而住所(state) 為 Georgia 的資料

如何刪除資料

delete 可以刪除單筆或多筆紀錄 delete from tablename where columnname OPERATOR value [and|or column OPERATOR value] [ ] = optional Examples delete from employee Note 如果你沒有指定 where 子句那麼全部的紀錄都會被刪除 delete from employee where lastname = May delete from employee where firstname = Mike or firstname = Eric delete from 接著資料表名 再接著是條件式判斷沒有條件式則全部紀錄會

被刪除

如何更新資料

update 用來更新你所指定的記錄要和 WHERE 配合小心使用 語法 update tablename set columnname = newvalue[nextcolumn = newvalue2] where columnname OPERATOR value [and|or column OPERATOR value] [] = optional Examples

89

update phone_book set area_code = 623 where prefix = 979 update phone_book set last_name = Smith prefix=555 suffix=9292 where last_name = Jones update employee set age = age+1 where first_name=Mary and last_name=Williams

90

附錄二Replication

測試環境

RedHat 90 + MySQL 32358 MySQL資料庫路徑 varlibmysql MySQL設定檔 etcmycnf Master IP 1921680100 Slave IP 1921680200 請至下列網址下載最新MySQL 32358套件並利用rpm ndashUvh 更新 httpupdatesredhatcom9enosi386

圖 最新 MySQL 套件

測試架構圖

91

1921680100

1921680200Master Server

erveSlave S r

圖 測試架構圖

測試步驟

Master server 部份 Step1 確認 MasterSlave機器上所裝的 MySQL版本能進行

replication( 32329 or higher ) Step2 在 Master MySQL上開放一個帳號給 Slave mysql ndashu root ndashp mysqlgtGRANT FILE ON TO repl1921680200 IDENTIFIED BY lsquoabc123rsquo mysqlgtq 上面是 Master開放一個帳號 repl密碼 abc123給 IP1921680200有檔案處理

的權限 Step3 shutdown MySQL on the Master mysqladmin ndashu root ndashp shutdown Step4 備份 Master所有資料庫 tar ndashcvf tmpmysql-snapshottar varlibmysql 注意tar的時候MySQL是要在 stop情況下 在mysql (wwwmysqlcom) 網站的FAQ有不用shutdown的方法

92

Step5 在 master機器上修改etcmycnf 在[mysqld]區段內加入參數 log-bin server-id=這邊設定 server-id=1 sql-bin-update-same binlog-do-db=CRM只針對 CRM資料庫做紀錄 Step6 Restart MySQL on the master service mysqld start 此時因為有加入 log-bin 參數因此開始有 index產生了在varlibmysql目錄下

有index檔案紀錄資料庫的異動 log Slave server 部份 Step1 在 slave設定etcmycnf 在[mysqld]區段加入 master-host= master-user= master-password= master-port= server-id= 這邊設定 master-host=1921680100 master-user=repl master-password=abc123 master-port=3306 server-id=2 master-connect-retry=60預設重試間隔 60秒 replicate-do-db=CRM告訴 slave只做 CRM資料庫的更新 log-slave-updates Step2 將 master上的 mysql-snapshottar copy到 slave上 用 ftp傳到 slave的tmp Step3 解壓縮 Master資料庫至 Slave Server上 cd varlib tar xvf tmpmysql-snapshottar chown ndashR mysqlmysql mysql

93

chmod ndashR 770 mysql (視情況) Step4 Restart MySQL on the slave server 這時在varlibmysql目錄會出現 masterinfo此檔案紀錄了 Master MySQL server的資訊

狀況測試

One-way replication

1921680100

1921680200Master Server

erveSlave S r

圖 One-way replication架構圖 Step1 Master跟 Slave網路及服務都正常情況下由 Master端異動資料後 到 Slave端瀏覽資料檢視是否有進行 replication Step2 模擬 Slave Server 當機 可用在於 slave真的當機或是 Slave 不一定需要一直跟 master connect將Slave MySQL server shutdown由 Master端異動資料到 slave端瀏覽此時Slave應該沒有被 replication 更新然後再將 Slave端 MySQL server start起來

預設 60秒後 Slave會嘗試跟 Master要求進行 replication再去 Slave端檢視是否有更新資料

94

Step3 模擬 Master當機因為是設定 One-way replication一旦 Master Server Slave端沒有 Master的 source可以 download Two-way replication 基於 Master當機狀況於是發展雙向 Replication即 1921680100 ( Host A ) 1921680200 ( Host B )都分別擔任 MasterSlave身分

1921680100

1921680200er

Server B MasterSlave Server

Server A MasterSlave Serv

圖 Two-way replication架構圖 以下是針對兩台 MySQL伺服器進行雙向 Replication Step1觀念同單向 replication只是改成 Master也有 Slave身分 Slave也有Master的身分先分別在 Server AServer B 都去 grant一個進行 replication的身分 [A]mysqlgtGRANT FILE ON TO repl1921680200 IDENTIFIED BY lsquoabc123rsquo [B]mysqlgt GRANT FILE ON TO repl1921680100 IDENTIFIED BY lsquoabc123rsquo Step2做完單向 replication後stop Server Aserver B MySQL service此時 AB資料是一樣的

95

修改etcmycnf設定 範例 Server A [mysqld] datadir=varlibmysql socket=varlibmysqlmysqlsock server-id=1 log-bin sql-bin-update-same binlog-do-db=CRM master-host=1921680200 master-user=repl master-password=abc123 log-slave-updates master-connect-retry=60 replicate-do-db=CRM Server B [mysqld] datadir=varlibmysql socket=varlibmysqlmysqlsock server-id=2 log-bin sql-bin-update-same binlog-do-db=CRM master-host=1921680100 master-user=repl master-password=abc123 log-slave-updates master-connect-retry=60 replicate-do-db=CRM 分別 start Server AServer B MySQL後此時雙方都是 MasterSlave身分一旦哪一方資料異動就會通知對方來 replication-若 replication失效則必須將Server AServer B的masterinfo及index00x 都砍掉然後分別 restart MySQL server進行測試檢視成果 實務上通常如果需要做Two-way replication通常會搭配Virtual Server使用

96

在前端架設一台Virtual Server不過此部份不在此份SOP討論範圍內有興趣

的讀者可參考 httpwwwlinuxvirtualserverorg 網站

1921680100 1921680200

Host A MasterSlave Server

Host B MasterSlave Server

Virtual Host

圖 Virtual Server + Two-way replication 架構圖

97

圖 High Availability Linux Virtual Server架構圖

98

  • COSA-SOP-03-006
  • 第一章 簡介
    • 11適用對象 (Audience)
    • 12 MySQL本身
    • 13 MySQL 40版跟50版重大的改進功能
    • 14 各家資料庫軟體比較
      • 第二章 前置需求
      • 第三章 安裝
        • 31 MySQL安裝
        • 32 phpMyAdmin安裝
        • 33 升級及注意事項
          • 第四章 MySQL管理
            • 41 Webmin 管理介面
            • 42 phpMyAdmin 的操作介面
            • 43管理指令介紹
              • 431 利用mysqladmin設定root的密碼
                  • 第五章 實用範例
                    • 51 任務一Web Base客戶通訊錄
                    • 52 任務二Web Base群組軟體 ( twig )
                      • 第六章 維護及更新程序
                        • 61 日常維護
                        • 62 更新程序
                        • 63 備份重要檔案
                        • 64 離線備份與還原
                        • 65 線上備份與還原
                          • 第七章 問題與解答
                          • 第八章 參考資料
                          • 附錄一 SQL Command 介紹
                          • 附錄二Replication
Page 87: DataBase Server Standard Operation Procedureebooks.lib.ntu.edu.tw/1_file/oss/63/93doc4-5.pdf · 業務的公司帶來了不少壓力,譬如微軟,甲骨文 ... 外的錢用在第三方的資料庫產品上,譬如就可以不用再購買甲骨文公司

SELECT employeeid lastname salary FROM employee_info WHERE lastname IN (Hernandez Jones Roberts Ruiz) 條件為姓氏(astname)要符合 Hernandez Jones Roberts or Ruiz 其中一個才會被傳回 IN運算元也可以使用 OR 的語法來取代如下結果相同 SELECT employeeid lastname salary FROM employee_info WHERE lastname = Hernandez OR lastname = Jones OR lastname = Roberts OR lastname = Ruiz 但使用 IN 句子比較短也比較易懂 你也可以使用 NOT IN 來去掉不要的記錄 BETWEEN 運算元使用在判斷是否存在兩個數值之間 For example SELECT employeeid age lastname salary FROM employee_info WHERE age BETWEEN 30 AND 40 傳回年紀 30歲到 40歲之間的資料(含 30及 40歲者) 相同的也可以使用以下語法來達到相同的結果 SELECT employeeid age lastname salary FROM employee_info WHERE age gt= 30 AND age lt= 40 你也可使用 NOT BETWEEN 來濾掉中間值的資料 數學運算 標準 ANSI SQL-92 提供以下運算

87

+ 加

- 減

餘數

餘數為除法後剩整數這不在標準的 ANSI SQL 中但大部份的資料庫都會支

援這運算元以下列出有用的函數雖不在 ANSI SQL-92 提供但一般資料庫

也會支援他們

ABS(x) 傳回 x 絕對值

SIGN(x) returns the sign of input x as -1 0 or 1 (negative zero or positive respectively)

MOD(xy) 餘數 - returns the integer remainder of x divided by y (同 xy)

FLOOR(x) 傳回小或等於 x 的最大整數值

CEILING(x) or CEIL(x)

傳回大或等於 x 的最小整數值

POWER(xy) x的 y 次方

ROUND(x) 把 x 四捨五入為整數

ROUND(xd) 四捨五入取到小數 d 位

SQRT(x) x 開平方

For example SELECT round(salary) firstname FROM employee_info 傳回薪資取到整數位

如何新增資料

insert 加入一筆新紀錄到資料表中 insert into tablename (first_columnlast_column) values (first_valuelast_value) [] = optional Example insert into employee

88

(first last age address city state) values (Luke Duke 45 2130 Boars Nest Hazard Co Georgia) Note 字串要以單引號住如string 數字框住也無妨 insert into 後面接資料表名稱再接以括號括住的欄位名在 values 後括號分別對映各欄位的值 以上的例子新增了一筆名(first) 為 Luke而住所(state) 為 Georgia 的資料

如何刪除資料

delete 可以刪除單筆或多筆紀錄 delete from tablename where columnname OPERATOR value [and|or column OPERATOR value] [ ] = optional Examples delete from employee Note 如果你沒有指定 where 子句那麼全部的紀錄都會被刪除 delete from employee where lastname = May delete from employee where firstname = Mike or firstname = Eric delete from 接著資料表名 再接著是條件式判斷沒有條件式則全部紀錄會

被刪除

如何更新資料

update 用來更新你所指定的記錄要和 WHERE 配合小心使用 語法 update tablename set columnname = newvalue[nextcolumn = newvalue2] where columnname OPERATOR value [and|or column OPERATOR value] [] = optional Examples

89

update phone_book set area_code = 623 where prefix = 979 update phone_book set last_name = Smith prefix=555 suffix=9292 where last_name = Jones update employee set age = age+1 where first_name=Mary and last_name=Williams

90

附錄二Replication

測試環境

RedHat 90 + MySQL 32358 MySQL資料庫路徑 varlibmysql MySQL設定檔 etcmycnf Master IP 1921680100 Slave IP 1921680200 請至下列網址下載最新MySQL 32358套件並利用rpm ndashUvh 更新 httpupdatesredhatcom9enosi386

圖 最新 MySQL 套件

測試架構圖

91

1921680100

1921680200Master Server

erveSlave S r

圖 測試架構圖

測試步驟

Master server 部份 Step1 確認 MasterSlave機器上所裝的 MySQL版本能進行

replication( 32329 or higher ) Step2 在 Master MySQL上開放一個帳號給 Slave mysql ndashu root ndashp mysqlgtGRANT FILE ON TO repl1921680200 IDENTIFIED BY lsquoabc123rsquo mysqlgtq 上面是 Master開放一個帳號 repl密碼 abc123給 IP1921680200有檔案處理

的權限 Step3 shutdown MySQL on the Master mysqladmin ndashu root ndashp shutdown Step4 備份 Master所有資料庫 tar ndashcvf tmpmysql-snapshottar varlibmysql 注意tar的時候MySQL是要在 stop情況下 在mysql (wwwmysqlcom) 網站的FAQ有不用shutdown的方法

92

Step5 在 master機器上修改etcmycnf 在[mysqld]區段內加入參數 log-bin server-id=這邊設定 server-id=1 sql-bin-update-same binlog-do-db=CRM只針對 CRM資料庫做紀錄 Step6 Restart MySQL on the master service mysqld start 此時因為有加入 log-bin 參數因此開始有 index產生了在varlibmysql目錄下

有index檔案紀錄資料庫的異動 log Slave server 部份 Step1 在 slave設定etcmycnf 在[mysqld]區段加入 master-host= master-user= master-password= master-port= server-id= 這邊設定 master-host=1921680100 master-user=repl master-password=abc123 master-port=3306 server-id=2 master-connect-retry=60預設重試間隔 60秒 replicate-do-db=CRM告訴 slave只做 CRM資料庫的更新 log-slave-updates Step2 將 master上的 mysql-snapshottar copy到 slave上 用 ftp傳到 slave的tmp Step3 解壓縮 Master資料庫至 Slave Server上 cd varlib tar xvf tmpmysql-snapshottar chown ndashR mysqlmysql mysql

93

chmod ndashR 770 mysql (視情況) Step4 Restart MySQL on the slave server 這時在varlibmysql目錄會出現 masterinfo此檔案紀錄了 Master MySQL server的資訊

狀況測試

One-way replication

1921680100

1921680200Master Server

erveSlave S r

圖 One-way replication架構圖 Step1 Master跟 Slave網路及服務都正常情況下由 Master端異動資料後 到 Slave端瀏覽資料檢視是否有進行 replication Step2 模擬 Slave Server 當機 可用在於 slave真的當機或是 Slave 不一定需要一直跟 master connect將Slave MySQL server shutdown由 Master端異動資料到 slave端瀏覽此時Slave應該沒有被 replication 更新然後再將 Slave端 MySQL server start起來

預設 60秒後 Slave會嘗試跟 Master要求進行 replication再去 Slave端檢視是否有更新資料

94

Step3 模擬 Master當機因為是設定 One-way replication一旦 Master Server Slave端沒有 Master的 source可以 download Two-way replication 基於 Master當機狀況於是發展雙向 Replication即 1921680100 ( Host A ) 1921680200 ( Host B )都分別擔任 MasterSlave身分

1921680100

1921680200er

Server B MasterSlave Server

Server A MasterSlave Serv

圖 Two-way replication架構圖 以下是針對兩台 MySQL伺服器進行雙向 Replication Step1觀念同單向 replication只是改成 Master也有 Slave身分 Slave也有Master的身分先分別在 Server AServer B 都去 grant一個進行 replication的身分 [A]mysqlgtGRANT FILE ON TO repl1921680200 IDENTIFIED BY lsquoabc123rsquo [B]mysqlgt GRANT FILE ON TO repl1921680100 IDENTIFIED BY lsquoabc123rsquo Step2做完單向 replication後stop Server Aserver B MySQL service此時 AB資料是一樣的

95

修改etcmycnf設定 範例 Server A [mysqld] datadir=varlibmysql socket=varlibmysqlmysqlsock server-id=1 log-bin sql-bin-update-same binlog-do-db=CRM master-host=1921680200 master-user=repl master-password=abc123 log-slave-updates master-connect-retry=60 replicate-do-db=CRM Server B [mysqld] datadir=varlibmysql socket=varlibmysqlmysqlsock server-id=2 log-bin sql-bin-update-same binlog-do-db=CRM master-host=1921680100 master-user=repl master-password=abc123 log-slave-updates master-connect-retry=60 replicate-do-db=CRM 分別 start Server AServer B MySQL後此時雙方都是 MasterSlave身分一旦哪一方資料異動就會通知對方來 replication-若 replication失效則必須將Server AServer B的masterinfo及index00x 都砍掉然後分別 restart MySQL server進行測試檢視成果 實務上通常如果需要做Two-way replication通常會搭配Virtual Server使用

96

在前端架設一台Virtual Server不過此部份不在此份SOP討論範圍內有興趣

的讀者可參考 httpwwwlinuxvirtualserverorg 網站

1921680100 1921680200

Host A MasterSlave Server

Host B MasterSlave Server

Virtual Host

圖 Virtual Server + Two-way replication 架構圖

97

圖 High Availability Linux Virtual Server架構圖

98

  • COSA-SOP-03-006
  • 第一章 簡介
    • 11適用對象 (Audience)
    • 12 MySQL本身
    • 13 MySQL 40版跟50版重大的改進功能
    • 14 各家資料庫軟體比較
      • 第二章 前置需求
      • 第三章 安裝
        • 31 MySQL安裝
        • 32 phpMyAdmin安裝
        • 33 升級及注意事項
          • 第四章 MySQL管理
            • 41 Webmin 管理介面
            • 42 phpMyAdmin 的操作介面
            • 43管理指令介紹
              • 431 利用mysqladmin設定root的密碼
                  • 第五章 實用範例
                    • 51 任務一Web Base客戶通訊錄
                    • 52 任務二Web Base群組軟體 ( twig )
                      • 第六章 維護及更新程序
                        • 61 日常維護
                        • 62 更新程序
                        • 63 備份重要檔案
                        • 64 離線備份與還原
                        • 65 線上備份與還原
                          • 第七章 問題與解答
                          • 第八章 參考資料
                          • 附錄一 SQL Command 介紹
                          • 附錄二Replication
Page 88: DataBase Server Standard Operation Procedureebooks.lib.ntu.edu.tw/1_file/oss/63/93doc4-5.pdf · 業務的公司帶來了不少壓力,譬如微軟,甲骨文 ... 外的錢用在第三方的資料庫產品上,譬如就可以不用再購買甲骨文公司

+ 加

- 減

餘數

餘數為除法後剩整數這不在標準的 ANSI SQL 中但大部份的資料庫都會支

援這運算元以下列出有用的函數雖不在 ANSI SQL-92 提供但一般資料庫

也會支援他們

ABS(x) 傳回 x 絕對值

SIGN(x) returns the sign of input x as -1 0 or 1 (negative zero or positive respectively)

MOD(xy) 餘數 - returns the integer remainder of x divided by y (同 xy)

FLOOR(x) 傳回小或等於 x 的最大整數值

CEILING(x) or CEIL(x)

傳回大或等於 x 的最小整數值

POWER(xy) x的 y 次方

ROUND(x) 把 x 四捨五入為整數

ROUND(xd) 四捨五入取到小數 d 位

SQRT(x) x 開平方

For example SELECT round(salary) firstname FROM employee_info 傳回薪資取到整數位

如何新增資料

insert 加入一筆新紀錄到資料表中 insert into tablename (first_columnlast_column) values (first_valuelast_value) [] = optional Example insert into employee

88

(first last age address city state) values (Luke Duke 45 2130 Boars Nest Hazard Co Georgia) Note 字串要以單引號住如string 數字框住也無妨 insert into 後面接資料表名稱再接以括號括住的欄位名在 values 後括號分別對映各欄位的值 以上的例子新增了一筆名(first) 為 Luke而住所(state) 為 Georgia 的資料

如何刪除資料

delete 可以刪除單筆或多筆紀錄 delete from tablename where columnname OPERATOR value [and|or column OPERATOR value] [ ] = optional Examples delete from employee Note 如果你沒有指定 where 子句那麼全部的紀錄都會被刪除 delete from employee where lastname = May delete from employee where firstname = Mike or firstname = Eric delete from 接著資料表名 再接著是條件式判斷沒有條件式則全部紀錄會

被刪除

如何更新資料

update 用來更新你所指定的記錄要和 WHERE 配合小心使用 語法 update tablename set columnname = newvalue[nextcolumn = newvalue2] where columnname OPERATOR value [and|or column OPERATOR value] [] = optional Examples

89

update phone_book set area_code = 623 where prefix = 979 update phone_book set last_name = Smith prefix=555 suffix=9292 where last_name = Jones update employee set age = age+1 where first_name=Mary and last_name=Williams

90

附錄二Replication

測試環境

RedHat 90 + MySQL 32358 MySQL資料庫路徑 varlibmysql MySQL設定檔 etcmycnf Master IP 1921680100 Slave IP 1921680200 請至下列網址下載最新MySQL 32358套件並利用rpm ndashUvh 更新 httpupdatesredhatcom9enosi386

圖 最新 MySQL 套件

測試架構圖

91

1921680100

1921680200Master Server

erveSlave S r

圖 測試架構圖

測試步驟

Master server 部份 Step1 確認 MasterSlave機器上所裝的 MySQL版本能進行

replication( 32329 or higher ) Step2 在 Master MySQL上開放一個帳號給 Slave mysql ndashu root ndashp mysqlgtGRANT FILE ON TO repl1921680200 IDENTIFIED BY lsquoabc123rsquo mysqlgtq 上面是 Master開放一個帳號 repl密碼 abc123給 IP1921680200有檔案處理

的權限 Step3 shutdown MySQL on the Master mysqladmin ndashu root ndashp shutdown Step4 備份 Master所有資料庫 tar ndashcvf tmpmysql-snapshottar varlibmysql 注意tar的時候MySQL是要在 stop情況下 在mysql (wwwmysqlcom) 網站的FAQ有不用shutdown的方法

92

Step5 在 master機器上修改etcmycnf 在[mysqld]區段內加入參數 log-bin server-id=這邊設定 server-id=1 sql-bin-update-same binlog-do-db=CRM只針對 CRM資料庫做紀錄 Step6 Restart MySQL on the master service mysqld start 此時因為有加入 log-bin 參數因此開始有 index產生了在varlibmysql目錄下

有index檔案紀錄資料庫的異動 log Slave server 部份 Step1 在 slave設定etcmycnf 在[mysqld]區段加入 master-host= master-user= master-password= master-port= server-id= 這邊設定 master-host=1921680100 master-user=repl master-password=abc123 master-port=3306 server-id=2 master-connect-retry=60預設重試間隔 60秒 replicate-do-db=CRM告訴 slave只做 CRM資料庫的更新 log-slave-updates Step2 將 master上的 mysql-snapshottar copy到 slave上 用 ftp傳到 slave的tmp Step3 解壓縮 Master資料庫至 Slave Server上 cd varlib tar xvf tmpmysql-snapshottar chown ndashR mysqlmysql mysql

93

chmod ndashR 770 mysql (視情況) Step4 Restart MySQL on the slave server 這時在varlibmysql目錄會出現 masterinfo此檔案紀錄了 Master MySQL server的資訊

狀況測試

One-way replication

1921680100

1921680200Master Server

erveSlave S r

圖 One-way replication架構圖 Step1 Master跟 Slave網路及服務都正常情況下由 Master端異動資料後 到 Slave端瀏覽資料檢視是否有進行 replication Step2 模擬 Slave Server 當機 可用在於 slave真的當機或是 Slave 不一定需要一直跟 master connect將Slave MySQL server shutdown由 Master端異動資料到 slave端瀏覽此時Slave應該沒有被 replication 更新然後再將 Slave端 MySQL server start起來

預設 60秒後 Slave會嘗試跟 Master要求進行 replication再去 Slave端檢視是否有更新資料

94

Step3 模擬 Master當機因為是設定 One-way replication一旦 Master Server Slave端沒有 Master的 source可以 download Two-way replication 基於 Master當機狀況於是發展雙向 Replication即 1921680100 ( Host A ) 1921680200 ( Host B )都分別擔任 MasterSlave身分

1921680100

1921680200er

Server B MasterSlave Server

Server A MasterSlave Serv

圖 Two-way replication架構圖 以下是針對兩台 MySQL伺服器進行雙向 Replication Step1觀念同單向 replication只是改成 Master也有 Slave身分 Slave也有Master的身分先分別在 Server AServer B 都去 grant一個進行 replication的身分 [A]mysqlgtGRANT FILE ON TO repl1921680200 IDENTIFIED BY lsquoabc123rsquo [B]mysqlgt GRANT FILE ON TO repl1921680100 IDENTIFIED BY lsquoabc123rsquo Step2做完單向 replication後stop Server Aserver B MySQL service此時 AB資料是一樣的

95

修改etcmycnf設定 範例 Server A [mysqld] datadir=varlibmysql socket=varlibmysqlmysqlsock server-id=1 log-bin sql-bin-update-same binlog-do-db=CRM master-host=1921680200 master-user=repl master-password=abc123 log-slave-updates master-connect-retry=60 replicate-do-db=CRM Server B [mysqld] datadir=varlibmysql socket=varlibmysqlmysqlsock server-id=2 log-bin sql-bin-update-same binlog-do-db=CRM master-host=1921680100 master-user=repl master-password=abc123 log-slave-updates master-connect-retry=60 replicate-do-db=CRM 分別 start Server AServer B MySQL後此時雙方都是 MasterSlave身分一旦哪一方資料異動就會通知對方來 replication-若 replication失效則必須將Server AServer B的masterinfo及index00x 都砍掉然後分別 restart MySQL server進行測試檢視成果 實務上通常如果需要做Two-way replication通常會搭配Virtual Server使用

96

在前端架設一台Virtual Server不過此部份不在此份SOP討論範圍內有興趣

的讀者可參考 httpwwwlinuxvirtualserverorg 網站

1921680100 1921680200

Host A MasterSlave Server

Host B MasterSlave Server

Virtual Host

圖 Virtual Server + Two-way replication 架構圖

97

圖 High Availability Linux Virtual Server架構圖

98

  • COSA-SOP-03-006
  • 第一章 簡介
    • 11適用對象 (Audience)
    • 12 MySQL本身
    • 13 MySQL 40版跟50版重大的改進功能
    • 14 各家資料庫軟體比較
      • 第二章 前置需求
      • 第三章 安裝
        • 31 MySQL安裝
        • 32 phpMyAdmin安裝
        • 33 升級及注意事項
          • 第四章 MySQL管理
            • 41 Webmin 管理介面
            • 42 phpMyAdmin 的操作介面
            • 43管理指令介紹
              • 431 利用mysqladmin設定root的密碼
                  • 第五章 實用範例
                    • 51 任務一Web Base客戶通訊錄
                    • 52 任務二Web Base群組軟體 ( twig )
                      • 第六章 維護及更新程序
                        • 61 日常維護
                        • 62 更新程序
                        • 63 備份重要檔案
                        • 64 離線備份與還原
                        • 65 線上備份與還原
                          • 第七章 問題與解答
                          • 第八章 參考資料
                          • 附錄一 SQL Command 介紹
                          • 附錄二Replication
Page 89: DataBase Server Standard Operation Procedureebooks.lib.ntu.edu.tw/1_file/oss/63/93doc4-5.pdf · 業務的公司帶來了不少壓力,譬如微軟,甲骨文 ... 外的錢用在第三方的資料庫產品上,譬如就可以不用再購買甲骨文公司

(first last age address city state) values (Luke Duke 45 2130 Boars Nest Hazard Co Georgia) Note 字串要以單引號住如string 數字框住也無妨 insert into 後面接資料表名稱再接以括號括住的欄位名在 values 後括號分別對映各欄位的值 以上的例子新增了一筆名(first) 為 Luke而住所(state) 為 Georgia 的資料

如何刪除資料

delete 可以刪除單筆或多筆紀錄 delete from tablename where columnname OPERATOR value [and|or column OPERATOR value] [ ] = optional Examples delete from employee Note 如果你沒有指定 where 子句那麼全部的紀錄都會被刪除 delete from employee where lastname = May delete from employee where firstname = Mike or firstname = Eric delete from 接著資料表名 再接著是條件式判斷沒有條件式則全部紀錄會

被刪除

如何更新資料

update 用來更新你所指定的記錄要和 WHERE 配合小心使用 語法 update tablename set columnname = newvalue[nextcolumn = newvalue2] where columnname OPERATOR value [and|or column OPERATOR value] [] = optional Examples

89

update phone_book set area_code = 623 where prefix = 979 update phone_book set last_name = Smith prefix=555 suffix=9292 where last_name = Jones update employee set age = age+1 where first_name=Mary and last_name=Williams

90

附錄二Replication

測試環境

RedHat 90 + MySQL 32358 MySQL資料庫路徑 varlibmysql MySQL設定檔 etcmycnf Master IP 1921680100 Slave IP 1921680200 請至下列網址下載最新MySQL 32358套件並利用rpm ndashUvh 更新 httpupdatesredhatcom9enosi386

圖 最新 MySQL 套件

測試架構圖

91

1921680100

1921680200Master Server

erveSlave S r

圖 測試架構圖

測試步驟

Master server 部份 Step1 確認 MasterSlave機器上所裝的 MySQL版本能進行

replication( 32329 or higher ) Step2 在 Master MySQL上開放一個帳號給 Slave mysql ndashu root ndashp mysqlgtGRANT FILE ON TO repl1921680200 IDENTIFIED BY lsquoabc123rsquo mysqlgtq 上面是 Master開放一個帳號 repl密碼 abc123給 IP1921680200有檔案處理

的權限 Step3 shutdown MySQL on the Master mysqladmin ndashu root ndashp shutdown Step4 備份 Master所有資料庫 tar ndashcvf tmpmysql-snapshottar varlibmysql 注意tar的時候MySQL是要在 stop情況下 在mysql (wwwmysqlcom) 網站的FAQ有不用shutdown的方法

92

Step5 在 master機器上修改etcmycnf 在[mysqld]區段內加入參數 log-bin server-id=這邊設定 server-id=1 sql-bin-update-same binlog-do-db=CRM只針對 CRM資料庫做紀錄 Step6 Restart MySQL on the master service mysqld start 此時因為有加入 log-bin 參數因此開始有 index產生了在varlibmysql目錄下

有index檔案紀錄資料庫的異動 log Slave server 部份 Step1 在 slave設定etcmycnf 在[mysqld]區段加入 master-host= master-user= master-password= master-port= server-id= 這邊設定 master-host=1921680100 master-user=repl master-password=abc123 master-port=3306 server-id=2 master-connect-retry=60預設重試間隔 60秒 replicate-do-db=CRM告訴 slave只做 CRM資料庫的更新 log-slave-updates Step2 將 master上的 mysql-snapshottar copy到 slave上 用 ftp傳到 slave的tmp Step3 解壓縮 Master資料庫至 Slave Server上 cd varlib tar xvf tmpmysql-snapshottar chown ndashR mysqlmysql mysql

93

chmod ndashR 770 mysql (視情況) Step4 Restart MySQL on the slave server 這時在varlibmysql目錄會出現 masterinfo此檔案紀錄了 Master MySQL server的資訊

狀況測試

One-way replication

1921680100

1921680200Master Server

erveSlave S r

圖 One-way replication架構圖 Step1 Master跟 Slave網路及服務都正常情況下由 Master端異動資料後 到 Slave端瀏覽資料檢視是否有進行 replication Step2 模擬 Slave Server 當機 可用在於 slave真的當機或是 Slave 不一定需要一直跟 master connect將Slave MySQL server shutdown由 Master端異動資料到 slave端瀏覽此時Slave應該沒有被 replication 更新然後再將 Slave端 MySQL server start起來

預設 60秒後 Slave會嘗試跟 Master要求進行 replication再去 Slave端檢視是否有更新資料

94

Step3 模擬 Master當機因為是設定 One-way replication一旦 Master Server Slave端沒有 Master的 source可以 download Two-way replication 基於 Master當機狀況於是發展雙向 Replication即 1921680100 ( Host A ) 1921680200 ( Host B )都分別擔任 MasterSlave身分

1921680100

1921680200er

Server B MasterSlave Server

Server A MasterSlave Serv

圖 Two-way replication架構圖 以下是針對兩台 MySQL伺服器進行雙向 Replication Step1觀念同單向 replication只是改成 Master也有 Slave身分 Slave也有Master的身分先分別在 Server AServer B 都去 grant一個進行 replication的身分 [A]mysqlgtGRANT FILE ON TO repl1921680200 IDENTIFIED BY lsquoabc123rsquo [B]mysqlgt GRANT FILE ON TO repl1921680100 IDENTIFIED BY lsquoabc123rsquo Step2做完單向 replication後stop Server Aserver B MySQL service此時 AB資料是一樣的

95

修改etcmycnf設定 範例 Server A [mysqld] datadir=varlibmysql socket=varlibmysqlmysqlsock server-id=1 log-bin sql-bin-update-same binlog-do-db=CRM master-host=1921680200 master-user=repl master-password=abc123 log-slave-updates master-connect-retry=60 replicate-do-db=CRM Server B [mysqld] datadir=varlibmysql socket=varlibmysqlmysqlsock server-id=2 log-bin sql-bin-update-same binlog-do-db=CRM master-host=1921680100 master-user=repl master-password=abc123 log-slave-updates master-connect-retry=60 replicate-do-db=CRM 分別 start Server AServer B MySQL後此時雙方都是 MasterSlave身分一旦哪一方資料異動就會通知對方來 replication-若 replication失效則必須將Server AServer B的masterinfo及index00x 都砍掉然後分別 restart MySQL server進行測試檢視成果 實務上通常如果需要做Two-way replication通常會搭配Virtual Server使用

96

在前端架設一台Virtual Server不過此部份不在此份SOP討論範圍內有興趣

的讀者可參考 httpwwwlinuxvirtualserverorg 網站

1921680100 1921680200

Host A MasterSlave Server

Host B MasterSlave Server

Virtual Host

圖 Virtual Server + Two-way replication 架構圖

97

圖 High Availability Linux Virtual Server架構圖

98

  • COSA-SOP-03-006
  • 第一章 簡介
    • 11適用對象 (Audience)
    • 12 MySQL本身
    • 13 MySQL 40版跟50版重大的改進功能
    • 14 各家資料庫軟體比較
      • 第二章 前置需求
      • 第三章 安裝
        • 31 MySQL安裝
        • 32 phpMyAdmin安裝
        • 33 升級及注意事項
          • 第四章 MySQL管理
            • 41 Webmin 管理介面
            • 42 phpMyAdmin 的操作介面
            • 43管理指令介紹
              • 431 利用mysqladmin設定root的密碼
                  • 第五章 實用範例
                    • 51 任務一Web Base客戶通訊錄
                    • 52 任務二Web Base群組軟體 ( twig )
                      • 第六章 維護及更新程序
                        • 61 日常維護
                        • 62 更新程序
                        • 63 備份重要檔案
                        • 64 離線備份與還原
                        • 65 線上備份與還原
                          • 第七章 問題與解答
                          • 第八章 參考資料
                          • 附錄一 SQL Command 介紹
                          • 附錄二Replication
Page 90: DataBase Server Standard Operation Procedureebooks.lib.ntu.edu.tw/1_file/oss/63/93doc4-5.pdf · 業務的公司帶來了不少壓力,譬如微軟,甲骨文 ... 外的錢用在第三方的資料庫產品上,譬如就可以不用再購買甲骨文公司

update phone_book set area_code = 623 where prefix = 979 update phone_book set last_name = Smith prefix=555 suffix=9292 where last_name = Jones update employee set age = age+1 where first_name=Mary and last_name=Williams

90

附錄二Replication

測試環境

RedHat 90 + MySQL 32358 MySQL資料庫路徑 varlibmysql MySQL設定檔 etcmycnf Master IP 1921680100 Slave IP 1921680200 請至下列網址下載最新MySQL 32358套件並利用rpm ndashUvh 更新 httpupdatesredhatcom9enosi386

圖 最新 MySQL 套件

測試架構圖

91

1921680100

1921680200Master Server

erveSlave S r

圖 測試架構圖

測試步驟

Master server 部份 Step1 確認 MasterSlave機器上所裝的 MySQL版本能進行

replication( 32329 or higher ) Step2 在 Master MySQL上開放一個帳號給 Slave mysql ndashu root ndashp mysqlgtGRANT FILE ON TO repl1921680200 IDENTIFIED BY lsquoabc123rsquo mysqlgtq 上面是 Master開放一個帳號 repl密碼 abc123給 IP1921680200有檔案處理

的權限 Step3 shutdown MySQL on the Master mysqladmin ndashu root ndashp shutdown Step4 備份 Master所有資料庫 tar ndashcvf tmpmysql-snapshottar varlibmysql 注意tar的時候MySQL是要在 stop情況下 在mysql (wwwmysqlcom) 網站的FAQ有不用shutdown的方法

92

Step5 在 master機器上修改etcmycnf 在[mysqld]區段內加入參數 log-bin server-id=這邊設定 server-id=1 sql-bin-update-same binlog-do-db=CRM只針對 CRM資料庫做紀錄 Step6 Restart MySQL on the master service mysqld start 此時因為有加入 log-bin 參數因此開始有 index產生了在varlibmysql目錄下

有index檔案紀錄資料庫的異動 log Slave server 部份 Step1 在 slave設定etcmycnf 在[mysqld]區段加入 master-host= master-user= master-password= master-port= server-id= 這邊設定 master-host=1921680100 master-user=repl master-password=abc123 master-port=3306 server-id=2 master-connect-retry=60預設重試間隔 60秒 replicate-do-db=CRM告訴 slave只做 CRM資料庫的更新 log-slave-updates Step2 將 master上的 mysql-snapshottar copy到 slave上 用 ftp傳到 slave的tmp Step3 解壓縮 Master資料庫至 Slave Server上 cd varlib tar xvf tmpmysql-snapshottar chown ndashR mysqlmysql mysql

93

chmod ndashR 770 mysql (視情況) Step4 Restart MySQL on the slave server 這時在varlibmysql目錄會出現 masterinfo此檔案紀錄了 Master MySQL server的資訊

狀況測試

One-way replication

1921680100

1921680200Master Server

erveSlave S r

圖 One-way replication架構圖 Step1 Master跟 Slave網路及服務都正常情況下由 Master端異動資料後 到 Slave端瀏覽資料檢視是否有進行 replication Step2 模擬 Slave Server 當機 可用在於 slave真的當機或是 Slave 不一定需要一直跟 master connect將Slave MySQL server shutdown由 Master端異動資料到 slave端瀏覽此時Slave應該沒有被 replication 更新然後再將 Slave端 MySQL server start起來

預設 60秒後 Slave會嘗試跟 Master要求進行 replication再去 Slave端檢視是否有更新資料

94

Step3 模擬 Master當機因為是設定 One-way replication一旦 Master Server Slave端沒有 Master的 source可以 download Two-way replication 基於 Master當機狀況於是發展雙向 Replication即 1921680100 ( Host A ) 1921680200 ( Host B )都分別擔任 MasterSlave身分

1921680100

1921680200er

Server B MasterSlave Server

Server A MasterSlave Serv

圖 Two-way replication架構圖 以下是針對兩台 MySQL伺服器進行雙向 Replication Step1觀念同單向 replication只是改成 Master也有 Slave身分 Slave也有Master的身分先分別在 Server AServer B 都去 grant一個進行 replication的身分 [A]mysqlgtGRANT FILE ON TO repl1921680200 IDENTIFIED BY lsquoabc123rsquo [B]mysqlgt GRANT FILE ON TO repl1921680100 IDENTIFIED BY lsquoabc123rsquo Step2做完單向 replication後stop Server Aserver B MySQL service此時 AB資料是一樣的

95

修改etcmycnf設定 範例 Server A [mysqld] datadir=varlibmysql socket=varlibmysqlmysqlsock server-id=1 log-bin sql-bin-update-same binlog-do-db=CRM master-host=1921680200 master-user=repl master-password=abc123 log-slave-updates master-connect-retry=60 replicate-do-db=CRM Server B [mysqld] datadir=varlibmysql socket=varlibmysqlmysqlsock server-id=2 log-bin sql-bin-update-same binlog-do-db=CRM master-host=1921680100 master-user=repl master-password=abc123 log-slave-updates master-connect-retry=60 replicate-do-db=CRM 分別 start Server AServer B MySQL後此時雙方都是 MasterSlave身分一旦哪一方資料異動就會通知對方來 replication-若 replication失效則必須將Server AServer B的masterinfo及index00x 都砍掉然後分別 restart MySQL server進行測試檢視成果 實務上通常如果需要做Two-way replication通常會搭配Virtual Server使用

96

在前端架設一台Virtual Server不過此部份不在此份SOP討論範圍內有興趣

的讀者可參考 httpwwwlinuxvirtualserverorg 網站

1921680100 1921680200

Host A MasterSlave Server

Host B MasterSlave Server

Virtual Host

圖 Virtual Server + Two-way replication 架構圖

97

圖 High Availability Linux Virtual Server架構圖

98

  • COSA-SOP-03-006
  • 第一章 簡介
    • 11適用對象 (Audience)
    • 12 MySQL本身
    • 13 MySQL 40版跟50版重大的改進功能
    • 14 各家資料庫軟體比較
      • 第二章 前置需求
      • 第三章 安裝
        • 31 MySQL安裝
        • 32 phpMyAdmin安裝
        • 33 升級及注意事項
          • 第四章 MySQL管理
            • 41 Webmin 管理介面
            • 42 phpMyAdmin 的操作介面
            • 43管理指令介紹
              • 431 利用mysqladmin設定root的密碼
                  • 第五章 實用範例
                    • 51 任務一Web Base客戶通訊錄
                    • 52 任務二Web Base群組軟體 ( twig )
                      • 第六章 維護及更新程序
                        • 61 日常維護
                        • 62 更新程序
                        • 63 備份重要檔案
                        • 64 離線備份與還原
                        • 65 線上備份與還原
                          • 第七章 問題與解答
                          • 第八章 參考資料
                          • 附錄一 SQL Command 介紹
                          • 附錄二Replication
Page 91: DataBase Server Standard Operation Procedureebooks.lib.ntu.edu.tw/1_file/oss/63/93doc4-5.pdf · 業務的公司帶來了不少壓力,譬如微軟,甲骨文 ... 外的錢用在第三方的資料庫產品上,譬如就可以不用再購買甲骨文公司

附錄二Replication

測試環境

RedHat 90 + MySQL 32358 MySQL資料庫路徑 varlibmysql MySQL設定檔 etcmycnf Master IP 1921680100 Slave IP 1921680200 請至下列網址下載最新MySQL 32358套件並利用rpm ndashUvh 更新 httpupdatesredhatcom9enosi386

圖 最新 MySQL 套件

測試架構圖

91

1921680100

1921680200Master Server

erveSlave S r

圖 測試架構圖

測試步驟

Master server 部份 Step1 確認 MasterSlave機器上所裝的 MySQL版本能進行

replication( 32329 or higher ) Step2 在 Master MySQL上開放一個帳號給 Slave mysql ndashu root ndashp mysqlgtGRANT FILE ON TO repl1921680200 IDENTIFIED BY lsquoabc123rsquo mysqlgtq 上面是 Master開放一個帳號 repl密碼 abc123給 IP1921680200有檔案處理

的權限 Step3 shutdown MySQL on the Master mysqladmin ndashu root ndashp shutdown Step4 備份 Master所有資料庫 tar ndashcvf tmpmysql-snapshottar varlibmysql 注意tar的時候MySQL是要在 stop情況下 在mysql (wwwmysqlcom) 網站的FAQ有不用shutdown的方法

92

Step5 在 master機器上修改etcmycnf 在[mysqld]區段內加入參數 log-bin server-id=這邊設定 server-id=1 sql-bin-update-same binlog-do-db=CRM只針對 CRM資料庫做紀錄 Step6 Restart MySQL on the master service mysqld start 此時因為有加入 log-bin 參數因此開始有 index產生了在varlibmysql目錄下

有index檔案紀錄資料庫的異動 log Slave server 部份 Step1 在 slave設定etcmycnf 在[mysqld]區段加入 master-host= master-user= master-password= master-port= server-id= 這邊設定 master-host=1921680100 master-user=repl master-password=abc123 master-port=3306 server-id=2 master-connect-retry=60預設重試間隔 60秒 replicate-do-db=CRM告訴 slave只做 CRM資料庫的更新 log-slave-updates Step2 將 master上的 mysql-snapshottar copy到 slave上 用 ftp傳到 slave的tmp Step3 解壓縮 Master資料庫至 Slave Server上 cd varlib tar xvf tmpmysql-snapshottar chown ndashR mysqlmysql mysql

93

chmod ndashR 770 mysql (視情況) Step4 Restart MySQL on the slave server 這時在varlibmysql目錄會出現 masterinfo此檔案紀錄了 Master MySQL server的資訊

狀況測試

One-way replication

1921680100

1921680200Master Server

erveSlave S r

圖 One-way replication架構圖 Step1 Master跟 Slave網路及服務都正常情況下由 Master端異動資料後 到 Slave端瀏覽資料檢視是否有進行 replication Step2 模擬 Slave Server 當機 可用在於 slave真的當機或是 Slave 不一定需要一直跟 master connect將Slave MySQL server shutdown由 Master端異動資料到 slave端瀏覽此時Slave應該沒有被 replication 更新然後再將 Slave端 MySQL server start起來

預設 60秒後 Slave會嘗試跟 Master要求進行 replication再去 Slave端檢視是否有更新資料

94

Step3 模擬 Master當機因為是設定 One-way replication一旦 Master Server Slave端沒有 Master的 source可以 download Two-way replication 基於 Master當機狀況於是發展雙向 Replication即 1921680100 ( Host A ) 1921680200 ( Host B )都分別擔任 MasterSlave身分

1921680100

1921680200er

Server B MasterSlave Server

Server A MasterSlave Serv

圖 Two-way replication架構圖 以下是針對兩台 MySQL伺服器進行雙向 Replication Step1觀念同單向 replication只是改成 Master也有 Slave身分 Slave也有Master的身分先分別在 Server AServer B 都去 grant一個進行 replication的身分 [A]mysqlgtGRANT FILE ON TO repl1921680200 IDENTIFIED BY lsquoabc123rsquo [B]mysqlgt GRANT FILE ON TO repl1921680100 IDENTIFIED BY lsquoabc123rsquo Step2做完單向 replication後stop Server Aserver B MySQL service此時 AB資料是一樣的

95

修改etcmycnf設定 範例 Server A [mysqld] datadir=varlibmysql socket=varlibmysqlmysqlsock server-id=1 log-bin sql-bin-update-same binlog-do-db=CRM master-host=1921680200 master-user=repl master-password=abc123 log-slave-updates master-connect-retry=60 replicate-do-db=CRM Server B [mysqld] datadir=varlibmysql socket=varlibmysqlmysqlsock server-id=2 log-bin sql-bin-update-same binlog-do-db=CRM master-host=1921680100 master-user=repl master-password=abc123 log-slave-updates master-connect-retry=60 replicate-do-db=CRM 分別 start Server AServer B MySQL後此時雙方都是 MasterSlave身分一旦哪一方資料異動就會通知對方來 replication-若 replication失效則必須將Server AServer B的masterinfo及index00x 都砍掉然後分別 restart MySQL server進行測試檢視成果 實務上通常如果需要做Two-way replication通常會搭配Virtual Server使用

96

在前端架設一台Virtual Server不過此部份不在此份SOP討論範圍內有興趣

的讀者可參考 httpwwwlinuxvirtualserverorg 網站

1921680100 1921680200

Host A MasterSlave Server

Host B MasterSlave Server

Virtual Host

圖 Virtual Server + Two-way replication 架構圖

97

圖 High Availability Linux Virtual Server架構圖

98

  • COSA-SOP-03-006
  • 第一章 簡介
    • 11適用對象 (Audience)
    • 12 MySQL本身
    • 13 MySQL 40版跟50版重大的改進功能
    • 14 各家資料庫軟體比較
      • 第二章 前置需求
      • 第三章 安裝
        • 31 MySQL安裝
        • 32 phpMyAdmin安裝
        • 33 升級及注意事項
          • 第四章 MySQL管理
            • 41 Webmin 管理介面
            • 42 phpMyAdmin 的操作介面
            • 43管理指令介紹
              • 431 利用mysqladmin設定root的密碼
                  • 第五章 實用範例
                    • 51 任務一Web Base客戶通訊錄
                    • 52 任務二Web Base群組軟體 ( twig )
                      • 第六章 維護及更新程序
                        • 61 日常維護
                        • 62 更新程序
                        • 63 備份重要檔案
                        • 64 離線備份與還原
                        • 65 線上備份與還原
                          • 第七章 問題與解答
                          • 第八章 參考資料
                          • 附錄一 SQL Command 介紹
                          • 附錄二Replication
Page 92: DataBase Server Standard Operation Procedureebooks.lib.ntu.edu.tw/1_file/oss/63/93doc4-5.pdf · 業務的公司帶來了不少壓力,譬如微軟,甲骨文 ... 外的錢用在第三方的資料庫產品上,譬如就可以不用再購買甲骨文公司

1921680100

1921680200Master Server

erveSlave S r

圖 測試架構圖

測試步驟

Master server 部份 Step1 確認 MasterSlave機器上所裝的 MySQL版本能進行

replication( 32329 or higher ) Step2 在 Master MySQL上開放一個帳號給 Slave mysql ndashu root ndashp mysqlgtGRANT FILE ON TO repl1921680200 IDENTIFIED BY lsquoabc123rsquo mysqlgtq 上面是 Master開放一個帳號 repl密碼 abc123給 IP1921680200有檔案處理

的權限 Step3 shutdown MySQL on the Master mysqladmin ndashu root ndashp shutdown Step4 備份 Master所有資料庫 tar ndashcvf tmpmysql-snapshottar varlibmysql 注意tar的時候MySQL是要在 stop情況下 在mysql (wwwmysqlcom) 網站的FAQ有不用shutdown的方法

92

Step5 在 master機器上修改etcmycnf 在[mysqld]區段內加入參數 log-bin server-id=這邊設定 server-id=1 sql-bin-update-same binlog-do-db=CRM只針對 CRM資料庫做紀錄 Step6 Restart MySQL on the master service mysqld start 此時因為有加入 log-bin 參數因此開始有 index產生了在varlibmysql目錄下

有index檔案紀錄資料庫的異動 log Slave server 部份 Step1 在 slave設定etcmycnf 在[mysqld]區段加入 master-host= master-user= master-password= master-port= server-id= 這邊設定 master-host=1921680100 master-user=repl master-password=abc123 master-port=3306 server-id=2 master-connect-retry=60預設重試間隔 60秒 replicate-do-db=CRM告訴 slave只做 CRM資料庫的更新 log-slave-updates Step2 將 master上的 mysql-snapshottar copy到 slave上 用 ftp傳到 slave的tmp Step3 解壓縮 Master資料庫至 Slave Server上 cd varlib tar xvf tmpmysql-snapshottar chown ndashR mysqlmysql mysql

93

chmod ndashR 770 mysql (視情況) Step4 Restart MySQL on the slave server 這時在varlibmysql目錄會出現 masterinfo此檔案紀錄了 Master MySQL server的資訊

狀況測試

One-way replication

1921680100

1921680200Master Server

erveSlave S r

圖 One-way replication架構圖 Step1 Master跟 Slave網路及服務都正常情況下由 Master端異動資料後 到 Slave端瀏覽資料檢視是否有進行 replication Step2 模擬 Slave Server 當機 可用在於 slave真的當機或是 Slave 不一定需要一直跟 master connect將Slave MySQL server shutdown由 Master端異動資料到 slave端瀏覽此時Slave應該沒有被 replication 更新然後再將 Slave端 MySQL server start起來

預設 60秒後 Slave會嘗試跟 Master要求進行 replication再去 Slave端檢視是否有更新資料

94

Step3 模擬 Master當機因為是設定 One-way replication一旦 Master Server Slave端沒有 Master的 source可以 download Two-way replication 基於 Master當機狀況於是發展雙向 Replication即 1921680100 ( Host A ) 1921680200 ( Host B )都分別擔任 MasterSlave身分

1921680100

1921680200er

Server B MasterSlave Server

Server A MasterSlave Serv

圖 Two-way replication架構圖 以下是針對兩台 MySQL伺服器進行雙向 Replication Step1觀念同單向 replication只是改成 Master也有 Slave身分 Slave也有Master的身分先分別在 Server AServer B 都去 grant一個進行 replication的身分 [A]mysqlgtGRANT FILE ON TO repl1921680200 IDENTIFIED BY lsquoabc123rsquo [B]mysqlgt GRANT FILE ON TO repl1921680100 IDENTIFIED BY lsquoabc123rsquo Step2做完單向 replication後stop Server Aserver B MySQL service此時 AB資料是一樣的

95

修改etcmycnf設定 範例 Server A [mysqld] datadir=varlibmysql socket=varlibmysqlmysqlsock server-id=1 log-bin sql-bin-update-same binlog-do-db=CRM master-host=1921680200 master-user=repl master-password=abc123 log-slave-updates master-connect-retry=60 replicate-do-db=CRM Server B [mysqld] datadir=varlibmysql socket=varlibmysqlmysqlsock server-id=2 log-bin sql-bin-update-same binlog-do-db=CRM master-host=1921680100 master-user=repl master-password=abc123 log-slave-updates master-connect-retry=60 replicate-do-db=CRM 分別 start Server AServer B MySQL後此時雙方都是 MasterSlave身分一旦哪一方資料異動就會通知對方來 replication-若 replication失效則必須將Server AServer B的masterinfo及index00x 都砍掉然後分別 restart MySQL server進行測試檢視成果 實務上通常如果需要做Two-way replication通常會搭配Virtual Server使用

96

在前端架設一台Virtual Server不過此部份不在此份SOP討論範圍內有興趣

的讀者可參考 httpwwwlinuxvirtualserverorg 網站

1921680100 1921680200

Host A MasterSlave Server

Host B MasterSlave Server

Virtual Host

圖 Virtual Server + Two-way replication 架構圖

97

圖 High Availability Linux Virtual Server架構圖

98

  • COSA-SOP-03-006
  • 第一章 簡介
    • 11適用對象 (Audience)
    • 12 MySQL本身
    • 13 MySQL 40版跟50版重大的改進功能
    • 14 各家資料庫軟體比較
      • 第二章 前置需求
      • 第三章 安裝
        • 31 MySQL安裝
        • 32 phpMyAdmin安裝
        • 33 升級及注意事項
          • 第四章 MySQL管理
            • 41 Webmin 管理介面
            • 42 phpMyAdmin 的操作介面
            • 43管理指令介紹
              • 431 利用mysqladmin設定root的密碼
                  • 第五章 實用範例
                    • 51 任務一Web Base客戶通訊錄
                    • 52 任務二Web Base群組軟體 ( twig )
                      • 第六章 維護及更新程序
                        • 61 日常維護
                        • 62 更新程序
                        • 63 備份重要檔案
                        • 64 離線備份與還原
                        • 65 線上備份與還原
                          • 第七章 問題與解答
                          • 第八章 參考資料
                          • 附錄一 SQL Command 介紹
                          • 附錄二Replication
Page 93: DataBase Server Standard Operation Procedureebooks.lib.ntu.edu.tw/1_file/oss/63/93doc4-5.pdf · 業務的公司帶來了不少壓力,譬如微軟,甲骨文 ... 外的錢用在第三方的資料庫產品上,譬如就可以不用再購買甲骨文公司

Step5 在 master機器上修改etcmycnf 在[mysqld]區段內加入參數 log-bin server-id=這邊設定 server-id=1 sql-bin-update-same binlog-do-db=CRM只針對 CRM資料庫做紀錄 Step6 Restart MySQL on the master service mysqld start 此時因為有加入 log-bin 參數因此開始有 index產生了在varlibmysql目錄下

有index檔案紀錄資料庫的異動 log Slave server 部份 Step1 在 slave設定etcmycnf 在[mysqld]區段加入 master-host= master-user= master-password= master-port= server-id= 這邊設定 master-host=1921680100 master-user=repl master-password=abc123 master-port=3306 server-id=2 master-connect-retry=60預設重試間隔 60秒 replicate-do-db=CRM告訴 slave只做 CRM資料庫的更新 log-slave-updates Step2 將 master上的 mysql-snapshottar copy到 slave上 用 ftp傳到 slave的tmp Step3 解壓縮 Master資料庫至 Slave Server上 cd varlib tar xvf tmpmysql-snapshottar chown ndashR mysqlmysql mysql

93

chmod ndashR 770 mysql (視情況) Step4 Restart MySQL on the slave server 這時在varlibmysql目錄會出現 masterinfo此檔案紀錄了 Master MySQL server的資訊

狀況測試

One-way replication

1921680100

1921680200Master Server

erveSlave S r

圖 One-way replication架構圖 Step1 Master跟 Slave網路及服務都正常情況下由 Master端異動資料後 到 Slave端瀏覽資料檢視是否有進行 replication Step2 模擬 Slave Server 當機 可用在於 slave真的當機或是 Slave 不一定需要一直跟 master connect將Slave MySQL server shutdown由 Master端異動資料到 slave端瀏覽此時Slave應該沒有被 replication 更新然後再將 Slave端 MySQL server start起來

預設 60秒後 Slave會嘗試跟 Master要求進行 replication再去 Slave端檢視是否有更新資料

94

Step3 模擬 Master當機因為是設定 One-way replication一旦 Master Server Slave端沒有 Master的 source可以 download Two-way replication 基於 Master當機狀況於是發展雙向 Replication即 1921680100 ( Host A ) 1921680200 ( Host B )都分別擔任 MasterSlave身分

1921680100

1921680200er

Server B MasterSlave Server

Server A MasterSlave Serv

圖 Two-way replication架構圖 以下是針對兩台 MySQL伺服器進行雙向 Replication Step1觀念同單向 replication只是改成 Master也有 Slave身分 Slave也有Master的身分先分別在 Server AServer B 都去 grant一個進行 replication的身分 [A]mysqlgtGRANT FILE ON TO repl1921680200 IDENTIFIED BY lsquoabc123rsquo [B]mysqlgt GRANT FILE ON TO repl1921680100 IDENTIFIED BY lsquoabc123rsquo Step2做完單向 replication後stop Server Aserver B MySQL service此時 AB資料是一樣的

95

修改etcmycnf設定 範例 Server A [mysqld] datadir=varlibmysql socket=varlibmysqlmysqlsock server-id=1 log-bin sql-bin-update-same binlog-do-db=CRM master-host=1921680200 master-user=repl master-password=abc123 log-slave-updates master-connect-retry=60 replicate-do-db=CRM Server B [mysqld] datadir=varlibmysql socket=varlibmysqlmysqlsock server-id=2 log-bin sql-bin-update-same binlog-do-db=CRM master-host=1921680100 master-user=repl master-password=abc123 log-slave-updates master-connect-retry=60 replicate-do-db=CRM 分別 start Server AServer B MySQL後此時雙方都是 MasterSlave身分一旦哪一方資料異動就會通知對方來 replication-若 replication失效則必須將Server AServer B的masterinfo及index00x 都砍掉然後分別 restart MySQL server進行測試檢視成果 實務上通常如果需要做Two-way replication通常會搭配Virtual Server使用

96

在前端架設一台Virtual Server不過此部份不在此份SOP討論範圍內有興趣

的讀者可參考 httpwwwlinuxvirtualserverorg 網站

1921680100 1921680200

Host A MasterSlave Server

Host B MasterSlave Server

Virtual Host

圖 Virtual Server + Two-way replication 架構圖

97

圖 High Availability Linux Virtual Server架構圖

98

  • COSA-SOP-03-006
  • 第一章 簡介
    • 11適用對象 (Audience)
    • 12 MySQL本身
    • 13 MySQL 40版跟50版重大的改進功能
    • 14 各家資料庫軟體比較
      • 第二章 前置需求
      • 第三章 安裝
        • 31 MySQL安裝
        • 32 phpMyAdmin安裝
        • 33 升級及注意事項
          • 第四章 MySQL管理
            • 41 Webmin 管理介面
            • 42 phpMyAdmin 的操作介面
            • 43管理指令介紹
              • 431 利用mysqladmin設定root的密碼
                  • 第五章 實用範例
                    • 51 任務一Web Base客戶通訊錄
                    • 52 任務二Web Base群組軟體 ( twig )
                      • 第六章 維護及更新程序
                        • 61 日常維護
                        • 62 更新程序
                        • 63 備份重要檔案
                        • 64 離線備份與還原
                        • 65 線上備份與還原
                          • 第七章 問題與解答
                          • 第八章 參考資料
                          • 附錄一 SQL Command 介紹
                          • 附錄二Replication
Page 94: DataBase Server Standard Operation Procedureebooks.lib.ntu.edu.tw/1_file/oss/63/93doc4-5.pdf · 業務的公司帶來了不少壓力,譬如微軟,甲骨文 ... 外的錢用在第三方的資料庫產品上,譬如就可以不用再購買甲骨文公司

chmod ndashR 770 mysql (視情況) Step4 Restart MySQL on the slave server 這時在varlibmysql目錄會出現 masterinfo此檔案紀錄了 Master MySQL server的資訊

狀況測試

One-way replication

1921680100

1921680200Master Server

erveSlave S r

圖 One-way replication架構圖 Step1 Master跟 Slave網路及服務都正常情況下由 Master端異動資料後 到 Slave端瀏覽資料檢視是否有進行 replication Step2 模擬 Slave Server 當機 可用在於 slave真的當機或是 Slave 不一定需要一直跟 master connect將Slave MySQL server shutdown由 Master端異動資料到 slave端瀏覽此時Slave應該沒有被 replication 更新然後再將 Slave端 MySQL server start起來

預設 60秒後 Slave會嘗試跟 Master要求進行 replication再去 Slave端檢視是否有更新資料

94

Step3 模擬 Master當機因為是設定 One-way replication一旦 Master Server Slave端沒有 Master的 source可以 download Two-way replication 基於 Master當機狀況於是發展雙向 Replication即 1921680100 ( Host A ) 1921680200 ( Host B )都分別擔任 MasterSlave身分

1921680100

1921680200er

Server B MasterSlave Server

Server A MasterSlave Serv

圖 Two-way replication架構圖 以下是針對兩台 MySQL伺服器進行雙向 Replication Step1觀念同單向 replication只是改成 Master也有 Slave身分 Slave也有Master的身分先分別在 Server AServer B 都去 grant一個進行 replication的身分 [A]mysqlgtGRANT FILE ON TO repl1921680200 IDENTIFIED BY lsquoabc123rsquo [B]mysqlgt GRANT FILE ON TO repl1921680100 IDENTIFIED BY lsquoabc123rsquo Step2做完單向 replication後stop Server Aserver B MySQL service此時 AB資料是一樣的

95

修改etcmycnf設定 範例 Server A [mysqld] datadir=varlibmysql socket=varlibmysqlmysqlsock server-id=1 log-bin sql-bin-update-same binlog-do-db=CRM master-host=1921680200 master-user=repl master-password=abc123 log-slave-updates master-connect-retry=60 replicate-do-db=CRM Server B [mysqld] datadir=varlibmysql socket=varlibmysqlmysqlsock server-id=2 log-bin sql-bin-update-same binlog-do-db=CRM master-host=1921680100 master-user=repl master-password=abc123 log-slave-updates master-connect-retry=60 replicate-do-db=CRM 分別 start Server AServer B MySQL後此時雙方都是 MasterSlave身分一旦哪一方資料異動就會通知對方來 replication-若 replication失效則必須將Server AServer B的masterinfo及index00x 都砍掉然後分別 restart MySQL server進行測試檢視成果 實務上通常如果需要做Two-way replication通常會搭配Virtual Server使用

96

在前端架設一台Virtual Server不過此部份不在此份SOP討論範圍內有興趣

的讀者可參考 httpwwwlinuxvirtualserverorg 網站

1921680100 1921680200

Host A MasterSlave Server

Host B MasterSlave Server

Virtual Host

圖 Virtual Server + Two-way replication 架構圖

97

圖 High Availability Linux Virtual Server架構圖

98

  • COSA-SOP-03-006
  • 第一章 簡介
    • 11適用對象 (Audience)
    • 12 MySQL本身
    • 13 MySQL 40版跟50版重大的改進功能
    • 14 各家資料庫軟體比較
      • 第二章 前置需求
      • 第三章 安裝
        • 31 MySQL安裝
        • 32 phpMyAdmin安裝
        • 33 升級及注意事項
          • 第四章 MySQL管理
            • 41 Webmin 管理介面
            • 42 phpMyAdmin 的操作介面
            • 43管理指令介紹
              • 431 利用mysqladmin設定root的密碼
                  • 第五章 實用範例
                    • 51 任務一Web Base客戶通訊錄
                    • 52 任務二Web Base群組軟體 ( twig )
                      • 第六章 維護及更新程序
                        • 61 日常維護
                        • 62 更新程序
                        • 63 備份重要檔案
                        • 64 離線備份與還原
                        • 65 線上備份與還原
                          • 第七章 問題與解答
                          • 第八章 參考資料
                          • 附錄一 SQL Command 介紹
                          • 附錄二Replication
Page 95: DataBase Server Standard Operation Procedureebooks.lib.ntu.edu.tw/1_file/oss/63/93doc4-5.pdf · 業務的公司帶來了不少壓力,譬如微軟,甲骨文 ... 外的錢用在第三方的資料庫產品上,譬如就可以不用再購買甲骨文公司

Step3 模擬 Master當機因為是設定 One-way replication一旦 Master Server Slave端沒有 Master的 source可以 download Two-way replication 基於 Master當機狀況於是發展雙向 Replication即 1921680100 ( Host A ) 1921680200 ( Host B )都分別擔任 MasterSlave身分

1921680100

1921680200er

Server B MasterSlave Server

Server A MasterSlave Serv

圖 Two-way replication架構圖 以下是針對兩台 MySQL伺服器進行雙向 Replication Step1觀念同單向 replication只是改成 Master也有 Slave身分 Slave也有Master的身分先分別在 Server AServer B 都去 grant一個進行 replication的身分 [A]mysqlgtGRANT FILE ON TO repl1921680200 IDENTIFIED BY lsquoabc123rsquo [B]mysqlgt GRANT FILE ON TO repl1921680100 IDENTIFIED BY lsquoabc123rsquo Step2做完單向 replication後stop Server Aserver B MySQL service此時 AB資料是一樣的

95

修改etcmycnf設定 範例 Server A [mysqld] datadir=varlibmysql socket=varlibmysqlmysqlsock server-id=1 log-bin sql-bin-update-same binlog-do-db=CRM master-host=1921680200 master-user=repl master-password=abc123 log-slave-updates master-connect-retry=60 replicate-do-db=CRM Server B [mysqld] datadir=varlibmysql socket=varlibmysqlmysqlsock server-id=2 log-bin sql-bin-update-same binlog-do-db=CRM master-host=1921680100 master-user=repl master-password=abc123 log-slave-updates master-connect-retry=60 replicate-do-db=CRM 分別 start Server AServer B MySQL後此時雙方都是 MasterSlave身分一旦哪一方資料異動就會通知對方來 replication-若 replication失效則必須將Server AServer B的masterinfo及index00x 都砍掉然後分別 restart MySQL server進行測試檢視成果 實務上通常如果需要做Two-way replication通常會搭配Virtual Server使用

96

在前端架設一台Virtual Server不過此部份不在此份SOP討論範圍內有興趣

的讀者可參考 httpwwwlinuxvirtualserverorg 網站

1921680100 1921680200

Host A MasterSlave Server

Host B MasterSlave Server

Virtual Host

圖 Virtual Server + Two-way replication 架構圖

97

圖 High Availability Linux Virtual Server架構圖

98

  • COSA-SOP-03-006
  • 第一章 簡介
    • 11適用對象 (Audience)
    • 12 MySQL本身
    • 13 MySQL 40版跟50版重大的改進功能
    • 14 各家資料庫軟體比較
      • 第二章 前置需求
      • 第三章 安裝
        • 31 MySQL安裝
        • 32 phpMyAdmin安裝
        • 33 升級及注意事項
          • 第四章 MySQL管理
            • 41 Webmin 管理介面
            • 42 phpMyAdmin 的操作介面
            • 43管理指令介紹
              • 431 利用mysqladmin設定root的密碼
                  • 第五章 實用範例
                    • 51 任務一Web Base客戶通訊錄
                    • 52 任務二Web Base群組軟體 ( twig )
                      • 第六章 維護及更新程序
                        • 61 日常維護
                        • 62 更新程序
                        • 63 備份重要檔案
                        • 64 離線備份與還原
                        • 65 線上備份與還原
                          • 第七章 問題與解答
                          • 第八章 參考資料
                          • 附錄一 SQL Command 介紹
                          • 附錄二Replication
Page 96: DataBase Server Standard Operation Procedureebooks.lib.ntu.edu.tw/1_file/oss/63/93doc4-5.pdf · 業務的公司帶來了不少壓力,譬如微軟,甲骨文 ... 外的錢用在第三方的資料庫產品上,譬如就可以不用再購買甲骨文公司

修改etcmycnf設定 範例 Server A [mysqld] datadir=varlibmysql socket=varlibmysqlmysqlsock server-id=1 log-bin sql-bin-update-same binlog-do-db=CRM master-host=1921680200 master-user=repl master-password=abc123 log-slave-updates master-connect-retry=60 replicate-do-db=CRM Server B [mysqld] datadir=varlibmysql socket=varlibmysqlmysqlsock server-id=2 log-bin sql-bin-update-same binlog-do-db=CRM master-host=1921680100 master-user=repl master-password=abc123 log-slave-updates master-connect-retry=60 replicate-do-db=CRM 分別 start Server AServer B MySQL後此時雙方都是 MasterSlave身分一旦哪一方資料異動就會通知對方來 replication-若 replication失效則必須將Server AServer B的masterinfo及index00x 都砍掉然後分別 restart MySQL server進行測試檢視成果 實務上通常如果需要做Two-way replication通常會搭配Virtual Server使用

96

在前端架設一台Virtual Server不過此部份不在此份SOP討論範圍內有興趣

的讀者可參考 httpwwwlinuxvirtualserverorg 網站

1921680100 1921680200

Host A MasterSlave Server

Host B MasterSlave Server

Virtual Host

圖 Virtual Server + Two-way replication 架構圖

97

圖 High Availability Linux Virtual Server架構圖

98

  • COSA-SOP-03-006
  • 第一章 簡介
    • 11適用對象 (Audience)
    • 12 MySQL本身
    • 13 MySQL 40版跟50版重大的改進功能
    • 14 各家資料庫軟體比較
      • 第二章 前置需求
      • 第三章 安裝
        • 31 MySQL安裝
        • 32 phpMyAdmin安裝
        • 33 升級及注意事項
          • 第四章 MySQL管理
            • 41 Webmin 管理介面
            • 42 phpMyAdmin 的操作介面
            • 43管理指令介紹
              • 431 利用mysqladmin設定root的密碼
                  • 第五章 實用範例
                    • 51 任務一Web Base客戶通訊錄
                    • 52 任務二Web Base群組軟體 ( twig )
                      • 第六章 維護及更新程序
                        • 61 日常維護
                        • 62 更新程序
                        • 63 備份重要檔案
                        • 64 離線備份與還原
                        • 65 線上備份與還原
                          • 第七章 問題與解答
                          • 第八章 參考資料
                          • 附錄一 SQL Command 介紹
                          • 附錄二Replication
Page 97: DataBase Server Standard Operation Procedureebooks.lib.ntu.edu.tw/1_file/oss/63/93doc4-5.pdf · 業務的公司帶來了不少壓力,譬如微軟,甲骨文 ... 外的錢用在第三方的資料庫產品上,譬如就可以不用再購買甲骨文公司

在前端架設一台Virtual Server不過此部份不在此份SOP討論範圍內有興趣

的讀者可參考 httpwwwlinuxvirtualserverorg 網站

1921680100 1921680200

Host A MasterSlave Server

Host B MasterSlave Server

Virtual Host

圖 Virtual Server + Two-way replication 架構圖

97

圖 High Availability Linux Virtual Server架構圖

98

  • COSA-SOP-03-006
  • 第一章 簡介
    • 11適用對象 (Audience)
    • 12 MySQL本身
    • 13 MySQL 40版跟50版重大的改進功能
    • 14 各家資料庫軟體比較
      • 第二章 前置需求
      • 第三章 安裝
        • 31 MySQL安裝
        • 32 phpMyAdmin安裝
        • 33 升級及注意事項
          • 第四章 MySQL管理
            • 41 Webmin 管理介面
            • 42 phpMyAdmin 的操作介面
            • 43管理指令介紹
              • 431 利用mysqladmin設定root的密碼
                  • 第五章 實用範例
                    • 51 任務一Web Base客戶通訊錄
                    • 52 任務二Web Base群組軟體 ( twig )
                      • 第六章 維護及更新程序
                        • 61 日常維護
                        • 62 更新程序
                        • 63 備份重要檔案
                        • 64 離線備份與還原
                        • 65 線上備份與還原
                          • 第七章 問題與解答
                          • 第八章 參考資料
                          • 附錄一 SQL Command 介紹
                          • 附錄二Replication
Page 98: DataBase Server Standard Operation Procedureebooks.lib.ntu.edu.tw/1_file/oss/63/93doc4-5.pdf · 業務的公司帶來了不少壓力,譬如微軟,甲骨文 ... 外的錢用在第三方的資料庫產品上,譬如就可以不用再購買甲骨文公司

圖 High Availability Linux Virtual Server架構圖

98

  • COSA-SOP-03-006
  • 第一章 簡介
    • 11適用對象 (Audience)
    • 12 MySQL本身
    • 13 MySQL 40版跟50版重大的改進功能
    • 14 各家資料庫軟體比較
      • 第二章 前置需求
      • 第三章 安裝
        • 31 MySQL安裝
        • 32 phpMyAdmin安裝
        • 33 升級及注意事項
          • 第四章 MySQL管理
            • 41 Webmin 管理介面
            • 42 phpMyAdmin 的操作介面
            • 43管理指令介紹
              • 431 利用mysqladmin設定root的密碼
                  • 第五章 實用範例
                    • 51 任務一Web Base客戶通訊錄
                    • 52 任務二Web Base群組軟體 ( twig )
                      • 第六章 維護及更新程序
                        • 61 日常維護
                        • 62 更新程序
                        • 63 備份重要檔案
                        • 64 離線備份與還原
                        • 65 線上備份與還原
                          • 第七章 問題與解答
                          • 第八章 參考資料
                          • 附錄一 SQL Command 介紹
                          • 附錄二Replication