MySQL外键关联(一对多)&MySQL连接查询

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;
在这里插入图片描述

发布了75 篇原创文章 · 获赞 62 · 访问量 4625

猜你喜欢

转载自blog.csdn.net/weixin_45139342/article/details/105317081
今日推荐