1. 程式人生 > 其它 >MySQL學習小記

MySQL學習小記

 

資料庫 建立與刪除

create database 資料庫名
drop database 資料庫名

資料表 建立與刪除

CREATE TABLE table_name (
    column_name column_type,
    column_name column_type,
    column_name column_type);
     
DROP TABLE table_name ;

INSERT 插入資料

 INSERT INTO

INSERT INTO table_name ( field1, field2,...fieldN )
                      VALUES
                      ( value1, value2,...valueN );
      即field與value一一對應
注: 在插入資料時 首先原表得有對應的欄位
  INSERT INTO runoob_tbl
  -> (runoob_title, runoob_author, submission_date)
  -> VALUES
  -> ("學習 PHP", "菜鳥教程", NOW());
  如該例 若原表無runoob_title, runoob_author,則加不進去 報錯

SELECT 查詢資料

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

可以使用一個或者多個表,表之間使用逗號(,)分割
SELECT 命令可以讀取一條或者多條記錄
可以使用 LIMIT 屬性來設定返回的記錄數

WHERE 選取資料

SELECT field1, field2,...fieldN 
FROM table_name1, table_name2...
[WHERE condition1 [AND [OR]] condition2.....

eg: select *
    from runoob_tbl
    where runoob_author="菜鳥教程";

UPDATE 更新資料

UPDATE table_name 
SET field1=new-value1, field2=new-value2
[WHERE Clause]
可以在 WHERE 子句中指定任何條件 可以同時更新一個或多個欄位
使用 WHERE 子句來更新 runoob_tbl 表中指定的資料

Eg:
UPDATE runoob_tbl
SET runoob_title='學習 C++'       注:多個條件之間逗號隔開
WHERE runoob_id=3;

DELETE 刪除資料

DELETE FROM table_name [WHERE Clause]
eg:
刪除 表中 runoob_id 為3 的記錄
DELETE FROM runoob_tbl
WHERE runoob_id=3;

DML思維導圖

 

LIKE 子句

SELECT field1, field2,...fieldN 
FROM table_name
WHERE field1 LIKE condition1 [AND [OR]] filed2 = 'somevalue'
可以在 WHERE 子句中使用LIKE子句
LIKE 通常與 % 一同使用,類似於一個元字元的搜尋
使用 AND 或者 OR 指定一個或多個條件
可以在 DELETE 或 UPDATE 命令使用 WHERE...LIKE 子句來指定條件
'%a'     //以a結尾的資料
'a%'     //以a開頭的資料
'%a%'   //含有a的資料
'_a_'   //三位且中間字母是a的
'_a'     //兩位且結尾字母是a的
'a_'     //兩位且開頭字母是a的
%:表示任意 0 個或多個字元。可匹配任意型別和長度的字元,有些情況下若是中文,請使用兩個百分號(%%)表示。
_:表示任意單個字元。匹配單個任意字元,它常用來限制表示式的字元長度語句。
[]:表示括號內所列字元中的一個(類似正則表示式)。指定一個字元、字串或範圍,要求所匹配物件為它們中的任一個。
[^] :表示不在括號所列之內的單個字元。其取值和 [] 相同,但它要求所匹配物件為指定字元以外的任一個字元

UNION 操作符

用於連線兩個以上的 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: 可選,返回所有結果集,包含重複資料。

ORDER BY 排序

SELECT field1, field2,...fieldN FROM table_name1, table_name2...
ORDER BY field1 [ASC [DESC][預設 ASC]], [field2...] [ASC [DESC][預設 ASC]]
asc 為升序   desc為降序

注:

可以使用任何欄位來作為排序的條件,從而返回排序後的查詢結果

可以使用 ASC 或 DESC 關鍵字來設定查詢結果是按升序或降序排列。 預設情況下,它是按升序排列。可以新增 WHERE...LIKE 子句來設定條件。

SELECT * 
from runoob_tbl
ORDER BY submission_date ASC;

GROUP BY 語句

根據一個或多個列對結果集進行分組。
在分組的列上我們可以使用 COUNT, SUM, AVG,等函式
SELECT column_name, function(column_name)
FROM table_name
WHERE column_name operator value
GROUP BY column_name;
WITH ROLLUP

可以實現在分組統計資料基礎上再進行相同的統計(SUM,AVG,COUNT…)

即就是在group by分組之後,再次對聚合函式進行求和

MySQL 連線

  • INNER JOIN(內連線,或等值連線):獲取兩個表中欄位匹配關係的記錄。

  • LEFT JOIN(左連線):獲取左表所有記錄,即使右表沒有對應匹配的記錄。

  • RIGHT JOIN(右連線): 與 LEFT JOIN 相反,用於獲取右表所有記錄,即使左表沒有對應匹配的記錄。

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;
等價於
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;

NULL 值處理

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

MySQL 事務

主要用於處理操作量大,複雜度高的資料
事務處理可以用來維護資料庫的完整性,保證成批的 SQL 語句要麼全部執行,要麼全部不執行
  1. BEGIN 或 START TRANSACTION 顯式地開啟一個事務

  2. COMMIT 也可以使用 COMMIT WORK,不過二者是等價的。COMMIT 會提交事務,並使已對資料庫進行的所有修改成為永久性的

  3. ROLLBACK 回滾會結束使用者的事務,並撤銷正在進行的所有未提交的修改;可以執行多次

  4. SAVEPOINT identifier,SAVEPOINT 允許在事務中建立一個儲存點,一個事務中可以有多個 SAVEPOINT;

  5. RELEASE SAVEPOINT identifier 刪除一個事務的儲存點,當沒有指定的儲存點時,執行該語句會丟擲一個異常;

  6. ROLLBACK TO identifier 把事務回滾到標記點

MYSQL 事務處理主要有兩種方法:

1、用 BEGIN, ROLLBACK, COMMIT來實現

BEGIN 開始一個事務
ROLLBACK 事務回滾
COMMIT 事務確認
2、直接用 SET 來改變 MySQL 的自動提交模式:

SET AUTOCOMMIT=0 禁止自動提交
SET AUTOCOMMIT=1 開啟自動提交
[注]  一句一句的使用和執行

ALTER命令

修改資料

需要修改資料表名或者修改資料表字段時,就需要使用到MySQL ALTER命令

 ADD    子句來向資料表中新增列
DROP   子句來向資料表中刪除列
注: 如果你需要指定新增欄位的位置 使用關鍵字 FIRST (設定位第一列), AFTER 欄位名(設定位於某個欄位之後)
修改欄位型別名稱

如果需要修改欄位型別及名稱, 你可以在ALTER命令中

使用 MODIFY 或 CHANGE 子句 。

eg:
把欄位 c 的型別從 CHAR(1) 改為 CHAR(10),可以執行以下命令:

ALTER TABLE testalter_tbl MODIFY c CHAR(10);
修改表名

需要修改資料表的名稱,可以在 ALTER TABLE 語句中使用 RENAME 子句來實現

eg:
將資料表 testalter_tbl 重新命名為 alter_tbl:

ALTER TABLE testalter_tbl RENAME TO alter_tbl;

MySQL索引

MySQL索引的建立對於MySQL的高效執行是很重要的,索引可以大大提高MySQL的檢索速度

建立索引
CREATE INDEX indexName ON table_name (column_name)
修改表結構 新增索引
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))

MySQL 臨時表

臨時表只在當前連線可見,當關閉連線時,Mysql會自動刪除表並釋放所有空間

MySQL約束

 

表中資料的限制條件
比如有些列的值不能為空 有些值(身份證號)不能重複

 

主鍵約束
是一個列或者多個列的組合
相當於 唯一約束和非空約束的組合
每個表最多一個主鍵   primary key
新增單列主鍵
create table ep1(
eid int primary key,
name varchar(10),
salary double
);
新增多列主鍵
即由一個表中的多個欄位組成的
注 :當主鍵由多個欄位組成時,不能直接在欄位後面宣告主鍵
  一張表只能有一個主鍵,聯合主鍵也是一個主鍵

create table ep1(
eid int ,
name varchar(10),
salary double
primary key(name,salary)
);
修改表結構新增主鍵
create table 表名(
...
);
alter table 表名 add primary key(欄位列表)
刪除主鍵約束
alter table 資料表名 drop primary key
自增長約束
在MySQL中 當主鍵定義為自增長後 該主鍵值就不需要使用者輸入資料 而是由資料庫系統根據定義自動複製
每增加一條記錄 主鍵就會自動以相同的步長進行增長
關鍵字 auto_increment
語法
欄位名 資料型別 auto_increment
操作
create table ep1(
eid int primary key auto_increment,
name varchar(10),
);
指定自增長初始值
create table ep1(
eid int primary key auto_increment,
name varchar(10),
) auto_increment=100;

MySQL DQL基本查詢

簡化版

select * |列名
from 表
where 條件
運算子
eg:
-- 將所有商品的價格上調10%
select pname,price * 1.1 as new_price
from product;
-- 查詢商品價格是200或800的所有商品
select * from product where price = 200 or price = 800;
select * from product where price in (200,800);
-- 查詢含有‘褲'字的所有商品
select * from product where pname like ‘%褲%';
-- 查詢以'海'開頭的所有商品
select * from product where pname like '海%';
-- 查詢第二個字為'蔻'的所有商品
select * from product where pname like '_蔻%';
-- 查詢category_id為null的商品
select * from product where category_id is null;
-- 查詢category_id不為null分類的商品
select * from product where category_id is not null;
排序查詢
select 
欄位名1,欄位名2,……
from 表名
order by 欄位名1 [asc|desc],欄位名2[asc|desc]……
注:
1.asc代表升序,desc代表降序,如果不寫預設升序
2.order by用於子句中可以支援單個欄位,多個欄位,表示式,函式,別名
3.order by子句,放在查詢語句的最後面。LIMIT子句除外
-- 1.使用價格排序(降序)
select *
from product
order by price desc;
-- 2.在價格排序(降序)的基礎上,以分類排序(降序)
select *
from product
order by price desc,category_id asc;
-- 3.顯示商品的價格(去重複),並排序(降序)
select distinct price
from product order by price desc;
聚合查詢
聚合函式 作用
count() 統計指定列不為NULL的記錄行數;
sum() 計算指定列的數值和,如果指定列型別不是數值型別,那麼計算結果為0
max() 計算指定列的最大值,如果指定列是字串型別,那麼使用字串排序運算;
min() 計算指定列的最小值,如果指定列是字串型別,那麼使用字串排序運算;
avg() 計算指定列的平均值,如果指定列型別不是數值型別,那麼計算結果為0
-- 1 查詢商品的總條數
select count(*) from product;
-- 2 查詢價格大於200商品的總條數
select count(*) from product where price > 200;
-- 3 查詢分類為'c001'的所有商品的總和
select sum(price)
from product
where category_id = 'c001';
-- 4 查詢商品的最大價格
select max(price)
from product;
-- 5 查詢商品的最小价格
select min(price)
from product;
-- 6 查詢分類為'c002'所有商品的平均價格
select avg(price)
from product
where category_id = 'c002';

注:count函式對null值的處理

如果count函式的引數為星號(*),則統計所有記錄的個數。而如果引數為某欄位,不統計含null值的記錄個數。其他基本都忽略null的存在

分組查詢
select 欄位1,欄位2… 
from 表名
group by 分組欄位 having 分組條件
統計各個分類商品的個數,且只顯示個數大於4的資訊
select category_id ,count(*)
from product
group by category_id
having count(*) > 4;
分頁查詢

由於資料量很大,顯示屏長度有限,因此對資料需要採取分頁顯示方式。例如資料共有30條,每頁顯示5條,第一頁顯示1-5條,第二頁顯示6-10條。

-- 查詢product表的前5條記錄 
select * from product limit 5
-- 從第4條開始顯示,顯示5條
select * from product limit 3,5
INSERT INTO SELECT
將一張表的資料匯入到另一張表中,可以使用INSERT INTO SELECT語句 
insert into Table2(field1,field2,…) 
select value1,value2,… from Table1 或者:
insert into Table2 select * from Table1
注:要求目標表Table2必須存在
SELECT INTO FROM
將一張表的資料匯入到另一張表中,有兩種選擇 SELECT INTO 和 INSERT INTO SELECT 

SELECT vale1, value2 into Table2 from Table1

注: 要求目標表Table2不存在,因為在插入時會自動建立表Table2,並將Table1中指定欄位資料複製到Table2中。

正則表示式
使用 REGEXP 操作符來進行正則表示式匹配
eg:
1.SELECT name     查詢name欄位中以'st'為開頭的所有資料
FROM person_tbl
WHERE name REGEXP '^st';
2.SELECT name     查詢name欄位中以'ok'為結尾的所有資料
FROM person_tbl
WHERE name REGEXP 'ok$';
3.SELECT name     查詢name欄位中包含'mar'字串的所有資料
FROM person_tbl
WHERE name REGEXP 'mar';
4.查詢name欄位中以母音字元開頭或以'ok'字串結尾的所有資料
SELECT name      
FROM person_tbl
WHERE name REGEXP '^[aeiou]|ok$';
^ 匹配輸入字串的開始位置。如果設定了 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 次。

MySQL的多表操作

MySQL多表之間的關係可以概括為:一對一、一對多/多對一關係,多對多

交叉連線查詢
假如A表有m行資料,B表有n行資料,則返回m*n行資料
笛卡爾積會產生很多冗餘的資料,後期的其他查詢可以在該集合的基礎上進行條件篩選
內連線查詢

求多張表的交集

select * from A inner join B on 條件;
外連線查詢
左外連線:left outer join
        select * from A left outer join B on 條件;
右外連線:right outer join
        select * from A right outer join B on 條件;
滿外連線: full outer join
        select * from A full outer join B on 條件;
子查詢

在一個完整的查詢語句之中,巢狀若干個不同功能的小查詢,從而一起完成複雜查詢的一種編寫形式,通俗一點就是包含select巢狀的查詢。

查詢年齡最大的員工資訊,顯示資訊包含員工號、員工名字,員工年齡
select eid,ename,age
from emp3
where age = (select max(age) from emp3);

select …from …where exists(查詢語句)

-- 查詢公司是否有大於60歲的員工,有則輸出
select *
from emp3 a
where exists(select * from emp3 b where a.age > 60);

MySQL函式

聚合函式
group_concat()
函式首先根據group by指定的列進行分組,並且用分隔符分隔,將同一個分組中的值連線起來,返回一個字串結果。
group_concat([distinct] 欄位名 [order by 排序欄位 asc/desc] [separator '分隔符'])
-- 將所有員工的名字合併成一行 
select group_concat(emp_name) from emp
-- 指定分隔符合並
select department,group_concat
      (emp_name separator ';' )
from emp group by department;
控制流函式
select 
case 100
when 50 then 'tom'
when 100 then 'mary'
else 'tim'
end ;
CASE 
表示函式開始,END 表示函式結束。如果 condition1 成立,則返回 result1, 如果 condition2 成立,則返回 result2,當全部不成立則返回 result,而當有一個成立之後,後面的就不執行了
視窗函式
window_function ( expr ) OVER ( 
PARTITION BY ...
ORDER BY ...
frame_clause
)

注:window_function 是視窗函式的名稱;expr 是引數,有些函式不需要引數
分割槽(PARTITION BY)
PARTITION BY選項用於將資料行拆分成多個分割槽(組),它的作用類似於GROUP BY分組。如果省略了 PARTITION BY,所有的資料作為一個組進行計算
排序(ORDER BY)
OVER 子句中的ORDER BY選項用於指定分割槽內的排序方式,與 ORDER BY 子句的作用類似
以及視窗大小(frame_clause)。
frame_clause選項用於在當前分割槽內指定一個計算視窗,也就是一個與當前行相關的資料子集
序號函式
格式:
row_number()|rank()|dense_rank() over (
partition by ...
order by ...
)
序號函式有三個:
ROW_NUMBER()、 RANK()、 DENSE_RANK(),
可以用來實現分組排序,並新增序號。

eg:

-- 對每個部門的員工按照薪資排序,並給出排名
select dname,ename,salary,
row_number() over(partition by dname order by salary desc) as rn
from employee;
前後函式
LAG和LEAD
返回位於當前行的前n行(LAG(expr,n))或後n行(LEAD(expr,n))的expr的值

MySQL檢視

檢視(view)是一個虛擬表,非真實存在,其本質是根據SQL語句獲取動態的資料集,併為其命名,使用者使用時只需使用檢視名稱即可獲取結果集,並可以將其當作表來使用。
資料庫中只存放了檢視的定義,而並沒有存放檢視中的資料。這些資料存放在原來的表中。
使用檢視查詢資料時,資料庫系統會從原來的表中取出對應的資料。因此,檢視中的資料是依賴於原來的表中的資料的。一旦表中的資料發生改變,顯示在檢視中的資料也會發生改變。

MySQL的JDBC

pymysql

import pymysql
conn = pymysql.connect(host='localhost', port=3306, user='root',password='333666',database='mydb4', charset='utf8')
# 獲取遊標
cursor = conn.cursor()
# 執行SQL語句 返回值就是SQL語句在執行過程中影響的行數
sql = "select * from employee;"
row_count = cursor.execute(sql)
print("SQL語句執行影響的行數%d" % row_count)
for line in cursor.fetchall():
  print(line)
cursor.close()
conn.close()