MySQL 數據庫的約束和表的關係


MySQL

I. 數據庫的約束

1. 概述

  • 作用:對錶中的數據進行限定,保證數據的正確性、有效性和完整性。

2. 分類

primary key:主鍵約束,要求表中有一個字段,唯一且非空,通常使用 ID 作爲主鍵

unique:唯一約束

not null:非空約束

default:默認值

foreign key:外鍵約束

3. 主鍵約束 primary key

a. 作用

  • 主鍵的作用一條數據的唯一標識,限定某一列的值非空且唯一。

b. 語法

1. 設置主鍵約束
	1)創建表
		create table 表名(
		  id int primary key,
		  ...
		  ...
		);
	2)已有表
		alter tabe 表名 add primary key(id);
		
2. 特點:
	一張表只能有一個主鍵約束,但是可以設置聯合主鍵,即:
		PRIMARY KEY (`id`,`keyword`)
	刪除也是非常簡單隻要: 
		ALTER TABLE test DROP PRIMARY KEY ,ADD PRIMARY KEY (`id`); 
	如果僅僅是刪除聯合主鍵會報錯: 
		ERROR 1075 (42000): Incorrect table definition; there can be only one auto column and it must be defined as a key 
		
3. 自增器
	1)創建表
		create table 表名(
			id int priamry key auto_increment,
			...
			...
		);
	2)特點:自增器起始值爲1,可以手動指定
		alter table 表名 auto_increment=起始值;		
		
4. 刪除主鍵約束
	1)先移出自增器
		alter table 表名 modify id int;
	2)才能刪除主鍵約束
		alter table 表名 drop primary key;
  • MySQL 中的命名規範:單詞與單詞之間使用下劃線分割。

c. 示例

-- 主鍵約束
-- 給student表添加主鍵約束
ALTER TABLE student ADD PRIMARY KEY(id);

-- 創建表時指定主鍵約束
CREATE TABLE stu1(
 id INT PRIMARY KEY,
 `name` VARCHAR(32)
);
-- 插入數據測試
INSERT INTO stu1 VALUES(1,'jack');
-- Duplicate entry '1' for key 'PRIMARY' 錯誤:主鍵不能重複
INSERT INTO stu1 VALUES(1,'lucy');
-- Column 'id' cannot be null 錯誤:主鍵不能爲空
INSERT INTO stu1 VALUES(NULL,'lucy');

-- 我想讓name字段,也作爲主鍵使用...
-- Multiple primary key defined -- 錯誤:主鍵被重複定義了
ALTER TABLE stu1 ADD PRIMARY KEY(`name`);



-- 聯合主鍵(主鍵字段完全相同,在進行約束的限定)
CREATE TABLE stu2(
 id INT ,
 `name` VARCHAR(32),
 PRIMARY KEY(id,`name`)
);
-- 插入數據測試
INSERT INTO stu2 VALUES(1,'jack');
INSERT INTO stu2 VALUES(1,'lucy');
-- Duplicate entry '1-lucy' for key 'PRIMARY' 錯誤
INSERT INTO stu2 VALUES(1,'lucy');


-- 自增器
CREATE TABLE stu3(
  id INT PRIMARY KEY AUTO_INCREMENT,
  `name` VARCHAR(32)
);
-- 插入數據測試
INSERT INTO stu3 VALUES(1,'jack');
INSERT INTO stu3 VALUES(NULL,'jack');
INSERT INTO stu3 VALUES(3,'jack');
INSERT INTO stu3 VALUES(NULL,'jack');
INSERT INTO stu3 VALUES(10,'jack');
INSERT INTO stu3 VALUES(NULL,'jack');

-- 設置自增器起始值
ALTER TABLE stu3 AUTO_INCREMENT=1000;
INSERT INTO stu3 VALUES(NULL,'jack');

-- delete(橡皮擦) 和 truncat(撕紙) 區別:delete繼續主鍵約束自增器,truncate清除主鍵約束自增器
DELETE FROM stu3;
INSERT INTO stu3 VALUES(NULL,'jack');


TRUNCATE TABLE stu3;
INSERT INTO stu3 VALUES(NULL,'jack');


-- 1)先移出自增器
	ALTER TABLE stu3 MODIFY id INT;
-- 2)才能刪除主鍵約束
	ALTER TABLE stu3 DROP PRIMARY KEY;

d. 主鍵與唯一非空

  • 問題:唯一 + 非空 = 主鍵 嗎?
    • 不等於,主鍵約束一張表只能有一個,唯一 + 非空 設置多個。
  • 主鍵的特點:
    • 唯一
    • 非空
    • 被引用
  • 某一列設置了非空與唯一與主鍵的區別: 不能被其他表所引用。
-- 創建一個部門表
CREATE TABLE dept(
	id INT PRIMARY KEY AUTO_INCREMENT,  -- tab鍵是自動補全
	NAME VARCHAR(10) NOT NULL UNIQUE  -- 非空, 唯一。 
);
     
INSERT INTO dept VALUES(NULL,'財務部');
     
 -- 創建一個員工表
CREATE TABLE emp(
	id INT PRIMARY KEY AUTO_INCREMENT,
	NAME VARCHAR(10),
	dept_id INT, -- 員工所屬的部門名稱
	CONSTRAINT fk_emp_dept FOREIGN KEY(dept_id) REFERENCES dept(id)-- 建立外鍵關係
);

4. 唯一約束 unique

a. 作用

  • 限定某一列的值不能重複,可以出現多個 null。

b. 語法

1. 創建表時設置唯一約束
		create table 表名(
			列名 數據類型 unique,
			...
			...
		);

c. 示例

-- 唯一約束
CREATE TABLE stu4(
  id INT PRIMARY KEY AUTO_INCREMENT,
  `name` VARCHAR(32) UNIQUE 
);

INSERT INTO stu4 VALUES(1,'jack');
-- Duplicate entry 'jack' for key 'name' 錯誤:名稱重複了
INSERT INTO stu4 VALUES(2,'jack');
INSERT INTO stu4 VALUES(3,NULL);
INSERT INTO stu4 VALUES(4,NULL);

5. 非空約束 not null

a. 作用

  • 限定某一列的值不能爲 null。

b. 語法

1. 創建表時設置非空約束
		create table 表名(
			列名 數據類型 not null,-- 非空約束
			列名 數據類型 unique not null,-- (唯一+非空)
		
		);

c. 示例

-- 唯一+非空
CREATE TABLE stu5(
 id INT PRIMARY KEY AUTO_INCREMENT,
 `name` VARCHAR(32) UNIQUE NOT NULL
);

INSERT INTO stu5 VALUES(1,'jack');
-- Column 'name' cannot be null 錯誤:名稱不能爲空
INSERT INTO stu5 VALUES(2,NULL);

6. 默認值 default

a. 作用

  • 限定某一列的默認值,再沒有指定的情況下所有列的默認值爲 null。

b. 語法

1. 創建表設置默認值
		create table 表名(
		  列名 數據類型 default 默認值,
		  ...
		  ...
		);

c. 示例

-- 默認值
CREATE TABLE stu6(
  id INT PRIMARY KEY AUTO_INCREMENT,
  `name` VARCHAR(32),
  sex VARCHAR(5) DEFAULT '男'
);
INSERT INTO stu6(id,`name`) VALUES(1,'小張');
INSERT INTO stu6(id,`name`,sex) VALUES(2,'小劉','女');
-- 因爲這裏指定了默認值爲男,如果再插入null,會把默認值覆蓋...
INSERT INTO stu6 VALUES(3,'小王',NULL);

II. 表的關係

1. 概述

  • 現實生活中,(班級)實體與(學生)實體之間肯定是有關係的,那麼在設計表的時候,就應該體現出(班級)表與(學生)表之間的這種關係。
  • 簡稱:關係型數據庫(Relation DBMS)

2. 分類

  1. 一對多
    • 應用場景:班級和學生、部門和員工。
    • 解釋:一個班級下面有多名同學,多名同學屬於某一個班級。
  2. 多對多
    • 應用場景:老師和學生、學生和課程。
    • 解釋:一名老師可以教導多名學生,一名學生可以被多個老師教導。
  3. 一對一
    • 應用場景:公民和身份證號、公司和註冊地。
    • 解釋:一個公民只能有一個身份證號,一個身份證號對應一個公民。

a. 一對多

  • 例如,班級和學生。
    在這裏插入圖片描述
  • 稱“一”方爲:主表或一表;稱“多”方爲:從表或多表。
  • 建立原則:在從表中添加一個字段(列),字段名(主表名_id)類型與主表的主鍵一致。這個字段稱作外鍵,通過主外鍵關聯,就建立兩張表的關聯了。
-- 創建新庫
CREATE DATABASE day19_pro;
USE day19_pro;

-- 一對多

-- 班級表(主表)
CREATE TABLE class(
  id INT PRIMARY KEY AUTO_INCREMENT,
  `name` VARCHAR(32)
);
INSERT INTO class VALUES(1,'java一班');
INSERT INTO class VALUES(2,'java二班');

-- 學生表(從表)
CREATE TABLE student(
  id INT PRIMARY KEY AUTO_INCREMENT,
  `name` VARCHAR(32),
  class_id INT -- 外鍵字段
  
);
INSERT INTO student VALUES(1,'流川楓',1);
INSERT INTO student VALUES(2,'櫻木花道',1);
INSERT INTO student VALUES(3,'大猩猩',2);
INSERT INTO student VALUES(4,'赤木晴子',2);

-- 通過班級找學生
SELECT * FROM student WHERE class_id =1;

-- 通過學生找班級
SELECT * FROM class WHERE id = 2;


-- 給學生表添加外鍵約束
ALTER TABLE student ADD CONSTRAINT class_id_fk FOREIGN KEY(class_id) REFERENCES class(id);

-- 刪除學生表的外鍵約束
ALTER TABLE student DROP FOREIGN KEY class_id_fk;

b. 多對多

  • 例如,學生和課程。
    在這裏插入圖片描述
  • 建表原則:由兩個一對多組成。創建第三張表(從表,又稱中間表),在中間表中添 2 個外鍵字分別指向各自的主鍵,通常中間表的這 2 個外鍵字稱作聯合主鍵。
-- 多對多

-- 課程表(主表)
CREATE TABLE course(
  id INT PRIMARY KEY AUTO_INCREMENT,
  `name` VARCHAR(32)
);
INSERT INTO course VALUES(1,'java');
INSERT INTO course VALUES(2,'ui');
INSERT INTO course VALUES(3,'美容美髮');
INSERT INTO course VALUES(4,'挖掘機');
-- 中間表(從表)
CREATE TABLE sc(
  s_id INT,
  c_id INT,
  PRIMARY KEY(s_id,c_id)
);
INSERT INTO sc VALUES(1,1);
INSERT INTO sc VALUES(1,2);
INSERT INTO sc VALUES(2,1);
INSERT INTO sc VALUES(2,3);

-- 聯合主鍵,可以處理校驗重複選修問題
INSERT INTO sc VALUES(1,1);


-- 給中間表增加外鍵約束
ALTER TABLE sc ADD CONSTRAINT s_id_fk FOREIGN KEY(s_id) REFERENCES student(id);
ALTER TABLE sc ADD CONSTRAINT c_id_fk FOREIGN KEY(c_id) REFERENCES course(id);

-- 流川楓不能選修,不存在的課程
INSERT INTO sc VALUES(1,6);

c. 表與實體類

  • 數據庫的表是映射的 Java 中的類。
  • 表與表的關係在 Java 中會用類中的某個字段等形式體現出來,但不會有什麼“中間類”。
  • 多對多可以分爲兩個一對多,而一對多的表的關係在 Java 類中以 包含 關係體現,比如,一個班級有多個學生。
class 班級 {
	private List<學生> 學生List;
}

d. 一對一

  • 一對一關係在實際開發中用的並不多,因爲可以辦關聯字段設計在同一張表。
  • 例如,公司和註冊地。
-- 一對一

-- 公司表
CREATE TABLE company(
 id INT PRIMARY KEY AUTO_INCREMENT,
 `name` VARCHAR(32)
);
INSERT INTO company VALUES(1,'拼多多');
INSERT INTO company VALUES(2,'傳智播客');
-- 地址表
CREATE TABLE address(
 id INT PRIMARY KEY AUTO_INCREMENT, -- 同時也作爲外鍵
 `name` VARCHAR(32),
 CONSTRAINT id_fk FOREIGN KEY(id) REFERENCES company(id)
);
INSERT INTO address VALUES(1,'上海');
INSERT INTO address VALUES(2,'江蘇沭陽');

3. 外鍵約束 foreign key references

a. 作用

  • 限定二張表有關係的數據,保證數據的正確性、有效性和完整性。
  • 在企業開發過程中:傳統的項目需要外鍵約束,互聯網項目因爲性能問題絕對不用。實際開發中,大部分項目會對數據庫禁止使用約束。

b. 特點

  1. 主表不能刪除從表已引用的數據。
  2. 從表不能添加主表未擁有的數據。
  3. 先添加主表數據再添加從表數據。
  4. 先刪除從表數據再刪除主表數據。
  5. 外鍵約束允許爲空但不能是錯的。

c. 語法

1. 在從表中添加外鍵約束
	1)創建表
		create table 表名(
			列名 數據類型,
			[constraint] [約束名] foreign key(外鍵列) references 主表(主鍵)
		);		
	2)已有表
		alter table 表名 add [constraint] [約束名] foreign key(外鍵列) references 主表(主鍵);
		
		
2. 刪除外鍵約束
		alter table 表名 drop foreign key 約束名;

4. 外鍵的級聯

a. 作用

  • 對主表進行修改、刪除的時候自動級聯到從表中(即修改了主表,那麼從表的數據跟着變化)

b. 語法

on update cascade 更新級聯

on delete cascade 刪除級聯


CREATE TABLE 表名(
  CONSTRAINT 外鍵名稱 FOREIGN KEY(從表外鍵列) REFERENCES 主表(主鍵列) on update cascade || on delete cascade   -- 建立外鍵關係,並且創建外鍵的級聯關係
);

c. 示例

-- 創建一個部門表
CREATE TABLE dept(
   id INT PRIMARY KEY AUTO_INCREMENT,  -- tab鍵是自動補全
    
   NAME VARCHAR(10) NOT NULL UNIQUE  -- 非空, 唯一。 
);

INSERT INTO dept VALUES(NULL,'財務部');

-- 創建一個員工表
CREATE TABLE emp(
  id INT PRIMARY KEY AUTO_INCREMENT,
  NAME VARCHAR(10),
  dept_id INT, -- 員工所屬的部門名稱
  CONSTRAINT fk_emp_dept FOREIGN KEY(dept_id) REFERENCES dept(id)
  ON UPDATE CASCADE ON DELETE CASCADE-- 建立外鍵關係
);

INSERT INTO emp VALUES(NULL,'老闆',1);
INSERT INTO emp VALUES(NULL,'小明',2);
INSERT INTO emp VALUES(NULL,'小陳',2);
INSERT INTO emp VALUES(NULL,'花花',2);

原文鏈接:https://qwert.blog.csdn.net/article/details/105840314

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章