數據庫:存放數據的倉庫python
sql及其規範mysql
sql是Structured Query Language(結構化查詢語言)的縮寫。SQL是專爲數據庫而創建的操做命令集,是一種功能齊全的數據庫語言。
在使用它時,只須要發出「作什麼」的命令,「怎麼作」是不用使用者考慮的。SQL功能強大、簡單易學、使用方便,已經成爲了數據庫操做的基礎,而且如今幾乎全部的數據庫均支持sql。正則表達式
<1> 在數據庫系統中,SQL語句不區分大小寫(建議用大寫) 。但字符串常量區分大小寫。建議命令大寫,表名庫名小寫; <2> SQL語句可單行或多行書寫,以「;」結尾。關鍵詞不能跨多行或簡寫。 <3> 用空格和縮進來提升語句的可讀性。子句一般位於獨立行,便於編輯,提升可讀性。 SELECT * FROM tb_table WHERE NAME="YUAN"; <4> 註釋:單行註釋:-- 多行註釋:/*......*/ <5>sql語句能夠折行操做 <6> DDL,DML和DCL
MYSQL經常使用命令算法
--
-- 啓動mysql服務與中止mysql服務命令:
--
-- net start mysql
-- net stop mysql
--
--
-- 登錄與退出命令:
--
-- mysql -h 服務器IP -P 端口號 -u 用戶名 -p 密碼 --prompt 命令提示符 --delimiter 指定分隔符
-- mysql -h 127.0.0.1 -P 3306 -uroot -p123
-- quit------exit----\q;
--
--
-- \s; ------my.ini文件:[mysql] default-character-set=gbk [mysqld] character-set-server=gbk
--
-- prompt 命令提示符(\D:當前日期 \d:當前數據庫 \u:當前用戶)
--
-- \T(開始日誌) \t(結束日誌)
--
-- show warnings;
--
-- help() ? \h
--
-- \G;
--
-- select now();
-- select version();
-- select user;
--
-- \c 取消命令
--
-- delimiter 指定分隔符
2、.數據庫操做(DDL) sql
1.查看:
(1)查看全部數據庫:show databases;
(2)查看某一數據庫建立編碼:show create database num;
2.建立:
create database if not exists sxmu; (若是不存在則建立,若存在不建立也不報錯,但會warning.查看warning:show warnings;)
create database if not exists num character set gbk;
3.刪除:drop database if exists kokusho;
4.修改:alter database num character set gbk;
5 使用:切換:use sxmu;
檢測當前數據庫:select database();
注:數據庫文件默認存放路徑(C:\ProgramData\MySQL\MySQL Server 5.7\Data)
默認建立的全部數據庫都是一個文件夾,每一張表都是該文件夾下的一個文件。
故若是要遷移數據庫文件,可直接複製數據庫文件夾
select user();
select now();
3、數據表操做 數據庫
主鍵:非空且惟一(not null,unique)django
數據類型:flask
數值類型服務器
日期和時間類型數據結構
字符串類型
建立表:
create table tab_name(
field1 type[完整性約束條件],
field2 type,
...
fieldn type
)[character set xxx];
建立員工表:
CREATE TABLE employee(
id TINYINT PRIMARY KEY AUTO_INCREMENT,
name VARCHAR(25),
gender BOOLEAN,
age INT,
department VARCHAR(20),
salary DOUBLE(7,2)
)
表結構:
1.查看
查看錶結構:desc employee;
show columns from employee;
查看建立表語句:show create table employee;
查看當前數據庫全部表:show tables;
2.增長字段:alter table employee add is_married tinyint(1);
alter table employee add entry_date date not null;
alter table employee add A int,add b varchar(20);
3.刪除字段:alter table employee drop A;
alter table employee drop b,drop entry_date;
刪除表:drop table emp;
4.修改字段信息:alter table employee modify age smallint not null default 18 after name;
alter table employee change department depart varchar(20) after salary;
修改表名: rename table employee to emp;
修改表所用字符集: alter table student character set utf8;
4、表記錄操做
準備表數據
CREATE TABLE ExamResult( id INT PRIMARY KEY auto_increment, name VARCHAR (20), JS DOUBLE , Django DOUBLE , OpenStack DOUBLE );
插入:insert [into] tab_name (field1,filed2,.......) values (value1,value2,.......)
刪除:DELETE FROM emp WHERE id=11 OR id=2;
修改:UPDATE emp SET salary=salary+20000 WHERE name='yuan';
查詢:select [distinct] *|filed1,field2| [as 別名]|[別名] from tab_name;
mysql中五種查詢字句
mysql查詢執行順序
(7) SELECT (8) DISTINCT <select_list> (1) FROM <left_table> (3) <join_type> JOIN <right_table> (2) ON <join_condition> (4) WHERE <where_condition> (5) GROUP BY <group_by_list> (6) HAVING <having_condition> (9) ORDER BY <order_by_condition> (10) LIMIT <limit_number>
(1)增刪改查 insert into emp (id,age,name,gender,salary,depart,is_married) values(1,18,'alex',0,1700,'技術部',1); INSERT INTO emp(name,salary,depart) VALUES ('瞎驢',30000,'python'); INSERT INTO emp(name,salary,depart) VALUES ('xialv',30000,'python'), ('小雨',5000,'銷售部'), ('冰冰',9000,'銷售部'); insert emp set name='珊珊'; insert into emp values(10,'丹丹',29,0,3000,'銷售部',1); INSERT INTO emp(name,salary,depart) VALUES ('yuan',30000,'python'); UPDATE emp SET salary=salary+20000,depart='保安部' WHERE name='xialv'; delete from emp; (刪除表內容) truncate table emp; (先直接刪除整個表,在建立一個相同表結構的空表。大量數據時使用,直接刪除錶速度快。) insert into examresult(name) value('周守成'); INSERT INTO ExamResult VALUES (1,"yuan",98,98,98), (2,"xialv",35,98,67), (3,"alex",59,59,62), (4,"wusir",88,89,82), (5,"alvin",88,98,67), (6,"yuan",86,100,55); 練習:select * from examresult; select name,JS,Django,flask from examresult; select name 姓名,JS+10 as JS,Django+10 as Django,flask+10 as flask from examresult; select distinct name from examresult; //去重 (1)where:where字句中可以使用[比較運算符:< > <= >= <> !=,between and,in,like,邏輯運算符:and or not] 練習:select name,JS+Django+flask as 總成績 from examresult where JS+flask+Django>200; select name,JS from examresult where JS!=80; select name,JS from examresult where JS between 90 and 100; select name,JS from examresult where JS in(88,99,77); select name,JS from examresult where name like 'y%'; // %: 任意多個字符 select name,JS from examresult where name like 'y_'; // _:一個字符 select name,JS from examresult where name='yuan' and JS>80; select name from examresult where JS is null; //空考的學生 (2)order by 指定排序的列(排序的列可使表中的列名,也能夠是select語句中的別名) --asc爲升序,desc爲降序,默認爲asc,order by應爲於select語句的結尾 select name,JS from examresult order by JS; select name,JS from examresult where JS between 70 and 100 order by JS; //默認升序 select name,JS from examresult where JS between 70 and 100 order by JS desc; //降序 select name,JS+Django+flask as 總成績 from examresult order by 總成績 desc; select name,JS+Django+flask as 總成績 from examresult where name='yuan' order by 總成績 desc; 注:select JS as JS總成績 from examresult where JS總成績>70; 這條語句不能正確執行 select語句的執行順序:from 表名 -> where -> select ->......->order by (3)group by:分組查詢 --常和聚合函數配合使用 注:-- 按分組條件分組後每一組只會顯示第一條記錄 -- group by字句,其後能夠接多個列名,也能夠跟having子句,對group by 的結果進行篩選。 按列名分組 select * from examresult group by name; 按位置字段分組 select * from examresult group by 2; 將成績表按名字分組後,顯示每一組JS成績的分數總和 select name,sum(JS) from examresult group by name; 將成績表按照名字分組後,顯示每一類名字的Django的分數總和>150的類名字和Django總分 select name,sum(Django) from examresult group by name having sum(Django)>150; 查詢每一個部門中男性和女性的人數 select depart,gender,count(id) from emp group by depart,gender; having 和 where二者均可以對查詢結果進行進一步的過濾,差異有: <1>where語句只能用在分組以前的篩選,having能夠用在分組以後的篩選; <2>使用where語句的地方均可以用having進行替換 <3>having中能夠用聚合函數,where中就不行。 (4)聚合函數:[count,sum,avg,max,min]--常和分組函數配合使用 --統計JS>70的人數 select count(id) from examresult where JS>70; --統計JS的平均分 select sum(JS)/count(name) from examresult; //算上了JS爲null的狀況 select avg(JS) from examresult; //不算JS爲null -- 統計總分大於280的人數有多少? select count(name) from ExamResult where (ifnull(JS,0)+ifnull(Django,0)+ifnull(OpenStack,0))>280; --查詢JS總分中最小值 select min(JS) from examresult; select min(ifnull(JS,0)) from examresult; --查詢JS+Django+flask總分中最大的 select max(JS+Django+flask) from examresult; (5)limit: select * from examresult limit 3;顯示前3條 select * from examresult limit 2,3; //跳過前兩條顯示接下來的3條 (6)重點: --sql語句書寫順序:select from where group by having order by --sql語句執行順序:from where select group by having order by 例子: select JS as JS成績 from examresult where JS成績>70; //執行不成功 select JS as JS成績 from examresult where JS成績>70; //成功執行 (7)使用正則表達式查詢 SELECT * FROM employee WHERE name REGEXP '^yu'; SELECT * FROM employee WHERE name REGEXP 'yun$'; SELECT * FROM employee WHERE name REGEXP 'm{2}';
5、外鍵約束
建立外鍵
--- 每個班主任會對應多個學生 , 而每一個學生只能對應一個班主任
--1.數據準備:
----主表
CREATE TABLE ClassCharger(
id TINYINT PRIMARY KEY auto_increment,
name VARCHAR (20),
age INT ,
is_marriged boolean -- show create table ClassCharger: tinyint(1)
);
INSERT INTO ClassCharger (name,age,is_marriged) VALUES ("冰冰",12,0),
("丹丹",14,0),
("歪歪",22,0),
("姍姍",20,0),
("小雨",21,0);
----子表
CREATE TABLE Student(
id INT PRIMARY KEY auto_increment,
name VARCHAR (20),
charger_id TINYINT,
foreign key (charger_id) references classcharger(id) on delete cascade
) ENGINE=INNODB;
--切記:做爲外鍵必定要和關聯主鍵的數據類型保持一致
-- [ADD CONSTRAINT charger_fk_stu]FOREIGN KEY (charger_id) REFERENCES ClassCharger(id)
INSERT INTO Student2(name,charger_id) VALUES ("alvin1",2),
("alvin2",4),
("alvin3",1),
("alvin4",3),
("alvin5",5),
("alvin6",3),
("alvin7",3);
--2.外鍵約束練習
刪除班主任丹丹
delete from classcharger where id=2; --會報錯
先刪除班主任丹丹關聯的學生
update student set charger_id=4 where id=1 or id=7;
delete from classcharger where id=2; --成功執行
添加一個學生,班主任選擇丹丹
insert into student(name,charger_id) values('sasa',2); --添加失敗
-----------增長外鍵和刪除外鍵---------
ALTER TABLE student ADD CONSTRAINT abc
FOREIGN KEY(charger_id)
REFERENCES classcharger(id);
ALTER TABLE student DROP FOREIGN KEY abc;
alter table student3 drop foreign key student3_ibfk_1;
alter table student3 add constraint s3_fk_c foreign key(charger_id) references C(id) on delete set null;
3.INNODB支持的on語句
--外鍵約束對子表的含義: 若是在父表中找不到候選鍵,則不容許在子表上進行insert/update
--外鍵約束對父表的含義: 在父表上進行update/delete以更新或刪除在子表中有一條或多條對
-- 應匹配行的候選鍵時,父表的行爲取決於:在定義子表的外鍵時指定的
-- on update/on delete子句
-----------------innodb支持的四種方式---------------------------------------
-----cascade方式 在父表上update/delete記錄時,同步update/delete掉子表的匹配記錄
-----外鍵的級聯刪除:若是父表中的記錄被刪除,則子表中對應的記錄自動被刪除--------
FOREIGN KEY (charger_id) REFERENCES ClassCharger(id)
ON DELETE CASCADE
------set null方式 在父表上update/delete記錄時,將子表上匹配記錄的列設爲null
-- 要注意子表的外鍵列不能爲not null
FOREIGN KEY (charger_id) REFERENCES ClassCharger(id)
ON DELETE SET NULL
------Restrict方式 :拒絕對父表進行刪除更新操做(瞭解)
------No action方式 在mysql中同Restrict,若是子表中有匹配的記錄,則不容許對父表對應候選鍵
-- 進行update/delete操做(瞭解)
6、連表查詢
一、內聯接(典型的聯接運算,使用像 = 或 <> 之類的比較運算符)。包括相等聯接和天然聯接。
二、外聯接。外聯接能夠是左向外聯接、右向外聯接或完整外部聯接。
三、交叉聯接
交叉聯接返回左表中的全部行,左表中的每一行與右表中的全部行組合。交叉聯接也稱做笛卡爾積。
FROM 子句中的表或視圖可經過內聯接或完整外部聯接按任意順序指定;可是,用左或右向外聯接指定表或視圖時,表或視圖的順序很重要。有關使用左或右向外聯接排列表的更多信息,請參見使用外聯接。
mysql> use flask_code Database changed mysql> show tables; +----------------------+ | Tables_in_flask_code | +----------------------+ | record | | userinfo | +----------------------+ 2 rows in set (0.00 sec) mysql> select * from record; +----+------+------------+---------+ | id | line | ctime | user_id | +----+------+------------+---------+ | 1 | 1000 | 2018-12-19 | 1 | | 2 | 5000 | 2018-12-17 | 3 | | 3 | 3000 | 2018-12-21 | 3 | | 5 | 269 | 2018-12-26 | 3 | | 6 | 269 | 2018-12-27 | 3 | +----+------+------------+---------+ 5 rows in set (0.00 sec) mysql> select * from userinfo; +----+------------+----------------------------------+--------------+ | id | username | password | nickname | +----+------------+----------------------------------+--------------+ | 1 | zhangsan | 317bc264bfd3d562fa415dbb905e2d8a | 就是這麼牛逼 | | 2 | lisi | 317bc264bfd3d562fa415dbb905e2d8a | 看把你牛逼的 | | 3 | zhangyafei | 317bc264bfd3d562fa415dbb905e2d8a | 張亞飛 | +----+------------+----------------------------------+--------------+ 3 rows in set (0.00 sec) mysql> select userinfo.nickname,record.line from record,userinfo where record.us er_id = userinfo.id; +--------------+------+ | nickname | line | +--------------+------+ | 就是這麼牛逼 | 1000 | | 張亞飛 | 5000 | | 張亞飛 | 3000 | | 張亞飛 | 269 | | 張亞飛 | 269 | +--------------+------+ 5 rows in set (0.00 sec) mysql> select userinfo.nickname,record.line from record inner join userinfo on u serinfo.id = record.user_id; +--------------+------+ | nickname | line | +--------------+------+ | 就是這麼牛逼 | 1000 | | 張亞飛 | 5000 | | 張亞飛 | 3000 | | 張亞飛 | 269 | | 張亞飛 | 269 | +--------------+------+ 5 rows in set (0.00 sec) mysql> select userinfo.nickname,record.line from record left join userinfo on us erinfo.id = record.user_id; +--------------+------+ | nickname | line | +--------------+------+ | 就是這麼牛逼 | 1000 | | 張亞飛 | 5000 | | 張亞飛 | 3000 | | 張亞飛 | 269 | | 張亞飛 | 269 | +--------------+------+ 5 rows in set (0.00 sec) mysql> select userinfo.nickname,record.line from record right join userinfo on u serinfo.id = record.user_id; +--------------+------+ | nickname | line | +--------------+------+ | 就是這麼牛逼 | 1000 | | 張亞飛 | 5000 | | 張亞飛 | 3000 | | 張亞飛 | 269 | | 張亞飛 | 269 | | 看把你牛逼的 | NULL | +--------------+------+ 6 rows in set (0.00 sec) mysql> select * from record right join userinfo on userinfo.id = record.user_id; +------+------+------------+---------+----+------------+------------------------ ----------+--------------+ | id | line | ctime | user_id | id | username | password | nickname | +------+------+------------+---------+----+------------+------------------------ ----------+--------------+ | 1 | 1000 | 2018-12-19 | 1 | 1 | zhangsan | 317bc264bfd3d562fa415db b905e2d8a | 就是這麼牛逼 | | 2 | 5000 | 2018-12-17 | 3 | 3 | zhangyafei | 317bc264bfd3d562fa415db b905e2d8a | 張亞飛 | | 3 | 3000 | 2018-12-21 | 3 | 3 | zhangyafei | 317bc264bfd3d562fa415db b905e2d8a | 張亞飛 | | 5 | 269 | 2018-12-26 | 3 | 3 | zhangyafei | 317bc264bfd3d562fa415db b905e2d8a | 張亞飛 | | 6 | 269 | 2018-12-27 | 3 | 3 | zhangyafei | 317bc264bfd3d562fa415db b905e2d8a | 張亞飛 | | NULL | NULL | NULL | NULL | 2 | lisi | 317bc264bfd3d562fa415db b905e2d8a | 看把你牛逼的 | +------+------+------------+---------+----+------------+------------------------ ----------+--------------+ 6 rows in set (0.00 sec) mysql> select userinfo.id,nickname,ifnull(sum(line),0) as line from record right join userinfo on userinfo.id=record.user_id group by userinfo.id order by line desc; +----+--------------+------+ | id | nickname | line | +----+--------------+------+ | 3 | 張亞飛 | 8538 | | 1 | 就是這麼牛逼 | 1000 | | 2 | 看把你牛逼的 | 0 | +----+--------------+------+ 3 rows in set (0.00 sec)
mysql> select * from record; +----+------+------------+---------+ | id | line | ctime | user_id | +----+------+------------+---------+ | 1 | 1000 | 2018-12-19 | 1 | | 2 | 5000 | 2018-12-17 | 3 | | 3 | 3000 | 2018-12-21 | 3 | | 5 | 269 | 2018-12-26 | 3 | | 6 | 269 | 2018-12-27 | 3 | +----+------+------------+---------+ 5 rows in set (0.00 sec) mysql> select * from userinfo; +----+------------+----------------------------------+--------------+ | id | username | password | nickname | +----+------------+----------------------------------+--------------+ | 1 | zhangsan | 317bc264bfd3d562fa415dbb905e2d8a | 就是這麼牛逼 | | 2 | lisi | 317bc264bfd3d562fa415dbb905e2d8a | 看把你牛逼的 | | 3 | zhangyafei | 317bc264bfd3d562fa415dbb905e2d8a | 張亞飛 | | 4 | yaoming | 317bc264bfd3d562fa415dbb905e2d8a | 姚明 | +----+------------+----------------------------------+--------------+ 4 rows in set (0.00 sec) mysql> select * from record cross join userinfo; +----+------+------------+---------+----+------------+-------------------------- --------+--------------+ | id | line | ctime | user_id | id | username | password | nickname | +----+------+------------+---------+----+------------+-------------------------- --------+--------------+ | 1 | 1000 | 2018-12-19 | 1 | 1 | zhangsan | 317bc264bfd3d562fa415dbb9 05e2d8a | 就是這麼牛逼 | | 1 | 1000 | 2018-12-19 | 1 | 2 | lisi | 317bc264bfd3d562fa415dbb9 05e2d8a | 看把你牛逼的 | | 1 | 1000 | 2018-12-19 | 1 | 3 | zhangyafei | 317bc264bfd3d562fa415dbb9 05e2d8a | 張亞飛 | | 1 | 1000 | 2018-12-19 | 1 | 4 | yaoming | 317bc264bfd3d562fa415dbb9 05e2d8a | 姚明 | | 2 | 5000 | 2018-12-17 | 3 | 1 | zhangsan | 317bc264bfd3d562fa415dbb9 05e2d8a | 就是這麼牛逼 | | 2 | 5000 | 2018-12-17 | 3 | 2 | lisi | 317bc264bfd3d562fa415dbb9 05e2d8a | 看把你牛逼的 | | 2 | 5000 | 2018-12-17 | 3 | 3 | zhangyafei | 317bc264bfd3d562fa415dbb9 05e2d8a | 張亞飛 | | 2 | 5000 | 2018-12-17 | 3 | 4 | yaoming | 317bc264bfd3d562fa415dbb9 05e2d8a | 姚明 | | 3 | 3000 | 2018-12-21 | 3 | 1 | zhangsan | 317bc264bfd3d562fa415dbb9 05e2d8a | 就是這麼牛逼 | | 3 | 3000 | 2018-12-21 | 3 | 2 | lisi | 317bc264bfd3d562fa415dbb9 05e2d8a | 看把你牛逼的 | | 3 | 3000 | 2018-12-21 | 3 | 3 | zhangyafei | 317bc264bfd3d562fa415dbb9 05e2d8a | 張亞飛 | | 3 | 3000 | 2018-12-21 | 3 | 4 | yaoming | 317bc264bfd3d562fa415dbb9 05e2d8a | 姚明 | | 5 | 269 | 2018-12-26 | 3 | 1 | zhangsan | 317bc264bfd3d562fa415dbb9 05e2d8a | 就是這麼牛逼 | | 5 | 269 | 2018-12-26 | 3 | 2 | lisi | 317bc264bfd3d562fa415dbb9 05e2d8a | 看把你牛逼的 | | 5 | 269 | 2018-12-26 | 3 | 3 | zhangyafei | 317bc264bfd3d562fa415dbb9 05e2d8a | 張亞飛 | | 5 | 269 | 2018-12-26 | 3 | 4 | yaoming | 317bc264bfd3d562fa415dbb9 05e2d8a | 姚明 | | 6 | 269 | 2018-12-27 | 3 | 1 | zhangsan | 317bc264bfd3d562fa415dbb9 05e2d8a | 就是這麼牛逼 | | 6 | 269 | 2018-12-27 | 3 | 2 | lisi | 317bc264bfd3d562fa415dbb9 05e2d8a | 看把你牛逼的 | | 6 | 269 | 2018-12-27 | 3 | 3 | zhangyafei | 317bc264bfd3d562fa415dbb9 05e2d8a | 張亞飛 | | 6 | 269 | 2018-12-27 | 3 | 4 | yaoming | 317bc264bfd3d562fa415dbb9 05e2d8a | 姚明 | +----+------+------------+---------+----+------------+-------------------------- --------+--------------+ 20 rows in set (0.00 sec) mysql> select * from record,userinfo; +----+------+------------+---------+----+------------+-------------------------- --------+--------------+ | id | line | ctime | user_id | id | username | password | nickname | +----+------+------------+---------+----+------------+-------------------------- --------+--------------+ | 1 | 1000 | 2018-12-19 | 1 | 1 | zhangsan | 317bc264bfd3d562fa415dbb9 05e2d8a | 就是這麼牛逼 | | 1 | 1000 | 2018-12-19 | 1 | 2 | lisi | 317bc264bfd3d562fa415dbb9 05e2d8a | 看把你牛逼的 | | 1 | 1000 | 2018-12-19 | 1 | 3 | zhangyafei | 317bc264bfd3d562fa415dbb9 05e2d8a | 張亞飛 | | 1 | 1000 | 2018-12-19 | 1 | 4 | yaoming | 317bc264bfd3d562fa415dbb9 05e2d8a | 姚明 | | 2 | 5000 | 2018-12-17 | 3 | 1 | zhangsan | 317bc264bfd3d562fa415dbb9 05e2d8a | 就是這麼牛逼 | | 2 | 5000 | 2018-12-17 | 3 | 2 | lisi | 317bc264bfd3d562fa415dbb9 05e2d8a | 看把你牛逼的 | | 2 | 5000 | 2018-12-17 | 3 | 3 | zhangyafei | 317bc264bfd3d562fa415dbb9 05e2d8a | 張亞飛 | | 2 | 5000 | 2018-12-17 | 3 | 4 | yaoming | 317bc264bfd3d562fa415dbb9 05e2d8a | 姚明 | | 3 | 3000 | 2018-12-21 | 3 | 1 | zhangsan | 317bc264bfd3d562fa415dbb9 05e2d8a | 就是這麼牛逼 | | 3 | 3000 | 2018-12-21 | 3 | 2 | lisi | 317bc264bfd3d562fa415dbb9 05e2d8a | 看把你牛逼的 | | 3 | 3000 | 2018-12-21 | 3 | 3 | zhangyafei | 317bc264bfd3d562fa415dbb9 05e2d8a | 張亞飛 | | 3 | 3000 | 2018-12-21 | 3 | 4 | yaoming | 317bc264bfd3d562fa415dbb9 05e2d8a | 姚明 | | 5 | 269 | 2018-12-26 | 3 | 1 | zhangsan | 317bc264bfd3d562fa415dbb9 05e2d8a | 就是這麼牛逼 | | 5 | 269 | 2018-12-26 | 3 | 2 | lisi | 317bc264bfd3d562fa415dbb9 05e2d8a | 看把你牛逼的 | | 5 | 269 | 2018-12-26 | 3 | 3 | zhangyafei | 317bc264bfd3d562fa415dbb9 05e2d8a | 張亞飛 | | 5 | 269 | 2018-12-26 | 3 | 4 | yaoming | 317bc264bfd3d562fa415dbb9 05e2d8a | 姚明 | | 6 | 269 | 2018-12-27 | 3 | 1 | zhangsan | 317bc264bfd3d562fa415dbb9 05e2d8a | 就是這麼牛逼 | | 6 | 269 | 2018-12-27 | 3 | 2 | lisi | 317bc264bfd3d562fa415dbb9 05e2d8a | 看把你牛逼的 | | 6 | 269 | 2018-12-27 | 3 | 3 | zhangyafei | 317bc264bfd3d562fa415dbb9 05e2d8a | 張亞飛 | | 6 | 269 | 2018-12-27 | 3 | 4 | yaoming | 317bc264bfd3d562fa415dbb9 05e2d8a | 姚明 | +----+------+------------+---------+----+------------+-------------------------- --------+--------------+ 20 rows in set (0.00 sec)
7、聯合查詢
1、UNION和UNION ALL的做用和語法
UNION 用於合併兩個或多個 SELECT 語句的結果集,並消去表中任何重複行。
UNION 內部的 SELECT 語句必須擁有相同數量的列,列也必須擁有類似的數據類型。
同時,每條 SELECT 語句中的列的順序必須相同.
SQL UNION 語法:
sql腳本代碼以下:
1 SELECT column_name FROM table1 2 UNION 3 SELECT column_name FROM table2
註釋:默認地,UNION 操做符選取不一樣的值。若是容許重複的值,請使用 UNION ALL。
當 ALL 隨 UNION 一塊兒使用時(即 UNION ALL),不消除重複行
SQL UNION ALL 語法
sql腳本代碼以下:
1 SELECT column_name FROM table1 2 UNION ALL 3 SELECT column_name FROM table2
註釋:另外,UNION 結果集中的列名老是等於 UNION 中第一個 SELECT 語句中的列名。
注意:一、UNION 結果集中的列名老是等於第一個 SELECT 語句中的列名
二、UNION 內部的 SELECT 語句必須擁有相同數量的列。列也必須擁有類似的數據類型。同時,每條 SELECT 語句中的列的順序必須相同
2、union的用法及注意事項
union:聯合的意思,即把兩次或屢次查詢結果合併起來。
要求:兩次查詢的列數必須一致
推薦:列的類型能夠不同,但推薦查詢的每一列,想對應的類型以同樣
能夠來自多張表的數據:屢次sql語句取出的列名能夠不一致,此時以第一個sql語句的列名爲準。
若是不一樣的語句中取出的行,有徹底相同(這裏表示的是每一個列的值都相同),那麼union會將相同的行合併,最終只保留一行。也能夠這樣理解,union會去掉重複的行。
若是不想去掉重複的行,可使用union all。
若是子句中有order by,limit,需用括號()包起來。推薦放到全部子句以後,即對最終合併的結果來排序或篩選。
如:sql腳本代碼以下:
1 (select * from a order by id) union (select * from b order id);
在子句中,order by 須要配合limit使用纔有意義。若是不配合limit使用,會被語法分析器優化分析時去除。
3、學習例子
# 選擇數據庫 mysql> use flask_code Database changed # 查看錶 mysql> show tables; +----------------------+ | Tables_in_flask_code | +----------------------+ | record | | userinfo | +----------------------+ 2 rows in set (0.01 sec) mysql> select * from userinfo; +----+------------+----------------------------------+--------------+ | id | username | password | nickname | +----+------------+----------------------------------+--------------+ | 1 | zhangsan | 317bc264bfd3d562fa415dbb905e2d8a | 就是這麼牛逼 | | 2 | lisi | 317bc264bfd3d562fa415dbb905e2d8a | 看把你牛逼的 | | 3 | zhangyafei | 317bc264bfd3d562fa415dbb905e2d8a | 張亞飛 | | 4 | yaoming | 317bc264bfd3d562fa415dbb905e2d8a | 姚明 | +----+------------+----------------------------------+--------------+ 4 rows in set (0.08 sec) # 建立和已有表結構相同的額表 mysql> create table userinfo2 like userinfo; Query OK, 0 rows affected (0.48 sec) # 插入和另外一個結構相同的表的數據 mysql> insert into userinfo2 select * from userinfo limit 1,3; Query OK, 3 rows affected (0.12 sec) Records: 3 Duplicates: 0 Warnings: 0 mysql> insert into userinfo2(username,password,nickname) values('kobe', '317b 64bfd3d562fa415dbb905e2d8a', '科比'); Query OK, 1 row affected (0.05 sec) mysql> select * from userinfo2; +----+------------+----------------------------------+--------------+ | id | username | password | nickname | +----+------------+----------------------------------+--------------+ | 2 | lisi | 317bc264bfd3d562fa415dbb905e2d8a | 看把你牛逼的 | | 3 | zhangyafei | 317bc264bfd3d562fa415dbb905e2d8a | 張亞飛 | | 4 | yaoming | 317bc264bfd3d562fa415dbb905e2d8a | 姚明 | | 5 | kobe | 317bc264bfd3d562fa415dbb905e2d8a | 科比 | +----+------------+----------------------------------+--------------+ 4 rows in set (0.00 sec) # union:上下鏈接兩張表,且去重重複的行 mysql> select * from userinfo -> union -> select * from userinfo2; +----+------------+----------------------------------+--------------+ | id | username | password | nickname | +----+------------+----------------------------------+--------------+ | 1 | zhangsan | 317bc264bfd3d562fa415dbb905e2d8a | 就是這麼牛逼 | | 2 | lisi | 317bc264bfd3d562fa415dbb905e2d8a | 看把你牛逼的 | | 3 | zhangyafei | 317bc264bfd3d562fa415dbb905e2d8a | 張亞飛 | | 4 | yaoming | 317bc264bfd3d562fa415dbb905e2d8a | 姚明 | | 5 | kobe | 317bc264bfd3d562fa415dbb905e2d8a | 科比 | +----+------------+----------------------------------+--------------+ 5 rows in set (0.00 sec) # union all:上下鏈接兩張表,不去除重複的行 mysql> select * from userinfo union all select * from userinfo2; +----+------------+----------------------------------+--------------+ | id | username | password | nickname | +----+------------+----------------------------------+--------------+ | 1 | zhangsan | 317bc264bfd3d562fa415dbb905e2d8a | 就是這麼牛逼 | | 2 | lisi | 317bc264bfd3d562fa415dbb905e2d8a | 看把你牛逼的 | | 3 | zhangyafei | 317bc264bfd3d562fa415dbb905e2d8a | 張亞飛 | | 4 | yaoming | 317bc264bfd3d562fa415dbb905e2d8a | 姚明 | | 2 | lisi | 317bc264bfd3d562fa415dbb905e2d8a | 看把你牛逼的 | | 3 | zhangyafei | 317bc264bfd3d562fa415dbb905e2d8a | 張亞飛 | | 4 | yaoming | 317bc264bfd3d562fa415dbb905e2d8a | 姚明 | | 5 | kobe | 317bc264bfd3d562fa415dbb905e2d8a | 科比 | +----+------------+----------------------------------+--------------+ 8 rows in set (0.00 sec)
8、limit分頁
Limit子句能夠被用於強制 SELECT 語句返回指定的記錄數。Limit接受一個或兩個數字參數。參數必須是一個整數常量。若是給定兩個參數,第一個參數指定第一個返回記錄行的偏移量,第二個參數指定返回記錄行的最大數目。
//初始記錄行的偏移量是 0(而不是 1):
mysql> SELECT * FROM table LIMIT 5,10; //檢索記錄行6-15
//若是隻給定一個參數,它表示返回最大的記錄行數目。換句話說,LIMIT n 等價於 LIMIT 0,n:
mysql> SELECT * FROM table LIMIT 5; //檢索前 5 個記錄行
Limit的效率高?
常說的Limit的執行效率高,是對於一種特定條件下來講的:即數據庫的數量很大,可是隻須要查詢一部分數據的狀況。
高效率的原理是:避免全表掃描,提升查詢效率。
好比:每一個用戶的email是惟一的,若是用戶使用email做爲用戶名登錄的話,就須要查詢出email對應的一條記錄。
SELECT * FROM t_user WHERE email=?;
上面的語句實現了查詢email對應的一條用戶信息,可是因爲email這一列沒有加索引,會致使全表掃描,效率會很低。
SELECT * FROM t_user WHERE email=? LIMIT 1;
加上LIMIT 1,只要找到了對應的一條記錄,就不會繼續向下掃描了,效率會大大提升。
Limit的效率低?
在一種狀況下,使用limit效率低,那就是:只使用limit來查詢語句,而且偏移量特別大的狀況
作如下實驗:
語句1:
select * from table limit 150000,1000;
語句2:
select * from table while id>=150000 limit 1000;
語句1爲0.2077秒;語句2爲0.0063秒
兩條語句的時間比是:語句1/語句2=32.968
比較以上的數據時,咱們能夠發現採用where...limit....性能基本穩定,受偏移量和行數的影響不大,而單純採用limit的話,受偏移量的影響很大,當偏移量大到必定後性能開始大幅降低。不過在數據量不大的狀況下,二者的區別不大。
因此應當先使用where等查詢語句,配合limit使用,效率才高
ps:在sql語句中,limt關鍵字是最後纔用到的。如下條件的出現順序通常是:where->group by->having-order by->limit
附錄:OFFSET
爲了與 PostgreSQL 兼容,MySQL 也支持句法: LIMIT # OFFSET #。
常常用到在數據庫中查詢中間幾條數據的需求
好比下面的sql語句:
① selete * from testtable limit 2,1;
② selete * from testtable limit 2 offset 1;
注意:
1.數據庫數據計算是從0開始的
2.offset X是跳過X個數據,limit Y是選取Y個數據
3.limit X,Y 中X表示跳過X個數據,讀取Y個數據
這兩個都是能完成須要,可是他們之間是有區別的:
①是從數據庫中第三條開始查詢,取一條數據,即第三條數據讀取,一二條跳過
②是從數據庫中的第二條數據開始查詢兩條數據,即第二條和第三條。
mysql> select * from proxy limit 5; +----+-----------------+-------+----------+-------+-------+-----------+--------- --------+ | ID | IP | PORT | POSITION | TYPE | SPEED | LIVE_TIME | LAST_CHE CK_TIME | +----+-----------------+-------+----------+-------+-------+-----------+--------- --------+ | 1 | 111.72.154.107 | 53128 | 江西宜春 | HTTPS | 1.221 | 17分鐘 | 18-07-17 09:01 | | 2 | 125.121.120.14 | 6666 | 浙江杭州 | HTTPS | 1.542 | 1分鐘 | 18-07-17 21:01 | | 3 | 1.197.59.174 | 41869 | 河南漯河 | HTTPS | 3.032 | 292天 | 18-07-17 08:55 | | 4 | 125.118.247.32 | 6666 | 浙江杭州 | HTTPS | 0.19 | 33天 | 18-07-18 09:22 | | 5 | 125.121.117.139 | 6666 | 浙江杭州 | HTTP | 0.161 | 4分鐘 | 18-07-18 05:20 | +----+-----------------+-------+----------+-------+-------+-----------+--------- --------+ 5 rows in set (0.00 sec) mysql> select * from proxy limit 5,10; +----+----------------+-------+----------+-------+-------+-----------+---------- -------+ | ID | IP | PORT | POSITION | TYPE | SPEED | LIVE_TIME | LAST_CHEC K_TIME | +----+----------------+-------+----------+-------+-------+-----------+---------- -------+ | 6 | 117.86.19.111 | 18118 | 江蘇南通 | HTTPS | 4.954 | 1分鐘 | 18-07-17 21:01 | | 7 | 110.73.41.238 | 8123 | 廣西南寧 | HTTP | 3.16 | 609天 | 18-07-17 12:30 | | 8 | 182.86.189.123 | 48148 | 江西 | HTTPS | 0.224 | 1分鐘 | 18-07-17 16:22 | | 9 | 221.228.17.172 | 8181 | 江蘇無錫 | HTTPS | 6.462 | 73天 | 18-07-18 17:41 | | 10 | 115.223.65.147 | 8010 | 浙江溫州 | HTTPS | 0.785 | 1分鐘 | 18-07-17 08:46 | | 11 | 49.87.135.30 | 53128 | 江蘇淮安 | HTTPS | 0.3 | 1分鐘 | 18-07-18 09:22 | | 12 | 183.15.121.130 | 28094 | 廣東深圳 | HTTP | 0.481 | 1分鐘 | 18-07-17 06:30 | | 13 | 183.128.241.77 | 6666 | 浙江杭州 | HTTPS | 3.093 | 25天 | 18-07-18 01:40 | | 14 | 49.74.91.98 | 53281 | 江蘇南京 | HTTP | 7.233 | 14天 | 18-07-18 05:20 | | 15 | 114.231.68.16 | 18118 | 江蘇南通 | HTTPS | 6.159 | 5分鐘 | 18-07-17 21:01 | +----+----------------+-------+----------+-------+-------+-----------+---------- -------+ 10 rows in set (0.00 sec) mysql> select count(*) from proxy; +----------+ | count(*) | +----------+ | 1800 | +----------+ 1 row in set (0.00 sec) mysql> select * from proxy limit 1795,-1; ERROR 1064 (42000): You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '-1' a t line 1 mysql> select * from proxy limit 795,-1; ERROR 1064 (42000): You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '-1' a t line 1 mysql> select * from proxy limit 2 offset 1; +----+----------------+-------+----------+-------+-------+-----------+---------- -------+ | ID | IP | PORT | POSITION | TYPE | SPEED | LIVE_TIME | LAST_CHEC K_TIME | +----+----------------+-------+----------+-------+-------+-----------+---------- -------+ | 2 | 125.121.120.14 | 6666 | 浙江杭州 | HTTPS | 1.542 | 1分鐘 | 18-07-17 21:01 | | 3 | 1.197.59.174 | 41869 | 河南漯河 | HTTPS | 3.032 | 292天 | 18-07-17 08:55 | +----+----------------+-------+----------+-------+-------+-----------+---------- -------+ 2 rows in set (0.00 sec)
9、 數據庫引擎
Mysql引擎種類:innodb,mysaim
Innodb引擎 Innodb引擎提供了對數據庫ACID事務的支持,而且實現了SQL標準的四種隔離級別,關於數據庫事務與其隔離級別的內容請見數據庫事務與其隔 離級別這篇文章。
該引擎還提供了行級鎖和外鍵約束,它的設計目標是處理大容量數據庫系統,它自己其實就是基於MySQL後臺的完整數據庫系統,MySQL 運行時Innodb會在內存中創建緩衝池,
用於緩衝數據和索引。可是該引擎不支持FULLTEXT類型的索引,並且它沒有保存表的行數,當SELECT COUNT(*) FROM TABLE時須要掃描全表。當須要使用數據庫事務時,
該引擎固然是首選。因爲鎖的粒度更小,寫操做不會鎖定全表,因此在併發較高時,使用Innodb引擎 會提高效率。可是使用行級鎖也不是絕對的,若是在執行一個SQL語句時
MySQL不能肯定要掃描的範圍,InnoDB表一樣會鎖全表。 MyIASM引擎 MyIASM是MySQL默認的引擎,可是它沒有提供對數據庫事務的支持,也不支持行級鎖和外鍵,所以當INSERT(插入)或UPDATE(更 新)數據時即寫操做須要鎖定整個表,
效率便會低一些。不過和Innodb不一樣,MyIASM中存儲了表的行數,因而SELECT COUNT(*) FROM TABLE時只須要直接讀取已經保存好的值而不須要進行全表掃描。
若是表的讀操做遠遠多於寫操做且不須要數據庫事務的支持,那麼MyIASM也是很好的選 擇。 兩種引擎的選擇 大尺寸的數據集趨向於選擇InnoDB引擎,由於它支持事務處理和故障恢復。數據庫的大小決定了故障恢復的時間長短,InnoDB能夠利用事務日誌 進行數據恢復,
這會比較快。主鍵查詢在InnoDB引擎下也會至關快,不過須要注意的是若是主鍵太長也會致使性能問題,關於這個問題我會在下文中講到。大 批的INSERT語句
(在每一個INSERT語句中寫入多行,批量插入)在MyISAM下會快一些,可是UPDATE語句在InnoDB下則會更快一些,尤 其是在併發量大的時候。 Index——索引 索引(Index)是幫助MySQL高效獲取數據的數據結構。MyIASM和Innodb都使用了樹這種數據結構作爲索引,關於樹我也曾經寫過一篇文章樹是一種偉大的數據結構,
只是本身的理解,有興趣的朋友能夠去閱讀。下面我接着講這兩種引擎使用的索引結構,講到這裏,首先應該談一下B-Tree和B+Tree。 B-Tree和B+Tree B+Tree是B-Tree的變種,那麼我就先講B-Tree吧,相信你們都知道紅黑樹,這是我前段時間學《算法》一書時,實現的一顆紅黑樹,你們 能夠參考。
其實紅黑樹相似2,3-查找樹,這種樹既有2叉結點又有3叉結點。B-Tree也與之相似,它的每一個結點作多能夠有d個分支(叉),d稱爲B- Tree的度,以下圖所示,
它的每一個結點能夠有4個元素,5個分支,因而它的度爲5。B-Tree中的元素是有序的,好比圖中元素7左邊的指針指向的結點 中的元素都小於7,而元素7和16之間
的指針指向的結點中的元素都處於7和16之間,正是知足這樣的關係,才能高效的查找:首先從根節點進行二分查找,找 到就返回對應的值,不然就進入相應的區間
結點遞歸的查找,直到找到對應的元素或找到null指針,找到null指針則表示查找失敗。這個查找是十分高效 的,其時間複雜度爲O(logN)(以d爲底,當d很大時,
樹的高度就很低),由於每次檢索最多隻須要檢索樹高h個結點。
mysql何時須要加鎖:計數- 應用場景- 商品數量
mysql如何加鎖:
終端1: begin; select * from tb for update; commit; 終端2: begin; select * from tb for update; commit;
mysql> begin; Query OK, 0 rows affected (0.00 sec) mysql> select * from record where id=2 for update; +----+------+------------+---------+ | id | line | ctime | user_id | +----+------+------------+---------+ | 2 | 5000 | 2018-12-17 | 3 | +----+------+------------+---------+ row in set (0.00 sec) mysql> select * from record for update; +----+------+------------+---------+ | id | line | ctime | user_id | +----+------+------------+---------+ | 1 | 1000 | 2018-12-19 | 1 | | 2 | 5000 | 2018-12-17 | 3 | | 3 | 3000 | 2018-12-21 | 3 | | 5 | 269 | 2018-12-26 | 3 | | 6 | 269 | 2018-12-27 | 3 | +----+------+------------+---------+ rows in set (0.00 sec) mysql> commit; Query OK, 0 rows affected (0.00 sec) mysql加鎖(行鎖和表鎖)示例
通常狀況下,mysql會默認提供多種存儲引擎,你能夠經過下面的查看:
mysql> show engines; +--------------------+---------+------------------------------------------------ ----------------+--------------+------+------------+ | Engine | Support | Comment | Transactions | XA | Savepoints | +--------------------+---------+------------------------------------------------ ----------------+--------------+------+------------+ | InnoDB | DEFAULT | Supports transactions, row-level locking, and f oreign keys | YES | YES | YES | | MRG_MYISAM | YES | Collection of identical MyISAM tables | NO | NO | NO | | MEMORY | YES | Hash based, stored in memory, useful for tempor ary tables | NO | NO | NO | | BLACKHOLE | YES | /dev/null storage engine (anything you write to it disappears) | NO | NO | NO | | MyISAM | YES | MyISAM storage engine | NO | NO | NO | | CSV | YES | CSV storage engine | NO | NO | NO | | ARCHIVE | YES | Archive storage engine | NO | NO | NO | | PERFORMANCE_SCHEMA | YES | Performance Schema | NO | NO | NO | | FEDERATED | NO | Federated MySQL storage engine | NULL | NULL | NULL | +--------------------+---------+------------------------------------------------ ----------------+--------------+------+------------+ 9 rows in set (0.00 sec) mysql> show variables like '%storage_engine%'; +----------------------------------+--------+ | Variable_name | Value | +----------------------------------+--------+ | default_storage_engine | InnoDB | | default_tmp_storage_engine | InnoDB | | disabled_storage_engines | | | internal_tmp_disk_storage_engine | InnoDB | +----------------------------------+--------+ 4 rows in set, 1 warning (0.11 sec) mysql> show create table record; +--------+---------------------------------------------------------------------- -------------------------------------------------------------------------------- -------------------------------------------------------------------------------- -------------------------------------------------------------------------------- ------------------------------------+ | Table | Create Table | +--------+---------------------------------------------------------------------- -------------------------------------------------------------------------------- -------------------------------------------------------------------------------- -------------------------------------------------------------------------------- ------------------------------------+ | record | CREATE TABLE `record` ( `id` int(11) NOT NULL AUTO_INCREMENT, `line` int(11) DEFAULT NULL, `ctime` date DEFAULT NULL, `user_id` int(11) DEFAULT NULL, PRIMARY KEY (`id`), KEY `user_id` (`user_id`), CONSTRAINT `record_ibfk_1` FOREIGN KEY (`user_id`) REFERENCES `userinfo` (`id` ) ) ENGINE=InnoDB AUTO_INCREMENT=7 DEFAULT CHARSET=utf8 | +--------+---------------------------------------------------------------------- -------------------------------------------------------------------------------- -------------------------------------------------------------------------------- -------------------------------------------------------------------------------- ------------------------------------+ 1 row in set (0.00 sec)
mysql> begin; Query OK, 0 rows affected (0.00 sec) mysql> select * from record where id=2 for update; +----+------+------------+---------+ | id | line | ctime | user_id | +----+------+------------+---------+ | 2 | 5000 | 2018-12-17 | 3 | +----+------+------------+---------+ 1 row in set (0.00 sec) mysql> select * from record for update; +----+------+------------+---------+ | id | line | ctime | user_id | +----+------+------------+---------+ | 1 | 1000 | 2018-12-19 | 1 | | 2 | 5000 | 2018-12-17 | 3 | | 3 | 3000 | 2018-12-21 | 3 | | 5 | 269 | 2018-12-26 | 3 | | 6 | 269 | 2018-12-27 | 3 | +----+------+------------+---------+ 5 rows in set (0.00 sec) mysql> commit; Query OK, 0 rows affected (0.00 sec)
pymysql cursor.execute('select * from record for update') django with trancation.automic(): models.User.objects.all().for_update()
補充:
explain select * from tb; id 查詢順序標識 如:mysql> explain select * from (select nid,name from tb1 where nid < 10) as B; +----+-------------+------------+-------+---------------+---------+---------+------+------+-------------+ | id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra | +----+-------------+------------+-------+---------------+---------+---------+------+------+-------------+ | 1 | PRIMARY | <derived2> | ALL | NULL | NULL | NULL | NULL | 9 | NULL | | 2 | DERIVED | tb1 | range | PRIMARY | PRIMARY | 8 | NULL | 9 | Using where | +----+-------------+------------+-------+---------------+---------+---------+------+------+-------------+ 特別的:若是使用union鏈接氣值可能爲null select_type 查詢類型 SIMPLE 簡單查詢 PRIMARY 最外層查詢 SUBQUERY 映射爲子查詢 DERIVED 子查詢 UNION 聯合 UNION RESULT 使用聯合的結果 ... table 正在訪問的表名 type 查詢時的訪問方式,性能:all < index < range < index_merge < ref_or_null < ref < eq_ref < system/const ALL 全表掃描,對於數據表從頭至尾找一遍 select * from tb1; 特別的:若是有limit限制,則找到以後就不在繼續向下掃描 select * from tb1 where email = 'seven@live.com' select * from tb1 where email = 'seven@live.com' limit 1; 雖然上述兩個語句都會進行全表掃描,第二句使用了limit,則找到一個後就再也不繼續掃描。 INDEX 全索引掃描,對索引從頭至尾找一遍 select nid from tb1; RANGE 對索引列進行範圍查找 select * from tb1 where name < 'alex'; PS: between and in > >= < <= 操做 注意:!= 和 > 符號 INDEX_MERGE 合併索引,使用多個單列索引搜索 select * from tb1 where name = 'alex' or nid in (11,22,33); REF 根據索引查找一個或多個值 select * from tb1 where name = 'seven'; EQ_REF 鏈接時使用primary key 或 unique類型 select tb2.nid,tb1.name from tb2 left join tb1 on tb2.nid = tb1.nid; CONST 常量 表最多有一個匹配行,由於僅有一行,在這行的列值可被優化器剩餘部分認爲是常數,const表很快,由於它們只讀取一次。 select nid from tb1 where nid = 2 ; SYSTEM 系統 表僅有一行(=系統表)。這是const聯接類型的一個特例。 select * from (select nid from tb1 where nid = 1) as A; possible_keys 可能使用的索引 key 真實使用的 key_len MySQL中使用索引字節長度 rows mysql估計爲了找到所需的行而要讀取的行數 ------ 只是預估值 extra 該列包含MySQL解決查詢的詳細信息 「Using index」 此值表示mysql將使用覆蓋索引,以免訪問表。不要把覆蓋索引和index訪問類型弄混了。 「Using where」 這意味着mysql服務器將在存儲引擎檢索行後再進行過濾,許多where條件裏涉及索引中的列,當(而且若是)它讀取索引時,就能被存儲引擎檢驗,所以不是全部帶where子句的查詢都會顯示「Using where」。有時「Using where」的出現就是一個暗示:查詢可受益於不一樣的索引。 「Using temporary」 這意味着mysql在對查詢結果排序時會使用一個臨時表。 「Using filesort」 這意味着mysql會對結果使用一個外部索引排序,而不是按索引次序從表裏讀取行。mysql有兩種文件排序算法,這兩種排序方式均可以在內存或者磁盤上完成,explain不會告訴你mysql將使用哪種文件排序,也不會告訴你排序會在內存裏仍是磁盤上完成。 「Range checked for each record(index map: N)」 這個意味着沒有好用的索引,新的索引將在聯接的每一行上從新估算,N是顯示在possible_keys列中索引的位圖,而且是冗餘的。
1 #建立數據庫# create database 數據庫名; 2 #查看數據庫# show databases; 3 4 #選擇數據庫# use 數據庫名; 5 6 #刪除數據庫# drop database 數據庫名; 7 8 9 10 #建立表# create table 表名(屬性名1 數據類型 ,屬性名2 數據類型。。。。); 11 12 #查看錶結構# desc 表名; 13 14 #查看建表語言# show create table 表名; 15 16 #表中新增字段# alter table 表名 add( 屬性名1 數據類型,屬性名2 數據類型.....); 17 18 #在表的第一個位置增長字段# alter table 表名 add 屬性名 數據類型 first; 19 20 #在指定字段後面增長字段# alter table 表名 add 新增屬性名 數據類型 after 屬性名; 21 22 #刪除表中字段# alter table 表名 drop 屬性名; 23 24 #刪除表# drop table 表名; 25 26 27 28 #修改表名# alter table 舊錶名 rename 新表名; 或alter table 舊錶名 rename to 新表名; 29 30 #修改表中字段的數據類型# alter table 表名 modify 須要修改的屬性名 想要修改爲的數據類型; 31 32 #修改表中字段名稱 alter table 表名 change 舊屬性名 新屬性名 舊數據類型; 33 34 #修改表中字段名稱和數據類型 alter table 表名 change 舊屬性名 新屬性名 新數據類型; 35 36 #修改表中字段爲頭字段# alter table 表名 modify 屬性名 數據類型 first; 37 38 #修改字段1爲順序,在字段2後面# alter table 表名 modify 屬性名1 數據類型 after 屬性名2; 39 40 41 42 #插入數據記錄# insert into 表名(字段1,字段2,.....或不寫) values(一條數據),(一條數據); 43 44 #插入查詢結果# insert into 要插入表表名 (插入表中字段1,插入表中字段2,.....) select (查詢表中字段1,查詢表中字段2......) from 要查詢表表名 查詢語句; 45 46 #更新數據記錄# update 表名 set 字段1=新值, 字段2=新值.........where 查詢語句; 47 48 #刪除數據記錄# delete from表名 where 查詢語句; 49 50 #查詢部分數據記錄# select 字段1,字段2。。。。 from 要查詢的表; 51 52 #避免重複查詢# select distinct 字段1,字段2。。。。 from 要查詢的表; 53 54 #爲查詢結果起別名# select 字段1 as或不寫 別名1,字段2 as或不寫 別名2。。。。 from 要查詢的表; 55 56 #設置顯示格式數據查詢# select concat(字段1,‘提示語句’,字段2。。。。) from 要查詢的表; 57 58 #where條件查詢# select * from 表名 where 字段=值; 59 60 #between and 關鍵字範圍查詢# select * from 表名 where 字段 between 值1 and 值2; 61 62 #between and 關鍵字再也不範圍內查詢# select * from 表名 where 字段 not between 值1 and 值2 ; 63 64 #帶null關鍵字空查詢# select * from 表名 where 字段 is not null; 或 select * from 表名 where 字段 is not null; 65 66 #帶in關鍵字的集合查詢# select 字段1 ,字段2.。。。。。from 表名 where 字段n in(值1,指2。。。。。); 67 68 #帶like關鍵字的模糊查詢# select * from 表名 where 字段 like ‘字段串%’ ; 或select * from 表名 where 字段 like ‘字段串_’ ; 或 select * from 表名 where not 字段 like ‘字段串_’ ; 69 70 #排序數據查詢# select * from 表名 order by 依照排序的字段名 asc(升序) 或 desc (降序); 71 72 #多字段排序# select * from 表名 order by 字段1 asc ,字段2 desc 。。。。; 73 74 #帶limit關鍵字的限制查詢數量# select * from 表名 where limit 開始條數位置 ,顯示條數; 75 76 #分組數據查詢# select * from 表名 group by 字段; #隨機顯示出每一個分組的一條數據,通常講分組與統計合起來使用纔有意義# 77 78 #帶having的分組限定查詢# select * from 表名 group by 字段 having 條件; 79 80 81 #inner join on內鏈接# select * from 表1 inner join 表2 on 條件; 82 83 #自鏈接# select e.字段 as 別名1,f.字段 as 別名2.。。。。from 表名 as e inner join 表 as f on 條件; 84 85 #from多表鏈接# select * from 表1 , 表 2 。。。 where 條件; 86 87 #左外鏈接# select * from 表1 left join 表2 on 條件; 88 89 #右外鏈接# select * from 表1 right join 表2 on 條件; 90 91 #容許重複值的合併查詢# select * from 表1 union all 表2 on 條件; 92 93 #不含重複值的合併查詢# select * from 表1 union 表2 on 條件; 94 95 #where型子查詢# select * from 表名 where (字段1,字段2)=(select 字段1, 字段2 from 表名 where 。。。。); 96 97 #in關鍵字的子查詢# select * from 表名 where 字段 in (select 。。。。查詢語句); 98 99 #any關鍵字的子查詢# select * from 表名 where 字段 >=any (select 。。。。查詢語句); 100 101 #all關鍵字的子查詢# select * from 表名 where 字段 <= all(select 。。。。查詢語句); 102 103 #exists關鍵字的子查詢# select * from 表名 where not exists (select 。。。。查詢語句); 104 105 #regexp正則表達式運算符# select ‘chshs’ rehexp ‘c.’ ; 106 107 108 109 110 111 112 #計數函數# count(); 113 114 #求平均函數# avg(); 115 116 #求和函數# sum(); 117 118 #取最大函數# max(); 119 120 #取最小函數# min(); 121 122 #取絕對值# abs(); 123 124 #取大於x的最大整數# cell(x); 125 126 #取小於x的最大整數# floor(x); 127 128 #取數值x的四捨五入後有y爲小數# round(x,y); 129 130 #直接截取x爲有y位的小數# truncate(x,y); 131 132 #返回0~1之間的一個隨機數#rand(); 133 134 #獲取第n組返回相同值得隨機數# rand(n); 135 136 137 #對字符串進行加密# password(); 138 139 #字符串鏈接函數# concat(字符串1,字符串2.。。); 140 141 #帶分隔符字符串合併# concat(分隔符,字符串1,字符串2.。。。); 142 143 #返回在字符串str2。。。中與str1相匹配的字符串位置# find_in_set(‘str1’,‘str2,str3.。。。。’); 144 145 #返回字符串str1第一次出現位置# field(‘str1’,‘str2’,‘str3’。。。。); 146 147 #返回子字符串str在字符串str1中匹配開始的位置# locate(str,str1);或 position(str in str1); 或 instr(str1 ,str); 148 149 #返回第n'個字符串# elt(n,str1,str2.。。strn); 150 #截取指定位置和長度的字符串# substring(str,num,length); 或 mid(str,num,length); 151 #將字符串str從第x位置開始,y個字符長的字串替換爲字符串str2# insert(str , x ,y,str2); 152 #將字符變爲小寫# lower(str);或 lcase(str) 153 #將字符變爲大寫# upper(str);或 ucase(str) 154 #獲取字符串長度# length(str); 155 #獲取字符數函數# char_length(str); 156 #返回字符串str中最左邊的x個字符# left(str,x); 157 #返回字符串str中最右邊的x個字符# right(str,x); 158 #使用字符串pad對字符串str最左邊進行填充,知道長度爲n個字符長度# lpad(str,n,pad); 159 #使用字符串pad對字符串str最右邊進行填充,知道長度爲n個字符長度# rpad(str,n,pad); 160 #去掉字符串str左邊的空格# ltrim(str); 161 #去掉字符串str右邊的空格# rtrim(str); 162 #返回字符串str重複x次的結果# repeat(str,x); 163 #使用字符串b代替字符串str中的全部字符串a# replace(str,a,b); 164 #比較字符串str1和str2# strcmp(str1,str2); 165 #去掉字符串str行頭和行尾的空格# trim(str); 166 #返回字符串str中從x位置起y個長度的字符串# substring(str,x,y); 167 #獲取當前日期# curdate(); 或 current_date(); 168 #獲取當前時間# curtime(); 或 current_time(); 169 #獲取當前日期和時間# now();或 current_timestamp() 或 localtime() 或 systemdate(); 170 #獲取日期date的UNIX時間戳# unix_timestamp(date); 171 #獲取unix時間戳的日期值# from_unixtime(); 172 #返回日期date爲一年中的第幾周# week(date); 或 weekofyear(time); 173 #返回日期的英文周幾# dayname(time); 174 #返回日期和時間中周幾(1:週日,2:週一)# dayofweek(); 175 #返回日期和時間中周幾(0:週一,1:週二)# weekday(); 176 #返回年中第幾天# dayofyear(time); 177 #返回月中第幾天# dayofmonth(time); 178 #返回日期date的年份# year(date); 179 #返回時間time的小時值# hour(time); 180 #返回時間time的分鐘值# minute(time); 181 #返回時間time的月份值# monthname(date); 或 month(time) 182 #截取日期中的各部分值# extrcat(年或月或日或時或分或秒 from time); 183 #計算date1與date2之間相隔天數# datediff(date1,date2); 184 #計算date加上n天后的日期# adddate(date,n); 185 #計算date減去n天后的日期# subdate(date,n); 186 #計算time加上n秒後的時間# adddate(time,n); 187 #計算time減去n秒後的時間# subdate(time,n); 188 #返回數據庫版本號# version(); 189 #返回當前數據庫名# database(); 190 #返回當前用戶# user(); 191 #將IP地址轉化爲數字# inet_aton(ip); 192 #將數字轉化爲IP地址# inet_ntoa(x); 193 #建立一個持續時間爲time的名爲name的鎖# cet_loct(name,time); 194 #爲名爲name的鎖解鎖# release_loct(name); 195 #將表達式重複執行count次# benchmark(count,表達式); 196 #將x變爲type形式# convert(x,type); 197 #設置字段的非空約束# create table 表名 (屬性名 數據類型 not null); 198 #設置字段的默認值# create table 表名 (屬性名 數據類型 default 默認值); 199 #設置字段的惟一約束# create table 表名(屬性名 數據類型 unique ); 200 #設置字段的惟一約束並未約束命名# create table 表名(屬性名1 數據類型 , 屬性名2 數據類型 .......... constraint 約束名 unique (屬性名1,屬性名2......)); 201 #設置單字段爲主鍵約束# create table 表名(屬性名1 數據類型 primary key....); 202 #設置多字段爲主鍵約束# create table 表名(屬性名1 數據類型 , 屬性名2 數據類型........constraint 約束名 primary key (屬性名1,屬性名2......)); 203 #設置字段自動增長值# create table 表名 (屬性名 數據類型 auto_increment.........); 204 #設置外鍵約束# create table 表名 (屬性名1 數據類型 , 屬性名2 數據類型........ constraint 外鍵約束名 foreing key (外鍵屬性名1) references 表名 (主鍵屬性名2)); 205 #建立普通索引# create table 表名(屬性名 數據類型 ,屬性名 數據類型..... index或 key 索引名(可省略)(屬性名 (長度(可省略)) asc或desc); 206 #在已存在表建立普通索引# create index 索引名 on 表名 ( 屬性名 (長度或不寫) asc或desc或不寫); 或 207 alter table 表名 add index或key 索引名(屬性名 (長度或不寫) asc或desc或不寫); 208 #建立惟一索引# create table 表名(屬性名 數據類型 ,屬性名 數據類型..... unique index或 key 索引名(可省略)(屬性名 (長度(可省略)) asc或desc); 209 #在已存在表建立惟一索引# create unique index 索引名 on 表名 ( 屬性名 (長度或不寫) asc或desc或不寫); 或 210 alter table 表名 add unique index或key 索引名(屬性名 (長度或不寫) asc或desc或不寫); 211 #建立全文索引# create table 表名(屬性名 數據類型 ,屬性名 數據類型..... fulltext index或 key 索引名(可省略)(屬性名 (長度(可省略)) asc或desc); 212 #在已存在表建立全文索引# create fulltext index 索引名 on 表名 ( 屬性名 (長度或不寫) asc或desc或不寫); 或 213 alter table 表名 add fulltext index或key 索引名(屬性名 (長度或不寫) asc或desc或不寫); 214 #建立多列索引# create table 表名(屬性名 數據類型 ,屬性名 數據類型..... index或 key 索引名(可省略)(屬性名1 (長度(可省略)) asc或desc ,屬性名2 (長度(可省略)) asc或desc.........); 215 #在已存在表建立多列索引# create index 索引名 on 表名 (屬性名1 (長度(可省略)) asc或desc ,屬性名2 (長度(可省略)) asc或desc.........); 或 216 alter table 表名 add index或key 索引名(屬性名1 (長度(可省略)) asc或desc ,屬性名2 (長度(可省略)) asc或desc.........);; 217 #查看索引是否用到# explain select * from 表名 where .......; 218 #刪除索引# drop index 索引名 on 表名; 219 #建立視圖# create view 視圖名 as 查詢語句; 220 #查看視圖詳細信息# show table status from 數據庫名 like '視圖名'; 或 show table status 221 #查看視圖定義信息# show create view 視圖名; 222 #查看視圖設計信息# desc 視圖名; 223 #經過系統表查看視圖信息# use information_schema ; select * from views where table_name='視圖名'\G; 224 #刪除視圖# drop view 視圖名; 225 #修改視圖# create or replace view 視圖名 as 查詢語句; 或 alter view 視圖名 as 查詢語句 ; 226 #建立觸發器# create trigger 觸發器名 before或after 觸發條件(delete、insert、update) on 觸發條件的操做表表名 for each row 觸發語句; 227 #建立含多條語句的觸發器# delimiter $$ create trigger 觸發器名 before或after 觸發條件(delete、insert、update) on 觸發條件的操做表表名 for each row begin 觸發語句1; 觸發語句2;......;end $$ delimiter; 228 #查看觸發器# show triggers\G 229 #經過查看系統表查看觸發器信息# use information_schema; select * from triggers\G 230 #刪除觸發器# drop trigger 觸發器名字 231 #查看錯誤信息# show warnings; 232 #查看支持的存儲引擎# show engines; 或 show variables like 'have%'; 233 #查看默認存儲引擎# show variables like 'storage_engine% '; 234 #查看MySQL的幫助文檔目錄列表# help contents; 235 #查看數據類型# help data types; 236 #顯示當前年月日# select curdate(); 237 #顯示當前年月日和時間# select now(); 238 #顯示當前時間# select time(now()); 239 #顯示當前年月日# select year (now()) ; 240 #建立存儲過程# create procedure 存儲過程名字 (存儲過程參數:輸入/輸出類型,參數名,參數類型) 存儲過程特性或不寫 存儲過程的語句; 241 #建立函數過程# create function 函數名字 (函數的參數:參數名,參數類型) 函數特性或不寫 函數過程語句; 242 #查看存儲過程# show procedure status like '存儲過程名' \G 或 use information_schema; select * from routines where specific_name='存儲過程名'\G 243 #查看函數過程# show function status like '函數過程' \G或 use information_schema; select * from routines where specific_name='函數過程名'\G 244 #查看存儲過程定義信息# show create procedure 存儲過程名\G 245 #查看函數過程定義信息# show crate function 函數名\G 246 #刪除存儲過程# drop procedure 存儲過程名\G 247 # 刪除函數# drop function 函數名\G 248 #建立普通用戶帳戶# create user 用戶名 identified by ‘密碼’; 249 #建立帶權限的普通用戶帳戶# grant 權限參數:select、create、drop等 on 庫.表(權限範圍) to 用戶名 identified by ‘密碼’; 250 #更改超級用戶root的密碼# set password=password(「新密碼」); 251 #利用root用戶修改帶權限的普通用戶密碼# grant 權限參數:select、create、drop等 on 庫.表(權限範圍) to 用戶名 identified by ‘新密碼’; 252 #利用root用戶修改普通用戶密碼#set password for 用戶名=password(「新密碼」); 253 #普通用戶更改自身密碼#set password=password(「新密碼」); 254 #刪除普通用戶# drop user 用戶名; 或 delete from user where user=「用戶名」; 255 #對普通用戶進行受權# grant 權限參數:select、create、drop等 on 庫.表(權限範圍) to 用戶名; 256 #收回權限# revoke 權限參數:select、create、drop等 on 庫.表(權限範圍) from 用戶名; 257 #收回全部權限# revoke all privileges,grant option from 用戶名;