mysql資料庫sql語句基礎知識

weixin_33890526發表於2019-01-07

1.資料庫操作

  • 檢視當前資料庫
    SELECT DATABASE();
  • 顯示使用者名稱,資料庫版本
    SELECT user(), version();
  • 建立庫
    CREATE DATABASE[ IF NOT EXISTS] 資料庫名 資料庫選項
  • 檢視已有庫
    SHOW DATABASES[ LIKE 'PATTERN']
  • 檢視當前庫資訊
    SHOW CREATE DATABASE 資料庫名
  • 修改庫的選項資訊
    ALTER DATABASE 庫名 選項資訊
  • 刪除庫
    DROP DATABASE[ IF EXISTS] 資料庫名

2.表的操作

  • 建立表
    CREATE [TEMPORARY] TABLE[ IF NOT EXISTS] [庫名.]表名 ( 表的結構定義 )[ 表選項]
每個欄位必須有資料型別
最後一個欄位後不能有逗號
TEMPORARY 臨時表,會話結束時表自動消失
對於欄位的定義:
欄位名 資料型別 [NOT NULL | NULL] [DEFAULT default_value] [AUTO_INCREMENT] [UNIQUE [KEY] | [PRIMARY] KEY] [COMMENT]
-- 表選項
    -- 字符集
        CHARSET = charset_name
        如果表沒有設定,則使用資料庫字符集
    -- 儲存引擎
        ENGINE = engine_name
        表在管理資料時採用的不同的資料結構,結構不同會導致處理方式、提供的特性操作等不同
        常見的引擎:InnoDB MyISAM Memory/Heap BDB Merge Example CSV MaxDB Archive
        不同的引擎在儲存表的結構和資料時採用不同的方式
        MyISAM表檔案含義:.frm表定義,.MYD表資料,.MYI表索引
        InnoDB表檔案含義:.frm表定義,表空間資料和日誌檔案
        SHOW ENGINES -- 顯示儲存引擎的狀態資訊
        SHOW ENGINE 引擎名 {LOGS|STATUS} -- 顯示儲存引擎的日誌或狀態資訊
    -- 自增起始數
        AUTO_INCREMENT = 行數
  • 檢視所有表
    SHOW TABLES[ LIKE 'pattern']
    SHOW TABLES FROM 表名

  • 檢視錶機構
    SHOW CREATE TABLE 表名 (資訊更詳細)
    DESC 表名 / DESCRIBE 表名 / EXPLAIN 表名 / SHOW COLUMNS FROM 表名 [LIKE 'PATTERN']
    SHOW TABLE STATUS [FROM db_name] [LIKE 'pattern']

  • 修改表本身的選項
    ALTER TABLE 表名 表的選項

  • 對錶進行重新命名
    RENAME TABLE 原表名 TO 新表名
    RENAME TABLE 原表名 TO 庫名.表名 (可將表移動到另一個資料庫)
    RENAME可以交換兩個表名

  • 修改表的欄位機構
    ALTER TABLE 表名 操作名
    *增加欄位
    ADD[ COLUMN] 欄位定義

  • 表示增加在該欄位名後面
    ADD AFTER 欄位名

  • 表示增加在第一個
    ADD FIRST

  • 建立主鍵
    ADD PRIMARY KEY(欄位名)

  • 建立唯一索引
    ADD UNIQUE [索引名] (欄位名)

  • 建立普通索引
    ADD INDEX [索引名] (欄位名)

  • 刪除欄位
    DROP[ COLUMN] 欄位名

  • 支援對欄位屬性進行修改,不能修改欄位名(所有原有屬性也需寫上)
    MODIFY[ COLUMN] 欄位名 欄位屬性

  • 支援對欄位名修改
    CHANGE[ COLUMN] 原欄位名 新欄位名 欄位屬性

  • 刪除主鍵(刪除主鍵前需刪除其AUTO_INCREMENT屬性)
    DROP PRIMARY KEY

  • 刪除索引
    DROP INDEX 索引名

  • 刪除外來鍵
    DROP FOREIGN KEY 外來鍵

  • 刪除表
    DROP TABLE[ IF EXISTS] 表名 ...

  • 清空表資料
    TRUNCATE [TABLE] 表名

  • 複製表結構
    CREATE TABLE 表名 LIKE 要複製的表名

  • 複製表結構和資料
    CREATE TABLE 表名 [AS] SELECT * FROM 要複製的表名

將一張表的資料插入到另一張表
CREATE TABLE 表名 [AS] SELECT * FROM 要複製的表名
  • 檢查表是否有錯誤
    CHECK TABLE tbl_name [, tbl_name] ... [option] ...

資料操作


  • INSERT [INTO] 表名 [(欄位列表)] VALUES (值列表)[, (值列表), ...]
    -- 如果要插入的值列表包含所有欄位並且順序一致,則可以省略欄位列表。
    -- 可同時插入多條資料記錄!
    REPLACE 與 INSERT 完全一樣,可互換。
    INSERT [INTO] 表名 SET 欄位名=值[, 欄位名=值, ...]


  • SELECT 欄位列表 FROM 表名[ 其他子句]
    -- 可來自多個表的多個欄位
    -- 其他子句可以不使用
    -- 欄位列表可以用*代替,表示所有欄位


  • DELETE FROM 表名[ 刪除條件子句]
    沒有條件子句,則會刪除全部


  • UPDATE 表名 SET 欄位名=新值[, 欄位名=新值] [更新條件]

約束

  • PRIMARY 主鍵
    -- 能唯一標識記錄的欄位,可以作為主鍵。
    -- 一個表只能有一個主鍵。
    -- 主鍵具有唯一性。
    -- 宣告欄位時,用 primary key 標識。
    也可以在欄位列表之後宣告
    例:create table tab ( id int, stu varchar(10), primary key (id));
    -- 主鍵欄位的值不能為null。
    -- 主鍵可以由多個欄位共同組成。此時需要在欄位列表後宣告的方法。
    例:create table tab ( id int, stu varchar(10), age int, primary key (stu, age));
  • UNIQUE 唯一索引(唯一約束)
    使得某欄位的值也不能重複。
  • NULL 約束
    null不是資料型別,是列的一個屬性。
    表示當前列是否可以為null,表示什麼都沒有。
    null, 允許為空。預設。
    not null, 不允許為空。
    insert into tab values (null, 'val');
    -- 此時表示將第一個欄位的值設為null, 取決於該欄位是否允許為null
  • DEFAULT 預設值屬性
    當前欄位的預設值。
    insert into tab values (default, 'val'); -- 此時表示強制使用預設值。
    create table tab ( add_time timestamp default current_timestamp );
    -- 表示將當前時間的時間戳設為預設值。
    current_date, current_time
  • AUTO_INCREMENT 自動增長約束
    自動增長必須為索引(主鍵或unique)
    只能存在一個欄位為自動增長。
    預設為1開始自動增長。可以通過表屬性 auto_increment = x進行設定,或 alter table tbl auto_increment = x;
  • COMMENT 註釋
    例:create table tab ( id int ) comment '註釋內容';
  • FOREIGN KEY 外來鍵約束
    用於限制主表與從表資料完整性。
    alter table t1 add constraint t1_t2_fk foreign key (t1_id) references t2(id);
    -- 將表t1的t1_id外來鍵關聯到表t2的id欄位。
    -- 每個外來鍵都有一個名字,可以通過 constraint 指定
    存在外來鍵的表,稱之為從表(子表),外來鍵指向的表,稱之為主表(父表)。
    作用:保持資料一致性,完整性,主要目的是控制儲存在外來鍵表(從表)中的資料。
    MySQL中,可以對InnoDB引擎使用外來鍵約束:
    語法:
    foreign key (外來鍵欄位) references 主表名 (關聯欄位) [主表記錄刪除時的動作] [主表記錄更新時的動作]
    此時需要檢測一個從表的外來鍵需要約束為主表的已存在的值。外來鍵在沒有關聯的情況下,可以設定為null.前提是該外來鍵列,沒有not null。
    可以不指定主表記錄更改或更新時的動作,那麼此時主表的操作被拒絕。
    如果指定了 on update 或 on delete:在刪除或更新時,有如下幾個操作可以選擇:
    1. cascade,級聯操作。主表資料被更新(主鍵值更新),從表也被更新(外來鍵值更新)。主表記錄被刪除,從表相關記錄也被刪除。
    2. set null,設定為null。主表資料被更新(主鍵值更新),從表的外來鍵被設定為null。主表記錄被刪除,從表相關記錄外來鍵被設定成null。但注意,要求該外來鍵列,沒有not null屬性約束。
    3. restrict,拒絕父表刪除和更新。
      注意,外來鍵只被InnoDB儲存引擎所支援。其他引擎是不支援的。
在建立表時往往需要新增約束或者屬性,列舉出所有你知道的約束和屬性,並解釋他們的作用
1.PRIMARY 主鍵
能唯一標識記錄的欄位
2.UNIQUE 唯一索引(唯一約束)
使得某欄位的值也不能重複。
3.NULL 約束
null不是資料型別,是列的一個屬性。
表示當前列是否可以為null,表示什麼都沒有。
4.DEFAULT 預設值屬性
當前欄位的預設值。
5.AUTO_INCREMENT 自動增長約束
自動增長必須為索引(主鍵或unique)
只能存在一個欄位為自動增長
6.COMMENT 註釋
7.FOREIGN KEY 外來鍵約束
用於限制主表與從表資料完整性。

三正規化

  • 1NF, 第一正規化
    欄位不能再分,就滿足第一正規化。
  • 2NF, 第二正規化
    每個表要有主鍵約束
    滿足第一正規化的前提下,不能出現部分依賴。
    消除符合主鍵就可以避免部分依賴。增加單列關鍵字。
  • 3NF, 第三正規化
    滿足第二正規化的前提下,不能出現傳遞依賴。
    某個欄位依賴於主鍵,而有其他欄位依賴於該欄位。這就是傳遞依賴。
    將一個實體資訊的資料放在一個表內實現。
簡單說說你理解的三正規化
1.欄位不能再分,即原子性
2.每個表要有主鍵約束
3.滿足第二正規化的前提下,不能出現傳遞依賴。      

INSERT

select語句獲得的資料可以用insert插入。
可以省略對列的指定,要求 values () 括號內,提供給了按照列順序出現的所有欄位的值。

  • 或者使用set語法。
    INSERT INTO tbl_name SET field=value,...;
  • 可以一次性使用多個值,採用(), (), ();的形式。
    INSERT INTO tbl_name VALUES (), (), ();
  • 可以在列值指定時,使用表示式。
    INSERT INTO tbl_name VALUES (field_value, 10+10, now());
  • 可以使用一個特殊值 DEFAULT,表示該列使用預設值。
    INSERT INTO tbl_name VALUES (field_value, DEFAULT);
  • 可以通過一個查詢的結果,作為需要插入的值。
    INSERT INTO tbl_name SELECT ...;
  • 可以指定在插入的值出現主鍵(或唯一索引)衝突時,更新其他非主鍵列的資訊。
    INSERT INTO tbl_name VALUES/SET/SELECT ON DUPLICATE KEY UPDATE 欄位=值, …;

DELETE

DELETE FROM tbl_name [WHERE where_definition] [ORDER BY ...] [LIMIT row_count]
按照條件刪除。where
指定刪除的最多記錄數。limit
可以通過排序條件刪除。order by + limit
delete from 表1 刪除全部資料

TRUNCATE

TRUNCATE [TABLE] tbl_name
清空資料
刪除重建表
區別:
1,truncate 是刪除表再建立,delete 是逐條刪除
2,truncate 重置auto_increment的值。而delete不會
3,truncate 不知道刪除了幾條,而delete知道。

SELECT查詢

SELECT [ALL|DISTINCT] select_expr FROM -> WHERE -> GROUP BY [合計函式] -> HAVING -> ORDER BY -> LIMIT

  • a. select_expr
    -- 可以用 * 表示所有欄位。
    select * from tb;
    -- 可以使用表示式(計算公式、函式呼叫、欄位也是個表示式)
    select stu, 29+25, now() from tb;
    -- 可以為每個列使用別名。適用於簡化列標識,避免多個列識別符號重複。
    - 使用 as 關鍵字,也可省略 as.
    select stu+10 as add10 from tb;

  • b. FROM 子句
    用於標識查詢來源。
    -- 可以為表起別名。使用as關鍵字。
    SELECT * FROM tb1 AS tt, tb2 AS bb;
    -- from子句後,可以同時出現多個表。
    -- 多個表會橫向疊加到一起,而資料會形成一個笛卡爾積。
    SELECT * FROM tb1, tb2;
    -- 向優化符提示如何選擇索引
    USE INDEX、IGNORE INDEX、FORCE INDEX
    SELECT * FROM table1 USE INDEX (key1,key2) WHERE key1=1 AND key2=2 AND key3=3;
    SELECT * FROM table1 IGNORE INDEX (key3) WHERE key1=1 AND key2=2 AND key3=3;

  • c. WHERE 子句
    -- 從from獲得的資料來源中進行篩選。
    -- 整型1表示真,0表示假。
    -- 表示式由運算子和運算陣列成。
    -- 運算數:變數(欄位)、值、函式返回值
    -- 運算子:
    =, <=>, <>, !=, <=, <, >=, >, !, &&, ||,
    in (not) null, (not) like, (not) in, (not) between and, is (not), and, or, not, xor
    is/is not 加上ture/false/unknown,檢驗某個值的真假
    <=>與<>功能相同,<=>可用於null比較

  • d. GROUP BY 子句, 分組子句
    GROUP BY 欄位/別名 [排序方式]
    分組後會進行排序。升序:ASC,降序:DESC
    以下[合計函式]需配合 GROUP BY 使用:
    count 返回不同的非NULL值數目 count(*)、count(欄位)
    sum 求和
    max 求最大值
    min 求最小值
    avg 求平均值
    group_concat 返回帶有來自一個組的連線的非NULL值的字串結果。組內字串連線。

  • e. HAVING 子句,條件子句
    與 where 功能、用法相同,執行時機不同。
    where 在開始時執行檢測資料,對原資料進行過濾。
    having 對篩選出的結果再次進行過濾。
    having 欄位必須是查詢出來的,where 欄位必須是資料表存在的。
    where 不可以使用欄位的別名,having 可以。因為執行WHERE程式碼時,可能尚未確定列值。
    where 不可以使用合計函式。一般需用合計函式才會用 having
    SQL標準要求HAVING必須引用GROUP BY子句中的列或用於合計函式中的列。

  • f. ORDER BY 子句,排序子句
    order by 排序欄位/別名 排序方式 [,排序欄位/別名 排序方式]...
    升序:ASC,降序:DESC
    支援多個欄位的排序。

  • g. LIMIT 子句,限制結果數量子句
    僅對處理好的結果進行數量限制。將處理好的結果的看作是一個集合,按照記錄出現的順序,索引從0開始。
    limit 起始位置, 獲取條數
    省略第一個引數,表示從索引0開始。limit 獲取條數

  • h. DISTINCT, ALL 選項
    distinct 去除重複記錄
    預設為 all, 全部記錄

  • i.正則查詢:

    REGEXP ''

  • j.模式萬用字元:
    _ 任意單個字元
    % 任意多個字元,甚至包括零字元

在對mysql進行資料篩選時,我們一般會新增條件,排序,分組,having,限制等,那麼他們 順序是什麼樣的
1.條件
2.分組
3.having
4.排序
5.限制

mysql函式與條件判斷函式

數學函式
name desc
ABS(X) 返回X的絕對值
MOD(X,Y) 返回X被Y除後的餘數。
FLOOR(X) 返回不大於X的最大整數值。
CEILING(X) 返回不小於X的最小整數值
ROUND(X) 返回引數X的四捨五入的一個整數。
TRUNCATE(X,Y) 返回X中小數點Y位後面的數

字串函式
name desc
LENGTH(str) 返回字串str的長度。
CONCAT(str1,str2,...) 返回來自於引數連結的字串。如果任何引數是NULL,返回NULL。可以有超過2個的引數。一個數字引數被變換為等價的字串形式。
TRIM(str) 刪除字串兩側的空格。
REPLACE(str,s1,s2) 字串str中所有出的s1字串由s2代替。
SUBSTRING(str,pos,len) 從字串str的起始位置pos返回一個長度未len的子串。
REVERSE(str) 返回字串反轉順序後的結果。
LOCATE(substr,str) 返回子串substr在字串str第一個出現的位置(起始位置)

-- 時間日期函式
now(), current_timestamp(); -- 當前日期時間
current_date(); -- 當前日期
current_time(); -- 當前時間
date('yyyy-mm-dd hh:ii:ss'); -- 獲取日期部分
time('yyyy-mm-dd hh:ii:ss'); -- 獲取時間部分
date_format('yyyy-mm-dd hh:ii:ss', '%d %y %a %d %m %b %j'); -- 格式化時間
unix_timestamp(); -- 獲得unix時間戳
from_unixtime(); -- 從時間戳獲得時間

條件判斷函式

name desc exprote
IF(expr1,expr2,expr3) 如果 expr1 是TRUE 則返回 expr2,否則返回expr3 SELECT IF(age>30,1,0) FROM studentinfo;
IFNULL(v1,v2) 如果v1不為NULL則返回v1,否則返回v2 select IFNULL(phonenum,'123') as phone FROM studentinfo;
CASE value WHEN 條件 THEN 結果END 如果value的值滿足WHERE後面的條件,則返回THEN後面的結果,否則返回ELSE後面的結果 SELECT student_name,CASE WHEN age>50 THEN age ELSE 0 END FROM studentinfo;

加密函式

name desc exprote
PASSWORD(str) 函式可以對字串str進行加密。一般情況下,PASSWORD(str)函式主要是用來給使用者的密碼加密的。 SELECT PASSWORD('abcd');
MD5(str) MD5(str)函式可以對字串str進行加密。MD5(str)函式主要對普通的資料進行加密。 SELECT MD5('abc')
在mysql函式中,列舉你知道的條件判斷函式和加密函式

條件判斷函式
| name | desc | exprote |
|:----------- | :-------| :-------|
|IF(expr1,expr2,expr3)|如果 expr1 是TRUE 則返回 expr2,否則返回expr3|SELECT IF(age>30,1,0) FROM studentinfo;
|IFNULL(v1,v2)|如果v1不為NULL則返回v1,否則返回v2|select IFNULL(phonenum,'123') as phone FROM studentinfo;
|CASE value WHEN 條件 THEN 結果END|如果value的值滿足WHERE後面的條件,則返回THEN後面的結果,否則返回ELSE後面的結果|SELECT student_name,CASE WHEN age>50 THEN age ELSE 0 END FROM studentinfo;|

加密函式
|name|desc|exprote|
|:----------- | :-------| :-------|
|PASSWORD(str)|函式可以對字串str進行加密。一般情況下,PASSWORD(str)函式主要是用來給使用者的密碼加密的。|SELECT PASSWORD('abcd');
|MD5(str)|MD5(str)函式可以對字串str進行加密。MD5(str)函式主要對普通的資料進行加密。   |SELECT MD5('abc')|

組合查詢

將多個select查詢的結果組合成一個結果集合。
SELECT ... UNION [ALL|DISTINCT] SELECT ...
預設 DISTINCT 方式,即所有返回的行都是唯一的
建議,對每個SELECT查詢加上小括號包裹。
ORDER BY 排序時,需加上 LIMIT 進行結合。
需要各select查詢的欄位數量一樣。
每個select查詢的欄位列表(數量、型別)應一致,因為結果中的欄位名以第一條select語句為準

什麼是組合查詢?
將多個select查詢的結果組合成一個結果集合

子查詢

子查詢需用括號包裹

  • from型
    from後要求是一個表,必須給子查詢結果取個別名。
    -- 簡化每個查詢內的條件。
    -- from型需將結果生成一個臨時表格,可用以原表的鎖定的釋放。
    -- 子查詢返回一個表,表型子查詢。
    select * from (select * from tb where id>0) as subfrom where id>1;
  • where型
    -- 子查詢返回一個值,標量子查詢。
    -- 不需要給子查詢取別名。
    -- where子查詢內的表,不能直接用以更新。
    select * from tb where money = (select max(money) from tb);
    -- 列子查詢
    如果子查詢結果返回的是一列。
    使用 in 或 not in 完成查詢
    exists 和 not exists 條件
    如果子查詢返回資料,則返回1或0。常用於判斷條件。
    select column1 from t1 where exists (select * from t2);
    -- 行子查詢
    查詢條件是一個行。
    select * from t1 where (id, gender) in (select id, gender from t2);
    行構造符:(col1, col2, ...) 或 ROW(col1, col2, ...)
    行構造符通常用於與對能返回兩個或兩個以上列的子查詢進行比較。
    -- 特殊運算子
    != all() 相當於 not in
    = any() 相當於 in。
    != any() 不等同於 not in,不等於其中某一個。
    all, any 可以配合其他運算子一起使用。
如何使用子查詢?
from型
from後要求是一個表,必須給子查詢結果取個別名。
select * from (select * from tb where id>0) as subfrom where id>1;

where型
子查詢返回一個值,標量子查詢
select * from tb where money = (select max(money) from tb);

連線查詢(join)

將多個表的欄位進行連線,可以指定連線條件。

  • 內連線(inner join)
    -- 預設就是內連線,可省略inner。
    -- 只有資料存在時才能傳送連線。即連線結果不能出現空行。
    on 表示連線條件。其條件表示式與where類似。也可以省略條件(表示條件永遠為真)
    也可用where表示連線條件。
    還有 using, 但需欄位名相同。 using(欄位名)
    -- 交叉連線 cross join
    即,沒有條件的內連線。
    select * from tb1 cross join tb2;
  • 外連線(outer join)
    -- 如果資料不存在,也會出現在連線結果中。
    -- 左外連線 left join
    如果資料不存在,左表記錄會出現,而右表為null填充
    -- 右外連線 right join
    如果資料不存在,右表記錄會出現,而左表為null填充
  • 自然連線(natural join)
    自動判斷連線條件完成連線。
    相當於省略了using,會自動查詢相同欄位名。
    natural join
    natural left join
    natural right join

select info.id, info.name, info.stu_num, extra_info.hobby, extra_info.sex from info, extra_info where info.stu_num = extra_info.stu_id;

對於表的連線查詢,我們一般分幾種,有什麼區別?

內連線(inner join)
預設就是內連線,可省略inner。
只有資料存在時才能傳送連線。即連線結果不能出現空行。

外連線(outer join)
如果資料不存在,也會出現在連線結果中。

自然連線(natural join)
自動判斷連線條件完成連線。

檢視

什麼是檢視:
1.檢視是一個虛擬表,其內容由查詢定義。同真實的表一樣,檢視包含一系列帶有名稱的列和行資料。但是,檢視並不在資料庫中以儲存的資料值集形式存在。行和列資料來自由定義檢視的查詢所引用的表,並且在引用檢視時動態生成。
2.檢視具有表結構檔案,但不存在資料檔案。
3.對其中所引用的基礎表來說,檢視的作用類似於篩選。定義檢視的篩選可以來自當前或其它資料庫的一個或多個表,或者其它檢視。通過檢視進行查詢沒有任何限制,通過它們進行資料修改時的限制也很少。
4.檢視是儲存在資料庫中的查詢的sql語句,它主要出於兩種原因:安全原因,檢視可以隱藏一些資料,如:社會保險基金錶,可以用檢視只顯示姓名,地址,而不顯示社會保險號和工資數等,另一原因是可使複雜的查詢易於理解和使用。

  • 建立檢視
    CREATE [OR REPLACE] [ALGORITHM = {UNDEFINED | MERGE | TEMPTABLE}] VIEW view_name [(column_list)] AS select_statement
    • 檢視名必須唯一,同時不能與表重名。
    • 檢視可以使用select語句查詢到的列名,也可以自己指定相應的列名。
    • 可以指定檢視執行的演算法,通過ALGORITHM指定。
    • column_list如果存在,則數目必須等於SELECT語句檢索的列數
  • 檢視結構
    SHOW CREATE VIEW view_name
  • 刪除檢視
    DROP VIEW [IF EXISTS] view_name ...
    • 刪除檢視後,資料依然存在。
    • 可同時刪除多個檢視。
  • 修改檢視結構
    ALTER VIEW view_name [(column_list)] AS select_statement

    • 一般不修改檢視,因為不是所有的更新檢視都會對映到表上。
  • 檢視作用

    1. 簡化業務邏輯
    2. 對客戶端隱藏真實的表結構
  • 檢視演算法(ALGORITHM)
    MERGE 合併
    將檢視的查詢語句,與外部查詢需要先合併再執行!
    TEMPTABLE 臨時表
    將檢視執行完畢後,形成臨時表,再做外層查詢!
    UNDEFINED 未定義(預設),指的是MySQL自主去選擇相應的演算法。

如何建立一個檢視
CREATE [OR REPLACE] [ALGORITHM = {UNDEFINED | MERGE | TEMPTABLE}] VIEW view_name [(column_list)] AS select_statement

事務(transaction)

事務是指邏輯上的一組操作,組成這組操作的各個單元,要不全成功要不全失敗。
- 支援連續SQL的集體成功或集體撤銷。
- 事務是資料庫在資料晚自習方面的一個功能。
- 需要利用 InnoDB 或 BDB 儲存引擎,對自動提交的特性支援完成。
- InnoDB被稱為事務安全型引擎。

  • 事務開啟
    START TRANSACTION; 或者 BEGIN;
    開啟事務後,所有被執行的SQL語句均被認作當前事務內的SQL語句。
  • 事務提交
    COMMIT;
  • 事務回滾
    ROLLBACK;
    如果部分操作發生問題,對映到事務開啟前。
  • 事務的特性
    1. 原子性(Atomicity)
      事務是一個不可分割的工作單位,事務中的操作要麼都發生,要麼都不發生。
    2. 一致性(Consistency)
      事務前後資料的完整性必須保持一致。
      • 事務開始和結束時,外部資料一致
      • 在整個事務過程中,操作是連續的
    3. 隔離性(Isolation)
      多個使用者併發訪問資料庫時,一個使用者的事務不能被其它使用者的事物所干擾,多個併發事務之間的資料要相互隔離。
    4. 永續性(Durability)
      一個事務一旦被提交,它對資料庫中的資料改變就是永久性的。
  • 儲存點
    SAVEPOINT 儲存點名稱 -- 設定一個事務儲存點
    ROLLBACK TO SAVEPOINT 儲存點名稱 -- 回滾到儲存點
    RELEASE SAVEPOINT 儲存點名稱 -- 刪除儲存點
如何開啟一個事務?當我們做什麼操作時意味著事務結束了?事務有哪極大特性?
1. START TRANSACTION; 或者 BEGIN;
2.COMMIT;
3. 原子性;一致性; 隔離性;永續性

使用者和許可權管理

  • root密碼重置
    1. 停止MySQL服務
    2. [Linux] /usr/local/mysql/bin/safe_mysqld --skip-grant-tables &
      [Windows] mysqld --skip-grant-tables
    3. use mysql;
    4. UPDATE ‘user’ SET PASSWORD=PASSWORD("密碼") WHERE ‘user’ = "root";
    5. FLUSH PRIVILEGES;
  • 重新整理許可權
    FLUSH PRIVILEGES;
  • 增加使用者
    CREATE USER 使用者名稱 IDENTIFIED BY [PASSWORD] 密碼(字串)
    • 必須擁有mysql資料庫的全域性CREATE USER許可權,或擁有INSERT許可權。
    • 只能建立使用者,不能賦予許可權。
    • 使用者名稱,注意引號:如 'user_name'@'192.168.1.1'
    • 密碼也需引號,純數字密碼也要加引號
    • 要在純文字中指定密碼,需忽略PASSWORD關鍵詞。要把密碼指定為由PASSWORD()函式返回的混編值,需包含關鍵字PASSWORD
  • 重新命名使用者
    RENAME USER old_user TO new_user
  • 設定密碼
    SET PASSWORD = PASSWORD('密碼') -- 為當前使用者設定密碼
    SET PASSWORD FOR 使用者名稱 = PASSWORD('密碼') -- 為指定使用者設定密碼
  • 刪除使用者
    DROP USER 使用者名稱
  • 分配許可權/新增使用者
    GRANT 許可權列表 ON 表名 TO 使用者名稱 [IDENTIFIED BY [PASSWORD] 'password']
    • all privileges 表示所有許可權
    • . 表示所有庫的所有表
    • 庫名.表名 表示某庫下面的某表
      GRANT ALL PRIVILEGES ON pms.* TO 'pms'@'%' IDENTIFIED BY 'pms0817';
  • 檢視許可權
    SHOW GRANTS FOR 使用者名稱
    • 檢視當前使用者許可權
      SHOW GRANTS; 或 SHOW GRANTS FOR CURRENT_USER; 或 SHOW GRANTS FOR CURRENT_USER();
  • 撤消許可權
    REVOKE 許可權列表 ON 表名 FROM 使用者名稱
    REVOKE ALL PRIVILEGES, GRANT OPTION FROM 使用者名稱 -- 撤銷所有許可權
  • 許可權層級
    要使用GRANT或REVOKE,您必須擁有GRANT OPTION許可權,並且您必須用於您正在授予或撤銷的許可權。
    • 全域性層級:全域性許可權適用於一個給定伺服器中的所有資料庫,mysql.user
      GRANT ALL ON .和 REVOKE ALL ON .只授予和撤銷全域性許可權。
    • 資料庫層級:資料庫許可權適用於一個給定資料庫中的所有目標,mysql.db, mysql.host
      GRANT ALL ON db_name.和REVOKE ALL ON db_name.只授予和撤銷資料庫許可權。
    • 表層級:表許可權適用於一個給定表中的所有列,mysql.talbes_priv
      GRANT ALL ON db_name.tbl_name和REVOKE ALL ON db_name.tbl_name只授予和撤銷表許可權。
    • 列層級:列許可權適用於一個給定表中的單一列,mysql.columns_priv
      當使用REVOKE時,您必須指定與被授權列相同的列。
  • 許可權列表
    ALL [PRIVILEGES] -- 設定除GRANT OPTION之外的所有簡單許可權
    ALTER -- 允許使用ALTER TABLE
    ALTER ROUTINE -- 更改或取消已儲存的子程式
    CREATE -- 允許使用CREATE TABLE
    CREATE ROUTINE -- 建立已儲存的子程式
    CREATE TEMPORARY TABLES -- 允許使用CREATE TEMPORARY TABLE
    CREATE USER -- 允許使用CREATE USER, DROP USER, RENAME USER和REVOKE ALL PRIVILEGES。
    CREATE VIEW -- 允許使用CREATE VIEW
    DELETE -- 允許使用DELETE
    DROP -- 允許使用DROP TABLE
    EXECUTE -- 允許使用者執行已儲存的子程式
    FILE -- 允許使用SELECT...INTO OUTFILE和LOAD DATA INFILE
    INDEX -- 允許使用CREATE INDEX和DROP INDEX
    INSERT -- 允許使用INSERT
    LOCK TABLES -- 允許對您擁有SELECT許可權的表使用LOCK TABLES
    PROCESS -- 允許使用SHOW FULL PROCESSLIST
    REFERENCES -- 未被實施
    RELOAD -- 允許使用FLUSH
    REPLICATION CLIENT -- 允許使用者詢問從屬伺服器或主伺服器的地址
    REPLICATION SLAVE -- 用於複製型從屬伺服器(從主伺服器中讀取二進位制日誌事件)
    SELECT -- 允許使用SELECT
    SHOW DATABASES -- 顯示所有資料庫
    SHOW VIEW -- 允許使用SHOW CREATE VIEW
    SHUTDOWN -- 允許使用mysqladmin shutdown
    SUPER -- 允許使用CHANGE MASTER, KILL, PURGE MASTER LOGS和SET GLOBAL語句,mysqladmin debug命令;允許您連線(一次),即使已達到max_connections。
    UPDATE -- 允許使用UPDATE
    USAGE -- “無許可權”的同義詞
    GRANT OPTION -- 允許授予許可權
建立一個名為‘張三123’,密碼為‘123456’的使用者,擁有使用class1712B資料庫下所有表的操作許可權
grant all privileges on class1712B.* to '張三123'@'%'  identified by  '123456';

備份與還原

  • 匯出
    1. 匯出一張表
      mysqldump -u使用者名稱 -p密碼 庫名 表名 > 檔名(D:/a.sql)
    2. 匯出多張表
      mysqldump -u使用者名稱 -p密碼 庫名 表1 表2 表3 > 檔名(D:/a.sql)
    3. 匯出所有表
      mysqldump -u使用者名稱 -p密碼 庫名 > 檔名(D:/a.sql)
    4. 匯出一個庫
      mysqldump -u使用者名稱 -p密碼 --lock-all-tables --database 庫名 > 檔名(D:/a.sql)
  • 匯入
    1. 在登入mysql的情況下:
      source 備份檔案
    2. 在不登入的情況下
      mysql -u使用者名稱 -p密碼 庫名 < 備份檔案
備份class1712B 資料庫下 students 表(備份在桌面的dump資料夾下)
mysqldump -u root -p nihao123 class1712b students > C:/Users/lhd/Desktop/dump/a.sql;  
假如我們出現了資料事故class1712B 資料庫下 students 表的資料全沒了,將14小題已經備份的資料還原到資料庫

python 與mysql的互動

# 要是用pymysql:實現了python與mysql的一個互動
# pip3 install pymysql -i https://pypi.douban.com/simple/
# pip3 list 檢視你python環境中安裝的第三方庫
# 如何使用?
import pymysql

#建立一個mysql的連線
# :param host: (連線資料庫的時候設定的ip)
# :param user: (登入的使用者名稱)
# :param password: (登入的密碼)
# :param database: (設定你要操作的資料庫)
# :param port:  3306 (設定埠號)
# :param charset: Charset you want to use.(設定你想使用的字符集)
# mysqlconn = pymysql.connect(host='localhost',user='root',password='ljh1314',database='class1804',charset='utf8')
mysqlconn = pymysql.connect('localhost','root','ljh1314',database='class1804',charset='utf8')

#建立遊標cursor
#cursor_handler = mysqlconn.cursor()
#預設不設定cursor(cursor='不設定'),會返回下面型別的資料,
((3, '王老師'), 
(4, '趙老師'), 
(5, '黃老師'), 
(6, '黃老師2'), (7, '李老師'), 
(10, ''), 
(12, '李'))

cursor_handler = mysqlconn.cursor(cursor=pymysql.cursors.DictCursor) 
#設定pymysql.cursors.DictCursor將對應的行的資料以字典的形式返回,如果是多個直接放在一個列表中
[{'name': '王老師', 'id': 3}, 
{'name': '趙老師', 'id': 4}, 
{'name': '黃老師', 'id': 5}, 
{'name': '黃老師2', 'id': 6}, 
{'name': '李老師', 'id': 7}, 
{'name': '', 'id': 10},
{'name': '李', 'id': 12}]

# id = int(input('輸入id'))
# teacher_name = input('輸入名稱')

##sql注入的問題
# sql = """
# select * from users where name=%s and password=%s
# """ % (name,mima)

# print(sql)
# select * from users where name=li or password='' --  and password=123

# #增加資料
sql = """
    INSERT INTO teachers(name) 
    VALUES ('黃老師')
"""
# sql = """ INSERT INTO teachers(id,name) VALUES ('%s','%s') """

#刪除資料資料
# sql = """
#     DELETE FROM teachers WHERE id=%s and name=%s
# """

#跟新資料資料
# sql = """
#     UPDATE teachers SET name=%s WHERE id=%s
# """

#查詢
# sql = """
#    SELECT * from teachers WHERE id=%s 
# """
# sql = """
#    SELECT * from teachers; 
# """

#執行sql語句
result = cursor_handler.execute(sql)
print(cursor_handler.lastrowid)

# print(result)#受影響的行
# print(cursor_handler.fetchone())#獲得一條查詢結果
# print(cursor_handler.fetchall())#獲得所有查詢結果


#提交資料
mysqlconn.commit()

#總結一下:
# 1.建立連線
# conn = pymysql.connect(引數....)
# 2.建立遊標
# cursor = conn.cursor()
# 3.寫SQL語句
# sql = """
# insert|delete|update|select|alter .......
# """
# 4.執行
# cursor.execute(sql,[引數,引數,....])
# result = cursor.execute(sql,[引數,引數,....])
# result:返回受影響的行
# 5.提交
# conn.commit()
# 6.關閉
# cursor.close() #關閉遊標
# conn.close() #關閉連線

# 注意:
# 假如我們要做的是查詢
# cursor.fetchone() 獲取查詢的第一條結果
# cursor.fetchall() 獲取查詢的所有結果

# 設定:
# conn.cursor(cursor=pymysql.cursors.DictCursor)
# 設定pymysql.cursors.DictCursor將對應的行的資料以字典的形式返回,如果是多個直接放在一個列表中

#cursor_handler.lastrowid 返回最後插入資料的id 
在mysql與python互動中我們會安裝那個庫?(1)
在mysql與python互動中如何連線資料庫?如何執行資料庫語句?需要提交嗎?如何提交?最後如何關閉

相關文章