日萌社
人工智能AI:Keras PyTorch MXNet TensorFlow PaddlePaddle 深度學習實戰(不定時更新)
1.mysql數據庫的登錄的服務:
1.用戶登錄:mysql -u 用戶名 -p 密碼
可選參數:(默認連接本地服務器,可以省略下面兩個參數)
-h hostNameIP地址
-P port端口號
2.格式:mysql -u賬戶 -p密碼 -h數據庫服務器安裝的主機 -P數據庫端口
mysql -uroot -padmin -h127.0.0.1 -P3306
若連接的數據庫服務器在本機上,並且端口是3306。
則可以簡寫: mysql -uroot -padmin
3.啓動/停止MySQL服務:
2.SQL語句:
1.SQL語句的分類:(關鍵字不區分大小寫)
1.DDL、DCL、DML、DQL:
1.DDL:數據定義語句,用來定義數據庫對象:數據庫,表,列等。關鍵字:create,alter,drop等
2.DCL:數據控制語句,用來定義數據庫的訪問權限和安全級別,及創建用戶。
3.DML:數據操作語句,用來對數據庫中表的記錄進行更新。關鍵字:insert,delete,update等
4.DQL:數據查詢語句,用來查詢數據庫中表的記錄。關鍵字:select,from,where等
2.SQL包含6個部分:
1.數據查詢語言(DQL):
其語句,也稱爲“數據檢索語句”,用以從表中獲得數據,確定數據怎樣在應用程序給出。
保留字SELECT是DQL(也是所有SQL)用得最多的動詞,其他DQL常用的保留字有WHERE,ORDER BY,GROUP BY和HAVING。
這些DQL保留字常與其他類型的SQL語句一起使用。
2.數據操作語言(DML):
其語句包括動詞INSERT,UPDATE和DELETE。它們分別用於添加,修改和刪除表中的行。也稱爲動作查詢語言。
3.事務處理語言(TPL):
它的語句能確保被DML語句影響的表的所有行及時得以更新。TPL語句包括BEGIN TRANSACTION,COMMIT和ROLLBACK。
4.數據控制語言(DCL):
它的語句通過GRANT或REVOKE獲得許可,確定單個用戶和用戶組對數據庫對象的訪問。
某些RDBMS可用GRANT或REVOKE控制對錶單個列的訪問。
5.數據定義語言(DDL):
其語句包括動詞CREATE和DROP。在數據庫中創建新表或刪除表(CREAT TABLE 或 DROP TABLE);
爲表加入索引等。DDL包括許多與人數據庫目錄中獲得數據有關的保留字。它也是動作查詢的一部分。
6.指針控制語言(CCL):
它的語句,像DECLARE CURSOR,FETCH INTO和UPDATE WHERE CURRENT用於對一個或多個表單獨行的操作。
3.書寫規則:
1.在數據庫中,SQL語句大小寫不敏感,SELECT/select/SeLeCt
2.SQL語句可單行或多行書寫
3.在SQL語句中,關鍵字不能跨多行或縮寫
4.爲了提高可讀性,一般關鍵字大寫,其他小寫.
5.空格和縮進使程序易讀
2.SQL對數據庫進行操作:
1.創建數據庫:
1.create database 數據庫名;
2.create database 數據庫名 character set 字符集;
3.create database 數據庫名 character set 字符集 collate 字符集的校對規則;
4.例子:create database test character set utf8 collate utf8_general_ci;
5.一種拷貝 表結構 和 表數據的語句:(不會拷貝 表的索引)
CREATE TABLE emp_copy AS SELECT * FROM emp
CREATE TABLE emp_copy AS SELECT * FROM emp WHERE 1=2
6.一種拷貝 表結構 和 表數據的語句:(不會拷貝外鍵)
CREATE TABLE emp_bak LIKE emp
2.查看數據庫:
1.查看所有數據庫:show databases;
2.查看 “用於創建數據庫的”SQL語句:show create database 數據庫名;
3.修改數據庫:
1.修改數據庫的字符集/字符集的校對規則:
alter database 數據庫名 character set 字符集;
alter database 數據庫名 character set 字符集 collate 字符集的校對規則;
2.例子:alter database test character set utf8 collate utf8_general_ci;
4.刪除數據庫:
1.drop database 數據庫名;
5.切換/使用 數據庫:
1.use 數據庫名;
6.查看正在使用的數據庫:
1.select database();
3.SQL對錶進行操作:
注意:and、or、not 的優先級 就是 and --> or --> not
1.創建表:
1.creaet table 表名(字段名稱 字段類型(長度) 約束,
字段名稱 字段類型(長度) 約束, ......);
例子:
creaet table test(id int primary key auto_increment,
userName varchar(20) unique,
passWord varchar(20) not null);
注意:
最後一行沒有逗號;
若在建表中使用到了數據庫的關鍵字,比如新建一張訂單表order,但是order是數據庫中的關鍵字用來排序使用的;
若非要使用order這個單詞,此時可以使用反引號 括起來:`order`
2.查看錶:
1.查看當前使用的數據庫中所有的表:show tables;
2.查看該表的結構:desc 表名;
3.刪除表:
drop table 表名;
4.修改表:
1.添加列(字段):
alter table 表名 add 字段名稱 字段類型(長度);
alter table 表名 add 字段名稱 字段類型(長度) 約束;
2.修改列(字段)的類型、長度、約束:
alter table 表名 modify 列名 類型(長度);
alter table 表名 modify 列名 類型(長度) 約束;
3.刪除列(字段):
alter table 表名 drop 列名/字段名
4.修改列名(字段名):
alter table 表名 change 舊列名 新列名 舊列名的類型(長度);
alter table 表名 change 舊列名 新列名 舊列名的類型(長度) 約束;
5.修改表名:
rename table 舊錶名 to 新表名;
6.修改表的字符集:
alter table 表名 character set 字符集;
4.MySQL常用字段類型:
1.Java中的字段類型 MySQL中的字段類型
byte/short tinyint/smallint
int/Integer INT/INTEGER
long/Long BIGINT
---------------------------------------------------------------------------------------------
float/Float FLOAT
double/Double DOUBLE
BigDecimal DECIMAL
FLOAT[(s,p)]、DOUBLE[(s,p)]:小數類型,可存放 實型、整型、精度(p)、範圍(s);
double(5,2):整數和小數一共佔5位,其中小數佔2位,最大值 999.99,最小 -999.99;但都不夠精準;
DECIMAL:定點數據類型,高精度類型,金額貨幣優先選擇;
---------------------------------------------------------------------------------------------
boolean bit
char/String char/varchar
BIT:我們一般存儲0或1,存儲是Java中的boolean/Boolean類型的值。
char(size):定長字符,0 - 255字節,size指N個字符數,若插入字符數超過設定長度,會被截取並警告。
varchar(size):變長字符,0 - 255字節,從MySQL5開始支持65535個字節,若插入字符數超過設定長度,會被截取並警告。
varchar 相當於 Java中字符串(String / StringBuilder / StringBuffer)
一般存儲大量的字符串,比如文章的純文本,可以選用TEXT系列類型。
注意:在MySQL中,char字符 使用 '單引號' 引起來。
---------------------------------------------------------------------------------------------
Date date/time/datetime/timestamp
日期和時間類型爲DATETIME(日期+時間)、DATE(日期)、TIMESTAMP(日期+時間)、TIME(時間)、YEAR,相當於Java中Date / Calender。
注意:在MySQL中,日期時間值使用 '單引號' 引起來。
---------------------------------------------------------------------------------------------
File BLOB/TEXT
BINARY、VARBINARY、TINYBLOB、BLOB、MEDIUMBLOB、LONGBLOB:存放圖形、聲音和影像,二進制對象,0-4GB。
但是,在開發中,我們一般把 二進制文件的路徑 存儲在 數據庫中。
---------------------------------------------------------------------------------------------
2.MySQL中的字段類型中的 char(長度) 和 varchar(長度) 的區別:
1.char(長度):
1.固定長度的字符 或 固定長度的字符串
2.存儲的數據不滿固定長度的話,則額外空格補齊,大於固定長度則報錯無法插入
2.varchar(長度):
1.可變長度的字符串
2.存儲的數據不滿固定長度的話,也不會額外空格補齊,不會有任何額外操作,大於固定長度則報錯無法插入
3. MySQL中的字段類型中的 date/time/datetime/timestamp:
1.date:只有日期;
date的用途:可用於 記錄生日日期
2.time:只有時間
3.datetime:既有日期又有時間,如果不往這個字段存值的話,則MySQL會默認使用null值存入到這個字段中
4.timestamp:既有日期又有時間,如果不往這個字段存值的話,則MySQL會默認使用當前的系統時間存入到這個字段中
timestamp的用途:可用於 記錄用戶註冊時間
4.MySQL中的字段類型中的 BLOB/TEXT
1.一般不會直接把文件數據存到數據庫中,而是一般都是把上傳的文件保存到服務器本地,
然後可以使用varchar 記錄該文件的路徑
5.MySQL 以一個可選的顯示寬度指示器的形式對 SQL 標準進行擴展,這樣當從數據庫檢索一個值時,可以把這個值加長到指定的長度。
例如,指定一個字段的類型爲 INT(6),就可以保證所包含數字少於 6 個的值從數據庫中檢索出來時能夠自動地用空格填充。
需要注意的是,使用一個寬度指示器不會影響字段的大小和它可以存儲的值的範圍。一般不用指定位寬。
age int(2):並不是代表age最多存儲99,查詢age值的時候 使用兩個0來佔位;
5.約束:
1.約束的作用:保證數據的完整性;
2.單表約束
1.主鍵約束:使用 primary key 修飾,如id;
主鍵約束 並且默認自帶 唯一約束 和 非空約束的;
2.唯一約束:使用 unique 修飾
3.非空約束:使用 not null 修飾
3.多表約束:外鍵約束,用於多表之間保證數據的完整性;
4.刪除約束(索引):alter table 表名 drop index 字段名
5.表的約束(針對於某一列):
1.非空約束:NOT NULL,不允許某列的內容爲空。
2.設置列的默認值:DEFAULT。
3.唯一約束:UNIQUE,在該表中,該列的內容必須唯一。
4.主鍵約束:PRIMARY KEY, 非空且唯一。
5.主鍵自增長:AUTO_INCREMENT,從1開始,步長爲1。
6.外鍵約束:FOREIGN KEY,A表中的外鍵列的值必須參照於B表中的某一列(B表主鍵)。
6.主鍵設計,唯一標識某一行數據的:
1.單字段主鍵:單列作爲主鍵,建議使用。
複合主鍵:使用多列充當主鍵,不建議。
2.主鍵分爲兩種:
1.自然主鍵:使用有業務含義的列作爲主鍵(不推薦使用),比如身份證號碼;
2.代理主鍵:使用沒有業務含義的列作爲主鍵(推薦使用);
6.SQL對數據庫表中的數據進行操作:
1.添加/插入 表數據:
1.insert / insert into 表名 (列名1, 列名2, ......) values (值1, 值2, ......):插入一行 全部字段 / 部分字段 的數據
2.insert / insert into 表名 values (值1, 值2, ......):插入一行 全部字段 的數據,比如有字段存入的是空值的話 必須使用null值代替
3.insert / insert into 表名 values (null, 值2, ......):因爲id是從0開始自動增長的,所以可以不指定id的值;
如果不存入指定的id值的話,必須改爲使用null值代替;
3.注意:
1.表名 和 後面的括號 之間、values 和 後面的括號 之間 都需要空格隔開,可有空格也可沒有空格隔開,但推薦有空格隔開;
原因:當批處理中values 和 後面的括號 之間 如果沒有使用空格隔開的話,那麼性能會慢幾倍,
所以values 和 後面的括號 之間需要空格隔開,滿足格式要求;
2.插入的值的類型和順序 都要和 列名(字段名) 的類型和順序 要一致
3.插入的值的最大長度不能超過列名(字段名) 設置的長度
4.插入的值是字符串/日期時間,那麼使用 單引號/雙引號 引起來
4.一般語法:INSERT INTO table_name [(column [, column...])] VALUES (value [, value...]);
5.一般來說,一條INSERT只能插入一條數據,因爲MYSQL沒有batch操作,所以,MYSQL也支持在一條INSERT中插入多條數據:
INSERT INTO table [(column [, column...])] VALUES (value [, value...]),(value [, value...]),...
當然,一條SQL的長度是有限的,可以通過調整max_allowed_packet參數;
2.添加/插入 中文數據時,出現亂碼的原因:
1.原因一:當前使用的字符集不支持中文;
解決方法:必須設置數據庫/表的字符集爲 character set utf8
2.原因二:使用的是window的(黑窗口)命令提示符窗口中 進行SQL語句操作中文數據時,出現中文亂碼並且無法把中文亂碼
添加/插入到數據庫 ;
window下安裝mysql服務器時,設置了使用的是utf-8字符集,那麼MySQL數據庫服務器中的客戶端和服務器
都是默認使用utf-8字符集,而window平臺使用的字符集是gbk,所以在window的(黑窗口)命令提示符窗口中
操作中文數據也是gbk編碼,因此把該gbk編碼的中文數據傳給MySQL數據庫服務器中的客戶端時,
使用的默認utf-8編碼無法對 gbk編碼的中文數據 進行正常解碼識別,因此導致最終的亂碼並且無法把該亂碼數據
存入到數據庫中;
解決方法:1.通過 show variables like '%character%'; 語句可以查看得知到 數據庫服務器中的 客戶端和服務器 使用的
字符集編碼的相關參數;
2.到MySQL安裝目錄下的my.ini文件中,把 數據庫服務器中的 客戶端 使用的 字符集編碼 修改爲 gbk編碼;
3.重啓MySQL服務:可以打開系統服務進行重啓MySQL服務
3.修改表數據:
1.update 表名 set 字段名1 = 字段值, 字段名2 = 字段值:把該列上的 所有每行數據 都修改爲新的值
2.update 表名 set 字段名 = 字段值 where 條件語句:按條件 只修改 該列上的某行數據 爲新的值
3.注意:
1.修改的值的類型 要和 列名(字段名) 的類型 要一致
2.修改的值的最大長度不能超過列名(字段名) 設置的長度
3.修改的值是字符串/日期時間,那麼使用 單引號/雙引號 引起來
4.語法:UPDATE table_name SET columnName = value [, column = value] … [WHERE condition];
UPDATE語句也可以使用表連接,子查詢等多種方式執行;
5.注意事項:
1.可以多表更新:(sqlserver不允許多表更新)
1.UPDATE table1, table2 SET columnName = value [, column = value] … [WHERE condition]
2.UPDATE table1, (select ... from ...) 別名 SET columnName = value [, column = value] … [WHERE condition]
“select ... from ...”可以作爲臨時表,使用上別名
2.(mysql是不允許)update更新的表,不能用於 set子句 或 where子句的 子查詢中,
即子查詢中用到的表 不能和 update更新的表 是一樣;
4.刪除表數據:
1.delete from 表名 where 條件語句:刪除表中某行數據
2.delete from 表名:刪除表中所有數據
3.delete 和 truncate 的區別:
1.delete 和 truncate 都爲刪除表中數據
2.delete from 表名:屬於DML(數據操作語句),逐條記錄刪除,事務可以作用在DML(數據操作語句)上,
意思即爲可通過 roolback; 命令語句 回滾之前的刪除操作,恢復被刪除的數據;
3.truncate table 表名:屬於DDL(數據定義語句),會先把表刪除了,然後重新創建一個結構一樣的空的表,
事務無法作用在DDL(數據操作語句)上,意思即爲無法通過 roolback; 命令語句 進行回滾
之前的刪除操作,無法恢復被刪除的數據;
4.開啓事務/回滾事務:
1.指的是邏輯上的一組操作,組成這組操作的各個邏輯單元,要麼全都成功,要麼全都失敗。
回滾(Rollback)指的是程序或數據處理錯誤,將程序或數據恢復到上一次正確狀態的行爲。
2.開啓事物:START TRANSACTION / BEGIN TRANSACTION
3.提交事務:COMMIT
4.回滾事物:ROLLBACK
4.語法:DELETE FROM table_name [WHERE condition];
在delete語句中,where子句是可選的部分,如果使用了where子句,則刪除的數據是符合where條件的所有記錄;
如果省略了where子句,則全表的數據都會被刪除,delete語句的where條件也同樣支持子查詢,但是一定注意,
刪除語句中的where條件不能是要刪除的數據表中的數據;
所以,在涉及到 刪除的數據 是需要通過要刪除的表中的數據查詢出來的時候,
那麼便需要把查詢結果臨時保存到另一張表,再通過delete語句刪除;
5.查詢表數據:(like、group by ... having、group_concat、order by、ifnull、limit [offset,] row)
1.基本查詢:select [distinct] *|列名 from 表名 where 條件語句
1.select * from 表名:查詢所有每行數據
2.select 列名1, 列名2, ...... from 表名:查詢某列上的所有每行數據
3.select distinct 列名 from 表名:查詢並對某列上的所有每行數據進行去重
4.select 列名1 + 列名2 + ...... from 表名:查詢並計算多列字段數據的和
select (列名1 + 列名2 + ......) / n from 表名:查詢並計算多列字段數據的平均值
5.select 列名 [as] otherName from 表名:(as可以省略)查詢並對列名 取 別名
2.條件查詢:
1.可用於條件查詢的 運算符、關鍵字
1.可以使用 比較運算符:>、<、=、>=、<=、<>
2.模糊查詢:like '_值%'
select * from 表名 where 列名1 like '_值%':% 和 _ 都爲佔位符
like '_值%':該值的前面可以包含任意一個字符,該值的後面可以包含示一個或任意多個字符
like '%值%':% 表示一個或任意多個字符,該值的前後都可以包含示一個或任意多個字符
like '_值_':_ 表示任意一個字符,該值的前後都可以包含任意一個字符
例子:
like ‘李_’:名字中必須是兩個字,而且是姓李的。
like ‘李%’:名字中姓李的學生,李子後可以是1個或任意個字符。
like ‘%四’:名字中以四結尾的。
like ‘%王%’:只要名稱中包含這個字就可以。
3.範圍查詢:in、between ... and ...
select * from 表名 where 列名 in (值1, 值2, ......):該列名的值可以是該多個值中任意一個值
select * from 表名 where 列名 between 值1 and 值2:該列名的值在值1和值2範圍之間任意一個值
select * from 表名 where 列名 > 值1 and 列名 < 值2:該列名的值在值1和值2範圍之間任意一個值
4.條件關聯:and、or、not
select * from 表名 where 列名1 = 值 and 列名2 = 值:多列字段 並列條件查詢
3.排序查詢:order by 字段名 asc / desc
1.單個字段 升序/降序:
order by 字段名 asc:升序,即位置從上到下的方向上,值按小到大排序
order by 字段名 desc:降序,即位置從上到下的方向上,值按大到小排序
order by 字段名:默認升序
2.多個字段 升序/降序:(如果第一個字段值相同,則按照第二個字段值進行排序)
order by 字段名1 asc, 字段名2 desc:
先按照 字段名1 進行升序排序,如果同時多個字段名1 的值相同,則按照 字段名2 進行降序排序;
例子:
查詢學生信息,先按照語文成績進行倒序排序,如果成績相同再按照英語成績升序排序
select * from 表名 order by chinese desc, english asc;
4.分組統計查詢:聚合函數、ifnull函數、if函數、分頁查詢函數、分組查詢group by ...... having ......
1.聚合函數:sum():求和;count()、count(distinct 字段名):統計個數;max():獲取最大值;min():獲取最小值;avg():求平均值;
select avg(字段名1), sum(字段名1) from 表名:查詢該字段名1上的所有每行數據的 平均值 和 總和
select count(*) from 表名:統計個數
注意:
1.select、group by ... having ...、order by 後面都可以使用 聚合函數,就只有where 後面不能使用 聚合函數,
因爲聚合函數本身只能得出一個結果數據,即查詢的結果只有一行數據,
並且where本身是對全局數據進行條件查詢的,因爲是先執行from再執行where,
所以如果where後面可以使用聚合函數的話,就會對全部數據進行聚合函數查詢,
最終的查詢結果就只有一行數據,是無法獲取多行的數據的,因此也是where 後面不能使用 聚合函數的原因;
2.在having後面可以使用聚合函數 可以代替 where後面無法使用聚合函數 的作用:
group by......having......:having不能單獨使用,having必須和group by才能一起使用;
having本身是對分組數據進行條件查詢的,而where本身是對全局數據進行條件查詢的;
group by 字段名 having 聚合函數:
having 後面可以使用 聚合函數,因此 正好可以 替代 where後面無法使用聚合函數 的作用;
對分組數據進行進行聚合函數查詢,每個分組都是有一條數據,所以最終查詢結果是多條數據;
3.where 和 having 的區別:
1.共同點:兩者都可用於對數據進行條件過濾篩選
2.不同點:
1.where是執行在from之後,所以where是對錶中所有的數據進行全局條件過濾,得出查詢結果集;
2.group by ... having ...:
1.having不能單獨使用,必須和 group by 一起使用;
2.group by ... having ... 是執行在where之後,因此group by是對查詢結果集進行分組的,
而having 是執行在group by之後,所以having 是對分組數據進行條件過濾篩選的;
3.having 後面要使用 聚合函數 的話,必須在 select 中寫出該聚合函數 ;
3.聚合函數可以用在select、group by、having、order by 的後面,唯獨不能用在where的後面;
因爲聚合函數是 對查詢結果集/分組數據 的基礎上進行 條件查詢的,
而執行where對錶中所有數據進行條件過濾篩選之後,才能得出查詢結果集,
所以聚合函數無法用在where的條件查詢中;
4.例子:
按商品名稱統計,統計每類商品花費的總金額在5000元以上的商品,
並且按照總金額升序排序
select product, sum(price) from orderitem group by product having sum(price) > 5000
order by sum(price) asc;
2.ifnull函數、if函數:
ifnull(字段名, 0) null值和任意值相加都會變爲null,所以必須判斷遇到null值時要變爲使用0值來代替使用
1.sum( ifnull(字段名1, 0) + ifnull(字段名2, 0) ):先計算每行數據的和,然後再把每行數據之和 進行相加
2.sum( ifnull(字段名1, 0) ) + sum( ifnull(字段名2, 0) ):先計算每列數據的和,然後再把每列數據之和 進行相加
3.IFNULL(expression_1,expression_2):
如果expression_1不爲NULL,則IFNULL函數返回expression_1;
如果expression_1爲NULL,返回expression_2的結果
SELECT IFNULL(NULL,"11"); 結果爲 11
SELECT IFNULL("00","11"); 結果爲 00
if(true,a,b) 和 if(false,a,b):第一個參數如果是true,就返回a;第一個參數如果是false,就返回b,像三元表達式
把salary表中的女改成男,男改成女:update salary set sex = if( sex = '男','女','男');
3.分頁查詢函數:limit [offset,] row
1.limit [offset,] row:從哪行開始取多少行,意思即從offset行開始取row行
[offset,]:表示可寫可不寫,不寫offset的話,offset默認爲0,意思即初始行爲0,表示第一行開始取
offset:從哪一行數據開始,初始行是從0開始
row:取多少行數據
2.select * from 表名 limit 0, 5:同下,從第一行開始,取5行數據;
select * from 表名 limit 5:同上,從第一行開始,取5行數據;
SELECT * FROM exam LIMIT 3, 1:只取第4條數據
SELECT * FROM exam LIMIT 3, 3:取出第4條到第6條的數據
4.分組查詢group by ...... having ...... :
1.select sum(字段名2) from 表名 group by 字段名1 having sum(字段名2) > 值 order by sum(字段名2) asc;
2.在having後面可以使用聚合函數 可以代替 where後面無法使用聚合函數 的作用:
group by......having......:having不能單獨使用,having必須和group by才能一起使用;
having本身是對分組數據進行條件查詢的,而where本身是對全局數據進行條件查詢的;
group by 字段名 having 聚合函數:
having 後面可以使用 聚合函數,因此 正好可以 替代 where後面無法使用聚合函數 的作用;
對分組數據進行進行聚合函數查詢,每個分組都是有一條數據,所以最終查詢結果是多條數據;
3.where 和 having 的區別:
1.共同點:兩者都可用於對數據進行條件過濾篩選
2.不同點:
1.where是執行在from之後,所以where是對錶中所有的數據進行全局條件過濾,得出查詢結果集;
2.group by ... having ...:
1.having不能單獨使用,必須和 group by 一起使用;
2.group by ... having ... 是執行在where之後,因此group by是對查詢結果集進行分組的,
而having 是執行在group by之後,所以having 是對分組數據進行條件過濾篩選的;
3.having 後面要使用 聚合函數 的話,必須在 select 中寫出該聚合函數 ;
3.聚合函數可以用在select、group by ... having ...、order by 的後面,唯獨不能用在where的後面;
因爲聚合函數是 對查詢結果集/分組數據 的基礎上進行 條件查詢的,
而執行where對錶中所有數據進行條件過濾篩選之後,才能得出查詢結果集,
所以聚合函數無法用在where的條件查詢中;
4.例子:
按商品名稱統計,統計每類商品花費的總金額在5000元以上的商品,
並且按照總金額升序排序
select product, sum(price) from orderitem group by product having sum(price) > 5000
order by sum(price) asc;
5.分組查詢語法:
SELECT [DISTINCT] *|分組字段1 [別名] [,分組字段2 [別名] ,…] | 聚合函數
FROM 表名稱 [別名], [表名稱 [別名] ,…]
[WHERE 條件(s)]
[GROUP BY 分組字段1 [,分組字段2 ,…] ]
[HAVING 條件 | [,聚合函數] ]
[ORDER BY 排序字段 ASC | DESC [,排序字段 ASC | DESC] | [,聚合函數ASC | DESC] ] ;
1.寫法順序:select...from...where...group by...having...order by...limit start count
2.執行順序:from ---> where ---> group by ---> select ---> having ---> order by ---> limit start count
3.where、group by、having 、聚合函數:
1.where 後面不能使用 聚合函數
2.having 後面要使用 聚合函數 的話,必須在 select 中寫出該聚合函數
1.select、group by ... having ...、order by 後面都可以使用 聚合函數,就只有where 後面不能使用 聚合函數
2.需要忽略NULL值時,需要使用ifnull函數:
ifnull(字段名, 0) null值和任意值相加都會變爲null,所以必須判斷遇到null值時要變爲使用0值來代替使用
3.分組:group by 字段名(把只要 該字段的字段值 都爲同一個值 的多行數據 都會被 分到 同一組)
select 字段名1 from table group by 字段名1
1.按某字段的值進行分組查詢;
該某字段的值首先會被去重,然後按照“只要該字段爲該分組的字段值的”行數據都會被分爲這一組;
2.使用GROUP BY的 正確寫法:
1.group by 後面進行分組的字段 出不出現在 select 後面的查詢字段中 都可以;
2.select 後面出現的 單獨使用的 查詢字段 都必須出現在 group by 後面進行分組的字段中;
3.如果 select 後面的查詢字段中 要使用 “不是group by的”分組字段的話,那麼便要在select 後面,
把該“不是group by的分組字段的” select 查詢字段 放到聚合函數(sum()等)中 或 group_concat()中;
原因:因爲首先聚合函數只會得出一個結果數據,即一行數據,
而SELECT後面單獨使用的字段是可能存在多行數據的,所以不符合要求並且毫無意義,
雖然不會報錯;
4.sum() / count() / 聚合函數() / group_concat() / concat() 都可以把 “不是group by的分組字段的”
select 查詢字段 作爲參數;
group_concat():可以把多個“不是group by的分組字段的” select 查詢字段 拼接爲 一個字符串,並且每個字段值的默認分隔符是逗號;
例子:select concat(字段,字段,字段) as 別名 from 表名 where 字段=xx group by concat(字段,字段,字段);
3.使用GROUP BY的 錯誤寫法:
select 後面出現的 單獨使用的 查詢字段 如果沒有出現在 group by 後面進行分組的字段中 是錯誤的;
4.使用GROUP BY要注意的點:
1.使用GROUP BY之後,出現在SELECT後面的字段不能單獨使用,SELECT中的字段 要麼是出現在
select後面的聚合函數中(如:select count(name)),要麼出現在GROUP BY中;
原因:因爲首先聚合函數只會得出一個結果數據,即一行數據,
而SELECT後面單獨使用的字段是可能存在多行數據的,所以不符合要求並且毫無意義,
雖然不會報錯;
2.在GROUP BY 子句中出現的字段,可以不出現在SELECT列表中
3.例子:
1.聚合函數單獨使用:SELECT COUNT(name) FROM table;
2.錯誤的使用,出現了單獨使用的字段:SELECT name, COUNT(name) FROM table;
3.如果使用GROUP BY 進行分組的話,則SELECT子句中,
只能出現分組的字段(GROUP BY子句中出現的字段) 或 聚合函數,
其他單獨使用的字段不能出現:
1.正確做法:
SELECT job, COUNT(empno), AVG(sal)
FROM emp
GROUP BY job;
2.錯誤的做法:(SELECT子句中單獨使用了字段deptno)
SELECT deptno, job, COUNT(empno), AVG(sal)
FROM emp
GROUP BY job;
5.group_concat(字段名):可以把多個“不是group by的分組字段的” select 查詢字段 拼接爲 一個字符串;
1.select 字段名1 , group_concat(字段名2) from table group by 字段名1
2.select 字段名1 , group_concat(字段名1 , 字段名2 , ......) from table group by 字段名1
3.select 字段名1 , group_concat(字段名1 , “-” , 字段名2 , “-” , ......) from table group by 字段名1
使用 “-” 作爲分隔符,那麼使用group_concat拼接多個字段爲一個字符串時,
該字符串中的每個字段之間都帶有“-”,
那麼便可以使用正則表達式根據“-”從該字符串中取出每個字段值;
4.group by 後面的字段 可以不需要出現在 select 和 from之間,但 select 和 from之間不能單獨使用
group by 後面不存在的字段,
但可以在select 和 from之間 使用 聚合(集合)函數 或 group_concat() 帶上 group by 後面不存在的字段;
7.SQL中select、from、where、group by、having、order by、limit [offset,] row 的定義順序 和 執行順序:
1.定義順序:select ... from ... where ... group by ... having ... order by ... limit [offset,] row
其中select和from是必須的,其他關鍵詞是可選的;
例子:select ... from ... where ... group by 字段1, 字段2 having 字段1=xx and 字段2 =xx order by 字段1 asc, 字段2 desc limit [offset,] row
2.執行順序:from ... where ... group by ... having ... select ... order by ... limit [offset,] row
3.每個關鍵字的意義:(按照執行順序來排列)
from:從哪個數據表中 檢索數據
where:對錶中所有數據 進行條件過濾,根據條件 過濾表中所有數據
group by:將where條件過濾過濾出來的數據進行分組查詢
having:對group by已經分組好的數據 進行 條件過濾
select:通過where、group by、having等進行多重條件查詢後 得出查詢結果集,然後使用select獲取出查詢結果集中的某列數據
order by:按照升序/降序來對 “從結果集中取出的” 列數據 進行排序
limit [offset,] row:分頁每次取出部分數據
8.開啓事務/回滾事務:
1.指的是邏輯上的一組操作,組成這組操作的各個邏輯單元,要麼全都成功,要麼全都失敗。
回滾(Rollback)指的是程序或數據處理錯誤,將程序或數據恢復到上一次正確狀態的行爲。
2.事務的作用:從事務開啓之後 到 事務提交之前這一段時間裏面,如果程序出現異常錯誤等導致程序崩潰停止的話,
即使沒有手動回滾,事務開啓之後的全部操作也照樣不會提交到數據庫中執行保存;
也可以使用手動回滾 對出現的異常錯誤情況 進行處理回滾事務;
3.開啓事物:START TRANSACTION / BEGIN TRANSACTION
4.提交事務:COMMIT
5.回滾事物:ROLLBACK
6.delete 和 truncate 的區別:
1.delete 和 truncate 都爲刪除表中數據
2.delete from 表名:屬於DML(數據操作語句),逐條記錄刪除,事務可以作用在DML(數據操作語句)上,
意思即爲可通過 roolback; 命令語句 回滾之前的刪除操作,恢復被刪除的數據;
3.truncate table 表名:屬於DDL(數據定義語句),會先把表刪除了,然後重新創建一個結構一樣的空的表,
事務無法作用在DDL(數據操作語句)上,意思即爲無法通過 roolback; 命令語句 進行回滾
之前的刪除操作,無法恢復被刪除的數據;
3.數據庫、存儲引擎:
1.數據庫對象:存儲,管理和使用數據的不同結構形式,如:表、視圖、存儲過程、函數、觸發器、事件、索引等。
2.數據庫:存儲數據庫對象的容器。
3.數據庫分兩種:
1.系統數據庫(系統自帶的數據庫):不能修改
information_schema:存儲數據庫對象信息,如:用戶表信息,列信息,權限,字符,分區等信息。
performance_schema:存儲數據庫服務器性能參數信息。
mysql:存儲數據庫用戶權限信息。
2.用戶數據庫(用戶自定義的數據庫):一般的,一個項目一個用戶數據庫。
4.MySQL的存儲引擎:
1.MySQL中的數據用各種不同的技術存儲在文件(或者內存)中。這些技術中的每一種技術都使用不同的存儲機制、索引技巧、
鎖定水平並且最終提供不同的功能和能力。
通過選擇不同的技術,你能夠獲得額外的速度或者功能,從而改善你的應用的整體功能。
2.MyISAM:擁有較高的插入,查詢速度,但不支持事務,不支持外鍵。
3.InnoDB:支持事務,支持外鍵,支持行級鎖定,性能較低。
InnoDB 存儲引擎提供了具有提交、回滾和崩潰恢復能力的事務安全。
但對比MyISAM,處理效率差,且會佔用更多的磁盤空間以保留數據和索引。
4.數據庫對象:
1.數據庫對象:包括 表、索引、視圖、圖表、缺省值、規則、觸發器、語法、函數等。
2.數據庫對象名稱必須以字母開頭
3.有效的字符包括數字、字母和三個特殊字符(# _ $)
4.不要使用保留字作爲數據庫對象名稱
5.同一用戶下的數據庫對象不能同名,即使是不同的對象類型
5.索引:
1.索引爲 一個數據庫對象,用來加速對錶的查詢,通過使用快速路徑訪問方法快速定位數據,減少了磁盤的I/O ;
索引 與 表獨立存放,由數據庫自動維護;
2.創建索引:
自動創建索引:當在表上定義一個PRIMARY KEY時,自動創建一個對應的唯一索引;
當在表上定義一個外鍵時,自動創建一個普通索引;
手動創建索引:用戶可以創建索引以加速查詢;可以在一列或者多列上創建索引;
3.創建索引語法:CREATE INDEX 索引名 ON table (column[, column]...);
4.複合索引:多列在一起作爲一個索引,就叫做複合索引;
在很多情況下,複合索引比單個索引更好(理解原理即可);
5.哪些值可以創建索引?
1.外鍵一般要創建索引
2.經常使用的查詢條件要創建索引。如果使用like ‘%’操作,不會使用索引。
3.索引不是越多越好
4.不要在可選值很少的屬性上面創建索引
5.MySQL索引的使用,並不是所有情況下都會使用索引,只有當MySQL認爲索引足夠能夠提升查詢性能時纔會使用;
6.視圖:
1.視圖也就是虛表,實際上視圖就是一個命名的查詢,用於改變基表數據的顯示。
2.視圖的作用:
1.可以限制對數據的訪問
2.可以使複雜的查詢變的簡單
3.提供了數據的獨立性
4.提供了對相同數據的不同顯示
3.語法:
在CREATE VIEW語句後加入子查詢:
CREATE [OR REPLACE] VIEW view
[(alias[, alias]...)]
AS subquery
[WITH READ ONLY];
4.創建視圖:
CREATE OR REPLACE VIEW 視圖名emp_v_30
AS SELECT empno, ename, sal
FROM emp
WHERE deptno =30;
CREATE VIEW 視圖名sal_v_10
AS SELECT employee_id ID, last_name NAME, salary*12 ANN_SALARY
FROM employees
WHERE department_id = 10;
5.使用視圖:
在查詢時,不需要再寫完全的Select查詢語句,只需要簡單的寫上從視圖中查詢的語句就可以了;
例如:SELECT * FROM 視圖名sal_v_10;
默認情況下,可以直接通過對視圖的DML操作去修改視圖對應表中的內容(前提是視圖中沒有通過公式導出的列);
6.刪除視圖:
刪掉視圖不會導致數據的丟失,因爲視圖是基於數據庫的表之上的一個查詢定義.
例如:DROP VIEW 視圖名view_name;
安裝、卸載MySQL
MySQL的安裝
1.這兩個路徑是可以改的,但是需要記住他的位置
MySQL Server mysql服務器的安裝位置
Server data files 數據存放的位置
2.勾選standard configuration(手動配置)my服務器
3.standard Charater 默認的不支持中文 需要 選擇第3個選擇 手動選擇 UTF-8
4.Include BIn directory Windows Path 一定要勾選 否則用不了命令行
5.modify security setting 輸入mysql最高管理員 root密碼
6.驗證是否安裝成功:打開命令行 輸入 mysql -u root -p 輸入密碼 顯示 welcom to the MySQL
存儲引擎選用第一個(Multifunction DataBase):多功能存儲引擎,支持多種存儲引擎;
1.InnoDB:支持事務,支持外鍵,但是性能相對較低,開發中;
2.MyISAM:不支持事務,不支持外鍵,但是性能相對較高;
數據庫安裝常見錯誤
1.安裝時忘了勾選 Include BIn directory Windows Path:
在登入MySQL服務器的時候不能直接輸入mysql登入命令,
因爲我們沒有把MySQl的bin目錄添加到系統的環境變量裏面。
每次輸入”cd F:\Program Files\MySQL\MySQL Server 5.7\bin“才能使用登入,
這樣顯得比較麻煩,下面就介紹怎樣手動配置Path變量。
1. 打開左面右擊【我的電腦】圖標,在彈出的快捷菜單中選擇【屬性命令】。
2. 選擇【高級系統設置】,彈出對話框,選擇【環境變量】
3. 單擊【環境變量】按鈕,打開【環境變量】對話框,在系統變量列表中選擇【Path】變量
4.單擊【編輯】按鈕,在編輯系統變量對話框中,將MySQL的bin目錄添加到變量值中,用分號將其與其它路徑分隔開
5.添加完成後,單擊【確定】按鈕,這樣就完成了配置Path變量的路徑,然後就可以直接輸入mysql命令來登入數據庫了
2.數據庫安裝1045錯誤:
提示: 1045 access denied for user 'root'@'localhost' using password yes錯誤
解決:
1. 開始 --> cmd --> net stop mysql (停用MySQL服務 沒啓動的可以省略)
2. 找到安裝路徑 MySQL Server 5.1下的my.ini
3. 打開 my.ini 找到 [mysqld] 然後在下面加上
這句: skip_grant_tables (意思好像是 啓動MySQL服務的時候跳過權限表認證 )
4. 然後就啓動數據庫修改密碼了
開始 --> cmd --> net start mysql (啓動MySQL服務)---> mysql 回車 ( 如果成功,將出現MySQL提示符)
5. 輸入use mysql; (連接權限數據庫)。
6. 改密碼:update user set password=password("123") where user="root";(別忘了最後加分號) 。
7. 刷新權限(必須步驟):flush privileges; 。
8. 退出 quit。
9. 將第3 步的 my.ini裏的 skip_grant_tables 去掉(啓動MySQL服務的時候不能讓他跳過權限表認證 )
10. 重啓MySQL ,再進入,使用用戶名root和剛纔設置的新密碼123就可以登錄了。
3.數據庫安裝2503錯誤:
方法一:
1、按WIN+R,在運行框中輸入“gpedit.msc” 確認;
2、打開本地策略組編輯器後依次展開 :“計算機配置”-》“管理模板”-》“windows組件”-》“windows installer”,
並找到“始終以提升的權限進行安裝”;
3、雙擊該選項,設置爲“已啓用”,並應用;
4、最後我們還要在【用戶配置】中進行同樣的操作;
5、就可以安裝了。
方法二:
1、鼠標移到桌面左下角->右鍵(或者直接: WIN+X鍵),命令提示符(管理員);
2、輸入:msiexec /package +‘msi文件路徑’(輸入的時候注意半角字符且路徑不能爲中文名)
方法三:
先執行 方法一,再執行方法二
注意:gpedit.msc 這個命令(針對win10 家庭版)可能找不到,需要升級系統到專業版,不然安裝不成功
concat() 和 group_concat()
一、CONCAT()函數
CONCAT()函數用於將多個字符串連接成一個字符串。
使用數據表Info作爲示例,其中SELECT id,name FROM info LIMIT 1;的返回結果爲
+----+--------+
| id | name |
+----+--------+
| 1 | BioCyc |
+----+--------+
1、語法及使用特點:
CONCAT(str1,str2,…)
返回結果爲連接參數產生的字符串。如有任何一個參數爲NULL ,則返回值爲 NULL。可以有一個或多個參數。
2、使用示例:
SELECT CONCAT(id, ‘,’, name) AS con FROM info LIMIT 1;返回結果爲
+----------+
| con |
+----------+
| 1,BioCyc |
+----------+
SELECT CONCAT(‘My’, NULL, ‘QL’);返回結果爲
+--------------------------+
| CONCAT('My', NULL, 'QL') |
+--------------------------+
| NULL |
+--------------------------+
3、如何指定參數之間的分隔符
使用函數CONCAT_WS()。使用語法爲:CONCAT_WS(separator,str1,str2,…)
CONCAT_WS() 代表 CONCAT With Separator ,是CONCAT()的特殊形式。第一個參數是其它參數的分隔符。分隔符的位置放在要連接的兩個字符串之間。分隔符可以是一個字符串,也可以是其它參數。如果分隔符爲 NULL,則結果爲 NULL。函數會忽略任何分隔符參數後的 NULL 值。但是CONCAT_WS()不會忽略任何空字符串。 (然而會忽略所有的 NULL)。
如SELECT CONCAT_WS('_',id,name) AS con_ws FROM info LIMIT 1;返回結果爲
+----------+
| con_ws |
+----------+
| 1_BioCyc |
+----------+
SELECT CONCAT_WS(',','First name',NULL,'Last Name');返回結果爲
+----------------------------------------------+
| CONCAT_WS(',','First name',NULL,'Last Name') |
+----------------------------------------------+
| First name,Last Name |
+----------------------------------------------+
二、GROUP_CONCAT()函數
GROUP_CONCAT函數返回一個字符串結果,該結果由分組中的值連接組合而成。
使用表info作爲示例,其中語句SELECT locus,id,journal FROM info WHERE locus IN('AB086827','AF040764');的返回結果爲
+----------+----+--------------------------+
| locus | id | journal |
+----------+----+--------------------------+
| AB086827 | 1 | Unpublished |
| AB086827 | 2 | Submitted (20-JUN-2002) |
| AF040764 | 23 | Unpublished |
| AF040764 | 24 | Submitted (31-DEC-1997) |
+----------+----+--------------------------+
1、使用語法及特點:
GROUP_CONCAT([DISTINCT] expr [,expr ...]
[ORDER BY {unsigned_integer | col_name | formula} [ASC | DESC] [,col ...]]
[SEPARATOR str_val])
在 MySQL 中,你可以得到表達式結合體的連結值。通過使用 DISTINCT 可以排除重複值。如果希望對結果中的值進行排序,可以使用 ORDER BY 子句。
SEPARATOR 是一個字符串值,它被用於插入到結果值中。缺省爲一個逗號 (","),可以通過指定 SEPARATOR "" 完全地移除這個分隔符。
可以通過變量 group_concat_max_len 設置一個最大的長度。在運行時執行的句法如下: SET [SESSION | GLOBAL] group_concat_max_len = unsigned_integer;
如果最大長度被設置,結果值被剪切到這個最大長度。如果分組的字符過長,可以對系統參數進行設置:SET @@global.group_concat_max_len=40000;
2、使用示例:
語句 SELECT locus,GROUP_CONCAT(id) FROM info WHERE locus IN('AB086827','AF040764') GROUP BY locus; 的返回結果爲
+----------+------------------+
| locus | GROUP_CONCAT(id) |
+----------+------------------+
| AB086827 | 1,2 |
| AF040764 | 23,24 |
+----------+------------------+
語句 SELECT locus,GROUP_CONCAT(distinct id ORDER BY id DESC SEPARATOR '_') FROM info WHERE locus IN('AB086827','AF040764') GROUP BY locus;的返回結果爲
+----------+----------------------------------------------------------+
| locus | GROUP_CONCAT(distinct id ORDER BY id DESC SEPARATOR '_') |
+----------+----------------------------------------------------------+
| AB086827 | 2_1 |
| AF040764 | 24_23 |
+----------+----------------------------------------------------------+
語句SELECT locus,GROUP_CONCAT(concat_ws(', ',id,journal) ORDER BY id DESC SEPARATOR '. ') FROM info WHERE locus IN('AB086827','AF040764') GROUP BY locus;的返回結果爲
+----------+--------------------------------------------------------------------------+
| locus | GROUP_CONCAT(concat_ws(', ',id,journal) ORDER BY id DESC SEPARATOR '. ') |
+----------+--------------------------------------------------------------------------+
| AB086827 | 2, Submitted (20-JUN-2002). 1, Unpublished |
| AF040764 | 24, Submitted (31-DEC-1997) . 23, Unpublished |
+----------+--------------------------------------------------------------------------+
1.允許對數據庫進行指定IP的遠程訪問連接:
1.問題:無法對數據庫進行指定IP的遠程連接,只能使用localhost進行連接數據庫
2.解決方法一:
1.在系統自帶的 叫做mysql名稱的數據庫下的 user表,把host字段的值localhost 修改爲 %,意思即 允許任何IP地址訪問
2.重啓MySQL服務
3.解決方法二:修改root用戶的登錄權限,允許任何IP地址訪問
1.可以使用mysql -uroot -p密碼進入mysql數據庫的情況下:
mysql> use mysql
mysql> update user set host = '%' where user = 'root';
mysql> flush privileges
然後重新啓動mysql服務就可以了
(在管理員模式下的命令提示符窗口中 先執行 net stop mysql,然後執行 net start mysql)
2.不能使用mysql -uroot -p密碼進入mysql數據庫的情況下:
需要先停止mysql服務,這裏分兩種情況,一種可以用service mysqld stop,另外一種是/etc/init.d/mysqld stop
當提示mysql已停止後進行下一步操作
在終端命令行輸入:mysqld_safe --skip-grant-tables &
(其中 –skip-grant-tables 的意思是跳過授權表,通過此參數來跳過輸入密碼,後面跟得 & 符號是表示設置)
輸入:mysql,也可以回車之後在輸入命令: mysql (登錄mysql系統)
進入 mysql數據庫,然後通過語句修改密碼:
mysql> use mysql
mysql> update user set host = '%' where user = 'root';
mysql> flush privileges
mysql> exit;
然後重新啓動mysql服務就可以了
(在管理員模式下的命令提示符窗口中 先執行 net stop mysql,然後執行 net start mysql)
2.外鍵:
1.多表約束:外鍵約束,用於多表之間保證數據的完整性
2.外鍵:指向另外一張表的主鍵,外鍵的值一般也不能爲空,外鍵的值應爲 not null 非空約束;
外鍵之所以要關聯主鍵,因爲主鍵是唯一併且非空的,根據主鍵就能確定一條唯一的記錄;
主表:被引入外鍵的表;
從表:引入外鍵的表;
注意:在MySQL中,存儲引擎InnoDB才支持事務和外鍵,因此需要保證存儲引擎爲InnoDB;
修改表的存儲引擎爲InnDB:ALTER TABLE 表名 ENGINE='InnoDB';
3.添加外鍵約束的寫法:
例子:
1.A表 通過外鍵關聯 B表的主鍵:alter table A表 add foreign key(外鍵字段名) references B表(主鍵字段名)
不創建外鍵約束名的話,底層會自動創建一個外鍵約束名,也可以自定義一個任意名字的外鍵約束名
2.修改外鍵爲not null 非空約束:alter table A表 modify 外鍵字段名 int not null
3.一對一關係、一對多關係、多對多關係:
1.一對一關係:一般會把兩張表合併爲一張表,需要情況下才會分拆爲兩張表的一對一關係;
1.第一種創建方式:唯一外鍵對應
兩張表中 其中一張表 設置外鍵,關聯指向另外一張表的主鍵,並且該外鍵必須設置爲 unique 唯一約束
2.第二種創建方式:主鍵對應
不需要創建外鍵,兩張表各自的主鍵 對應 對方的 主鍵,那麼要求 雙方的主鍵值 一一對應並且主鍵值相同
3.一對一關係的優點和用處:
可用於數據庫的優化:分表;
在一張表中,把不常用的字段分離出來放到另外一張表中,此時這兩張表就是一對一的關係;
可以達到減少正常查詢時的數據負擔,提高效率;
2.一對多關係:在多的一方的表中 創建外鍵字段 指向 一的一方的表中的 主鍵字段
3.多對多關係:應使用 中間表(第三張表) 來存儲指向 多對多的兩張表的主鍵字段,中間表中會創建兩個字段均作爲外鍵,
兩個外鍵分別指向 多對多的兩張表各自的主鍵字段;
4.多表查詢之連接查詢:交叉連接、外連接、內連接、自關聯(自連接)、union、union all
1.多表查詢,如果沒有連接條件,則會產生笛卡爾積:
數學中定義:假設集合A={a,b},集合B={0,1,2},則兩個集合的笛卡爾積爲{(a,0),(a,1),(a,2),(b,0),(b,1),(b,2)}。
實際運行環境下,應避免使用全笛卡爾集。
2.連接條件:
在 on / where 子句中 寫入連接條件。
當多個表中有重名列時,必須在列的名字前加上表名作爲前綴/或使用表的別名爲前綴。
等值連接是連接操作中最常見的一種,通常是在存在主外鍵約束條件的多表上建立的,連接條件中的兩個字段通過等號建立等值關係。
使用表的別名簡化了查詢,提高了查詢的性能。
連接 n張表,至少需要 n-1個連接條件。
2.交叉連接:查詢到的結果集數據是帶有笛卡爾積,因爲沒有使用連接條件進行關聯再進行條件查詢,所以纔會出現笛卡爾積的結果集數據
1.select * from 表1 cross join 表2
2.select * from 表1, 表2
3.外連接:
1.左外連接:left outer join ... on ... (outer 可以省略)
1.查的是左邊表的全部和兩張表的交集;
查詢出JOIN左邊表的全部數據查詢出來,JOIN右邊的表不匹配的數據使用NULL來填充數據;
2.select * from 表1 left outer join 表2 on 連接條件
首先獲取左邊表的全部數據,以左邊表爲標準,獲取兩張表的共有(交集)的數據;
如果左邊表中的 某數據沒有對應的 右表數據的話,那麼以NULL代替顯示爲 “左邊表中該數據對應的” 右表數據
2.右外連接:right outer join ... on ... (outer 可以省略)
1.查的是右邊表的全部和兩張表的交集;
查詢出JOIN右邊表的全部數據查詢出來,JOIN左邊的表不匹配的數據使用NULL來填充數據;
2.select * from 表1 right outer join 表2 on 連接條件
首先獲取右邊表的全部數據,以右邊表爲標準,獲取兩張表的共有(交集)的數據;
如果右邊表中的 某數據沒有對應的 左表數據的話,那麼以NULL代替顯示爲 “右邊表中該數據對應的” 左表數據
4.內連接:
內連接只獲取出兩張表的共有(交集)的數據,也即查的是兩張表的交集 ;
連接條件:表1.字段名1 = 表2.字段名2;
顯式內連接 和 隱式內連接 查詢出的結果都是一樣的,僅是寫法不一樣;
1.顯式內連接:使用了 inner join ... on ... (inner 可以省略)
select * from 表1 inner join 表2 on 連接條件
注意:
1.ON table1.name = table1.name 相當於 USING(name)
2.例子:
SELECT e.empno, e.ename, d.dname FROM emp e JOIN dept d ON e.deptno = d.deptno
SELECT e.empno, e.ename, d.dname FROM emp e JOIN dept d USING(deptno)
2.隱式內連接:沒有使用 inner join ... on ...,而是改爲使用 where
select * from 表1, 表2 where 連接條件
5.自關聯(自連接):(自關聯(自連接) 可以使用 內連接 / 左外連接 / 右外連接)
select parent.字段, son.字段 from table1 as parent inner join table1 as son on parent.id = son.parent_id
select parent.字段, son.字段 from table1 as parent right outer join table1 as son on parent.id = son.parent_id
select parent.字段, son.字段 from table1 as parent left outer join join table1 as son on parent.id = son.parent_id
把多張表 的數據放到同一張表中,可以使用 自關聯;
下面的需求都可以用到 自關聯:
1.把 省表、市表、區表 都放到同一張表中:
省數據的parent_id爲NULL,而表示市數據的parent_id等於表示省數據的id,以此類推。
2.把 一級菜單、二級菜單、三級菜單 都放到同一張表中;
一級菜單 的parent_id爲NULL,而二級菜單的parent_id 等於 一級菜單的id,以此類推。
3.需求:查詢員工名稱和其對應經理的名稱
SELECT e.empno, e.ename, m.ename FROM emp e LEFT JOIN emp m ON e.mgr = m.empno;
6.UNION / UNION ALL:
1.UNION / UNION ALL:
JOIN是用於把表橫向連接,UNION/UNION ALL是用於把表縱向連接(一般用於做查詢的臨時表)
UNION 操作符用於合併兩個或多個 SELECT 語句的結果集。
2.使用注意:
1.UNION 內部的 SELECT 語句必須擁有相同數量的列。
2.列也必須擁有兼容的數據類型。
3.每條 SELECT 語句中的列的順序必須相同。
4.UNION 結果集中的列名總是等於 UNION 中第一個 SELECT 語句中的列名
5.UNION 操作符選取不同的值。如果允許重複的值,請使用 UNION ALL(性能高)
3.語法:
SELECT column_name(s) FROM table_name1
UNION|UNION ALL
SELECT column_name(s) FROM table_name2
4.在MYSQL 中實現FULL JOIN全連接,MYSQL中暫時不支持全連接,可以使用 “union + 左外連接 和 右外連接” 來完成 全連接的效果;
例子:查詢員工的編號,名稱和部門名稱
SELECT empno,ename,dname FROM emp LEFT JOIN dept USING (deptno)
UNION
SELECT empno,ename,dname FROM emp RIGHT JOIN dept USING (deptno)
上面的寫法 等同於 下面的寫法:ON table1.name = table1.name 相當於 USING(name)
SELECT empno,ename,dname FROM emp LEFT JOIN dept ON emp.deptno= dept.deptno
UNION
SELECT empno,ename,dname FROM emp RIGHT JOIN dept ON emp.deptno= dept.deptno
5.多表查詢之子查詢:
1.子查詢的意思:
一條sql語句的查詢結果 作爲 另外一條sql語句 中的查詢條件,也即一個查詢語句條件需要依賴另一個查詢語句的結果;
子查詢指的就是在一個查詢之中嵌套了其他的若干查詢,在使用select語句查詢數據時,有時候會遇到這樣的情況,
在where查詢條件中的限制條件不是一個確定的值,而是一個來自於另一個查詢的結果。
2.子查詢的用法:
1.子查詢一般出現在FROM/JOIN子句中 或 WHERE子句中,即子查詢 可以作爲表數據 使用在 from / join後面,
或子查詢作爲 條件查詢數據 使用在where 後面;
2.使用子查詢的注意事項:
1.子查詢要用括號括起來
2.將子查詢放在比較運算符的右邊(增強可讀性)
3.對單行子查詢使用單行運算符
4.對多行子查詢使用多行運算符
3.子查詢的分類,根據子查詢的結果分爲以下情況:
1.單行單列的 子查詢 結果數據:只包含一個字段的查詢,返回的查詢結果也只包含一行數據, 看做是一個值,使用在WHERE之後
2.多行單列的 子查詢 結果數據:只包含了一個字段,返回多行查詢結果數據,看做是多個值,使用在WHERE之後
3.單行多列的 / 多行多列的 子查詢 結果數據:
包含多個字段的返回,返回的查詢結果數據可能是單行或者多行,看做是臨時表,使用在FROM/JOIN之後
4.單行單列的 子查詢 結果數據:
1.子查詢返回一行一列記錄,看做是一個值,使用在WHERE之後;
2.使用單行記錄比較運算符:=;>;>=;<;<=;<>
3.例子:
查詢大於公司平均工資的員工姓名
SELECT ename,sal FROM emp WHERE sal >(SELECT AVG(sal) FROM emp)
查詢出工資比MARTIN還要高的全部僱員信息
SELECT * FROM emp WHERE sal > (SELECT sal FROM emp WHERE ename = 'MARTIN')
5.多行單列的 子查詢 結果數據:
1.返回多行查詢結果數據,看做是多個值
2.使用多行比較運算符
1.IN:與列表中的任意一個值相等 ;where 字段名 IN (子查詢SQL)
2. ANY:與子查詢返回的任意一個值比較
1.where 字段名 = ANY:此時和IN操作符相同
2.where 字段名 > ANY:大於子查詢中最小的數據
3.where 字段名 < ANY:大於子查詢中最大的數據
3.ALL:與子查詢返回的每一個值比較
1.where 字段名 > ALL:大於子查詢中最大的數據
2.where 字段名 < ALL:小於子查詢中最小的數據
4.帶 in 的 子查詢:
select * from 表1 where 字段名1 in (select 查詢出 多個字段值)
例子:
select * from Class where id in (select 外鍵class_id from Student where ......)
獲取出Student表中多個 “關聯Class表id的” 外鍵class_id,
然後範圍查詢 “Class表的id in 外鍵class_id” 獲取出 多行Class表數據;
5.帶 any 的 子查詢:
select * from Class where id > any (select 查詢出 多個字段值):大於任意一個值,即大於最小值
表示只要Class 表中的id 大於 子查詢中多個值中的 任意一個值,那麼便成立,便可查詢出對應的數據;
也即只要Class 表中的id 大於 子查詢中多個值中的 最小值,那麼便成立,便可查詢出對應的數據;
6.帶 all 的 子查詢:
select * from Class where id > all (select 查詢出 多個字段值):大於全部多個值,即大於最大值
表示只要Class 表中的id 大於 子查詢中全部的多個值,那麼便成立,便可查詢出對應的數據;
也即只要Class 表中的id 大於 子查詢中多個值中的最大值,那麼便成立,便可查詢出對應的數據;
6.單行多列的 / 多行多列的 子查詢 結果數據:
1.一般會把 單行多列的 / 多行多列的 子查詢 結果數據 當成一個臨時表,一般用在FROM/JOIN子句後面,
接着在臨時表上繼續查詢或者連接查詢;
注意:單行多列的 / 多行多列的 子查詢 結果數據 必須要設置一個臨時表名;
2.例子:查詢出每個部門的編號、部門名稱、部門人數、部門平均工資:
1.可以先把每一個部門的編號、部門總人數、部門平均工資先查詢出來:
SELECT deptno dno,COUNT(empno) count ,AVG(sal) avg FROM emp GROUP BY dno
2.再和dept表聯合查詢部門名稱:
SELECT dept.deptno,temp.count,temp.avg FROM dept JOIN
(SELECT deptno dno,COUNT(empno) count ,AVG(sal) avg FROM emp GROUP BY dno) temp
ON dept.deptno = temp.dno
7.帶 exists 的 子查詢:
1.select * from Class where exists (select 是否查詢出數據)
只要子查詢的sql語句查詢出數據,那麼exists就判斷爲true,那麼就執行 子查詢外的sql語句;
如果子查詢的sql語句查詢不出任何數據的話,那麼exists就判斷爲false,那麼就不會執行 子查詢外的sql語句。
2.select * from Class where ...... and / or exists (select 是否查詢出數據) group by ......
使用and:當exists 爲true(子查詢select 查詢出數據) 時,纔會執行 子查詢外的sql語句;
使用or:不管exists 是否爲true,即不管子查詢select 是否查詢出數據,只要or前面的條件爲true,那麼都會執行 子查詢外的sql語句;
8.注意事項:
1.可以多表更新:(sqlserver不允許多表更新)
1.UPDATE table1, table2 SET columnName = value [, column = value] … [WHERE condition]
2.UPDATE table1, (select ... from ...) 別名 SET columnName = value [, column = value] … [WHERE condition]
“select ... from ...”可以作爲臨時表,使用上別名
2.(mysql是不允許)update更新的表,不能用於 set子句 或 where子句的 子查詢中,
即子查詢中用到的表 不能和 update更新的表 是一樣;
6.事務:
1.數據庫的事務併發問題:
1.存在五種問題:髒讀、不可重複讀、幻讀、第一類丟失更新、第二類丟失更新。
爲了解決上述的問題,我們提出了隔離級別的概念,不同的隔離級別可以處理的併發問題是不一樣的;
使用不同的隔離級別就可以阻止自己所期望的併發問題;
2.使用鎖機制來解決事務併發問題:
1.悲觀鎖:SELECT ....... FOR UPDATE;
2.樂觀鎖:使用版本控制
2.事務的 開啓、提交、回滾:
1.開啓事務:start transaction
2.提交事務:commit
3.回滾事務:rollback
4.MySQL的事務一旦提交之後是無法回滾的,而Oracle的事務在提交之後都還是可以回滾的,
因爲Oracle提交的數據還會緩存一下後纔會保存到本地;
3.事務的 特點:原子性、一致性、隔離性、持久性
1.原子性:事務的不可分割,組成事務的各個邏輯單元不可分割
2.一致性:事務執行的前後,數據完整性保持一致
3.隔離性:事務執行不應該受到其他事務的干擾
4.持久性:事務一旦結束,數據就持久化到數據庫中
4.事務的隔離級別:
1.MySQL默認的隔離級別:repeatable read 避免 髒讀、不可重複讀,但是 虛讀 有可能發生
1.修改更新、讀取查詢 操作都上鎖了,因此在一個事務中 是無法讀取到 別的事務 修改並提交之後的 新數據,
所以叫做避免了 不可重複讀,即在一個事務中只能讀取到當前事務中(修改/提交之後)的數據,
是無法讀取到別的事務修改提交後的新數據,不同事務之間是完全隔離的;
2.即使修改更新、讀取查詢 操作都上鎖了,不同事務之間依然可以併發修改同一數據,當一個事務修改了同一數據並提交之後,
另一事務也接着也修改 同一數據並提交,最終該同一數據照樣可以被修改爲最新的更新值。
2.Oracle默認的隔離級別:read committed 避免 髒讀,但是 不可重複讀、虛讀是有可能發生
1.修改更新操作 上鎖了,但是讀取查詢操作沒有上鎖,因此在一個事務中 是可以讀取到 別的事務 修改並提交之後的 新數據,
所以叫做 沒有避免 不可重複讀,即在一個事務中可以讀取到別的事務中修改/提交之後 的數據,
因爲即使是不同事務之間的讀取查詢操作是沒有上鎖的,所以性能比較高;
2.即使修改更新上鎖了,讀取查詢操作沒有上鎖,不同事務之間依然可以併發修改同一數據,
當一個事務修改了同一數據並提交之後,另一事務也接着也修改 同一數據並提交,
最終該同一數據照樣可以被修改爲最新的更新值。
3.最高的隔離級別serializable(串行化):
串行化:多個事務排成隊列,排隊執行,每個事務逐一執行,一個事務執行結束了,才輪到下一個事務開始執行;
serializable 不允許併發,每個事務都只能按順序逐一執行,一個事務結束了才輪到下一個事務執行,因此效率也是最低;
比如說:有兩個客戶端 同時對同一張表 進行操作時 都開啓了事務,那麼客戶端A 正在操作(插入/修改)該表中的數據時,
而客戶端B 執行select查詢時 會一直阻塞等待 客戶端A 開啓的事務 提交數據之後,客戶端B 才能獲取到查詢數據;
也即說明事務不允許出現併發,客戶端B 需要等待客戶端A 的事務執行完成以後,纔會執行客戶端B 的事務,
當 客戶端A的事務結束(提交或者回滾),那麼客戶端B 馬上就會出現查詢數據結果。
4.隔離級別的 安全性從高到低,但是效率從低到高:serializable ----> repeatable read ----> read committed ----> read uncommitted
1.read uncommitted:髒讀、不可重複讀、虛讀 都有可能發生
2.read committed:避免 髒讀,但是 不可重複讀、虛讀是有可能發生
3.repeatable read:避免 髒讀、不可重複讀,但是 虛讀 有可能發生。
4.serializable:避免 髒讀、不可重複讀、虛讀。
5.查看當前的隔離級別:select @@tx_isolation
6.設置事務的隔離級別:set session transaction isolation level 隔離級別的英文名
set session transaction isolation level serializable/ repeatable read/read committed/read uncommitted
7.髒讀:一個事務 讀到 別的事務 沒有提交的數據;
不同之間的事務應該是完全隔離的,所以一個事務 不應該 讀到 別的事務 沒有提交的數據
8.不可重複讀:一個事務 讀到 別的事務 已經提交了的update的數據;
不同之間的事務應該是完全隔離的,所以一個事務 不應該 讀到 別的事務 已經提交了的update的數據;
在同一個事務中,多次的查詢結果都應是一致的;
9.虛讀/幻讀:一個事務 讀到 別的事務 已經提交了的insert的數據;
不同之間的事務應該是完全隔離的,所以一個事務 不應該 讀到 別的事務 已經提交了的insert的數據;
在同一個事務中,多次的查詢結果都應是一致的;
5.在數據庫中,所謂事務是指一組邏輯操作單元,使數據從一種狀態變換到另一種狀態。
1.爲確保數據庫中數據的一致性,數據的操縱應當是離散的成組的邏輯單元:
當它全部完成時,數據的一致性可以保持,而當這個單元中的一部分操作失敗,整個事務應全部視爲錯誤,
所有從起始點以後的操作應全部回退到開始狀態。
2.事務的操作:
先定義開始一個事務,然後對數據作修改操作,這時如果提交(COMMIT),這些修改就永久地保存下來,
如果回退(ROLLBACK),數據庫管理系統將放棄您所作的所有修改而回到開始事務時的狀態。
3.事務的ACID:
1. 原子性(Atomicity):原子性是指事務是一個不可分割的工作單位,事務中的操作要麼都發生,要麼都不發生。
2. 一致性(Consistency):事務必須使數據庫從一個一致性狀態變換到另外一個一致性狀態。(數據不被破壞)
3. 隔離性(Isolation):事務的隔離性是指一個事務的執行不能被其他事務干擾,
即一個事務內部的操作及使用的數據對併發的其他事務是隔離的,併發執行的各個事務之間不能互相干擾,
每一個事務都存在一個事務空間,彼此不干擾。
4. 持久性(Durability):持久性是指一個事務一旦被提交,它對數據庫中數據的改變就是永久性的,
接下來的其他操作和數據庫故障 不應該對其有任何影響。
4.事務控制的語言:
begin:開啓一個事務,開啓一個新的事務空間
commit:提交事務
rollback:回滾事務
5.COMMIT和 ROLLBACK可以顯示的控制事務。
好處:
1.保證數據一致性,修改過的數據在沒有提交之前是不能被其他用戶看到的。
2.在數據永久性生效前重新查看修改的數據
3.將相關操作組織在一起,一個事務中相關的數據改變或者都成功,或者都失敗。
7.重置MySQL的密碼:
1.第一步:停止MySQL的服務:命令行 sevices.msc 啓動服務界面 手動停止服務
2.第二步:在cmd下啓動MySQL服務:輸入 mysql --skip-grant-tables ,不需要權限認證的啓動
3.第三步:重新開啓cmd的命令行,然後登錄MySQL,不需要輸入密碼
4.第四步:修改root的密碼
use mysql;
update user set password = password('新密碼') where user = 'root';
5.第五步:結束mysqld的進程:執行 net stop mysql
6.第六步:重新啓動MySQL的服務:執行 net start mysql
8.數據庫的備份和還原:
1.數據庫的備份:
1.第一步:打開cmd的命令行窗口(一定要注意這個不是在mysql命令下,若命令位置不對,會報1064(42000)錯誤);
輸入 mysqldump -u root -p 數據庫名 > C:/數據庫名.sql (表和表裏面的信息反編譯成sql語句)
2.數據庫的還原:
2.第一種還原方式:
1.第一步:在數據庫服務器內部創建數據庫:create database 數據庫名;
2.第二步:在命令行窗口輸入mysql -u root -p 數據庫名 < C:/數據庫名.sql(一定要注意這個不是在mysql命令下)
3.第二種還原方式:
1.第一步:在數據庫服務器內部創建數據庫:create database 數據庫名;
2.第二步:切換到該數據庫使用,然後使用source命令還原數據庫數據
use 數據庫名;
source C:/數據庫名.sql;
等值連接:SELECT * FROM 表A INNER JOIN 表B ON 表A.字段名 = 表B.字段名
SELECT * FROM 表A FULL [OUTER] JOIN 表B ON 表A.字段名 = 表B.字段名
SELECT * FROM 表A LEFT [OUTER] JOIN 表B ON 表A.字段名 = 表B.字段名
SELECT * FROM 表A RIGHT [OUTER] JOIN 表B ON 表A.字段名 = 表B.字段名
SELECT * FROM 表A RIGHT [OUTER] JOIN 表B ON 表A.字段名 = 表B.字段名
SELECT * FROM 表A RIGHT [OUTER] JOIN 表B ON 表A.字段名 = 表B.字段名 WHERE 表A.字段名 IS NULL
UNION 與 UNION ALL
笛卡爾乘積:cross join