MySQL外鍵關聯(一對多)
外鍵說明
什麼是外鍵?
1)表A中有字段(如身份證號)做了主鍵,表B中也有這個字段(身份證號),這裏的身份證號一定來自表A同樣字段裏的內容,但再B表中身份證號對應id可以重複
2)那麼表B的這個字段就叫表A字段的外鍵,也就是兩個表以身份證號這個字段建立了聯繫
外鍵作用
1)爲了一張表記錄的數據不要太過冗餘
2)保持數據的一致性、完整性
- 一致性: 外鍵的作用就是可以讓身份證號保證是來自表A中,也就是保證了數據的一致性
- 完整性: 如果要刪除A表中的某個身份證號,那麼首先要刪除B表中同樣的身份證號,這保證了數據的完整性
創建學生表(student), 和學生每天上課記錄表(student_record)
student和student_record表創建語法
#1、student表
create table student(
id int auto_increment,
name char(32) not null,
age int not null,
register_data date not null,
primary key (id))
engine=InnoDB
;
#2、student_record表
create table study_record (
id int(11) auto_increment,
day int NOT NULL,
status char(32) NOT NULL,
stu_id int(11) NOT NULL,
primary key (id),
CONSTRAINT fk_student_key FOREIGN KEY (stu_id) REFERENCES student (id)
)
engine=InnoDB
;
在student表中創建兩條記錄
mysql> insert into student(name,age,register_data) values("zhangsan",100,"2016-06-20");
mysql> insert into student(name,age,register_data) values("lisi",101,"2016-06-21");
在student_record表中創建與student表的關聯記錄(day,status,stu_id)
mysql> insert into study_record (day,status,stu_id) values(1,"yes",1); # student表id=1第一天到了
mysql> insert into study_record (day,status,stu_id) values(1,"yes",2); # student表id=2第一天到了
mysql> insert into study_record (day,status,stu_id) values(1,"yes",3); # 會報錯,因爲student沒id=3
如果有student表中有student_record表關聯的數據,你是不能刪除student表中的記錄(報錯)
mysql> delete from student where name='lisi';
查看剛剛創建study_record表結構創建記錄
mysql> show create table study_record;
django在model中添加一對多字段後migrate報錯,手動解決衝突
- 添加普通字段(django model中添加 max_times 字段)
alter table notify_notifybytagrelation add column max_times int not null;
- 創建外鍵關聯的表(django model添加了notify_tagnotifygroup表)
notify_tagnotifygroup
create table notify_tagnotifygroup(
id int auto_increment,
name char(255) not null,
notify_interval int not null,
max_times int not null,
primary key (id));
- 添加外鍵(django model中已有表的group_notify字段關聯了2中的表,一對多)
1)添加字段(這個字段作爲本表外鍵)
alter table notify_notifybytagrelation add column group_notify_id int;
2)創建外鍵關係(將上面創建的 group_notify_id 外鍵添加外鍵關係)
說明:notify_notifybytagrelation 表中的group_notify_id作爲外鍵關聯notify_tagnotifygroup表的主鍵id
alter table notify_notifybytagrelation add foreign key(group_notify_id) references notify_tagnotifygroup(id);
- mysql手動創建和刪除外鍵約束
創建student和student_record表,但不直接創建外鍵關聯
#1、student表
create table student(
id int auto_increment,
name char(32) not null,
age int not null,
primary key (id))
engine=InnoDB
;
#2、student_record表
create table study_record (
id int(11) auto_increment,
day int NOT NULL,
status char(32) NOT NULL,
primary key (id))
engine=InnoDB
;
手動創建外鍵關聯的字段和外鍵約束
alter table study_record add column stu_id int; # 創建stu_id作爲外鍵關聯字段
# 說明:創建外鍵約束study_record 表中的 stu_id 字段 一對多外鍵關聯 student 表的 id 字段
alter table study_record add foreign key(stu_id) references student(id);
查看數據庫表創建的sql語句
mysql> show create table study_record;
| study_record | CREATE TABLE `study_record` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`day` int(11) NOT NULL,
`status` char(32) NOT NULL,
`stu_id` int(11) DEFAULT NULL,
PRIMARY KEY (`id`),
KEY `stu_id` (`stu_id`),
CONSTRAINT `study_record_ibfk_1` FOREIGN KEY (`stu_id`) REFERENCES `student` (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 |
解除外鍵約束
alter table study_record drop foreign key study_record_ibfk_1;
show create table study_record;
| study_record | CREATE TABLE `study_record` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`day` int(11) NOT NULL,
`status` char(32) NOT NULL,
`stu_id` int(11) DEFAULT NULL,
PRIMARY KEY (`id`),
KEY `stu_id` (`stu_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 |
刪除外鍵
mysql> alter table study_record drop stu_id;
show create table study_record;
| study_record | CREATE TABLE `study_record` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`day` int(11) NOT NULL,
`status` char(32) NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 |
手動創建django表關聯關係
class NewFlowUserRoleActionConf(models.Model):
flowconf = models.ForeignKey(FlowConf, verbose_name='流程審批名稱')
approvetype = models.CharField(max_length=32, verbose_name='審批類型')
sequence = models.IntegerField(verbose_name='審批序號')
approvetogroupuser = models.BooleanField(default=True, verbose_name='是否允許指派組內執行')
approvetorole = models.BooleanField(default=False, verbose_name='是否角色組審批')
create table workflow_newflowuserroleactionconf (
id int(11) auto_increment,
flowconf_id int NOT NULL,
approvetype char(64) NOT NULL,
sequence int NOT NULL,
approvetogroupuser int NOT NULL,
approvetorole int NOT NULL,
primary key (id),
CONSTRAINT fk_workflow_flowconf_key FOREIGN KEY (flowconf_id) REFERENCES workflow_newflowuserroleactionconf (id)
)
engine=InnoDB
;
MySQL連接查詢:兩個表之間外鍵關聯
left join (左連接:兩個表的差集)
1、左連接where隻影向右表,所以左表(student)中數據全部顯示,右表study_record表中不符合where條件的數據不會顯示
2、select * from student left join study_record on student.id=study_record.stu_id;
right join (右連接:兩個表的差集)
1、右連接where隻影向左表,所以左表(student)中不符合where條件的數據不會顯示,右表study_record表內容全部顯示
2、select * from student right join study_record on student.id=study_record.stu_id;
inner join (內連接:兩個表的交集)
inner join:理解爲“有效連接”,兩張表中都有的數據纔會顯示left join
select * from student inner join study_record on student.id=study_record.stu_id; # 等價於面這條語句
select * from student,study_record where study_record.stu_id = student.id;
Full join(兩個表的並集)
select * from a FULL JOIN b on a.a = b.b; # MySQL不支持這個命令(可以使用下面語句代替,兩行是一個語句)
select * from student left join study_record on student.id=study_record.stu_id UNION
select * from student right join study_record on student.id=study_record.stu_id;