1. 程式人生 > >MySQL 複習筆記

MySQL 複習筆記

-- ==================建庫刪庫===========================================

-- 顯示所有資料庫
SHOW DATABASES;

-- MySQL 建立資料庫
CREATE DATABASE RUNOOB;

-- MySql 刪除資料庫
-- drop database RUNOOB;

-- MySQL 選擇資料庫
USE RUNOOB;

/*
MySQL支援多種型別,大致可以分為三類:數值、日期/時間和字串(字元)型別

1.MySQL支援所有標準SQL數值資料型別。

這些型別包括嚴格數值資料型別(INTEGER、SMALLINT、DECIMAL和NUMERIC),
以及近似數值資料型別(FLOAT、REAL和DOUBLE PRECISION)。
關鍵字INT是INTEGER的同義詞,關鍵字DEC是DECIMAL的同義詞

2.日期和時間型別

表示時間值的日期和時間型別為DATETIME、DATE、TIMESTAMP、TIME和YEAR。
每個時間型別有一個有效值範圍和一個"零"值,當指定不合法的MySQL不能表示的值時使用"零"值

3.字串型別

字串型別指CHAR、VARCHAR、BINARY、VARBINARY、BLOB、TEXT、ENUM和SET
*/

-- ======================建表刪表==================================================================================

-- MySQL 建立資料表
CREATE TABLE IF NOT EXISTS `runoob_tb`(
  `runoob_id` INT UNSIGNED AUTO_INCREMENT, 
  -- AUTO_INCREMENT定義列為自增的屬性,一般用於主鍵,數值會自動加1
  
  `runoob_title` VARCHAR(100) NOT NULL,
  `runoob_author` VARCHAR(40) NOT NULL,
  `submission_date` DATE,
  PRIMARY KEY(`runoob_id`)
  -- PRIMARY KEY關鍵字用於定義列為主鍵。 您可以使用多列來定義主鍵,列間以逗號分隔
  )ENGINE=INNODB DEFAULT CHARSET=utf8;
  
  -- ENGINE 設定儲存引擎,CHARSET 設定編碼


-- MySQL 刪除資料表
-- drop table runoob_tb;

-- ================================增刪改查=========================================================
-- MySQL 插入資料
INSERT INTO runoob_tb
(runoob_title,runoob_author,submission_date)
VALUES
("學習PHP","菜鳥教程",NOW());

INSERT INTO runoob_tb
(runoob_title,runoob_author,submission_date)
VALUES
("學習mysql","菜鳥教程",NOW());

INSERT INTO runoob_tb
(runoob_title,runoob_author,submission_date)
VALUES
("學習java","菜鳥教程",NOW());

-- NOW() 是一個 MySQL 函式,該函式返回日期和時間

-- INSERT 插入多條資料
INSERT INTO runoob_tb
(runoob_title,runoob_author,submission_date)
VALUES
("學習python","菜鳥教程",NOW()),
("學習jsp","菜鳥教程",NOW()),
("學習c","菜鳥教程",NOW()),
("學習c++","菜鳥教程",NOW()),
("學習c#","菜鳥教程",NOW());

-- ---------------------------------------------------------------------------

-- MySQL 查詢資料

/*
mysql的 SELECT 語法:

SELECT column_name,column_name
FROM table_name
[WHERE Clause]
[LIMIT N][ OFFSET M]

select * : 返回所有記錄
 limit N : 返回 N 條記錄
 offset M : 跳過 M 條記錄, 預設 M=0, 單獨使用似乎不起作用
 limit N,M : 相當於 offset N limit M , 從第 N 條記錄開始, 返回 M 條記錄
 
查詢語句中你可以使用一個或者多個表,表之間使用逗號(,)分割,並使用WHERE語句來設定查詢條件。
SELECT 命令可以讀取一條或者多條記錄。
你可以使用星號(*)來代替其他欄位,SELECT語句會返回表的所有欄位資料
你可以使用 WHERE 語句來包含任何條件。
你可以使用 LIMIT 屬性來設定返回的記錄數。
你可以通過OFFSET指定SELECT語句開始查詢的資料偏移量。預設情況下偏移量為0

*/

-- 查詢所有資料(*表示所有列)
SELECT * FROM runoob_tb;

-- 返回前5條記錄
SELECT	* FROM runoob_tb LIMIT 5;
-- 從第1條記錄開始,返回5條記錄
SELECT * FROM runoob_tb LIMIT 0,5;
-- 以上這兩句話,效果相同

/*
一共8條記錄,要求分頁,每頁顯示3條
即8/3=2餘2
8%3=2

總記錄數totalRecord=8
每頁記錄數pageSize=3

求總頁數totalPageNum:

  總頁數=(8%3)+1=3    即每頁3條,可以分3頁顯示
int totalPageNum = (totalRecord % pageSize) + 1;

  總頁數=(8+3-1)/3=3  在java中 /相當於取整 ,%是取餘
int totalPageNum = (totalRecord + pageSize  - 1) / pageSize;

三目運算子,(判斷總記錄數是否能整除,不能整除則取整後加1)
totalPageNum=(totalRecord%pagesize==0)?totalRecord/pagesize:totalRecord/pagesize+1;


--------------
三目運算子:
  變數 = 表示式1 ? 表示式2 : 表示式3;
  
計算方法:  
  若 表示式1 為真,變數等於 表示式2
  若 表示式1 為假,變數等於 表示式3


------------------計算頁碼對應的記錄-------------------
第一頁頁碼begin=1                     1~3
第二頁頁碼                            4~6
第三頁頁碼(最末頁)end=3               7~8 (不足3條也要佔1頁)


上一頁頁碼last                        3n-6~3n-3
             
當前頁頁碼pageNow=2(假設為第二頁)     2*3=6,本頁最後的記錄為第6條記錄
當前頁頁碼pageNow=n                   n*3=3n,本頁最後的記錄為第3n條記錄
                                      即當前的記錄為3n-3 ~ 3n 

下一頁頁碼next                        3n+1~最後


----
總結:
要求分頁顯示,每頁顯示3條記錄
上一頁的頁碼last       對應的記錄為  3*pageNow-6 ~ 3*pageNow-3  (即LIMIT 0,3)

設當前頁頁碼為pageNow,對應的記錄為  3*pageNow-3 ~ 3*pageNow    (即LIMIT 3,3)

下一頁的頁碼next       對應的記錄為  3*pageNow   ~ 3*pageNow+3  (即LIMIT 6,3)




簡記:
第一條: select * from 表名 limit 1;
最後一條:select * from 表名 order by 表_id desc limit 1


*/

-- 查詢總記錄數
SELECT COUNT(*) FROM runoob_tb

-- 第一頁begin,對應第一條記錄 
SELECT * FROM runoob_tb LIMIT 1

-- 最末頁end,對應最後一條記錄
SELECT * FROM runoob_tb ORDER BY runoob_id DESC LIMIT 1

-- =========MySQL分頁法1=================================
-- 從第1條記錄開始,返回3條記錄(即1~3)
SELECT * FROM runoob_tb LIMIT 0,3;
-- 從第4條記錄開始,返回3條記錄(即4~6)
SELECT * FROM runoob_tb LIMIT 3,3;
-- 從第7條記錄開始,返回3條記錄(剩餘的不夠3條,就返回剩餘記錄)
SELECT * FROM runoob_tb LIMIT 6,3;


-- ========MySQL分頁法2==================================
-- 跳過0條記錄,返回3條記錄(即1~3)
SELECT * FROM runoob_tb LIMIT 3 OFFSET 0;
-- 跳過3條記錄,返回3條記錄(即4~6)
SELECT * FROM runoob_tb LIMIT 3 OFFSET 3;
-- 跳過6條記錄,返回3條記錄(剩餘的不夠3條,就返回剩餘記錄)
SELECT * FROM runoob_tb LIMIT 3 OFFSET 6;


-- *****************************************************************************************
/* 模糊查詢表資料 
LIKE 子句
語法
SELECT field1, field2,...fieldN 
FROM table_name
WHERE field1 LIKE condition1 [AND [OR]] filed2 = 'somevalue'

你可以在 WHERE 子句中指定任何條件。
你可以在 WHERE 子句中使用LIKE子句。
你可以使用LIKE子句代替等號 =。
LIKE 通常與 % 一同使用,類似於一個元字元的搜尋。
你可以使用 AND 或者 OR 指定一個或多個條件。
你可以在 DELETE 或 UPDATE 命令中使用 WHERE...LIKE 子句來指定條件

----------------------------------------------
like 模糊匹配,會與 % 和 _ 結合使用。

'%a'     //以a結尾的資料
'a%'     //以a開頭的資料
'%a%'    //含有a的資料
'_a_'    //三位且中間字母是a的
'_a'     //兩位且結尾字母是a的
'a_'     //兩位且開頭字母是a的

-----------------------------------------------
*/
-- 以p結尾的資料,%號表示任意長度的任意字元
SELECT * FROM runoob_tb WHERE runoob_title LIKE "%p";  
-- 以p開頭的資料,%號表示任意長度的任意字元
SELECT * FROM runoob_tb WHERE runoob_title LIKE "p%";  
-- 模糊查詢時不區分大小寫,所以能查出python和PHP


-- 以c開頭的資料,_下劃線表示1個長度的任意字元
SELECT * FROM runoob_tb WHERE runoob_title LIKE "c_";  

-- 以p結尾的資料,2個_下劃線表示2個長度的任意字元
SELECT * FROM runoob_tb WHERE runoob_title LIKE "__p"; 


-- 模糊查詢首字元任意,第二個字元為a,餘下為任意長度的任意字元
SELECT * FROM runoob_tb WHERE runoob_title LIKE "_a%"; 


-- *********************************************************************************
-- 查詢表字段資料 
SELECT runoob_title FROM runoob_tb;
/* 查詢表字段下where條件資料 */
SELECT * FROM runoob_tb WHERE runoob_title = "PHP";  

/*
MySQL WHERE 子句
語法
SELECT field1, field2,...fieldN FROM table_name1, table_name2...
[WHERE condition1 [AND [OR]] condition2.....

查詢語句中你可以使用一個或者多個表,表之間使用逗號, 分割,並使用WHERE語句來設定查詢條件。
你可以在 WHERE 子句中指定任何條件。
你可以使用 AND 或者 OR 指定一個或多個條件。
WHERE 子句也可以運用於 SQL 的 DELETE 或者 UPDATE 命令。
WHERE 子句類似於程式語言中的 if 條件,根據 MySQL 表中的欄位值來讀取指定的資料
------------------------------------------------------------------------------------------------
=	等號,檢測兩個值是否相等,如果相等返回true	(A = B) 返回false。

<>, !=	不等於,檢測兩個值是否相等,如果不相等返回true	(A != B) 返回 true。

>    大於號,檢測左邊的值是否大於右邊的值, 如果左邊的值大於右邊的值返回true	(A > B) 返回false。

<    小於號,檢測左邊的值是否小於右邊的值, 如果左邊的值小於右邊的值返回true	(A < B) 返回 true。

>=   大於等於號,檢測左邊的值是否大於或等於右邊的值, 如果左邊的值大於或等於右邊的值返回true	(A >= B) 返回false。

<=   小於等於號,檢測左邊的值是否小於於或等於右邊的值, 如果左邊的值小於或等於右邊的值返回true	(A <= B) 返回 true

------------------------------------------------------------------------------------------------------------------------

*/

SELECT * FROM runoob_tb;
SELECT * FROM runoob_tb WHERE runoob_author='菜鳥教程';
SELECT runoob_title FROM runoob_tb;

/* 查詢表下欄位範圍資料 */
SELECT * FROM runoob_tb WHERE runoob_id BETWEEN "2" AND "5";
/* 查詢去重值 */
SELECT DISTINCT runoob_author FROM runoob_tb;
/*查詢表下範圍條件資料*/
SELECT * FROM runoob_tb WHERE runoob_author="runoob" AND submission_date > "2018-11-02";
/* 查詢表下條件不同值 */
SELECT * FROM runoob_tb WHERE runoob_author="runoob" OR submission_date < "2018-11-05";

-- 按runoob_title升序排序
SELECT * FROM runoob_tb ORDER BY runoob_title;

-- 按runoob_title降序排序
SELECT * FROM runoob_tb ORDER BY runoob_title DESC;

-- 查詢前6條資料
SELECT * FROM runoob_tb LIMIT 6;

-- 查詢某一列的值,然後起別名
SELECT runoob_title AS "技術" FROM runoob_tb;



-- ===================================================================================
-- 查詢某個庫所有表
SELECT * FROM information_schema.`TABLES`
WHERE table_schema = 'runoob'

-- 查詢某個庫所有表的欄位
SELECT * FROM information_schema.COLUMNS
WHERE table_schema = 'runoob'

-- 查詢所有表的註釋和欄位註釋
SELECT
a.table_name 表名,
a.table_comment 表說明,
b.COLUMN_NAME 欄位名,
b.column_comment 欄位說明,
b.column_type 欄位型別,
b.column_key 約束
FROM
information_schema. TABLES a
LEFT JOIN information_schema. COLUMNS b ON a.table_name = b.TABLE_NAME
WHERE
a.table_schema = 'runoob'
ORDER BY
a.table_name


--  查詢某個資料庫中所有表名
SELECT table_name FROM information_schema.tables WHERE table_schema='runoob' AND table_type='base table';

-- 查詢指定資料庫中指定表的所有欄位名column_name
SELECT column_name FROM information_schema.columns WHERE table_schema='runoob' AND table_name='runoob_tb'


-- ========================================================================================================
-- -----------------------------------------------------------------



CREATE TABLE w3cschool_tb(
  id INT NOT NULL AUTO_INCREMENT,
  title VARCHAR(100) NOT NULL,
  author VARCHAR(40) NOT NULL,
  sub_date DATE,
  PRIMARY KEY (id)
);


INSERT INTO w3cschool_tb
(title, author, sub_date)
 VALUES
("Learn PHP", "John Poul", NOW());


INSERT INTO w3cschool_tb
(title, author, sub_date)
 VALUES
("Learn MySQL", "Abdul S", NOW()),
("JAVA Tutorial", "Sanjay", '2007-05-06');



-- ---------------------------------------------------------------------
-- UPDATE 更新
/*
語法
UPDATE table_name SET field1=new-value1, field2=new-value2
[WHERE Clause]
update 表名稱 set 列名稱=新值 where 更新條件;

你可以同時更新一個或多個欄位。
你可以在 WHERE 子句中指定任何條件

*/

UPDATE runoob_tb 
SET runoob_title = '學C++' 
WHERE runoob_id = 7;

SELECT * FROM runoob_tb WHERE runoob_id = 7;

-- --------------------------------------------------------------
/*
delete  刪除

語法
DELETE FROM table_name [WHERE Clause]

如果沒有指定 WHERE 子句,MySQL 表中的所有記錄將被刪除。
可以在 WHERE 子句中指定任何條件
可以在單個表中一次性刪除記錄

*/

-- 刪除 id 為 7 的行
DELETE FROM runoob_tb WHERE runoob_id = 7;

-- 刪除所有 `sex` != '男'的行
DELETE FROM USER WHERE user.`sex` != '男';


-- ======================================================================================
/*
MySQL UNION 操作符 (全連線查詢)

MySQL UNION 操作符用於連線兩個以上的 SELECT 語句的結果組合到一個結果集合中。多個 SELECT 語句會刪除重複的資料。

MySQL UNION 操作符語法格式:

SELECT expression1, expression2, ... expression_n
FROM tables
[WHERE conditions]
UNION [ALL | DISTINCT]
SELECT expression1, expression2, ... expression_n
FROM tables
[WHERE conditions];

引數
expression1, expression2, ... expression_n: 要檢索的列
tables: 要檢索的資料表。
WHERE conditions: 可選, 檢索條件。

DISTINCT: 可選,刪除結果集中重複的資料。預設情況下 UNION 操作符已經刪除了重複資料,所以 DISTINCT 修飾符對結果沒啥影響

ALL: 可選,返回所有結果集,包含重複資料
--------------------------------------
UNION 語句:用於將不同表中相同列中查詢的資料展示出來;(不包括重複資料)

UNION ALL 語句:用於將不同表中相同列中查詢的資料展示出來;(包括重複資料)
----------------------------
*/
SELECT * FROM Websites;
SELECT * FROM app;

-- 從 "Websites" 和 "app" 表中選取所有不同的country(只有不同的值)
SELECT country FROM Websites
UNION
SELECT country FROM app
ORDER BY country;

-- 使用 UNION ALL 從 "Websites" 和 "app" 表中選取所有的country(也有重複的值)
SELECT country FROM Websites
UNION ALL
SELECT country FROM app
ORDER BY country;


-- 使用 UNION ALL 從 "Websites" 和 "app" 表中選取所有的中國(CN)的資料(也有重複的值)
SELECT country, NAME FROM Websites
WHERE country='CN'
UNION ALL
SELECT country, app_name FROM app
WHERE country='CN'
ORDER BY country;

-- ==============================================================================================

/*
MySQL 排序

SELECT field1, field2,...fieldN table_name1, table_name2...
ORDER BY field1, [field2...] [ASC [DESC]]

可以使用任何欄位來作為排序的條件,從而返回排序後的查詢結果。
可以設定多個欄位來排序。
可以使用 ASC 或 DESC 關鍵字來設定查詢結果是按升序或降序排列。 預設情況下,它是按升序排列
可以新增 WHERE...LIKE 子句來設定條件。

*/


 SELECT * FROM runoob_tb ORDER BY submission_date ASC;

 SELECT * FROM runoob_tb ORDER BY submission_date DESC;
 
 -- ========================================================================================
 
 /*
 GROUP BY 語句
 
 SELECT column_name, function(column_name)
FROM table_name
WHERE column_name operator value
GROUP BY column_name;


 
 */
 
 
/* 
 SET NAMES utf8;
SET FOREIGN_KEY_CHECKS = 0;

-- ----------------------------
--  Table structure for `employee_tbl`
-- ----------------------------
DROP TABLE IF EXISTS `employee_tbl`;
CREATE TABLE `employee_tbl` (
  `id` int(11) NOT NULL,
  `name` char(10) NOT NULL DEFAULT '',
  `date` datetime NOT NULL,
  `singin` tinyint(4) NOT NULL DEFAULT '0' COMMENT '登入次數',
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

-- ----------------------------
--  Records of `employee_tbl`
-- ----------------------------
BEGIN;
INSERT INTO `employee_tbl` VALUES ('1', '小明', '2016-04-22 15:25:33', '1'), ('2', '小王', '2016-04-20 15:25:47', '3'), ('3', '小麗', '2016-04-19 15:26:02', '2'), ('4', '小王', '2016-04-07 15:26:14', '4'), ('5', '小明', '2016-04-11 15:26:40', '4'), ('6', '小明', '2016-04-04 15:26:54', '2');
COMMIT;

SET FOREIGN_KEY_CHECKS = 1;
 
 
 */
 
 SELECT * FROM employee_tbl;
 
 SELECT NAME, COUNT(*) FROM   employee_tbl GROUP BY NAME;
 
 
-- 使用 WITH ROLLUP
-- WITH ROLLUP 可以實現在分組統計資料基礎上再進行相同的統計(SUM,AVG,COUNT…)。

SELECT NAME, SUM(singin) AS singin_count FROM  employee_tbl GROUP BY NAME WITH ROLLUP;


-- **********************************************************************************************
/*
Mysql 連線查詢

 按照功能大致分為如下三類:

INNER JOIN(內連線,或等值連線):獲取兩個表中欄位匹配關係的記錄。
LEFT JOIN(左外連線):獲取左表所有記錄,即使右表沒有對應匹配的記錄。
RIGHT JOIN(右外連線): 與 LEFT JOIN 相反,用於獲取右表所有記錄,即使左表沒有對應匹配的記錄

內連線,或等值連線:INNER JOIN ... ON ...
左連線查詢:left join ... on ...
右連線查詢:right join ... on ...

格式:
select 欄位 
from 表1 
right join 表2 
on  條件 (一般為表1與表2的關聯條件)



*/
-- 內連線
SELECT user.*,orders.`number` 
FROM USER 
INNER JOIN orders
ON user.`id` = orders.`user_id`;

-- 內連線:獲取兩個表中欄位匹配關係的記錄
SELECT a.runoob_id, a.runoob_author, b.runoob_count 
FROM runoob_tb a 
INNER JOIN tcount_tb b 
ON a.runoob_author = b.runoob_author;

-- 以上 SQL 語句等價於
SELECT a.runoob_id, a.runoob_author, b.runoob_count 
FROM runoob_tb a, tcount_tb b 
WHERE a.runoob_author = b.runoob_author;


-- ========================

-- 左外連線

/*

LEFT JOIN 會讀取左邊資料表的全部資料,即便右邊表無對應資料

LEFT JOIN讀取的資料除了公共部分外,還包括左邊全部資料。
*/

SELECT a.`runoob_id`,a.`runoob_author`,b.`runoob_count`
FROM runoob_tb a
LEFT JOIN tcount_tb b
ON a.`runoob_author`=b.`runoob_author`;

-- 左外連線
SELECT user.*,orders.`number` 
FROM USER 
LEFT JOIN orders 
ON user.`id` = orders.`user_id`



-- =================================

-- 右外連線
/*
RIGHT JOIN 會讀取右邊資料表的全部資料,即便左邊邊表無對應資料。
RIGHT JOIN讀取的資料除了公共部分外,還包括右邊全部資料
*/

SELECT a.`runoob_id`,a.`runoob_author`,b.`runoob_count`
FROM runoob_tb a
RIGHT JOIN tcount_tb b
ON a.`runoob_author`=b.`runoob_author`;


-- *********************************************************************************

-- -------------------------------------------------
/*
NULL 值處理

MySQL提供了三大運算子:

IS NULL: 當列的值是 NULL,此運算子返回 true。
IS NOT NULL: 當列的值不為 NULL, 運算子返回 true。
<=>: 比較操作符(不同於=運算子),當比較的的兩個值為 NULL 時返回 true


*/


CREATE TABLE runoob_test_tbl
(
runoob_author VARCHAR(40) NOT NULL,
runoob_count  INT
);


INSERT INTO runoob_test_tbl (runoob_author, runoob_count) VALUES ('RUNOOB', 20);
INSERT INTO runoob_test_tbl (runoob_author, runoob_count) VALUES ('菜鳥教程', NULL);
INSERT INTO runoob_test_tbl (runoob_author, runoob_count) VALUES ('Google', NULL);
INSERT INTO runoob_test_tbl (runoob_author, runoob_count) VALUES ('FK', 20);

/*where 限定某列為空null ,不能用=等號限定,
  而是需要用is null 操作符判斷
*/
SELECT * FROM  runoob_test_tbl WHERE runoob_count =NULL;
SELECT * FROM  runoob_test_tbl WHERE runoob_count !=NULL;
-- 你可以看到 = 和 != 運算子是不起作用的
--  必須使用is null 或 is not null 來判斷
SELECT * FROM  runoob_test_tbl WHERE runoob_count IS NULL;
SELECT * FROM  runoob_test_tbl WHERE runoob_count IS NOT NULL;


-- *************************************************************************************
/*
MySQL 正則表示式

MySQL除了可以通過 LIKE ...% 來進行模糊匹配之外,
還可以使用正則表示式

 用法如下:(在where 子句中使用REGEXP 正則表示式)
 
  SELECT name FROM person_tbl WHERE name REGEXP '^st';
  
  
常用的REGEXP 操作符:
  
^	匹配輸入字串的開始位置。如果設定了 RegExp 物件的 Multiline 屬性,^ 也匹配 '\n' 或 '\r' 之後的位置。
$	匹配輸入字串的結束位置。如果設定了RegExp 物件的 Multiline 屬性,$ 也匹配 '\n' 或 '\r' 之前的位置。
.	匹配除 "\n" 之外的任何單個字元。要匹配包括 '\n' 在內的任何字元,請使用象 '[.\n]' 的模式。
[...]	字元集合。匹配所包含的任意一個字元。例如, '[abc]' 可以匹配 "plain" 中的 'a'。
[^...]	負值字元集合。匹配未包含的任意字元。例如, '[^abc]' 可以匹配 "plain" 中的'p'。
p1|p2|p3	匹配 p1 或 p2 或 p3。例如,'z|food' 能匹配 "z" 或 "food"。'(z|f)ood' 則匹配 "zood" 或 "food"。
*	匹配前面的子表示式零次或多次。例如,zo* 能匹配 "z" 以及 "zoo"。* 等價於{0,}。
+	匹配前面的子表示式一次或多次。例如,'zo+' 能匹配 "zo" 以及 "zoo",但不能匹配 "z"。+ 等價於 {1,}。
{n}	n 是一個非負整數。匹配確定的 n 次。例如,'o{2}' 不能匹配 "Bob" 中的 'o',但是能匹配 "food" 中的兩個 o。
{n,m}	m 和 n 均為非負整數,其中n <= m。最少匹配 n 次且最多匹配 m 次。


*/

-- 查詢以'p'為結尾的所有資料:
SELECT * FROM runoob_tb WHERE runoob_title REGEXP 'p$';

-- 查詢以'j'為開頭的所有資料
SELECT * FROM runoob_tb WHERE runoob_title REGEXP '^j';

-- 包含'a'字串的所有資料:
SELECT * FROM runoob_tb WHERE runoob_title REGEXP 'a';



-- ********************************************************************************

-- 等值連線(where子句中使用=等號為限定條件)
SELECT *
FROM runoob_tb a, tcount_tb b 
WHERE a.runoob_author = b.runoob_author;


-- 自然連線NATURAL JOIN (自然連線只考慮屬性相同的元組對)
SELECT * FROM runoob_tb NATURAL JOIN tcount_tb;


-- 笛卡爾積 (使用,逗號連線兩個表 ,mysql預設的連線就是笛卡爾積連線)
-- 即表A中的每一個元素,都對錶B中的所有元素做連線運算
-- 假設A中有m 個元組,B中有n個元組,則笛卡爾乘積= m*n 個元組

SELECT * FROM runoob_tb , tcount_tb;

-- **********************************************************************************

/*

MySQL 事務主要用於處理操作量大,複雜度高的資料

1.在 MySQL 中只有使用了 Innodb 資料庫引擎的資料庫或表才支援事務。
2.事務處理可以用來維護資料庫的完整性,保證成批的 SQL 語句要麼全部執行,要麼全部不執行。
3.事務用來管理 insert,update,delete 語句

事務是必須滿足4個條件(ACID):
	原子性(Atomicity,或稱不可分割性)
	一致性(Consistency)
	隔離性(Isolation,又稱獨立性)
	永續性(Durability)。

事務控制語句:
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 開啟自動提交	

*/

# 建立資料表
CREATE TABLE runoob_transaction_test( id INT(5)) ENGINE=INNODB;  

SELECT * FROM runoob_transaction_test;

#開始事務
BEGIN;

#可以將多個增刪改操作寫入一個事務中
INSERT INTO runoob_transaction_test VALUE(1);
INSERT INTO runoob_transaction_test VALUE(2);

ROLLBACK; -- 回滾生效,因為資料還未提交

INSERT INTO runoob_transaction_test VALUE(7);
INSERT INTO runoob_transaction_test VALUE(8);

#提交事務後,就不能再回滾  
COMMIT;

-- ROLLBACK; 回滾無效,因為資料已經提交

-- 再次查詢,發現只有7,8插入生效,1,2因為回滾插入失敗
SELECT * FROM runoob_transaction_test;

-----------------------------------------

#開始事務
BEGIN;
INSERT INTO runoob_transaction_test VALUES(7);
# 回滾
ROLLBACK;   
# 因為回滾所以資料沒有插入
SELECT * FROM runoob_transaction_test;   


-- ******************************************************************************
/* alter 修改表結構  */

CREATE TABLE testalter_tb
(
i INT,
c CHAR(1)
);

-- 刪除列 
ALTER TABLE testalter_tb
DROP i;

-- 新增列
ALTER TABLE testalter_tb
ADD i INT;

-- 指定新增欄位的位置,關鍵字 FIRST (設定位第一列)
ALTER TABLE testalter_tb DROP i;
ALTER TABLE testalter_tb ADD i INT FIRST;

-- 指定新增欄位的位置,AFTER 欄位名(設定位於某個欄位之後)
ALTER TABLE testalter_tb DROP i;
ALTER TABLE testalter_tb ADD i INT AFTER c;


-- 修改欄位型別及名稱
ALTER TABLE testalter_tb MODIFY c CHAR(10);


-- 在 CHANGE 關鍵字之後,緊跟著的是你要修改的欄位名,然後指定新欄位名及型別
ALTER TABLE testalter_tb CHANGE i  j BIGINT;

ALTER TABLE testalter_tb CHANGE j i INT;

-- 修改非空和預設值

ALTER TABLE testalter_tb
MODIFY j BIGINT NOT NULL DEFAULT 100;

-- 若不設定欄位的預設值,則mysql會自動設定欄位預設值為null 

ALTER TABLE testalter_tb ALTER i SET DEFAULT 1000;


-- 使用 ALTER 命令及 DROP子句來刪除欄位的預設值
ALTER TABLE testalter_tb ALTER i DROP DEFAULT;

-- 修改資料表型別(修改儲存引擎),將表 testalter_tbl 的型別修改為 MYISAM 

ALTER TABLE testalter_tb ENGINE = MYISAM;

-- 修改表名
ALTER TABLE testalter_tb RENAME TO alter_tb;

-- 刪除外來鍵約束:keyName是外來鍵別名

-- alter table tableName drop foreign key keyName;

ALTER TABLE orders DROP FOREIGN KEY fk_1;


-- **************************************************************************************
/*
MySQL 索引

通過索引可以更加快速高效地查詢資料。
使用者無法看到索引,它們只能被用來加速查詢
索引也是一張表,該表儲存了主鍵與索引欄位,並指向實體表的記錄

索引可以大大提高MySQL的檢索速度。

索引也會有它的缺點:
   索引會降低更新表的速度,
   如對錶進行INSERT、UPDATE和DELETE。
   因為更新表時,MySQL不僅要儲存資料,還要儲存一下索引檔案
*/

-- 建立普通索引
/*
語法:

create index  索引名
on  表名(表的主鍵)

*/

-- 建立普通索引
CREATE INDEX  runoob_tb_index
ON runoob_tb (runoob_id);

-- 使用者無法看到索引,它們只能被用來加速查詢
SELECT * FROM runoob_tb;


/*
在修改表結構時,新增索引
語法:
alter table 表名
add index  索引名(表的主鍵)
*/
-- 在修改表結構時,新增索引
ALTER TABLE websites 
ADD INDEX websites_index(id);


/*
建立表的時候直接指定索引
語法:
CREATE TABLE 表名(
 列名  型別  約束,
 列名  型別  約束,
 列名  型別  約束,
 
 index  索引名(列名)
);
*/

-- drop table mytable;

CREATE TABLE mytable(  
ID INT NOT NULL,   
username VARCHAR(16) NOT NULL,  
INDEX   mytable_index (username)
);  


/*
刪除索引

法1:
DROP INDEX 索引名 ON  表名; 

法2:
alter table 表名
drop index  索引名
*/


DROP INDEX mytable_index ON mytable;


ALTER TABLE websites
DROP INDEX websites_index;


/*
建立唯一索引
CREATE  UNIQUE INDEX  索引名
ON 表名 (表的主鍵或其他列名);

唯一索引:
索引列的值必須唯一,但允許有空值。
如果是組合索引,則列值的組合必須唯一

*/

CREATE  UNIQUE INDEX  websites_index
ON websites (id);

DROP INDEX websites_index ON websites;

-- ==============================================================================


/*
檢視是基於 SQL 語句的結果集的視覺化的表。
檢視是虛擬的表,本身不包含資料,也就不能對其進行索引操作。
對檢視的操作和對普通表的操作一樣
*/
-- 建立檢視
CREATE VIEW top_2_runoob_tb_view AS
SELECT runoob_id,runoob_title
FROM runoob_tb
WHERE runoob_id < 3;	
 
 
-- 查詢檢視
SELECT * FROM top_2_runoob_tb_view;
 
-- 撤銷檢視
DROP VIEW top_2_runoob_tb_view;


-- ***********************************************************