mysql数据库应用_MySQL数据库应用 从入门到精通 学习笔记
以下內容是學習《MySQL數據庫應用 從入門到精通》過程中總結的一些內容提要,供以后自己復現使用。
一:數據庫
查看所有數據庫:SHOW DATABASES
創建數據庫:CREATE DATABSE database_name
切換數據庫:USE database_name
刪除數據庫:DROP DATABASE database_name
二:存儲引擎
查看MYSQL支持的引擎:SHOW ENGINES \G (\G 使顯示格式更好看)
查看所支持的存儲引擎: SHOW VARIABLES LIKE 'have%';
查看默認的存儲引擎:SHOW VARIABLES LIKE 'storage_engine%';
經試驗,自己mysql上運行應該是: SHOW VARIABLES LIKE 'default_storage_engine%'
修改默認存儲引擎:方法1:向導模式修改 方法2:修改配置文件my.ini中default-storage-engine
三:數據類型
數據類型 字節
TINYINT 1
SMALLINT 2
MEDIUMINT 3
INT 和 INTEGER 4
BIGINT 8
FLOAT 4
DOUBLE 8
DECI(M,D) M+2
DECIMAL(M,D) M+2
存儲小數用float,需要精確到小數點后10位,用double;需要更精確的,用decimal
BIT(M) 1~8
DATE 4
DATETIME 8
TIMESTAMP 4
TIME 3
YEAR 1
年月日用DATE;年月日時分秒用DATETIME;經常插入或更新日期為當前系統時間,用TIMESTAMP;時分秒用TIME;年份用YEAR。
存儲的日期需要讓不同地區矠用戶使用,則可以使用TIMESTAMP,因為只有該類型日期能夠與實際時區相對應。
eg:
create table t_data_test(
f_date DATE,
f_datetime DATETIME,
f_timestamp TIMESTAMP,
f_time TIME,
f_year YEAR);
SELECT CURDATE(),NOW(),NOW(),TIME(NOW()),YEAR(NOW());
結果:
CURDATE()NOW()NOW()TIME(NOW())YEAR(NOW())
12/1/201712/1/2017 20:16:5612/1/2017 20:16:5620:16:562017
INSERT INTO t_data_test VALUES(CURDATE(),NOW(), NOW(), time(NOW()), YEAR(NOW()));
SELECT * FROM t_data_test;
f_datef_datetimef_timestamp f_timef_year
12/1/201712/1/2017 20:13:37 12/1/2017 20:13:3720:13:37 2017
CHAR(M) M
VARCHAR(M) M
TINYTEXT 0~255
TEXT0~65535
MEDIUMTEXT0~167772150
LONGTEXT0~4294967295
存文本文件
BINARY(M)M
VARBINARY(M)M
存二進制數據(如圖片、音樂、視屏文件)
TINYBLOB 0~255
BLOB0~2^16
MEDIUMBLOB0~2^24
LONGBLOB0~2^32
存大量二進制數據(如電影等視屏文件)
四:表
創建表:
CREATE TABLE table_name(
屬性名 數據類型,
屬性名 數據類型,
屬性名 數據類型,
.
.
.
屬性名 數據類型
)
查看表:
DESCRIBE table_name;
查看表詳細定義(創建語句):
SHOW CREATE TABLE table_name (\G);
刪除表:
DROP TABLE table_name;
修改表:
改表名: ALTER TABLE old_table_name RENAME [TO] new_table_name;
在表的最后一個位置增加字段: ALTER TABLE table_name ADD 屬性名 數據類型;
在表的最后一個位置增加字段: ALTER TABLE table_name ADD 屬性名 數據類型 FIRST;
在表的指定字段之后增加字段: ALTER TABLE table_name ADD 屬性名 數據類型 AFTER 屬性名;
刪除字段:ALTER TABLE table_name DROP 屬性名;
修改字段:ALTER TABLE table_name MODIFY 屬性名 數據類型;
修改字段名字:ALTER TABLE table_name CHANGE 舊屬性名 新屬性名 數據類型;
同時修改字段名字和屬性:ALTER TABLE table_name CHANGE 舊屬性名 新屬性名 新數據類型;
修改字段的順序:ALTER TABLE table_name MODIFY 屬性名1 數據類型 FIRST
或: ALTER TABLE table_name MODIFY 屬性名1 數據類型 AFTER 屬性名2
五:表約束
NOT NULL
DEFAULT
UNIQUE KEY(UK)
PRIMARY KEY(PK)
FOREIGH KEY(FK)
AUTO_INCREMENT
eg:
CREATE TABLE table_name(
屬性名 數據類型 NOT NULL,
屬性名 數據類型 DEFAULT 默認值,
屬性名 數據類型 UNIQUE,
屬性名 數據類型 PRIMARY KEY,
屬性名 數據類型 AUTO_INCREMENT
)
或將約束條件寫在后面:
CREATE TABLE table_name(
屬性名 數據類型 NOT NULL,
屬性名 數據類型 DEFAULT 默認值,
屬性名 數據類型,
屬性名 數據類型,
屬性名 數據類型,
CONSTRAINT UK約束名 UNIQUE(dname),
CONSTRAINT PK約束名 PRIMARY KEY(屬性名,屬性名……),
CONSTRAINT FK約束名 FOREIGH KEY(屬性名1) REFERENCES 表名(屬性名2)
)
六:索引
表是存儲和操作數據的邏輯結構,而索引則是一種有效組合數據的方式。通過索引對象,可以快速查詢到表中矠特定記錄,是一種提高性能的常用方式。 一個索引會包含表中按照一定順序排序的一列或多列字段。
索引按照存儲類型,可以分為B型樹索引(BTREE)和哈希索引(HASH). InnoDB和MyISAM存儲引擎支持BTREE類型索引,MEMORY存儲引擎支持HASH類型索引。默認為前者索引。
索引除了可以提高數據庫管理系統的查找速度,還可以保證字段的唯一性,從而實現數據庫表的完整性。創建索引可以提高查詢速度,但過多的創建索引則會占據許多磁盤空間。
以下情況適合創建索引:
1)經常被查詢的字段,即在where子句中出現的字段;
2)分組的字段,即在group by子句中出現的字段;
3)存在依賴關系的子表和父表之間的聯合查詢,即主鍵或外鍵字段。
4)設置唯一完整性約束的字段。
以下情況不適合創建索引:
1)在查詢中很少被使用的字段;
2)擁有許多重復值的字段。
索引可以分為普通索引、全文索引、單列索引、多列索引和空間索引。
創建(3種方式):
CREATE TABLE table_name(
屬性名 數據類型,
屬性名 數據類型,
……
屬性名 數據類型,
【UNIQUE|FULLTEXT】INDEX | KEY [索引名] (屬性名 【(長度)】 【ASC|DESC】, ...)
);
CREATE 【UNIQUE|FULLTEXT】INDEX 索引名 ON 表明 (屬性名 【(長度)】 【ASC|DESC】, ...)
ALTER TABLE table_name ADD 【UNIQUE|FULLTEXT】INDEX|KEY 索引名(屬性名 【(長度)】 【ASC|DESC】, ...)
eg: CREATE TABLE t_dept(
deptno INT,
dname VARCHAR(20),
loc VARCHAR(40),
INDEX index_deptno(deptno)
);
唯一索引要加UNIQUE修飾符,全文索引加FULLTEXT修飾符。普通索引和多列索引不需要加。 多列索引后面是多個列名,中間用,分隔。
查看索引:
SHOW CREATE TABLE table_name \G;
校驗索引是否被啟用:
EXPLAIN SELECT * FROM t_dept WHERE deptno = 1\G;
刪除索引:
DROP INDEX index_name ON table_name;
七、視圖
視圖可以提高復雜SQL語句矠復用性和表操作的安全性。視圖本質上是一種虛擬表,其內容與真實的表相似,但視圖并不在數據庫中以存儲的數據值形式存在。行和列數據來自定義視圖的查詢所引用基本表,并且在具體引用視圖時動態生成。
視圖特點如下:
1)視圖的列可以來自不同的表,是表的抽象和在邏輯意義上建立的新關系;
2)視圖是由基本表(實表)產生的表(虛表);
3)視圖的建立和刪除不影響基本表;
4)對視圖內容的更新(添加、刪除和修改)直接影響基本表;
5)當視圖來自多個基本表時,不允許添加和刪除數據。
創建視圖:
CREATE VIEW view_name AS 查詢語句;
查看視圖:
SHOW TABLES;
DESCRIBE view_name;
SHOW CREATE VIEW view_name;
select * from information_schema.views where table_name like 'v%'
查看視圖詳細信息:
SHOW TABLE STATUS 【FROM db_name】 【LIKE 'pattern'】
刪除視圖:
DROP VIEW view_name【,view_name2, ...】
修改視圖:
CREATE OR REPLACE VIEW view_name AS 查詢語句
ALTER VIEW view_name as 查詢語句
或:先刪除后創建新的
利用視圖操作基本表:
和操作實表一樣,只不過將表名換成了視圖名。
八、觸發器
經常使用觸發器是因為觸發器可以加強數據庫表中數據的完整性約束和業務規則等。
觸發器使用地方:DELETE、INSERT、UPDATE。
觸發器中可以寫一行語句,也可以寫多行語句。
每張表只能針對DELETE、INSERT、UPDATE三個事件的BEFORE和AFTER兩個時間點添加最多六個(3event*2時間點)觸發器。
創建觸發器:
CREATE TRIGGER trigger_name
BEFORE|AFTER trigger_event
ON table_name FOR EACH ROW
【BEGIN】
trigger_stmt;
【END】
其中trigger_event就是DELETE、INSERT、UPDATE;trigger_stmt就是要執行的語句,單行語句不需要加BEGIN END,多行則需要。
eg:
每次t_dept表插入數據前都在t_diary日志表中增加一條日志記錄。
CREATE TRIGGER tri_diarytime
BEFORE INSERT
ON t_dept FOR EACH ROW
INSERT INTO t_diary VALUES(NULL,'t_dept',now());
DELIMITER $$
CREATE TRIGGER tri_diarytime
BEFORE INSERT
ON t_dept FOR EACH ROW
BEGIN
INSERT INTO t_diary VALUES(NULL,'t_dept',now());
INSERT INTO t_diary VALUES(NULL,'t_dept',now());
END
$$
DELIMITER ;
寫多行語句前要通過DELIMITER更換分隔符或還原分隔符。
查看觸發器:
SHOW TRIGGERS;
SELECT * FROM information_schema.triggers where trigger_name like 'pattern';
刪除觸發器:
DROP TRIGGER trigger_name;
九、插入、更新、刪除數據
插入完整數據記錄:
INSERT INTO table_name VALUES(value1,value2...);
插入數據記錄一部分:
INSERT INTO table_name(field1,field2,...) VALUES(value1,value2,...);
插入多條數據:
INSERT INTO table_name VALUES(value11,value12...),(value21,value22...),...;
INSERT INTO table_name(field1,field2,...) VALUES(value11,value12...),(value21,value22...),...;
插入查詢結果:
INSERT INTO table_name(field1,field2,...)
SELECT (field1,field2,...)
FROM table_name2 WHERE ...
注意:自增的字段或有默認值的字段,可以采用插入數據記錄的一部分的方法插入,這種方法還不依賴表字段的順序,可擴展性好,建議使用。
更新數據:
UPDATE table_name
SET field1 = value1,
SET field2 = value2,
...
WHERE CONDITION;
刪除數據:
DELETE FROM table_name WHERE CONDITION;
刪除整張表里的數據:
DELETE FROM table_name;
TRUNCATE table_name;(速度更快,建議使用,原理:刪除整張表,然后再根據原表DLL語句創建一個一模一樣的表)
十、單筆數據記錄簡單查詢
簡單查詢使用方式包括:
1)簡單數據查詢;
2)避免重復數據查詢;
3)實現數學四則運算數據查詢; +-*/%
4)設置顯示格式數據查詢。
eg:
SELECT * FROM t_dept;
SELECT DISTINCT filed1,field2 ... fieldn FROM table_name; (多個字段組合起來唯一)
SELECT ename, sal*12 AS yearsalary FROM t_employee;
SELECT CONCAT(ename, '雇員的年薪為: ', sal*12) yearsalary FROM t_employee;
條件數據查詢:
單條件
多條件
between and
NOT
IS NULL / IS NOT NULL
IN / NOT IN (使用IN時,查詢的集合(IN后面的枚舉值)中如果存在NULL,則不會影響查詢;如果使用關鍵字NOT IN,查詢的集合中如果存在NULL,則不會查詢到任何數據)
LIKE / NOT LIKE _ %
排序:
SELECT field1,field2...fieldn
FROM table_name
WHERE CONDITION
ORDER BY fieldm1 [ASC|DESC], fieldm2 [ASC|DESC] ...
如果字段的值為空值(NULL),則該值為最小值,因此在降序排序中將最后顯示,在升序排序中將最先顯示。
限制數據記錄查詢數量
SELECT field1,field2...fieldn
FROM table_name
WHERE CONDITION
LIMIT offset_start,row_count;
使用方式:
1)不指定初始位置,只指定行數。 LIMIT row_count;
2)指定初始位置,指定行數。 LIMIT offset_start,row_count; 不包括offset那一行
統計函數:
count() avg() sum() max() min()
count(*):對表中數據進行統計,不管表字段中包含的是NULL值還是非NULL值;
count(field):對指定字段的記錄進行統計,忽略NULL值。
其他幾個統計函數,必須指定字段,所以忽略NULL值。
如果所操作的表中沒有任何數據記錄,則count()函數返回0,其他統計函數返回NULL。
分組數據記錄查詢:
SELECT function()
FROM table_name
WHERE CONDITION
GROUP BY field1,field2...
HAVING CONDITION
在具體進行分組查詢時,分組所依賴的字段上的值一定要具有重復值,否則將沒有任何意義。
首先針對field1進行分組,然后針對每組按照字段field2進行分組,以此類推。
SELECT * FROM table_name GROUP BY CONDITION; 是從分組中隨機選擇一條記錄顯示。 所以group by 要和統計函數一起使用才有意義。
SELET deptno,GROUP_CONCAT(ename),COUNT(ename) number enames FROM t_employee GROUP BY deptno;
會將每組中的ename組合在一起顯示.
結果:
deptnoenamesnumber
10MILLER,KING,CLARK3
20FORD,ADAMS,SCOTT,JONES,SMITH4
30BLAKE,MARTIN2
十一、多表數據記錄查詢:
在具體應用中如果需要實現多表數據記錄查詢,一般不使用連接查詢,因為該操作效率比較低,而是使用子查詢操作。進行連接操作時,會求笛卡爾積,如果表數據記錄多,則可能會造成死機。
MYSQL在具體實現連接查詢操作時,首先將兩個或兩個以上的表按照某個條件連接起來,然后再查詢到所要求的數據記錄。
連接操作是關系數據庫操作中專門用于數據庫操作的關系運算,包括并(UNION)、笛卡爾積(CARTESIAN PRODUCT)和專門針對數據庫操作的運算-連接(JOIN)。
并(UNION):把具有相同字段數目和字段類型的表合并到一起。
笛卡爾積(CARTESIAN PRODUCT):是沒有連接條件表關系返回的結果。
eg:表A:字段數目為m,行數為k。 表B字段數目為n,行數為l。 則結果表字段數目為m+n,行數為k*l.
連接(JOIN):在表關系的笛卡爾積數據記錄中,按照相應字段值的比較條件進行選擇生成一個新的關系。
連接分為內連接(inner join) 、外連接(outer join) 和交叉連接(cross join)。
1.內連接:在表關系的笛卡爾積數據記錄中,保留表關系中所有匹配的數據記錄,舍棄不匹配的數據記錄。
按照匹配的條件可以分成自然連接、等值連接和不等連接。
自然連接:在表關系的笛卡爾積中,首先根據表關系中相同名稱的字段自動進行記錄匹配,然后去掉重復的字段。
eg:表A 有字段名a,b;表B也有字段名a,b。則自然連接時,先求A和B的笛卡爾積,然后匹配A.a=B.a and A.b = B.b的記錄,不符合該條件的全部舍棄。 笛卡爾積中,A.a A.b B.a B.b都會顯示,共4個字段,但自然連接中,只顯示a,b2個字段。
特點:1)在具體執行自然連接時,會自動判斷相同名稱的字段,然后進行數據值的匹配。
2)在執行完自然連接的新關系中,雖然可以指定包含哪些字段,但是不能指定執行過程中的匹配條件,即哪些字段的值進行匹配。
3)在執行完自然連接的關系中,執行過程中所有匹配的字段名只有一個,即會去掉重復字段。
等值連接:在表關系的笛卡爾積中,選擇所匹配字段值相等的數據記錄。
特點:1)使用=指定匹配條件;
2)在新關系中,不會去掉重復字段。
不等連接:在表關系的笛卡爾積中,選擇所匹配字段值不相等的數據記錄。
特點:1)使用!=指定匹配條件;
2)在新關系中,不會去掉重復字段。
2.外連接:在表關系的笛卡爾積數據記錄中,不僅保留表關系中所有匹配的數據記錄,而且還會保留部分不匹配的數據記錄。
按照保留不匹配條件數據記錄來源可以分為左外連接(left outer join)、右外連接(right outer join)和全外連接(full outer join)。
左外連接:在表關系的笛卡爾積中,除了選擇相匹配的數據記錄,還包含關聯左邊表中不相匹配的數據記錄。
右外連接:在表關系的笛卡爾積中,除了選擇相匹配的數據記錄,還包含關聯右邊表中不相匹配的數據記錄。
全外連接:在表關系的笛卡爾積中,除了選擇相匹配的數據記錄,還包含關聯左右兩邊表中不相匹配的數據記錄。
3.交叉連接:不帶where子句的連接,返回的就是笛卡爾積數據記錄。
總結:
表A和B
UNION: A并B
inner join: A交B 根據交的條件分為:自然連接、等值連接、不等值連接。 使用的是比較運算符進行匹配條件的判斷。
outer join:
左外連接:A并(A交B)
右外連接:(A交B)并B
全外連接:A并(A交B)并B
cross join: A乘B 十字交叉,笛卡爾積
語法:
內連接:
SELECT field1 field2 ... fieldn
FROM join_table_name1 INNER JOIN join_table_name2 [INNER JOIN join_table_namen]
ON join_condition
外連接:
SELECT field1 field2 ... fieldn
FROM join_table_name1 LEFT|RIGHT|FULL [OUTER] JOIN join_table_name2 [INNER JOIN join_table_namen]
ON join_condition
UNION:
SELECT field1 field2 ... fieldn
FROM table_name1
UNION | UNION ALL
SELECT field1 field2 ... fieldn
FROM table_name2
UNION | UNION ALL
SELECT field1 field2 ... fieldn
FROM table_nameN
...
子查詢:一個查詢之中嵌套了其他的若干查詢,即在一個SELECT查詢語句的WHERE或FROM子句中包含另外一個SELECT查詢語句。
通過子查詢可以實現多表查詢,該查詢語句中可能包含IN、ANY、ALL和EXISTS等關鍵字,除此之外還可能包含比較運算符。理論上子查詢可以出現在查詢語句的任意位置,但是在實際開發中,子查詢經常出現在WHERE和FROM子句中。
WHERE子句中的子查詢:該位置處的子查詢一般返回單行單列、多行單列、單行多列數據記錄。
FROM 子句中的子查詢:該位置處的子查詢一般返回多行多列數據記錄,可以當做一張臨時表。
eg:
子查詢返回單行單列: select * from t_employee where sal > (select sal from t_employee where ename = 'SMITH'); (工資大于SMITH的人)
子查詢返回單行多列:select ename,sal,job from t_employee where (sal,job) = (select sal,job from t_employee where ename='SMITH');
(職位和工資和SIMITH一樣的人)
子查詢返回多行單列:select * from t_employee where deptno in (select deptno from t_dept);
select ename,sal from t_employee where sal > any(select sal from t_employee where job = 'MANAGER');
=ANY(等同于IN) >ANY
>ALL
select * from t_deptno c where not EXISTS(select * from t_employee where deptno = c.deptno); (列出沒有雇員的部門)
子查詢返回多行多列:
select d.deptno,d.dname,d.loc,number,average
from t_dept d inner join (
select deptno dno,count(empno) number, avg(sal) average
from t_employee group by deptno desc ) employee
on d.deptno = employee.dno;
(查詢t_employee表中各個部門的部門號、部門名稱、部門地址、雇員人數和平均工資)
十二、Mysql運算符
算術運算符: + - * / % (除數為0時返回null)
比較運算符: > < =或<=> != 或 <> >= <=
BETWEEN AND IS NULL INLIKEREGEXP
=不能操作NULL,如果一方為NULL則返回NULL。 而<=>則可以操作NULL。
eg: SELECT NULL <=> NULL '<=>符號效果', NULL = NULL '=符號效果';
結果:1 NULL
!= 和 <>都不能操作NULL。> >= < <=也不能操作NULL。
REGEXP:正則表達式
MYSQL支持的模式字符:
^匹配字符串的開始部分
$匹配字符串的結束部分
.匹配字符串中的任意一個字符
[字符集合]匹配字符集合中的任意一個字符
[^字符集合]匹配字符集合外的任意一個字符
str1|str2|str3匹配str1、str2、str3中的任意一個字符串
* 匹配字符,包含0個和1個
+匹配字符,包含1個或以上
字符串[N]字符串出現N次
字符串[M,N]字符串出現至少M次,至多N次
邏輯運算符:AND(&&) OR(||) NOT(!) XOR
AND:所有操作數不為0且不為NULL,返回1;存在任意一個操作數為0,返回0;存在任意一個操作數為NULL,且沒有操作數為0,返回NULL。
OR:所有操作數存在任何一個操作數不為0,則返回1;所有操作數都為0數字,返回0;所有操作數中不包含非0數字,但包含NULL,返回NULL。
NOT:操作數為非0數字,返回0,;操作數為0,返回1,操作數為NULL,返回NULL;
XOR:操作數同為0數字或非0數字,返回0;操作數一個為0,另一個為非0,返回1;操作數中包含NULL,返回NULL.
總結:OR NOT XOR如果有一個操作數為NULL,就返回NULL,其他和正常理解的一樣;
AND 如果有一個操作數為0,就為0;如果存在NULL,且不存在0則返回NULL;
位運算符: & | ~ ^ << >> 現將十進制數轉換為二進制,然后再進行位運算,最后結果轉換為十進制,再顯示。
顯示二進制形式:BIN(name);
十三、常用函數
mysql中,函數不僅可以出現在select語句及其子句中,還可以出現在update和delete語句中。
函數可移植性不好。
字符串函數:
concat(str1,str2,...strn)連接字符串str1,str2,...strn為一個完整字符串 (一個為NULL,則結果為NULL)
concat_ws(sep,str1,str2,...strn)連接字符串str1,str2,...strn為一個完整字符串,各個字符串使用sep分隔符分割。(分隔符為NULL,則返回NULL,字符串中有NULL,則忽略。)
lower(str) lcase(str)將字符串str中所有字符變為小寫
upper(str) ucase(str)將字符串str中所有字符變為大寫
strcmp(str1,str2)比較字符串str1和str2
length(str)返回字符串長度(一個英文算一個,一個漢字算兩個)
char_length(str)返回字符串長度(一個英文算一個,一個漢字算一個)
left(str,count)返回字符串str中最左邊的count個字符
right(str,count)返回字符串str中最右邊的count個字符
substring(str,pos,count)返回字符串str中pos位置之后的count個字符。(從1開始數,包括pos)
mid(str,pos,count)返回字符串str中pos位置之后的count個字符。(從1開始數,包括pos)
ltrim(str)去掉字符串左側的空格
rtrim(str)去掉字符串右側的空格
trim(str)去掉字符串兩側的空格
insert(str,pos,len,newstr)將字符串str中的pos位置開始長度為len的字符串用字符串newstr替換。若任何一個參數為null,返回null.
replace(str,substr,newstr)將字符串str中的子字符串substr用newstr替換
數值函數:
abs(x)返回x的絕對值
ceil(x)ceiling(x)返回大于x的最小正整數
floor(x)返回小于x的最大正整數
round(x)返回x四舍五入后的整數
round(x,y)返回x四舍五入后有y位小數的數值
mod(x,y)返回x%y
rand() rand(x)返回0~1內的隨機數(rand()多次調用返回值不同,但rand(x)只要x一樣,多次調用返回值一樣。)
truncate(x,y)返回x截斷為y位小數的數值
注:y表示小數位數時,如果取負數,表示整數位。如-1,表示截斷個位數。
日期函數:
curdate() current_date()獲取當前日期
curtime() current_timestamp()獲取當前時間
localtime()獲取當前時間
sysdate()獲取當前時間
now()獲取當前日期和時間
unix_timestamp(date)from_unixtime(utime)
utc_date(date)utc_time(date)
獲取日期和時間各個部分:
year(date) quarter(date) month(date) week(date) hour(time) minute(time) second(time)
monthname(date) dayname(date)
weekofyear(date) dayofyear(date) dayofmonth(date) dayofweek(date) weekday(date)
extract(type from date): extract(year from now()) extract(month from now()) ...
datediff(date1,date2)date1和date2相隔天數
adddate(date,n)date加上n天
subdate(date,n)date減去n天
addtime(time,n)time加上n秒
subtime(time,n)time減去n秒
系統信息函數:
version()返回數據庫版本號
datebase()返回當前數據庫名
user()返回當前用戶
last_insert_id()返回最近生成的auto_increment值
流程函數:
if(value,t f)如果value為真,返回t,否則返回f
ifnull(value1,value2)如果value1不為空值,返回value1,否則返回value2
case when [value1] then [result1] ... else [default] end
如果value1為真,返回result1,...都不符合返回default
case [expr] when [value1] then [result1] ... else [default] end
如果expr等于value1返回result1,...都不符合返回defalut。
十四、存儲過程和函數
存儲過程和函數是事先經過編譯并存儲在數據庫中的一組sql語句集合。
函數必須有返回值,而存儲過程則沒有。
存儲過程的參數類型遠遠多于函數參數類型。
優點:
1)存儲過程和函數運行標注組件式編程,提高了SQL語句的重用性、共享性和可移植性;
2)存儲過程和函數能夠實現較快的執行速度,能夠減少網絡流量;
3)存儲過程和函數可以被當做為一種安全機制來利用。
缺陷:
1)存儲過程和函數的編寫比單條sql語句復雜,需要用戶具有更高的技能和更豐富的經驗;
2)在編寫存儲過程和函數時,需要創建這些數據庫對象的權限。
創建存儲過程:
CREATE PROCEDURE procedure_name([procedure_parameter[,...]])
[characteristic...] routine_body
procedure_name:存儲過程名字
procedure_parameter:存儲過程參數,語法形式為[IN|OUT|INOUT] parameter_name type
characteristic:存儲過程特性
routine_body:存儲過程SQL語句代碼,可以用BEGIN...END 來標識SQL語句的開始和結束
創建函數:
CREATE FUNCTION function_name ([function_parameter[,...]])
[characteristic...] routine_body
function_parameter:函數參數,語法形式為 parameter_name type.
存儲過程和函數中的表達式中:由變量、運算符和流程控制構成。
變量:
聲明變量:DECLARE var_name[,...] type [DEFAULT value]
變量賦值:SET var_name = expr[,...] 或 SELECT field_name[,...] INTO var_name[,...] FROM table_name WHERE condition;
游標(取出結果集進行處理效率低,能不使用就不使用游標):
聲明游標:DECLARE cursor_name CURSOR FOR select_statement;
打開游標:OPEN cursor_name
使用游標:FETCH cursor_name INTO var_name[,var_name] ...
關閉游標:CLOSE cursor_name
流程控制:
條件控制語句:
IF search_condition THEN statement_list
[ELSEIF search_condition THEN statement_list] ...
[ELSE statement_list]
END IF
CASE case_value
WHEN when_value THEN statement_list
[WHEN when_value THEN statement_list] ...
[ELSE statement_list]
END CASE
循環控制語句:
[begin_label:] LOOP
statement_list
END LOOP [end_label]
[begin_label:] WHILE search_condition DO
statement_list
END WHILE [end_label]
[begin_label:] REPEAT search_condition DO
statement_list
END REPEAT [end_label]
查看存儲過程和函數:
SHOW CREATE PROCEDURE procedure_name;
SHOW CREATE FUNCTION function_name;
SHOW PROCEDURE STATUS [LIKE 'pattern'] \G
SHOW FUNCTION STATUS [LIKE 'pattern'] \G
SELECT * FROM information_schema.routines \G;
SELECT * FROM information_schema.routines WHERE specific_name = 'name' \G;
修改存儲過程和函數:
ALTER PROCEDURE procedure_name
[characteristic ...]
ALTER FUNCTION function_name
[characteristic ...]
刪除存儲過程和函數:
DROP PROCEDURE procedure_name;
DROP FUNCTION function_name;
十五、事務
MYSQL引擎中,InnoDB和BDB支持事務,MyISAM和MEMORY不支持事務。 InnoDB通過UNDO日志和REDO日志來實現事務。
事務4個特性:
1)原子性(atomicity):事務中所有的操作視為一個原子單元,即對于事務所進行的數據修改等操作只能是完全提交或完全回滾。
2)一致性(consistency):事務在完成時,必須使所有的數據從一種一致性狀態變更為另一種一致性狀態,所有的變更都必須應用于事務的修改,以確保事務的完整性。
3)隔離性(isolation):一個事務中的操作語句所做的修改必須與其他事務所做的修改相隔離。在進行事務查看數據時,數據所處的狀態,要么是被另一并發事務修改之前的狀態,喲啊么是被另一個并發事務修改之后的狀態,即當前事務不會查看由另一個并發事務正在修改的數據。這種特性通過鎖機制來實現。
4)持久性(durability):事務完成之后,所做的修改對數據的影響是永久性的,即使系統重啟或者出現系統故障仍可以恢復。
MYSQL使用BEGIN開始事務,使用COMMIT結束事務,中間可以使用ROLLBACK回滾事務。
START TRANSACTION | BEGIN [WORK]
COMMIT [WORK] [AND [NO] CHAIN] [[NO] RELEASE]
ROLLBACK [WORK] [AND [NO] CHAIN] [[NO] RELEASE]
SET AUTOCOMIT = {0 | 1}
事務隔離級別:
SQL標準定義了4種隔離級別,指定了事務中哪些數據改變其他事務可以見,哪些數據改變其他事務不可見。低級別的隔離級別可以支持更高的并發處理,同時占用的資源更少。
事務隔離級別可以使用以下語句設置:
#未提交讀
SET GLOBAL TRANSACTION ISOLATION LEVEL READ UNCOMMITTED;
#提交讀
SET GLOBAL TRANSACTION ISOLATION LEVEL READ COMMITTED;
#可重復性
SET GLOBAL TRANSACTION ISOLATION LEVEL REPEATABLE READ;
#可串行化
SET GLOBAL TRANSACTION ISOLATION LEVEL SERIALIZABLE;
1)READ UNCOMMITTED(讀取未提交內容)
在該隔離級別,所有事務都可以看到其他未提交事務的執行結果,因為其性能也不必其他級別搞很多,因為此隔離級別實際應用中一般很少使用,讀取未提交的數據被稱為臟讀(Dirty Read)。
2)READ COMMITTED(讀取提交內容)
這是大多數數據庫系統的默認隔離級別,但不是MYSQL默認的隔離級別。
其滿足了隔離的簡單定義:一個事務從開始到提交前所做的任何改變都是不可見的。事務只能看見已經提交事務所做的改變。
這種隔離級別也支持所謂的不可重復讀(Nonrepeatable Read),因為同一事務的其他實例在該實例處理期間可能會有新的數據提交導致數據改變,所以統一查詢可能返回不同結果。
3)REPEATABLE-READ(可重復讀)
這是MYSQL的默認事務隔離級別,能確保同一事務的多個實例在并發讀取數據時,會看到同樣的數據行。
理論上會導致另一個問題:幻讀(Phantom Read)。
eg:第1個事務對一個表中的數據進行了修改,這種修改涉及表中的全部數據行。同時第2個事務也修改這個表中的數據,這種修改是向表中插入一行新數據。那么,以后就會發生操作第1個事務的用戶發現表中還有沒有修改的數據行。
InnoDB和Falcon存儲引擎通過多版本并發控制(Multi_Version Concurrency Control,MVCC)機制解決了該問題。
4)Serializable(可串行化)
這是最高的隔離級別,通過強制事務排序,使之不能相互沖突,從而解決幻讀問題。簡言之,就是在每個讀的數據行上加上共享鎖實現。
在這個級別,可能會導致大量的超時現象和鎖競爭,一般不推薦使用。
MySQL中所有的DDL語句是不能回滾的,并且部分的DDL語句會造成隱式的提交。比如ALTER TABLE、TRUNCATE TABLE 和 DROP TABLE等。
鎖機制:
共享鎖:S(Share) 讀鎖 鎖粒度為行或元組(多個行) 一個事務獲取了共享鎖之后,可以對鎖定范圍內的數據進行讀操作。
排他鎖:X(eXclusive) 寫鎖 鎖粒度為行或元組(多個行) 一個事務獲取了排他鎖之后,可以對鎖定范圍內的數據進行寫操作。
意向鎖:分意向共享鎖(IS)和意向排他鎖(IX)。 鎖粒度為整張表。 "有意"表示事務想執行操作但還沒有真正執行。
鎖和鎖之間的關系:相容(兩個事務可以對同一組數據同時加鎖)或互斥(一個事務對一組數據加鎖后,其他事務不能再加鎖了)。
各個鎖的關系如下:(Y:相容 N:互斥)
參數XSIXIS
XNNNN
SNNYNY
IXNNYY
ISNYYY
鎖粒度:分為表鎖和行鎖。
表鎖管理鎖的開銷最小,同時運行的并發來那個也是最小的。 MyISAM存儲引擎使用該鎖機制。 一些特定的動作也使用表鎖,如ALTER TABLE.
行鎖可以支持最大的并發。InnoDB存儲引擎使用的是行鎖。 如果要支持并發讀/寫,建議采用InnoDB存儲引擎,因為其是采用行級鎖,可以獲的更多的更新性能。
SQL執行時加鎖:
SELECT ... LOCK IN SHARE MODE 加上一個共享鎖
SELECT ... FOR UPDATE 加上一個排他鎖
InnoDB引擎會自動給會話事務中的共享鎖、更新鎖以及排他鎖,需要加到一個區間值域時,再加上個間隙鎖或稱為范圍鎖,對不存在的數據也鎖住,防止出現幻寫。
十六、Mysql安全機制
創建用戶:
CREATE USER username@ip IDENTIFIED BY [PASSWORD] 'password', username@ip IDENTIFIED BY [PASSWORD] 'password' ...;
通過向mysql數據庫中的user表插入記錄的方式來創建用戶。注意:1)需要插入x509_issuer等字段值,2)需要FLUSH PRIVILEGES;生效。3)密碼要使用PASSWORD函數加密。
INSERT INTO user(Host,User,Password,ssl_cipher,x509_issuer,x509_subject)
VALUES('localhost','wyl',PASSWORD('password'),'','','');
通過GRANT語句創建用戶并同時賦權限
GRANT priv_type ON databasename.tablename
TO username [IDENTIFIED BY [PASSWORD] 'password']
[,username [IDENTIFIED BY [PASSWORD] 'password']]
...
eg:GRANT SELECT ON paydb.t_txn_ds TO 'paydb'@'localhost' IDENTIFIED BY '123456';
修改密碼:
使用超級權限用戶修改root用戶密碼:
方法一:mysqladmin -u username -p oldpassword "new_password";
方法二: SET PASSWORD=PASSWORD("new_password");
方法三:通過修改user表記錄修改。
UPDATE user SET password=PASSWORD("new_password") WHERE user = 'root' and host = 'localhost';
使用超級權限用戶修改普通用戶密碼:
方法一:GRANT priv_type ON database.table TO user[IDENTIFIED BY [PASSWORD] "new_password"]
方法二:SET PASSWORD FOR 'username'@'hostname'=PASSWORD("new_password"); 如果是修改自己的密碼,不需要寫FOR 'username'@'hostname'.
方法三:通過修改user表記錄修改。
UPDATE user SET password=PASSWORD("new_password") WHERE user = 'username' and host = 'localhost';
刪除用戶:
方法一:DROP USER user1[,user2...];
方法二:用root賬號登陸,刪除user表中記錄。
DELETE FROM user where user = 'wyl' AND host = 'localhost';
權限管理:
授權:
GRANT priv_type [(column_list)] ON database.table
TO user [IDENTIFIED BY [PASSWORD] 'password']
[,user [IDENTIFIED BY [PASSWORD] 'password']]
...
[WITH with_option...];
column_list表示權限作用的字段,沒有時表示作用于整張表。
with_option取值:
GRANT OPTION:被授權的用戶可以將權限授權給其他用戶。(給其他用戶賦權限時,權限不得超過自己的)
MAX_QUERIES_PER_HOUR count:設置每小時可以執行count次查詢
MAX_UPDATES_PER_HOUR count:設置每小時可以執行count次更新
MAX_CONNECTIONS_PER_HOUR count:設置每小時可以建立count次連接
MAX_USER_CONNECTIONS count:設置單個用戶可以用事具有count個連接
查看權限:
SHOW GRANTS FOR username \G;
或者去user表查看相應字段取值
eg:
SELECT host,user,password,select_priv,update_priv,grant_priv,drop_priv
FROM mysql.user WHERE user = 'wyl' \G;
收回權限:
REVOKE priv_type [(column_list)] ON database.table
FROM user [IDENTIFIED BY [PASSWORD] 'password']
[,user [IDENTIFIED BY [PASSWORD] 'password']]
...;
回收全有權限:
REVOKE ALL PREVILEGES,GRANT OPTION
FROM user [IDENTIFIED BY [PASSWORD] 'password']
[,user [IDENTIFIED BY [PASSWORD] 'password']]
...;
十七、日志管理
Mysql日志分為二進制日志、錯誤日志和查詢日志。
默認情況下,MYSQL指揮啟動錯誤日志文件,其他日志文件需要手動啟動才可以被啟動。
二進制日志:該日志文件會以二進制形式記錄數據庫的各種操作,記錄DDL和DML語句,但是卻不會記錄查詢語句。
錯誤日志:該日志文件會記錄MYSQL服務器啟動、關閉和運行時出錯等信息。
通用查詢日志:該日志記錄MYSQL服務器的啟動和關閉信息、客戶端的連接信息、更新SQL語句和查詢SQL語句。
慢查詢日志:記錄執行時間超過指定時間的各種操作,通過工具分析慢查詢日志可以定位MYSQL服務器性能瓶頸所在。
啟動日志后,雖然可以實現對MYSQL服務器進行維護,但是會降低mysql軟件的執行速度。
日志在my.ini配置文件中的mysqld組下面進行配置,有配置就是啟動了日志,沒有就是沒啟動。
查看二進制日志:mysqlbinlog filename.number;
其他日志是文本形式,可以直接打開查看。
動態打開或關閉通用日志: SET global general_log = on/off; 立刻生效
動態打開或關閉慢查詢日志:SET global slow_query_log = on/off; 需要重新連接才能生效
SET global long_query_time = 3;//單位:秒
配置文件:
[mysqld]
log-low-queries[=dir\[filename]]
long_query_time = n (單位:秒,默認10秒)
MYSQL自帶的慢查詢日志分析工具:mysqldumpslow.pl
mysqldumpslow.pl -s at -t 1 'slow.log'
-s:分析慢查詢日志時指定排序參數。取值有:al-平均鎖定時間 ar-平均返回記錄數 at-平均查詢時間
-t:指定顯示的行數
最后跟慢查詢日志的名稱。
刪除mysql的日志,進行重新寫入:
mysqladmin -u root -p flush-logs
十八、數據庫維護和性能提高
數據庫維護:包括備份數據、還原數據、數據庫遷移、表導出和導入。
注:mysql和mysqldump命令不是在mysql命令窗口執行的,而是在操作系統命令窗口(cmd命令窗口或者linux命令窗口)下執行的,后面不需要加;
數據庫備份:
方法一:復制數據文件進行備份。
只適合存儲引擎為MyISAM的表,不適合InnoDB存儲引擎的表。
復制前:1)FLUSH TABLES; 2)停止mysql服務器。
拷貝文件:MySQL Server 5.5\data目錄
方法二:通過mysqldump命令實現數據備份
該命令會將包含數據的表結構和數據內容保存在相應的文件中。
mysqldump -u username -p dbname table1 table2 ... tablen > backupname.sql
mysqldump -u username -p --database dbname1 dbname2 ... dbnamen > backupname.sql
mysqldump -u username -p --all -databases > backupname.sql
數據還原:
方法一:復制數據文件進行還原。
方法二:通過mysql命令還原
mysqldump -u username -p [dbname]< backupname.sql
表導出到文本文件:
方法一:SELECT ... INTO OUTFILE
SELECT ... FROM table_name [WHERE condition] INTO OUTFILE 'file_name' [OPTION]
方法二:通過mysqldump命令
mysqldump -u root -pPassword -T file_directory dbname table_name [OPTION]
eg:mysqldump -u root -proot -T c:\ company t_dept
方法三:通過mysql命令導出
mysql -u root -pPassword -e "SELECT ... FROM table_namme" dbname>file_name
eg:mysql -u root -p -e "SELECT * FROM customers" crashcourse > C:/customers.txt
后綴可以改為其他,比如xlsx.
文本文件導入到數據庫:
方法一:執行LOAD DATA INFILE命令
LOAD DATA[LOCAL] INFILE file_name INTO TABLE table_name [OPTION]
方法二:執行mysqlimport命令
mysqlimport -u root -pPassword[--LOCAL] dbname file_name[OPTION]
數據庫遷移:
先導入再導入
或:同時進行。
eg:
mysqldump -h hostname1 -u root -password=password1 -all-databases
|
mysql -h hostname2 -u root -password=password2
MYSQL性能優化建議:
1)硬件參數要滿足,建議運行在專用的服務器上;
2)隨著運行時間的推移,不斷調整內存分配、緩存區大小等參數配置。 可以通過SHOW VARIABLES和SHOW STATUS來查看當前設置。
3)MYSQL是一個多用戶多線程的數據庫管理系統。可以通過SHOW PROCESSLIST顯示所有活動進程,通過執行kill命令終結消耗太多資源的進程。
4)通過SELECT 語句實現多表查詢時,應該多次試驗連接和子查詢等各種方式,找出最佳的方式。在具體判斷SELECT語句執行性能時,可以通過EXPLAIN語句查看SELECT語句的執行情況。
5)使用存儲過程比一條一條執行語句速度要塊許多;
6)不要查找比需求還要多的數據內容,換言之,不要執行"SELECT *"語句(除非真正要查詢所有字段);
7)通過UNION關鍵字連接的SELECT語句,代替包含一系列復雜OR條件的SELECT 語句可以有極大的性能改進。
8)索引可以改善數據檢索的性能,但是會損失數據CUD操作(數據插入、數據更新和數據刪除)性能。因此對于不經常被查詢的表,最好不要創建索引。
9)關鍵字LIKE的執行效率很低,一般來說,會通過"FULL TEXT"來代替關鍵字LIKE;
10)數據庫中的表是不斷變化的尸體。一組結構優良的表,使用一段時間后,表的使用和內容就會需要進行更改,因此當初理想的優化和配置就需要改變。
總結
以上是生活随笔為你收集整理的mysql数据库应用_MySQL数据库应用 从入门到精通 学习笔记的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 安卓airpods弹窗软件(安卓airp
- 下一篇: 查找linux文件位置(查找linux文