Mysql 數(shù)據(jù)庫day3(2019.4.25)

一、列屬性

真正的對列的約束是依賴于數(shù)據(jù)的類型,但是這種約束比較單一,所以需要更多的約束,整個時候就是用到了字段的屬性。


image.png

1.MySQL的記錄長度

MySQL規(guī)定:一條記錄最大只能有65535個字節(jié)。也就是64K。varchar的最大長度655356個字符。
而varchar還需要1-2個字節(jié)去記錄長度。也就是說varchar永遠(yuǎn)存不滿。
中文字符在不同編碼下所占用的空間。
gbk:一個中文字符是2個字節(jié),一個英文字符是一個字節(jié)。
utf8:一個中文字符是3個字節(jié),一個英文字符是1個字節(jié)。
嘗試使用最大空間建立數(shù)據(jù)庫表:

create table mutf8(
name varchar(65535)
)charset utf8;

creaTE table mgbk(
name varchar(65535)
)charset gbk;
image.png

image.png

數(shù)據(jù)庫忽略了varchar需要使用1-2個字節(jié)保存長度。

計算是能夠使用的長度:
gbk:32767 * 2 +2 = 65536 所以 就變成 32766 2 + 2 = 65534
utf8:21845
3 +2 = 65537 21844*3+2 = 65534
建表語句變成:

create table mutf8(
name varchar(21844)
)charset utf8;

creaTE table mgbk(
name varchar(32766)
)charset gbk;
image.png

還有一個字節(jié)沒有使用到。那是不是可以再加一個tinyint類型的字段進(jìn)去?

alter table mgbk add num tinyint;
image.png

在MySQL中,如果一條記錄著某一個字段位可以空的話,那么數(shù)據(jù)庫就會使用一個字節(jié)去保存這種狀態(tài)。
所以說要想完全的使用65535個字節(jié)的話,就要保證數(shù)據(jù)所有的字段都不能為null。
修改原來的name字段不為空:

alter table mgbk modify name varchar(32766) not null;
image.png

再去嘗試添加新的tinyint字段:

alter table mgbk add num tinyint;


image.png

再去嘗試添加新的tinyint字段:

alter table mgbk add num tinyint;
image.png

新增的字段也要保證不能為空

(null)
alter table mgbk  add num tinyint not null;
image.png

image.png

2.null/not null 空屬性

雖然MySQL字段默認(rèn)的基本都是空類型,但是在實(shí)際開發(fā)過程中基本上要做到所有的數(shù)據(jù)字段不為空。
一旦出現(xiàn)某個字段可以為空的話,整個數(shù)據(jù)表查詢就會變慢。


image.png

如何指定字段不為空:
定義的時候指定:


image.png

修改指定:
image.png

image.png

3.comment 列描述

描述:相當(dāng)于注釋,沒有實(shí)際意義。專門用來描述字段的意義或者字段的數(shù)據(jù)格式。會隨著表的創(chuàng)建語句一起保存,是用來給程序員或者DBA看的。


image.png
show create table table_name;
image.png

4.default 默認(rèn)值

在實(shí)際中經(jīng)常會發(fā)生某種數(shù)據(jù)在一開始就具有某個值。比如說人的年齡。一出生就是0.比如說表示數(shù)據(jù)是否寶刪除的狀態(tài)字段。0表示未刪除,1表示已經(jīng)刪除。
軟刪除:基本上很少有數(shù)據(jù)是使用delete刪除的。
創(chuàng)建數(shù)據(jù)表:我們?nèi)サ搅伺畠簢?,要記錄所有女兒國國民的表,要求有用戶名,有用戶的性別。

create  table nrg(
usernam varchar(30) not null,
sex  enum('男','女') default '女'
);
image.png

插入數(shù)據(jù):

insert into nrg(usernam) values (‘月兒’);
image.png

注意: 有默認(rèn)值得字段在數(shù)據(jù)插入的時候需要指定字段,默認(rèn)值得字段直接忽略。

image.png

還有另外一種方式:使用default占位:

insert into nrg values(‘魚兒’,default);
image.png

5.primary key 主鍵

主鍵是唯一標(biāo)識數(shù)據(jù)庫中的每一行(記錄)的字段。所以主鍵是不能重復(fù)的,同時主鍵也不能為null。主鍵可以包含多個字段,但是一個表只能有一個主鍵。當(dāng)主鍵包含多個字段的時候叫組合鍵或者復(fù)合主鍵。
為數(shù)據(jù)表增加主鍵的方法有三種:
第一種:在創(chuàng)建數(shù)據(jù)表的時候在字段的屬性中申明添加。(只能指定一個字段)

--創(chuàng)建具有主鍵的數(shù)據(jù)表結(jié)構(gòu)
學(xué)號,姓名,班級 ,學(xué)號作為主鍵
create table my_student (
name  varchar(30) not null,
class char(4)
);

--添加學(xué)號字段
alter table my_student  add  num  char(13) not null;
image.png

添加主鍵:


image.png

標(biāo)準(zhǔn)用法:

create table my_student (
num  char(13) not null primary key,
name  varchar(30) not null,
class char(4)
);

這種方式只能有一個字段是 主鍵。
第二種:在創(chuàng)建數(shù)據(jù)表的時候在建表語句的字段申明之后指定主鍵。(可以指定多個字段)

create table my_student(
num  char(13) not null ,
name  varchar(30) not null,
class char(4),
primary key(num,name)   --可以指定多個表字段作為主鍵
);
image.png

第三種方式:當(dāng)表已經(jīng)創(chuàng)建好之后追加主鍵,可以修改表字段,也可以直接追加。
創(chuàng)建沒有主鍵的表結(jié)構(gòu):

create table my_student(
num  char(13) not null ,
name  varchar(30) not null,
class char(4)
);
image.png

增加主鍵:

alter table my_student add primary key (num);  --也可以指定多個表字段作為主鍵
image.png

這種方式要保證表中的主鍵字段的數(shù)據(jù)每一條都是唯一的。否則會產(chǎn)生錯誤。
插入數(shù)據(jù):

insert into my_student  values ('itzpark170101','李中渲',1701);
insert into my_student  values ('itzpark170102','馬建龍',1701);
insert into my_student  values ('itzpark170103','弓嘉偉',1701);
insert into my_student  values ('itzpark170101','史騰飛',1701);

image.png

更新主鍵:沒有辦法更新主鍵,只能刪掉主鍵,再添加主鍵

刪除主鍵:

alter table table_name drop primary key;
image.png

因為一個表只有一個主鍵,所以主鍵的刪除非常的方便。

主鍵的分類:
在實(shí)際工作中,我們在創(chuàng)建表的時候一般很少用真實(shí)業(yè)務(wù)數(shù)據(jù)字段當(dāng)做主鍵。如果使用了,那么我們把這種主鍵稱為業(yè)務(wù)主鍵。比如學(xué)生的姓名。課程號之類的。大部分的時候是使用一個邏輯字段(字段沒有實(shí)際的意義,同時字段的值對于整個數(shù)據(jù)行來說也沒有什么影響)。將這種主鍵稱之為邏輯主鍵。
例如:

create table student(
id int primary kry auto_increment comment ‘自增的 邏輯主鍵’,
num char(10) not null comment ‘學(xué)號’,
name varchar(30) not null comment ‘姓名’
)charset utf8;

6.a(chǎn)uto_increment 自動增長

當(dāng)對應(yīng)的字段不給值或者給null的時候,系統(tǒng)會自動的從上一條數(shù)據(jù)中取值加一作為這個字記錄的值。
任何一個字段想要設(shè)置自增長,必須是整數(shù)形式,同時必須是索引(也就是key欄位必須有值)。
測試:

alter table table_name modify num char(13) not null auto_incremrnt;
image.png

添加一個整數(shù)形式的字段:

alter table  my_student  add id int;
image.png

image.png

自增字段一般與主鍵一起使用:(因為自增字段必須是索引)
單獨(dú)刪除主鍵,自增屬性不能存在。


image.png

image.png

添加主鍵:

alter table my_student  add primary key (id);
image.png

image.png

再來也添加主鍵:


image.png

看圖說話:主鍵只能唯一,主鍵的值不能重復(fù),有重復(fù)值得字段不能設(shè)置為主鍵。
image.png

一張數(shù)據(jù)表只能有一個自增字段。

create table my_student(
num  char(13) not null ,
name  varchar(30) not null,
class char(4),
id int  not null ,
ip int not null,
primary key(id,ip)
);
image.png

image.png

插入數(shù)據(jù):

insert into my_student(num,name,class,ip)  values( 'itzpark170101','李中渲',1701,1);
image.png

默認(rèn)的自增長是從1開始的。但是可以使用指定值改變自增的原本數(shù)值。
查看下一個自增字段增長的數(shù)值是多少:

show create table table_name;
image.png

image.png

修改自增字段:
如果要修改的是自增長的字段,那么只能先刪除再添加(因為一個表只能有一個自增的字段)。
修改當(dāng)前自增長的值:修改的值只能比當(dāng)前自增長的最大值大。小不生效。

alter table table_name auto_increment=數(shù)值
image.png

image.png

思考問題:為什么自增長的字段是從1開始的?為什么自增長的值每次都是1?
系統(tǒng)的所有實(shí)現(xiàn)都是由系統(tǒng)的變量來控制的。
查看系統(tǒng)變量的命令:

show variables like ‘%auto_increment%’;
image.png

修改自增變量的值:

set 變量名 = 變量值
image.png

image.png

刪除自增長:

alter table table_name modify 字段 字段屬性 去掉主鍵;

7.unique key 唯一鍵

一張表當(dāng)中往往有一些字段他的值是不能重復(fù)的。但是一張表中只能有一個主鍵。唯一鍵就是解決表中多個字段需要唯一約束的問題。
唯一鍵的本質(zhì)與主鍵差不多。唯一鍵允許默認(rèn)為空,并且允許多個字段為空。為空字段不參與唯一性比較。
添加唯一鍵的方法:
方法一:在創(chuàng)建表的時候,在字段之后添加unique 或者 unique key.

create table munique(
 num char(10) not null unique  comment '編號',
 name varchar(30) not null comment '姓名'
 
 );

這種語發(fā)只能將唯一鍵建立在一個字段上,無法使用多字段唯一鍵。


image.png

PRI 屬性可以表示本字段是主鍵也能表示本字段是唯一鍵。

方法二:在所有的字段之后增加unique key 申明。

 create table munique1(

 num char(10) not null  comment '編號',

 name varchar(30) not null comment '姓名',

 unique key(num)

 );

顯示為PRI是因為這個表沒有主鍵。而剛好有唯一鍵。唯一鍵的本質(zhì)與主鍵是相同的。

這種語法可以指定多個字段作位唯一鍵。

方法三:在創(chuàng)建完表之后,追加unique鍵。

  create table munique3(

  id  int not null primary key auto_increment,

 num char(10) not null  comment '編號',

 name varchar(30) not null comment '姓名'

 );

-追加unique key

完全使用的是修改表字段的語法:

alter table table_name modify num char(10) not null unique key ;

使用添加表字段的語法。

alter table table_name add 字段 字段屬性 unique;

唯一鍵的修改與刪除:

修改:唯一鍵可以使用先刪除后新增的方式進(jìn)行修改。但是也可以不刪除,因為唯一鍵可以有多個。

刪除:

alter table drop primary key;  --刪除主鍵的操作。(因為主鍵是唯一的)

alter table drop unique key ;   --錯誤,唯一鍵可以有多個(因為唯一鍵是可以有多個)

alter table drop index 索引名稱; --唯一鍵本質(zhì)是一個索引

使用 desc只能看到表結(jié)構(gòu),不能看到索引的有關(guān)信息。

image.png

如何去查看索引的有關(guān)信息,索引也是同表的檢表語句一起保存的。

image.png

image.png

二、索引

幾乎所有的索引都是建立在表字段之上的。
索引:系統(tǒng)根據(jù)某種算法,將表中的數(shù)據(jù)能夠快速的進(jìn)行匹配。能夠快速的找到需要的記錄一種機(jī)制。
索引的作用:
提高數(shù)據(jù)的查詢效率。
對數(shù)據(jù)的格式進(jìn)行約束(比如唯一性)。
增加索引的影響:
增加索引后會產(chǎn)生索引文件,并且有的時候可能比數(shù)據(jù)本身還要大。所以建立索引是會產(chǎn)生空間消耗的。同時由于約束條件,數(shù)據(jù)插入的時候會比較慢。
什么時候要建立索引:
如果某個字段需要作為查詢的條件經(jīng)常使用。比如根據(jù)學(xué)號去查詢學(xué)生的信息。
如果某個字段需要進(jìn)行明確的數(shù)據(jù)約束。比如唯一性索引。
MySQL中的索引:
主鍵索引
唯一索引
普通索引
全文索引
其中最最難的是全文索引。
全文索引最大的苦難是關(guān)鍵字的確定。
英文的全文索引比較簡單:因為單詞與單詞之間是有空格的。
中文很難:中文之間沒有空格,而且分詞也比較困難。sphinx分詞

三、數(shù)據(jù)的高級操作

數(shù)據(jù)的操作:增刪改查(CURD)

8.新增數(shù)據(jù)

基本語法:
insert into table_name(字段1,字段2,。。。) values (值1 ,值2,。、。);
insert into table_name(字段1,字段2,。。。) values(值1 ,值2,。、。),
(值1 ,值2,。、。),(值1 ,值2,。、。),(值1 ,值2,。、。);
我們操作主鍵的時候,有這樣一種情況,當(dāng)數(shù)據(jù)表中以及存在數(shù)據(jù)的時候,再次插入數(shù)據(jù),如果主鍵發(fā)生沖突,那么會產(chǎn)生錯誤。
遇到這種情況,我們可以先將已經(jīng)存在的數(shù)據(jù)刪除掉,然后添加新的數(shù),也可以修改新數(shù)據(jù)的主鍵值。
但是我們一般期望能夠有更好的辦法解決這種問題。

1)主鍵沖突

image.png

第一種:當(dāng)主鍵沖突的時候修改:

insert into table_name [字段列表] values(值列表) on duplicate key update 內(nèi)容;

image.png

當(dāng)我出現(xiàn)主鍵沖突的時候指定更新內(nèi)容比較麻煩,有沒有什么辦法將所有不同的內(nèi)容全部更新。
第二種辦法:替換

replace into table_name(字段列表) values (值列表);

注意:值列表和字段列表都要包含主鍵字段。


image.png

image.png

2)蠕蟲復(fù)制

根據(jù)已經(jīng)存在的表快速創(chuàng)建新表:

create table new_table_name like old_table_name;
image.png

表結(jié)構(gòu)完全一致:


image.png

image.png

看圖說話:
表的組成有兩部分構(gòu)成,表的結(jié)構(gòu)和表的數(shù)據(jù)。
通過like創(chuàng)建的表只會復(fù)制表的結(jié)構(gòu),不會復(fù)制表數(shù)據(jù)。
蠕蟲復(fù)制:
有了表結(jié)構(gòu),如何能夠?qū)⒈淼臄?shù)據(jù)也復(fù)制過來,這種辦法叫蠕蟲復(fù)制。

insert into new_table_name select */字段列表 from old——table_name;
image.png

image.png

蠕蟲復(fù)制的作用:
1.能夠從一張表的數(shù)據(jù)復(fù)制到另一張表。
2.能夠快速的使得一張表的數(shù)據(jù)增加到一定的范圍,一般用于檢測數(shù)據(jù)的數(shù)據(jù)抗壓能力和性能。

9.修改數(shù)據(jù)

基本語法:
update table_

name  set 字段=值,字段=值。。 where 條件;

要注意修改時候的where條件,因為沒有條件的修改會修改整個數(shù)據(jù)表。
限制級修改:

update table_name set 字段=值,字段=值。[where 條件] limit 數(shù)字;

意思:修改指定數(shù)據(jù)的值,要按照指定的數(shù)量去修改。


image.png

但是如果數(shù)據(jù)庫的數(shù)據(jù)比較多,多到了一定的數(shù)量級,任何長時間的操作都有可能造成系統(tǒng)宕機(jī)。
所以要盡可能的控制一次性修改的數(shù)據(jù)量。所以會在修改操作的最后添加一個limit的限制條件。


image.png

說明這種語法每次都是從第一行數(shù)據(jù)開始,進(jìn)行匹配,找到符合數(shù)量的數(shù)據(jù)進(jìn)行修改。如果不需要修改也不會再去匹配其他的數(shù)據(jù)。

1.刪除數(shù)據(jù)

基本語法:

delete from table_name where 條件;

高級用法:限制刪除數(shù)量

delete from table_name where 條件 limit 數(shù)量;

11.查詢數(shù)據(jù)

查詢操作的常規(guī)語法:

select */字段  from table_name [where 條件];

完整的查詢語法:
select[select選項] */字段列表[字段別名] from 數(shù)據(jù)源 [where 條件子句][group by 子句][having子句] [order by 子句][limit 子句];

1)select選項

select 選項會對查出來的數(shù)據(jù)進(jìn)行處理
select 選項有兩種:
all :全部的數(shù)據(jù),默認(rèn)的select是all 。
distinct:去除重復(fù),重復(fù)是針對所有查詢的數(shù)據(jù)列。


image.png

2)字段別名
當(dāng)數(shù)據(jù)查詢出來的時候字段的名稱不能夠滿足實(shí)際的需求,特別是在多表查詢的時候,如果表中具有相同的字段。就去要給字段起個別名。
基本語法:

字段名 as 別名
例如 :
name as  姓名
sex as 性別
image.png

3)數(shù)據(jù)源

數(shù)據(jù)源:數(shù)據(jù)的來源。關(guān)系型數(shù)據(jù)庫的數(shù)據(jù)源都是數(shù)據(jù)表。

數(shù)據(jù)源分為:單表數(shù)據(jù)源,多表數(shù)據(jù)源,查詢結(jié)果。
單表數(shù)據(jù)源:

select from table_name;
image.png

多表數(shù)據(jù)源:

select  字段/*  from table1,table2 where 條件;
image.png

查詢結(jié)果來源:數(shù)據(jù)的來源是一條查詢語句。

select * from (select 語句) as 表名;
image.png

4)where子句

where子句是一個判斷條件,比如where id>8;
where子句返回的是 TRUE 或者FALSE,也就是0或者1.
判斷條件:>,<,=,>=,<= , like , between and , in /not in, && ,|| ,! and or
like:模糊匹配,左右兩邊都可以使用% ,%是一個占位符,表示可以是任何符號。


image.png

in 與not in 相當(dāng)于數(shù)組


image.png

where原理:where是唯一一個從磁盤獲取數(shù)據(jù)的時候進(jìn)行判斷的條件,從磁盤取出一條記錄,如果符合條件放入內(nèi)存,否則直接放棄。保證取出來的就是有效數(shù)據(jù)。
練習(xí):
查詢學(xué)生ID為 1或者3或者5的學(xué)生信息
select * from student where id in (1,3,5);
select * from student where id=1 || id=3 || id=5;
查詢學(xué)生年齡在20-25之間的學(xué)生信息:
select * from student where age between 20 and 25;
select * from student where age>=20 && age <=25;

5)group by 子句

group by 字段 : 按照什么字段分組。


image.png

在使用group by 查詢的時候,每一個分組只是出來了一條數(shù)據(jù)。事實(shí)上group by是進(jìn)行分組統(tǒng)計的,而不是進(jìn)行分組查詢的。
group by分組基本上都是和數(shù)據(jù)統(tǒng)計一起使用的。沒有統(tǒng)計函數(shù)的group by 沒有實(shí)際意義。
SQL提供了一組的數(shù)據(jù)統(tǒng)計函數(shù)(聚合函數(shù))。
count():計算結(jié)果的條數(shù)。
max():計算指定字段的最大值。
min():計算制定字段的最小值。
avg():計算制定字段的平均值。
sum():計算指定字段的和。
count:count()的參數(shù)可以使* ,表示所有的字段。也可以指定字段。但是字段的值為null的時候統(tǒng)計不計數(shù)。


image.png

分組排序:ASC/DESC:是對分組的整個結(jié)果進(jìn)行排序,而不是對分組的內(nèi)部進(jìn)行排序。
ASC :升序排序。默認(rèn)的排序方式。

DESC:降序排序。


image.png

多字段分組:
先對一個字段進(jìn)行分組,分組之后在分組中再按照另外一個字段分組。
查詢每個班級男生與女生的數(shù)量
select cid,sex,count(sex) from student group by cid,sex;

需求:有的時候我們進(jìn)行分組之后還需要獲取儲所有分組數(shù)據(jù)的某個字段。
比如說:要獲取儲所有分組之后的人名。
group_concat(字段) --獲取分組中所有數(shù)據(jù)的某個字段

select cid,sex,count(sex),group_concat(name) from student group by cid,sex;
image.png

將上面的顯示結(jié)果按照先class升序排列,然后在按照班級降序排列

image.png

回溯統(tǒng)計:with rollup;
任何一個分組之后都會有一個小組,在這個小組上再次進(jìn)行統(tǒng)計就可以使用with rollup。
注意:with rollup 與order by是互斥的操作。
單字段分組排序,最后統(tǒng)計的是這個分組的總和。多字段分組之后,with rollup 最后統(tǒng)計的是各個分組內(nèi)部的總和各進(jìn)行一次統(tǒng)計,最后再來一次所有分組的統(tǒng)計。


image.png

image.png

6)having子句

having子句與where子句一樣,是進(jìn)行數(shù)據(jù)條件篩選的。
where與having的區(qū)別
where子句是磁盤級別的。只有符合where子句判斷的才會進(jìn)入內(nèi)存,group by是將進(jìn)入內(nèi)存的數(shù)據(jù)進(jìn)行分組。如果需要對分組之后的數(shù)據(jù)進(jìn)行過濾選擇,那么就要使用having子句。
having可以實(shí)現(xiàn)where的所有操作,但是where不一定能夠?qū)崿F(xiàn)having的所有操作。
查詢出所有班級ID大于2的學(xué)生,并且按照班級進(jìn)行分組。

select * from student where classid>2 group by cid;
select * from student  group by cid having cid>2;

查詢所有學(xué)生人數(shù)大于2的班級

select cout(*) from student   group by cid;

select cout(*) from student where cout(*)>2 group  by cid;
image.png

hanving是內(nèi)存級查詢,能夠使用分組,統(tǒng)計以及 別名等進(jìn)入內(nèi)存之后才會產(chǎn)的查詢條件。
總結(jié)


image.png

image.png

注意:
1. 分組查詢只能在having里面使用,不能夠在where里面使用。因為where的時候還沒有分組統(tǒng)計的結(jié)果。
2.having能夠使用字段的別名,但是where不行,原理類似。別名也是在進(jìn)入內(nèi)存之后添加的。
3.能夠使用where盡量使用where,因為where能夠講數(shù)據(jù)提前在進(jìn)入內(nèi)存的時候過濾掉。提高內(nèi)存的利用率。

7)order by 子句

order by:排序,根據(jù)某個字段進(jìn)行升序或者降序排序,需要依賴校對集。
基本語法: order by 字段[ASC |DESC]
排序可以進(jìn)行多字段排序:
多字段排序的時候,先根據(jù)某個字段進(jìn)行排序,然后在排好序的內(nèi)部再根據(jù)第二個字段進(jìn)行排序。所以,第二個字段不會影響第一個字段的排序。


image.png

8)limit 子句

limit子句是一種限制結(jié)果的子句。在一定程度上可以實(shí)現(xiàn)數(shù)據(jù)獲取量的安全性。
limit有兩種使用方式。
第一種:只用來限制記錄的數(shù)量:
limit 數(shù)量;


image.png

第二種使用方式:
limit 起始位置,數(shù)量;


image.png

這種方式主要用于實(shí)現(xiàn)分頁功能。
可以根據(jù)用戶操作的頁碼數(shù)改變limit的起始位置。后面的數(shù)據(jù)量是不會改變的,也就是每頁的分頁數(shù)量數(shù)(展示條數(shù))不會變化的。
起始位置 = (頁數(shù)-1)* 數(shù)量
數(shù)據(jù)庫的內(nèi)容在計數(shù)的時候是從0開始的。
select * from my_student1 limit 5,5;
image.png

四、聯(lián)合查詢

1.使用場景

當(dāng)數(shù)據(jù)表的數(shù)據(jù)量比較大的時候,我們有時會進(jìn)行分表切割,將數(shù)據(jù)按照一定的規(guī)則存放在不同的數(shù)據(jù)表中,但是每個表的數(shù)據(jù)結(jié)構(gòu)是完全相同的,比如我們按照省份進(jìn)行會員的存儲。
查詢同一張表,但是對于數(shù)據(jù)的排序操作是不同的,比如男生身高升序,女生身高降序。
那么在我們需要查詢每個省份前10位用戶的時候就可以使用聯(lián)合查詢。

2.基本語法:

select 語句1
union [union選項]
select 語句2;

注意:兩個數(shù)據(jù)表的查詢可以在不同的數(shù)據(jù)表中,但是查詢結(jié)果的字段以及字段的順序必須一致。

union選項:
union選項與select選項一樣,都是兩個。
all :保留所有。
distinct :去除重復(fù)(默認(rèn)的)。

3.聯(lián)合查詢結(jié)果集排序

看圖說話:
如果第二個查詢語句中具有排序,那么最終會全部按照這個排序進(jìn)行。
select 排序控制:
可以使用()將兩個語句完全分割開查詢。
也可以使用()對單個select進(jìn)行排序。
可以在單個select語句最后添加limit,limit行數(shù)盡量設(shè)置的大些。

五、連接查詢

數(shù)據(jù)庫的數(shù)據(jù)表一般只存儲一個方面的內(nèi)容,所以在有些時候如果想要獲取完整的數(shù)據(jù)就需要使用幾張表之間的關(guān)聯(lián)條件連接多張表進(jìn)行查詢。

需求:查詢一下某個學(xué)生的所有班級信息。
學(xué)生信息保存在學(xué)生表中,班級信息報訊在班級表中,如何根據(jù)學(xué)生的信息查詢到班級表中的信息。
連接查詢的分類:SQL中將連接查詢分為四類:內(nèi)連接,外連接,自然連接和交叉連接。
語法: 左表 join 右表
左表:在join左邊的表
右表:在join右邊的表

1.交叉連接

cross join : 交叉連接。
從一張表中循環(huán)取出每一條記錄,然后與另外一張表中的的每一條數(shù)據(jù)進(jìn)行匹配(無條件匹配),每一條數(shù)據(jù)都會保留。而連接之后的字段也都會保留。這種方式也叫笛卡爾積。
基本語法:左表 cross join 右表 ;=== from 左表,右表
學(xué)生表與教師表交叉連接:
查看兩張表的數(shù)據(jù)。

select * from table_name;

兩張表進(jìn)行交叉連接,理論上會產(chǎn)生4*3 = 12條數(shù)據(jù)。

select * from student cross join teacher;
select * from 是查詢語句
student cross join teacher 整體是數(shù)據(jù)源。

也就是說交叉查詢的數(shù)據(jù)一定是在經(jīng)過全部交叉運(yùn)算之后才會進(jìn)行取數(shù)據(jù)的。
笛卡爾積本身沒有意義,所以交叉連接沒有意義。應(yīng)該竟可能的避免進(jìn)行交叉連接。

2.內(nèi)連接

內(nèi)連接 :[ inner] join;
從左表中取出每一條記錄,去與右表中的每一條記錄進(jìn)行匹配,匹配的結(jié)果必須是某個條件在左表中與在右表中相同再回最終保留這條匹配結(jié)果。
基本語法:左表 【inner 】 join 右邊 on 左表.字段 = 右表.字段
on表示連接條件。左表的字段與右表的字段表示相同的業(yè)務(wù)意義。

select * from student inner join class on  student.cid = class.id ;
當(dāng)字段在兩個表中中是唯一的時候可以省略表名稱

select * from student inner join class on  cid = class.id ;
下面的這表SQL是錯誤的,因為ID在兩個表中都有
select * from student inner join class on  student.cid = id ;

在進(jìn)行多表連接查詢的時候,如果不同的表右相同名稱的字段,需要給字段前加上表的名稱作為前綴,或者使用as起別名。

select s.*,c.name as c_name ,c.root            -- 字段別名
from student as s inner join class as c    -- 表別名
on s.cid = c.id;

內(nèi)連接可以沒有連接條件,在沒有連接條件的情況下。內(nèi)連接相當(dāng)于交叉連接(笛卡爾積)。
內(nèi)連接的on條件可以使用where條件替換。但是通常不會使用where替代on,因為on的效率更高。

3.外鏈接

外鏈接:以某張表為準(zhǔn),取出表中的所有字段然后與另一張表中的每一條記錄進(jìn)行匹配,不管能不能匹配上連接條件,最終都會保存。如果能夠匹配上匹配條件,正確保存,如果不能匹配,那另一張表的字段全部為null值。
外鏈接有兩種:以某個表作為準(zhǔn),那個表作為主表進(jìn)行關(guān)聯(lián)。主表的字段都是有值得。
左外連接(左連接):left join 以左表為主表
右外連接(右連接):right join 以右表為主表
基本語法:
左表 left/right join 右表 on 左表.字段 = 右表.字段;

左外連接
select s.*,c.name as c_name ,c.root     
from student as s left join class as c  
on s.cid = c.id;

右連接
select s.*,c.name as c_name ,c.root     
from student as s right join class as c  
on s.cid = c.id;

左連接與右連接的數(shù)據(jù)量都是等于主表的數(shù)據(jù)條數(shù)。
左連接與右連接的主表是不一樣的,但是顯示的時候總是左表的字段在左,右表的字段在右。左右連接可以相互之間互相轉(zhuǎn)換。只是數(shù)據(jù)表的順序不一樣。

4.自然連接

自然連接:natural join :自動連接,自動匹配連接條件。
系統(tǒng)以字段的名稱作為匹配的條件(同名的字段作為連接條件,多個同名字段都會作為條件)
自然連接也分為:自然內(nèi)連接 和 自然外鏈接
自然內(nèi)連接:
自然外鏈接:

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容