MySQL教程 | 菜鳥教程


裝數據庫失敗后的重裝步驟!!!

 

--【創建數據庫】
CREATE DATABASE <數據庫名>;

--使用mysqladamin 創建數據庫
-- 使用普通用戶,你可能需要特定的權限來創建或者刪除MySQL數據庫。
-- 所以我們這邊使用用戶登陸,root用戶擁有最高權限,可以使用mysql mysqladmin 命令來創建數據庫。
-- 以下命令簡單的演示了創建數據庫的過程,數據名為RUNOOB:
[root@host]# mysqladmin -u root -p create RUNOOB
Enter password:******
--以上命令執行成功后會創建MySQL數據庫RUNOOB.

--【刪除數據庫】
DROP DATABASE <數據庫名>;

--使用mysqladmin命令在東段來執行刪除命令。
-- 以下時上面創建的數據庫
[root@host]# mysqladmin -u root -p drop RUNOOB
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 'RUNOOB' database [y/N] y
--Database "RUNOOB" dropped

--【MySQL 選擇數據庫】
[root@host]# mysql -u root -p
Enter password:******
mysql> use RUNOOB;
Database changed
mysql>

--執行以上命令后,你就已經成功選擇了 RUNOOB 數據庫,在后續的操作中都會在 RUNOOB 數據庫中執行。

--【注意】:所有的數據庫名,表名,表字段都是區分大小寫的。所以你在使用SQL命令時需要輸入正確的名稱。


--【MySQL 數據類型】
--MySQL支持多種類型,大致可以分為三類:數值、日期/時間和字符串(字符)類型。
--[數據類型]

--[日期/時間類型]

--[字符串(字符)類型]


--【MySQL創建數據表】
--創建MySQL數據表需要以下信息:
-- ·表名
-- ·表字段名
-- ·定義每個表字段
CREATE TABLE TABLE_name(column_name column_type);
--舉例
CREATE TABLE IF NOT EXISTS 'runoob_tbl'(
'runoob_id' INT UNSIGNED AUTO_INCREMENT,
'runoob_title' VARCHAR(100) NOT NULL,
'runoob_author' VARCHAR(40) NOT NULL,
'submission_date' DATE,
PRIMARY KEY ('runoob_id')
)ENGINE=InnoDB DEFAULT CHARSET=UTF8;
--實例解析:
-- ·如果你不想字段為 NULL 可以設置字段的屬性為 NOT NULL, 在操作數據庫時如果輸入該字段的數據為NULL ,就會報錯。
-- ·AUTO_INCREMENT定義列為自增的屬性,一般用於主鍵,數值會自動加1。
-- ·PRIMARY KEY關鍵字用於定義列為主鍵。 您可以使用多列來定義主鍵,列間以逗號分隔。
-- ·ENGINE 設置存儲引擎,CHARSET 設置編碼。


--【MySQL 刪除數據表】
DROP TABLE table_name;
--DROP TABLE runoob_tbl;

--執行成功后,我們使用以下命令,就看不到 runoob_tbl 表了:
mysql> show tables;
Empty set (0.01 sec)

 

--【MySQL插入數據】

--語法:
INSERT INTO table_name(field1,field2, ···fieldN)
VALUES
(value1, value2, ···valueN);
--[注意]如果數據是字符型,必須使用SQL INSERT INTO 語句向MySQL數據表runoob_tbl

--實例
root@host# mysql -u root -p password;
Enter password:*******
mysql> use RUNOOB;
Database changed
mysql> INSERT INTO runoob_tbl
-> (runoob_title, runoob_author, submission_date)
-> VALUES
-> ("學習 PHP", "菜鳥教程", NOW());
Query OK, 1 rows affected, 1 warnings (0.01 sec)
mysql> INSERT INTO runoob_tbl
-> (runoob_title, runoob_author, submission_date)
-> VALUES
-> ("學習 MySQL", "菜鳥教程", NOW());
Query OK, 1 rows affected, 1 warnings (0.01 sec)
mysql> INSERT INTO runoob_tbl
-> (runoob_title, runoob_author, submission_date)
-> VALUES
-> ("JAVA 教程", "RUNOOB.COM", '2016-05-06');
Query OK, 1 rows affected (0.00 sec)
mysql>
--讀取語句表
SELECT * FROM runoob_tbl;


--【MySQL查詢數據】
--語法
SELECT column_name, column_name
FROM table_name
[WHERE Clause]
[LIMIT N][OFFSET M]

--SELECT 命令可以讀取一條或者多條記錄
--WHERE 語句來包含任何條件。
--LIMIT 屬性來設定返回的記錄數。
--OFFSET指定SELECT語句開始查詢的數據偏移量,默認情況下偏移量為0。

--【MySQL WHERE子句】
--語法
SELECT field1, field2, ···fieldN FROM table_name1, table_name2···
[WHERE condition1] [AND [OR]] condition2·····
--可以在WHERE 子句中指定任何條件。
--可以使用AND或者OR指定一個或多個條件。
--WHERE子句也可以運用於SQL的DELETE或者UPDATE命令

--SQL SELECT WHERE 子句
SELECT * FROM runoob_tbl WHERE runoob_author='菜鳥教程';

--MySQL 的 WHERE 子句的字符串比較是不區分大小寫的。
-- 你可以使用 BINARY 關鍵字來設定 WHERE 子句的字符串比較是區分大小寫的。
--BINARY關鍵字
mysql> SELECT * from runoob_tbl WHERE BINARY runoob_author='runoob.com';
Empty set (0.01 sec)


mysql> SELECT * from runoob_tbl WHERE BINARY runoob_author='RUNOOB.COM';
+-----------+---------------+---------------+-----------------+
| runoob_id | runoob_title | runoob_author | submission_date |
+-----------+---------------+---------------+-----------------+
| 3 | JAVA 教程 | RUNOOB.COM | 2016-05-06 |
| 4 | 學習 Python | RUNOOB.COM | 2016-03-06 |
+-----------+---------------+---------------+-----------------+
2 rows in set (0.01 sec)


--【MySQL UPDATE 更新】
--語法
UPDATE table_name SET field1=new-value1, field2=new-value2
[WHERE Clause]
-- ·更新一個或多個字段
-- ·在WHERE子句中指定任何條件
-- ·在一個單獨表中同時更新數據

--實例
mysql> UPDATE runoob_tbl SET runoob_title='學習 C++' WHERE runoob_id=3;
Query OK, 1 rows affected (0.01 sec)

mysql> SELECT * from runoob_tbl WHERE runoob_id=3;
+-----------+--------------+---------------+-----------------+
| runoob_id | runoob_title | runoob_author | submission_date |
+-----------+--------------+---------------+-----------------+
| 3 | 學習 C++ | RUNOOB.COM | 2016-05-06 |
+-----------+--------------+---------------+-----------------+
1 rows in set (0.01 sec)


--【MySQL DELETE 語句】
--語法
DELETE FROM table_name [WHERE Clause]
-- ·如果沒有指定WHERE子句,MySQL表中的所有記錄將被刪除
-- ·可以在單個表中一次性刪除記錄

--實例
mysql> use RUNOOB;
Database changed
mysql> DELETE FROM runoob_tbl WHERE runoob_id=3;
Query OK, 1 row affected (0.23 sec)


--【MySQL LIKE子句】
--語法
SELECT field1, filed2, field3,···fieldN
FROM table_name
WHERE field1 LIKE condition1 [AND [OR]] field2 = 'somevalue'
--如果沒有使用%,LIKE子句與=的效果是一樣的。
--LIKE 通常和%一同使用,類似一個元字符的搜索
--可以在DELETE或UPDATE命令中使用WHERE···子句來指定條件

--實例
mysql> use RUNOOB;
Database changed
mysql> SELECT * from runoob_tbl WHERE runoob_author LIKE '%COM';
+-----------+---------------+---------------+-----------------+
| runoob_id | runoob_title | runoob_author | submission_date |
+-----------+---------------+---------------+-----------------+
| 3 | 學習 Java | RUNOOB.COM | 2015-05-01 |
| 4 | 學習 Python | RUNOOB.COM | 2016-03-06 |
+-----------+---------------+---------------+-----------------+
2 rows in set (0.01 sec)


--【MySQL UNION操作符】
--描述
--MySQL UNION操作符用於連接兩個以上的SELECT語句的結果組合到一個結果集合中,多個SELECT語句會刪除重復的數據。
--語法
SELECT expression1, expression2, ···expression_n
FROM tables
[WHERE conditions]
UNION [ALL | DISTINCT]
SELECT expression1, expression2, ···expression_n
FROM tables
[WHERE conditions];

--DISTINCT:可選,刪除結果集中重復的數據。默認情況下UNION操作符已經刪除了重復數據,所以
--DISTINCT修飾符對結果沒啥影響。
--ALL:可選,返回所有結果集,包含重復數據。

--演示數據庫
--Websites
mysql> SELECT * FROM Websites;
+----+--------------+---------------------------+-------+---------+
| id | name | url | alexa | country |
+----+--------------+---------------------------+-------+---------+
| 1 | Google | https://www.google.cm/ | 1 | USA |
| 2 | 淘寶 | https://www.taobao.com/ | 13 | CN |
| 3 | 菜鳥教程 | http://www.runoob.com/ | 4689 | CN |
| 4 | 微博 | http://weibo.com/ | 20 | CN |
| 5 | Facebook | https://www.facebook.com/ | 3 | USA |
| 7 | stackoverflow | http://stackoverflow.com/ | 0 | IND |
+----+---------------+---------------------------+-------+---------+
--apps APP
mysql> SELECT * FROM apps;
+----+------------+-------------------------+---------+
| id | app_name | url | country |
+----+------------+-------------------------+---------+
| 1 | QQ APP | http://im.qq.com/ | CN |
| 2 | 微博 APP | http://weibo.com/ | CN |
| 3 | 淘寶 APP | https://www.taobao.com/ | CN |
+----+------------+-------------------------+---------+
3 rows in set (0.00 sec)

--綜合以上兩個表,SQL UNION實例 選取不同的country
SELECT country FROM Websites
UNION
SELECT country FROM apps
ORDER BY country;
--UNION不能用於列出兩個表中所有的country。如果一些網站和APP來自同一個國家,每個國家指揮列出一次。
--UNION只會選取不容的值。請使用UNION ALL來選取重復的值!
--SQL UNION ALL實例
SELETE country FROM Websites
UNION ALL
SELETE country FROM apps
ORDER BY country;

--帶有WHERE的SQL UNION ALL
--下面SQL語句使用UNION ALL從“Websites”和"apps"表中選取所有的中國的數據(也有重復的值):
--實例
SELECT country, name FROM Websites
WHERE country='CN'
UNION ALL
SELECT country, app_name FROM apps
WHERE country='CN'
ORDER BY country;


--【MySQL排序】
--我們知道從 MySQL 表中使用 SQL SELECT 語句來讀取數據。
--語法
SELECT field1,field2,···fieldN FROM table_name1, table_name2···
ORDER BY field1 [ASC [DESC]],[field2···] [ASC [DESC]]
-- ·可以使用任何字段作為排序的條件,從而返回排序后的查詢結果。
-- ·可以設定多個字段來排序。
-- ·可以使用ASC或DESC關鍵字來設置查詢結果是按升序或降序排列。默認情況下,它是按升序[ASC]排列。

--在命令提示符中使用ORDER BY子句
--實例
--[ASC] 升序
mysql> use RUNOOB;
Database changed
mysql> SELECT * from runoob_tbl ORDER BY submission_date ASC;
+-----------+---------------+---------------+-----------------+
| runoob_id | runoob_title | runoob_author | submission_date |
+-----------+---------------+---------------+-----------------+
| 3 | 學習 Java | RUNOOB.COM | 2015-05-01 |
| 4 | 學習 Python | RUNOOB.COM | 2016-03-06 |
| 1 | 學習 PHP | 菜鳥教程 | 2017-04-12 |
| 2 | 學習 MySQL | 菜鳥教程 | 2017-04-12 |
+-----------+---------------+---------------+-----------------+
4 rows in set (0.01 sec)
--[DESC] 降序
mysql> SELECT * from runoob_tbl ORDER BY submission_date DESC;
+-----------+---------------+---------------+-----------------+
| runoob_id | runoob_title | runoob_author | submission_date |
+-----------+---------------+---------------+-----------------+
| 1 | 學習 PHP | 菜鳥教程 | 2017-04-12 |
| 2 | 學習 MySQL | 菜鳥教程 | 2017-04-12 |
| 4 | 學習 Python | RUNOOB.COM | 2016-03-06 |
| 3 | 學習 Java | RUNOOB.COM | 2015-05-01 |
+-----------+---------------+---------------+-----------------+
4 rows in set (0.01 sec)

--解讀以上:讀取 runoob_tbl 表中所有數據並按 submission_date 字段的升序排列。


--【MySQL GROUP BY】語句
--GROUP BY 語句根據一個或多個列對結果集進行分組
--在分組的列上我們使用COUNT, SUM,AVG,等函數

--語法
SELECT column_name, function(column_name)
FROM table_name
WHERE column_name operator value
GROUP BY column_name;

mysql> SELECT name, COUNT(*) FROM employee_tbl GROUP BY name;

--使用WITH ROLLUP
--WITH ROLLUP 可以實現在分組統計數據基礎上再進行相同的統計(SUM,AVG,COUNT…)。
mysql> SELECT name, SUM(singin) as singin_count FROM employee_tbl GROUP BY name WITH ROLLUP;
--其中記錄 NULL 表示所有人的登錄次數。
--我們可以使用 coalesce 來設置一個可以取代 NUll 的名稱,coalesce 語法:
select coalesce(a,b,c);
--參數說明:如果a==null,則選擇b;如果b==null,則選擇c;如果a!=null,則選擇a;如果a b c 都為null ,則返回為null(沒意義)。
mysql> SELECT coalesce(name, '總數'), SUM(singin) as singin_count FROM employee_tbl GROUP BY name WITH ROLLUP;

 

--MySQL 連接的使用
--作用是從不同的數據表中讀取數據 JOIN
--JOIN 可以使用在SELECT UPDATE DELETE 語句中使用,聯合多表查詢
--JOIN 的功能大致分成三類:
-- INNER JOIN(內連接,或等值連接):獲取兩個表中字段匹配關系的記錄。
-- LEFT JOIN(左連接):獲取左表所有記錄,即使右表沒有對應匹配的記錄。
-- RIGHT JOIN(右連接):與LEFT JOIN相反,用於獲取右表所有記錄,即使左表沒有對應匹配的記錄。

--INNER JOIN
--以RUNOOB數據庫中有兩張表tocunt_tbl和runoob_tbl。
--實例
mysql> use RUNOOB;
Database changed
mysql> SELECT * FROM tcount_tbl;
+---------------+--------------+
| runoob_author | runoob_count |
+---------------+--------------+
| 菜鳥教程 | 10 |
| RUNOOB.COM | 20 |
| Google | 22 |
+---------------+--------------+
3 rows in set (0.01 sec)

mysql> SELECT * from runoob_tbl;
+-----------+---------------+---------------+-----------------+
| runoob_id | runoob_title | runoob_author | submission_date |
+-----------+---------------+---------------+-----------------+
| 1 | 學習 PHP | 菜鳥教程 | 2017-04-12 |
| 2 | 學習 MySQL | 菜鳥教程 | 2017-04-12 |
| 3 | 學習 Java | RUNOOB.COM | 2015-05-01 |
| 4 | 學習 Python | RUNOOB.COM | 2016-03-06 |
| 5 | 學習 C | FK | 2017-04-05 |
+-----------+---------------+---------------+-----------------+
5 rows in set (0.01 sec)
--使用INNER JOIN(可以省略INNER使用JOIN,效果一樣)來連接上面兩張表來讀取
--runoob_tbl表中所有的runoob_author字段在tcount_tbl表對應的runoob_count字段值:
--INNER JOIN
mysql> SELECT a.runoob_id, a.runoob_author, b.runoob_count FROM runoob_tbl a INNER JOIN tcount_tbl b ON a.runoob_author = b.runoob_author;
+-------------+-----------------+----------------+
| a.runoob_id | a.runoob_author | b.runoob_count |
+-------------+-----------------+----------------+
| 1 | 菜鳥教程 | 10 |
| 2 | 菜鳥教程 | 10 |
| 3 | RUNOOB.COM | 20 |
| 4 | RUNOOB.COM | 20 |
+-------------+-----------------+----------------+
4 rows in set (0.00 sec)
--等價於
--WHERE子句
mysql> SELECT a.runoob_id, a.runoob_author, b.runoob_count FROM runoob_tbl a, tcount_tbl b WHERE a.runoob_author = b.runoob_author;
+-------------+-----------------+----------------+
| a.runoob_id | a.runoob_author | b.runoob_count |
+-------------+-----------------+----------------+
| 1 | 菜鳥教程 | 10 |
| 2 | 菜鳥教程 | 10 |
| 3 | RUNOOB.COM | 20 |
| 4 | RUNOOB.COM | 20 |
+-------------+-----------------+----------------+
4 rows in set (0.01 sec)

--LEFT JOIN,和 JOIN 不同,前者會讀取左邊數據表的全部數據,即使右邊表無對應的數據
--實例 以 runoob_tbl 為左表,tcount_tbl 為右表
--LEFT JOIN
mysql> SELECT a.runoob_id, a.runoob_author, b.runoob_count FROM runoob_tbl a LEFT JOIN tcount_tbl b ON a.runoob_author = b.runoob_author;
+-------------+-----------------+----------------+
| a.runoob_id | a.runoob_author | b.runoob_count |
+-------------+-----------------+----------------+
| 1 | 菜鳥教程 | 10 |
| 2 | 菜鳥教程 | 10 |
| 3 | RUNOOB.COM | 20 |
| 4 | RUNOOB.COM | 20 |
| 5 | FK | NULL |
+-------------+-----------------+----------------+
5 rows in set (0.01 sec)
--以上實例中使用了 LEFT JOIN,該語句會讀取左邊的數據表 runoob_tbl 的所有選取的字段數據,即便在右側表 tcount_tbl中 沒有對應的 runoob_author 字段值。
--RIGHT JOIN 會讀取右邊數據表的全部數據,即便左邊邊表無對應數據。
--實例以 runoob_tbl 為左表,tcount_tbl 為右表
--RIGHT JOIN
mysql> SELECT a.runoob_id, a.runoob_author, b.runoob_count FROM runoob_tbl a RIGHT JOIN tcount_tbl b ON a.runoob_author = b.runoob_author;
+-------------+-----------------+----------------+
| a.runoob_id | a.runoob_author | b.runoob_count |
+-------------+-----------------+----------------+
| 1 | 菜鳥教程 | 10 |
| 2 | 菜鳥教程 | 10 |
| 3 | RUNOOB.COM | 20 |
| 4 | RUNOOB.COM | 20 |
| NULL | NULL | 22 |
+-------------+-----------------+----------------+
5 rows in set (0.01 sec)
--以上實例中使用了 RIGHT JOIN,該語句會讀取右邊的數據表 tcount_tbl 的所有選取的字段數據,即便在左側表 runoob_tbl 中沒有對應的runoob_author 字段值。


--【MySQL NULL值處理】
--為了避免出現當提供查詢的數據表中的查詢條件為NULL時,該命令可能無法正常工作:
--因此:
-- ·IS NULL:當列的值是 NULL,此運算符返回 true。
-- ·IS NOT NULL: 當列的值不為 NULL, 運算符返回 true。
-- ·<=>: 比較操作符(不同於 = 運算符),當比較的的兩個值相等或者都為 NULL 時返回 true。
--關於 NULL 的條件比較運算是比較特殊的。你不能使用 = NULL 或 != NULL 在列中查找 NULL 值 。
--在 MySQL 中,NULL 值與任何其它值的比較(即使是 NULL)永遠返回 NULL,即 NULL = NULL 返回 NULL 。
--MySQL 中處理 NULL 使用 IS NULL 和 IS NOT NULL 運算符。

--[注意]
--select * , columnName1+ifnull(columnName2,0) from tableName;
--columnName1,columnName2 為 int 型,當 columnName2 中,有值為 null 時,columnName1+columnName2=null, ifnull(columnName2,0) 把 columnName2 中 null 值轉為 0。

-在命令提示符中使用NULL值
--以下實例中假設數據庫 RUNOOB 中的表 runoob_test_tbl 含有兩列 runoob_author 和 runoob_count, runoob_count 中設置插入NULL值。
--實例:
--創建數據表runoob_test_tbl
root@host# mysql -u root -p password;
Enter password:*******
mysql> use RUNOOB;
Database changed
mysql> create table runoob_test_tbl
-> (
-> runoob_author varchar(40) NOT NULL,
-> runoob_count INT
-> );
Query OK, 0 rows affected (0.05 sec)
mysql> INSERT INTO runoob_test_tbl (runoob_author, runoob_count) values ('RUNOOB', 20);
mysql> INSERT INTO runoob_test_tbl (runoob_author, runoob_count) values ('菜鳥教程', NULL);
mysql> INSERT INTO runoob_test_tbl (runoob_author, runoob_count) values ('Google', NULL);
mysql> INSERT INTO runoob_test_tbl (runoob_author, runoob_count) values ('FK', 20);

mysql> SELECT * from runoob_test_tbl;
+---------------+--------------+
| runoob_author | runoob_count |
+---------------+--------------+
| RUNOOB | 20 |
| 菜鳥教程 | NULL |
| Google | NULL |
| FK | 20 |
+---------------+--------------+
4 rows in set (0.01 sec)

--以下實例中你可以看到 = 和 != 運算符是不起作用的:
mysql> SELECT * FROM runoob_test_tbl WHERE runoob_count = NULL;
Empty set (0.00 sec)
mysql> SELECT * FROM runoob_test_tbl WHERE runoob_count != NULL;
Empty set (0.01 sec)

--查找數據表中 runoob_test_tbl 列是否為 NULL,必須使用 IS NULL 和 IS NOT NULL,如下實例:
mysql> SELECT * FROM runoob_test_tbl WHERE runoob_count IS NULL;
+---------------+--------------+
| runoob_author | runoob_count |
+---------------+--------------+
| 菜鳥教程 | NULL |
| Google | NULL |
+---------------+--------------+
2 rows in set (0.01 sec)

mysql> SELECT * from runoob_test_tbl WHERE runoob_count IS NOT NULL;
+---------------+--------------+
| runoob_author | runoob_count |
+---------------+--------------+
| RUNOOB | 20 |
| FK | 20 |
+---------------+--------------+
2 rows in set (0.01 sec)


--【MySQL 正則表達式】?
--MySQL中使用REGEXP操作符來進行正則表達式匹配


--【MySQL事務】
--主要處理操作量大,復雜度高的數據
-- ·在MySQL中只有使用了lnnodb數據庫引擎的數據庫或表才支持事務
-- ·事務處理可以用來維護數據庫的完整性,保證成批的 SQL 語句要么全部執行,要么全部不執行。
-- ·事務用來管理 insert,update,delete 語句、
--一般來說,事務是必須滿足4個條件(ACID)::原子性(Atomicity,或稱不可分割性)、一致性(Consistency)、隔離性(Isolation,又稱獨立性)、持久性(Durability)。
-- ·原子性:一個事務(transaction)中的所有操作,要么全部完成,要么全部不完成,不會結束在中間某個環節。事務在執行過程中發生錯誤,會被回滾(Rollback)到事務開始前的狀態,就像這個事務從來沒有執行過一樣。
-- ·一致性:在事務開始之前和事務結束以后,數據庫的完整性沒有被破壞。這表示寫入的資料必須完全符合所有的預設規則,這包含資料的精確度、串聯性以及后續數據庫可以自發性地完成預定的工作。、
-- ·隔離性:數據庫允許多個並發事務同時對其數據進行讀寫和修改的能力,隔離性可以防止多個事務並發執行時由於交叉執行而導致數據的不一致。事務隔離分為不同級別,包括讀未提交(Read uncommitted)、讀提交(read committed)、可重復讀(repeatable read)和串行化(Serializable)。
-- ·持久性:事務處理結束后,對數據的修改就是永久的,即便系統故障也不會丟失。
--*在 MySQL 命令行的默認設置下,事務都是自動提交的,即執行 SQL 語句后就會馬上執行 COMMIT 操作。
--*因此要顯式地開啟一個事務務須使用命令 BEGIN 或 START TRANSACTION,或者執行命令 SET AUTOCOMMIT=0,
--*用來禁止使用當前會話的自動提交。

--事務控制語句
-- BEGIN 或 START TRANSACTION 顯式地開啟一個事務;
-- COMMIT 也可以使用 COMMIT WORK,不過二者是等價的。
-- COMMIT 會提交事務,並使已對數據庫進行的所有修改成為永久性的;
-- ROLLBACK 也可以使用 ROLLBACK WORK,不過二者是等價的。
-- 回滾會結束用戶的事務,並撤銷正在進行的所有未提交的修改;
-- SAVEPOINT identifier,SAVEPOINT 允許在事務中創建一個保存點,一個事務中可以有多個 SAVEPOINT;
-- RELEASE SAVEPOINT identifier 刪除一個事務的保存點,當沒有指定的保存點時,執行該語句會拋出一個異常;
-- ROLLBACK TO identifier 把事務回滾到標記點;
-- SET TRANSACTION 用來設置事務的隔離級別。InnoDB 存儲引擎提供事務的隔離級別有READ UNCOMMITTED、READ COMMITTED、REPEATABLE READ 和 SERIALIZABLE。

--MySQL事務處理主要有兩種方法:
--1、用 BEGIN, ROLLBACK, COMMIT來實現
-- BEGIN 開始一個事務
-- ROLLBACK 事務回滾
-- COMMIT 事務確認
--2、直接用 SET 來改變 MySQL 的自動提交模式:
-- SET AUTOCOMMIT=0 禁止自動提交
-- SET AUTOCOMMIT=1 開啟自動提交

--事務測試
mysql> use RUNOOB;
Database changed
mysql> CREATE TABLE runoob_transaction_test( id int(5)) engine=innodb; # 創建數據表
Query OK, 0 rows affected (0.04 sec)

mysql> select * from runoob_transaction_test;
Empty set (0.01 sec)

mysql> begin; # 開始事務
Query OK, 0 rows affected (0.00 sec)

mysql> insert into runoob_transaction_test value(5);
Query OK, 1 rows affected (0.01 sec)

mysql> insert into runoob_transaction_test value(6);
Query OK, 1 rows affected (0.00 sec)

mysql> commit; # 提交事務
Query OK, 0 rows affected (0.01 sec)

mysql> select * from runoob_transaction_test;
+------+
| id |
+------+
| 5 |
| 6 |
+------+
2 rows in set (0.01 sec)

mysql> begin; # 開始事務
Query OK, 0 rows affected (0.00 sec)

mysql> insert into runoob_transaction_test values(7);
Query OK, 1 rows affected (0.00 sec)

mysql> rollback; # 回滾
Query OK, 0 rows affected (0.00 sec)

mysql> select * from runoob_transaction_test; # 因為回滾所以數據沒有插入
+------+
| id |
+------+
| 5 |
| 6 |
+------+
2 rows in set (0.01 sec)

mysql>


--【MySQL ALTER命令】
--當我們需要修改數據表名或者修改數據表字段時,就需要使用到MySQL ALTER命令。
--讓我們先創建一個表:testallter_tbl
root@host# mysql -u root -p password;
Enter password:*******
mysql> use RUNOOB;
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)
--刪除,添加或修改表字段
-- 如下命令使用了 ALTER 命令及 DROP 子句來刪除以上創建表的 i 字段:
mysql> ALTER TABLE testalter_tbl DROP i;
--如果數據表中只剩余一個字段則無法使用DROP來刪除字段。

--MySQL 中使用 ADD 子句來向數據表中添加列,如下實例在表 testalter_tbl 中添加 i 字段,並定義數據類型:
mysql> ALTER TABLE testalter_tbl ADD i INT;
--執行以上命令后,i 字段會自動添加到數據表字段的末尾。
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)
--如果需要指定新增字段的位置,則
--使用MySQL提供的關鍵字 FIRST (設定位第一列), AFTER 字段名(設定位於某個字段之后)。
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;
--嘗試以下 ALTER TABLE 語句, 在執行成功后,使用 SHOW COLUMNS 查看表結構的變化:
--FIRST 和 AFTER 關鍵字可用於 ADD 與 MODIFY 子句,所以如果你想重置數據表字段的位置就需要先使用 DROP 刪除字段然后使用 ADD 來添加字段並設置位置。

--修改字段類型及名稱
--如果需要修改字段類型及名稱, 你可以在ALTER命令中使用 MODIFY 或 CHANGE 子句 。
--例如,把字段 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;
mysql> ALTER TABLE testalter_tbl CHANGE j j INT;

--ALTER TABLE 對 Null 值和默認值的影響
--當你修改字段時,你可以指定是否包含值或者是否設置默認值。

--以下實例,指定字段 j 為 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)
Changing a Table Type:

--修改數據表類型,可以使用 ALTER 命令及 TYPE 子句來完成。嘗試以下實例,我們將表 testalter_tbl 的類型修改為 MYISAM :

--注意:查看數據表類型可以使用 SHOW TABLE STATUS 語句。
mysql> ALTER TABLE testalter_tbl ENGINE = 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: 2007-06-03 08:04:36
Update_time: 2007-06-03 08:04: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;


【MySQL索引】
--合理的設計且使用索引的MySQL是一輛蘭博基尼的話
--沒有設計和使用索引的MySQL就是一個人力三輪車。
--單列索引,組合索引
-- ·單列索引,索引只包含單個列,一個表可以有多個單列索引,但這不是組合索引
-- ·組合索引,一個索引包含多個列。
--索引的缺點
-- ·索引提高了查詢速度,但是同時也降低了更新表的速度
-- ·因為更新表時,MySQL不僅要保存數據,還要保存一下索引文件
-- ·建立索引會占用磁盤空間的索引文件

--普通索引
-- ·創建索引
--這是最基本的索引,它沒有任何限制。它有以下幾種創建方式:
CREATE INDEX indexName ON table_name (column_name)
--如果是CHAR,VARCHAR類型,length可以小於字段實際長度;如果是BLOB和TEXT類型,必須指定 length。

-- ·修改表結構(添加索引)
ALTER table tableName ADD INDEX indexName(columnName)
-- ·創建表的時候直接指定
CREATE TABLE mytable(

ID INT NOT NULL,

username VARCHAR(16) NOT NULL,

INDEX [indexName] (username(length))

);
-- ·刪除索引的語法
DROP INDEX [indexName] ON mytable;
-- ·唯一索引
--它與前面的普通索引類似,不同的就是:索引列的值必須唯一,但允許有空值。如果是組合索引,則列值的組合必須唯一。
-- ·創建索引
CREATE UNIQUE INDEX indexName ON mytable(username(length))
-- ·修改表結構
ALTER table mytable ADD UNIQUE [indexName] (username(length))
-- ·創建表的時候直接指定
CREATE TABLE mytable(

ID INT NOT NULL,

username VARCHAR(16) NOT NULL,

UNIQUE [indexName] (username(length))

);

--使用ALTER 命令添加和刪除索引(四種方式)
-- ·ALTER TABLE tbl_name ADD PRIMARY KEY (column_list): 該語句添加一個主鍵,這意味着索引值必須是唯一的,且不能為NULL。
-- ·ALTER TABLE tbl_name ADD UNIQUE index_name (column_list): 這條語句創建索引的值必須是唯一的(除了NULL外,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 命令添加和刪除主鍵
-- ·主鍵作用於列上(可以一個列或多個列聯合主鍵),添加主鍵索引時,你需要確保該主鍵默認不為空(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;
-- ·刪除主鍵時只需指定PRIMARY KEY,但在刪除索引時,你必須知道索引名。
--顯示索引信息
--你可以使用 SHOW INDEX 命令來列出表中的相關的索引信息。可以通過添加 \G 來格式化輸出信息。

--嘗試以下實例:
mysql> SHOW INDEX FROM table_name; \G


--【MySQL 臨時表】
--臨時表只是在但錢連接可見,當關閉連接時,Mysql會自動刪除表並釋放所有空間
--臨時表在MySQL 3.23版本中添加,如果你的MySQL版本低於 3.23版本就無法使用MySQL的臨時表。不過現在一般很少有再使用這么低版本的MySQL數據庫服務了。
--MySQL臨時表只在當前連接可見,如果你使用PHP腳本來創建MySQL臨時表,那每當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)

--刪除MySQL臨時表
--默認情況下,當你斷開與數據庫的連接后,臨時表就會自動被銷毀。當然你也可以在當前MySQL會話使用 DROP TABLE 命令來手動刪除臨時表。
--以下是手動刪除臨時表的實例:
mysql> DROP TABLE SalesSummary;
mysql> SELECT * FROM SalesSummary;
ERROR 1146: Table 'RUNOOB.SalesSummary' doesn't exist


--【MySQL復制表】
--如何完整的復制MySQL數據表,步驟如下:
-- ·使用 SHOW CREATE TABLE 命令獲取創建數據表(CREATE TABLE) 語句,該語句包含了原數據表的結構,索引等。
-- ·復制以下命令顯示的SQL語句,修改數據表名,並執行SQL語句,通過以上命令 將完全的復制數據表結構。
-- ·如果你想復制表的內容,你就可以使用 INSERT INTO ... SELECT 語句來實現。
--實例
--步驟一:
-- 獲取數據表的完整結構
mysql> SHOW CREATE TABLE runoob_tbl \G;
*************************** 1. row ***************************
Table: runoob_tbl
Create Table: CREATE TABLE `runoob_tbl` (
`runoob_id` int(11) NOT NULL auto_increment,
`runoob_title` varchar(100) NOT NULL default '',
`runoob_author` varchar(40) NOT NULL default '',
`submission_date` date default NULL,
PRIMARY KEY (`runoob_id`),
UNIQUE KEY `AUTHOR_INDEX` (`runoob_author`)
) ENGINE=InnoDB
1 row in set (0.00 sec)

ERROR:
No query specified
--步驟二:
-- 修改SQL語句的數據表名,並執行SQL語句。
mysql> CREATE TABLE `clone_tbl` (
-> `runoob_id` int(11) NOT NULL auto_increment,
-> `runoob_title` varchar(100) NOT NULL default '',
-> `runoob_author` varchar(40) NOT NULL default '',
-> `submission_date` date default NULL,
-> PRIMARY KEY (`runoob_id`),
-> UNIQUE KEY `AUTHOR_INDEX` (`runoob_author`)
-> ) ENGINE=InnoDB;
Query OK, 0 rows affected (1.80 sec)
--步驟三:
-- 執行完第二步驟后,你將在數據庫中創建新的克隆表 clone_tbl。 如果你想拷貝數據表的數據你可以使用 INSERT INTO... SELECT 語句來實現。
mysql> INSERT INTO clone_tbl (runoob_id,
-> runoob_title,
-> runoob_author,
-> submission_date)
-> SELECT runoob_id,runoob_title,
-> runoob_author,submission_date
-> FROM runoob_tbl;
Query OK, 3 rows affected (0.07 sec)
Records: 3 Duplicates: 0 Warnings: 0
--執行以上步驟后,就完整的復制表,包括表結構及表數據


--【MySQL 元數據】
--你可能想知道以下三種信息:
-- ·查詢結果信息: SELECT, UPDATE 或 DELETE語句影響的記錄數。
-- ·數據庫和數據表的信息: 包含了數據庫及數據表的結構信息。
-- ·MySQL服務器信息: 包含了數據庫服務器的當前狀態,版本號等。
--那么就需要了元數據這個概念

--獲取查詢語句影響的記錄數
--PERL實例
-- 在DBI腳本中,語句影響的記錄數通過函數do()或execute()返回:
# 方法 1
# 使用do( ) 執行 $query
my $count = $dbh->do ($query);
# 如果發生錯誤會輸出 0
printf "%d 條數據被影響\n", (defined ($count) ? $count : 0);

# 方法 2
# 使用prepare( ) 及 execute( ) 執行 $query
my $sth = $dbh->prepare ($query);
my $count = $sth->execute ( );
printf "%d 條數據被影響\n", (defined ($count) ? $count : 0);

--獲取服務器元數據
-- 以下命令語句可以在MySQL的命令提示符使用,也可以在腳本中使用
SELECT VERSION( ) 服務器版本信息
SELECT DATABASE( ) 當前數據庫名 (或者返回空)
SELECT USER( ) 當前用戶名
SHOW STATUS 服務器狀態
SHOW VARIABLES 服務器配置變量


--【MySQL序列使用】
--MySQL 序列是一組整數:1, 2, 3, ...,
--由於一張數據表只能有一個字段自增主鍵, 如果你想實現其他字段也實現自動增加,就可以使用MySQL序列來實現。

--使用AUTO_INCREMENT
-- MySQL中最簡單使用序列的方法就是使用MySQL AUTO_INCREMENT來定義列
--實例
-- 以下實例中創建了數據表insect, insect表中id無需指定值可實現自動增長
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','2001-09-10','kitchen'),
-> (NULL,'millipede','2001-09-10','driveway'),
-> (NULL,'grasshopper','2001-09-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 | 2001-09-10 | kitchen |
| 2 | millipede | 2001-09-10 | driveway |
| 3 | grasshopper | 2001-09-10 | front yard |
+----+-------------+------------+------------+
3 rows in set (0.00 sec)

--獲取AUTO_INCREMENT值
--在MySQL的客戶端中你可以使用SQL中LAST_INSERT_ID()函數來獲取最后的插入表的自增列的值。
--在PHP或PERL腳本中也提供了相應的函數后來獲取最后的插入表中的自增列的值。

--PERL實例
--使用mysql_insertid 屬性來獲取AUTO_INCREMENT的值。示例如下:
$dbh->do ("INSERT INTO insect (name,date,origin)
VALUES('moth','2001-09-14','windowsill')");
my $seq = $dbh->{mysql_insertid};

--重置序列
-- 如果你刪除了數據表中多條記錄,並希望對剩下數據的AUTO_INCREMENT列進行重新排列,那么你可以通過刪除自增的列,
-- 然后重新添加來實現。不過操作要非常小心,如果在刪除的同時又有新紀錄添加,有可能會出現數據會亂。操作
-- 如下所示:
mysql> ALTER TABLE insect DROP id;
mysql> ALTER TABLE insect
-> ADD id INT UNSIGNED NOT NULL AUTO_INCREMENT FIRST,
-> ADD PRIMARY KEY (id);

--設置序列的開始值
-- 一般情況下序列的開始值為1,但如果你需要指定一個開始值100,那我們可以通過以下語句來實現:
mysql> CREATE TABLE insect
-> (
-> id INT UNSIGNED NOT NULL AUTO_INCREMENT,
-> PRIMARY KEY (id),
-> name VARCHAR(30) NOT NULL,
-> date DATE NOT NULL,
-> origin VARCHAR(30) NOT NULL
)engine=innodb auto_increment=100 charset=utf8;
-- 或者你也可以在表創建成功后,通過以下語句來實現:
mysql> ALTER TABLE t AUTO_INCREMENT = 100;


--【MySQL 處理重復數據】
--有些 MySQL 數據表中可能存在重復的記錄,有些情況我們允許重復數據的存在,但有時候我們也需要刪除這些重復的數據。
--防止表中出現重復數據
-- 你可以在 MySQL 數據表中設置指定的字段為 PRIMARY KEY(主鍵) 或者 UNIQUE(唯一) 索引來保證數據的唯一性。
-- 讓我們嘗試一個實例:下表中無索引及主鍵,所以該表允許出現多條重復記錄。
CREATE TABLE person_tbl
(
fiest_name CHAR(20),
last_name CHAR(20),
sex CHAR(10)
);
--如果你想設置表中字段 first_name,last_name 數據不能重復,
--你可以設置雙主鍵模式來設置數據的唯一性, 如果你設置了雙主鍵,那么那個鍵的默認值不能為 NULL,可設置為 NOT NULL。如下所示:
CREATE TABLE person_tal
(
first_name CHAR(2O) NOT NULL,
last_name CHAR(20) NOT NULL,
sex CHAR(10),
PRIMARY KEY (last_name, first_name)
);

--如果我們設置了唯一索引,那么在插入重復數據時,SQL 語句將無法執行成功,並拋出錯。
--
--INSERT IGNORE INTO 與 INSERT INTO 的區別就是 INSERT IGNORE INTO 會忽略數據庫中已經存在的數據,如果數據庫沒有數據,就插入新的數據,如果有數據的話就跳過這條數據。這樣就可以保留數據庫中已經存在數據,達到在間隙中插入數據的目的。
--
--以下實例使用了 INSERT IGNORE INTO,執行后不會出錯,也不會向數據表中插入重復數據:
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)

--INSERT IGNORE INTO 當插入數據時,在設置了記錄的唯一性后,如果插入重復數據,將不返回錯誤,只以警告形式返回。 而 REPLACE INTO 如果存在 primary 或 unique 相同的記錄,則先刪除掉。再插入新記錄。

--另一種設置數據的唯一性方法是添加一個 UNIQUE 索引,如下所示:
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;
-- 你也可以使用 GROUP BY 來讀取數據表中不重復的數據:
mysql> SELECT last_name, first_name
-> FROM person_tbl
-> GROUP BY (last_name, first_name);

--刪除重復數據
-- 如果你想刪除數據表中的重復數據,你可以使用以下的SQL語句:
mysql> CREATE TABLE tmp SELECT last_name, first_name, sex FROM person_tbl GROUP BY (last_name, first_name, sex);
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數據庫,那么就有可能發生SQL注入安全的問題。
--所謂SQL注入,就是通過把SQL命令插入到Web表單遞交或輸入域名或頁面請求的查詢字符串,最終達到欺騙服務器執行惡意的SQL命令。
--我們永遠不要信任用戶的輸入,我們必須認定用戶輸入的數據都是不安全的,我們都需要對用戶輸入的數據進行過濾處理。

--下實例中,輸入的用戶名必須為字母、數字及下划線的組合,且用戶名長度為 8 到 20 個字符之間:
if (preg_match("/^\w{8,20}$/", $_GET['username'], $matches))
{
$result = mysqli_query($conn, "SELECT * FROM users
WHERE username=$matches[0]");
}
else
{
echo "username 輸入異常";
}
--來讓我們看下在沒有過濾特殊字符時,出現的SQL的情況:
// 設定$name 中插入了我們不需要的SQL語句
$name = "Qadir'; DELETE FROM users;";
mysqli_query($conn, "SELECT * FROM users WHERE name='{$name}'");
--以上的注入語句中,我們沒有對 $name 的變量進行過濾,$name 中插入了我們不需要的SQL語句,將刪除 users 表中的所有數據。

--防止SQL注入

--Like語句中的注入
like查詢時,如果用戶輸入的值有"_"和"%",則會出現這種情況:用戶本來只是想查詢“accd_”,查詢結果中卻有“abcd_”、"accde"、 "accdf"等等;用戶要查詢“30%”(注:百分之三十)時也會出現問題。


--【MySQL導出數據】
--MySQL中你可以使用SELECT...INTO OUTFILE語句來簡單的導出數據到文本文件上。
--使用 SELECT ... INTO OUTFILE 語句導出數據
mysql> SELECT * FROM runoob_tbl
-> INTO OUTFILE '/tmp/runoob.txt';
--你可以通過命令選項來設置數據輸出的指定格式,以下實例為導出 CSV 格式:
ysql> SELECT * FROM passwd INTO OUTFILE '/tmp/runoob.txt'
-> FIELDS TERMINATED BY ',' ENCLOSED BY '"'
-> LINES TERMINATED BY '\r\n';
--在下面的例子中,生成一個文件,各值用逗號隔開。這種格式可以被許多程序使用。
SELECT a,b,a+b INTO OUTFILE '/tmp/result.text'
FIELDS TERMINATED BY ',' OPTIONALLY ENCLOSED BY '"'
LINES TERMINATED BY '\n'
FROM test_table;

--SELECT ... INTO OUTFILE 語句有以下屬性:
-- ·LOAD DATA INFILE是SELECT ... INTO OUTFILE的逆操作,SELECT句法。為了將一個數據庫的數據寫入一個文件,使用SELECT ... INTO OUTFILE,為了將文件讀回數據庫,使用LOAD DATA INFILE。
-- ·SELECT...INTO OUTFILE 'file_name'形式的SELECT可以把被選擇的行寫入一個文件中。該文件被創建到服務器主機上,因此您必須擁有FILE權限,才能使用此語法。
-- ·輸出不能是一個已存在的文件。防止文件數據被篡改。
-- ·你需要有一個登陸服務器的賬號來檢索文件。否則 SELECT ... INTO OUTFILE 不會起任何作用。
-- ·在UNIX中,該文件被創建后是可讀的,權限由MySQL服務器所擁有。這意味着,雖然你就可以讀取該文件,但可能無法將其刪除。

--導出表作為原始數據
-- ·sqldump 是 mysql 用於轉存儲數據庫的實用程序。它主要產生一個 SQL 腳本,其中包含從頭重新創建數據庫所必需的命令 CREATE TABLE INSERT 等。
-- ·使用 mysqldump 導出數據需要使用 --tab 選項來指定導出文件指定的目錄,該目標必須是可寫的。
-- ·以下實例將數據表 runoob_tbl 導出到 /tmp 目錄中:
$ mysqldump -u root -p --no-create-info \
--tab=/tmp RUNOOB runoob_tbl
password ******

--導出 SQL 格式的數據
--導出 SQL 格式的數據到指定文件,如下所示:
$ mysqldump -u root -p RUNOOB runoob_tbl > dump.txt
password ******
--以上命令創建的文件內容如下:
-- MySQL dump 8.23
--
-- Host: localhost Database: RUNOOB
---------------------------------------------------------
-- Server version 3.23.58

--
-- Table structure for table `runoob_tbl`
--

CREATE TABLE runoob_tbl (
runoob_id int(11) NOT NULL auto_increment,
runoob_title varchar(100) NOT NULL default '',
runoob_author varchar(40) NOT NULL default '',
submission_date date default NULL,
PRIMARY KEY (runoob_id),
UNIQUE KEY AUTHOR_INDEX (runoob_author)
) TYPE=MyISAM;

--
-- Dumping data for table `runoob_tbl`
--

INSERT INTO runoob_tbl
VALUES (1,'Learn PHP','John Poul','2007-05-24');
INSERT INTO runoob_tbl
VALUES (2,'Learn MySQL','Abdul S','2007-05-24');
INSERT INTO runoob_tbl
VALUES (3,'JAVA Tutorial','Sanjay','2007-05-06');
--如果你需要導出整個數據庫的數據,可以使用以下命令:
$ mysqldump -u root -p RUNOOB > 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 *****
--如果完整備份數據庫,則無需使用特定的表名稱。
--如果你需要將備份的數據庫導入到MySQL服務器中,可以使用以下命令,使用以下命令你需要確認數據庫已經創建:
$ mysql -u root -p database_name < dump.txt
password *****
--你也可以使用以下命令將導出的數據直接導入到遠程的服務器上,但請確保兩台服務器是相通的,是可以相互訪問的:
$ mysqldump -u root -p database_name \
| mysql -h other-host.com database_name
--以上命令中使用了管道來將導出的數據導入到指定的遠程主機上。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM