數據庫
面試題 https://blog.csdn.net/liu_weiliang10405/article/details/123930244
概念
數據 data
數據庫 database
數據庫管理系統 DBMS
數據庫管理員 DBA

數據庫的分類
關系型: mysql\oracle\ sqlite\ sql server 適合我們在存取數據的時候 字段不確定的情況下
非關系型: redis\mongdb 我們總是用一個固定的字段來獲取某些信息 并且對數據的存取速度要求都非常高
區別
1)mysql :關系型數據庫,用于持久化的存儲數據到硬盤,功能強大,但讀取速度較慢
2)redis :非關系型數據庫,也是緩存數據庫,用于存儲使用 較為頻繁的數據 到緩存中,讀取速度快 ,持久化是使用AOF和rdb方式,支持事務,存儲小量的數據
3)mongodb: 不支持事務,支持查詢的語言比較多(json,xml,bson),適合大數據量的存儲
應用場景
redis:數據量較小的更性能操作和運算上
MongoDB:主要解決海量數據的訪問效率問題
explain執行計劃
使用explain關鍵字可以模擬優化器執行sql查詢語句,explain主要用于分析查詢語句或表結構的性能瓶頸。
1.explain的作用
通過explain+sql語句可以知道如下內容:
①表的讀取順序。(對應id)
②數據讀取操作的操作類型。(對應select_type)
③哪些索引可以使用。(對應possible_keys)
④哪些索引被實際使用。(對應key)
⑤表直接的引用。(對應ref)
⑥每張表有多少行被優化器查詢。(對應rows)
explain(執行計劃)包含的信息十分的豐富,著重關注以下幾個字段信息。
①id,select子句或表執行順序,id相同,從上到下執行,id不同,id值越大,執行優先級越高。
②type,type主要取值及其表示sql的好壞程度(由好到差排序):system>const>eq_ref>ref>range>index>ALL。保證range,最好到ref。
③key,實際被使用的索引列。
④ref,關聯的字段,常量等值查詢,顯示為const,如果為連接查詢,顯示關聯的字段。
⑤Extra,額外信息,使用優先級Using index>Using filesort(九死一生)>Using temporary(十死無生)。
mysql 有哪些日志
undo 日志:用于支持事務的原子性、一致性,用于支持事務回滾以及MVCC
redo 日志:用于支持事務的持久化
查詢日志:記錄所有對數據庫請求的信息。
慢查詢日志:將運行時間超過閾值的所有SQL語句都記錄到慢查詢的日志文件中
二進制日志:記錄對數據庫執行更改的所有操作。
中繼日志:用于從機復制主機信息。
mysql刪除所有重復的數據
https://blog.csdn.net/qq_37634156/article/details/125428654
mysql客戶端的啟動:
-
在cmd里執行
mysql -uroot -p
Enter password:
root默認的用戶 權限相對大 -
在mysql的客戶端執行
mysql> exit # 退出客戶端
-
在cmd中執行的 服務端的啟停:
net start mysql
net stop mysql
mysql 導入 導出
導出(備份)所有:
導出時沒有參數--databases 需要先創建數據庫在source,加上--databases,直接source就行
#備份表(不需要進入到mysql)
語法:mysqldump -u root -p 數據庫名 > 路勁/新名字 (注:路經后邊不能有中文)
mysqldump -u root -p --all-databases > /tmp/db.sql
恢復到表數據
先進入到mysql
create database 數據庫名
use 數據庫
source 文件的路勁
導出db1、db2兩個數據庫的所有數據
mysqldump -uroot -proot --databases db1 db2 >/tmp/user.sql
mysqldump -uroot -p -B db1 db2 >/tmp/user.sql
恢復數據庫
source 文件路勁
導入:
Mysql -uroot -p -b 數據庫名< /opt/all db.sql
或者
mysql>source /data/all.sql;
其實導出的是庫里面的表,要想導入,先建一個database庫,進入庫里邊后再source.


存儲引擎
- Innodb:默認使用mysql5.6
特點: 支持事務\行級鎖\外鍵
事務: 事務由單獨單元的一個或者多個sql語句組成,在這個單元中,每個mysql語句時相互依賴的。而整個單獨單元作為一個不可分割的整體,
n句sql是一個完整的事件,這n句sql要么一起成功,要么一起失敗(轉賬)
事務的四個特性:
原子性(Atomicity):所有操作要么全部成功,要么全部失敗回滾
一致性(Consistency):事務必須使數據庫從一個一致性狀態變換到另一個一致性狀態
隔離性(Isolation):一個事務的執行不能讓其它事務干擾
持久性(Durability):事務一旦結束,數據就持久到數據庫
數據庫事務可以對應哪些隔離級別
1、臟讀:B事務讀取到了A事務尚未提交的數據
2、不可重復讀:一個事務中兩次讀取的數據的內容不一致
3、幻讀/虛讀:一個事務中兩次讀取的數據的數量不一致
隔離級別:
1、read uncommitted : 讀未提交 :哪個問題都不能
2、read committed:讀已提交 :可以解決臟讀 —- oracle默認的
3、repeatable read:可重復讀:可以解決臟讀和不可重復讀 —mysql默認的
4、serializable:串行化:可以解決臟讀不可重復讀和虛讀—相當于鎖表
mysql默認事務并發隔離級別是什么?
默認的為Repeatable read (可重復讀)
行級鎖: 優點: 能夠支持更多的修改數據的并發操作; 缺: 修改的行數太多,效率會受影響
表級鎖:
缺點: 不支持并發的修改同一張表中的數據;
優:不需要加很多鎖,,效率高
外鍵: 在本表中有一個字段 關聯 外表中的另一個字段
為什么要用innodb做存儲引擎?
因為他是mysql5.6 以上默認使用的,考慮到程序今后的擴展,我要用支持事務的inndb,并且并發的刪除和修改的效率比其他引擎高一些
- myisam: 默認使用mysql5.5
特點:表級鎖
3)memory: 緩存的存儲方式 內存
特點:讀取快,不能完成數據的持久化存儲,斷電數據就會消失
4)blackhole :黑洞
特點: 集群(多臺mysql服務,提供高可用的時候涉及到的一種存儲引擎) 多級主從復制中的一臺機器上的數據庫常用的存儲引擎

表級鎖
https://blog.csdn.net/xixihaha_coder/article/details/126407735
分三類: 1. 表鎖,2. 元數據鎖(meta data lock,MDL)3. 意向鎖
對于表鎖,分為兩類:
1.表共享讀鎖(read lock)
2. 表獨占寫鎖(write lock)
語法:
加鎖: lock tables 表名 ... read/write
釋放鎖:unlock tables / 客戶端斷開鏈接


創建表
create table 表名(
字段名1 類型[(寬度) 約束條件],
字段名2 類型[(寬度) 約束條件],
字段名3 類型[(寬度) 約束條件]
);
例:
mysql> create table staff_info (id int,name char(10),age int(3),sex enum('male', 'female'), phone char(11),job char(12));
2) 查看表結構
desc (describe) 表名; 查看表的基礎信息
show create table 表名 \G; 查看表的詳細信息(編碼 和 存儲引擎)
3)修改表結構

基礎數據類型
1) 數值類型
Int 整型的長度約束,實際沒效果
Float 小數: float(n,m) 這個數據總長度n,小數點后為m 如:(126,45)
2) 日期時間類型
now()

datetime : 允許為空,沒有默認值,能夠表示的時間范圍大
timestamp :不允許為空,默認值是當前時間,能夠表示的時間范圍小,超出范圍表示為 0000-00-00 00:00:00
如果同一個表中有兩個該字段,只有第一個字段會被表示為默認當前時間
3) 字符串格式
char: 定長,存儲相對浪費空間,存取速度快,不管你存儲什么樣的數據,他都會幫你把數據的空格在顯示的時候去掉
varchar: 變長,相對節省空間,存取效率相對慢,varchar類型的最大長度通常為65535個字符
檢驗:
concat(ch,'+')字符串格式
例子:舉例: varchar(32) 和 varchar(64)區別是啥?
影響性能
首先,varchar 大家都知道是動態長度分配,他們空間開銷是一樣的。
區別和聯系:
對于內存的消耗是不同的。對于VARCHAR數據類型來說,硬盤上的存儲空間雖然都是根據實際字符長度來分配存儲空間的,也就是上面所說空間開銷一樣。
但是對于內存來說,則不是。其時使用固定大小的內存塊來保存值。就是使用字符類型中定義的長度,即定義的64或32個字符空間。顯然,這對于排序或者臨時表(這些內容都需要通過內存來實現)操作會產生比較大的不利影響。
再者,MySQL對于該字段建索引時如果沒有限制索引的大小,索引長度會默認采用的該字段的長度,也就是說varchar(64)建立的索引存儲大小要比varchar(32)建立索引存儲大小大的多,加載索引使用的內存也更多,效率會低
char和vachar 區別
通過區別我們可以知道,char類型因為其長度固定,所以存儲/查找時速度快,但是長度沒分配好的話浪費空間,而varchar類型長度隨存儲數據的長度改變,所以存儲/查找時速度較char類型慢,但是不浪費空間,所以當需求高存儲查找速率并且對空間資源的浪費與否不是那么看重時當采用char類型,而對于空間資源的分配要求高當采用varchar類型
4) ENUM和SET類型
enum 枚舉 單選+不能選不在枚舉范圍里的
set 集合 多選+去重+不能選不在集合里的
例
create table t9 (name char(20),gender enum('female','male'))
# 多選框--程序中 勾選
create table t10 (name char(20),hobby set('抽煙','喝酒','燙頭','翻車'))
**)comment 添加注釋
例:
CREATE TABLE `cloud_info` (
id bigint NOT NULL AUTO_INCREMENT,
region varchar(20) DEFAULT '',
area varchar(50) DEFAULT '' COMMENT '地域',)
查看注釋:
show full columns from 表名;
修改注釋:
alter table a modify column regin varchar(50) comment 'diyu';
5) 表的約束
(1)Not null 非空
unique 唯一:不能重復輸入非空的內容,但可以輸入多個null
(2) primary key 主鍵:非空+唯一 一張表只能有一個主鍵,其他的還是維持原來的約束

6) 外鍵
外鍵(foreign key)所關聯的外表中的那個字段必須是唯一的,建議關聯外表的主鍵
創建外鍵
create table staff_info (s_id int,name varchar(20),dep_id int,foreign key(dep_id) references departments(dep_id));
增加外鍵
語法:alter table 表名 add constraint FK_ID foreign key(你的外鍵字段名) REFERENCES 外表表名(對應的表的主鍵字段名); //FK_ID是外鍵的名稱
alter table book add constraint fk_id foreign key(press_id) references press(id);
刪除外鍵
語法: ALTER TABLE 表名 DROP FOREIGN KEY 外鍵字段名;
7) 設置自增字段
unique auto_increment 至少是唯一的才可以
default 關鍵字 # 設置一個默認值
一對多 刪除某個字段
方式一:刪除class里某一個字段
create table class (id int,class_name char(12));
alter table class modify id int unique; 關聯外鍵,字段至少唯一
create table stu (id int,stu_name char(20),class_id int,foreign key (class_id)
references class(id));
先刪除stu里所關聯class的id的字段
delete from class where id =1;
才能刪class里對應的字段:
delete from class id=1;
方式二:刪除外鍵所關聯的多個字段(直接刪除)
加上on update cascade on delete cascade(連級刪除或更新)
create table class (id int primary key,class_name char(12));
關聯外鍵,字段至少唯一
create table stu (id int primary key,stu_name char(20),class_id int,foreign key (class_id) references class(id) on update cascade on delete cascade);
多對多 外鍵
創建表
create table author(
id int primary key auto_increment,
name varchar(20)
);
create table book(
id int primary key auto_increment,
name varchar(20)
);
#這張表就存放作者表與書表的關系,即查詢二者的關系查這表就可以了
create table author2book(
id int not null unique auto_increment,
author_id int not null,
book_id int not null,
constraint fk_author foreign key(author_id) references author(id)
on delete cascade
on update cascade,
constraint fk_book foreign key(book_id) references book(id)
on delete cascade
on update cascade,
primary key(author_id,book_id)
);
數據的增刪改查
1)增加數據
insert into 表名 value (1,'alex',83,'不詳'); 一次插入一條數據
insert into 表名 values (1,'alex',83,'不詳'),(2,'wusir',74,'male'); 支持一次寫入多條數據
insert into 表名 (name,age,sex) values ('alex',83,'不詳');
2) 修改數據
update 表名 set 字段名=值 where 條件
update 表名 set(修改成啥) 字段名1=值1,字段名2=值2 where 條件(在那一行)
3) 刪除數據
delete from 表 where 條件;
delete from 表; 清空表
auto_increment 自增字段 至少是(int unique)
select * from 表名; * 表示所有的內容
select 字段1,字段2 from 表; 表示查指定的列的內容
select distinct 字段名 from 表; distinct關鍵字表示去重
在select字段可以使用四則(加減乘除)運算
select 字段*12 from 表
select 字段 as 新字段名 from 表 給字段重命名
兩個格式化函數
concat() concat_ws()
concat('自己想拼的內容',字段,'你想拼的內容');
Select concat('姓名:',emp_name,'年薪:',salary) AS annual_salary from employee;
concat_ws(':',字段1,字段2)
Case語句
SELECT
(
CASE
WHEN emp_name = 'jingliyang' THEN
emp_name
WHEN emp_name = 'alex' THEN
CONCAT(emp_name,'_BIGSB')
ELSE
concat(emp_name, 'SB')
END
) as new_name
FROM
employee;
where條件
對表當中的數據進行一個條件的篩選
對一個值的判斷 = > < != <> >= <=
對一個范圍的判斷 between 小的值 and 大的值 [小的值,大的值]
select emp_name,salary from employee where salary between 10000 and 20000;
關鍵字IS NULL(判斷某個字段是否為NULL不能用等號,需要用IS)
select emp_name,post_comment from employee where post_comment is not null;
**模糊匹配 **
like '%a_'
regext :字段名 ‘^\d{15}$’
'a'的名字
'%a'以a結尾,'a%'表示以a開頭,'%a%'表示匹配中間帶個a的字符串
'%'通配符 匹配任意長度的任意內容
SELECT * FROM employee
WHERE emp_name LIKE 'eg%';
'a' 表示任意的一個字符a,'a_'以a開頭后面是任意的兩個字符
'_' 匹配一個長度的任意內容
邏輯運算符
and 兩個條件必須都成立 才算成立
or 只要有一個條件成立就成立
not 非
SELECT emp_name,salary FROM employee
WHERE salary=3000 OR salary=3500 OR salary=4000 OR salary=9000 ;
SELECT emp_name,salary FROM employee
WHERE salary IN (3000,3500,4000,9000) ;
SELECT emp_name,salary FROM employee
WHERE salary NOT IN (3000,3500,4000,9000) ;
group by 分組(帶去重的功能)
1) select 數據 from 表 where 條件 group by 分組
select post from employee where depart_id > 1;
結果 是 查出來有多少個部門 就有多少條數據
2) GROUP BY關鍵字和GROUP_CONCAT()函數一起使用
想要拿到部門對應的所有員工的名字,用GROUP_CONCAT()函數
select post,group_concat(emp_name) from employee where depart_id<3 group by post; 結果是符合條件里的部門的所有人名字
聚合函數
count(字段) 統計有多少條記錄是符合條件的 只統計字段不為空的那一行數據
count(*) # count(1) # min # max # avg # sum
order by 排序
默認是升序
降序 從大到小排 desc
SELECT * FROM employee ORDER BY salary DESC;
limit限制
limit n 取n個
limit m,n 從m +1 開始 取n條
limit n offset m 從m+1開始 取n個
**having **
對group by 分組后的結果進行過濾和篩選
能夠 使用聚合函數
Having: 如果是group by 用到的關鍵字, select 當中用到的名字 聚合函數要用到的名字
優先級
FROM 表名
WHERE 條件
GROUP BY field
HAVING 篩選
ORDER BY field
LIMIT 限制條數
.多表查詢
Select * from 表一,表二
1.連表查詢:
用的是on連接
1) 內連接 (inner join) :只有兩張表中條件互相匹配上的項才能被顯示出來
select 字段 from 表1 inner join 表2 on 條件
select * from class inner join stu on stu.class_id = class.id;
等同于
Select * from class,stu where stu.class_id = class.id
2) 外鏈接
左外鏈接(left join):會完整的顯示左表,根據條件顯示右表
select 字段 from 表1 left join 表2 on 條件
右外鏈接(right join):會完整的顯示右表,根據條件顯示左表
select 字段 from 表1 right join 表2 on 條件
全外鏈接
用union連接
from 表1 left join 表2 on 條件 union 表1 right join 表2 on 條件
select * from employee as emp left join department as dep on emp.dep_id = dep.id
union
select * from employee as emp right join department as dep on emp.dep_id = dep.id;
2.子查詢 (效率比連表查詢低)
在一條sql中兩個select,并且一個select的結果是另一個select的條件
用的是 in 連接
select * from 表1 where 字段 = (select 字段 from 表2 where 條件 = 值)
select * from 表1 where 字段 in (select 字段 from 表2 where 條件 = 值)
例子: 查詢品駿年齡在25歲以上的部門
#用鏈表查詢
select dem.name from department as dep inner join employee as emp on emp.dep_id = dep.id group by dep_id having avg(age)>25;
#子查詢
select name from department where id in (select dep_id from employee group by dep_id having avg(age)>25)
例子:查看技術部員工的名字
#連表
select emp.name from employee as emp inner join department as dep on emp.dep_id = dep.id where dep.name='技術';
#子查詢
select name from employee where dep_id = (select id from department where name='技術')
索引
1.索引原理
索引的目的在于提高查詢效率
有什么好處壞處:占空間,拖慢寫的速度
本質都是:通過不斷地縮小想要獲取數據的范圍來篩選出最終想要的結果,同時把隨機的事件變成順序的事件,也就是說,有了這種索引機制,我們可以總是用同一種查找方式來鎖定數據
索引越多,占用磁盤空間越大,修改表時對索引 的重構和更新很麻煩
2.對哪些字段添加索引
1、表的主鍵、外鍵必須有索引;
2、數據量超過300的表應該有索引;
3、經常與其他表進行連接的表,在連接字段上應該建立索引;
4、經常出現在Where子句中的字段,特別是大表的字段,應該建立索引;
5、索引應該建在選擇性高的字段上;
6、索引應該建在小字段上,對于大的文本字段甚至超長字段,不要建索引;
7、復合索引的建立需要進行仔細分析;盡量考慮用單字段索引代替:
A、正確選擇復合索引中的主列字段,一般是選擇性較好的字段;
B、復合索引的幾個字段是否經常同時以AND方式出現在Where子句中?單字段查詢是否極少甚至沒有?如果是,則可以建立復合索引;否則考慮單字段索引;
C、如果復合索引中包含的字段經常單獨出現在Where子句中,則分解為多個單字段索引;
D、如果復合索引所包含的字段超過3個,那么仔細考慮其必要性,考慮減少復合的字段;
E、如果既有單字段索引,又有這幾個字段上的復合索引,一般可以刪除復合索引;
8、頻繁進行數據操作的表,不要建立太多的索引;
9、刪除無用的索引,避免對執行計劃造成負面影響
創建索引:
Create index age on student(age)
刪除索引
drop index 索引名字 on索引的表
1.b+樹 以平衡樹為基礎的
1).所有的非葉子結點不存儲真實的數據
2).所有的葉子結點之間都被添加了雙向鏈表
數據庫索引的原理,為什么要用 B+樹,為什么不用二叉樹?
二叉樹特殊化為一個鏈表,相當于全表掃描。平衡二叉樹相比于二叉查找樹來說,查找效率更穩定,總體的查找速度也更快。
平衡二叉樹可是每個節點只存儲一個鍵值和數據的,如果是B樹,可以存儲更多的節點數據,樹的高度也會降低,因此讀取磁盤的次數就降下來啦,查詢效率就快啦。
B+樹非葉子節點上是不存儲數據的,僅存儲鍵值,而B樹節點中不僅存儲鍵值,也會存儲數據。innodb中頁的默認大小是16KB,如果不存儲數據,那么就會存儲更多的鍵值,相應的樹的階數(節點的子節點樹)就會更大,樹就會更矮更胖,如此一來我們查找數據進行磁盤的IO次數有會再次減少,數據查詢的效率也會更快。
B+樹索引的所有數據均存儲在葉子節點,而且數據是按照順序排列的,鏈表連著的。那么B+樹使得范圍查找,排序查找,分組查找以及去重查找變得異常簡單。
2. innodb和myisam的索引的存儲方式
innodb 內部 有一個 聚集索引(聚簇索引),非聚集索引
myisam 內部 沒有聚集索引 ,所有索引都是非聚集索引
3. 索引的種類
primary key: 除了約束 非空 + 唯一之外 還有其他的作用 聚集索引
unique: 約束 唯一 非聚集索引的作用
index: 沒有約束的作用 普通的非聚集索引
聯合唯一索引
聯合主鍵索引
聯合索引
4. 正確使用索引
1.條件必須是已經創建了索引的列
2.如果在條件中對索引列使用了范圍,并且這個范圍很大,速度就很慢 > < != between and not in
3.like條件 后面 必須是 'abc%' ,如果 like '%abbasff'
4.確認使用的索引列的區分度 選擇區分度低的列作為索引實際上并不能有加速查找的效果
5.索引列在條件中不能參與計算
6.and和or
and/or
使用and條件的時候 mysql在優化查詢的時候會有限選擇區分度高的列先查詢,來縮小其他條件要查詢的范圍
or 只會從左到右依次進行判斷
所有條件中出現的列區分度都需要很高
對每一個字段都要添加索引
**5.聯合索引(重復值比較多時用它)
聯合索引是指對表上的多個列合起來做一個索引
create index 索引名 on 表名(字段1,字段2...);
create index name_email on s1(name,email);
最左前綴原則
# s1(name,email)
# sql語句中條件必須含有name這個字段**
6.覆蓋索引
InnoDB存儲引擎支持覆蓋索引(covering index,或稱索引覆蓋),即從輔助索引中就可以得到查詢記錄,而不需要查詢聚集索引中的記錄。(不需要再回表查了)
例子:
s elect name from 表 where id =10000 # 用到索引了 ,但是不是覆蓋索引
select id from 表 where id =10000 # 用到索引了 ,也是覆蓋索引
索引不適合哪些場景
數據量少的不適合加索引
更新比較頻繁的也不適合加索引
區分度低的字段不適合加索引(如性別)
mysql優化
1.數據庫的優化
讀寫分離
多級的主從復制
2.數據結構的優化
正確建立表關系 表該拆的拆
垂直分表
水平分表
要使用固定長度的字段而不是變長字段
長度越固定的字段要在建建表的時候放在左邊
適當的字段的約束
3.sql語句的優化
使用連表查詢代替子查詢
正確建立索引,不要創建沒有用的索引
正確的使用索引
分庫與分表的設計
水平分庫:以字段為依據,按照一定策略(hash、range等),將一個庫中的數據拆分到多個庫中。
水平分表:以字段為依據,按照一定策略(hash、range等),將一個表中的數據拆分到多個表中。
垂直分庫:以表為依據,按照業務歸屬不同,將不同的表拆分到不同的庫中。
垂直分表:以字段為依據,按照字段的活躍性,將表中字段拆到不同的表(主表和擴展表)中。
分庫分表可能遇到的問題
事務問題:需要用分布式事務啦
跨節點Join的問題:解決這一問題可以分兩次查詢實現
跨節點的count,order by,group by以及聚合函數問題:分別在各個節點上得到結果后在應用程序端進行合并。
數據遷移,容量規劃,擴容等問題
ID問題:數據庫被切分后,不能再依賴數據庫自身的主鍵生成機制啦,最簡單可以考慮UUID
跨分片的排序分頁問題(后臺加大pagesize處理?)
mysql 連接數據庫
1.在終端提交事務
begin; # 開啟事務
select * from emp where id = 1 for update; # 查詢id值,for update添加行鎖;
update emp set salary=10000 where id = 1; # 完成更新
commit; # 提交事務
2.使用python 操作mysql數據庫
import pymysql
conn = pymysql.connect(
host='localhost', user='root', password="root",
database='db', port=3306, charset='utf-8', )
cur = conn.cursor(cursor=pymysql.cursors.DictCursor)
創建一個游標對象
# 游標里什么都不寫是元祖形式,寫上.cursors.DictCursor 就是字典形式
sql2 = 'select sname from student for update;', 添加一個鎖
cursor.execute('select * from s1 where email="eva2300@oldboy" or email="eva6666@oldboy"')
ret = cursor.fetchmany(2) # 取幾就打印幾個
fetchall() # 全取
fetchone() #只取一個
print(ret)
conn.commit() # 提交到數據庫
conn.close()
簡述mysql主從復制原理?
(1) master將改變記錄到二進制日志(binary log)中(這些記錄叫做二進制日志事件,binary log events);
(2) slave將master的binary log events拷貝到它的中繼日志(relay log);
(3) slave重做中繼日志中的事件,將改變反映它自己的數據。
總結:
查
單表查
select distinct * from 表 where 條件 group by 字段 having 過濾條件 order by 字段 limit n,m;
聚合函數 : sum avg max min count
分組聚合 : 求某個商品的平均價格,總銷量,求部門的最高工資,求本月平均打卡時間最早的
多表查
多表查詢
連表查詢
inner join
left join
right join
子查詢
在一條sql中兩個select,并且一個select的結果是另一個select的條件
推薦連表查詢的效率高
四, mongodb與MySQL的不同有哪些
愛喝馬黛茶的安東尼愛喝馬黛茶的安東尼2020-01-03 11:03:12原創4175
MySQL與MongoDB都是開源的常用數據庫,但是MySQL是傳統的關系型數據庫,MongoDB則是非關系型數據庫,也叫文檔型數據庫,是一種NoSQL的數據庫。它們各有各的優點,關鍵是看用在什么地方。所以我們所熟知的那些SQL語句就不適用于MongoDB了,因為SQL語句是關系型數據庫的標準語言。
一、關系型數據庫-MySQL
1、在不同的引擎上有不同的存儲方式。
2、查詢語句是使用傳統的sql語句,擁有較為成熟的體系,成熟度很高。
3、開源數據庫的份額在不斷增加,mysql的份額頁在持續增長。
4、缺點就是在海量數據處理的時候效率會顯著變慢。
二、非關系型數據庫-MongoDB
非關系型數據庫(nosql ),屬于文檔型數據庫。先解釋一下文檔的數據庫,即可以存放xml、json、bson類型系那個的數據。這些數據具備自述性,呈現分層的樹狀數據結構。數據結構由鍵值(key=>value)對組成。
1、存儲方式:虛擬內存+持久化。
2、查詢語句:是獨特的MongoDB的查詢方式。
3、適合場景:事件的記錄,內容管理或者博客平臺等等。
4、架構特點:可以通過副本集,以及分片來實現高可用。
5、數據處理:數據是存儲在硬盤上的,只不過需要經常讀取的數據會被加載到內存中,將數據存儲在物理內存中,從而達到高速讀寫。
6、成熟度與廣泛度:新興數據庫,成熟度較低,Nosql數據庫中最為接近關系型數據庫,比較完善的DB之一,適用人群不斷在增長。
三、MongoDB優勢與劣勢
優勢:
1、在適量級的內存的MongoDB的性能是非常迅速的,它將熱數據存儲在物理內存中,使得熱數據的讀寫變得十分快。
2、MongoDB的高可用和集群架構擁有十分高的擴展性。
3、在副本集中,當主庫遇到問題,無法繼續提供服務的時候,副本集將選舉一個新的主庫繼續提供服務。
4、MongoDB的Bson和JSon格式的數據十分適合文檔格式的存儲與查詢。
劣勢:
1、 不支持事務操作。MongoDB本身沒有自帶事務機制,若需要在MongoDB中實現事務機制,需通過一個額外的表,從邏輯上自行實現事務。
2、 應用經驗少,由于NoSQL興起時間短,應用經驗相比關系型數據庫較少。
3、MongoDB占用空間過大。
四、對比

TOP PERCENT 實例
使用百分比作為參數
例: SQL 語句從 websites 表中選取前面百分之 50 的記錄
SELECT TOP 50 PERCENT * FROM Websites;
使用 SQL [charlist] 通配符
MySQL 中使用 REGEXP 或 NOT REGEXP 運算符 (或 RLIKE 和 NOT RLIKE) 來操作正則表達式。
下面的 SQL 語句選取 name 以 "G"、"F" 或 "s" 開始的所有網站:
SELECT * FROM Websites
WHERE name REGEXP '^[GFs]';

帶有文本值的 NOT BETWEEN 操作符實例
下面的 SQL 語句選取 name 不介于 'A' 和 'H' 之間字母開始的所有網站:
實例
SELECT * FROM Websites
WHERE name NOT BETWEEN 'A' AND 'H';

UNION 操作
UNION 操作符用于合并兩個或多個 SELECT 語句的結果集。
請注意,UNION 內部的每個 SELECT 語句必須擁有相同數量的列。列也必須擁有相似的數據類型。同時,每個 SELECT 語句中的列的順序必須相同。
SQL UNION 語法
SELECT column_name(s) FROM table1
UNION
SELECT column_name(s) FROM table2;
注釋:默認地,UNION 操作符選取不同的值。如果允許重復的值,請使用 UNION ALL。
SQL UNION ALL 語法
SELECT column_name(s) FROM table1
UNION ALL
SELECT column_name(s) FROM table2;
注釋:UNION 結果集中的列名總是等于 UNION 中第一個 SELECT 語句中的列名。


insert into select 語句
INSERT INTO SELECT 語句從一個表復制數據,然后把數據插入到一個已存在的表中。目標表中任何已存在的行都不會受影響
insert into selec 語法
我們可以從一個表中復制所有的列插入到另一個已存在的表中:
INSERT INTO table2
SELECT * FROM table1;
或者我們可以只復制希望的列插入到另一個已存在的表中:
INSERT INTO table2
(column_name(s))
SELECT column_name(s)
FROM table1;
select into from 和 insert into select from和create table as select * from 都是用來復制表
select into from不是用在sql 的
兩者的主要區別為:
select into from 和 create table as select * from 要求目標表不存在,因為在插入時會自動創建;insert into select from 要求目標表存在。所以我們除了插入源表source_table的字段外,還可以插入常量,如sql語句:
1.新表不存在
復制表結構即數據到新表
create table new_table
select * from old_talbe;
這種方法會將old_table中所有的內容都拷貝過來,用這種方法需要注意,new_table中沒有了old_table中的primary key,Extra,auto_increment等屬性,需要自己手動加,具體參看后面的修改表即字段屬性.
只復制表結構到新表
# 第一種方法,和上面類似,只是數據記錄為空,即給一個false條件
create table new_table
select * from old_table where 1=2;
# 第二種方法
create table new_table like old_table;
2.新表存在
復制舊表數據到新表(假設兩個表結構一樣)
insert into new_table
select * from old_table;
復制舊表數據到新表(假設兩個表結構不一樣)
insert into new_table(field1,field2,.....)
select field1,field2,field3 from old_table;
復制全部數據
select * into new_table from old_table;
只復制表結構到新表
select * into new_talble from old_table where 1=2;
浙公網安備 33010602011771號