1. 程式人生 > >day037-2 mysql資料庫完整性約束

day037-2 mysql資料庫完整性約束

本節內容:

1、介紹什麼是約束條件
2、not null(不能為空)與default(預設值)
3、unique(唯一)
4、primary key(主鍵,不為空且唯一)
5、auto_incerment(自增id序號)
6、foreign key(外來鍵,表之間的指向關係,關聯關係)

一、介紹什麼是約束條件

約束條件與資料型別的寬度一樣,都是可選引數

  作用:用於保證資料的完整性和一致性
  主要分為:

PRIMARY KEY (PK)    標識該欄位為該表的主鍵,可以唯一的標識記錄
FOREIGN KEY (FK)    標識該欄位為該表的外來鍵

NOT NULL    標識該欄位不能為空,即不可為null,但是可以為'',空字元並不是空

UNIQUE KEY (UK)    標識該欄位的值是唯一的

AUTO_INCREMENT    標識該欄位的值自動增長(整數型別,而且為主鍵)

DEFAULT    為該欄位設定預設值,設定以後,當not null條件下,不輸入,就為預設值

UNSIGNED 無符號
ZEROFILL 使用0填充
Mysql Copy

一些說明

1. 是否允許為空,預設NULL,可設定NOT NULL,欄位不允許為空,必須賦值
2. 欄位是否有預設值,預設的預設值是NULL,如果插入記錄時不給欄位賦值,此欄位使用預設值
sex enum('male','female') not null default 'male' age int unsigned NOT NULL default 20 必須為正值(無符號) 不允許為空 預設是20 3. 是否是key 主鍵 primary key 外來鍵 foreign key 索引 (index,unique...) 
Python Copy

二、not null與default

1、not null(不可空)

是否可空,null表示空,非字串,

  not null – 不可空(指什麼都沒有輸入),但是空字元可以,
  null – 可空,不輸入任何都可以

2、default(預設值)

預設值,建立列時可以指定預設值,
當插入資料時如果未主動設定,則自動新增預設值

3、輸入相關命令的示例及結論

create table tb2(

    id int not null default 2, # int型別的,不可為空且設定了預設值
    num int not null # 不可為空,但沒有設定預設值,預設值為null
  );

# 1、非嚴格模式,如果int型別,不傳值,因null不是int型別,該處的值將預設為0;
mysql> insert into tb2(id,num) values (1,); # 只插入一條資料也是可以的

# 注意:即便是你只給一個欄位傳值了,那麼也是生成一整條記錄,
這條記錄的其他欄位的值如果可以為空,那麼他們就都是null空值,
如果不能為空,就會報錯。

# 2、嚴格模式,傳非int型別的值,該處的值也是0
mysql> insert into tb2(id,num) values (1,'疏影');
Mysql Copy

綜合練習

mysql> create table student(
    -> name varchar(20) not null, -> age int(3) unsigned not null default 18, -> sex enum('male','female') default 'male', -> hobby set('play','study','read','music') default 'play,music' -> ); mysql> desc student; +-------+------------------------------------+------+-----+------------+-------+ | Field | Type | Null | Key | Default | Extra | +-------+------------------------------------+------+-----+------------+-------+ | name | varchar(20) | NO | | NULL | | | age | int(3) unsigned | NO | | 18 | | | sex | enum('male','female') | YES | | male | | | hobby | set('play','study','read','music') | YES | | play,music | | +-------+------------------------------------+------+-----+------------+-------+ mysql> insert into student(name) values('chao'); mysql> select * from student; +------+-----+------+------------+ | name | age | sex | hobby | +------+-----+------+------------+ | chao| 18 | male | play,music | +------+-----+------+------------+ 
Python Copy

三、unique(唯一性,一種key)

獨一無二,唯一屬性:id,身份證號等

  是一種key,唯一鍵,是在資料型別之外的附加屬性,
其實還有加速查詢的作用,後面再講這個。

1、unique建立

unique建立

============設定唯一約束 UNIQUE=============== 方法一: create table department1( id int, name varchar(20) unique, # 設定唯一 comment varchar(100) ); 方法二: create table department2( id int, name varchar(20), comment varchar(100), constraint uk_name unique(name) # 設定唯一 ); mysql> insert into department1 values(1,'IT','技術'); Query OK, 1 row affected (0.00 sec) mysql> insert into department1 values(1,'IT','技術'); # 報錯,唯一性,不可重複 ERROR 1062 (23000): Duplicate entry 'IT' for key 'name' 
Python Copy

2、聯合唯一(多值相同,方為重複)

就是多個值都相同,才是重複;
多個值,只要有一項不同,就不影響唯一性
例如:兩個妹子的打扮,
聯合唯一可以比喻成衣服和褲子同時一樣才是重複,才跟唯一性衝突
褲子一樣,衣服不同,這時並不是重複,並不影響唯一性

聯合唯一

create table service(
id int primary key auto_increment,
name varchar(20), host varchar(15) not null, port int not null, unique(host,port) # 聯合唯一,這兩個值都相同,才是重複,才是唯一 ); mysql> insert into service values -> (1,'nginx','192.168.0.10',80), -> (2,'haproxy','192.168.0.20',80), -> (3,'mysql','192.168.0.30',3306) -> ; Query OK, 3 rows affected (0.01 sec) Records: 3 Duplicates: 0 Warnings: 0 mysql> insert into service(name,host,port) values('nginx','192.168.0.10',80); ERROR 1062 (23000): Duplicate entry '192.168.0.10-80' for key 'host' 
Python Copy

四、primary key(主鍵,設定後不為空且唯一)

從約束角度看primary key欄位的值不為空且唯一,
那我們直接使用not null+unique不就可以了嗎,要它幹什麼?

  主鍵primary key是innodb儲存引擎組織資料的依據,
innodb稱之為索引組織表,一張表中必須有且只有一個主鍵。

  一個表中可以:
   單列做主鍵
   多列做主鍵(複合主鍵或者叫做聯合主鍵)

1、關於主鍵的通俗解釋和強調內容(重點*****)

unique key和primary key都是MySQL的特殊型別,
不僅僅是個欄位約束條件,還稱為索引,可以加快查詢速度,
這個索引功能我們後面再講,現在只講一下這些key作為約束條件的效果。

關於主鍵的強調內容:
  1.一張表中必須有,並且只能由一個主鍵欄位:innodb引擎下儲存表資料的時候,
   會通過你的主鍵欄位的資料來組織管理所有的資料,將資料做成一種樹形結構的資料結構,
   幫你較少IO次數,提高獲取定位資料、獲取資料的速度,優化查詢。

   解釋:如果我們在一張表中沒有設定primary key,那麼mysql在建立表的時候,
   會按照順序從上到下遍歷你設定的欄位,直到找到一個not null unique的欄位,
   自動識別成主鍵pri,通過desc可以看到,這樣是不是不好啊,所以我們在建立表的時候,
   要給他一個主鍵,讓他優化的時候用,

   如果沒有pri也沒有not null unique欄位,那麼innodb引擎下的mysql被逼無奈,
   你沒有設定主鍵欄位,主鍵又有不為空且唯一的約束,又不能擅自給你的欄位加上這些約束,
   那麼沒辦法,它只能給你新增一個隱藏欄位來幫你組織資料,
   如果是這樣,你想想,主鍵是不是幫我們做優化查詢用的啊,

   這個優化是我們可以通過主鍵來查詢資料:
   例如:如果我們將id設定為主鍵,當我們查一個id為30的資料的時候,
   也就是select * from tb1 where id=30;這個查詢語句的速度非常快,
   不需要遍歷前面三十條資料,就好像我們使用的字典似的,找一個字,不需要一頁一頁的翻書,
   可以首先看目錄,然後看在哪一節,然後看在哪一頁,一步步的範圍,
   然後很快就找到了,這就像我們說的mysql的索引(主鍵、唯一鍵)的工作方式,一步一步的縮小範圍來查詢,
   幾步就搞定了,所以通過主鍵你能夠快速的查詢到你所需要的資料,
   所以,如果你的主鍵是mysql幫你加的隱藏的欄位,你查詢資料的時候,
   就不能將這個隱藏欄位作為條件來查詢資料了,就不能享受到優化後的查詢速度了,對麼

  2.一張表裡面,通常都應該有一個id欄位,而且通常把這個id欄位作為主鍵,
   當然你非要讓其他的欄位作為主鍵也是可以的,看你自己的設計,
   建立表的時候,一般都會寫create table t1(id int primary key);id int primary key這個東西在建表的時候直接就寫上
Mysql Copy

2、在沒有設定主鍵的時候,not null+unique會被預設當成主鍵

在沒有設定主鍵的時候,not null+unique會被預設當成主鍵

mysql> create table t1(id int not null unique); Query OK, 0 rows affected (0.02 sec) mysql> desc t1; +-------+---------+------+-----+---------+-------+ | Field | Type | Null | Key | Default | Extra | +-------+---------+------+-----+---------+-------+ | id | int(11) | NO | PRI | NULL | | +-------+---------+------+-----+---------+-------+ 1 row in set (0.00 sec) 
Python Copy

3、單列主鍵測試

單列主鍵測試

============單列做主鍵=============== #方法一:not null+unique create table department1( id int not null unique, #主鍵 name varchar(20) not null unique, comment varchar(100) ); mysql> desc department1; +---------+--------------+------+-----+---------+-------+ | Field | Type | Null | Key | Default | Extra | +---------+--------------+------+-----+---------+-------+ | id | int(11) | NO | PRI | NULL | | | name | varchar(20) | NO | UNI | NULL | | | comment | varchar(100) | YES | | NULL | | +---------+--------------+------+-----+---------+-------+ rows in set (0.01 sec) #方法二:在某一個欄位後用primary key create table department2( id int primary key, #主鍵 name varchar(20), comment varchar(100) ); mysql> desc department2; +---------+--------------+------+-----+---------+-------+ | Field | Type | Null | Key | Default | Extra | +---------+--------------+------+-----+---------+-------+ | id | int(11) | NO | PRI | NULL | | | name | varchar(20) | YES | | NULL | | | comment | varchar(100) | YES | | NULL | | +---------+--------------+------+-----+---------+-------+ rows in set (0.00 sec) #方法三:在所有欄位後單獨定義primary key create table department3( id int, name varchar(20), comment varchar(100), constraint pk_name primary key(id); #建立主鍵併為其命名pk_name mysql> desc department3; +---------+--------------+------+-----+---------+-------+ | Field | Type | Null | Key | Default | Extra | +---------+--------------+------+-----+---------+-------+ | id | int(11) | NO | PRI | NULL | | | name | varchar(20) | YES | | NULL | | | comment | varchar(100) | YES | | NULL | | +---------+------------