日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 运维知识 > 数据库 >内容正文

数据库

MySQL基础学习特殊篇 入门限定

發布時間:2023/12/10 数据库 32 豆豆
生活随笔 收集整理的這篇文章主要介紹了 MySQL基础学习特殊篇 入门限定 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

相信看了一會第十三章 MySQL數據庫的你一定一頭霧水把?太抽象了也沒有什么詳細的學習,根本無從下手,這篇特殊的文章照顧了一下零基礎的小伙伴,也是純實機演示。
本文章參照了 尚硅谷MySQL基礎學習視頻教學!
安裝數據庫的步驟還是非常簡單的,只要網速好去官方下載msi的安裝包既可。

安裝過程比較簡單,這邊設置不建議復雜,因為學習初期的階段。

安裝完畢后如何打開數據庫

#sql專用代碼欄 #打開數據庫的方法其實很多我們挑選一種常用既可 #首先先大概介紹一下登入的關鍵字 # mysql[數據庫] -u[用戶名] -h[主機名] -P[端口] -p[密碼] mysql -h localhost -u root -P 3306 -p #這里mysql指定了數據庫 #-h localhost 表示輸入主機名 localhost代表本地的意思 #-u root 代表用戶名 默認用戶名為 root #-P 3306 端口 端口默認為3306 #-p 密碼 輸入完回車會要求輸入密碼 Enter password:

我們看執行詳細流程。
首先按下電腦快捷鍵 win+R 調出運行并輸入 'cmd’打開命令提示符,顯示窗口后輸入:

mysql -h localhost -u root -P 3306 -p

回車后會要求輸入密碼,輸入完密碼看到如圖的內容代表成功進入數據庫。




MySQL常見命令

#顯示數據庫 show databases;

#打開/進入 指定的數據庫 use mysql;

#顯示當前數據庫所有的表 show table;


如果沒有表格會提示如下信息。

#實現不退出或不切換數據顯示其他數據庫表格 show tables from sys;

#顯示當前所在數據庫 select database();

上面的數據庫比如:

這些都是系統的數據庫并不推薦在里面做練習或者修改數據,所以我們通過如下代碼創建一個空的數據庫進行學習:

#這里的 'database'關鍵字大小寫效果一致 create DATABASE test; create database test;



#刪除數據庫 drop database test;


我們學習了打開數據庫、創建數據庫、顯示數據庫里的表格等基本指令,現在我們組合這些操作一口氣創建一個表。

#登入 mysql -h localhost -u root -P 3306 -p #顯示所有的數據庫 show databases; #打開指定的數據庫 use sys; #顯示當前數據庫的表 show tables; #顯示其它數據庫的表 show tables from mysql; #顯示當前所在的數據庫 select database(); #創建數據庫 create database test; create DATABASE testtow; #刪除指定的數據庫 #顯示所有數據庫觀察執行結果 show databases; #打開/進入 test數據庫 use test; #顯示當前所有表 show tables; #顯示當前所在數據庫 select database(); #創建表 create table stuinfo(#整形id int,#字符型name varchar(20));#這里的聲明其實和Java變量差不多 暫時這么理解 #顯示表結構 desc stuinfo;



這里就完成了一個最簡單的完整流程操作,繼續看基本指令的學習:

#創建一個表 create table stuinfo(id int,name varchar(20) ); #顯示表結構 desc stuinfo;


Field代表字段、Type代表類型,后面代表的是一些其他的約束,先不看這些。

#查看表數據 select * from stuinfo;


這里表現的為沒有數據的結果,因為只是創建了表的字段沒有賦值。

#插入數據 insert into stuinfo (id,name) values(1,'洛天依');


這時候我們再次使用顯示數據的指令來訪問數據。

可以看到如上的手動添加的內容。
通過小鍵盤的 上鍵 ↑來調用上次指令記憶,找到插入數據的代碼再次添加一條數據。

insert into stuinfo (id,name) values(2,'樂正綾');

不小心添加了重復的數據?看如下操作

#修改數據 update stuinfo set name = '樂正綾' where id = 2;


如果多添加了并且不想要的時候,通過如下代碼刪除:

#刪除指定數據 delete from stuinfo where id = 3;


查看客戶端的版本 #客戶端內查看 mysql>select version(); #客戶端外查看 #這里不用分號 因為是doc命令 C:\Users\YueDie>mysql --version #簡寫 C:\Users\YueDie>mysql -V


我們看客戶端外查看的效果:


MySQL常見命令總結

  • 查看當前所有數據庫
  • show databases;
  • 打開指定的庫
  • use 庫名
  • 查看當前庫的所有表
  • show tables;
  • 查看其它庫所有表
  • show tables from 庫名;
  • 創建表
  • create table 表名(列名 列類型,列名 列類型,... )
  • 查看表結構
  • desc 表名
  • 查看服務端版本
  • #方式一: #在服務端內 select version(); #方式二: #在服務端外 #注意在服務單外于是系統指令不用加分號 mysql --version #方式三: #在服務端外 mysql -V

    我們現在登入方式改為:

    mysql -u root -p

    MySQL的語法規范

    不分區大寫小,但建議關鍵字大寫,表名和列名小寫

    show databases; SHOW DATABASES;


    最好每條命令以分號結尾

    use test; select*from stuinfo; SELECT*FROM stuinfo\g


    每條命令根據需要,可以進行縮進或換行

    create table stuinfo(id int,name varchar(20));




    注釋

    第一種單行注釋:#注釋內容 第二種單行注釋:-- 注釋內容 多行注釋:/*注釋內容*/

    好,上面就是我們入門第十三章的小練習,也是作為基礎鋪墊的內容,接下來開始嘗試學習文章里的MySQL內容!

    創建表

    #注意這里test后面的一定是()圓括號不要是大括號 create table test(#整形通用inttest_id int,#小數點數test_price decimal,#普通長度文本,使用default 指定默認值test_name varchar(255) default 'xxx',#大文本類型test_desc text,#圖片test_img blob,test_date datetime);

    使用子查詢語句建表

    #語法: create table [模式名.]表名[column[,column...]] as subquery; #創建hehe數據表,該數據表和test完全相同,數據也完全相同 create table hehe as select*from test;

    修改表結構的語法

    alter table 表名 add(#可以有多個列定義column_name1 datatype [default expr],... );

    上面語法格式中的圓括號部分與建表語法的圓括號部分完全相同,只是此時圓括號里的列定義是追加到已有表的列定義后面。還有一點需要指出,如果只是新增一列,則可以省略圓括號,僅在add后緊跟一個列定義既可。為數據表增加字段的SQL語句如下:

    #為hehe數據表增加一個hehe_id字段,該字段的類型為int alter table hehe add hehe_id int; #這里也是對應了上面的:如果只是新增一列,則可以省略圓括號

    #這里如果是修改新增多列就不可以忽略圓括號 alter table hehe add(aaa varchar(255) default 'xxx',bbb varchar(255));

    上面第二條SQL語句增加aaa字段時,為該字段指定默認值為’xxx’,值得指出的是,SQL語句中的字符串值不是用雙引號引起的,而是用單引號引起的。

    修改列定義的語法

    alter table 表名 modify column_name datatype[default expr][first|after col_name];

    上面語法中first或者after col_name指定需要將目標修改到指定位置。
    修改前的hehe_id列

    代碼執行

    #將hehe表的hehe_id列修改成varchar(255)類型 alter table_hehe modify hehe_id varchar(255);

    修改bbb列前


    修改后

    alter table hehe modify bbb int;

    從上面代碼中不難看出,使用SQL修改數據表里列定義的語法和為數據表里增加一個列定義的語法幾乎完全一樣,關鍵是增加列定義所使用的add關鍵字,而修改列定義使用modify(修改)關鍵字(alter直譯為 改變)。還有一點需要指出,add新增的列名必須是源表表中不存在的,而modify修改的列名必須是原表中已存在的。
    MySQL的一個modify命令不支持修改多個列定義,其他數據庫支持,比如Oracle支持一個modify命令修改多個列,一個modify命令修改多個列定義的語法和一個add命令增加多個列定義的語法非常相似,也是需要使用圓括號將多個列定義括起來。如果需要修改多行列定義,只需要在alter table后使用多個modify命令即可。

    刪除列

    從數據表中刪除列的語法比較簡單。

    alter table 表名 drop column_name

    刪除列只要在drop后竟跟需要刪除的列名即可。例如:

    #刪除hehe表中的aaa字段 alter table hehe drop aaa;


    重命名數據表

    重命名數據表的語法格式如下:

    alter table 表名 rename to 新表名

    #將hehe數據表重命名為wawa: alter table hehe rename to wawa;

    MySQL為alter table提供了change選項,該選項可以改變列名。change選項的語法格式如下:

    alter table 表名 change old+column_name new_cloumn_name type[default expr] [first[after col_name]]

    通過對比不難發現 change和modify兩個選項:change選項比modify選項多了一個列名,因為change可以改變列名,所以它需要兩個列名。一般而言,如果不需要改變列名使用alter table 的 modify 選項即可,只有當需要修改列名時才會使用change選項。語句如下:

    #將wawa的bbb字段重命名為ddd alter table wawa change bbb ddd int; #關鍵字 舊字段名 新字段名 類型


    像這種不小心使用 insert into 插入了新數據的情況下就應該將其多余的內容刪除掉。
    通過如下操作刪除

    刪除表的語法

    刪除表的語法格式如下:

    drop table 表名;

    如下SQL語句將會把數據庫中已有的表刪除:

    #刪除數據表 drop table wawa;

    先看處理上面的語句

    #刪除數據表的數據 delete from wawa;


    試了實驗上面的drop語法 我們再次加入新的數據

    insert into

    現在我們試試上面的 drop table wawa;

    這里直接刪除了wawa數據表,而非刪除里面的數據列。

    關于drop和delete的區別

    上面的結果差距很大
    看例子
    delete : delete from 表名 where 條件
    delete選中指定表的內容刪除,刪除的是數據
    drop : alter table 表名 drop 字段 drop table 表
    drop刪除的是表
    相當于drop直接刪除了表,釋放了內存,所以drop速度大于delete,所以使用drop也一定要慎重,雖然可以恢復但是很麻煩,使用delete也一定要帶上where子句。
    刪除數據表的效果如下:

    • 表結構被刪除,表對象不再存在
    • 表里的所有數據也被刪除
    • 該表所有相關索引、約束也被刪除

    truncate表

    對于大部分數據庫而言,truncate都被當成DDL處理(和drop一列),truncate被稱為“截斷”某個表——它的作用是刪除該表里全部數據,但保留表結構,相對于DML里的delete命令而言,truncate的速度要快的多,而且truncate不像delete可以刪除指定的記錄,truncate只能一次性刪除整個表的全部記錄。
    truncate命令的語法如下:

    truncate 表名

    這里做實驗也很簡單,我們再次創建wawa表

    #這里起碼要在 test表里 show tables; use test; select database(); #這里表列我們就不搞那么復雜了 create table wawa(id int,name varchar(255)); desc wawa; #插入一列數據 insert into wawa (id,name) values(1,'洛天依'); select*from wawa; truncate wawa; show tables; desc wawa;



    MySQL對truncate的處理比較特殊——如果使用非InnoDB存儲機制,truncate比delete速度要快;如果使用InnoDB存儲機制,在MySQL5.0.3之前,truncate和delete完全一樣,在5.0.3之后,truncate table比delete效率高,但如果該表被建外約束所參照,truncate又變為delete操作。在5.0.13之后,快速truncate總是可用,即比delete性能要好。

    數據庫約束

    約束更好保證了數據表里數據的完整性。約束時在表上強行執行的數據校驗規則,約束主要還用于保證數據的完整性。除此之外,當表中數據存在互相依賴性時,可以保護相關的數據不被刪除。
    大部分數據庫支持下面5種完整性約束。

    • NOT NULL:非空約束,指定某列不能為空。
    • UNIQUE:唯一約束,指定某列或者幾列組合不能重復。
    • PRIMARY KEY:主鍵,指定該列的值可以唯一地標識該條記錄。
    • FOREIGN KEY:外鍵,指定該行記錄從屬于主表中的一條記錄,主要用于保證參照完整性。
    • CHECK:檢查,指定一個布爾表達施,用于指定對應列的值必須滿足該表達式。

    雖然大部分數據庫都支持上面5種約束,但MySQL不支持CHECK約束,雖然MySQL的SQL語句也可以使用CHECK約束,但這個CHECK約束不會有任何作用。
    雖然約束的作用只是保證數據表里數據的完整性,但約束也是數據庫對象,被存儲在系統表中,也擁有自己的名字。根據約束對數據列的限制,約束分為如下兩類。

    • 單列約束:每個約束只約束一列。
    • 多列約束:每個約束可以約束多個數據列。

    為數據表指定約束有如下兩個時機:

    • 建表的同時為相應的數據列指定約束。
    • 建表后創建,以修改表的方式來增加約束。
      大部分約束都可以采用列級約束語法或者表級約束語法。下面依次介紹5種約束的建立和刪除(約束通常無法修改)。
      MySQL使用information_schema數據庫里的TABLE_CONSTRAINTS表來保存該數據庫實例中所有的約束信息,用戶可以通過查詢TABLE_CONSTRAINTS來獲取該數據庫的約束信息。

    1.NOT NULL約束

    非口約束用于確保指定列不允許為空,非空約束是比較特殊的約束,它只能作為列級約束使用,只能使用列級約束語法定義。這里要介紹一下SQL中的null值,SQL的null不區分大小寫。SQL中的null具有如下特征。

    • 所有數據類型的值都可以是null,包括int、float、boolean等數據類型。
    • 與Java類似的是,空字符串不等于null,0也不等于null。

    如果需要在建表時為指定列指定非空約束,只要在列定義后面增加 not null即可。建表語句如下:

    #如果是跟著我的文章走的,那現在test表中肯定有個wawa,現在我們給它刪掉 #刪掉wawa表和test表 drop table test; drop table wawa; #使用函數來確定自己是否處于test數據庫 select database(); create table hehe(#建立了非空約束,這意味著hehe_id不可以為nulhehe_id int not null,#MySQL的非空約束不能指定名字hehe_name varchar(255) default 'xyz' not null,#下面可以為空,默認就是為空hehe_gender varchar(2) null);


    除此之外,也可以在使用alter table 修改表時增加或刪除非空約束,SQL命令如下:

    #增加非空約束 alter table hehe modify hehe_gender varchar(2) not null;

    #取消非空約束 alter table hehe modify hehe_name varchar(2) null;

    #取消非空約束,并指定默認值 alter table hehe modify hehe_name varchar(255) default 'abc' null;


    最終結果

    UNIQUE約束

    唯一約束用于保證指定列或指定列組合不允許出現重復值。雖然唯一約束的列不可以出現重復值,但可以出現多個null值(因為在數據庫中null不等于null)。
    一個表內可創建多個唯一約束,當為某列創建唯一約束時,MySQL會為該列相應的創建唯一索引,如果不給唯一索引起名,則該唯一約束默認與列名相同。
    當建立唯一約束時,MySQL在唯一約束所在列或列組合上建立對應的唯一索引。
    使用列級約束語法建立唯一約束非常簡單,只要簡單地在列定義后增加unique關鍵字即可。SQL語句如下:

    create table unique_test(#建立了非空約束,這意味著test_id不可以為nulltest_id int not null,#unique就是唯一索引,使用列級約束語法建立唯一索引test_name varchar(255) unique);

    如果需要為多列組合建立唯一約束,或者向自行指定約束名,則需要使用表級約束語法。表級約束語法格式如下:

    [constraint 約束名] 約束定義

    上面的表級約束語法格式既可以放在 create table 語句中與列定義并列,也可以放在 alter table 語句中使用 add關鍵字來添加約束。SQL語句如下:

    create table unique_test2(#建立了非空約束,這意味著test_id 不可以為nulltest_id int not null,test_name varchar(255),var_pass varchar(255),#使用表級約束語法建立唯一約束unique(test_name),#使用表級約束語法建立唯一約束,而且指定約束名constraint test2_uk unique(test_pass) );

    上面的建表語句為test_name、test_pass分別建立了唯一約束,這意味著這兩列都不能出現重復值。除此之外,還可以為這兩列組合建立唯一約束,SQL語句如下:

    @建表時創建唯一約束,使用表級約束語法建立約束 create table unique_test3(#建立了非空約束,這意味著test_id不可以為nulltest_id int not null,test_name varchar(255),test_pass varchar(255),#使用表級約束語法建立唯一約束,指定兩列組合不允許重復constraint test3_uk unique(test_name,test_pass) );

    對于上面的unique_test2和unique_test3兩個表,都是對test_name、test_pass建立唯一約束,其中unique_test2要求test_name、test_pass都不能出現重復值,而unique_test3只要求test_name、test_pass兩列值組合不能重復。
    也可以在修改表結構時使用add關鍵字來增加唯一約束,SQL語句?:

    #增加唯一約束 alter table unique_test3 add unique(test_name,test_pass);

    還可以在修改表時使用 modify關鍵字,為單列采用列級約束語法來增加唯一約束,代碼如下

    #為unique test3表的test_name增加唯一約束 alter table unique_test3 add unique(test_name,test_pass);

    對于大部分數據庫而言,刪除約束都是在alter table 語句后使用 "drop constraint 約束名"語法來完成的,但MySQL并不使用這種方式,而是使用 "drop index 約束名"的方式來刪除約束。例如如下SQL語句:

    #刪除unique_test3表上的test3_uk唯一約束 alter table unique_test3 drop index test3_uk;

    PRIMARY KEY約束

    主鍵約束相當于非空約束和唯一約束,即主鍵約束的列既不允許出現重復值,也不允許出現null值;如果對多列組合建立主鍵約束,則多列里包含的每一列都不能為空,但只要求這些列組合不能重復。主鍵列的值可用于唯一地標識表中的一條記錄。
    每一個表只允許有一個主鍵,但這個主鍵可以由多個數據列組合而成,主鍵是表中能唯一確定一行記錄的字段或字段組合,和唯一約束的語法相似,建立主鍵約束使用 primary key。

    練習結束就可以刪掉之前的數據庫了減少內存和礙眼。
    記得use數據庫哦。

    #列級語法 create table primary_test(#建立了主鍵約束test_id int primary key,test_name varchar(255));

    #表級語法 create table primary_test2 (test_id int not null,test_name varchar(255),test_pass varchar(255),#指定主鍵約束名為test2_pk,對大部分數據庫有效,但對MySQL無效#MySQL數據庫中該主鍵約束名依然是PRIMARYconstraint test2_pk primary key(test_id);

    其實這里也看到了,表級和列級從外觀來看的區別就像 表級定義像調用帶有參數的方法;而列級定義更像定義變量那樣字,在MySQL的變量定義是 名字在前 關鍵字在后 和Java是相反的。

    建表時創建主鍵約束,以多列建立組合主鍵,只能使用表級約束語法。

    create table primary_test3 (test_id varchar(255),test_pass varchar(255),#建立多列組合的主鍵約束primary key(test_name,test_pass) );


    如果需要刪除指定表的主鍵約束,則在alter table 語句后使用 drop primary key子句即可。SQL語句如下:

    #刪除主鍵約束


    這里不小心刪除了,少打了個3

    如果需要為指定表增加主鍵約束,既可通過modify修改列定義來增加主鍵約束,這將采用列級約束語法來增加主鍵約束;也可以通過add來增加主鍵約束,這將采用表級約束語法來增加主鍵約束。SQL語句如下:

    #使用表級約束語法來增加主鍵約束 alter table primary_test3 add primary key(test_name,test_pass);


    如果只是為單獨的數據列增加主鍵約束,則可使用modify修改列定義來實現。SQL語句如下:
    注意,如果報錯了,原因大概率是字母打錯和重復添加主鍵看下面示意圖



    #使用列級約束語法來增加主鍵約束 alter table primary_test3 modify test_name varchar(255) primary key;

    這里因為上面誤刪了 primary_test的test_id的主鍵約束可以補回來

    不要連續執行上面兩條SQL語句,因為上面兩條SQL語句都是為primary_test3增加主鍵約束,而同一個表里最多只能有一個主鍵約束,所以連續執行上面兩條SQL語句肯定出現錯誤。為了避免這個問題,可以在成功執行了第一條增加主鍵約束的SQL語句之后,先將primary_test3里的主鍵約束刪除后再執行第二條增加主鍵約束的SQL語句。
    很多數據庫對主鍵列都支持一種自增長的特性——如果某個數據列的類型是整形,而且該列作為主鍵列,則可指定該列具有自增長功能。指定自增長功能通常用于設置邏輯主鍵列——該列的值沒有任何物理意義,僅僅用于標識每行記錄。MySQL使用auto_increment來設置自增長,SQL語句如下:
    SQL最后的一行不用 , 直接以)結尾即可


    一旦指定了某列具有自增長特性,則向該表插入記錄時不可為該列指定值,該列的值由數據庫系統自動生成。

    FOREIGN KEY 約束

    外鍵約束主要用于保證一個或兩個數據表之間的參照完整性,外鍵是構建與一個表的兩個字段或者兩個表的兩個字段之間的參照關系。外鍵確保了相關的兩個字段的參照關系:子(從)表外鍵列的值必須在主表被參照列的值范圍之內,或者為空(也可以通過非空約束來約束外鍵列不允許為空)。
    當刪除主表記錄時不允許直接刪除,而是需要刪除從表里參照該記錄的所有記錄,全部刪除后才可以刪除主表的該記錄。或者刪除主表記錄時級聯從表中的所有參照該記表的從表記錄。

    #為了保證從表參照的主表存在,通常應該先建主表 create table teacher_table(#auto_increment:代表數據庫的自動編號策略,通常用作數據表的邏輯主鍵teacher_id int auto_increment,teacher_name varchar(255),primary key(teacher_id));

    create table student_table(#為本表建立主鍵約束student_id int auto_increment primary key,student_name varchar(255),#指定java_teacher 參照到teacher_table的teacher_id列java_teacher int references teacher_table(teacher_id) );

    值得指出的是,雖然MySQL支持使用列級約束語法來建立外鍵約束,但這種列級約束語法建立的外鍵約束不會生效,MySQL提供這種列級約束語法僅僅是為了和標準SQL保持良好的兼容性,因此,如果要使MySQL中的外鍵約束生效,則應使用表級約束語法。

    #為了保證從表參照的主表存在,通常應該先建主表 create table teacher_table1(#auto_increment:代表數據庫的自動編號策略,通常用作數據表的邏輯主鍵teacher_id int auto_increment,teacher_name varchar(255),primary key(teacher_id) );

    create table student_table1(#為本表建立主鍵約束student_id int auto_increment primary key,student_name varchar(255),#指定java_teacher參照到teacher_table1的teacher_id列java_teacher int,foreign key(java_teacher) references teacher_table1(teacher_id) );

    如果使用表級約束語法,則需要使用foregin key來指定本表的外鍵列,并使用references來指定參照哪個主表,以及參照到主表的哪個數據列。如果沒有創建約束名,則MySQL會為該外鍵約束命名為 table_name_ibfk_n,其中table_name是從表的表名,而n是從1開始的整數。
    如果需要顯式指定外鍵約束的名字,則可使用constraint來指定名字。SQL語句如下:

    #為了保證從表參照的主表存在,通常應該先建主表 create table teacher_table2(#auto_increment:代表數據庫的自動編號策略,通常用作數據表的邏輯主鍵teacher_id int auto_increment,teacher_name varchar(255),primary key(teacher_id) );

    create table student_table2(#為本表建立主鍵約束student_id int auto_increment primary key,student_name varchar(255),java_teacher int,#使用表級約束語法建立外鍵約束,指定外鍵約束的約束名為student_teacher_fkconstraint student_teacher_fk foreign key(java_teacher) references teacher_table2(teacher_id) );

    #為了保證從表參照的主表存在,通常應該先建立主表 create table teacher_table3(teacher_name varchar(255),teacher_pass varchar(255),#以兩列建立組合primary key(teacher_name,teacher_pass) );

    create table student_table3(#為本表建立主鍵約束student_id int auto_increment primary key,student_name varchar(255),java_teacher_name varchar(255),java_teacher_pass varchar(255),#使用表級約束語法建立外鍵約束,指定兩列的聯合外鍵foreign key(java_teacher_name,java_teacher_pass) references teacher_table3(teacher_name,teacher_pass) );

    刪除外鍵約束的語法很簡單,在alter table 后面增加“drop foreign key 約束名”子句即可。代碼如下:

    #刪除student_table3表上名為student_table3_ibfk_1的外鍵約束 alter table student_table3 drop foreign key student_table3_ibfk_1;

    增加外鍵約束通常使用add foreign key命令。SQL語句如下:

    #修改student_table3數據表,增加外鍵約束 alter table student_table3 add foreign key(java_teacher_name,java_teacher_pass) references teacher_table3(teacher_name,teacher_pass);

    值得支出的是,外鍵約束不僅可以參照其他表,而且可以參照自身,這種參照自身的通常被稱為自關聯。例如,如果一個包保存某個公司的所有員工記錄,員工之間有部門經理和普通員工之分,部分經理和普通員工之間存在一對多的關聯關系,但他們都是保存在同一個數據表里的記錄,這就是典型的自關聯。下面的SQL語句用于建立自關聯的外鍵約束。

    #使用表級約束語法建立外約束鍵,且直接參照自身 create table foreign_test(foreign_id int auto_increment primary key,foreign_name varchar(255),#使用該表的refer_id參照到本表的foreign_id列refer_id int,foreign key(refer_id)references foreign_test(foreign_id) );

    如果想定義刪除主表記錄時,從表記錄也會隨之刪除,則需要在建立外鍵約束后添加 on delete cascade或添加 on delete set null,第一種是刪除主表記錄時,把參照該主表記錄的從表記錄全部級聯刪除;第二種是指定刪除主表記錄時,把參照該主表記錄的從表記錄的外鍵設為null。SQL語句如下:

    #為了保證從表參照的主表存在,通常應該先建立主表 create table teacher_table4(#auto_increment:代表數據庫的自動編號策略,通常用作數據表的邏輯主鍵teacher_id int auto_increment,teacher_name varchar(255),primary key(teacher_id) );

    create table student_table4(#為本表建立主鍵約束student_id int auto_increment primary key,student_name varchar(255),java_teacher int,#使用表級約束語法建立外鍵約束,定義級聯刪除foreign key(java_teacher)references teacher_table4(teacher_id)on delete cascade #也可用 on delete set null );

    CHECK約束

    當前版本的MySQL支持建表時使用CHECK約束,但是這個CHECK約束不會有任何作用。建立CHECK約束的語法很簡單,只要在建表時列定義后增加check(邏輯表達式)即可。SQL語句如下:

    create table check_test(emp_id int auto_increment,emp_name varchar(255),emp_salary decimal not null,primary key(emp_id),#建立CHECK約束check(emp_salary>0) );

    雖然上面的SQL語句建立的CHECK_test表中有CHECK約束,CHECK約束要求emp_salary大于0,但實際上并不會起作用。
    MySQL作為一個開源、免費的數據庫系統,對有些功能支持確實不太好,如果讀者確實希望MySQL創建數據表有CHECK約束,甚至有更復雜的完整性約束,則可借助于MySQL的觸發器機制。本階段(Java基礎)不會介紹,可期待下一階段(MySQL)文章。
    關于約束學習的總結,其實約束這個內容不是很難,只是現在剛剛學習MySQL基礎操作語句還很抽象,我也不清楚約束具體作用,這些都需要慢慢的學習去完善認知和使用以及學習!

    索引

    索引是存在在模式中的一個數據庫對象,它加速了查詢,減少了磁盤的I/O。
    索引作為數據庫對象,在數據字典中獨立存在,但不能獨立存在,必須屬于某個表。
    MySQL使用information_schema數據庫里的STATISTICS表來保存該數據庫實例中的所有索引信息,用戶可通過查詢該表來獲取該數據庫的索引信息。
    創建索引有兩種方式.

    • 自動:當在表上定義主鍵約束、唯一約束和外鍵約束時,系統會為該數據列自動創建對應索引。
    • 手動:用戶可以通過create index…語句來創建索引。

    刪除索引也有兩種方式。

    • 自動:數據表被刪除時,索引自動被刪除。
    • 手動:用戶可以通過drop index…語句來刪除指定數據表上的指定索引。

    索引的作用類似于書的目錄,幾乎沒有一本書沒有目錄,因此幾乎沒有一個表沒有索引。一個表中可以有多個索引列,每個索引都可以用于加速該列的查詢速度。
    創建索引的語法格式如下:

    create index index_name on table_name (column[,column]...);

    下面的索引將會提供對employees表基于last_name字段的查詢速度。

    變綠在cmd原始狀態下輸入 color a 就行了 也可以直接輸入color調出提示。

    #這里我們先創建一個只有含有一個 last_name字段的表 create table employees(last_name varchar(255) );

    創建employees表中last_name的索引

    create index emp_last_name_idx on employees(last_name);

    也可同時對多列建立索引,SQL語句如下:
    先刪掉原來的employees表

    drop table employees;

    create table employess(#這次多了一列 first_namefirst_name varchar(255),last_name varchar(255) );


    #下面語句為employees的first_name和last_name兩列同時建立索引 create index emp_last_name_idx on employees(first_name,last_name);

    刪除索引

    刪除索引需要指定表:

    drop index 索引名 on 表名

    如下SQL語句刪除了employees表上的emp_last_name_idx索引:

    drop index emp_last_name_idx on employees;

    有些數據庫刪除索引時無須指定表名,因為它們要求建立索引時每個索引都有唯一的名字,所以無須指定表名,例如Oracle就采用這種策略。但MySQL只要求同一個表內的索引不能同名,所以刪除索引時必須指定表名。
    索引的好處是可以加速查詢。但索引也有如下兩個壞處。

    • 與書的目錄類似,當數據表中的記錄被添加、刪除、修改時,數據庫系統需要維護索引,因此有一定的系統開銷。
    • 存儲索引信息需要一定的磁盤空間。

    視圖

    視圖看上去很像一個數據表,但它不是數據表,因為它不能存儲數據。視圖只是一個或多個數據表中數據的邏輯顯示。使用視圖有如下幾個好處。

    • 可以限制對數據的訪問。
    • 可以使復雜的查詢變得簡單。
    • 提供了數據的獨立性。
    • 提供了對相同數據的不同顯示。
      因為視圖只是數據表中數據邏輯的顯示——也就是一個查詢結果,所以創建視圖就是建立視圖名和查詢語句的關聯。創建視圖的語法如下:
    create or replace view 視圖名 as subquery

    從上面語法可以看出,創建、修改視圖都可使用上面語法。上面語法的含義是,如果該視圖不存在則創建視圖;如果指定視圖名的視圖已經存在,則使用新視圖替換原有視圖。后面的subquery就是一個查詢語句,這個查詢可以非常復雜。
    通過建立視圖的語法規則不難看出,所謂視圖的本質,其實就是一條被命名的SQL查詢語句。
    一旦建立了視圖以后,使用該視圖與使用數據表就沒有上面區別了,但通常只是查詢視圖數據,不會修改視圖里的數據,因為視圖本身沒有存儲數據。
    如下SQL語句就創建了一個簡單的視圖:
    這里因為刪除了之前的 teacher_table,所以重新建立一個

    create table teacher_table(teacher_name varchar(255) default '視圖測試',teacher_pass varchar(255) );

    創建視圖

    create or replace view view_test as select teacher_name,teacher_pass from teacher_table;

    我們來看結果




    可以看到,我們通過 desc關鍵字查詢兩者時,顯示的數據毫無區別。
    通常不推薦直接改變視圖的數據,因為視圖并不存儲數據,它只是相當于一條命名的查詢語句而已。為了強制不允許改變視圖的數據,MySQL允許在創建視圖時使用with check option子句,使用該子句創建的視圖不允許修改,如下所示。

    這里刪除視圖的語句就不再是

    drop table view_test;

    而是

    drop view view_test;

    create or replace view view_test as select teacher_name from teacher_table #指定不允許修改該視圖的數據 with check option;


    大部分數據庫都采用 with check option來強制不允許修改數據庫的數據,但Oracle采用 with read olny 來強制不允許修改視圖的數據。
    刪除視圖語句如下:

    drop view 視圖名

    上面刪除過了一次 view_test視圖

    drop view view_test;

    DML語句語法

    與DDL操作數據庫對象不同,DML主要操作數據表里的數據,使用DML可以完成如下三個任務。

    • 插入新數據。
    • 修改已有數據。
    • 刪除不需要的數據。

    DML語句由insert into、update 和 delete from三個命令組成。

    1.insert into語句

    其實這三個文章剛開始就都講過了,所以只要前面的實例跟著做過,再學這個還是非常簡單的,包括會了前面文章的所有內容。不過注意,文章剛開始確實講過這三個關鍵字但是都是使用,并沒有將很多細節,所以主要學習的時候才是最重要的,提前實習只是打下基礎。
    insert into 用于向指定數據表中插入數據。對于標準的SQL語句而言,每次只能插入一條記錄。insert into語句的語法格式如下:

    insert into table_name [(column[,column...])] values(value[,value...]);

    執行插入操作時,表名后可以用括號列出所有需要插入值的列名,而values后用括號列出對應需要插入的值。
    如果省略了表名后面的括號及括號里的列名列表,默認將為所有列都插入值,則需要為每一列都指定一個值。如果既不想在表名后列出列名,又不想為所有列都指定值,則可以為那些無法確定值的列分配null。下面SQL語句示范了如何向數據表中插入記錄。
    只有在數據庫中已經成功創建了數據表之后,才可以向數據表中插入記錄。下面的SQL語句以前面外鍵約束時所創建的teacher_table2和student_table2為列來介紹數據插入操作。
    在表名后使用括號列出所有需要插入值的列:

    如果之前把前面的實例刪了,就再創建一下兩個表。

    這里應該使用 select查詢表中數據,而不再是 desc

    insert into teacher_table2(teacher_name) values('xyz'); select*from teacher_table2;//查詢語句

    insert into teacher_table2 #使用null代替主鍵列的值 values(null,'abc');

    從上面中看到 abc記錄的主鍵列的值是2,而不是SQL語句插入的NULL,因為主鍵列是自增長的,系統自動分配值。
    根據前面介紹的外鍵約束規則:外鍵列里的值必須是被參照列里已有的值,所以向表中插入記錄之前,通常應該先向主表中插入記錄。否則從表記錄的外鍵列只能為null、現在主表teacher_table2中已有了2條記錄,現在可以向從表student_table2中插入記錄了,SQL語句如下:

    inserto into student_table2 #當向外鍵列里插值時,外建列的值必須是被參照列里已有的值 values(null,'張三',2);

    外鍵約束保證被參照的記錄存在,但并不保證必須有被參照記錄,即外建立可以為null,如果想保證每條記錄必須存在對應的主表記錄,則應使用非空、外鍵兩個約束。
    在一些特殊的情況下,可以使用帶子查詢的插入語句,帶子查詢的插入語句可以一次插入多條記錄,SQL語句如下:

    insert into student_table2(student_name) #使用子查詢的值來插入 select teacher_name from teacher_table2;

    正如上面的SQL語句所示,帶子查詢的插入語句甚至不要求查詢數據的源表和插入數據的目標表是同一個表,它只要求選擇出來的數據列和插入目的表的數據列個數相等、數據類型匹配既可。
    MySQL甚至提供了一種擴展的語法,通過這種擴展的語法也可以一次插入多條記錄。MySQL允許在values后使用多個括號包含多條記錄,表示多條記錄的多個括號之間以英文逗號格式。SQL語句如下:

    insert into teacher_table2 #同時插入多個值 values(null,"Yeeku"),(null,"Sharyfly");


    2.update語句

    這個文章初期也有講過,修改語句。
    update語句用于修改數據表的記錄,每次可以修改多條記錄,通過使用where子句限定修改哪些記錄。where子句是一個條件表達式,該條件表達式類似于Java語句的if,只有符合該條件的記錄才會被修改。沒有where子句以意味著where表達式的值總是true。即該表的所有記錄都會被修改。update語句的語法格式如下。

    update table_name set column1 = value1[,column2 = value2]... [WHERE condition];

    使用update語句不僅可以一次修改多條記錄,也可以一次修改多列。修改多列都是通過在set關鍵字后使用 cloumn1 = value1,column2 = value2…來實現的,修改多列之間的值以英文逗號隔開。
    下面的SQL語句將把teacher_table2表中的所有記錄的teacher_name列的值都改為’孫悟空’。

    update teacher_table2 set teacher_name= '孫悟空';

    也可以通過添加where條件來指定值修改特定記錄,SQL語句如下。

    3.delete from語句

    delete from語句用于刪除指定數據表的記錄。使用delete from語句刪除時不需要指定列名,因為總是整行地刪除。
    使用delete from語句可以一次刪除多行,刪除哪些行采用where子句限定,只刪除滿足where條件的記錄。沒有where子句限定將會把表中的全部記錄刪掉。
    delete from語句的語法格式如下:

    delete from table_name [WHERE condition];

    如下SQL語句將會把student_table2表的記錄全部刪除

    delete from student_table2;

    也可以使用where條件來限定只刪除指定記錄,SQL語句如下:

    delete from teacher_table2 where teacher_id>2;

    當主表記錄被從表記錄參照時,主表記錄不能被餐廚,只有先將從表中參照主表記錄的所有記錄全部刪除后,才可以刪除主表記錄。還有一種情況,定義外鍵約束時定義了主表記錄和從表記錄之間的級聯刪除 on delete cascade,或者使用 on delete set null 用于指定當主表記錄被刪除時,從表中參照該記錄的從表記錄被外鍵列的值設為null。

    單表查詢

    有示意圖,但是不展示了,光看示意圖看不懂,看介紹。
    select語句的功能就是查詢數據,select語句也是SQL中最豐富的語句,select語句不僅可以執行單表查詢,而且可以執行多表連接查詢,還可以進行子查詢,select語句用于從一個胡哦多個數據表中選出特定行、特定列的交集。
    select后的列用于確定選擇哪些列,where條件用于確定選擇哪些行,只有滿足where條件的記錄才會被選擇出來;如果沒有where條件,則默認選出所有行。如果想選擇出所有列,則可使用星號代表所有列。
    下面的SQL語句將會選擇出teacher_table表中的所有行、所有列的數據。

    select*from teacher_table;

    為了能看到查詢結果,必須準備數據表,并向數據表中插入一些數據,因此在運行本節的select之前準備好之前的數據表 student_table。
    如果增加where條件,則只選擇出符合where條件的記錄。如下SQL語句將選擇出student_table表中java_teacher值大于3的記錄的student_name列的值。


    select student_name from student_table where java_teacher>3;


    先添加好數據,再執行上面的內容:

    當使用select語句進行查詢時,還可以在select語句中使用算術運算符(+、-、*、/),從而形成算術表達式。使用算術表達式的規則如下:

    • 對數值型數據列、變量、常量可以使用算術運算符(+、-、*、/)創建表達式。
    • 對日期型數據、變量、常量可以使用部分運算術運算符(+、-)創建表達式,兩個日期之間可以進行減法運算,日期和數值之間可以進行加、減運算。
    • 運算符不僅可以在列和變量之間進行運算,也可以在兩列之間進行運算。

    不論從哪個角度來看,數據列都很像一個變量,只是這個變量值具有指定的范圍——逐行計算表中的每條記錄時,數據列的值依次變化。因此能使用變量的地方,基本上都可以使用數據列。
    下面的select語句中使用了算術運算符。

    #數據列實際上可以當成一個變量 select teacher_id +5 from teacher_table;

    #查詢出teacher_table表中teacher_id*3大于4的記錄 select*from teacher_table where teacher_id *3 >4;

    需要指出的是,select后的不僅可以是數據列,也可以是表達式,還可以是變量、常量等。例如:

    #在select后直接使用表達式或常量 select 3*5,20 from teacher_table;

    SQL語句中算術運算符的優先級與Java語言中的運算符優先級完全相同,乘法和除法的優先級高于加法和減法,同級運算的順序是從左到右,表達式中使用括號可以強行改變優先級的運算順序。
    MySQL中沒有提供字符串連接運算符,即無法使用加號(+)將字符串常量、字符串變量或字符串列連接起來。MySQL使用concat函數來進行字符串連接運算。
    SQL語句如下:

    #選擇出teacher_name和'xx'字符串連接后的結果 select concat(teacher_name,'xx') from teacher_table;

    MySQL的算術表達式中也可以使用null,但是會導致整個算術表達式的返回結果都為null,使用字符串連接也是null。

    select concat(teacher_name,null) from teacher_table;

    如果不希望直接使用列名作為列標題,則可以為數據列或表達式起一個別名,為數據列或表達式起別名時,別名緊跟數據列,中間以空格隔開,或者使用as關鍵字隔開。SQL語句如下:

    select teacher_id +5 as MY_ID from teacher_table;

    可以看出,為列起別名,可以改變列的標題頭,用于標識計算結果的具體含義。如果列別名中使用特殊字符(如空格),或者強制大小寫敏感,都可以通過為別名添加雙引號來實現。SQL語句如下:

    #可以為選出的列起別名,別名中包括單引號字符,所以把別名用雙引號引起來 select teacher_id +5 "MY'id" from teacher_table;

    如果要選擇多列,并未多列起名,則列與列之間以逗號隔開,但列與列名之間以空格隔開。

    select teacher_id +5 MY_ID,teacher_name 老師名

    也可以為表起別名,為表起別名的語法和為列或表達式起別名的語法完全一樣。

    select teacher_id + 5 MY_ID,teacher_name 老師名 #為teacher_table其別名 from teacher_table t;

    前面已經提到,列名可以當成變量處理,所以運算符也可以在多列之間進行運算,SQL語句如下。

    select teacher_id +5 MY_ID,concat(teacher_name,teacher_id)teacher_name from teacher_table where teacher_id * 2 >3;

    甚至可以在select、where子句中都不出現列名,SQL語句如下:

    select 5+4 from teacher_table where 2<9;

    這種情況這叫特殊:where語句后的表達式總是true,所以會把teacher_table表中的每條記錄都選擇出來)但SQL語句沒有選擇任何列,僅僅選擇了一個常量,所以SQL會把該常量當成一列,teacher_table表中有多少條記錄,該常量就會出現多少次。
    對于選擇常量的情形,指定數據表可能沒有太大的意義,所以MySQL提供了一種擴展語法,允許select語句后沒有from子句,即可寫成如下形成。

    select 5+4;

    上面語句并不是標準的SQL語句,例如,Oracle就提供了一個名為dual的虛標(最新的MySQL數據庫也支持dual虛標),它沒有任何意義,僅僅相當于from后的占位符。如果選擇常量,則可使用如下語句。

    select 5+4 from dual;

    select默認會把所有的符合條件的記錄全部選出來,即使兩行記錄完全一樣。如果想除去重復行,則可以使用distinct關鍵字從查詢結果中清除重復行。

    額實際上,沒有重復行,去了個寂寞
    但是可以手動添加一個:

    再次執行如上指令。

    這里看到了,查詢到了重復的值。
    看去除重復行的效果

    #去除重復行查詢 select distinct student_name,java_teacher from student_table;

    使用ddistinct去除重復行時,distinct緊跟select關鍵字。它的作用是去除后面字段組合的重復值,而不管對應記錄在數據庫里是否重復。例如,(1,‘a’,‘b’)和(2,‘a’,‘b’)兩條記錄在數據庫里是不重復的,但如果僅選擇后面兩列,則distinct會認為兩條記錄重復。
    前面已經看到了where子句的作用——可以控制只選擇指定的行,因為where子句里包含的是一個條件表達式,所以可以使用 >、>=、<、<=、=和<>等基本的比較運算符。SQL中比較運算符不僅可以比較數值之間的大小,也可以比較字符串、日期之間的大小。
    SQL中判斷兩個值是否相等的比較運算符是單等號,判斷不相等的運算符是<>;SQL中的賦值運算符不是等號,而是冒號等號(:=)。
    除此之外,SQL還支持如下表所示的特殊比較運算符。

    可能有點看不清楚


    概念只是個人理解不一定正確。
    下面的SQL語句選出student_id 大于等于2,且小于等于4的所有記錄。

    select*from student_table where student_id between 2 and 4;

    使用betwwen val 1 and val2必須保證val1小于val2,否則將選不出任何記錄。此處之外,between val1and val2中的兩個值不僅可以是常量,也可以是變量,或者是列名也行。如下SQL語句選出java_teacher小于等于2,student_id大于等于2的所有記錄

    select*from student_table where 2 between java_teacher and student_id;

    使用in比較運算符時,必須在in后的括號里列出一個或多個值,它要求指定列必須與in括號里任意一個值相等,SQL語句如下:

    #選出student_id為2或4的記錄 select*from student_table where student_id in(2,4);

    與此類似的是,in括號里的值既可以是常量,也可以是變量或者列名,SQL語句如下:

    select*from student_table where 2 in (student_id,java_teacher);


    運行結果也就那幾個,詳細使用還是等到JDBC吧。
    like運算主要用于模糊查詢,例如:查 ‘張開頭的記錄’
    這就需要使用模糊查詢了,比如查找 '張’姓名開頭的學生。
    SQL有兩個通配符:下畫線(_)和百分號(%),其中下畫線可以代表任意一個字符,百分號可以代表多個字符。
    下面語句查詢名為張的學生。
    這里比較坑,得自己再加點數據了

    通過結構顯示可以知道有3個數值,而id是自動增長,所以可以直接null讓系統自動分配,name是我們這次主要的內容

    我就新建這么多的數據,主要看查詢結果。

    select*from student_table where student_name like '張%';

    下面SQL語句將查詢名為兩個字符的所有學生。

    select*from student_table where student_name like '__';

    在某些特殊情況下,查詢的條件里需要使用下畫線或百分號,不希望SQL把下畫線和百分號當成通配符使用,這就需要使用轉義字符,MySQL使用反斜線(\)作為轉義字符,SQL語句如下:

    這里再次自導自演一次,添加帶有_下畫線的數據
    查詢帶有下畫線的數據:

    這里大意了

    標準SQL語句并沒有提供反斜線(\)的轉義字符,而是使用escape關鍵字顯式進行轉義。例如,為了實現上面的功能需要使用SQL語句。

    這里就不要再執行這個代碼了,有奇怪的BUG。
    is null用于判斷某些值是否為空,判斷是否為空不要用=null來判斷,因為SQL中 null=null返回null,如下SQL語句將選擇出student_table表中student_name為null的所有記錄。

    select*from student_table where student_name is null;

    如果where子句后有多個條件需要組合,SQL提供了and和or邏輯運算符來組合兩個條件,并提供了not來對邏輯表達式求否。如下SQL語句將選出學生名字為2個字符,且student_id大于3的所有記錄。

    select*from student_table where student_name like '__' and student_id >3; select*from student_table where student_name like '__' or student_id >3;


    下面語句將選出不以下畫線開頭的name。

    select*from student_table where not student_name like '\_%';

    下面示意了邏輯運算符的優先級。

    如果SQL代碼需要改變優先級默認順序,則可以使用括號,括號的優先級比所有的運算符都高

    select*from student_table where(student_id > 3 or student_name >'張')and java_teacher>1;


    執行查詢后的查詢結果默認按插入順序排列;如果需要查詢結果按某列值大小進行排序,則可以使用 order by 子句。 order by 子句的語法格式如下:

    order by column_name1 [desc],column_name2 ...

    進行排序時默認按升序排列,如果強制按降序排列,則需要在列后使用desc關鍵字(與之對應的是asc關鍵字,用不用該關鍵字的效果完全一樣,因為默認就是按升序排序的)。
    上面語法中設定排序列時可采用列名、序列名和列別名。如下SQL語句選出student_table表中所有記錄,選出后按java_teacher列的升序排列。

    如果需要按多列排序,則每列的asc、desc必須單獨設定,如果指定了多個排序列,則第一個排序了是首要排序列,只有當第一列中存在多個相同的值時,第二個排序列才會起作用。如下SQL語句先按java_teacher列的降序排列,當java_teacher列的相同值同時按student_name列的升序排列。

    select*from student_table order by java_teacher desc,student_name;

    數據庫函數

    前面看到的連接字符串使用的concat函數,每個數據庫都會在標準的SQL基礎上擴展一些函數,這些函數用于進行數據處理和復雜計算,它們通過對一組數據進行計算,得到最終需要輸出的結果。
    函數一般都會有一個或者多個輸入,這些輸入被稱為函數的參數,函數內部會對這些參數進行判斷和計算,最終只有一個值作為返回值。函數可以出現在SQL語句中的各個位置,比較常用的位置是select之后和where子句之中。
    根據函數對多行數據的處理方式,函數被分為單行函數和多行函數,單行函數對每行輸入值單獨計算,每行得到一個計算結果返回給用戶,多行函數對多行輸入值整體計算,最后只會得到一個結果。
    SQL中的函數和Java語言中的方法有些相似,但SQL中的函數是獨立的程序單元,也就是說,調用函數時無須使用任何類、對象作為調用者,而是直接執行函數。執行函數的語法如下:

    function_name(arg1,arg2...)

    多行函數也稱為聚集函數、分組函數,主要用于完成一些統計計算,在大部分數據庫中基本相同。但不同數據庫中的單行函數差別非常大,MySQL中的單行函數具有如下特征。

    • 單行函數的參數可以是變量、常量或數據列。
      單行函數可以接收多個參數,但只返回一個值。
    • 單行函數會對每行單獨起作用,每行(可能包含多個參數)返回一個結果。
    • 使用單行函數可以改變參數的數據類型。單行函數支持嵌套使用,即內層函數的返回值是外層函數的參數。

    MySQL數據庫的數據類型大致分為數值型、字符串和日期時間型,所以MySQL提供了對應的函數。轉換函數主要負責完成類型轉換。其他函數又大致分為如下幾類。

    • 位函數
    • 流程控制函數
    • 加密解密函數
    • 信息函數

    每個數據庫都包含了大量的單行函數,這些單行函數的用法也存在一些差異,但是有一點是相同的——每個數據庫都會為一些常用計算功能提供相應的函數,這些函數的函數名可能不同,用法可能有差異,但所有數據庫提供的函數庫所能完成的功能大致相似。
    MySQL單行函數的用法。
    這里代碼比較多

    #選出teacher_table表中teacher_name列的字符長度 select char_length(teacher_name);

    #計算teacher_name的列的字符長度的sin值 select sin(char_length(teacher_name)) from teacher_table;

    #計算1.57的sin值,約等于1 select sin(1.57);

    #為指定日期添加一定的時間 #在這種用法下interval是關鍵字,需要一個數值,還需要一個單位 SELECT DATE_ADD('1998-01-02',interval 2 MONTH);

    #這種用法更簡單 select ADDDATE('1998-01-02',3);

    #獲取當前日期 select CURDATE(); #獲取當前時間 select curtime(); #下面的MD5是MD5加密函數 select MD5('testing');

    MySQL提供了如下幾個處理null的函數

    • ifnull(expr1,expr2):如果expr1為null,則返回expr2,否則返回expr1。
    • nullif(expr1,expr2):如果expr1和expr2相等,則返回null,否則返回expr1。
    • if(expr1,expr2,expr3):有點類似于 ? : 三目運算符,如果expr1為true,不等于0,且不等于null,null返回expr2,否則返回expr3。
    • isnull(expr1):判斷expr1是否為null,如果為null則返回true,否則返回false。

    #如果student_name列等于'張三',則返回null select nullif(student_name,'張三') from student_table;


    這里應該只是針對兩個字符長度的篩查

    #如果student_name列為null,則返回'沒有名字',否則返回'有名字' select if(isnull(student_name),'沒有名字','有名字') from student_table;


    MySQL還提供了一個case函數,該函數是一個流程控制函數。case函數有兩個用法,case函數第一個用法的語法格式如下:

    case value when compare_value1 then result1 when compare_value2 then result2 ... else result end

    case函數用value和后面的compare_value1、compare_value2、…依次比較,如果value和指定的compare_value1相等,則返回對應的result1,否則返回else后的result。

    #如果java_teacher為1,則返回'Java老師',為2返回'Ruby老師',否則返回'其他老師' select student_name,case java_teacher when 1 then 'Java老師' when 2 then 'Ruby老師' else '其他老師' end from student_table;

    case函數第二個用法的語法格式如下:

    case when condition1 then result1 when condition2 then result2 ... else result end

    在第二個用法中,condition1、condition2都是一個返回boolean值的條件表達式,因此這種用法更加靈活。例如如下語句:

    #id小于3的為初級班,3~6的為中級班,其他的為高級班 select student_name,case when student_id <=3 then '初級班' when student_id <=6 then '中級班' else '高級班' end from student_table;

    雖然此處介紹了一些MySQL常用函數的簡單用法,但通常不推薦在Java程序中使用特定數據庫的函數,因為這將導致程序代碼與特定數據庫耦合;如果需要把該程序移植到其他數據庫系統上時,可能需要打開源程序,重新修改SQL語句。

    分組和組函數

    組函數也是前面提到的多行函數,組函數將一組記錄作為整體計算,每組記錄返回一個結果,而不是每條記錄返回一個結果。常用的組函數又如下5個

    • avg([distinct|all]expr):計算多行expr的平均值,其中,expr可以是變量、常量或數據列,但起數據類型必須是數值型。還可以在變量、列前使用distinct或all關鍵字,如果使用distinct,則表明不計算重復值;all用和不用效果完全一樣,表明需要計算重復值。
    • count({*[distinct|all]expr}):計算多行expr的總條數,其中expr可以是變量、常量或數據列,其數據類型可以是任意類型:用星號表示統計該表內的記錄行數;distinct表示不計算重復值。
    • max(expr):計算多行expr的最大值,其中expr可以是變量、常量或數據列,其數據類型可以是任意類型。
    • min(expr):計算多行expr的最小值,其中expr可以是變量、常量或數據列,其數據類型可以是任意類型。
    • sum([distinct|all]expr):計算多行expr的總和,其中expr可以是變量、常量或數據列,但其數據類型必須是數值型;distinct表示不計算重復值。

    #計算student_table表中的記錄條數 select count(*) from student_table;

    #計算java_teacher列總共有多少個值 select count(distinct java_teacher) from student_table;

    select sum(student_id) 'student_id的所有總和' from student_table; #上面是別名的應用

    #計算的結果是20*記錄的行數 select sum(20) from student_table;

    #選出student_table表中最大的id值 select max(student_id) from student_table;

    #選出teacher_table表中teacher_id最小的值 select min(teacher_id) from student_table; #因為sum里的expr是常量34,所以每行的值都相同 #使用distinct強制不計算重復值,所以下面的計算結果為34 select sum(distinct 34) from student_table;


    select count(student_name) from student_table;

    對于可能出現null的列,可以使用ifnull函數來處理該列。

    #計算java_teacher列所有記錄的平均值 select avg(ifnull(java_teacher,0)) from student_table;

    值得支出的是,distinct和*不同時使用,如下SQL語句有錯誤

    select count(distinct *) from student_table;

    在默認情況下,組函數會把所有記錄當一組,為了對記錄進行顯式分組,可以在select語句后使用group by子句,group by子句后通常會跟一個或多個列名,表明查詢結果根據一列或多列進行分組——當一列或多列組合的值完全相同時,系統會把這些記錄當成一組。SQL語句如下:

    #count(*)將會對每組得到一個結果 select count(*) from student_table #將java_teacher列值相同的記錄當成一組 group by java_teacher;

    如果對多列進行分組,則要求多列的值完全相同才會被當成一組。SQL語句如下:

    select count(*) from student_table #當java_teacher、student_name兩列的值完全相同時才會被當成一組 group by java_teacher,student_name;


    如果需要對組過濾

    • 不能在where子句中過濾組,where子句僅用于過濾行。過濾組必須使用having子句。
    • 不能在where子句中使用組函數,having子句才可使用組函數。

    多表連接查詢

    很多時候,需要選擇的數據并不是來自一個表,而是來自多個數據表,這就需要使用多表連接查詢,例如,對于上面的student_table和teacher_table兩個數據表,如果希望查詢出所有學生以及他的老師名字,這就需要從兩個表中取數據。
    多表連接查詢有兩種規范,較早的SQL92規范支持如下幾種多表連接查詢。

    • 等值連接。
    • 非等值連接。
    • 外連接。
    • 廣義笛卡兒積。
      SQL99規范提供了可讀性更好的多表連接
    • 交叉連接。
    • 自然連接。
    • 使用using子句的連接。
    • 使用on子句的連接。
    • 全外連接或者左、右外連接。

    1.SQL92的連接查詢

    SQL92的多表連接查詢語法比較簡潔。多個表都放在from之后,多個表以逗號可開,連接條件在where之后,與查詢條件之間用and邏輯運算符連接。如果連接條件要求兩列值相等,則稱為等值連接,否則稱為非等值連接;如果沒有任何連接條件,則被稱為廣義笛卡兒積,SQL92中多表連接查詢的語法格式如下:

    select column1,colum2... from table1,table2... [where join_coondition]

    多表連接查詢中可能出現兩個或多個數據列具有相同的列名,則需要在這些同名列之間使用表名前綴或表別名前綴作為限制,避免系統混淆。
    如果只是單表查詢是不可能重復的,但是多表查詢應該加上前綴或表別名。
    如下SQL語句查詢出所有學生的資料以及對應的老師姓名。

    實際上,多表查詢的過程可以理解成一個嵌套循環。這個嵌套循環的偽碼如下:

    //依次遍歷teacher_table表中的每條記錄 for t in teacher_table{//遍歷student_table表中的每條記錄for s in student_table{//當滿足連接條件時,輸出兩個表連接后的結果if(s.java_teacher = t.teacher_id)output s + t} }


    #不使用連接條件,得到廣義笛卡兒積 select s.*,teacher_name #指定多個數據表,并指定表別名 from student_table s,teacher_table t;

    與此類似的是,非等值連接的執行結果可以使用上面的嵌套循環來計算,SQL語句如下:

    select s.*,teacher_name #指定多個數據表,并指定表別名 from student_table s,teacher_table t #使用where指定連接條件,并指定student_name列不能為null where s.java_teacher = t.teacher_id and student_name is ot null;

    SQL不支持SQL 92的左外連接、右外連接。

    自連接只是連接的一種用法,并不是一種連接類型,不管是SQL92還是SQL99棟可以使用自連接查詢。自連接本質就是把一個表當兩個表來用。
    下面的SQL語句建立了一個自連接的數據表,并向表中插入了4條數據。

    create tabl emp_table(emp_id int auto_increment priamry key,emp_name varchar(255),manager_id int,foreign key(manager_id) references emp_table(emp_id));

    insert into emp_table values(null,'唐僧',null), (null,'孫悟空',1), (null,'豬八戒',1), (null,'沙僧',1);

    如果需要查詢該數據表中的所有員工名,以及每個員工對應的經理名,則必須使用自連接查詢。所謂自連接就是把一個表當成兩個表來用,這就需要為一個表起兩個別名,而且查詢中用的所有數據列都要加表別名前綴,因為兩個表數據完全一樣。下面的自連接查詢可以查詢出所有的員工名,以及對應的經理名。

    select emp.emp_id,emp.emp_name 員工名, mar.emp_name 經理名 from emp_table emp,emp_table mgr where emp.manager_id = mgr.emp_id;

    SQL99的連接查詢

    SQL99的連接查詢與SQL 92的連接查詢原理基本相似,不同的是SQL99連接查詢的可讀性更強——查詢用多個數據表顯式使用 xxx join連接,而不是直接依次排列在from之后,from后只需要放一個數據表;連接條件不再放在where之后,而是提供了專門的連接條件子句。

    • 交叉連接(cross join):交叉連接效果就是SQL92中的廣義笛卡兒積,所以交叉連接無須任何條件。
    select s.*,teacher_name #SQL99多表連接查詢的from后只有一個表名 from student_table s #cross join 交叉連接,相當于廣義笛卡兒積 cross join teacher_table t;
    • 自然連接(natural join):自然連接表面上看起來也無須指定連接條件,但自然連接是有連接條件的,自然連接會以兩個表中的同名列作為連接條件;如果兩個表中沒有同名列,則自然連接與交叉連接效果完全一樣——因為沒有連接條件。

    select s.*,teacher_name from student_table s natural join teacher_table t;
    • using子句連接:using子句可以指定一列或多列,用于顯式指定兩個表中的同名列作為連接條件。假設兩個表中有超過一列的同名列,如果使用natural join ,則會把所有的同名列當成連接條件;使用using子句,就可顯式指出使用哪些同名列作為連接條件。SQL語句如下:


    運行上面語句將出現一個錯誤,因為student_table表中并不存在名為teacher_id的列,也就是說,如果使用using子句來指定連接條件,則兩個表必須有同名列,否則將會出現錯誤。

    • on子句連接:這是最常用的連接方式,SQL99語法的連接條件放在on子句只指定一個連接條件。這意味著:如果需要進行N表連接,則需要有N-1個join…on對。

    select s.*,teacher_name #SQL99多表連接查詢的from后只有一個表名 from student_table s #join連接另一個表 join teacher_table t #使用on來指定連接條件 on s.java_teacher = t.teacher_id;

    使用on子句的連接完全可以替代SQL92的等值連接、非等值連接,因為on子句的連接條件除等值條件之外,也可以是非等值條件。如下SQ語句就是SQL99中的非等值連接。

    select s.*,teacher_name #SQL 99多表連接查詢的from后只有一個表名 from student_table s #join連接另一個表 #使用on來指定連接條件;非等值連接 on s.java_teacher>t.teacher_id;
    • 左、右、全外連接:這三種外連接分別使用left[outer] join、right[outer]join和full[outer]join,這三種外連接的連接條件一樣通過on子句來指定,既可以是等值連接條件,也可以是非等值連接條件。
      下面使用右外連接,連接條件時非等值連接
      內連接:結合兩張表的記錄,返回相關的查詢結果,返回的是兩個表的交集部分。 關鍵字:INNER JOIN
      左連接:左連接查詢,左表的信息全部展示出來,右表只會展示符合搜索條件的信息,不滿足的地方記為NULL 關鍵字:LEFT JOIN
      右連接:右連接查詢,右表的信息全部展示出來,左表只會展示符合搜索條件的信息,不滿足的地方記為NULL RIGHT JOIN

      來自該博主的借鑒。

    select s.*,teacher_name #SQL 99多表連接查詢的from后只有一個表名 from student_table s #right join 右外連接另一個表 right join teacher_table t #使用on來指定連接條件,使用非等值連接 on s.java_teacher<t.teacher_id;

    下面使用左外連接,連接條件是非等值連接。

    select s.*,teacher_name from student_table s left join teacher_table t on s.java_teacher>t.teacher_id;

    不難發現SQL99與SQL92外連接恰好相反,SQL99左外連接會把左邊表中所有不滿足連接條件的記錄全部列出;SQL99右外連接將會把右邊表中所有不滿足條件的記錄全部列出。
    下面的SQL語句使用全外連接,連接條件是等值連接。

    會出錯誤,因為MySQL并不支持全外連接。
    這些查詢我也懵,到了JDBC多練練就行了,現在有點抽象

    子查詢

    子查詢就是指定查詢語句中嵌套另一個查詢,子查詢可以支持多層嵌套。對于一個普通的查詢語句而言,子查詢可以出現在兩個位置。

    • 出現在from語句后當成數據表,這種用法也被稱為行內視圖,因為該子查詢的實質就是一個臨時視圖。
    • 出現在where條件后作為過濾條件的值
      使用子查詢時要注意如下幾點。
    • 子查詢要用括號括起來
    • 把子查詢當數據表時(出現在from之后),可以為該子查詢起別名,尤其是作為前綴來限定數據列時,必須給子查詢起別名。
    • 把子查詢當成過濾條件時,將子查詢放在比較運算符的右邊,這樣可增強程序的可讀性。
    • 把子查詢當成過濾條件時,單行子查詢使用單行運算符,多行子查詢使用多行運算符。

    對于把子查詢當成數據表是完全把子查詢當做數據表來用,只是把之前的表名變成子查詢(也可為子查詢起別名),其他部分與普通查詢沒有任何區別。下面SQL語句示范了把子查詢當數據表的用法。

    select* #把子查詢當數據表 from(select*from student_table) t where t.java_teacher>1;

    把子查詢當數據表的用法更準確地說是當成視圖,可以把上面的SQL語句理解成在執行查詢時創建了一個臨時視圖,該視圖名為t,所以這種臨時創建的視圖被稱為行內視圖。
    還有一種情形:把子查詢當where條件中的值,如果子查詢返回單行、單列值,則被當成一個標準量使用,也就是可以單行記錄比較運算符。例如如下SQL語句:


    先加一個數據

    select *from student_table where java_teacher > (select teacher_id from teacher_tablewhere teacher_name = 'Yeeku' ); #顯示student_table的值(java_teacher大于teacher_id)



    這里因為前面都是相等的,所以只有最后幾列輸出了出來。比如容易誤導。
    上面查詢語句中的子查詢將返回一個單行、單列值(該值就是1),如果把上面查詢語句的括號部分換位1,那么這條語句就再簡單不過了——實際上,這就是這種子查詢的實質,單行、單列子查詢被當成標準量處理。
    如果子查詢返回多個值,則需要使用in、any和all等關鍵字,in可以單獨使用,與前面介紹比較運算符所講的in完全一樣,此時可以把子查詢返回的多個值當成一個值列表。

    select*from student_table where student_id in (select teacher_id from teacher_table);

    上面查詢語句中的子查詢將返回多個值,這多個值將被當成一個值列表,只要student_id與該值列表的任意一個值相等,就可以選中這條記錄。
    any和all可以與>、>=、<、<=、<>、=等運算符結合使用,與any結合使用分表表示大于、大于等于、小于、小于等于、不等于、等于其中任意一個值;與all結合使用分別表示大于、大于等于、小于、小于等于、不等于、等于全部值。從上面介紹可以看出,=any的作用與in的作用相同。如下語句使用=any來替代上面的in。

    select*from student_table where student_id> all(select teacher_id from teacher_table);

    還有一種子查詢可以返回多行、多列,此時where子句中應該有對應的數據列,并使用圓括號將多個數據列組合起來。SQL語句如下:

    查了個寂寞,我們直接看集合運算然后看JDBC基礎入門。

    集合運算

    select語句查詢的結果是一個包含多條數據的結果級,類似于數學里的集合,還可以進行交(intersect)、并(union)和差(minus)運算,select查詢得到的結果集也可能需要進行這三種運算。
    為了對兩個結果集進行集合運算。這兩個結果集必須滿足如下條件。

    • 兩個結果集所包含的數據列的數量必須相等。
    • 兩個結果集所包含的數據列的數據類型也必須一一對應。

    1.unicon運算

    union運算的語法格式如下:

    select 語句 union select 語句

    下面的SQL語句查詢出所有教師的信息和主鍵小于4的學生信息。

    #查詢結果集包含兩列,第一列為int類型,第二列為varchar類型 select*from teacher_table union #這個結果集的數據列必須與前一個結果集的數據列一一對等 select student_id,student_name from student_table;

    2.minus運算

    minus運算的語法格式如下:

    select 語句 minus select 語句

    上面的語法格式十分簡單,不過很遺憾,MySQL并不支持使用minus運算符們只能借助于子查詢來“曲線”實現上面的minus運算。
    假如向從所有學生記錄中“減去”與老師記錄的ID相同、姓名相同的記錄,則可進行如下的minus運算

    MySQL并不支持這種運算。但可以通過如下子查詢來實現上面的運算。

    3.intersect運算

    intersect運算的語法格式如下:

    select 語句 intersect select 語句

    上面的語法格式十分簡單,不過很遺憾,MySQL并不支持使用intersect運算符,因此只能借助于多表連接查詢來“曲線”實現上面的intersect運算。
    假如想找出學生記錄中與老師記錄中的ID相同、姓名相同的記錄,則可以進行如下的intersect運算。

    select student_id,student_name from student_table intersect #兩個結果級的數據列的數量必須相等,數據類型一一對應,可以進行intersect運算 select teacher_id,teacher_name from teacher_table;

    不過MySQL并不支持這種運算。但可以通過如下多表連接查詢來實現上面運算。

    select student_id ,student_name from student_table join teacher_table on(student_id=teacher_id and student_name = teacher_name);

    需要指出的是,如果進行intersect運算的兩個select子句中都包括了where條件,那么將intersect運算改成多表連接查詢后還需要將兩個where條件進行and運算。假如有如下intersect運算的SQL語句:

    上面語句改寫如下;

    某種意義上來說 沒有數據就是查詢了個寂寞。

    JDBC的典型用法

    重頭戲來了。
    連接方式
    準備好驅動JAR包即可

    import java.sql.Connection; import java.sql.DriverManager; import java.sql.ResultSet; import java.sql.Statement;public class ConnMySql {public static void main(String[] args)throws Exception {//1.加載驅動,使用反射知識,現在記住這么寫Class.forName("com.mysql.cj.jdbc.Driver");try(//2.使用DriverManger獲取數據庫連接//其中返回的Connection就代表了Java程序和數據庫的連接//不同數據庫的URL寫法需要查驅動問道,用戶名、密碼由DBA分配Connection conn = DriverManager.getConnection("jdbc:mysql://127.0.0.1:3306/test?useSSL=false&serverTimezone=UTC","root","123456789");//3.使用Connection來創建一個Statement對象Statement stmt = conn.createStatement();//4.執行SQL語句/*Statement有三種執行SQL語句的方法:1.excute()可執行任何SQL語句-返回一個boolean值如果執行后第一個結果是ResultSet,則返回true,否則返回false2.excuteQuery()執行select語句-返回查詢到的結果級3.excuteUpdate()用于執行DML語句-返回一個整數*/ResultSet rs = stmt.executeQuery("select*from teacher_table")){//ResultSet有一系列的getXxx(列索引|列名)方法,用于獲取記錄指針//指定行、特定列的值,不斷地使用next()將記錄指針下移一行//如果移動之后記錄指針依然指向有效行,則next()方法返回truewhile(rs.next()){System.out.print("老師編號:"+rs.getInt("teacher_id")+" ");System.out.println("老師名稱:"+rs.getString("teacher_name"));}}} }

    本文章就此結束了,加油哦。

    總結

    以上是生活随笔為你收集整理的MySQL基础学习特殊篇 入门限定的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。