數據庫學習之MySQL基礎

                 數據庫基礎              

      1、數據庫簡介                                 

數據庫:存放數據的倉庫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中五種查詢字句
  • where子句(條件查詢):按照「條件表達式」指定的條件進行查詢。
  • group by子句(分組):按照「屬性名」指定的字段進行分組。group by子句一般和count()、sum()等聚合函數一塊兒使用。
  • having子句(篩選):有group by才能having子句,只有知足「條件表達式」中指定的條件的纔可以輸出。
  • order by子句(排序):按照「屬性名」指定的字段進行排序。排序方式由「asc」和「desc」兩個參數指出,默認是按照「asc」來排序,即升序
  • limit(限制結果集)。

   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、連表查詢                                                                          

一、內聯接(典型的聯接運算,使用像 =  或 <> 之類的比較運算符)。包括相等聯接和天然聯接。     

  • inner join(等值鏈接) 只返回兩個表中聯結字段相等的行

二、外聯接。外聯接能夠是左向外聯接、右向外聯接或完整外部聯接。     

  • left join(左聯接) 返回包括左表中的全部記錄和右表中聯結字段相等的記錄 
  • right join(右聯接) 返回包括右表中的全部記錄和左表中聯結字段相等的記錄
  • full join(全聯接) 返回包括右表中的全部記錄和左表中全部的記錄

三、交叉聯接   
  交叉聯接返回左表中的全部行,左表中的每一行與右表中的全部行組合。交叉聯接也稱做笛卡爾積。    
  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)
limit查詢實例

    9、 數據庫引擎                                                               

Mysql引擎種類innodb,mysaim 
  • 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查看存儲引擎
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)
mysql加鎖(行鎖和表鎖)示例
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  用戶名;
mysql經常使用語法命令及函數
相關文章
相關標籤/搜索