PHP 詳細面試總結 (五 每日更新)

A_aliane發表於2019-03-18

Windows服務

啟動MySQL
net start mysql

建立Windows服務
sc create mysql binPath= mysqld_bin_path(注意:等號與值之間有空格)

連線與斷開伺服器

mysql -h 地址 -P 埠 -u 使用者名稱 -p 密碼

SHOW PROCESSLIST 顯示哪些執行緒正在執行
SHOW VARIABLES 顯示系統變數資訊

資料庫操作

檢視當前資料庫

SELECT DATABASE();

顯示當前時間、使用者名稱、資料庫版本

SELECT now(), user(), version();

建立庫

     CREATE DATABASE[ IF NOT EXISTS] 資料庫名 資料庫選項

資料庫選項:

CHARACTER SET charset_name
COLLATE collation_name

檢視已有庫

SHOW DATABASES[ LIKE 'PATTERN']

檢視當前庫資訊

SHOW CREATE DATABASE 資料庫名

修改庫的選項資訊

ALTER DATABASE 庫名 選項資訊

刪除庫

DROP DATABASE[ IF EXISTS] 資料庫名

同時刪除該資料庫相關的目錄及其目錄內容

表的操作

 建立表
CREATE [TEMPORARY] TABLE[ IF NOT EXISTS] [庫名.]表名 ( 表的結構定義 )[ 表選項]
每個欄位必須有資料型別
最後一個欄位後不能有逗號
TEMPORARY 臨時表,會話結束時表自動消失
對於欄位的定義:
欄位名 資料型別 [NOT NULL | NULL] [DEFAULT default_value] [AUTO_INCREMENT] [UNIQUE [KEY] | [PRIMARY] KEY] [COMMENT 'string']
 表選項
 字符集
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 = 行數
 資料檔案目錄
DATA DIRECTORY = '目錄'
 索引檔案目錄
INDEX DIRECTORY = '目錄'
 表註釋
COMMENT = 'string'
 分割槽選項
PARTITION BY ... (詳細見手冊)

 檢視所有表
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 表名 表的選項
eg: ALTER TABLE 表名 ENGINE=MYISAM;
 對錶進行重新命名
RENAME TABLE 原表名 TO 新表名
RENAME TABLE 原表名 TO 庫名.表名 (可將表移動到另一個資料庫)
 RENAME可以交換兩個表名
 修改表的欄位機構(13.1.2. ALTER TABLE語法)
ALTER TABLE 表名 操作名
 操作名
ADD[ COLUMN] 欄位定義        增加欄位
AFTER 欄位名           表示增加在該欄位名後面
FIRST                表示增加在第一個
ADD PRIMARY KEY(欄位名)    建立主鍵
ADD UNIQUE [索引名] (欄位名) 建立唯一索引
ADD INDEX [索引名] (欄位名)  建立普通索引
DROP[ COLUMN] 欄位名       刪除欄位
MODIFY[ COLUMN] 欄位名 欄位屬性      支援對欄位屬性進行修改,不能修改欄位名(所有原有屬性也需寫上)
CHANGE[ COLUMN] 原欄位名 新欄位名 欄位屬性       支援對欄位名修改
DROP PRIMARY KEY     刪除主鍵(刪除主鍵前需刪除其AUTO_INCREMENT屬性)
DROP INDEX 索引名  刪除索引
DROP FOREIGN KEY 外來鍵     刪除外來鍵
 刪除表
DROP TABLE[ IF EXISTS] 表名 ...

 清空表資料
TRUNCATE [TABLE] 表名

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

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

 檢查表是否有錯誤
CHECK TABLE tbl_name [, tbl_name] ... [option] ...

 優化表
OPTIMIZE [LOCAL | NO_WRITE_TO_BINLOG] TABLE tbl_name [, tbl_name] ...

 修復表
REPAIR [LOCAL | NO_WRITE_TO_BINLOG] TABLE tbl_name [, tbl_name] ... [QUICK] [EXTENDED] [USE_FRM]

 分析表
ANALYZE [LOCAL | NO_WRITE_TO_BINLOG] TABLE tbl_name [, tbl_name] ...

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

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

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

 改
UPDATE 表名 SET 欄位名=新值[, 欄位名=新值] [更新條件]
## 字符集編碼
 MySQL、資料庫、表、欄位均可設定編碼
 資料編碼與客戶端編碼不需一致
SHOW VARIABLES LIKE 'character_set_%'    檢視所有字符集編碼項
character_set_client        客戶端向伺服器傳送資料時使用的編碼
character_set_results       伺服器端將結果返回給客戶端所使用的編碼
character_set_connection    連線層編碼
SET 變數名 = 變數值
SET character_set_client = gbk;
SET character_set_results = gbk;
SET character_set_connection = gbk;
SET NAMES GBK;   相當於完成以上三個設定

 校對集
校對集用以排序
SHOW CHARACTER SET [LIKE 'pattern']/SHOW CHARSET [LIKE 'pattern']   檢視所有字符集
SHOW COLLATION [LIKE 'pattern']     檢視所有校對集
CHARSET 字符集編碼     設定字符集編碼
COLLATE 校對集編碼     設定校對集編碼

資料型別(列型別)

1. 數值型別
 a. 整型 
型別         位元組     範圍(有符號位)
tinyint     1位元組    -128 ~ 127      無符號位:0 ~ 255
smallint    2位元組    -32768 ~ 32767
mediumint   3位元組    -8388608 ~ 8388607
int         4位元組
bigint      8位元組
int(M)  M表示總位數
- 預設存在符號位,unsigned 屬性修改
- 顯示寬度,如果某個數不夠定義欄位時設定的位數,則前面以0補填,zerofill 屬性修改
例:int(5)   插入一個數'123',補填後為'00123'
- 在滿足要求的情況下,越小越好。
- 1表示bool值真,0表示bool值假。MySQL沒有布林型別,通過整型0和1表示。常用tinyint(1)表示布林型。

 b. 浮點型 
型別             位元組     範圍
float(單精度)     4位元組
double(雙精度)    8位元組
浮點型既支援符號位 unsigned 屬性,也支援顯示寬度 zerofill 屬性。
不同於整型,前後均會補填0.
定義浮點型時,需指定總位數和小數位數。
float(M, D)     double(M, D)
M表示總位數,D表示小數位數。
M和D的大小會決定浮點數的範圍。不同於整型的固定範圍。
M既表示總位數(不包括小數點和正負號),也表示顯示寬度(所有顯示符號均包括)。
支援科學計數法表示。
浮點數表示近似值。

 c. 定點數 
decimal  可變長度
decimal(M, D)   M也表示總位數,D表示小數位數。
儲存一個精確的數值,不會發生資料的改變,不同於浮點數的四捨五入。
將浮點數轉換為字串來儲存,每9位數字儲存為4個位元組。

2. 字串型別
 a. char, varchar 
char    定長字串,速度快,但浪費空間
varchar 變長字串,速度慢,但節省空間
M表示能儲存的最大長度,此長度是字元數,非位元組數。
不同的編碼,所佔用的空間不同。
char,最多255個字元,與編碼無關。
varchar,最多65535字元,與編碼有關。
一條有效記錄最大不能超過65535個位元組。
utf8 最大為21844個字元,gbk 最大為32766個字元,latin1 最大為65532個字元
varchar 是變長的,需要利用儲存空間儲存 varchar 的長度,如果資料小於255個位元組,則採用一個位元組來儲存長度,反之需要兩個位元組來儲存。
varchar 的最大有效長度由最大行大小和使用的字符集確定。
最大有效長度是65532位元組,因為在varchar存字串時,第一個位元組是空的,不存在任何資料,然後還需兩個位元組來存放字串的長度,所以有效長度是64432-1-2=65532位元組。
例:若一個表定義為 CREATE TABLE tb(c1 int, c2 char(30), c3 varchar(N)) charset=utf8; 問N的最大值是多少? 答:(65535-1-2-4-30*3)/3

 b. blob, text 
blob 二進位制字串(位元組字串)
tinyblob, blob, mediumblob, longblob
text 非二進位制字串(字元字串)
tinytext, text, mediumtext, longtext
text 在定義時,不需要定義長度,也不會計算總長度。
text 型別在定義時,不可給default值

 c. binary, varbinary 
類似於char和varchar,用於儲存二進位制字串,也就是儲存位元組字串而非字元字串。
char, varchar, text 對應 binary, varbinary, blob.

3. 日期時間型別
一般用整型儲存時間戳,因為PHP可以很方便的將時間戳進行格式化。
datetime    8位元組    日期及時間     1000-01-01 00:00:00 到 9999-12-31 23:59:59
date        3位元組    日期         1000-01-01 到 9999-12-31
timestamp   4位元組    時間戳        19700101000000 到 2038-01-19 03:14:07
time        3位元組    時間         -838:59:59 到 838:59:59
year        1位元組    年份         1901 - 2155
datetime    YYYY-MM-DD hh:mm:ss
timestamp   YY-MM-DD hh:mm:ss
YYYYMMDDhhmmss
YYMMDDhhmmss
YYYYMMDDhhmmss
YYMMDDhhmmss
date        YYYY-MM-DD
YY-MM-DD
YYYYMMDD
YYMMDD
YYYYMMDD
YYMMDD
time        hh:mm:ss
hhmmss
hhmmss
year        YYYY
YY
YYYY
YY

4. 列舉和集合
 列舉(enum) 
enum(val1, val2, val3...)
在已知的值中進行單選。最大數量為65535.
列舉值在儲存時,以2個位元組的整型(smallint)儲存。每個列舉值,按儲存的位置順序,從1開始逐一遞增。
表現為字串型別,儲存卻是整型。
NULL值的索引是NULL。
空字串錯誤值的索引值是0。
 集合(set) 
set(val1, val2, val3...)
create table tab ( gender set('男', '女', '無') );
insert into tab values ('男, 女');
最多可以有64個不同的成員。以bigint儲存,共8個位元組。採取位運算的形式。
當建立表時,SET成員值的尾部空格將自動被刪除。

選擇型別

 PHP角度
1. 功能滿足
2. 儲存空間儘量小,處理效率更高
3. 考慮相容問題

 IP儲存 
1. 只需儲存,可用字串
2. 如果需計算,查詢等,可儲存為4個位元組的無符號int,即unsigned
1) PHP函式轉換
ip2long可轉換為整型,但會出現攜帶符號問題。需格式化為無符號的整型。
利用sprintf函式格式化字串
sprintf("%u", ip2long('192.168.3.134'));
然後用long2ip將整型轉回IP字串
2) MySQL函式轉換(無符號整型,UNSIGNED)
INET_ATON('127.0.0.1') 將IP轉為整型
INET_NTOA(2130706433) 將整型轉為IP
## 列屬性(列約束)

1. 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));

2. UNIQUE 唯一索引(唯一約束)
使得某欄位的值也不能重複。

3. NULL 約束
null不是資料型別,是列的一個屬性。
表示當前列是否可以為null,表示什麼都沒有。
null, 允許為空。預設。
not null, 不允許為空。
insert into tab values (null, 'val');
 此時表示將第一個欄位的值設為null, 取決於該欄位是否允許為null

4. DEFAULT 預設值屬性
當前欄位的預設值。
insert into tab values (default, 'val');     此時表示強制使用預設值。
create table tab ( add_time timestamp default current_timestamp );
 表示將當前時間的時間戳設為預設值。
current_date, current_time

5. AUTO_INCREMENT 自動增長約束
自動增長必須為索引(主鍵或unique)
只能存在一個欄位為自動增長。
預設為1開始自動增長。可以通過表屬性 auto_increment = x進行設定,或 alter table tbl auto_increment = x;

6. COMMENT 註釋
例:create table tab ( id int ) comment '註釋內容';

7. 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儲存引擎所支援。其他引擎是不支援的。

建表規範

 Normal Format, NF
- 每個表儲存一個實體資訊
- 每個具有一個ID欄位作為主鍵
- ID主鍵 + 原子表

 1NF, 第一正規化
欄位不能再分,就滿足第一正規化。

 2NF, 第二正規化
滿足第一正規化的前提下,不能出現部分依賴。
消除符合主鍵就可以避免部分依賴。增加單列關鍵字。

 3NF, 第三正規化
滿足第二正規化的前提下,不能出現傳遞依賴。
某個欄位依賴於主鍵,而有其他欄位依賴於該欄位。這就是傳遞依賴。
將一個實體資訊的資料放在一個表內實現。
## 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, 全部記錄

UNION

將多個select查詢的結果組合成一個結果集合。
SELECT ... UNION [ALL|DISTINCT] SELECT ...
預設 DISTINCT 方式,即所有返回的行都是唯一的
建議,對每個SELECT查詢加上小括號包裹。
ORDER BY 排序時,需加上 LIMIT 進行結合。
需要各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
= some()    相當於 in。any 是 some 的別名
!= some()   不等同於 not in,不等於其中某一個。
all, some 可以配合其他運算子一起使用。

連線查詢(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;

匯出

select * into outfile 檔案地址 [控制格式] from 表名;    匯出表資料

load data [local] infile 檔案地址 [replace|ignore] into table 表名 [控制格式];  匯入資料
生成的資料預設的分隔符是製表符
local未指定,則資料檔案必須在伺服器上
replace 和 ignore 關鍵詞控制對現有的唯一鍵記錄的重複的處理

 控制格式
fields  控制欄位格式
預設:fields terminated by '\t' enclosed by '' escaped by '\\'
terminated by 'string'   終止
enclosed by 'char'       包裹
escaped by 'char'        轉義

 示例:
SELECT a,b,a+b INTO OUTFILE '/tmp/result.text'
FIELDS TERMINATED BY ',' OPTIONALLY ENCLOSED BY '"'
LINES TERMINATED BY '\n'
FROM test_table;
lines   控制行格式
預設:lines terminated by '\n'
terminated by 'string'   終止

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,表2 using 表連線操作 條件。
## TRUNCATE
TRUNCATE [TABLE] tbl_name
清空資料
刪除重建表
區別:
1,truncate 是刪除表再建立,delete 是逐條刪除
2,truncate 重置auto_increment的值。而delete不會
3,truncate 不知道刪除了幾條,而delete知道。
4,當被用於帶分割槽的表時,truncate 會保留分割槽

備份與還原

備份,將資料的結構與表內資料儲存起來。
利用 mysqldump 指令完成。

 匯出
mysqldump [options] db_name [tables]
mysqldump [options] -database DB1 [DB2 DB3...]
mysqldump [options] alldatabase
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)
可以-w攜帶WHERE條件

 匯入
1. 在登入mysql的情況下:
  source  備份檔案
2. 在不登入的情況下
  mysql -u使用者名稱 -p密碼 庫名 < 備份檔案

檢視

什麼是檢視:

  • 檢視是一個虛擬表,其內容由查詢定義。同真實的表一樣,檢視包含一系列帶有名稱的列和行資料。但是,檢視並不在資料庫中以儲存的資料值集形式存在。行和列資料來自由定義檢視的查詢所引用的表,並且在引用檢視時動態生成。
  • 檢視具有表結構檔案,但不存在資料檔案。
  • 對其中所引用的基礎表來說,檢視的作用類似於篩選。定義檢視的篩選可以來自當前或其它資料庫的一個或多個表,或者其它檢視。通過檢視進行查詢沒有任何限制,通過它們進行資料修改時的限制也很少。
  • 檢視是儲存在資料庫中的查詢的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自主去選擇相應的演算法。

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

    事務開啟
    START TRANSACTION; 或者 BEGIN;
    開啟事務後,所有被執行的SQL語句均被認作當前事務內的SQL語句。

    事務提交
    COMMIT;

    事務回滾
    ROLLBACK;
    如果部分操作發生問題,對映到事務開啟前。

    
    事務的特性
    >     1. 原子性(Atomicity)
    >         事務是一個不可分割的工作單位,事務中的操作要麼都發生,要麼都不發生。
    >     2. 一致性(Consistency)
    >         事務前後資料的完整性必須保持一致。
    >         - 事務開始和結束時,外部資料一致
    >         - 在整個事務過程中,操作是連續的
    >     3. 隔離性(Isolation)
    >         多個使用者併發訪問資料庫時,一個使用者的事務不能被其它使用者的事物所干擾,多個併發事務之間的資料要相互隔離。
    >     4. 永續性(Durability)
    >         一個事務一旦被提交,它對資料庫中的資料改變就是永久性的。

事務的實現

1. 要求是事務支援的表型別
2. 執行一組相關的操作前開啟事務
3. 整組操作完成後,都成功,則提交;如果存在失敗,選擇回滾,則會回到事務開始的備份點。

事務的原理

  • 利用InnoDB的自動提交(autocommit)特性完成。
  • 普通的MySQL執行語句後,當前的資料提交操作均可被其他客戶端可見。
  • 而事務是暫時關閉“自動提交”機制,需要commit提交持久化資料操作。
    注意
    1. 資料定義語言(DDL)語句不能被回滾,比如建立或取消資料庫的語句,和建立、取消或更改表或儲存的子程式的語句。
    2. 事務不能被巢狀

儲存點

  • SAVEPOINT 儲存點名稱 設定一個事務儲存點
  • ROLLBACK TO SAVEPOINT 儲存點名稱 回滾到儲存點
  • RELEASE SAVEPOINT 儲存點名稱 刪除儲存點

InnoDB自動提交特性設定

  • SET autocommit = 0|1; 0表示關閉自動提交,1表示開啟自動提交。
    • 如果關閉了,那普通操作的結果對其他客戶端也不可見,需要commit提交後才能持久化資料操作。
    • 也可以關閉自動提交來開啟事務。但與START TRANSACTION不同的是,
  • SET autocommit是永久改變伺服器的設定,直到下次再次修改該設定。(針對當前連線)
  • 而START TRANSACTION記錄開啟前的狀態,而一旦事務提交或回滾後就需要再次開啟事務。(針對當前事務)

    鎖表

    表鎖定只用於防止其它客戶端進行不正當地讀取和寫入
    MyISAM 支援表鎖,InnoDB 支援行鎖

    鎖定
    LOCK TABLES tbl_name [AS alias]
    解鎖
    UNLOCK TABLES

觸發器

觸發程式是與表有關的命名資料庫物件,當該表出現特定事件時,將啟用該物件。
監聽:記錄的增加、修改、刪除。

 建立觸發器
CREATE TRIGGER trigger_name trigger_time trigger_event ON tbl_name FOR EACH ROW trigger_stmt
引數:
trigger_time是觸發程式的動作時間。它可以是 before 或 after,以指明觸發程式是在啟用它的語句之前或之後觸發。
trigger_event指明瞭啟用觸發程式的語句的型別
INSERT:將新行插入表時啟用觸發程式
UPDATE:更改某一行時啟用觸發程式
DELETE:從表中刪除某一行時啟用觸發程式
tbl_name:監聽的表,必須是永久性的表,不能將觸發程式與TEMPORARY表或檢視關聯起來。
trigger_stmt:當觸發程式啟用時執行的語句。執行多個語句,可使用BEGIN...END複合語句結構

 刪除
DROP TRIGGER [schema_name.]trigger_name
可以使用old和new代替舊的和新的資料
更新操作,更新前是old,更新後是new.
刪除操作,只有old.
增加操作,只有new.
 注意
1. 對於具有相同觸發程式動作時間和事件的給定表,不能有兩個觸發程式。
 字元連線函式
concat(str1,str2,...])
concat_ws(separator,str1,str2,...)

 分支語句
if 條件 then
執行語句
elseif 條件 then
執行語句
else
執行語句
end if;

 修改最外層語句結束符
delimiter 自定義結束符號
SQL語句
自定義結束符號
delimiter ;      修改回原來的分號

 語句塊包裹
begin
語句塊
end

 特殊的執行
1. 只要新增記錄,就會觸發程式。
2. Insert into on duplicate key update 語法會觸發:
如果沒有重複記錄,會觸發 before insert, after insert;
如果有重複記錄並更新,會觸發 before insert, before update, after update;
如果有重複記錄但是沒有發生更新,則觸發 before insert, before update
3. Replace 語法 如果有記錄,則執行 before insert, before delete, after delete, after insert

SQL程式設計

區域性變數


變數宣告
declare var_name[,...] type [default value]
這個語句被用來宣告區域性變數。要給變數提供一個預設值,請包含一個default子句。值可以被指定為一個表示式,不需要為一個常數。如果沒有default子句,初始值為null。
 賦值
使用 set 和 select into 語句為變數賦值。
- 注意:在函式內是可以使用全域性變數(使用者自定義的變數)

// 全域性變數 
 定義、賦值
set 語句可以定義併為變數賦值。
set @var = value;
也可以使用select into語句為變數初始化並賦值。這樣要求select語句只能返回一行,但是可以是多個欄位,就意味著同時為多個變數進行賦值,變數的數量需要與查詢的列數一致。
還可以把賦值語句看作一個表示式,通過select執行完成。此時為了避免=被當作關係運算子看待,使用:=代替。(set語句可以使用= 和 :=)。
select @var:=20;
select @v1:=id, @v2=name from t1 limit 1;
select * from tbl_name where @var:=30;
select into 可以將表中查詢獲得的資料賦給變數。
-| select max(height) into @max_height from tb;

 自定義變數名
為了避免select語句中,使用者自定義的變數與系統識別符號(通常是欄位名)衝突,使用者自定義變數在變數名前使用@作為開始符號。
@var=10;
- 變數被定義後,在整個會話週期都有效(登入到退出)

// 控制結構 
 if語句
if search_condition then
statement_list
[elseif search_condition then
statement_list]
...
[else
statement_list]
end if;
 case語句
CASE value WHEN [compare-value] THEN result
[WHEN [compare-value] THEN result ...]
[ELSE result]
END
 while迴圈
[begin_label:] while search_condition do
statement_list
end while [end_label];
- 如果需要在迴圈內提前終止 while迴圈,則需要使用標籤;標籤需要成對出現。
 退出迴圈
退出整個迴圈 leave
退出當前迴圈 iterate
通過退出的標籤決定退出哪個迴圈

// 內建函式 
 數值函式
abs(x)           絕對值 abs(-10.9) = 10
format(x, d)     格式化千分位數值 format(1234567.456, 2) = 1,234,567.46
ceil(x)          向上取整 ceil(10.1) = 11
floor(x)         向下取整 floor (10.1) = 10
round(x)         四捨五入去整
mod(m, n)        m%n m mod n 求餘 10%3=1
pi()             獲得圓周率
pow(m, n)        m^n
sqrt(x)          算術平方根
rand()           隨機數
truncate(x, d)   擷取d位小數

 時間日期函式
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();                 從時間戳獲得時間

 字串函式
length(string)           string長度,位元組
char_length(string)      string的字元個數
substring(str, position [,length])       從str的position開始,取length個字元
replace(str ,search_str ,replace_str)    在str中用replace_str替換search_str
instr(string ,substring)     返回substring首次在string中出現的位置
concat(string [,...])    連線字串
charset(str)             返回字串字符集
lcase(string)            轉換成小寫
left(string, length)     從string2中的左邊起取length個字元
load_file(file_name)     從檔案讀取內容
locate(substring, string [,start_position])  同instr,但可指定開始位置
lpad(string, length, pad)    重複用pad加在string開頭,直到字串長度為length
ltrim(string)            去除前端空格
repeat(string, count)    重複count次
rpad(string, length, pad)   在str後用pad補充,直到長度為length
rtrim(string)            去除後端空格
strcmp(string1 ,string2)     逐字元比較兩字串大小

 流程函式
case when [condition] then result [when [condition] then result ...] [else result] end   多分支
if(expr1,expr2,expr3)  雙分支。

 聚合函式
count()
sum();
max();
min();
avg();
group_concat()

 其他常用函式
md5();
default();

// 儲存函式,自定義函式 
 新建
CREATE FUNCTION function_name (引數列表) RETURNS 返回值型別
函式體
- 函式名,應該合法的識別符號,並且不應該與已有的關鍵字衝突。
- 一個函式應該屬於某個資料庫,可以使用db_name.funciton_name的形式執行當前函式所屬資料庫,否則為當前資料庫。
- 引數部分,由"引數名"和"引數型別"組成。多個引數用逗號隔開。
- 函式體由多條可用的mysql語句,流程控制,變數宣告等語句構成。
- 多條語句應該使用 begin...end 語句塊包含。
- 一定要有 return 返回值語句。

 刪除
DROP FUNCTION [IF EXISTS] function_name;

 檢視
SHOW FUNCTION STATUS LIKE 'partten'
SHOW CREATE FUNCTION function_name;

 修改
ALTER FUNCTION function_name 函式選項

// 儲存過程,自定義功能 
 定義
儲存儲存過程 是一段程式碼(過程),儲存在資料庫中的sql組成。
一個儲存過程通常用於完成一段業務邏輯,例如報名,交班費,訂單入庫等。
而一個函式通常專注與某個功能,視為其他程式服務的,需要在其他語句中呼叫函式才可以,而儲存過程不能被其他呼叫,是自己執行 通過call執行。

 建立
CREATE PROCEDURE sp_name (引數列表)
過程體
引數列表:不同於函式的引數列表,需要指明引數型別
IN,表示輸入型
OUT,表示輸出型
INOUT,表示混合型
注意,沒有返回值。

/* 儲存過程 */ 
儲存過程是一段可執行性程式碼的集合。相比函式,更偏向於業務邏輯。
呼叫:CALL 過程名
 注意
- 沒有返回值。
- 只能單獨呼叫,不可夾雜在其他語句中

 引數
IN|OUT|INOUT 引數名 資料型別
IN      輸入:在呼叫過程中,將資料輸入到過程體內部的引數
OUT     輸出:在呼叫過程中,將過程體處理完的結果返回到客戶端
INOUT   輸入輸出:既可輸入,也可輸出

 語法
CREATE PROCEDURE 過程名 (引數列表)
BEGIN
過程體
END

使用者和許可權管理

 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;
使用者資訊表:mysql.user

 重新整理許可權
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     允許授予許可權

## 表維護

分析和儲存表的關鍵字分佈
ANALYZE [LOCAL | NO_WRITE_TO_BINLOG] TABLE 表名 ...

檢查一個或多個表是否有錯誤
CHECK TABLE tbl_name [, tbl_name] ... [option] ...
option = {QUICK | FAST | MEDIUM | EXTENDED | CHANGED}

整理資料檔案的碎片
OPTIMIZE [LOCAL | NO_WRITE_TO_BINLOG] TABLE tbl_name [, tbl_name] ...
雜項

  1. 可用反引號(`)為識別符號(庫名、表名、欄位名、索引、別名)包裹,以避免與關鍵字重名!中文也可以作為識別符號!
  2. 每個庫目錄存在一個儲存當前資料庫的選項檔案db.opt。
  3. 註釋:
    單行註釋 # 註釋內容
    多行註釋 / 註釋內容 /
    單行註釋 註釋內容 (標準SQL註釋風格,要求雙破折號後加一空格符(空格、TAB、換行等))
  4. 模式萬用字元:
    _ 任意單個字元
    % 任意多個字元,甚至包括零字元
    單引號需要進行轉義 \'
  5. CMD命令列內的語句結束符可以為 ";", "\G", "\g",僅影響顯示結果。其他地方還是用分號結束。delimiter 可修改當前對話的語句結束符。
  6. SQL對大小寫不敏感
  7. 清除已有語句:\c
    . ```
  • mysql中 myisam,innodb預設使用的是 Btree索引,至於btree的資料結構是怎樣的都不重要,

  • 只需要知道結果,既然是索引那這個資料結構最後是排好序;就像新華字典他的目錄就是按照a,b,c..這樣排好序的;

  • 所以你在找東西的時候才快,比如你找 “中” 這個字的解釋,你肯定就會定位到目錄的 z 開頭部分;

  • 組合索引可以這樣理解,比如(a,b,c),abc都是排好序的,在任意一段a的下面b都是排好序的,任何一段b下面c都是排好序的;

  • 組合索引的生效原則是 從前往後依次使用生效,如果中間某個索引沒有使用,那麼斷點前面的索引部分起作用,斷點後面的索引沒有起作用;
    比如

  • where a=3 and b=45 and c=5 .... 這種三個索引順序使用中間沒有斷點,全部發揮作用;

  • where a=3 and c=5... 這種情況下b就是斷點,a發揮了效果,c沒有效果

  • where b=3 and c=4... 這種情況下a就是斷點,在a後面的索引都沒有發揮作用,這種寫法聯合索引沒有發揮任何效果;

  • where b=45 and a=3 and c=5 .... 這個跟第一個一樣,全部發揮作用,abc只要用上了就行,跟寫的順序無關

(a,b,c) 三個列上加了聯合索引(是聯合索引 不是在每個列上單獨加索引)

還需注意, (a,b,c)多列索引和 (a,c,b)是不一樣的,看上面的圖也看得出來關係順序是不一樣的;
分析幾個實際例子來加強理解;
分析句子中使用的索引情況

  • (0) select * from mytable where a=3 and b=5 and c=4;
  • abc三個索引都在where條件裡面用到了,而且都發揮了作用
  • (1) select * from mytable where c=4 and b=6 and a=3;
  • 這條語句列出來只想說明 mysql沒有那麼笨,where裡面的條件順序在查詢之前會被mysql自動優化,效果跟上一句一樣
  • (2) select * from mytable where a=3 and c=7;
  • a用到索引,b沒有用,所以c是沒有用到索引效果的
  • (3) select * from mytable where a=3 and b>7 and c=3;
  • a用到了,b也用到了,c沒有用到,這個地方b是範圍值,也算斷點,只不過自身用到了索引
  • (4) select * from mytable where b=3 and c=4;
  • 因為a索引沒有使用,所以這裡 bc都沒有用上索引效果
  • (5) select * from mytable where a>4 and b=7 and c=9;
  • a用到了 b沒有使用,c沒有使用
  • (6) select * from mytable where a=3 order by b;
  • a用到了索引,b在結果排序中也用到了索引的效果,前面說了,a下面任意一段的b是排好序的
  • (7) select * from mytable where a=3 order by c;
  • a用到了索引,但是這個地方c沒有發揮排序效果,因為中間斷點了,使用 explain 可以看到 filesort
  • (8) select * from mytable where b=3 order by a;
  • b沒有用到索引,排序中a也沒有發揮索引效果

相關文章