文件儲存
網頁版爬蟲數據庫 : https://spidertools.cn/#/crypto
TEXT 文本儲存
可以使用記事本打開
r #讀取。
r+ #讀寫,文件指針放在文件的開頭。
w #寫入,覆蓋原文件。
w+ #讀寫,覆蓋原文件。
a #附加。
a+ #讀寫,文件指針放在文件的結尾。
rd / wd / ad # 讀取、寫入、追加二進制數據到二進制文件中
語法 | 描述 |
---|---|
f.close() | 關閉文件對象f,并將屬性f.closed設置為True |
f.closed | 文件已關閉,則返回True |
f.encoding | bytes語str之間進行轉換時使用的代碼 |
f.read(count) | 從文件對象f中讀取至多ciunt個字節,如果沒有指定count,就讀取從當前文件指針直至最后的每一個字節。 |
f.write(string) | 將str對象s寫入到文件(二進制模式下寫入bytrs) |
f.readline(count) | 讀取下一(如果指定count,并在\n字符前滿足這一數值,name最多讀取count個字節),包括\n |
f.writelines(sep) | 批量寫入 |
f.name | 文件對象f的文件名(如果有) |
f.flush() | 清空文件對象f,并將緩存中的內容寫入到磁盤(如果有) |
with open('explore.text','a',encoding='utf-8') as file:file.write('\n'.join([question,author,answer]))file.write('\n' + '=' * 50 + '\n')'''=============================================='''def save_text(http,https,socks):'''將有用的信息進行保存'''http_csv = 'ip地址\http.csv'https_csv = 'ip地址\https.csv'socks_csv = 'ip地址\socks.csv'with open(http_csv,'w+') as p:for i in http:p.write("{:},{:}\n".format(i[0],i[1]))with open(https_csv,'w+') as ps:for o in https:ps.write("{:},{:}\n".format(o[0],o[1]))with open(socks_csv,'w+') as ks:for s in socks:ks.write("{:},{:}\n".format(s[0],s[1]))
JSON 文件儲存
可以使用Word打開
JSON 數據需要用雙引號來包圍,不能使用單引號,否則會報錯:
JSONDecodeError: Expecting property name enclosed in double quotes: line 1 column 3 (char 2)
import jsona = '''[{"name":"Bob",
"gender":"male",
"birthday":"1992-10-18"},{
"name":"Selina",
"gender":"female",
"birthday":"1995-10-18"}]''' # 創建 str 格式的一組數據data = json.loads(a) #使用loads()方法將字符串轉換為JSON對象
data[0].get('name') #通過get()方法來獲取name屬性的值,等同 data[0]['name'],前者不會報錯,如果沒有會返回None
data[1].get('age',25) #通過get()方法來獲取age屬性的值,如果沒有會返回默認值25
json.dumps(data) #將列表格式轉換為字符串格式,等同str(data),前者可以接受關鍵字with open(wite,'w') as file:file.write(json.dumps(data,indent=2)) #使用dumps()將data轉換為字符串格式,并添加關鍵字indent,保存后會首行縮進2格file.write(json.dumps(data,indent=2,ensure_ascii=False)) #將 ensure_ascii 設為 False 就可以保存中文字符
with open(‘E:\data.json’,‘w’,encoding = ‘utf-8’) as file: #這種設置編碼的方式對json無效
CSV 文件儲存
可以使用Excel打開,使用逗號分隔值或制表符分隔值
import csvwith open('E:\data.csv','w',encoding = 'utf-8') as file: #設置打開的編碼格式為 utf-8writer = csv.witer(file,delimiter = '\t') #將分隔符更改為制表符writer.writerow(['id','name','age']) #單列表形式儲存writer.writerows(['10001','Mike',20],['10002','BOd',22],['10003','Jordan',21]) #多列表形式儲存'''字典形式儲存'''
with open('E:\data.csv','w') as file:fieldnames = ['id','name','age'] #定義三個字段名writer = csv.DictWriter(file,fieldnames=fieldnames) #保存字典格式,并輸入關鍵字fieldnames來確定字段名writer.writeheader() # 寫入頭信息,及['id','name','age']
writer.writerows([{'id':'1001','name':'Mike','age':'20'},{'id':'1002','name':'BOd','age':'22'},{'id':'1003','name':'Jordan','age':'21'}])'''用pandas讀取CSV文件'''
import pandas as pddf = pd.read_csv('E:\data.csv')
print(df)
關系數據庫儲存
MySQL 的儲存
https://www.runoob.com/mysql/mysql-tutorial.html 菜鳥教程
異步需要使用 aiomysql
SHOW 數據庫名; # 查看數據庫
USE 數據庫名; #使用數據庫
CREATE DATABASE 數據庫名; #創建數據庫
SQL分類
種類 | 功能 | 關鍵字 |
---|---|---|
DQL匯總(Data Query Language,數據查詢語言) | 查詢數據 | Select |
DML(Data Manipulation Language,數據操作語言) | 檢索或者修改數據 | INSERT、UPDATE、DELETE |
DDL(Data Definition Language,數據定義語言) | 定義數據結構,如創建或刪除數據庫對象 | CREATE、TRUNCATE、DROP、ALTER |
DCL(Data Control Language,數據控制語言) | 定義數據庫用戶權限 | grant、revoke等 |
新建數據庫
字符集:utf8mb4
排序規則:utf8mb4_general_ci 或者 utf8mb4_unicode_ci
SELECT 查詢
SELECT * FROM dept; #查詢數據表,* 為表的所有列(可以為一個或者多個,用逗號隔開), dapt為表名
SELECT dname AS d FROM dept; #使用 as 給列取別名
SELECT dname AS `as` FROM dept; # 使用關鍵字做為別名時,可以增加 ` ` 來進行標注
SELECT DISTINCT job FROM emp; # 使用 DISTINCT 進行去重
WHERE 限定查詢
SELECT *|列名 FROM 表名 WHERE 條件;
限定查詢
運算符 | 說明 |
---|---|
> | 大于 |
< | 小于 |
= | 等于 |
>= | 大于等于 |
<= | 小于等于 |
!=或者<> | 不等于 |
SELECT * FROM emp WHERE sal>1500; # 在 emp 表中查詢 sal 值大于 1500 的項。
SELECT * FROM emp WHERE ename=‘ALLEN’; # 在 emp 表中查詢 ename 值等于 ‘ALLEN’ 的項。(在windows中,列值不區分大小寫,而在linux/ios中列值是區分大小寫的)
SELECT * FROM emp WHERE BINARY ename=‘Allen’; #使用 BINARY 來使 Windows 中區分大小寫。
IS NULL和IS NOT NULL
IS NULL #不占用空間的
**IS NOT NULL ** #占用空間的,包括空格
SELECT ename FROM emp WHERE comm IS NOT NULL; # 查詢 comm 列中占用了空間的項
SELECT ename FROM emp WHERE comm IS NULL; # 查詢 comm 列中不占用空間的項
SELECT ename FROM emp WHERE ename !=’ '; #查詢 cname 列中所有不是空格(’ ')和空(NULL)的項
AND和OR、NOT
SELECT * FROM emp WHERE sal>1500 AND comm IS NOT NULL; #使用 AND 同時限制 sal>1500 和 comm IS NOT NULL ,需要同時滿足
SELECT * FROM emp WHERE sal BETWEEN 1500 AND 3000; #使用 BETWEEN AND 限制滿足大于等于 1500 和小于等于 3000 的項
**SELECT * FROM emp WHERE sal>1500 OR comm IS NOT NULL; ** #使用 OR 限制 sal>1500 和 comm IS NOT NULL ,需要滿足其中一個
SELECT * FROM emp WHERE NOT (sal>1500 OR comm IS NOT NULL); #使用 NOT 對限制 sal>1500 和 comm IS NOT NULL 進行取反
SELECT * FROM emp WHERE hiredate BETWEEN ‘1981-10-17’ AND ‘1985-12-17’; #日期查詢需要是日期格式。
IN 和 NOT IN
SELECT * FROM emp WHERE empno IN(7369,7499,7521); #查詢 empno 值為 7369,7499,7521 的項
SELECT * FROM emp WHERE empno NOT IN(7369,7499,7521); #查詢 empno 值不為7369,7499,7521 的項
LIKE 模糊查詢
SELECT * FROM emp WHERE ename LIKE ‘_M%’; #查詢 ename 中第二個字符是 M 的項(LIKE是用來進行模糊匹配的,_ 匹配一個字符,% 匹配0個或多個字符)
ORDER BY 排序
SELECT * FROM emp WHERE sal>1500 ORDER BY sal; #查詢 sal>1500 的項,并進行排序(默認為升序)
SELECT * FROM emp WHERE sal>1500 ORDER BY sal DESC; #查詢 sal>1500 的項,并進行降序排序(使用 DESC 進行降序排序)
SELECT * FROM emp WHERE sal>1500 ORDER BY sal DESC, hiredate ASC ; #先對 sal 進行降序排序,然后對 hiredate 進行升序排序。(多重排序)
DML 數據操作
功能:檢索或者修改數據
關鍵字:INSERT、UPDATE、DELETE
INSERT(插入)
單一數據插入
語法1:INSERT INTO 表名(列名,列名,列名) VALUES(值,值,值);
語法2:INSERT INTO 表名 VALUES (值,值,值);
注意:你輸入幾個列名就插入幾個值,列名和值的位置需要一一對應,如果你使用第二種結構,不寫列名,就要保證后面的賦值個數覆蓋了表中所有的列
示例:
INSERT INTO myemp(empno) VALUES(7788);
INSERT INTO myemp VALUES(7788,NULL,NULL,NULL,NULL...);
批量數據插入
語法:INSERT INTO 表名 SELECT 字段列表 FROM 表名 WHERE條件;
注意:INSERT表和SELECT表結果集的列數、列序、數據類型必須要一致
示例:
INSERT INTO TESR SELECT * FROM emp;
INSERT INTO TESR(deptno,dname,loc) SELECT * FROM dept; -- 將dept表插入到TESR表中
INSERT INTO TESR(deptno,dname,loc) SELECT deptno,dname,loc FROM dept;
-- 手動插入多行-在TESR表中的depto,dname,loc屬性插入值
INSERT INTO TESR(deptno,dname,loc) VALUES
(61,'A','AA'),
(62,'B','BB'),
(63,'C','');
實例:
-- 插入數據
INSERT INTO tt(pid,`name`,job) VALUES
(01,'孟東亮','服務主管'),
(02,'伍增榮','高級領班'),
(03,'羅渝川','領班'),
(04,'官佳珍','領班');
UPDATE(修改)
語法:UPDATE 表名 SET 要修改的字段1=新值,要修改的字段2=新值,... [WHERE 條件];
UPDATE myemp SET comm=100 WHERE empno=7896; -- 將 myemp 表中 empno 為78996的項內 comm 的值改為100
UPDATE tesr SET dname='luo',loc='luo' WHERE deptno=12;
UPDATE TESR SET loc='111'; -- 將TESR表中的loc列全部改為111
UPDATE `學員基本信息表` SET sex='男' WHERE pid IN(2,3,4,5,6,7,9,10,11,12,13);
UPDATE `學員基本信息表` SET job='保潔員' WHERE pid IN(14,15,16);
DELETE(刪除)
語法:DELETE FROM 表名 [WHERE 條件];
DELETE FROM TESR WHERE deptno=62; -- 將TESR表中,deptno=62的這一條記錄刪除
DELETE FROM TESR WHERE deptno IN(61,63); -- 刪除多行
DELETE FROM TESR; -- 刪除表
DDL 數據定義語言
導入數據表
語法:LOAD DATA INFILE 要導入的文件路徑,INTO TABLE 表名 FIELDS TERMINATED BY 分割字段方式(這里默認是逗號,可以更改為其他的分割方式)ENCLOSED BY 分號分割,默認就行 LINES TERMINATED BY 換行 IGNORE 1 ROWS 忽略第一行(本例中第一行為數據庫中對應的字段,如果你的文件中第一行就是數據的話,就不要忽略第一行了)。
LOAD DATA INFILE 'D:\\Document\\Download\\test0142.csv' INTO TABLE city_china FIELDS TERMINATED BY ',' ENCLOSED BY '"' LINES TERMINATED BY '\n' IGNORE 1 ROWS ;
創建數據表
功能:定義數據結構,如創建或刪除數據庫對象
關鍵字:CREATE、TRUNCATE、DROP、ALTER
語法1:CREATE TABLE 表名(
字段名1 字段類型 [DEFAULT 默認值],
字段名2 字段類型 [DEFAULT 默認值],
字名3 字段類型 [DEFAULT 默認值]
...
字段名n 字段類型 [DEFAULT 默認值]
) ENGINE=引擎名稱 CHARSET='編碼方式';
語法2:CREATE TABLE 表名 AS (查詢);
注意:當查詢不成立時,如1=2,則值復制表結構,不復制表數據
CREATE TABLE tt(abc int, string varchar(5), test int DEFAULT 6) ENGINE=INNODB CHARSET='utf-8'; -- string varchar(5) 表示 string 為varchar類型,字符長度為5 ;test int DEFAULT 6 表示 test 為int格式,默認值為6
常見的數據類型
類型 | 大小 | 范圍 | 描述 |
---|---|---|---|
INT或INTEGER | 4字節 | (-2147483648,2147483647) | 大整數值 |
FLOAT | 4字節 | (-3.402823466E+38,-1.175494351E-38) 0 (1.175494351E-38,3.402823466E+38) | 單精度浮點數值 |
DOUBLE | 8字節 | (-1.7976931348623157E+308,-2.2250738585072014E-308) 0 (2.2250738585072014E-308,1.7976931348623157E+308) | 雙精度浮點數值 |
CHAR | 0-255字節 | 無 | 定長字符串 |
VARCHAR | 0-65535字節 | 無 | 定長字符串 |
DATE | 3字節 | 1000-01-01~9999-12-31 | 日期值 |
DATETIME | 8字節 | 1000-01-01 00:00:00~9999-12-31 23:59:59 | 混合日期和時間值 |
數據類型選取規則
類型 | 比較 |
---|---|
整數類型和浮點數類型 | 如果要表示小數只能用浮點數類型,整數類型不能表示小數。 浮點類型DOUBLE精度比FLOAT類型高,如果需要精度到10位以上,就應該選擇DOUBLE類型。 |
浮點數類型和定點數類型 | 對于精度要求高的時候需要使用定點數存,因為定點數內部是以字符串形式儲存 |
CHAR類型和VARCHAR類型和TEXT類型 | CHAR定長字符串,占用空間大,速度快。 VARCHAR變長字符串,占用空間小,速度慢。 TEXT類型是一種特殊字符串類型。只能保存字符數據,而不能有默認值。 它們3個存儲和檢索數據方式都不一樣,數據檢索的效率CHAR>VARCHAR>TEXT。 CHAR在保存的時候,后面會用空格填充到指定的長度,在檢索的時候后面的空格會去掉。 VARCHAR在保存的時候,不進行填充。當值保存和檢索時尾部的空格任然保留。 |
日期和時間類型 | YEAR只保存年份,占用空間小。 其它和日期時間有關的可以通過整型保存時間戳,方便計算。 |
補充:一般我們的整型的定義不用在后面去加它的一個長度。少用像test、blob那種比較長,比較不可控的類型,盡量使用CHAR或者VARCHAR來做,因為它們的檢索效率是不一樣的。除此之外要注意的是VACHAR里面的N指代的是數據的字符長度,而不是字節數。在存一些精度特別高的數據的時候,不管是使用float還是用的double,它因為浮點數的原則問題就和python一樣始終會有精度上的缺陷,這個時候你可以使用定點數的方式存儲(decimal格式)
實例:
CREATE TABLE student(
pid VARCHAR(18), -- 表示人的編號
`name` VARCHAR(30), -- 表示人的姓名
age INT(3), -- 表示人的年齡
brithdate DATE, -- 表示出生日期
sex VARCHAR(2) DEFAULT '男' -- 表示性別,默認值為'男'
);
CREATE index pf ON player_attributes(preferred_foot); #創建一個索引,能夠加快后續的檢索速度 pf為檢索類容,player_attributes為表名,preferred_foot為檢索項目
常用的五類約束
名稱 | 含義 |
---|---|
NOT NULL | 非空約束,指定某列不為空 |
UNIQUE | 唯一約束,指定某類列和幾列組合的數據不能重復 |
PRIMARY KEY | 主鍵約束,指定某列的數據不能重復,值必須唯一 |
FOREIGN KEY | 外鍵,指定該列記錄屬于主表中的一條記錄,值參照另一條數據 |
DEFAULT | 默認約束,當沒有給對應列的值的時候,默認的內容 |
注意:在MySQL中不支持CHECK約束,但可以使用CHECK約束,而沒有任何效果
CREATE TABLE student2(
pid INT PRIMARY KEY, -- 表示人的編號 (主約束)
`name` VARCHAR(30) UNIQUE NOT NULL, -- 表示人的姓名 (唯一約束,非空約束)
age INT(3) NOT NULL, -- 表示人的年齡 (非空約束)
brithdate DATE, -- 表示出生日期
sex VARCHAR(2) DEFAULT '男' -- 表示性別,默認值為'男'
);
auto_increment #設置自動增加屬性
auto_increment=n #指定一個自增的初始值n
外鍵約束
在創建表的時候進行添加:
語法:[CONSTRAINT symbol] FOREIGN KEY (主表字段) REFERENCES 從表(從表字段);
FOREIGN KEY (pid) REFERENCES student2(pid) # 新建的表 pid 列與 student2 表 pid 列進行關聯
CONSTRAINT haha FOREIGN KEY (`name`) REFERENCES student2(`name`) # 使用 CONSTRAINT 對外鍵名進行更改
對于創建好的表,繼續修改表的結構來添加外鍵 :
語法:ALTER TABLE 主表 ADD [CONSTRAINT symbol] FOREIGN KEY(主表字段) REFERENCES 從表(從表字段);
實例:
-- 創建部門基本信息表
CREATE TABLE tt(
pid INT UNIQUE NOT NULL, -- 編號(int類型,唯一及非空約束)
`name` VARCHAR(30) PRIMARY KEY, -- 姓名(VARCHAR類型,長度為30,主約束)
sex VARCHAR(2) DEFAULT('女'), -- 性別(VARCHAR類型,長度為2,默認值為“女”)
dname VARCHAR(50) DEFAULT('服務保潔部服務組'), -- 部門(VARCHAR類型,長度為50,默認值為“服務保潔部服務組”)
job VARCHAR(30)); -- 職位(VARCHAR類型,長度為30)
ALTER (修改表)
功能 | 語法 |
---|---|
增加表的字段 | ALTER TABLE 表名稱 ADD(列名稱 數據類型 DEFAULT 默認值); |
刪除某一列 | ALTER TABLE 表名稱 DROP 列名稱; |
給表重新命名 | ALTER TABLE 表名稱 RENAME 新表名字; |
添加約束 | ALTER TABLE 表名稱 ADD CONSTRAINT 約束名 約束; |
刪除約束 | ALTER TABLE 表名稱 DROP CONSTRAINT 約束名; |
ALTER TABLE student ADD CONSTRAINT lala FOREIGN KEY (name
) REFERENCES student2(name
); # 用ALTER 語句增加一個外鍵
ALTER TABLE tablemoney ADD CHECK (money>0); # 限定金額大于0
ALTER TABLE tablemoney ADD CHECK (rate>0 and rate<4)
ALTER TABLE tablemoney ADD CHECK (rate IN (1,2,3)) # 規定難度級別,只能為1,2,3
ALTER TABLE tablemoney ADD CHECK (uname like’A%') #必須以A開頭的
DROP (刪除表)
語法:DROP TABLE <表名>;
DROP TABLE person; # 刪除表名為person的表
創建表、插入數據、修改數據實例:
-- 創建部門基本信息表
CREATE TABLE `部門人員基本信息`(
pid INT UNIQUE NOT NULL auto_increment, -- 編號(int類型,唯一及非空約束)
`name` VARCHAR(30) PRIMARY KEY, -- 姓名(VARCHAR類型,長度為30,主約束)
sex VARCHAR(2) DEFAULT('女'), -- 性別(VARCHAR類型,長度為2,默認值為“女”)
dname VARCHAR(50) DEFAULT('服務保潔部服務組'), -- 部門(VARCHAR類型,長度為50,默認值為“服務保潔部服務組”)
job VARCHAR(30), -- 職位(VARCHAR類型,長度為30)
tel BIGINT(11) UNIQUE); -- 插入數據
INSERT INTO `部門人員基本信息`(pid,`name`,job,tel) VALUES
(01,'孟東亮','服務主管',16659075935),
(02,'伍增榮','高級領班',13143205828),
(03,'羅渝川','領班',15723051314),
(04,'官佳珍','領班',18200758592),
(05,'謝偉龍','員工',18814011708),
(06,'溫景霞','員工',15876319784),
(07,'江靜怡','員工',14718365136);-- 修改數據
UPDATE `部門人員基本信息` SET sex='男' WHERE pid IN(2,3,5);CREATE TABLE `學員基本信息表`(
pid int UNIQUE NOT NULL,
`name` VARCHAR(30) PRIMARY KEY,
sex VARCHAR(2) DEFAULT('女'), -- 性別(VARCHAR類型,長度為2,默認值為“女”)
dname VARCHAR(50) DEFAULT('服務保潔部服務組'), -- 部門(VARCHAR類型,長度為50,默認值為“服務保潔部服務組”)
job VARCHAR(30) DEFAULT('學員'), -- 職位(VARCHAR類型,長度為30)
tel BIGINT(15) UNIQUE); INSERT INTO `學員基本信息表`(pid,`name`,tel) VALUES
(1,'楊佳慧',18922842063),
(2,'楊榆',13510598604),
(3,'張永鈐',17780119952),
(4,'雷奇',18681490921),
(6,'曾渝敏',14774735437),
(7,'藍林榮',17875764983),
(5,'周慧銘',13723721976),
(8,'況蕾',18807425813),
(9,'陳周沂',13417607122),
(10,'楊侃',18152641986),
(11,'李旌揚',18033081862),
(12,'陳敏武',13322762903),
(13,'曾錦濤',13242946460),
(14,'賈瑞華',13622364972),
(15,'郭秀蘭',19974231328),
(16,'胡足足',13689575311);UPDATE `學員基本信息表` SET sex='男' WHERE pid IN(2,3,4,5,6,7,9,10,11,12,13);
UPDATE `學員基本信息表` SET job='保潔員' WHERE pid IN(14,15,16);INSERT INTO `部門人員基本信息`(`name`,sex,dname,job,tel)
SELECT `name`,sex,dname,job,tel FROM `學員基本信息表`; -- 將后表的數據插入的前表中ALTER TABLE `部門人員基本信息` RENAME `部門人員信息表`; -- 更改表名SELECT * FROM `部門人員信息表` ORDER BY pid; -- 按pid進行升序排序
SELECT 函數
字符串函數
字符串拼接:concat(str1,str2,…)
SELECT ename,job,CONCAT(ename,‘+’,job) FROM emp; # 表emp中的ename屬性值和job屬性值使用加號進行拼接
字符串長度:length(str)
SELECT ename,LENGTH(ename) FROM emp; # 求表emp中neame屬性值的長度
數學函數
絕對值:abs(n)
SELECT ABS(5.6); #求5.6的絕對值
截取數值:trunc(n)
SELECT TRUNCATE(5.5558,3); # 小數點后保留3位
四舍五入:round(n,d)
SELECT ROUND(5.5558,3); # 讓小數點后只保留三位數字(這個操作是會四舍五入的)
日期函數
當前時間:now()
格式化:date_format(date,format)
SELECT DATE_FORMAT(‘2008-08-08’,“%Y年 %m月 %d日”); #對日期進行格式化
返回天數:to_days(date)
IFNULL(expr1,expr2)函數
如果expr1不是NULL,IFNULL返回expr1,否則返回expr2
主要解決如果表達式中有空值會干擾計算的問題
SELECT ename,sal+IFNULL(comm,0) FROM emp; #使用 IFNULL 對 comm 中的空值進行處理,如果為空就替換為0
分組查詢
將查詢結果按照1個或者多個字段進行分組,字段值相同的為一組
GROUP BY 可用于單個字段分組,也可用于多個字段分組
語法:SELECT 列名..., 列函數
`FROM 表名...``WHERE 條件...``GROUP BY 列名...``HAVING 條件...``ORDER BY 列名...`
注意:上面的語法的先后順序是嚴格的
SELECT * FROM emp GROUP BY job; #通過job類型進行分組
聚合函數
函數名 | 描述 |
---|---|
SUM(expression) | 求和 |
MAX(expression) | 求最大值 |
MIN(expression) | 求最小值 |
COUNT(expression) | 統計記錄函數 |
COUNT(DISITINCT colname) | 統計去重后的記錄數 |
AVG(expression) | 求平均值 |
SELECT *,count(*) FROM emp GROUP BY job; # 每個job類型的數量
*SELECT ,MAX(sal) FROM emp GROUP BY deptno; #求每個depno中sal的最大值
*SELECT ,count(DISTINCT job) FROM emp GROUP BY deptno; #求每個deptno中job去重后的數量
GROUP BY + GROUP_CONCAT(expr) 分組統計
**SELECT deptno,count(*),GROUP_CONCAT(ename) `部門員工名單` FROM emp GROUP BY deptno; ** #找出每個部門的員工個數,同時輸出每個部門的人的名字
SELECT * AVG(sal) FROM emp GROUP BY deptno HAVING AVG(sal)>2000; #使用AVG對分組后的sal求平均值,并使用HAVING增加限定條件進行查詢
實例:
SELECT *,count(*) `部門人數`,AVG(sal) `部門平均工資`
FROM emp
WHERE job !='PRESIDENT'
GROUP BY deptno
HAVING `部門平均工資`>1800
ORDER BY `部門平均工資` DESC;-- 計算除了總裁以外,部門的平均薪資,并取部門平均薪資>1800,最后將數據降序排列
LIMIT 2,1 -- 限制最后輸出數據,從第2行開始,只輸出1行,一般這個函數是在數據比較多的時候去限制輸出行數的,同樣的可以寫作LIMIT 1 OFFSET 1,OFFSET代表跳過幾行才進行輸出
LIMIT 2,1 #限制最后輸出數據,從第2行開始,只輸出1行,一般這個函數是在數據比較多的時候去限制輸出行數的,同樣的可以寫作LIMIT 1 OFFSET 1,OFFSET代表跳過幾行才進行輸出
LIMIT 2 #只顯示1條數據
多表查詢
笛卡爾積 (交叉連接)
在MySQL中可以為CROSS JOIN 或者省略CROSS即JOIN,或者使用’ ,’
返回結果為被連接的兩個數據表的乘積
其實笛卡爾積就是把每一個表1數據都和表2數據做一次組合,把所有組合的可能性都列出來
SELECT emp.*,dept.* FROM emp JOIN dept; #查詢表emp和表dept,并將兩張表的數據交叉連接
內連接(等值連接)
語法:FROM 表名 [INNER] JOIN 表名 ON 條件 或者 WHERE后面用=
SELECT emp.*,dept.* FROM emp JOIN dept ON emp.deptno=dept.deptno; #增加判定條件emp.deptno=dept.deptno,將交叉后的數據用on(和where效果一樣)進行篩選。
內連接(非等值連接)
指的是不用等號連接,而是用>=,<=,>,<,!=,<>等進行連接,主要是為了解決一些比較特殊的結果查詢,不常用
外連接
外連接分為左外連接和右外連接,即除了返回符合連接條件的結果之外,還要返回左表(左連接)或者右表(右連接)中不符合連接條件的結果,相對應的使用NULL對應
LEFT OUTER JOIN 左外連接
SELECT c.*,t.* FROM course as c LEFT OUTER JOIN teacher as t ON c.tid=t.id; #完整顯示左表,右表只顯示完成匹配的。
RIGHT OUTER JOIN 右外連接
SELECT c.*,t.* FROM course as c RIGHT JOIN teacher as t ON c.tid=t.id; #完整顯示右表,左表只顯示完成匹配的。
**注意:這里LEFT OUTER JOIN和RIGHT OUTER JOIN中間的OUTER是可以省略的,不影響結果**
聯合查詢
UNION和UNION ALL
UNION:操作符用于合并兩個或者多個SELECT語句的結果集
語法:SELECT 字段名 FROM 表名1 UNION[UNION ALL] SELECT 字段名 FROM 表名2;
注意:UNION內部的SELECT語句必須擁有相同數量的列,列不要求數據類型相同,UNION得到的是去重后的結果,UNION ALL得到所有記錄,效率高于UNION
SELECT c.*,t.* FROM course as c LEFT JOIN teacher as t ON c.tid=t.id
UNION
SELECT c.*,t.* FROM course as c RIGHT JOIN teacher as t ON c.tid=t.id;
-- 將拼接后的左表和拼接后的右表進行拼接并去重。SELECT c.*,t.* FROM course as c LEFT JOIN teacher as t ON c.tid=t.id
UNION ALL
SELECT c.*,t.* FROM course as c RIGHT JOIN teacher as t ON c.tid=t.id;
-- 將拼接后的左表和拼接后的右表進行拼接。
自連接
自連接:自己和自己連接,虛擬出同一張表,找出兩個表中的關聯關系
SELECT e1.ename,e1.empno,e1.mgr,e2.empno,e2.ename FROM emp e1 LEFT JOIN emp e2 ON e1.mgr=e2.empno; #將表復制一份,并對所需要的數據進行交叉匹配,然后篩選
子查詢
- 子查詢:把內層查詢結果當作外層查詢的參考條件
- WHERE 后面子查詢:
WHERE 別名 運算符 (子查詢)
- 子查詢的列數需要對上,如果查詢結果個數大于1,一定要使用IN,如果只有1個值使用=
SELECT * FROM
(SELECT deptno,AVG(sal) as `avg` FROM emp GROUP BY deptno) as a
WHERE a.`AVG`>1500;
-- 將(SELECT deptno,AVG(sal) as `avg` FROM emp GROUP BY deptno)視為子表
利用Python進行數據庫操作
pymysql基本操作步驟
db = pymysql.connect(host=‘127.0.0.1’, port=3306,user=‘root’, password=‘123456’, db=‘dc_2019’) #創建數據庫連接,host(本機IP地址,本地就是localhost), port(本機端口號),user(用戶名), password(密碼), db(數據庫名稱)
import pymysqldb = pymysql.connect(host='localhost',user='root',password='****',port=3306) #使用connect()的方法聲明MySQL連接對象db,因在本地啟動,host(IP)傳入的是localhost,遠程啟動需要傳入公網IP地址。
cursor = db.cursor() #使用cursor()方法獲取操作坐標
cursor.execute('SELECT VERSION()') #獲取當前版本
cursor.execute('select * from dept;') #括號內直接跟SQL代碼,需要以字符串的格式輸入
cursor.fetchall() #查看當前獲取的結果
db.close() #關閉數據庫
db = pymysql.connect(host=‘127.0.0.1’, port=3306,user=‘root’, password=‘123456’, db=‘dc_2019’,cursorclass=pymysql.cursors.DictCursor) #使用cursorclass=pymysql.cursors.DictCursor將獲取的數據由元祖嵌套元祖格式改為列表嵌套字典格式
cursor.fetchall()
:拿到所有數據
cursor.fetchone()
:拿到一條數據
cursor.fetchmany()
:拿到指定的多條數據
數據插入
import pymysqldb = pymysql.connect(host='127.0.0.1', port=3306,\
user='root', password='123456', db='dc_2019',cursorclass=pymysql.cursors.DictCursor)cursor = db.cursor()
sql2 = 'INSERT INTO dept(deptno, dname, loc) VALUES(%s, %s, %s)' #創建SQL插入語句
data = [('70', 'Tech2','Xi"an'),('80', 'Tech3', 'Guiyang')] #創建插入的數據
try:cursor.executemany(sql2, data) #執行插入數據操作db.commit() #將插入的數據提交到數據庫中
except:db.rollback() #rollback操作,是數據庫的一個回滾操作,是為了使數據庫中的固化數據和能存數據同步的一個操作
cursor.executemany('select * from dept;') #獲取dapt數據表信息
result = cursor.fetchall()print(result)db.close()
sqlalchemy操作數據庫
sqlalchemy官方操作手冊: https://docs.sqlalchemy.org/en/13/orm/tutorial.html
from sqlalchemy import create_engine db = create_engine("mysql+pymysql://root:123456@localhost:3306/test?harset=utf8") #創建引擎 (數據庫+連接工具: //賬號:密碼@地址:端口號/字符集engine = sqlalchemy.create_engine(string)cur = engine.execute('select * from dept;') # 執行sqlprint(cur.fetchone()) # 返回結果--獲取其中一行db.dispose() # 關閉連接
M0ngoDB 儲存
https://www.runoob.com/mongodb/mongodb-tutorial.html 菜鳥教程
異步需要使用 motor
import pymongo
client = pymongo.MongoClient() # 連接數據庫,默認連接本地的MongoDB
collection = client['stu']['info'] # 打開集合,如果沒有這個集合則會自動創建
# 插入單條數據
stu_info = {'_id': 1, 'name': "luoyuchuan", 'age': 30}
conllection.insert_one(stu_info)# 插入多條數據
stu_info_list = [{'_id': 2, 'name': "luoyuchuan1", 'age': 32}, {'_id': 3, 'name': "luoyuchuan2", 'age': 33}]
collention.insert_many(stu_info_list)# 查詢數據
results = collection.find()
for item in results:print(item)
Redis 儲存
數據結構有 set、str、list等
redis 支持異步
import redis
client = redis.Redis() # 連接redis數據庫
result = client.sadd('movie:filter', value) # 保存集合 (key, values)
# 如果已經存在,就會保存失敗,則返回為 0 ,保存成功則返回為 1# 清空緩存
client.delete('movie:filter') # 清空指定key的緩存 # 關閉數據庫
MD5
import hashlib
md5_hash = hashlib.md5(str(value).encode('utf-8')) # 將 value 進行md5 加密 md5 加密只接收字節格式數據,將其他格式強制轉換為字符串,然后進行編碼為字節格式
md5_hash = md5_hash.hexdigest() # 計算哈希值,哈希值是惟一的,長度為32位