D:\software\mysql-5.6.25-winx64\bin> mysqladmin --version看到結果如下:
mysqladmin Ver 8.42 Distrib 5.6.25, for Win64 on x86_64如果看到這樣的消息,則有可能是在安裝了一些問題,需要一些幫助解決它。
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)
D:\software\mysql-5.6.25-winx64\bin> mysqladmin -u root password "123456";注:
D:\software\mysql-5.6.25-winx64\bin> mysql -u root -p Enter password: ******
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: ******
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
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命令的結尾。
大多數情況下,不需要去修改這個文件。默認情況下,它會具有以下項:
[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數據庫的管理或工作中使用:
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的數據庫管理系統的性能和統計數據的詳細信息。
可以使用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
下面是一個簡單的例子,創建名為 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)
需要特殊權限來創建或刪除一個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服務器上。
這是非常簡單的,從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命令。
正確地定義的表中的字段在數據庫的整體優化是非常重要的。我們應該只使用真正需要使用類型和字段的大小; 如果知道只使用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)才能用來填充這個字段。
表的創建命令需要:
表的名稱
字段名稱
定義每個字段(類型、長度等)
下面是通用的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命令結束。
查看創建表的結果:
刪除現有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>
想要將數據插入到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函數,返回當前的日期和時間。
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>
我們已經看到使用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,則:
當想要從一個表中提取所選行,尤其是當使用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>
可能會有一個需要,要在一個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>
如果想從任何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>
我們已經看到使用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>
我們已經看到使用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子句以通用的方式放置條件
使用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>
驗證所有的作者名稱列出來是按升序排列。
到目前為止,我們只是從一個表讀取數據。這是相對簡單的,但在大多數現實中的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>
我們已經看到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。
假設在 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)
在前面我們已經看到了MySQL的模式匹配:LIKE ...%. MySQL支持另一種類型的模式匹配的操作基於正則表達式和正則表達式運算符。如果知道PHP或Perl,那麼它是非常簡單的,因為這匹配非常相似於腳本正則表達式。
以下是模式的表格,其可以連同REGEXP運算符使用。
現在根據上面的表格,可以在不同的設備類型用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$';
事務是數據庫處理操作,其中執行就好像它是一個單一的一組有序的工作單元。換言之,事務將永遠不會是完全的,除非在組內每個單獨的操作是成功的。如果事務中的任何操作失敗,整個事務將失敗。
實際上,許多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編程,那麼需要使用一個特殊的方式來創建表。 有許多類型的表其支持事務,但目前最流行的一種是: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時,是否支持這兩種類型。
當想改變表名,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;
當使用 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的文件刪除索引。我們將在下一章看到此功能。
數據庫索引是一種數據結構,目的是提高表的操作速度。可以使用一個或多個列,提供快速隨機查找和訪問記錄的高效排序來創建索引。
要創建的索引,應當認為哪列將用於使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 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);
也可以用同樣的方法添加主鍵。但要在列確保主鍵正常使用,需要指定使用 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 ........
臨時表可能在某些情況下是非常有用的,以保持臨時數據。 臨時表的最重要的事情是,當前客戶端會話結束時,它們將會被刪除。
臨時表是在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
可能有一種情況,當需要一個表精確的副本,那麼CREATE TABLE... SELECT可能達不到目的,因為副本必須包含相同的索引,默認值等等。
可以通過以下步驟處理這種情況:
使用 SHOW CREATE TABLE以獲得CREATE TABLE語句用於指定源表的結構,索引和所有其它的。
修改語句用來更改表名為克隆表並執行該語句。通過這種方式,將有確切的克隆表。
或者,如果需要復制以及表的內容,再發出一個INSERT INTO... SELECT語句。
試試下面的例子來創建表tutorials_tbl的一個克隆表。
獲取有關表的完整結構。
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
重命名該表,並創建另一個表。
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)
執行步驟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
最後,這是想要確切復制的一張表。
有三個信息,經常要從MySQL獲取。
有關查詢結果的信息: 這包括任何SELECT,UPDATE或DELETE語句所影響的記錄數量。
有關表和數據庫的信息: 這包括關於表和數據庫的結構的信息。
關於MySQL服務器的信息: 這包括數據庫服務器的當前狀態,版本號等。
在mysql的提示符下,很容易得到這些信息,但如果使用Perl或PHP的API,需要顯式調用各種API來獲取這些信息。 下面的部分將說明如何獲取這些信息。
在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中,調用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 中。
# Get all the tables available in current database. my @tables = $dbh->tables ( ); foreach $table (@tables ){ print "Table Name $table\n"; }
Database . " "; } mysql_close($con); ?>
有哪些可以在mysql提示符下執行,或使用任何如PHP腳本來獲取各種有關數據庫服務器的重要信息。
序列是一組整數如1,2,3,...為了在需要時生成的。數據庫中序列是常用的,因為很多應用都需要在表的每行中,包含一個唯一的值,並且序列提供了一種簡單的方法來生成它們。本章將介紹如何在MySQL中使用序列。
在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)
LAST_INSERT_ID( )是一個SQL函數,這樣可以了解如何發出SQL語句,從任何客戶端中使用它。 以其他方式,Perl 和 PHP 腳本提供了獨有的函數來獲取最後一條記錄的自動遞增值。
表或結果集有時含有重復記錄。有時,它是允許的,但有時它被要求停止使用重復記錄。有時,需要識別重復記錄並從表中刪除它們。本章將介紹如何防止在一個表中,以及如何刪除已有的重復記錄。
可以使用適當表字段的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);
如果通過網頁需要用戶輸入一些數據信息,並將其插入到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,它們會樂意地進行堆查詢,執行一個字符串提供的查詢,並創建一個嚴重的安全問題。
可以在腳本語言,如 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困境,自定義的轉義機制必須把用戶提供%和_字符到常量。使用addcslashes()函數,它可以讓指定的字符范圍轉義。
$sub = addcslashes(mysql_real_escape_string("%something_"), "%_"); // $sub == \%something\_ mysql_query("SELECT * FROM messages WHERE subject LIKE '{$sub}%'");
導出表數據到一個文本文件的最簡單方法是使用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格式的表導出到一個文件,使用這樣的命令:
$ 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服務器。