Many examples in this document are adapted from Java: How To Program
(3rd Ed.), written by Deitel and Deitel, and Thinking in Java (2nd
Edition), written by Bruce Eckel. All examples are solely
used for educational purposes. Hopefully, I am not violating any
copyright issue here. If so, please do
email
me.
Please install JDK 1.3.1_02 or later with Java Plugin to view this page. Also, this page is best viewed with browsers (for examples, Mozilla 0.99 or later, IE 6.x or later) with CSS2 support. This document is provided as is. You are welcomed to use it for non-commercial purpose.
Written by: 國立中興大學資管系呂瑞麟 Eric Jui-Lin Lu
The materials presented in this web page is provided as is and is used
solely for educational purpose. Use at your own risks.
Written by: 國立中興大學資管系呂瑞麟 Eric Jui-Lin Lu
The materials presented in this web page is provided as is and is used
solely for educational purpose. Use at your own risks.
Written by: 國立中興大學資管系呂瑞麟 Eric Jui-Lin Lu
The materials presented in this web page is provided as is and is used
solely for educational purpose. Use at your own risks.
Written by: 國立中興大學資管系呂瑞麟 Eric Jui-Lin Lu
本文假設你已經安裝了 MySQL Server 5.1.x 版,而且你也依據之前的說明,
建立了使用者 jlu,而且你也為 jlu 建立了一個資料庫 eric,並把這個資料庫
所有權限給了 jlu;也就是說,jlu 可以任意在資料庫 eric 中新增、修改、
以及刪除表格(tables)。
在以下的步驟中,jlu 即將在資料庫 eric 中新增一個表格 Product:
以 jlu 登入
// 以 jlu 登入,並使用資料庫 eric
mysql -u jlu -p eric
// 如果要登入遠端 hostname 的 MySQL Server
mysql -h hostname -u jlu -p eric
// 如果 jlu 不喜歡或者想更改 root 指定的密碼,可以執行以下指令
// 同樣的,newpassword 指的是你想輸入的密碼
set password for jlu@localhost=password('newpassword');
產生表格 Product:每一樣產品包含編號、名稱、價格、以及數量。
// create table
create table Product (
ID int,
Name varchar(30),
Price decimal(5,2),
Qty int);
// 查看 Product 是否已經產生
// Windows 版產生的 table 名稱變成 product
show tables;
The materials presented in this web page is provided as is and is used
solely for educational purpose. Use at your own risks.
Written by: 國立中興大學資管系呂瑞麟 Eric Jui-Lin Lu
The materials presented in this web page is provided as is and is used
solely for educational purpose. Use at your own risks.
Written by: 國立中興大學資管系呂瑞麟 Eric Jui-Lin Lu
請勿轉貼
看其他教材
本文假設你已經安裝了 MySQL Server 5.1.x 或者 5.5.x 版。由於 root 擁有最高權限,
因此練習中非常容易造成嚴重的錯誤,為了方便,大多數都會產生一個擁有
一般權限的使用者,並為其指定一個專用的資料庫,以便於測試。
以下我們假設要產生一個使用者 jlu 並使他成為名為 eric 資料庫的擁有者,而且
允許這個使用者能從任何電腦連到這個資料庫。這個步驟主要是給資料庫
管理員的,而你需要使用 mysql 這個執行檔。
啟動 MySQL 資料庫:如果你依據之前的建議安裝方式,請在 e:\mysql
目錄下,執行
.\startup.bat
如果你的 MySQL 是安裝在 Unix/Linux 環境下,請在提示下輸入(註:早期的文件中,
我假設建置的環境是 Unix/Linux 環境;這些年由於教學環境的限制,大多轉成了
Windows 的環境,所以畫面大多以 Windows 為主)
// 請在命令提示字元視窗內,進入 e:\mysql\bin,語法是在
// 視窗內,分別輸入
// e:
// cd \mysql\bin
// 這兩個指令。然後,輸入
mysql -u root
輸入之後,你應該可以看到如下的畫面:
在畫面的底下,有一個 mysql> 的提示,我們稱它為 MySQL 提示;
之後文章內的指令,都是輸入在 mysql> 之後,然後 Enter。
// 想看看目前有幾個 databases,所有系統設定都在 mysql 這個資料庫
show databases;
// 使用 mysql 這個資料庫
use mysql;
// 想看看目前使用的 database 有幾個 tables
show tables;
// 看看有哪些使用者
select host, user from user;
// 讓我們為 root 設定密碼
// 更改 user table 中的 password 欄位的值
// 下列指令中的 newpasswd 請把它改成你希望的密碼
update user set password = password('newpasswd') where user='root';
// 讓我們把 anonymous 帳號刪除
delete from user where user='';
// 讓修改馬上生效
flush privileges;
// logout
quit
// 重新 login, 這次就需要密碼了
// 以 -p 來指定在 enter 後輸入密碼
// 依照 MySQL 的官方文件,從 MySQL 4.1.1 版之後,你所輸入的密碼
// 並不會是以明文的方市在網路上傳送,因此他們認為非常安全
// 但是所有傳送的資料卻都是明文的。建議使用 ssh
mysql -u root -p
產生新的使用者 jlu
// 兩個 some-password 可以不同,但是這會造成再 localhost 登入時
// 所用的密碼和遠端登入時不一樣
//
// 授與使用者 jlu 在資料庫 eric 中所有的權限
grant all privileges on eric.* to 'jlu'@'localhost'
identified by 'some-password' with grant option;
// 你可以檢查一下使用者是否已經產生
select host, user from mysql.user;
// % 代表所有遠端電腦都可以登入,如果你的安全需求比較高,建議不要
grant all privileges on eric.* to 'jlu'@'%'
identified by 'some-password' with grant option;
產生資料庫 eric 並將 eric 的權限給使用者 jlu。以下的語法,資料庫
eric 以綠色表示。
// 產生資料庫 eric
create database eric;
// 將 eric 的權限給使用者 jlu
grant all on eric.* to jlu@'localhost';
// 檢查資料庫 eric 是否已經產生
show databases;
由於資料庫系統安裝於遠端的 Unix 電腦上,而我們一般都是使用 Microsoft
Windows 的系統,因此使用一個 GUI 介面的程式將會非常方便,我們建議安裝
MySQL 下載頁 中的
MySQL Workbench。
The materials presented in this web page is provided as is and is used
solely for educational purpose. Use at your own risks.
Written by: 國立中興大學資管系呂瑞麟 Eric Jui-Lin Lu
請勿轉貼
看其他教材
首先,請到 http://dev.mysql.com/downloads/ 下載 MySQL。本文的說明,以 MySQL Server 5.1.x 的 Noinstall Zip
Archive 版為例,因此下載的檔案名稱類似 mysql-noinstall-5.1.x-win32.zip;
如果下載的版本是 5.11.14 版,則 x 的值就是 14。
解壓縮:我們建議將下載的檔案安裝於電腦分割區的根目錄,以 E 槽為例,
請將檔案解壓縮在 E:\,並將目錄名稱更改為 mysql。
建立設定檔:請在 e:\mysql 的目錄下建立設定檔 my.ini,
檔案內容如下:
[mysqld]
# set basedir to your installation path
basedir=E:/mysql
# set datadir to the location of your data directory
datadir=E:/mysql/data
# set default character set
default-character-set=utf8
[client]
default-character-set=big5
The materials presented in this web page is provided as is and is used
solely for educational purpose. Use at your own risks.
Written by: 國立中興大學資管系呂瑞麟 Eric Jui-Lin Lu
首先,請到 http://dev.mysql.com/downloads/ 下載 MySQL 5.5.x。本文的說明,以 MySQL Server 5.5.x 的 Noinstall Zip
Archive 版為例,因此下載的檔案名稱類似 mysql-5.5.x-win32.zip;
如果下載的版本是 5.5.9 版,則 x 的值就是 9。
解壓縮:我們建議將下載的檔案安裝於電腦分割區的根目錄,以 E 槽為例,
請將檔案解壓縮在 E:\,並將目錄名稱更改為 mysql。
建立索引的通則:一般來說,這會因為你的經驗、使用時效能的考量等因素
來考量,並沒有一個百戰百勝的方程式。但是,你還是可以從你的
表格的存取方式來決定;例如,雖然說學號是學生資料表的主鍵,
但是若查詢的大部分時間是利用姓名和科系來決定,那麼你大概就可以
新增一個以姓名和科系為主的索引。另外,索引的其他候選者也包含
外來鍵以及 ORDER BY 與 GROUP BY 裡面所含的欄位。如果欄位的內容
同質性很高,例如性別欄只有男跟女兩種,那麼這個欄位就不適合做索引。
多少個索引才不會造成效能的明顯下降?
雖然索引的確能增快查詢的速度,但是卻會導致新、修改的速度下降,
究竟可以建立多少個索引才不會造成效能的明顯下降? 依據
Stephen Wynkoop 的說法,SQL Server 的 magic number 是 5 個。
索引的使用:關鍵在於 SQL Server 考慮一索引時,SELECT
敘述的其中一個欄位名稱必須是在索引中的第一欄位,否則不會
使用這個索引。在上述的學生例子中,若 SELECT 敘述只用到
科系,則該索引不會被使用到,反之,查詢中若包含「姓名」或
「姓名與科系」,則該索引會被使用。
if not exists (select * from bookstores where rank = 35)
print '目前無 rank 為 35 的書局'
begin ... end:
if exists (select * from bookstores where rank=30)
begin
print 'record found'
select no, name, city from bookstores where rank=30
end
while:
/* 變數的宣告是將變數名稱前加上 @ */
/* 宣告 x 為 int, x 為區域變數 */
/* 若 x 前加入兩個 @,則 x 為全域變數 */
declare @x int
/* 設定 x 的初始值為 1 */
select @x = 1
while @x < 6
begin
/* + 號為將字串聯起來 */
/* str() 是將整數轉換為字串 */
print '書局編號為 ' + str(@x,3) + ' 的訂單資料有'
select * from orders where no = @x
/* 故意空出兩行 */
print ' '
print ' '
/* 將 x 加 1 */
select @x=@x+1
end
break:
declare @x int
select @x = 1
while @x < 6
begin
select * from orders where no = @x
print ' '
print ' '
/* 當 x 為 3 時,跳出迴圈 */
if @x = 3
break
select @x=@x+1
end
continue:
declare @x int
select @x = 1
while @x < 6
begin
/* 當 x 為 1 時,直接進入下一個迴圈 */
if @x = 1
begin
select @x = @x + 1
continue
end
select * from orders where no = @x
print ' '
print ' '
select @x=@x+1
end
觸發程序與規則以及預設的不同?
SQL Server 會在將資訊寫入資料庫以前,套用系統中所定義的規則和預設。
但是觸發程序卻是在資料更動之後才去觸發 Triggers,因此
觸發程序可視為維持資料一致性的最後一道防線。
建立觸發程序: 當你建立一觸發時,你必須是資料庫的擁有人。
語法:
CREATE TRIGGER trigger_name
ON table_name
FOR {INSERT | UPDATE | DELETE}
[WITH ENCRYPTION]
AS sql_statements
範例:廠商所下的訂單數量不得高於 50
/* 建立觸發程序 orders_insert_note */
create trigger orders_insert_note
on orders
for insert, update
as
declare @q int
select @q = quantity from orders where quantity > 50
if @q > 50
begin
rollback tran
/* 產生錯誤訊息:
第一個參數是訊息,第二個參數是嚴重等級,一般會設在 11 至 16 間,
第三個參數是狀態(state) */
/* 訊息錯誤碼以及其敘述可以從 sysmessages 中得知(可以執行
select * from master.dbo.sysmessages) */
raiserror('The quantity of orders must be less than 50 units',
16, 10)
end
/* 嘗試執行下列指令,剛剛建立的觸發程序會被自動執行 */
insert into orders values(3,3,55)
範例: 若訂單數量更改,將發 email 通知
create trigger update_quantity_note
on orders
for update
as
/* 當欄位 quantity 有任何更動 */
if update(quantity) and (@@rowcount = 1)
begin
declare @mesg varchar(50)
select @mesg = 'You have updated your orders'
/* 經由 email 將通知發出去 */
exec master.dbo.xp_sendmail @recipients = 'jllu@nchu.edu.tw',
@message = @mesg
end
啟動 SQL Mail: 首先請你在你的電腦上安裝 MAPI Enabled 的
電子郵件用戶端程式 (如 Exchange Client, Mail Client, or Outlook 等,
不過要注意的是 Outlook Express 不是 MAPI Enabled 的用戶端程式)
展開伺服器
展開「支援服務」並於「SQL Mail」上按右鍵
於「內容」內給予一 Profile 名稱(如 ec1)
在「SQL Mail」上按右鍵並選擇「Start」
範例: 通知取消的訂單
create trigger delet_quantity_note
on orders
for delete
as
declare @mesg varchar(50)
declare @q int
/* DELETED 內包含剛剛被刪除和更改的資料 */
/* INSERTED 內含剛剛新增的資料 */
select @q = D.quantity from DELETED D
select @mesg = 'You have deleted your orders of ' + str(@q)
+ ' units'
exec master.dbo.xp_sendmail @recipients = 'jllu@nchu.edu.tw',
@message = @mesg
練習:請更改以上的範例,使得使用者於更改訂單數量後,
會收到更改(含更新前、後的數量)的通知。
顯示觸發資訊:
sp_help trigger_name
Enterprise Manager
選取你要處理的表格
按右鍵並選取「所有工作 / 管理觸發程序」
交易與鎖定
交易的特性在於交易只能全部完成或全部沒完成。在一般資訊系統,
需要確定是否交易完成的往往是涉及到兩個以上的
更動。例如,如果我們要將 bookstores 中 no 為 1 的資料去除,
我們一定要確認 orders 內的所有 no 為 1 的資料全部被刪除,
而且 bookstores 中 no 為 1 的資料被刪除。兩者缺一不可。
為達成以上的目標,SQL Server 提供了一些指令。
BEGIN TRAN;
DELETE FROM orders WHERE no = 1;
DELETE FROM bookstores WHERE no = 1;
SELECT * FROM orders;
SELECT * FROM bookstores;
BEGIN TRAN;
UPDATE orders
SET quantity = quantity + 10
WHERE no = 4 AND id = 5;
IF @@ERROR > 0 AND @@ROWCOUNT <> 1
GOTO NeedRollBack;
UPDATE orders
SET quantity = quantity - 10
WHERE no = 1 AND id = 5;
NeedRollBack:
IF @@ERROR > 0 AND @@ROWCOUNT <> 1
ROLLBACK TRAN
ELSE
COMMIT TRAN;
SELECT * FROM orders WHERE id = 5;
begin tran
update orders with (rowlock) set quantity=30 where no=4 and id=5
session 2:
/* 只有非 dirty 的資料顯示出來 */
/* readpast: 略過鎖定的資料列。readpast 提示僅套用於在 READ COMMITTED
隔離等級下運作的交易。僅套用於 SELECT 陳述式。 */
select * from orders with (readpast)
/* 依舊無法查詢 */
select * from orders
REPEATABLE READ 等級: SQL Server 允許你重複的存取同一筆資料,
並保證每一次所讀到的內容都相同。在這個設定下,其他交易不可以對正被讀取的
資料進行更改或刪除,但是別人仍然可以新增記錄。
session 1:
/* 保證已經讀取的資料不被更改 */
set transaction isolation level repeatable read
begin tran
select * from orders
session 2:
/* 預設的 isolation level 為 read committed */
begin tran
/* 無法 update */
update orders set quantity=quantity+5 where no=4 and id=5
/* 但是可以 insert */
insert into orders values(5,5,20)
SERIALIZABLE 等級: 這是 SQL Server 提供的最高
隔離等級,所有的交易全部互相隔離。
你可以重複之前的範例,只是在 session 1 設定的等級為 serializable
在 session 2,現在便無法 update and insert。
注意,隔離等級設的越高,對於同時性(concurrency)的負面影響越大。
至於需不需要每一筆交易都設定為 SERIALIZABLE 等級,這必須考量系統
的需求。例如,一本書的 editor 為書本的每一章邀請作者寫作,每一個
作者對這本書的更動僅及於他負責的那一章,因此對這本書的所有
交易不必設過高的隔離等級。
(從 online books 的內容) Transactions must be run at an isolation level
of repeatable read or higher to prevent lost updates that can occur when
two transactions each retrieve the same row, and then later update the
row based on the originally retrieved values. If the two transactions
update rows using a single UPDATE statement and do not base the update
on the previously retrieved values, lost updates cannot occur at the
default isolation level of read committed.
begin tran
select * from orders with (REPEATABLEREAD)
session 2:
/* select OK */
select * from orders
/* insert OK */
insert into orders values(2,3,40)
/* cannot update */
update orders set quantity=20 where no=2 and id=1
ROWLOCK:鎖定一個 row 而非整個表格或分頁。
session 1:
begin tran
select * from orders with (ROWLOCK,REPEATABLEREAD)
where no=1 and id=1
The materials presented in this web page is provided as is and is used
solely for educational purpose. Use at your own risks.
Written by: 國立中興大學資管系呂瑞麟 Eric Jui-Lin Lu
The following examples had been tested on Mozilla's Firefox and Microsoft's
IE. The document is provided as is. You are welcomed to use it for
non-commercial purpose.
Written by: 國立中興大學資管系呂瑞麟 Eric Jui-Lin Lu
我們的範例程式到此已經介紹完畢,可是我們要提醒讀者:這個系統只是
設計給單一使用者的;也就是說,這個系統的設計是假設一次只有一個使用者
在使用。試試看:打開兩個瀏覽器的視窗,然後分別開啟我們剛剛設計好的系統,
並分別在兩個視窗中新增資料,請觀察新增的資料是否立即反應再另一個視窗中。
練習題: 請新增一個"清除"的按鈕,使用者點選它之後,會把所有欄位的輸入
或者選擇的資料清除。
Written by: 國立中興大學資管系呂瑞麟 Eric Jui-Lin Lu
The following examples had been tested on Mozilla's Firefox and Microsoft's
IE. The document is provided as is. You are welcomed to use it for
non-commercial purpose.
Written by: 國立中興大學資管系呂瑞麟 Eric Jui-Lin Lu
The following examples had been tested on Mozilla's Firefox and Microsoft's
IE. The document is provided as is. You are welcomed to use it for
non-commercial purpose.
Written by: 國立中興大學資管系呂瑞麟 Eric Jui-Lin Lu
The following examples had been tested on Mozilla's Firefox and Microsoft's
IE. The document is provided as is. You are welcomed to use it for
non-commercial purpose.
Written by: 國立中興大學資管系呂瑞麟 Eric Jui-Lin Lu
在本範例中,我們使用了第一種和第三種方式。第三種的使用方式就像
在 Part II 中說明的 Product 類別;至於第一種的使用方式
就是 Part III 的重點。在載入 inv.zul 網頁的時候,我們希望能夠
先到資料庫中把已經存在的存貨資料載入,並放到視窗內。為了
達成這個目標,我們首先把資料載入,載入的方式如下所示,
而 <zscript> 需要放在 <window> 內。