1. 程式人生 > >MySQL學習筆記(三)

MySQL學習筆記(三)

集中 外鍵 部分 進行 drop 非空約束 類型 級聯操作 space

1 數據約束

1.1什麽數據約束

對用戶操作表的數據進行約束

1.2 默認值

作用: 當用戶對使用默認值的字段不插入值的時候,就使用默認值。

註意:

1)對默認值字段插入null是可以的。

2)對默認值字段可以插入非null

-- 1.1 默認值

CREATE TABLE student(

id INT,

NAME VARCHAR(20),

address VARCHAR(20) DEFAULT ‘山東淄博‘ -- 默認值

)

DROP TABLE student;

-- 當字段沒有插入值的時候,mysql自動給該字段分配默認值

INSERT INTO student(id,NAME) VALUES(1,‘張三

‘);

-- 註意:默認值的字段允許為null

INSERT INTO student(id,NAME,address) VALUE(2,‘李四‘,NULL);

INSERT INTO student(id,NAME,address) VALUE(3,‘王五‘,‘山東淄博‘);

1.3 非空

作用: 限制字段必須賦值

註意:

1)非空字符必須賦值

2)非空字符不能賦null

-- 1.2 非空

-- 需求: gender字段必須有值(不為null

CREATE TABLE student(

id INT,

NAME VARCHAR(20),

gender VARCHAR(2) NOT NULL -- 非空

)

-- 非空字段必須賦值

INSERT INTO student(id,NAME) VALUES(1,‘李四‘);

-- 非空字符不能插入null

INSERT INTO student(id,NAME,gender) VALUES(1,‘李四‘,NULL);

1.4 唯一

作用: 對字段的值不能重復

註意:

1)唯一字段可以插入null

2)唯一字段可以插入多個null

-- 1.3 唯一

CREATE TABLE student(

id INT UNIQUE, -- 唯一

NAME VARCHAR(20)

)

INSERT INTO student(id,NAME) VALUES(1,‘zs‘);

INSERT INTO student(id,NAME) VALUES(1,‘lisi‘); -- ERROR 1062 (23000): Duplicate entry ‘1‘ for key ‘id‘

INSERT INTO student(id,NAME) VALUES(2,‘lisi‘);

1.5 主鍵

作用: 非空+唯一

註意:

1)通常情況下,每張表都會設置一個主鍵字段。用於標記表中的每條記錄的唯一性。

2)建議不要選擇表的包含業務含義的字段作為主鍵,建議給每張表獨立設計一個非業務含義的id字段。

-- 1.4 主鍵(非空+唯一)

DROP TABLE student;

CREATE TABLE student(

id INT PRIMARY KEY, -- 主鍵

NAME VARCHAR(20)

)

INSERT INTO student(id,NAME) VALUES(1,‘張三‘);

INSERT INTO student(id,NAME) VALUES(2,‘張三‘);

-- INSERT INTO student(id,NAME) VALUES(1,‘李四‘); -- 違反唯一約束: Duplicate entry ‘1‘ for key ‘PRIMARY‘

-- insert into student(name) value(‘李四‘); -- 違反非空約束: ERROR 1048 (23000): Column ‘id‘ cannot be null

1.6 自增長

作用: 自動遞增

-- 1.5 自增長

CREATE TABLE student(

id INT(4) ZEROFILL PRIMARY KEY AUTO_INCREMENT, -- 自增長,從0開始 ZEROFILL 零填充

NAME VARCHAR(20)

)

-- 自增長字段可以不賦值,自動遞增

INSERT INTO student(NAME) VALUES(‘張三‘);

INSERT INTO student(NAME) VALUES(‘李四‘);

INSERT INTO student(NAME) VALUES(‘王五‘);

SELECT * FROM student;

-- 不能影響自增長約束

DELETE FROM student;

-- 可以影響自增長約束

TRUNCATE TABLE student;

1.7 外鍵

作用:約束兩種表的數據

出現兩種表的情況:

解決數據冗余高問題: 獨立出一張表

例如: 員工表 部門表

問題出現:在插入員工表數據的時候,員工表的部門ID字段可以隨便插入!!!!!

使用外鍵約束:約束插入員工表的部門ID字段值

解決辦法: 在員工表的部門ID字段添加一個外鍵約束

-- 部門表(主表)

CREATE TABLE dept(

id INT PRIMARY KEY,

deptName VARCHAR(20)

)

-- 修改員工表(副表/從表)

CREATE TABLE employee(

id INT PRIMARY KEY,

empName VARCHAR(20),

deptId INT,-- 把部門名稱改為部門ID

-- 聲明一個外鍵約束

CONSTRAINT emlyee_dept_fk FOREIGN KEY(deptId) REFERENCES dept(id)

-- 外鍵名稱 外鍵 參考表(參考字段)

)

註意:

1)被約束的表稱為副表,約束別人的表稱為主表,外鍵設置在副表上的!!!

2)主表的參考字段通用為主鍵!

3)添加數據: 先添加主表,再添加副表

4)修改數據: 先修改副表,再修改主表

5)刪除數據: 先刪除副表,再刪除主表

-- 1.6 外鍵約束

-- 員工表

CREATE TABLE employee(

id INT PRIMARY KEY,

empName VARCHAR(20),

deptName VARCHAR(20) -- 部門名稱

)

INSERT INTO employee VALUES(1,‘張三‘,‘軟件開發部‘);

INSERT INTO employee VALUES(2,‘李四‘,‘軟件開發部‘);

INSERT INTO employee VALUES(3,‘王五‘,‘應用維護部‘);

SELECT * FROM employee;

-- 添加員工,部門名稱的數據冗余高

INSERT INTO employee VALUES(4,‘陳六‘,‘軟件開發部‘);

-- 解決數據冗余高的問題:給冗余的字段放到一張獨立表中

-- 獨立設計一張部門表

CREATE TABLE dept(

id INT PRIMARY KEY,

deptName VARCHAR(20)

)

DROP TABLE employee;

-- 修改員工表

CREATE TABLE employee(

id INT PRIMARY KEY,

empName VARCHAR(20),

deptId INT,-- 把部門名稱改為部門ID

-- 聲明一個外鍵約束

CONSTRAINT emlyee_dept_fk FOREIGN KEY(deptId) REFERENCES dept(id) ON UPDATE CASCADE ON DELETE CASCADE -- ON CASCADE UPDATE :級聯修改

-- 外鍵名稱 外鍵 參考表(參考字段)

)

INSERT INTO dept(id,deptName) VALUES(1,‘軟件開發部‘);

INSERT INTO dept(id,deptName) VALUES(2,‘應用維護部‘);

INSERT INTO dept(id,deptName) VALUES(3,‘秘書部‘);

INSERT INTO employee VALUES(1,‘張三‘,1);

INSERT INTO employee VALUES(2,‘李四‘,1);

INSERT INTO employee VALUES(3,‘王五‘,2);

INSERT INTO employee VALUES(4,‘陳六‘,3);

-- 問題: 該記錄業務上不合法,員工插入了一個不存在的部門數據

INSERT INTO employee VALUES(5,‘陳六‘,4); -- 違反外鍵約束: Cannot add or update a child row: a foreign key constraint fails (`day16`.`employee`, CONSTRAINT `emlyee_dept_fk` FOREIGN KEY (`deptId`) REFERENCES `dept` (`id`))

-- 1)當有了外鍵約束,添加數據的順序: 先添加主表,再添加副表數據

-- 2)當有了外鍵約束,修改數據的順序: 先修改副表,再修改主表數據

-- 3)當有了外鍵約束,刪除數據的順序: 先刪除副表,再刪除主表數據

-- 修改部門(不能直接修改主表)

UPDATE dept SET id=4 WHERE id=3;

-- 先修改員工表

UPDATE employee SET deptId=2 WHERE id=4;

-- 刪除部門

DELETE FROM dept WHERE id=2;

-- 先刪除員工表

DELETE FROM employee WHERE deptId=2;

SELECT * FROM dept;

SELECT * FROM employee;

1.8 級聯操作

問題: 當有了外鍵約束的時候,必須先修改或刪除副表中的所有關聯數據,才能修改或刪除主表!但是,我們希望直接修改或刪除主表數據,從而影響副表數據。可以使用級聯操作實現!!!

級聯修改: ON UPDATE CASCADE

級聯刪除: ON DELETE CASCADE

CREATE TABLE employee(

id INT PRIMARY KEY,

empName VARCHAR(20),

deptId INT,-- 把部門名稱改為部門ID

-- 聲明一個外鍵約束

CONSTRAINT emlyee_dept_fk FOREIGN KEY(deptId) REFERENCES dept(id) ON UPDATE CASCADE ON DELETE CASCADE -- ON CASCADE UPDATE :級聯修改

-- 外鍵名稱 外鍵 參考表(參考字段)

)

註意: 級聯操作必須在外鍵基礎上使用

-- 級聯修改(修改)

-- 直接修改部門

UPDATE dept SET id=5 WHERE id=4;

-- 級聯刪除

-- 直接刪除部門

DELETE FROM dept WHERE id=1;

2 連接查詢(多表查詢)

2.1基本含義

連接就是指兩個或2個以上的表(數據源)“連接起來成為一個數據源”。

實際上,兩個表的完全的連接是這樣的一個過程:

左邊的表的每一行,跟右邊的表的每一行,兩兩互相“橫向對接”後所得到的所有數據行的結果。

註意:連接之後,並非形成了一個新的數據表,而只是一種“內存形態”。

2.2連接語法的基本形式

from 1 [連接方式] join 2 [on 連接條件]

連接的結果可以當作一個“表”來使用。常用有以下幾種連接方式:

2.3交叉連接:

實際上,交叉連接是將兩個表不設定任何條件的連接結果。

交叉連接通常也被叫做“笛卡爾積”——數學上可能比較多。

語法:

from 1 [cross] join 2 ; //可見交叉連接只是沒有on條件而已。

cross這個詞也可以省略,還可以使用inner這個詞代替

1

2

交叉:

2.4內連接:

語法:

from 1 [inner] join 2 on 1.字段1=2.字段2

含義:找出(過濾)在交叉連接的結果表中的表1的字段1的值等於表2的字段2的值的那些行。

分析交叉連接的“無意義性”,以及內連接的“有意義性”:

先看交叉連接:

再看內連接:

可見,在現實的常見需求中,上述內連接的結果就都是“有意義”的數據了。

也可以指定只列出其中部分字段:

SELECT t1.pro_id, pro_name, price, t2.protype_name FROM product as t1 join `product_type` as t2 on t1.protype_id=t2.protype_id WHERE 1

結果為:

2.5左[外]連接:

形式:

from 1 left [outer] join 2 on 連接條件。

說明:

1,這裏,left是關鍵字。

2,連接條件跟內連接一樣。

3,含義是:內連接的結果基礎上,加上左邊表中所有不符合連接條件的數據,相應放右邊表的字段的位置就自動補為“null”值。

則左連接結果為:

2.6右[外]連接:

右連接跟左連接恰恰相反:

形式:

from 1 right [outer] join 2 on 連接條件。

說明:

1,這裏,right是關鍵字。

2,連接條件跟內連接一樣。

3,含義是:在內連接的結果基礎上,加上右邊表中所有不符合連接條件的數據,相應本應放左邊表的字段的位置就自動補為“null”值。

2.7全[外]連接:

形式:

from 1 full [outer] join 2 on 連接條件;

說明:

1,含義:其實是左右連接的“並集”(消除重復項),即內連接的結果,加上左表中不滿足條件的所有行(右邊對應補null),再加上,右表中不滿足條件的所有行(左邊對應補null)。

2mysql中其實不認識全[]連接語法,即mysql這個軟件本身不支持全連接的語法。

3,此概念在其他數據庫有的存在,了解就可以。

2.8連接查詢舉例:

原始數據:

1:找出索尼4G手機所屬類別名稱:

2,找出所有屬於手機數碼的產品:

3.什麽叫子查詢

子查詢就是把一個查詢的結果當作另一個查詢的條件。

使用in子查詢

in的基本語法形式為:

where 操作數 in (1,值2....

in子查詢就是:

where 操作數 in ( 列子查詢 );

含義:

表示該操作數(字段值) 等於 該子查詢的其中任意一個只,就算滿足條件。

舉例:

找出所有帶“電”字的類別的產品

第一步:找出所有帶“電”字的類別ID

第二步:根據結果找出這些類別的產品:

select * from product where protype_id in (1, 3); ==

select * from product where protype_id in (

select protype_id from product_type where protype_name like ‘%%‘

);

4.聯合查詢

聯合查詢的關鍵字是: union

基本含義

聯合查詢就是將兩個select語句的查詢結果“層疊”到一起成為一個“大結果”。

兩個查詢結果的能夠進行“聯合”的先覺條件是:結果字段數相等。

語法形式:

select 語句1

union [ALL | DISTINCT]

select 語句2

說明:

1,兩個select語句的輸出段(結果字段)一樣數目一樣,應用中通常類型一樣才有意義。

2,結果集中的字段以第一個select語句的字段為準。

3,第一個select語句的字段可以做別名,但如果做別名,則後續的wheregrouporder等子句應該用該別名。

4,聯合查詢默認是會消除重復項的(DISTINCT),要想不消除,則必須明確些“ALL”。

5,如果要對整個聯合結果進行排序或limit,則應該對各自的select語句加括號:

select 語句1

union

select 語句2

order by ..... limit ....

MySQL學習筆記(三)