mysql常見的數(shù)據(jù)庫引擎和區(qū)別:
MyISAM:默認(rèn)的MySQL插件式存儲引擎,它是在Web讥此、數(shù)據(jù)倉儲和其他應(yīng)用環(huán)境下最常使用的存儲引擎之一论寨。注意花吟,通過更改STORAGE_ENGINE配置變量,能夠方便地更改MySQL服務(wù)器的默認(rèn)存儲引擎们颜。
InnoDB:用于事務(wù)處理應(yīng)用程序吕朵,具有眾多特性,包括ACID事務(wù)支持窥突。(提供行級鎖
BDB:可替代InnoDB的事務(wù)引擎努溃,支持COMMIT、ROLLBACK和其他事務(wù)特性阻问。
Memory:將所有數(shù)據(jù)保存在RAM中梧税,在需要快速查找引用和其他類似數(shù)據(jù)的環(huán)境下,可提供極快的訪問称近。
Merge:允許MySQL DBA或開發(fā)人員將一系列等同的MyISAM表以邏輯方式組合在一起第队,并作為1個對象引用它們。對于諸如數(shù)據(jù)倉儲等VLDB環(huán)境十分適合刨秆。
Archive:為大量很少引用的歷史斥铺、歸檔、或安全審計信息的存儲和檢索提供了完美的解決方案坛善。
Federated:能夠?qū)⒍鄠€分離的MySQL服務(wù)器鏈接起來晾蜘,從多個物理服務(wù)器創(chuàng)建一個邏輯數(shù)據(jù)庫。十分適合于分布式環(huán)境或數(shù)據(jù)集市環(huán)境眠屎。
Cluster/NDB:MySQL的簇式數(shù)據(jù)庫引擎剔交,尤其適合于具有高性能查找要求的應(yīng)用程序,這類查找需求還要求具有最高的正常工作時間和可用性改衩。
Other:其他存儲引擎包括CSV(引用由逗號隔開的用作數(shù)據(jù)庫表的文件)岖常,Blackhole(用于臨時禁止對數(shù)據(jù)庫的應(yīng)用程序輸入),以及Example引擎(可為快速創(chuàng)建定制的插件式存儲引擎提供幫助)葫督。
關(guān)系型數(shù)據(jù)庫:Oracle竭鞍、DB2、Microsoft SQL Server橄镜、Microsoft Access偎快、MySQL等
:指采用了關(guān)系模型來組織數(shù)據(jù)的數(shù)據(jù)庫。簡單來說洽胶,關(guān)系模式就是二維表格模型晒夹。
優(yōu)點 (1)容易理解,二維表的結(jié)構(gòu)非常貼近現(xiàn)實世界,二維表格丐怯,容易理解喷好。
? ? (2)使用方便,通用的sql語句使得操作關(guān)系型數(shù)據(jù)庫非常方便读跷。
? ? (3)易于維護梗搅,數(shù)據(jù)庫的ACID屬性,大大降低了數(shù)據(jù)冗余和數(shù)據(jù)不一致的概率效览。
非關(guān)系型數(shù)據(jù)庫:NoSql无切、Cloudant、MongoDb钦铺、redis、HBase
? ? ? ? 優(yōu)勢:1. 性能NOSQL是基于鍵值對的肢预,可以想象成表中的主鍵和值的對應(yīng)關(guān)系矛洞,而且不需要經(jīng)過SQL層的解析,所以性能非常高烫映。
? ? ? ? ? ? ? 2. 可擴展性同樣也是因為基于鍵值對沼本,數(shù)據(jù)之間沒有耦合性,所以非常容易水平擴展锭沟。
設(shè)置自增的起始值:
? ? ? ? ? alter table tablename auto_increment = 0;
? ? 設(shè)置自增的步長:
? ? ? mysql
? ? ? ? ? 基于會話級別:
? ? ? ? ? show session variables like 'auto_inc%'? 查看全局變量
? ? ? ? ? set session auto_increment_increment = 2; 設(shè)置會話的步長
? ? ? ? ? set session auto_increment_offset = 10;? 設(shè)置起始值
? ? ? ? 全局級別:
? ? ? ? ? show global variables like 'auto_inc%'?
? ? ? ? ? set global auto_increment_increment = 200;設(shè)置全局的步長
? ? ? ? ? set global auto_increment_offset = 10;
? ? 外鍵的變種:
? ? ? ? 唯一索引
? ? 不等于:? ?
? ? select * from tb1 where id !=1;
? ? select * from tb2 where id <> 1抽兆;
? ? select * from tb2 where id in (1,5,12);
? ? select * from tb2 where id not in (1,5,13);
? ? select *from tb2 where id between 5 and 12;//取到的是閉區(qū)間
? ? select * from tb2 where id in (select id from tb1);
? ? select * from tb2 where name like "a%"? ? ? ? ? ? ? ? ?
? ? %表示多個字符? _是一個字符,%a%只要有a就行
? ? select * from tb12 limit 10;? ? //前幾條
? ? select * from tb2? ? limit 1,1? ? ? ? ? //起始位置族淮,往后取幾條數(shù)據(jù)
? ? select * from tb2 limit 10 offset 20;? ? //limit后是取幾條辫红,offfset從第幾條取
排序:
? ? select * from tb2 order by id desc(倒序)/asc(正序) limit 10; 取后10條數(shù)據(jù)
分組:
? ? select * from tb2 group by id ;
? ? sum max min avg count ;
? ? having
連表操作:
? ? select * from tb1 ,tb2 where tb1.id = tb2.id;
? ? select * from tb1 left join tb2 on tb1.id = tb2.id;//左側(cè)表全部顯示
? ? select * from tb1 right join tb2 on tb1.id = tb2.id;//右側(cè)表全部顯示即t b2
? ? select * from tb1 inner join tb2 on tb1.id = tb2.id;? //將出現(xiàn)null的一行隱藏
? ? 臨時表:
? ? select sid from (select * from score where num > 60) as B;
pymysql模塊:
pip3 install pymysql
觸發(fā)器: 當(dāng)對某表的做增刪改操作時,使用觸發(fā)器自定義關(guān)聯(lián)行為祝辣,
create triggr t1(視圖名稱) before insert on student(表名) for? each row
begin
insert into teacher(tname) values('sdaas')
values值New.name 為插入時的值
? ? ? ? Old.name? 為插入贴妻,刪除的值
end
修改終止符:delimiter //
? ? ? ? ? delimiter ;
函數(shù):
內(nèi)置函數(shù):
執(zhí)行函數(shù)
? ? 時間格式化:
自定義函數(shù):
存儲過程:保存在mysql上的一個別名,一堆sql語句蝙斜,調(diào)用別名進行使用
? ? 保存在數(shù)據(jù)庫中
? 創(chuàng)建存儲過程
? delimiter //
CREATE PROCEDURE p1()
BEGIN
select * from student;
select * from teacher;
END
delimiter ;
執(zhí)行存儲過程
call p1()
方式一:
mysql:存儲過程
程序:調(diào)用存儲過程
方式二:
? mysql:程序員
? 程序:sql語句
方式三:
mysql:程序員
ORM框架:類和對象
1名惩、存儲過程傳參:(in ,out, inout)
create PROCEDURE p(
IN? N1 int,
IN N2 INT)
BEGIN
select * from user where sid >N1;
END
2孕荠、參數(shù)out:
delimiter //
create PROCEDURE p2(
out n2 int,用于標(biāo)識存儲過程的執(zhí)行結(jié)果
in n1 int)
begin
set n2 = 123123;
select * from student where sid >n1;
END //
delimiter ;
? ? ? ? ? ? ? ? 3娩鹉、事務(wù)
索引:
作用:
? 約束
? 加速查找
索引:
普通索引(加速查找)
主鍵索引(加速查找,不能為空稚伍,不能重復(fù))
唯一索引(加速查找弯予,不能重復(fù))
聯(lián)合索引(聯(lián)合唯一)(多列索引)
? --聯(lián)合主鍵索引
? --聯(lián)合唯一索引
? --聯(lián)合普通索引
加速查找:
快:
select * from tb where name = "asdf"
假設(shè):
id name email
無索引:從前到后一次查找
? 索引:
? id 創(chuàng)建額外文件(某種格式存儲)
? name email 創(chuàng)建額外文件(某種格式存儲)
索引種類:
hash索引:
單值索引快
范圍索引慢
BTree索引(常用):
原理:二叉樹
? ? 建立索引
? ? create index 索引名 on 表名(字段)? -- 針對字段進行建立索引
? ? drop index 索引名
? ? 缺點:額外的文件保存特殊的數(shù)據(jù)結(jié)構(gòu)
? ? 查詢快个曙,插入更新刪除慢
? ? 命中索引:
? ? select * from user where email ="asdf"
? ? 普通索引(加速查找):
? ? --create index 索引名 on 表名(字段)? -- 針對字段進行建立索引
? ? --drop index 索引名
? ? 唯一索引
? ? --create unique index 索引名 on 表名(字段)? -- 針對字段進行建立索引
? ? --drop unique index 索引名
? 聯(lián)合索引:(普通的索引)
? ? ? --create index 索引名 on 表名(字段1,字段2)? -- 針對字段進行建立索引
? ? --drop index 索引名
? ? 索引名詞補充:
? ? ? ? ? 覆蓋索引:在創(chuàng)建的索引文件中直接將數(shù)據(jù)取到
? ? ? ? ? select id from user where id = "111"
? ? ? ? ? 索引合并:把多個單列索引合并使用
? ? ? ? ? select * from user where id="111" and email="aaa"
? ? ? ? ? 最左前綴匹配:需要?
? ? ? ? ? create index ix_name on user (id,name)
? ? ? ? ? select * from user where id ="1" and name= "asdf"
? ? 組合索引效率 > 索引合并:把多個單列索引合并使用
? ? ? ? ? ? ? --(name,id)
? ? ? ? ? ? ? select * from user where name = "sss" and id ='11'
? ? ? ? ? ? ? --name
? ? ? ? ? ? ? --id
? ? ? ? ? ? ? select * from user where id ="sss" and name= "ddfd"
? ? 頻繁查找的列創(chuàng)建索引:
? ? -創(chuàng)建索引
? ? -命中索引
? ? ? ? ? ? - like '%xx'
? ? select * from tb1 where name like '%cn';
- 使用函數(shù)
? ? select * from tb1 where reverse(name) = 'wupeiqi';
- or
? ? select * from tb1 where nid = 1 or email = 'seven@live.com';
? ? 特別的:當(dāng)or條件中有未建立索引的列才失效祠挫,以下會走索引
? ? ? ? ? ? select * from tb1 where nid = 1 or name = 'seven';
? ? ? ? ? ? select * from tb1 where nid = 1 or email = 'seven@live.com' and name = 'alex'
- 類型不一致
? ? 如果列是字符串類型那槽,傳入條件是必須用引號引起來,不然...
? ? select * from tb1 where name = 999;
- !=
? ? select * from tb1 where name != 'alex'
? ? 特別的:如果是主鍵骚灸,則還是會走索引
? ? ? select * from tb1 where nid != 123
- >
? ? select * from tb1 where name > 'alex'
? ? 特別的:如果是主鍵或索引是整數(shù)類型慌植,則還是會走索引
? ? ? ? select * from tb1 where nid > 123
? ? ? ? select * from tb1 where num > 123
- order by
? ? select email from tb1 order by name desc;
? ? 當(dāng)根據(jù)索引排序時候甚牲,選擇的映射如果不是索引,則不走索引
? ? 特別的:如果對主鍵排序蝶柿,則還是走索引:
? ? ? ? select * from tb1 order by nid desc;
- 組合索引最左前綴
? ? 如果組合索引為:(name,email)
? ? name and email? ? ? -- 使用索引
? ? name? ? ? ? ? ? ? ? -- 使用索引
? ? email? ? ? ? ? ? ? ? -- 不使用索引
3丈钙、時間
? 執(zhí)行計劃,讓mysql預(yù)估執(zhí)行操作
? explain? 預(yù)估:
? 快:select * from user where id ='2'
? type:ref(索引掃描)
? 慢:select * from user where name? = "alex"
? type:all(全表掃描)
4交汤、DBA工作
慢日志
-執(zhí)行時間 > 10
-未命中索引
-日志路徑
配置:
內(nèi)存:
? show variable like '%query%'
? set global 變量名 = 值
配置文件
--mysql的配置文件
mysql --defaults-file ='D:\my.conf'
? ? 修改配置文件之后,需要重啟服務(wù)
? ? 5星岗、分頁:
? ? select * from user limit
? ? 翻的頁越大戒洼,越慢,因為月在后面掃描的記錄條數(shù)就越長圈浇,就越慢
? ? ? ? 解決方法一:索引表里面掃描
? ? ? ? select * from user where id in (
? ? ? ? ? ? select id from user limit 200,10)
方法二:select * from user where id >200 order by desc? limit 10;
記錄當(dāng)前頁的最大或者最小的id,
頁面只有上一頁下一頁:
當(dāng)一類函數(shù)公用同樣的參數(shù)對象的時候曹仗,可以轉(zhuǎn)變?yōu)轭愡M行? --分類
面向?qū)ο螅簲?shù)據(jù)和邏輯(屬性和行為)組合在一起
函數(shù)編程:數(shù)據(jù)和邏輯分離
ORM框架:SQLAlchemy
-作用
提供簡單的規(guī)則
自動轉(zhuǎn)化為sql語句
-DBfirst 手動建表
-Code first 手動創(chuàng)建類和數(shù)據(jù)庫蠕搜,通過orm框架,自動生成表
創(chuàng)建數(shù)據(jù)庫
連接數(shù)據(jù)庫
類轉(zhuǎn)換sql語句
子查詢:
--query(表名)? :要查詢的表名? 轨蛤,filter是條件限制虫埂,filter()里面兩個條件的話,是條件之間是and
# 條件
ret = session.query(Users).filter_by(name='alex').all()
ret = session.query(Users).filter(Users.id > 1, Users.name == 'eric').all()
ret = session.query(Users).filter(Users.id.between(1, 3), Users.name == 'eric').all()
--
ret = session.query(Users).filter(Users.id.in_([1,3,4])).all() -- 加下劃線? 這條語句的在user.id是1 3 4 中查詢
ret = session.query(Users).filter(~Users.id.in_([1,3,4])).all() --? ~非(not)的意思? 這條語句的在user.id是1 3 4 中查詢
? --filter_by :? 內(nèi)部子查詢 的限制條件? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?
ret = session.query(Users).filter(Users.id.in_(session.query(Users.id).filter_by(name='eric'))).all()
from sqlalchemy import and_, or_
--引入and_,or_
ret = session.query(Users).filter(and_(Users.id > 3, Users.name == 'eric')).all()
ret = session.query(Users).filter(or_(Users.id < 2, Users.name == 'eric')).all()
ret = session.query(Users).filter(
? ? or_(
? ? ? ? Users.id < 2,
? ? ? ? and_(Users.name == 'eric', Users.id > 3),
? ? ? ? Users.extra != ""
? ? )).all()
# 通配符
ret = session.query(Users).filter(Users.name.like('e%')).all()
ret = session.query(Users).filter(~Users.name.like('e%')).all()
# 限制(分頁缝呕,直接切片)
ret = session.query(Users)[1:2]
# 排序
--order_by desc ,asc
ret = session.query(Users).order_by(Users.name.desc()).all()
ret = session.query(Users).order_by(Users.name.desc(), Users.id.asc()).all()
# 分組(group_by)
from sqlalchemy.sql import func
ret = session.query(Users).group_by(Users.extra).all()
ret = session.query(
? ? func.max(Users.id),
? ? func.sum(Users.id),
? ? func.min(Users.id)).group_by(Users.name).all()
ret = session.query(
? ? func.max(Users.id),
? ? func.sum(Users.id),
? ? func.min(Users.id)).group_by(Users.name).having(func.min(Users.id) >2).all()
? ? ? ? ? --having? 根據(jù)分組之后,進行二次篩選
# 連表
--query要查的兩個表
ret = session.query(Users, Favor).filter(Users.id == Favor.nid).all()
ret = session.query(Person).join(Favor).all()? --默認(rèn)為inner_join
ret = session.query(Person).join(Favor, isouter=True).all()? --未outer join
# 組合
q1 = session.query(Users.name).filter(Users.id > 2)
q2 = session.query(Favor.caption).filter(Favor.nid < 2)
ret = q1.union(q2).all()? #去重
q1 = session.query(Users.name).filter(Users.id > 2)
q2 = session.query(Favor.caption).filter(Favor.nid < 2)
ret = q1.union_all(q2).all()? #不去重
#臨時表
--select * from (select * from A) as B
q1 = session.query(Users.name).filter(Users.id > 2).subquery()
ret = session.query(q1).all()
print(ret)