這裏把本身學的mysql數據庫的知識總結一下,當是給本身複習一遍,也是方便之後查詢html
安裝和配置mysql就不說了,能夠借鑑這位博友的安裝過程 http://www.javashuo.com/article/p-nqahavrl-bz.htmlpython
mysql -uroot -p密碼;(也能夠不帶密碼,以後輸入) 本地登陸mysql
mysql -h 登陸ip -p 端口(一般3306) -uroot -p密碼; 遠程登陸算法
desc 表名;查看錶的各個字段的屬性,以及自增鍵sql
mysqldump -u用戶 -p 數據庫名 > xx.sql; 導出數據庫文件,保存數據庫
mysql -u用戶 -p密碼 數據庫名< xx.sql;導入數據庫文件(也能夠選擇登陸進去,在選擇數據庫後,使用source命令導入數據)服務器
create user '用戶名' @'ip' identified by '密碼'; 建立用戶session
ip是指用戶登陸mysql的電腦ip,能夠寫%,本地寫localhost數據結構
grant 權限(select/insert/updata/all priveleges) on 表/數據庫名 to '用戶'@'ip' identified by '密碼'; 用戶受權併發
drop user 用戶名@ip 刪除用戶
show databases; 查數據庫
show tables; 看錶
create database 數據庫名 default charset utf8; 建立數據庫
create table 表名(列名 數據類型 約束···,列名 數據類型 約束···)engine=innodb default charset=utf8 建立表
其中數據類型種類 數字(int,tinyint,smallint,float,double),字符串(char(個數)varchar(個數))時間(DATE,TIME,DATETIME),枚舉enum(值只能是枚舉中的元素),集合set(值只能是結合元素的組合)
create table 表名(列名 數據類型 primary key auto_increment,列名 數據類型 約束···)engine=innodb default charset=utf8 建立含主鍵的表
create table 表名(列名 數據類型 primary key,列名 數據類型 constraint fk_外鍵名 foreign key (列名[,]) references 表名2(列名[,])···)engine=innodb default charset=utf8 建立含外鍵的表
select * from 表名;
select 列名···from 表名;
select 列名 from 表名 where 列名(id等) >/</!= value;
select 列名,常量 from 表名; 增長一個常量列
select 列名 from 表名 where 列名 in/not in/between and value;
select 列名 from 表名 where 條件1 and 條件2;
特殊的:select 列名 from 表名 where 列名 in (select 列名(只能一列) from 表名);
select 列名 from 表名 where 列名 like 'xx%'/'%xx'/"xx_"; 查詢以xx開頭/xx結尾 %表明任意位,_表明一位
select xx,(select xx from ...) from ..... 查詢條件作常量值
select 列名 from 表名 limit num; 顯示num個
select 列名 from 表名 limit num1,num2;從num1後取num2行數據,num1是起始位置,num2是個數
select 列名 from 表名 limit num1 offset num2;從num2後取num1行數據,num2是起始位置,num1是個數
select * from 表名 order by 列名 desc;從大到小排序
select * from 表名 order by 列名 asc;從小到大排序
select * from 表名 order by 列名1 desc 列名2 asc; 首先遵循列1從大到小排序,遇到相同數據時,按列2從小到大排序
select count/sum/max/min/avg(列名1),列名2 from 表名 group by 列名(一般是列名2);分組操做
select count/sum/max/min/avg(列名1),列名2 from 表名 group by 列名(一般是列名2)having 條件;分組操做後篩選
select * from 表1 left join 表2 on 表1.列名=表2.列名; 左鏈接
select * from 表1 right join 表2 on 表1.列名=表2.列名; 右鏈接
select * from 表1 inner join 表2 on 表1.列名=表2.列名; 內鏈接
注意:若是超過3個表聯合操做,若是其中兩個表操做時已經改變了表結構,應該將這兩個表操做的結果做爲一個臨時表再與第三個表聯合操做。
臨時表
(select * from 表名)as e
insert into 表名(列名1,列名2···) values(值1,值2···),(值1,值2···),(值1,值2···); 插入值
insert into 表名1(列名) select 列名 from 表2; 在一個表中插入另外一個表中數據
update 表名 set 列名1=value1,列名2=value2 where 條件1 [and/or 條件2];
delete from 表名; 清除表(若是有自增id,id 不會從新開始)
delete from 表名 where 條件; 清除特定數據
truncate table 表名;清除表(若是有自增id,id 會從新開始)
alter table 表名 auto_increment=value;設置自增鍵起始值;
alter table 表名 drop 列名;刪除列
alter table 表名 add 列名 數據類型 約束; 增長列
alter table 表名 change 舊列名 新列名 數據類型; 修改字段類型
alter table 表名 modify 列名 數據類型; 修改數據類型
alter table 舊錶名 rename 新表名; 修改表名
alter table 表名 drop primary key; 刪除表中主鍵
alter table 表名 add 列名 數據類型 primary key;添加主鍵
alter table 表名 add primary key(列名);設置主鍵
alter table 表名 add column 列名 數據類型 after 列名;在某一列後添加主鍵
外鍵適用於一對多,一對一,多對多三種狀況
一對多
典型案例員工與部門,一個部門對應於多個員工,一個員工對應於一個部分,因此要在員工表中設置部門id列,並設置爲外鍵,與部門表id關聯。
一對一
案例博客園用戶與博客,不是每一個用戶都寫博客,寫博客的用戶與擁有的博客地址一一對應,因此在博客用戶表user中設置blog_id,設置成外鍵和惟一索引,與博客表blog中id關聯
create table user(id int not null auto_increment primary key,name char(10), blog_id int,unique uq1(blog_id),constraint fk_user_blog foreign key(blog_id) references blog(id))engine=innodb default charset=utf8;
多對多
典型案例電腦與用戶,一個用戶可使用多臺電腦,一臺電腦對應多個用戶,多對多,此時通常選擇新建一個表contact,在其中設置兩個外鍵,同時關聯用戶表id與電腦表id
create table contact(id int not null auto_increment primary key,user_id int,computer_id int,unique uq2(user_id,computer_id),constraint fk_user foreign key(user_id) references user(id),constraint fk_user foreign key(computer_id) references computer(id))engine=innodb default charset=utf8;
能夠看狀況決定要不要把兩個外鍵弄成聯合惟一索引。
show create table 表名 [\G];查看錶的建立信息
對於自增鍵,咱們能夠設置它的初始值以及與自增步長
alter table auto_increment=value;設置自增初始值
對於自增步長有兩種類型:
第一種:基於會話級別(只對本次登陸有效)
show session variables like "auto_incre%"; 查看步長
set session auto_increment_increment=value; 改變步長
set session auto_increment_offest=value; 設置起始值(不經常使用,由於有以前的alter)
第二種:基於全局級別(對全部會話都有用)
set global auto_increment_increment=value; 設置全局步長
pymysql 是python第三方模塊,主要用於python與mysql交互。
pymysql 方法:
connect(host=,user=,passwd=,database=) 鏈接數據庫
cursor() 創建遊標
execute(sql)執行sql語句
fetchone()從查詢結果中取出一條數據
fetchmany(num)從查詢結果中取出num條數據
fetchall()從查詢結果中取出全部數據
commit() 改變(updata,insert,drop)數據庫內容專用,execute sql語句後必須commit才能真正改變數據庫
close()注意最後有兩個close,遊標要關閉,鏈接也要關閉
sql注入就是經過把SQL命令插入到Web表單提交或輸入域名或頁面請求的查詢字符串,最終達到欺騙服務器執行惡意的SQL命令。
實例以下:
假設咱們輸入用戶名和密碼,而後登陸數據庫,在數據庫中查找用戶和密碼是否存在,存在即登陸成功,不然登陸失敗
程序如上,一開始咱們輸入數據庫存在的用戶和密碼,天然可以登陸成功
輸入錯誤用戶和密碼,也能成功
追究其原有,緣由出在sql語句字符串拼接上,拼接的字符串爲 ‘’ or 1=1 -- ‘‘ and passwd='123',有1=1,固然成立
解決辦法:將要拼接的內容放入execute括號中,由其本身拼接
視圖
視圖是一種虛擬存在的表,自己不包含數據,做爲一個select語句保存在數據庫中。通俗的講視圖表明的是一條select語句產生的結果集。
create view 視圖名稱 as select語句; 建立視圖
視圖單獨不能插入,修改數據,由於視圖是虛擬的。但能夠修改select語句,改變視圖結果集。
alter view 視圖名稱 as sql語句; 修改結果集
drop view 視圖名稱; 刪除視圖
定義:索引(Index)是幫助MYSQL高效獲取數據的數據結構
索引的做用:約束,加速查找
索引種類
普通索引:加速查找
主鍵索引:加速查找;約束(主鍵不能爲空,不能重複)
惟一索引:加速查找;約束(索引不能重複)
組合索引:多列組成一個索引(聯合主鍵索引,聯合惟一索引,聯合普通索引)
create index 索引名 on 表名(列名[,列名]);建立[聯合]普通索引
create table 表名(列名 數據類型···index 索引名(列名[,列名])); 建立表時建立[聯合]普通索引
create unique index 索引名 on 表名(列名);建立惟一索引
create table 表名(列名 數據類型···unique 索引名(列名)); 建立表時建立惟一索引
create unique index 索引名 on 表名(列名,列名);建立聯合惟一索引
create table 表名(列名 數據類型···unique 索引名(列名,列名)); 建立表時建立聯合惟一索引
drop index 索引名 on 表名; 刪除索引
索引結構
索引通常有兩種結構:哈希索引和BTree索引
哈希索引
哈希索引會產生一張索引表,把數據經過算法換算成哈希值,索引表存儲這些哈希值,並在表中保存指向數據的指針,值得注意的是索引表存儲哈希值時打亂了原有的存儲順序。哈希索引查找一條數據時特別快速,優於BTree索引,但由於打亂了原有的數據順序,不支持範圍查找與排序功能。
BTree索引
MYSQL廣泛採用B+Tree結構
B+Tree全部索引數據都在葉子節點上,而且增長了順序訪問指針,每一個葉子節點都有指向相鄰葉子節點的指針。BTree索引查找單條數據的速度不如哈希索引,可是更加適用於範圍查找與排序,因此用的最爲普遍,引擎innodb與MyIsam都使用了BTree索引。
索引是否是越多越好?
答:不是的,索引越多,佔據的物理空間越大;索引只是加快了查詢速度,而減緩了插入和修改速度。
定義:在MYSQL中,事務實際上是一個最小的不可分割的工做單元,事務能保證一個業務的完整性。
場景:在開發中,有多條語句可能會有同時成功的要求,若是隻有一部分紅功,則所有失敗,回滾到原來的狀態。
經過select @@autocommit;語句查詢自動提交是否開啓,1表示開啓,0表示沒有開啓
當查詢結果爲1時,自動提交開啓,執行sql語句(insert into,alter),系統默認提交確認,在物理表生效
當查詢結果爲0時,自動提交關閉,執行sql語句,系統會等待用戶手動提交確認(commit;),不然能夠撤回修改,回滾爲原狀態(rollback;)
通常@@autocommit咱們默認開啓,不然每次都需手動提交太麻煩,但當咱們想開啓一個事務時應該怎麼作?
咱們能夠經過begin或start transaction 開啓一個事務,最後以commit;或rollback;結束一個事務。
A 原子性:事務是最小的不可分割的工做單元
C 一致性:在一個事務中,事務先後數據的完整性必須保持一致,sql語句要麼所有成功,要麼失敗,回滾到原狀態。如銀行轉帳,總的錢數不變
I 隔離性:不一樣事務之間具備隔離性
D 持久性:事務一旦結束,就不能夠返回,不能夠rollback
讀未提交(read uncommitted)
不可重複讀(read committed)
可重複讀(repeatable read)
串行化(serializable)
mysql事務隔離級別默認是可重複讀(repeatable-read)
select @@ global.tx_isolation;mysql(5.x版本)查看隔離級別
set [global/session] transaction isolation level 隔離級別; 設置隔離級別
四種隔離級別致使的問題:
髒讀:事務1讀到了事務2未提交的數據,若是事務2rollback,這些數據即是髒數據
不可重複讀:事務1對同一數據重複讀,可是另外一個事務不斷修改這些數據,形成事務1每次讀到的數據不同
幻讀:是指當事務不是獨立執行時發生的一種現象,例如第一個事務對一個表中的數據進行了修改,這種修改涉及到表中的所有數據行。同時,第二個事務也修改這個表中的數據,這種修改是向表中插入一行新數據。那麼,之後就會發生操做第一個事務的用戶在新開啓的事務中發現表中還有沒有修改的數據行,就好象發生了幻覺同樣(用戶1開啓事務查看數據,而後同時有用戶2開啓事務對數據修改並提交,用戶1在當前事務沒有發現數據改變,結束事務,而後在新開啓的事務中發現了新修改的數據,這像幻覺)
注意:不可重複讀側重修改,幻讀側重插入和刪除
幻讀試驗:
設置隔離級別
開啓一個事務,查詢數據
從新打開一個窗口登陸,開啓事務插入數據,並commit
先前的事務查詢數據,看不到新增語句,解決了不可重複讀問題
關閉先前事務,從新查詢,查到新增數據,出現幻讀
InnoDB支持事務,而MyISAM不支持事務;
InnoDB支持行級鎖,而MyISAM支持表級鎖;
InnoDB支持MVCC(多版本併發控制), 而MyISAM不支持;
InnoDB支持外鍵,而MyISAM不支持;
InnoDB不支持全文索引,而MyISAM支持;
內鏈接:返回兩表指定列名相同的數據,若是沒有返回空。
select * from 表1 inner join 表2 on 表1.列名=表2.列名; 內鏈接
左鏈接:左邊數據全顯示,右邊表只顯示符合條件的數據,若是右邊沒有相符數據或知足的數據少於左邊數據行,以null代替(記錄不足的地方以null代替)
select * from 表1 left join 表2 on 表1.列名=表2.列名; 左鏈接
右鏈接:與左鏈接相反
select * from 表1 right join 表2 on 表1.列名=表2.列名; 右鏈接
drop直接刪掉表
truncate刪除表中數據,再插入時自增加id又從1開始
delete刪除表中數據,能夠加where字句,delete刪除整個表數據時,再插入自增id不會從1開始
哈希:雖然單詞查詢快,可是沒有順序,不適合範圍查詢
二叉樹:樹的高度不均勻,不能自平衡,查找效率與樹的高度有關,IO代價高
紅黑樹:樹的高度隨數據量而變,IO代價高(數據量過大時,樹的深度越高,IO讀寫越頻繁)
Btree:數據很大時,不可能放在內存,因此放在磁盤上,BTree 每層節點數多,層數少,減小了IO讀寫次數,查詢結果更加穩定
主鍵:數據庫表中對儲存數據對象予以惟一和完整標識的數據列或屬性的組合。一個表只能有一個主鍵,且主鍵的取值不能缺失,即不能爲空值(Null)。
外鍵:在一個表中存在的另外一個表的主鍵稱此表的外鍵。
char是一種固定長度的類型,varchar則是一種可變長度的類型
char 長度是固定的,無論你存儲的數據是多少他都會都固定的長度。而varchar則處可變長度
varchar(50)中50表示最多有50個字符
varchar節省空間,查詢速度沒有char速度快
表級:直接鎖定整張表,在你鎖按期間,其它進程沒法對該表進行寫操做。若是你是寫鎖,則其它進程則讀也不容許
行級:僅對指定的記錄進行加鎖,這樣其它進程仍是能夠對同一個表中的其它記錄進行操做。