MySQL(三)数据库的六种约束、表的关系、三大范式
文章目錄
- 數據庫約束
- NOT NULL(非空約束)
- UNIQUE(唯一約束)
- DEFAULT(缺省約束)
- PRIMARY KEY(主鍵約束)
- AUTO_INCREMENT 自增
- FOREIGN KEY(外鍵約束)
- CHECK(檢查約束)
- 表的設計
- 表的關系
- 一對一
- 一對多
- 多對多
- 三大范式
- 第一范式
- 第二范式
- 第三范式
數據庫約束
數據庫中主要有六種約束
- NOT NULL(非空約束) - 指示某列不能存儲 NULL 值。
- UNIQUE(唯一約束) - 保證某列的每行必須有唯一的值。
- DEFAULT(缺省約束) - 規(guī)定沒有給列賦值時的默認值。
- PRIMARY KEY(主鍵約束) - NOT NULL 和 UNIQUE 的結合。確保某列(或兩個列多個列的結合)有唯一標識,有助于更容易更快速地找到表中的一個特定的記錄。
- FOREIGN KEY(外鍵約束) - 保證一個表中的數據匹配另一個表中的值的參照完整性。
- CHECK(檢查約束) - 保證列中的值符合指定的條件。對于MySQL數據庫,對CHECK子句進行分析,但是忽略CHECK子句。
NOT NULL(非空約束)
指示某列不能存儲 NULL 值。
例如在這里對birth添加非空約束
create table student(id int,age int,name varchar(8),birth date NOT NULL,math decimal(10, 2),english decimal(10, 2) );接著向其中插入數據,如果不給birth一個確定的值,就會導致插入失敗
INSERT INTO student VALUES(6, 13, "馬六", NULL, 85.9, 95.4);ERROR 1048 (23000): Column 'birth' cannot be null INSERT INTO student(id, age, name) values(3, 16, "李華");ERROR 1364 (HY000): Field 'birth' doesn't have a default value添加了非空約束后該列就不能為空,必須要給一個值
UNIQUE(唯一約束)
保證某列的每行必須有唯一的值,即對于添加了唯一約束的數據項不能有重復
//對id添加unique約束 create table student(id int UNIQUE,age int,name varchar(8),birth date,math decimal(10, 2),english decimal(10, 2) );//插入第一條數據 INSERT INTO student VALUES(1, 11, "李華", 20200812, 76.5, 87.5);Query OK, 1 row affected (0.002 sec)//插入成功//插入第二條數據,除了id與第一條相同,其他全都不同 INSERT INTO student VALUES(1, 15, "李梅", 20200813, 88.5, 90.5);ERROR 1062 (23000): Duplicate entry '1' for key 'id'//報錯,id必須唯一,不能重復DEFAULT(缺省約束)
規(guī)定沒有給列賦值時的默認值。
//為math和english添加缺省約束,缺省值為60 create table student(id int,age int,name varchar(8),birth date,math decimal(10, 2) DEFAULT 60,english decimal(10, 2) DEFAULT 60 );//插入數據,沒有指定math和english INTO student(id, age, name) values(3, 16, "李華"); Query OK, 1 row affected (0.001 sec)select * from student; +------+------+--------+-------+-------+---------+ | id | age | name | birth | math | english | +------+------+--------+-------+-------+---------+ | 3 | 16 | 李華 | NULL | 60.00 | 60.00 | +------+------+--------+-------+-------+---------+ //沒有指定時會被修改為默認值PRIMARY KEY(主鍵約束)
NOT NULL 和 UNIQUE 的結合。確保某列(或兩個列多個列的結合)有唯一標識,有助于更容易更快速地找到表中的一個特定的記錄。
主鍵的特性即非空且唯一,如果在沒有指定主鍵的時候,如果某一列具有非空且唯一的特性,他就會被暫定為主鍵,但是主鍵只能有一個。
//id為非空且唯一 create table student(id int NOT NULL UNIQUE,age int,name varchar(8),birth date,math decimal(10, 2),english decimal(10, 2) );desc student;//可以看到id成為了主鍵 +---------+---------------+------+-----+---------+-------+ | Field | Type | Null | Key | Default | Extra | +---------+---------------+------+-----+---------+-------+ | id | int(11) | NO | PRI | NULL | | | age | int(11) | YES | | NULL | | | name | varchar(8) | YES | | NULL | | | birth | date | YES | | NULL | | | math | decimal(10,2) | YES | | NULL | | | english | decimal(10,2) | YES | | NULL | | +---------+---------------+------+-----+---------+-------+//使用PRIMARY KEY DROP TABLE student; create table student(id int PRIMARY KEY,age int,name varchar(8),birth date,math decimal(10, 2),english decimal(10, 2) ); DESC student;+---------+---------------+------+-----+---------+-------+ | Field | Type | Null | Key | Default | Extra | +---------+---------------+------+-----+---------+-------+ | id | int(11) | NO | PRI | NULL | | | age | int(11) | YES | | NULL | | | name | varchar(8) | YES | | NULL | | | birth | date | YES | | NULL | | | math | decimal(10,2) | YES | | NULL | | | english | decimal(10,2) | YES | | NULL | | +---------+---------------+------+-----+---------+-------+但是非空且唯一并不代表主鍵,主鍵只能有一個,而非空不唯一可以有多個,如果有多個非空不唯一,則只會有第一個是主鍵
//將id和name都設置為非空且唯一 DROP TABLE student; create table student(id int NOT NULL UNIQUE,age int,name varchar(8) NOT NULL UNIQUE,birth date,math decimal(10, 2),english decimal(10, 2) );desc student;//id和name都是非空且唯一,但是只有id是主鍵 +---------+---------------+------+-----+---------+-------+ | Field | Type | Null | Key | Default | Extra | +---------+---------------+------+-----+---------+-------+ | id | int(11) | NO | PRI | NULL | | | age | int(11) | YES | | NULL | | | name | varchar(8) | NO | UNI | NULL | | | birth | date | YES | | NULL | | | math | decimal(10,2) | YES | | NULL | | | english | decimal(10,2) | YES | | NULL | | +---------+---------------+------+-----+---------+-------+如果想要使用多個列共同作為主鍵,就得使用下面這種語法
//在末尾表明組合主鍵的列有哪些 create table student(id int,age int,name varchar(8),birth date,math decimal(10, 2),english decimal(10, 2),PRIMARY KEY(id, name) );+---------+---------------+------+-----+---------+-------+ | Field | Type | Null | Key | Default | Extra | +---------+---------------+------+-----+---------+-------+ | id | int(11) | NO | PRI | NULL | | | age | int(11) | YES | | NULL | | | name | varchar(8) | NO | PRI | NULL | | | birth | date | YES | | NULL | | | math | decimal(10,2) | YES | | NULL | | | english | decimal(10,2) | YES | | NULL | | +---------+---------------+------+-----+---------+-------+//不能直接在多個列后面加上PRIMARY KEY,那樣的意思是創(chuàng)建多個主鍵,但是主鍵是唯一的,所以會報錯 //錯誤寫法 create table student(id int PRIMARY KEY,age int,name varchar(8) PRIMARY KEY,birth date,math decimal(10, 2),english decimal(10, 2) );ERROR 1068 (42000): Multiple primary key defined//報錯,定義了多個主鍵AUTO_INCREMENT 自增
添加自增屬性的項必須為數字,并且必須為主鍵,并且只有缺省的時候才會使用自增。
- 表中數據從1開始自增,每次為上一條記錄的+1
- 如果刪除了表中數據,序號并不會重置,而是繼續(xù)從刪除的位置自增
FOREIGN KEY(外鍵約束)
保證一個表中的數據匹配另一個表中的值的參照完整性。
當我們的表中有數據與另一個表有關聯的時候,就需要用到外鍵約束。例如學生表中存儲了班級的信息,但是在班級表中并沒有這個班級存在,就會導致數據出現沖突,所以必須將兩個表關聯起來。
語法
FOREIGN KEY (外鍵項) REFERENCES 關聯表名(關聯表中的對應項) create table classes(id int PRIMARY KEY AUTO_INCREMENT );create table student(id int PRIMARY KEY AUTO_INCREMENT,age int,name varchar(8),classid int,FOREIGN KEY (classid) REFERENCES classes(id) );//添加班級 insert into classes values(1); insert into classes values(2);//插入學生信息 //插入成功 INSERT INTO student(name, classid) VALUES("張三", 1); INSERT INTO student(name, classid) VALUES("李四", 2);//插入失敗,3號班級并不存在 INSERT INTO student(name, classid) VALUES("王五", 3); ERROR 1452 (23000): Cannot add or update a child row: a foreign key constraint fails (`lee`.`student`, CONSTRAINT `student_ibfk_1` FOREIGN KEY (`classid`) REFERENCES `classes` (`id`))CHECK(檢查約束)
保證列中的值符合指定的條件。對于MySQL數據庫,對CHECK子句進行分析,但是忽略CHECK子句。
create table student(id int ,age int,name varchar(8),birth date,math decimal(10, 2),english decimal(10, 2),CHECK(age < 18)//確保年齡小于18 );//插入一個年齡為11的數據 INSERT INTO student VALUES(1, 11, "李華", 20200812, 76.5, 87.5); Query OK, 0 rows affected (0.009 sec)//插入成功在MySQL中,CHECK子句的功能并沒有被實現,所以它雖然會對語句進行分析,但是并不會去真正使用這個功能。
表的設計
表的關系
如果要設計一個表,首先就要考慮多個表之間的關系
一對一
例如人和身份證的關系,每個人都對應有著只屬于自己的身份證
一對多
例如學生和班級的關系,一個班級擁有多個學生,但是一個學生只能屬于一個班級
多對多
例如學生、課程、選課表的關系。
一個學生可以選擇多門課程,一個課程也可以被多個學生選擇
三大范式
表的關系只是設計的最基礎的一項,考慮好關系,確認好數據項,將數據填進去即可。
但是那樣的設計并不合理,可能會存在數據冗余、傳輸性能、查詢性能等問題,所以需要用到三大范式來規(guī)范數據庫表的設計,減少數據庫的冗余性。
范式是針對數據庫表設計的幾種方案,目前關系數據庫有六種范式:第一范式(1NF)、第二范式(2NF)、第三范式(3NF)、巴斯-科德范式(BCNF)、第四范式(4NF)和第五范式(5NF,又稱完美范式)。
通常我們使用的都是第一范式(1NF)、第二范式(2NF)、第三范式(3NF),所以又將他們稱為三大范式。
第一范式
第一范式:要求數據庫表的每一列都是不可分割的原子數據項。
例如
在這個表中,家庭信息和學校信息并不是原子的,例如家庭信息中包含了家庭組成和所在地,學校信息包含了年級和學位。
對于第一范式,需要確保每一項數據都是不可分割的原子性數據,不能是一個集合
調整后
第二范式
第二范式:在第一范式的基礎上,非主鍵數據必須完全依賴主鍵,不能部分依賴(針對組合主鍵)
第二范式的目的是確保一個表只說明一個事物
例如
在這個圖中訂單號和產品號作為組合主鍵,但是后面的訂單信息、訂單時間只與訂單號相關,而與產品號無關,部分依賴于主鍵,違反了第二范式。可以看到,后面的數據中存在著大量的重復,造成了數據冗余
所以需要將其分割出去單獨建立一個表
第三范式
第三范式:在第二范式的基礎上,非主鍵數據之間不能相互依賴,依賴關系不能傳遞,每一個非主鍵數據都必須要和主鍵直接依賴而非間接依賴
第三范式主要解決依賴關系傳遞帶來的數據冗余問題
例如
該圖中,班主任性別與班主任年齡直接依賴于班主任姓名,而與主鍵學號并沒有直接的依賴關系,而是間接,存在著依賴傳遞的問題。
所以需要將這兩項分割出去單獨建表
總結
以上是生活随笔為你收集整理的MySQL(三)数据库的六种约束、表的关系、三大范式的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: MySQL(二): 表的增删查改
- 下一篇: MySQL(四)复合查询与联合查询