位置:首頁 > 數據庫 > MySQL教學 > MySQL快速學習入門

MySQL快速學習入門

本教學主要是麵向想學習MySQL的初學者,在通過本教學的學習後,能夠對MySQL有一個初步的認識並能比較熟練地操作MySQL數據庫。

1、MySQL安裝(Window7 安裝)

在任何版本的 Windows 默認安裝是現在比以前要容易得多,MySQL巧妙地打包安裝程序。隻需下載安裝包,隨地把它解壓縮,並運行 mysql.exe. 下載地址:http://dev.mysql.com/downloads/ 頁麵如下圖所示:

這裡點擊:DOWNLOAD 鏈接,進入一下頁麵:

MySQL安裝

這裡點擊:DOWNLOAD 鏈接,進入一下頁麵:

這裡要求注冊網站帳號,但可以直接通過。如上點擊 "No thanks, just start my download",繼續下一步:

提示下載保存文件,下載完成後(本教學中下載完成的文件是:mysql-5.6.25-winx64.zip)解壓文件放到目錄:D:\software 下,這是一個免安裝包,這裡不需要安裝步驟。

在本教學中MySQL執行文件在:D:\software\mysql-5.6.25-winx64\bin,  它通過從命令提示符第一次進入測試MySQL服務器。轉到mysqld服務器的位置,這裡進入 D:\software\mysql-5.6.25-winx64\bin,然後輸入mysqld.exe,

注:或直接雙擊文件:mysqld.exe 啟動MySQL服務,如果不啟動數據庫,以下的步驟無法操作;

    如果一切順利,會看到有關啟動和InnoDB一些消息。如果冇有看到,可能有權限問題。請確保保存數據的目錄可以訪問任何根據用戶(可能是MySQL)運行數據庫進程。

    MySQL不會自己添加到開始菜單,並冇有特彆漂亮的GUI的方式來停止服務器。 因此,如果傾向於通過雙擊可執行 mysqld 啟動服務器,應該記住通過並用 mysqladmin,任務列表,任務管理器或其他 Windows 特定方式來執行。

驗證MySQL安裝

MySQL已經被成功安裝後,基礎表已經被初始化,並且服務器已經啟動,可以通過一些簡單的測試驗證。

使用中mysqladmin工具程序來獲取服務器狀態

使用 mysqladmin 來檢查服務器版本。在目錄 D:\software\mysql-5.6.25-winx64\bin

D:\software\mysql-5.6.25-winx64\bin> mysqladmin --version

看到結果如下:

mysqladmin  Ver 8.42 Distrib 5.6.25, for Win64 on x86_64

如果看到這樣的消息,則有可能是在安裝了一些問題,需要一些幫助解決它。

使用MySQL客戶端執行簡單的SQL命令

可以使用MySQL客戶端使用 mysql 命令連接到 MySQL 服務器。此時,不需要給任何密碼,因為默認情況下它被設置為空。

所以,隻需要使用下麵的命令:

D:\software\mysql-5.6.25-winx64\bin> mysql

應該出現一個mysql>提示符。 現在,已連接到MySQL服務器,可以在MySQL的命令>提示符下執行所有SQL,如下:

mysql> SHOW DATABASES;
+----------+
| Database |
+----------+
| mysql    |
| test     |
+----------+
2 rows in set (0.13 sec)

安裝後的步驟:

MySQL附帶了一個空密碼有的root用戶。成功後安裝了數據庫和客戶端,需要進行如下設置root密碼:

D:\software\mysql-5.6.25-winx64\bin> mysqladmin -u root password "123456";

注:

1. 關閉正在運行的MySQL服務。 
2. 打開DOS窗口,轉到 D:\software\mysql-5.6.25-winx64\bin 目錄。 
3. 輸入mysqld --skip-grant-tables 回車。--skip-grant-tables 的意思是啟動MySQL服務的時候跳過權限表認證。 
4. 再開一個DOS窗口(因為剛才那個DOS窗口已經不能動了),轉到mysql\bin目錄。 
5. 輸入mysql回車,如果成功,將出現MySQL提示符 >。 
6. 連接權限數據庫: use mysql; 。 
6. 改密碼:update user set password=password("123456") where user="root";(彆忘了最後加分號) 。 
7. 刷新權限(必須步驟):flush privileges; 
8. 退出 quit。 
9. 注銷係統,再進入,使用用戶名root和剛才設置的新密碼 123456 登錄。

現在使MySQL服務器的連接,那麼使用下麵的命令:

D:\software\mysql-5.6.25-winx64\bin> mysql -u root -p
Enter password: ******

2、運行和關閉MySQL服務器

首先檢查MySQL服務器正在運行與否。在資源管理器查看有冇有mysqld的進程,如果MySQL正在運行,那麼會看到列出來的 mysqld 進程。如果服務器冇有運行,那麼可以使用下麵的命令來啟動它:

D:\software\mysql-5.6.25-winx64\bin>mysqld
2015-07-30 22:59:20 0 [Warning] TIMESTAMP with implicit DEFAULT value is deprecated. Please use --explicit_defaults_for_timestamp server option (see documentation for more details).
2015-07-30 22:59:20 0 [Note] mysqld (mysqld 5.6.25) starting as process 3028 ...

現在,如果想關閉已經運行的 MySQL 服務器,那麼可以使用下麵的命令做到這一點:

D:\software\mysql-5.6.25-winx64\bin>mysqladmin -u root -p shutdown
Enter password: ******

3、設置MySQL用戶帳戶

要添加一個新用戶到 MySQL,隻需要在數據庫中的新記錄添加到用戶表:mysql.user

下麵是添加新用戶:yiibai 的例子,給定 SELECT, INSERT 和 UPDATE權限並使用密碼:yiibai123; SQL 查詢是:

D:\software\mysql-5.6.25-winx64\bin> mysql -u root -p
Enter password:
mysql> use mysql;
Database changed

mysql> INSERT INTO user 
          (host, user, password, 
           select_priv, insert_priv, update_priv) 
           VALUES ('localhost', 'yiibai', 
           PASSWORD('123456'), 'Y', 'Y', 'Y');
Query OK, 1 row affected (0.20 sec)

mysql> FLUSH PRIVILEGES;
Query OK, 1 row affected (0.01 sec)

mysql> SELECT host, user, password FROM user WHERE user = 'yiibai';
+-----------+---------+------------------+
| host      | user    | password         |
+-----------+---------+------------------+
| localhost | yiibai | *59A8740AAC5DBCB2907F38891BE42957F699CB77 |
+-----------+---------+------------------+
1 row in set (0.00 sec)

當要添加一個新用戶,記得要PASSWORD()函數加密MySQL新使用的密碼。正如在上麵的例子中看到密碼為mypass,進行加密後為:*59A8740AAC5DBCB2907F38891BE42957F699CB77

注意最後要使用 FLUSH PRIVILEGES 語句。 這告訴服務器重新加載授權表。如果不使用它,那麼將無法使用新的用戶帳戶連接到MySQL服務器,至少在服務器重新啟動後才可以。

也可以通過在用戶設置表以下幾列的值為'Y',指定給新用戶的權限,在執行INSERT查詢後,也可以在以後使用UPDATE查詢更新它們:

  • Select_priv

  • Insert_priv

  • Update_priv

  • Delete_priv

  • Create_priv

  • Drop_priv

  • Reload_priv

  • Shutdown_priv

  • Process_priv

  • File_priv

  • Grant_priv

  • References_priv

  • Index_priv

  • Alter_priv

下麵我們來創建一個數據庫:tutorials,使用以下命令:

D:\software\mysql-5.6.25-winx64\bin> mysql -u root -p password;
Enter password:
mysql>create database tutorials default character set utf8 collate utf8_general_ci;

添加用戶帳戶的另一種方式是通過使用GRANT SQL命令; 下麵的例子將增加用戶zara 並使用密碼zara123 為特定數據庫:tutorials

D:\software\mysql-5.6.25-winx64\bin> mysql -u root -p password;
Enter password:
mysql> use mysql;
Database changed

mysql> GRANT SELECT,INSERT,UPDATE,DELETE,CREATE,DROP
    -> ON tutorials.*
    -> TO 'yiibai'@'localhost'
    -> IDENTIFIED BY '123456';

這也將創建一條記錄在MySQL數據庫中的表: user

注意: MySQL不會終止命令,直到給一個分號(;)在SQL命令的結尾。

my.ini 文件配置

大多數情況下,不需要去修改這個文件。默認情況下,它會具有以下項:

[mysqld]
datadir=/var/lib/mysql
socket=/var/lib/mysql/mysql.sock

[mysql.server]
user=mysql
basedir=/var/lib

[safe_mysqld]
err-log=/var/log/mysqld.log
pid-file=/var/run/mysqld/mysqld.pid

在這裡,可以指定錯誤日誌為其它的目錄,否則不應該更改此文件中的任何內容。

管理 mysql 命令

這裡是重要的MySQL命令,經常在MySQL數據庫的管理或工作中使用:

  • USE Databasename : 用於選擇在MySQL工作區指定的數據庫。

  • SHOW DATABASES: 列出了MySQL數據庫管理係統中的所有可訪問的數據庫。

  • SHOW TABLES: 顯示已經選擇數據庫中的表的命令。

  • SHOW COLUMNS FROM tablename: 顯示屬性,屬性類型,關鍵信息,NULL是否被允許,默認值和其它的表信息。

  • SHOW INDEX FROM tablename: 提供所有指標的詳細信息表,其中包括PRIMARY KEY.

  • SHOW TABLE STATUS LIKE tablename\G: 報告MySQL的數據庫管理係統的性能和統計數據的詳細信息。

4、使用MySQL二進製連接MySQL

可以使用MySQL二進製在命令提示符下建立MySQL數據庫的連接。

示例:

下麵是一個簡單的例子,從命令提示符連接MySQL服務器:

D:\software\mysql-5.6.25-winx64\bin> mysql -u root -p
Enter password:

注意,這裡密碼為空,直接回車就就進入mysql>命令提示符下,能夠執行任何SQL命令。以下是上述命令的結果:

Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 2
Server version: 5.6.25 MySQL Community Server (GPL)

Copyright (c) 2000, 2015, Oracle and/or its affiliates. All rights reserved.

Oracle is a registered trademark of Oracle Corporation and/or its affiliates. Other names may 
be trademarks of their respective owners.

Type 'help;' or '\h' for help. Type '\c' to clear the buffer.

在上麵的例子中,我們使用 root 用戶,但可以使用任何其他用戶。任何用戶將能夠執行所有的SQL操作(前提這個用戶有對應執行SQL權限)。

任何時候使用exit命令在mysql>提示符下,從MySQL數據庫斷開。

mysql> exit
Bye

5、MySQL創建數據庫

需要特殊權限創建或刪除一個MySQL數據庫。因此,假如有權使用 root 用戶,就可以用mysql中的mysqladmin來創建數據庫。

示例:

下麵是一個簡單的例子,創建名為 tutorials 的數據庫。

D:\software\mysql-5.6.25-winx64\bin> mysqladmin -u root -p create tutorials
Enter password:<回車>

D:\software\mysql-5.6.25-winx64\bin> mysql -u root -p
Enter password:
mysql>create database yiibai_tutorials1;
mysql>create database yiibai_tutorials2;

這將創建一個MySQL數據庫:yiibai_tutorials1   和 yiibai_tutorials2,使用下麵命令查看結果:

mysql> show databases;
+--------------------+
| Database           |
+--------------------+
| information_schema |
| mysql              |
| performance_schema |
| test               |
| yiibai_tutorials1  |
| yiibai_tutorials2  |
+--------------------+
6 rows in set (0.00 sec)

6、MySQL刪除數據庫

需要特殊權限來創建或刪除一個MySQL數據庫。因此,假如你有機會獲得root用戶來登錄,可以用mysql中mysqladmin二進製來創建任何數據庫。

在刪除任何數據庫時要注意,因為刪除數據庫時所有的數據在數據庫中。

下麵是一個例子,用來刪除前麵的章節中所創建的數據庫:

D:\software\mysql-5.6.25-winx64\bin> mysqladmin -u root -p drop yiibai_tutorials1
Enter password:******
這會給出一個警告,它會確認你是否真的要刪除這個數據庫或不刪除。
Dropping the database is potentially a very bad thing to do.
Any data stored in the database will be destroyed.

Do you really want to drop the 'yiibai_tutorials1' database [y/N] y
Database "yiibai_tutorials1" dropped
或使用:
mysql> drop database yiibai_tutorials1;
Query OK, 0 rows affected (0.01 sec)
使用下麵命令看刪除後,數據庫的列表情況:
mysql> show databases;
+--------------------+
| Database           |
+--------------------+
| information_schema |
| mysql              |
| performance_schema |
| test               |
| yiibai             |
+--------------------+
6 rows in set (0.00 sec)

連接到MySQL服務器後,則需要選擇特定的數據庫的來工作。這是因為可能有多個數據庫可使用在MySQL服務器上。

7、從命令提示符選擇MySQL數據庫

這是非常簡單的,從MySQL>提示符下選擇一個特定的數據庫。可以使用SQL命令的 user 來選擇一個特定的數據庫。

示例:

下麵是一個例子,選擇數據庫為 test :

D:\software\mysql-5.6.25-winx64\bin> mysql -u root -p
Enter password:
mysql> use test;
Database changed
mysql> 

現在,我們已經選擇 test 數據庫,後續所有操作將在 test 數據庫上執行。

注意: 所有的數據庫名,表名,表中的字段名稱是區分大小寫的。所以,我們必須使用適當的名稱,在給定任何SQL命令。

8、MySQL表字段類型

正確地定義的表中的字段在數據庫的整體優化是非常重要的。我們應該隻使用真正需要使用類型和字段的大小; 如果知道隻使用2個字符,就不使用10個字符寬定義一個字段。這些類型的字段(或列),也被稱為數據類型,數據存儲這些字段之中。

MySQL使用許多不同的數據類型,總體上分為三類:數字,日期,時間和字符串類型。

數字數據類型

MySQL使用所有標準的ANSI SQL數字數據類型,所以,如果在學習MySQL之前,有接觸過其它不同的數據庫係統,那麼這些定義看起來很熟悉。下麵列出了常見的數字數據類型及其說明:

  • INT - 正常大小的整數,可以帶符號。如果是有符號的,它允許的範圍是從-2147483648到2147483647。如果是無符號,允許的範圍是從0到4294967295。 可以指定多達11位的寬度。

  • TINYINT - 一個非常小的整數,可以帶符號。如果是有符號,它允許的範圍是從-128到127。如果是無符號,允許的範圍是從0到255,可以指定多達4位數的寬度。

  • SMALLINT - 一個小的整數,可以帶符號。如果有符號,允許範圍為-32768至32767。如果無符號,允許的範圍是從0到65535,可以指定最多5位的寬度。

  • MEDIUMINT - 一個中等大小的整數,可以帶符號。如果有符號,允許範圍為-8388608至8388607。 如果無符號,允許的範圍是從0到16777215,可以指定最多9位的寬度。

  • BIGINT - 一個大的整數,可以帶符號。如果有符號,允許範圍為-9223372036854775808到9223372036854775807。如果無符號,允許的範圍是從0到18446744073709551615. 可以指定最多20位的寬度。

  • FLOAT(M,D) - 不能使用無符號的浮點數字。可以定義顯示長度(M)和小數位數(D)。這不是必需的,並且默認為10,2。其中2是小數的位數,10是數字(包括小數)的總數。小數精度可以到24個浮點。

  • DOUBLE(M,D) - 不能使用無符號的雙精度浮點數。可以定義顯示長度(M)和小數位數(D)。 這不是必需的,默認為16,4,其中4是小數的位數。小數精度可以達到53位的DOUBLE。 REAL是DOUBLE同義詞。

  • DECIMAL(M,D) - 非壓縮浮點數不能是無符號的。在解包小數,每個小數對應於一個字節。定義顯示長度(M)和小數(D)的數量是必需的。 NUMERIC是DECIMAL的同義詞。

日期和時間類型

MySQL的日期和時間數據類型包括:

  • DATE - 以YYYY-MM-DD格式的日期,在1000-01-01和9999-12-31之間。 例如,1973年12月30日將被存儲為1973-12-30。

  • DATETIME - 日期和時間組合以YYYY-MM-DD HH:MM:SS格式,在1000-01-01 00:00:00 到9999-12-31 23:59:59之間。例如,1973年12月30日下午3:30,會被存儲為1973-12-30 15:30:00。

  • TIMESTAMP - 1970年1月1日午夜之間的時間戳,到2037的某個時候。這看起來像前麵的DATETIME格式,無需隻是數字之間的連字符; 1973年12月30日下午3點30分將被存儲為19731230153000(YYYYMMDDHHMMSS)。

  • TIME - 存儲時間在HH:MM:SS格式。

  • YEAR(M) - 以2位或4位數字格式來存儲年份。如果長度指定為2(例如YEAR(2)),年份就可以為1970至2069(70〜69)。如果長度指定為4,年份範圍是1901-2155,默認長度為4。

字符串類型

雖然數字和日期類型比較有意思,但存儲大多數數據都可能是字符串格式。 下麵列出了在MySQL中常見的字符串數據類型。

  • CHAR(M) - 固定長度的字符串是以長度為1到255之間個字符長度(例如:CHAR(5)),存儲右空格填充到指定的長度。 限定長度不是必需的,它會默認為1。

  • VARCHAR(M) - 可變長度的字符串是以長度為1到255之間字符數(高版本的MySQL超過255); 例如: VARCHAR(25). 創建VARCHAR類型字段時,必須定義長度。

  • BLOB or TEXT - 字段的最大長度是65535個字符。 BLOB是“二進製大對象”,並用來存儲大的二進製數據,如圖像或其他類型的文件。定義為TEXT文本字段還持有大量的數據; 兩者之間的區彆是,排序和比較上存儲的數據,BLOB大小寫敏感,而TEXT字段不區分大小寫。不用指定BLOB或TEXT的長度。

  • TINYBLOB 或 TINYTEXT - BLOB或TEXT列用255個字符的最大長度。不指定TINYBLOB或TINYTEXT的長度。

  • MEDIUMBLOB or MEDIUMTEXT - BLOB或TEXT列具有16777215字符的最大長度。不指定MEDIUMBLOB或MEDIUMTEXT的長度。

  • LONGBLOB 或 LONGTEXT -  BLOB或TEXT列具有4294967295字符的最大長度。不指定LONGBLOB或LONGTEXT的長度。

  • ENUM - 枚舉,這是一個奇特的術語列表。當定義一個ENUM,要創建它的值的列表,這些是必須用於選擇的項(也可以是NULL)。例如,如果想要字段包含“A”或“B”或“C”,那麼可以定義為ENUM為 ENUM(“A”,“B”,“C”)也隻有這些值(或NULL)才能用來填充這個字段。

8、MySQL創建表

表的創建命令需要:

  • 表的名稱

  • 字段名稱

  • 定義每個字段(類型、長度等)

語法

下麵是通用的SQL語法用來創建MySQL表:

CREATE TABLE table_name (column_name column_type);

現在,我們將在 test 數據庫中創建以下表。

create table tutorials_tbl(
   tutorial_id INT NOT NULL AUTO_INCREMENT,
   tutorial_title VARCHAR(100) NOT NULL,
   tutorial_author VARCHAR(40) NOT NULL,
   submission_date DATE,
   PRIMARY KEY ( tutorial_id )
);

在這裡,一些數據項需要解釋:

  • 字段使用NOT NULL屬性,是因為我們不希望這個字段的值為NULL。 因此,如果用戶將嘗試創建具有NULL值的記錄,那麼MySQL會產生錯誤。

  • 字段的AUTO_INCREMENT屬性告訴MySQL自動增加id字段下一個可用編號。

  • 關鍵字PRIMARY KEY用於定義此列作為主鍵。可以使用逗號分隔多個列來定義主鍵。

通過命令提示符來創建表

在mysql>提示符下,創建一個MySQL表這是很容易的。使用 SQL 命令 CREATE TABLE 來創建表。

下麵是一個例子,創建一個表: tutorials_tbl: 

D:\software\mysql-5.6.25-winx64\bin> mysql -u root -p
Enter password:
mysql> use tutorials;
Database changed
mysql> CREATE TABLE tutorials_tbl(
   -> tutorial_id INT NOT NULL AUTO_INCREMENT,
   -> tutorial_title VARCHAR(100) NOT NULL,
   -> tutorial_author VARCHAR(40) NOT NULL,
   -> submission_date DATE,
   -> PRIMARY KEY ( tutorial_id )
   -> );
Query OK, 0 rows affected (0.16 sec)
mysql>

注: MySQL不會終止命令,直到給一個分號(;)表示SQL命令結束。

查看創建表的結果:

9、MySQL刪除表

刪除現有MySQL表這是很容易的,但必須非常小心,當刪除表後丟失的數據將不能恢複。

語法

這是用來刪除MySQL表的通用SQL語法:

DROP TABLE table_name ;

從命令行提示符刪除表

這需要隻是在 MySQL>提示符下執行DROP TABLE SQL命令。

下麵是一個例子,它將刪除表:tutorials_tbl:

root@host# mysql -u root -p
Enter password:
mysql> use test;
Database changed
mysql> DROP TABLE tutorials_tbl;
Query OK, 0 rows affected (0.8 sec)
mysql>

10、MySQL插入數據

想要將數據插入到MySQL表,需要使用SQL INSERT INTO命令。 可以通過用mysql>提示符或通過使用像PHP腳本將任何數據插入到MySQL表。

語法

這裡是INSERT INTO命令將數據插入到MySQL表的通用SQL語法:

INSERT INTO table_name ( field1, field2,...fieldN )
                       VALUES
                       ( value1, value2,...valueN );

要插入字符串類型數據,則需要雙或單引號保留到所有的值,例如:- "value".

這將使用SQL 的INSERT INTO命令將數據插入到MySQL表:tutorials_tbl

示例

下麵的例子將創建3條記錄到表:tutorials_tbl

root@host# mysql -u root -p password;
Enter password:
mysql> use use;
Database changed
mysql> INSERT INTO tutorials_tbl (tutorial_title, tutorial_author, submission_date) VALUES ("Learn PHP", "Paul", NOW());
Query OK, 1 row affected (0.01 sec)
mysql> INSERT INTO tutorials_tbl
     ->(tutorial_title, tutorial_author, submission_date)
     ->VALUES
     ->("Learn MySQL", "Saya", NOW());
Query OK, 1 row affected (0.01 sec)
mysql> INSERT INTO tutorials_tbl
     ->(tutorial_title, tutorial_author, submission_date)
     ->VALUES
     ->("JAVA Tutorial", "yiibai", '2015-05-06');
Query OK, 1 row affected (0.01 sec)
mysql>

注意: 請注意,所有的箭頭符號(->)不是SQL命令的一部分; 它表示一個新行,是由MySQL提示符按下回車鍵冇有給出一個分號,命令自動創建在行尾。

在上麵的例子中,未提供 tutorial_id 對應的值,因為在創建表時它會自動創建,這個字段我們給了AUTO_INCREMENT選項。因此MySQL會自動分配插入ID的值。 這裡, NOW() 是MySQL函數,返回當前的日期和時間。

11、MySQL SELECT查詢

SQL SELECT命令用於從MySQL數據庫獲取數據。可以在MySQL>提示符使用這個命令,以及任何像PHP的腳本和語言等。

語法

下麵是通用的SQL的SELECT命令語法,從MySQL表獲取數據:

SELECT field1, field2,...fieldN table_name1, table_name2...
[WHERE Clause]
[OFFSET M ][LIMIT N]
  • 可以使用分隔的一個或多個逗號從多個表,以及使用WHERE子句包括各種條件,但WHERE子句是SELECT命令的可選部分

  • 可以在一個SELECT命令指定讀取一個或多個字段

  • 可以指定星號(*)代替選擇的字段。在這種情況下,將返回所有字段

  • 可以指定任意的條件在 WHERE 子句後麵

  • 可以使用OFFSET指定一個偏移量,SELECT從那裡開始返回記錄。默認情況下 offset 的值是 0

  • 可以使用LIMIT屬性限製返回的數量

這將使用SQL SELECT命令從MySQL 表 tutorials_tbl 讀取數據

示例

下麵的例子將從 tutorials_tbl 表返回所有記錄:

root@host# mysql -u root -p password;
Enter password:
mysql> use test;
Database changed
mysql> SELECT * from tutorials_tbl;
+-------------+----------------+-----------------+-----------------+
| tutorial_id | tutorial_title | tutorial_author | submission_date |
+-------------+----------------+-----------------+-----------------+
|           1 | Learn PHP      | Paul            | 2015-07-17      |
|           2 | Learn MySQL    | Saya            | 2015-07-17      |
|           3 | JAVA Tutorial  | yiibai          | 2007-05-06      |
+-------------+----------------+-----------------+-----------------+
3 rows in set (0.25 sec)
mysql>

12、MySQL WHERE子句

我們已經看到使用SQL SELECT命令從MySQL表中獲取數據。我們可以用 WHERE子句來篩選出結果的條件子句。使用WHERE子句,我們可以指定一個選擇標準,從表中選擇所需的記錄。

語法

下麵是SELECT命令使用WHERE子句來從MySQL表數據的通用SQL語法:

SELECT field1, field2,...fieldN table_name1, table_name2...
[WHERE condition1 [AND [OR]] condition2.....
  • 可以使用逗號分隔一個或多個表,以及WHERE子句包括各種條件,但WHERE子句隻是SELECT命令的可選部分

  • 可以指定使用任何條件在WHERE子句中

  • 可以指定一個以上的條件在使用AND或OR運算符中

  • WHERE子句可以用DELETE 或 UPDATE的SQL命令一起,也可以指定一個條件使用。

WHERE子句就像是if一個條件在編程語言中, 此子句是用來比較給定值的字段值在MySQL表是否可用。如果從外部給定值等於在MySQL表可用字段值,那麼它返回該行。

這裡是運算符的列表,它可以在WHERE子句中使用。

假設字段A=10,字段B=20,則:

操作符 描述 示例
= 檢查兩個操作數的值是否相等,如果是,則條件變為真。 (A = B) 不為 true.
!= 檢查兩個操作數的值是否相等,如果值不相等,則條件變為真。 (A != B) 為 true.
> 檢查左操作數的值是否大於右操作數的值,如果是,則條件為真。 (A > B) 不為 true.
< 檢查左操作數的值是否小於右操作數的值,如果是,則條件為真。 (A < B) 為 true.
>= 檢查左操作數的值是否大於或等於右操作數的值,如果是,則條件為真。 (A >= B) 不為 true.
<= 檢查左操作數的值是否小於或等於右操作數的值,如果是,則條件變為真。 (A <= B) 為 true.

當想要從一個表中提取所選行,尤其是當使用MySQL聯接的WHERE子句是非常有用的。 聯接在另一章討論。

搜索使用主鍵進行快速搜索記錄是常見的做法。

如果給定的條件不匹配表任何記錄,那麼查詢將不會返回任何行。

使用SQL SELECT命令以及WHERE子句,從MySQL表tutorials_tbl選擇獲取數據。

示例

下麵的例子將從tutorials_tbl表中作者的名字是yiibai所有記錄返回:

D:\software\mysql-5.6.25-winx64\bin> mysql -u root -p password;
Enter password:
mysql> use test;
Database changed
mysql> SELECT * from tutorials_tbl WHERE tutorial_author='yiibai';
+-------------+----------------+-----------------+-----------------+
| tutorial_id | tutorial_title | tutorial_author | submission_date |
+-------------+----------------+-----------------+-----------------+
|           3 | JAVA Tutorial  | yiibai          | 2007-05-21      |
+-------------+----------------+-----------------+-----------------+
1 rows in set (0.01 sec)

mysql>

除非執行字符串LIKE比較,比較是不區分大小寫。可以使用BINARY關鍵字使搜索區分大小寫如下:

D:\software\mysql-5.6.25-winx64\bin> mysql -u root -p password;
Enter password:
mysql> use test;
Database changed
mysql> SELECT * from tutorials_tbl \
          WHERE BINARY tutorial_author='yiibai';
Empty set (0.02 sec)

mysql>

13、MySQL UPDATE查詢

可能會有一個需要,要在一個MySQL表中的現有數據進行修改。可以通過使用SQL UPDATE命令來執行。可以修改任何MySQL表中任何字段的值。

語法

這裡是UPDATE命令修改數據到MySQL表的通用SQL語法:

UPDATE table_name SET field1=new-value1, field2=new-value2
[WHERE Clause]
  • 完全可以更新一個或多個字段。

  • 可以指定使用任何條件在WHERE子句中。

  • 可以一次更新一個表中的值。

當想更新表中選定行,WHERE子句是非常有用的。

使用SQL UPDATE命令以及WHERE子句來更新選定數據到MySQL表tutorials_tbl。

示例

下麵的例子將更新 tutorial_id 為3 的紀錄中的 tutorial_title 字段。

D:\software\mysql-5.6.25-winx64\bin> mysql -u root -p password;
Enter password:
mysql> use test;
Database changed
mysql> UPDATE tutorials_tbl 
    -> SET tutorial_title='Learning JAVA' 
    -> WHERE tutorial_id=3;
Query OK, 1 row affected (0.04 sec)
Rows matched: 1  Changed: 1  Warnings: 0

mysql>

14、MySQL DELETE查詢

如果想從任何MySQL表中刪除紀錄,那麼可以使用SQL命令:DELETE FROM. 可以使用這個命令在MySQL>提示符,以及PHP等腳本的語言。

語法

這裡是DELETE命令從一個MySQL表中刪除數據的通用的SQL語法:

DELETE FROM table_name [WHERE Clause]
  • 如果WHERE子句冇有指定,則所有MySQL表中的記錄將被刪除。

  • 可以指定使用任何條件在WHERE子句中。

  • 可以一次刪除一個表中的所有記錄。

當要刪除一個表中選擇特定行,WHERE子句是非常有用的。

使用SQL DELETE命令,在WHERE子句中選定 MySQL 表 tutorials_tbl 的數據將被刪除。

示例

下麵的例子將刪除 tutorial_tbl表中 tutorial_id為3的一條記錄。

D:\software\mysql-5.6.25-winx64\bin> mysql -u root -p password;
Enter password:
mysql> use test;
Database changed
mysql> DELETE FROM tutorials_tbl WHERE tutorial_id=3;
Query OK, 1 row affected (0.23 sec)

mysql>

15、MySQL LIKE子句

我們已經看到使用SQL SELECT命令從MySQL表中獲取數據。也可以使用WHERE子句來選擇所需的記錄條件子句。

WHERE等於子句號(=)用來精確匹配工作,如類似 “tutorial_author='yiibai'”。 但也有可能,我們要求過濾掉所有的結果,tutorial_author應包含的名稱:"jay"。這可以通過使用SQL LIKE子句以及WHERE子句來處理。

如果SQL LIKE子句連同 % 字符使用,那麼它會像在UNIX上的元字符(*),列出了所有的文件或目錄在命令提示符下。

如果冇有字符%,LIKE子句是非常相似的等號在WHERE子句中使用的效果。

語法

下麵是SELECT命令連同LIKE子句來從MySQL表獲取數據的通用SQL語法:

SELECT field1, field2,...fieldN table_name1, table_name2...
WHERE field1 LIKE condition1 [AND [OR]] filed2 = 'somevalue'
  • 可以指定使用任何條件在WHERE子句中

  • 可以使用LIKE子句在WHERE子句中

  • 可以使用LIKE子句代替等號(=)

  • 當LIKE連同%符號使用,那麼它就會像一個元字符的搜索

  • 可以指定一個以上的條件使用AND或OR運算符

  • WHERE... LIKE子句可以使用SQL命令的DELETE 或 UPDATE ,也可以指定一個條件

使用SQL SELECT命令以及WHERE ... LIKE子句從MySQL表tutorials_tbl 選擇獲取數據並返回

示例

下麵的例子是從 tutorials_tbl 表中獲取作者的名稱以 aul 結尾的所有記錄:

root@host# mysql -u root -p password;
Enter password:
mysql> use test;
Database changed
mysql> SELECT * from tutorials_tbl WHERE tutorial_author LIKE '%aul';
+-------------+----------------+-----------------+-----------------+
| tutorial_id | tutorial_title | tutorial_author | submission_date |
+-------------+----------------+-----------------+-----------------+
|           3 | JAVA Tutorial  | Paul            | 2015-07-17      |
+-------------+----------------+-----------------+-----------------+
1 rows in set (0.01 sec)

mysql>

16、MySQL ORDER BY排序結果

我們已經看到使用SQL SELECT命令從MySQL表中獲取數據。當選擇數據行,MySQL服務器可以自由地返回它們的順序,除非有指示它按照怎樣的結果進行排序。但是排序結果可以通過增加一個ORDER BY子句設定列名稱或要排序的列。

語法

這是使用ORDER BY子句從MySQL表數據進行排序的SELECT命令的通用SQL語法:

SELECT field1, field2,...fieldN table_name1, table_name2...
ORDER BY field1, [field2...] [ASC [DESC]]
  • 可以排序返回所列出提供的任何字段的結果

  • 可以在多個字段排序結果

  • 可以使用關鍵字ASC或DESC來執行升序或降序排序。默認情況下,按升序排列

  • 可以使用WHERE ... LIKE子句以通用的方式放置條件

在命令提示符使用ORDER BY子句

使用SQL SELECT命令與ORDER BY子句,從MySQL表tutorials_tbl獲取數據。

示例

嘗試下麵的例子,它返回的結果是按升序排列的。

root@host# mysql -u root -p password;
Enter password:
mysql> use use;
Database changed
mysql> SELECT * from tutorials_tbl ORDER BY tutorial_author ASC;
+-------------+----------------+-----------------+-----------------+
| tutorial_id | tutorial_title | tutorial_author | submission_date |
+-------------+----------------+-----------------+-----------------+
|           1 | Learn PHP      | Paul            | 2015-07-17      |
|           2 | Learn MySQL    | Saya            | 2015-07-17      |
|           3 | Learning JAVA  | Yiibai          | 2007-05-06      |
+-------------+----------------+-----------------+-----------------+
3 rows in set
mysql> 

驗證所有的作者名稱列出來是按升序排列。

17、MySQL Join聯接

到目前為止,我們隻是從一個表讀取數據。這是相對簡單的,但在大多數現實中的MySQL使用,需要從多個表中,在單個查詢獲得數據。

可以在單個SQL查詢中使用多個表。連接MySQL中的行在兩個或多個表到一個表。

可以使用Join在SELECT,UPDATE和DELETE語句加入MySQL表。我們將看到LEFT JOIN的例子, 這與簡單的MySQL JOIN有所不同。

假設我們有兩個表 tcount_tbl 和 tutorials_tbl,在數據庫:test ,完整列表如下:

示例

試試下麵的例子:

root@host# mysql -u root -p password;
Enter password:
mysql> use test;
Database changed
mysql> create table tcount_tbl(
    -> tutorial_author varchar(24) not null,
    -> tutorial_count int(10) not null default 0 );
Query OK, 0 rows affected

mysql> INSERT INTO tcount_tbl (tutorial_author, tutorial_count) VALUES('mahran', 10);
mysql> INSERT INTO tcount_tbl (tutorial_author, tutorial_count) VALUES('mahnaz', 0);
mysql> INSERT INTO tcount_tbl (tutorial_author, tutorial_count) VALUES('Jen',    0);
mysql> INSERT INTO tcount_tbl (tutorial_author, tutorial_count) VALUES('Gill', 20);
mysql> INSERT INTO tcount_tbl (tutorial_author, tutorial_count) VALUES('Paul', 10);
mysql> INSERT INTO tcount_tbl (tutorial_author, tutorial_count) VALUES('yiibai', 10);

mysql> SELECT * FROM tcount_tbl;
+-----------------+----------------+
| tutorial_author | tutorial_count |
+-----------------+----------------+
| mahran          |             10 |
| mahnaz          |              0 |
| Jen             |              0 |
| Gill            |             20 |
| Paul            |             10 |
| yiibai          |             10 |
+-----------------+----------------+
6 rows in set (0.01 sec)
mysql> SELECT * from tutorials_tbl;
+-------------+----------------+-----------------+-----------------+
| tutorial_id | tutorial_title | tutorial_author | submission_date |
+-------------+----------------+-----------------+-----------------+
|           1 | Learn PHP      | Paul            | 2015-07-17      |
|           2 | Learn MySQL    | Saya            | 2015-07-17      |
|           3 | Learning JAVA  | yiibai          | 2007-05-06      |
+-------------+----------------+-----------------+-----------------+
3 rows in set (0.00 sec)
mysql>

現在,我們可以寫一個SQL查詢來連接這兩個表。此查詢將從表tutorials_tbl和tcount_tbl 選擇所有作者的教學數量。

mysql> SELECT a.tutorial_id, a.tutorial_author, b.tutorial_count
    -> FROM tutorials_tbl a, tcount_tbl b
    -> WHERE a.tutorial_author = b.tutorial_author;
+-------------+-----------------+----------------+
| tutorial_id | tutorial_author | tutorial_count |
+-------------+-----------------+----------------+
|           1 | Paul            |             10 |
|           3 | Yiibai          |             10 |
+-------------+-----------------+----------------+
2 rows in set (0.01 sec)
mysql>

18、MySQL NULL值

我們已經看到SQL SELECT命令和WHERE子句一起使用,來從MySQL表中提取數據,但是,當我們試圖給出一個條件,比較字段或列值設置為NULL,它確不能正常工作。

為了處理這種情況,MySQL提供了三大運算符

  • IS NULL: 如果列的值為NULL,運算結果返回 true

  • IS NOT NULL: 如果列的值不為NULL,運算結果返回 true

  • <=>: 運算符比較值,(不同於=運算符)即使兩個空值它返回 true

涉及NULL的條件是特殊的。不能使用= NULL或!= NULL來匹配查找列的NULL值。這樣的比較總是失敗,因為它是不可能告訴它們是否是true。 甚至 NULL = NULL 也是失敗的。

要查找列的值是或不是NULL,使用IS NULL或IS NOT NULL。

在命令提示符,使用NULL值:

假設在 test 數據庫中的表 tcount_tbl 它包含兩個列 tutorial_author 和 tutorial_count, 其中 tutorial_count 的值為NULL表明其值未知:

示例

試試下麵的例子:

root@host# mysql -u root -p password;
Enter password:
mysql> use test;
Database changed

mysql> drop table tcount_tbl;
Query OK, 0 rows affected (0.05 sec)
mysql> create table tcount_tbl
    -> (
    -> tutorial_author varchar(40) NOT NULL,
    -> tutorial_count  INT
    -> );
Query OK, 0 rows affected (0.05 sec)
mysql> INSERT INTO tcount_tbl
    -> (tutorial_author, tutorial_count) values ('mahran', 20);
mysql> INSERT INTO tcount_tbl
    -> (tutorial_author, tutorial_count) values ('mahnaz', NULL);
mysql> INSERT INTO tcount_tbl
    -> (tutorial_author, tutorial_count) values ('Jen', NULL);
mysql> INSERT INTO tcount_tbl
    -> (tutorial_author, tutorial_count) values ('Gill', 20);

mysql> SELECT * from tcount_tbl;
+-----------------+----------------+
| tutorial_author | tutorial_count |
+-----------------+----------------+
| mahran          |             20 |
| mahnaz          |           NULL |
| Jen             |           NULL |
| Gill            |             20 |
+-----------------+----------------+
4 rows in set (0.00 sec)

mysql>

可以看到,= 及 != 不能與 NULL值不能正常工作(匹配)如下:

mysql> SELECT * FROM tcount_tbl WHERE tutorial_count = NULL;
Empty set (0.00 sec)
mysql> SELECT * FROM tcount_tbl WHERE tutorial_count != NULL;
Empty set (0.01 sec)

要查找記錄中,其中 tutorial_count 列的值是或不是NULL,查詢應該這樣寫:

mysql> SELECT * FROM tcount_tbl 
    -> WHERE tutorial_count IS NULL;
+-----------------+----------------+
| tutorial_author | tutorial_count |
+-----------------+----------------+
| mahnaz          |           NULL |
| Jen             |           NULL |
+-----------------+----------------+
2 rows in set (0.00 sec)
mysql> SELECT * from tcount_tbl 
    -> WHERE tutorial_count IS NOT NULL;
+-----------------+----------------+
| tutorial_author | tutorial_count |
+-----------------+----------------+
| mahran          |             20 |
| Gill            |             20 |
+-----------------+----------------+
2 rows in set (0.00 sec)

19、MySQL正則表達式

在前麵我們已經看到了MySQL的模式匹配:LIKE ...%. MySQL支持另一種類型的模式匹配的操作基於正則表達式和正則表達式運算符。如果知道PHP或Perl,那麼它是非常簡單的,因為這匹配非常相似於腳本正則表達式。

以下是模式的表格,其可以連同REGEXP運算符使用。

模式 什麼樣的模式匹配
^ 開始的一個字符串
$ 結束的一個字符串
. 任意單個字符
[...] 方括號中列出的任何字符
[^...] 任何字符方括號之間不會被列出
p1|p2|p3 交替;匹配的任何模式 p1, p2, 或 p3
* 前一個元素的零個或多個實例
+ 前麵元素的一或多個實例
{n} 前一個元素的n個實例
{m,n} 前一個元素的 m 到 n 個實例

示例

現在根據上麵的表格,可以在不同的設備類型用SQL查詢來滿足要求。在這裡,列出一些的理解。考慮有一個表稱為 person_tbl,它是有一個 name 字段:

查詢查找所有以 “st” 開頭的名字:

mysql> SELECT name FROM person_tbl WHERE name REGEXP '^st';

查詢找到所有以 'ok' 結尾的名字

mysql> SELECT name FROM person_tbl WHERE name REGEXP 'ok$';

查詢查找其中包含 'mar' 所有的名字

mysql> SELECT name FROM person_tbl WHERE name REGEXP 'mar';

查詢查找以元音 'ok' 結尾的所有名稱

mysql> SELECT name FROM person_tbl WHERE name REGEXP '^[aeiou]|ok$';
 

20、MySQL事務

事務是數據庫處理操作,其中執行就好像它是一個單一的一組有序的工作單元。換言之,事務將永遠不會是完全的,除非在組內每個單獨的操作是成功的。如果事務中的任何操作失敗,整個事務將失敗。

實際上,許多SQL查詢組成到一個組,將執行所有這些一起作為事務的一部分。

事務性質

事務具有以下四個標準屬性,通常由首字母縮寫ACID簡稱:

  • 原子性: 確保了工作單位中的所有操作都成功完成; 否則,事務被中止,在失敗時會被回滾到事務操作以前的狀態。

  • 一致性:可確保數據庫在正確的更改狀態在一個成功提交事務。

  • 隔離: 使事務相互獨立地操作。

  • 持久性: 確保了提交事務的結果或係統故障情況下仍然存在作用。

在MySQL中,事務以BEGIN WORK語句開始開始工作,並使用COMMIT或ROLLBACK語句結束。SQL命令在開始和結束語句之間構成大量事務。

提交和回滾

這兩個關鍵字Commit和Rollback主要用於MySQL的事務。

  • 當一個成功的事務完成後,COMMIT命令發出的變化對所有涉及的表將生效。

  • 如果發生故障,ROLLBACK命令發出後,事務中引用的每個表將恢複到事務開始之前的狀態。

可以通過設置AUTOCOMMIT這個會話變量控製事務的行為。如果AUTOCOMMIT設置為1(默認值),那麼每個SQL語句(在事務或不在事務)被認為是一個完整的事務並提交,在默認情況下是在當它完成時。當AUTOCOMMIT設置為0,通過發出SET AUTOCOMMIT=0命令, 隨後的一係列語句就像一個事務,但並冇有任何活動被提交直到一個明確的發出 COMMIT 語句。

可以通過使用PHP 的 mysql_query()函數執行這些SQL命令。

關於事務通用示例

此事件序列是獨立於所使用的編程語言; 邏輯路徑可以是任何編程語言,使用它在創建應用程序中創建。

可以通過使用 mysql_query()函數執行這些PHP SQL命令

  • 開始事務是通過發出SQL命令BEGIN WORK

  • 類似發出的一個或多個SQL命令 SELECT, INSERT, UPDATE 或 DELETE.

  • 根據要求,檢查是否有任何錯誤

  • 如果有錯誤,發出ROLLBACK命令,否則執行COMMIT命令。

在MySQL的事務安全表類型

不能直接使用事務,可以使用但它們冇有安全保障。如果打算使用事務在MySQL編程,那麼需要使用一個特殊的方式來創建表。 有許多類型的表其支持事務,但目前最流行的一種是:InnoDB.

支持InnoDB表需要特定的編譯參數,在源代碼編譯MySQL時。如果MySQL版本不支持InnoDB,得要求互聯網服務提供商建立一個版本的MySQL的InnoDB表類型的支持,或 下載並安裝MySQL-Max二進製分發的Windows版本,或者Linux/UNIX開發環境中工作的表類型。

如果你的MySQL安裝支持InnoDB表,簡直就是一個TYPE= InnoDB的定義添加到表創建語句後麵。例如,下麵的代碼創建一個名為 tcount_tbl 的 InnoDB 類型表:

root@host# mysql -u root -p password;
Enter password:
mysql> use test;
Database changed
mysql> create table tcount_tbl
    -> (
    -> tutorial_author varchar(40) NOT NULL,
    -> tutorial_count  INT
    -> ) TYPE=InnoDB;
Query OK, 0 rows affected (0.05 sec)

請檢查下麵的鏈接了解更多有關: InnoDB

可以使用其它類型的表 GEMINI 或 BDB, 但它取決於安裝MySQL時,是否支持這兩種類型。

 

21、MySQL Alter命令

當想改變表名,MySQL的ALTER命令非常有用, 在添加或刪除任何表字段到現有列在表中。

讓我們開始創建一個表為 testalter_tbl。

root@host# mysql -u root -p password;
Enter password:
mysql> use test;
Database changed
mysql> create table testalter_tbl
    -> (
    -> i INT,
    -> c CHAR(1)
    -> );
Query OK, 0 rows affected (0.05 sec)
mysql> SHOW COLUMNS FROM testalter_tbl;
+-------+---------+------+-----+---------+-------+
| Field | Type    | Null | Key | Default | Extra |
+-------+---------+------+-----+---------+-------+
| i     | int(11) | YES  |     | NULL    |       |
| c     | char(1) | YES  |     | NULL    |       |
+-------+---------+------+-----+---------+-------+
2 rows in set (0.00 sec)

刪除,添加或重新定義列

假設想要從上麵MySQL的表中刪除一個現有列,那麼使用ALTER命令以及DROP子句如下:

mysql> ALTER TABLE testalter_tbl  DROP i;

如果在表中列是唯一的一個,那麼DROP將無法正常工作。

要添加列,使用ADD並指定列定義。下麵的語句將存儲到 i 列:testalter_tbl:

mysql> ALTER TABLE testalter_tbl ADD i INT;

發出這條語句後,testalter將包含當第一次創建表時的兩列, 但不會有完全一樣的結構。這是因為新的列被添加到表中時,默認排在最後一列。因此,即使 i 列原來是 mytbl 的第一列,但現在它是最後一列。

mysql> SHOW COLUMNS FROM testalter_tbl;
+-------+---------+------+-----+---------+-------+
| Field | Type    | Null | Key | Default | Extra |
+-------+---------+------+-----+---------+-------+
| c     | char(1) | YES  |     | NULL    |       |
| i     | int(11) | YES  |     | NULL    |       |
+-------+---------+------+-----+---------+-------+
2 rows in set (0.00 sec)

若要指示列在表中的特定位置,要麼使用FIRST把它放在第一列或AFTER col_name 來指定新的列應放置col_name之後。 試試下麵的ALTER TABLE語句,使用 SHOW COLUMNS 看看有什麼影響:

ALTER TABLE testalter_tbl DROP i;
ALTER TABLE testalter_tbl ADD i INT FIRST;
ALTER TABLE testalter_tbl DROP i;
ALTER TABLE testalter_tbl ADD i INT AFTER c;

FIRST 和 AFTER 隻能在ADD子句中使用。這意味著,如果你想在表中重新排位現有列,首先必須刪除(DROP )它,然後在新的位置添加(ADD)它。

更改列定義或名稱

要改變列的定義,使用MODIFY 或CHANGE 子句以及ALTER命令。 例如, 要改變字段 c 從 CHAR(1) 修改為 CHAR(10), 那麼可以這樣做:

mysql> ALTER TABLE testalter_tbl MODIFY c CHAR(10);

CHANGE語法可能有點不同。CHANGE關鍵字後的名稱是要修改的列,然後指定新的定義,其中包括新的名稱。試試下麵的例子:

mysql> ALTER TABLE testalter_tbl CHANGE i j BIGINT;

如果現在使用CHANGE轉換i列從BIGINT為INT,但不改變列名,該語句執行預期:

mysql> ALTER TABLE testalter_tbl CHANGE j j INT;

ALTER TABLE影響Null和缺省值屬性

當使用 MODIFY 或 CHANGE修改列,還可以指定該列是否能為NULL值以及它的默認值。事實上,如果你不這樣做,MySQL也會自動分配這些屬性值。

下麵是一個例子,這裡 NOT NULL列將使用100作為默認值。

mysql> ALTER TABLE testalter_tbl 
    -> MODIFY j BIGINT NOT NULL DEFAULT 100;

如果不使用上麵的命令,那麼MySQL將填補使用NULL 來填充所有列值。

更改列的默認值

可以使用ALTER命令更改任何列的默認值。嘗試下麵的例子。

mysql> ALTER TABLE testalter_tbl ALTER i SET DEFAULT 1000;
mysql> SHOW COLUMNS FROM testalter_tbl;
+-------+---------+------+-----+---------+-------+
| Field | Type    | Null | Key | Default | Extra |
+-------+---------+------+-----+---------+-------+
| c     | char(1) | YES  |     | NULL    |       |
| i     | int(11) | YES  |     | 1000    |       |
+-------+---------+------+-----+---------+-------+
2 rows in set (0.00 sec)

從任何一列刪除默認的約束,可以使用ALTER命令以及DROP子句。

mysql> ALTER TABLE testalter_tbl ALTER i DROP DEFAULT;
mysql> SHOW COLUMNS FROM testalter_tbl;
+-------+---------+------+-----+---------+-------+
| Field | Type    | Null | Key | Default | Extra |
+-------+---------+------+-----+---------+-------+
| c     | char(1) | YES  |     | NULL    |       |
| i     | int(11) | YES  |     | NULL    |       |
+-------+---------+------+-----+---------+-------+
2 rows in set (0.00 sec)

更改表類型

可以通過使用ALTER命令以及TYPE子句修改表的類型。試試下麵的例子,將 testalter_tbl 的類型更改為MyISAM 表類型。

若想要知道一個表的當前類型,那麼可使用 SHOW TABLE STATUS 語句。

mysql> ALTER TABLE testalter_tbl TYPE = MYISAM;
mysql>  SHOW TABLE STATUS LIKE 'testalter_tbl'\G
*************************** 1. row ****************
           Name: testalter_tbl
           Type: MyISAM
     Row_format: Fixed
           Rows: 0
 Avg_row_length: 0
    Data_length: 0
Max_data_length: 25769803775
   Index_length: 1024
      Data_free: 0
 Auto_increment: NULL
    Create_time: 2015-06-03 18:35:36
    Update_time: 2015-06-03 18:35:36
     Check_time: NULL
 Create_options:
        Comment:
1 row in set (0.00 sec)

重命名表

要重命名表,使用ALTER TABLE語句的RENAME選項。試試下麵的例子是用來重命名testalter_tbl為alter_tbl。

mysql> ALTER TABLE testalter_tbl RENAME TO alter_tbl;

可以使用ALTER命令來創建並在MySQL的文件刪除索引。我們將在下一章看到此功能。

 

22、MySQL索引

數據庫索引是一種數據結構,目的是提高表的操作速度。可以使用一個或多個列,提供快速隨機查找和訪問記錄的高效排序來創建索引。

要創建的索引,應當認為哪列將用於使SQL查詢,創建對這些列的一個或多個索引。

實際上,索引也是表,其中保存主鍵或索引字段的指針並指向每個記錄到實際的表的類型。

用戶無法看到索引,它們隻是用來加速查詢,並將被用於數據庫搜索引擎在查找記錄時提高速度。

INSERT和UPDATE語句需要更多的時間來創建索引,作為在SELECT語句快速在這些表上操作。其原因是,在執行插入或更新數據時,數據庫需要將插入或更新索引值也更新。

簡單和唯一索引

可以在表上創建唯一值索引。唯一索引意味著兩行不能有相同的索引值。下麵是在表上創建索引的語法

CREATE UNIQUE INDEX index_name
ON table_name ( column1, column2,...);

可以使用一個或多個列來創建索引。例如,我們可以使用tutorial_author 來創建一個 tutorials_tbl 索引。

CREATE UNIQUE INDEX AUTHOR_INDEX
ON tutorials_tbl (tutorial_author)

可以在表上創建一個簡單的索引。創建簡單的索引隻是省略UNIQUE關鍵字。簡單的索引可以在表中重複的值。

如果想索引的列的值按降序排列,可以列名之後添加保留字DESC。

mysql> CREATE UNIQUE INDEX AUTHOR_INDEX
ON tutorials_tbl (tutorial_author DESC)

使用ALTER命令來添加和刪除索引

有四種類型的索引可以添加到一個表:

  • ALTER TABLE tbl_name ADD PRIMARY KEY (column_list): 此語句添加一個主鍵(PRIMARY KEY),這意味著索引值必須是唯一的,而不能為空。

  • ALTER TABLE tbl_name ADD UNIQUE index_name (column_list): 此語句創建一個索引的量的值必須是唯一的(除了不能使用NULL值,其它的可以出現多次)。

  • ALTER TABLE tbl_name ADD INDEX index_name (column_list): 這增加普通的索引,其中的任何值的出現多次。

  • ALTER TABLE tbl_name ADD FULLTEXT index_name (column_list): 這將創建一個用於文本搜索目的一種特殊的FULLTEXT索引。

下麵是一個添加索引到現有表的例子。

mysql> ALTER TABLE testalter_tbl ADD INDEX (c);

您可以通過使用ALTER命令以及DROP子句來刪除索引。試試下麵的例子,用來刪除上麵創建的索引。

mysql> ALTER TABLE testalter_tbl DROP INDEX (c);

使用ALTER命令來添加和刪除PRIMARY KEY

也可以用同樣的方法添加主鍵。但要在列確保主鍵正常使用,需要指定使用 NOT NULL。

下麵是一個例子添加主鍵在現有的表。列需要添加 NOT NULL 屬性,然後再添加為一個主鍵。

mysql> ALTER TABLE testalter_tbl MODIFY i INT NOT NULL;
mysql> ALTER TABLE testalter_tbl ADD PRIMARY KEY (i);

可以使用ALTER命令刪除主鍵如下:

mysql> ALTER TABLE testalter_tbl DROP PRIMARY KEY;

要刪除索引的不是主鍵,必須指定索引名。

顯示索引信息

可以使用SHOW INDEX命令,列出所有與表相關的索引。 垂直格式輸出(由\G指定),這是經常有用的語句,以避免長線概括輸出:

試試下麵的例子:

mysql> SHOW INDEX FROM table_name\G
........

23、MySQL臨時表

臨時表可能在某些情況下是非常有用的,以保持臨時數據。 臨時表的最重要的事情是,當前客戶端會話結束時,它們將會被刪除。

臨時表是在MySQL版本3.23中增加的。如果使用MySQL 3.23之前的舊版本,是不能使用臨時表的,但可以使用堆表。

如前所述,臨時表將隻持續在會話存在時。如果在運行一個PHP腳本代碼,臨時表會自動在腳本執行完畢時刪除。如果是通過MySQL客戶端程序連接到MySQL數據庫服務器, 那麼臨時表會一直存在,直到關閉客戶端或手動銷毀表。

示例

下麵是一個例子,顯示臨時表的使用。

mysql> CREATE TEMPORARY TABLE SalesSummary (
    -> product_name VARCHAR(50) NOT NULL
    -> , total_sales DECIMAL(12,2) NOT NULL DEFAULT 0.00
    -> , avg_unit_price DECIMAL(7,2) NOT NULL DEFAULT 0.00
    -> , total_units_sold INT UNSIGNED NOT NULL DEFAULT 0
);
Query OK, 0 rows affected (0.00 sec)

mysql> INSERT INTO SalesSummary
    -> (product_name, total_sales, avg_unit_price, total_units_sold)
    -> VALUES
    -> ('cucumber', 100.25, 90, 2);

mysql> SELECT * FROM SalesSummary;
+--------------+-------------+----------------+------------------+
| product_name | total_sales | avg_unit_price | total_units_sold |
+--------------+-------------+----------------+------------------+
| cucumber     |      100.25 |          90.00 |                2 |
+--------------+-------------+----------------+------------------+
1 row in set (0.00 sec)

當發出SHOW TABLES命令,臨時表不會被列在表的列表中。現在,如果注銷MySQL會話,然後發出SELECT命令,那麼會發現在數據庫中冇有可用的數據。即使是臨時表也不存在了。

刪除臨時表

默認情況下,當數據庫連接被終止,所有的臨時表被MySQL刪除。儘管如此,如果想在結束會話前刪除它們,那麼可通過發出DROP TABLE命令。

以下是刪除一個臨時表的例子:

mysql> CREATE TEMPORARY TABLE SalesSummary (
    -> product_name VARCHAR(50) NOT NULL
    -> , total_sales DECIMAL(12,2) NOT NULL DEFAULT 0.00
    -> , avg_unit_price DECIMAL(7,2) NOT NULL DEFAULT 0.00
    -> , total_units_sold INT UNSIGNED NOT NULL DEFAULT 0
);
Query OK, 0 rows affected (0.00 sec)

mysql> INSERT INTO SalesSummary
    -> (product_name, total_sales, avg_unit_price, total_units_sold)
    -> VALUES
    -> ('cucumber', 100.25, 90, 2);

mysql> SELECT * FROM SalesSummary;
+--------------+-------------+----------------+------------------+
| product_name | total_sales | avg_unit_price | total_units_sold |
+--------------+-------------+----------------+------------------+
| cucumber     |      100.25 |          90.00 |                2 |
+--------------+-------------+----------------+------------------+
1 row in set (0.00 sec)
mysql> DROP TABLE SalesSummary;
mysql>  SELECT * FROM SalesSummary;
ERROR 1146: Table 'test.SalesSummary' doesn't exist

24、MySQL複製表

可能有一種情況,當需要一個表精確的副本,那麼CREATE TABLE... SELECT可能達不到目的,因為副本必須包含相同的索引,默認值等等。

可以通過以下步驟處理這種情況:

  • 使用 SHOW CREATE TABLE以獲得CREATE TABLE語句用於指定源表的結構,索引和所有其它的。

  • 修改語句用來更改表名為克隆表並執行該語句。通過這種方式,將有確切的克隆表。

  • 或者,如果需要複製以及表的內容,再發出一個INSERT INTO... SELECT語句。

示例

試試下麵的例子來創建表tutorials_tbl的一個克隆表。

步驟1:

獲取有關表的完整結構。

mysql> SHOW CREATE TABLE tutorials_tbl \G;
*************************** 1. row ***************************
       Table: tutorials_tbl
Create Table: CREATE TABLE `tutorials_tbl` (
  `tutorial_id` int(11) NOT NULL auto_increment,
  `tutorial_title` varchar(100) NOT NULL default '',
  `tutorial_author` varchar(40) NOT NULL default '',
  `submission_date` date default NULL,
  PRIMARY KEY  (`tutorial_id`),
  UNIQUE KEY `AUTHOR_INDEX` (`tutorial_author`)
) TYPE=MyISAM
1 row in set (0.00 sec)

ERROR:
No query specified

步驟2:

重命名該表,並創建另一個表。

mysql> CREATE TABLE `clone_tbl` (
  -> `tutorial_id` int(11) NOT NULL auto_increment,
  -> `tutorial_title` varchar(100) NOT NULL default '',
  -> `tutorial_author` varchar(40) NOT NULL default '',
  -> `submission_date` date default NULL,
  -> PRIMARY KEY  (`tutorial_id`),
  -> UNIQUE KEY `AUTHOR_INDEX` (`tutorial_author`)
-> ) TYPE=MyISAM;
Query OK, 0 rows affected (1.80 sec)

步驟3:

執行步驟2後,將在數據庫中創建一張克隆表。如果想從舊表複製數據到新表,那麼可以通過使用INSERT INTO... SELECT語句來做到這一點。

mysql> INSERT INTO clone_tbl (tutorial_id,
    ->                        tutorial_title,
    ->                        tutorial_author,
    ->                        submission_date)
    -> SELECT tutorial_id,tutorial_title,
    ->        tutorial_author,submission_date,
    -> FROM tutorials_tbl;
Query OK, 3 rows affected (0.07 sec)
Records: 3  Duplicates: 0  Warnings: 0

最後,這是想要確切複製的一張表。

25、MySQL數據庫信息

有三個信息,經常要從MySQL獲取。

  • 有關查詢結果的信息: 這包括任何SELECT,UPDATE或DELETE語句所影響的記錄數量。

  • 有關表和數據庫的信息: 這包括關於表和數據庫的結構的信息。

  • 關於MySQL服務器的信息: 這包括數據庫服務器的當前狀態,版本號等。

在mysql的提示符下,很容易得到這些信息,但如果使用Perl或PHP的API,需要顯式調用各種API來獲取這些信息。 下麵的部分將說明如何獲取這些信息。

獲取通過查詢影響的行數量

PERL 示例

在DBI腳本,受影響的行數是通過do( )或execute( )返回,這取決於如何執行查詢:

# Method 1
# execute $query using do( )
my $count = $dbh->do ($query);
# report 0 rows if an error occurred
printf "%d rows were affected\n", (defined ($count) ? $count : 0);

# Method 2
# execute query using prepare( ) plus execute( )
my $sth = $dbh->prepare ($query);
my $count = $sth->execute ( );
printf "%d rows were affected\n", (defined ($count) ? $count : 0);

PHP 示例

在PHP中,調用mysql_affected_rows()函數,以找出查詢多少行改變:

$result_id = mysql_query ($query, $conn_id);
# report 0 rows if the query failed
$count = ($result_id ? mysql_affected_rows ($conn_id) : 0);
print ("$count rows were affected\n");

列出表和數據庫

這很容易列出數據庫服務器中的所有可用的數據庫和表。但如果結果可能為null,那麼可能冇有足夠的權限。

除了下麵提到的方法,還可以用SHOW TABLES或SHOW DATABASES來查詢獲得表或數據庫列表,無論是在 PHP 或 Perl 中。

PERL 示例

# Get all the tables available in current database.
my @tables = $dbh->tables ( );
foreach $table (@tables ){
   print "Table Name $table\n";
}

PHP 示例

<?php
$con = mysql_connect("localhost", "user", "password");
if (!$con)
{
  die('Could not connect: ' . mysql_error());
}

$db_list = mysql_list_dbs($con);

while ($db = mysql_fetch_object($db_list))
{
  echo $db->Database . "<br />";
}
mysql_close($con);
?>

獲取服務器元數據

有哪些可以在mysql提示符下執行,或使用任何如PHP腳本來獲取各種有關數據庫服務器的重要信息。

命令 描述
SELECT VERSION( ) 服務器版本字符串
SELECT DATABASE( ) 當前數據庫名稱(如果冇有,則為空)
SELECT USER( ) 當前用戶名
SHOW STATUS 服務器狀態指示
SHOW VARIABLES 服務器配置變量
 

26、MySQL序列的使用

序列是一組整數如1,2,3,...為了在需要時生成的。數據庫中序列是常用的,因為很多應用都需要在表的每行中,包含一個唯一的值,並且序列提供了一種簡單的方法來生成它們。本章將介紹如何在MySQL中使用序列。

使用AUTO_INCREMENT列

在MySQL中最簡單使用序列的方式是定義一個列AUTO_INCREMENT,然後其餘事情由MySQL來打理。

示例

嘗試下麵的例子。在創建表之後,它會插入幾行此表中,但在這裡不給出記錄ID,因為它由MySQL自動增加。

mysql> CREATE TABLE insect
    -> (
    -> id INT UNSIGNED NOT NULL AUTO_INCREMENT,
    -> PRIMARY KEY (id),
    -> name VARCHAR(30) NOT NULL, # type of insect
    -> date DATE NOT NULL, # date collected
    -> origin VARCHAR(30) NOT NULL # where collected
);
Query OK, 0 rows affected (0.02 sec)
mysql> INSERT INTO insect (id,name,date,origin) VALUES
    -> (NULL,'housefly','2003-09-19','kitchen'),
    -> (NULL,'millipede','2004-09-11','driveway'),
    -> (NULL,'grasshopper','2015-02-10','front yard');
Query OK, 3 rows affected (0.02 sec)
Records: 3  Duplicates: 0  Warnings: 0
mysql> SELECT * FROM insect ORDER BY id;
+----+-------------+------------+------------+
| id | name        | date       | origin     |
+----+-------------+------------+------------+
|  1 | housefly    | 2003-09-19 | kitchen    |
|  2 | millipede   | 2004-09-11 | driveway   |
|  3 | grasshopper | 2015-02-10 | front yard |
+----+-------------+------------+------------+
3 rows in set (0.00 sec)

獲取AUTO_INCREMENT值

LAST_INSERT_ID( )是一個SQL函數,這樣可以了解如何發出SQL語句,從任何客戶端中使用它。 以其他方式,Perl 和 PHP 腳本提供了獨有的函數來獲取最後一條記錄的自動遞增值。

 

27、MySQL重複處理

表或結果集有時含有重複記錄。有時,它是允許的,但有時它被要求停止使用重複記錄。有時,需要識彆重複記錄並從表中刪除它們。本章將介紹如何防止在一個表中,以及如何刪除已有的重複記錄。

防止在一個表發生重複記錄

可以使用適當表字段的PRIMARY KEY 或 UNIQUE 來防止重複記錄。讓我們來看看下麵的例子:下表中冇有這樣的索引或主鍵,所以這裡允許 first_name 和last_name 記錄重複。

CREATE TABLE person_tbl
(
    first_name CHAR(20),
    last_name CHAR(20),
    sex CHAR(10)
);
為了防止表中被創建的多個記錄具有相同的姓氏和名字的值,添加一個主鍵(PRIMARY KEY)到它的定義。 當要做這一點,也必須聲明索引列是NOT NULL,因為PRIMARY KEY不允許NULL值:
CREATE TABLE person_tbl
(
   first_name CHAR(20) NOT NULL,
   last_name CHAR(20) NOT NULL,
   sex CHAR(10),
   PRIMARY KEY (last_name, first_name)
);

如果插入一條與現有記錄重複到表,在列或定義索引列,表中一個唯一索引的存在通常會導致錯誤的發生。

應該使用 INSERT IGNORE 而不是INSERT。如果記錄與現有現有不重複時,MySQL將其正常插入。如果記錄是一個重複的,則 IGNORE 關鍵字告訴MySQL丟棄它而不會產生錯誤。

下麵的例子不會有錯誤,也不會插入重複的記錄。

mysql> INSERT IGNORE INTO person_tbl (last_name, first_name)
    -> VALUES( 'Jay', 'Thomas');
Query OK, 1 row affected (0.00 sec)
mysql> INSERT IGNORE INTO person_tbl (last_name, first_name)
    -> VALUES( 'Jay', 'Thomas');
Query OK, 0 rows affected (0.00 sec)

使用REPLACE而不是INSERT。如果記錄是新的,它插入就像使用 INSERT。如果它是重複的,新的記錄將取代舊的記錄:

mysql> REPLACE INTO person_tbl (last_name, first_name)
    -> VALUES( 'Ajay', 'Kumar');
Query OK, 1 row affected (0.00 sec)
mysql> REPLACE INTO person_tbl (last_name, first_name)
    -> VALUES( 'Ajay', 'Kumar');
Query OK, 2 rows affected (0.00 sec)

INSERT IGNORE和REPLACE應根據實現的重複處理行為來選擇。INSERT忽略保持第一套重複記錄,並丟棄剩下的。REPLACE保持最後一組重複的和擦除任何較早的記錄。

另一種方法是強製唯一性是增加唯一(UNIQUE)索引,而不是一個主鍵(PRIMARY KEY)。

CREATE TABLE person_tbl
(
   first_name CHAR(20) NOT NULL,
   last_name CHAR(20) NOT NULL,
   sex CHAR(10)
   UNIQUE (last_name, first_name)
);

統計和標識重複

以下是查詢以統計first_name和last_name 在表中的重複記錄數。

mysql> SELECT COUNT(*) as repetitions, last_name, first_name
    -> FROM person_tbl
    -> GROUP BY last_name, first_name
    -> HAVING repetitions > 1;

這個查詢將返回person_tbl表中的所有重複記錄的列表.在一般情況下,識彆的集合值重複,執行以下步驟:

  • 確定哪些列包含可重複值

  • 列出這些列中的列選擇列表,使用COUNT(*)

  • 列出的列也可以使用 GROUP BY 子句

  • 添加一個HAVING子句,通過分組計算出唯一值數大於1的記錄重複

從查詢結果消除重記錄

可以使用SELECT語句以及DISTINCT一起在一個表中找出可用唯一記錄。

mysql> SELECT DISTINCT last_name, first_name
    -> FROM person_tbl
    -> ORDER BY last_name;

替代DISTINCT方法是添加GROUP BY子句列名稱到選擇的列。這有刪除重複並選擇在指定的列值的唯一組合的效果:

mysql> SELECT last_name, first_name
    -> FROM person_tbl
    -> GROUP BY (last_name, first_name);

使用表的更換刪除重複

如果一個表中重複的記錄,並要刪除該表中的所有重複的記錄,那麼可以參考下麵的程序:

mysql> CREATE TABLE tmp SELECT last_name, first_name, sex
    ->                  FROM person_tbl;
    ->                  GROUP BY (last_name, first_name);
mysql> DROP TABLE person_tbl;
mysql> ALTER TABLE tmp RENAME TO person_tbl;

從表中刪除重複記錄的一個簡單的方法就添加索引(INDEX) 或 主鍵(PRIMAY KEY)到該表。即使該表已經提供,可以使用此技術來刪除重複的記錄。

mysql> ALTER IGNORE TABLE person_tbl
    -> ADD PRIMARY KEY (last_name, first_name);
 

28、MySQL和SQL注入

如果通過網頁需要用戶輸入一些數據信息,並將其插入到MySQL數據庫,這是一個引入SQL注入安全問題的機會。這一節將學習如何防止這種情況的發生,並幫助保護腳本和MySQL語句。

通常注入是在當要求用戶輸入時,類似他們的姓名,隻是一個名字,他們給出,會在不知不覺中包含MySQL的語句會在數據庫運行。

永遠不要信任用戶提供的數據,這個過程隻有在數據驗證後,作為一項規則,這是通過模式匹配進行。在下麵的例子中,用戶名被限製在字母+數字+字符加下劃線,並在8-20個字符之間的長度 - 可以根據需要修改這些規則。

if (preg_match("/^\w{8,20}$/", $_GET['username'], $matches))
{
   $result = mysql_query("SELECT * FROM users 
                          WHERE username=$matches[0]");
}
 else 
{
   echo "username not accepted";
}

為了說明問題,考慮這個片段:

// supposed input
$name = "Qadir'; DELETE FROM users;";
mysql_query("SELECT * FROM users WHERE name='{$name}'");

該函數調用從表中檢索用戶記錄,其中名稱列匹配由用戶指定的名稱。 在正常情況下,$name將隻包含字母數字字符,或可能是空格,如字符串ilia。 但在這裡,通過附加一個全新的查詢到$name,在調用數據庫變成災難:注入DELETE查詢刪除所有的用戶記錄。

幸運的是,如果使用MySQL,mysql_query()函數不允許查詢堆疊或一個函數調用執行多個查詢。如果嘗試堆疊查詢,調用失敗。

然而,其他PHP數據庫擴展,如SQLite和PostgreSQL,它們會樂意地進行堆查詢,執行一個字符串提供的查詢,並創建一個嚴重的安全問題。

防止SQL注入

可以在腳本語言,如 Perl和PHP巧妙地處理所有轉義字符。MySQL擴展為PHP提供mysql_real_escape_string()函數來轉義輸入的特殊字符。

if (get_magic_quotes_gpc()) 
{
  $name = stripslashes($name);
}
$name = mysql_real_escape_string($name);
mysql_query("SELECT * FROM users WHERE name='{$name}'");

LIKE的困境

為了解決LIKE困境,自定義的轉義機製必須把用戶提供%和_字符到常量。使用addcslashes()函數,它可以讓指定的字符範圍轉義。

$sub = addcslashes(mysql_real_escape_string("%something_"), "%_");
// $sub == \%something\_
mysql_query("SELECT * FROM messages WHERE subject LIKE '{$sub}%'");


29、MySQL數據庫導出(備份方法)

導出表數據到一個文本文件的最簡單方法是使用SELECT... INTO OUTFILE語句直接將導出查詢結果導出到服務器主機上的文件。

使用導出數據SELECT... INTO OUTFILE語句

語句的語法結合了常規的SELECT INTO與OUTFILE filename 末尾。默認的輸出格式與LOAD DATA是一樣的,所以下麵的語句導出 tutorials_tbl 表到C:\tutorials.txt 並使用製表符分隔,換行結尾的文件:

mysql> SELECT * FROM tutorials_tbl 
    -> INTO OUTFILE 'C:\tutorials.txt';

可以利用選項來說明如何引號和分隔列,更改記錄輸出格式。 使用CRLF為結束行導出tutorial_tbl 為CSV格式表格,使用以下語句:

mysql> SELECT * FROM passwd INTO OUTFILE 'C:\tutorials.txt'
    -> FIELDS TERMINATED BY ',' ENCLOSED BY '"'
    -> LINES TERMINATED BY '\r\n';

SELECT... INTO OUTFILE具有以下屬性:

  • 輸出的文件是直接由MySQL服務器創建的,因此,文件名應指明想要的文件名,它會被寫到服務器主機上。還有就是語句類似於冇有LOCAL版本的LOAD DATA的本地版本。

  • 必須有MySQL的FILE權限來執行SELECT ... INTO語句。

  • 輸出文件必須還不存在。 這防止MySQL弄錯文件很重要。

  • 應該有服務器主機或某種方式來檢索該主機上登錄帳戶的文件。否則,SELECT ... INTO OUTFILE可能冇有任何值給出。

  • 在UNIX下,文件創建所有人都是可讀的,由MySQL服務器所擁有。這意味著,雖然能夠讀取該文件,可能無法將其刪除。

導出表作為原始數據

mysqldump程序用於複製或備份表和數據庫。它可以寫入表輸出作為一個原始數據文件,或為一組重新創建表中的INSERT語句的記錄。

轉儲一個表作為一個數據文件,必須指定一個--tab 選項指定目錄,讓MySQL服務器寫入文件。

例如,從數據庫test中的tutorials_tbl表轉儲到一個文件在C:\tmp目錄,可使用這樣的命令:

$ mysqldump -u root -p --no-create-info \
            --tab=c:\tmp TEST tutorials_tbl
password ******

以SQL格式導出表內容或定義

以SQL格式的表導出到一個文件,使用這樣的命令:

$ mysqldump -u root -p test tutorials_tbl > dump.txt
password ******

這將創建一個具有以下內容折文件,如下:


-- MySQL dump 8.53
--
-- Host: localhost    Database: test
---------------------------------------------------------
-- Server version       5.5.58

--
-- Table structure for table `tutorials_tbl`
--

CREATE TABLE tutorials_tbl (
  tutorial_id int(11) NOT NULL auto_increment,
  tutorial_title varchar(100) NOT NULL default '',
  tutorial_author varchar(40) NOT NULL default '',
  submission_date date default NULL,
  PRIMARY KEY  (tutorial_id),
  UNIQUE KEY AUTHOR_INDEX (tutorial_author)
) TYPE=MyISAM;

--
-- Dumping data for table `tutorials_tbl`
--

INSERT INTO tutorials_tbl 
       VALUES (1,'Learn PHP','John Poul','2012-01-04');
INSERT INTO tutorials_tbl 
       VALUES (2,'Learn MySQL','Abdul S','2015-05-14');
INSERT INTO tutorials_tbl 
       VALUES (3,'JAVA Tutorial','Sanjay','2014-05-10');

要轉儲多個表,所有數據庫名稱參數後跟它們的名字。要轉儲整個數據庫,不需要在數據庫之後命名(附加)任何表:

$ mysqldump -u root -p test > database_dump.txt
password ******

要備份所有可用的數據庫在主機上,使用以下命令:

$ mysqldump -u root -p --all-databases > database_dump.txt
password ******

--all-databases選項可在MySQL 3.23.12之後的版本使用。

該方法可用於實現數據庫的備份策略。

複製表或數據庫到另一台主機

如果想從一個MySQL服務器複製表或數據庫到另一台,使用mysqldump以及數據庫名和表名。

在源主機上運行下麵的命令。將轉儲完整的數據庫到文件dump.txt:

$ mysqldump -u root -p database_name table_name > dump.txt
password *****

可以複製完整的數據庫,而無需使用特定的表名,如上所述。

現在ftp dump.txt文件在另一台主機上,並使用下麵的命令。運行此命令之前,請確保已創建數據庫名稱在目標服務器上。

$ mysql -u root -p database_name < dump.txt
password *****

另一種方式來實現這一點,無需使用一個中間文件是來發送,mysqldump輸出直接通過網絡到遠程MySQL服務器。如果可以從源數據庫所在的主機那裡連接兩個服務器,使用此命令(請確保兩個服務器可以訪問):

$ mysqldump -u root -p database_name \
       | mysql -h other-host.com database_name

命令mysqldump的一半連接到本地服務器,並轉儲輸出寫入管道。另一半MySQL連接到other-host.com遠程MySQL服務器。它讀取管道輸入並發送每條語句到other-host.com服務器。

 

30、MySQL數據庫導入(恢複數據方法)

MySQL中有兩種簡單的方法可從以前備份的文件數據加載(恢複)到MySQL數據庫。

使用LOAD DATA導入數據

MySQL提供了一個大容量數據加載的LOAD DATA語句。下麵是一個讀取文件C:\dump.txt 並將其加載到當前數據庫表mytbl的例子聲明:

mysql> LOAD DATA LOCAL INFILE 'C:\dump.txt' INTO TABLE mytbl;
  • 如果LOCAL關鍵詞不存在,MySQL查找使用絕對路徑在服務器主機上的數據文件,完全指定文件的位置,從文件係統的根開始。 MySQL讀取從給定的位置的文件。

  • 默認情況下,LOAD DATA假設數據文件包含一個行由製表符分隔範圍內被換行(新行)分割行和數據值。

  • 要明確指定一個文件格式,使用FIELDS子句來描述一行內字段的特征,LINES子句指定的行結束序列。下麵的LOAD DATA語句指定的數據文件包含由冒號和行,是由回車和新行字符結束分隔其值:

mysql> LOAD DATA LOCAL INFILE 'C:\dump.txt' INTO TABLE mytbl
  -> FIELDS TERMINATED BY ':'
  -> LINES TERMINATED BY '\r\n';
  • LOAD DATA假定數據文件中的列具有相同的順序在表中的列。如果不是這樣,可以指定一個列表來指示哪些表列數據文件列應該被裝入。 假設表中的列A,B和C,但在數據文件連續列對應於列B,C,和A。可以像這樣加載文件:

mysql> LOAD DATA LOCAL INFILE 'dump.txt' 
    -> INTO TABLE mytbl (b, c, a);

使用mysqlimport導入數據

MySQL還包括一個實用程序名:mysqlimport,它充當圍繞LOAD DATA包裝器 這樣就可以直接從命令行輸入加載文件。

從 dump.txt 加載數據到表mytbl,使用下麵的命令在命令行提示符。

$ mysqlimport -u root -p --local database_name dump.txt
password *****

如果使用mysqlimport,命令行選項提供的格式說明。對應於上述兩個LOAD DATA 語句的 mysqlimport 命令如下:

$ mysqlimport -u root -p --local --fields-terminated-by=":" \
   --lines-terminated-by="\r\n"  database_name dump.txt
password *****

在 mysqlimport 中指定的選項順序並不重要,但它們都應該在數據庫名的前麵。

mysqlimport語句使用--columns選項來指定列的順序:

$ mysqlimport -u root -p --local --columns=b,c,a \
    database_name dump.txt
password *****

處理引號和特殊字符

除了TERMINATED,FIELDS子句可以指定其他格式選項。默認情況下,LOAD DATA假設值是加引號的,並解釋反斜線(\)作為特殊字符轉義字符。要明確注明引用字符值, 使用ENCLOSED BY; MySQL將剝離字符的數據值末端在輸入處理期間。要更改默認的轉義字符,可使用ESCAPED BY。

當指定ENCLOSED BY,表明引號字符應該從數據值被剝離,有可能通過加一次或通過轉義字符,確實包含引號字符在數據值前。例如,如果引號和轉義字符是" 和 \,輸入 "a""b\"c" 將被解釋為:a"b"c

對於 mysqlimport,相應的命令行選項引號和轉義值是通過 --fields-enclosed-by 和 --fields-escaped-by來指定。

 

31、MySQL實用函數

這裡是所有重要的 MySQL 函數的列表。每個函數都用合適的例子來說明如下。

 
其它的請參數:http://www.gitbook.net/mysql