1. 程式人生 > >mysql之外鍵

mysql之外鍵

1.2 pri 一對多 charset host incr name one 字符串

完整性約束

概念:約束條件與數據類型的寬度一樣,都是可選參數

作用:用於保證表與表之間的數據的完整性和準確性

可分為以下幾種:

PRIMARY KEY (PK) 標識該字段為該表的主鍵,可以唯一的標識記錄

FOREIGN KEY (FK) 標識該字段為該表的外鍵

UNIQUE KEY (UK) 標識該字段的值是唯一的

NOT NULL 標識該字段不能為空

AUTO_INCREMENT 標識該字段的值自動增長(整數類型,而且為主鍵)

DEFAULT 為該字段設置默認值

PRIMARY KEY

primary key字段的值不為空且唯一

1單列做主鍵

方法一: not null+unique
    create table department1(
                id int not null unique,    #主鍵
                name varchar(20) not null unique, 
                comment varchar(100)
                );    

方法二: 在某一個字段後用primary key (推薦)
create table department2(
id int primary key, #主鍵
name varchar(20),
         comment varchar(100)
          );

方法三:在所有字段後單獨定義primary key
   create table department3(
          id int,
          name varchar(20),
          comment varchar(100),
          primary key(id)
          # constraint pk_name primary key(id) #創建主鍵並為其命名pk_name
          );

2多列做主鍵(復合主鍵)

  create table service(
          ip varchar(15),
          port char(5),
          service_name varchar(10) not null,
          primary key(ip,port)
          );

FOREIGN KEY

外鍵的使用條件:

1.兩個表類型必須是InnoDB表,MyISAM表暫時不支持外鍵(據說以後的版本有可能支持,但至少目前不支持);

2.外鍵列必須建立了索引,MySQL 4.1.2以後的版本在建立外鍵時會自動創建索引,但如果在較早的版本則需要顯示建立;

3.外鍵關系的兩個表的列必須是數據類型相似,也就是可以相互轉換類型的列,比如int和tinyint可以,而int和char則不可以;

基本操作

1創建外表:

第一種方法:建立從表的時候就和主表建立外鍵
    CREATE TABLE TABLE_NAME(
        ‘字段‘ 類型,
        ‘字段‘ 類型,
         ...  ...
        FOREIGN KEY (從表字段) REFERENCES 主表(字段)
     );

第二種方法:建表完成之後,也可以通過sql語句和主表建立聯系
    ALTER TABLE 從表 ADD CONSTRAINT 
      外鍵名稱(形如:FK_從表_主表)
      FOREIGN KEY (從表字段)
      REFERENCES 主表(字段);

2刪除外鍵

ALTER TABLE 表名 DROP FOREIGN KEY 外鍵名稱

表與表的對應關系

通過外鍵,我們可以快速建立表與表之間的關系

  •   多對一:左表多條記錄對應右表一條記錄
  •   一對多:左表一條記錄對應右表多條記錄
  •   一對一:左表一條記錄對應右表一條記錄
  •   多對多:左表多條記錄對應右表多條記錄
例:出版社、作者信息、書
出版社出版多本書(一對多)
一個作者寫一本書(一對一)
多個出版社出版同一作者的多本書(多對多)

多對一:

# 首先應該創建被關聯的表
主表 create table press(   id int primary key auto_increment,   name varchar(20)   ); 從表 create table book(   id int primary key auto_increment,   name varchar(20),   press_id int not null,   foreign key(press_id) references press(id)   on delete cascade
  on update cascade
  );
....

多對多:

create table author(
    id int primary key auto_increment,
    name varchar(20)
    );
# 創建一張新表來存放作者表與書表的關系
create table author2book(
    id int not null unique auto_increment,
    author_id int not null,
    book_id int not null,
    constraint fk_author foreign key(author_id) references author(id)  #創建外鍵並命名為fk_author
    on delete cascade
    on update cascade,
    constraint fk_book foreign key(book_id) references book(id)
    on delete cascade
    on update cascade,
    primary key(author_id,book_id)
    );   

一對一:

create table customer(
    id int primary key auto_increment,
    name varchar(20) not null,
    qq varchar(10) not null,
    phone char(16) not null
    );

create table student(
    id int primary key auto_increment,
    class_name varchar(20) not null,
    customer_id int unique,                      #該字段一定要是唯一的
    foreign key(customer_id) references customer(id)     #外鍵的字段一定要保證unique
    on delete cascade
    on update cascade
    );    

UNIQUE KEY  

設置唯一的約束

方法一:在某一個字段後用 unique
    create table department1(
                id int,
                name varchar(20) unique,
                comment varchar(100)
                );     
方法二:在所有的字段後單獨定義unique
    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‘

聯合唯一:

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‘

NOT NULL 

是否可空,null表示空,非字符串
not null - 不可空
null - 可空

mysql> create table t2(id int not null); #設置字段id不為空
mysql> desc t2;
+-------+---------+------+-----+---------+-------+
| Field | Type    | Null | Key | Default | Extra |
+-------+---------+------+-----+---------+-------+
|  id   | int(11) | NO   |     | NULL    |       |
+-------+---------+------+-----+---------+-------+

AUTO_INCREMENT  

約束字段為自動增長,被約束的字段必須同時被key約束

1創建自增字段

create table student(
        id int primary key auto_increment,
        name varchar(20),
        sex enum(‘male‘,‘female‘) default ‘male‘
        );
# 當不指定id時,會按照自增的id增長下去,當指定id時,會按照指定的id進行增長 

2刪除自增字段

truncate student;        # 請空表
註意:對於自增的字段,使用delete刪除後,在插入值,該字段仍按照刪除前的位置繼續增長

3設置自增字段

設置自增字段的起始值  auto_increment

mysql> alter table student auto_increment=3; mysql> show create table student; ....... ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=utf8

設置步長 auto_increment_increment
  #基於會話級別
  set session auth_increment_increment=2 #修改會話級別的步長
  #基於全局級別的
  set global auth_increment_increment=2 #修改全局級別的步長(所有會話都生效)
起始值auto_increment_offset
註意:
如果auto_increment_offset的值大於auto_increment_increment的值,則auto_increment_offset的值會被忽略

DEFAULT

默認值,創建列時可以指定默認值,當插入數據時如果未主動設置,則自動添加默認值

#設置id字段有默認值後,則無論id字段是null還是not null,都可以插入空,插入空默認填入default指定的默認值
mysql> create table t3(id int default 1);
mysql> alter table t3 modify id int not null default 1; 

mysql之外鍵