通常爲了高可用,還會備份大量的數據到備用數據庫,當運行的數據庫死掉以後能夠接替原來的數據庫python
數據庫的優點mysql
什麼是數據linux
什麼是數據庫面試
什麼是數據庫管理系統(DataBase Management System)簡稱DBMSredis
概念sql
數據庫的分類mongodb
mysql數據庫
https://downloads.mysql.com/archives/community/windows
下載以後點擊安裝包進行安裝安全
環境變量的配置:
在任何目錄下都能找到對應的文件
才能在任意位置輸入命令啓動該應用
windows下mysql install 安裝mysql服務 mysql服務就被註冊到操做系統中
net start mysql 啓動mysql
net stop mysql 關閉mysql
啓動客戶端鏈接server
mysql -u root -p
輸入密碼
或者 mysql -uroot -p123456
mysql -uroot -p123456
mysql帳號操做
#進入mysql客戶端 $mysql mysql> select user(); #查看當前用戶 mysql> exit # 也能夠用\q quit退出 # 默認用戶登錄以後並無實際操做的權限 # 須要使用管理員root用戶登錄 $ mysql -uroot -p # mysql5.6默認是沒有密碼的 #遇到password直接按回車鍵 mysql> set password = password('root'); # 給當前數據庫設置密碼 # 建立帳號 # create user '用戶名'@'主機ip/主機域名' identified by '密碼'; mysql> create user 'wrr'@'192.168.10.%' IDENTIFIED BY '123';# 指示網段 mysql> create user 'wrr'@'192.168.10.5' # 指示某機器能夠鏈接 mysql> create user 'wrr'@'%' #指示全部機器均可以鏈接 mysql> show grants for 'wrr'@'192.168.10.5';查看某個用戶的權限 # 遠程登錄 $ mysql -uroot -p123 -h 192.168.10.3 # 給帳號受權 #grant select on 數據庫名.* to '用戶名'@'主機的ip/主機域名' mysql> grant all on *.* to 'wrr'@'%'; #grant 權限類型 #grant all 給全部的權限 #grant select,insert 給查詢和插入的權限 mysql> flush privileges; # 刷新使受權當即生效 # 建立帳號並受權 mysql> grant all on *.* to 'wrr'@'%' identified by '123'
SQL語言主要用於存取數據、查詢數據、更新數據和管理關係數據庫系統,SQL語言由IBM開發。SQL語言分爲3種類型:
一、DDL語句 數據庫定義語言(defined): 數據庫、表、視圖、索引、存儲過程,例如CREATE DROP ALTER
二、DML語句 數據庫操縱語言(manager): 插入數據INSERT、刪除數據DELETE、更新數據UPDATE、查詢數據SELECT
三、DCL語句 數據庫控制語言(control): 例如控制用戶的訪問權限GRANT、REVOKE
show engines; 查看支持的存儲引擎
show variables like '%engin%'; 查看默認的引擎
Support:mysql是否支持這種存儲引擎
mysql5.6 默認爲Innodb存儲引擎
Myisam 在mysql5.5以前默認的存儲引擎 表鎖
操做數據的代碼-》 存儲引擎 - 〉數據
(1)數據存儲在硬盤上
數據和索引存儲在一塊兒 2個文件 Innodb存儲引擎 數據持久化
數據索引一個文件
表結構一個文件
Transactions:事務,保持數據安全
Supports transactions:支持事務,保證數據的完整性,將多個操做變成原子性操做
開啓事務-》 執行原子性操做-〉提交事務
row-level locking:行級鎖:修改的行少的時候使用,修改數據頻繁的時候
表級鎖:批量修改多行,對於大量數據的同時修改
foreign keys:外鍵,約束兩張表中的關聯字段不能隨意的添加、刪除,下降數據增刪改的出錯率
學生表中能夠添加學生的姓名和年齡,再設置一個id 一、2
在班級表裏設置id 一、2分別表示一班和二班,顯示對應的班級人數
可是想要在學生表中id能夠設置爲3,若是想要學生表的id根據班級表存在的id進行設置,那麼可給id加上外鍵,當id設置爲3會報錯
而且當學生表中有設置id爲2的,那麼班級表中的二班不能刪除
數據和索引不須要存儲在一塊兒 3個文件 Myisam存儲引擎 數據持久化
(2)數據存在內存中,也就是說斷電數據消失 1個文件 Memory 存儲引擎
表結構
MEMORY:Hash based基於哈希的,存儲在內存中,useful for temporary tables對臨時表很是有用
通常像首頁的熱點新聞就會存儲在memory中,查找不到再到大表中查找
面試題:
你瞭解mysql存儲引擎嗎?
你的項目用了什麼存儲引擎?
數字 和 bool
字符串
char 0-255字節 經常使用於身份證號、手機號、qq號(12位的qq更多)、username(12-18)、password(10-16)
varchar 0-65535字節 經常使用於評論、朋友圈、微博
時間
datetime 八個字節20210415121900 表示範圍1000-01-01 00:00:00/9999-12-31 23:59:59
year 一個字節 1901/2155
date 三個字節 20210415 表示範圍1000-01-01/9999-12-31
time 三個字節 121900 表示範圍 '-838:59:59'/'838:59:59'
timestamp 四個字節 1970-01-01 00:00:00/2038 默認值爲當前時間戳 不能爲空 更新其餘數據的時候自動按照當前的時間戳更新最新的時間戳,像登錄的時候,能夠記錄最後一次登錄的時間
enum/set
按照必定的範圍選擇
無符號的:只和數字有關 unsigned
不能爲空 not null
默認值 default
不能重複 unique 值不能重複,null能夠寫入多個 第一個被定義爲非空+惟一的那一列會成爲這張表的primary key
聯合惟一 unique
create table t14( id int, server_name char(12), ip char(15), port char(5), unique(ip, port) );
自增 auto_increment 只能對數字有效,自帶非空約束,至少是unique的約束以後才能使用auto_increment
create table t16( id int primary key auto_increment, name char(12) )
主鍵:非空+惟一約束 = 主鍵 primary key 一張表只能定義一個主鍵 若是不指定主鍵 默認是第一個非空+惟一
聯合主鍵 primary key( )
create table t17( id int, server_name char(12), ip char(15), port char(5), primary key(ip, port) );
外鍵: foreign key (本身的字段) references 外表(外表字段)
外表字段必須至少是惟一的
學生表
create table student( id int primary key auto_increment, name char(12) not null, gender enum('male', 'female') default 'male', class_id int, foreign key(class_id) references class_t(cid) );
班級表
create table class_t( cid int primary key auto_increment, cname char(12) not null, startd date );
須要先創建班級表,而且寫入數據,讓學生表能夠關聯到
且學生表內有關聯到班級表的,須要修改班級或者刪除,才能對班級表進行修改或者刪除
須要級聯更新、級聯刪除,能夠在foreign key(class_id) references class_t(cid) on update cascade on delete cascade
刪除班級表中一個班,那學生表中關聯這一個班的數據也會刪除
注意空字符串' '和空null在數據庫中不同
語法: 1. 修改表名 ALTER TABLE 表名 RENAME 新表名; 2. 增長字段 ALTER TABLE 表名 ADD 字段名 數據類型 [完整性約束條件…], ADD 字段名 數據類型 [完整性約束條件…]; 3. 刪除字段 ALTER TABLE 表名 DROP 字段名; 4. 修改字段 ALTER TABLE 表名 MODIFY 字段名 數據類型 [完整性約束條件…]; ALTER TABLE 表名 CHANGE 舊字段名 新字段名 舊數據類型 [完整性約束條件…]; ALTER TABLE 表名 CHANGE 舊字段名 新字段名 新數據類型 [完整性約束條件…]; 5.修改字段排列順序/在增長的時候指定字段位置 ALTER TABLE 表名 ADD 字段名 數據類型 [完整性約束條件…] FIRST; ALTER TABLE 表名 ADD 字段名 數據類型 [完整性約束條件…] AFTER 字段名; ALTER TABLE 表名 CHANGE 字段名 舊字段名 新字段名 新數據類型 [完整性約束條件…] FIRST; ALTER TABLE 表名 MODIFY 字段名 數據類型 [完整性約束條件…] AFTER 字段名;
多對一:
學生-班級
多個學生是一個班級的
學生表有一個外鍵關聯班級
書籍-做者
商品-訂單
多對多:
一對一:
select * from employee;
select id,name from employee; 查詢幾個字段
select id,name as n from employee; 查詢出來的時候重命名(加as)
select id,name n from employee; 查詢出來的時候重命名(空格)
select distinct post from employee; 查詢結果去除重複項
select distinct age,sex from employee; 查詢的結果只有當年齡和性別都重複纔會是重複項
select emo_name,salary*12 as annual_salary from employee; 四則運算(計算年薪)
select concat(emp_name,':',salary) from employee; 拼接concat,有時候姓和名的拼接
select concat_ws('|','apple','male'); 默認以第一個字符爲拼接符進行拼接後面的內容
結合case語句 case ... end
selcet ( case when emp_name = 'apple' then emp_name when emp_name = 'banana' then concat(emp_name, 'BIGSB') else concat(emp_name, 'SB') end ) as new_name from employee;
篩選符合條件的行
group by :
根據誰分組,能夠求這個組的總人數,最大值,最小值,平均值,求和,可是求出來的值只和分組字段對應
並不和其餘任何字段對應,這個時候查出來的全部字段都不生效
count(根據分組計數) max min sum avg
select sex,count(sex) from employee group by sex; 顯示男女分別有多少人
select age,count(age) from employee group by age; 顯示不一樣的年齡有多少人
更好的查看
select post,group_concat(emp_name) from employee group by post; 會自動拼接,可是拿不到每個的值
選擇各個部門最低工資的人
select post,emp_name,min(salary) from employee group by post; 這是錯誤的,由於分組顯示的姓名不是真正工資最低的,是分組出來
找不到對應的人
在having條件中可使用聚合函數
適合去篩選符合條件的某一組數據,而不是某一行數據
先分組,再過濾:求人數大於xx的性別,求年齡大於多少人的年齡
獲取每一個部門的平均工資篩選出平均值大於10000的部門
select post,avg(salary) from employee group by post having avg(salary) > 10000;
默認升序排 asc
降序 desc
select * from employee order by selery; 根據薪資從小到大排
select * from employee order by age desc; 根據年齡從大到小排
select * from employee order by age,salary desc; 先根據年齡從小到大排,年齡相同,再根據薪資從大到小排
limit n 取前幾條數據 不寫m默認爲0
select * from employee order by selery desc limit 3; 只取薪資最高的前三我的的數據
limit m,n 從第m+1項開始取n項
limit n offset m 與上面相同,從m+1項開始取n項
連表查詢
一張department表,一張employee員工表
select * from department, employee; 會產生一個大表,表是笛卡爾積的形式產生的
select * from department, employee where department.id = dep_id; id有多個須要指定是department仍是employee表裏的
所謂連表:
表與表之間的鏈接方式:
查詢平均年齡在25歲以上的部門
select dep_id from employee 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 name from employee where dep_id in (select id from department where name='技術');
查詢大於全部人平均年齡的員工名與年齡
select name, age from employee where age>(select avg(age) from employee);
查詢大於部門內平均年齡的員工名與年齡
select name,age from employee as t1 inner join (select dep_id,avg(age) as avg_age from employee group by dep_id) as t2 on t1.dep_id=t2.dep_id where age>avg_age;
exists關鍵字表示存在,使用這個關鍵字以後內層查詢語句不返回查詢的記錄,返回一個真假值,返回True,外層查詢語句將進行查詢,當返回值爲False,外層查詢語句不進行查詢
select * from employee where exists (select id from department where id=200);
工做中必備:
建立
刪除
知道用了它會加快查詢速度
面試:
函數都是處理簡單的邏輯
存儲過程處理的邏輯比較複雜
複雜的邏輯都是用python代碼來處理
簡單的數據增刪改查用sql解決
查詢過程當中不須要回表
分別建立的兩個索引在某一次查詢中臨時合併成一條索引 a=1 or b=2
explain select 語句 可以查看sql語句有沒有按照預期執行,能夠查看索引的使用狀況,type等級
通常都是經過python操做數據
import pymysql conn = pymysql.connect(host='127.0.0.1', user='root', password='123', database='homework') cur = conn.cursor() #cursor遊標 默認以元組返回 #cur = conn.cursor(cursor=pymysql.cursors.DictCursoor) #取出來的數據是以字典返回 更浪費空間 cur.execute('select * from student;') ret = cur.fetchone() print(ret) # 拿到一條數據 ret2 = cur.fetchmany(10) # 拿到多條數據 print(ret2) ret3 = cur.fetchall() # 拿到全部剩餘的數據 print(ret3) print(cur.rowcount) # 表示拿到多少條數據 cur.close() conn.close()
#增 刪 改 import pymysql conn = pymysql.connect(host='127.0.0.1', user='root', password='123', database='homework') cur = conn.cursor() try: cur.execute('insert into student values(17, "男", 3, "apple")') #執行了只至關於在內存中插入 cur.execute('update student set gender ="male" where id=17') # 修改 cur.execute('delete from student where id=17') conn.commit() #提交 except Exception as e: print(e) conn.rollback() # 回滾 cur.close() conn.close()
實際在操做中會遇到的問題
結合數據庫和python寫一個登錄
import pymysql usr = input('username :') pwd = input('password :') conn = pymysql.connect(host='127.0.0.1', user='root', password='123', database='test' ) conn.cursor() cur.execute('select * from userinfo where user="%s" and password="%s"'%(usr, pwd)) # select * from userinfo where user = "apple" or 1=1; --"... 後面的東西註釋了 #sql注入 #最好使用execute自動拼接 cur.execute('select * from userinfo where user=%s and password=%s', (usr, pwd)) #不用拼接,也不用加"" cur.close() conn.close()
事務
鎖
begin #開啓事務 select age from userinfo where id=1 for update; # 查詢id值,for update 加上行級鎖 update emp set salary=100000 where id=1; # 完成更新 commit #提交事務
備份
表和數據的備份
mydqldump.exe
在cmd命令直接執行
mysqldump -h 服務器 -u用戶名 -p密碼 數據庫名 > 備份文件名.sql
回覆數據 在mysql中執行命令
source D:\python\備份文件名.sql
數據的
增
刪
改
查
select 字段 from 表
順序:from 表--> where -> group by -> having -> select -> order by -> limit m,n
拓展
在執行select語句的時候,其實是經過where,group by,having這幾個語句鎖定對應的行
而後循環每一行執行select語句
select name from t where id>2;
先from t,再where id>2拿到數據,再循環拿到的數據,篩選name字段
select name,(select_now()) from t; 一樣也是循環拿到數據進行篩選
若是一個問題既可使用連表查詢也可使用子查詢解決,推薦那個連表查詢,效率更高
習題:
查詢至少有一門可與學號爲1的同窗所學課程相同的同窗的學號和姓名
select sid,sname from student right join (
select distinct student_id from score where cid in (select course_id from score where student_id=1) and student_id != 1;
) as t in student_sid = t.student_id;
查詢課程編號爲‘2’的成績比課程編號‘1’低的全部同窗的學號、姓名
正確的使用mysql數據庫